@tea-agent/loop-agent 0.42.0-next.1 → 0.42.0-next.11
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 +1 -1
- package/CHANGELOG.md +321 -1
- package/dist/application/dag/generate-task-dag.js +75 -19
- package/dist/application/dag/run-dag.js +41 -0
- package/dist/application/task-lifecycle/advance.js +24 -5
- package/dist/application/task-lifecycle/observe.js +171 -17
- package/dist/application/task-lifecycle/plan-transitions.js +42 -7
- package/dist/application/task-lifecycle/recommendations.js +13 -2
- package/dist/build-stamp.json +3 -3
- package/dist/cli/command-definitions.js +7 -0
- package/dist/cli/program.js +6 -1
- package/dist/commands/client-recovery.js +3 -0
- package/dist/commands/dag-follow-up.js +138 -0
- package/dist/commands/dag-rerun-task.js +2 -0
- package/dist/commands/init.js +27 -1
- package/dist/commands/task-advance.js +19 -0
- package/dist/executors/dag-pi-executor.js +4010 -78
- package/dist/executors/pi-executor.js +15 -4
- package/dist/executors/pi-extension-resolver.js +14 -2
- package/dist/executors/pi-read-budget-policy.js +239 -0
- package/dist/executors/shell-executor.js +978 -188
- package/dist/executors/shell-write-guard.js +7 -0
- package/dist/infrastructure/console/operation-store.js +226 -6
- package/dist/shared/dag-failure-category.js +12 -0
- package/dist/shared/openspec-spec.js +70 -4
- package/dist/shared/operator/capabilities.js +7 -0
- package/dist/task/config-types.js +105 -5
- package/dist/task/contract/adopt.js +4 -0
- package/dist/task/contract/import-revision.js +4 -0
- package/dist/task/contract/project.js +3 -0
- package/dist/task/contract/schema.js +2 -1
- package/dist/task/frontend-project-capability.js +203 -20
- package/dist/task/runtime.js +5 -2
- package/dist/task/source-prepare/build-draft.js +3 -3
- package/dist/task/source-prepare/fragment-inventory.js +64 -25
- package/dist/task/source-prepare/prepare.js +126 -21
- package/dist/task/source-prepare/semantic-intake.js +6 -2
- package/dist/task/source-references.js +22 -1
- package/dist/worker/console/chat/chat-ui-policy.js +4 -2
- package/dist/worker/console/chat/model-resolver.js +7 -4
- package/dist/worker/console/chat/pi-runtime.js +258 -11
- package/dist/worker/console/chat/repo-browser.js +10 -3
- package/dist/worker/console/chat/routes.js +165 -71
- package/dist/worker/console/chat/sdd-data-alignment.js +222 -0
- package/dist/worker/console/chat/session-catalog.js +2 -0
- package/dist/worker/console/chat/session-store.js +159 -70
- package/dist/worker/console/chat/shortcuts.js +19 -3
- package/dist/worker/console/chat/turn-process.js +111 -56
- package/dist/worker/console/frontend-human-decision-adapter.js +19 -0
- package/dist/worker/console/frontend-split-operation-adapter.js +20 -0
- package/dist/worker/console/index.js +3 -0
- package/dist/worker/console/operator-actions.js +169 -7
- package/dist/worker/console/pi-readiness.js +3 -2
- package/dist/worker/console/server.js +23 -1
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-DZZ8m3PO.js → abnfDiagram-N423BO3Z-CcS17TBr.js} +1 -1
- package/dist/worker/console/static/assets/{arc-D6PvaVd-.js → arc-COptKq2S.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-B_OTOiI8.js → architectureDiagram-T3A2C74G-h4LKMHjP.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-Bv6rqHBg.js → blockDiagram-VBNYF7ZC-COA1MOH0.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-B8eHr0oz.js → c4Diagram-5PPSVZJV-DJUf0QPm.js} +1 -1
- package/dist/worker/console/static/assets/channel-DdBCaOJ6.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-DYwR0im2.js → chunk-2GRJ4B5K-mtWfKrUX.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-D2WPGqXt.js → chunk-2Q5K7J3B-B8pXsxDQ.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-CQISJ_I7.js → chunk-5RXB4S5H-ipKzByl1.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-C0o2Du1e.js → chunk-5VM5RSS4-DYi3Ald_.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-4f8kr-U7.js → chunk-6Q2QTUOP-DQtGYoty.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-D_OWvXzX.js → chunk-GF5L2VYU-BU0qS2YV.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-CasdPz5X.js → chunk-JWPE2WC7-DVH9dIGE.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-Cj8lRrla.js → chunk-KBJHAD2P-Dt60SmgM.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-CUvD1FSd.js → chunk-RYQCIY6F-BoaUGuEY.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-CqLw_eqB.js → chunk-XXDRQBXY-_WHFDTp2.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DZFra1GO.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DZFra1GO.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-ku-WqJPx.js → cose-bilkent-JH36ORCC-BxkbTIRd.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-Bq_PYDhl.js → cynefin-VYW2F7L2-Bf2UVnoG.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-BiGZV641.js → cynefinDiagram-MW4NZA55-Bo23q1J_.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-C4JRlglF.js → dagre-VZM6K2ZE-Dd_UU49i.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-B0dNeWYG.js → diagram-7IWD3JNH-ebUa1a9y.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-Cj35YvYM.js → diagram-B4RE2ZJO-BucthU8r.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-uzQoJ2-8.js → diagram-LBJQPF4R-BgqNpAkm.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-D1a-Buoz.js → diagram-Q27KOJAE-DC4q5NGa.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-XjRrLRSs.js → diagram-UB23O5K3-CBqCaMeb.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-Da_O24cW.js → ebnfDiagram-BXEA7PRR-CGtnbQ3-.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-BLJ8jrYU.js → erDiagram-JOGREHBK-CG3LUao5.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-B9GrLjM0.js → flowDiagram-UKHOOZJN-D2ZVgoFS.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-CeJ0TqiK.js → ganttDiagram-PKOTCBZU-DoYFZiKt.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Bm2eNNFX.js → gitGraphDiagram-DS77QQ5N-CKoP1s6j.js} +1 -1
- package/dist/worker/console/static/assets/index-CAZ2fC_X.css +1 -0
- package/dist/worker/console/static/assets/index-vbTcFnFs.js +449 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-DB26i3d8.js → infoDiagram-6WML65LV-Duofv8p2.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-BOGRyeZT.js → ishikawaDiagram-WSZJBQD7-D2nlCkA1.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-CZRoBO_6.js → journeyDiagram-NVQOT4AX-Dd4IHdus.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-qlWhJyoB.js → kanban-definition-27J2QSJJ-Bi20AOdt.js} +1 -1
- package/dist/worker/console/static/assets/{linear-CfUiDDB3.js → linear-D59YJ9kB.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-BQe6fpqj.js → mermaid.core-Bl13LpNa.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-zFzWHw64.js → mindmap-definition-FAOFIHXS-C6DLP5eY.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-DFGUqjZO.js → pegDiagram-VL7TDLO6-BjO4cy64.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-BB5i0l8Z.js → pieDiagram-7S7Q4E2Y-D7i2qZTG.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-obbVZ_X5.js → quadrantDiagram-CIZ2JOQS-Dx8o_h0y.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-BwdaNzc1.js → railroadDiagram-AXF67PYL-B55orI_t.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-CkTJaugh.js → requirementDiagram-LRYGKXZP-zWaehp6f.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-BwJ-hIgq.js → sankeyDiagram-W5VNT64P-CcA-pjvD.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-BzSgmm7w.js → sequenceDiagram-SI44F4Z6-BOFbzNHI.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-Bn3oj5Q1.js → sizeCapture-X5ZJPWSS-BjAejah1.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-dxhGtL8K.js → stateDiagram-OKZ733FA-DXYwxJwZ.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-Clg3V9t1.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-BLpEInya.js → swimlanes-SLNWSIFB-OYiOch8n.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DX1dxAAW.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-ChJGYcXy.js → timeline-definition-Z64GVDOM-cZfH3nmU.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-DK-qjRer.js → vennDiagram-T6HMQDX7-BDE7b3E1.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-3qeaWAg-.js → wardleyDiagram-T6FBY63Y-kyyGy9WJ.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-CootlyP9.js → xychartDiagram-ELKLHX3M-CJj6VTog.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/active-run-badge.js +17 -0
- package/dist/worker/console/static-src/app/useRecoveryConsole.js +5 -5
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +19 -8
- package/dist/worker/console/static-src/operator-chat/input-history.js +8 -6
- package/dist/worker/console/static-src/operator-chat/open-preview-in-browser.js +15 -7
- package/dist/worker/console/static-src/operator-chat/runtime-snapshot-store.js +10 -0
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +258 -23
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +112 -4
- package/dist/worker/console/static-src/operator-chat/useComposer.js +13 -4
- package/dist/worker/console/static-src/operator-chat/useRuntimeControls.js +29 -6
- package/dist/worker/console/static-src/operator-chat/useRuntimeSnapshot.js +8 -2
- package/dist/worker/console/static-src/shell/console-update-reload.js +36 -9
- package/dist/worker/console/static-src/shell/workspace-route.js +11 -0
- package/dist/worker/console/workspace-context.js +115 -1
- package/dist/worker/materialize/frontend-split-task-materializer.js +72 -0
- package/dist/worker/observe/routes.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-helpers.js +4 -2
- 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 +13 -8
- package/dist/worker/observe/static/index.html +4 -4
- package/dist/worker/observe/static/inspect-workspace.js +23 -0
- package/dist/worker/observe/static/kpi.js +2 -2
- package/dist/worker/observe/static/operator-chrome.d.ts +10 -2
- package/dist/worker/observe/static/operator-chrome.js +37 -23
- package/dist/worker/observe/static/prompt-restart-candidates.js +4 -2
- package/dist/worker/observe/static/relations.js +7 -7
- package/dist/worker/observe/static/router.d.ts +12 -1
- package/dist/worker/observe/static/router.js +48 -6
- package/dist/worker/observe/static/run-processing.js +4 -2
- package/dist/worker/observe/static/shell-chrome.js +2 -2
- package/dist/worker/observe/static/state.js +5 -0
- package/dist/worker/observe/static/styles.css +231 -0
- package/dist/worker/observe/static/views/dag-graph.js +1 -1
- package/dist/worker/observe/static/views/dag-inspector.js +336 -181
- package/dist/worker/observe/static/views/dag.js +26 -14
- package/dist/worker/observe/static/views/dags.js +3 -1
- package/dist/worker/observe/static/views/dashboard.js +14 -6
- package/dist/worker/observe/static/views/pool.js +7 -2
- package/dist/worker/observe/static/views/run.js +12 -3
- package/dist/worker/observe/static/views/session-timeline.js +74 -13
- package/dist/worker/observe/static/views/task.js +7 -2
- package/dist/workflows/dag/backend-test-case-coverage-analysis.js +215 -28
- package/dist/workflows/dag/backend-test-markdown-workflow.js +13 -1
- package/dist/workflows/dag/backend-test-plan-protocol.js +210 -0
- package/dist/workflows/dag/backend-test-scenario-param.js +172 -25
- package/dist/workflows/dag/backend-test-scenario-partitions.js +62 -1
- package/dist/workflows/dag/backend-test-writer-completeness.js +104 -12
- package/dist/workflows/dag/contract-validator-registrations.js +1 -2
- package/dist/workflows/dag/dag-retry-schema.js +138 -0
- package/dist/workflows/dag/frontend-closeout.js +221 -0
- package/dist/workflows/dag/frontend-design-policy.js +400 -0
- package/dist/workflows/dag/frontend-human-decision.js +182 -0
- package/dist/workflows/dag/frontend-implementation-contract.js +1237 -192
- package/dist/workflows/dag/frontend-plan-render.js +2 -1
- package/dist/workflows/dag/frontend-prewrite-gate.js +256 -350
- package/dist/workflows/dag/frontend-provider-capability-matrix.js +159 -0
- package/dist/workflows/dag/frontend-recovery-capsule.js +455 -0
- package/dist/workflows/dag/frontend-recovery-controller.js +226 -0
- package/dist/workflows/dag/frontend-recovery-lineage.js +178 -0
- package/dist/workflows/dag/frontend-recovery-plan.js +21 -10
- package/dist/workflows/dag/frontend-recovery-run.js +166 -34
- package/dist/workflows/dag/frontend-repair.js +1 -432
- package/dist/workflows/dag/frontend-review-context.js +261 -15
- package/dist/workflows/dag/frontend-review-findings.js +270 -0
- package/dist/workflows/dag/frontend-shadow-dual-write.js +941 -0
- package/dist/workflows/dag/frontend-shape-capsule-store.js +191 -0
- package/dist/workflows/dag/frontend-shape-facts.js +419 -0
- package/dist/workflows/dag/frontend-shape.js +435 -0
- package/dist/workflows/dag/frontend-source-fidelity-ledger.js +108 -0
- package/dist/workflows/dag/frontend-split-application-service.js +203 -0
- package/dist/workflows/dag/frontend-split-orchestrator.js +899 -0
- package/dist/workflows/dag/frontend-typed-event-store.js +452 -0
- package/dist/workflows/dag/frontend-typed-event-transaction.js +180 -0
- package/dist/workflows/dag/frontend-verification-trace.js +252 -25
- package/dist/workflows/dag/frontend-worktree-diff.js +250 -17
- package/dist/workflows/dag/frontend-writer-admission.js +319 -0
- package/dist/workflows/dag/frontend-writer-status.js +256 -0
- package/dist/workflows/dag/init-hybrid.js +1031 -564
- package/dist/workflows/dag/interrupt-request.js +7 -0
- package/dist/workflows/dag/node-execution.js +854 -4
- package/dist/workflows/dag/prompt.js +70 -3
- package/dist/workflows/dag/recovery-lease.js +170 -0
- package/dist/workflows/dag/report.js +37 -1
- package/dist/workflows/dag/rerun-feedback.js +315 -1
- package/dist/workflows/dag/rerun-plan.js +17 -6
- package/dist/workflows/dag/rerun-run.js +44 -6
- package/dist/workflows/dag/rerun-task.js +251 -13
- package/dist/workflows/dag/retry-policy.js +230 -104
- package/dist/workflows/dag/runner.js +580 -124
- package/dist/workflows/dag/scheduler.js +133 -20
- package/dist/workflows/dag/types.js +244 -16
- package/dist/workflows/dag/validate.js +28 -12
- package/docs/examples/README.md +5 -0
- package/docs/init-surface.manifest.json +30 -12
- package/docs/skills/vetted-skill-registry.md +4 -2
- package/docs/templates/README.md +2 -0
- package/docs/templates/agent-dag-report.schema.json +8 -2
- package/docs/templates/agent-dag.schema.json +1 -1
- package/docs/templates/backend-test-dag.json +25 -20
- package/docs/templates/frontend-implementation-contract.schema.json +4 -1
- package/docs/templates/frontend-implementation-dag.json +89 -0
- package/docs/templates/spec-registry.schema.json +45 -0
- package/harness.json +1 -1
- package/package.json +4 -3
- package/skills/frontend-bounded-implement/SKILL.md +15 -14
- package/skills/frontend-bounded-implement/references/code-standards.md +19 -0
- package/skills/frontend-contract/SKILL.md +23 -0
- package/skills/frontend-contract/references/contract-protocol.md +34 -0
- package/skills/frontend-design-review/SKILL.md +22 -41
- package/skills/frontend-plan/SKILL.md +26 -0
- package/skills/frontend-plan/references/decision-contract.md +37 -0
- package/skills/frontend-plan/references/design-decisions.md +17 -0
- package/skills/frontend-review/SKILL.md +20 -15
- package/skills/frontend-review/references/review-findings.md +6 -7
- package/skills/frontend-scout/SKILL.md +25 -0
- package/skills/frontend-scout/references/design-evidence.md +16 -0
- package/skills/frontend-scout/references/scout-evidence.md +23 -0
- package/skills/frontend-verification/SKILL.md +1 -1
- package/skills/loop-agent/references/command-reference.md +1 -0
- package/skills/loop-agent/references/hybrid-dag.md +2 -2
- package/dist/worker/console/static/assets/channel-BU5gOilw.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DIzKJGHr.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DIzKJGHr.js +0 -1
- package/dist/worker/console/static/assets/index-H9rFJiGL.css +0 -1
- package/dist/worker/console/static/assets/index-xwu9GxEc.js +0 -451
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-Cld2qK9v.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-TIHpiT7w.js +0 -8
- package/skills/frontend-implementation/SKILL.md +0 -52
- package/skills/frontend-implementation/references/code-standards.md +0 -33
- package/skills/frontend-implementation/references/design-spec.md +0 -56
- package/skills/frontend-implementation/references/node-contracts.md +0 -31
|
@@ -1,61 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { projectProtocolFailureReason, } from "./frontend-recovery-capsule.js";
|
|
2
|
+
import { TYPED_EVENT_FACT_KINDS } from "./frontend-typed-event-store.js";
|
|
2
3
|
/**
|
|
3
|
-
* Failure
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* `quota` is intentionally NOT included: a quota exhaustion is an account
|
|
10
|
-
* billing/plan state, not a transient rate limit, and retrying immediately
|
|
11
|
-
* will not help and may waste budget.
|
|
12
|
-
*/
|
|
13
|
-
export const DEFAULT_DAG_RETRY_CATEGORIES = [
|
|
14
|
-
"timeout",
|
|
15
|
-
"network",
|
|
16
|
-
"rate-limit",
|
|
17
|
-
"unavailable",
|
|
18
|
-
"empty-output",
|
|
19
|
-
];
|
|
20
|
-
export const STRUCTURED_OUTPUT_RETRY_CATEGORY = "output-too-large";
|
|
21
|
-
export const PROTOCOL_INVALID_RETRY_CATEGORY = "protocol-invalid";
|
|
22
|
-
/** Recoverable model artifact/schema formatting failure on read-only structured nodes. */
|
|
23
|
-
export const STRUCTURED_ARTIFACT_INVALID_RETRY_CATEGORY = "invalid-output";
|
|
24
|
-
/** Provider stopReason=length truncated the response before the JSON contract completed. */
|
|
25
|
-
export const STRUCTURED_OUTPUT_TRUNCATED_RETRY_CATEGORY = "structured-output-truncated";
|
|
26
|
-
/** Retry only a proven no-op from an explicitly opt-in bounded Pi writer. */
|
|
27
|
-
export const WRITER_EMPTY_DIFF_RETRY_CATEGORY = "writer-empty-diff";
|
|
28
|
-
/** Retry when a backend-test writer finished but Completeness Gate found missing/broken targets. */
|
|
29
|
-
export const INCOMPLETE_WRITE_SET_RETRY_CATEGORY = "incomplete-write-set";
|
|
30
|
-
/**
|
|
31
|
-
* Provider/transport stall or absolute timeout on a Pi exclusive writer that
|
|
32
|
-
* left zero attributed workspace writes and zero write-tool calls. Safe to
|
|
33
|
-
* retry once because the attempt was a pure provider flake (no side effects).
|
|
34
|
-
* Partial writes keep the original `timeout` category and do NOT retry.
|
|
4
|
+
* Failure-category constants, the zod retry-policy schema, and the
|
|
5
|
+
* target-template transient retry profile live in the leaf module
|
|
6
|
+
* `dag-retry-schema.ts` (see its header for the cycle rationale). Everything
|
|
7
|
+
* is re-exported here unchanged so retry-policy stays the single import
|
|
8
|
+
* surface for retry policies and helpers.
|
|
35
9
|
*/
|
|
36
|
-
export
|
|
37
|
-
|
|
38
|
-
...DEFAULT_DAG_RETRY_CATEGORIES,
|
|
39
|
-
STRUCTURED_OUTPUT_RETRY_CATEGORY,
|
|
40
|
-
STRUCTURED_ARTIFACT_INVALID_RETRY_CATEGORY,
|
|
41
|
-
STRUCTURED_OUTPUT_TRUNCATED_RETRY_CATEGORY,
|
|
42
|
-
];
|
|
43
|
-
/** Categories allowed on nodes that declare a machine-readable outputProtocol. */
|
|
44
|
-
export const PROTOCOL_AWARE_DAG_RETRY_CATEGORIES = [
|
|
45
|
-
...DEFAULT_DAG_RETRY_CATEGORIES,
|
|
46
|
-
PROTOCOL_INVALID_RETRY_CATEGORY,
|
|
47
|
-
STRUCTURED_ARTIFACT_INVALID_RETRY_CATEGORY,
|
|
48
|
-
];
|
|
49
|
-
export const ALL_DAG_RETRY_CATEGORIES = [
|
|
50
|
-
...DEFAULT_DAG_RETRY_CATEGORIES,
|
|
51
|
-
STRUCTURED_OUTPUT_RETRY_CATEGORY,
|
|
52
|
-
PROTOCOL_INVALID_RETRY_CATEGORY,
|
|
53
|
-
STRUCTURED_ARTIFACT_INVALID_RETRY_CATEGORY,
|
|
54
|
-
STRUCTURED_OUTPUT_TRUNCATED_RETRY_CATEGORY,
|
|
55
|
-
WRITER_EMPTY_DIFF_RETRY_CATEGORY,
|
|
56
|
-
INCOMPLETE_WRITE_SET_RETRY_CATEGORY,
|
|
57
|
-
WRITER_CLEAN_TIMEOUT_RETRY_CATEGORY,
|
|
58
|
-
];
|
|
10
|
+
export { ALL_DAG_RETRY_CATEGORIES, CONTEXT_OVERFLOW_RETRY_CATEGORY, DEFAULT_DAG_RETRY_CATEGORIES, INCOMPLETE_WRITE_SET_RETRY_CATEGORY, PROTOCOL_AWARE_DAG_RETRY_CATEGORIES, PROTOCOL_INVALID_RETRY_CATEGORY, READ_BURST_RETRY_CATEGORY, REVIEW_TERMINAL_MISSING_RETRY_CATEGORY, STRUCTURED_ARTIFACT_INVALID_RETRY_CATEGORY, STRUCTURED_OUTPUT_RETRY_CATEGORY, STRUCTURED_OUTPUT_TRUNCATED_RETRY_CATEGORY, STRUCTURED_REQUIRED_DAG_RETRY_CATEGORIES, TARGET_TEMPLATE_TRANSIENT_RETRY_PROFILE, WRITER_CLEAN_TIMEOUT_RETRY_CATEGORY, WRITER_EMPTY_DIFF_RETRY_CATEGORY, dagRetryBackoffSchema, dagRetryCategorySchema, dagRetryPolicySchema, } from "./dag-retry-schema.js";
|
|
11
|
+
import { CONTEXT_OVERFLOW_RETRY_CATEGORY, DEFAULT_DAG_RETRY_CATEGORIES, INCOMPLETE_WRITE_SET_RETRY_CATEGORY, PROTOCOL_AWARE_DAG_RETRY_CATEGORIES, READ_BURST_RETRY_CATEGORY, REVIEW_TERMINAL_MISSING_RETRY_CATEGORY, STRUCTURED_ARTIFACT_INVALID_RETRY_CATEGORY, STRUCTURED_OUTPUT_RETRY_CATEGORY, STRUCTURED_REQUIRED_DAG_RETRY_CATEGORIES, TARGET_TEMPLATE_TRANSIENT_RETRY_PROFILE, WRITER_CLEAN_TIMEOUT_RETRY_CATEGORY, WRITER_EMPTY_DIFF_RETRY_CATEGORY, } from "./dag-retry-schema.js";
|
|
59
12
|
const RETRY_SAFE_PI_ROLES = new Set([
|
|
60
13
|
"planner",
|
|
61
14
|
"scout",
|
|
@@ -64,53 +17,38 @@ const RETRY_SAFE_PI_ROLES = new Set([
|
|
|
64
17
|
"supervisor",
|
|
65
18
|
"closeout",
|
|
66
19
|
]);
|
|
67
|
-
export const dagRetryCategorySchema = z.enum(ALL_DAG_RETRY_CATEGORIES);
|
|
68
|
-
export const dagRetryBackoffSchema = z.enum(["exponential"]);
|
|
69
|
-
/**
|
|
70
|
-
* Opt-in retry policy for a DagTask. Generated for safe read-only Pi nodes,
|
|
71
|
-
* except the single validation-gated writer-empty-diff policy. Validation
|
|
72
|
-
* rejects all other writers, dynamic, shell, static, and decision-gate nodes.
|
|
73
|
-
*/
|
|
74
|
-
export const dagRetryPolicySchema = z
|
|
75
|
-
.object({
|
|
76
|
-
/**
|
|
77
|
-
* Total number of attempts (including the first try). Must be 1..5.
|
|
78
|
-
* A value of 1 disables retry (one attempt, no retry).
|
|
79
|
-
*/
|
|
80
|
-
maxAttempts: z.number().int().positive().max(5),
|
|
81
|
-
backoff: dagRetryBackoffSchema.default("exponential"),
|
|
82
|
-
/** Initial delay before the second attempt, in milliseconds. */
|
|
83
|
-
initialDelayMs: z.number().int().nonnegative().default(2000),
|
|
84
|
-
/** Upper bound on a single backoff delay, in milliseconds. */
|
|
85
|
-
maxDelayMs: z.number().int().nonnegative().default(30000),
|
|
86
|
-
/**
|
|
87
|
-
* Explicit set of failure categories eligible for retry. Defaults to
|
|
88
|
-
* {@link DEFAULT_DAG_RETRY_CATEGORIES}. `quota` and other categories
|
|
89
|
-
* are never retried.
|
|
90
|
-
*/
|
|
91
|
-
retryCategories: z
|
|
92
|
-
.array(dagRetryCategorySchema)
|
|
93
|
-
.default([...DEFAULT_DAG_RETRY_CATEGORIES]),
|
|
94
|
-
})
|
|
95
|
-
.superRefine((policy, ctx) => {
|
|
96
|
-
if (policy.maxDelayMs < policy.initialDelayMs) {
|
|
97
|
-
ctx.addIssue({
|
|
98
|
-
code: z.ZodIssueCode.custom,
|
|
99
|
-
message: "retryPolicy.maxDelayMs must be >= retryPolicy.initialDelayMs",
|
|
100
|
-
path: ["maxDelayMs"],
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
20
|
/**
|
|
105
21
|
* The default retry policy applied to safe generated read-only Pi nodes.
|
|
106
22
|
* Total attempts: 3, exponential backoff with cap.
|
|
23
|
+
*
|
|
24
|
+
* Includes `context-overflow`: a read-only node that blew the context window
|
|
25
|
+
* (400 request too large, e.g. a review node accumulating too many reads) is a
|
|
26
|
+
* transient, safe-to-retry failure — the retry re-runs the node with a
|
|
27
|
+
* compact-context instruction instead of failing the whole run. Previously
|
|
28
|
+
* only writer transport policies had context-overflow; contract/scout/
|
|
29
|
+
* design-review/review fell straight to ERROR without a retry attempt.
|
|
107
30
|
*/
|
|
108
31
|
export const DEFAULT_READ_ONLY_PI_RETRY_POLICY = {
|
|
109
32
|
maxAttempts: 3,
|
|
110
33
|
backoff: "exponential",
|
|
111
34
|
initialDelayMs: 2000,
|
|
112
35
|
maxDelayMs: 30000,
|
|
113
|
-
retryCategories: [
|
|
36
|
+
retryCategories: [
|
|
37
|
+
...DEFAULT_DAG_RETRY_CATEGORIES,
|
|
38
|
+
READ_BURST_RETRY_CATEGORY,
|
|
39
|
+
CONTEXT_OVERFLOW_RETRY_CATEGORY,
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
/** Scout is the discovery authority. A missing/incomplete typed target surface
|
|
43
|
+
* is safe to retry in-node, rather than making Plan rediscover the repository. */
|
|
44
|
+
export const FRONTEND_SCOUT_COMPLETENESS_RETRY_POLICY = {
|
|
45
|
+
...DEFAULT_READ_ONLY_PI_RETRY_POLICY,
|
|
46
|
+
retryCategories: [
|
|
47
|
+
...DEFAULT_DAG_RETRY_CATEGORIES,
|
|
48
|
+
STRUCTURED_ARTIFACT_INVALID_RETRY_CATEGORY,
|
|
49
|
+
READ_BURST_RETRY_CATEGORY,
|
|
50
|
+
CONTEXT_OVERFLOW_RETRY_CATEGORY,
|
|
51
|
+
],
|
|
114
52
|
};
|
|
115
53
|
/**
|
|
116
54
|
* Structured planner nodes may retry with a compact-output instruction
|
|
@@ -120,7 +58,11 @@ export const DEFAULT_READ_ONLY_PI_RETRY_POLICY = {
|
|
|
120
58
|
*/
|
|
121
59
|
export const STRUCTURED_REQUIRED_PI_RETRY_POLICY = {
|
|
122
60
|
...DEFAULT_READ_ONLY_PI_RETRY_POLICY,
|
|
123
|
-
retryCategories: [
|
|
61
|
+
retryCategories: [
|
|
62
|
+
...STRUCTURED_REQUIRED_DAG_RETRY_CATEGORIES,
|
|
63
|
+
READ_BURST_RETRY_CATEGORY,
|
|
64
|
+
CONTEXT_OVERFLOW_RETRY_CATEGORY,
|
|
65
|
+
],
|
|
124
66
|
};
|
|
125
67
|
/**
|
|
126
68
|
* Planner read-only nodes (standard DAG contract-pi / plan-pi) may retry with
|
|
@@ -131,7 +73,23 @@ export const STRUCTURED_REQUIRED_PI_RETRY_POLICY = {
|
|
|
131
73
|
*/
|
|
132
74
|
export const PLANNER_OUTPUT_LIMIT_RETRY_POLICY = {
|
|
133
75
|
...DEFAULT_READ_ONLY_PI_RETRY_POLICY,
|
|
134
|
-
retryCategories: [
|
|
76
|
+
retryCategories: [
|
|
77
|
+
...DEFAULT_DAG_RETRY_CATEGORIES,
|
|
78
|
+
STRUCTURED_OUTPUT_RETRY_CATEGORY,
|
|
79
|
+
READ_BURST_RETRY_CATEGORY,
|
|
80
|
+
CONTEXT_OVERFLOW_RETRY_CATEGORY,
|
|
81
|
+
],
|
|
82
|
+
};
|
|
83
|
+
/** Backend-test N2 emits a mandatory run-owned Markdown protocol, so both
|
|
84
|
+
* provider length truncation and deterministic protocol validation failures
|
|
85
|
+
* are safe producer-local retries. */
|
|
86
|
+
export const BACKEND_TEST_MD_PLAN_RETRY_POLICY = {
|
|
87
|
+
...STRUCTURED_REQUIRED_PI_RETRY_POLICY,
|
|
88
|
+
retryCategories: [
|
|
89
|
+
...STRUCTURED_REQUIRED_DAG_RETRY_CATEGORIES,
|
|
90
|
+
READ_BURST_RETRY_CATEGORY,
|
|
91
|
+
CONTEXT_OVERFLOW_RETRY_CATEGORY,
|
|
92
|
+
],
|
|
135
93
|
};
|
|
136
94
|
/**
|
|
137
95
|
* Default retry for reviewer / recovery nodes that declare outputProtocol.
|
|
@@ -141,6 +99,22 @@ export const PROTOCOL_AWARE_PI_RETRY_POLICY = {
|
|
|
141
99
|
...DEFAULT_READ_ONLY_PI_RETRY_POLICY,
|
|
142
100
|
retryCategories: [...PROTOCOL_AWARE_DAG_RETRY_CATEGORIES],
|
|
143
101
|
};
|
|
102
|
+
/**
|
|
103
|
+
* frontend-review-pi retry policy. The review verdict must be committed
|
|
104
|
+
* through the typed terminal tools (approve_review / request_review_changes);
|
|
105
|
+
* a model that only echoes "VERDICT: pass" text fails as
|
|
106
|
+
* review-terminal-missing. That is read-only and safe to retry with a
|
|
107
|
+
* corrected instruction so a single model slip does not burn the whole run.
|
|
108
|
+
*/
|
|
109
|
+
export const FRONTEND_REVIEW_TERMINAL_RETRY_POLICY = {
|
|
110
|
+
...DEFAULT_READ_ONLY_PI_RETRY_POLICY,
|
|
111
|
+
retryCategories: [
|
|
112
|
+
...DEFAULT_DAG_RETRY_CATEGORIES,
|
|
113
|
+
READ_BURST_RETRY_CATEGORY,
|
|
114
|
+
CONTEXT_OVERFLOW_RETRY_CATEGORY,
|
|
115
|
+
REVIEW_TERMINAL_MISSING_RETRY_CATEGORY,
|
|
116
|
+
],
|
|
117
|
+
};
|
|
144
118
|
/**
|
|
145
119
|
* The sole writer retry policy for requireChangedFiles writers. It is
|
|
146
120
|
* intentionally not included in any read-only default: a writer may retry only
|
|
@@ -163,7 +137,10 @@ export const WRITER_TRANSPORT_RETRY_POLICY = {
|
|
|
163
137
|
backoff: "exponential",
|
|
164
138
|
initialDelayMs: 5000,
|
|
165
139
|
maxDelayMs: 30000,
|
|
166
|
-
retryCategories: [
|
|
140
|
+
retryCategories: [
|
|
141
|
+
WRITER_CLEAN_TIMEOUT_RETRY_CATEGORY,
|
|
142
|
+
CONTEXT_OVERFLOW_RETRY_CATEGORY,
|
|
143
|
+
],
|
|
167
144
|
};
|
|
168
145
|
/**
|
|
169
146
|
* Implicit runtime retry for canonical final verify shells. Not a DagRetryPolicy:
|
|
@@ -182,18 +159,23 @@ export const VERIFY_SHELL_RETRY_POLICY = {
|
|
|
182
159
|
maxDelayMs: 30000,
|
|
183
160
|
retryCategories: VERIFY_SHELL_RETRY_CATEGORIES,
|
|
184
161
|
};
|
|
185
|
-
export const TARGET_TEMPLATE_TRANSIENT_RETRY_PROFILE = "standard-reviewed-supervised-v1";
|
|
186
162
|
/**
|
|
187
163
|
* Target-template exclusive implement-pi transport retry. Same schema category
|
|
188
164
|
* as frontend (`writer-clean-timeout`) so DagSpec validation stays unchanged;
|
|
189
|
-
* only the delay cap is wider.
|
|
165
|
+
* only the delay cap is wider. Context overflow is added so a writer whose
|
|
166
|
+
* session hit the context window (compact+retry inside the SDK) can retry once
|
|
167
|
+
* more at the DAG level with a fresh attempt. Do not mutate
|
|
168
|
+
* {@link WRITER_TRANSPORT_RETRY_POLICY}.
|
|
190
169
|
*/
|
|
191
170
|
export const TARGET_TEMPLATE_WRITER_TRANSPORT_RETRY_POLICY = {
|
|
192
171
|
maxAttempts: 2,
|
|
193
172
|
backoff: "exponential",
|
|
194
173
|
initialDelayMs: 5000,
|
|
195
174
|
maxDelayMs: 60000,
|
|
196
|
-
retryCategories: [
|
|
175
|
+
retryCategories: [
|
|
176
|
+
WRITER_CLEAN_TIMEOUT_RETRY_CATEGORY,
|
|
177
|
+
CONTEXT_OVERFLOW_RETRY_CATEGORY,
|
|
178
|
+
],
|
|
197
179
|
};
|
|
198
180
|
/**
|
|
199
181
|
* Backend-test generation writers: empty-diff once, plus bounded incomplete-write-set
|
|
@@ -209,6 +191,11 @@ export const BACKEND_TEST_WRITER_COMPLETENESS_RETRY_POLICY = {
|
|
|
209
191
|
INCOMPLETE_WRITE_SET_RETRY_CATEGORY,
|
|
210
192
|
],
|
|
211
193
|
};
|
|
194
|
+
/** Markdown shard writers use one full attempt plus at most one bounded binding repair. */
|
|
195
|
+
export const BACKEND_TEST_MARKDOWN_BINDING_RETRY_POLICY = {
|
|
196
|
+
...BACKEND_TEST_WRITER_COMPLETENESS_RETRY_POLICY,
|
|
197
|
+
maxAttempts: 2,
|
|
198
|
+
};
|
|
212
199
|
/**
|
|
213
200
|
* Deterministic helper: is this raw failure category eligible for retry under
|
|
214
201
|
* the given policy? Pure function; executor never decides retry eligibility.
|
|
@@ -259,13 +246,14 @@ export function isWriterEmptyDiffRetryCandidate(task) {
|
|
|
259
246
|
task.writerOutcomePolicy?.requireChangedFiles === true);
|
|
260
247
|
}
|
|
261
248
|
/**
|
|
262
|
-
* Standard exclusive implementers (implementation-outcome
|
|
263
|
-
* single clean-timeout transport retry. Backend
|
|
264
|
-
* have their own policy and are excluded here.
|
|
249
|
+
* Standard exclusive implementers (implementation-outcome and frontend-facts
|
|
250
|
+
* writers) may take a single clean-timeout transport retry. Backend
|
|
251
|
+
* completeness writers already have their own policy and are excluded here.
|
|
265
252
|
*/
|
|
266
253
|
export function isWriterTransportRetryCandidate(task) {
|
|
267
254
|
return (isExclusivePiImplementer(task) &&
|
|
268
|
-
task.writerOutcomePolicy?.type === "implementation-outcome-v1"
|
|
255
|
+
(task.writerOutcomePolicy?.type === "implementation-outcome-v1" ||
|
|
256
|
+
task.writerOutcomePolicy?.type === "frontend-facts-v1") &&
|
|
269
257
|
task.writerOutcomePolicy.requireChangedFiles !== true);
|
|
270
258
|
}
|
|
271
259
|
/**
|
|
@@ -370,3 +358,141 @@ export function computeBackoffDelayMs(attemptNumber, policy) {
|
|
|
370
358
|
const raw = policy.initialDelayMs * 2 ** exponent;
|
|
371
359
|
return Math.min(raw, policy.maxDelayMs);
|
|
372
360
|
}
|
|
361
|
+
/**
|
|
362
|
+
* A+B (AC-001/AC-005): project raw executor signals to the canonical 7-value
|
|
363
|
+
* protocol failure reason. Specific signals win first, then the existing
|
|
364
|
+
* alias/enum passthrough; unknown signals fail closed to `undefined`.
|
|
365
|
+
*/
|
|
366
|
+
export function projectFrontendNodeProtocolFailureReason(input) {
|
|
367
|
+
// 1. length stop reason without a terminal → length-before-terminal.
|
|
368
|
+
if (input.stopReason === "length" && input.hasTerminalFact === false) {
|
|
369
|
+
return "length-before-terminal";
|
|
370
|
+
}
|
|
371
|
+
// 2. timeout with reasoning-side evidence → reasoning-timeout.
|
|
372
|
+
if (input.failureCategory === "timeout" &&
|
|
373
|
+
/(?:reasoning|thinking|thought)/i.test(input.assistantText ?? "")) {
|
|
374
|
+
return "reasoning-timeout";
|
|
375
|
+
}
|
|
376
|
+
// 3. empty output without a terminal → provider-ended-without-terminal.
|
|
377
|
+
if (input.failureCategory === "empty-output" &&
|
|
378
|
+
input.hasTerminalFact === false) {
|
|
379
|
+
return "provider-ended-without-terminal";
|
|
380
|
+
}
|
|
381
|
+
// 4. Alias/enum passthrough; unknown fails closed to undefined.
|
|
382
|
+
return projectProtocolFailureReason(input.failureCategory ?? "");
|
|
383
|
+
}
|
|
384
|
+
export const FRONTEND_PLAN_LADDER = [
|
|
385
|
+
"normal",
|
|
386
|
+
"compact-terminal-first",
|
|
387
|
+
"bounded-tool-only",
|
|
388
|
+
"backup-model",
|
|
389
|
+
];
|
|
390
|
+
/**
|
|
391
|
+
* Map a 7-value protocol failure reason to the closest provider capability
|
|
392
|
+
* fact kind for backup-model routing. `unsupported-tool-capability` is a
|
|
393
|
+
* protocol reason, not a provider capability kind, so it is deliberately NOT
|
|
394
|
+
* a valid route (fail-closed to `unsupported-provider-capability`).
|
|
395
|
+
*/
|
|
396
|
+
export function frontendPlanProtocolReasonToCapabilityKind(reason) {
|
|
397
|
+
switch (reason) {
|
|
398
|
+
case "length-before-terminal":
|
|
399
|
+
return "length-before-terminal";
|
|
400
|
+
case "reasoning-timeout":
|
|
401
|
+
return "reasoning-timeout";
|
|
402
|
+
case "provider-ended-without-terminal":
|
|
403
|
+
return "provider-ended-without-terminal";
|
|
404
|
+
case "terminal-event-missing":
|
|
405
|
+
case "terminal-conflict":
|
|
406
|
+
return "terminal-commit";
|
|
407
|
+
case "typed-fact-invalid":
|
|
408
|
+
return "read-only-fact-channel";
|
|
409
|
+
case "unsupported-tool-capability":
|
|
410
|
+
return "unsupported-tool-capability";
|
|
411
|
+
default:
|
|
412
|
+
return undefined;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* A+B (AC-003): resolve a backup-model route against the frozen seven-kind
|
|
417
|
+
* provider capability catalog (the exact set `routeFrontendProviderCapability`
|
|
418
|
+
* consults). `unsupported-tool-capability` is a protocol reason, not a
|
|
419
|
+
* provider capability kind, so it (and any unmapped reason) fails closed to
|
|
420
|
+
* `unsupported-provider-capability` — never swapped for the 7-value reason.
|
|
421
|
+
*/
|
|
422
|
+
export function resolveFrontendPlanBackupRoute(reason) {
|
|
423
|
+
const factKind = frontendPlanProtocolReasonToCapabilityKind(reason);
|
|
424
|
+
if (!factKind) {
|
|
425
|
+
return { ok: false, reason: "unsupported-provider-capability" };
|
|
426
|
+
}
|
|
427
|
+
return TYPED_EVENT_FACT_KINDS.includes(factKind)
|
|
428
|
+
? { ok: true, factKind }
|
|
429
|
+
: { ok: false, reason: "unsupported-provider-capability" };
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* A+B (AC-002): deterministic ladder resolution. Reason-mandated upgrades
|
|
433
|
+
* (length → compact-terminal-first; terminal/timeout/empty → bounded-tool-only)
|
|
434
|
+
* never regress below the current rung. A repeated failure fingerprint with no
|
|
435
|
+
* new committed fact escalates one rung instead of re-running the same step;
|
|
436
|
+
* at `backup-model` that becomes `non-converging`, and an unavailable backup
|
|
437
|
+
* provider route fails closed to `unsupported-provider-capability`.
|
|
438
|
+
*/
|
|
439
|
+
export function resolveFrontendPlanRetryStep(input) {
|
|
440
|
+
if (input.currentStep === "non-converging" ||
|
|
441
|
+
input.currentStep === "unsupported-provider-capability") {
|
|
442
|
+
return input.currentStep;
|
|
443
|
+
}
|
|
444
|
+
const currentIndex = FRONTEND_PLAN_LADDER.indexOf(input.currentStep);
|
|
445
|
+
const reasonStep = reasonMandatedFrontendPlanRetryStep(input.protocolFailureReason);
|
|
446
|
+
const reasonIndex = reasonStep
|
|
447
|
+
? FRONTEND_PLAN_LADDER.indexOf(reasonStep)
|
|
448
|
+
: -1;
|
|
449
|
+
let nextIndex = Math.max(currentIndex, reasonIndex);
|
|
450
|
+
const repeated = input.priorFingerprints.includes(input.fingerprint);
|
|
451
|
+
if (repeated && !input.hasNewCommittedFact) {
|
|
452
|
+
nextIndex = Math.max(nextIndex, currentIndex + 1);
|
|
453
|
+
}
|
|
454
|
+
const nextStep = nextIndex >= FRONTEND_PLAN_LADDER.length
|
|
455
|
+
? "non-converging"
|
|
456
|
+
: (FRONTEND_PLAN_LADDER[nextIndex] ?? "non-converging");
|
|
457
|
+
if (nextStep === "backup-model" && input.backupRouteAvailable === false) {
|
|
458
|
+
return "unsupported-provider-capability";
|
|
459
|
+
}
|
|
460
|
+
return nextStep;
|
|
461
|
+
}
|
|
462
|
+
function reasonMandatedFrontendPlanRetryStep(reason) {
|
|
463
|
+
switch (reason) {
|
|
464
|
+
case "length-before-terminal":
|
|
465
|
+
return "compact-terminal-first";
|
|
466
|
+
case "terminal-event-missing":
|
|
467
|
+
case "reasoning-timeout":
|
|
468
|
+
case "provider-ended-without-terminal":
|
|
469
|
+
return "bounded-tool-only";
|
|
470
|
+
default:
|
|
471
|
+
return undefined;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Opt-in retry policy mounted on the frontend-plan-pi node. maxAttempts=3
|
|
476
|
+
* bounds plan retry cost: the four-rung ladder is only partially traversable
|
|
477
|
+
* before the run fails non-converging (rungs: normal → bounded-tool-only →
|
|
478
|
+
* compact-terminal-first → backup-model). `invalid-output` (typed-fact schema
|
|
479
|
+
* violations, e.g. verification targets referencing undeclared UI states)
|
|
480
|
+
* retries at the `normal` rung with the contractCheck reason injected via
|
|
481
|
+
* `<retry_instruction>` (§5.1 ladder).
|
|
482
|
+
*/
|
|
483
|
+
export const FRONTEND_PLAN_LADDER_RETRY_POLICY = {
|
|
484
|
+
// Extreme-environment (small output window) plan nodes submit dozens of
|
|
485
|
+
// incremental record_* calls; dense call bursts hit provider rate limits
|
|
486
|
+
// whose windows exceed the old 30s cap. Longer backoff gives the limit
|
|
487
|
+
// window time to expire before the next attempt.
|
|
488
|
+
maxAttempts: 3,
|
|
489
|
+
backoff: "exponential",
|
|
490
|
+
initialDelayMs: 5000,
|
|
491
|
+
maxDelayMs: 60000,
|
|
492
|
+
retryCategories: [
|
|
493
|
+
...DEFAULT_DAG_RETRY_CATEGORIES,
|
|
494
|
+
STRUCTURED_ARTIFACT_INVALID_RETRY_CATEGORY,
|
|
495
|
+
READ_BURST_RETRY_CATEGORY,
|
|
496
|
+
CONTEXT_OVERFLOW_RETRY_CATEGORY,
|
|
497
|
+
],
|
|
498
|
+
};
|