Problem / 问题
On a new user prompt, the runtime clears on-demand tool activations (activeDeferredToolNames.clear()), but the transcript still contains successful ToolSearch results (addedToolNames, “Activated on-demand tools: …”).
The model therefore believes those tools are in the current schema. They are not. The next call fails or the model retries ToolSearch / invents a call.
新用户消息会清空按需激活集,但历史里成功的 ToolSearch 结果还在上下文。模型以为工具可用,实际拿不到。
Stock 0.14.6 (packages/agent-runtime/src/runtime.ts):
private resetDeferredToolsForPrompt(): void {
this.activeDeferredToolNames.clear();
this.agent.state.tools = this.activeTools();
}
Called from prompt() and executeApprovedPlan() at the start of every turn.
ToolSearch.execute already writes addedToolNames onto the tool result. Compaction / UI history keep those rows. Nothing reads them back into activeDeferredToolNames.
Repro
- Agent mode, catalog with deferred tools (Skill, BrowserPreview, plugin tools, …).
ToolSearch { query: "Skill" } → “Activated on-demand tools: Skill.”
- Use
Skill successfully.
- Send a new user message in the same session.
- First provider request of the new turn:
Skill is absent from tools. History still shows the activation. Model calls Skill anyway or ToolSearches again.
Proposed change / 期望改动
On each new prompt (and mode switch), rebuild the active deferred set from the effective context, do not start from empty:
- Walk
buildSessionContext messages.
- Only successful
toolResult rows (!isError).
- For
ToolSearch, use addedToolNames; for a direct deferred-tool result, use toolName.
- Keep a name only if it is still in the current deferred catalog, still in
toolCatalog, and allowed in the current mode.
- Ignore UI placeholders such as
[no tool result recorded] / interrupted stubs — those are not evidence the tool ever succeeded.
Do not parse assistant/user prose. After restore, set agent.state.tools = activeTools().
Mode switch should restore after rebuild (clear then restore from context is fine; a bare clear is not).
Alternatives / 其他方案
Additional context / 补充信息
PI-Desktop 0.14.6. packages/agent-runtime resetDeferredToolsForPrompt / buildToolSearchTool / activeTools().
Related: #204 (Skill as core) — even if Skill is core, BrowserPreview / Plugin* / MCP still hit this hole.
Problem / 问题
On a new user prompt, the runtime clears on-demand tool activations (
activeDeferredToolNames.clear()), but the transcript still contains successfulToolSearchresults (addedToolNames, “Activated on-demand tools: …”).The model therefore believes those tools are in the current schema. They are not. The next call fails or the model retries
ToolSearch/ invents a call.新用户消息会清空按需激活集,但历史里成功的 ToolSearch 结果还在上下文。模型以为工具可用,实际拿不到。
Stock 0.14.6 (
packages/agent-runtime/src/runtime.ts):Called from
prompt()andexecuteApprovedPlan()at the start of every turn.ToolSearch.executealready writesaddedToolNamesonto the tool result. Compaction / UI history keep those rows. Nothing reads them back intoactiveDeferredToolNames.Repro
ToolSearch { query: "Skill" }→ “Activated on-demand tools: Skill.”Skillsuccessfully.Skillis absent fromtools. History still shows the activation. Model callsSkillanyway or ToolSearches again.Proposed change / 期望改动
On each new prompt (and mode switch), rebuild the active deferred set from the effective context, do not start from empty:
buildSessionContextmessages.toolResultrows (!isError).ToolSearch, useaddedToolNames; for a direct deferred-tool result, usetoolName.toolCatalog, and allowed in the current mode.[no tool result recorded]/ interrupted stubs — those are not evidence the tool ever succeeded.Do not parse assistant/user prose. After restore, set
agent.state.tools = activeTools().Mode switch should restore after rebuild (clear then restore from context is fine; a bare clear is not).
Alternatives / 其他方案
Additional context / 补充信息
PI-Desktop 0.14.6.
packages/agent-runtimeresetDeferredToolsForPrompt/buildToolSearchTool/activeTools().Related: #204 (Skill as core) — even if Skill is core, BrowserPreview / Plugin* / MCP still hit this hole.