@tea-agent/loop-agent 0.38.1 → 0.38.2
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 +109 -13
- package/dist/application/dag/generate-task-dag.js +9 -0
- package/dist/build-stamp.json +3 -3
- package/dist/commands/init.js +2 -14
- package/dist/executors/dag-pi-executor.js +41 -4
- package/dist/executors/shell-executor.js +269 -15
- package/dist/governance/manifest-types.js +0 -2
- package/dist/shared/operator/capabilities.js +87 -22
- package/dist/task/config-types.js +22 -0
- package/dist/worker/console/chat/deferred-turn.js +91 -0
- package/dist/worker/console/chat/pi-runtime.js +10 -5
- package/dist/worker/console/chat/routes.js +458 -47
- package/dist/worker/console/chat/semantic-activity.js +13 -13
- package/dist/worker/console/chat/session-store.js +146 -2
- package/dist/worker/console/harness-pi-model-matrix.js +2 -11
- package/dist/worker/console/operator-actions.js +5 -4
- package/dist/worker/console/pi-readiness.js +1 -0
- package/dist/worker/console/recovery-cta.js +4 -4
- package/dist/worker/console/recovery-error-copy.js +4 -4
- package/dist/worker/console/server.js +6 -1
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-Hfsot6rP.js → abnfDiagram-N423BO3Z-C4bmo3iY.js} +1 -1
- package/dist/worker/console/static/assets/{arc-YGwEASin.js → arc-SAD7McOS.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-CmOM0F92.js → architectureDiagram-T3A2C74G-DAVLUdK1.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-DDLuaHC5.js → blockDiagram-VBNYF7ZC-CPPdv4vj.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-B0Um43W4.js → c4Diagram-5PPSVZJV-D1GRGZax.js} +1 -1
- package/dist/worker/console/static/assets/channel-R6oQIDkw.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-DvBN4JZc.js → chunk-2GRJ4B5K-D_Bq2ZqK.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-B1UVgW4E.js → chunk-2Q5K7J3B-CPLVtamK.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-Cf0GgXzX.js → chunk-5RXB4S5H-DnaZWcL3.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-DbNA24sj.js → chunk-5VM5RSS4-BRTmFgnq.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-Bi_0Be06.js → chunk-6Q2QTUOP-BRlfYZoH.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-C8pPGvRd.js → chunk-GF5L2VYU-CjNybD4u.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-BitQY8Z-.js → chunk-JWPE2WC7-D3e-74fG.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-U67GCiEo.js → chunk-KBJHAD2P-Br3ir6f2.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-IoJwXPBA.js → chunk-RYQCIY6F-1NgVuRbh.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-YDZ_UHgE.js → chunk-XXDRQBXY-BTYuvuWN.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BPXlmPWI.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BPXlmPWI.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-CUZgsiRC.js → cose-bilkent-JH36ORCC-BC6Bgosf.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-COmCh4pT.js → cynefin-VYW2F7L2-DV-HypfL.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-Ta6FSm68.js → cynefinDiagram-MW4NZA55-DhTaddO-.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-UdcR-VW9.js → dagre-VZM6K2ZE-BnEcOmiI.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-DybcO3Et.js → diagram-7IWD3JNH-xphGRVKp.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-wErDFWLw.js → diagram-B4RE2ZJO-CrdD1mRG.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-DkVHZWqz.js → diagram-LBJQPF4R-D4YdLsaF.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-DdqWs7QN.js → diagram-Q27KOJAE-LCKyGZ5U.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-C9dMVmDo.js → diagram-UB23O5K3-BeiTe7t0.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-B2T2WcBK.js → ebnfDiagram-BXEA7PRR-BO2cq8GS.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-Bt9rjDFq.js → erDiagram-JOGREHBK-CmWww3Nt.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-U8ic_tvi.js → flowDiagram-UKHOOZJN-C2kkUYg5.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-BfQJdQoO.js → ganttDiagram-PKOTCBZU-DY_JZ2iQ.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-CpMftH4O.js → gitGraphDiagram-DS77QQ5N-BizhCSw9.js} +1 -1
- package/dist/worker/console/static/assets/index-BXN89VPX.js +325 -0
- package/dist/worker/console/static/assets/index-CuH5CNFu.css +1 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-DzqWXNO_.js → infoDiagram-6WML65LV-Dlo2eK_d.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-CJmGQ5Yp.js → ishikawaDiagram-WSZJBQD7-3EIlIIuZ.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-ChPtKFLz.js → journeyDiagram-NVQOT4AX-DiMDe5Yh.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-PRe7wB5u.js → kanban-definition-27J2QSJJ-sN553oIN.js} +1 -1
- package/dist/worker/console/static/assets/{linear-DpKX6QNp.js → linear-D9Py31Ld.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-Dnl76b7Y.js → mermaid.core-D7Occzk_.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-S9PCXc3J.js → mindmap-definition-FAOFIHXS-DjDRboiR.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-Du8e-FSX.js → pegDiagram-VL7TDLO6-Cgc4qlzp.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-CY6OmHTc.js → pieDiagram-7S7Q4E2Y-DxZj8pKd.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-C65GPhpj.js → quadrantDiagram-CIZ2JOQS-CJ50MngR.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-U6IUiTCL.js → railroadDiagram-AXF67PYL-BY-OD8Tr.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-D-I_9Qhi.js → requirementDiagram-LRYGKXZP-CQFButfK.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-B57Fhed0.js → sankeyDiagram-W5VNT64P-BB_QUK_b.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-CJOtiw21.js → sequenceDiagram-SI44F4Z6-CqhXZjyx.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-FyX8zxSh.js → sizeCapture-X5ZJPWSS-2l1U4rgJ.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-eF-pbs9t.js → stateDiagram-OKZ733FA-BX1FbrhJ.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DJKi0Qel.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-CcfkA-Dq.js → swimlanes-SLNWSIFB-DOSnT7hb.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-YYe7EEm5.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-DH8FjnOK.js → timeline-definition-Z64GVDOM-DVJQA7AN.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-beoTagJg.js → vennDiagram-T6HMQDX7-74uxl9gx.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-CQSfw4cK.js → wardleyDiagram-T6FBY63Y-DsBxlcg_.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-CQgzQ6jn.js → xychartDiagram-ELKLHX3M-snuW9Mjw.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/app/console-types.js +0 -12
- package/dist/worker/console/static-src/app/useOperatorActions.js +1 -1
- package/dist/worker/console/static-src/app/useRecoveryActions.js +2 -2
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +38 -1
- package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +8 -1
- package/dist/worker/console/static-src/operator-chat/turn-submission.js +42 -0
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +3 -0
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +204 -11
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +23 -1
- package/dist/workflows/dag/backend-test-case-coverage-analysis.js +755 -51
- package/dist/workflows/dag/backend-test-case-manifest.js +4 -0
- package/dist/workflows/dag/backend-test-execution-contract.js +18 -9
- package/dist/workflows/dag/backend-test-gap-fill.js +205 -0
- package/dist/workflows/dag/backend-test-intake-context.js +32 -0
- package/dist/workflows/dag/backend-test-layout.js +133 -0
- package/dist/workflows/dag/backend-test-markdown-workflow.js +167 -32
- package/dist/workflows/dag/backend-test-module-stem.js +5 -0
- package/dist/workflows/dag/backend-test-pytest-collection.js +368 -33
- package/dist/workflows/dag/backend-test-result-contract.js +1 -1
- package/dist/workflows/dag/backend-test-scenario-param.js +884 -140
- package/dist/workflows/dag/backend-test-scenario-partitions.js +249 -0
- package/dist/workflows/dag/backend-test-writer-completeness.js +100 -56
- package/dist/workflows/dag/contract-validator-registrations.js +2 -1
- package/dist/workflows/dag/convergence/controller.js +141 -0
- package/dist/workflows/dag/dynamic-runtime/map.js +24 -8
- package/dist/workflows/dag/dynamic-runtime/shared.js +1 -1
- package/dist/workflows/dag/frontend-implementation-contract.js +236 -8
- package/dist/workflows/dag/frontend-prewrite-gate.js +95 -35
- package/dist/workflows/dag/init-hybrid.js +652 -87
- package/dist/workflows/dag/node-execution.js +45 -18
- package/dist/workflows/dag/prompt.js +45 -0
- package/dist/workflows/dag/rerun-feedback.js +212 -0
- package/dist/workflows/dag/rerun-plan.js +93 -27
- package/dist/workflows/dag/rerun-run.js +3 -0
- package/dist/workflows/dag/rerun-task.js +61 -2
- package/dist/workflows/dag/retry-policy.js +18 -0
- package/dist/workflows/dag/types.js +98 -0
- package/docs/templates/backend-test-dag.json +60 -35
- package/docs/templates/harness.schema.json +0 -8
- package/harness.json +1 -8
- package/package.json +1 -1
- package/skills/frontend-implementation/references/node-contracts.md +2 -2
- package/dist/worker/console/static/assets/channel-Dp_2Aqf1.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL--CODy37j.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE--CODy37j.js +0 -1
- package/dist/worker/console/static/assets/index-BA5-N5ER.css +0 -1
- package/dist/worker/console/static/assets/index-DKPXBrdc.js +0 -325
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-B-mvnLEc.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-JtpBmIv4.js +0 -8
|
@@ -13,13 +13,45 @@ const CONTROLLER_PROTOCOL_CAPABILITIES = [
|
|
|
13
13
|
"worker-attempt-revision-v1",
|
|
14
14
|
"recovery-decision-v2",
|
|
15
15
|
];
|
|
16
|
-
function officialModelCallable(coverage,
|
|
16
|
+
function officialModelCallable(coverage, _kind) {
|
|
17
17
|
if (coverage === "human-gated-required")
|
|
18
18
|
return "prepare-only";
|
|
19
|
-
|
|
19
|
+
// 2026-08-18: advanced actions (read or mutation) stay OUT of the model
|
|
20
|
+
// tool surface — low-frequency/forensic commands with generic args[] params
|
|
21
|
+
// diluted model attention. They remain dispatchable via UI capabilities.
|
|
22
|
+
if (coverage === "advanced")
|
|
20
23
|
return "never";
|
|
21
24
|
return "always";
|
|
22
25
|
}
|
|
26
|
+
const OFFICIAL_ACTION_DESCRIPTIONS = {
|
|
27
|
+
dagDecisionInspect: "Inspect a pending DAG decision envelope (inputs, options, chosen branch). Use before advising the operator on approve/reject; read-only.",
|
|
28
|
+
dagDecisionValidate: "Validate a DAG decision envelope against its schema. Use when a decision payload looks malformed or a writer emitted a suspect envelope; read-only.",
|
|
29
|
+
dagCloseoutDraft: "Draft the closeout handoff document for a finished DAG run. Use when the run is FINISHED and you need the handoff text; read-only.",
|
|
30
|
+
planList: "List execution plans in the repository. Use to discover plan ids before plan create/complete/check.",
|
|
31
|
+
planCreate: "Create an execution plan from a summary. Use to record the next work block before starting it.",
|
|
32
|
+
planComplete: "Mark an execution plan complete with a summary of what was delivered. Use after a work block is done and verified.",
|
|
33
|
+
planCheck: "Check execution-plan health and drift. Use to audit plan state without mutating anything.",
|
|
34
|
+
docsAudit: "Audit docs freshness and links (document catalog policy). Use when asked whether docs are stale or need review.",
|
|
35
|
+
handoffCheck: "Check handoff document completeness against the verification matrix. Use before claiming a task is fully handed off.",
|
|
36
|
+
handoffCoverage: "Show verification coverage across tests/docs/links for the repo. Use when asked what is verified and what is not.",
|
|
37
|
+
coverageReport: "Produce the verification coverage report. Use for a structured view of tests vs requirements.",
|
|
38
|
+
stats: "Repository workflow statistics (tasks, runs, durations). Use for quantitative status questions.",
|
|
39
|
+
promoteRun: "Task advance alias; passes a task id and flags through to task advance to promote a run. Does not pre-verify run state here — confirm with dagReport that the run is FINISHED before calling.",
|
|
40
|
+
closeoutTask: "Task advance alias; passes a task id and flags through to task advance to close out a task. Confirm the task's work is delivered and verified before calling.",
|
|
41
|
+
knowledgeCurate: "Generate knowledge-base curation proposals (may write a proposal file when --output is passed). Write-capable; use via the operator CLI, not as a model tool.",
|
|
42
|
+
knowledgeQuery: "Query the repository knowledge base. Use instead of re-reading files when a curated answer may exist.",
|
|
43
|
+
workerFeatureReview: "Review worker feature status and checkpoints (agent-worker). Use to see where a feature line stands.",
|
|
44
|
+
workerFeatureDoctor: "Diagnose worker feature health (agent-worker). Use when a feature line looks stuck or inconsistent.",
|
|
45
|
+
workerTaskValidate: "Validate a worker task spec (agent-worker). Use before queuing or when a task looks malformed.",
|
|
46
|
+
workerBatchPlanReady: "Show which batch tasks are ready to run (agent-worker). Use for queue triage before workerBatchRunReady.",
|
|
47
|
+
workerReportMorning: "Morning report for overnight worker activity (agent-worker). Use at the start of a session to catch overnight failures.",
|
|
48
|
+
workerReportMetrics: "Worker throughput and failure metrics (agent-worker). Use for quantitative worker questions.",
|
|
49
|
+
workerAdmissionShow: "Show night admission queue state (agent-worker). Use before night-scheduler mutations.",
|
|
50
|
+
workerSchedulerList: "List night-scheduler schedules (agent-worker). Use to discover schedule ids.",
|
|
51
|
+
workerSchedulerStatus: "Night-scheduler status overview (agent-worker). Use to check whether overnight jobs are healthy.",
|
|
52
|
+
workerSchedulerLedger: "Night-scheduler harvest ledger (agent-worker). Use to audit what overnight runs produced.",
|
|
53
|
+
workerSchedulerDoctor: "Diagnose night-scheduler health (agent-worker). Use when overnight jobs fail to fire or harvest.",
|
|
54
|
+
};
|
|
23
55
|
const officialAction = (action, cli, kind, coverage) => ({
|
|
24
56
|
action,
|
|
25
57
|
cli,
|
|
@@ -38,7 +70,8 @@ const officialAction = (action, cli, kind, coverage) => ({
|
|
|
38
70
|
"TRANSACTION_INCOMPLETE",
|
|
39
71
|
"NOT_FOUND",
|
|
40
72
|
],
|
|
41
|
-
description:
|
|
73
|
+
description: OFFICIAL_ACTION_DESCRIPTIONS[action] ??
|
|
74
|
+
`Official CLI action coverage for ${cli}.`,
|
|
42
75
|
inputParams: [
|
|
43
76
|
{
|
|
44
77
|
name: "args",
|
|
@@ -158,8 +191,8 @@ const OFFICIAL_ACTIONS = [
|
|
|
158
191
|
[
|
|
159
192
|
"knowledgeCurate",
|
|
160
193
|
"loop-agent knowledge curate",
|
|
161
|
-
"
|
|
162
|
-
"
|
|
194
|
+
"mutation",
|
|
195
|
+
"advanced",
|
|
163
196
|
],
|
|
164
197
|
["knowledgeQuery", "loop-agent knowledge query", "read", "model-callable"],
|
|
165
198
|
[
|
|
@@ -334,6 +367,12 @@ const OFFICIAL_ACTIONS = [
|
|
|
334
367
|
],
|
|
335
368
|
],
|
|
336
369
|
].map(([action, cli, kind, coverage]) => officialAction(action, cli, kind, coverage));
|
|
370
|
+
/**
|
|
371
|
+
* Action ids produced by the officialAction() factory (the generic CLI
|
|
372
|
+
* coverage tail). Derived from the same tuple table so dispatcher / gate
|
|
373
|
+
* checks do not string-match descriptions.
|
|
374
|
+
*/
|
|
375
|
+
export const OFFICIAL_TAIL_ACTION_IDS = new Set(OFFICIAL_ACTIONS.map((entry) => entry.action));
|
|
337
376
|
/** Shared constants so dag + dagSpecVersions cannot diverge. */
|
|
338
377
|
const DAG_SPEC_SUPPORTED_PARSE = [1, 2, 3, 4];
|
|
339
378
|
const DAG_SPEC_NEW_WRITER_DEFAULT = 4;
|
|
@@ -609,7 +648,7 @@ export function buildOperatorCapabilitiesDocument() {
|
|
|
609
648
|
resultSchemaVersion: 1,
|
|
610
649
|
envelopeSchemaVersion: 1,
|
|
611
650
|
requiredErrorCodes: [...COMMON_MUTATION_ERRORS],
|
|
612
|
-
description: "Create
|
|
651
|
+
description: "Create a new task (lifecycle entry). Prefer taskAdvance for the standard flow (PRD import, taskKind, boundaries, DAG generation); newTask only bootstraps a task id + title.",
|
|
613
652
|
inputParams: [
|
|
614
653
|
{
|
|
615
654
|
name: "taskId",
|
|
@@ -685,7 +724,7 @@ export function buildOperatorCapabilitiesDocument() {
|
|
|
685
724
|
resultSchemaVersion: 1,
|
|
686
725
|
envelopeSchemaVersion: 1,
|
|
687
726
|
requiredErrorCodes: ["NOT_FOUND", "INVALID_INPUT"],
|
|
688
|
-
description: "Read source instruction contract
|
|
727
|
+
description: "Read the task's source instruction contract (需求.md/执行约束.md projection: requirements, constraints, allowed/forbidden paths). Use before drafting or revising a contract to stay aligned with the source.",
|
|
689
728
|
inputParams: [
|
|
690
729
|
{
|
|
691
730
|
name: "taskId",
|
|
@@ -835,8 +874,33 @@ export function buildOperatorCapabilitiesDocument() {
|
|
|
835
874
|
resultSchemaVersion: 1,
|
|
836
875
|
envelopeSchemaVersion: 1,
|
|
837
876
|
requiredErrorCodes: ["INVALID_INPUT"],
|
|
838
|
-
description: "Build Observe deep link from stable object identity.",
|
|
839
|
-
inputParams: [
|
|
877
|
+
description: "Build Observe deep link from stable object identity. Pass exactly one of dagRunId (preferred), taskId (resolves to latest run), featureId, or workerRunId; omit all for the Console home link.",
|
|
878
|
+
inputParams: [
|
|
879
|
+
{
|
|
880
|
+
name: "dagRunId",
|
|
881
|
+
type: "string",
|
|
882
|
+
required: false,
|
|
883
|
+
description: "dag run id; deep-links to #/dag/<runId> (preferred when known)",
|
|
884
|
+
},
|
|
885
|
+
{
|
|
886
|
+
name: "taskId",
|
|
887
|
+
type: "string",
|
|
888
|
+
required: false,
|
|
889
|
+
description: "task id; resolves to the latest dag run when one exists, else #/task/<taskId>",
|
|
890
|
+
},
|
|
891
|
+
{
|
|
892
|
+
name: "featureId",
|
|
893
|
+
type: "string",
|
|
894
|
+
required: false,
|
|
895
|
+
description: "feature line id; deep-links to the feature view",
|
|
896
|
+
},
|
|
897
|
+
{
|
|
898
|
+
name: "workerRunId",
|
|
899
|
+
type: "string",
|
|
900
|
+
required: false,
|
|
901
|
+
description: "worker run id; deep-links to the worker run view",
|
|
902
|
+
},
|
|
903
|
+
],
|
|
840
904
|
modelCallable: "always",
|
|
841
905
|
humanConfirmation: "none",
|
|
842
906
|
},
|
|
@@ -848,7 +912,7 @@ export function buildOperatorCapabilitiesDocument() {
|
|
|
848
912
|
resultSchemaVersion: 1,
|
|
849
913
|
envelopeSchemaVersion: 1,
|
|
850
914
|
requiredErrorCodes: ["INVALID_INPUT"],
|
|
851
|
-
description: "
|
|
915
|
+
description: "Preflight a repository for loop-agent: checks harness presence, task-pool layout, and reports what the Console can operate on. Use at session start on an unfamiliar repo, before init/upgrade decisions.",
|
|
852
916
|
inputParams: [],
|
|
853
917
|
modelCallable: "always",
|
|
854
918
|
humanConfirmation: "none",
|
|
@@ -907,7 +971,7 @@ export function buildOperatorCapabilitiesDocument() {
|
|
|
907
971
|
resultSchemaVersion: 1,
|
|
908
972
|
envelopeSchemaVersion: 1,
|
|
909
973
|
requiredErrorCodes: ["NOT_FOUND", "INVALID_INPUT"],
|
|
910
|
-
description: "
|
|
974
|
+
description: "Read one task's lifecycle status: state, blockers, gates, contract revision, run associations. Use for task-level questions; use dagStatus for a specific DAG run's live node/liveness.",
|
|
911
975
|
inputParams: [
|
|
912
976
|
{
|
|
913
977
|
name: "taskId",
|
|
@@ -927,7 +991,7 @@ export function buildOperatorCapabilitiesDocument() {
|
|
|
927
991
|
resultSchemaVersion: 1,
|
|
928
992
|
envelopeSchemaVersion: 1,
|
|
929
993
|
requiredErrorCodes: ["NOT_FOUND", "INVALID_INPUT"],
|
|
930
|
-
description: "
|
|
994
|
+
description: "Audit a task's minimal spec spine: source docs, path ownership, requirement ids, final verification coverage. Use before closing out a task to confirm every AC is verified.",
|
|
931
995
|
inputParams: [
|
|
932
996
|
{
|
|
933
997
|
name: "taskId",
|
|
@@ -1020,7 +1084,7 @@ export function buildOperatorCapabilitiesDocument() {
|
|
|
1020
1084
|
"EXTERNALLY_MODIFIED",
|
|
1021
1085
|
"INVALID_INPUT",
|
|
1022
1086
|
],
|
|
1023
|
-
description: "Generate + strict-validate DAG via task advance
|
|
1087
|
+
description: "Generate + strict-validate a task's DAG (via task advance, stops at the writeSet gate). Legacy entry; the standard flow is taskAdvance then prepareDagExecution + runDag.",
|
|
1024
1088
|
inputParams: [
|
|
1025
1089
|
{
|
|
1026
1090
|
name: "taskId",
|
|
@@ -1099,7 +1163,7 @@ export function buildOperatorCapabilitiesDocument() {
|
|
|
1099
1163
|
resultSchemaVersion: 1,
|
|
1100
1164
|
envelopeSchemaVersion: 1,
|
|
1101
1165
|
requiredErrorCodes: ["INVALID_INPUT", "NOT_FOUND"],
|
|
1102
|
-
description: "Read-only check
|
|
1166
|
+
description: "Read-only check for failed-node recovery; it does not execute. Call after dagReport with primaryFailure.nodeId. eligible=true returns the exact planHash required by dagRerun. eligible=false covers writer/decision/fingerprint, unsafe shell, Worker ownership, or workspace/controller drift: use workerTaskRetry for Worker/Task Pool failures, or standaloneTaskRerun after any required contract adopt for standalone runs. Do not force dagRerun or invent a new task.",
|
|
1103
1167
|
inputParams: [
|
|
1104
1168
|
{
|
|
1105
1169
|
name: "runId",
|
|
@@ -1129,7 +1193,7 @@ export function buildOperatorCapabilitiesDocument() {
|
|
|
1129
1193
|
"BINDING_DRIFT",
|
|
1130
1194
|
"INVALID_INPUT",
|
|
1131
1195
|
],
|
|
1132
|
-
description: "Continue the same DAG from
|
|
1196
|
+
description: "Continue the same DAG from the effective failed node by creating a continuation run. Requires a fresh eligible dagRerunPlan and its exact planHash. Prefer this for provider, network, rate-limit, timeout, and other safe downstream failures. Not a full task regenerate: use standaloneTaskRerun for that. Server rejects stale planHash, binding, or fingerprint drift.",
|
|
1133
1197
|
inputParams: [
|
|
1134
1198
|
{
|
|
1135
1199
|
name: "runId",
|
|
@@ -1495,7 +1559,7 @@ export function buildOperatorCapabilitiesDocument() {
|
|
|
1495
1559
|
"INVALID_INPUT",
|
|
1496
1560
|
"HUMAN_CONFIRMATION_REQUIRED",
|
|
1497
1561
|
],
|
|
1498
|
-
description: "Regenerate the whole standalone DAG from the CURRENT contract, then validate and execute a new run
|
|
1562
|
+
description: "Regenerate the whole standalone DAG from the CURRENT contract, then validate and execute a new run with parent lineage and the latest unresolved verify/review feedback when available. This is NOT continue-from-failed-node (use dagRerun for that). Server rejects the call when dagRerunPlan is eligible, primaryRecovery.humanRequired=true, or run facts do not recommend rerun-task. Feedback is recovery context, not a contract rewrite; adopt required contract changes before calling or the new DAG repeats the same failure.",
|
|
1499
1563
|
inputParams: [
|
|
1500
1564
|
{
|
|
1501
1565
|
name: "runId",
|
|
@@ -2004,12 +2068,12 @@ export const OPERATOR_COMMAND_COVERAGE = Object.freeze([
|
|
|
2004
2068
|
},
|
|
2005
2069
|
{
|
|
2006
2070
|
command: "loop-agent knowledge curate",
|
|
2007
|
-
coverage: "
|
|
2071
|
+
coverage: "advanced",
|
|
2008
2072
|
action: "knowledgeCurate",
|
|
2009
2073
|
source: "loop-agent",
|
|
2074
|
+
note: "Writes knowledge proposals (conditional on --output); not model-callable.",
|
|
2010
2075
|
},
|
|
2011
|
-
{
|
|
2012
|
-
command: "loop-agent knowledge query",
|
|
2076
|
+
{ command: "loop-agent knowledge query",
|
|
2013
2077
|
coverage: "model-callable",
|
|
2014
2078
|
action: "knowledgeQuery",
|
|
2015
2079
|
source: "loop-agent",
|
|
@@ -2584,9 +2648,10 @@ export function assertCoverageManifestConsistent() {
|
|
|
2584
2648
|
capability.humanConfirmation !== "required"))
|
|
2585
2649
|
throw new Error(`invalid required gate classification: ${entry.action}`);
|
|
2586
2650
|
if (entry.coverage === "advanced") {
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2651
|
+
// 2026-08-18: advanced actions are never model-callable (read or
|
|
2652
|
+
// mutation) — see officialModelCallable. UI dispatch stays available.
|
|
2653
|
+
if (capability.modelCallable !== "never") {
|
|
2654
|
+
throw new Error(`invalid advanced classification: ${entry.action} (expected modelCallable=never)`);
|
|
2590
2655
|
}
|
|
2591
2656
|
}
|
|
2592
2657
|
}
|
|
@@ -124,6 +124,26 @@ export const frontendTestConfigSchema = z.object({
|
|
|
124
124
|
.strict()
|
|
125
125
|
.optional(),
|
|
126
126
|
});
|
|
127
|
+
/** Backend-test artifact layout and pipeline mode configuration (plan A/B/D). */
|
|
128
|
+
export const backendTestConfigSchema = z
|
|
129
|
+
.object({
|
|
130
|
+
/** Repository-relative test root. Default "testcase". */
|
|
131
|
+
testRoot: z.string().min(1).optional(),
|
|
132
|
+
/** Markdown subdirectory relative to testRoot. Default "md". */
|
|
133
|
+
markdownRel: z.string().min(1).optional(),
|
|
134
|
+
/** Pytest script subdirectory relative to testRoot. Default "." (testRoot itself). */
|
|
135
|
+
scriptRel: z.string().min(1).optional(),
|
|
136
|
+
/** User-provided shared setup document (plan B). Read-only bound source. */
|
|
137
|
+
sharedSetupDoc: z.string().min(1).optional(),
|
|
138
|
+
/** Pipeline mode: full 16-node chain (default) or gap-fill incremental DAG (plan D). */
|
|
139
|
+
mode: z.enum(["full", "gap-fill"]).optional(),
|
|
140
|
+
/** Required for mode=gap-fill: user missing-scenario document path. */
|
|
141
|
+
gapDoc: z.string().min(1).optional(),
|
|
142
|
+
/** gap-fill pytest execution scope: only affected items (default) or all eligible. */
|
|
143
|
+
executeScope: z.enum(["affected", "all"]).optional(),
|
|
144
|
+
})
|
|
145
|
+
.strict()
|
|
146
|
+
.optional();
|
|
127
147
|
export const convergenceConfigSchema = z.object({
|
|
128
148
|
enabled: z.boolean().optional().default(false),
|
|
129
149
|
maxPasses: z.number().int().positive().optional().default(3),
|
|
@@ -196,6 +216,8 @@ const taskConfigObjectSchema = z.object({
|
|
|
196
216
|
frontendTest: frontendTestConfigSchema.optional(),
|
|
197
217
|
/** Frontend OpenSpec gate policy and contract-declared required read paths. */
|
|
198
218
|
frontendOpenspec: frontendOpenspecConfigSchema.optional(),
|
|
219
|
+
/** Backend-test layout / shared-setup / gap-fill configuration. */
|
|
220
|
+
backendTest: backendTestConfigSchema,
|
|
199
221
|
notes: z.string().optional().default(""),
|
|
200
222
|
});
|
|
201
223
|
export const taskConfigSchema = z.preprocess((raw) => {
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
const IMAGE_MIME_TYPES = new Set([
|
|
3
|
+
"image/png",
|
|
4
|
+
"image/jpeg",
|
|
5
|
+
"image/gif",
|
|
6
|
+
"image/webp",
|
|
7
|
+
]);
|
|
8
|
+
export function hashDeferredTurnPayload(input) {
|
|
9
|
+
return createHash("sha256")
|
|
10
|
+
.update(JSON.stringify({
|
|
11
|
+
text: input.text,
|
|
12
|
+
images: input.images.map(({ type, mimeType, data }) => ({
|
|
13
|
+
type,
|
|
14
|
+
mimeType,
|
|
15
|
+
data,
|
|
16
|
+
})),
|
|
17
|
+
}))
|
|
18
|
+
.digest("hex");
|
|
19
|
+
}
|
|
20
|
+
export function parseDeferredTurn(value) {
|
|
21
|
+
if (!value || typeof value !== "object")
|
|
22
|
+
return undefined;
|
|
23
|
+
const item = value;
|
|
24
|
+
if (item.schemaVersion !== 1 ||
|
|
25
|
+
!Number.isSafeInteger(item.revision) ||
|
|
26
|
+
(item.revision ?? 0) < 1 ||
|
|
27
|
+
typeof item.clientRequestId !== "string" ||
|
|
28
|
+
!item.clientRequestId.trim() ||
|
|
29
|
+
typeof item.payloadHash !== "string" ||
|
|
30
|
+
!/^[a-f0-9]{64}$/.test(item.payloadHash) ||
|
|
31
|
+
typeof item.blockedByTurnId !== "string" ||
|
|
32
|
+
!item.blockedByTurnId.trim() ||
|
|
33
|
+
typeof item.text !== "string" ||
|
|
34
|
+
!Array.isArray(item.images) ||
|
|
35
|
+
!["queued", "dispatching", "accepted", "failed"].includes(item.state) ||
|
|
36
|
+
typeof item.createdAt !== "string" ||
|
|
37
|
+
typeof item.updatedAt !== "string") {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
const images = [];
|
|
41
|
+
for (const image of item.images) {
|
|
42
|
+
if (!image || typeof image !== "object")
|
|
43
|
+
return undefined;
|
|
44
|
+
const candidate = image;
|
|
45
|
+
if (typeof candidate.name !== "string" ||
|
|
46
|
+
candidate.type !== "image" ||
|
|
47
|
+
typeof candidate.mimeType !== "string" ||
|
|
48
|
+
!IMAGE_MIME_TYPES.has(candidate.mimeType) ||
|
|
49
|
+
typeof candidate.data !== "string") {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
images.push(candidate);
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
schemaVersion: 1,
|
|
56
|
+
revision: item.revision,
|
|
57
|
+
clientRequestId: item.clientRequestId.trim(),
|
|
58
|
+
payloadHash: item.payloadHash,
|
|
59
|
+
blockedByTurnId: item.blockedByTurnId.trim(),
|
|
60
|
+
text: item.text,
|
|
61
|
+
images,
|
|
62
|
+
state: item.state,
|
|
63
|
+
createdAt: item.createdAt,
|
|
64
|
+
updatedAt: item.updatedAt,
|
|
65
|
+
...(typeof item.acceptedTurnId === "string" && item.acceptedTurnId
|
|
66
|
+
? { acceptedTurnId: item.acceptedTurnId }
|
|
67
|
+
: {}),
|
|
68
|
+
...(item.lastError &&
|
|
69
|
+
typeof item.lastError.code === "string" &&
|
|
70
|
+
typeof item.lastError.message === "string"
|
|
71
|
+
? { lastError: { code: item.lastError.code, message: item.lastError.message } }
|
|
72
|
+
: {}),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export function projectDeferredTurnSummary(deferredTurn) {
|
|
76
|
+
if (!deferredTurn)
|
|
77
|
+
return null;
|
|
78
|
+
return {
|
|
79
|
+
revision: deferredTurn.revision,
|
|
80
|
+
clientRequestId: deferredTurn.clientRequestId,
|
|
81
|
+
blockedByTurnId: deferredTurn.blockedByTurnId,
|
|
82
|
+
state: deferredTurn.state,
|
|
83
|
+
updatedAt: deferredTurn.updatedAt,
|
|
84
|
+
textPreview: deferredTurn.text.replace(/\s+/g, " ").trim().slice(0, 120),
|
|
85
|
+
imageCount: deferredTurn.images.length,
|
|
86
|
+
...(deferredTurn.acceptedTurnId
|
|
87
|
+
? { acceptedTurnId: deferredTurn.acceptedTurnId }
|
|
88
|
+
: {}),
|
|
89
|
+
...(deferredTurn.lastError ? { lastError: deferredTurn.lastError } : {}),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
@@ -228,19 +228,24 @@ async function buildCustomOperatorTools(options) {
|
|
|
228
228
|
// TypeBox schema is built dynamically; cast through unknown to the builder
|
|
229
229
|
// since Static<TParams> is structural and cannot be statically inferred here.
|
|
230
230
|
const parameters = Type.Object(schema.inputParams.reduce((acc, param) => {
|
|
231
|
+
// Carry the registry's param description into the tool schema so
|
|
232
|
+
// the model sees parameter semantics, not just names/types.
|
|
233
|
+
const desc = param.description?.trim()
|
|
234
|
+
? { description: param.description }
|
|
235
|
+
: {};
|
|
231
236
|
let t;
|
|
232
237
|
switch (param.type) {
|
|
233
238
|
case "string":
|
|
234
|
-
t = Type.String();
|
|
239
|
+
t = Type.String(desc);
|
|
235
240
|
break;
|
|
236
241
|
case "boolean":
|
|
237
|
-
t = Type.Boolean();
|
|
242
|
+
t = Type.Boolean(desc);
|
|
238
243
|
break;
|
|
239
244
|
case "number":
|
|
240
|
-
t = Type.Number();
|
|
245
|
+
t = Type.Number(desc);
|
|
241
246
|
break;
|
|
242
247
|
case "array":
|
|
243
|
-
t = Type.Array(Type.String());
|
|
248
|
+
t = Type.Array(Type.String({}), Object.keys(desc).length ? desc : {});
|
|
244
249
|
break;
|
|
245
250
|
default:
|
|
246
251
|
t = Type.Object({}, { additionalProperties: true });
|
|
@@ -252,7 +257,7 @@ async function buildCustomOperatorTools(options) {
|
|
|
252
257
|
name: schema.toolId,
|
|
253
258
|
label: schema.toolId,
|
|
254
259
|
description: `${schema.description} (kind=${schema.kind}; cli: ${schema.cli})`,
|
|
255
|
-
promptSnippet:
|
|
260
|
+
promptSnippet: schema.description,
|
|
256
261
|
parameters: parameters,
|
|
257
262
|
async execute(toolCallId, params) {
|
|
258
263
|
const decision = authorizeOperatorChatTool(schema.toolId);
|