@mjasnikovs/pi-task 0.38.28 → 0.38.30
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/dist/config/config.d.ts +70 -70
- package/dist/config/config.js +26 -35
- package/dist/config/extension-list.d.ts +6 -5
- package/dist/config/extension-list.js +3 -2
- package/dist/config/reasoning-args.d.ts +9 -7
- package/dist/config/reasoning-args.js +12 -10
- package/dist/config/reasoning.d.ts +44 -105
- package/dist/config/reasoning.js +27 -704
- package/dist/config/register.d.ts +34 -48
- package/dist/config/register.js +41 -51
- package/dist/config/tool-list.d.ts +16 -16
- package/dist/config/tool-list.js +1 -1
- package/dist/remote/bridge.d.ts +19 -10
- package/dist/remote/bridge.js +3 -2
- package/dist/remote/broadcast.js +3 -1
- package/dist/remote/events.js +12 -11
- package/dist/remote/history.d.ts +1 -1
- package/dist/remote/protocol.d.ts +6 -3
- package/dist/remote/protocol.js +2 -1
- package/dist/remote/push.d.ts +16 -16
- package/dist/remote/push.js +27 -27
- package/dist/remote/register.d.ts +3 -3
- package/dist/remote/register.js +17 -19
- package/dist/remote/server.d.ts +9 -8
- package/dist/remote/server.js +15 -14
- package/dist/remote/session-state.d.ts +5 -4
- package/dist/remote/session-state.js +8 -5
- package/dist/remote/sw.d.ts +7 -6
- package/dist/remote/sw.js +7 -6
- package/dist/remote/tailscale.d.ts +4 -2
- package/dist/remote/tailscale.js +4 -2
- package/dist/remote/ui-highlight.js +6 -5
- package/dist/remote/ui-render.js +4 -4
- package/dist/remote/ui-script.js +24 -24
- package/dist/remote/ui-styles.d.ts +1 -1
- package/dist/remote/ui-styles.js +10 -13
- package/dist/remote/ui-tools.js +9 -6
- package/dist/shared/child-extensions.d.ts +29 -17
- package/dist/shared/child-extensions.js +29 -17
- package/dist/shared/child-output.d.ts +30 -24
- package/dist/shared/child-output.js +25 -17
- package/dist/shared/child-process.d.ts +47 -40
- package/dist/shared/child-process.js +50 -59
- package/dist/shared/command-watchdog.d.ts +22 -16
- package/dist/shared/command-watchdog.js +28 -21
- package/dist/shared/fs-text.d.ts +16 -10
- package/dist/shared/fs-text.js +16 -10
- package/dist/shared/git-runner.d.ts +25 -25
- package/dist/shared/git-runner.js +25 -25
- package/dist/shared/leaked-tool-call.d.ts +17 -11
- package/dist/shared/leaked-tool-call.js +23 -15
- package/dist/shared/model-endpoint.d.ts +29 -16
- package/dist/shared/model-endpoint.js +33 -21
- package/dist/shared/pi-invocation.d.ts +7 -4
- package/dist/shared/pi-invocation.js +12 -7
- package/dist/shared/pkg-version.d.ts +13 -5
- package/dist/shared/pkg-version.js +13 -5
- package/dist/shared/reasoning-capability.d.ts +35 -24
- package/dist/shared/reasoning-capability.js +35 -24
- package/dist/shared/stream-watchdog.d.ts +60 -44
- package/dist/shared/stream-watchdog.js +62 -45
- package/dist/task/accept-debt.d.ts +41 -43
- package/dist/task/accept-debt.js +73 -65
- package/dist/task/api-synthesis.d.ts +24 -21
- package/dist/task/api-synthesis.js +32 -26
- package/dist/task/apis-contract.d.ts +32 -64
- package/dist/task/apis-contract.js +32 -64
- package/dist/task/artifact-closure.d.ts +27 -13
- package/dist/task/artifact-closure.js +95 -67
- package/dist/task/auto-commit.d.ts +46 -35
- package/dist/task/auto-commit.js +51 -38
- package/dist/task/auto-io.d.ts +45 -25
- package/dist/task/auto-io.js +57 -29
- package/dist/task/auto-orchestrator.d.ts +26 -24
- package/dist/task/auto-orchestrator.js +178 -162
- package/dist/task/auto-prompts.d.ts +36 -24
- package/dist/task/auto-prompts.js +40 -26
- package/dist/task/autofix-ledger.d.ts +27 -25
- package/dist/task/autofix-ledger.js +29 -26
- package/dist/task/batch-test-task.d.ts +20 -12
- package/dist/task/batch-test-task.js +67 -60
- package/dist/task/boot-probe.d.ts +60 -44
- package/dist/task/boot-probe.js +91 -72
- package/dist/task/cancel-input.d.ts +30 -16
- package/dist/task/cancel-input.js +20 -11
- package/dist/task/cancel-points.d.ts +27 -20
- package/dist/task/cancel-points.js +30 -22
- package/dist/task/child-runner.d.ts +46 -51
- package/dist/task/child-runner.js +48 -49
- package/dist/task/child-status.d.ts +23 -16
- package/dist/task/child-status.js +23 -16
- package/dist/task/clamp-output.js +12 -5
- package/dist/task/command-run.d.ts +31 -28
- package/dist/task/command-run.js +44 -35
- package/dist/task/command-shrink.d.ts +25 -18
- package/dist/task/command-shrink.js +37 -31
- package/dist/task/command-watchdog.d.ts +9 -6
- package/dist/task/command-watchdog.js +21 -15
- package/dist/task/context-attribution.d.ts +34 -26
- package/dist/task/context-attribution.js +34 -26
- package/dist/task/context-silence.d.ts +39 -29
- package/dist/task/context-silence.js +35 -25
- package/dist/task/context-usage.d.ts +25 -7
- package/dist/task/context-usage.js +21 -6
- package/dist/task/contracts.d.ts +8 -4
- package/dist/task/contracts.js +25 -17
- package/dist/task/coverage-loop.d.ts +22 -18
- package/dist/task/coverage-loop.js +35 -30
- package/dist/task/critique-probes.d.ts +13 -14
- package/dist/task/critique-probes.js +50 -39
- package/dist/task/debug-log.d.ts +13 -5
- package/dist/task/debug-log.js +32 -20
- package/dist/task/decompose-fidelity.d.ts +11 -9
- package/dist/task/decompose-fidelity.js +38 -33
- package/dist/task/decompose-granularity.d.ts +41 -38
- package/dist/task/decompose-granularity.js +41 -38
- package/dist/task/deep-render-check.d.ts +22 -14
- package/dist/task/deep-render-check.js +40 -31
- package/dist/task/dropped-input.d.ts +12 -7
- package/dist/task/dropped-input.js +5 -2
- package/dist/task/enforce-attribution.d.ts +38 -47
- package/dist/task/enforce-attribution.js +46 -52
- package/dist/task/enforce-guidelines.d.ts +31 -20
- package/dist/task/enforce-guidelines.js +32 -21
- package/dist/task/enrichment.d.ts +7 -2
- package/dist/task/enrichment.js +26 -14
- package/dist/task/env-notes.d.ts +16 -7
- package/dist/task/env-notes.js +48 -31
- package/dist/task/env-template-closure.d.ts +4 -4
- package/dist/task/env-template-closure.js +42 -34
- package/dist/task/external-context.d.ts +28 -21
- package/dist/task/external-context.js +17 -12
- package/dist/task/failure-classifier.d.ts +4 -5
- package/dist/task/failure-classifier.js +6 -7
- package/dist/task/file-inventory.d.ts +15 -11
- package/dist/task/file-inventory.js +25 -22
- package/dist/task/final-gate-fix.d.ts +74 -86
- package/dist/task/final-gate-fix.js +97 -116
- package/dist/task/final-gate-progress.d.ts +29 -46
- package/dist/task/final-gate-progress.js +40 -51
- package/dist/task/final-gate.d.ts +64 -97
- package/dist/task/final-gate.js +192 -199
- package/dist/task/fix-child.d.ts +21 -27
- package/dist/task/fix-child.js +21 -27
- package/dist/task/foreign-path.d.ts +6 -5
- package/dist/task/foreign-path.js +0 -0
- package/dist/task/frozen-conflict.d.ts +9 -10
- package/dist/task/frozen-conflict.js +61 -64
- package/dist/task/frozen-path-guard.d.ts +35 -14
- package/dist/task/frozen-path-guard.js +56 -39
- package/dist/task/gate-child.d.ts +27 -28
- package/dist/task/gate-child.js +37 -35
- package/dist/task/gate-deps.d.ts +34 -27
- package/dist/task/gate-deps.js +169 -159
- package/dist/task/gate-tally.d.ts +77 -80
- package/dist/task/gate-tally.js +65 -68
- package/dist/task/git-state-guard.d.ts +15 -11
- package/dist/task/git-state-guard.js +76 -66
- package/dist/task/impl-widget.d.ts +25 -16
- package/dist/task/impl-widget.js +27 -17
- package/dist/task/implementation-thinking.d.ts +33 -31
- package/dist/task/implementation-thinking.js +5 -6
- package/dist/task/implementation-turn.d.ts +34 -31
- package/dist/task/implementation-turn.js +29 -27
- package/dist/task/inline-markdown.d.ts +20 -7
- package/dist/task/inline-markdown.js +15 -6
- package/dist/task/launch-config-gap.js +25 -39
- package/dist/task/launch-contract.d.ts +18 -21
- package/dist/task/launch-contract.js +28 -30
- package/dist/task/launch-manifest.d.ts +6 -2
- package/dist/task/launch-manifest.js +35 -34
- package/dist/task/ledger.js +16 -14
- package/dist/task/lint-fix.d.ts +6 -8
- package/dist/task/lint-fix.js +67 -69
- package/dist/task/loop-detector.d.ts +9 -8
- package/dist/task/loop-detector.js +16 -12
- package/dist/task/mid-run-input.d.ts +17 -15
- package/dist/task/mid-run-input.js +17 -15
- package/dist/task/orchestrator.d.ts +24 -28
- package/dist/task/orchestrator.js +62 -64
- package/dist/task/orientation.d.ts +18 -23
- package/dist/task/orientation.js +24 -31
- package/dist/task/owned-freeze-conflict.d.ts +21 -20
- package/dist/task/owned-freeze-conflict.js +52 -85
- package/dist/task/owned-freeze-reassign.d.ts +40 -60
- package/dist/task/owned-freeze-reassign.js +41 -61
- package/dist/task/parsers.d.ts +4 -2
- package/dist/task/parsers.js +4 -4
- package/dist/task/phases.d.ts +41 -48
- package/dist/task/phases.js +180 -248
- package/dist/task/plan-io.d.ts +6 -7
- package/dist/task/plan-io.js +6 -7
- package/dist/task/plan-orchestrator.d.ts +10 -8
- package/dist/task/plan-orchestrator.js +14 -10
- package/dist/task/plan-prompts.d.ts +6 -5
- package/dist/task/plan-prompts.js +6 -5
- package/dist/task/plan-readonly.d.ts +4 -5
- package/dist/task/plan-readonly.js +4 -5
- package/dist/task/plan-rounds.d.ts +17 -29
- package/dist/task/plan-rounds.js +21 -34
- package/dist/task/plan-session.d.ts +58 -72
- package/dist/task/plan-session.js +61 -83
- package/dist/task/probe-gaming.d.ts +28 -27
- package/dist/task/probe-gaming.js +0 -0
- package/dist/task/prohibition-probe.d.ts +14 -16
- package/dist/task/prompts.d.ts +3 -4
- package/dist/task/prompts.js +17 -26
- package/dist/task/qa-transcript.d.ts +15 -22
- package/dist/task/qa-transcript.js +15 -21
- package/dist/task/question-box.d.ts +17 -13
- package/dist/task/question-box.js +19 -15
- package/dist/task/question-dedup.d.ts +6 -7
- package/dist/task/question-dedup.js +13 -14
- package/dist/task/question-dialog.d.ts +22 -32
- package/dist/task/question-dialog.js +22 -32
- package/dist/task/question-source.d.ts +18 -44
- package/dist/task/question-source.js +22 -51
- package/dist/task/refuted-constraint.d.ts +11 -31
- package/dist/task/refuted-constraint.js +27 -51
- package/dist/task/regenerable-artifacts.d.ts +12 -31
- package/dist/task/regenerable-artifacts.js +12 -31
- package/dist/task/render-check.d.ts +11 -22
- package/dist/task/render-check.js +33 -46
- package/dist/task/repo-health-check.d.ts +10 -14
- package/dist/task/repo-health-check.js +17 -23
- package/dist/task/requirements.d.ts +38 -71
- package/dist/task/requirements.js +78 -126
- package/dist/task/research-fanout-budget.d.ts +51 -88
- package/dist/task/research-fanout-budget.js +51 -88
- package/dist/task/research-worker.d.ts +33 -36
- package/dist/task/research-worker.js +39 -61
- package/dist/task/resume-gap.d.ts +14 -15
- package/dist/task/root-cause-repair.d.ts +9 -9
- package/dist/task/root-cause-repair.js +28 -40
- package/dist/task/run-bracket.d.ts +10 -13
- package/dist/task/run-end.d.ts +12 -22
- package/dist/task/run-end.js +8 -16
- package/dist/task/run-final-gate.d.ts +19 -21
- package/dist/task/run-final-gate.js +62 -80
- package/dist/task/runner-globs.d.ts +12 -13
- package/dist/task/runner-globs.js +12 -13
- package/dist/task/runner-resolve.d.ts +9 -9
- package/dist/task/runner-resolve.js +22 -23
- package/dist/task/script-escape.d.ts +10 -12
- package/dist/task/script-escape.js +13 -14
- package/dist/task/serve-entry.d.ts +1 -1
- package/dist/task/serve-entry.js +22 -25
- package/dist/task/service-blocks.js +4 -2
- package/dist/task/shipped-source.d.ts +11 -29
- package/dist/task/shipped-source.js +11 -29
- package/dist/task/skip-escape.js +10 -14
- package/dist/task/spec-urls.d.ts +26 -65
- package/dist/task/spec-urls.js +26 -65
- package/dist/task/spec-validation.d.ts +17 -20
- package/dist/task/spec-validation.js +17 -20
- package/dist/task/stall-detector.d.ts +23 -30
- package/dist/task/stall-detector.js +23 -30
- package/dist/task/stream-watchdog.d.ts +14 -12
- package/dist/task/stream-watchdog.js +14 -12
- package/dist/task/substitution-probe.d.ts +17 -20
- package/dist/task/substitution-probe.js +17 -20
- package/dist/task/task-gates.d.ts +36 -41
- package/dist/task/task-gates.js +95 -106
- package/dist/task/task-io.d.ts +4 -4
- package/dist/task/task-io.js +4 -4
- package/dist/task/task-parsers.js +4 -3
- package/dist/task/task-provenance.d.ts +2 -2
- package/dist/task/task-provenance.js +11 -13
- package/dist/task/task-types.d.ts +4 -3
- package/dist/task/terminal-outcome.d.ts +14 -16
- package/dist/task/terminal-outcome.js +12 -14
- package/dist/task/test-assembly.d.ts +13 -20
- package/dist/task/test-assembly.js +13 -20
- package/dist/task/timings.d.ts +5 -3
- package/dist/task/timings.js +5 -3
- package/dist/task/title-label.d.ts +9 -4
- package/dist/task/title-label.js +9 -4
- package/dist/task/type-only-answer.d.ts +44 -52
- package/dist/task/type-only-answer.js +44 -52
- package/dist/task/unfailable-command.d.ts +18 -24
- package/dist/task/unfailable-command.js +21 -27
- package/dist/task/unknown-routing.d.ts +10 -4
- package/dist/task/unknown-routing.js +10 -4
- package/dist/task/user-directives.d.ts +5 -8
- package/dist/task/user-directives.js +5 -8
- package/dist/task/verify-quality.d.ts +18 -22
- package/dist/task/verify-quality.js +45 -46
- package/dist/task/verify-reconcile.d.ts +15 -10
- package/dist/task/verify-reconcile.js +45 -43
- package/dist/task/verify-resolution.d.ts +24 -20
- package/dist/task/verify-resolution.js +51 -50
- package/dist/task/verify-work.d.ts +59 -66
- package/dist/task/verify-work.js +101 -138
- package/dist/task/widget.d.ts +15 -14
- package/dist/task/widget.js +22 -17
- package/dist/task/wiring-claims.d.ts +25 -32
- package/dist/task/wiring-claims.js +30 -35
- package/dist/task/write-guard.d.ts +39 -39
- package/dist/task/write-guard.js +48 -51
- package/dist/task/yolo.d.ts +34 -30
- package/dist/task/yolo.js +42 -37
- package/dist/workers/abstention.d.ts +21 -41
- package/dist/workers/abstention.js +27 -48
- package/dist/workers/brave-search.d.ts +4 -3
- package/dist/workers/brave-search.js +5 -2
- package/dist/workers/brave-warning.d.ts +7 -4
- package/dist/workers/brave-warning.js +19 -7
- package/dist/workers/ddg-search.d.ts +6 -6
- package/dist/workers/ddg-search.js +18 -12
- package/dist/workers/docs-cache.js +5 -2
- package/dist/workers/docs-chunk.d.ts +30 -37
- package/dist/workers/docs-chunk.js +37 -41
- package/dist/workers/docs-core.d.ts +28 -44
- package/dist/workers/docs-core.js +25 -44
- package/dist/workers/docs-index.js +4 -3
- package/dist/workers/docs-lookup.d.ts +15 -22
- package/dist/workers/docs-lookup.js +12 -21
- package/dist/workers/docs-project.d.ts +15 -9
- package/dist/workers/docs-project.js +17 -10
- package/dist/workers/docs-resolve.d.ts +19 -20
- package/dist/workers/docs-resolve.js +35 -32
- package/dist/workers/docs-retrieve.d.ts +5 -6
- package/dist/workers/docs-retrieve.js +18 -15
- package/dist/workers/exa-search.d.ts +9 -6
- package/dist/workers/exa-search.js +23 -12
- package/dist/workers/fetch-core.d.ts +13 -16
- package/dist/workers/fetch-core.js +23 -23
- package/dist/workers/focused-extractor.d.ts +12 -12
- package/dist/workers/focused-extractor.js +16 -19
- package/dist/workers/html-clean.js +24 -14
- package/dist/workers/http-request.d.ts +28 -20
- package/dist/workers/http-request.js +22 -17
- package/dist/workers/npm-version.d.ts +28 -11
- package/dist/workers/npm-version.js +24 -15
- package/dist/workers/phantom-imports.d.ts +15 -12
- package/dist/workers/phantom-imports.js +30 -24
- package/dist/workers/pi-worker-core.d.ts +86 -54
- package/dist/workers/pi-worker-core.js +112 -112
- package/dist/workers/pi-worker-docs.d.ts +24 -19
- package/dist/workers/pi-worker-docs.js +67 -76
- package/dist/workers/pi-worker-fetch.d.ts +7 -3
- package/dist/workers/pi-worker-fetch.js +27 -19
- package/dist/workers/pi-worker-search.js +12 -8
- package/dist/workers/pi-worker.d.ts +9 -4
- package/dist/workers/pi-worker.js +23 -10
- package/dist/workers/reasoning-warning.d.ts +18 -17
- package/dist/workers/reasoning-warning.js +22 -20
- package/dist/workers/research-cache.js +50 -78
- package/dist/workers/search-core.js +7 -5
- package/dist/workers/search-types.d.ts +10 -9
- package/dist/workers/search-types.js +9 -8
- package/dist/workers/session-hint.d.ts +13 -14
- package/dist/workers/session-hint.js +8 -9
- package/dist/workers/shared.d.ts +21 -25
- package/dist/workers/shared.js +0 -0
- package/dist/workers/single-read-extension.d.ts +14 -7
- package/dist/workers/single-read-extension.js +14 -7
- package/dist/workers/single-read-guard.d.ts +25 -28
- package/dist/workers/single-read-guard.js +32 -32
- package/dist/workers/typeonly-log.d.ts +12 -9
- package/dist/workers/typeonly-log.js +29 -33
- package/dist/workers/worker-channels.d.ts +15 -23
- package/dist/workers/worker-channels.js +15 -23
- package/dist/workers/worker-failure.d.ts +38 -46
- package/dist/workers/worker-failure.js +31 -39
- package/dist/workers/worker-kill.d.ts +25 -26
- package/dist/workers/worker-kill.js +16 -19
- package/dist/workers/worker-profiles.d.ts +43 -53
- package/dist/workers/worker-profiles.js +30 -38
- package/package.json +10 -8
|
@@ -5,25 +5,24 @@
|
|
|
5
5
|
* Why this module exists. `RunWorkerResult` reports each kill cause as its own
|
|
6
6
|
* optional field (`loopHit`, `timedOut`, `stalled`, `commandTimedOut`,
|
|
7
7
|
* `streamStalled`, `leakedToolCall`, `aborted`, `exitCode`), and every kill path
|
|
8
|
-
* ALSO sets
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* ALSO sets the two generic ones. `killProc` sets `aborted` on every route out,
|
|
9
|
+
* and pi's own print/json mode installs a SIGTERM handler that exits 143, so a
|
|
10
|
+
* terminated child carries a non-zero exit too. So a consumer cannot read the
|
|
11
|
+
* fields in any order it likes: the specific causes must be matched before the
|
|
12
|
+
* generic `aborted`/`exitCode` ones, or a dead backend is reported to the user as
|
|
13
|
+
* "you cancelled".
|
|
12
14
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* was added to the result and to `finalAttemptFailed`, but the enforce ladder
|
|
18
|
-
* never grew an arm for it, so an enforcement child killed for a hung model
|
|
19
|
-
* stream fell all the way through to `if (aborted) return USER_CANCELLED` — the
|
|
20
|
-
* exact mislabel the comment above that line warns against.
|
|
15
|
+
* Written as prose, or as the source order of each consumer's own hand-rolled
|
|
16
|
+
* ladder, that rule gets a fresh chance to drift per consumer — and the failure is
|
|
17
|
+
* silent: add a new kill cause to the result, forget one ladder's arm for it, and
|
|
18
|
+
* that consumer falls through to `if (aborted)` and reports a cancel.
|
|
21
19
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
20
|
+
* So the order is DATA. `FAILURE_RULES` is ordered, the first matching row wins,
|
|
21
|
+
* and consumers `switch` on the resulting `kind` — `classifyEnforceChildFailure`
|
|
22
|
+
* (enforce-guidelines.ts) and `classifyResearchWorker` (research-worker.ts) both
|
|
23
|
+
* call `classifyWorkerFailure` and say only what each cause means to THEM. A new
|
|
24
|
+
* kill cause is one row here plus a compile error in every consumer that has not
|
|
25
|
+
* handled it.
|
|
27
26
|
*/
|
|
28
27
|
const _kindsAreKills = true;
|
|
29
28
|
void _kindsAreKills;
|
|
@@ -45,9 +44,8 @@ void _kindsAreKills;
|
|
|
45
44
|
* class of event: a watchdog, not the model, ended the attempt.
|
|
46
45
|
* 4. `worker-timeout` — the wall-clock backstop.
|
|
47
46
|
* 5. `loop` — killed for repeating one tool call past threshold. After the
|
|
48
|
-
* timeouts
|
|
49
|
-
*
|
|
50
|
-
* can expire.
|
|
47
|
+
* timeouts: a loop kill ends the attempt, so its own timer does not go on to
|
|
48
|
+
* expire as well.
|
|
51
49
|
* 6. `leaked-tool-call` — the model wrote a call as prose instead of invoking
|
|
52
50
|
* it. Only ever set on an otherwise clean run.
|
|
53
51
|
* 7. `aborted` — no specific cause survived, so this really is a cancel.
|
|
@@ -78,31 +76,20 @@ export const FAILURE_RULES = [
|
|
|
78
76
|
{ id: 'aborted', match: r => (r.aborted ? { kind: 'aborted' } : null) },
|
|
79
77
|
{ id: 'exit', match: r => (r.exitCode !== 0 ? { kind: 'exit', code: r.exitCode } : null) }
|
|
80
78
|
];
|
|
81
|
-
/**
|
|
82
|
-
* Classify a finished child. Returns `undefined` when nothing killed it —
|
|
83
|
-
* which is not the same as "it answered": the text may still be empty, and that
|
|
84
|
-
* judgement belongs to the caller.
|
|
85
|
-
*/
|
|
86
79
|
/**
|
|
87
80
|
* What a worker failure SAYS to the caller that asked for the work.
|
|
88
81
|
*
|
|
89
|
-
* WHY IT EXISTS. The ladder above already names the cause exactly, with its
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
* put in the debug trail, which a user reading a tool result never sees.
|
|
97
|
-
*
|
|
98
|
-
* That is not only unhelpful; it is why the `pi-worker` tool's 240s cap has no
|
|
99
|
-
* base rate. 53 recorded invocations across eight repos carry 14 failures, and
|
|
100
|
-
* NOTHING in the transcript says which of them ran out of time — the honest
|
|
101
|
-
* bound recoverable from timestamps alone is "somewhere between 0 and 8".
|
|
82
|
+
* WHY IT EXISTS. The ladder above already names the cause exactly, with its detail
|
|
83
|
+
* — which tool hung, how long the stream was idle, which exit code. Answering
|
|
84
|
+
* `if (aborted) return abortedMessage` instead throws all of it away: a wall-clock
|
|
85
|
+
* kill, a hung `bash`, a dead model backend, a loop kill and a user pressing ESC
|
|
86
|
+
* then print the SAME words, and the discriminating value only reaches a debug
|
|
87
|
+
* trail a user reading a tool result never sees. Every arm below returns a
|
|
88
|
+
* different message, and only `aborted` returns the caller's own.
|
|
102
89
|
*
|
|
103
90
|
* A switch, not a table: `WorkerFailure` is a discriminated union carrying a
|
|
104
91
|
* different payload per arm, so the exhaustiveness check is the compiler's and a
|
|
105
|
-
*
|
|
92
|
+
* new arm cannot be added without a message.
|
|
106
93
|
*/
|
|
107
94
|
export function describeWorkerFailure(f,
|
|
108
95
|
/** What a genuine user cancel says. The caller's wording — only this arm is theirs. */
|
|
@@ -137,6 +124,11 @@ stderr = '') {
|
|
|
137
124
|
return `Worker exited ${f.code}.\n${stderr.trim().slice(-500) || '(no stderr)'}`;
|
|
138
125
|
}
|
|
139
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* Classify a finished child against the ladder. Returns `undefined` when nothing
|
|
129
|
+
* killed it — which is not the same as "it answered": the text may still be empty,
|
|
130
|
+
* and that judgement belongs to the caller.
|
|
131
|
+
*/
|
|
140
132
|
export function classifyWorkerFailure(r) {
|
|
141
133
|
for (const rule of FAILURE_RULES) {
|
|
142
134
|
const hit = rule.match(r);
|
|
@@ -1,31 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The ROSTER of ways a worker child can die, and what each one implies.
|
|
3
3
|
*
|
|
4
|
-
* WHY IT EXISTS.
|
|
4
|
+
* WHY IT EXISTS. Without it, one kill cause is named in six unlinked places: a
|
|
5
5
|
* `RunWorkerInput` guard option, a `RunWorkerResult` field, the
|
|
6
|
-
* `WorkerRestartReason` union, a `RESTART_RULES` row, the
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* enforce ladder never grew an arm for it, so an enforcement child killed for a
|
|
12
|
-
* hung model stream fell all the way through to `if (aborted) return
|
|
13
|
-
* USER_CANCELLED`"*. That fix closed the READER side. This closes the author
|
|
14
|
-
* side.
|
|
6
|
+
* `WorkerRestartReason` union, a `RESTART_RULES` row, the carry-forward set, and a
|
|
7
|
+
* `FAILURE_RULES` row. Adding a cause is six coordinated edits, and most of them
|
|
8
|
+
* still compile if one is skipped — so the new cause simply does not exist on
|
|
9
|
+
* whichever path was missed. `worker-failure.ts` closes the READER side of that;
|
|
10
|
+
* this closes the AUTHOR side.
|
|
15
11
|
*
|
|
16
12
|
* WHAT IS AND IS NOT UNIFIED. The roster is one table. The two ORDERINGS stay
|
|
17
13
|
* two, because they genuinely disagree and each says so in its own prose: the
|
|
18
14
|
* restart ladder puts `loop` first (its hint is the most specific thing to tell a
|
|
19
|
-
* re-spawn), and the failure ladder puts `stalled` first (the diagnosis most
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* here is that neither can name a cause with no row, nor silently omit one.
|
|
15
|
+
* re-spawn), and the failure ladder puts `stalled` first (the diagnosis most easily
|
|
16
|
+
* lost behind the `aborted` every kill path sets). Folding two precedences into one
|
|
17
|
+
* row type would need an escape hatch per row. What the orderings gain here is that
|
|
18
|
+
* neither can name a cause with no row, nor silently omit one.
|
|
24
19
|
*
|
|
25
|
-
* Not every cause appears in both ladders, and that asymmetry is real
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
20
|
+
* Not every cause appears in both ladders, and that asymmetry is real. Six of the
|
|
21
|
+
* nine are `restartable` and those six are exactly RESTART_ORDER; eight are
|
|
22
|
+
* `reported` and those eight are exactly FAILURE_ORDER. `connection-error` is the
|
|
23
|
+
* one that restarts without ever being reported as a kill — it reaches the caller
|
|
24
|
+
* as a `modelError`. `stalled`, `aborted` and `exit` end an attempt outright, and
|
|
25
|
+
* no hint would help.
|
|
29
26
|
*/
|
|
30
27
|
/** Every way a worker attempt can end other than by answering. */
|
|
31
28
|
export type WorkerKillId = 'stalled' | 'command-timeout' | 'stream-stall' | 'worker-timeout' | 'connection-error' | 'loop' | 'leaked-tool-call' | 'aborted' | 'exit';
|
|
@@ -37,18 +34,20 @@ export interface WorkerKill {
|
|
|
37
34
|
* (`connection-error` arrives as `modelError`; `aborted` and `exit` are the
|
|
38
35
|
* generic fields every kill path also sets).
|
|
39
36
|
*
|
|
40
|
-
*
|
|
41
|
-
* pi-worker-core's
|
|
42
|
-
*
|
|
37
|
+
* Null for three rows: `connection-error`, `aborted` and `exit`. A string rather
|
|
38
|
+
* than `keyof RunWorkerResult` so this module stays out of pi-worker-core's
|
|
39
|
+
* import graph; worker-kill.test.ts checks every non-null one against a real
|
|
40
|
+
* result object.
|
|
43
41
|
*/
|
|
44
42
|
resultField: string | null;
|
|
45
43
|
/**
|
|
46
44
|
* Is a killed attempt's partial output worth carrying into the next one?
|
|
47
45
|
*
|
|
48
|
-
*
|
|
49
|
-
* work the model genuinely did. A loop kill and a leaked tool
|
|
50
|
-
* the first is by definition the same call repeated, the second is
|
|
51
|
-
* protocol text, and replaying either would feed the failure back to
|
|
46
|
+
* True for exactly four: a clock kill, a hung tool, an idle stream and a dropped
|
|
47
|
+
* socket all discard work the model genuinely did. A loop kill and a leaked tool
|
|
48
|
+
* call do not — the first is by definition the same call repeated, the second is
|
|
49
|
+
* malformed protocol text, and replaying either would feed the failure back to
|
|
50
|
+
* itself.
|
|
52
51
|
*/
|
|
53
52
|
carryForward: boolean;
|
|
54
53
|
/** Does the restart ladder have a rule for this cause? */
|
|
@@ -1,31 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The ROSTER of ways a worker child can die, and what each one implies.
|
|
3
3
|
*
|
|
4
|
-
* WHY IT EXISTS.
|
|
4
|
+
* WHY IT EXISTS. Without it, one kill cause is named in six unlinked places: a
|
|
5
5
|
* `RunWorkerInput` guard option, a `RunWorkerResult` field, the
|
|
6
|
-
* `WorkerRestartReason` union, a `RESTART_RULES` row, the
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* enforce ladder never grew an arm for it, so an enforcement child killed for a
|
|
12
|
-
* hung model stream fell all the way through to `if (aborted) return
|
|
13
|
-
* USER_CANCELLED`"*. That fix closed the READER side. This closes the author
|
|
14
|
-
* side.
|
|
6
|
+
* `WorkerRestartReason` union, a `RESTART_RULES` row, the carry-forward set, and a
|
|
7
|
+
* `FAILURE_RULES` row. Adding a cause is six coordinated edits, and most of them
|
|
8
|
+
* still compile if one is skipped — so the new cause simply does not exist on
|
|
9
|
+
* whichever path was missed. `worker-failure.ts` closes the READER side of that;
|
|
10
|
+
* this closes the AUTHOR side.
|
|
15
11
|
*
|
|
16
12
|
* WHAT IS AND IS NOT UNIFIED. The roster is one table. The two ORDERINGS stay
|
|
17
13
|
* two, because they genuinely disagree and each says so in its own prose: the
|
|
18
14
|
* restart ladder puts `loop` first (its hint is the most specific thing to tell a
|
|
19
|
-
* re-spawn), and the failure ladder puts `stalled` first (the diagnosis most
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* here is that neither can name a cause with no row, nor silently omit one.
|
|
15
|
+
* re-spawn), and the failure ladder puts `stalled` first (the diagnosis most easily
|
|
16
|
+
* lost behind the `aborted` every kill path sets). Folding two precedences into one
|
|
17
|
+
* row type would need an escape hatch per row. What the orderings gain here is that
|
|
18
|
+
* neither can name a cause with no row, nor silently omit one.
|
|
24
19
|
*
|
|
25
|
-
* Not every cause appears in both ladders, and that asymmetry is real
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
20
|
+
* Not every cause appears in both ladders, and that asymmetry is real. Six of the
|
|
21
|
+
* nine are `restartable` and those six are exactly RESTART_ORDER; eight are
|
|
22
|
+
* `reported` and those eight are exactly FAILURE_ORDER. `connection-error` is the
|
|
23
|
+
* one that restarts without ever being reported as a kill — it reaches the caller
|
|
24
|
+
* as a `modelError`. `stalled`, `aborted` and `exit` end an attempt outright, and
|
|
25
|
+
* no hint would help.
|
|
29
26
|
*/
|
|
30
27
|
export const WORKER_KILLS = [
|
|
31
28
|
{
|
|
@@ -2,25 +2,14 @@
|
|
|
2
2
|
* The GUARD POLICY each kind of worker child runs under, keyed on the ways it
|
|
3
3
|
* can die.
|
|
4
4
|
*
|
|
5
|
-
* WHY IT EXISTS. `RunWorkerInput
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* NO command watchdog, NO stream watchdog. Everything else
|
|
14
|
-
* default.
|
|
15
|
-
* pi-worker.ts nothing at all — every default, silently.
|
|
16
|
-
*
|
|
17
|
-
* So "a gate child runs unbounded but with a per-command watchdog; a research
|
|
18
|
-
* worker is the reverse" existed only as three option literals in three files,
|
|
19
|
-
* and the reasoning was attached to whichever line happened to need defending.
|
|
20
|
-
* `gate-child.ts` explained why it disables the path rule and said nothing about
|
|
21
|
-
* why it takes no progress deadline. Nothing anywhere said that the ad-hoc
|
|
22
|
-
* `pi-worker` tool is the strictest-clocked of the three. That was not a
|
|
23
|
-
* decision; it was the residue of never having had a place to write one down.
|
|
5
|
+
* WHY IT EXISTS. As independent options on `RunWorkerInput`, ten guard knobs in
|
|
6
|
+
* four different shapes, each of the three production callers hand-picks its own
|
|
7
|
+
* subset — and "a gate child runs unbounded but with a per-command watchdog; a
|
|
8
|
+
* research worker is the reverse" then exists only as three option literals in
|
|
9
|
+
* three files. The reasoning attaches to whichever line happened to need
|
|
10
|
+
* defending, a caller that names nothing gets a full policy silently, and no file
|
|
11
|
+
* is the place to say which child is the strictest-clocked of the three. That is
|
|
12
|
+
* not a decision; it is the residue of having nowhere to write one down.
|
|
24
13
|
*
|
|
25
14
|
* WHY IT IS KEYED ON `WorkerKillId`. A guard exists to prevent a specific way a
|
|
26
15
|
* child can die, so the roster of deaths (`worker-kill.ts`) is the correct key —
|
|
@@ -55,8 +44,8 @@
|
|
|
55
44
|
* silently re-level a gate child, which is the exact mistake
|
|
56
45
|
* `RunWorkerInput.thinking`'s comment already records.
|
|
57
46
|
*
|
|
58
|
-
* `projectDocsBudget()` (
|
|
59
|
-
*
|
|
47
|
+
* `projectDocsBudget()` (research-fanout-budget.ts) stays out. It bounds what a
|
|
48
|
+
* worker ASKS FOR, via its prompt and its tool, not how it dies.
|
|
60
49
|
*
|
|
61
50
|
* `RESTART_ORDER` and `FAILURE_ORDER` are untouched. This is a third view of
|
|
62
51
|
* the same key, not a merge of the two orderings.
|
|
@@ -67,18 +56,20 @@ import type { WorkerKillId } from './worker-kill.js';
|
|
|
67
56
|
* LoopDetector only catches *identical* repeated tool calls; a model that
|
|
68
57
|
* thrashes with slightly-varied calls (different grep patterns each time) slips
|
|
69
58
|
* past it and would otherwise run unbounded. This is the backstop for that case:
|
|
70
|
-
* after this long with no clean exit, abort and restart with a hint.
|
|
71
|
-
*
|
|
72
|
-
*
|
|
59
|
+
* after this long with no clean exit, abort and restart with a hint.
|
|
60
|
+
*
|
|
61
|
+
* A fixed elapsed-time cap is a poor bound on a read-only worker — see the
|
|
62
|
+
* `adhoc` profile's `why`, which is why that profile disables it. The two
|
|
63
|
+
* profiles that keep it pair it with a progress ceiling or accept the trade.
|
|
73
64
|
*/
|
|
74
65
|
export declare const RESEARCH_WORKER_TIMEOUT_MS = 240000;
|
|
75
66
|
/**
|
|
76
|
-
* Output-stall window before the dead-backend probe fires
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
67
|
+
* Output-stall window before the dead-backend probe fires: a model server that
|
|
68
|
+
* dies mid-child leaves it hung MUTE with nothing else to notice. This is NOT a
|
|
69
|
+
* wall-clock cap — output progress resets it, and even a fully stalled child is
|
|
70
|
+
* killed only when the model endpoint is actually unreachable. Sized so a long
|
|
71
|
+
* local prompt-processing pass, which is minutes of legitimate silence from a
|
|
72
|
+
* live server, gets probed and then waited on.
|
|
82
73
|
*/
|
|
83
74
|
export declare const STALL_AFTER_MS = 180000;
|
|
84
75
|
/**
|
|
@@ -111,8 +102,8 @@ export interface StalledGuard {
|
|
|
111
102
|
* bigger file — and must not cost the user their answer; the second is a real
|
|
112
103
|
* fault, and one the dead-backend probe already catches on its own terms.
|
|
113
104
|
*
|
|
114
|
-
* `fanout` is
|
|
115
|
-
*
|
|
105
|
+
* `fanout` is off unless BOTH of its env vars are set — `fanoutTimeoutPolicy`
|
|
106
|
+
* returns null when either the per-lookup or the ceiling value is missing.
|
|
116
107
|
*/
|
|
117
108
|
export interface WorkerTimeoutGuard {
|
|
118
109
|
/** 0 disables the wall clock entirely: the child runs until it exits. */
|
|
@@ -138,15 +129,13 @@ export interface WorkerTimeoutGuard {
|
|
|
138
129
|
*
|
|
139
130
|
* `detector` judges ARGUMENTS over a 20-call window, so a child that rotates
|
|
140
131
|
* through MORE DISTINCT CALLS THAN THE WINDOW HOLDS is invisible to it — every
|
|
141
|
-
* key occurs once per window and the count never reaches the threshold.
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* having done 25s of useful work.
|
|
132
|
+
* key occurs once per window and the count never reaches the threshold. A worker
|
|
133
|
+
* rotating over as many distinct files as the window holds can re-read every one
|
|
134
|
+
* of them repeatedly without either the exact rule or the path rule tripping, and
|
|
135
|
+
* then die on the absolute deadline having produced almost nothing.
|
|
146
136
|
*
|
|
147
|
-
* `progress` judges RESULTS, which a rotating reader cannot vary. It
|
|
148
|
-
* for exactly that class
|
|
149
|
-
* `runWorker` grew an option for it.
|
|
137
|
+
* `progress` judges RESULTS, which a rotating reader cannot vary. It is the rule
|
|
138
|
+
* written for exactly that class.
|
|
150
139
|
*
|
|
151
140
|
* Either can be `false` independently — a pass that legitimately revisits one
|
|
152
141
|
* file raises `pathThreshold`; a harness isolating one rule turns the other off.
|
|
@@ -192,20 +181,19 @@ interface WorkerGuardShapes {
|
|
|
192
181
|
/**
|
|
193
182
|
* Stream-inactivity ceiling, ms (shared/stream-watchdog.ts). 0 = off.
|
|
194
183
|
*
|
|
195
|
-
* The dead-backend probe cannot catch a HUNG stream on a HEALTHY backend
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
184
|
+
* The dead-backend probe cannot catch a HUNG stream on a HEALTHY backend: it
|
|
185
|
+
* reads a reachable endpoint as proof of life, which a hung stream leaves
|
|
186
|
+
* intact. This one asks nothing of the backend — no output for this long, tool
|
|
187
|
+
* executions excluded, means kill and restart the attempt with
|
|
188
|
+
* `streamStallHint`, inside the same shared restart budget.
|
|
200
189
|
*/
|
|
201
190
|
'stream-stall': number;
|
|
202
191
|
'worker-timeout': WorkerTimeoutGuard;
|
|
203
192
|
/**
|
|
204
193
|
* Connection-error restart budget. The SHARED restart counter is what
|
|
205
|
-
* actually binds — a worker that already spent the budget looping does not
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
* already ships the retry.
|
|
194
|
+
* actually binds — a worker that already spent the budget looping does not get
|
|
195
|
+
* extra lives here. 0 turns the retry off entirely, which is how a harness
|
|
196
|
+
* obtains a no-retry arm from a build that ships the retry.
|
|
209
197
|
*/
|
|
210
198
|
'connection-error': number;
|
|
211
199
|
loop: LoopGuard;
|
|
@@ -266,7 +254,8 @@ export interface WorkerPolicyInputs {
|
|
|
266
254
|
streamInactivityMs?: number;
|
|
267
255
|
/** research: only `worker:apis` fans out, so only it can be scaled. */
|
|
268
256
|
fanoutBounded?: boolean;
|
|
269
|
-
/** research: the
|
|
257
|
+
/** research: the env reader the fanout and progress-ceiling levers use.
|
|
258
|
+
* Injectable so a test does not depend on the machine's environment. */
|
|
270
259
|
env?: (key: string) => string | undefined;
|
|
271
260
|
}
|
|
272
261
|
export interface WorkerProfile {
|
|
@@ -306,9 +295,10 @@ export declare function workerPolicy(id: WorkerProfileId, inputs?: WorkerPolicyI
|
|
|
306
295
|
/**
|
|
307
296
|
* Lay whole rows over a resolved policy.
|
|
308
297
|
*
|
|
309
|
-
* For tests and
|
|
310
|
-
*
|
|
311
|
-
*
|
|
298
|
+
* For tests and harnesses ONLY. Production code names a profile: an override at a
|
|
299
|
+
* production call site is the exact "hand-pick a subset" this module exists to
|
|
300
|
+
* stop, and worker-profiles.test.ts scans src/ for a leading `override:` and fails
|
|
301
|
+
* on any hit.
|
|
312
302
|
*/
|
|
313
303
|
export declare function applyOverride(policy: WorkerGuardPolicy, override: WorkerGuardOverride | undefined): WorkerGuardPolicy;
|
|
314
304
|
export {};
|
|
@@ -2,25 +2,14 @@
|
|
|
2
2
|
* The GUARD POLICY each kind of worker child runs under, keyed on the ways it
|
|
3
3
|
* can die.
|
|
4
4
|
*
|
|
5
|
-
* WHY IT EXISTS. `RunWorkerInput
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* NO command watchdog, NO stream watchdog. Everything else
|
|
14
|
-
* default.
|
|
15
|
-
* pi-worker.ts nothing at all — every default, silently.
|
|
16
|
-
*
|
|
17
|
-
* So "a gate child runs unbounded but with a per-command watchdog; a research
|
|
18
|
-
* worker is the reverse" existed only as three option literals in three files,
|
|
19
|
-
* and the reasoning was attached to whichever line happened to need defending.
|
|
20
|
-
* `gate-child.ts` explained why it disables the path rule and said nothing about
|
|
21
|
-
* why it takes no progress deadline. Nothing anywhere said that the ad-hoc
|
|
22
|
-
* `pi-worker` tool is the strictest-clocked of the three. That was not a
|
|
23
|
-
* decision; it was the residue of never having had a place to write one down.
|
|
5
|
+
* WHY IT EXISTS. As independent options on `RunWorkerInput`, ten guard knobs in
|
|
6
|
+
* four different shapes, each of the three production callers hand-picks its own
|
|
7
|
+
* subset — and "a gate child runs unbounded but with a per-command watchdog; a
|
|
8
|
+
* research worker is the reverse" then exists only as three option literals in
|
|
9
|
+
* three files. The reasoning attaches to whichever line happened to need
|
|
10
|
+
* defending, a caller that names nothing gets a full policy silently, and no file
|
|
11
|
+
* is the place to say which child is the strictest-clocked of the three. That is
|
|
12
|
+
* not a decision; it is the residue of having nowhere to write one down.
|
|
24
13
|
*
|
|
25
14
|
* WHY IT IS KEYED ON `WorkerKillId`. A guard exists to prevent a specific way a
|
|
26
15
|
* child can die, so the roster of deaths (`worker-kill.ts`) is the correct key —
|
|
@@ -55,8 +44,8 @@
|
|
|
55
44
|
* silently re-level a gate child, which is the exact mistake
|
|
56
45
|
* `RunWorkerInput.thinking`'s comment already records.
|
|
57
46
|
*
|
|
58
|
-
* `projectDocsBudget()` (
|
|
59
|
-
*
|
|
47
|
+
* `projectDocsBudget()` (research-fanout-budget.ts) stays out. It bounds what a
|
|
48
|
+
* worker ASKS FOR, via its prompt and its tool, not how it dies.
|
|
60
49
|
*
|
|
61
50
|
* `RESTART_ORDER` and `FAILURE_ORDER` are untouched. This is a third view of
|
|
62
51
|
* the same key, not a merge of the two orderings.
|
|
@@ -69,18 +58,20 @@ import { fanoutTimeoutPolicy, workerCarryForward, workerProgressCeilingMs } from
|
|
|
69
58
|
* LoopDetector only catches *identical* repeated tool calls; a model that
|
|
70
59
|
* thrashes with slightly-varied calls (different grep patterns each time) slips
|
|
71
60
|
* past it and would otherwise run unbounded. This is the backstop for that case:
|
|
72
|
-
* after this long with no clean exit, abort and restart with a hint.
|
|
73
|
-
*
|
|
74
|
-
*
|
|
61
|
+
* after this long with no clean exit, abort and restart with a hint.
|
|
62
|
+
*
|
|
63
|
+
* A fixed elapsed-time cap is a poor bound on a read-only worker — see the
|
|
64
|
+
* `adhoc` profile's `why`, which is why that profile disables it. The two
|
|
65
|
+
* profiles that keep it pair it with a progress ceiling or accept the trade.
|
|
75
66
|
*/
|
|
76
67
|
export const RESEARCH_WORKER_TIMEOUT_MS = 240_000;
|
|
77
68
|
/**
|
|
78
|
-
* Output-stall window before the dead-backend probe fires
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
69
|
+
* Output-stall window before the dead-backend probe fires: a model server that
|
|
70
|
+
* dies mid-child leaves it hung MUTE with nothing else to notice. This is NOT a
|
|
71
|
+
* wall-clock cap — output progress resets it, and even a fully stalled child is
|
|
72
|
+
* killed only when the model endpoint is actually unreachable. Sized so a long
|
|
73
|
+
* local prompt-processing pass, which is minutes of legitimate silence from a
|
|
74
|
+
* live server, gets probed and then waited on.
|
|
84
75
|
*/
|
|
85
76
|
export const STALL_AFTER_MS = 180_000;
|
|
86
77
|
/** The shipped `detector` half of the `loop` row: the read-only research/impl guard. */
|
|
@@ -219,19 +210,20 @@ export function workerPolicy(id, inputs = {}) {
|
|
|
219
210
|
/**
|
|
220
211
|
* Lay whole rows over a resolved policy.
|
|
221
212
|
*
|
|
222
|
-
* For tests and
|
|
223
|
-
*
|
|
224
|
-
*
|
|
213
|
+
* For tests and harnesses ONLY. Production code names a profile: an override at a
|
|
214
|
+
* production call site is the exact "hand-pick a subset" this module exists to
|
|
215
|
+
* stop, and worker-profiles.test.ts scans src/ for a leading `override:` and fails
|
|
216
|
+
* on any hit.
|
|
225
217
|
*/
|
|
226
218
|
export function applyOverride(policy, override) {
|
|
227
219
|
if (override === undefined)
|
|
228
220
|
return policy;
|
|
229
221
|
const { carryForward, ...rows } = override;
|
|
230
|
-
// Present-but-`undefined` is DROPPED, not laid down. A conditional row is
|
|
231
|
-
//
|
|
232
|
-
//
|
|
233
|
-
//
|
|
234
|
-
//
|
|
222
|
+
// Present-but-`undefined` is DROPPED, not laid down. A conditional row is the
|
|
223
|
+
// natural way to write one — `{'command-timeout': on ? ms : undefined}` — and a
|
|
224
|
+
// plain spread would put `undefined` into the policy, which either disarms the
|
|
225
|
+
// guard silently or throws on `clock.timeoutMs`. This tsconfig does not set
|
|
226
|
+
// `exactOptionalPropertyTypes`, so the compiler allows it through.
|
|
235
227
|
const set = Object.fromEntries(Object.entries(rows).filter(([, v]) => v !== undefined));
|
|
236
228
|
return {
|
|
237
229
|
guards: { ...policy.guards, ...set },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mjasnikovs/pi-task",
|
|
3
|
-
"version": "0.38.
|
|
3
|
+
"version": "0.38.30",
|
|
4
4
|
"description": "Deterministic task planning and spec-orchestration for local models — crash-safe /task pipelines with verify/enforce gates, a real-time remote web view, and web/docs/fetch/worker subagent tools.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
],
|
|
14
14
|
"scripts": {
|
|
15
15
|
"build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json",
|
|
16
|
-
"lint": "prettier --log-level warn --write 'src/**/*.ts' && eslint --fix . && tsc --noEmit
|
|
17
|
-
"
|
|
16
|
+
"lint": "prettier --log-level warn --write '{src,test}/**/*.ts' && eslint --fix . && tsc --noEmit",
|
|
17
|
+
"lint:check": "prettier --check '{src,test}/**/*.ts' && eslint . --max-warnings 0 && tsc --noEmit",
|
|
18
|
+
"test": "cross-env AGENT=1 bun test --isolate test/ scripts/",
|
|
18
19
|
"prepublishOnly": "bun run build"
|
|
19
20
|
},
|
|
20
21
|
"peerDependencies": {
|
|
@@ -41,12 +42,13 @@
|
|
|
41
42
|
"@types/turndown": "5.0.6",
|
|
42
43
|
"@types/web-push": "3.6.4",
|
|
43
44
|
"@types/ws": "8.18.1",
|
|
44
|
-
"cross-env": "
|
|
45
|
-
"eslint": "10.
|
|
46
|
-
"
|
|
47
|
-
"
|
|
45
|
+
"cross-env": "10.1.0",
|
|
46
|
+
"eslint": "10.9.1",
|
|
47
|
+
"eslint-config-prettier": "10.1.8",
|
|
48
|
+
"globals": "17.11.0",
|
|
49
|
+
"prettier": "3.9.6",
|
|
48
50
|
"typescript": "6.0.3",
|
|
49
|
-
"typescript-eslint": "8.
|
|
51
|
+
"typescript-eslint": "8.68.0"
|
|
50
52
|
},
|
|
51
53
|
"keywords": [
|
|
52
54
|
"pi-package",
|