From 83a2cd1ac24ca0feda34ae877aaf31f41b58b86c Mon Sep 17 00:00:00 2001 From: aichat-agent Date: Thu, 1 Oct 2026 14:58:06 +0000 Subject: feat: add built-in subquery tool with hierarchical query ids * Add config options subquery and subquery_max_depth. * Register an internal subquery function that spawns a fresh LLM query with the current model configuration but without the full context. The model selects context numerically (message_indexes) or by text excerpt (excerpts). * Subqueries can use tools, including further nested subqueries up to subquery_max_depth. * Queries and subqueries get hierarchical ids ([0], [0/1], [0/1/2]) that prefix tool-call prints and spinner messages. --- src/config/mod.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/config/mod.rs') diff --git a/src/config/mod.rs b/src/config/mod.rs index 10718df..693c9f5 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -2,6 +2,7 @@ mod agent; mod input; mod role; mod session; +mod subquery; pub use self::agent::{complete_agent_variables, list_agents, Agent, AgentVariables}; pub use self::input::Input; @@ -9,6 +10,7 @@ pub use self::role::{ Role, RoleLike, CODE_ROLE, CREATE_TITLE_ROLE, EXPLAIN_SHELL_ROLE, SHELL_ROLE, }; use self::session::Session; +pub use self::subquery::{eval_subquery, SubqueryContext}; use crate::client::{ create_client_config, list_client_types, list_models, ClientConfig, MessageContentToolCalls, @@ -117,6 +119,9 @@ pub struct Config { pub mapping_tools: IndexMap, pub use_tools: Option, + pub subquery: bool, + pub subquery_max_depth: usize, + pub repl_prelude: Option, pub cmd_prelude: Option, pub agent_prelude: Option, @@ -193,6 +198,9 @@ impl Default for Config { mapping_tools: Default::default(), use_tools: None, + subquery: false, + subquery_max_depth: 3, + repl_prelude: None, cmd_prelude: None, agent_prelude: None, @@ -599,6 +607,8 @@ impl Config { ("rag_top_k", rag_top_k.to_string()), ("dry_run", self.dry_run.to_string()), ("function_calling", self.function_calling.to_string()), + ("subquery", self.subquery.to_string()), + ("subquery_max_depth", self.subquery_max_depth.to_string()), ("stream", self.stream.to_string()), ("save", self.save.to_string()), ("keybindings", self.keybindings.clone()), @@ -677,6 +687,14 @@ impl Config { } config.write().function_calling = value; } + "subquery" => { + let value = value.parse().with_context(|| "Invalid value")?; + config.write().subquery = value; + } + "subquery_max_depth" => { + let value = value.parse().with_context(|| "Invalid value")?; + config.write().subquery_max_depth = value; + } "stream" => { let value = value.parse().with_context(|| "Invalid value")?; config.write().stream = value; @@ -1710,6 +1728,10 @@ impl Config { ); functions = agent_functions; } + + if self.subquery { + functions.push(self::subquery::subquery_declaration()); + } }; if functions.is_empty() { None -- cgit v1.2.3