@tea-agent/loop-agent 0.42.0-next.9 → 0.43.0-next.1
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/CHANGELOG.md +65 -59
- package/dist/application/dag/run-dag.js +3 -2
- package/dist/application/task-lifecycle/advance.js +9 -4
- package/dist/build-stamp.json +3 -3
- package/dist/cli/program.js +1 -1
- package/dist/commands/dag-rerun-task.js +2 -0
- package/dist/commands/task-source-prepare.js +3 -1
- package/dist/executors/dag-pi-executor.js +1514 -175
- package/dist/executors/pi-extension-resolver.js +14 -2
- package/dist/executors/shell-executor.js +131 -54
- package/dist/shared/dag-failure-category.js +6 -0
- package/dist/task/contract/apply.js +36 -2
- package/dist/task/source-prepare/parse-intent.js +7 -0
- package/dist/worker/console/chat/chat-event-store.js +4 -2
- package/dist/worker/console/chat/pi-runtime.js +45 -2
- package/dist/worker/console/chat/resource-loader.js +4 -1
- package/dist/worker/console/chat/routes.js +28 -12
- package/dist/worker/console/chat/sdd-data-alignment.js +13 -2
- package/dist/worker/console/chat/session-store.js +5 -1
- package/dist/worker/console/chat/subagents/agent-tool.js +62 -0
- package/dist/worker/console/chat/subagents/explore-agent.js +169 -0
- package/dist/worker/console/chat/subagents/index.js +5 -0
- package/dist/worker/console/chat/subagents/orchestrator.js +273 -0
- package/dist/worker/console/chat/subagents/tool-policy.js +53 -0
- package/dist/worker/console/chat/subagents/types.js +13 -0
- package/dist/worker/console/chat/tool-preview.js +10 -0
- package/dist/worker/console/chat/tools.js +11 -1
- package/dist/worker/console/chat/turn-process.js +1 -0
- package/dist/worker/console/interview/tools.js +1 -0
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-C6n9_m0P.js → abnfDiagram-N423BO3Z-B0Q0nClf.js} +1 -1
- package/dist/worker/console/static/assets/{arc-DQh-IfZ1.js → arc-DCPjC19G.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-54NnrwUC.js → architectureDiagram-T3A2C74G-CP5n9jmG.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-pivRALGK.js → blockDiagram-VBNYF7ZC-CmaWi_Wg.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-BR7OV2NJ.js → c4Diagram-5PPSVZJV-Ct5tcMfZ.js} +1 -1
- package/dist/worker/console/static/assets/channel-DAS07MdS.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-B1Aq6BcK.js → chunk-2GRJ4B5K-C0osm1Zf.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-CbdU0rjo.js → chunk-2Q5K7J3B-CDWviED7.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-Dqi2GJeD.js → chunk-5RXB4S5H-mtSk1-j7.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-BYn1Hu4R.js → chunk-5VM5RSS4-D5J9PHC7.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-DRLjDL0k.js → chunk-6Q2QTUOP-Begg4WAa.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-CY9Xx2jV.js → chunk-GF5L2VYU-sF1AEy7T.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-BNCZs7_z.js → chunk-JWPE2WC7-BqbsWXZb.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-DZ8AStLL.js → chunk-KBJHAD2P-BKJrPcJ6.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-DsxjYrzz.js → chunk-RYQCIY6F-CcwNMRho.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-Ddx1KC1l.js → chunk-XXDRQBXY-BEJi3iIs.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-Cwk-5jiW.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-Cwk-5jiW.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-W9TveCnK.js → cose-bilkent-JH36ORCC-DRLgTvVu.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-l9j_ztZH.js → cynefin-VYW2F7L2-BoAVG3cs.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-BMJMKi4G.js → cynefinDiagram-MW4NZA55-Bzol06hR.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-Bb4mG9pH.js → dagre-VZM6K2ZE-UmliJM77.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-BMgL_Qv0.js → diagram-7IWD3JNH-BWLcJkFo.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-Bvo2T4OQ.js → diagram-B4RE2ZJO-CgApOm-O.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-_5kWRN9c.js → diagram-LBJQPF4R-Bh3RgTLs.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-DqdMrltM.js → diagram-Q27KOJAE-Dsh-D5nE.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-CDDYsNkp.js → diagram-UB23O5K3-Dkbbpcpb.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-c4nfnZUV.js → ebnfDiagram-BXEA7PRR-3EBaA3t3.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DnkUcNMs.js → erDiagram-JOGREHBK-Bq2Dc5ok.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-Dz0KGLZE.js → flowDiagram-UKHOOZJN-De7y55ha.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-Cj1t1uka.js → ganttDiagram-PKOTCBZU-fLiDbQRh.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-tp2FrBHd.js → gitGraphDiagram-DS77QQ5N-Du617mp1.js} +1 -1
- package/dist/worker/console/static/assets/index-C0O48S_P.js +449 -0
- package/dist/worker/console/static/assets/index-CzKf4U8P.css +1 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-DQwJS8DH.js → infoDiagram-6WML65LV-BwmlF-XP.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-eimCQWD4.js → ishikawaDiagram-WSZJBQD7-zsGtS59u.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-Dd9Gbwgv.js → journeyDiagram-NVQOT4AX-DTTPTe3f.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-Qve3cyft.js → kanban-definition-27J2QSJJ-BkXg9aP-.js} +1 -1
- package/dist/worker/console/static/assets/{linear-UXKSe36Z.js → linear-7U2ue5IE.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-CWhj4JXN.js → mermaid.core-BUuGHmWO.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-yTcwf4SJ.js → mindmap-definition-FAOFIHXS-7q6fX0Sv.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-_7qToaZP.js → pegDiagram-VL7TDLO6-CkQPJN55.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-CXmrKmDm.js → pieDiagram-7S7Q4E2Y-CCal_tfX.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-hMmrJyaS.js → quadrantDiagram-CIZ2JOQS-B7bpxyAZ.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-BXw8tCBe.js → railroadDiagram-AXF67PYL-CJmww7D-.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-BmjgnLZl.js → requirementDiagram-LRYGKXZP-D6ldWJEv.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-Bj77SPpN.js → sankeyDiagram-W5VNT64P-VGh33I9e.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-B2FDVysL.js → sequenceDiagram-SI44F4Z6-CCkDrIjU.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-UChNY9ZZ.js → sizeCapture-X5ZJPWSS-NC8f5Otb.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-wbAEkbd7.js → stateDiagram-OKZ733FA-_92ezZdF.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DyJg5gzW.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-DCEkU8HR.js → swimlanes-SLNWSIFB-BdUCGtbP.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-B1cw_0Uy.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-BGp7H06U.js → timeline-definition-Z64GVDOM-CdD1H8ia.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-DsCIQuWR.js → vennDiagram-T6HMQDX7-Dkdk3oFo.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-cRZLP4Xe.js → wardleyDiagram-T6FBY63Y-CKu2uPPY.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-CP0xLR9Y.js → xychartDiagram-ELKLHX3M-ClqAnuG8.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/chat-view-types.js +1 -1
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +23 -0
- package/dist/worker/console/static-src/operator-chat/pending-user-message.js +32 -0
- package/dist/worker/console/static-src/operator-chat/tools-catalog.js +21 -2
- package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +2 -0
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +2 -0
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +30 -14
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +133 -5
- package/dist/worker/console/static-src/shell/workspace-route.js +4 -0
- package/dist/worker/observe/static/constants.js +22 -22
- package/dist/worker/observe/static/dag-context-reason-labels.js +19 -0
- package/dist/worker/observe/static/dag-history-labels.js +1 -0
- package/dist/worker/observe/static/dag-inspector-humanize.d.ts +16 -0
- package/dist/worker/observe/static/dag-inspector-humanize.js +339 -0
- package/dist/worker/observe/static/dag-node-purpose.js +10 -10
- package/dist/worker/observe/static/index.html +4 -4
- package/dist/worker/observe/static/prompt-restart-candidates.js +4 -2
- package/dist/worker/observe/static/relations.js +5 -5
- package/dist/worker/observe/static/styles.css +171 -0
- package/dist/worker/observe/static/views/dag-graph.js +1 -1
- package/dist/worker/observe/static/views/dag-inspector.js +329 -174
- package/dist/worker/observe/static/views/dag.js +16 -12
- package/dist/worker/observe/static/views/session-timeline.js +5 -3
- package/dist/workflows/dag/backend-test-plan-protocol.js +104 -0
- package/dist/workflows/dag/dag-retry-schema.js +3 -0
- package/dist/workflows/dag/frontend-contract-facts.js +130 -0
- package/dist/workflows/dag/frontend-design-policy.js +101 -16
- package/dist/workflows/dag/frontend-implementation-contract.js +410 -41
- package/dist/workflows/dag/frontend-plan-render.js +13 -2
- package/dist/workflows/dag/frontend-prewrite-gate.js +1 -1
- package/dist/workflows/dag/frontend-recovery-controller.js +25 -1
- package/dist/workflows/dag/frontend-recovery-plan.js +4 -1
- package/dist/workflows/dag/frontend-recovery-run.js +142 -16
- package/dist/workflows/dag/frontend-risk.js +2 -0
- package/dist/workflows/dag/frontend-shadow-dual-write.js +17 -1
- package/dist/workflows/dag/frontend-shape.js +16 -6
- package/dist/workflows/dag/frontend-test-execution-evidence.js +48 -0
- package/dist/workflows/dag/frontend-typed-event-store.js +3 -0
- package/dist/workflows/dag/frontend-verification-trace.js +38 -4
- package/dist/workflows/dag/frontend-writer-admission.js +2 -2
- package/dist/workflows/dag/init-hybrid.js +57 -28
- package/dist/workflows/dag/node-execution.js +201 -85
- package/dist/workflows/dag/recovery-lease.js +106 -16
- package/dist/workflows/dag/rerun-feedback.js +1 -0
- package/dist/workflows/dag/rerun-plan.js +90 -4
- package/dist/workflows/dag/rerun-run.js +28 -6
- package/dist/workflows/dag/rerun-task.js +221 -18
- package/dist/workflows/dag/retry-policy.js +27 -10
- package/dist/workflows/dag/runner-exit-diagnostics.js +125 -0
- package/dist/workflows/dag/runner.js +220 -18
- package/dist/workflows/dag/structured-output-repair.js +4 -1
- package/dist/workflows/dag/types.js +4 -3
- package/dist/workflows/dag/validate.js +10 -8
- package/dist/workflows/dag/workspace-checkpoint.js +66 -0
- package/docs/operations/README.md +1 -0
- package/docs/templates/agent-dag.schema.json +2 -2
- package/docs/templates/backend-test-dag.json +6 -4
- package/docs/templates/frontend-implementation-contract.schema.json +34 -2
- package/harness.json +1 -1
- package/package.json +4 -5
- package/skills/frontend-plan/SKILL.md +14 -1
- package/skills/frontend-plan/references/decision-contract.md +101 -5
- package/skills/frontend-plan/references/design-decisions.md +32 -0
- package/dist/worker/console/static/assets/channel-DsZxrgqe.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-CuToPeGV.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-CuToPeGV.js +0 -1
- package/dist/worker/console/static/assets/index-D9Sc0f0y.js +0 -449
- package/dist/worker/console/static/assets/index-DDQc5a50.css +0 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-yPoT19ft.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-VWdarchG.js +0 -8
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
1
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
2
|
import { buildTurnProcessGroups, hydrateSessionThread, selectRecentTurnGroups, } from "../../chat/turn-process.js";
|
|
3
3
|
import { mergeOperationCardState, } from "../../chat/operation-card.js";
|
|
4
4
|
import { createChatSseEventApplier, } from "./chat-sse-events.js";
|
|
5
|
+
import { mergePendingSubmissionOnHydration } from "./pending-user-message.js";
|
|
5
6
|
import { taskContextUnchanged } from "./format.js";
|
|
6
7
|
import { upsertCompactionMessage } from "./compaction-message.js";
|
|
7
8
|
const EMPTY_USAGE = {
|
|
@@ -118,6 +119,10 @@ export function useChatThread(params) {
|
|
|
118
119
|
const [operationCards, setOperationCards] = useState([]);
|
|
119
120
|
const [artifactCards, setArtifactCards] = useState([]);
|
|
120
121
|
const [historyLimit, setHistoryLimit] = useState(50);
|
|
122
|
+
const [historyHasMore, setHistoryHasMore] = useState(false);
|
|
123
|
+
const [historyNextCursor, setHistoryNextCursor] = useState(null);
|
|
124
|
+
const [historyLoading, setHistoryLoading] = useState(false);
|
|
125
|
+
const historyLoadingRef = useRef(false);
|
|
121
126
|
const [unread, setUnread] = useState(0);
|
|
122
127
|
const [humanGateCards, setHumanGateCards] = useState([]);
|
|
123
128
|
const [interview, setInterview] = useState(null);
|
|
@@ -136,6 +141,8 @@ export function useChatThread(params) {
|
|
|
136
141
|
/** Assistant bubble id for the in-flight turn; only this row shows the streaming cursor. */
|
|
137
142
|
const [streamingAssistantId, setStreamingAssistantId] = useState(null);
|
|
138
143
|
const [showSystemInMessages] = useState(false);
|
|
144
|
+
const completedGroupsRef = useRef([]);
|
|
145
|
+
const previousTimelineRef = useRef(null);
|
|
139
146
|
const refreshSessionTelemetry = useCallback(async () => {
|
|
140
147
|
const targetSessionId = refs.sessionRef.current?.sessionId;
|
|
141
148
|
if (!targetSessionId)
|
|
@@ -301,12 +308,55 @@ export function useChatThread(params) {
|
|
|
301
308
|
};
|
|
302
309
|
}, [toolCalls]);
|
|
303
310
|
const turnGroups = useMemo(() => {
|
|
304
|
-
const
|
|
311
|
+
const previousTimeline = previousTimelineRef.current;
|
|
312
|
+
let built;
|
|
313
|
+
const activeIndex = streamingAssistantId
|
|
314
|
+
? timelineMessages.findIndex((message) => message.id === streamingAssistantId)
|
|
315
|
+
: -1;
|
|
316
|
+
const canBuildActiveTail = Boolean(previousTimeline && streaming && streamingAssistantId && activeIndex >= 0) &&
|
|
317
|
+
previousTimeline?.activeAssistantId === streamingAssistantId &&
|
|
318
|
+
(previousTimeline?.messages.every((message, index) => message.id === streamingAssistantId || timelineMessages[index]?.id === message.id) ?? false);
|
|
319
|
+
if (canBuildActiveTail && previousTimeline) {
|
|
320
|
+
let tailStart = activeIndex;
|
|
321
|
+
while (tailStart > 0 && timelineMessages[tailStart - 1]?.role !== "user")
|
|
322
|
+
tailStart -= 1;
|
|
323
|
+
const tailMessages = timelineMessages.slice(tailStart);
|
|
324
|
+
const tailIds = new Set(tailMessages.map((message) => message.id));
|
|
325
|
+
const tailTurnIds = new Set(tailMessages.map((message) => message.turnId).filter(Boolean));
|
|
326
|
+
const tailTools = toolCalls.filter((tool) => tailIds.has(tool.assistantMessageId ?? "") ||
|
|
327
|
+
(Boolean(tool.turnId) && tailTurnIds.has(tool.turnId)) ||
|
|
328
|
+
(tool.createdAt >= (tailMessages[0]?.createdAt ?? Number.POSITIVE_INFINITY)));
|
|
329
|
+
const activeTail = buildTurnProcessGroups({
|
|
330
|
+
messages: tailMessages,
|
|
331
|
+
toolCalls: tailTools,
|
|
332
|
+
streaming,
|
|
333
|
+
activeAssistantId: streamingAssistantId,
|
|
334
|
+
});
|
|
335
|
+
built = [...previousTimeline.groups.filter((group) => !group.live), ...activeTail];
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
built = buildTurnProcessGroups({
|
|
339
|
+
messages: timelineMessages,
|
|
340
|
+
toolCalls,
|
|
341
|
+
streaming,
|
|
342
|
+
activeAssistantId: streamingAssistantId,
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
// Preserve completed group objects across streaming tokens. The active
|
|
346
|
+
// tail is rebuilt, while stable historical groups keep their references so
|
|
347
|
+
// memoized rows do not re-render or re-parse the full conversation.
|
|
348
|
+
const previous = new Map(completedGroupsRef.current.map((group) => [group.key, group]));
|
|
349
|
+
const all = built.map((group) => {
|
|
350
|
+
const cached = previous.get(group.key);
|
|
351
|
+
return cached && !group.live ? cached : group;
|
|
352
|
+
});
|
|
353
|
+
completedGroupsRef.current = all.filter((group) => !group.live);
|
|
354
|
+
previousTimelineRef.current = {
|
|
305
355
|
messages: timelineMessages,
|
|
306
356
|
toolCalls,
|
|
307
|
-
streaming,
|
|
308
357
|
activeAssistantId: streamingAssistantId,
|
|
309
|
-
|
|
358
|
+
groups: all,
|
|
359
|
+
};
|
|
310
360
|
return selectRecentTurnGroups(all, historyLimit);
|
|
311
361
|
}, [
|
|
312
362
|
timelineMessages,
|
|
@@ -315,6 +365,50 @@ export function useChatThread(params) {
|
|
|
315
365
|
streamingAssistantId,
|
|
316
366
|
historyLimit,
|
|
317
367
|
]);
|
|
368
|
+
const loadEarlierMessages = useCallback(async () => {
|
|
369
|
+
const targetSessionId = refs.sessionRef.current?.sessionId;
|
|
370
|
+
const beforeId = historyNextCursor;
|
|
371
|
+
if (!targetSessionId || !historyHasMore || !beforeId || historyLoadingRef.current)
|
|
372
|
+
return false;
|
|
373
|
+
historyLoadingRef.current = true;
|
|
374
|
+
setHistoryLoading(true);
|
|
375
|
+
try {
|
|
376
|
+
const query = new URLSearchParams({ limit: "50", beforeId });
|
|
377
|
+
const res = await fetch(`${origin}/api/operator/v1/chat/sessions/${encodeURIComponent(targetSessionId)}/messages?${query.toString()}`, { credentials: "include" });
|
|
378
|
+
if (!res.ok || refs.sessionRef.current?.sessionId !== targetSessionId)
|
|
379
|
+
return false;
|
|
380
|
+
const body = (await res.json());
|
|
381
|
+
const page = hydrateSessionThread(body.messages ?? []);
|
|
382
|
+
setMessages((current) => {
|
|
383
|
+
const seen = new Set();
|
|
384
|
+
const merged = [...page.messages, ...current].filter((message) => {
|
|
385
|
+
if (seen.has(message.id))
|
|
386
|
+
return false;
|
|
387
|
+
seen.add(message.id);
|
|
388
|
+
return true;
|
|
389
|
+
});
|
|
390
|
+
return merged.sort((a, b) => {
|
|
391
|
+
if (a.eventSeq !== undefined && b.eventSeq !== undefined && a.eventSeq !== b.eventSeq)
|
|
392
|
+
return a.eventSeq - b.eventSeq;
|
|
393
|
+
return a.createdAt - b.createdAt;
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
setToolCalls((current) => {
|
|
397
|
+
const byId = new Map(current.map((tool) => [tool.id, tool]));
|
|
398
|
+
for (const tool of page.toolCalls)
|
|
399
|
+
byId.set(tool.id, tool);
|
|
400
|
+
return [...byId.values()].sort((a, b) => a.createdAt - b.createdAt);
|
|
401
|
+
});
|
|
402
|
+
setHistoryHasMore(body.hasMore === true);
|
|
403
|
+
setHistoryNextCursor(body.nextCursor ?? null);
|
|
404
|
+
setHistoryLimit((value) => value + 50);
|
|
405
|
+
return true;
|
|
406
|
+
}
|
|
407
|
+
finally {
|
|
408
|
+
historyLoadingRef.current = false;
|
|
409
|
+
setHistoryLoading(false);
|
|
410
|
+
}
|
|
411
|
+
}, [historyHasMore, historyNextCursor, origin, refs]);
|
|
318
412
|
const visibleMessages = useMemo(() => {
|
|
319
413
|
const next = [];
|
|
320
414
|
for (const group of turnGroups) {
|
|
@@ -346,6 +440,11 @@ export function useChatThread(params) {
|
|
|
346
440
|
setStreamingAssistantId(null);
|
|
347
441
|
setUnread(0);
|
|
348
442
|
setHistoryLimit(50);
|
|
443
|
+
setHistoryHasMore(false);
|
|
444
|
+
setHistoryNextCursor(null);
|
|
445
|
+
historyLoadingRef.current = false;
|
|
446
|
+
completedGroupsRef.current = [];
|
|
447
|
+
previousTimelineRef.current = null;
|
|
349
448
|
refs.usageResponseKeysRef.current = new Set();
|
|
350
449
|
}, [refs]);
|
|
351
450
|
/** Adopt a freshly activated session's hydrated thread + streaming flags. */
|
|
@@ -374,6 +473,10 @@ export function useChatThread(params) {
|
|
|
374
473
|
setStreamingAssistantId(null);
|
|
375
474
|
setUnread(0);
|
|
376
475
|
setHistoryLimit(50);
|
|
476
|
+
setHistoryHasMore(next.history?.hasMore === true);
|
|
477
|
+
setHistoryNextCursor(next.history?.nextCursor ?? null);
|
|
478
|
+
completedGroupsRef.current = [];
|
|
479
|
+
previousTimelineRef.current = null;
|
|
377
480
|
}, [refs]);
|
|
378
481
|
/** Reconcile recovery (AC-001/AC-002/AC-003): reload the canonical session
|
|
379
482
|
* facts (session-store messages + event-ring tail cursor) and REPLACE the
|
|
@@ -415,8 +518,29 @@ export function useChatThread(params) {
|
|
|
415
518
|
refs.turnAssistantIdsRef.current = new Map();
|
|
416
519
|
refs.sealedAssistantIdsRef.current = new Set();
|
|
417
520
|
const hydrated = hydrateSessionThread(body.session.messages ?? []);
|
|
418
|
-
|
|
521
|
+
const pending = refs.pendingSubmissionRef.current;
|
|
522
|
+
const recovered = mergePendingSubmissionOnHydration(hydrated.messages, pending
|
|
523
|
+
? {
|
|
524
|
+
clientRequestId: pending.clientRequestId,
|
|
525
|
+
user: {
|
|
526
|
+
id: pending.userMessageId,
|
|
527
|
+
role: "user",
|
|
528
|
+
text: pending.text,
|
|
529
|
+
createdAt: Date.now(),
|
|
530
|
+
clientRequestId: pending.clientRequestId,
|
|
531
|
+
},
|
|
532
|
+
assistant: {
|
|
533
|
+
id: pending.assistantId,
|
|
534
|
+
role: "assistant",
|
|
535
|
+
text: "",
|
|
536
|
+
createdAt: Date.now(),
|
|
537
|
+
},
|
|
538
|
+
}
|
|
539
|
+
: undefined);
|
|
540
|
+
setMessages(mergeCompactionMessages(recovered, body.compactions));
|
|
419
541
|
setToolCalls(hydrated.toolCalls);
|
|
542
|
+
setHistoryHasMore(body.history?.hasMore === true);
|
|
543
|
+
setHistoryNextCursor(body.history?.nextCursor ?? null);
|
|
420
544
|
setStreamingAssistantId(null);
|
|
421
545
|
return true;
|
|
422
546
|
}
|
|
@@ -446,6 +570,10 @@ export function useChatThread(params) {
|
|
|
446
570
|
artifactCards,
|
|
447
571
|
historyLimit,
|
|
448
572
|
setHistoryLimit,
|
|
573
|
+
historyHasMore,
|
|
574
|
+
historyNextCursor,
|
|
575
|
+
historyLoading,
|
|
576
|
+
loadEarlierMessages,
|
|
449
577
|
unread,
|
|
450
578
|
humanGateCards,
|
|
451
579
|
interview,
|
|
@@ -170,6 +170,10 @@ export function withWorkspaceId(href, workspaceId) {
|
|
|
170
170
|
const qs = query.toString();
|
|
171
171
|
return `/#${path}${qs ? `?${qs}` : ""}`;
|
|
172
172
|
}
|
|
173
|
+
/** The primary Observe mode is a section entry, not an object deep link. */
|
|
174
|
+
export function buildPrimaryInspectHref(workspaceId) {
|
|
175
|
+
return withWorkspaceId(DEFAULT_INSPECT_HREF, workspaceId);
|
|
176
|
+
}
|
|
173
177
|
/** Preserve the selected scope for a deep link emitted inside an Operate page.
|
|
174
178
|
* Components should prefer this to hand-writing `/#/inspect/...`: it reads the
|
|
175
179
|
* canonical hash at click/render time and intentionally leaves bare Chat URLs
|
|
@@ -20,20 +20,20 @@ export const OUTPUT_FOLLOW_LATEST_PX = 48;
|
|
|
20
20
|
|
|
21
21
|
export const UI_TEXT = {
|
|
22
22
|
dashboard: "总览",
|
|
23
|
-
dagRuns: "
|
|
24
|
-
dagHistory: "
|
|
23
|
+
dagRuns: "运行流程",
|
|
24
|
+
dagHistory: "运行历史",
|
|
25
25
|
viewAllDags: "查看全部 →",
|
|
26
|
-
failures: "
|
|
26
|
+
failures: "异常任务",
|
|
27
27
|
nightJobs: "夜间任务",
|
|
28
28
|
batchDetail: "批次详情",
|
|
29
29
|
runDetail: "运行详情",
|
|
30
|
-
dagDetail: "
|
|
31
|
-
activeDags: "
|
|
32
|
-
recentDags: "
|
|
33
|
-
batches: "
|
|
34
|
-
noActiveDags: "
|
|
35
|
-
noRecentDags: "
|
|
36
|
-
noFormalDagHistory: "
|
|
30
|
+
dagDetail: "运行详情",
|
|
31
|
+
activeDags: "进行中的流程",
|
|
32
|
+
recentDags: "最近运行",
|
|
33
|
+
batches: "任务批次",
|
|
34
|
+
noActiveDags: "当前没有进行中的流程,启动后将出现在这里。",
|
|
35
|
+
noRecentDags: "暂无运行记录。",
|
|
36
|
+
noFormalDagHistory: "暂无正式运行记录",
|
|
37
37
|
noFormalDagHistoryHint:
|
|
38
38
|
"dry-run / init-only 预检记录不会出现在此列表中。",
|
|
39
39
|
dagHistoryRefreshFailed: "刷新失败,当前展示上一次结果",
|
|
@@ -41,34 +41,34 @@ export const UI_TEXT = {
|
|
|
41
41
|
dagHistoryCopiedAnnounce: "已复制运行 ID",
|
|
42
42
|
dagHistoryCopyFailed: "复制失败,请手动选择运行 ID",
|
|
43
43
|
dagHistoryCopyTooltip: "复制运行 ID",
|
|
44
|
-
noBatches: "
|
|
44
|
+
noBatches: "暂无任务批次,运行后将出现在这里。",
|
|
45
45
|
noNodes: "暂无节点。",
|
|
46
46
|
noOutput: "暂无节点输出。",
|
|
47
47
|
noInput: "暂无节点输入。",
|
|
48
48
|
inputLoading: "正在加载节点输入…",
|
|
49
|
-
inputUnavailable: "
|
|
49
|
+
inputUnavailable: "没有在本次运行保存的执行计划中找到该节点设置。",
|
|
50
50
|
inputDynamicUnsupported:
|
|
51
|
-
"
|
|
52
|
-
inputRunSpecUnavailable: "
|
|
51
|
+
"该节点是在运行过程中动态生成的,暂时无法展示完整的运行前设置。",
|
|
52
|
+
inputRunSpecUnavailable: "无法读取本次运行开始前保存的执行计划(run.json)。",
|
|
53
53
|
inputError: "加载节点输入失败。",
|
|
54
|
-
inputFrozenLabel: "
|
|
55
|
-
inputFingerprintNote: "
|
|
56
|
-
noSessionEvents: "该
|
|
57
|
-
noShellProcess: "
|
|
54
|
+
inputFrozenLabel: "本次运行开始前保存的执行设置",
|
|
55
|
+
inputFingerprintNote: "这里只保存最终提示内容的校验信息,没有保存完整文本。",
|
|
56
|
+
noSessionEvents: "该 AI 节点暂无过程日志(可能尚未执行、通过命令行执行,或来自较早的运行)。",
|
|
57
|
+
noShellProcess: "该命令节点尚未留下执行记录。",
|
|
58
58
|
noPresetProcess: "该内部处理器尚未留下过程回执。",
|
|
59
|
-
staticNoProcess: "
|
|
59
|
+
staticNoProcess: "系统直接生成的节点没有逐步执行过程,请查看节点输出。",
|
|
60
60
|
processLoading: "正在加载执行过程…",
|
|
61
61
|
processError: "加载执行过程失败。",
|
|
62
|
-
shellCommandsHeading: "
|
|
62
|
+
shellCommandsHeading: "命令执行记录",
|
|
63
63
|
shellPresetHeading: "内部处理器",
|
|
64
64
|
noArtifacts: "暂无产物记录。",
|
|
65
65
|
noActiveCommand: "当前没有正在执行的命令。",
|
|
66
|
-
noFailures: "
|
|
66
|
+
noFailures: "当前没有异常任务。",
|
|
67
67
|
enterDetail: "查看详情 →",
|
|
68
68
|
repoRoot: "仓库根目录",
|
|
69
69
|
generatedAt: "生成时间",
|
|
70
70
|
refreshStatus: "更新",
|
|
71
|
-
failureInbox: "
|
|
71
|
+
failureInbox: "异常任务",
|
|
72
72
|
nearRealtime: "轮询刷新",
|
|
73
73
|
manualRefresh: "手动刷新",
|
|
74
74
|
autoRefresh: "自动刷新",
|
|
@@ -30,6 +30,25 @@ const CONTEXT_TRANSFER_REASON_LABELS = {
|
|
|
30
30
|
WORKER_CONTINUATION_AUTHORITY_MISMATCH: "Worker 派生运行的归属事实不一致",
|
|
31
31
|
WORKER_CONTINUATION_NEEDS_RECONCILE: "Worker 派生运行已存在,需要先恢复核对",
|
|
32
32
|
WORKER_CONTINUATION_LEASE_CONFLICT: "该 Worker Task 已有运行占用",
|
|
33
|
+
"parent-lifecycle-ineligible": "原运行尚未完整结束,只有已完成的运行才能从这里继续",
|
|
34
|
+
"convergence-rerun-unsupported": "原运行使用自动收敛流程,暂不支持替换产出后继续",
|
|
35
|
+
"evaluation-rerun-unsupported": "评测运行暂不支持替换产出后继续",
|
|
36
|
+
"budget-lineage-missing": "缺少原运行的额度使用记录",
|
|
37
|
+
"budget-lineage-breached": "原运行已经用完或超出额度",
|
|
38
|
+
"budget-lineage-drift": "原运行的额度规则已经变化",
|
|
39
|
+
"sourceBindingMatched-drift": "任务来源与原运行不一致",
|
|
40
|
+
"taskContractBindingMatched-drift": "任务约定与原运行不一致",
|
|
41
|
+
"controllerIdentityMatched-drift": "运行控制器版本与原运行不一致",
|
|
42
|
+
"skillSnapshotVerified-drift": "节点使用的技能版本无法与原运行核对",
|
|
43
|
+
"workspaceMatched-drift": "当前工作区内容与原运行结束时不一致",
|
|
44
|
+
"restart-subgraph-contains-writer": "受影响范围里有写入节点,但它的文件边界不够明确",
|
|
45
|
+
"restart-subgraph-contains-decision-gate": "受影响范围里包含需要人工重新决定的关卡",
|
|
46
|
+
"restart-subgraph-contains-unsafe-shell": "受影响范围里有不能安全自动重跑的命令",
|
|
47
|
+
"dynamic-rerun-unsupported": "受影响范围里有无法安全重新生成的动态节点",
|
|
48
|
+
"parent-facts-invalid": "准备沿用的节点没有完整的成功记录",
|
|
49
|
+
"workspace-checkpoint-missing": "缺少原运行结束时的工作区校验记录",
|
|
50
|
+
"workspace-drift": "当前工作区已经发生变化,不能安全接着写",
|
|
51
|
+
HIGH_RISK_AUTHORITY_MISSING: "高风险重跑缺少完整的写入、动态节点或额度校验信息",
|
|
33
52
|
INELIGIBLE: "当前不满足继续运行的条件",
|
|
34
53
|
PARENT_IMMUTABILITY_VIOLATION: "父运行事实发生变化,已阻止派生",
|
|
35
54
|
PARENT_LIFECYCLE: "父运行状态不允许派生继续",
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type InspectorMetaCopy = {
|
|
2
|
+
label: string;
|
|
3
|
+
value: string;
|
|
4
|
+
help: string | null;
|
|
5
|
+
rawLabel: string | null;
|
|
6
|
+
rawValue: string | null;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export function inspectorFieldLabel(field: unknown): string;
|
|
10
|
+
export function inspectorValueLabel(field: unknown, value: unknown): string;
|
|
11
|
+
export function inspectorListValueLabel(value: unknown): string;
|
|
12
|
+
export function inspectorFieldHelp(field: unknown): string | null;
|
|
13
|
+
export function describeInspectorMeta(
|
|
14
|
+
field: unknown,
|
|
15
|
+
value: unknown,
|
|
16
|
+
): InspectorMetaCopy;
|