Merge pull request #3970 from jeremymcs/fix/ask-user-question-stream-order
fix(web): preserve only final ask_user_questions text
This commit is contained in:
commit
679587bee2
2 changed files with 48 additions and 13 deletions
|
|
@ -358,6 +358,7 @@ function routeEvent(state: MinimalLiveState, event: any): MinimalLiveState {
|
|||
}
|
||||
case "tool_execution_start": {
|
||||
s.activeToolExecution = { id: event.toolCallId, name: event.toolName };
|
||||
s.streamingAssistantText = "";
|
||||
break;
|
||||
}
|
||||
case "tool_execution_end": {
|
||||
|
|
@ -802,6 +803,7 @@ test("(g-2) tool_execution_start/end update activeToolExecution", async () => {
|
|||
assert.ok(state.activeToolExecution);
|
||||
assert.equal(state.activeToolExecution.id, "tc-1");
|
||||
assert.equal(state.activeToolExecution.name, "bash");
|
||||
assert.equal(state.streamingAssistantText, "");
|
||||
|
||||
state = routeEvent(state, {
|
||||
type: "tool_execution_end",
|
||||
|
|
@ -813,6 +815,46 @@ test("(g-2) tool_execution_start/end update activeToolExecution", async () => {
|
|||
assert.equal(state.activeToolExecution, null);
|
||||
});
|
||||
|
||||
test("(g-3) tool_execution_start clears provisional streaming text so only post-tool final text survives", async () => {
|
||||
let state = createMinimalLiveState();
|
||||
|
||||
state = routeEvent(state, {
|
||||
type: "message_update",
|
||||
assistantMessageEvent: {
|
||||
type: "text_delta",
|
||||
delta: "It seems the questions were presented to the user. Let me wait for them to answer.",
|
||||
},
|
||||
});
|
||||
assert.equal(state.streamingAssistantText, "It seems the questions were presented to the user. Let me wait for them to answer.");
|
||||
|
||||
state = routeEvent(state, {
|
||||
type: "tool_execution_start",
|
||||
toolCallId: "tc-ask-1",
|
||||
toolName: "ask_user_questions",
|
||||
});
|
||||
assert.equal(state.streamingAssistantText, "");
|
||||
|
||||
state = routeEvent(state, {
|
||||
type: "tool_execution_end",
|
||||
toolCallId: "tc-ask-1",
|
||||
toolName: "ask_user_questions",
|
||||
result: {},
|
||||
isError: false,
|
||||
});
|
||||
state = routeEvent(state, {
|
||||
type: "message_update",
|
||||
assistantMessageEvent: {
|
||||
type: "text_delta",
|
||||
delta: "What are you working on? Once you answer I'll tailor my approach accordingly.",
|
||||
},
|
||||
});
|
||||
state = routeEvent(state, { type: "turn_end" });
|
||||
|
||||
assert.deepEqual(state.liveTranscript, [
|
||||
"What are you working on? Once you answer I'll tailor my approach accordingly.",
|
||||
]);
|
||||
});
|
||||
|
||||
test("(h) steer and abort commands post the correct RPC command type", async (t) => {
|
||||
const fixture = makeWorkspaceFixture();
|
||||
const sessionPath = createSessionFile(fixture.projectCwd, fixture.sessionsDir, "sess-steer", "Steer Session");
|
||||
|
|
|
|||
|
|
@ -5134,25 +5134,18 @@ export class GSDWorkspaceStore {
|
|||
}
|
||||
|
||||
private handleToolExecutionStart(event: ToolExecutionStartEvent): void {
|
||||
// Finalize any in-flight streaming content into segments before the tool runs
|
||||
const pendingSegments: TurnSegment[] = []
|
||||
if (this.state.streamingThinkingText.length > 0) {
|
||||
pendingSegments.push({ kind: "thinking", content: this.state.streamingThinkingText })
|
||||
}
|
||||
if (this.state.streamingAssistantText.length > 0) {
|
||||
pendingSegments.push({ kind: "text", content: this.state.streamingAssistantText })
|
||||
}
|
||||
this.patchState({
|
||||
activeToolExecution: {
|
||||
id: event.toolCallId,
|
||||
name: event.toolName,
|
||||
args: (event as Record<string, unknown>).args as Record<string, unknown> | undefined,
|
||||
},
|
||||
...(pendingSegments.length > 0 ? {
|
||||
currentTurnSegments: [...this.state.currentTurnSegments, ...pendingSegments],
|
||||
streamingAssistantText: "",
|
||||
streamingThinkingText: "",
|
||||
} : {}),
|
||||
// Treat pre-tool streaming text as ephemeral. Claude Code can emit
|
||||
// provisional assistant text before a tool call, then replace it with
|
||||
// the real final text after the tool completes. If we finalize that
|
||||
// interim text here, the chat timeline shows stale text above the tool.
|
||||
streamingAssistantText: "",
|
||||
streamingThinkingText: "",
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue