forked from kent/consciousness
Add {{tool:}} placeholder for agent templates
Agent templates can now inline tool call results with
{{tool: tool_name args}}. Dispatches to the same store
operations the tools use, but runs synchronously during
prompt resolution. Supports memory_render, memory_query,
memory_search, memory_links, and journal_tail.
This replaces the need for special-purpose placeholders —
{{pairs}}, {{rename}}, etc. can be expressed as queries
through {{tool: memory_query {"query": "..."}}} instead.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
be6ac762f6
commit
2587303e98
1 changed files with 44 additions and 0 deletions
|
|
@ -561,6 +561,12 @@ fn resolve(
|
||||||
Some(Resolved { text, keys })
|
Some(Resolved { text, keys })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tool:NAME ARGS — run a tool call and include its output
|
||||||
|
_ if name.starts_with("tool:") => {
|
||||||
|
let spec = name[5..].trim();
|
||||||
|
resolve_tool(spec, store, graph)
|
||||||
|
}
|
||||||
|
|
||||||
// bash:COMMAND — run a shell command and include its stdout
|
// bash:COMMAND — run a shell command and include its stdout
|
||||||
_ if name.starts_with("bash:") => {
|
_ if name.starts_with("bash:") => {
|
||||||
let cmd = &name[5..];
|
let cmd = &name[5..];
|
||||||
|
|
@ -721,6 +727,44 @@ fn resolve_memory_ratio() -> String {
|
||||||
pct, keys.len(), memory_bytes / 1024, transcript_size / 1024)
|
pct, keys.len(), memory_bytes / 1024, transcript_size / 1024)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resolve a {{tool: name {args}}} placeholder by calling the tool
|
||||||
|
/// handler from the registry. Uses block_in_place to bridge sync→async.
|
||||||
|
fn resolve_tool(spec: &str, _store: &Store, _graph: &Graph) -> Option<Resolved> {
|
||||||
|
// Parse "tool_name {json args}" or "tool_name arg"
|
||||||
|
let (name, args) = match spec.find('{') {
|
||||||
|
Some(i) => {
|
||||||
|
let name = spec[..i].trim();
|
||||||
|
let args: serde_json::Value = serde_json::from_str(&spec[i..]).ok()?;
|
||||||
|
(name, args)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let mut parts = spec.splitn(2, char::is_whitespace);
|
||||||
|
let name = parts.next()?;
|
||||||
|
match parts.next() {
|
||||||
|
Some(arg) => (name, serde_json::json!({"key": arg})),
|
||||||
|
None => (name, serde_json::json!({})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let tools = crate::agent::tools::tools();
|
||||||
|
let tool = tools.iter().find(|t| t.name == name)?;
|
||||||
|
|
||||||
|
let result = tokio::task::block_in_place(|| {
|
||||||
|
tokio::runtime::Handle::current().block_on(
|
||||||
|
(tool.handler)(None, args.clone())
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(text) => Some(Resolved { text, keys: vec![] }),
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("[defs] {{{{tool: {}}}}} failed: {}", name, e);
|
||||||
|
Some(Resolved { text: format!("(tool error: {})", e), keys: vec![] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Resolve all {{placeholder}} patterns in a prompt template.
|
/// Resolve all {{placeholder}} patterns in a prompt template.
|
||||||
/// Returns the resolved text and all node keys collected from placeholders.
|
/// Returns the resolved text and all node keys collected from placeholders.
|
||||||
pub fn resolve_placeholders(
|
pub fn resolve_placeholders(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue