@sema-agent/core 7.15.0 → 7.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +202 -0
- package/dist/agents/builtin-agents.d.ts +3 -3
- package/dist/agents/cross-session-envelope.d.ts +0 -1
- package/dist/agents/cross-session-envelope.js +0 -1
- package/dist/agents/peer-notices.d.ts +0 -9
- package/dist/agents/peer-notices.js +0 -63
- package/dist/agents/subagent.js +7 -15
- package/dist/brain/request-params.d.ts +2 -2
- package/dist/config/defaults.d.ts +0 -7
- package/dist/config/defaults.js +0 -2
- package/dist/core/artifact-host.d.ts +218 -0
- package/dist/core/artifact-host.js +92 -0
- package/dist/core/ask-origin.d.ts +29 -3
- package/dist/core/ask-origin.js +17 -9
- package/dist/core/ask-question.d.ts +25 -0
- package/dist/core/ask-question.js +4 -0
- package/dist/core/ask-unresolvable-notice.d.ts +30 -21
- package/dist/core/ask-unresolvable-notice.js +16 -8
- package/dist/core/auto-compaction.d.ts +10 -10
- package/dist/core/auto-mode-arming.d.ts +2 -2
- package/dist/core/background-agent-store.d.ts +5 -5
- package/dist/core/background-shell.d.ts +1 -1
- package/dist/core/checkpoint-execution-record.d.ts +0 -3
- package/dist/core/checkpoint-execution-record.js +0 -4
- package/dist/core/checkpoint-store.d.ts +71 -99
- package/dist/core/checkpoint-store.js +9 -16
- package/dist/core/context-edit.d.ts +36 -104
- package/dist/core/context-edit.js +37 -60
- package/dist/core/effective-path-target.d.ts +68 -8
- package/dist/core/effective-path-target.js +42 -30
- package/dist/core/engine-notice.d.ts +46 -32
- package/dist/core/env-budget.d.ts +31 -0
- package/dist/core/env-budget.js +39 -0
- package/dist/core/exec-output-tail.d.ts +5 -5
- package/dist/core/file-history-store.js +3 -6
- package/dist/core/fs-write-gate-policy.d.ts +1 -1
- package/dist/core/fs-write-gate-policy.js +3 -3
- package/dist/core/gate-lanes.js +9 -15
- package/dist/core/governance-codes.d.ts +1 -1
- package/dist/core/governance-codes.js +4 -0
- package/dist/core/hands-band.d.ts +1 -1
- package/dist/core/hooks.d.ts +18 -17
- package/dist/core/lsp-session.d.ts +1 -1
- package/dist/core/lsp.d.ts +1 -1
- package/dist/core/lsp.js +5 -4
- package/dist/core/mcp.d.ts +5 -5
- package/dist/core/mcp.js +4 -48
- package/dist/core/memory-engine/delegation-settlement.d.ts +37 -12
- package/dist/core/memory-engine/delegation-settlement.js +128 -39
- package/dist/core/memory-engine/engine.d.ts +9 -8
- package/dist/core/memory-engine/engine.js +115 -120
- package/dist/core/memory-engine/file-backend.d.ts +17 -5
- package/dist/core/memory-engine/file-backend.js +78 -34
- package/dist/core/memory-engine/index.d.ts +2 -2
- package/dist/core/memory-engine/index.js +2 -2
- package/dist/core/memory-engine/layout.d.ts +152 -54
- package/dist/core/memory-engine/layout.js +441 -104
- package/dist/core/memory-engine/types.d.ts +8 -3
- package/dist/core/memory-engine/types.js +5 -0
- package/dist/core/memory-recall.d.ts +0 -8
- package/dist/core/memory.d.ts +1 -1
- package/dist/core/oracle-isolation.js +2 -2
- package/dist/core/parent-spec-seat.d.ts +66 -0
- package/dist/core/parent-spec-seat.js +47 -0
- package/dist/core/permission-rule-model.d.ts +11 -6
- package/dist/core/permission-rule-model.js +53 -37
- package/dist/core/permission-rules.js +8 -3
- package/dist/core/protocol-naming.d.ts +2 -2
- package/dist/core/remote-env.d.ts +1 -1
- package/dist/core/retired-keys.d.ts +19 -0
- package/dist/core/retired-keys.js +15 -0
- package/dist/core/runner/abort-race.d.ts +3 -3
- package/dist/core/runner/active-skill-scope.d.ts +2 -2
- package/dist/core/runner/active-skill-scope.js +3 -3
- package/dist/core/runner/assemble-result.d.ts +42 -40
- package/dist/core/runner/assemble-result.js +5 -4
- package/dist/core/runner/checkpoint-scope.d.ts +4 -4
- package/dist/core/runner/clock-and-limits.d.ts +3 -3
- package/dist/core/runner/compaction-call-options.d.ts +35 -99
- package/dist/core/runner/compaction-knobs.d.ts +4 -4
- package/dist/core/runner/compaction-seams.d.ts +5 -5
- package/dist/core/runner/contracts.d.ts +232 -233
- package/dist/core/runner/decide-continuation.d.ts +6 -6
- package/dist/core/runner/denial-limit-arms.d.ts +8 -8
- package/dist/core/runner/derived-route-fallback.d.ts +2 -2
- package/dist/core/runner/gate-exit.d.ts +6 -6
- package/dist/core/runner/gate-exit.js +15 -1
- package/dist/core/runner/git-status-frame.d.ts +7 -7
- package/dist/core/runner/halt-attribution.d.ts +35 -0
- package/dist/core/runner/halt-attribution.js +16 -0
- package/dist/core/runner/inherited-ask-grants.d.ts +6 -6
- package/dist/core/runner/memory-capture-optout.d.ts +1 -1
- package/dist/core/runner/memory-consolidation-driver.d.ts +4 -4
- package/dist/core/runner/memory-consolidation.d.ts +6 -8
- package/dist/core/runner/memory-consolidation.js +0 -1
- package/dist/core/runner/park-commit.d.ts +6 -6
- package/dist/core/runner/permission-rule-lanes.d.ts +19 -19
- package/dist/core/runner/prepare-acquire-reconcile.d.ts +4 -4
- package/dist/core/runner/prepare-artifact.d.ts +53 -0
- package/dist/core/runner/prepare-artifact.js +77 -0
- package/dist/core/runner/prepare-ask-lane.d.ts +3 -3
- package/dist/core/runner/prepare-boundary-parks.d.ts +3 -3
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +9 -7
- package/dist/core/runner/prepare-caps-and-workflow.js +2 -3
- package/dist/core/runner/prepare-config-doors.d.ts +24 -24
- package/dist/core/runner/prepare-config-doors.js +5 -2
- package/dist/core/runner/prepare-context-lane.d.ts +8 -8
- package/dist/core/runner/prepare-context-lane.js +2 -13
- package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
- package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
- package/dist/core/runner/prepare-file-history.d.ts +3 -3
- package/dist/core/runner/prepare-file-history.js +3 -52
- package/dist/core/runner/prepare-gate-stations.d.ts +5 -5
- package/dist/core/runner/prepare-hands-readface.d.ts +35 -38
- package/dist/core/runner/prepare-hands-readface.js +3 -2
- package/dist/core/runner/prepare-inherited-gate.d.ts +9 -6
- package/dist/core/runner/prepare-inherited-gate.js +7 -8
- package/dist/core/runner/prepare-listings.d.ts +3 -3
- package/dist/core/runner/prepare-lsp.d.ts +3 -3
- package/dist/core/runner/prepare-memory-engine-session.d.ts +5 -5
- package/dist/core/runner/prepare-memory.d.ts +4 -6
- package/dist/core/runner/prepare-memory.js +10 -9
- package/dist/core/runner/prepare-offload-wrappers.d.ts +2 -2
- package/dist/core/runner/prepare-park-ask.d.ts +6 -6
- package/dist/core/runner/prepare-policy-chain.d.ts +7 -7
- package/dist/core/runner/prepare-policy-chain.js +15 -30
- package/dist/core/runner/prepare-prompt-assembly.js +1 -1
- package/dist/core/runner/prepare-prompt-inputs.d.ts +5 -5
- package/dist/core/runner/prepare-protocol-tools.d.ts +1 -1
- package/dist/core/runner/prepare-question-face.d.ts +4 -4
- package/dist/core/runner/prepare-run-refs.d.ts +11 -11
- package/dist/core/runner/prepare-safety-scan.d.ts +2 -2
- package/dist/core/runner/prepare-suspend-saga.d.ts +4 -4
- package/dist/core/runner/prepare-suspend-saga.js +0 -2
- package/dist/core/runner/prepare-task.d.ts +12 -12
- package/dist/core/runner/prepare-task.js +10 -9
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +2 -3
- package/dist/core/runner/prepare-wiring-manifest.d.ts +4 -4
- package/dist/core/runner/prepare-wiring-manifest.js +9 -7
- package/dist/core/runner/prepare-workspace-restore.d.ts +1 -1
- package/dist/core/runner/remote-env-retry.d.ts +3 -3
- package/dist/core/runner/resume-admission.d.ts +1 -1
- package/dist/core/runner/resume-admission.js +2 -1
- package/dist/core/runner/resume-claim.d.ts +1 -1
- package/dist/core/runner/resume-internals-and-config.d.ts +1 -1
- package/dist/core/runner/resume-internals-and-config.js +4 -0
- package/dist/core/runner/resume-policy-outcome.d.ts +1 -1
- package/dist/core/runner/resume-preflight.d.ts +1 -1
- package/dist/core/runner/resume-review-outcome.d.ts +1 -1
- package/dist/core/runner/retired-runner-deps.d.ts +3 -0
- package/dist/core/runner/retired-runner-deps.js +7 -0
- package/dist/core/runner/run-brain-sinks.d.ts +1 -1
- package/dist/core/runner/run-clock-and-content.d.ts +4 -4
- package/dist/core/runner/run-compaction-machinery.d.ts +3 -3
- package/dist/core/runner/run-git-lane.d.ts +1 -1
- package/dist/core/runner/run-harness-handlers.d.ts +2 -2
- package/dist/core/runner/run-harness-handlers.js +2 -3
- package/dist/core/runner/run-identity-wiring.d.ts +4 -4
- package/dist/core/runner/run-leg.d.ts +3 -3
- package/dist/core/runner/run-notification-lane.d.ts +2 -2
- package/dist/core/runner/run-reasoning-seat.d.ts +2 -2
- package/dist/core/runner/run-settle-and-teardown.d.ts +5 -5
- package/dist/core/runner/run-settle-and-teardown.js +3 -1
- package/dist/core/runner/run-telemetry-and-budget-seats.d.ts +2 -2
- package/dist/core/runner/run-terminal-adoption.d.ts +5 -5
- package/dist/core/runner/runtask.d.ts +14 -14
- package/dist/core/runner/session-file-state-replay.d.ts +3 -3
- package/dist/core/runner/session-file-state-replay.js +3 -3
- package/dist/core/runner/session-rule-policy.d.ts +2 -2
- package/dist/core/runner/session-rule-policy.js +3 -4
- package/dist/core/runner/steer-admission.d.ts +2 -2
- package/dist/core/runner/stream-halt-verbs.d.ts +1 -1
- package/dist/core/runner/stream-halt-verbs.js +1 -1
- package/dist/core/runner/stream-reap.d.ts +1 -1
- package/dist/core/runner/stream-steer-verb.js +1 -4
- package/dist/core/runner/synthetic-tools.d.ts +8 -8
- package/dist/core/runner/teardown-bounded.d.ts +2 -2
- package/dist/core/runner/tool-defer-gate.d.ts +1 -1
- package/dist/core/runner/tool-disclosure.d.ts +33 -33
- package/dist/core/runner/tool-end-body.d.ts +3 -3
- package/dist/core/runner/tool-face-overlay.d.ts +2 -2
- package/dist/core/runner/tool-output-projection.d.ts +2 -2
- package/dist/core/runner/turn-attachments.d.ts +53 -53
- package/dist/core/runner/usage-accounting.d.ts +4 -4
- package/dist/core/runner/workspace-path.d.ts +1 -1
- package/dist/core/runner/workspace-path.js +3 -0
- package/dist/core/runner-deps.d.ts +30 -49
- package/dist/core/safe-notify.d.ts +1 -1
- package/dist/core/sensitive-path-policy.d.ts +1 -1
- package/dist/core/sensitive-path-policy.js +4 -4
- package/dist/core/session.d.ts +2 -2
- package/dist/core/skill-tool-specifier.d.ts +1 -1
- package/dist/core/skills-directory.d.ts +1 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +1 -1
- package/dist/core/strategy-store.d.ts +8 -11
- package/dist/core/task-event.d.ts +20 -17
- package/dist/core/task-limits.d.ts +1 -1
- package/dist/core/task-notification.d.ts +5 -5
- package/dist/core/task-registry-agent.d.ts +5 -5
- package/dist/core/task-registry-monitor.d.ts +2 -2
- package/dist/core/task-registry-shared.d.ts +27 -27
- package/dist/core/task-registry-shared.js +3 -13
- package/dist/core/task-registry.d.ts +8 -8
- package/dist/core/task-result.d.ts +37 -37
- package/dist/core/task-spec.d.ts +5 -5
- package/dist/core/task-stream.d.ts +16 -11
- package/dist/core/tool-catalog-entries.d.ts +1 -0
- package/dist/core/tool-catalog-entries.js +5 -0
- package/dist/core/tool-conformance.d.ts +0 -2
- package/dist/core/tool-conformance.js +1 -3
- package/dist/core/tool-errors.d.ts +5 -0
- package/dist/core/tool-errors.js +1 -0
- package/dist/core/tool-policy.d.ts +51 -22
- package/dist/core/tool-policy.js +28 -5
- package/dist/core/tool-result-budget.d.ts +1 -1
- package/dist/core/tool-result-store.d.ts +11 -11
- package/dist/core/tool-spec.d.ts +34 -38
- package/dist/core/tools.d.ts +2 -2
- package/dist/core/trace.d.ts +12 -15
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/core/wiring-manifest.d.ts +4 -3
- package/dist/core/workflow-journal-store.d.ts +11 -11
- package/dist/engine/execution-env/node-execution-env.d.ts +3 -2
- package/dist/engine/execution-env/node-execution-env.js +4 -2
- package/dist/engine/harness/agent-harness.d.ts +47 -4
- package/dist/engine/harness/agent-harness.js +52 -9
- package/dist/engine/llm/types.d.ts +1 -1
- package/dist/engine/loop/agent-loop.js +15 -8
- package/dist/engine/loop/types.d.ts +5 -0
- package/dist/index.d.ts +21 -16
- package/dist/index.js +17 -12
- package/dist/internal/harness.d.ts +1 -0
- package/dist/orchestration/run-spec.d.ts +3 -0
- package/dist/orchestration/run-spec.js +3 -3
- package/dist/orchestration/run-workflow-tool.d.ts +12 -6
- package/dist/orchestration/run-workflow-tool.js +23 -5
- package/dist/orchestration/workflow-primitives.d.ts +4 -2
- package/dist/orchestration/workflow-primitives.js +1 -4
- package/dist/orchestration/workflow-types.d.ts +34 -4
- package/dist/orchestration/workflow-types.js +2 -0
- package/dist/orchestration/workflow.d.ts +39 -7
- package/dist/orchestration/workflow.js +234 -113
- package/dist/prompt-assembly/assemble.d.ts +2 -2
- package/dist/prompt-assembly/assemble.js +9 -9
- package/dist/prompt-assembly/composer.d.ts +6 -7
- package/dist/prompt-assembly/composer.js +10 -10
- package/dist/prompt-assembly/epoch.js +1 -1
- package/dist/prompt-assembly/event-registry.d.ts +0 -21
- package/dist/prompt-assembly/packs/sema-default.js +30 -30
- package/dist/prompt-assembly/types.d.ts +14 -14
- package/dist/prompts/coordinator.d.ts +0 -13
- package/dist/prompts/coordinator.js +0 -3
- package/dist/stores/file/checkpoint-store.js +1 -5
- package/dist/stores/file/file-history-store.js +2 -2
- package/dist/stores/file/permission-rule-store.d.ts +4 -35
- package/dist/stores/file/permission-rule-store.js +4 -148
- package/dist/tools/artifact/artifact-text.d.ts +62 -0
- package/dist/tools/artifact/artifact-text.js +68 -0
- package/dist/tools/artifact/artifact-tool.d.ts +52 -0
- package/dist/tools/artifact/artifact-tool.js +351 -0
- package/dist/tools/artifact/local-stub.d.ts +26 -0
- package/dist/tools/artifact/local-stub.js +296 -0
- package/dist/tools/fs/bash-readonly-classifier.d.ts +114 -48
- package/dist/tools/fs/bash-readonly-classifier.js +171 -60
- package/dist/tools/fs/encoding.d.ts +31 -40
- package/dist/tools/fs/fs-bash.d.ts +49 -45
- package/dist/tools/fs/fs-bash.js +19 -27
- package/dist/tools/fs/fs-pdf.d.ts +8 -8
- package/dist/tools/fs/fs-search-tools.d.ts +4 -4
- package/dist/tools/fs/fs-search-tools.js +5 -2
- package/dist/tools/fs/fs-shared.d.ts +146 -158
- package/dist/tools/fs/fs-shared.js +3 -11
- package/dist/tools/fs/fs-write.d.ts +8 -8
- package/dist/tools/fs/gh-rate-limit.d.ts +13 -14
- package/dist/tools/fs/index.d.ts +78 -78
- package/dist/tools/fs/index.js +4 -1
- package/dist/tools/fs/notebook.d.ts +24 -25
- package/dist/tools/fs/pdf.d.ts +3 -3
- package/dist/tools/fs/read-deny.d.ts +22 -22
- package/dist/tools/fs/read-face.d.ts +21 -24
- package/dist/tools/fs/repo-map.d.ts +8 -8
- package/dist/tools/fs/safety.d.ts +233 -130
- package/dist/tools/fs/safety.js +131 -31
- package/dist/tools/fs/search.d.ts +63 -71
- package/dist/tools/fs/search.js +8 -6
- package/package.json +6 -2
- package/test/export-surface.snapshot.json +119 -39
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { homedir } from "node:os";
|
|
2
2
|
import { isAbsolute, join, resolve } from "node:path";
|
|
3
|
-
import { canonicalizeTarget, expandHomeTilde,
|
|
3
|
+
import { canonicalizeTarget, expandHomeTilde, isAbsoluteForFamily, isWinFormPath, pathFamilyOf, writeTargetPath } from "../tools/fs/safety.js";
|
|
4
4
|
import { compileSegmentPattern, matchSegmentPatterns } from "../tools/fs/read-deny.js";
|
|
5
5
|
import { isProtectedWrite, protectivePathTargetOf } from "./tool-registry.js";
|
|
6
6
|
import { pathTargetBaseOf } from "./effective-path-target.js";
|
|
@@ -40,7 +40,7 @@ export function dataRootSpellings(explicit) {
|
|
|
40
40
|
const engineForm = isAbsolute(raw) ? raw : resolve(raw);
|
|
41
41
|
const out = [];
|
|
42
42
|
for (const v of [raw, tilde, engineForm]) {
|
|
43
|
-
const anchored =
|
|
43
|
+
const anchored = isAbsoluteForFamily(pathFamilyOf({ root: v }), v) ? v : resolve(v);
|
|
44
44
|
if (!out.includes(anchored))
|
|
45
45
|
out.push(anchored);
|
|
46
46
|
}
|
|
@@ -82,7 +82,7 @@ export function createSensitivePathPolicy(opts) {
|
|
|
82
82
|
const keys = [];
|
|
83
83
|
for (const spelling of dataRootPaths) {
|
|
84
84
|
try {
|
|
85
|
-
const r = await canonicalizeTarget(opts.env, spelling, signal);
|
|
85
|
+
const r = await canonicalizeTarget(opts.env, spelling, signal, pathFamilyOf({ root: spelling }));
|
|
86
86
|
if (r.ok && !keys.includes(r.key))
|
|
87
87
|
keys.push(r.key);
|
|
88
88
|
}
|
|
@@ -102,7 +102,7 @@ export function createSensitivePathPolicy(opts) {
|
|
|
102
102
|
const path = writeTargetPath(req, protective);
|
|
103
103
|
if (typeof path !== "string" || path.length === 0)
|
|
104
104
|
return { action: "allow" };
|
|
105
|
-
const canon = await canonicalizeTarget(opts.env, path, signal, pathTargetBaseOf(protective, { root: opts.rootPath, cwd: req.cwd }));
|
|
105
|
+
const canon = await canonicalizeTarget(opts.env, path, signal, pathFamilyOf({ root: opts.rootPath, cwd: req.cwd ?? opts.env.cwd }), pathTargetBaseOf(protective, { root: opts.rootPath, cwd: req.cwd }));
|
|
106
106
|
if (!canon.ok) {
|
|
107
107
|
if (canon.unresolvedSymlink) {
|
|
108
108
|
return {
|
package/dist/core/session.d.ts
CHANGED
|
@@ -74,7 +74,7 @@ export interface SessionStoreSummary {
|
|
|
74
74
|
* Absent until a task has run on the session (recorded via {@link SessionStore.noteTaskRun}). */
|
|
75
75
|
lastTaskId?: string;
|
|
76
76
|
/**
|
|
77
|
-
*
|
|
77
|
+
* An ENGINE-minted run identity for this session ({@link import("./types.js").TaskResult.runId}),
|
|
78
78
|
* recorded by the most recent {@link SessionStore.noteTaskRun} write to LAND.
|
|
79
79
|
* {@link lastTaskId} above is `spec.taskId ?? sessionId`, so on the ordinary deployment that supplies no
|
|
80
80
|
* host task id it answers the SESSION's own id: a "last run" handle that names the session it hangs off
|
|
@@ -317,7 +317,7 @@ export declare function boundedTail(pathEntries: readonly SessionTreeEntry[]): {
|
|
|
317
317
|
* times in one prepare (project-memory phase, design/148 center adoption, the epoch-pin
|
|
318
318
|
* discriminator), and an entry-COUNT proxy at ANY of them re-creates the same lie: a host may write
|
|
319
319
|
* session_info / model_change / … rows before the first turn (naming a new chat, recording a model
|
|
320
|
-
* pick), and none of that is evidence of a prior session (
|
|
320
|
+
* pick), and none of that is evidence of a prior session (the count proxy
|
|
321
321
|
* survived at the adoption arm after the pin arm was fixed, silently costing a pre-named session
|
|
322
322
|
* its published center prompt for life). Conversation content — and only that — is the evidence.
|
|
323
323
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Pattern specifiers inside a {@link import("./types.js").SkillManifest}'s `allowTools`.
|
|
3
3
|
*
|
|
4
4
|
* An entry may be a bare tool name (`Bash`) or a name carrying a specifier (`Bash(git:*)`). A bare name
|
|
5
5
|
* claims the whole tool; a specifier claims a NARROWER slice of it. Both directions of that sentence are
|
|
@@ -42,7 +42,7 @@ export type SkillsDirectoryWarningCode =
|
|
|
42
42
|
| "name_mismatch"
|
|
43
43
|
/** Required `description` absent. */
|
|
44
44
|
| "missing_description"
|
|
45
|
-
/**
|
|
45
|
+
/** An `allowed-tools` entry carries a pattern specifier (`Bash(git:*)`) — the scope policy
|
|
46
46
|
* matches names, not patterns, so the entry cannot match and the tool is DISABLED in this skill
|
|
47
47
|
* frame. Disclosed loudly until pattern enforcement lands (the entry is deliberately NOT widened to
|
|
48
48
|
* its base name: that would turn "only git" into "all of Bash"). */
|
|
@@ -185,7 +185,7 @@ export async function checkpointStoreContract(make, runAssertion) {
|
|
|
185
185
|
assert.equal(q[0].text, "go");
|
|
186
186
|
assert.equal(q[0].trusted, false);
|
|
187
187
|
assert.equal(q[0].seq, 1);
|
|
188
|
-
assert.equal((await store.get(cp.token)).state
|
|
188
|
+
assert.equal("pendingSteer" in (await store.get(cp.token)).state, false);
|
|
189
189
|
});
|
|
190
190
|
run("setPendingSteer APPENDS: two steers both survive in issue order, each keeping its frozen trust", async () => {
|
|
191
191
|
const store = make();
|
|
@@ -156,19 +156,16 @@ export declare function validateStrategyForWrite(s: StoredStrategy): void;
|
|
|
156
156
|
* source for the in-memory and file-backed stores, so retrieval semantics cannot fork between
|
|
157
157
|
* backends.
|
|
158
158
|
*
|
|
159
|
-
* TWO acceptance arms, OR-combined
|
|
159
|
+
* TWO acceptance arms, OR-combined (retrieval semantics, pinned):
|
|
160
160
|
* - full arm — every significant term (alphanumeric AND CJK) present in the problem;
|
|
161
|
-
* -
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
* have silently un-matched that pair — a recall regression hiding inside a recall fix. Keeping
|
|
165
|
-
* the legacy arm costs precision only relative to a strictness nobody ever had.
|
|
161
|
+
* - alphanumeric arm — every significant ALPHANUMERIC term present (and there is ≥1), so a mixed
|
|
162
|
+
* query ("请帮我 extract tables from report.pdf") still matches an English-only stored problem —
|
|
163
|
+
* requiring the CJK boilerplate too would un-match that pair.
|
|
166
164
|
*
|
|
167
|
-
* ACCEPTED COST (documented, pinned): via the
|
|
168
|
-
* match can hit a problem whose CJK terms CONFLICT (提取 X vs 删除 X)
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
* injection audit); tightening precision is a measured-recalibration change, not a retrieval patch.
|
|
165
|
+
* ACCEPTED COST (documented, pinned): via the alphanumeric arm, a mixed query whose alphanumeric
|
|
166
|
+
* terms all match can hit a problem whose CJK terms CONFLICT (提取 X vs 删除 X). The mitigation is
|
|
167
|
+
* the surrounding depth (negation preamble, verify-before-use instruction, injection audit);
|
|
168
|
+
* tightening precision is a measured-recalibration change, not a retrieval patch.
|
|
172
169
|
*/
|
|
173
170
|
export declare function compileStrategyQuery(query: string): ((problem: string) => boolean) | null;
|
|
174
171
|
export declare function normalizeStrategyText(s: string): string;
|
|
@@ -64,7 +64,7 @@ export interface TaskEventIdentity {
|
|
|
64
64
|
*/
|
|
65
65
|
export type BrainStatusPhase = "rate_limited" | "retrying" | "reconnecting" | "circuit_open"
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
67
|
+
* TERMINAL frames closing a retry sequence. Without them a consumer that rendered a
|
|
68
68
|
* `rate_limited`/`retrying`/`reconnecting` frame has nothing telling it the wait is over, so the
|
|
69
69
|
* warning row stays pinned until the next unrelated event. Exactly one terminal frame is emitted,
|
|
70
70
|
* and only for a call that actually waited (a retry wait, or a `waiting_first_token` trail —
|
|
@@ -75,7 +75,7 @@ export type BrainStatusPhase = "rate_limited" | "retrying" | "reconnecting" | "c
|
|
|
75
75
|
*/
|
|
76
76
|
| "recovered" | "gave_up"
|
|
77
77
|
/**
|
|
78
|
-
*
|
|
78
|
+
* The first-token WAIT, before any failure: a first-token watchdog is armed
|
|
79
79
|
* (`firstTokenTimeoutMs > 0`) and nothing has arrived yet. Emitted once the wait has lasted
|
|
80
80
|
* `WAITING_FIRST_TOKEN_AFTER_MS` and re-emitted every `WAITING_FIRST_TOKEN_EVERY_MS` while it goes
|
|
81
81
|
* on, carrying {@link BrainStatus.elapsedMs} and {@link BrainStatus.timeoutMs}; never carries a
|
|
@@ -126,7 +126,7 @@ export interface BrainStatus {
|
|
|
126
126
|
detail?: string;
|
|
127
127
|
/** Seconds until the brain's next retry attempt (from the honored backoff / `Retry-After`), when known. */
|
|
128
128
|
retryInSec?: number;
|
|
129
|
-
/**
|
|
129
|
+
/** Millisecond precision of {@link retryInSec}, for a client that renders a countdown.
|
|
130
130
|
* A wait longer than the re-announce slice is re-emitted with the REMAINING time, so a consumer
|
|
131
131
|
* that simply overwrites its row always shows a live number instead of a stale one. */
|
|
132
132
|
retryInMs?: number;
|
|
@@ -149,17 +149,17 @@ export interface BrainStatus {
|
|
|
149
149
|
* the authoritative RELATIVE quantity, and this seat is the absolute convenience derived from it.
|
|
150
150
|
*/
|
|
151
151
|
retryAtMs?: number;
|
|
152
|
-
/**
|
|
152
|
+
/** On a `waiting_first_token` frame: how long the first token has been awaited, ms, at the
|
|
153
153
|
* moment the frame is emitted (the emitting process's clock; approximate across a hop). Absent on
|
|
154
154
|
* every other phase. */
|
|
155
155
|
elapsedMs?: number;
|
|
156
|
-
/**
|
|
156
|
+
/** On a `waiting_first_token` frame: the armed first-token watchdog, ms — the wait's ceiling,
|
|
157
157
|
* so a consumer can render "45s of 120s". Absent on every other phase. */
|
|
158
158
|
timeoutMs?: number;
|
|
159
|
-
/**
|
|
159
|
+
/** 1-based index of the attempt that just failed (the wait precedes attempt `attempt + 1`);
|
|
160
160
|
* same numbering as the `brain.retry` telemetry frame. Absent on frames that are not a retry wait. */
|
|
161
161
|
attempt?: number;
|
|
162
|
-
/**
|
|
162
|
+
/** The retry budget of THIS lane, so a consumer can render "attempt 3 of 10". Lane, not
|
|
163
163
|
* engine: a failure class served by a shorter ladder reports that ladder's budget, so the fraction a
|
|
164
164
|
* consumer renders is the one actually in force rather than the engine-wide ceiling. */
|
|
165
165
|
maxRetries?: number;
|
|
@@ -259,7 +259,7 @@ export type TaskEvent = ({
|
|
|
259
259
|
delta: string;
|
|
260
260
|
} & TaskEventIdentity) | ({
|
|
261
261
|
/**
|
|
262
|
-
*
|
|
262
|
+
* The assistant's streaming PROSE SEGMENT is COMPLETE: the model closed the text content
|
|
263
263
|
* block whose bytes just streamed as `text_delta`s. This is the explicit segment boundary a
|
|
264
264
|
* REMOTE consumer needs so it never has to guess segment ends from wire silence (the idle-flush
|
|
265
265
|
* heuristic this retires cut one slow-model reply into N fragments). CC-aligned: CC's agent
|
|
@@ -449,7 +449,7 @@ export type TaskEvent = ({
|
|
|
449
449
|
*/
|
|
450
450
|
truncated?: boolean;
|
|
451
451
|
/**
|
|
452
|
-
*
|
|
452
|
+
* Present iff {@link truncated}: the TRUE original size (characters) of
|
|
453
453
|
* the content this event's {@link output} was degraded from — for a string result, the string's own
|
|
454
454
|
* length; for a non-string result (a blocks array), the SUM of each block's own true size (a text
|
|
455
455
|
* block's `.text.length`; an image/document block's `.data.length`, i.e. its base64 payload) — never
|
|
@@ -469,7 +469,7 @@ export type TaskEvent = ({
|
|
|
469
469
|
totalChars?: number;
|
|
470
470
|
} & TaskEventIdentity) | ({
|
|
471
471
|
/**
|
|
472
|
-
*
|
|
472
|
+
* Context occupancy at a compaction boundary, emitted on EVERY
|
|
473
473
|
* boundary (not only when a compaction fires). The three numbers are the engine's own trigger
|
|
474
474
|
* inputs, verbatim: `usedTokens > compactAtTokens` IS the predicate `shouldCompact` evaluates, so a
|
|
475
475
|
* consumer's "context is N% full" indicator and the moment compaction actually fires can never
|
|
@@ -490,15 +490,17 @@ export type TaskEvent = ({
|
|
|
490
490
|
/**
|
|
491
491
|
* Per-turn token usage + cost (the turn that just ended), for live per-turn accounting / a trace UI
|
|
492
492
|
* (service [41]). Re-priced in core from injected pricing (authoritative, like `TaskResult.stats`).
|
|
493
|
-
*
|
|
493
|
+
* ALWAYS present: a turn that produced no provider usage frame carries the counted ZEROS beside
|
|
494
|
+
* `usageMissing: true` — zero is unknown, not free, the one law `TaskResult.stats` states (numbers
|
|
495
|
+
* always present, the flag says they under-count), so a consumer handles ONE frame shape.
|
|
494
496
|
*
|
|
495
|
-
*
|
|
497
|
+
* `inputTokens` is the cache-MISS count (Anthropic-protocol shape, matches
|
|
496
498
|
* `stats.promptTokens` / the tracer's `brain.call.promptTokens`); `totalInputTokens` is the
|
|
497
499
|
* cache-INCLUSIVE total (`inputTokens + cacheReadTokens + cacheWriteTokens`) that cost is computed
|
|
498
500
|
* from. Sum `totalInputTokens` for context/window/spend views; read `inputTokens` only where the
|
|
499
501
|
* protocol's `input_tokens` is meant. Up to 2.13.x `inputTokens` carried the total.
|
|
500
502
|
*/
|
|
501
|
-
usage
|
|
503
|
+
usage: {
|
|
502
504
|
/** Cache-MISS input tokens for this turn (the Anthropic protocol's `input_tokens` meaning;
|
|
503
505
|
* matches `stats.promptTokens` / `brain.call.promptTokens`). **Up to 2.13.x this field
|
|
504
506
|
* carried the cache-INCLUSIVE total** (RB-457-a, BREAKING at 3.0.0) — that value now lives
|
|
@@ -514,9 +516,10 @@ export type TaskEvent = ({
|
|
|
514
516
|
costMicroUsd: number;
|
|
515
517
|
};
|
|
516
518
|
/** TB 尸检 T1-5: set when the turn ended WITHOUT a provider usage frame (e.g. a degenerate-repetition
|
|
517
|
-
* cutoff cancelled the stream before usage arrived)
|
|
518
|
-
* UNKNOWN — not
|
|
519
|
-
* than polluting the single-source accounting
|
|
519
|
+
* cutoff cancelled the stream before usage arrived) or the brain flagged its frame unknown. Consumers
|
|
520
|
+
* must treat `usage` as UNKNOWN — its zeros are not a measured 0 (the provider still served the
|
|
521
|
+
* request; `stats` under-counts it honestly rather than polluting the single-source accounting
|
|
522
|
+
* with an estimate). Absent on a measured turn (never `false`). */
|
|
520
523
|
usageMissing?: true;
|
|
521
524
|
/** TB telemetry B1: the NORMALIZED finish reason of the turn's LAST model call —
|
|
522
525
|
* the engine's `AssistantMessage.stopReason` (`StopReason`: `"stop"`/`"length"`/`"toolUse"`/
|
|
@@ -789,7 +792,7 @@ export type TaskEvent = ({
|
|
|
789
792
|
*/
|
|
790
793
|
taskType?: DelegationTaskType;
|
|
791
794
|
/**
|
|
792
|
-
*
|
|
795
|
+
* The registry row's STOP-CYCLE generation this tick reports from (fresh
|
|
793
796
|
* spawn = 1, every launched revival bumps it), the same counter `TaskNotificationPayload.seq`
|
|
794
797
|
* and `BackgroundChildEvent.seq` already speak — one axis, not a third spelling. It answers
|
|
795
798
|
* the one question a fleet consumer cannot otherwise decide when a frame arrives late: "late
|
|
@@ -92,7 +92,7 @@ export interface TaskLimits {
|
|
|
92
92
|
atCostFraction: number;
|
|
93
93
|
};
|
|
94
94
|
/**
|
|
95
|
-
*
|
|
95
|
+
* The OUTER wall on how long the engine waits for a single brain
|
|
96
96
|
* call, in ms. Default {@link import("../brain/timeout.js").BRAIN_CALL_GUARDRAIL_DEFAULT_MS}
|
|
97
97
|
* (one hour); `false` or `0` switches it off; any other non-positive / non-finite value is a
|
|
98
98
|
* config error (fail-loud, never folded to a default). Overrides `RunnerDeps.brainCallGuardrailMs`.
|
|
@@ -279,7 +279,7 @@ export interface SystemInjection<TPayload = unknown> {
|
|
|
279
279
|
* repeat, or refusing the repeat typed, would each turn a dedup fold into a delivery mutation. */
|
|
280
280
|
export declare function taskNotificationDedupKey(n: Pick<TaskNotificationPayload, "task_id" | "task_type" | "status" | "seq">): string;
|
|
281
281
|
/**
|
|
282
|
-
*
|
|
282
|
+
* The lane-scoped identity of a task, extracted from {@link taskNotificationDedupKey} so every
|
|
283
283
|
* place that treats "same task" as one bucket applies the SAME lane rule.
|
|
284
284
|
*
|
|
285
285
|
* The dedup key had the lane segment from the start; three other sites did not — the pending store's
|
|
@@ -397,7 +397,7 @@ export interface DrainedPendingNotifications {
|
|
|
397
397
|
priorities?: Map<TaskNotificationPayload, SystemInjectionPriority>;
|
|
398
398
|
/** task_id → notifications evicted by the bounds while pending (never delivered). `taskType` remembers
|
|
399
399
|
* the victim's lane so a survivors-none disclosure can still render an honest synthetic payload. */
|
|
400
|
-
/**
|
|
400
|
+
/** Keyed by {@link taskNotificationLaneKey}, NOT the bare `task_id` — the external lane's ids are
|
|
401
401
|
* caller-supplied, so one bare-id row could cover two lanes and name only one of their types. `taskId`
|
|
402
402
|
* carries the victim's real id back out (the lane key is process-internal and must never be rendered). */
|
|
403
403
|
dropped: Map<string, {
|
|
@@ -406,7 +406,7 @@ export interface DrainedPendingNotifications {
|
|
|
406
406
|
taskId: string;
|
|
407
407
|
}>;
|
|
408
408
|
/**
|
|
409
|
-
*
|
|
409
|
+
* Notifications lost when this whole SESSION was evicted by the
|
|
410
410
|
* session-count cap, kept OUT of `dropped`. RB-91 folded them in under a `"(evicted-session)"` string
|
|
411
411
|
* key, which put a session-level fact into a per-task ledger and broke twice for it: the key could
|
|
412
412
|
* collide with a real, free-form external `task_id` (merging two unrelated counts and mislabelling the
|
|
@@ -421,7 +421,7 @@ export declare class PendingSessionNotifications {
|
|
|
421
421
|
/** Whole sessions evicted by {@link MAX_PENDING_SESSIONS} (their pendings were never delivered). */
|
|
422
422
|
droppedSessions: number;
|
|
423
423
|
/**
|
|
424
|
-
*
|
|
424
|
+
* A TOMBSTONE per whole-session eviction, so that session's next drain
|
|
425
425
|
* can still say what it lost. The two item-level caps disclose their drops per task (they mutate a
|
|
426
426
|
* surviving session's `dropped` map), but the session-count cap deleted the whole record and only
|
|
427
427
|
* bumped a global, unattributed counter — from the evicted session's point of view its next drain
|
|
@@ -430,7 +430,7 @@ export declare class PendingSessionNotifications {
|
|
|
430
430
|
* Bounded like the sessions map itself (a tombstone is two numbers and a lane tag).
|
|
431
431
|
*/
|
|
432
432
|
private readonly evictedSessions;
|
|
433
|
-
/**
|
|
433
|
+
/** Whole-session losses whose tombstone was itself evicted — the count survives, the attribution
|
|
434
434
|
* does not. Surfaced on the next session-level disclosure so it is never simply forgotten. */
|
|
435
435
|
private unattributedDrops;
|
|
436
436
|
pend(sessionId: string, n: TaskNotificationPayload, priority?: SystemInjectionPriority): void;
|
|
@@ -173,7 +173,7 @@ export declare function parkBackgroundAgentLane(core: DurableAgentCore, id: stri
|
|
|
173
173
|
* `excludeWriterId` = this instance's writerId, so foreign (dead-process) rows are cleaned
|
|
174
174
|
* without ever touching a row this process is live-managing.
|
|
175
175
|
*
|
|
176
|
-
*
|
|
176
|
+
* The live half used to skip EVERY non-expired/missing state, `resolved` included, and
|
|
177
177
|
* that was the whole zombie: a parked row whose checkpoint was decided by the task-level
|
|
178
178
|
* `resumeCheckpoint` leg (a serving layer's documented fallback when its parked-row discriminator
|
|
179
179
|
* misses) is decided but still says `parked`, its side effects already executed by a path that never
|
|
@@ -321,7 +321,7 @@ export declare function resolveBackgroundAgentByNameLane(core: DurableAgentCore,
|
|
|
321
321
|
* a capacity/pin failure (or plain session-scope) could never drain. No-op on unknown ids. */
|
|
322
322
|
export declare function markRetainedContinuationLane(core: DurableAgentCore, id: string): void;
|
|
323
323
|
/**
|
|
324
|
-
*
|
|
324
|
+
* The stop-cycle generation of the RUN BEING SPAWNED under this row (the same counter the
|
|
325
325
|
* register/revive lanes keep on the handle: fresh spawn = 1, durable-seeded revive = the claimed
|
|
326
326
|
* row's seq, in-memory wake = the bump). The spawn lanes read it ONCE, right after registering, to
|
|
327
327
|
* thread into the child's `RunInternals.cycleSeq` — one authoritative source instead of each lane
|
|
@@ -444,7 +444,7 @@ export declare function deliverToRunningAgentLane(core: DurableAgentCore, id: st
|
|
|
444
444
|
* very rows a retry needs. The task faces' split lives in `runningAgentFooterLane` (RB-332). */
|
|
445
445
|
export declare function runningBackgroundAgentLabelsLane(core: DurableAgentCore, access: TaskAccess): string[];
|
|
446
446
|
/**
|
|
447
|
-
*
|
|
447
|
+
* The not-found FOOTER's two rows, split the way CC 220 assembles them:
|
|
448
448
|
* - `named` = CC `uG_` (220:467941-467953): the agentNameRegistry's KEYS whose task is a running local
|
|
449
449
|
* agent, listed as BARE NAMES — the string a retry should pass verbatim. sema's counterpart
|
|
450
450
|
* of "has a registry entry" is the handle carrying an explicit `name` (spawn-time label),
|
|
@@ -461,7 +461,7 @@ export declare function runningAgentFooterLane(core: DurableAgentCore, access: T
|
|
|
461
461
|
named: string[];
|
|
462
462
|
background: string[];
|
|
463
463
|
};
|
|
464
|
-
/**
|
|
464
|
+
/** The not-found TAIL both task faces share (CC `rxo`, appended by `uMs` for TaskStop
|
|
465
465
|
* and by `xwd` 220:472095-472097 for TaskOutput). Empty string when the caller has nothing running. */
|
|
466
466
|
export declare function notFoundRunningAgentsTail(footer: {
|
|
467
467
|
named: string[];
|
|
@@ -543,7 +543,7 @@ export declare function serveDurableAgentRowLane(row: BackgroundAgentRecord): Un
|
|
|
543
543
|
*/
|
|
544
544
|
export declare function spillClippedAgentResult(handle: BackgroundAgentTaskHandle, full: string, clipped: string, store: ToolResultStore | undefined, sessionId: string | undefined): Promise<string>;
|
|
545
545
|
export declare function pollBackgroundAgentLane(handle: BackgroundAgentTaskHandle, deadline?: number, signal?: AbortSignal,
|
|
546
|
-
/**
|
|
546
|
+
/** Mirrors {@link import("./types.js").TaskSpec.oneShot} (see
|
|
547
547
|
* {@link import("./task-registry.js").TaskToolOptions.oneShot} for the full contract): this run has
|
|
548
548
|
* no later turn for an async background notification to land in, so the still-running body must
|
|
549
549
|
* not teach "you will be notified when it completes". */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { TaskNotificationPayload } from "./task-notification.js";
|
|
2
2
|
import { type RegistryCore, type RegisterMonitorInput, type MonitorTaskHandle, type UnifiedTaskResult } from "./task-registry-shared.js";
|
|
3
3
|
export declare function registerMonitorLane(core: RegistryCore, input: RegisterMonitorInput): string;
|
|
4
|
-
/**
|
|
4
|
+
/** ONE absorption arithmetic for a monitor poll — env-side-loss accounting
|
|
5
5
|
* (RB-238), the spool roll (registry memory bound) and the completed-line split — shared by the
|
|
6
6
|
* watcher tick and the stop-time final drain. A hand-copied twin in stopMonitor is how half-fixes
|
|
7
7
|
* happen: any change to the roll/line rules must reach both consumers through this method. Returns
|
|
@@ -12,7 +12,7 @@ export declare function absorbMonitorPollLane(handle: MonitorTaskHandle, v: {
|
|
|
12
12
|
truncated?: boolean;
|
|
13
13
|
bytesDroppedBeforeCursor?: number;
|
|
14
14
|
}): string[];
|
|
15
|
-
/**
|
|
15
|
+
/** The swallow-guarded event sink, shared by the watcher's emits and the stop-time drain. */
|
|
16
16
|
export declare function emitMonitorEventLane(handle: MonitorTaskHandle, n: TaskNotificationPayload): void;
|
|
17
17
|
/** The monitor watcher tick loop. Same zombie-proofing discipline as {@link startBashWatcher}
|
|
18
18
|
* (re-entrancy guard / stop on eviction / stop on vanished shell / stop on a throwing adapter),
|
|
@@ -22,7 +22,7 @@ export type SemaTaskStatus = "pending" | "running" | "parked" | "completed" | "f
|
|
|
22
22
|
export type TaskRetrievalStatus = "success" | "not_ready" | "timeout";
|
|
23
23
|
export interface UnifiedTaskOutput {
|
|
24
24
|
task_id: string;
|
|
25
|
-
/**
|
|
25
|
+
/** `"unknown"` is a DECLARED member here, not a stray literal. A
|
|
26
26
|
* not-found lookup has no task kind to report, and the TaskStop envelope's `task_type` is required by
|
|
27
27
|
* the client schema — so the wrapper was already emitting `"unknown"` while the type said it could
|
|
28
28
|
* only be a `SemaTaskType`. Declaring it keeps the two honest with each other, and keeps `SemaTaskType`
|
|
@@ -146,7 +146,7 @@ export interface BackgroundBashTaskHandle extends SemaTaskHandle {
|
|
|
146
146
|
* `mirrorFailed` records that at least one append to the advertised output FILE failed — the terminal
|
|
147
147
|
* frame then discloses the file as incomplete instead of letting the launch receipt's "full output is
|
|
148
148
|
* appended there" promise stand over a silently partial file. */
|
|
149
|
-
/**
|
|
149
|
+
/** `droppedBytes`/`dropUnknown` account ENV-SIDE tail-buffer eviction disclosed by
|
|
150
150
|
* the poll (`bytesDroppedBeforeCursor`/`truncated`) — a loss upstream of (and distinct from) the
|
|
151
151
|
* registry's own `rolledChars` memory bound. Bytes counted here never reached the spool at all. */
|
|
152
152
|
spool?: {
|
|
@@ -182,7 +182,7 @@ export interface WorkflowTaskHandle extends SemaTaskHandle {
|
|
|
182
182
|
store?: WorkflowRunStore;
|
|
183
183
|
/** B-1 (live leg) — see {@link RegisterWorkflowInput.originatingSessionId}. */
|
|
184
184
|
originatingSessionId?: string;
|
|
185
|
-
/**
|
|
185
|
+
/** Design/129 session-lifetime discipline, extended to workflow — the
|
|
186
186
|
* ONE background kind that never had it (`background_bash`/`monitor`/`background_agent` all do).
|
|
187
187
|
* Unlike those three (task-scoped BY DEFAULT, `sessionScoped` an explicit opt-in via
|
|
188
188
|
* `TaskSpec.backgroundScope`), a workflow is unconditionally session-anchored — `originatingSessionId`
|
|
@@ -198,7 +198,7 @@ export interface WorkflowTaskHandle extends SemaTaskHandle {
|
|
|
198
198
|
sessionScoped?: true;
|
|
199
199
|
/** See {@link RegisterWorkflowInput.onServedTerminal}. Cleared after the single fire. */
|
|
200
200
|
onServedTerminal?: () => void;
|
|
201
|
-
/**
|
|
201
|
+
/** The bounded return value, captured on the done-hook so the STORE-LESS in-memory lane's
|
|
202
202
|
* terminal poll can hand it over too (the launch note promises it; without a store there was no result). */
|
|
203
203
|
result?: string;
|
|
204
204
|
/** T2A-8: the failure reason (bounded + redacted), captured on the done-hook's rejection so a store-less
|
|
@@ -232,7 +232,7 @@ export interface BackgroundAgentTaskHandle extends SemaTaskHandle {
|
|
|
232
232
|
type: "background_agent";
|
|
233
233
|
/** design/115 P3: aborting this cancels the child run (TaskStop / parent teardown). */
|
|
234
234
|
abort: AbortController;
|
|
235
|
-
/**
|
|
235
|
+
/** Lineage axes, declared (registration always spread them into the handle; readers used
|
|
236
236
|
* to cast). `rootSessionId` feeds {@link canAccess}'s root-session arm; the other two stay
|
|
237
237
|
* read-only lineage metadata on the live face (no parentSessionId access arm — see the arm's
|
|
238
238
|
* comment for why). The register side clamps `parentTaskId`. */
|
|
@@ -313,7 +313,7 @@ export interface BackgroundAgentTaskHandle extends SemaTaskHandle {
|
|
|
313
313
|
/** Terminal snapshot (bounded, {@link BG_AGENT_RESULT_MAX} in subagent.ts) — served by TaskOutput
|
|
314
314
|
* once the child finishes. */
|
|
315
315
|
result?: string;
|
|
316
|
-
/**
|
|
316
|
+
/** The FULL result (bounded only by the defensive {@link BG_AGENT_RESULT_FULL_MAX} ceiling
|
|
317
317
|
* in subagent.ts), set ONLY when it differs from `result` — same shape as {@link WorkflowRun.resultFull}
|
|
318
318
|
* (workflow.ts NH-1). Before this field existed, the settle call sites pre-sliced `child.result` to
|
|
319
319
|
* ~2-4K chars with no disclosure — clipTaskOutput's own file-pointer/offload-friendly design at the
|
|
@@ -350,7 +350,7 @@ export interface BackgroundAgentTaskHandle extends SemaTaskHandle {
|
|
|
350
350
|
* overloaded/timeout/network ⇒ true, logic ⇒ false). Stored rather than re-derived so the core
|
|
351
351
|
* poll lane never has to import the agents-domain classifier (no new domain cycle). */
|
|
352
352
|
errorRetryable?: boolean;
|
|
353
|
-
/**
|
|
353
|
+
/** The coarse classification KIND beside `errorRetryable`
|
|
354
354
|
* (classifySubagentError's error_kind ∈ rate_limit/overloaded/timeout/network/logic), threaded
|
|
355
355
|
* from the same settle mint point and stored for the same no-domain-cycle reason as its sibling.
|
|
356
356
|
* Rendered on the FAILED row's poll TEXT face as the `(error_kind: …, retryable: …)` clause —
|
|
@@ -421,7 +421,7 @@ export interface MonitorTaskHandle extends SemaTaskHandle {
|
|
|
421
421
|
lineBuf: string;
|
|
422
422
|
/** Per-batch monotonic counter → unique notification dedup keys (see task-notification.ts). */
|
|
423
423
|
seq: number;
|
|
424
|
-
/**
|
|
424
|
+
/** The TWO-LEVEL event-storm control's state.
|
|
425
425
|
* Level 1 = a token bucket (`stormTokens` out of `stormBurst`, refilled one per
|
|
426
426
|
* `stormRefillIntervalMs`): a batch that cannot consume a token is SUPPRESSED (its lines stay in the
|
|
427
427
|
* re-readable spool) and counted in `suppressedBatches`; the next batch that DOES consume one first
|
|
@@ -452,7 +452,7 @@ export interface MonitorTaskHandle extends SemaTaskHandle {
|
|
|
452
452
|
deadlineAt?: number;
|
|
453
453
|
timeoutMs?: number;
|
|
454
454
|
watcher?: unknown;
|
|
455
|
-
/**
|
|
455
|
+
/** A watcher tick is suspended on its pollBackground await RIGHT NOW. The stop-time
|
|
456
456
|
* final drain must skip its own poll then (that in-flight tick already consumed the env cursor — and a
|
|
457
457
|
* never-resolving adapter must not pin TaskStop). Set/cleared in lockstep with the tick's re-entrancy
|
|
458
458
|
* guard. */
|
|
@@ -486,7 +486,7 @@ export interface MonitorTaskHandle extends SemaTaskHandle {
|
|
|
486
486
|
/** design/158 S2 — cumulative chars (UTF-16 code units, `string.length`) handed to `store.put`
|
|
487
487
|
* across every segment this handle has spilled so far (both streams combined) — the per-handle
|
|
488
488
|
* disk-cap accounting ({@link import("./task-registry-monitor.js")} reads `MONITOR_SPILL_CAP_CHARS`
|
|
489
|
-
* against this).
|
|
489
|
+
* against this). The field used to be named `spillBytesUsed` while the ledger counted
|
|
490
490
|
* chars — renamed to the axis it really measures (see the constant's own doc for why chars). */
|
|
491
491
|
spillCharsUsed?: number;
|
|
492
492
|
/** design/158 S2 — the per-handle spill cap (`MONITOR_SPILL_CAP_CHARS`) was reached; further
|
|
@@ -518,10 +518,10 @@ export interface RegisterMonitorInput extends TaskAccess {
|
|
|
518
518
|
timers?: MonitorTimers;
|
|
519
519
|
/** Batch window (ms, default 200): lines arriving within one tick coalesce into one notification. */
|
|
520
520
|
batchWindowMs?: number;
|
|
521
|
-
/**
|
|
521
|
+
/** The SUSTAINED batch rate the storm bucket refills at (default 50/min). Exceeding it is
|
|
522
522
|
* suppression, not death — see `stormBurst` and MONITOR_STORM_KILL_AFTER_MS. */
|
|
523
523
|
maxBatchesPerMinute?: number;
|
|
524
|
-
/**
|
|
524
|
+
/** Burst capacity of the storm bucket (default MONITOR_STORM_BURST = CC's 10). */
|
|
525
525
|
stormBurst?: number;
|
|
526
526
|
now?: number;
|
|
527
527
|
/** design/158 S2 (RB-364 半) — the offload store a rolled-off spool middle spills to (see
|
|
@@ -563,23 +563,23 @@ export declare const MONITOR_BATCH_WINDOW_MS = 200;
|
|
|
563
563
|
export declare const MONITOR_DEFAULT_TIMEOUT_MS = 300000;
|
|
564
564
|
export declare const MONITOR_MAX_TIMEOUT_MS = 3600000;
|
|
565
565
|
export declare const MONITOR_MAX_BATCHES_PER_MINUTE = 50;
|
|
566
|
-
/**
|
|
566
|
+
/** Burst capacity of the storm token bucket — how many batches may fire
|
|
567
567
|
* back-to-back before the SUPPRESSION level engages. CC value, adopted verbatim. */
|
|
568
568
|
export declare const MONITOR_STORM_BURST = 10;
|
|
569
|
-
/**
|
|
569
|
+
/** How long a monitor must stay CONTINUOUSLY over budget before the
|
|
570
570
|
* second level (kill) fires. CC value, adopted verbatim. */
|
|
571
571
|
export declare const MONITOR_STORM_KILL_AFTER_MS = 30000;
|
|
572
|
-
/**
|
|
572
|
+
/** The partial-line accumulator bound. sema's `lineBuf` had NO bound —
|
|
573
573
|
* a monitored process emitting megabytes without a single newline grew it without limit (the spool's
|
|
574
574
|
* own roll never covered it). Keep the TAIL (the newest bytes are the ones a watch is about). */
|
|
575
575
|
export declare const MONITOR_LINE_BUF_CAP = 1048576;
|
|
576
|
-
/**
|
|
576
|
+
/** The monitor event-result clip, shared by the watcher's batch/terminal emits and
|
|
577
577
|
* the stop-time drain emit (one clip, one truncation wording). */
|
|
578
578
|
export declare function clipMonitorEvent(s: string): string;
|
|
579
|
-
/**
|
|
579
|
+
/** Per-line clip applied to the `lines[]` a batch carries. Spool untouched. */
|
|
580
580
|
export declare function clipMonitorLine(s: string): string;
|
|
581
581
|
/**
|
|
582
|
-
*
|
|
582
|
+
* The ONE terminal-notification summary
|
|
583
583
|
* HEAD for a background command / monitor watch. Every terminal frame in the bash and monitor lanes
|
|
584
584
|
* composes its summary as `terminalTaskSummary(...)` plus this lane's own honest detail clause — the
|
|
585
585
|
* pre-RB-335 code had six hand-written phrasings whose comment claimed "no CC sample for those faces"
|
|
@@ -619,14 +619,14 @@ export declare function rollSpoolText(spool: {
|
|
|
619
619
|
* matching the pre-S2 loss shape for whatever is dropped PAST the cap. Exported so the boundary is a
|
|
620
620
|
* testable contract, not a buried literal.
|
|
621
621
|
*
|
|
622
|
-
*
|
|
622
|
+
* The constant used to be named
|
|
623
623
|
* `..._BYTES` while the ledger added `dropped.length` — chars, up to ~3× fewer than UTF-8 bytes on
|
|
624
624
|
* multibyte content. CHARS is the axis kept (name changed, arithmetic untouched) because it is the
|
|
625
625
|
* offload store family's own coordinate (`InMemoryToolResultStore.maxTotalChars` evicts by
|
|
626
626
|
* `content.length`; `ToolResultSlice.totalChars`) and the spool's `rolledChars` axis — one unit
|
|
627
627
|
* end-to-end; a `Buffer.byteLength` ledger here would sit crosswise to the store's own cap. */
|
|
628
628
|
export declare const MONITOR_SPILL_CAP_CHARS: number;
|
|
629
|
-
/**
|
|
629
|
+
/** Fold one poll's env-side-loss disclosure into the spool's account. The env's
|
|
630
630
|
* tail buffer evicts its HEAD under pressure (node-execution-env 8MB bound) — those bytes are gone
|
|
631
631
|
* before any watcher ever saw them, which is a different loss than the registry-side `rolledChars`
|
|
632
632
|
* middle-drop. `bytesDroppedBeforeCursor` only counts bytes dropped before an unconsumed cursor, so
|
|
@@ -645,7 +645,7 @@ export declare function accountDroppedBytes(spool: {
|
|
|
645
645
|
truncated?: boolean;
|
|
646
646
|
bytesDroppedBeforeCursor?: number;
|
|
647
647
|
}): void;
|
|
648
|
-
/**
|
|
648
|
+
/** The POLL-FACE wording for env-side loss (the terminal/event-frame wording is
|
|
649
649
|
* {@link droppedGapNote}'s; the two faces differ by design and always have). One function so the two
|
|
650
650
|
* quantified/unquantified branches cannot drift between the three legs that render it: the monitor
|
|
651
651
|
* re-readable spool, the bash re-readable spool, and the bash blocked wait. Trailing newline included
|
|
@@ -686,7 +686,7 @@ export interface SpoolBodyOptions {
|
|
|
686
686
|
/** A full banner line (own trailing newline) rendered after the drop note, or "". */
|
|
687
687
|
drainNote: string;
|
|
688
688
|
}
|
|
689
|
-
/**
|
|
689
|
+
/** The ONE renderer for a re-readable spool's TaskOutput body,
|
|
690
690
|
* shared by the monitor lane (pollMonitorLane) and the bash spool lane (pollBackgroundBash).
|
|
691
691
|
*
|
|
692
692
|
* Both faces were hand-copied twins carrying three real disclosure bugs' worth of wording (env-side
|
|
@@ -700,19 +700,19 @@ export interface SpoolBodyOptions {
|
|
|
700
700
|
* wording ("accumulated char(s) dropped from the middle during the blocked wait"), an intentional
|
|
701
701
|
* divergence — it shares {@link accountDroppedBytes} + {@link spoolDropNote}, not this. */
|
|
702
702
|
export declare function renderSpoolBody(spool: RenderableSpool, opts: SpoolBodyOptions): string;
|
|
703
|
-
/**
|
|
703
|
+
/** The honesty suffix for frames over a spool with env-side loss. Empty when nothing dropped. */
|
|
704
704
|
export declare function droppedGapNote(spool: {
|
|
705
705
|
droppedBytes?: number;
|
|
706
706
|
dropUnknown?: true;
|
|
707
707
|
}): string;
|
|
708
|
-
/**
|
|
708
|
+
/** The event-stream disclosure rides the FIRST batch after a loss is observed (once-latch —
|
|
709
709
|
* a chatty watch must not repeat the note on every batch; terminal frames disclose unconditionally). */
|
|
710
710
|
export declare function firstDropNote(spool: {
|
|
711
711
|
droppedBytes?: number;
|
|
712
712
|
dropUnknown?: true;
|
|
713
713
|
dropNotified?: true;
|
|
714
714
|
}): string;
|
|
715
|
-
/**
|
|
715
|
+
/** ONE wording for "you stopped nothing" across every already-terminal stop face —
|
|
716
716
|
* the in-process bash/monitor/agent arms and the durable-row fallback previously split: the durable
|
|
717
717
|
* arm answered honestly while the in-process arms claimed `Terminated <id>.` over work that finished
|
|
718
718
|
* (or was killed) on its own. CC 220 refuses the call outright (`Task X is not running (status: …)`,
|
|
@@ -781,7 +781,7 @@ export declare function editDistance(a: string, b: string): number;
|
|
|
781
781
|
/** CC `htr` shape (206:519814-519827): candidates within Levenshtein ≤2 (length-diff ≤2 pre-filter),
|
|
782
782
|
* best-first; the single best is the "Did you mean" suggestion (`htr(e, keys, 1)[0]`, 206:575196). */
|
|
783
783
|
export declare function closestName(query: string, candidates: Iterable<string>): string | undefined;
|
|
784
|
-
/**
|
|
784
|
+
/** DEFAULT-DENY on BOTH axes — the old predicate skipped
|
|
785
785
|
* a missing axis (owner-less handle = readable by everyone in scope; scope-less handle = readable
|
|
786
786
|
* across scopes), splitting polarity with `canAccessAgentRecord` and re-opening the session-axis
|
|
787
787
|
* class cli/server just swept. Registration now REQUIRES both axes ({@link assertOwnership}), so a
|
|
@@ -822,7 +822,7 @@ export interface ParkedClaimTicket {
|
|
|
822
822
|
reservedRev: number;
|
|
823
823
|
row: import("./background-agent-store.js").BackgroundAgentRecord;
|
|
824
824
|
}
|
|
825
|
-
/**
|
|
825
|
+
/** Sibling of {@link mintCompletionId} for a caller that must compute the
|
|
826
826
|
* value BEFORE it is safe to commit (a CAS not yet known to win): fill-once with an EXTERNALLY-chosen
|
|
827
827
|
* value instead of generating a fresh one. Exists because `rollbackParkedClaim`'s original fix minted
|
|
828
828
|
* directly onto the live handle before its durable CAS was confirmed — a losing CAS then left a
|
|
@@ -2,8 +2,8 @@ import { uuidv7 } from "../internal/harness.js";
|
|
|
2
2
|
import { summarizeWorkflowRun } from "./workflow-run-store.js";
|
|
3
3
|
import { delimitUntrusted } from "./untrusted-text.js";
|
|
4
4
|
import { boundedRedactedSummary } from "./untrusted-egress.js";
|
|
5
|
-
import { clipWithFilePointer } from "./tool-errors.js";
|
|
6
|
-
import {
|
|
5
|
+
import { clipWithFilePointer, OUTPUT_BUDGET_MIN_CHARS } from "./tool-errors.js";
|
|
6
|
+
import { resolveEnvBudget } from "./env-budget.js";
|
|
7
7
|
export function mintCompletionId(target) {
|
|
8
8
|
if (target.completionId === undefined)
|
|
9
9
|
target.completionId = uuidv7();
|
|
@@ -60,18 +60,8 @@ export function terminalTaskSummary(kind, label, status, exitCode) {
|
|
|
60
60
|
}
|
|
61
61
|
const TASK_OUTPUT_DEFAULT_CHARS = 32_000;
|
|
62
62
|
export const TASK_OUTPUT_MAX_CHARS = 160_000;
|
|
63
|
-
const TASK_OUTPUT_MIN_CHARS = 512;
|
|
64
63
|
function taskMaxOutputChars() {
|
|
65
|
-
|
|
66
|
-
if (rawEnv === undefined || rawEnv.trim() === "")
|
|
67
|
-
return TASK_OUTPUT_DEFAULT_CHARS;
|
|
68
|
-
const raw = rawEnv.trim();
|
|
69
|
-
const n = /^\d+$/.test(raw) ? parseInt(raw, 10) : Number.NaN;
|
|
70
|
-
if (!Number.isFinite(n) || n <= 0) {
|
|
71
|
-
announceEnvKnob(`TASK_MAX_OUTPUT_LENGTH=${rawEnv} was ignored — it is not a positive whole number of characters. Using ${TASK_OUTPUT_DEFAULT_CHARS} instead.`);
|
|
72
|
-
return TASK_OUTPUT_DEFAULT_CHARS;
|
|
73
|
-
}
|
|
74
|
-
return Math.min(Math.max(n, TASK_OUTPUT_MIN_CHARS), TASK_OUTPUT_MAX_CHARS);
|
|
64
|
+
return resolveEnvBudget(process.env.TASK_MAX_OUTPUT_LENGTH, { name: "TASK_MAX_OUTPUT_LENGTH", unit: "characters", default: TASK_OUTPUT_DEFAULT_CHARS, min: OUTPUT_BUDGET_MIN_CHARS, max: TASK_OUTPUT_MAX_CHARS });
|
|
75
65
|
}
|
|
76
66
|
export function clipTaskOutput(s, fullOutputPath) {
|
|
77
67
|
return clipWithFilePointer(s, taskMaxOutputChars(), fullOutputPath);
|