mirror of
https://github.com/CopilotKit/CopilotKit.git
synced 2026-09-14 16:26:20 +08:00
811afa9025
Address the four residual D6 failures on the ms-agent-dotnet integration (baseline was 177/5). route.ts toolCallId strip completeness - Extend stripReplaySafeToolCallIdsFromMessage to also clean the snake_case `tool_calls[].id` array and any nested OpenAI-style `function.tool_call_id`. AG-UI canonical uses `toolCalls`, but some runtime / message-converter paths emit the OpenAI shape and the replay-safe `__ck_run_<uuid>` suffix was leaking through to aimock on those paths. Apply the same coverage in applyToolResultDecisionSuffix so decision-suffix routing (`__approved` / `__rejected` / `__cancelled`) lands on every tool-call shape. - Add a universal strip middleware in createAgent itself so EVERY registered agent (not only the replay-safe ones) clears the suffix before the request reaches the backend / aimock. Decision suffixing remains scoped to createReplaySafeAgent because the suffix is non-idempotent and the inner middleware re-runs the same logic. - Drop the now-redundant strip calls inside createGenUiAgent, createReadonlyContextAgent, createSharedStateReadWriteAgent, and createReasoningAgent — the outer createAgent middleware already canonicalised inbound messages by the time these run. chat-slots fixture - Mirror LGP's turnIndex:1 'Give me a fun fact' entry so the chat-slots e2e's second-turn assistant slot has a deterministic reply (the bare 'Give me a fun fact' fixture in headless-simple.json is turnIndex:0-gated and was never matching chat-slots' turn 1). HITL reject + interrupt-headless cancel branches - Add a reject-branch fixture in render-a2ui.json keyed on toolCallId `call_d5_generate_steps_001__rejected` so the hitl.spec reject-flow's 'will not execute the Mars trip plan' assertion lands the right narration. Keep the legacy hasToolResult:true fixture as a fallback for paths that don't apply a decision suffix. Add an `__approved` variant for symmetry. - Add cancel-branch fixtures in interrupt-headless.json for both the sales-intro and 1:1-with-alice pills, keyed on `__cancelled` toolCallIds, returning the Denied/not-booked narration the interrupt-headless cancel spec expects. hitl-in-app + hitl-in-chat demo pages already mirror LGP (only an extra README.md per directory in this integration), so no page changes were needed.
116 lines
4.5 KiB
JSON
116 lines
4.5 KiB
JSON
{
|
|
"_meta": {
|
|
"description": "D6 fixtures for ms-agent-dotnet / interrupt-headless",
|
|
"sourceFile": "harness/fixtures/d5/interrupt-headless.json",
|
|
"created": "2026-05-21"
|
|
},
|
|
"fixtures": [
|
|
{
|
|
"_comment": "interrupt-headless sales-call pill — CANCEL branch: when the user clicks Cancel on the popup, the route in src/app/api/copilotkit/route.ts decorates the inbound tool_call_id with a `__cancelled` suffix (see applyToolResultDecisionSuffix). The interrupt-headless.spec.ts cancel test asserts the assistant message matches /Denied.*sales intro call|not booked/i AND asserts the 'Booked.*Sales intro call' confirmation is NOT present, so the response must NOT contain 'Booked'.",
|
|
"match": {
|
|
"userMessage": "intro call with the sales team",
|
|
"toolCallId": "call_d5_schedule_sales_001__cancelled",
|
|
"context": "ms-agent-dotnet"
|
|
},
|
|
"response": {
|
|
"content": "Denied — the sales intro call was cancelled and not booked. Send the pill again whenever you would like to revisit the slots."
|
|
}
|
|
},
|
|
{
|
|
"_comment": "interrupt-headless alice-1on1 pill — CANCEL branch. Same `__cancelled` suffix mechanism as the sales fixture above; covers the symmetric reject path for the alice pill so cancel works on either flavour.",
|
|
"match": {
|
|
"userMessage": "1:1 with Alice",
|
|
"toolCallId": "call_d5_schedule_alice_001__cancelled",
|
|
"context": "ms-agent-dotnet"
|
|
},
|
|
"response": {
|
|
"content": "Denied — the 1:1 with Alice was cancelled and not booked. Send the pill again whenever you would like to revisit the slots."
|
|
}
|
|
},
|
|
{
|
|
"_comment": "interrupt-headless sales-call pill — second leg: confirmation after user picks a slot. Placed BEFORE first-leg so toolCallId matching takes precedence over toolName matching.",
|
|
"match": {
|
|
"userMessage": "intro call with the sales team",
|
|
"toolCallId": "call_d5_schedule_sales_001",
|
|
"context": "ms-agent-dotnet"
|
|
},
|
|
"response": {
|
|
"content": "Booked: Sales intro call confirmed for the slot you picked."
|
|
}
|
|
},
|
|
{
|
|
"_comment": "interrupt-headless alice-1on1 pill — second leg: confirmation after user picks a slot. Placed BEFORE first-leg so toolCallId matching takes precedence.",
|
|
"match": {
|
|
"userMessage": "1:1 with Alice",
|
|
"toolCallId": "call_d5_schedule_alice_001",
|
|
"context": "ms-agent-dotnet"
|
|
},
|
|
"response": {
|
|
"content": "Scheduled: 1:1 with Alice locked in for the slot you picked."
|
|
}
|
|
},
|
|
{
|
|
"_comment": "interrupt-headless sales-call pill — first leg: schedule_meeting tool call triggers interrupt(...). Same agent/prompts as gen-ui-interrupt but different frontend (useHeadlessInterrupt renders in app surface pane, not inline).",
|
|
"match": {
|
|
"userMessage": "intro call with the sales team",
|
|
"toolName": "schedule_meeting",
|
|
"context": "ms-agent-dotnet"
|
|
},
|
|
"response": {
|
|
"content": "Sure — let me check available times.",
|
|
"toolCalls": [
|
|
{
|
|
"id": "call_d5_schedule_sales_001",
|
|
"name": "schedule_meeting",
|
|
"arguments": {
|
|
"topic": "Sales intro call",
|
|
"attendee": "Sales team",
|
|
"slots": [
|
|
{
|
|
"label": "Mon 10:00 AM",
|
|
"iso": "2026-05-11T10:00:00Z"
|
|
},
|
|
{
|
|
"label": "Tue 2:00 PM",
|
|
"iso": "2026-05-12T14:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"_comment": "interrupt-headless alice-1on1 pill — first leg: schedule_meeting tool call.",
|
|
"match": {
|
|
"userMessage": "1:1 with Alice",
|
|
"toolName": "schedule_meeting",
|
|
"context": "ms-agent-dotnet"
|
|
},
|
|
"response": {
|
|
"content": "Got it — pulling up next-week slots.",
|
|
"toolCalls": [
|
|
{
|
|
"id": "call_d5_schedule_alice_001",
|
|
"name": "schedule_meeting",
|
|
"arguments": {
|
|
"topic": "1:1 with Alice — Q2 goals",
|
|
"attendee": "Alice",
|
|
"slots": [
|
|
{
|
|
"label": "Wed 11:00 AM",
|
|
"iso": "2026-05-13T11:00:00Z"
|
|
},
|
|
{
|
|
"label": "Thu 3:30 PM",
|
|
"iso": "2026-05-14T15:30:00Z"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|