agent_sdk_toolkit/discovery/
index.rs1use std::collections::BTreeMap;
6
7use agent_sdk_core::{
8 AgentError, CapabilityCatalogSnapshot, CapabilityId, CapabilitySourceKind, PackageDelta,
9 PolicyRef, ToolPackSnapshot, TrustClass,
10};
11
12use super::types::ToolDiscoveryCandidate;
13
14#[derive(Clone, Debug, Default)]
15pub struct ToolDiscoveryIndex {
18 candidates: BTreeMap<String, ToolPackSnapshot>,
19}
20
21impl ToolDiscoveryIndex {
22 pub fn new() -> Self {
26 Self::default()
27 }
28
29 pub fn insert(&mut self, snapshot: ToolPackSnapshot) {
32 self.candidates
33 .insert(snapshot.pack_id.as_str().to_string(), snapshot);
34 }
35
36 pub fn search(&self, query: &str) -> Vec<ToolDiscoveryCandidate> {
40 self.candidates
41 .iter()
42 .filter(|(id, snapshot)| {
43 id.contains(query)
44 || snapshot
45 .tools
46 .iter()
47 .any(|tool| tool.canonical_tool_name.as_str().contains(query))
48 })
49 .map(|(id, snapshot)| ToolDiscoveryCandidate {
50 pack_id: id.clone(),
51 tool_names: snapshot
52 .tools
53 .iter()
54 .map(|tool| tool.canonical_tool_name.as_str().to_string())
55 .collect(),
56 package_delta_required: true,
57 })
58 .collect()
59 }
60
61 pub fn activation_delta(
65 &self,
66 pack_id: &str,
67 package: &agent_sdk_core::RuntimePackage,
68 requested_by: agent_sdk_core::SourceRef,
69 activation_policy_ref: PolicyRef,
70 ) -> Result<PackageDelta, AgentError> {
71 let snapshot = self
72 .candidates
73 .get(pack_id)
74 .cloned()
75 .ok_or_else(|| AgentError::missing_required_field("tool_discovery.candidate"))?;
76 let capabilities = snapshot.capability_specs()?;
77 let catalog = CapabilityCatalogSnapshot {
78 catalog_id: format!("catalog.discovery.{pack_id}"),
79 source_kind: CapabilitySourceKind::DiscoveryIndex,
80 source_ref: requested_by.clone(),
81 version: Some("v1".to_string()),
82 content_hash: Some(snapshot.content_hash()?),
83 trust_state: TrustClass::SdkGenerated,
84 activation_policy_ref,
85 candidates: capabilities
86 .iter()
87 .map(|capability| capability.capability_id.clone())
88 .collect::<Vec<CapabilityId>>(),
89 };
90 Ok(PackageDelta {
91 previous_fingerprint: package.fingerprint()?,
92 requested_by,
93 reason: "activate hidden tool discovery candidate for next package".to_string(),
94 activated_capabilities: capabilities,
95 deactivated_capability_ids: Vec::new(),
96 catalogs: vec![catalog],
97 sidecars: vec![snapshot.package_sidecar_snapshot()?],
98 })
99 }
100}