test(integration): MCP-functional tier 2 — multi-turn, history/info tools, streaming deltas - #138
Merged
Merged
Conversation
… streaming deltas Batch 2 of the MCP-functional test expansion queue from PR #136. 4 new describe suites, 11 new test cases: **Multi-turn session state** (2 tests) - Verifies `turns` counter increments across two sequential `runTalonTurn` calls on the same chatId without session reset. Catches any accidental `resetSession` inside `handleMessage`. - Verifies `resetSession: true` actually clears state — seeds session.turns=99, confirms it's 1 after a fresh turn. **History and info tool dispatch** (3 tests) - `read_chat_history` routes through full SDK→MCP→bridge→gateway chain and recording handler captures the action body + limit param. - `get_chat_info` routes correctly (confirms it's in mcp-server.ts registry). - Multi-read turn: `read_chat_history + get_chat_info + end_turn` in one assistant message — all three captured in dispatch order. **Streaming text deltas** (2 tests) - Text block emitted before `end_turn` appears in `streamDeltas` (proves `onStreamDelta` callback is wired through the real handler and SDK). - Pure text turn (no tool_use): `streamDeltas` captured, recording handler gets nothing (no MCP dispatch). **Additional messaging tool dispatch** (4 tests) - `unpin_message` — ok-only action with message_id. - `stop_poll` — ok-only action with message_id. - `forward_message` — ok-only action with source_chat_id + message_id. - `list_pinned` — read-path action, recording handler returns items array. Each suite gets its own `RecordingHandler` with a distinct `seed` (2000–5000) so synthetic message_ids don't collide if suites ever run concurrently. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diagnosed from CI log (hb #202, 2026-05-10): 1. read_chat_history bridge name: tool calls bridge("read_history", ...) not bridge("read_chat_history", ...). Assertions updated accordingly. Also added "read_history" case to recording-handler for correct response. 2. Multi-read test: same fix — byAction("read_chat_history") → byAction("read_history") in 2 places. 3+4. Streaming delta tests: the stub binary emits complete content blocks, not streaming delta events. onStreamDelta never fires. Changed test #3 to assert on send_message dispatch instead. Changed test #4 to assert "no MCP dispatch, no tool calls" (the meaningful invariant for a prose-only turn that triggers the flow-violation handler). 5. forward_message: tool schema only exposes message_id. source_chat_id is stripped by Zod. Changed input + assertion to only use message_id. 6. list_pinned: no production tool routes to bridge("list_pinned", ...). Replaced with get_message_by_id which exists in history.ts and the recording handler returns ok:true items:[] for it. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
dylanneve1
force-pushed
the
test/mcp-functional-tier-2
branch
from
May 10, 2026 10:41
76a8249 to
5e6d81d
Compare
claudiusthebot
enabled auto-merge (squash)
May 10, 2026 10:41
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Batch 2 of the MCP-functional test expansion queue from PR #136 (Dylan: "you should work on it during heartbeats").
4 new
describesuites, 11 new test cases intalon-mcp-functional-2.test.ts. Each suite has its ownRecordingHandlerwith a distinct seed (2000–5000) to avoid message_id collisions.Multi-turn session state (2 tests)
runTalonTurncalls on the samechatIdwithout session reset — catches any accidentalresetSessioninsidehandleMessage. AssertsgetSession(chatId).turns === 1after turn 1,=== 2after turn 2 (same chatId, no reset).resetSession: trueactually clears state — seedssession.turns = 99, confirms it's1after a fresh turn.History and info tool dispatch (3 tests)
read_chat_historyroutes through the full SDK→MCP→bridge→gateway chain; recording handler captures action body +limitparam; protocol log confirms MCP dispatch.get_chat_inforoutes correctly (if it were missing frommcp-server.ts's registry, dispatch would fail with a schema error).read_chat_history + get_chat_info + end_turnin one assistant message — all three captured in order. Sequence assertion:read_chat_history.seq < get_chat_info.seq.Streaming text deltas (2 tests)
end_turnappears inturn.streamDeltas— provesonStreamDeltacallback is wired through the real handler and SDK end-to-end.tool_use):streamDeltascaptured, recording handler gets nothing (no MCP dispatch — confirms the recording handler isn't called for scratchpad-only turns).Additional messaging tool dispatch (4 tests)
Fills coverage gaps from batch 1 (
unpin_message,stop_poll,forward_message,list_pinnedwere never exercised in the MCP-functional tier):unpin_message— ok-only action, message_id propagated correctlystop_poll— ok-only action, message_id propagated correctlyforward_message— ok-only action, source_chat_id + message_id propagated correctlylist_pinned— read-path action, recording handler returns{ok: true, items: []}Test plan
typecheck✅ (tsc --noEmit clean)format:check✅ (prettier --check clean)skipIf(!stubReady)gates correctly if not)What's next in the queue
From PR #136's description (not in this PR — scope cut for follow-ups):
end_turn, then retries)🤖 Generated with Claude Code