@mjasnikovs/pi-task 0.38.29 → 0.38.31
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/index.js +2 -0
- 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 +85 -16
- package/dist/shared/command-watchdog.js +115 -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 +192 -165
- 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 +124 -55
- package/dist/task/child-runner.js +298 -90
- 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 +16 -9
- package/dist/task/context-usage.js +16 -9
- 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 +30 -8
- 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 +36 -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-guards.d.ts +26 -0
- package/dist/task/implementation-guards.js +177 -0
- package/dist/task/implementation-thinking.d.ts +33 -31
- package/dist/task/implementation-thinking.js +5 -6
- package/dist/task/implementation-turn.d.ts +39 -31
- package/dist/task/implementation-turn.js +41 -28
- 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 +27 -8
- package/dist/task/loop-detector.js +38 -14
- 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 +89 -66
- 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 +196 -252
- 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 +29 -39
- package/dist/task/research-worker.js +37 -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 +13 -12
- package/dist/workers/focused-extractor.js +27 -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 +65 -96
- package/dist/workers/pi-worker-core.js +93 -181
- 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 +21 -14
- 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 +27 -30
- package/dist/workers/single-read-guard.js +36 -36
- 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 +54 -56
- package/dist/workers/worker-profiles.js +63 -39
- package/package.json +10 -8
|
@@ -1,24 +1,19 @@
|
|
|
1
1
|
import { getPiInvocation } from '../shared/pi-invocation.js';
|
|
2
2
|
import { runChildDefault } from '../shared/child-process.js';
|
|
3
|
-
import {
|
|
3
|
+
import { commandCeilingForAttempt, commandTimeoutHint, commandWatch } from '../shared/command-watchdog.js';
|
|
4
|
+
export { commandCeilingForAttempt } from '../shared/command-watchdog.js';
|
|
4
5
|
import { isGroundingRetrieval as isGrounding, workerChannel } from './worker-channels.js';
|
|
5
6
|
import { childBaseArgs } from '../shared/child-extensions.js';
|
|
6
|
-
import { LoopDetector } from '../task/loop-detector.js';
|
|
7
|
+
import { LoopDetector, MAX_LOOP_RESTARTS } from '../task/loop-detector.js';
|
|
7
8
|
import { StallDetector, formatStallHint } from '../task/stall-detector.js';
|
|
8
|
-
import {
|
|
9
|
+
import { formatLoopHint, isConnectionError, connectionRetryBackoffMs } from '../task/child-runner.js';
|
|
9
10
|
import { detectLeakedToolCall, leakedToolCallHint, MAX_LEAK_RETRIES } from '../shared/leaked-tool-call.js';
|
|
10
11
|
import { discoverModelEndpoints, probeModelEndpoints } from '../shared/model-endpoint.js';
|
|
11
12
|
import { streamStallHint } from '../shared/stream-watchdog.js';
|
|
12
13
|
import { classifyWorkerFailure } from './worker-failure.js';
|
|
13
|
-
import { CARRY_FORWARD_IDS } from './worker-kill.js';
|
|
14
|
+
import { CARRY_FORWARD_IDS, RESTART_ORDER } from './worker-kill.js';
|
|
14
15
|
import { applyOverride, WORKER_PROFILES } from './worker-profiles.js';
|
|
15
|
-
|
|
16
|
-
// buffering the assistant text and flushing on exit. That matters for the
|
|
17
|
-
// wait/work timing split: in text mode the first stdout chunk only arrives at
|
|
18
|
-
// the very end, so onFirstByte fires moments before close and workMs is
|
|
19
|
-
// effectively zero. With JSON events the first byte lands as soon as the
|
|
20
|
-
// model starts producing — making waitMs the real queue/cold-start cost and
|
|
21
|
-
// workMs the real generation+tool-call cost.
|
|
16
|
+
/** The tool whitelist a caller gets when it names none. */
|
|
22
17
|
const DEFAULT_TOOLS = 'read,grep,find,ls';
|
|
23
18
|
/**
|
|
24
19
|
* The one place `'unknown'` becomes the 0 both consumers already treat as
|
|
@@ -33,18 +28,19 @@ function contextWindowTokens(cw) {
|
|
|
33
28
|
* command could be cited from. `pi-worker-docs` (the primary), `read` and `grep`
|
|
34
29
|
* (project source), and the web escalations `pi-worker-search`/`pi-worker-fetch`.
|
|
35
30
|
*
|
|
36
|
-
* `ls` and `find` are deliberately EXCLUDED: they return file
|
|
37
|
-
* and APIS owns symbols by name only, never paths (
|
|
38
|
-
* enumeration cannot verify a
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
31
|
+
* `ls` and `find` are deliberately EXCLUDED: they return file and directory
|
|
32
|
+
* NAMES, and APIS owns symbols by name only, never paths (see
|
|
33
|
+
* RESEARCH_APIS_PROMPT in prompts.ts). Bare enumeration cannot verify a
|
|
34
|
+
* signature, so a worker that fabricates its section from memory cannot launder
|
|
35
|
+
* itself grounded by calling `ls` once — "one trivial `ls` then fabricate the
|
|
36
|
+
* rest" still leaves groundingRetrievalCount at 0.
|
|
37
|
+
*
|
|
38
|
+
* The set is DERIVED from WORKER_CHANNELS (worker-channels.ts), not hand-kept.
|
|
39
|
+
* Re-exported here only so worker-channels.test.ts can assert this module hands
|
|
40
|
+
* back the same predicate.
|
|
42
41
|
*/
|
|
43
|
-
// The grounding set is derived from WORKER_CHANNELS (worker-channels.ts), not
|
|
44
|
-
// hand-kept — this was a second copy of the four tool names. Re-exported because
|
|
45
|
-
// several call sites and tests import it from here.
|
|
46
42
|
export { isGroundingRetrieval } from './worker-channels.js';
|
|
47
|
-
// RESEARCH_WORKER_TIMEOUT_MS and STALL_AFTER_MS live on the profile table
|
|
43
|
+
// RESEARCH_WORKER_TIMEOUT_MS and STALL_AFTER_MS live on the profile table
|
|
48
44
|
// (worker-profiles.ts): they are the default VALUES of two guard rows, and a
|
|
49
45
|
// default that lives apart from the table stating it is a second place to look.
|
|
50
46
|
/**
|
|
@@ -59,49 +55,44 @@ const WORKER_TIMEOUT_HINT = '[SYSTEM NOTE: Your previous attempt ran out of time
|
|
|
59
55
|
/**
|
|
60
56
|
* How much of a discarded attempt's answer is carried into the next one.
|
|
61
57
|
*
|
|
62
|
-
* A restart
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* lookups, 5 of 5 workers burned the FULL restart budget, because every attempt
|
|
67
|
-
* re-read the same files against the same clock and died in the same place.
|
|
58
|
+
* A restart that hands the re-spawn nothing but a hint is why WORKER_TIMEOUT_HINT
|
|
59
|
+
* above can tell a worker "do not re-explore ground you have already covered"
|
|
60
|
+
* while giving it no record of what that ground was. It cannot comply, so it
|
|
61
|
+
* re-reads the same files against the same clock and dies in the same place.
|
|
68
62
|
*
|
|
69
|
-
* Carrying the partial
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* framed as findings to VERIFY-or-DROP rather than as settled fact.
|
|
63
|
+
* Carrying the partial forward is what lets a restart converge instead of repeat.
|
|
64
|
+
* The risk is real: a half-written or speculative entry, replayed under "already
|
|
65
|
+
* established", is how a fabrication gets laundered into a final answer. That is
|
|
66
|
+
* why `formatCarryForward` frames it as findings to VERIFY-or-DROP rather than as
|
|
67
|
+
* settled fact.
|
|
75
68
|
*/
|
|
76
69
|
const CARRY_FORWARD_LIMIT = 24_000;
|
|
77
70
|
/**
|
|
78
71
|
* Restart reasons whose partial output is worth keeping.
|
|
79
72
|
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
73
|
+
* Exactly four, derived from WORKER_KILLS: `command-timeout`, `stream-stall`,
|
|
74
|
+
* `worker-timeout` and `connection-error` all discard work the model genuinely
|
|
75
|
+
* did. A loop kill and a leaked tool call do not — the first is by definition the
|
|
76
|
+
* same call repeated, the second is malformed protocol text, and replaying either
|
|
77
|
+
* would feed the failure back to itself.
|
|
85
78
|
*/
|
|
86
79
|
const CARRY_FORWARD_REASONS = CARRY_FORWARD_IDS;
|
|
87
80
|
/**
|
|
88
81
|
* Does this partial output carry ANSWER CONTENT, or is it the model clearing its
|
|
89
82
|
* throat?
|
|
90
83
|
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* attempts and salvage shipped this as the section:
|
|
84
|
+
* Keeping the LONGEST partial is not the same question, and it has an obvious
|
|
85
|
+
* failure: a preamble sentence like
|
|
94
86
|
*
|
|
95
87
|
* "Now let me get more details on the specific APIs and components I need:"
|
|
96
88
|
*
|
|
97
|
-
*
|
|
98
|
-
* nothing. Both trials scored 2 entries and DEGRADED, against 22 and 5 for the
|
|
99
|
-
* same fixtures in baseline.
|
|
89
|
+
* beats an empty string on length and carries nothing.
|
|
100
90
|
*
|
|
101
91
|
* A research worker's answer is a list of lines that each name something and
|
|
102
|
-
* describe it. The test is therefore structural, not lexical: at least
|
|
103
|
-
* that look like entries — a name, then a gap, then a description. Prose wraps
|
|
104
|
-
*
|
|
92
|
+
* describe it. The test is therefore structural, not lexical: at least TWO lines
|
|
93
|
+
* that look like entries — a name, then a gap, then a description. Prose wraps at
|
|
94
|
+
* no particular column and does not repeat that shape; the sentence above scores
|
|
95
|
+
* zero entry lines.
|
|
105
96
|
*/
|
|
106
97
|
export function hasAnswerContent(text) {
|
|
107
98
|
return text.split('\n').filter(isEntryLine).length >= 2;
|
|
@@ -109,13 +100,15 @@ export function hasAnswerContent(text) {
|
|
|
109
100
|
/**
|
|
110
101
|
* Is ONE line an entry — a name, a gap, then a description — rather than prose?
|
|
111
102
|
*
|
|
112
|
-
* Split out of `hasAnswerContent` so the same rule can decide what a line IS,
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
103
|
+
* Split out of `hasAnswerContent` so the same rule can decide what a line IS, not
|
|
104
|
+
* just how many of them there are — a reader of a FILES section needs the same
|
|
105
|
+
* test, and its own idea of an entry would count a preamble sentence or a leaked
|
|
106
|
+
* `</tool_call>` as one.
|
|
116
107
|
*
|
|
117
|
-
*
|
|
118
|
-
* spaced dash
|
|
108
|
+
* A leading `-`, `*`, `•` or `1.`/`1)` bullet is stripped first. What remains must
|
|
109
|
+
* hold a two-space gap or a spaced dash and must NOT end in `.` or `:`. Prose
|
|
110
|
+
* wraps at no particular column, so it carries neither; when it does carry one, it
|
|
111
|
+
* ends in punctuation and an entry does not.
|
|
119
112
|
*/
|
|
120
113
|
export function isEntryLine(raw) {
|
|
121
114
|
const l = raw.replace(/^\s*(?:[-*•]|\d+[.)])\s+/, '').trim();
|
|
@@ -183,10 +176,10 @@ absoluteCeilingMs) {
|
|
|
183
176
|
return {
|
|
184
177
|
signal: ctrl.signal,
|
|
185
178
|
timedOut: () => timedOut,
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
-
//
|
|
189
|
-
//
|
|
179
|
+
// Push the deadline out, never past `started + ceilingMs`. Inert unless a
|
|
180
|
+
// caller calls it. A disabled timeout (nothing armed) stays disabled —
|
|
181
|
+
// extending "never" is meaningless — and an already-fired timer is not
|
|
182
|
+
// resurrected.
|
|
190
183
|
extend: (byMs, ceilingMs) => {
|
|
191
184
|
if (!armed || timedOut || ctrl.signal.aborted)
|
|
192
185
|
return;
|
|
@@ -224,33 +217,6 @@ absoluteCeilingMs) {
|
|
|
224
217
|
}
|
|
225
218
|
};
|
|
226
219
|
}
|
|
227
|
-
/**
|
|
228
|
-
* The per-command ceiling for attempt N, halving each time a hang recurs.
|
|
229
|
-
*
|
|
230
|
-
* The first attempt gets the full configured ceiling — a genuinely slow build or
|
|
231
|
-
* test suite deserves it. But every hang-caused restart carries
|
|
232
|
-
* commandTimeoutHint, which tells the model in as many words to bound its
|
|
233
|
-
* command; a SECOND hang means it ignored an explicit instruction, and a third
|
|
234
|
-
* means it ignored it twice. Giving a non-complying child the full ceiling again
|
|
235
|
-
* would put the worst case at 3 × 15 min = 45 minutes of dead time, resting
|
|
236
|
-
* entirely on the model obeying prose. Halving bounds it at ~26 min while
|
|
237
|
-
* costing a complying child nothing.
|
|
238
|
-
*
|
|
239
|
-
* `priorHangs` counts watchdog kills specifically, NOT total restarts — the
|
|
240
|
-
* restart budget is shared with loop kills, and a child restarted for LOOPING
|
|
241
|
-
* never received the bound-your-command hint, so its first hang still deserves
|
|
242
|
-
* the full ceiling. Only a hang after a hang is defiance.
|
|
243
|
-
*
|
|
244
|
-
* Floored at 30s so repeated halving cannot shrink the ceiling to something no
|
|
245
|
-
* real command could finish inside — but never ABOVE the configured ceiling
|
|
246
|
-
* itself, or a caller asking for 10s would silently get 30.
|
|
247
|
-
*/
|
|
248
|
-
export function commandCeilingForAttempt(baseMs, priorHangs) {
|
|
249
|
-
if (!(baseMs > 0))
|
|
250
|
-
return 0;
|
|
251
|
-
const floor = Math.min(baseMs, 30_000);
|
|
252
|
-
return Math.max(floor, Math.round(baseMs / 2 ** priorHangs));
|
|
253
|
-
}
|
|
254
220
|
/**
|
|
255
221
|
* The restart ladder, in precedence order. FIRST MATCH WINS.
|
|
256
222
|
*
|
|
@@ -323,8 +289,8 @@ export const RESTART_RULES = [
|
|
|
323
289
|
// a loop also tripped — the loop hint above is more specific.
|
|
324
290
|
reason: 'worker-timeout',
|
|
325
291
|
detect: s => s.timedOut && !s.loopHit && s.restartBudgetSpent < MAX_LOOP_RESTARTS ?
|
|
326
|
-
// The EFFECTIVE cap, which
|
|
327
|
-
// configured one would misname why this attempt died.
|
|
292
|
+
// The EFFECTIVE cap, which `extend`/`progress` can have moved —
|
|
293
|
+
// reporting the configured one would misname why this attempt died.
|
|
328
294
|
{ detail: `cap ${s.effectiveCapMs}ms` }
|
|
329
295
|
: null,
|
|
330
296
|
hint: () => WORKER_TIMEOUT_HINT,
|
|
@@ -332,22 +298,15 @@ export const RESTART_RULES = [
|
|
|
332
298
|
},
|
|
333
299
|
{
|
|
334
300
|
// A connection-class model error is restartable on the same budget, exactly
|
|
335
|
-
// as runPhaseChild already treats it
|
|
336
|
-
//
|
|
337
|
-
//
|
|
301
|
+
// as runPhaseChild already treats it. Without it one dropped socket fails
|
|
302
|
+
// the whole task at research, while the identical blip in refine or compose
|
|
303
|
+
// is absorbed.
|
|
338
304
|
//
|
|
339
|
-
//
|
|
340
|
-
//
|
|
341
|
-
//
|
|
342
|
-
//
|
|
343
|
-
//
|
|
344
|
-
// a re-spawn only helps when the outage outlasts it. It does: at a 20s
|
|
345
|
-
// outage the baseline never recovered and this policy always did, 0/8 → 8/8
|
|
346
|
-
// (Fisher p=0.00016), and the same at 35s. Below ~15s pi absorbs it alone —
|
|
347
|
-
// 8/8 both arms, so the retry neither helps nor costs there. Beyond ~46s
|
|
348
|
-
// (three spawns' combined budget) both arms fail. The price is paid only on
|
|
349
|
-
// a backend that is really gone: time-to-report goes ~15s → ~46s. Re-run:
|
|
350
|
-
// scripts/connection-retry-ab.ts.
|
|
305
|
+
// pi retries a failed turn itself before reporting anything, and a run that
|
|
306
|
+
// recovers reports no modelError at all (see JsonEventSink). So a SURFACED
|
|
307
|
+
// connection error means pi's own budget is already spent, and a re-spawn
|
|
308
|
+
// only helps when the outage outlasts it. The price is paid only on a
|
|
309
|
+
// backend that is really gone: time-to-report grows by the extra spawns.
|
|
351
310
|
//
|
|
352
311
|
// Connection class ONLY. Auth, bad request and context overflow still fail
|
|
353
312
|
// fast: re-issuing the same request cannot fix them, so spending the budget
|
|
@@ -374,60 +333,15 @@ export const RESTART_RULES = [
|
|
|
374
333
|
counters: { leak: true }
|
|
375
334
|
}
|
|
376
335
|
];
|
|
377
|
-
/**
|
|
378
|
-
* Build the child-side command watchdog for ONE attempt: a per-tool-call timer
|
|
379
|
-
* machine (shared with the main session) whose `onFire` aborts `signal`, which
|
|
380
|
-
* runChild turns into a process-GROUP kill — reaping the hung command itself,
|
|
381
|
-
* not just the pi child holding it.
|
|
382
|
-
*
|
|
383
|
-
* LIMIT: the group kill only reaches processes still IN the group. A hung
|
|
384
|
-
* command that detached a daemon (setsid/nohup dev server) leaves it running —
|
|
385
|
-
* the fresh attempt can then hit a port the dead attempt's escapee still holds
|
|
386
|
-
* (the run-9 orphan-dev-server → false-EADDRINUSE shape). No cheap fix from
|
|
387
|
-
* here; the restart hint's "check current state" line is the mitigation.
|
|
388
|
-
*
|
|
389
|
-
* Returns null when the watchdog is off, so the caller keeps the plain timeout
|
|
390
|
-
* signal and no per-call bookkeeping happens at all.
|
|
391
|
-
*/
|
|
392
|
-
function commandWatch(timeoutMs) {
|
|
393
|
-
if (!(timeoutMs > 0))
|
|
394
|
-
return null;
|
|
395
|
-
const ctrl = new AbortController();
|
|
396
|
-
// pi's toolCallId pairs start↔end. When it is absent (a fake stream in a
|
|
397
|
-
// test, an older pi), fall back to one shared slot: tool executions in a
|
|
398
|
-
// child are sequential, so a single slot is still correctly paired.
|
|
399
|
-
const key = (id) => id ?? 'anon';
|
|
400
|
-
const details = new Map();
|
|
401
|
-
let killed;
|
|
402
|
-
const watchdog = new CommandWatchdog({
|
|
403
|
-
getTimeoutMs: () => timeoutMs,
|
|
404
|
-
...realTimerDeps,
|
|
405
|
-
onFire: (toolCallId, toolName, ms) => {
|
|
406
|
-
killed = {
|
|
407
|
-
toolName,
|
|
408
|
-
timeoutMs: ms,
|
|
409
|
-
...(details.has(toolCallId) ? { detail: details.get(toolCallId) } : {})
|
|
410
|
-
};
|
|
411
|
-
ctrl.abort();
|
|
412
|
-
}
|
|
413
|
-
});
|
|
414
|
-
return {
|
|
415
|
-
onStart: call => {
|
|
416
|
-
const id = key(call.toolCallId);
|
|
417
|
-
const args = call.args;
|
|
418
|
-
if (typeof args?.command === 'string') {
|
|
419
|
-
details.set(id, args.command.slice(0, 120));
|
|
420
|
-
}
|
|
421
|
-
watchdog.onStart(id, call.name);
|
|
422
|
-
},
|
|
423
|
-
onEnd: id => watchdog.onEnd(key(id)),
|
|
424
|
-
killed: () => killed,
|
|
425
|
-
signal: ctrl.signal,
|
|
426
|
-
clear: () => watchdog.clearAll()
|
|
427
|
-
};
|
|
428
|
-
}
|
|
429
336
|
export async function runWorker(input) {
|
|
430
337
|
const tools = input.tools ?? DEFAULT_TOOLS;
|
|
338
|
+
// `--mode json` makes pi emit structured events as they happen instead of
|
|
339
|
+
// buffering the assistant text and flushing on exit. Its print-mode source
|
|
340
|
+
// shows both halves: under `json` a session subscriber writes every event to
|
|
341
|
+
// stdout as it arrives, while under `text` NOTHING is written until after the
|
|
342
|
+
// prompt resolves, when the last assistant message is printed once. That is
|
|
343
|
+
// what makes the wait/work split real — onFirstByte would otherwise fire
|
|
344
|
+
// moments before close and leave workMs at nearly zero.
|
|
431
345
|
const baseArgs = [
|
|
432
346
|
...childBaseArgs(input.extensions ?? []),
|
|
433
347
|
...(input.thinking ?? []),
|
|
@@ -475,11 +389,10 @@ export async function runWorker(input) {
|
|
|
475
389
|
const salvage = { text: null };
|
|
476
390
|
for (;;) {
|
|
477
391
|
const carried = salvage.text === null ? null : formatCarryForward(salvage.text);
|
|
478
|
-
// Announce the INJECTION, not just the restart.
|
|
479
|
-
//
|
|
480
|
-
//
|
|
481
|
-
//
|
|
482
|
-
// downstream of here can show it.
|
|
392
|
+
// Announce the INJECTION, not just the restart. The prompt goes to the child
|
|
393
|
+
// on stdin, so no log downstream of here can show it — without this hook
|
|
394
|
+
// "the carry reached the re-spawn" could only be inferred from the answer,
|
|
395
|
+
// which is inferring what a worker did from what it produced.
|
|
483
396
|
if (carried !== null) {
|
|
484
397
|
input.onCarryForward?.({
|
|
485
398
|
attempt: restarts.length + 1,
|
|
@@ -506,8 +419,8 @@ export async function runWorker(input) {
|
|
|
506
419
|
null
|
|
507
420
|
: new StallDetector(guards.loop.progress.limit, guards.loop.progress.churnFactor);
|
|
508
421
|
// Arm the churn rule BEFORE the first tool call. pi's stream carries no
|
|
509
|
-
// context event
|
|
510
|
-
//
|
|
422
|
+
// context event at all, so waiting for one leaves the rule permanently
|
|
423
|
+
// disarmed. The parent knows the window at spawn time.
|
|
511
424
|
stallDetector?.noteContext(contextWindowTokens(input.contextWindow));
|
|
512
425
|
// Capture the hit the detector reports (it also returns it to the unified
|
|
513
426
|
// runner, which kills the child on a hit). Without capturing it here the
|
|
@@ -546,8 +459,9 @@ export async function runWorker(input) {
|
|
|
546
459
|
// A tool call is the worker working. Inert unless the
|
|
547
460
|
// caller opted into a progress-based deadline.
|
|
548
461
|
timeout.progress();
|
|
549
|
-
//
|
|
550
|
-
//
|
|
462
|
+
// Naming ONE tool and ONE of its parameters here would put
|
|
463
|
+
// that knowledge in the generic runner, so it asks the
|
|
464
|
+
// tool's own row in WORKER_CHANNELS instead.
|
|
551
465
|
if (clock.fanout
|
|
552
466
|
&& workerChannel(call.name)?.isProjectSourceLookup?.(call.args ?? {}) === true) {
|
|
553
467
|
timeout.extend(clock.fanout.perLookupMs, clock.fanout.ceilingMs);
|
|
@@ -570,11 +484,11 @@ export async function runWorker(input) {
|
|
|
570
484
|
timeout.progress();
|
|
571
485
|
input.onLine?.(line);
|
|
572
486
|
},
|
|
573
|
-
// Always wired
|
|
574
|
-
//
|
|
575
|
-
//
|
|
576
|
-
//
|
|
577
|
-
//
|
|
487
|
+
// Always wired, never conditional on the command watchdog: the
|
|
488
|
+
// sink only emits a tool-execution-end if a handler exists, and
|
|
489
|
+
// a completed tool call is the clearest progress signal there
|
|
490
|
+
// is. Without it a worker whose tool calls all succeed would
|
|
491
|
+
// still look idle to the deadline.
|
|
578
492
|
onToolResult: r => {
|
|
579
493
|
timeout.progress();
|
|
580
494
|
cmdWatch?.onEnd(r.toolCallId);
|
|
@@ -637,7 +551,7 @@ export async function runWorker(input) {
|
|
|
637
551
|
// there would just mislabel the real failure.
|
|
638
552
|
const leaked = result.exitCode === 0 && !result.aborted ? detectLeakedToolCall(text) : null;
|
|
639
553
|
// THE RESTART LADDER. Precedence is RESTART_RULES' row order; this loop
|
|
640
|
-
// owns the ritual every rule
|
|
554
|
+
// owns the ritual every rule would otherwise repeat: budget, hint, counters,
|
|
641
555
|
// record-and-announce, backoff, re-spawn.
|
|
642
556
|
const state = {
|
|
643
557
|
...(loopHit ? { loopHit } : {}),
|
|
@@ -678,24 +592,22 @@ export async function runWorker(input) {
|
|
|
678
592
|
}
|
|
679
593
|
if (restarted)
|
|
680
594
|
continue;
|
|
681
|
-
// SALVAGE.
|
|
682
|
-
//
|
|
683
|
-
//
|
|
684
|
-
//
|
|
685
|
-
//
|
|
686
|
-
// with a worse one.
|
|
595
|
+
// SALVAGE. Returning the LAST attempt's text unconditionally makes a
|
|
596
|
+
// worker whose final attempt was killed early report nothing at all — even
|
|
597
|
+
// when a discarded attempt produced a usable answer that was still in hand
|
|
598
|
+
// at the moment it was thrown away. A restart budget is meant to buy more
|
|
599
|
+
// chances at an answer, not to overwrite a good attempt with a worse one.
|
|
687
600
|
//
|
|
688
601
|
// Gated on the final attempt having FAILED, not on it being shorter. A
|
|
689
602
|
// worker that finished cleanly has answered, and a short answer is a
|
|
690
603
|
// legitimate answer — length would let a long half-finished fragment
|
|
691
604
|
// override a concise correct one, which is the opposite of the fix.
|
|
692
|
-
// ASK THE LADDER — do not restate it.
|
|
693
|
-
//
|
|
694
|
-
//
|
|
695
|
-
//
|
|
696
|
-
//
|
|
697
|
-
//
|
|
698
|
-
// outcome the comment above forbids.
|
|
605
|
+
// ASK THE LADDER — do not restate it. Hand-writing this test restates the
|
|
606
|
+
// taxonomy `worker-failure.ts` owns, and a restatement drifts: drop
|
|
607
|
+
// `leakedToolCall` or a plain non-zero `exitCode` from it and an attempt
|
|
608
|
+
// that produced nothing usable counts as NOT failed, so salvage is skipped
|
|
609
|
+
// and a good earlier partial is overwritten — the outcome the comment above
|
|
610
|
+
// forbids.
|
|
699
611
|
//
|
|
700
612
|
// The two non-kill terms stay explicit because `worker-failure.ts`
|
|
701
613
|
// deliberately excludes them as CONSUMER policy: an empty answer and a
|
|
@@ -23,21 +23,25 @@ interface DocsDetails {
|
|
|
23
23
|
versionSource?: 'declared-range' | 'npm-latest';
|
|
24
24
|
declaredRange?: string;
|
|
25
25
|
/**
|
|
26
|
-
* The answer restated a declaration for a question that needed usage semantics, so
|
|
27
|
-
* is UNANSWERED
|
|
28
|
-
* never memoised and re-served to a later sibling task.
|
|
26
|
+
* The answer restated a declaration for a question that needed usage semantics, so
|
|
27
|
+
* it is UNANSWERED. Set by isTypeOnlyAnswer; read by `docsCacheable` so a non-answer
|
|
28
|
+
* is never memoised and re-served to a later sibling task.
|
|
29
29
|
*/
|
|
30
30
|
typeOnly?: boolean;
|
|
31
|
-
/** The
|
|
31
|
+
/** The project-lookup budget for this attempt is spent, so the call was refused
|
|
32
|
+
* before any work. Only set when PI_TASK_PROJECT_DOCS_BUDGET is configured. */
|
|
32
33
|
budgetSpent?: boolean;
|
|
33
34
|
}
|
|
34
35
|
/**
|
|
35
36
|
* Pull `@see {@link https://…}` pointers out of retrieved .d.ts/README text.
|
|
36
37
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
38
|
+
* When the answer to a type-only lookup is not in the package, it is often at the
|
|
39
|
+
* `@see` URL the excerpt being returned already carries. Surfacing that link costs
|
|
40
|
+
* nothing: the pointer is already in hand.
|
|
41
|
+
*
|
|
42
|
+
* Matches `{@link URL}` and a bare `@link URL`, case-insensitively; strips a trailing
|
|
43
|
+
* `.`/`,`/`;` the surrounding prose added; deduplicates. A bare URL with no `@see` is
|
|
44
|
+
* not a pointer and is not returned.
|
|
41
45
|
*/
|
|
42
46
|
export declare function extractSeeUrls(content: string): string[];
|
|
43
47
|
/**
|
|
@@ -57,24 +61,25 @@ export interface PiWorkerDocsInternals {
|
|
|
57
61
|
}
|
|
58
62
|
export declare function registerPiWorkerDocs(pi: ExtensionAPI, internals?: PiWorkerDocsInternals): void;
|
|
59
63
|
/**
|
|
60
|
-
* The
|
|
61
|
-
*
|
|
64
|
+
* The cache rule for the docs channel, as a NAMED export rather than an anonymous
|
|
65
|
+
* property of an adapter literal.
|
|
62
66
|
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* exists to prevent: four regexes matching three phrasings, documented at length in
|
|
68
|
-
* abstention.ts, which cost a real bug.
|
|
67
|
+
* As a property of the adapter literal it would be reachable only through
|
|
68
|
+
* `registerTool → execute()`, so a test would have to retype the rule and would then
|
|
69
|
+
* assert against its own copy — green even after the shipped rule changed. Exported,
|
|
70
|
+
* the test imports the rule it is checking.
|
|
69
71
|
*/
|
|
70
72
|
export declare function docsCacheable(d: Pick<DocsDetails, 'typeOnly' | 'excerptVerified'>, text: string): boolean;
|
|
71
|
-
/** The docs cache key: a package's answer is per (module, question)
|
|
72
|
-
*
|
|
73
|
+
/** The docs cache key: a package's answer is per (module, question), with the question
|
|
74
|
+
* lowercased and its whitespace collapsed so phrasing variants share one entry. Returns
|
|
75
|
+
* null for the project-source `.` lookup, which is never cached — the working tree
|
|
76
|
+
* mutates as tasks implement. */
|
|
73
77
|
export declare function docsCacheKey(params: {
|
|
74
78
|
module: string;
|
|
75
79
|
query: string;
|
|
76
80
|
}): string | null;
|
|
77
|
-
/** Package provenance for per-entry resume invalidation
|
|
81
|
+
/** Package provenance for per-entry resume invalidation: the package ROOT of the
|
|
82
|
+
* specifier (`hono/client` → `hono`), and undefined for the project-source `.`. */
|
|
78
83
|
export declare function docsCachePkg(params: {
|
|
79
84
|
module: string;
|
|
80
85
|
}): string | undefined;
|