Skip to main content

runifold_tool/
descriptor.rs

1use std::collections::BTreeMap;
2
3use runifold_core::{CapabilityDescriptor, CapabilityId, CapabilityKind, EffectClass, RiskLevel};
4use runifold_model::ToolSpec;
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7
8/// Versioned model-facing and policy-facing description of a tool.
9#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
10pub struct ToolDescriptor {
11    /// Stable capability identity.
12    pub id: CapabilityId,
13    /// Model-facing tool name.
14    pub name: String,
15    /// Semantic contract version.
16    pub version: String,
17    /// Model-facing description.
18    pub description: String,
19    /// JSON Schema for invocation input.
20    pub input_schema: Value,
21    /// JSON Schema for successful output.
22    pub output_schema: Value,
23    /// External side-effect classification.
24    pub effect: EffectClass,
25    /// Risk classification used by policy and approval middleware.
26    pub risk: RiskLevel,
27    /// Host-only namespaced metadata.
28    pub metadata: BTreeMap<String, Value>,
29}
30
31impl ToolDescriptor {
32    /// Converts this descriptor into a grantable runtime capability.
33    pub fn capability(&self) -> CapabilityDescriptor {
34        CapabilityDescriptor {
35            id: self.id,
36            name: self.name.clone(),
37            version: self.version.clone(),
38            kind: CapabilityKind::Tool,
39            input_schema: self.input_schema.clone(),
40            output_schema: self.output_schema.clone(),
41            effect: self.effect,
42            risk: self.risk,
43            metadata: self.metadata.clone(),
44        }
45    }
46
47    /// Converts this descriptor into the subset exposed to a model.
48    pub fn model_spec(&self) -> ToolSpec {
49        ToolSpec {
50            name: self.name.clone(),
51            description: self.description.clone(),
52            input_schema: self.input_schema.clone(),
53            output_schema: Some(self.output_schema.clone()),
54            metadata: self.metadata.clone(),
55        }
56    }
57}