Enhance tool documentation and add new features

- Added module-level documentation for memory tools (`remember`, `recall`, `forget`) to clarify their purpose.
- Improved documentation in `recall.rs` and `remember.rs` to describe the functionality and flow of memory entry operations.
- Updated `mod.rs` to include descriptions for the tool trait and execution context.
- Enhanced `plan.rs` with detailed comments on plan-mode signaling tools.
- Documented text search tools in `search.rs` to explain their functionality.
- Improved sequential-thinking tool documentation in `seqthink.rs`.
- Added safety filter documentation in `shell_filter` for credential and git operations.
- Enhanced utility tools documentation, including `cd`, `dir_cache_update`, and `todowrite`.
- Improved rendering documentation in view modules (`chat`, `markdown`, `status`, `workflow`) to clarify rendering flows and purposes.
This commit is contained in:
asepharyana
2026-07-12 11:28:39 +07:00
parent 7158d362fd
commit 2efd40ca88
124 changed files with 2379 additions and 19 deletions
+38 -5
View File
@@ -1,3 +1,7 @@
//! Subagent execution loop: drive an LLM conversation, gate tool calls
//! against the context's allowlist, run tools, and stream progress events
//! to the parent via an mpsc channel.
use tokio::sync::mpsc;
use crate::dto::chat::message::ChatMessage;
use crate::dto::provider::request::ToolDef;
@@ -5,12 +9,20 @@ use crate::tool::{all_tools, tool_defs, tool_is_risky};
use super::context::SubagentContext;
use super::event::SubagentEvent;
/// Upper bound on agent loop steps; effectively unbounded (`usize::MAX`).
#[allow(dead_code)]
pub const MAX_AGENT_STEPS: usize = usize::MAX;
/// Maps a subagent's allowed tool names to concrete Tool trait objects and
/// OpenAI-style tool definitions. When `allowed_tools` is empty every tool is
/// available; otherwise only explicitly allowed ones are included.
/// OpenAI-style tool definitions.
///
/// Flow: load `all_tools()` → if `allowed_tools` is empty, use all; else
/// filter by membership → derive `ToolDef`s for the LLM.
///
/// Why: an empty allowlist means "no restriction" (matches
/// `build_subagent_context`'s default for non-reviewer roles).
///
/// Return: `(tool impls, schema defs)` for the subagent to use.
fn build_subagent_tools(allowed_tools: &[String]) -> (Vec<Box<dyn crate::tool::Tool>>, Vec<ToolDef>) {
let all = all_tools();
let filtered: Vec<Box<dyn crate::tool::Tool>> = if allowed_tools.is_empty() {
@@ -24,9 +36,16 @@ fn build_subagent_tools(allowed_tools: &[String]) -> (Vec<Box<dyn crate::tool::T
(filtered, defs)
}
/// Resolves the API key, model, and base URL from the persisted application
/// configuration rather than environment variables, matching how the main agent
/// resolves its credentials.
/// Resolve the API key, model, and base URL from persisted app config.
///
/// Flow: try the settings key for the active provider → fall back to the
/// provider's `api_key_env` env-var → fall back to the provider's
/// `default_api_key` → fall back to an empty string.
///
/// Why: matches the main agent's credential resolution exactly, so
/// subagents automatically inherit the same provider settings.
///
/// Return: `(api_key, model, optional_base_url)`.
fn resolve_provider_config() -> (String, String, Option<String>) {
let settings = crate::model::settings::Settings::load();
let app_config = crate::model::app_config::AppConfig::load();
@@ -54,6 +73,20 @@ fn resolve_provider_config() -> (String, String, Option<String>) {
(api_key, model, base_url)
}
/// Synchronous subagent entry point: run up to `ctx.max_steps` iterations
/// of the LLM tool loop.
///
/// Flow: inject system prompt → for each step: resolve provider config,
/// build an LLM client, call `chat_with_tools_non_streaming`, process tool
/// calls or collect text output → send `SubagentEvent`s on `tx` → break on
/// first text-only (non-empty) response.
///
/// Why: runs synchronously on a dedicated thread so the main async event
/// loop is not blocked. Tool gating prevents restricted or risky tools from
/// executing unless explicitly allowed.
///
/// Return: the concatenated text output, or an `anyhow::Error` if the LLM
/// call fails at any step.
pub fn run_subagent(ctx: SubagentContext, tx: mpsc::Sender<SubagentEvent>) -> anyhow::Result<String> {
let mut output = String::new();
let mut messages: Vec<ChatMessage> = Vec::new();