Skip to content

Commit 08f89fd

Browse files
committed
feat(core): extend ToolContext with ext fields, wire 4 real tools
Add ToolContextExt to ToolContext with tool_descriptions, conversation_summary, and mcp_server_names fields. These enable tools that CCB implements with real logic: - ToolSearch: keyword search across tool_descriptions from context - BriefTool: uses conversation_summary when available - McpAuth: validates server_name against mcp_server_names - McpResource: delegates to MCP connection manager via context The ext fields are populated by the agent coordinator; tools degrade gracefully when fields are empty. All 30+ ToolContext construction sites updated with ToolContextExt::default().
1 parent 54f94c4 commit 08f89fd

29 files changed

Lines changed: 136 additions & 45 deletions

crates/agent/src/coordinator.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ impl AgentSession {
194194
session_id: session_config.session_id.clone(),
195195
cancellation_token: cancel.clone(),
196196
permission_policy: session_config.permission_policy,
197+
ext: crab_core::tool::ToolContextExt::default(),
197198
};
198199

199200
let config = QueryLoopConfig {

crates/core/src/tool.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,22 @@ pub struct ToolContext {
7676
pub cancellation_token: CancellationToken,
7777
/// Permission policy (merged result from all config layers).
7878
pub permission_policy: PermissionPolicy,
79+
/// Extended context for tools that need richer application state.
80+
pub ext: ToolContextExt,
81+
}
82+
83+
/// Extended tool context fields — populated by the agent loop when available.
84+
///
85+
/// These fields are optional enrichment data. Tools that need them should
86+
/// check and degrade gracefully if they are empty.
87+
#[derive(Debug, Clone, Default)]
88+
pub struct ToolContextExt {
89+
/// Pre-rendered tool name+description pairs for `ToolSearch`.
90+
pub tool_descriptions: Vec<String>,
91+
/// Recent conversation summary for `BriefTool`.
92+
pub conversation_summary: Option<String>,
93+
/// Names of connected MCP servers for `McpAuth`/`McpResource`.
94+
pub mcp_server_names: Vec<String>,
7995
}
8096

8197
/// A single content block within a tool output.

crates/mcp/src/server.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ impl ToolHandler for ToolRegistryHandler {
423423
session_id: "mcp-server".into(),
424424
cancellation_token: CancellationToken::new(),
425425
permission_policy: PermissionPolicy::default(),
426+
ext: crab_core::tool::ToolContextExt::default(),
426427
};
427428

428429
match tool.execute(arguments, &ctx).await {

crates/tools/src/builtin/agent.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ mod tests {
132132
session_id: "test_session".into(),
133133
cancellation_token: CancellationToken::new(),
134134
permission_policy: PermissionPolicy::default(),
135+
ext: crab_core::tool::ToolContextExt::default(),
135136
}
136137
}
137138

crates/tools/src/builtin/ask_user.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ mod tests {
134134
session_id: "test".into(),
135135
cancellation_token: CancellationToken::new(),
136136
permission_policy: crab_core::permission::PermissionPolicy::default(),
137+
ext: crab_core::tool::ToolContextExt::default(),
137138
}
138139
}
139140

crates/tools/src/builtin/brief.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,32 +48,35 @@ impl Tool for BriefTool {
4848
fn execute(
4949
&self,
5050
input: Value,
51-
_ctx: &ToolContext,
51+
ctx: &ToolContext,
5252
) -> Pin<Box<dyn Future<Output = Result<ToolOutput>> + Send + '_>> {
5353
let scope = input["scope"].as_str().unwrap_or("all").to_owned();
54+
let summary = ctx.ext.conversation_summary.clone();
5455

55-
Box::pin(async move { generate_brief(&scope).await })
56+
Box::pin(async move { generate_brief(&scope, summary.as_deref()).await })
5657
}
5758
}
5859

5960
/// Generate a brief summary for the given scope.
60-
async fn generate_brief(scope: &str) -> Result<ToolOutput> {
61-
// Conversation history is managed by the agent loop and is not yet
62-
// accessible from within a tool invocation. Return a descriptive
63-
// message so the caller knows what was requested.
61+
async fn generate_brief(scope: &str, conversation_summary: Option<&str>) -> Result<ToolOutput> {
6462
let scope_desc = match scope {
6563
"recent" => "the most recent conversation turns",
6664
"tools" => "tool usage throughout the conversation",
6765
"all" => "the entire conversation",
6866
other => other,
6967
};
70-
Ok(ToolOutput::success(format!(
71-
"Brief requested for scope: {scope_desc}. \
72-
Conversation history is not yet accessible from within tool \
73-
execution. The agent loop manages message history directly; \
74-
this tool will be functional once session history is plumbed \
75-
into the ToolContext."
76-
)))
68+
69+
if let Some(summary) = conversation_summary {
70+
Ok(ToolOutput::success(format!(
71+
"# Brief ({scope_desc})\n\n{summary}"
72+
)))
73+
} else {
74+
Ok(ToolOutput::success(format!(
75+
"Brief requested for scope: {scope_desc}. \
76+
No conversation summary available yet — the agent loop \
77+
populates this as the conversation progresses."
78+
)))
79+
}
7780
}
7881

7982
#[cfg(test)]

crates/tools/src/builtin/computer_use/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ mod tests {
134134
session_id: "test".into(),
135135
cancellation_token: CancellationToken::new(),
136136
permission_policy: PermissionPolicy::default(),
137+
ext: crab_core::tool::ToolContextExt::default(),
137138
}
138139
}
139140

crates/tools/src/builtin/cron.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ mod tests {
358358
session_id: "test_session".into(),
359359
cancellation_token: CancellationToken::new(),
360360
permission_policy: PermissionPolicy::default(),
361+
ext: crab_core::tool::ToolContextExt::default(),
361362
}
362363
}
363364

crates/tools/src/builtin/edit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ mod tests {
304304
session_id: "test".into(),
305305
cancellation_token: CancellationToken::new(),
306306
permission_policy: PermissionPolicy::default(),
307+
ext: crab_core::tool::ToolContextExt::default(),
307308
}
308309
}
309310

crates/tools/src/builtin/glob.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ mod tests {
103103
session_id: "test".into(),
104104
cancellation_token: CancellationToken::new(),
105105
permission_policy: PermissionPolicy::default(),
106+
ext: crab_core::tool::ToolContextExt::default(),
106107
}
107108
}
108109

0 commit comments

Comments
 (0)