feat(design): render assistant activity progress

This commit is contained in:
2026-09-07 09:57:21 +08:00
parent da29294979
commit 81b524a02c
9 changed files with 2066 additions and 80 deletions

View File

@@ -4,11 +4,13 @@ import {
type DesignAsset,
type DesignAssetUploadInput,
type DesignAssistantDeltaEvent,
type DesignAssistantProgressEvent,
type DesignCapabilities,
type DesignChangeSet,
type DesignCommandFailureOutcome,
type DesignCommandInput,
type DesignCommandResult,
type DesignCommandTerminalEvent,
type DesignCompilationIssue,
type DesignCreateWorkspaceInput,
type DesignDecisionPrompt,
@@ -67,6 +69,7 @@ type ServerAgentEvent = {
sequence: number;
runtime: string;
type: string;
client_command_id?: unknown;
schema_version: number;
payload: unknown;
};
@@ -92,6 +95,12 @@ const RUN_MAX_POLL_MS = 4_000;
const WEBSOCKET_OPEN_TIMEOUT_MS = 10_000;
const WEBSOCKET_PING_INTERVAL_MS = 20_000;
const WEBSOCKET_OPEN = 1;
const PUBLIC_ASSISTANT_PROGRESS_MESSAGES: Record<DesignAssistantProgressEvent['stage'], string> = {
understanding: '正在听懂你刚补充的内容…',
reviewing_context: '正在把它和前面的设计想法放在一起看…',
validating: '正在确认整理结果没有漏掉或弄错…',
composing: '已经整理好,正在准备回复…',
};
function record(value: unknown): Record<string, unknown> {
if (!value || typeof value !== 'object' || Array.isArray(value)) {
@@ -419,6 +428,29 @@ function normalizeWorkspaceEvent(
|| event.sequence < 1) return null;
const payload = record(event.payload);
const id = `${sessionId}:${event.sequence}`;
if ([
'command.completed',
'command.failed',
'command.cancelled',
].includes(event.type)) {
const clientOperationId = stringValue(event.client_command_id, 'Operation ID');
const outcome = event.type === 'command.completed'
? 'succeeded'
: event.type === 'command.failed'
? 'failed'
: 'cancelled';
const errorCode = outcome === 'failed'
? stringValue(record(payload.error).code, 'Command error code')
: null;
return {
id,
type: event.type as DesignCommandTerminalEvent['type'],
workspaceId,
clientOperationId,
outcome,
errorCode,
} satisfies DesignCommandTerminalEvent;
}
if (event.type === 'design.session.snapshot') {
return { id, type: event.type, form: mapForm(payload.form) } satisfies DesignSessionSnapshotEvent;
}
@@ -435,12 +467,34 @@ function normalizeWorkspaceEvent(
delta: stringValue(payload.delta, 'Assistant delta'),
} satisfies DesignAssistantDeltaEvent;
}
if (event.type === 'design.assistant.progress') {
if (payload.workspace_id !== workspaceId) return null;
const stage = stringValue(payload.stage, 'Assistant progress stage');
if (![
'understanding',
'reviewing_context',
'validating',
'composing',
].includes(stage)) return null;
return {
id,
type: event.type,
workspaceId,
directionId: stringValue(payload.direction_id, 'Direction ID'),
clientOperationId: stringValue(payload.client_operation_id, 'Operation ID'),
stage: stage as DesignAssistantProgressEvent['stage'],
message: PUBLIC_ASSISTANT_PROGRESS_MESSAGES[
stage as DesignAssistantProgressEvent['stage']
],
} satisfies DesignAssistantProgressEvent;
}
if (event.type === 'design.direction.updated') {
const form = mapForm(payload.form);
if (form.workspaceId !== workspaceId) return null;
return {
id,
type: event.type,
clientOperationId: stringValue(event.client_command_id, 'Operation ID'),
replayed: Boolean(payload.replayed),
operation: mapInteraction(payload.operation),
form,