@sema-agent/core 7.5.2 → 7.6.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 +67 -0
- package/dist/agents/agent-transcript-tool.d.ts +2 -2
- package/dist/agents/cascade.d.ts +4 -5
- package/dist/agents/cascade.js +12 -10
- package/dist/agents/repair-loop.d.ts +7 -5
- package/dist/agents/repair-loop.js +13 -15
- package/dist/agents/retain-ledger.d.ts +2 -3
- package/dist/agents/send-message-tool.d.ts +2 -2
- package/dist/agents/session-util.d.ts +2 -2
- package/dist/agents/subagent.d.ts +27 -46
- package/dist/agents/subagent.js +119 -105
- package/dist/agents/suspend-guard.d.ts +31 -19
- package/dist/agents/suspend-guard.js +14 -8
- package/dist/agents/teacher.d.ts +2 -2
- package/dist/agents/teacher.js +9 -9
- package/dist/agents/team.d.ts +6 -5
- package/dist/agents/team.js +10 -8
- package/dist/agents/verify.d.ts +8 -9
- package/dist/agents/verify.js +17 -17
- package/dist/core/a2a.js +2 -1
- package/dist/core/agent-definition.d.ts +172 -0
- package/dist/core/agent-definition.js +1 -0
- package/dist/core/ask-origin.d.ts +60 -7
- package/dist/core/ask-origin.js +26 -1
- package/dist/core/checkpoint-store.d.ts +78 -76
- package/dist/core/checkpoint-store.js +17 -1
- package/dist/core/delegation-frames.d.ts +298 -0
- package/dist/core/delegation-frames.js +21 -0
- package/dist/core/engine-notice.d.ts +555 -0
- package/dist/core/engine-notice.js +55 -0
- package/dist/core/gate-fold.d.ts +12 -0
- package/dist/core/gate-fold.js +158 -0
- package/dist/core/gate-lanes.d.ts +93 -0
- package/dist/core/gate-lanes.js +626 -0
- package/dist/core/gate-outcome.d.ts +189 -0
- package/dist/core/gate-outcome.js +70 -0
- package/dist/core/hands-band.d.ts +134 -0
- package/dist/core/hands-band.js +1 -0
- package/dist/core/hooks.d.ts +22 -177
- package/dist/core/hooks.js +53 -851
- package/dist/core/mcp-failure.d.ts +142 -0
- package/dist/core/mcp-failure.js +145 -0
- package/dist/core/mcp-server-spec.d.ts +217 -0
- package/dist/core/mcp-server-spec.js +1 -0
- package/dist/core/mcp.d.ts +21 -77
- package/dist/core/mcp.js +76 -150
- package/dist/core/model-seat.d.ts +99 -0
- package/dist/core/model-seat.js +1 -0
- package/dist/core/pause-registry.d.ts +131 -0
- package/dist/core/pause-registry.js +27 -0
- package/dist/core/reminder-mint.d.ts +10 -0
- package/dist/core/reminder-mint.js +3 -0
- package/dist/core/runner/assemble-result.d.ts +32 -41
- package/dist/core/runner/assemble-result.js +55 -74
- package/dist/core/runner/contracts.d.ts +427 -69
- package/dist/core/runner/denial-limit-arms.d.ts +1 -1
- package/dist/core/runner/denial-limit-arms.js +3 -3
- package/dist/core/runner/gate-exit.d.ts +242 -0
- package/dist/core/runner/gate-exit.js +124 -0
- package/dist/core/runner/park-commit.d.ts +17 -23
- package/dist/core/runner/park-commit.js +14 -15
- package/dist/core/runner/prepare-ask-lane.d.ts +0 -3
- package/dist/core/runner/prepare-ask-lane.js +3 -5
- package/dist/core/runner/prepare-boundary-parks.d.ts +3 -6
- package/dist/core/runner/prepare-boundary-parks.js +3 -3
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +2 -7
- package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
- package/dist/core/runner/prepare-delegation-surface.d.ts +2 -7
- package/dist/core/runner/prepare-gate-stations.d.ts +4 -7
- package/dist/core/runner/prepare-gate-stations.js +29 -54
- package/dist/core/runner/prepare-inherited-gate.js +1 -1
- package/dist/core/runner/prepare-memory.d.ts +44 -26
- package/dist/core/runner/prepare-park-ask.d.ts +2 -4
- package/dist/core/runner/prepare-park-ask.js +5 -5
- package/dist/core/runner/prepare-task.d.ts +2 -2
- package/dist/core/runner/prepare-task.js +8 -9
- package/dist/core/runner/prepare-wiring-manifest.d.ts +7 -15
- package/dist/core/runner/prepare-wiring-manifest.js +9 -10
- package/dist/core/runner/runtask.d.ts +20 -102
- package/dist/core/runner/runtask.js +119 -121
- package/dist/core/runner/terminal-projection.d.ts +22 -0
- package/dist/core/runner/terminal-projection.js +28 -0
- package/dist/core/runner-deps.d.ts +1416 -0
- package/dist/core/runner-deps.js +1 -0
- package/dist/core/runtime-caps.d.ts +164 -0
- package/dist/core/runtime-caps.js +1 -0
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +4 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +8 -2
- package/dist/core/task-event.d.ts +910 -0
- package/dist/core/task-event.js +1 -0
- package/dist/core/task-limits.d.ts +110 -0
- package/dist/core/task-limits.js +1 -0
- package/dist/core/task-result.d.ts +809 -0
- package/dist/core/task-result.js +1 -0
- package/dist/core/task-spec.d.ts +1370 -0
- package/dist/core/task-spec.js +1 -0
- package/dist/core/task-stream.d.ts +382 -0
- package/dist/core/task-stream.js +1 -0
- package/dist/core/terminal-cause.d.ts +137 -0
- package/dist/core/terminal-cause.js +9 -0
- package/dist/core/tool-policy.d.ts +43 -139
- package/dist/core/tool-policy.js +79 -112
- package/dist/core/tool-spec.d.ts +1174 -0
- package/dist/core/tool-spec.js +1 -0
- package/dist/core/types.d.ts +27 -7789
- package/dist/core/types.js +2 -76
- package/dist/core/warm-resume.d.ts +2 -2
- package/dist/core/wiring-manifest.d.ts +6 -3
- package/dist/core/workflow-journal-store.js +3 -4
- package/dist/engine/harness/agent-harness.d.ts +1 -1
- package/dist/index.d.ts +12 -8
- package/dist/index.js +9 -6
- package/dist/orchestration/builtin-workflows.d.ts +2 -2
- package/dist/orchestration/builtin-workflows.js +1 -1
- package/dist/orchestration/goal.d.ts +2 -2
- package/dist/orchestration/goal.js +8 -7
- package/dist/orchestration/run-spec.d.ts +2 -2
- package/dist/orchestration/run-spec.js +5 -3
- package/dist/orchestration/run-workflow-tool.d.ts +4 -4
- package/dist/orchestration/run-workflow-tool.js +4 -4
- package/dist/orchestration/workflow-governance.d.ts +4 -4
- package/dist/orchestration/workflow-governance.js +4 -2
- package/dist/orchestration/workflow-primitives.d.ts +1 -1
- package/dist/orchestration/workflow-primitives.js +1 -1
- package/dist/orchestration/workflow.d.ts +15 -4
- package/dist/orchestration/workflow.js +64 -39
- package/dist/prompts/supervisor.d.ts +1 -1
- package/dist/prompts/supervisor.js +3 -3
- package/dist/scenarios/scenario-registry.d.ts +3 -3
- package/dist/scenarios/scenario-registry.js +1 -1
- package/dist/scenarios/teacher-quickstart.d.ts +2 -2
- package/dist/server/http.d.ts +2 -2
- package/dist/stores/file/fs-atomic.d.ts +88 -12
- package/dist/stores/file/fs-atomic.js +184 -55
- package/dist/stores/file/index.d.ts +1 -0
- package/dist/stores/file/index.js +1 -0
- package/package.json +3 -1
- package/test/export-surface.snapshot.json +82 -22
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,72 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 7.6.1 — 2026-09-07
|
|
4
|
+
|
|
5
|
+
Patch: three bug fixes from the 7.6.0 field and black-box rounds (#608 P1, #609, #610) and the first refactor wave (design/393 S0, #594, #598), all byte-invariant on the runtime except where named. One public d.ts narrowing is called out below.
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **#608 (P1)** — the file store's single-writer directory lock judged its owner by pid number alone, so a dead holder's pid recycled to an unrelated process kept the lock "in use" and every engine start failed with `store.dir_in_use` until an operator deleted the lock by hand (the cli production shape: two LOCK files reading `79814`, no trailing newline). The lock record now carries a process fingerprint `{pid, startedAtMs, startedSinceBootMs, host, v: 2}`; liveness is "pid alive AND not falsified by BOTH clocks" (a wall-clock start and an uptime-relative start — each unreliable exactly where the other is sound); a record from another host, or one without a comparable measure, keeps the pre-fingerprint verdict (a false "dead" reclaims a working writer's directory; a false "live" costs one refusal an operator can act on); a reboot the host has outlived is the uptime measure's second way of saying gone. Bare-pid locks are read by pid and rewritten on reclaim. What the guards cannot see (a same-boot backward clock correction hiding a genuine reuse; a reboot the machine has since outlived with no comparable measure) falls back to the pre-existing refusal, never a wrong reclaim — a boot-scoped kernel start token is the design-level fix (#612).
|
|
9
|
+
- **#609** — a resume of a parked policy ask that still spells the retired decision facts (`settledBy` / `approver` as top-level keys) is refused before the CAS with a coded error naming the `hostDecision` shape, instead of having the keys silently ignored (found by the 7.6.0 black-box round, G2.b).
|
|
10
|
+
- **#610** — every connect-phase MCP failure reports `delivered: "no"` — the dial has dispatched nothing of the caller's, so the verdict is a fact, not the in-flight guess; the two kinds a server itself answered (`protocol`, `http_status`) keep the table verdict. One verdict table (`DELIVERED_BY_KIND`, fenced over the closed set) replaces the per-row spellings. A stdio child that exits before the handshake is now `connection_closed / no` (was `unknown`); a 401 endpoint stays `http_status / unknown`; the request phase is unchanged. The dial's `no` promises that no call of the caller's was dispatched — it does not promise that no user data crossed the line during the handshake's elicitation (#611).
|
|
11
|
+
- **#594-b** — the #594 station relocation had put one microtask between the fold and the lanes (and one more inside the screening wrapper), so an org rule cleared on that tick was read as absent and a call 7.6.0 denied was let through; the three station-group seams (screening→fold, fold→lanes, lanes→exit) are back to the one-body form's await boundaries — the next group runs inside the previous group's continuation via a `GatePass.afterFold` seat. Five boundary pins record the microtask counts against the 7.6.0 tree.
|
|
12
|
+
- 7.6.0 carry-over disclosure: the D-8 refusal text `Resume it via checkpointToken` became `Resume it via the pause's token` (wording only).
|
|
13
|
+
|
|
14
|
+
### BREAKING (d.ts face only — runtime unchanged)
|
|
15
|
+
- Option types and orchestration entry points that used to name the `Runner` CLASS for their `runner` member / parameter (`TaskServerOptions`, `SubagentToolOptions`, `SendMessageToolOptions`, `RunWorkflowToolDeps`, `warmResume`, `runGoal`, `runCascade`, `runRepairLoop`, `verify*`, `runWithTeacher`, `startWorkflow`, `runWorkflow`) now name **`RunnerSelfSeat`** — the one seat the Runner implements and every consumer names (`sessions`, `runTask`, `runTaskStream`, `resume`, `resumeStream`, `agentCatalog`, `emitTaskOutcome`, `gateBaseline`). A host that read `opts.runner.swapModels` or `opts.runner.sideQuery` THROUGH an option type no longer type-checks; call them on the Runner instance it constructed. No shipped consumer does (server calls `swapModels` on its own instances). Passing a `Runner` where a seat is expected still compiles.
|
|
16
|
+
|
|
17
|
+
### Changed (refactor wave 1 — byte-invariant on the runtime)
|
|
18
|
+
- **design/393 S0** — the run loop's seven contract declarations move down to `contracts.ts`; runtask.ts takes its contracts from their declaring modules (orchestrator contract edges 2→0; G2 exemptions 3→1); the G5 phase-api gate is driven by a `PHASE_FAMILIES` table; LAYERING gains the "run lanes" stratum. runtask.ts 12 215 → 11 946 lines. dist `runtask.js` differs only in import lines.
|
|
19
|
+
- **#594** — the 23 gate stations (+4 exits) leave hooks.ts for the three-layer shape: `gate-fold.ts` (L1, the policy fold), `gate-lanes.ts` (L1, the org + ask-resolution lanes), `runner/gate-exit.ts` (L0, the exits + the one mint); hooks.ts keeps only the hook machinery and a six-call dispatch; `GatePass` is the one record the three read and write. hooks.ts 4 047 → 2 291 lines. Station-file closed-set pin + wiring pin. Words, order, deny layers, settlement kinds: unchanged and pinned.
|
|
20
|
+
- **#598** — the 7 721-line public type hub `types.ts` becomes a 54-line re-export hub over fourteen layer-0 domain modules (`model-seat`, `task-spec`, `tool-spec`, `hands-band`, `agent-definition`, `mcp-server-spec`, `task-limits`, `task-result`, `task-event`, `task-stream`, `runtime-caps`, `delegation-frames`, `runner-deps`, `engine-notice`); every import path and the public export surface are byte-identical; a re-export closed-set pin refuses a declaration re-appearing in the hub.
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- `processFingerprint(pid?)`, `isProcessLive(record)`, `type ProcessFingerprint` — the file store's process-identity pair, exported for a host's own liveness arm.
|
|
24
|
+
- `type RunnerSelfSeat`.
|
|
25
|
+
|
|
26
|
+
### Unchanged and pinned
|
|
27
|
+
- Public export surface: 7.6.0's 2 098 names plus the four above, zero removed. Wire frames, the durable park row, the 23 gate stations, `TaskResult.terminal`, the MCP failure record's kinds: unchanged.
|
|
28
|
+
|
|
29
|
+
## 7.6.0 — 2026-09-07
|
|
30
|
+
|
|
31
|
+
**BREAKING.** design/390 S6 (three slices, merged): the tool gate's settlement/origin words become ONE `GateOutcome` record, `TaskResult` becomes ONE terminal record, MCP failures become ONE structural record with a delivery verdict, and the durable off switch becomes a word. Every consumer that read the retired keys must migrate (server 7.64.0, cli/client-core, web-admin, desktop — the criteria post lists the frames old→new).
|
|
32
|
+
|
|
33
|
+
### BREAKING — exports removed (10)
|
|
34
|
+
- `APPROVAL_SETTLED_BY_VALUES`, `ASK_DENY_RESOLUTION_VALUES`, `isApprovalSettledBy`, `isAskDenyResolution`, `type ApprovalSettledBy`, `type AskDenyResolution`, `type PermissionDeniedSource` (S6-A — replaced by `GateOutcome` / `Settlement` / `DeniedBy`).
|
|
35
|
+
- `MCP_FAILURE_CODES`, `mcpFailureCodeOf`, `type McpFailureCode` (S6-B — replaced by `McpFailure` / `MCP_FAILURE_KINDS` / `classifyMcpFailure`).
|
|
36
|
+
|
|
37
|
+
### BREAKING — same-name shape changes
|
|
38
|
+
- `TaskResult`: the eight plane fields `status` / `errorCode` / `errorMessage` / `blockedReason` / `checkpointToken` / `checkpointId` / `checkpointGate` / `workspaceRestoreMode` are deleted; the run's end is ONE required `terminal: TerminalCause` (`completed` | `failed{code?, message?, nestedPause?}` | `blocked{reason}` | `paused{gate, token, checkpointId?, restoreMode?}`). `terminalProjection(terminal)` is the explicit projection for a face that keeps the old shape. The `done` frame, the HTTP task body and SSE `done.result` are the result itself, so they lose the eight keys and carry `terminal`; a nested boundary's pause is `failed` + `nestedPause` (its token no longer rides `checkpointToken`).
|
|
39
|
+
- `TaskSpec.checkpointStore`: the per-run durable off switch is the word `"disabled"`; the retired `null` is refused at the first prepare with `config.invalid_checkpoint_store` (also through a worktree baseline overlay). `engine_notice` cause `task_store_null` → `task_store_disabled`.
|
|
40
|
+
- `Checkpoint` is a type (`CheckpointRow & CheckpointPause`) whose gate × pendingAction pairing is fixed by `PAUSE_REGISTRY`; hand-built rows go through `checkpointFrom` / `pauseOf`. A dry-run `needs_review` row carries its own `pendingAction.kind: "review"`.
|
|
41
|
+
- `ResumeOutcome.policy_ask.hostDecision` is required: a host resolving a park supplies decision FACTS (`{decision, decidedBy: "person" | "sla_timeout", …}`) and core mints every settlement word — a host never spells a kind.
|
|
42
|
+
- `RealApprovalGateBit.origin` is the full `AskOrigin` set (was a five-word subset) and gains the org FACT member `org?: "rule" | "unavailable"`; read governance through `realApprovalOrgFact(bit)`, never through the routing word. `AskOrigin` gains `safety_tighten` and `shell_gate_tighten`.
|
|
43
|
+
- `TeacherRunResult` and `VerificationResult` (they extend `TaskResult`) lose the same eight plane keys; `ResumeOutcome` loses `settledBy` / `approver` (the host supplies `hostDecision` facts instead).
|
|
44
|
+
- `ResolvedAsk` loses its four settlement keys; `RepairResult.terminal` → `repairTerminal`; `McpErrorMarks.errorKind` is replaced by `McpFailure{kind, delivered, httpStatus?}`; `SubagentErrorKind` drops `overloaded` and gains `unknown`.
|
|
45
|
+
|
|
46
|
+
### BREAKING — wire frames
|
|
47
|
+
- `tool_end`: `settledBy` / `resolution` / `autoDenied` / `approver` deleted → `gate?: GateOutcome` (`disposition: {kind:"allowed"} | {kind:"denied", deniedBy}`, `settlement?: Settlement` (12 kinds, `who` fixed by `kind`), `origin?: AskOrigin`); `errorCode` speaks `McpFailureKind` (`connection_failed` / `connection_closed` / `timeout` / `protocol` / `http_status` / …; `network` and `http_<n>` retired) or a result code (`mcp.task_required`, `mcp.tool_error`, `mcp.server_revoked`); new `delivered?: "yes" | "no" | "unknown"`.
|
|
48
|
+
- `permissionDenied` observer payload: `source` / `resolution` / `autoDenied` deleted → `gate: GateOutcome` (frozen). `DeniedBy` = policy / hook / org / classifier / plan_mode / compliance / write_protection / ask_resolution.
|
|
49
|
+
- `wiring_manifest.mcp[]`: `errorCode` in the new words, plus `delivered` and `httpStatus`.
|
|
50
|
+
- Checkpoint rows: `realApproval.origin` full set + `org`; resolved rows record `resolvedOutcome.gateOutcome`; a `review` pending kind exists.
|
|
51
|
+
- Agent card `error_kind`: `overloaded` → gone, `unknown` added (no structured code ⇒ `unknown`, not retryable).
|
|
52
|
+
|
|
53
|
+
### Changed (narrowings, named)
|
|
54
|
+
- An approval-factory approver's bare refusal on the parent thread halts the batch like a live approver's; a person's yes vetoed by a later layer is recorded as `human_allowed` beside the vetoing `deniedBy`; the post-CAS belt's refusal carries the veto record.
|
|
55
|
+
- The HTTP MCP transport no longer follows redirects (3xx ⇒ `http_status`, delivered `unknown`); a listing requiring task support is refused before any send (`mcp.task_required`, delivered `no`); a server's `isError:true` reply is `mcp.tool_error` with delivered `yes`; same-raw-name listings mount from one accepted view; a bare `TypeError` classifies as `unknown`, never `connection_failed`.
|
|
56
|
+
- A resume journal entry whose result carries no closed-set terminal cause (a journal written before `TaskResult.terminal`, or a malformed entry) refuses the resume with `WorkflowJournalIncompatibleError` (`workflow.journal_incompatible`) before any agent is dispatched — it no longer diverges into a live re-run of completed work. `TERMINAL_CAUSE_IS_REPLAYABLE` is the one table behind admission and replay.
|
|
57
|
+
- A background child's "durable pause without a token" arm is retired (unconstructible).
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
- `GateOutcome` / `Settlement` / `DeniedBy` (+ `SETTLEMENT_KINDS`, `DENIED_BY_VALUES`, `SETTLEMENT_IS_REFUSAL`, `DENIED_BY_MAY_VETO`, `isSettlementKind`, `isDeniedBy`, `screenGateOutcome`), minted once at the gate exit (`mintGateOutcome`) and projected onto three faces; invariants I1–I4 screened at the wire entry; `ORIGIN_IMPLIES_REAL_APPROVAL`.
|
|
61
|
+
- `PAUSE_REGISTRY` (+ `GateKind`, `PendingKind`, `ResumeGate`, `isGateKind`, `resumeGateMatches`, `checkpointFrom`, `pauseOf`, `CheckpointFields`, `CheckpointPause`, `CheckpointRow`).
|
|
62
|
+
- `TerminalCause`, `PausedCause`, `terminalProjection`, `realApprovalOrgFact`, `resolveCheckpointStore`.
|
|
63
|
+
- `McpFailure`, `MCP_FAILURE_KINDS`, `MCP_DELIVERY_VERDICTS`, `McpDelivered`, `classifyMcpFailure` (ordered structural classifier, no text regex).
|
|
64
|
+
- `WorkflowJournalIncompatibleError`.
|
|
65
|
+
- Gates: `gate:closed-sets` (`docs/CLOSED-SETS.md` registry + `AssertAllKeysHandled` fences + switch exhaustiveness) and `gate:contract-sentences` (`@contract` ids, `docs/CONTRACT-SENTENCES.md`, duplicate-sentence baseline); invariant pins `test/gate-outcome-invariants.test.ts`; `test/design390-d8-terminal-only.test.ts`.
|
|
66
|
+
|
|
67
|
+
### Unchanged and pinned
|
|
68
|
+
- The suspendAsk 13-parameter `AskCarry`; the 23 gate stations (words, order); delegation lifecycle frames, `task.end` trace, agent cards, reports and workflow records keep their shape through the explicit projection; `engine_notice` codes other than the renamed cause; `wiring_manifest` keys other than `mcp[]`.
|
|
69
|
+
|
|
3
70
|
## 7.5.2 — 2026-09-06
|
|
4
71
|
|
|
5
72
|
Maintenance release: design/390 slices S3–S4 complete the `prepareTask` decomposition (4 756 → 1 666 driver lines, 34 phase modules), one settlement-path narrowing (#587), and the wire-manifest tooling that the 7.5.1 review asked for (#588 / #589). **No BREAKING change**: the export surface is byte-identical to 7.5.1; the only behaviour delta is that a reserved-tool-name collision now disposes an acquired protocol handle once instead of twice (below).
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
|
-
import type {
|
|
2
|
+
import type { RunnerSelfSeat } from "../core/runner/contracts.js";
|
|
3
3
|
/** Model-facing name of the child-transcript read tool (residual lane C). */
|
|
4
4
|
export declare const AGENT_TRANSCRIPT_TOOL_NAME = "AgentTranscript";
|
|
5
5
|
export interface AgentTranscriptToolOptions {
|
|
6
6
|
/** Runner whose `sessions` store holds the child's persisted history. */
|
|
7
|
-
runner:
|
|
7
|
+
runner: RunnerSelfSeat;
|
|
8
8
|
/** The unified registry the background Agent lane registered its a* handles in (scopes reads to lineage). */
|
|
9
9
|
registry: import("../core/task-registry.js").TaskRegistry;
|
|
10
10
|
/** design/151 S1b: the durable ledger — when the live row/retain entry is gone (restart, terminal GC,
|
package/dist/agents/cascade.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type { ModelRef, TaskResult, TaskSpec } from "../core/types.js";
|
|
1
|
+
import type { RunInternals, RunnerSelfSeat } from "../core/runner/contracts.js";
|
|
2
|
+
import type { ModelRef, TaskResult, TaskSpec, TaskStatus } from "../core/types.js";
|
|
4
3
|
/**
|
|
5
4
|
* Quality-gate cascade (design/27). Run the SAME task across a ladder of models (cheapest → strongest);
|
|
6
5
|
* after each rung a caller-supplied **decidable gate** judges "good enough" — pass = keep it, fail =
|
|
@@ -109,7 +108,7 @@ export interface CascadeAttempt {
|
|
|
109
108
|
* F4) — a fabricated 0 here both misreported the attempt and let escalation ride under a finite
|
|
110
109
|
* ceiling the engine could not actually enforce. */
|
|
111
110
|
costMicroUsd?: number;
|
|
112
|
-
status:
|
|
111
|
+
status: TaskStatus;
|
|
113
112
|
/** The rung's own failure code (e.g. "auth") if its `runTask` failed — distinct from "gate rejected it". */
|
|
114
113
|
errorCode?: string;
|
|
115
114
|
/** Set when the gate THREW (vs returned false) — surfaces a broken verifier-gate (expired key, etc.). */
|
|
@@ -154,7 +153,7 @@ export interface CascadeRunResult extends TaskResult {
|
|
|
154
153
|
* (`effect: "write"`), those execute once PER rung — ensure idempotency, or gate before the side effect
|
|
155
154
|
* (e.g. a structured-output gate). `TaskSpec` never guaranteed idempotency; cascade makes it explicit.
|
|
156
155
|
*/
|
|
157
|
-
export declare function runCascade(runner:
|
|
156
|
+
export declare function runCascade(runner: RunnerSelfSeat, spec: TaskSpec, config: CascadeConfig,
|
|
158
157
|
/**
|
|
159
158
|
* The TRUSTED, run-scoped internals channel — the same object `Runner.runTask` takes as its second
|
|
160
159
|
* argument — forwarded to EVERY rung under the composition forward contract (identity, with the one
|
package/dist/agents/cascade.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { terminalProjection } from "../core/runner/terminal-projection.js";
|
|
1
2
|
import { releaseSession } from "./session-util.js";
|
|
2
3
|
import { mapNestedSuspend, isDurablePause } from "./suspend-guard.js";
|
|
3
4
|
import { buildCumulativeStats } from "./cumulative-stats.js";
|
|
@@ -10,9 +11,13 @@ function cascadeConfigError(message) {
|
|
|
10
11
|
e.code = CASCADE_CONFIG_ERROR_CODE;
|
|
11
12
|
return e;
|
|
12
13
|
}
|
|
14
|
+
function attemptTerminal(result) {
|
|
15
|
+
const face = terminalProjection(result.terminal);
|
|
16
|
+
return { status: face.status, errorCode: face.errorCode };
|
|
17
|
+
}
|
|
13
18
|
function createDefaultGate(spec) {
|
|
14
19
|
const requiresStructured = spec.outputSchema != null;
|
|
15
|
-
return (result) => result.
|
|
20
|
+
return (result) => result.terminal.kind === "completed" && (!requiresStructured || result.structuredOutput !== undefined);
|
|
16
21
|
}
|
|
17
22
|
export async function runCascade(runner, spec, config, internals) {
|
|
18
23
|
const ladder = config.ladder;
|
|
@@ -126,9 +131,9 @@ export async function runCascade(runner, spec, config, internals) {
|
|
|
126
131
|
nestedTasks += s.nested.tasks;
|
|
127
132
|
nestedCostMicro += s.nested.costMicroUsd ?? 0;
|
|
128
133
|
}
|
|
129
|
-
if (isDurablePause(result.
|
|
134
|
+
if (isDurablePause(result.terminal)) {
|
|
130
135
|
const mapped = mapNestedSuspend(result);
|
|
131
|
-
attempts.push({ index: i, model: rung.model, passed: false, costMicroUsd: rungCost, status: result.status, errorCode: mapped.errorCode });
|
|
136
|
+
attempts.push({ index: i, model: rung.model, passed: false, costMicroUsd: rungCost, status: attemptTerminal(result).status, errorCode: attemptTerminal(mapped).errorCode });
|
|
132
137
|
return {
|
|
133
138
|
...mapped,
|
|
134
139
|
stats: cumulativeStats(result.stats),
|
|
@@ -145,8 +150,7 @@ export async function runCascade(runner, spec, config, internals) {
|
|
|
145
150
|
model: rung.model,
|
|
146
151
|
passed: false,
|
|
147
152
|
costMicroUsd: rungCost,
|
|
148
|
-
|
|
149
|
-
errorCode: result.errorCode,
|
|
153
|
+
...attemptTerminal(result),
|
|
150
154
|
...(deadlineFired ? { timedOut: true } : { cancelled: true }),
|
|
151
155
|
});
|
|
152
156
|
notifier.notify(() => config.onRung?.({ index: i, model: rung.model, passed: false, result }), CASCADE_ON_RUNG_SITE);
|
|
@@ -170,7 +174,7 @@ export async function runCascade(runner, spec, config, internals) {
|
|
|
170
174
|
passed = false;
|
|
171
175
|
gateError = e instanceof Error ? e.message : String(e);
|
|
172
176
|
}
|
|
173
|
-
const statusRejected = passed && config.acceptPartial !== true && result.
|
|
177
|
+
const statusRejected = passed && config.acceptPartial !== true && result.terminal.kind !== "completed";
|
|
174
178
|
if (statusRejected)
|
|
175
179
|
passed = false;
|
|
176
180
|
attempts.push({
|
|
@@ -178,8 +182,7 @@ export async function runCascade(runner, spec, config, internals) {
|
|
|
178
182
|
model: rung.model,
|
|
179
183
|
passed,
|
|
180
184
|
costMicroUsd: rungCost,
|
|
181
|
-
|
|
182
|
-
errorCode: result.errorCode,
|
|
185
|
+
...attemptTerminal(result),
|
|
183
186
|
gateError,
|
|
184
187
|
diagnostics,
|
|
185
188
|
...(statusRejected ? { statusRejected: true } : {}),
|
|
@@ -198,9 +201,8 @@ export async function runCascade(runner, spec, config, internals) {
|
|
|
198
201
|
return {
|
|
199
202
|
taskId: spec.taskId ?? "",
|
|
200
203
|
sessionId: "",
|
|
201
|
-
status: "failed",
|
|
202
204
|
result: `runCascade: the overall wall-clock budget (totalTimeoutMs ${config.totalTimeoutMs}ms) was already spent when the ladder was entered — no rung dispatched`,
|
|
203
|
-
|
|
205
|
+
terminal: { kind: "failed", code: CASCADE_NO_DISPATCH_ERROR_CODE },
|
|
204
206
|
stats: { tokens: 0, turns: 0, costMicroUsd: 0 },
|
|
205
207
|
cascadeOutcome: "exhausted",
|
|
206
208
|
escalated: false,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RunnerSelfSeat } from "../core/runner/contracts.js";
|
|
2
2
|
import type { TaskSpec } from "../core/types.js";
|
|
3
3
|
import type { ExecutionEnv } from "../internal/harness-types.js";
|
|
4
4
|
import type { VerificationResult } from "./verify.js";
|
|
@@ -179,7 +179,7 @@ export interface RepairLoopConfig {
|
|
|
179
179
|
/** Per-attempt callback (observability). */
|
|
180
180
|
onAttempt?: (info: {
|
|
181
181
|
attempt: number;
|
|
182
|
-
|
|
182
|
+
repairTerminal?: RepairTerminal;
|
|
183
183
|
oracle: OracleResult;
|
|
184
184
|
}) => void;
|
|
185
185
|
/**
|
|
@@ -191,8 +191,10 @@ export interface RepairLoopConfig {
|
|
|
191
191
|
onWarn?: (warning: Error) => void;
|
|
192
192
|
}
|
|
193
193
|
export interface RepairResult extends VerificationResult {
|
|
194
|
-
/** The projected terminal (§2)
|
|
195
|
-
|
|
194
|
+
/** The projected REPAIR terminal (§2) — the loop's own word (fixed / candidate_only / gave_up / …), distinct
|
|
195
|
+
* from the inherited run terminal `terminal` (a {@link import("../core/types.js").TerminalCause}, WHY the
|
|
196
|
+
* worker's last leg ended). SAFE-tier never returns `fixed`. */
|
|
197
|
+
repairTerminal: RepairTerminal;
|
|
196
198
|
/** The final repair state (in-memory unless an orthogonal suspend serialized it — §4). */
|
|
197
199
|
bundle: RepairBundle;
|
|
198
200
|
/**
|
|
@@ -276,4 +278,4 @@ export declare function terminalForTier(oracle: OracleResult): RepairTerminal |
|
|
|
276
278
|
* SAFE-tier: the projection caps every PASS at `candidate_only` — this NEVER auto-accepts. `runRepairLoop` is a
|
|
277
279
|
* SIBLING of {@link verifyCompleted}: it composes over `runner.runTask` and never touches the Runner core.
|
|
278
280
|
*/
|
|
279
|
-
export declare function runRepairLoop(runner:
|
|
281
|
+
export declare function runRepairLoop(runner: RunnerSelfSeat, implSpec: TaskSpec, config: RepairLoopConfig): Promise<RepairResult>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isDurablePause } from "./suspend-guard.js";
|
|
1
|
+
import { isDurablePause, pauseFamily } from "./suspend-guard.js";
|
|
2
2
|
import { delimitUntrusted, sanitizeUntrustedText } from "../core/untrusted-text.js";
|
|
3
3
|
import { assertOracleIsolation } from "../core/oracle-isolation.js";
|
|
4
4
|
import { buildCumulativeStats } from "./cumulative-stats.js";
|
|
@@ -48,12 +48,11 @@ export async function runRepairLoop(runner, implSpec, config) {
|
|
|
48
48
|
const oracle = { tier: "none", passed: false, flaky: false, retries: 0 };
|
|
49
49
|
return {
|
|
50
50
|
taskId: implSpec.taskId ?? "",
|
|
51
|
-
status: "failed",
|
|
52
51
|
result: `oracle isolation check failed: ${reason}`,
|
|
53
|
-
|
|
52
|
+
terminal: { kind: "failed", code: "oracle.unprotected", message: `oracle isolation check failed: ${reason}` },
|
|
54
53
|
sessionId: "",
|
|
55
54
|
stats: { tokens: 0, turns: 0, costMicroUsd: 0 },
|
|
56
|
-
|
|
55
|
+
repairTerminal: "oracle.unprotected",
|
|
57
56
|
...(isolationClass ? { isolationClass } : {}),
|
|
58
57
|
bundle: { ...freshBundle(), attemptCount: config.resumeBundle?.attemptCount ?? 0 },
|
|
59
58
|
oracleCostMicroUsd: 0,
|
|
@@ -157,12 +156,11 @@ export async function runRepairLoop(runner, implSpec, config) {
|
|
|
157
156
|
};
|
|
158
157
|
const exhaustedBeforeDispatch = (message, errorCode) => ({
|
|
159
158
|
taskId: implSpec.taskId ?? "",
|
|
160
|
-
status: "failed",
|
|
161
159
|
result: message ?? `repair loop: attempt budget already spent (attemptCount ${bundle.attemptCount} >= maxAttempts ${maxAttempts}) — no attempt dispatched`,
|
|
162
|
-
|
|
160
|
+
terminal: { kind: "failed", code: errorCode ?? "repair.attempts_exhausted", message: message ?? `repair loop: attempt budget already spent (attemptCount ${bundle.attemptCount} >= maxAttempts ${maxAttempts}) — no attempt dispatched` },
|
|
163
161
|
sessionId: implSpec.sessionId ?? "",
|
|
164
162
|
stats: { tokens: 0, turns: 0, costMicroUsd: 0 },
|
|
165
|
-
|
|
163
|
+
repairTerminal: "gave_up",
|
|
166
164
|
bundle,
|
|
167
165
|
...(isolationClass ? { isolationClass } : {}),
|
|
168
166
|
oracleCostMicroUsd,
|
|
@@ -208,22 +206,22 @@ export async function runRepairLoop(runner, implSpec, config) {
|
|
|
208
206
|
accumulate(result.stats);
|
|
209
207
|
lastResult = result;
|
|
210
208
|
bundle.attemptCount += 1;
|
|
211
|
-
if (isDurablePause(result.
|
|
209
|
+
if (isDurablePause(result.terminal)) {
|
|
212
210
|
return {
|
|
213
211
|
...result,
|
|
214
212
|
stats: cumulativeStats(result.stats),
|
|
215
|
-
|
|
213
|
+
repairTerminal: "gave_up",
|
|
216
214
|
bundle,
|
|
217
215
|
...(isolationClass ? { isolationClass } : {}),
|
|
218
216
|
oracleCostMicroUsd,
|
|
219
|
-
verification: { verdict: "unverified", unverifiedReason: result.
|
|
217
|
+
verification: { verdict: "unverified", unverifiedReason: pauseFamily(result.terminal), rounds: bundle.attemptCount, findings: [] },
|
|
220
218
|
};
|
|
221
219
|
}
|
|
222
|
-
if (result.
|
|
220
|
+
if (result.terminal.kind !== "completed") {
|
|
223
221
|
return {
|
|
224
222
|
...result,
|
|
225
223
|
stats: cumulativeStats(result.stats),
|
|
226
|
-
|
|
224
|
+
repairTerminal: "gave_up",
|
|
227
225
|
bundle,
|
|
228
226
|
...(isolationClass ? { isolationClass } : {}),
|
|
229
227
|
oracleCostMicroUsd,
|
|
@@ -237,12 +235,12 @@ export async function runRepairLoop(runner, implSpec, config) {
|
|
|
237
235
|
lastOracle = oracle;
|
|
238
236
|
bundle.oracleTier = oracle.tier;
|
|
239
237
|
const projected = terminalForTier(oracle);
|
|
240
|
-
config.onAttempt?.({ attempt: bundle.attemptCount,
|
|
238
|
+
config.onAttempt?.({ attempt: bundle.attemptCount, repairTerminal: projected, oracle });
|
|
241
239
|
if (projected !== undefined) {
|
|
242
240
|
return {
|
|
243
241
|
...result,
|
|
244
242
|
stats: cumulativeStats(result.stats),
|
|
245
|
-
|
|
243
|
+
repairTerminal: projected,
|
|
246
244
|
bundle,
|
|
247
245
|
...(isolationClass ? { isolationClass } : {}),
|
|
248
246
|
oracleCostMicroUsd,
|
|
@@ -266,7 +264,7 @@ export async function runRepairLoop(runner, implSpec, config) {
|
|
|
266
264
|
return {
|
|
267
265
|
...lastResult,
|
|
268
266
|
stats: cumulativeStats(lastResult.stats),
|
|
269
|
-
terminal,
|
|
267
|
+
repairTerminal: terminal,
|
|
270
268
|
bundle,
|
|
271
269
|
...(isolationClass ? { isolationClass } : {}),
|
|
272
270
|
oracleCostMicroUsd,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RunInternals, RunnerSelfSeat } from "../core/runner/contracts.js";
|
|
2
2
|
import type { TaskSpec } from "../core/types.js";
|
|
3
|
-
import type { RunInternals } from "../core/runner/prepare-task.js";
|
|
4
3
|
/** design/122 D2 — per-child resume cap (default 8): a child can be revived at most this many times. */
|
|
5
4
|
export declare const SUBAGENT_RESUME_CAP = 8;
|
|
6
5
|
/**
|
|
@@ -25,7 +24,7 @@ export interface SubagentRetainEntry {
|
|
|
25
24
|
* resume.evicted, the 1.283 ruling). Lifetime: the entry's `release` closure already captures the same
|
|
26
25
|
* runner, so this adds no new retention class.
|
|
27
26
|
*/
|
|
28
|
-
runner?:
|
|
27
|
+
runner?: RunnerSelfSeat;
|
|
29
28
|
agentName?: string;
|
|
30
29
|
/** fix-C5: PER-ENTRY retain TTL override (ms). A SESSION-scoped ledger is shared by two purposes with
|
|
31
30
|
* different windows (failure-evidence retain = FAILED_SESSION_RETAIN_TTL_MS vs a session-scoped bg
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
|
-
import type {
|
|
2
|
+
import type { RunnerSelfSeat } from "../core/runner/contracts.js";
|
|
3
3
|
import type { TaskNotificationPayload } from "../core/task-notification.js";
|
|
4
4
|
import { type ToolCtxEnricher } from "../core/tools.js";
|
|
5
5
|
import { type TaskAccess } from "../core/task-registry.js";
|
|
@@ -12,7 +12,7 @@ import { type PeerAdmissionConfig, type PeerInboundChainRef, type PeerSelfRef }
|
|
|
12
12
|
export declare const SEND_MESSAGE_TOOL_NAME = "SendMessage";
|
|
13
13
|
export interface SendMessageToolOptions {
|
|
14
14
|
/** Runner used to execute the resumed child run (the design/122 resume face's delegation runner). */
|
|
15
|
-
runner:
|
|
15
|
+
runner: RunnerSelfSeat;
|
|
16
16
|
/** The unified task registry the background Agent lane registered its a* handles in. */
|
|
17
17
|
registry: import("../core/task-registry.js").TaskRegistry;
|
|
18
18
|
/** design/122 D1 — the parent run's retain ledger (present only when `TaskSpec.retainSubagentSessions`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RunnerSelfSeat } from "../core/runner/contracts.js";
|
|
2
2
|
/**
|
|
3
3
|
* Release a throwaway session, swallowing errors — best-effort cleanup for the verifier/cascade-rung
|
|
4
4
|
* sessions that agents spin up and discard. Always call this in a `finally` so a throwing `runTask`
|
|
5
5
|
* result handler or caller hook (`onRung`/`onRound`) can't leak the session.
|
|
6
6
|
*/
|
|
7
|
-
export declare function releaseSession(runner:
|
|
7
|
+
export declare function releaseSession(runner: RunnerSelfSeat, sessionId: string): Promise<void>;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { AgentDefinition, Model, ModelRef, TaskLimits, ToolSpec } from "../core/types.js";
|
|
1
|
+
import type { RunInternals, RunnerSelfSeat } from "../core/runner/contracts.js";
|
|
2
|
+
import type { AgentDefinition, Model, ModelRef, TaskLimits, TerminalCause, ToolSpec } from "../core/types.js";
|
|
3
3
|
import { type ExecutionEnv } from "../internal/harness.js";
|
|
4
|
-
import type { RunInternals } from "../core/runner/prepare-task.js";
|
|
5
4
|
import type { TaskNotificationPayload } from "../core/task-notification.js";
|
|
6
5
|
import { RETAIN_DEFAULT_TTL_MS, RETAIN_DEFAULT_MAX } from "../config/defaults.js";
|
|
7
6
|
/**
|
|
@@ -215,45 +214,28 @@ export declare function createSubagentWorktreeHelper(baseEnv: ExecutionEnv, repo
|
|
|
215
214
|
/** Cap for the inline-defused worker-controlled report metadata lines (blocked_reason / error). Matches the
|
|
216
215
|
* ask-question.ts inline-value convention (300) — a one-line operator-facing reason, not a bulk payload. */
|
|
217
216
|
export declare const REPORT_FIELD_MAX = 300;
|
|
218
|
-
/** The machine-readable failure class stamped on a FAILED sub-agent report (sema form — see below). */
|
|
219
|
-
export type SubagentErrorKind = "rate_limit" | "overloaded" | "timeout" | "network" | "logic" | "governance";
|
|
220
217
|
/**
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
* that wants to re-auth and retry.
|
|
241
|
-
*
|
|
242
|
-
* Classification (unchanged) — a FAILED child run into a coarse `error_kind` +
|
|
243
|
-
* `retryable` pair so the PARENT model (and an orchestrating deployment) can react correctly without
|
|
244
|
-
* string-matching the report: a `rate_limit`/`overloaded`/`timeout`/`network` failure is transient
|
|
245
|
-
* (re-delegating the same subtask may succeed); a `logic` failure is not (auth/invalid_request/budget/
|
|
246
|
-
* output.* — re-delegating unchanged just burns tokens). Derived from the EXISTING taxonomy: the
|
|
247
|
-
* child's `TaskResult.errorCode` (assemble-result's priority chain — brain `[code]` prefixes lifted
|
|
248
|
-
* via `extractErrorCode`, `limits.max_walltime_exceeded`, `budget.*`, …) plus a message sniff for the two classes our
|
|
249
|
-
* BrainError codes fold together ("server" covers overloaded_error/529 AND plain 5xx; "network"
|
|
250
|
-
* covers both timeouts and resets). Returns undefined for a non-failed child (no error to classify).
|
|
218
|
+
* The machine-readable failure class stamped on a FAILED sub-agent report (the Agent card's `error_kind`
|
|
219
|
+
* beside `retryable`). A sema form, not a CC one: CC's kind lives on an error class and gates
|
|
220
|
+
* partial-output handback, not retry; sema's pair answers the parent's one question — re-delegate or not.
|
|
221
|
+
* · `rate_limit` / `network` / `timeout` — transient (re-delegating the same subtask may succeed);
|
|
222
|
+
* · `governance` — a registered policy-plane refusal; retryability is the
|
|
223
|
+
* governance table's transient/terminal split;
|
|
224
|
+
* · `logic` — a coded failure re-delegating unchanged cannot fix
|
|
225
|
+
* (auth / invalid_request / http / output.* / budget axes);
|
|
226
|
+
* · `unknown` — the child reported NO code: nothing structural to classify,
|
|
227
|
+
* and the class is not guessed from the message (not retried).
|
|
228
|
+
*/
|
|
229
|
+
export declare const SUBAGENT_ERROR_KINDS: readonly ["rate_limit", "timeout", "network", "logic", "governance", "unknown"];
|
|
230
|
+
export type SubagentErrorKind = (typeof SUBAGENT_ERROR_KINDS)[number];
|
|
231
|
+
/**
|
|
232
|
+
* Classify a FAILED child run into its `error_kind` + `retryable` pair from the child's STRUCTURED
|
|
233
|
+
* terminal code alone (the `TerminalCause.failed.code` taxonomy: brain codes, `limits.*`, `budget.*`,
|
|
234
|
+
* governance codes). The message is never read: a class read out of prose moved when the prose moved,
|
|
235
|
+
* and a remote's own error text could steer it. A child with no code is `unknown`. Returns undefined
|
|
236
|
+
* for a non-failed child (no error to classify).
|
|
251
237
|
*/
|
|
252
|
-
export declare function classifySubagentError(
|
|
253
|
-
status: string;
|
|
254
|
-
errorCode?: string;
|
|
255
|
-
errorMessage?: string;
|
|
256
|
-
}): {
|
|
238
|
+
export declare function classifySubagentError(terminal: TerminalCause): {
|
|
257
239
|
errorKind: SubagentErrorKind;
|
|
258
240
|
retryable: boolean;
|
|
259
241
|
} | undefined;
|
|
@@ -315,13 +297,12 @@ export declare function classifySubagentError(child: {
|
|
|
315
297
|
export declare function completedAgentCard(child: {
|
|
316
298
|
taskId: string;
|
|
317
299
|
sessionId: string;
|
|
318
|
-
status
|
|
300
|
+
/** The child's terminal cause. The card speaks its projection (`status` + the failure-attribution keys), never the
|
|
301
|
+
* cause's own members: a paused token, or the pause a nested boundary wrapped on `nestedPause`, is the resume CAPABILITY. */
|
|
302
|
+
terminal: TerminalCause;
|
|
319
303
|
model?: string;
|
|
320
304
|
result: string;
|
|
321
305
|
salvagedOutput?: string;
|
|
322
|
-
blockedReason?: string;
|
|
323
|
-
errorMessage?: string;
|
|
324
|
-
errorCode?: string;
|
|
325
306
|
/** The child run's provider-boundary fault assertion, verbatim from its `TaskResult.apiFailure`.
|
|
326
307
|
* PRESENCE is the claim ("this child's terminal failure came from the transport/provider, not from
|
|
327
308
|
* this deployment refusing to send, a limit, or unusable model output"); the members are whatever
|
|
@@ -451,7 +432,7 @@ export declare function markerFragment(): string;
|
|
|
451
432
|
export declare function createSubagentResume(deps: {
|
|
452
433
|
ledger: SubagentRetainLedger | undefined;
|
|
453
434
|
parentToolCallId: string;
|
|
454
|
-
runner:
|
|
435
|
+
runner: RunnerSelfSeat;
|
|
455
436
|
notify?: (n: TaskNotificationPayload, opts?: {
|
|
456
437
|
priority?: "now" | "next" | "later";
|
|
457
438
|
}) => void;
|
|
@@ -634,7 +615,7 @@ export interface SubagentToolOptions {
|
|
|
634
615
|
* .jsonl` + a `.meta.json` sidecar), so "the child conversation is readable afterwards" is a
|
|
635
616
|
* property CC never makes conditional on a store tier.
|
|
636
617
|
*/
|
|
637
|
-
runner:
|
|
618
|
+
runner: RunnerSelfSeat;
|
|
638
619
|
/**
|
|
639
620
|
* design/115 P3 — background sub-agents (CC `run_in_background`). When set, the tool exposes the
|
|
640
621
|
* `run_in_background` parameter: the call returns an `a*` task_id immediately, the child runs
|