1use serde::{Deserialize, Serialize};
16
17pub const SDK_CAPABILITIES_SCHEMA_V1: &str = "a3s-code/sdk-capabilities/v1";
19
20pub const SDK_CAPABILITIES_SCHEMA_V2: &str = "a3s-code/sdk-capabilities/v2";
22
23#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
25#[serde(rename_all = "snake_case")]
26pub enum CapabilityTier {
27 Baseline,
29 Advanced,
31}
32
33impl CapabilityTier {
34 pub const fn as_str(self) -> &'static str {
35 match self {
36 Self::Baseline => "baseline",
37 Self::Advanced => "advanced",
38 }
39 }
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
49pub struct SdkCapability {
50 pub id: String,
52 pub category: String,
54 pub description: String,
56 pub operations: Vec<String>,
59 pub host_owned: bool,
61 pub tier: CapabilityTier,
63}
64
65struct CapabilitySpec {
66 id: &'static str,
67 category: &'static str,
68 description: &'static str,
69 operations: &'static [&'static str],
70 host_owned: bool,
71 tier: CapabilityTier,
72}
73
74const CAPABILITY_SPECS: &[CapabilitySpec] = &[
75 CapabilitySpec {
76 id: "agent_runtime",
77 category: "runtime",
78 description: "Create agents, bind workspaces, resume, replace, and close sessions.",
79 operations: &["agent.create", "agent.session", "agent.resume_session", "agent.close"],
80 host_owned: false,
81 tier: CapabilityTier::Baseline,
82 },
83 CapabilitySpec {
84 id: "conversation",
85 category: "runtime",
86 description: "Send, run, stream, attach content, inspect history, and cancel transcript-affecting turns.",
87 operations: &[
88 "session.send",
89 "session.run",
90 "session.stream",
91 "session.send_with_attachments",
92 "session.history",
93 "session.cancel",
94 ],
95 host_owned: false,
96 tier: CapabilityTier::Baseline,
97 },
98 CapabilitySpec {
99 id: "run_control",
100 category: "runtime",
101 description: "Steer or cooperatively interrupt an active run with idempotent receipts and optimistic turn guards.",
102 operations: &["session.steer", "session.interrupt", "session.run_control_snapshot"],
103 host_owned: true,
104 tier: CapabilityTier::Baseline,
105 },
106 CapabilitySpec {
107 id: "governed_tools",
108 category: "execution",
109 description: "Invoke built-in and MCP tools through validation, policy, confirmation, hooks, budgets, and tracing.",
110 operations: &["session.tool", "session.governed_tool", "session.tool_definitions"],
111 host_owned: true,
112 tier: CapabilityTier::Baseline,
113 },
114 CapabilitySpec {
115 id: "workspace_tools",
116 category: "workspace",
117 description: "Read, write, list, edit, patch, shell, glob, and grep through the governed workspace boundary.",
118 operations: &[
119 "session.read_file",
120 "session.write_file",
121 "session.ls",
122 "session.edit_file",
123 "session.patch_file",
124 "session.bash",
125 "session.glob",
126 "session.grep",
127 "session.git",
128 ],
129 host_owned: true,
130 tier: CapabilityTier::Baseline,
131 },
132 CapabilitySpec {
133 id: "workspace_retrieval",
134 category: "workspace",
135 description: "Run exact, lexical, symbol, semantic, and hybrid retrieval with bounded session-owned state.",
136 operations: &[
137 "session.workspace_retrieval_status",
138 "session.semantic_search",
139 "session.hybrid_search",
140 ],
141 host_owned: true,
142 tier: CapabilityTier::Baseline,
143 },
144 CapabilitySpec {
145 id: "model_adapters",
146 category: "model",
147 description: "Resolve configured Anthropic, OpenAI-compatible, and custom host model adapters.",
148 operations: &["agent.create", "session.send", "session.stream"],
149 host_owned: true,
150 tier: CapabilityTier::Baseline,
151 },
152 CapabilitySpec {
153 id: "structured_output",
154 category: "model",
155 description: "Request schema-constrained model output with validation and bounded repair.",
156 operations: &["session.send", "session.run", "session.task"],
157 host_owned: true,
158 tier: CapabilityTier::Baseline,
159 },
160 CapabilitySpec {
161 id: "mcp_and_skills",
162 category: "extension",
163 description: "Discover and mutate isolated MCP servers and filesystem or inline Skills.",
164 operations: &[
165 "session.add_mcp",
166 "session.remove_mcp",
167 "session.mcps",
168 "session.add_skill",
169 "session.skill_names",
170 ],
171 host_owned: true,
172 tier: CapabilityTier::Baseline,
173 },
174 CapabilitySpec {
175 id: "planning_delegation",
176 category: "orchestration",
177 description: "Run plans, worker agents, and unified `task` delegation with bounded fan-out and cancellation. Model-visible `parallel_task` is removed (`HARNESS-CONV4`); use `session.tasks` / multi-item `task`.",
178 operations: &["session.task", "session.tasks", "session.register_worker_agent"],
179 host_owned: true,
180 tier: CapabilityTier::Baseline,
181 },
182 CapabilitySpec {
183 id: "priority_scheduling",
184 category: "orchestration",
185 description: "Share bounded priority/FIFO admission and observe scheduler occupancy, fairness, and lifecycle counters.",
186 operations: &[
187 "session.task_scheduler_stats",
188 "session.task_scheduler_health",
189 "session.model_generation_pool_health",
190 "session.model_middleware_health",
191 "session.queue_stats",
192 "session.set_lane_handler",
193 ],
194 host_owned: false,
195 tier: CapabilityTier::Baseline,
196 },
197 CapabilitySpec {
198 id: "persistence",
199 category: "state",
200 description: "Atomically save and restore session state, runs, artifacts, traces, and verification evidence.",
201 operations: &["session.save", "agent.resume_session", "session.get_artifact"],
202 host_owned: true,
203 tier: CapabilityTier::Baseline,
204 },
205 CapabilitySpec {
206 id: "governance",
207 category: "security",
208 description: "Configure permissions, confirmations, hooks, budgets, verification, sanitization, and sandbox policy.",
209 operations: &[
210 "session.pending_confirmations",
211 "session.confirm_tool_use",
212 "session.register_hook",
213 "session.set_budget_guard",
214 "session.verify_commands",
215 ],
216 host_owned: true,
217 tier: CapabilityTier::Baseline,
218 },
219 CapabilitySpec {
220 id: "run_observability",
221 category: "observability",
222 description: "Inspect durable run snapshots, event pages, active tools, traces, and child-task state.",
223 operations: &[
224 "session.runs",
225 "session.run_snapshot",
226 "session.run_events",
227 "session.run_event_page",
228 "session.active_tools",
229 "session.subagent_tasks",
230 ],
231 host_owned: false,
232 tier: CapabilityTier::Baseline,
233 },
234 CapabilitySpec {
235 id: "context_memory",
236 category: "context",
237 description: "Use working, short-term, durable, and semantic memory with typed health and recall APIs.",
238 operations: &[
239 "session.memory",
240 "session.remember",
241 "session.recall",
242 "session.memory_stats",
243 ],
244 host_owned: true,
245 tier: CapabilityTier::Baseline,
246 },
247 CapabilitySpec {
248 id: "web_search",
249 category: "web",
250 description: "Search HTTP, native, RSS, and JavaScript-rendered engines through a3s-search v3.1.0.",
251 operations: &["session.web_search", "session.tool:web_search"],
252 host_owned: true,
253 tier: CapabilityTier::Baseline,
254 },
255 CapabilitySpec {
256 id: "code_intelligence",
257 category: "workspace",
258 description: "Query saved-file symbols, navigation, and diagnostics when a language service is available.",
259 operations: &[
260 "session.tool:code_symbols",
261 "session.tool:code_navigation",
262 "session.tool:code_diagnostics",
263 ],
264 host_owned: true,
265 tier: CapabilityTier::Advanced,
266 },
267 CapabilitySpec {
268 id: "cognitive_packages",
269 category: "context",
270 description: "Bind exact cited cognitive knowledge generations supplied by an authoritative host.",
271 operations: &[
272 "session.cognitive_package_binding",
273 "session.current_cognitive_package_binding",
274 ],
275 host_owned: true,
276 tier: CapabilityTier::Advanced,
277 },
278 CapabilitySpec {
279 id: "use_runtime_tasks",
280 category: "integration",
281 description: "Project host-owned A3S Use runtime tasks as governed model and direct-tool capabilities.",
282 operations: &["session.tool:use_runtime_task"],
283 host_owned: true,
284 tier: CapabilityTier::Advanced,
285 },
286 CapabilitySpec {
287 id: "programmable_workflows",
288 category: "orchestration",
289 description: "Execute bounded QuickJS programs and resumable parallel or Flow-backed workflows. Prefer unified `task` for model-driven coding fan-out; treat this surface as host-authored Advanced orchestration.",
290 operations: &[
291 "session.program",
292 "session.parallel",
293 "session.parallel_resumable",
294 "session.workflow_step",
295 ],
296 host_owned: true,
297 tier: CapabilityTier::Advanced,
298 },
299 CapabilitySpec {
300 id: "state_graph",
301 category: "state",
302 description: "Maintain hash-linked state graph events, patches, forks, and deterministic diffs.",
303 operations: &[
304 "state_graph.create",
305 "state_graph.restore",
306 "state_graph.propose_patch",
307 "state_graph.diff",
308 ],
309 host_owned: true,
310 tier: CapabilityTier::Advanced,
311 },
312 CapabilitySpec {
313 id: "agent_release_contract",
314 category: "deployment",
315 description: "Validate versioned asset manifests, provenance, and compatibility before activation.",
316 operations: &["release.admit", "release.bind_publication", "release.verify"],
317 host_owned: true,
318 tier: CapabilityTier::Advanced,
319 },
320 CapabilitySpec {
321 id: "agent_protocol",
322 category: "transport",
323 description: "Serve versioned session/run start, cancellation, recovery, and event-page protocols.",
324 operations: &[
325 "agent_protocol.start",
326 "agent_protocol.cancel",
327 "agent_protocol.recover",
328 "agent_protocol.events",
329 ],
330 host_owned: true,
331 tier: CapabilityTier::Advanced,
332 },
333 CapabilitySpec {
334 id: "evaluation_substrate",
335 category: "evaluation",
336 description: "Project bounded evidence, isolated auxiliary lifecycle, restart-safe dispatch claims, and immutable evaluation records through versioned boundaries.",
337 operations: &[
338 "evaluation.evidence",
339 "evaluation.auxiliary",
340 "evaluation.dispatch_ledger",
341 "evaluation.result",
342 "evaluation.result_store",
343 "evaluation.wire_v1",
344 ],
345 host_owned: true,
346 tier: CapabilityTier::Advanced,
347 },
348 CapabilitySpec {
349 id: "moli_runtime",
350 category: "web",
351 description: "Use a verified packaged or shared-cache Moli runtime with cross-process installation locking.",
352 operations: &["moli.default", "moli.ensure", "moli.packaged"],
353 host_owned: true,
354 tier: CapabilityTier::Advanced,
355 },
356 CapabilitySpec {
357 id: "s3_workspace",
358 category: "workspace",
359 description: "Use an S3-compatible workspace backend with bounded reads and search. Requires the SDK `s3` Cargo feature.",
360 operations: &[
361 "session.workspace_backend:s3",
362 "session.read_file",
363 "session.write_file",
364 ],
365 host_owned: true,
366 tier: CapabilityTier::Advanced,
367 },
368 CapabilitySpec {
369 id: "filesystem_agent_server",
370 category: "deployment",
371 description: "Serve agent directories with validated schedules, tools, readiness, and joined shutdown. Requires the SDK `serve` Cargo feature.",
372 operations: &["agent.serve_agent_dir", "serve.status", "serve.stop"],
373 host_owned: true,
374 tier: CapabilityTier::Advanced,
375 },
376 CapabilitySpec {
377 id: "opentelemetry",
378 category: "observability",
379 description: "Export redacted runtime traces and metrics through the optional OTLP integration. Requires the Core `telemetry` Cargo feature.",
380 operations: &["telemetry.init", "session.trace_events"],
381 host_owned: true,
382 tier: CapabilityTier::Advanced,
383 },
384];
385
386pub fn sdk_capabilities() -> Vec<SdkCapability> {
388 CAPABILITY_SPECS
389 .iter()
390 .map(|spec| SdkCapability {
391 id: spec.id.to_owned(),
392 category: spec.category.to_owned(),
393 description: spec.description.to_owned(),
394 operations: spec
395 .operations
396 .iter()
397 .map(|value| (*value).to_owned())
398 .collect(),
399 host_owned: spec.host_owned,
400 tier: spec.tier,
401 })
402 .collect()
403}
404
405pub fn sdk_baseline_capabilities() -> Vec<SdkCapability> {
407 sdk_capabilities()
408 .into_iter()
409 .filter(|capability| capability.tier == CapabilityTier::Baseline)
410 .collect()
411}
412
413pub const fn sdk_capabilities_schema() -> &'static str {
415 SDK_CAPABILITIES_SCHEMA_V2
416}
417
418#[cfg(test)]
419mod tests {
420 use super::*;
421 use std::collections::HashSet;
422
423 #[test]
424 fn inventory_is_stable_and_complete() {
425 let capabilities = sdk_capabilities();
426 assert!(capabilities.len() >= 20);
427 let ids = capabilities
428 .iter()
429 .map(|item| item.id.as_str())
430 .collect::<Vec<_>>();
431 assert_eq!(ids.len(), ids.iter().collect::<HashSet<_>>().len());
432 for capability in &capabilities {
433 assert!(!capability.category.is_empty());
434 assert!(!capability.description.is_empty());
435 assert!(!capability.operations.is_empty());
436 }
437 let required_baseline = [
438 "agent_runtime",
439 "conversation",
440 "governed_tools",
441 "workspace_tools",
442 "workspace_retrieval",
443 "planning_delegation",
444 "persistence",
445 "governance",
446 "run_control",
447 "web_search",
448 ];
449 for id in required_baseline {
450 let capability = capabilities
451 .iter()
452 .find(|item| item.id == id)
453 .unwrap_or_else(|| panic!("missing capability {id}"));
454 assert_eq!(
455 capability.tier,
456 CapabilityTier::Baseline,
457 "{id} must be baseline"
458 );
459 }
460 let required_advanced = [
461 "evaluation_substrate",
462 "state_graph",
463 "programmable_workflows",
464 "s3_workspace",
465 "filesystem_agent_server",
466 "opentelemetry",
467 "moli_runtime",
468 ];
469 for id in required_advanced {
470 let capability = capabilities
471 .iter()
472 .find(|item| item.id == id)
473 .unwrap_or_else(|| panic!("missing capability {id}"));
474 assert_eq!(
475 capability.tier,
476 CapabilityTier::Advanced,
477 "{id} must be advanced"
478 );
479 }
480 }
481
482 #[test]
483 fn planning_delegation_omits_deprecated_parallel_task() {
484 let planning = sdk_capabilities()
485 .into_iter()
486 .find(|item| item.id == "planning_delegation")
487 .expect("planning_delegation");
488 assert!(planning
489 .operations
490 .iter()
491 .all(|operation| operation != "session.parallel_task"));
492 assert!(
493 planning.description.contains("removed")
494 || planning.description.contains("HARNESS-CONV4"),
495 "planning_delegation must document parallel_task removal"
496 );
497 }
498
499 #[test]
500 fn baseline_filter_excludes_advanced_surfaces() {
501 let baseline = sdk_baseline_capabilities();
502 assert!(baseline
503 .iter()
504 .all(|capability| capability.tier == CapabilityTier::Baseline));
505 assert!(!baseline.iter().any(|capability| {
506 matches!(
507 capability.id.as_str(),
508 "evaluation_substrate"
509 | "state_graph"
510 | "s3_workspace"
511 | "filesystem_agent_server"
512 | "programmable_workflows"
513 )
514 }));
515 assert!(baseline.len() >= 12);
516 assert!(baseline.len() < sdk_capabilities().len());
517 }
518
519 #[test]
520 fn inventory_serializes_with_schema() {
521 let value = serde_json::json!({
522 "schema": sdk_capabilities_schema(),
523 "capabilities": sdk_capabilities(),
524 });
525 assert_eq!(value["schema"], SDK_CAPABILITIES_SCHEMA_V2);
526 let first = &value["capabilities"][0];
527 assert!(first.get("tier").is_some());
528 assert!(value["capabilities"]
529 .as_array()
530 .is_some_and(|items| !items.is_empty()));
531 }
532
533 #[test]
534 fn tier_display_strings_are_stable() {
535 assert_eq!(CapabilityTier::Baseline.as_str(), "baseline");
536 assert_eq!(CapabilityTier::Advanced.as_str(), "advanced");
537 }
538}