feat(design): integrate agent activity timeline

This commit is contained in:
2026-09-07 12:21:40 +08:00
parent 81b524a02c
commit 7bdb42f26c
12 changed files with 243 additions and 133 deletions

View File

@@ -172,6 +172,9 @@ export function DesignConversationPane({
const text = assistantStreams[message.operationId]?.trim();
return text ? [{ ...message, text }] : [];
});
const streamingReplyByOperationId = new Map(
streamingReplies.map((reply) => [reply.operationId, reply.text]),
);
const projectedDraft = chatDraft.trim() !== ''
&& pendingChatMessages.some((message) => message.message === chatDraft.trim());
const composerDraft = projectedDraft ? '' : chatDraft;
@@ -290,6 +293,7 @@ export function DesignConversationPane({
{pendingChatMessages.map((message) => {
const linkedActivity = activityByOperationId.get(message.operationId);
const streamingReply = streamingReplyByOperationId.get(message.operationId);
return (
<div
key={message.operationId}
@@ -318,27 +322,25 @@ export function DesignConversationPane({
operationId={message.operationId}
/>
)}
{streamingReply && (
<div
data-testid={`streaming-design-assistant-${message.operationId}`}
role="status"
aria-live="polite"
aria-atomic="true"
className="mr-auto max-w-[92%] rounded-2xl rounded-bl-md border border-brand/20 bg-background px-3.5 py-3 text-sm leading-6 text-foreground shadow-sm"
>
{streamingReply}
<span
aria-hidden="true"
className="ml-1 inline-block h-3.5 w-1 animate-pulse rounded-full bg-brand align-middle"
/>
</div>
)}
</div>
);
})}
{streamingReplies.map((reply) => (
<div
key={reply.operationId}
data-testid={`streaming-design-assistant-${reply.operationId}`}
role="status"
aria-live="polite"
aria-atomic="true"
className="mr-auto max-w-[92%] rounded-2xl rounded-bl-md border border-brand/20 bg-background px-3.5 py-3 text-sm leading-6 text-foreground shadow-sm"
>
{reply.text}
<span
aria-hidden="true"
className="ml-1 inline-block h-3.5 w-1 animate-pulse rounded-full bg-brand align-middle"
/>
</div>
))}
{canRequestQuote && pendingChatMessages.length === 0 && (
<div
data-testid="design-conversation-quote-action"

View File

@@ -550,12 +550,13 @@ export const useImageWorkspaceStore = create<ImageWorkspaceState>((set, get) =>
const assistantActivities = isChatCommand(command)
? existingActivity
? {
...state.assistantActivities,
[operation.id]: {
...existingActivity,
status: 'active' as const,
},
}
: {}
: state.assistantActivities
: state.assistantActivities;
return {
pendingOperations: { ...state.pendingOperations, [operation.id]: operation },