fix(chat): preserve accepted MCP elicitation URLs

This commit is contained in:
murashit 2026-07-18 18:52:44 +09:00
parent 358cdd7b7c
commit eecf73dc77
2 changed files with 36 additions and 2 deletions

View file

@ -67,7 +67,7 @@ export function createMcpElicitationResultItem(
...definedProp("turnId", elicitation.params.turnId ?? undefined),
provenance: { source: "localUser", channel: "response", interaction: "userInputResponse", sourceId: String(elicitation.requestId) },
executionState: accepted ? "completed" : "failed",
questions: mcpElicitationResultQuestions(elicitation, accepted ? content : null),
questions: mcpElicitationResultQuestions(elicitation, accepted, accepted ? content : null),
};
}
@ -98,6 +98,7 @@ function mcpElicitationResultText(elicitation: PendingMcpElicitation, action: Mc
function mcpElicitationResultQuestions(
elicitation: PendingMcpElicitation,
accepted: boolean,
content: Record<string, McpElicitationContentValue> | null,
): readonly ThreadStreamUserInputQuestionResult[] {
if (elicitation.params.mode === "url") {
@ -106,7 +107,7 @@ function mcpElicitationResultQuestions(
id: "url",
header: "URL",
question: elicitation.params.message,
...(content ? { answer: elicitation.params.url } : {}),
...(accepted ? { answer: elicitation.params.url } : {}),
},
];
}

View file

@ -807,6 +807,37 @@ describe("ChatInboundHandler", () => {
});
});
it("records the accepted URL in the MCP elicitation result item", () => {
const state = chatStateFixture();
const respondToServerRequest = vi.fn(() => true);
const handler = handlerForState(state, { respondToServerRequest });
handler.handleServerRequest({
id: 46,
method: "mcpServer/elicitation/request",
params: {
threadId: "thread-active",
turnId: "turn-active",
serverName: "github",
mode: "url",
_meta: null,
message: "Confirm in browser",
url: "https://example.com/confirm",
elicitationId: "elicit-1",
},
});
handler.resolveMcpElicitation(46, "accept");
expect(respondToServerRequest).toHaveBeenCalledWith(46, { action: "accept", content: null, _meta: null });
expect(chatStateThreadStreamItems(handler.currentState()).at(-1)).toMatchObject({
kind: "userInputResult",
text: "MCP request from github accepted.",
executionState: "completed",
questions: [{ id: "url", answer: "https://example.com/confirm" }],
});
});
it("declines MCP elicitation URL server requests", () => {
const state = chatStateFixture();
const respondToServerRequest = vi.fn(() => true);
@ -835,7 +866,9 @@ describe("ChatInboundHandler", () => {
kind: "userInputResult",
text: "MCP request from github declined.",
executionState: "failed",
questions: [{ id: "url" }],
});
expect(chatStateThreadStreamItems(handler.currentState()).at(-1)).not.toHaveProperty("questions.0.answer");
});
it("ignores missing requestUserInput ids", () => {