feat: add opt-in early tool call dispatch

This commit is contained in:
2026-09-29 11:07:59 +09:00
parent d1303ab638
commit cc2f8b3422
15 changed files with 1433 additions and 73 deletions
+7 -1
View File
@@ -965,6 +965,7 @@ fn manifest_to_reusable_config(manifest: &WorkerManifest) -> WorkerManifestConfi
stop_sequences: (!manifest.engine.stop_sequences.is_empty())
.then_some(manifest.engine.stop_sequences.clone()),
reasoning: manifest.engine.reasoning.clone(),
tool_call_dispatch: Some(manifest.engine.tool_call_dispatch),
tool_output: ToolOutputLimitsPartial {
default_max_bytes: Some(manifest.engine.tool_output.default_max_bytes),
per_tool: manifest.engine.tool_output.per_tool.clone(),
@@ -2226,7 +2227,8 @@ max_tokens = 3333
Some("reviewer"),
&[("reviewer", "reviewer.toml", REVIEWER_PROFILE)],
);
let parent = parent_manifest(&parent_root, Some(&parent_root.join("deny")));
let mut parent = parent_manifest(&parent_root, Some(&parent_root.join("deny")));
parent.engine.tool_call_dispatch = manifest::ToolCallDispatchMode::OnToolCallComplete;
let scope = vec![abs_rule(&delegated, Permission::Read)];
let profile_config = child_config_from_profile(
@@ -2248,6 +2250,10 @@ max_tokens = 3333
SpawnProfileSelector::Inherit,
);
assert_eq!(
inherit_config.engine.tool_call_dispatch,
Some(manifest::ToolCallDispatchMode::OnToolCallComplete)
);
for config in [profile_config, inherit_config] {
assert_eq!(config.scope.allow, scope);
assert!(config.scope.deny.is_empty());
+14
View File
@@ -7138,6 +7138,12 @@ pub fn apply_worker_manifest<C: LlmClient + 'static, A: Send + Sync>(
) {
worker.set_request_config(request_config_from_engine_manifest(wm));
worker.set_max_turns(wm.max_turns.map(|n| n.get()));
worker.set_tool_call_dispatch_mode(match wm.tool_call_dispatch {
manifest::ToolCallDispatchMode::AfterResponse => agen::ToolCallDispatchMode::AfterResponse,
manifest::ToolCallDispatchMode::OnToolCallComplete => {
agen::ToolCallDispatchMode::OnToolCallComplete
}
});
// Worker owns the lifecycle strategy for already-started tool operations.
// The provider must first accept cooperative cancellation, then confirm a
// terminal result before this bounded deadline; Agen handles only the
@@ -8721,6 +8727,7 @@ mod build_summary_prompt_tests {
top_k: Some(40),
stop_sequences: vec!["\n\n".into(), "</stop>".into()],
reasoning: None,
tool_call_dispatch: manifest::ToolCallDispatchMode::OnToolCallComplete,
tool_output: manifest::ToolOutputLimits::default(),
file_upload: manifest::FileUploadLimits::default(),
};
@@ -8732,6 +8739,13 @@ mod build_summary_prompt_tests {
assert_eq!(config.top_p, Some(0.9));
assert_eq!(config.top_k, Some(40));
assert_eq!(config.stop_sequences, vec!["\n\n", "</stop>"]);
let mut engine = Engine::new(NoopClient);
apply_worker_manifest(&mut engine, &manifest);
assert_eq!(
engine.tool_call_dispatch_mode(),
agen::ToolCallDispatchMode::OnToolCallComplete
);
}
#[test]