@sema-agent/core 5.20.0 → 5.21.1
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 +19 -0
- package/dist/agents/agent-definition.d.ts +7 -0
- package/dist/agents/agent-transcript-tool.d.ts +30 -0
- package/dist/agents/builtin-agents.d.ts +60 -0
- package/dist/agents/cascade.d.ts +107 -0
- package/dist/agents/cumulative-stats.d.ts +56 -0
- package/dist/agents/observer.d.ts +162 -0
- package/dist/agents/peer-admission.d.ts +95 -0
- package/dist/agents/repair-loop.d.ts +226 -0
- package/dist/agents/retain-ledger.d.ts +141 -0
- package/dist/agents/roster-store.d.ts +105 -0
- package/dist/agents/send-message-tool.d.ts +92 -0
- package/dist/agents/session-util.d.ts +5 -0
- package/dist/agents/subagent-steps.d.ts +66 -0
- package/dist/agents/subagent.d.ts +600 -0
- package/dist/agents/suspend-guard.d.ts +29 -0
- package/dist/agents/teacher.d.ts +75 -0
- package/dist/agents/team.d.ts +120 -1
- package/dist/agents/tool-filter.d.ts +34 -0
- package/dist/agents/verify.d.ts +198 -0
- package/dist/bench/metrics.d.ts +455 -0
- package/dist/brain/anthropic.d.ts +30 -0
- package/dist/brain/circuit-breaker.d.ts +33 -0
- package/dist/brain/context-overflow.d.ts +60 -3
- package/dist/brain/degrading.d.ts +67 -0
- package/dist/brain/errors.d.ts +42 -0
- package/dist/brain/failover.d.ts +15 -0
- package/dist/brain/media-degrade.d.ts +39 -0
- package/dist/brain/model-presets.d.ts +31 -0
- package/dist/brain/open-responses.d.ts +19 -0
- package/dist/brain/openai.d.ts +46 -0
- package/dist/brain/reasoning.d.ts +106 -1
- package/dist/brain/repetition.d.ts +83 -0
- package/dist/brain/request-params.d.ts +56 -0
- package/dist/brain/retry.d.ts +46 -0
- package/dist/brain/routing.d.ts +12 -0
- package/dist/brain/status-sink.d.ts +30 -1
- package/dist/brain/stream-engine.d.ts +147 -0
- package/dist/brain/stream-shared.d.ts +34 -0
- package/dist/brain/terminal-cause.d.ts +31 -0
- package/dist/brain/timeout.d.ts +107 -0
- package/dist/brain/tool-call-id.d.ts +20 -0
- package/dist/brain/tool-call-repair.d.ts +13 -0
- package/dist/config/catalog.d.ts +47 -0
- package/dist/config/defaults.d.ts +33 -0
- package/dist/core/a2a-task-state.d.ts +53 -0
- package/dist/core/a2a.d.ts +51 -0
- package/dist/core/arg-summary.d.ts +62 -0
- package/dist/core/ask-question.d.ts +272 -2
- package/dist/core/auto-compaction.d.ts +467 -0
- package/dist/core/auto-compaction.js +20 -6
- package/dist/core/auto-mode-prompt-assets.d.ts +8 -0
- package/dist/core/auto-mode-prompt.d.ts +27 -0
- package/dist/core/auto-mode.d.ts +54 -3
- package/dist/core/auto-promote.d.ts +100 -0
- package/dist/core/background-agent-store.d.ts +292 -0
- package/dist/core/background-shell.d.ts +110 -0
- package/dist/core/cache-break-detector.d.ts +34 -0
- package/dist/core/canonical-json.d.ts +57 -0
- package/dist/core/checkpoint-store.d.ts +1574 -16
- package/dist/core/compliance.d.ts +30 -0
- package/dist/core/consolidate-scope.d.ts +75 -0
- package/dist/core/context-edit.d.ts +99 -0
- package/dist/core/context-guard.d.ts +46 -0
- package/dist/core/exec-gate.d.ts +44 -0
- package/dist/core/exec-output-tail.d.ts +61 -0
- package/dist/core/file-snapshot-store.d.ts +104 -0
- package/dist/core/fs-write-gate-policy.d.ts +36 -0
- package/dist/core/git-worktree-env.d.ts +31 -0
- package/dist/core/governance-codes.d.ts +19 -0
- package/dist/core/hooks.d.ts +608 -1
- package/dist/core/human-input-projection.d.ts +37 -0
- package/dist/core/human-input-projection.js +13 -0
- package/dist/core/image-downsample.d.ts +74 -0
- package/dist/core/locked-config.d.ts +37 -0
- package/dist/core/lsp-diagnostics.d.ts +77 -0
- package/dist/core/lsp-protocol.d.ts +29 -0
- package/dist/core/lsp-session.d.ts +60 -1
- package/dist/core/lsp.d.ts +150 -1
- package/dist/core/mailbox-store.d.ts +57 -0
- package/dist/core/mcp.d.ts +381 -0
- package/dist/core/media-byte-cap.d.ts +21 -0
- package/dist/core/memory-admission.d.ts +71 -0
- package/dist/core/memory-engine/content-origin.d.ts +64 -0
- package/dist/core/memory-engine/data-plane.d.ts +43 -0
- package/dist/core/memory-engine/dual-root.d.ts +24 -0
- package/dist/core/memory-engine/engine.d.ts +230 -0
- package/dist/core/memory-engine/engine.js +103 -35
- package/dist/core/memory-engine/file-backend.d.ts +155 -0
- package/dist/core/memory-engine/frontmatter.d.ts +16 -0
- package/dist/core/memory-engine/layout.d.ts +217 -0
- package/dist/core/memory-engine/memory-backend-contract.d.ts +12 -0
- package/dist/core/memory-engine/migrate.d.ts +9 -0
- package/dist/core/memory-engine/scan.d.ts +12 -0
- package/dist/core/memory-engine/scope-contract.d.ts +61 -1
- package/dist/core/memory-engine/sync-client.d.ts +87 -0
- package/dist/core/memory-engine/sync.d.ts +60 -0
- package/dist/core/memory-engine/tools.d.ts +41 -0
- package/dist/core/memory-engine/types.d.ts +188 -0
- package/dist/core/memory-recall.d.ts +141 -0
- package/dist/core/memory-vector.d.ts +20 -0
- package/dist/core/memory.d.ts +458 -0
- package/dist/core/message-utils.d.ts +6 -0
- package/dist/core/oracle-isolation.d.ts +69 -0
- package/dist/core/permission-rule-consent.d.ts +138 -0
- package/dist/core/permission-rule-model.d.ts +122 -0
- package/dist/core/permission-rule-store.d.ts +119 -3
- package/dist/core/permission-rules.d.ts +87 -1
- package/dist/core/present-plan-tool.d.ts +20 -0
- package/dist/core/pricing.d.ts +26 -0
- package/dist/core/property-harness.d.ts +86 -0
- package/dist/core/protocol-naming.d.ts +38 -0
- package/dist/core/protocol-table.d.ts +61 -0
- package/dist/core/push-queue.d.ts +1 -0
- package/dist/core/remote-env.d.ts +383 -1
- package/dist/core/retention-policy.d.ts +33 -0
- package/dist/core/retention.d.ts +51 -0
- package/dist/core/roles.d.ts +59 -0
- package/dist/core/runner/active-skill-scope.d.ts +34 -0
- package/dist/core/runner/assemble-result.d.ts +134 -0
- package/dist/core/runner/compaction-call-options.d.ts +97 -1
- package/dist/core/runner/grounding-signal.d.ts +10 -0
- package/dist/core/runner/image.d.ts +17 -0
- package/dist/core/runner/image.js +29 -15
- package/dist/core/runner/memory-consolidation.d.ts +60 -0
- package/dist/core/runner/prepare-memory.d.ts +59 -0
- package/dist/core/runner/prepare-task.d.ts +1011 -2
- package/dist/core/runner/prepare-task.js +12 -11
- package/dist/core/runner/prompt-suggestions.d.ts +7 -0
- package/dist/core/runner/runtask.d.ts +304 -3
- package/dist/core/runner/session-file-state-replay.d.ts +49 -0
- package/dist/core/runner/session-rule-policy.d.ts +58 -0
- package/dist/core/runner/strict-output-schema.d.ts +18 -3
- package/dist/core/runner/synthetic-tools.d.ts +113 -0
- package/dist/core/runner/teardown-bounded.d.ts +34 -0
- package/dist/core/runner/tool-disclosure.d.ts +227 -0
- package/dist/core/runner/tool-output-projection.d.ts +6 -0
- package/dist/core/runner/turn-attachments.d.ts +634 -0
- package/dist/core/runner/usage-accounting.d.ts +32 -0
- package/dist/core/runtime.d.ts +9 -0
- package/dist/core/safe-notify.d.ts +64 -0
- package/dist/core/safety-axis-vocab.d.ts +23 -0
- package/dist/core/safety-merge-corpus.d.ts +37 -0
- package/dist/core/scheduler.d.ts +121 -0
- package/dist/core/secret-env.d.ts +32 -0
- package/dist/core/select-model.d.ts +15 -0
- package/dist/core/sensitive-path-policy.d.ts +42 -0
- package/dist/core/session-policy-store.d.ts +94 -0
- package/dist/core/session-reconcile.d.ts +80 -0
- package/dist/core/session-store.d.ts +85 -0
- package/dist/core/session.d.ts +153 -0
- package/dist/core/shared-memory/contract.d.ts +22 -0
- package/dist/core/shared-memory/normalize.d.ts +123 -2
- package/dist/core/shared-memory/tools.d.ts +14 -0
- package/dist/core/shared-memory/types.d.ts +105 -0
- package/dist/core/shutdown-debug.d.ts +6 -0
- package/dist/core/side-query.d.ts +38 -0
- package/dist/core/side-query.js +6 -1
- package/dist/core/skill-tool-specifier.d.ts +72 -0
- package/dist/core/skills-directory.d.ts +100 -1
- package/dist/core/spec-contract.d.ts +89 -0
- package/dist/core/store-contracts/background-agent-store-contract.d.ts +31 -0
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +26 -0
- package/dist/core/store-contracts/contract-harness.d.ts +20 -0
- package/dist/core/store-contracts/contract-kit-version.d.ts +27 -0
- package/dist/core/store-contracts/file-snapshot-store-contract.d.ts +8 -0
- package/dist/core/store-contracts/mailbox-store-contract.d.ts +42 -0
- package/dist/core/store-contracts/tool-result-store-contract.d.ts +13 -0
- package/dist/core/strategy-store.d.ts +37 -0
- package/dist/core/stub-env.d.ts +7 -0
- package/dist/core/surrogate-safe-slice.d.ts +35 -0
- package/dist/core/task-notification.d.ts +202 -0
- package/dist/core/task-outcome.d.ts +53 -0
- package/dist/core/task-registry-agent.d.ts +337 -1
- package/dist/core/task-registry-monitor.d.ts +12 -0
- package/dist/core/task-registry-shared.d.ts +540 -0
- package/dist/core/task-registry.d.ts +343 -0
- package/dist/core/task-registry.js +13 -2
- package/dist/core/task-tool-shape.d.ts +44 -0
- package/dist/core/tighten-task-spec.d.ts +21 -0
- package/dist/core/tool-detach.d.ts +21 -0
- package/dist/core/tool-errors.d.ts +131 -0
- package/dist/core/tool-errors.js +4 -0
- package/dist/core/tool-name-aliases.d.ts +27 -0
- package/dist/core/tool-policy.d.ts +555 -0
- package/dist/core/tool-result-budget.d.ts +32 -0
- package/dist/core/tool-result-store.d.ts +174 -1
- package/dist/core/tools.d.ts +45 -0
- package/dist/core/trace.d.ts +323 -0
- package/dist/core/types.d.ts +3859 -2
- package/dist/core/untrusted-egress.d.ts +8 -0
- package/dist/core/untrusted-text.d.ts +156 -0
- package/dist/core/usage-window-store.d.ts +95 -0
- package/dist/core/version.d.ts +1 -0
- package/dist/core/warm-resume.d.ts +17 -0
- package/dist/core/wiring-manifest.d.ts +169 -0
- package/dist/core/with-retry.d.ts +24 -0
- package/dist/core/workflow-journal-store.d.ts +160 -0
- package/dist/core/workflow-run-store-contract.d.ts +25 -0
- package/dist/core/workflow-run-store.d.ts +119 -0
- package/dist/engine/compaction/compaction.d.ts +256 -1
- package/dist/engine/compaction/utils.d.ts +94 -0
- package/dist/engine/execution-env/kill-tree.d.ts +29 -0
- package/dist/engine/execution-env/node-execution-env.d.ts +94 -0
- package/dist/engine/harness/agent-harness.d.ts +116 -0
- package/dist/engine/harness/agent-harness.js +3 -14
- package/dist/engine/harness/messages.d.ts +15 -0
- package/dist/engine/harness/types.d.ts +464 -2
- package/dist/engine/llm/diagnostics.d.ts +4 -0
- package/dist/engine/llm/event-stream.d.ts +3 -0
- package/dist/engine/llm/index.d.ts +7 -0
- package/dist/engine/llm/types.d.ts +500 -3
- package/dist/engine/llm/validation.d.ts +3 -0
- package/dist/engine/loop/agent-loop.d.ts +87 -2
- package/dist/engine/loop/runtime-deps.d.ts +7 -0
- package/dist/engine/loop/types.d.ts +424 -0
- package/dist/engine/lsp/frame-decoder.d.ts +13 -0
- package/dist/engine/lsp/node-lsp-manager.d.ts +107 -0
- package/dist/engine/lsp/stdio-lsp-transport.d.ts +7 -0
- package/dist/engine/session/import-validate.d.ts +27 -0
- package/dist/engine/session/log-digest.d.ts +93 -0
- package/dist/engine/session/memory-repo.d.ts +6 -0
- package/dist/engine/session/memory-storage.d.ts +2 -0
- package/dist/engine/session/session.d.ts +75 -0
- package/dist/engine/session/storage-base.d.ts +8 -0
- package/dist/fixtures/index.d.ts +36 -0
- package/dist/index.d.ts +16 -1
- package/dist/index.js +0 -1
- package/dist/internal/harness-types.d.ts +6 -0
- package/dist/internal/harness.d.ts +11 -0
- package/dist/internal/llm.d.ts +6 -0
- package/dist/orchestration/builtin-workflows.d.ts +53 -0
- package/dist/orchestration/dev-vm-script-runner.d.ts +19 -0
- package/dist/orchestration/goal.d.ts +57 -0
- package/dist/orchestration/goal.js +3 -0
- package/dist/orchestration/run-spec.d.ts +42 -0
- package/dist/orchestration/run-workflow-tool.d.ts +169 -0
- package/dist/orchestration/workflow-governance.d.ts +61 -0
- package/dist/orchestration/workflow-meta.d.ts +28 -0
- package/dist/orchestration/workflow-observe.d.ts +60 -0
- package/dist/orchestration/workflow-primitives.d.ts +23 -1
- package/dist/orchestration/workflow-sandbox-conformance.d.ts +38 -0
- package/dist/orchestration/workflow-script-runner.d.ts +88 -0
- package/dist/orchestration/workflow-script-store.d.ts +98 -0
- package/dist/orchestration/workflow-size-guideline.d.ts +67 -0
- package/dist/orchestration/workflow-types.d.ts +169 -2
- package/dist/orchestration/workflow.d.ts +358 -0
- package/dist/prompt-assembly/artifact-store.d.ts +33 -0
- package/dist/prompt-assembly/artifact.d.ts +25 -0
- package/dist/prompt-assembly/assemble.d.ts +20 -0
- package/dist/prompt-assembly/composer.d.ts +29 -0
- package/dist/prompt-assembly/epoch.d.ts +55 -1
- package/dist/prompt-assembly/event-registry.d.ts +35 -0
- package/dist/prompt-assembly/explain.d.ts +12 -0
- package/dist/prompt-assembly/tool-catalog.d.ts +38 -0
- package/dist/prompt-assembly/turn-snapshot.d.ts +40 -0
- package/dist/prompt-assembly/types.d.ts +115 -0
- package/dist/prompts/coordinator.d.ts +27 -0
- package/dist/prompts/default.d.ts +539 -0
- package/dist/prompts/simple-sections.d.ts +45 -0
- package/dist/prompts/supervisor.d.ts +66 -0
- package/dist/scenarios/env.d.ts +28 -0
- package/dist/scenarios/full-body.d.ts +50 -0
- package/dist/scenarios/scenario-registry.d.ts +60 -0
- package/dist/scenarios/teacher-quickstart.d.ts +27 -0
- package/dist/server/http.d.ts +17 -0
- package/dist/stores/cc/lockfile.d.ts +6 -0
- package/dist/stores/cc/mailbox-store.d.ts +8 -0
- package/dist/stores/cc/roster-adapter.d.ts +4 -0
- package/dist/stores/cc/sidecar-transcript.d.ts +66 -0
- package/dist/stores/file/background-agent-store.d.ts +24 -0
- package/dist/stores/file/checkpoint-store.d.ts +38 -0
- package/dist/stores/file/file-snapshot-store.d.ts +25 -0
- package/dist/stores/file/fs-atomic.d.ts +155 -0
- package/dist/stores/file/index.d.ts +89 -0
- package/dist/stores/file/mailbox-store.d.ts +36 -0
- package/dist/stores/file/memory-store.d.ts +82 -0
- package/dist/stores/file/permission-rule-store.d.ts +79 -0
- package/dist/stores/file/session-policy-store.d.ts +28 -0
- package/dist/stores/file/session-store.d.ts +40 -0
- package/dist/stores/file/shared-ledger.d.ts +83 -0
- package/dist/stores/file/tool-result-store.d.ts +11 -0
- package/dist/stores/file/usage-window-store.d.ts +18 -0
- package/dist/stores/file/workflow-journal-store.d.ts +100 -0
- package/dist/stores/file/workflow-run-store.d.ts +11 -0
- package/dist/tools/fs/bash-readonly-classifier.d.ts +282 -0
- package/dist/tools/fs/encoding.d.ts +60 -0
- package/dist/tools/fs/fs-bash.d.ts +133 -0
- package/dist/tools/fs/fs-pdf.d.ts +28 -0
- package/dist/tools/fs/fs-search-tools.d.ts +5 -0
- package/dist/tools/fs/fs-search-tools.js +0 -1
- package/dist/tools/fs/fs-shared.d.ts +360 -0
- package/dist/tools/fs/fs-write.d.ts +16 -0
- package/dist/tools/fs/gh-rate-limit.d.ts +22 -0
- package/dist/tools/fs/index.d.ts +79 -0
- package/dist/tools/fs/notebook.d.ts +56 -0
- package/dist/tools/fs/pdf.d.ts +70 -0
- package/dist/tools/fs/pdf.js +8 -2
- package/dist/tools/fs/repo-map.d.ts +10 -0
- package/dist/tools/fs/safety.d.ts +376 -0
- package/dist/tools/fs/search.d.ts +131 -0
- package/dist/tools/loop-tick.d.ts +24 -0
- package/dist/tools/monitor.d.ts +55 -0
- package/dist/tools/scheduler-tools.d.ts +51 -0
- package/dist/tools/sql-adapters.d.ts +18 -0
- package/dist/tools/sql.d.ts +25 -0
- package/dist/tools/task-list.d.ts +77 -0
- package/dist/tools/todo.d.ts +8 -0
- package/dist/tools/web.d.ts +184 -0
- package/dist/tools/worktree.d.ts +81 -0
- package/package.json +2 -2
- package/dist/tools/gitea-issue.d.ts +0 -13
- package/dist/tools/gitea-issue.js +0 -75
|
@@ -1,8 +1,42 @@
|
|
|
1
1
|
import { type RepetitionEvent } from "./repetition.js";
|
|
2
|
+
/**
|
|
3
|
+
* design/157 A10 — stream-parser pieces that the anthropic and openai SSE lanes carried BYTE-IDENTICALLY
|
|
4
|
+
* (verified by diff at 1469481: a 16-line repetition-telemetry closure). Provider-agnostic policy, so it
|
|
5
|
+
* lives here once and each lane keeps a pointer comment.
|
|
6
|
+
*
|
|
7
|
+
* REF-B1 extends that: the fail-closed ARGUMENT PARSE inside each lane's `closeToolCall*` (identical down to
|
|
8
|
+
* its comment) is hoisted here as {@link parseStreamedToolArgs}. Only the parse — each lane keeps its own
|
|
9
|
+
* accumulator fields, its `closedTc` cache and its own id prefix, which are real wire-format differences.
|
|
10
|
+
*
|
|
11
|
+
* Deliberately NOT hoisted: each lane's own degenerate-cut bookkeeping (`degenTextBlock` / `degenFace` are
|
|
12
|
+
* lane-specific content shapes).
|
|
13
|
+
*
|
|
14
|
+
* Internal module: not re-exported from `src/index.ts`.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* REF-B1 — turn a streamed tool call's accumulated argument bytes into its arguments object, FAIL-CLOSED.
|
|
18
|
+
*
|
|
19
|
+
* - no bytes (`""`) → `{}`: genuinely a no-argument call (the provider's frame carried no arguments);
|
|
20
|
+
* - valid JSON **object** → that object;
|
|
21
|
+
* - anything else (truncated/invalid JSON, or a top-level string/array/number/null) → `undefined`.
|
|
22
|
+
*
|
|
23
|
+
* bug-hunt #6 (kept from finalize): a non-object must never reach `tool.execute` / the MCP wire. `undefined`
|
|
24
|
+
* means "do not emit a `toolcall_end` for this call"; callers must NOT cache that outcome — finalize retries
|
|
25
|
+
* the parse against the complete accumulation.
|
|
26
|
+
*/
|
|
2
27
|
export declare function parseStreamedToolArgs(json: string): Record<string, unknown> | undefined;
|
|
28
|
+
/** Repetition telemetry for ONE stream — the cut event plus the allowance-spared hits. */
|
|
3
29
|
export interface RepetitionPoll {
|
|
30
|
+
/** Inspect the accumulated text; returns whether it is degenerate (the caller trips its own cut). */
|
|
4
31
|
poll(text: string): boolean;
|
|
32
|
+
/** The cut event, once a poll tripped. */
|
|
5
33
|
readonly cut: RepetitionEvent | undefined;
|
|
34
|
+
/** Allowance-spared hits, deduped by rule+segment with the loop's PEAK depth kept. */
|
|
6
35
|
readonly spared: RepetitionEvent[];
|
|
7
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Repetition telemetry (clay 2026-07-10): the cut event + allowance-spared hits for THIS stream.
|
|
39
|
+
* Polls re-inspect the same growing text every ~64 chars — dedupe spared by rule+segment so one
|
|
40
|
+
* boot block doesn't log once per poll. Attached to the final message as `repetition`.
|
|
41
|
+
*/
|
|
8
42
|
export declare function createRepetitionPoll(): RepetitionPoll;
|
|
@@ -1,3 +1,34 @@
|
|
|
1
1
|
import type { AssistantMessage } from "../internal/llm.js";
|
|
2
|
+
/**
|
|
3
|
+
* RB-464 — the DELIBERATE brain-side cut, read as a TYPED cause instead of by comparing the
|
|
4
|
+
* turn's human-readable `errorMessage` against an exported sentinel string.
|
|
5
|
+
*
|
|
6
|
+
* Why this file exists at all. The cut is a cross-LAYER signal: a brain stamps it, the loop's
|
|
7
|
+
* recovery lane reacts, and the assembler maps it to a terminal code. Before
|
|
8
|
+
* RB-464 the only carrier was the sentinel prose, compared by identity at six sites in two files.
|
|
9
|
+
* Identity-comparing an exported constant is much safer than matching a prose fragment — the value
|
|
10
|
+
* can be reworded freely and every site follows — but it still makes the CAUSE a string: a brain
|
|
11
|
+
* that stamps the same sentence without importing the constant (a custom `Brain`, a message rebuilt
|
|
12
|
+
* from a field whitelist, a re-encode through a host that normalizes whitespace) is invisible to all
|
|
13
|
+
* six sites at once, silently, with every test still green because the tests import the constant too.
|
|
14
|
+
* `errorKind` carries the cause as data instead; these predicates are the single place that knows how
|
|
15
|
+
* to read it.
|
|
16
|
+
*
|
|
17
|
+
* RB-482 #12 (ruled 2026-08-03, the RB-464 retirement condition met at this window): the transitional
|
|
18
|
+
* `errorMessage`-sentinel fallback is DELETED — `errorKind` is the ONE read. The two shapes the
|
|
19
|
+
* fallback served are closed the documented way: pre-RB-464 stored turns are the sacrificed-replay
|
|
20
|
+
* class (RB-476-A precedent), and stamping `errorKind` on every cut turn is now a documented Brain
|
|
21
|
+
* obligation (see the field's contract note on AssistantMessage). A custom brain that stamps only the
|
|
22
|
+
* sentinel prose is no longer recognized — declared in the 5.1.0 CHANGELOG.
|
|
23
|
+
*/
|
|
24
|
+
/** The subset of an assistant turn that carries a terminal cause. Accepts a full {@link AssistantMessage}. */
|
|
2
25
|
export type TerminalCauseCarrier = Pick<AssistantMessage, "errorKind">;
|
|
26
|
+
/**
|
|
27
|
+
* True when this turn is the brain's DEGENERATE-REPETITION cutoff (design/39): the model looped on the
|
|
28
|
+
* same text and the brain cancelled the stream, keeping the salvageable prefix.
|
|
29
|
+
*
|
|
30
|
+
* Deliberately does NOT also require `stopReason === "error"`. Callers that need the terminal shape
|
|
31
|
+
* check it themselves (the assembler does); the recovery lanes are handed an already-errored turn.
|
|
32
|
+
* Folding the check in here would silently change those call sites' meaning.
|
|
33
|
+
*/
|
|
3
34
|
export declare function isDegenerateCutMessage(message: TerminalCauseCarrier): boolean;
|
package/dist/brain/timeout.d.ts
CHANGED
|
@@ -1,31 +1,138 @@
|
|
|
1
1
|
import type { StreamFn } from "../internal/llm.js";
|
|
2
|
+
/**
|
|
3
|
+
* Tiered timeouts (1.38.1, design/17 §5B). The task-level `timeoutSec` only bounds the *whole* run;
|
|
4
|
+
* it can't tell apart a gateway that never accepts the connection from one that accepts it, opens the
|
|
5
|
+
* SSE stream, then hangs forever without emitting a token (the most common gateway-stall symptom).
|
|
6
|
+
* Two finer levels close that gap, each retryable as a transient `network` failure:
|
|
7
|
+
*
|
|
8
|
+
* - **connect**: `fetch` hasn't returned response headers in time.
|
|
9
|
+
* - **first-token**: the SSE stream is open but no content delta has arrived (see brain read loops).
|
|
10
|
+
*
|
|
11
|
+
* Both default to `undefined` (disabled) so existing behavior is unchanged.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The largest delay a host timer can actually wait for. Past this `setTimeout` does not schedule far in
|
|
15
|
+
* the future — it truncates the delay to 1ms and fires at once, which for a watchdog means the OPPOSITE
|
|
16
|
+
* of what a deployment widening the bound asked for: every call aborted immediately, while the failure
|
|
17
|
+
* text quotes the number that was requested. Any ms knob that reaches a timer is refused above it
|
|
18
|
+
* (knob-hygiene #98); a watchdog that is meant to be off has its own `0` / `false` spelling.
|
|
19
|
+
*/
|
|
2
20
|
export declare const MAX_TIMER_DELAY_MS = 2147483647;
|
|
21
|
+
/**
|
|
22
|
+
* Resolve one stall-timeout knob to its effective value, refusing invalid numbers loudly. `x && x > 0`
|
|
23
|
+
* downstream reads NaN as "unset" — a deployment that SET a tighter watchdog and fumbled the units
|
|
24
|
+
* ("120s" → Number → NaN) used to get every watchdog silently OFF, the dangerous direction (ruled
|
|
25
|
+
* 2026-08-03, cross-repo robustness batch; same posture as the guardrail knob). `0` stays legal —
|
|
26
|
+
* an explicit off. Absent stays absent. Above {@link MAX_TIMER_DELAY_MS} is refused for the mirror-image
|
|
27
|
+
* reason: the host timer would turn "watch for 34 days" into "abort on arrival".
|
|
28
|
+
*/
|
|
3
29
|
export declare function resolveStallTimeoutMs(value: number | undefined, knob: string): number | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* The engine's ADVISORY per-call stall watchdog values (`StreamOptions.stallTimeouts`), supplied on
|
|
32
|
+
* every provider call. They are a GUARDRAIL, not part of any budget lane: TB2.0 run89's production
|
|
33
|
+
* frame had an in-flight model call sit 680s with ZERO deltas, and `BrainTimeoutConfig` defaults
|
|
34
|
+
* every watchdog to OFF, so nothing finer than the hour-scale {@link BRAIN_CALL_GUARDRAIL_DEFAULT_MS}
|
|
35
|
+
* bounded it. A silent stream is never worth more than these bounds, whether or not the task declared
|
|
36
|
+
* a time limit. All three surface as the brain's existing retryable `network` stall class (design/124
|
|
37
|
+
* tier C retries a zero-content cut, so a transient gateway hang still recovers). 量纲:
|
|
38
|
+
* - connect 30s: bounds the fetch→response-HEADERS wait — the one segment every post-headers
|
|
39
|
+
* watchdog is blind to. On a streaming API the model's time is spent AFTER headers, so 30s with
|
|
40
|
+
* none at all is a hung gateway, not a slow model.
|
|
41
|
+
* - first-token 120s: bounds the headers→first-delta wait, NOT the model's thought (the first
|
|
42
|
+
* THINKING delta already counts as the first token, design/17 O5 — see
|
|
43
|
+
* {@link BrainTimeoutConfig.firstTokenTimeoutMs}), so a slow reasoner is safe; 2 minutes with
|
|
44
|
+
* literally NOTHING is a hung gateway.
|
|
45
|
+
* - idle 90s: mid-stream silence after output started — a healthy stream emits steadily
|
|
46
|
+
* (comfortably above any provider keep-alive cadence).
|
|
47
|
+
* ADVISORY: a brain whose construction-time {@link BrainTimeoutConfig} sets the corresponding field
|
|
48
|
+
* keeps it (deployment sovereignty; see the `StreamOptions.stallTimeouts` priority chain).
|
|
49
|
+
*/
|
|
4
50
|
export declare const STALL_CONNECT_MS = 30000;
|
|
5
51
|
export declare const STALL_FIRST_TOKEN_MS = 120000;
|
|
6
52
|
export declare const STALL_IDLE_MS = 90000;
|
|
7
53
|
export interface BrainTimeoutConfig {
|
|
54
|
+
/** Abort the request if `fetch` doesn't return response headers within this many ms. Retryable. */
|
|
8
55
|
connectTimeoutMs?: number;
|
|
56
|
+
/**
|
|
57
|
+
* After the stream opens, cancel it if no content delta (text / thinking / tool input) arrives
|
|
58
|
+
* within this many ms → `BrainError("network", "first-token timeout")`. For reasoning models the
|
|
59
|
+
* **first thinking delta also counts** as the first token, so a long-thinking model isn't killed
|
|
60
|
+
* for being slow to its first *visible* word (design/17 O5).
|
|
61
|
+
*/
|
|
9
62
|
firstTokenTimeoutMs?: number;
|
|
63
|
+
/**
|
|
64
|
+
* **Idle / mid-stream stall watchdog** (1.40.1, design/24 — gap found in the Claude Code source study).
|
|
65
|
+
* After the first delta, re-armed on every delta; if the stream then goes silent for this many ms
|
|
66
|
+
* (a gateway that hung mid-output) → `reader.cancel()` + `BrainError("network", "stream idle timeout")`.
|
|
67
|
+
* Complements `firstTokenTimeoutMs`: that one tolerates a long *first* token (reasoning), this one
|
|
68
|
+
* catches a stall *after* output has started, where a healthy stream emits steadily. Default off.
|
|
69
|
+
*/
|
|
10
70
|
idleTimeoutMs?: number;
|
|
11
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* A per-fetch-attempt abort controller that fires on a connect timeout while still forwarding an
|
|
74
|
+
* outer (task) abort. The returned `signal` governs the **whole** request including the streamed body
|
|
75
|
+
* — so once headers arrive, call `clearTimer()` (NOT `dispose()`) to stop the connect timer while
|
|
76
|
+
* keeping the outer-abort link alive for the body read; call `dispose()` only when the request is
|
|
77
|
+
* fully done or being discarded.
|
|
78
|
+
*/
|
|
12
79
|
export declare function createConnectController(connectTimeoutMs: number | undefined, outerSignal: AbortSignal | undefined): {
|
|
13
80
|
signal: AbortSignal;
|
|
14
81
|
timedOut: () => boolean;
|
|
15
82
|
clearTimer: () => void;
|
|
83
|
+
/** Abort this attempt's signal. The signal handed to `doFetch` is how an injected fetch wrapper
|
|
84
|
+
* learns it may release its transport, so an attempt being ABANDONED (its error body cut short by
|
|
85
|
+
* a bound, its response discarded before a retry) must say so rather than just dropping the
|
|
86
|
+
* reference. Idempotent; a no-op once the response is fully consumed. */
|
|
16
87
|
abort: () => void;
|
|
17
88
|
dispose: () => void;
|
|
18
89
|
};
|
|
90
|
+
/**
|
|
91
|
+
* Default ceiling on how long the ENGINE waits for a single brain call (ruled 2026-08-03: one hour).
|
|
92
|
+
* Deliberately far above any legitimate call: this is a wedged-run backstop, not a latency policy —
|
|
93
|
+
* a deployment that wants a tight per-call bound sets the fine tier above ({@link BrainTimeoutConfig},
|
|
94
|
+
* or the advisory {@link STALL_CONNECT_MS} family the engine supplies by default). All of these clocks
|
|
95
|
+
* run in parallel with the task's own `limits.timeoutSec`; whichever expires first owns the run.
|
|
96
|
+
*/
|
|
19
97
|
export declare const BRAIN_CALL_GUARDRAIL_DEFAULT_MS = 3600000;
|
|
98
|
+
/** Terminal `TaskResult.errorCode` for a run the guardrail stopped waiting on. */
|
|
20
99
|
export declare const BRAIN_CALL_GUARDRAIL_ERROR_CODE = "brain.call_guardrail_timeout";
|
|
100
|
+
/** Thrown at every await point of a brain call the guardrail has given up on. */
|
|
21
101
|
export declare class BrainCallGuardrailTimeoutError extends Error {
|
|
102
|
+
/** Read by the runner's terminal-code chain (`errorCodeOf`) — never matched on the message text. */
|
|
22
103
|
readonly code = "brain.call_guardrail_timeout";
|
|
23
104
|
readonly limitMs: number;
|
|
24
105
|
constructor(limitMs: number);
|
|
25
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* The guardrail knob's value space: a positive number of milliseconds, or `false`/`0` to switch the
|
|
109
|
+
* guardrail OFF entirely (a deployment that owns its own outer bound). Absent ⇒
|
|
110
|
+
* {@link BRAIN_CALL_GUARDRAIL_DEFAULT_MS}.
|
|
111
|
+
*/
|
|
26
112
|
export type BrainCallGuardrailKnob = number | false;
|
|
113
|
+
/**
|
|
114
|
+
* Resolve the knob to the effective limit, or `undefined` when the guardrail is off.
|
|
115
|
+
*
|
|
116
|
+
* FAIL-LOUD on a value that is neither: a negative / NaN / Infinity setting is a configuration bug,
|
|
117
|
+
* and silently folding it to a default (or to "off") is how an operator ends up believing a wedged
|
|
118
|
+
* run is bounded when nothing bounds it.
|
|
119
|
+
*/
|
|
27
120
|
export declare function resolveBrainCallGuardrailMs(knob: BrainCallGuardrailKnob | undefined): number | undefined;
|
|
121
|
+
/** Records the FIRST guardrail expiry of a run, so the runner can give the task a typed terminal. */
|
|
28
122
|
export interface BrainCallGuardrailRef {
|
|
123
|
+
/** Set once, by the first call the guardrail gave up on. Absent ⇒ the guardrail never fired. */
|
|
29
124
|
timedOut?: BrainCallGuardrailTimeoutError;
|
|
30
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Wrap a {@link StreamFn} so the ENGINE never waits longer than `limitMs` for one brain call.
|
|
128
|
+
*
|
|
129
|
+
* Every await point of the call is bounded: the `stream()` promise itself (a brain that never
|
|
130
|
+
* returns a stream), each iterator step (a brain that trickles events forever), and `result()` (a
|
|
131
|
+
* brain that opens a stream and never terminates it). The guardrail's clock starts when the call is
|
|
132
|
+
* issued and stops when the call ends — it bounds ONE call, not the turn and not the task.
|
|
133
|
+
*
|
|
134
|
+
* `return()` on the wrapped iterator forwards the inner cleanup WITHOUT awaiting it: the whole point
|
|
135
|
+
* is that the engine stops waiting on a brain, so releasing the iterator must not re-introduce a wait
|
|
136
|
+
* on the same hung code.
|
|
137
|
+
*/
|
|
31
138
|
export declare function withBrainCallGuardrail(streamFn: StreamFn, limitMs: number, ref: BrainCallGuardrailRef): StreamFn;
|
|
@@ -1 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REF-C5 — the ONE place a **fallback tool-call id** is minted.
|
|
3
|
+
*
|
|
4
|
+
* When a provider's wire frame carries no `id` for a tool call, the adapter must still hand downstream a
|
|
5
|
+
* non-`undefined`, process-unique handle: the whole execution/pairing chain keys on it (a tool_use must pair
|
|
6
|
+
* with its tool_result, and an in-stream executor's result must pair with the final content). Three adapters
|
|
7
|
+
* used to hand-roll the same `Math.random().toString(36)` short id with only their protocol prefix differing.
|
|
8
|
+
*
|
|
9
|
+
* The prefix is the caller's protocol identity (`toolu_` / `call_` / `repair_<name>_`) and is the ONLY
|
|
10
|
+
* parameter — the id BODY is deliberately opaque and uniform: no length/charset options, so there is exactly
|
|
11
|
+
* one collision profile to reason about for every lane.
|
|
12
|
+
*
|
|
13
|
+
* Zero-dependency leaf on purpose: `tool-call-repair.ts` is a pure parser with no runtime imports, so this
|
|
14
|
+
* must not drag a stream/telemetry dependency in. Internal module: not re-exported from `src/index.ts`.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Mint a placeholder tool-call id under `prefix`. Uniqueness is per-process and probabilistic
|
|
18
|
+
* (`Math.random`), which is what every call site already relied on — the id never crosses a trust boundary
|
|
19
|
+
* and is never a capability; it only has to not collide inside one response.
|
|
20
|
+
*/
|
|
1
21
|
export declare function mintFallbackToolCallId(prefix: string): string;
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import type { ToolCall } from "../internal/llm.js";
|
|
2
|
+
/**
|
|
3
|
+
* Best-effort recovery of tool calls that a weaker (non-native-function-calling) model emitted as
|
|
4
|
+
* TEXT instead of structured tool calls. Recognizes `<tool_call>{...}</tool_call>` /
|
|
5
|
+
* `<function_call>...` tags and fenced ```json blocks containing `{name|tool, arguments|parameters|input}`
|
|
6
|
+
* (or an array of them). Only names present in `toolNames` are promoted.
|
|
7
|
+
*
|
|
8
|
+
* Returns the promoted tool calls and the text with those blocks removed. Off by default — enable via
|
|
9
|
+
* `createOpenAIBrain({ repairTextToolCalls: true })` only for models that need it.
|
|
10
|
+
*
|
|
11
|
+
* A fenced block must carry an arguments face to be promoted at all (HRD-BRN-3) and a block is only removed
|
|
12
|
+
* from the text when everything in it was promoted (HRD-BRN-3) — so this never fabricates a call out of a
|
|
13
|
+
* JSON object that merely names a tool, and never deletes text it did not turn into a call.
|
|
14
|
+
*/
|
|
2
15
|
export declare function repairTextToolCalls(text: string, toolNames: Set<string>): {
|
|
3
16
|
toolCalls: ToolCall[];
|
|
4
17
|
cleanedText: string;
|
package/dist/config/catalog.d.ts
CHANGED
|
@@ -1,29 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config catalog (clay ruling 2026-07-19) — the SINGLE machine-readable source for the engineering
|
|
3
|
+
* configuration scale across every client (server / cli / TB harness / future shells).
|
|
4
|
+
*
|
|
5
|
+
* Why this exists: the same knob was found carrying FIVE different values across layers (maxTurns:
|
|
6
|
+
* core default 1000, TB cloud harness 80, a box-side adapter 500, cloud_companion 200, a server env
|
|
7
|
+
* cap) with no layer aware of the others. The catalog is the anti-chaos contract:
|
|
8
|
+
*
|
|
9
|
+
* 1. **Recommended values are imported from the live constants** — never hand-copied. A drift
|
|
10
|
+
* between catalog and engine is a compile/test failure, not a doc bug.
|
|
11
|
+
* 2. **Clients don't hand-write numbers.** A client either inherits the recommendation (writes
|
|
12
|
+
* nothing) or overrides it and DECLARES the override (`TaskSpec.configOverrides`, with a
|
|
13
|
+
* reason). Declared overrides ride the `config.assembled` trace, so every run self-reports its
|
|
14
|
+
* true knobs and their provenance — "who set 80" becomes a trace read, not archaeology.
|
|
15
|
+
* 3. **Announced change discipline** (clay): the recommendations are a living baseline — any repo
|
|
16
|
+
* changing one (or overriding persistently) posts the change to the shared blackboard so the
|
|
17
|
+
* scale evolves deliberately, together.
|
|
18
|
+
*
|
|
19
|
+
* v1 scope: the cross-client TASK-LAUNCH knobs (the chaos surface). Internal engine tuning
|
|
20
|
+
* (compaction thresholds, retry ladders…) stays out until a real cross-repo consumer appears.
|
|
21
|
+
*/
|
|
1
22
|
import type { TaskLimits } from "../core/types.js";
|
|
2
23
|
export declare const CONFIG_CATALOG_VERSION = "sema-config@1";
|
|
3
24
|
export interface ConfigKnob {
|
|
25
|
+
/** Dotted catalog key, e.g. `limits.maxTurns`. Stable — clients key parity probes off it. */
|
|
4
26
|
key: string;
|
|
27
|
+
/** The recommended value. `null` = deliberately UNSET (the summary says what unset means). */
|
|
5
28
|
recommended: number | boolean | string | null;
|
|
6
29
|
unit?: "turns" | "seconds" | "ms" | "days" | "usd" | "tokens" | "count";
|
|
30
|
+
/** What kind of knob this is: a runaway safety net, a spend bound, a behavior switch, retention. */
|
|
7
31
|
kind: "safety-net" | "budget" | "behavior" | "retention";
|
|
32
|
+
/** One-line semantics, including the meaning of unset and any derived-default coupling. */
|
|
8
33
|
summary: string;
|
|
34
|
+
/** Who may set it and who wins (highest first). */
|
|
9
35
|
precedence: string;
|
|
10
36
|
}
|
|
37
|
+
/** The v1 catalog. Recommended values reference the LIVE constants — the totality pin in
|
|
38
|
+
* `test/config-catalog.test.ts` fails if an entry and its engine source diverge. */
|
|
11
39
|
export declare function describeConfigCatalog(): {
|
|
12
40
|
version: string;
|
|
13
41
|
knobs: ConfigKnob[];
|
|
14
42
|
};
|
|
43
|
+
/**
|
|
44
|
+
* A host-layer override DECLARATION (`TaskSpec.configOverrides`) — the "changes must be announced"
|
|
45
|
+
* mechanical hook. A host that overrides a catalog knob at its own layer (env cap, adapter flag,
|
|
46
|
+
* harness default) attaches the declaration so the override rides the `config.assembled` trace with
|
|
47
|
+
* provenance `host-declared` instead of being invisible. Advisory: declarations are observability
|
|
48
|
+
* metadata — they do not themselves change any effective value.
|
|
49
|
+
*/
|
|
15
50
|
export interface ConfigOverrideDeclaration {
|
|
51
|
+
/** Catalog key (`limits.maxTurns`) — or a host-namespaced key (`tb.harness.maxTurns`) for knobs
|
|
52
|
+
* that live entirely outside core. */
|
|
16
53
|
key: string;
|
|
17
54
|
value: number | boolean | string | null;
|
|
55
|
+
/** Why this deployment deviates from the recommendation — required; this is the announcement. */
|
|
18
56
|
reason: string;
|
|
19
57
|
}
|
|
20
58
|
export type ConfigProvenance = "default" | "spec" | "derived" | "host-declared";
|
|
59
|
+
/** One field of the effective-config manifest (`config.assembled`). */
|
|
21
60
|
export interface EffectiveConfigField {
|
|
22
61
|
key: string;
|
|
23
62
|
value: number | boolean | string | null;
|
|
24
63
|
provenance: ConfigProvenance;
|
|
25
64
|
}
|
|
65
|
+
/** Declaration bounds (codex): host strings ride the trace stream — bounded and sanitized, never
|
|
66
|
+
* free-form. Beyond `MAX_OVERRIDE_DECLARATIONS` entries are dropped (count-capped, first-N kept). */
|
|
26
67
|
export declare const MAX_OVERRIDE_DECLARATIONS = 32;
|
|
68
|
+
/**
|
|
69
|
+
* Build the effective task-launch config + provenance from a spec's launch fields. Pure. The
|
|
70
|
+
* manifest must mirror ENGINE truth, not the spec's surface (codex): `maxOutputTokens` falls back
|
|
71
|
+
* to the model's own cap (provenance `derived`) before "provider default".
|
|
72
|
+
*/
|
|
27
73
|
export declare function resolveEffectiveConfig(spec: {
|
|
28
74
|
limits?: Pick<TaskLimits, "maxTurns" | "maxWalltimeMs" | "maxOutputTokens" | "maxCostUsd" | "maxTokens">;
|
|
29
75
|
resourceSuspend?: {
|
|
@@ -34,4 +80,5 @@ export declare function resolveEffectiveConfig(spec: {
|
|
|
34
80
|
}, ctx?: {
|
|
35
81
|
modelMaxTokens?: number;
|
|
36
82
|
}): EffectiveConfigField[];
|
|
83
|
+
/** Bounded, sanitized reasons map for the manifest's announcement face. */
|
|
37
84
|
export declare function declarationReasons(declarations: readonly ConfigOverrideDeclaration[] | undefined): Record<string, string>;
|
|
@@ -1,4 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dependency-free leaf module for engine default constants that `config/catalog.ts` needs as
|
|
3
|
+
* plain values. Extracted (design/157 S2) so the catalog no longer value-imports the modules that
|
|
4
|
+
* OWN these defaults (`core/runner/runtask.ts`, `agents/subagent.ts`, `core/session-store.ts`) —
|
|
5
|
+
* that import used to drag catalog.ts's runtime closure to 155 modules / 86119 lines (and formed
|
|
6
|
+
* the only size≥2 runtime SCC in the whole repo: catalog.ts ↔ runtask.ts). Each owning module now
|
|
7
|
+
* re-exports its constant(s) from here, so the original import surface (`import { X } from
|
|
8
|
+
* ".../runtask.js"`, etc.) stays byte-identical for every existing consumer.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* design/164 (ruled 2026-08-04): the engine no longer carries a per-task turn / wall-clock default at all.
|
|
12
|
+
* `DEFAULT_MAX_TURNS` (1000), `FORK_DEFAULT_MAX_TURNS` (200) and `SESSION_BG_DEFAULT_TIMEOUT_SEC` (30 min)
|
|
13
|
+
* are RETIRED — every task-level ceiling is now stated by the caller or absent.
|
|
14
|
+
*
|
|
15
|
+
* What replaced each obligation, so nothing is silently dropped:
|
|
16
|
+
* - the runaway backstop is the ENGINEERING GUARDRAIL family (brain-call guardrail, stall watchdogs),
|
|
17
|
+
* which answers "is the system hung" rather than "how much may this task spend";
|
|
18
|
+
* - the design/129 anti-zombie duty for a session-scoped background child moved to the stale-running
|
|
19
|
+
* reaper, which collects by STALL instead of by age (see TaskRegistry.reapStaleSessionBackgroundAgents):
|
|
20
|
+
* a background task legitimately busy for two hours should not be killed at thirty minutes.
|
|
21
|
+
*/
|
|
1
22
|
export declare const RETAIN_DEFAULT_TTL_MS: number;
|
|
2
23
|
export declare const RETAIN_DEFAULT_MAX = 16;
|
|
24
|
+
/** Default idle TTL (days) before a cached session is evicted (config-catalog `session.idleTtlDays`). */
|
|
3
25
|
export declare const SESSION_DEFAULT_TTL_DAYS = 7;
|
|
26
|
+
/**
|
|
27
|
+
* RB-369 / RB-427-c — the shared cadence for RUNNING-state observability driven by a child's tool
|
|
28
|
+
* activity. A beat is one tool-lifecycle event (start or end); the FIRST beat always fires immediately
|
|
29
|
+
* (a short-lived agent must be observable at all), then at most one emission per this many beats.
|
|
30
|
+
*
|
|
31
|
+
* One constant, two consumers, deliberately: the workflow lane's running-record persist (RB-369) and the
|
|
32
|
+
* background-agent lane's intra-turn fleet beat (RB-427-c) are the same trade — a row that only moves at
|
|
33
|
+
* turn boundaries is frozen for as long as a turn lasts, and a row that moves per tool call is write /
|
|
34
|
+
* frame amplification on a tool-heavy child. A second, independently-tuned number for the same trade is
|
|
35
|
+
* how two surfaces describing one agent start disagreeing about how fast it is going.
|
|
36
|
+
*/
|
|
4
37
|
export declare const RUNNING_AGENT_OBSERVE_EVERY_BEATS = 4;
|
|
@@ -1,15 +1,68 @@
|
|
|
1
1
|
import type { BackgroundAgentRecord } from "./background-agent-store.js";
|
|
2
|
+
/**
|
|
3
|
+
* The protocol's task states, as ONE list — the type is derived from it, so a value and its type can
|
|
4
|
+
* never drift apart, and a consumer validating wire input iterates the same source the mapping does.
|
|
5
|
+
*/
|
|
2
6
|
export declare const A2A_TASK_STATES: readonly ["submitted", "working", "input-required", "completed", "canceled", "failed", "rejected", "auth-required", "unknown"];
|
|
7
|
+
/** One A2A task state (see {@link A2A_TASK_STATES}). */
|
|
3
8
|
export type A2ATaskState = (typeof A2A_TASK_STATES)[number];
|
|
9
|
+
/**
|
|
10
|
+
* Durable row → protocol state. TOTAL and pure: every (status, stoppedBy) pair has an answer, and the
|
|
11
|
+
* answer depends on nothing else.
|
|
12
|
+
*
|
|
13
|
+
* The four direct arms:
|
|
14
|
+
* - `running` → `working`;
|
|
15
|
+
* - `completed` → `completed`;
|
|
16
|
+
* - `failed` → `failed`;
|
|
17
|
+
* - `parked` → `input-required`. This engine's `parked` is durably suspended ON AN APPROVAL CHECKPOINT
|
|
18
|
+
* — a NARROWING of the protocol's "waiting for the caller to supply something": the something is an
|
|
19
|
+
* approval decision, and it is redeemed through the durable approval inbox, not by a message reply.
|
|
20
|
+
*
|
|
21
|
+
* `killed` splits on the attribution, because the protocol distinguishes what this engine records in a
|
|
22
|
+
* second field: a stop by `user` or `parent` is a deliberate cancellation (`canceled`), while a
|
|
23
|
+
* `system` stop, an unrecognized source, or NO attribution at all is not — those are terminations the
|
|
24
|
+
* requester never asked for, and `canceled` would assert an intent nobody expressed. `failed` is the
|
|
25
|
+
* honest terminal for them.
|
|
26
|
+
*
|
|
27
|
+
* FOUR PROTOCOL STATES HAVE NO ARM HERE, as a fact of the type rather than an omission:
|
|
28
|
+
* - `submitted`, `rejected`, `auth-required` describe moments BEFORE a durable row exists (registration
|
|
29
|
+
* and start are one step in this engine; rejection and an authorization demand are admission-time
|
|
30
|
+
* outcomes of the serving layer, which has no row to project yet);
|
|
31
|
+
* - `unknown` belongs to the READ-PROJECTION layer one level up — the poll face's `not_local` arm,
|
|
32
|
+
* where a `running` row was written by ANOTHER engine instance and this instance genuinely cannot
|
|
33
|
+
* speak to its outcome. That arm has no record-level answer to give and never calls this function; a
|
|
34
|
+
* caller holding a record, by contrast, always has the state. Keeping the two apart is the boundary
|
|
35
|
+
* this function is drawn on.
|
|
36
|
+
* The switch is exhaustive over `status` with NO default arm, so tsc — not this comment — is what fails
|
|
37
|
+
* when a sixth durable status is added.
|
|
38
|
+
*/
|
|
4
39
|
export declare function toA2ATaskState(record: Pick<BackgroundAgentRecord, "status" | "stoppedBy">): A2ATaskState;
|
|
40
|
+
/** A reversal that keeps everything the protocol state carried. */
|
|
5
41
|
export interface A2ATaskStateReversalFaithful {
|
|
6
42
|
lossy: false;
|
|
7
43
|
status: BackgroundAgentRecord["status"];
|
|
8
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* A reversal that DROPPED something. `note` is required on this arm by construction: the whole purpose
|
|
47
|
+
* of the discriminant is that a consumer which branches on `lossy` cannot reach the lossy case without
|
|
48
|
+
* text describing what it lost.
|
|
49
|
+
*/
|
|
9
50
|
export interface A2ATaskStateReversalLossy {
|
|
10
51
|
lossy: true;
|
|
11
52
|
status: BackgroundAgentRecord["status"];
|
|
12
53
|
note: string;
|
|
13
54
|
}
|
|
55
|
+
/** The result of {@link fromA2ATaskState}: discriminated on `lossy`. */
|
|
14
56
|
export type A2ATaskStateReversal = A2ATaskStateReversalFaithful | A2ATaskStateReversalLossy;
|
|
57
|
+
/**
|
|
58
|
+
* Protocol state → durable row status. Nine onto five, so five arms lose information; each of those
|
|
59
|
+
* says so (`lossy: true`) and names what it dropped, rather than returning a bare status that reads as
|
|
60
|
+
* an exact translation.
|
|
61
|
+
*
|
|
62
|
+
* `lossy: false` holds EXACTLY for the states that survive `toA2ATaskState(fromA2ATaskState(s))`
|
|
63
|
+
* unchanged — that biconditional is pinned as a property test (`test/a2a-task-state.test.ts`), so the
|
|
64
|
+
* flag is tied to an observable fact and not to an author's intent.
|
|
65
|
+
*
|
|
66
|
+
* The exhaustive switch (no default arm) makes a newly-declared protocol state a compile error here.
|
|
67
|
+
*/
|
|
15
68
|
export declare function fromA2ATaskState(state: A2ATaskState): A2ATaskStateReversal;
|
package/dist/core/a2a.d.ts
CHANGED
|
@@ -1,23 +1,46 @@
|
|
|
1
1
|
import type { AgentTool } from "../internal/harness-types.js";
|
|
2
2
|
import type { A2aServerSpec, ToolEffect } from "./types.js";
|
|
3
|
+
/** The hard per-skill description bound (ruled 2026-08-03: ~2KiB). */
|
|
3
4
|
export declare const A2A_SKILL_DESCRIPTION_MAX_CHARS = 2048;
|
|
5
|
+
/**
|
|
6
|
+
* The safety axes carried alongside one materialized A2A tool, for `prepare-task` to fold into the SAME
|
|
7
|
+
* irreversible/egress collections first-party and MCP tools feed.
|
|
8
|
+
*
|
|
9
|
+
* Unlike MCP there is no server-hint leg to merge: the protocol has no per-skill annotation vocabulary,
|
|
10
|
+
* and a remote agent's self-declaration would not be trustworthy if it had one. Every A2A tool therefore
|
|
11
|
+
* starts at the ruled default (`egress:true`, `effect:"write"`) and the CALLER's
|
|
12
|
+
* {@link A2aServerSpec.toolAxes} is the only thing that can lower it (design F: caller = trust root).
|
|
13
|
+
*/
|
|
4
14
|
export interface A2aToolAxis {
|
|
15
|
+
/** Namespaced tool name (`a2a__<peer>__<skill>`). */
|
|
5
16
|
name: string;
|
|
17
|
+
/** `"never"` appears ONLY via an explicit caller override — enforcement ignores it (tighten-only),
|
|
18
|
+
* the ask's risk-axes report face consumes it. */
|
|
6
19
|
irreversibility?: "always" | "never";
|
|
20
|
+
/** `false` appears ONLY via an explicit caller override — same posture: enforcement ignores it,
|
|
21
|
+
* the report face consumes it (an explicit negative is a judgment, not silence). */
|
|
7
22
|
egress?: boolean;
|
|
8
23
|
effect?: ToolEffect;
|
|
9
24
|
}
|
|
25
|
+
/** design/99 §E9 equivalent for A2A — a per-peer projection of THIS materialization. A2A holds no
|
|
26
|
+
* connection (every call is its own HTTPS request), so `ready` means "the card was fetched and its
|
|
27
|
+
* skills were mounted at prepare time", never "the peer is alive right now". */
|
|
10
28
|
export interface A2aPeerStatus {
|
|
11
29
|
name: string;
|
|
12
30
|
status: "ready" | "failed";
|
|
31
|
+
/** The card's self-declared name, neutralized + bounded (it rides consumer-rendered lines). */
|
|
13
32
|
agentName?: string;
|
|
14
33
|
agentDescription?: string;
|
|
34
|
+
/** The negotiated JSON-RPC endpoint this task will call. */
|
|
15
35
|
endpoint?: string;
|
|
16
36
|
toolNames?: string[];
|
|
17
37
|
error?: string;
|
|
18
38
|
}
|
|
39
|
+
/** One per-peer entry of {@link MaterializedA2a.refresh}. */
|
|
19
40
|
export interface A2aRefreshResult {
|
|
20
41
|
peer: string;
|
|
42
|
+
/** The peer's namespaced-name prefix — the consumer's SPLICE DOMAIN for a wholesale swap (the same
|
|
43
|
+
* self-healing prefix domain the MCP refresh receipt hands out). Present on every entry. */
|
|
21
44
|
prefix: string;
|
|
22
45
|
status: "refreshed" | "failed" | "disposed";
|
|
23
46
|
toolCount: number;
|
|
@@ -27,16 +50,44 @@ export interface A2aRefreshResult {
|
|
|
27
50
|
axes?: A2aToolAxis[];
|
|
28
51
|
error?: string;
|
|
29
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Tools materialized from one or more A2A peers.
|
|
55
|
+
*
|
|
56
|
+
* Deliberately NARROWER than {@link import("./mcp.js").MaterializedMcp}: A2A has no server-instructions
|
|
57
|
+
* channel and no intake schema gate, so there is no `serverInstructions`, no `instructionsDelta` and no
|
|
58
|
+
* `droppedTools` face — an absent face is honest, an empty one that can never fill is a face a consumer
|
|
59
|
+
* writes code against for nothing.
|
|
60
|
+
*/
|
|
30
61
|
export interface MaterializedA2a {
|
|
31
62
|
tools: AgentTool[];
|
|
32
63
|
toolAxes: A2aToolAxis[];
|
|
64
|
+
/** One entry per peer that could not be materialized and was SKIPPED (fail-open, design/29): the task
|
|
65
|
+
* runs with the healthy peers' tools. The Runner forwards these to `onError(phase:"a2a")`. */
|
|
33
66
|
warnings: Error[];
|
|
34
67
|
statuses: A2aPeerStatus[];
|
|
68
|
+
/** Re-read one peer's card (or every declared peer) and re-derive its tools. Unlike the MCP refresh
|
|
69
|
+
* this dials nothing new — every A2A call is a fresh request anyway — so a peer that failed at
|
|
70
|
+
* prepare time can genuinely recover here. */
|
|
35
71
|
refresh: (peer?: string) => Promise<A2aRefreshResult[]>;
|
|
72
|
+
/**
|
|
73
|
+
* Task teardown. There is no socket to close (every call is its own request), so what this owns is the
|
|
74
|
+
* LIFETIME statement: after it resolves, a tool that somehow still holds a reference fails loudly
|
|
75
|
+
* instead of talking to a remote agent on behalf of a task that has ended.
|
|
76
|
+
*/
|
|
36
77
|
dispose: () => Promise<void>;
|
|
37
78
|
}
|
|
79
|
+
/** A JSON-RPC error answered BY the peer (the exchange happened; the peer refused or failed). Carries the
|
|
80
|
+
* numeric code for `instanceof`-plus-code discrimination — never message-text matching. */
|
|
38
81
|
export declare class A2aRpcError extends Error {
|
|
39
82
|
readonly code: number;
|
|
40
83
|
constructor(peer: string, method: string, code: number, message: string);
|
|
41
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Materialize every declared A2A peer into tools for one task.
|
|
87
|
+
*
|
|
88
|
+
* Peers are set up IN PARALLEL and merged in SPEC ORDER, so the tool roster (and therefore the system
|
|
89
|
+
* prompt's tool list and the prefix cache) is byte-identical regardless of which card answered first.
|
|
90
|
+
* `allSettled` keeps it fail-open: one unreachable peer is a skipped peer with a warning, never a task
|
|
91
|
+
* that cannot start.
|
|
92
|
+
*/
|
|
42
93
|
export declare function materializeA2aTools(specs: readonly A2aServerSpec[], principal?: string, signal?: AbortSignal): Promise<MaterializedA2a>;
|
|
@@ -1,5 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design/99 — a SHORT, SECRET-SCRUBBED one-line summary of a tool call's arguments, for an OPERATOR-FACING
|
|
3
|
+
* display (the MF-W workflow monitor's `Read(path)` / `Bash(grep …)` activity line; the MF-24 permission-denial
|
|
4
|
+
* ledger's denied-tool input). Shared so both the activity sink and the denial record scrub identically — a
|
|
5
|
+
* single audited boundary. NOT `redactHostLeaks` (that is for untrusted-LLM egress and over-redacts the very
|
|
6
|
+
* path the trusted owner-scoped monitor wants to show). codex-reviewed (3 BLOCKER + 5 MAJOR closed).
|
|
7
|
+
*/
|
|
8
|
+
/** Known credential SHAPES + `secretKey=value` — redacted from the FINAL abbreviated string, the single scrub
|
|
9
|
+
* point before any store/SSE fan-out (codex F-5/F-6/F-8/F-9/F-10). Conservative (real credential formats). */
|
|
10
|
+
/** [1608] every prefix is LEFT-ANCHORED with \`(?<![A-Za-z0-9])\` — without it, ordinary words whose
|
|
11
|
+
* TAIL spells a prefix were silently redacted (NETWORK-attached → NETWO[redacted], RTMARK-100,
|
|
12
|
+
* task_categories, monkey=abcd1234, MonkeyJumping…) while triggering unpredictably on suffix
|
|
13
|
+
* length. \`_\` is deliberately NOT in the anchor class: \`api_key=\`, \`STRIPE=sk_live_…\`-style glued
|
|
14
|
+
* assignments are REAL credential shapes that must keep scrubbing. The prefixed-token arm also
|
|
15
|
+
* drops the \`i\` flag: the real vendors' prefixes are lowercase-only (sk_/pk_/rk_/ghp_…), and the
|
|
16
|
+
* case-insensitive form is what turned every UPPERCASE technical word ending in RK/SK/PK into a
|
|
17
|
+
* false positive. */
|
|
1
18
|
export type RedactionConfidence = "high" | "medium" | "low";
|
|
19
|
+
/** Which module's rule table minted a finding (ANG-11 provenance). A closed set, and there is no public
|
|
20
|
+
* factory for a finding — a report's entries can only have been written by one of these tables running
|
|
21
|
+
* here, so "this finding says X" is an engine statement, not something a caller can hand-assemble into
|
|
22
|
+
* a report and have the pipeline endorse. */
|
|
2
23
|
export type RedactionSource = "arg-summary" | "untrusted-egress" | "secret-env";
|
|
24
|
+
/** One redaction hit: what was detected, where (ORIGINAL-input coordinates), how confidently, the marker
|
|
25
|
+
* literal written in its place, and which rule table minted it. */
|
|
3
26
|
export interface RedactionFinding {
|
|
4
27
|
kind: string;
|
|
5
28
|
span: readonly [number, number];
|
|
@@ -7,24 +30,63 @@ export interface RedactionFinding {
|
|
|
7
30
|
marker: string;
|
|
8
31
|
source: RedactionSource;
|
|
9
32
|
}
|
|
33
|
+
/** The minimum a finding must declare to be summarizable. Both text findings ({@link RedactionFinding})
|
|
34
|
+
* and the env arm's entry findings satisfy it, so {@link summarizeRedactions} is ONE helper rather than
|
|
35
|
+
* one per material kind. */
|
|
10
36
|
export interface SummarizableFinding {
|
|
11
37
|
kind: string;
|
|
12
38
|
confidence: RedactionConfidence;
|
|
13
39
|
}
|
|
40
|
+
/** ANG-3 (envelope declaration) — render findings as ONE human-readable line, e.g.
|
|
41
|
+
* `"3 redactions: prefixed-token (high) x1, url (medium) x1, fs-path (low) x1"`, so an upper layer can
|
|
42
|
+
* declare to its consumer how much was removed and how confidently.
|
|
43
|
+
*
|
|
44
|
+
* PURE, and deliberately only that: it reads the array, returns a string, and injects nothing anywhere.
|
|
45
|
+
* Attaching this line to an output is the caller's decision — a redaction pipeline that silently
|
|
46
|
+
* appended prose to the very text it was asked to bound would break both the size contract
|
|
47
|
+
* (`boundedString`) and the byte-invariance the whole channel is built on.
|
|
48
|
+
*
|
|
49
|
+
* Grouping is by kind AND confidence together: collapsing on kind alone would report whichever
|
|
50
|
+
* confidence happened to arrive first for the rest of that group, which is exactly the silent
|
|
51
|
+
* mis-statement ANG-4 exists to prevent. */
|
|
14
52
|
export declare function summarizeRedactions(findings: readonly SummarizableFinding[]): string;
|
|
53
|
+
/** The optional collector every redaction entry point accepts. `preexistingMarkers` (ANG-11) counts
|
|
54
|
+
* marker-shaped literals ALREADY present in the input before any pass ran — a nonzero value means the
|
|
55
|
+
* text arrived pre-redacted or carries forged markers, either way "marker present" is not proof this
|
|
56
|
+
* pipeline ran. Caller-owned: pass `{ findings: [] }` and read it back after the call. */
|
|
15
57
|
export interface RedactionReport {
|
|
16
58
|
findings: RedactionFinding[];
|
|
17
59
|
preexistingMarkers?: number;
|
|
18
60
|
}
|
|
61
|
+
/** A declared redaction pass — the unit {@link runRedactionPasses} executes and reports on. */
|
|
19
62
|
export interface RedactionPass {
|
|
20
63
|
kind: string;
|
|
21
64
|
confidence: RedactionConfidence;
|
|
22
65
|
marker: string;
|
|
66
|
+
/** The module this pass is declared in — copied verbatim onto every finding it mints (ANG-11). It
|
|
67
|
+
* travels WITH the pass, so a table composed into another module's pipeline (untrusted-egress chains
|
|
68
|
+
* {@link SECRET_PASSES}) still attributes its hits to the table that owns the rule, not to whoever ran it. */
|
|
23
69
|
source: RedactionSource;
|
|
24
70
|
re: RegExp;
|
|
71
|
+
/** A literal replacement (only `$1` substitution is used by these passes) or a replacer fn. */
|
|
25
72
|
replace: string | ((match: string, ...groups: string[]) => string);
|
|
26
73
|
}
|
|
74
|
+
/** Run the declared passes in order, collecting findings (original-input spans) when a report is given.
|
|
75
|
+
* An idempotent no-op replacement (inserted === matched, e.g. re-scrubbing already-redacted text) is
|
|
76
|
+
* NOT a finding — nothing was removed. */
|
|
27
77
|
export declare function runRedactionPasses(input: string, passes: readonly RedactionPass[], report?: RedactionReport): string;
|
|
78
|
+
/** The credential-shape passes (the pre-channel SECRET_PATTERNS, now with declared kinds/confidence).
|
|
79
|
+
* Exported for {@link runRedactionPasses} composition (untrusted-egress chains its URL passes after
|
|
80
|
+
* these in ONE pipeline so its findings' spans stay in original coordinates). */
|
|
28
81
|
export declare const SECRET_PASSES: readonly RedactionPass[];
|
|
29
82
|
export declare function scrubSecrets(s: string, report?: RedactionReport): string;
|
|
83
|
+
/** A SHORT, SECRET-SCRUBBED primary-arg summary. Abbreviation REDUCES the surface; a final {@link scrubSecrets}
|
|
84
|
+
* pass is the leak boundary (the value is PERSISTED + SSE-forwarded and may be read by a platform operator in a
|
|
85
|
+
* multi-tenant deployment — codex F-10). Rules (codex-reviewed):
|
|
86
|
+
* • command → the command NAME (skip leading `VAR=val` env-prefixes; bail to `undefined` on a quoted assignment
|
|
87
|
+
* or a lone assignment; basename a path-form command; `+ …` if it had args).
|
|
88
|
+
* • file path → BASENAME only (no host directory layout).
|
|
89
|
+
* • url → `new URL` origin+pathname (strips `user:pass@` userinfo + query/fragment).
|
|
90
|
+
* • else → pattern/query/description, else the first NON-sensitively-named string field.
|
|
91
|
+
* Then scrub-secrets + code-point-truncate. */
|
|
30
92
|
export declare function primaryActivityArg(args: unknown): string | undefined;
|