From 60390c477e92ad69df0199d3cbf37b79ab726a92 Mon Sep 17 00:00:00 2001 From: Jordan Ritter Date: Mon, 20 Jul 2026 12:15:58 -0700 Subject: [PATCH 1/2] docs: correct hasToolResult turn-scoping on the docs site MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hasToolResult became TURN-SCOPED in v1.37.3 (matcher) with the record side made symmetric in v1.37.4: it means "does the current turn — the messages after the last user message — contain a tool result", not the old "does the whole conversation contain a tool result". Several docs pages still described the old whole-conversation semantics and were misleading on the live site (aimock.copilotkit.dev). - docs/multi-turn/index.html: fix the field overview bullet, the "hasToolResult — match by tool execution state" prose, and the comparison table row to describe current-turn scoping; explain that this is what keeps leg-1 (tool call, false) vs leg-2 (narration, true) fixtures working on every turn of a multi-turn session. - docs/fixtures/index.html: fix the match-fields table row. - docs/record-replay/index.html: fix both recorder-derivation prose spots and update the buildFixtureMatch snippet to use the shared currentTurnHasToolResult predicate instead of a whole-conversation messages.some() scan. Matches src/router.ts currentTurnHasToolResult (with its no-user-message fallback to whole-conversation). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- docs/fixtures/index.html | 5 +++-- docs/multi-turn/index.html | 26 +++++++++++++++++--------- docs/record-replay/index.html | 10 +++++++--- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/docs/fixtures/index.html b/docs/fixtures/index.html index acbfc9e2..51c07e1a 100644 --- a/docs/fixtures/index.html +++ b/docs/fixtures/index.html @@ -166,8 +166,9 @@

Match Fields

hasToolResult boolean - true when at least one role: "tool" message is present; - false when none are. Stateless alternative to ordering fixtures by + true when the current turn (the messages after the last + role: "user" message) contains a role: "tool" result; + false when it does not. Stateless alternative to ordering fixtures by toolCallId. See Multi-Turn Conversations diff --git a/docs/multi-turn/index.html b/docs/multi-turn/index.html index 0d98c741..ecd0ac6c 100644 --- a/docs/multi-turn/index.html +++ b/docs/multi-turn/index.html @@ -90,7 +90,8 @@

How matching works across turns

- Two additional fields inspect the full message array rather than just the tail: + Two additional fields derive their value from the request shape rather than from a single + tail message:

@@ -166,9 +174,9 @@

turnIndex — match by conversation depth

hasToolResult — match by tool execution state

- hasToolResult checks whether the request contains any - role: "tool" messages. For a simple two-step tool round, this is often - simpler than turnIndex: + hasToolResult checks whether the current turn (the messages after + the last role: "user" message) contains a role: "tool" result. + For a simple two-step tool round, this is often simpler than turnIndex:

@@ -365,8 +373,8 @@

hasToolResult - Boolean check for role: "tool" presence. Stateless. Does not require - pinning a specific tool_call_id. + Boolean check for role: "tool" presence in the current turn. Stateless. + Does not require pinning a specific tool_call_id. diff --git a/docs/record-replay/index.html b/docs/record-replay/index.html index d5974b30..0c4b2fa1 100644 --- a/docs/record-replay/index.html +++ b/docs/record-replay/index.html @@ -636,7 +636,8 @@

Fixture Auto-Generation

inputText), the normalized model becomes model, and for chat requests the recorder also writes the multi-turn disambiguators turnIndex (the number of assistant messages already in the conversation) and - hasToolResult (whether a tool-result message is present). If no match + hasToolResult (whether the current turn — the messages after the last + user message — contains a tool result). If no match criteria can be derived (e.g., empty messages), the fixture is saved to disk with a warning but not registered in memory.

@@ -1040,7 +1041,8 @@

Recording Multi-Turn Conversationslast user message (match.userMessage), the normalized model, and two shape disambiguators read off the request itself: turnIndex (how many assistant messages the conversation already contains) and - hasToolResult (whether a tool-result message is present). Embedding requests + hasToolResult (whether the current turn — the messages after the last + user message — contains a tool result). Embedding requests key on the input text instead. There is no history-based fingerprinting of the full request body — but because a growing conversation carries a growing turnIndex, successive turns that happen to end with the same user message @@ -1063,7 +1065,9 @@

Recording Multi-Turn ConversationsuserMessage: getTextContent(lastUser.content), model: normalizeModelName(request.model), turnIndex: request.messages.filter((m) => m.role === "assistant").length, - hasToolResult: request.messages.some((m) => m.role === "tool"), + // Scoped to the current turn (messages after the last user message), so it + // shares the exact predicate the matcher uses — see router.ts. + hasToolResult: currentTurnHasToolResult(request.messages), }; // Capture context from X-AIMock-Context header if present if (request._context) match.context = request._context; From 331f6680a3d2352bbe98aa31f2faf86deda4385a Mon Sep 17 00:00:00 2001 From: Jordan Ritter Date: Mon, 20 Jul 2026 12:21:08 -0700 Subject: [PATCH 2/2] style: run prettier on updated docs pages Line-rewrap only (pinned prettier 3.8.1); no semantic wording changed. Fixes the Static Quality / prettier CI check on this branch. --- docs/multi-turn/index.html | 6 +++--- docs/record-replay/index.html | 14 ++++++-------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/docs/multi-turn/index.html b/docs/multi-turn/index.html index ecd0ac6c..e5d4c00a 100644 --- a/docs/multi-turn/index.html +++ b/docs/multi-turn/index.html @@ -104,9 +104,9 @@

How matching works across turns

hasToolResult checks whether the current turn — the messages after the last role: "user" message — contains a role: "tool" result. true means “a tool has executed in - this turn”; false means “no tool result yet this turn.” It - is scoped to the current turn, not the whole conversation — that is what keeps the - leg-1 tool-call fixture (false) and the leg-2 narration fixture + this turn”; false means “no tool result yet this turn.” + It is scoped to the current turn, not the whole conversation — that is what keeps + the leg-1 tool-call fixture (false) and the leg-2 narration fixture (true) working on every turn of a multi-turn session, because earlier turns’ tool results no longer force true forever. (If the request carries no user message at all, it falls back to scanning the whole diff --git a/docs/record-replay/index.html b/docs/record-replay/index.html index 0c4b2fa1..a3530e19 100644 --- a/docs/record-replay/index.html +++ b/docs/record-replay/index.html @@ -637,9 +637,8 @@

Fixture Auto-Generation

requests the recorder also writes the multi-turn disambiguators turnIndex (the number of assistant messages already in the conversation) and hasToolResult (whether the current turn — the messages after the last - user message — contains a tool result). If no match - criteria can be derived (e.g., empty messages), the fixture is saved to disk with a - warning but not registered in memory. + user message — contains a tool result). If no match criteria can be derived (e.g., + empty messages), the fixture is saved to disk with a warning but not registered in memory.

Model-Aware Recording

@@ -1042,11 +1041,10 @@

Recording Multi-Turn Conversationsmodel, and two shape disambiguators read off the request itself: turnIndex (how many assistant messages the conversation already contains) and hasToolResult (whether the current turn — the messages after the last - user message — contains a tool result). Embedding requests - key on the input text instead. There is no history-based fingerprinting of the full - request body — but because a growing conversation carries a growing - turnIndex, successive turns that happen to end with the same user message - still record as distinct fixtures. + user message — contains a tool result). Embedding requests key on the input text + instead. There is no history-based fingerprinting of the full request body — but + because a growing conversation carries a growing turnIndex, successive turns + that happen to end with the same user message still record as distinct fixtures.