Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/plans/core-decomposition-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,11 @@ pub fn create_tool_registry() -> ToolRegistry {
- `Tool` trait、`ToolUseContext` 和具体工具实现仍在 core;它们直接连接 workspace service、snapshot wrapper、computer-use host、cancellation token 与 Deep Review checkpoint hook。`ToolContextFacts` / `PortableToolContextProvider` 只能作为只读事实投影,继续迁移前必须先确认 service port 方案,并补工具清单等价性测试。
- 最新主干新增的 Deep Review shared-context / evidence-ledger checkpoint hook 仍保留在 core 的 `ToolUseContext` 中;在设计独立 tool context / event port 前,不应把 `ToolUseContext` 或 concrete tool implementation 继续外移。
- 最新主干新增 on-demand tool spec discovery:`ToolExposure`、`GetToolSpec` 名称、collapsed prompt stub、manifest ordering 与 GetToolSpec presentation/schema 的纯契约已可由 `bitfun-agent-tools` 承载;`manifest_resolver`、collapsed-tool catalog、context-aware `description_with_context` / `input_schema_for_model_with_context`、`GetToolSpecTool` 执行以及 `ToolUseContext.unlocked_collapsed_tools` 仍会影响模型可见工具集合。该变化不推翻 PR4 的低风险结论,但把后续 tool/provider 迁移提升为高风险项,不能在 product-domain runtime 收尾中顺带执行。
- H1 start(2026-05-19):`StaticToolProviderGroup` 通用容器已迁入
`bitfun-agent-tools`,core 的 `static_providers.rs` 只负责实例化 concrete tools 并按既有
provider group 顺序装配。该切片不移动 concrete tool implementation、`ToolUseContext`、
runtime manifest assembly 或 `GetToolSpec` 执行;provider id、工具顺序与 manifest 快照由
`bitfun-agent-tools` contract test、core registry snapshot 和 boundary check 共同保护。

**验证:**

Expand Down
11 changes: 8 additions & 3 deletions scripts/check-core-boundaries.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,10 @@ const requiredContentRules = [
regex: /\bpub fn sort_tool_manifest_definitions\b/,
message: 'missing prompt-visible manifest ordering helper',
},
{
regex: /\bpub struct StaticToolProviderGroup\b/,
message: 'missing generic static provider group container',
},
],
},
{
Expand Down Expand Up @@ -1227,8 +1231,8 @@ const requiredContentRules = [
message: 'missing builtin static tool provider owner',
},
{
regex: /\bStaticToolProvider\b/,
message: 'missing static provider contract use',
regex: /\bStaticToolProviderGroup\b/,
message: 'missing generic static provider group contract use',
},
{
regex: /core\.basic/,
Expand Down Expand Up @@ -3077,7 +3081,7 @@ function runManifestParserSelfTest() {
path: 'src/crates/core/src/agentic/tools/static_providers.rs',
contracts: [
'builtin_static_tool_providers',
'StaticToolProvider',
'StaticToolProviderGroup',
'core.basic',
'core.agent',
'core.session',
Expand All @@ -3092,6 +3096,7 @@ function runManifestParserSelfTest() {
'PortableToolContextProvider',
'ToolWorkspaceKind',
'StaticToolProvider',
'StaticToolProviderGroup',
'install_static_provider',
],
},
Expand Down
3 changes: 3 additions & 0 deletions src/crates/agent-tools/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ the product tool runtime.
path-resolution DTOs, generic/static/dynamic provider contracts, pure
manifest/exposure helpers, GetToolSpec presentation/schema helpers, and
`ToolContextFacts` / `PortableToolContextProvider`.
- This crate may own generic provider containers such as
`StaticToolProviderGroup`, but concrete tool construction and product runtime
registration stay outside this crate until H1 explicitly moves an owner.
- Do not move `ToolUseContext`, concrete tools, workspace services, cancellation
tokens, snapshot decoration, collapsed unlock state, runtime manifest
assembly, or `GetToolSpec` execution here without H1 approval and equivalence
Expand Down
21 changes: 21 additions & 0 deletions src/crates/agent-tools/src/framework.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,27 @@ pub trait StaticToolProvider<Tool: ?Sized>: Send + Sync {
fn tools(&self) -> Vec<ToolRef<Tool>>;
}

pub struct StaticToolProviderGroup<Tool: ?Sized> {
provider_id: &'static str,
tools: Vec<ToolRef<Tool>>,
}

impl<Tool: ?Sized> StaticToolProviderGroup<Tool> {
pub fn new(provider_id: &'static str, tools: Vec<ToolRef<Tool>>) -> Self {
Self { provider_id, tools }
}
}

impl<Tool: ?Sized + Send + Sync> StaticToolProvider<Tool> for StaticToolProviderGroup<Tool> {
fn provider_id(&self) -> &'static str {
self.provider_id
}

fn tools(&self) -> Vec<ToolRef<Tool>> {
self.tools.clone()
}
}

pub struct ToolRegistry<Tool: ToolRegistryItem + ?Sized> {
tools: IndexMap<String, ToolRef<Tool>>,
dynamic_tools: IndexMap<String, DynamicToolMetadata>,
Expand Down
20 changes: 10 additions & 10 deletions src/crates/agent-tools/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ pub use bitfun_runtime_ports::{
DynamicToolDescriptor, DynamicToolProvider, PortError, PortErrorKind, PortResult, ToolDecorator,
};
pub use framework::{
build_collapsed_tool_stub_definition, build_get_tool_spec_assistant_detail,
build_get_tool_spec_collapsed_tool_entry, build_get_tool_spec_description,
build_get_tool_spec_duplicate_load_hint, get_tool_spec_input_schema,
resolve_tool_manifest_policy, sort_tool_manifest_definitions, tool_manifest_sort_rank,
validate_get_tool_spec_input, DynamicMcpToolInfo, DynamicToolInfo, PortableToolContextProvider,
StaticToolProvider, ToolContextFacts, ToolExposure, ToolManifestDefinition,
ToolManifestPolicyResolution, ToolManifestPolicyTool, ToolPathBackend, ToolPathOperation,
ToolPathPolicy, ToolPathResolution, ToolRef, ToolRegistry, ToolRegistryItem, ToolRenderOptions,
ToolRestrictionError, ToolResult, ToolRuntimeRestrictions, ToolWorkspaceKind, ValidationResult,
GET_TOOL_SPEC_TOOL_NAME,
DynamicMcpToolInfo, DynamicToolInfo, GET_TOOL_SPEC_TOOL_NAME, PortableToolContextProvider,
StaticToolProvider, StaticToolProviderGroup, ToolContextFacts, ToolExposure,
ToolManifestDefinition, ToolManifestPolicyResolution, ToolManifestPolicyTool, ToolPathBackend,
ToolPathOperation, ToolPathPolicy, ToolPathResolution, ToolRef, ToolRegistry, ToolRegistryItem,
ToolRenderOptions, ToolRestrictionError, ToolResult, ToolRuntimeRestrictions,
ToolWorkspaceKind, ValidationResult, build_collapsed_tool_stub_definition,
build_get_tool_spec_assistant_detail, build_get_tool_spec_collapsed_tool_entry,
build_get_tool_spec_description, build_get_tool_spec_duplicate_load_hint,
get_tool_spec_input_schema, resolve_tool_manifest_policy, sort_tool_manifest_definitions,
tool_manifest_sort_rank, validate_get_tool_spec_input,
};
pub use input_validator::InputValidator;
56 changes: 40 additions & 16 deletions src/crates/agent-tools/tests/tool_contracts.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use bitfun_agent_tools::{
build_collapsed_tool_stub_definition, build_get_tool_spec_assistant_detail,
build_get_tool_spec_collapsed_tool_entry, build_get_tool_spec_description,
build_get_tool_spec_duplicate_load_hint, get_tool_spec_input_schema,
resolve_tool_manifest_policy, sort_tool_manifest_definitions, validate_get_tool_spec_input,
DynamicMcpToolInfo, DynamicToolInfo, InputValidator, ToolContextFacts, ToolExposure,
ToolImageAttachment, ToolManifestDefinition, ToolManifestPolicyTool, ToolPathBackend,
ToolPathResolution, ToolRenderOptions, ToolResult, ToolRuntimeRestrictions, ToolWorkspaceKind,
ValidationResult, GET_TOOL_SPEC_TOOL_NAME,
DynamicMcpToolInfo, DynamicToolInfo, GET_TOOL_SPEC_TOOL_NAME, InputValidator, ToolContextFacts,
ToolExposure, ToolImageAttachment, ToolManifestDefinition, ToolManifestPolicyTool,
ToolPathBackend, ToolPathResolution, ToolRenderOptions, ToolResult, ToolRuntimeRestrictions,
ToolWorkspaceKind, ValidationResult, build_collapsed_tool_stub_definition,
build_get_tool_spec_assistant_detail, build_get_tool_spec_collapsed_tool_entry,
build_get_tool_spec_description, build_get_tool_spec_duplicate_load_hint,
get_tool_spec_input_schema, resolve_tool_manifest_policy, sort_tool_manifest_definitions,
validate_get_tool_spec_input,
};
use bitfun_agent_tools::{
DynamicToolDescriptor, DynamicToolProvider, PortResult, PortableToolContextProvider,
StaticToolProvider, ToolDecorator, ToolRegistry, ToolRegistryItem,
StaticToolProvider, StaticToolProviderGroup, ToolDecorator, ToolRegistry, ToolRegistryItem,
};
use serde_json::json;
use std::path::PathBuf;
Expand Down Expand Up @@ -428,9 +428,10 @@ fn collapsed_tool_stub_definition_preserves_prompt_visible_guardrail() {

assert_eq!(stub.name, "WebFetch");
assert!(stub.description.contains("Fetch a URL"));
assert!(stub
.description
.contains("First call `GetToolSpec` with {\"tool_name\":\"WebFetch\"}"));
assert!(
stub.description
.contains("First call `GetToolSpec` with {\"tool_name\":\"WebFetch\"}")
);
assert_eq!(
stub.parameters,
json!({
Expand Down Expand Up @@ -475,10 +476,12 @@ fn get_tool_spec_contract_preserves_input_schema_and_validation() {
assert_eq!(schema["additionalProperties"], false);
assert_eq!(schema["required"], json!(["tool_name"]));
assert_eq!(schema["properties"]["tool_name"]["type"], "string");
assert!(schema["properties"]["tool_name"]["description"]
.as_str()
.unwrap_or_default()
.contains("canonical casing"));
assert!(
schema["properties"]["tool_name"]["description"]
.as_str()
.unwrap_or_default()
.contains("canonical casing")
);

let missing = validate_get_tool_spec_input(&json!({}));
assert!(!missing.result);
Expand Down Expand Up @@ -599,6 +602,27 @@ impl StaticToolProvider<RegistryMarkerTool> for RegistryMarkerProvider {
}
}

#[test]
fn static_tool_provider_group_preserves_provider_id_and_tool_order() {
let provider = StaticToolProviderGroup::new(
"core-basic",
vec![
registry_marker_tool("Read", None),
registry_marker_tool("Write", None),
],
);

assert_eq!(provider.provider_id(), "core-basic");
assert_eq!(
provider
.tools()
.iter()
.map(|tool| tool.name())
.collect::<Vec<_>>(),
vec!["Read", "Write"]
);
}

struct RegistryMarkerDecorator;

impl ToolDecorator<Arc<RegistryMarkerTool>> for RegistryMarkerDecorator {
Expand Down
51 changes: 18 additions & 33 deletions src/crates/core/src/agentic/tools/static_providers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,14 @@

use crate::agentic::tools::framework::Tool;
use crate::agentic::tools::implementations::*;
use bitfun_agent_tools::{StaticToolProvider, ToolRef};
use bitfun_agent_tools::StaticToolProviderGroup;
use std::sync::Arc;

pub(crate) struct CoreStaticToolProvider {
provider_id: &'static str,
tools: Vec<ToolRef<dyn Tool>>,
}

impl StaticToolProvider<dyn Tool> for CoreStaticToolProvider {
fn provider_id(&self) -> &'static str {
self.provider_id
}

fn tools(&self) -> Vec<ToolRef<dyn Tool>> {
self.tools.clone()
}
}

pub(crate) fn builtin_static_tool_providers() -> Vec<CoreStaticToolProvider> {
pub(crate) fn builtin_static_tool_providers() -> Vec<StaticToolProviderGroup<dyn Tool>> {
vec![
CoreStaticToolProvider {
provider_id: "core.basic",
tools: vec![
StaticToolProviderGroup::new(
"core.basic",
vec![
Arc::new(LSTool::new()),
Arc::new(FileReadTool::new()),
Arc::new(GlobTool::new()),
Expand All @@ -34,10 +19,10 @@ pub(crate) fn builtin_static_tool_providers() -> Vec<CoreStaticToolProvider> {
Arc::new(DeleteFileTool::new()),
Arc::new(BashTool::new()),
],
},
CoreStaticToolProvider {
provider_id: "core.agent",
tools: vec![
),
StaticToolProviderGroup::new(
"core.agent",
vec![
Arc::new(TaskTool::new()),
Arc::new(SkillTool::new()),
Arc::new(AskUserQuestionTool::new()),
Expand All @@ -48,20 +33,20 @@ pub(crate) fn builtin_static_tool_providers() -> Vec<CoreStaticToolProvider> {
Arc::new(GetFileDiffTool::new()),
Arc::new(LogTool::new()),
],
},
CoreStaticToolProvider {
provider_id: "core.session",
tools: vec![
),
StaticToolProviderGroup::new(
"core.session",
vec![
Arc::new(TerminalControlTool::new()),
Arc::new(SessionControlTool::new()),
Arc::new(SessionMessageTool::new()),
Arc::new(SessionHistoryTool::new()),
Arc::new(CronTool::new()),
],
},
CoreStaticToolProvider {
provider_id: "core.integration",
tools: vec![
),
StaticToolProviderGroup::new(
"core.integration",
vec![
Arc::new(WebSearchTool::new()),
Arc::new(WebFetchTool::new()),
Arc::new(ListMCPResourcesTool::new()),
Expand All @@ -75,6 +60,6 @@ pub(crate) fn builtin_static_tool_providers() -> Vec<CoreStaticToolProvider> {
Arc::new(ComputerUseTool::new()),
Arc::new(PlaybookTool::new()),
],
},
),
]
}
Loading