Skip to content

feat(chat): refresh the tool set mid-turn on host tool changes - #54

Open
BatLeDev wants to merge 1 commit into
mainfrom
feat-refresh-tools-mid-turn
Open

feat(chat): refresh the tool set mid-turn on host tool changes#54
BatLeDev wants to merge 1 commit into
mainfrom
feat-refresh-tools-mid-turn

Conversation

@BatLeDev

Copy link
Copy Markdown
Member

The tool map handed to streamText was frozen when the turn started: tools registered by a page the agent navigated to only became callable on the next user turn (measured in production traces: toolCount stays at 17 for the rest of the turn, 21 on the next), and the model concluded it was stuck.

The turn loop now snapshots the tool-name signature, watches the aggregated tool set, stops the stream at the next step boundary when the set changes, and relaunches streamText on the accumulated history with the re-partitioned tools (sub-agent resolution and flatten decisions re-run).

Guards: restart only on finishReason: 'tool-calls' (a finished answer is never relaunched), at most 2 restarts per turn, and a global 10-step budget across restarts. The pure decision logic lives in tool-refresh.ts with unit tests; docs/architecture/mcp-tools.md documents the mechanism.

Why: first blocker found by a traced audit of the assistant building a dashboard — it navigated to the creation page, saw no new tools, and gave up.

Heads-up: this touches the heart of the chat loop; most of the use-agent-chat.ts diff is re-indentation of the new restart loop (review with whitespace ignored). Two induced fixes: the moderation rollback truncates history via splice at the turn's start index, and announcedThisTurn accumulates across restarts. No e2e test covers the navigate-then-new-tools scenario yet (needs a host page that changes its tool set mid-turn); 348 unit tests pass, lint and check-types clean.

… tools

The tool map was frozen when the turn started: tools registered by a page the
agent navigated to only became callable on the next user turn (measured in
production: toolCount stays at 17 for the rest of the turn, 21 on the next),
and the model concluded it was stuck.

The turn loop now snapshots the tool-name signature, watches the aggregated
tool set, stops the stream at the next step boundary when the set changes and
relaunches streamText on the accumulated history with the re-partitioned
tools. Guards: restart only on finishReason tool-calls, at most 2 restarts per
turn, and a global 10-step budget across restarts. Pure decision logic lives
in tool-refresh.ts with unit tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant