Skip to content

fix(core): stamp id/name on the Toolkit.callTool single-call path - #3686

Closed
aiyili wants to merge 2 commits into
agentscope-ai:mainfrom
aiyili:fix/calltool-stamp-id-name
Closed

aiyili wants to merge 2 commits into
agentscope-ai:mainfrom
aiyili:fix/calltool-stamp-id-name

Conversation

@aiyili

@aiyili aiyili commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Fixes #3114

Problem

Toolkit.callTool(ToolCallParam) → ToolExecutor.execute(param) → executeCore — on the default zero-interceptor branch the returned block is never passed through withIdAndName, so any tool implementation that doesn't set id/name itself (most built-ins) returns a block with null id/name. The batch path (callTools → executeWithInfrastructure) always stamps. A caller following callTool's own javadoc gets a result it cannot pair back to the call.

Fix

The id/name backfill moved into applyResultErrorMapping(...) — the stage both branches already share — so the zero-interceptor and interceptor branches stamp identically, and the interceptor branch's duplicate map was removed. The batch path is untouched (executeWithInfrastructure stamps unconditionally downstream).

Test

ToolExecutorTest.callToolStampsIdAndName: register the add tool, call it via toolkit.callTool(...) with a ToolUseBlock carrying id="call-single-3114" — the returned block must have that id and name add; the same block via callTools must stamp identically. Fails on main (id is null).

callTool(param) 直达 execute→executeCore,零拦截器分支(默认路径)的
结果从不经 withIdAndName——工具实现未自带 id/name 时(内置工具多数
如此),返回块 id/name 均为 null,无法与调用配对;批量路径
callTools→executeWithInfrastructure 则总是盖章。

把回填统一收进两分支共用的 applyResultErrorMapping 末尾
(拦截器分支原地的同款 map 删除,避免双份):拦截器拒绝、错误/空合成
结果、以及未自带 id/name 的工具结果统一盖章。批量路径语义不变
(其基础设施层本就无条件盖章)。

测试:callTool 与 callTools 对同一 ToolUseBlock 返回的 id 必须一致。

Fixes agentscope-ai#3114
@aiyili

aiyili commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

You're right — and my apologies: #3130 predates mine by weeks and I missed it in the pre-claim sweep (I only scanned the first page of open PRs, sorted by creation date, and #3130 had already aged past that page). That's on me.

Facts for the maintainers, since both PRs are now on the table:

My suggestion: since #3130 has three weeks of history and review context, it should stay the canonical thread if you (KIM406) can rebase it — happy to review and close mine. If rebasing #3130 is not practical, #3686 is mergeable as-is and I'll maintain it. Either way the duplication ends with the next maintainer pass — I won't push further commits to #3686 unless asked.

@aiyili

aiyili commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

CI failure was mine — the pushed ToolExecutor.java violated Spotless (the re-wrapped indentation of the interceptor branch after the backfill moved). Fixed in 0417bfc (formatting only, no behavior change; verified the only delta vs the previous head is the re-indentation). The Windows job failed on the same spotless check cascading, so a rerun should go green.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Toolkit.callTool returns a ToolResultBlock with null id and name (bypasses executeWithInfrastructure)

1 participant