@steerable/agent-shell-web 0.6.28 → 0.6.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/src/components/AgentSidebar.tsx +3 -3
- package/src/components/BrandLockup.tsx +20 -4
- package/src/components/chat/AssistantMessage.tsx +83 -25
- package/src/components/chat/ChatInput.tsx +11 -3
- package/src/components/chat/ExecutedActionsCard.tsx +389 -27
- package/src/components/chat/LocalChatPanel.tsx +12 -16
- package/src/components/chat/MessageList.tsx +9 -4
- package/src/components/chat/OrchestrationChildrenCard.tsx +69 -5
- package/src/components/chat/SessionTodoList.tsx +117 -20
- package/src/components/chat/SuggestedReplies.tsx +11 -3
- package/src/components/chat/TaskProcessPanel.tsx +62 -17
- package/src/components/chat/TurnProcessGroup.tsx +27 -1
- package/src/components/chat/UserMessage.tsx +5 -5
- package/src/components/chat/executed-actions-model.ts +469 -0
- package/src/components/chat/orchestration-children-model.ts +120 -0
- package/src/components/chat/turn-timeline.ts +23 -0
- package/src/lib/local-api.ts +11 -0
- package/src/pages/AgentPage.tsx +27 -6
package/src/pages/AgentPage.tsx
CHANGED
|
@@ -23,8 +23,12 @@ import {
|
|
|
23
23
|
type ExecPolicy,
|
|
24
24
|
} from "@/lib/exec-policy";
|
|
25
25
|
import type { ExecutedAction } from "@/components/chat/ExecutedActionsCard";
|
|
26
|
+
import { inspectTaskTitle, type InspectTaskInput } from "@/components/chat/executed-actions-model";
|
|
26
27
|
import type { ChildInfo } from "@/components/chat/OrchestrationChildrenCard";
|
|
27
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
extractPersistedOrchestrationChildren,
|
|
30
|
+
foldOrchestrationChildEvents,
|
|
31
|
+
} from "@/components/chat/orchestration-children-model";
|
|
28
32
|
import { parseTurnBlocks, type TurnBlock } from "@/components/chat/turn-timeline";
|
|
29
33
|
import {
|
|
30
34
|
parseLlmSpeedPayload,
|
|
@@ -50,7 +54,6 @@ import {
|
|
|
50
54
|
type ChatLiveStream,
|
|
51
55
|
type LocalChatMessage,
|
|
52
56
|
type LocalProject,
|
|
53
|
-
type LocalTask,
|
|
54
57
|
} from "@/lib/local-api";
|
|
55
58
|
import type { AgentOutletContext } from "@/layouts/AgentLayout";
|
|
56
59
|
import {
|
|
@@ -237,6 +240,8 @@ function AgentChatLoader({
|
|
|
237
240
|
const [initialTurnFiles, setInitialTurnFiles] = useState<
|
|
238
241
|
Record<string, TurnFile[]>
|
|
239
242
|
>({});
|
|
243
|
+
const [initialOrchestrationChildren, setInitialOrchestrationChildren] =
|
|
244
|
+
useState<Record<string, ChildInfo[]>>({});
|
|
240
245
|
const [initialSuggestedReplies, setInitialSuggestedReplies] =
|
|
241
246
|
useState<SuggestedRepliesState | null>(null);
|
|
242
247
|
// W7-1: 后端在 messages 响应里下发 interrupted(上一轮崩溃/强杀中断)。
|
|
@@ -274,6 +279,9 @@ function AgentChatLoader({
|
|
|
274
279
|
setInitialTimelines(extractPersistedTimelines(response.messages));
|
|
275
280
|
setInitialDurations(extractPersistedDurations(response.messages));
|
|
276
281
|
setInitialTurnFiles(extractPersistedTurnFiles(response.messages));
|
|
282
|
+
setInitialOrchestrationChildren(
|
|
283
|
+
extractPersistedOrchestrationChildren(response.messages),
|
|
284
|
+
);
|
|
277
285
|
setInitialSuggestedReplies(
|
|
278
286
|
extractLatestSuggestedReplies(
|
|
279
287
|
ordered as ChatMessageWithMetadata[],
|
|
@@ -289,6 +297,7 @@ function AgentChatLoader({
|
|
|
289
297
|
setInitialTimelines({});
|
|
290
298
|
setInitialDurations({});
|
|
291
299
|
setInitialTurnFiles({});
|
|
300
|
+
setInitialOrchestrationChildren({});
|
|
292
301
|
setInitialSuggestedReplies(null);
|
|
293
302
|
setInitialInterrupted(false);
|
|
294
303
|
setInitialLiveStream({ active: false });
|
|
@@ -315,6 +324,7 @@ function AgentChatLoader({
|
|
|
315
324
|
initialTimelines={initialTimelines}
|
|
316
325
|
initialDurations={initialDurations}
|
|
317
326
|
initialTurnFiles={initialTurnFiles}
|
|
327
|
+
initialOrchestrationChildren={initialOrchestrationChildren}
|
|
318
328
|
initialSuggestedReplies={initialSuggestedReplies}
|
|
319
329
|
initialInterrupted={initialInterrupted}
|
|
320
330
|
initialLiveStream={initialLiveStream}
|
|
@@ -331,6 +341,7 @@ interface AgentChatViewProps {
|
|
|
331
341
|
initialTimelines: Record<string, TurnBlock[]>;
|
|
332
342
|
initialDurations: Record<string, number>;
|
|
333
343
|
initialTurnFiles: Record<string, TurnFile[]>;
|
|
344
|
+
initialOrchestrationChildren: Record<string, ChildInfo[]>;
|
|
334
345
|
initialSuggestedReplies: SuggestedRepliesState | null;
|
|
335
346
|
/** W7-1: 打开会话时上一轮处于中断态(崩溃/强杀,无完成记录)。 */
|
|
336
347
|
initialInterrupted: boolean;
|
|
@@ -347,6 +358,7 @@ function AgentChatView({
|
|
|
347
358
|
initialTimelines,
|
|
348
359
|
initialDurations,
|
|
349
360
|
initialTurnFiles,
|
|
361
|
+
initialOrchestrationChildren,
|
|
350
362
|
initialSuggestedReplies,
|
|
351
363
|
initialInterrupted,
|
|
352
364
|
initialLiveStream,
|
|
@@ -390,8 +402,14 @@ function AgentChatView({
|
|
|
390
402
|
dismissFinished,
|
|
391
403
|
} = useChatTasks(chatId);
|
|
392
404
|
const handleInspectTask = useCallback(
|
|
393
|
-
(task:
|
|
394
|
-
ctx.inspectTask({
|
|
405
|
+
(task: InspectTaskInput) => {
|
|
406
|
+
ctx.inspectTask({
|
|
407
|
+
id: task.id,
|
|
408
|
+
chatId: task.chatId,
|
|
409
|
+
title: inspectTaskTitle(task),
|
|
410
|
+
...(task.recordId ? { recordId: task.recordId } : {}),
|
|
411
|
+
...(task.live ? { live: true } : {}),
|
|
412
|
+
});
|
|
395
413
|
},
|
|
396
414
|
[ctx],
|
|
397
415
|
);
|
|
@@ -464,7 +482,7 @@ function AgentChatView({
|
|
|
464
482
|
// 与 currentTurnActions 同款 reconcile 模式(message_id 落库后按键归档)。
|
|
465
483
|
const [currentTurnChildren, setCurrentTurnChildren] = useState<ChildInfo[]>([]);
|
|
466
484
|
const [orchestrationChildrenByMessageId, setOrchestrationChildrenByMessageId] =
|
|
467
|
-
useState<Record<string, ChildInfo[]>>(
|
|
485
|
+
useState<Record<string, ChildInfo[]>>(initialOrchestrationChildren);
|
|
468
486
|
const pendingChildrenRef = useRef<ChildInfo[]>([]);
|
|
469
487
|
// Round counter for the in-flight turn. Bumped on every `round_end` event
|
|
470
488
|
// emitted by chat-transport (was previously suppressed). Driving this state
|
|
@@ -572,6 +590,8 @@ function AgentChatView({
|
|
|
572
590
|
task: ev.payload?.task as string | undefined,
|
|
573
591
|
depth: ev.payload?.depth as number | undefined,
|
|
574
592
|
profile: ev.payload?.profile as string | undefined,
|
|
593
|
+
// 子代理自己的 durable record:委派行靠它跳转右侧过程栏。
|
|
594
|
+
recordId: ev.payload?.recordId as string | undefined,
|
|
575
595
|
status: "running",
|
|
576
596
|
},
|
|
577
597
|
];
|
|
@@ -1049,6 +1069,7 @@ function AgentChatView({
|
|
|
1049
1069
|
pendingFollowUps={pendingFollowUps.map((m) => m.content)}
|
|
1050
1070
|
onRemoveFollowUp={removeFollowUp}
|
|
1051
1071
|
className="flex-1"
|
|
1072
|
+
chatId={chatId}
|
|
1052
1073
|
emptyHero={{
|
|
1053
1074
|
title: BRAND_NAME,
|
|
1054
1075
|
subtitle: '输入消息,直接开始一段新对话。',
|
|
@@ -1317,7 +1338,7 @@ function EmptyChatGate() {
|
|
|
1317
1338
|
className="flex h-full w-full items-center justify-center p-3 sm:p-5"
|
|
1318
1339
|
data-testid="empty-chat-home"
|
|
1319
1340
|
>
|
|
1320
|
-
<div className="flex w-full max-w-
|
|
1341
|
+
<div className="flex w-full max-w-3xl flex-col items-center gap-4">
|
|
1321
1342
|
<div className="text-center">
|
|
1322
1343
|
<h1 className="text-xl font-semibold tracking-tight text-agent-foreground">
|
|
1323
1344
|
{BRAND_NAME}
|