@tea-agent/loop-agent 0.38.3 → 0.38.4
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/AGENTS.md +4 -1
- package/CHANGELOG.md +153 -96
- package/README.md +9 -5
- package/dist/build-stamp.json +3 -3
- package/dist/cli/command-definitions.js +16 -5
- package/dist/cli/program.js +16 -2
- package/dist/cli/update/notifier.js +2 -2
- package/dist/cli.js +2 -1
- package/dist/commands/dag-rerun.js +55 -1
- package/dist/commands/init-model-catalog.js +464 -0
- package/dist/commands/init-upgrade.js +265 -97
- package/dist/commands/init.js +428 -27
- package/dist/commands/inspect-next.js +8 -0
- package/dist/executors/dag-pi-executor.js +18 -9
- package/dist/executors/pi-playwright-cli-tool.js +51 -12
- package/dist/executors/shell-executor.js +209 -13
- package/dist/shared/dag-prompt-override.js +28 -0
- package/dist/shared/operator/capabilities.js +32 -0
- package/dist/shared/playwright-cli-command-policy.js +15 -0
- package/dist/shared/update/console-notifier.js +100 -0
- package/dist/{cli → shared}/update/npm-client.js +41 -8
- package/dist/{cli → shared}/update/state.js +41 -13
- package/dist/task/source-prepare/parse-intent.js +24 -4
- package/dist/worker/cli.js +31 -1
- package/dist/worker/console/chat/routes.js +1 -0
- package/dist/worker/console/dag-execution-receipt.js +33 -0
- package/dist/worker/console/operator-actions.js +116 -0
- package/dist/worker/console/operator-user-error.js +2 -2
- package/dist/worker/console/routes.js +43 -2
- package/dist/worker/console/security.js +63 -9
- package/dist/worker/console/server.js +36 -5
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-C4kVYweA.js → abnfDiagram-N423BO3Z-gauhD9kD.js} +1 -1
- package/dist/worker/console/static/assets/{arc-Bj2M8iO5.js → arc-pm3c2Rsl.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-CLlXe4-6.js → architectureDiagram-T3A2C74G-D_JAg3wH.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-psEp5xH0.js → blockDiagram-VBNYF7ZC-Dk7-ex52.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-DeKcOCGJ.js → c4Diagram-5PPSVZJV-Uval9oRI.js} +1 -1
- package/dist/worker/console/static/assets/channel-CVrnUdZl.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-K0C744p1.js → chunk-2GRJ4B5K-BSYjHs-v.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-xbNw4J9-.js → chunk-2Q5K7J3B-KGUuBXI8.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-DjLaSDUO.js → chunk-5RXB4S5H-JqAtxD9N.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-CtiPlKel.js → chunk-5VM5RSS4-D6EJOVQK.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-DZtolir7.js → chunk-6Q2QTUOP-B1JriSjm.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-CPcdNeew.js → chunk-GF5L2VYU-D62b96Jd.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-NgHc6V37.js → chunk-JWPE2WC7-BsNKEC_r.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-DQ_T-hg8.js → chunk-KBJHAD2P-B56v6-ZP.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-DgLsxcVP.js → chunk-RYQCIY6F-D2KPnd8K.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-UrVoM9z1.js → chunk-XXDRQBXY-kzKSCaaL.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-aX91WTya.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-aX91WTya.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-CLkYvTb3.js → cose-bilkent-JH36ORCC-C6N6KNJd.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BwT_xKrE.js → cynefin-VYW2F7L2-DiyymT2D.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-Bi9tuzif.js → cynefinDiagram-MW4NZA55-BeKAXvf3.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-BCIqkWBV.js → dagre-VZM6K2ZE-TkIdXfPF.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-Dip6l9_Z.js → diagram-7IWD3JNH-BFmSG3ks.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-B-xkh_wK.js → diagram-B4RE2ZJO-DqpJT2Fs.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-DZO0kTt_.js → diagram-LBJQPF4R-r5ATN43t.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-D6ZplNbZ.js → diagram-Q27KOJAE-DEcSCMuR.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-BPekbhoS.js → diagram-UB23O5K3-VOvYRLVc.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-BtmaJpK5.js → ebnfDiagram-BXEA7PRR-D7f4Cb1u.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-6DS0Xc44.js → erDiagram-JOGREHBK-ziUf3U0G.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-CihnROSm.js → flowDiagram-UKHOOZJN-BoRdQ-1y.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-CZC4zOE2.js → ganttDiagram-PKOTCBZU-B1-GncNm.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Dq1fhzGN.js → gitGraphDiagram-DS77QQ5N-CTW-ph8W.js} +1 -1
- package/dist/worker/console/static/assets/{index-Ya5FE7cD.css → index-C8rOIAJr.css} +1 -1
- package/dist/worker/console/static/assets/{index-DTZOKgAn.js → index-DEbyrEfW.js} +71 -71
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-DlSl4BGx.js → infoDiagram-6WML65LV-BFA337tZ.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-snnzFl_U.js → ishikawaDiagram-WSZJBQD7-BtEujgRR.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-BDE7qpMx.js → journeyDiagram-NVQOT4AX-C8ZwD2Jp.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-CD2Ci04G.js → kanban-definition-27J2QSJJ-Ck-z8B11.js} +1 -1
- package/dist/worker/console/static/assets/{linear-DdnapKIH.js → linear-CAyXjQjN.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-BVjAT9b8.js → mermaid.core-CcWKn6tS.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-D0yJk-zA.js → mindmap-definition-FAOFIHXS-C2NuDO7E.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-BVo9tFP-.js → pegDiagram-VL7TDLO6-BFub3PDz.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-DnOV-mZ_.js → pieDiagram-7S7Q4E2Y-BJx5THZ5.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-CzUJo58i.js → quadrantDiagram-CIZ2JOQS-DhalkDWV.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-Bvikrolh.js → railroadDiagram-AXF67PYL-CVcBM36o.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-DtaSVCap.js → requirementDiagram-LRYGKXZP-D_vy4n0w.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-C2c9A0wW.js → sankeyDiagram-W5VNT64P-DGYdJL1D.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-DmXJcU7r.js → sequenceDiagram-SI44F4Z6-C1xJFg3k.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-B4GUFW92.js → sizeCapture-X5ZJPWSS-D_Fc43df.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-Dsad2MXf.js → stateDiagram-OKZ733FA-BhGbIjbu.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DUt1lyFL.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-DGq48Fbi.js → swimlanes-SLNWSIFB-DVkNcO-V.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BM6SGr7j.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CSSi6OFf.js → timeline-definition-Z64GVDOM-BQU9ufV0.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-BqyzPrWv.js → vennDiagram-T6HMQDX7-BCQhRmYB.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-DlznVb6S.js → wardleyDiagram-T6FBY63Y-DWerOyHO.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-CfBcgJ_K.js → xychartDiagram-ELKLHX3M-DxLeebQU.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/operator-chat/mutation-gate.js +1 -1
- package/dist/worker/loop-agent/loop-agent-client.js +7 -3
- package/dist/worker/observe/node-input.js +2 -0
- package/dist/worker/observe/node-process.js +377 -0
- package/dist/worker/observe/routes.js +36 -3
- package/dist/worker/observe/shell-handler-keys.js +34 -0
- package/dist/worker/observe/static/api.js +66 -0
- package/dist/worker/observe/static/constants.js +8 -1
- package/dist/worker/observe/static/format.js +23 -0
- package/dist/worker/observe/static/markdown-render.js +20 -1
- package/dist/worker/observe/static/operator-chrome.js +4 -0
- package/dist/worker/observe/static/state.js +11 -0
- package/dist/worker/observe/static/styles.css +73 -0
- package/dist/worker/observe/static/views/dag-inspector.js +561 -8
- package/dist/worker/observe/static/views/dag.js +8 -1
- package/dist/worker/observe/static/views/failures.js +5 -2
- package/dist/worker/observe/static/views/session-timeline.js +60 -4
- package/dist/workflows/dag/backend-test-case-coverage-analysis.js +20 -2
- package/dist/workflows/dag/failure-category.js +8 -0
- package/dist/workflows/dag/frontend-implementation-contract.js +5 -1
- package/dist/workflows/dag/frontend-repair.js +14 -0
- package/dist/workflows/dag/frontend-risk.js +15 -2
- package/dist/workflows/dag/frontend-test-case-checklist.js +26 -2
- package/dist/workflows/dag/frontend-test-case-manifest.js +5 -0
- package/dist/workflows/dag/frontend-test-result-contract.js +151 -11
- package/dist/workflows/dag/frontend-verification-trace.js +29 -4
- package/dist/workflows/dag/init-hybrid.js +125 -24
- package/dist/workflows/dag/node-execution.js +20 -2
- package/dist/workflows/dag/rerun-plan.js +112 -0
- package/dist/workflows/dag/rerun-run.js +58 -6
- package/dist/workflows/dag/retry-policy.js +91 -0
- package/dist/workflows/dag/types.js +9 -1
- package/docs/init-surface.manifest.json +5 -0
- package/docs/operations/README.md +1 -1
- package/docs/templates/init-managed-agents.md +13 -3
- package/harness.json +2 -2
- package/package.json +5 -1
- package/scripts/next-info.mjs +356 -0
- package/scripts/next-publish-gate.mjs +238 -0
- package/scripts/release-source-binding.mjs +251 -0
- package/skills/fe-test-ui-scout/SKILL.md +65 -0
- package/skills/fe-test-ui-scout/references/ledger-schema.md +62 -0
- package/skills/fe-test-ui-scout/references/recon-protocol.md +54 -0
- package/skills/loop-agent/references/command-reference.md +11 -4
- package/skills/playwright-cli/SKILL.md +22 -0
- package/skills/playwright-cli-case-generator/SKILL.md +20 -1
- package/dist/worker/console/static/assets/channel-CPF4N7pf.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-C2DwA_Y1.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-C2DwA_Y1.js +0 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-B8FB_cNk.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-CrZYaWfx.js +0 -8
|
@@ -2,6 +2,7 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
import { access, copyFile, mkdir, readdir, readFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { writeJsonAtomic } from "../../infrastructure/harness/atomic-write.js";
|
|
5
|
+
import { composeDagPromptOverridePrompt, isDagRerunPromptOverrideEnabled, } from "../../shared/dag-prompt-override.js";
|
|
5
6
|
import { resolveRunningControllerIdentity } from "../../shared/package-metadata.js";
|
|
6
7
|
import { readControllerIdentityArtifact, captureControllerIdentity } from "./controller-identity.js";
|
|
7
8
|
import { DAG_RUNS_DIR, getDagRunDir, isDagNonExecutionLifecycle, locateDagRun, readDagRunSpec, readDagRunState, } from "./lifecycle.js";
|
|
@@ -190,6 +191,8 @@ export async function planDagRerun(input) {
|
|
|
190
191
|
parentSpec: nonCompletedSpec,
|
|
191
192
|
parentState: nonCompletedState,
|
|
192
193
|
parentLifecycle,
|
|
194
|
+
promptOverrides: input.promptOverrides,
|
|
195
|
+
promptOverrideEnabled: isDagRerunPromptOverrideEnabled(),
|
|
193
196
|
workerManaged: nonCompletedWorkerHints.workerManaged,
|
|
194
197
|
workerAssociation: nonCompletedWorkerHints.workerManaged
|
|
195
198
|
? {
|
|
@@ -229,6 +232,8 @@ export async function planDagRerun(input) {
|
|
|
229
232
|
parentTerminalWorkspace,
|
|
230
233
|
currentWorkspace,
|
|
231
234
|
skillSnapshotOk,
|
|
235
|
+
promptOverrides: input.promptOverrides,
|
|
236
|
+
promptOverrideEnabled: isDagRerunPromptOverrideEnabled(),
|
|
232
237
|
workerManaged: workerHints.workerManaged,
|
|
233
238
|
workerAssociation: workerHints.workerManaged
|
|
234
239
|
? {
|
|
@@ -384,15 +389,57 @@ function buildPendingNodeRecord(task) {
|
|
|
384
389
|
...(task.outputMode ? { outputMode: task.outputMode } : {}),
|
|
385
390
|
};
|
|
386
391
|
}
|
|
392
|
+
/**
|
|
393
|
+
* Stage the continuation spec with operator prompt overrides applied. The
|
|
394
|
+
* parent spec stays frozen; every override must match the plan entry (sha256
|
|
395
|
+
* of the composed final prompt and of the parent base prompt) so the
|
|
396
|
+
* two-phase planHash remains the single source of truth for what changed.
|
|
397
|
+
* "append" entries keep the frozen base and append the operator addendum in a
|
|
398
|
+
* marked block; "replace" entries swap the whole prompt.
|
|
399
|
+
*/
|
|
400
|
+
function applyPromptOverridesToSpec(input) {
|
|
401
|
+
const planned = new Map((input.plan.promptOverrides ?? []).map((entry) => [entry.nodeId, entry]));
|
|
402
|
+
const spec = structuredClone(input.spec);
|
|
403
|
+
for (const override of input.overrides) {
|
|
404
|
+
const entry = planned.get(override.nodeId);
|
|
405
|
+
if (!entry) {
|
|
406
|
+
throw new Error(`prompt override is not present in the rerun plan: ${override.nodeId}`);
|
|
407
|
+
}
|
|
408
|
+
const task = spec.tasks.find((candidate) => candidate.id === override.nodeId);
|
|
409
|
+
if (!task) {
|
|
410
|
+
throw new Error(`prompt override node missing from spec: ${override.nodeId}`);
|
|
411
|
+
}
|
|
412
|
+
if (sha256Hex(task.subtask_prompt) !== entry.basePromptSha256) {
|
|
413
|
+
throw new Error(`prompt override base prompt drifted from plan: ${override.nodeId}`);
|
|
414
|
+
}
|
|
415
|
+
const finalPrompt = composeDagPromptOverridePrompt({
|
|
416
|
+
basePrompt: task.subtask_prompt,
|
|
417
|
+
text: override.prompt,
|
|
418
|
+
mode: override.mode === "append" ? "append" : "replace",
|
|
419
|
+
});
|
|
420
|
+
if (sha256Hex(finalPrompt) !== entry.promptSha256) {
|
|
421
|
+
throw new Error(`prompt override text does not match the planned sha256: ${override.nodeId}`);
|
|
422
|
+
}
|
|
423
|
+
task.subtask_prompt = finalPrompt;
|
|
424
|
+
}
|
|
425
|
+
return spec;
|
|
426
|
+
}
|
|
387
427
|
async function stageContinuationRun(input) {
|
|
388
|
-
const
|
|
389
|
-
|
|
428
|
+
const specForRun = input.promptOverrides !== undefined && input.promptOverrides.length > 0
|
|
429
|
+
? applyPromptOverridesToSpec({
|
|
430
|
+
spec: input.parentSpec,
|
|
431
|
+
plan: input.plan,
|
|
432
|
+
overrides: input.promptOverrides,
|
|
433
|
+
})
|
|
434
|
+
: input.parentSpec;
|
|
435
|
+
const { ranks } = topoSortToRanks(specForRun);
|
|
436
|
+
const runId = await buildDagRunId(specForRun, { cwd: input.cwd });
|
|
390
437
|
const runDir = getDagRunDir(input.cwd, "active", runId);
|
|
391
438
|
await prepareActiveRunDir(runDir);
|
|
392
|
-
await writeRunSpec(runDir,
|
|
439
|
+
await writeRunSpec(runDir, specForRun);
|
|
393
440
|
const resetSet = new Set(input.plan.resetNodeIds);
|
|
394
441
|
const importedSet = new Set(input.plan.importedNodeIds);
|
|
395
|
-
const tasksById = new Map(
|
|
442
|
+
const tasksById = new Map(specForRun.tasks.map((task) => [task.id, task]));
|
|
396
443
|
const importManifestNodes = [];
|
|
397
444
|
const nodes = {};
|
|
398
445
|
for (const nodeId of input.plan.importedNodeIds) {
|
|
@@ -433,6 +480,9 @@ async function stageContinuationRun(input) {
|
|
|
433
480
|
reason: input.reason,
|
|
434
481
|
requestId: input.requestId,
|
|
435
482
|
planHash: input.plan.planHash,
|
|
483
|
+
...(input.plan.promptOverrides
|
|
484
|
+
? { promptOverrides: input.plan.promptOverrides }
|
|
485
|
+
: {}),
|
|
436
486
|
createdAt,
|
|
437
487
|
};
|
|
438
488
|
const state = {
|
|
@@ -482,7 +532,7 @@ async function stageContinuationRun(input) {
|
|
|
482
532
|
await writeJsonAtomic(path.join(runDir, IMPORT_MANIFEST_REL_PATH), importManifest);
|
|
483
533
|
await writeJsonAtomic(path.join(runDir, RERUN_PLAN_REL_PATH), input.plan);
|
|
484
534
|
await writeRunState(runDir, state);
|
|
485
|
-
return { runId, runDir, state };
|
|
535
|
+
return { runId, runDir, state, spec: specForRun };
|
|
486
536
|
}
|
|
487
537
|
export async function executeDagRerun(input) {
|
|
488
538
|
const existing = await readExistingOperatorRequest(input.cwd, input.requestId);
|
|
@@ -493,6 +543,7 @@ export async function executeDagRerun(input) {
|
|
|
493
543
|
cwd: input.cwd,
|
|
494
544
|
parentRunId: input.parentRunId,
|
|
495
545
|
selectedNodeId: input.selectedNodeId,
|
|
546
|
+
promptOverrides: input.promptOverrides,
|
|
496
547
|
});
|
|
497
548
|
if (plan.planHash !== input.planHash) {
|
|
498
549
|
return {
|
|
@@ -530,10 +581,11 @@ export async function executeDagRerun(input) {
|
|
|
530
581
|
plan,
|
|
531
582
|
reason: input.reason,
|
|
532
583
|
requestId: input.requestId,
|
|
584
|
+
promptOverrides: input.promptOverrides,
|
|
533
585
|
});
|
|
534
586
|
const continuationOptions = {
|
|
535
587
|
cwd: input.cwd,
|
|
536
|
-
spec:
|
|
588
|
+
spec: staged.spec,
|
|
537
589
|
state: staged.state,
|
|
538
590
|
runDir: staged.runDir,
|
|
539
591
|
...(input.maxConcurrent !== undefined
|
|
@@ -165,6 +165,36 @@ export const WRITER_TRANSPORT_RETRY_POLICY = {
|
|
|
165
165
|
maxDelayMs: 30000,
|
|
166
166
|
retryCategories: [WRITER_CLEAN_TIMEOUT_RETRY_CATEGORY],
|
|
167
167
|
};
|
|
168
|
+
/**
|
|
169
|
+
* Implicit runtime retry for canonical final verify shells. Not a DagRetryPolicy:
|
|
170
|
+
* `spawn-error` / `test-timeout` are runtime command categories and must not enter
|
|
171
|
+
* `dagRetryPolicySchema` / `ALL_DAG_RETRY_CATEGORIES`.
|
|
172
|
+
*/
|
|
173
|
+
export const VERIFY_SHELL_RETRY_CATEGORIES = [
|
|
174
|
+
"timeout",
|
|
175
|
+
"spawn-error",
|
|
176
|
+
"test-timeout",
|
|
177
|
+
];
|
|
178
|
+
export const VERIFY_SHELL_RETRY_POLICY = {
|
|
179
|
+
maxAttempts: 2,
|
|
180
|
+
backoff: "exponential",
|
|
181
|
+
initialDelayMs: 2000,
|
|
182
|
+
maxDelayMs: 30000,
|
|
183
|
+
retryCategories: VERIFY_SHELL_RETRY_CATEGORIES,
|
|
184
|
+
};
|
|
185
|
+
export const TARGET_TEMPLATE_TRANSIENT_RETRY_PROFILE = "standard-reviewed-supervised-v1";
|
|
186
|
+
/**
|
|
187
|
+
* Target-template exclusive implement-pi transport retry. Same schema category
|
|
188
|
+
* as frontend (`writer-clean-timeout`) so DagSpec validation stays unchanged;
|
|
189
|
+
* only the delay cap is wider. Do not mutate {@link WRITER_TRANSPORT_RETRY_POLICY}.
|
|
190
|
+
*/
|
|
191
|
+
export const TARGET_TEMPLATE_WRITER_TRANSPORT_RETRY_POLICY = {
|
|
192
|
+
maxAttempts: 2,
|
|
193
|
+
backoff: "exponential",
|
|
194
|
+
initialDelayMs: 5000,
|
|
195
|
+
maxDelayMs: 60000,
|
|
196
|
+
retryCategories: [WRITER_CLEAN_TIMEOUT_RETRY_CATEGORY],
|
|
197
|
+
};
|
|
168
198
|
/**
|
|
169
199
|
* Backend-test generation writers: empty-diff once, plus bounded incomplete-write-set
|
|
170
200
|
* recovery attempts driven by Completeness Gate (missing/broken target files).
|
|
@@ -238,6 +268,67 @@ export function isWriterTransportRetryCandidate(task) {
|
|
|
238
268
|
task.writerOutcomePolicy?.type === "implementation-outcome-v1" &&
|
|
239
269
|
task.writerOutcomePolicy.requireChangedFiles !== true);
|
|
240
270
|
}
|
|
271
|
+
/**
|
|
272
|
+
* Canonical standard exclusive `implement-pi` only. Frontend designers and
|
|
273
|
+
* completeness writers stay on the existing timeout-only transport candidate.
|
|
274
|
+
*/
|
|
275
|
+
export function isTargetTemplateImplementPi(task) {
|
|
276
|
+
return isWriterTransportRetryCandidate(task) && task.id === "implement-pi";
|
|
277
|
+
}
|
|
278
|
+
export function hasTargetTemplateTransientRetryProfile(task) {
|
|
279
|
+
return (task?.transientRetryProfile === TARGET_TEMPLATE_TRANSIENT_RETRY_PROFILE);
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Dual-condition eligibility: canonical shape AND generated-path stamp.
|
|
283
|
+
* Custom / other-template nodes that only match id or shape stay ineligible.
|
|
284
|
+
*/
|
|
285
|
+
export function isTargetTemplateTransientRetryNode(task) {
|
|
286
|
+
if (!hasTargetTemplateTransientRetryProfile(task))
|
|
287
|
+
return false;
|
|
288
|
+
return (isCanonicalFinalVerifyShellRetryCandidate(task) ||
|
|
289
|
+
isTargetTemplateImplementPi(task));
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Shape-based eligibility for implicit canonical final verify-shell retry.
|
|
293
|
+
* Does not consult node id or a template field.
|
|
294
|
+
*/
|
|
295
|
+
export function isCanonicalFinalVerifyShellRetryCandidate(task) {
|
|
296
|
+
if (task.executor !== "shell")
|
|
297
|
+
return false;
|
|
298
|
+
if (task.role !== "verifier")
|
|
299
|
+
return false;
|
|
300
|
+
if (task.writePolicy !== undefined &&
|
|
301
|
+
task.writePolicy !== "read-only" &&
|
|
302
|
+
task.writePolicy !== "none") {
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
if ((task.writeSet?.length ?? 0) > 0)
|
|
306
|
+
return false;
|
|
307
|
+
const shell = task.shell;
|
|
308
|
+
if (!shell || (shell.commands?.length ?? 0) === 0)
|
|
309
|
+
return false;
|
|
310
|
+
const evidence = shell.verifyEvidence;
|
|
311
|
+
if (!evidence)
|
|
312
|
+
return false;
|
|
313
|
+
if (evidence.phase !== "final")
|
|
314
|
+
return false;
|
|
315
|
+
if (evidence.quota !== "full")
|
|
316
|
+
return false;
|
|
317
|
+
if (evidence.commandSource !== "adapter")
|
|
318
|
+
return false;
|
|
319
|
+
if (evidence.finalFullRequired !== true)
|
|
320
|
+
return false;
|
|
321
|
+
if (shell.frontendPrewriteGate ||
|
|
322
|
+
shell.frontendVerificationBundle ||
|
|
323
|
+
shell.frontendBrowserToolPreflight ||
|
|
324
|
+
shell.backendTestPipeline ||
|
|
325
|
+
shell.jacocoCoverage ||
|
|
326
|
+
shell.repairArtifactGate ||
|
|
327
|
+
shell.verdictGate) {
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
330
|
+
return true;
|
|
331
|
+
}
|
|
241
332
|
export function isSafeReadOnlyPiRetryCandidate(task) {
|
|
242
333
|
if (task.executor !== "pi")
|
|
243
334
|
return false;
|
|
@@ -2,7 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { isOpenspecSpecFilePath } from "../../shared/openspec-spec.js";
|
|
3
3
|
import { campaignBudgetSchema, } from "../../application/evaluation/budget.js";
|
|
4
4
|
import { assertDagPromptSourceRule } from "./prompt-source.js";
|
|
5
|
-
import { dagRetryPolicySchema } from "./retry-policy.js";
|
|
5
|
+
import { dagRetryPolicySchema, TARGET_TEMPLATE_TRANSIENT_RETRY_PROFILE, } from "./retry-policy.js";
|
|
6
6
|
import { dagLivenessPolicySchema, } from "./liveness-policy.js";
|
|
7
7
|
import { dagOutputProtocolSchema } from "./output-protocol.js";
|
|
8
8
|
export const dagComplexitySchema = z.enum(["HIGH", "MED", "LOW"]);
|
|
@@ -849,6 +849,14 @@ export const dagTaskSchema = z.object({ id: z.string().regex(/^[a-z][a-z0-9-]*$/
|
|
|
849
849
|
forbiddenPaths: z.array(z.string()).optional().default([]),
|
|
850
850
|
decisionGate: dagDecisionGateSchema.optional(),
|
|
851
851
|
retryPolicy: dagRetryPolicySchema.optional(),
|
|
852
|
+
/**
|
|
853
|
+
* Generation-path stamp for implicit same-run transient retry. Only the
|
|
854
|
+
* three target templates stamp canonical final verify shells and
|
|
855
|
+
* exclusive `implement-pi`. Zod-declared so parseDagSpec does not strip it.
|
|
856
|
+
*/
|
|
857
|
+
transientRetryProfile: z
|
|
858
|
+
.literal(TARGET_TEMPLATE_TRANSIENT_RETRY_PROFILE)
|
|
859
|
+
.optional(),
|
|
852
860
|
/** Optional per-node adaptive liveness override (merged over defaults). */
|
|
853
861
|
livenessPolicy: dagLivenessPolicySchema,
|
|
854
862
|
dynamicExpansion: dagDynamicExpansionSchema.optional(),
|
|
@@ -50,6 +50,9 @@
|
|
|
50
50
|
"scripts/kb-graph-materialize.mjs",
|
|
51
51
|
"scripts/kb-graph-promote.mjs",
|
|
52
52
|
"scripts/kb-graph-incremental-prepare.mjs",
|
|
53
|
+
"scripts/next-info.mjs",
|
|
54
|
+
"scripts/next-publish-gate.mjs",
|
|
55
|
+
"scripts/release-source-binding.mjs",
|
|
53
56
|
"docs/templates/agent-dag.schema.json",
|
|
54
57
|
"examples/example-dag.json",
|
|
55
58
|
"skills/agent-worker/SKILL.md",
|
|
@@ -277,6 +280,7 @@
|
|
|
277
280
|
"harness.json",
|
|
278
281
|
"package.json",
|
|
279
282
|
"src/commands/init.ts",
|
|
283
|
+
"src/commands/init-model-catalog.ts",
|
|
280
284
|
"src/commands/client-recovery.ts",
|
|
281
285
|
"src/commands/init-upgrade.ts",
|
|
282
286
|
"src/cli.ts",
|
|
@@ -302,6 +306,7 @@
|
|
|
302
306
|
"description": "Changes that may alter target-project initialization behavior, default DAG role skills, skill resolution, or package/init contracts.",
|
|
303
307
|
"patterns": [
|
|
304
308
|
"src/commands/init.ts",
|
|
309
|
+
"src/commands/init-model-catalog.ts",
|
|
305
310
|
"src/commands/client-recovery.ts",
|
|
306
311
|
"src/commands/init-upgrade.ts",
|
|
307
312
|
"src/cli.ts",
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
- [`local-development-environment.md`](local-development-environment.md):本地环境、Windows 差异和常见排障。
|
|
8
8
|
- [`branch-merge-guideline.md`](branch-merge-guideline.md):按风险选择合并模式并留下 source-SHA 证据。
|
|
9
9
|
- [`github-collaboration.md`](github-collaboration.md):仓库内 GitHub 协作约定及发布通道。
|
|
10
|
-
- [`version-and-release-management.md`](version-and-release-management.md):版本发布管理——next / release-x.y / latest
|
|
10
|
+
- [`version-and-release-management.md`](version-and-release-management.md):版本发布管理——next / release-x.y / latest 渠道、移动式 `npm-next` ref、`inspect next` 查询入口、workflow 与 promote 手册。
|
|
11
11
|
- [`production-readiness.md`](production-readiness.md):交付前的生产就绪判断。
|
|
12
12
|
- [`agent-worker-production-readiness.md`](agent-worker-production-readiness.md):agent-worker Feature/Task Pool 外层编排的 Production Readiness v1 操作合同。
|
|
13
13
|
- [`backend-test-jacoco-coverage.md`](backend-test-jacoco-coverage.md):Java 被测服务挂载 JaCoCo tcpserver agent 的 Maven、`java -jar` 与 Docker 操作手册。
|
|
@@ -80,9 +80,19 @@ loop-agent init update --repo-root . --apply-safe
|
|
|
80
80
|
当用户要求初始化 loop-agent(“初始化 loop-agent”“loop agent 初始化”“loop agent初始化”“loop-agent 初始化”),或发现 `README.md` / `__LOOP_AGENT_GOVERNANCE_ROOT__/verification-matrix.md` 仍停留在通用初始化状态时,模型应在同一轮工作中完成初始化闭环,不要把补全文档和验证矩阵留给用户交互。
|
|
81
81
|
|
|
82
82
|
1. 运行 `loop-agent init instructions --repo-root .`。
|
|
83
|
-
2. 运行 `loop-agent init --repo-root . --
|
|
84
|
-
3.
|
|
85
|
-
4.
|
|
83
|
+
2. 运行 `loop-agent init model-catalog --repo-root . --json`。loop-agent 不直接打开或解析认证文件原文,只让 Pi/OpenCode 自己的 runtime 加载其配置,并输出白名单模型元数据、Pi setup 状态、Pi 兼容性与 credential-ready 布尔值;token、headers、URL、原始命令输出和认证路径不会进入 catalog。
|
|
84
|
+
3. 先处理 `piSetup`:如果没有模型定义,向用户索取无法推断的 provider/model id、API/base URL、上下文窗口、最大输出、输入/推理能力、成本约束和凭据方式,帮助按 Pi 原生 schema 合并 `~/.pi/agent/models.json`;不得让用户把凭据值写入对话、harness 或报告,优先 Pi 登录/auth storage 或环境变量引用。如果已有定义但凭据未就绪,只修复认证。随后重跑 catalog,未出现 credential-ready Pi model 前不得继续初始化。
|
|
85
|
+
4. 对已有 `harness.json`,逐档保留仍存在于 Pi 的 LOW/MED/HIGH 原值;只为已移除或缺失的档位重新选择。结合目标项目实际技术栈、模型能力、成本与上下文窗口,从 `eligibleForHarness=true` 的候选中自主选择,并直接运行带完整三档参数的 init/update;代码会拒绝改动仍有效的档位。三档可以相同。只有凭据、成本、合规或可用性存在无法推断的实质歧义时才询问用户;OpenCode-only 候选不能证明 Pi executor 可用。
|
|
86
|
+
5. 基于真实项目文件补全根 `README.md`、`__LOOP_AGENT_GOVERNANCE_ROOT__/verification-matrix.md`,必要时适配 `scripts/ci-tests.sh`。
|
|
87
|
+
6. 运行 `loop-agent init doctor --repo-root .`、`loop-agent inspect`、`loop-agent docs audit` 并完成 quick verification;doctor 未确认 Pi model matrix 时不得开始 DAG。
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
loop-agent init --repo-root . --profile full --merge \
|
|
91
|
+
--low-model <provider/model> --med-model <provider/model> --high-model <provider/model>
|
|
92
|
+
# 已初始化项目只替换失效档位;仍有效档位在完整参数中保持当前引用
|
|
93
|
+
loop-agent init update --repo-root . --apply-safe \
|
|
94
|
+
--low-model <current-or-selected> --med-model <current-or-selected> --high-model <current-or-selected>
|
|
95
|
+
```
|
|
86
96
|
|
|
87
97
|
信息不足时写明尚未识别到的事实;不要留下泛化占位符。
|
|
88
98
|
|
package/harness.json
CHANGED
|
@@ -83,8 +83,8 @@
|
|
|
83
83
|
"pi": {
|
|
84
84
|
"description": "Pi 负责规划、评审、诊断;当 DAG toolProfile=write 时也可做有界写入。模型按复杂度三档配置,支持 provider/model 字符串或带 thinking 的对象;斜杠前为 Pi provider,后为 modelId,勿只写裸 modelId。",
|
|
85
85
|
"LOW": "wizard-local/minimax-m3",
|
|
86
|
-
"MED": "wizard-local/
|
|
87
|
-
"HIGH": "wizard-local/
|
|
86
|
+
"MED": "wizard-local/minimax-m3",
|
|
87
|
+
"HIGH": "wizard-local/minimax-m3"
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tea-agent/loop-agent",
|
|
3
|
-
"version": "0.38.
|
|
3
|
+
"version": "0.38.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"loop-agent": "bin/loop-agent.js",
|
|
@@ -33,6 +33,9 @@
|
|
|
33
33
|
"scripts/kb-graph-materialize.mjs",
|
|
34
34
|
"scripts/kb-graph-promote.mjs",
|
|
35
35
|
"scripts/kb-graph-incremental-prepare.mjs",
|
|
36
|
+
"scripts/next-info.mjs",
|
|
37
|
+
"scripts/next-publish-gate.mjs",
|
|
38
|
+
"scripts/release-source-binding.mjs",
|
|
36
39
|
"README.md",
|
|
37
40
|
"CHANGELOG.md"
|
|
38
41
|
],
|
|
@@ -58,6 +61,7 @@
|
|
|
58
61
|
"test": "node scripts/run-tests.mjs",
|
|
59
62
|
"test:host": "vitest run test/init-upgrade.test.ts --maxWorkers=1 -t \"records and reuses|controller-authorized semantic merge|authority-sensitive\"",
|
|
60
63
|
"test:fast": "vitest run --config vitest.fast.config.ts",
|
|
64
|
+
"test:io-heavy": "vitest run --config vitest.io-heavy.config.ts",
|
|
61
65
|
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
62
66
|
"docs:dev": "npm --prefix website start",
|
|
63
67
|
"docs:build": "npm --prefix website run build",
|