use std::collections::BTreeMap;
use runifold_core::{CapabilityDescriptor, CapabilityId, CapabilityKind, EffectClass, RiskLevel};
use runifold_model::ToolSpec;
use serde::{Deserialize, Serialize};
use serde_json::{Value, json};
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct AgentDescriptor {
pub id: CapabilityId,
pub name: String,
pub version: String,
pub description: String,
pub risk: RiskLevel,
pub metadata: BTreeMap<String, Value>,
}
impl AgentDescriptor {
pub fn new(name: impl Into<String>, description: impl Into<String>) -> Self {
Self {
id: CapabilityId::new(),
name: name.into(),
version: "1".into(),
description: description.into(),
risk: RiskLevel::Medium,
metadata: BTreeMap::new(),
}
}
pub fn capability(&self) -> CapabilityDescriptor {
CapabilityDescriptor {
id: self.id,
name: self.name.clone(),
version: self.version.clone(),
kind: CapabilityKind::Agent,
input_schema: input_schema(),
output_schema: output_schema(),
effect: EffectClass::Unknown,
risk: self.risk,
metadata: self.metadata.clone(),
}
}
pub fn model_spec(&self) -> ToolSpec {
ToolSpec {
name: self.name.clone(),
description: self.description.clone(),
input_schema: input_schema(),
output_schema: Some(output_schema()),
metadata: self.metadata.clone(),
}
}
}
fn input_schema() -> Value {
json!({
"type": "object",
"properties": {
"input": {
"type": "string",
"description": "Task or question delegated to the agent"
}
},
"required": ["input"],
"additionalProperties": false
})
}
fn output_schema() -> Value {
json!({
"type": "object",
"properties": {
"agent": {"type": "string"},
"content": {"type": "array"},
"turns": {"type": "integer", "minimum": 0},
"tool_calls": {"type": "integer", "minimum": 0},
"delegations": {"type": "integer", "minimum": 0}
},
"required": ["agent", "content", "turns", "tool_calls", "delegations"],
"additionalProperties": false
})
}