use serde_json::Value;
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct ToolManifest {
pub name: String,
pub description: String,
pub input_schema: Value,
pub scope: ToolScope,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ToolScope {
ReadOnly,
FileSystem,
Shell,
Network,
Memory,
Cloud,
}
pub struct ToolRegistry {
tools: HashMap<String, ToolManifest>,
}
impl ToolRegistry {
pub fn new() -> Self {
Self {
tools: HashMap::new(),
}
}
pub fn register(&mut self, manifest: ToolManifest) {
self.tools.insert(manifest.name.clone(), manifest);
}
pub fn get(&self, name: &str) -> Option<&ToolManifest> {
self.tools.get(name)
}
pub fn all(&self) -> Vec<&ToolManifest> {
self.tools.values().collect()
}
pub fn default_registry() -> Self {
let mut r = Self::new();
for (name, desc, scope) in BUILT_IN_TOOLS {
r.register(ToolManifest {
name: name.to_string(),
description: desc.to_string(),
input_schema: skill_schema(name),
scope: *scope,
});
}
r
}
}
impl Default for ToolRegistry {
fn default() -> Self {
Self::default_registry()
}
}
const BUILT_IN_TOOLS: &[(&str, &str, ToolScope)] = &[
(
"sieve",
"Filter raw output to task-relevant lines",
ToolScope::ReadOnly,
),
(
"cartograph",
"Scan directory → structured project map",
ToolScope::FileSystem,
),
(
"chisel",
"Extract AST symbols from files",
ToolScope::FileSystem,
),
("sediment", "Persist facts into Vault", ToolScope::Memory),
(
"prism",
"Full AST parse + index of project directory",
ToolScope::FileSystem,
),
(
"compass",
"Fuse BM25 + graph + Vault into ranked results",
ToolScope::FileSystem,
),
(
"condenser",
"Compress content via Lens stack",
ToolScope::ReadOnly,
),
(
"archivist",
"Query Vault for facts (read-only)",
ToolScope::Memory,
),
(
"scout",
"Execute shell command with output compression",
ToolScope::Shell,
),
(
"chronicler",
"Generate session narrative (read-only)",
ToolScope::ReadOnly,
),
(
"alchemist",
"Transform noisy content → structured JSON",
ToolScope::ReadOnly,
),
(
"sentinel",
"Static security risk assessment",
ToolScope::ReadOnly,
),
(
"cartridge",
"Package current context into portable bundle",
ToolScope::ReadOnly,
),
(
"resonator",
"Dense-vector semantic search over ProjectIndex",
ToolScope::FileSystem,
),
(
"surveyor",
"Compute dependency topology and impact analysis",
ToolScope::FileSystem,
),
];
fn skill_schema(name: &str) -> Value {
match name {
"scout" => serde_json::json!({
"type": "object",
"properties": {
"command": { "type": "string", "description": "Shell command to execute" },
"working_dir": { "type": "string", "description": "Working directory (default: cwd)" },
"timeout_secs": { "type": "number", "description": "Timeout in seconds (default: 30)" },
"dry_run": { "type": "boolean", "description": "Print command without executing" }
},
"required": ["command"]
}),
"cartograph" => serde_json::json!({
"type": "object",
"properties": {
"root": { "type": "string", "description": "Directory to map (default: cwd)" },
"depth": { "type": "number", "description": "Traversal depth (default: 3)" }
}
}),
"chisel" => serde_json::json!({
"type": "object",
"properties": {
"paths": { "type": "array", "items": { "type": "string" }, "description": "Files to extract symbols from" },
"filter_exported": { "type": "boolean", "description": "Only return exported symbols" }
},
"required": ["paths"]
}),
"sieve" => serde_json::json!({
"type": "object",
"properties": {
"content": { "type": "string", "description": "Raw output to filter" },
"task_hint": { "type": "string", "description": "Task context for relevance scoring" },
"budget_tokens":{ "type": "number", "description": "Token budget (default: 2000)" }
},
"required": ["content"]
}),
"condenser" => serde_json::json!({
"type": "object",
"properties": {
"content": { "type": "string", "description": "Text to compress (mutually exclusive with path)" },
"path": { "type": "string", "description": "File path to compress" },
"lens": { "type": "string", "description": "Lens to apply: clarity|narrow|focus|auto (default: auto)" },
"task_hint": { "type": "string" },
"budget_tokens":{ "type": "number", "description": "Token budget (default: 2000)" }
}
}),
"compass" => serde_json::json!({
"type": "object",
"properties": {
"query": { "type": "string", "description": "Search query" },
"root": { "type": "string", "description": "Project root (default: cwd)" },
"top_k": { "type": "number", "description": "Max results (default: 10)" }
},
"required": ["query"]
}),
"prism" => serde_json::json!({
"type": "object",
"properties": {
"root": { "type": "string", "description": "Project root to index (default: cwd)" },
"max_files": { "type": "number", "description": "Max files to parse (default: 500)" }
}
}),
"archivist" => serde_json::json!({
"type": "object",
"properties": {
"query": { "type": "string", "description": "Search query across Vault tiers" },
"top_k": { "type": "number", "description": "Max results (default: 10)" }
}
}),
"sediment" => serde_json::json!({
"type": "object",
"properties": {
"facts": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": { "type": "string" },
"value": { "type": "string" },
"category": { "type": "string" },
"confidence": { "type": "number" }
},
"required": ["key", "value"]
}
},
"target_tier": { "type": "string", "description": "resonant|crystallized (default: resonant)" }
},
"required": ["facts"]
}),
"chronicler" => serde_json::json!({
"type": "object",
"properties": {
"session_id": { "type": "string" },
"format": { "type": "string", "description": "markdown|json (default: markdown)" },
"limit": { "type": "number", "description": "Max events (default: 20)" }
}
}),
"alchemist" => serde_json::json!({
"type": "object",
"properties": {
"content": { "type": "string", "description": "Text to extract structure from" },
"domain_hint": { "type": "string", "description": "Domain hint for extraction (default: freetext)" }
},
"required": ["content"]
}),
"sentinel" => serde_json::json!({
"type": "object",
"properties": {
"subject": { "type": "string", "description": "Command, path, or code to assess" }
},
"required": ["subject"]
}),
"cartridge" => serde_json::json!({
"type": "object",
"properties": {
"max_tokens": { "type": "number", "description": "Token budget for bundle (default: 4000)" },
"session_id": { "type": "string" },
"include_recent_commands":{ "type": "boolean", "description": "Include recent shell commands (default: true)" }
}
}),
"resonator" => serde_json::json!({
"type": "object",
"properties": {
"query": { "type": "string", "description": "Semantic search query" },
"root": { "type": "string", "description": "Project root (default: cwd)" },
"top_k": { "type": "number", "description": "Max results (default: 15)" },
"auto_index": { "type": "boolean", "description": "Auto-run prism if no index found" }
},
"required": ["query"]
}),
"surveyor" => serde_json::json!({
"type": "object",
"properties": {
"root": { "type": "string", "description": "Project root (default: cwd)" },
"output_format": { "type": "string", "description": "dot|json|summary (default: dot)" }
}
}),
_ => serde_json::json!({
"type": "object",
"properties": {
"input": { "type": "string" }
}
}),
}
}