Merge pull request #1626 from QwenLM/fix/acp-subagent-stream-text

fix(acp): stream subagent text + reasoning chunks
This commit is contained in:
pomelo 2026-01-29 11:09:58 +08:00 committed by GitHub
commit 591eab8409
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 367 additions and 4 deletions

View file

@ -10,6 +10,7 @@ import type {
SubAgentToolResultEvent,
SubAgentApprovalRequestEvent,
SubAgentUsageEvent,
SubAgentStreamTextEvent,
ToolCallConfirmationDetails,
AnyDeclarativeTool,
AnyToolInvocation,
@ -109,11 +110,13 @@ export class SubAgentTracker {
const onToolResult = this.createToolResultHandler(abortSignal);
const onApproval = this.createApprovalHandler(abortSignal);
const onUsageMetadata = this.createUsageMetadataHandler(abortSignal);
const onStreamText = this.createStreamTextHandler(abortSignal);
eventEmitter.on(SubAgentEventType.TOOL_CALL, onToolCall);
eventEmitter.on(SubAgentEventType.TOOL_RESULT, onToolResult);
eventEmitter.on(SubAgentEventType.TOOL_WAITING_APPROVAL, onApproval);
eventEmitter.on(SubAgentEventType.USAGE_METADATA, onUsageMetadata);
eventEmitter.on(SubAgentEventType.STREAM_TEXT, onStreamText);
return [
() => {
@ -121,6 +124,7 @@ export class SubAgentTracker {
eventEmitter.off(SubAgentEventType.TOOL_RESULT, onToolResult);
eventEmitter.off(SubAgentEventType.TOOL_WAITING_APPROVAL, onApproval);
eventEmitter.off(SubAgentEventType.USAGE_METADATA, onUsageMetadata);
eventEmitter.off(SubAgentEventType.STREAM_TEXT, onStreamText);
// Clean up any remaining states
this.toolStates.clear();
},
@ -292,6 +296,26 @@ export class SubAgentTracker {
};
}
/**
* Creates a handler for stream text events.
* Emits agent message or thought chunks for text content from subagent model responses.
*/
private createStreamTextHandler(
abortSignal: AbortSignal,
): (...args: unknown[]) => void {
return (...args: unknown[]) => {
const event = args[0] as SubAgentStreamTextEvent;
if (abortSignal.aborted) return;
// Emit streamed text as agent message or thought based on the flag
void this.messageEmitter.emitMessage(
event.text,
'assistant',
event.thought ?? false,
);
};
}
/**
* Converts confirmation details to permission options for the client.
*/