@tea-agent/loop-agent 0.36.3-beta.0 → 0.37.0
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 +56 -55
- package/dist/build-stamp.json +3 -3
- package/dist/task/contract/project.js +4 -0
- package/dist/task/source-prepare/completeness.js +36 -0
- package/dist/task/source-prepare/parse-intent.js +67 -11
- package/dist/task/source-prepare/prepare.js +102 -5
- package/dist/worker/console/chat/chat-event-store.js +91 -0
- package/dist/worker/console/chat/pi-runtime.js +25 -0
- package/dist/worker/console/chat/routes.js +7 -2
- package/dist/worker/console/chat/semantic-activity.js +7 -1
- package/dist/worker/console/chat/session-store.js +6 -1
- package/dist/worker/console/chat/turn-process.js +119 -12
- package/dist/worker/console/operator-actions.js +18 -1
- package/dist/worker/console/static/assets/abnfDiagram-N423BO3Z-DSvF6RXQ.js +1 -0
- package/dist/worker/console/static/assets/arc-DuI4ogtJ.js +1 -0
- package/dist/worker/console/static/assets/architectureDiagram-T3A2C74G-DdBbgD4y.js +36 -0
- package/dist/worker/console/static/assets/blockDiagram-VBNYF7ZC-xQC2HELm.js +132 -0
- package/dist/worker/console/static/assets/c4Diagram-5PPSVZJV-DPMSgwIZ.js +10 -0
- package/dist/worker/console/static/assets/channel-DLVz9TYW.js +1 -0
- package/dist/worker/console/static/assets/chunk-2GRJ4B5K-WTEKTxin.js +1 -0
- package/dist/worker/console/static/assets/chunk-2Q5K7J3B-B6vZ0Pv_.js +1 -0
- package/dist/worker/console/static/assets/chunk-5RXB4S5H-BrerNAix.js +231 -0
- package/dist/worker/console/static/assets/chunk-5VM5RSS4-D_ch2aaI.js +15 -0
- package/dist/worker/console/static/assets/chunk-6Q2QTUOP-VvfacNrq.js +88 -0
- package/dist/worker/console/static/assets/chunk-GF5L2VYU-B-uGFIg2.js +206 -0
- package/dist/worker/console/static/assets/chunk-JWPE2WC7-BlysCtod.js +1 -0
- package/dist/worker/console/static/assets/chunk-KBJHAD2P-BjAUAfcT.js +1 -0
- package/dist/worker/console/static/assets/chunk-RYQCIY6F-BeZnBmb-.js +1 -0
- package/dist/worker/console/static/assets/chunk-XXDRQBXY-Bbfe3UJG.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BeAuGcO9.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BeAuGcO9.js +1 -0
- package/dist/worker/console/static/assets/cose-bilkent-JH36ORCC-BKJQnYVM.js +1 -0
- package/dist/worker/console/static/assets/cynefin-VYW2F7L2-B1wtI3hU.js +166 -0
- package/dist/worker/console/static/assets/cynefinDiagram-MW4NZA55-DCF6DBSu.js +62 -0
- package/dist/worker/console/static/assets/cytoscape.esm-yzknjiTM.js +321 -0
- package/dist/worker/console/static/assets/dagre-VZM6K2ZE-BJyNGRlP.js +4 -0
- package/dist/worker/console/static/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/dist/worker/console/static/assets/diagram-7IWD3JNH-B7j1-VsZ.js +30 -0
- package/dist/worker/console/static/assets/diagram-B4RE2ZJO-BREJ140a.js +3 -0
- package/dist/worker/console/static/assets/diagram-LBJQPF4R-CDPHmHGH.js +24 -0
- package/dist/worker/console/static/assets/diagram-Q27KOJAE-BtZLrez1.js +24 -0
- package/dist/worker/console/static/assets/diagram-UB23O5K3-mzybu8oU.js +41 -0
- package/dist/worker/console/static/assets/ebnfDiagram-BXEA7PRR-Dk3I2uO6.js +1 -0
- package/dist/worker/console/static/assets/erDiagram-JOGREHBK-BT97u_tQ.js +85 -0
- package/dist/worker/console/static/assets/flowDiagram-UKHOOZJN-CMOtYzui.js +156 -0
- package/dist/worker/console/static/assets/ganttDiagram-PKOTCBZU-DiNydkuY.js +292 -0
- package/dist/worker/console/static/assets/gitGraphDiagram-DS77QQ5N-Cwt6fLkl.js +106 -0
- package/dist/worker/console/static/assets/graph-DOmOIIwC.js +1 -0
- package/dist/worker/console/static/assets/index-DQxiso1w.js +325 -0
- package/dist/worker/console/static/assets/index-_j0Hzo69.css +1 -0
- package/dist/worker/console/static/assets/infoDiagram-6WML65LV-AsGIGKKB.js +2 -0
- package/dist/worker/console/static/assets/init-Gi6I4Gst.js +1 -0
- package/dist/worker/console/static/assets/ishikawaDiagram-WSZJBQD7-BL8ITZh3.js +70 -0
- package/dist/worker/console/static/assets/journeyDiagram-NVQOT4AX-VPKAUX8M.js +139 -0
- package/dist/worker/console/static/assets/kanban-definition-27J2QSJJ-BL56hfGp.js +89 -0
- package/dist/worker/console/static/assets/layout-D-LzfAck.js +1 -0
- package/dist/worker/console/static/assets/linear-BmSG3nIZ.js +1 -0
- package/dist/worker/console/static/assets/map-DxJ2ADlA.js +1 -0
- package/dist/worker/console/static/assets/mermaid.core-DWGK9kwP.js +308 -0
- package/dist/worker/console/static/assets/mindmap-definition-FAOFIHXS--vvKLjo0.js +96 -0
- package/dist/worker/console/static/assets/ordinal-Cboi1Yqb.js +1 -0
- package/dist/worker/console/static/assets/pegDiagram-VL7TDLO6-B41mxb2-.js +1 -0
- package/dist/worker/console/static/assets/pieDiagram-7S7Q4E2Y-DTlu77sw.js +39 -0
- package/dist/worker/console/static/assets/quadrantDiagram-CIZ2JOQS-Bk5A7alv.js +7 -0
- package/dist/worker/console/static/assets/railroadDiagram-AXF67PYL-Csf9jzQy.js +1 -0
- package/dist/worker/console/static/assets/requirementDiagram-LRYGKXZP-CeptoSNx.js +84 -0
- package/dist/worker/console/static/assets/sankeyDiagram-W5VNT64P-A-DLCLer.js +40 -0
- package/dist/worker/console/static/assets/sequenceDiagram-SI44F4Z6-22VbPdOI.js +162 -0
- package/dist/worker/console/static/assets/sizeCapture-X5ZJPWSS-DWvAyBC9.js +1 -0
- package/dist/worker/console/static/assets/stateDiagram-OKZ733FA-qICZ75yT.js +1 -0
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DzKvfHTX.js +1 -0
- package/dist/worker/console/static/assets/swimlanes-SLNWSIFB-xi7lcMyp.js +2 -0
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-Cxqr_qM1.js +8 -0
- package/dist/worker/console/static/assets/timeline-definition-Z64GVDOM-Bu6Nl6O2.js +120 -0
- package/dist/worker/console/static/assets/vennDiagram-T6HMQDX7-BzMz4Bn9.js +34 -0
- package/dist/worker/console/static/assets/wardleyDiagram-T6FBY63Y-CxaJnzc5.js +78 -0
- package/dist/worker/console/static/assets/xychartDiagram-ELKLHX3M-5JK-omQK.js +7 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_AMS-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Main-Bold.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Main-Italic.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Main-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Math-Italic.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Script-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Size1-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Size2-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Size3-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Size4-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +25 -0
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +37 -2
- package/dist/worker/observe/static/operator-chrome.js +4 -2
- package/dist/workflows/dag/failure-routing.js +4 -9
- package/dist/workflows/dag/init-hybrid.js +2 -47
- package/dist/workflows/dag/lifecycle.js +0 -4
- package/dist/workflows/dag/node-execution.js +6 -16
- package/dist/workflows/dag/report.js +0 -6
- package/dist/workflows/dag/retry-policy.js +0 -11
- package/dist/workflows/dag/runner.js +19 -3
- package/dist/workflows/dag/types.js +0 -2
- package/dist/workflows/dag/validate.js +2 -7
- package/docs/templates/frontend-task-constraints.md +7 -13
- package/package.json +6 -1
- package/skills/loop-agent/references/command-reference.md +1 -0
- package/dist/worker/console/static/assets/index-D83DYAFG.css +0 -1
- package/dist/worker/console/static/assets/index-IXm7oYjL.js +0 -59
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import { parseAssistantContent } from "./assistant-content.js";
|
|
16
16
|
import { OPERATOR_CHAT_ALLOWED_TOOLS, OPERATOR_CHAT_DENIED_TOOLS, OPERATOR_CHAT_DENIED_OPERATOR_ACTIONS, } from "./tools.js";
|
|
17
17
|
import { buildModelCallableToolSchemas } from "./tool-adapter.js";
|
|
18
|
-
import { cleanChatTitle } from "./session-store.js";
|
|
18
|
+
import { cleanChatTitle, acceptedOperationIdFromResult } from "./session-store.js";
|
|
19
19
|
import { hashChatTurnPayload, projectChatToolEventPayload, projectCompactSnapshot, } from "./chat-event-store.js";
|
|
20
20
|
import { THINKING_LEVELS, RuntimeSnapshotUnavailableError, } from "./pi-runtime.js";
|
|
21
21
|
import { ResourcePreferencesError, setSkillAutoInvocationPreference, } from "./resource-preferences-store.js";
|
|
@@ -106,7 +106,10 @@ function turnEventToStorePartial(event) {
|
|
|
106
106
|
value: event.args,
|
|
107
107
|
}),
|
|
108
108
|
};
|
|
109
|
-
case "tool_result":
|
|
109
|
+
case "tool_result": {
|
|
110
|
+
// Plan A (2026-08-16): surface the accepted-operation link on the live
|
|
111
|
+
// SSE frame so the frontend semantic event can resolve operation:<id>.
|
|
112
|
+
const resultOperationId = acceptedOperationIdFromResult(String(event.toolName ?? ""), event.result);
|
|
110
113
|
return {
|
|
111
114
|
kind: "tool_result",
|
|
112
115
|
data: projectChatToolEventPayload({
|
|
@@ -115,8 +118,10 @@ function turnEventToStorePartial(event) {
|
|
|
115
118
|
toolName: String(event.toolName ?? ""),
|
|
116
119
|
value: event.result,
|
|
117
120
|
isError: Boolean(event.isError),
|
|
121
|
+
...(resultOperationId ? { operationId: resultOperationId } : {}),
|
|
118
122
|
}),
|
|
119
123
|
};
|
|
124
|
+
}
|
|
120
125
|
case "agent_end":
|
|
121
126
|
return {
|
|
122
127
|
kind: "agent_end",
|
|
@@ -292,7 +292,13 @@ function maxWaitSeconds(args) {
|
|
|
292
292
|
return Math.max(1, Math.round(raw / 1000));
|
|
293
293
|
}
|
|
294
294
|
function activityRefForTool(tool) {
|
|
295
|
-
|
|
295
|
+
// Plan A (2026-08-16): server backfills operationId on the persisted tool
|
|
296
|
+
// entry (and live tool_result frames carry it in the result payload), so
|
|
297
|
+
// prefer the authoritative link before parsing args/result fallbacks.
|
|
298
|
+
const operationId = tool.operationId ??
|
|
299
|
+
operationIdFromArgs(tool.args) ??
|
|
300
|
+
operationIdFromArgs(tool.result) ??
|
|
301
|
+
operationIdFromArgs(tool.resultText);
|
|
296
302
|
return operationId ? `operation:${operationId}` : `tool:${tool.id}`;
|
|
297
303
|
}
|
|
298
304
|
function semanticKindForStatus(status) {
|
|
@@ -402,6 +402,11 @@ export async function runChatTurn(options) {
|
|
|
402
402
|
toolCallId: event.toolCallId,
|
|
403
403
|
toolName: event.toolName,
|
|
404
404
|
isError: event.isError,
|
|
405
|
+
// Durable tool→operation link (plan A): the restored timeline can
|
|
406
|
+
// resolve operation:<id> refs without the live operation-ref event.
|
|
407
|
+
...(acceptedOperationId
|
|
408
|
+
? { operationId: acceptedOperationId }
|
|
409
|
+
: {}),
|
|
405
410
|
}));
|
|
406
411
|
pending.push(store.recordToolInvocation(sessionId, {
|
|
407
412
|
toolCallId: event.toolCallId,
|
|
@@ -431,7 +436,7 @@ export async function runChatTurn(options) {
|
|
|
431
436
|
* huge operator-action payload (e.g. a full dagReport) cannot bloat the chat
|
|
432
437
|
* history record.
|
|
433
438
|
*/
|
|
434
|
-
function acceptedOperationIdFromResult(toolName, result) {
|
|
439
|
+
export function acceptedOperationIdFromResult(toolName, result) {
|
|
435
440
|
const candidates = [result];
|
|
436
441
|
if (result && typeof result === "object") {
|
|
437
442
|
const record = result;
|
|
@@ -70,6 +70,7 @@ export function hydrateSessionThread(raw) {
|
|
|
70
70
|
createdAt,
|
|
71
71
|
finishedAt: createdAt,
|
|
72
72
|
turnId,
|
|
73
|
+
...(item.operationId ? { operationId: item.operationId } : {}),
|
|
73
74
|
};
|
|
74
75
|
toolCalls.push(entry);
|
|
75
76
|
pendingTools.push(entry);
|
|
@@ -77,30 +78,89 @@ export function hydrateSessionThread(raw) {
|
|
|
77
78
|
}
|
|
78
79
|
return { messages, toolCalls };
|
|
79
80
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
/** Stable tool order: server eventSeq first, createdAt fallback, id tiebreak. */
|
|
82
|
+
function sortToolsStable(tools) {
|
|
83
|
+
return [...tools].sort((a, b) => {
|
|
84
|
+
if (a.eventSeq !== undefined &&
|
|
85
|
+
b.eventSeq !== undefined &&
|
|
86
|
+
a.eventSeq !== b.eventSeq) {
|
|
87
|
+
return a.eventSeq - b.eventSeq;
|
|
88
|
+
}
|
|
89
|
+
if (a.createdAt !== b.createdAt)
|
|
90
|
+
return a.createdAt - b.createdAt;
|
|
91
|
+
return a.id < b.id ? -1 : 1;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Flush buffered consecutive tools into process items. Semantic operator
|
|
96
|
+
* tools stay as individual activity events; plain tools group into a
|
|
97
|
+
* `tool-group` ("并行调用 · N 项") when two or more land back to back.
|
|
98
|
+
* Thinking/text/activity boundaries break the buffer upstream.
|
|
99
|
+
*/
|
|
100
|
+
function flushToolBuffer(processItems, buffer) {
|
|
101
|
+
if (buffer.length === 0)
|
|
102
|
+
return;
|
|
103
|
+
const sorted = sortToolsStable(buffer);
|
|
104
|
+
let plainGroup = [];
|
|
105
|
+
const flushPlain = () => {
|
|
106
|
+
if (plainGroup.length === 1) {
|
|
107
|
+
processItems.push({ kind: "tool", tool: plainGroup[0] });
|
|
108
|
+
}
|
|
109
|
+
else if (plainGroup.length > 1) {
|
|
110
|
+
processItems.push({ kind: "tool-group", tools: plainGroup });
|
|
111
|
+
}
|
|
112
|
+
plainGroup = [];
|
|
113
|
+
};
|
|
114
|
+
for (const tool of sorted) {
|
|
115
|
+
const activity = semanticActivityForTool(tool);
|
|
116
|
+
if (activity) {
|
|
117
|
+
flushPlain();
|
|
118
|
+
processItems.push({ kind: "activity", activity });
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
plainGroup.push(tool);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
flushPlain();
|
|
86
125
|
}
|
|
87
126
|
function emitProcessBlocks(blocks, group, processItems, usedToolIds) {
|
|
127
|
+
let buffer = [];
|
|
88
128
|
for (const block of blocks) {
|
|
89
129
|
if (block.type === "thinking") {
|
|
130
|
+
flushToolBuffer(processItems, buffer);
|
|
131
|
+
buffer = [];
|
|
90
132
|
processItems.push({ kind: "thinking", thinking: block.thinking });
|
|
91
133
|
continue;
|
|
92
134
|
}
|
|
93
135
|
if (block.type === "text") {
|
|
94
|
-
|
|
136
|
+
flushToolBuffer(processItems, buffer);
|
|
137
|
+
buffer = [];
|
|
138
|
+
if (block.text.trim()) {
|
|
95
139
|
processItems.push({ kind: "text", text: block.text });
|
|
140
|
+
}
|
|
96
141
|
continue;
|
|
97
142
|
}
|
|
98
143
|
const tool = group.tools.find((entry) => entry.id === block.toolCallId);
|
|
99
|
-
if (tool) {
|
|
100
|
-
|
|
144
|
+
if (tool && !usedToolIds.has(tool.id)) {
|
|
145
|
+
buffer.push(tool);
|
|
101
146
|
usedToolIds.add(tool.id);
|
|
102
147
|
}
|
|
103
148
|
}
|
|
149
|
+
flushToolBuffer(processItems, buffer);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Insert tools attributed to this assistant stage but without a matching
|
|
153
|
+
* content toolCall block (live SSE tool_call frames often arrive before the
|
|
154
|
+
* assistant content does). They follow the stage's thinking/text instead of
|
|
155
|
+
* sinking to the end of the whole turn.
|
|
156
|
+
*/
|
|
157
|
+
function appendAssistantUnmatchedTools(group, assistant, processItems, usedToolIds) {
|
|
158
|
+
const unmatched = group.tools.filter((tool) => !usedToolIds.has(tool.id) && tool.assistantMessageId === assistant.id);
|
|
159
|
+
if (unmatched.length === 0)
|
|
160
|
+
return;
|
|
161
|
+
for (const tool of unmatched)
|
|
162
|
+
usedToolIds.add(tool.id);
|
|
163
|
+
flushToolBuffer(processItems, unmatched);
|
|
104
164
|
}
|
|
105
165
|
function fillProcessDetails(group) {
|
|
106
166
|
const usedToolIds = new Set();
|
|
@@ -109,14 +169,20 @@ function fillProcessDetails(group) {
|
|
|
109
169
|
const finalAssistant = group.assistants.at(-1);
|
|
110
170
|
for (const assistant of prior) {
|
|
111
171
|
emitProcessBlocks(getDisplayableAssistantBlocks(assistant.content ?? []), group, processItems, usedToolIds);
|
|
172
|
+
appendAssistantUnmatchedTools(group, assistant, processItems, usedToolIds);
|
|
112
173
|
}
|
|
113
174
|
const blocks = finalAssistant?.content ?? [];
|
|
114
175
|
const split = splitFinalAssistantBlocks(blocks, { isStreaming: group.live });
|
|
115
176
|
emitProcessBlocks(split.processBlocks, group, processItems, usedToolIds);
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
pushToolProcessItem(processItems, tool);
|
|
177
|
+
if (finalAssistant) {
|
|
178
|
+
appendAssistantUnmatchedTools(group, finalAssistant, processItems, usedToolIds);
|
|
119
179
|
}
|
|
180
|
+
// Bounded fallback for legacy restored rows with no assistant attribution:
|
|
181
|
+
// keep them at this turn's end in stable server order instead of randomly
|
|
182
|
+
// interleaving them into earlier stages.
|
|
183
|
+
const orphans = group.tools.filter((tool) => !usedToolIds.has(tool.id));
|
|
184
|
+
if (orphans.length > 0)
|
|
185
|
+
flushToolBuffer(processItems, orphans);
|
|
120
186
|
group.processItems = processItems;
|
|
121
187
|
if (!finalAssistant)
|
|
122
188
|
return;
|
|
@@ -149,6 +215,14 @@ export function buildTurnProcessGroups(input) {
|
|
|
149
215
|
current.user = message;
|
|
150
216
|
continue;
|
|
151
217
|
}
|
|
218
|
+
if (message.kind === "compaction") {
|
|
219
|
+
// Compaction is a standalone timeline event. Starting a fresh group
|
|
220
|
+
// prevents it from replacing the previous turn's assistant answer.
|
|
221
|
+
current = startGroup(`compaction-${message.id}`);
|
|
222
|
+
current.assistants.push(message);
|
|
223
|
+
current = null;
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
152
226
|
if (!current)
|
|
153
227
|
current = startGroup(`assistant-${message.id}`);
|
|
154
228
|
current.assistants.push(message);
|
|
@@ -250,3 +324,36 @@ export function processGroupSummary(tools, options) {
|
|
|
250
324
|
parts.push("运行中");
|
|
251
325
|
return { count, errorCount, runningCount, stepCount, label: parts.join(" · ") };
|
|
252
326
|
}
|
|
327
|
+
/** Summary over rendered process items (tool-group tools count individually). */
|
|
328
|
+
export function summarizeProcessItems(items) {
|
|
329
|
+
const tools = [];
|
|
330
|
+
let thinkingCount = 0;
|
|
331
|
+
let textCount = 0;
|
|
332
|
+
let activityCount = 0;
|
|
333
|
+
let activityErrorCount = 0;
|
|
334
|
+
let activityRunningCount = 0;
|
|
335
|
+
for (const item of items) {
|
|
336
|
+
if (item.kind === "thinking")
|
|
337
|
+
thinkingCount += 1;
|
|
338
|
+
else if (item.kind === "text")
|
|
339
|
+
textCount += 1;
|
|
340
|
+
else if (item.kind === "activity") {
|
|
341
|
+
activityCount += 1;
|
|
342
|
+
if (item.activity.kind === "error")
|
|
343
|
+
activityErrorCount += 1;
|
|
344
|
+
else if (item.activity.kind === "progress")
|
|
345
|
+
activityRunningCount += 1;
|
|
346
|
+
}
|
|
347
|
+
else if (item.kind === "tool")
|
|
348
|
+
tools.push(item.tool);
|
|
349
|
+
else
|
|
350
|
+
tools.push(...item.tools);
|
|
351
|
+
}
|
|
352
|
+
return processGroupSummary(tools, {
|
|
353
|
+
thinkingCount,
|
|
354
|
+
textCount,
|
|
355
|
+
activityCount,
|
|
356
|
+
activityErrorCount,
|
|
357
|
+
activityRunningCount,
|
|
358
|
+
});
|
|
359
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { access, readFile } from "node:fs/promises";
|
|
2
2
|
import { buildOperatorCapabilitiesDocument } from "../../shared/operator/capabilities.js";
|
|
3
3
|
import { buildOperatorResult, operatorFailed, operatorSucceeded, } from "../../shared/operator/envelope.js";
|
|
4
|
-
import { getTaskPaths, loadTaskConfig } from "../../task/runtime.js";
|
|
4
|
+
import { CANONICAL_TASK_ID_PATTERN, formatLocalBusinessDate, getTaskPaths, loadTaskConfig, } from "../../task/runtime.js";
|
|
5
5
|
import { diffTaskContract, validateDraftForTask, } from "../../task/contract/index.js";
|
|
6
6
|
import { stageUtf8Text } from "./app-data.js";
|
|
7
7
|
import { ALL_CONFIRMATION_CHALLENGES, hashDagBytes, } from "./dag-confirmation.js";
|
|
@@ -63,6 +63,8 @@ function str(v) {
|
|
|
63
63
|
return typeof v === "string" && v.trim() ? v.trim() : undefined;
|
|
64
64
|
}
|
|
65
65
|
const TASK_ID_PLACEHOLDER_RE = /[<>]|^(?:id|task-?id|your-task-id|todo|tbd)$/i;
|
|
66
|
+
/** Mirror of runtime GENERIC_TASK_SLUGS (not exported there); keep in sync. */
|
|
67
|
+
const GENERIC_SLUG_SET = new Set(["test", "fix", "tmp", "new-task"]);
|
|
66
68
|
const TASK_ADVANCE_ALIAS_ACTIONS = new Set(["promoteRun", "closeoutTask"]);
|
|
67
69
|
function taskIdInputError(taskId) {
|
|
68
70
|
if (!TASK_ID_PLACEHOLDER_RE.test(taskId))
|
|
@@ -1502,6 +1504,21 @@ export async function dispatchOperatorAction(ctx, req) {
|
|
|
1502
1504
|
const taskIdError = taskIdInputError(taskId);
|
|
1503
1505
|
if (taskIdError)
|
|
1504
1506
|
return invalid(action, taskIdError);
|
|
1507
|
+
// Canonical id gate at admission (2026-08-16): non-canonical ids were
|
|
1508
|
+
// accepted here (validateNewTaskId only warns) and every downstream
|
|
1509
|
+
// advance/import then flailed on the malformed task directory. Fail
|
|
1510
|
+
// fast with a concrete suggested id instead.
|
|
1511
|
+
if (!CANONICAL_TASK_ID_PATTERN.test(taskId)) {
|
|
1512
|
+
const slug = taskId
|
|
1513
|
+
.toLowerCase()
|
|
1514
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
1515
|
+
.replace(/^-+|-+$/g, "")
|
|
1516
|
+
.slice(0, 48);
|
|
1517
|
+
const suggested = slug && !GENERIC_SLUG_SET.has(slug)
|
|
1518
|
+
? `${formatLocalBusinessDate()}-${slug}`
|
|
1519
|
+
: `${formatLocalBusinessDate()}-${slug || "task"}-r2`;
|
|
1520
|
+
return invalid(action, `taskId must be canonical YYYY-MM-DD-<kebab-slug> (local business date); got "${taskId}" — suggested id: "${suggested}" (e.g. 2026-08-16-tool-preview-edge-test); retry newTask with that id`);
|
|
1521
|
+
}
|
|
1505
1522
|
return acceptOperation(ctx, {
|
|
1506
1523
|
action,
|
|
1507
1524
|
actionParams: p,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-VvfacNrq.js";import{p as f}from"./chunk-JWPE2WC7-BlysCtod.js";import{_ as n,l as o}from"./mermaid.core-DWGK9kwP.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-B1wtI3hU.js";import"./index-DQxiso1w.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},B={parser:R,db:a,renderer:u,styles:p};export{B as diagram};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-DWGK9kwP.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,z,a){var O=I-l,i=D-h,n=z-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function U(l,h,I,D,v,A,z){var a=l-I,O=h-D,i=(z?A:-A)/J(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,B=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*J(on(0,T*T*R-P*P)),Y=(P*g-m*S)/R,$=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=Y-B,e=$-t,r=w-B,C=p-t;return x*x+e*e>r*r+C*C&&(Y=w,$=p),{cx:Y,cy:$,x01:-n,y01:-d,x11:Y*(v/T-1),y11:$*(v/T-1)}}function hn(){var l=cn,h=yn,I=j(0),D=null,v=gn,A=dn,z=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,B=rn(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(B>tn-y)a.moveTo(s*F(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*F(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=B,S=B,Y=z.apply(this,arguments)/2,$=Y>y&&(D?+D.apply(this,arguments):J(u*u+s*s)),w=_(rn(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if($>y){var C=sn($/u*q(Y)),K=sn($/s*q(Y));(P-=C*2)>y?(C*=t?1:-1,R+=C,T-=C):(P=0,R=T=(f+c)/2),(S-=K*2)>y?(K*=t?1:-1,m+=K,g-=K):(S=0,m=g=(f+c)/2)}var G=s*F(m),H=s*q(m),L=u*F(T),M=u*q(T);if(w>y){var N=s*F(g),Q=s*q(g),V=u*F(R),W=u*q(R),E;if(B<an)if(E=pn(G,H,V,W,N,Q,L,M)){var X=G-E[0],Z=H-E[1],b=N-E[0],k=Q-E[1],nn=1/q(fn((X*b+Z*k)/(J(X*X+Z*Z)*J(b*b+k*k)))/2),en=J(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=U(V,W,G,H,s,x,t),r=U(N,Q,L,M,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(G,H),a.arc(0,0,s,m,g,!t)):a.moveTo(G,H),!(u>y)||!(P>y)?a.lineTo(L,M):p>y?(e=U(L,M,N,Q,u,-p,t),r=U(G,H,V,W,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[F(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:j(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:j(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:j(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:j(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:j(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:j(+n),i):A},i.padAngle=function(n){return arguments.length?(z=typeof n=="function"?n:j(+n),i):z},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|