@sema-agent/core 7.33.8 → 7.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +462 -3
- package/dist/agents/cross-session-judge.d.ts +16 -7
- package/dist/agents/cross-session-judge.js +18 -15
- package/dist/agents/peer-session-drain.d.ts +4 -0
- package/dist/agents/peer-session-drain.js +5 -2
- package/dist/agents/repair-loop.d.ts +1 -1
- package/dist/agents/subagent.d.ts +3 -0
- package/dist/agents/subagent.js +12 -3
- package/dist/brain/anthropic.js +1 -0
- package/dist/brain/errors.d.ts +23 -1
- package/dist/brain/errors.js +19 -2
- package/dist/brain/open-responses.js +1 -0
- package/dist/brain/openai.js +1 -0
- package/dist/brain/status-sink.d.ts +7 -1
- package/dist/brain/stream-engine.d.ts +3 -0
- package/dist/brain/stream-engine.js +2 -1
- package/dist/brain/stream-shared.d.ts +3 -1
- package/dist/brain/stream-shared.js +16 -4
- package/dist/core/a2a.d.ts +3 -1
- package/dist/core/a2a.js +1 -1
- package/dist/core/ask-origin.d.ts +379 -154
- package/dist/core/ask-origin.js +224 -45
- package/dist/core/ask-question.js +2 -1
- package/dist/core/ask-unresolvable-notice.d.ts +5 -2
- package/dist/core/ask-unresolvable-notice.js +4 -3
- package/dist/core/auto-mode-arming.d.ts +17 -4
- package/dist/core/auto-mode-arming.js +31 -6
- package/dist/core/auto-mode-defaults.d.ts +16 -7
- package/dist/core/auto-mode-defaults.js +2 -1
- package/dist/core/auto-mode-directive.d.ts +18 -30
- package/dist/core/auto-mode-directive.js +9 -18
- package/dist/core/auto-mode-prompt.d.ts +62 -1
- package/dist/core/auto-mode-prompt.js +42 -4
- package/dist/core/auto-mode-rebuild.d.ts +2 -1
- package/dist/core/auto-mode-rebuild.js +1 -0
- package/dist/core/auto-mode.d.ts +32 -3
- package/dist/core/auto-mode.js +80 -41
- package/dist/core/checkpoint-store.d.ts +54 -35
- package/dist/core/checkpoint-store.js +58 -3
- package/dist/core/child-clamp-seats.js +1 -0
- package/dist/core/classifier-unavailable-arm.d.ts +57 -0
- package/dist/core/classifier-unavailable-arm.js +17 -0
- package/dist/core/effective-path-target.d.ts +12 -0
- package/dist/core/effective-path-target.js +18 -7
- package/dist/core/engine-notice.d.ts +53 -2
- package/dist/core/fs-write-gate-policy.d.ts +5 -1
- package/dist/core/fs-write-gate-policy.js +4 -1
- package/dist/core/gate-fold.js +19 -3
- package/dist/core/gate-lanes.js +116 -50
- package/dist/core/gate-outcome.d.ts +40 -7
- package/dist/core/gate-outcome.js +26 -4
- package/dist/core/governance-codes.d.ts +18 -2
- package/dist/core/governance-codes.js +23 -1
- package/dist/core/hooks.d.ts +53 -29
- package/dist/core/hooks.js +1 -3
- package/dist/core/mcp.js +1 -1
- package/dist/core/message-utils.d.ts +2 -1
- package/dist/core/message-utils.js +2 -1
- package/dist/core/mode-policy.d.ts +185 -0
- package/dist/core/mode-policy.js +184 -0
- package/dist/core/oracle-isolation.d.ts +3 -3
- package/dist/core/permission-rule-model.d.ts +20 -3
- package/dist/core/permission-rule-model.js +40 -3
- package/dist/core/permission-rule-provider.d.ts +22 -11
- package/dist/core/permission-rule-provider.js +17 -7
- package/dist/core/permission-rules.d.ts +23 -1
- package/dist/core/permission-rules.js +56 -9
- package/dist/core/persisted-rule-arms.d.ts +14 -10
- package/dist/core/persisted-rule-arms.js +13 -6
- package/dist/core/present-plan-tool.d.ts +1 -1
- package/dist/core/present-plan-tool.js +3 -3
- package/dist/core/read-only-shell.d.ts +19 -19
- package/dist/core/read-only-shell.js +38 -12
- package/dist/core/retired-keys.d.ts +9 -3
- package/dist/core/retired-keys.js +5 -1
- package/dist/core/runner/active-skill-scope.js +5 -4
- package/dist/core/runner/assemble-result.js +2 -2
- package/dist/core/runner/classifier-ladder.d.ts +43 -1
- package/dist/core/runner/classifier-ladder.js +29 -0
- package/dist/core/runner/contracts.d.ts +62 -38
- package/dist/core/runner/denial-limit-arms.d.ts +35 -7
- package/dist/core/runner/denial-limit-arms.js +15 -9
- package/dist/core/runner/env-capability-census.js +1 -1
- package/dist/core/runner/file-history-request.d.ts +26 -0
- package/dist/core/runner/file-history-request.js +90 -0
- package/dist/core/runner/gate-exit.d.ts +30 -4
- package/dist/core/runner/gate-exit.js +28 -7
- package/dist/core/runner/permission-rule-lanes.d.ts +11 -6
- package/dist/core/runner/permission-rule-lanes.js +55 -48
- package/dist/core/runner/persisted-path-rows.d.ts +64 -0
- package/dist/core/runner/persisted-path-rows.js +89 -0
- package/dist/core/runner/prepare-artifact.d.ts +5 -1
- package/dist/core/runner/prepare-artifact.js +9 -3
- package/dist/core/runner/prepare-ask-lane.d.ts +6 -4
- package/dist/core/runner/prepare-ask-lane.js +3 -3
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +39 -13
- package/dist/core/runner/prepare-caps-and-workflow.js +58 -29
- package/dist/core/runner/prepare-file-history.d.ts +9 -3
- package/dist/core/runner/prepare-file-history.js +4 -90
- package/dist/core/runner/prepare-gate-stations.d.ts +37 -9
- package/dist/core/runner/prepare-gate-stations.js +46 -29
- package/dist/core/runner/prepare-hands-readface.d.ts +40 -17
- package/dist/core/runner/prepare-hands-readface.js +64 -53
- package/dist/core/runner/prepare-inherited-gate.d.ts +30 -23
- package/dist/core/runner/prepare-inherited-gate.js +45 -25
- package/dist/core/runner/prepare-park-ask.d.ts +6 -4
- package/dist/core/runner/prepare-park-ask.js +7 -5
- package/dist/core/runner/prepare-policy-chain.d.ts +25 -4
- package/dist/core/runner/prepare-policy-chain.js +203 -180
- package/dist/core/runner/prepare-protocol-tools.d.ts +28 -0
- package/dist/core/runner/prepare-protocol-tools.js +13 -3
- package/dist/core/runner/prepare-run-refs.d.ts +6 -6
- package/dist/core/runner/prepare-run-refs.js +9 -4
- package/dist/core/runner/prepare-safety-scan.d.ts +5 -0
- package/dist/core/runner/prepare-safety-scan.js +19 -3
- package/dist/core/runner/prepare-suspend-saga.d.ts +5 -5
- package/dist/core/runner/prepare-suspend-saga.js +6 -6
- package/dist/core/runner/prepare-task.js +56 -24
- package/dist/core/runner/prepare-wiring-manifest.d.ts +10 -6
- package/dist/core/runner/prepare-wiring-manifest.js +5 -3
- package/dist/core/runner/read-root-grant.d.ts +9 -0
- package/dist/core/runner/read-root-grant.js +12 -0
- package/dist/core/runner/retired-runner-deps.js +1 -0
- package/dist/core/runner/run-brain-sinks.js +3 -1
- package/dist/core/runner/run-identity-wiring.js +1 -1
- package/dist/core/runner/run-leg.js +29 -18
- package/dist/core/runner/run-notification-lane.d.ts +3 -0
- package/dist/core/runner/run-notification-lane.js +3 -1
- package/dist/core/runner/run-telemetry-and-budget-seats.d.ts +2 -2
- package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
- package/dist/core/runner/run-turn-boundary.js +1 -1
- package/dist/core/runner/runtask.d.ts +1 -0
- package/dist/core/runner/runtask.js +8 -11
- package/dist/core/runner/session-mode-seats.d.ts +48 -0
- package/dist/core/runner/session-mode-seats.js +73 -0
- package/dist/core/runner/session-rule-policy.js +3 -2
- package/dist/core/runner/stream-mode-verb.d.ts +27 -0
- package/dist/core/runner/stream-mode-verb.js +19 -0
- package/dist/core/runner/turn-attachments.d.ts +3 -3
- package/dist/core/runner/turn-attachments.js +1 -1
- package/dist/core/runner/write-protection-station.d.ts +7 -1
- package/dist/core/runner/write-protection-station.js +6 -3
- package/dist/core/runner-deps.d.ts +31 -34
- package/dist/core/runtime-caps.d.ts +12 -3
- package/dist/core/safety-axis-vocab.d.ts +2 -2
- package/dist/core/safety-axis-vocab.js +1 -1
- package/dist/core/secret-env.d.ts +30 -58
- package/dist/core/secret-env.js +149 -586
- package/dist/core/sensitive-path-policy.d.ts +4 -2
- package/dist/core/sensitive-path-policy.js +41 -31
- package/dist/core/store-contracts/checkpoint-store-contract.js +2 -1
- package/dist/core/task-event.d.ts +1 -1
- package/dist/core/task-result.d.ts +1 -1
- package/dist/core/task-spec.d.ts +41 -89
- package/dist/core/task-stream.d.ts +16 -0
- package/dist/core/terminal-cause.js +1 -0
- package/dist/core/tighten-task-spec.d.ts +2 -2
- package/dist/core/tighten-task-spec.js +12 -14
- package/dist/core/tool-catalog-entries.js +4 -3
- package/dist/core/tool-policy.d.ts +84 -30
- package/dist/core/tool-policy.js +76 -16
- package/dist/core/tool-registry.d.ts +38 -0
- package/dist/core/tool-registry.js +25 -1
- package/dist/core/tool-roster.d.ts +17 -2
- package/dist/core/tool-roster.js +11 -1
- package/dist/core/tool-spec.d.ts +8 -9
- package/dist/core/trace.d.ts +18 -6
- package/dist/core/types.d.ts +2 -1
- package/dist/core/wiring-manifest.d.ts +31 -5
- package/dist/core/wiring-manifest.js +28 -1
- package/dist/core/write-protect.d.ts +11 -1
- package/dist/core/write-protect.js +26 -15
- package/dist/engine/execution-env/node-execution-env.d.ts +6 -1
- package/dist/engine/execution-env/node-execution-env.js +16 -3
- package/dist/engine/harness/agent-harness.js +2 -1
- package/dist/engine/harness/types.d.ts +6 -7
- package/dist/engine/llm/types.d.ts +2 -4
- package/dist/engine/loop/types.d.ts +7 -0
- package/dist/engine/lsp/node-lsp-manager.js +1 -1
- package/dist/index.d.ts +18 -8
- package/dist/index.js +15 -6
- package/dist/orchestration/workflow-governance.js +1 -1
- package/dist/orchestration/workflow-primitives.d.ts +1 -1
- package/dist/orchestration/workflow-size-guideline.js +2 -2
- package/dist/stores/file/index.d.ts +5 -3
- package/dist/stores/file/session-store.d.ts +8 -2
- package/dist/stores/file/session-store.js +5 -5
- package/dist/tools/artifact/artifact-tool.d.ts +17 -0
- package/dist/tools/artifact/artifact-tool.js +16 -1
- package/dist/tools/fs/bash-readonly-classifier.d.ts +28 -7
- package/dist/tools/fs/bash-readonly-classifier.js +88 -0
- package/dist/tools/fs/containment-face.d.ts +9 -3
- package/dist/tools/fs/containment-face.js +2 -0
- package/dist/tools/fs/file-read-check.d.ts +50 -0
- package/dist/tools/fs/file-read-check.js +79 -0
- package/dist/tools/fs/fs-bash.d.ts +3 -3
- package/dist/tools/fs/fs-read.d.ts +1 -0
- package/dist/tools/fs/fs-search-tools.d.ts +2 -2
- package/dist/tools/fs/fs-search-tools.js +4 -4
- package/dist/tools/fs/fs-shared.js +20 -6
- package/dist/tools/fs/fs-write.d.ts +4 -3
- package/dist/tools/fs/fs-write.js +9 -9
- package/dist/tools/fs/index.d.ts +39 -3
- package/dist/tools/fs/index.js +38 -15
- package/dist/tools/fs/read-deny-home.d.ts +93 -0
- package/dist/tools/fs/read-deny-home.js +225 -0
- package/dist/tools/fs/read-deny.d.ts +176 -34
- package/dist/tools/fs/read-deny.js +268 -61
- package/dist/tools/fs/safety.d.ts +6 -1
- package/dist/tools/fs/safety.js +18 -5
- package/dist/tools/fs/search.d.ts +3 -0
- package/dist/tools/fs/search.js +47 -9
- package/dist/tools/fs/shell-read-check.d.ts +52 -13
- package/dist/tools/fs/shell-read-check.js +199 -20
- package/dist/tools/fs/shell-read-establish.d.ts +7 -3
- package/dist/tools/fs/shell-read-establish.js +134 -21
- package/dist/tools/fs/shell-read-identity.d.ts +7 -0
- package/dist/tools/fs/shell-read-identity.js +21 -0
- package/dist/tools/fs/shell-read-judge.d.ts +92 -32
- package/dist/tools/fs/shell-read-judge.js +43 -18
- package/dist/tools/fs/shell-read-plan.d.ts +4 -0
- package/dist/tools/fs/shell-read-plan.js +26 -4
- package/dist/tools/fs/shell-read-write-targets.d.ts +73 -0
- package/dist/tools/fs/shell-read-write-targets.js +173 -0
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +117 -11
- package/wire-changes/core@7.34.0.json +2621 -0
- package/wire-changes/core@7.35.0.json +584 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { AskEffective } from "../core/wiring-manifest.js";
|
|
2
2
|
import { type PermissionModeClass } from "./cross-session-envelope.js";
|
|
3
|
+
/** The permission-mode words the fold reads (the engine's closed set, as the wire spells it). */
|
|
4
|
+
import type { PermissionMode } from "../core/ask-origin.js";
|
|
3
5
|
/**
|
|
4
6
|
* The explicit values of `crossSessionInbound`, loosest first: `wake` (deliver, and the HOST may start
|
|
5
7
|
* a turn on this session when its box grows), `next-turn` (deliver at the session's next turn
|
|
@@ -100,14 +102,21 @@ export interface CrossSessionInboundInput {
|
|
|
100
102
|
*/
|
|
101
103
|
export declare function judgeCrossSessionInbound(input: CrossSessionInboundInput): CrossSessionInboundVerdict;
|
|
102
104
|
/**
|
|
103
|
-
* design/385 §4.4 — sema's two-class fold of its own permission posture,
|
|
104
|
-
* the
|
|
105
|
-
*
|
|
106
|
-
* `
|
|
107
|
-
*
|
|
108
|
-
*
|
|
105
|
+
* design/385 §4.4 — sema's two-class fold of its own permission posture, from the session's EFFECTIVE
|
|
106
|
+
* permission mode (the engine's own resolution — never the requested one, never re-derived from spec shape)
|
|
107
|
+
* and the wiring manifest's ask derivation ({@link AskEffective}):
|
|
108
|
+
* · `bypass` — the effective mode is `bypassPermissions`, OR no human decides an ask (`auto_allow`, a
|
|
109
|
+
* blanket answering seat — the adapter's own reading of "nobody is watching");
|
|
110
|
+
* · `"unknown"` — otherwise, when the ask derivation is `unresolved` (the judge fails closed on it);
|
|
111
|
+
* · `prompting` — otherwise: an ask reaches a human or parks for one (`human_reachable`, `park_only`),
|
|
112
|
+
* and — CC's literal rule for a never-prompting-never-bypassing mode — `auto_deny`.
|
|
113
|
+
* `effective` absent (a leg with no mode fact) reads the ask derivation alone.
|
|
114
|
+
*
|
|
115
|
+
* WHAT THE CLASS IS: `fromMode` is a presence LABEL — whether a person is watching this session's approvals —
|
|
116
|
+
* attested to a peer so a bypass session does not park work where nobody watches. It is not a permission
|
|
117
|
+
* authority and authorizes no execution; the permission mode itself is read only from `effective`.
|
|
109
118
|
*/
|
|
110
|
-
export declare function foldPermissionModeClass(askEffective: AskEffective): PermissionModeClass | "unknown";
|
|
119
|
+
export declare function foldPermissionModeClass(effective: PermissionMode | undefined, askEffective: AskEffective): PermissionModeClass | "unknown";
|
|
111
120
|
/** The synchronous send outcomes a sender can observe at the send point (CC's ten classes on sema's
|
|
112
121
|
* codes; `sender_paced` is expressed by the admission gate's `rate_limited` and is deliberately not a
|
|
113
122
|
* second code). `parked_offline` is a DISPOSITION (durable append succeeded, recipient offline) and
|
|
@@ -154,22 +154,25 @@ export function judgeCrossSessionInbound(input) {
|
|
|
154
154
|
}
|
|
155
155
|
return selfModeClass === "bypass" ? holdFor("no-mode-asserted") : { verdict: "deliver" };
|
|
156
156
|
}
|
|
157
|
-
export function foldPermissionModeClass(askEffective) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
157
|
+
export function foldPermissionModeClass(effective, askEffective) {
|
|
158
|
+
const byAsk = (() => {
|
|
159
|
+
switch (askEffective) {
|
|
160
|
+
case "auto_allow":
|
|
161
|
+
return "bypass";
|
|
162
|
+
case "human_reachable":
|
|
163
|
+
case "park_only":
|
|
164
|
+
case "auto_deny":
|
|
165
|
+
return "prompting";
|
|
166
|
+
case "unresolved":
|
|
167
|
+
return "unknown";
|
|
168
|
+
default: {
|
|
169
|
+
const _exhaustive = askEffective;
|
|
170
|
+
void _exhaustive;
|
|
171
|
+
throw new Error(`unreachable ask effective ${String(askEffective)}`);
|
|
172
|
+
}
|
|
171
173
|
}
|
|
172
|
-
}
|
|
174
|
+
})();
|
|
175
|
+
return effective === "bypassPermissions" ? "bypass" : byAsk;
|
|
173
176
|
}
|
|
174
177
|
export const PEER_SEND_VERDICT_CODES = Object.freeze([
|
|
175
178
|
"peer_send.stale_socket",
|
|
@@ -7,6 +7,7 @@ import { type CrossSessionInboundSettingLayers } from "./cross-session-judge.js"
|
|
|
7
7
|
import { type PeerLaneConfig } from "./peer-admission.js";
|
|
8
8
|
import { type PeerDirectory } from "./peer-directory.js";
|
|
9
9
|
import { createListAgentsTool } from "./list-agents-tool.js";
|
|
10
|
+
import { foldPermissionModeClass } from "./cross-session-judge.js";
|
|
10
11
|
import type { AskEffective } from "../core/wiring-manifest.js";
|
|
11
12
|
import type { SendMessageToolOptions } from "./send-message-tool.js";
|
|
12
13
|
import { type PeerClock, type PeerHeldQueue } from "./peer-held-queue.js";
|
|
@@ -175,6 +176,9 @@ export declare function createPeerSessionDrain(opts: PeerSessionDrainOptions): P
|
|
|
175
176
|
* before it — both read this one cell. */
|
|
176
177
|
export interface PeerLaneRefs {
|
|
177
178
|
askEffective?: AskEffective;
|
|
179
|
+
/** The session's EFFECTIVE permission mode, read live (it follows a mid-run mode change); absent on a leg
|
|
180
|
+
* that carries no mode fact. Paired with `askEffective` in the one mode-class fold. */
|
|
181
|
+
permissionMode?: () => Parameters<typeof foldPermissionModeClass>[0];
|
|
178
182
|
/** The bound drain's pull face (filled by {@link bindPeerLaneDrain}); the `ReadInbox` tool reads it late. */
|
|
179
183
|
pull?: (limit?: number, toolCallId?: string, charBudget?: number) => Promise<PulledInbox>;
|
|
180
184
|
/** #1036 — the bound drain's BOUNDARY pass (filled by {@link bindPeerLaneDrain}); the leg's
|
|
@@ -655,6 +655,9 @@ export function createPeerSessionDrain(opts) {
|
|
|
655
655
|
idleMachine,
|
|
656
656
|
};
|
|
657
657
|
}
|
|
658
|
+
function peerModeClassOf(refs) {
|
|
659
|
+
return refs.askEffective !== undefined ? foldPermissionModeClass(refs.permissionMode?.(), refs.askEffective) : "unknown";
|
|
660
|
+
}
|
|
658
661
|
export function announcePeerLaneMount(deps, leg) {
|
|
659
662
|
const verdict = judgePeerLaneMount(deps, leg.sessionId);
|
|
660
663
|
if (verdict === undefined)
|
|
@@ -676,7 +679,7 @@ export function peerLaneSendMessageSeats(args) {
|
|
|
676
679
|
sessionId: args.sessionId,
|
|
677
680
|
scope: args.scope,
|
|
678
681
|
...(args.name !== undefined ? { name: args.name } : {}),
|
|
679
|
-
modeClass: () => (args.refs
|
|
682
|
+
modeClass: () => peerModeClassOf(args.refs),
|
|
680
683
|
},
|
|
681
684
|
};
|
|
682
685
|
}
|
|
@@ -753,7 +756,7 @@ export function bindPeerLaneDrain(harness, args) {
|
|
|
753
756
|
...(deps.peerLane !== undefined ? { lane: deps.peerLane } : {}),
|
|
754
757
|
ownTokens: args.ownTokens,
|
|
755
758
|
settingLayers: () => (typeof deps.crossSessionInbound === "function" ? deps.crossSessionInbound() : deps.crossSessionInbound),
|
|
756
|
-
selfModeClass: () => (args.refs
|
|
759
|
+
selfModeClass: () => peerModeClassOf(args.refs),
|
|
757
760
|
dialogExpiry: () => (typeof deps.crossSessionDialogExpiry === "function" ? deps.crossSessionDialogExpiry() : deps.crossSessionDialogExpiry),
|
|
758
761
|
selfName: () => rowName ?? args.selfName?.(),
|
|
759
762
|
warmup: lookupRowName,
|
|
@@ -142,7 +142,7 @@ export interface RepairLoopConfig {
|
|
|
142
142
|
* instead of the bare reference-identity check, and surfaces {@link RepairResult.isolationClass}. Omit it (the
|
|
143
143
|
* default) to keep the existing necessary-not-sufficient reference-identity check (the merged Slice-1 posture).
|
|
144
144
|
*
|
|
145
|
-
* The real isolated grader env is SERVICE-provided (
|
|
145
|
+
* The real isolated grader env is SERVICE-provided (the trusted control plane mints it; the engine has no seat for it);
|
|
146
146
|
* `graderEnv` here is its `.env`, and the control-plane `provenance` brand is reattached internally for the
|
|
147
147
|
* assertion. The assertion only matters for the (mandate-OFF) auto-accept path: `isolationClass` caps a
|
|
148
148
|
* non-`out_of_process` grader at `candidate_only`. SAFE-tier never auto-accepts regardless.
|
|
@@ -210,6 +210,9 @@ export interface SubagentWorktreeIsolation {
|
|
|
210
210
|
* parent's own (possibly factory-owned) env.
|
|
211
211
|
*/
|
|
212
212
|
export declare function createSubagentWorktreeHelper(baseEnv: ExecutionEnv, repoRoot: string): SubagentWorktreeIsolation;
|
|
213
|
+
/** Names an `AgentDefinition.name` must not collide with (would confuse the enum vs a real tool name). Includes the
|
|
214
|
+
* default delegation tool name itself, so a child agent can't be named "Agent" even when a custom `opts.name` is set. */
|
|
215
|
+
export declare const RESERVED_AGENT_NAMES: ReadonlySet<string>;
|
|
213
216
|
/** Cap for the inline-defused worker-controlled report metadata lines (blocked_reason / error). Matches the
|
|
214
217
|
* ask-question.ts inline-value convention (300) — a one-line operator-facing reason, not a bulk payload. */
|
|
215
218
|
export declare const REPORT_FIELD_MAX = 300;
|
package/dist/agents/subagent.js
CHANGED
|
@@ -350,7 +350,7 @@ function resumabilityClaim(f) {
|
|
|
350
350
|
return f.durableRow && f.named;
|
|
351
351
|
}
|
|
352
352
|
const BG_AGENT_COLLATERAL_REAP_REASON = "its parent run ended";
|
|
353
|
-
const RESERVED_AGENT_NAMES = new Set([OUTPUT_TOOL_NAME, TOOL_SEARCH_NAME, OFFLOAD_TOOL_NAME, REPORT_BLOCKED_TOOL_NAME, DEFAULT_SUBAGENT_TOOL_NAME]);
|
|
353
|
+
export const RESERVED_AGENT_NAMES = new Set([OUTPUT_TOOL_NAME, TOOL_SEARCH_NAME, OFFLOAD_TOOL_NAME, REPORT_BLOCKED_TOOL_NAME, DEFAULT_SUBAGENT_TOOL_NAME]);
|
|
354
354
|
export const REPORT_FIELD_MAX = 300;
|
|
355
355
|
const ROSTER_ECHO_MAX = 400;
|
|
356
356
|
function configError(message, code) {
|
|
@@ -1930,8 +1930,17 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
|
|
|
1930
1930
|
if (!isObserverTaskId(sid))
|
|
1931
1931
|
throw new ObserverStoppedByUserError("observer identity revoked — delivery refused");
|
|
1932
1932
|
const pickedRef = observerModelPick().modelRef;
|
|
1933
|
-
const
|
|
1934
|
-
|
|
1933
|
+
const parentGate = ctx.inheritedGateForChildren?.();
|
|
1934
|
+
const observerGate = parentGate === undefined
|
|
1935
|
+
? undefined
|
|
1936
|
+
: {
|
|
1937
|
+
...(parentGate.permissionMode !== undefined ? { permissionMode: parentGate.permissionMode } : {}),
|
|
1938
|
+
...(parentGate.permissionModeCeiling !== undefined ? { permissionModeCeiling: parentGate.permissionModeCeiling } : {}),
|
|
1939
|
+
...(parentGate.shellGate !== undefined ? { shellGate: parentGate.shellGate } : {}),
|
|
1940
|
+
admittedOrgScopes: parentGate.admittedOrgScopes,
|
|
1941
|
+
};
|
|
1942
|
+
const observerInternals = ctx.interactionPosture !== undefined || pickedRef !== undefined || observerGate !== undefined
|
|
1943
|
+
? { ...(ctx.interactionPosture !== undefined ? { parentInteractionPosture: ctx.interactionPosture } : {}), ...(pickedRef !== undefined ? { inheritedModelRef: pickedRef } : {}), ...(observerGate !== undefined ? { inheritedGate: observerGate } : {}) }
|
|
1935
1944
|
: undefined;
|
|
1936
1945
|
const r = await opts.runner.runTask(spec, observerInternals);
|
|
1937
1946
|
if (r.terminal.kind !== "completed") {
|
package/dist/brain/anthropic.js
CHANGED
|
@@ -240,6 +240,7 @@ export function createAnthropicBrain(config = {}) {
|
|
|
240
240
|
signal: options?.signal,
|
|
241
241
|
config,
|
|
242
242
|
httpLabel: "anthropic",
|
|
243
|
+
maxRetries: options?.maxRetries,
|
|
243
244
|
stallTimeouts: options?.stallTimeouts,
|
|
244
245
|
buildRequest: (overrides) => {
|
|
245
246
|
const root = resolveRequestRoot(model.baseUrl, config.baseUrl, "https://api.anthropic.com");
|
package/dist/brain/errors.d.ts
CHANGED
|
@@ -70,11 +70,33 @@ export declare class BrainError extends Error {
|
|
|
70
70
|
apiError?: boolean;
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* The shape a provider ECHO field must have to be carried: the request id a provider states on a response
|
|
75
|
+
* header (`AssistantMessage.requestId`, projected as `TaskResult.apiFailure.requestId`) and the model name it
|
|
76
|
+
* reports answering (`AssistantMessage.responseModel`). Both are UPSTREAM BYTES that end up persisted in a
|
|
77
|
+
* transcript and rendered by a UI, so one alphabet governs both: visible ASCII (0x21–0x7E — no space, no
|
|
78
|
+
* control byte, no non-ASCII), 1–128 characters. A value outside it is dropped (the field is absent), never
|
|
79
|
+
* truncated or rewritten; the empty string is outside it. No flags, so `test` is stateless. This object is the
|
|
80
|
+
* consumer's copy: the engine judges with its own instance built from the same source, so recompiling or
|
|
81
|
+
* otherwise mutating this one cannot change what the engine admits.
|
|
82
|
+
*/
|
|
83
|
+
export declare const PROVIDER_ECHO_SHAPE: RegExp;
|
|
84
|
+
/** Does `value` fit {@link PROVIDER_ECHO_SHAPE}? A non-string answers `false` (a JS caller's number is not an echo). */
|
|
85
|
+
export declare function isProviderEchoShape(value: string): boolean;
|
|
86
|
+
/** How the brains read one provider echo value: a non-string or the empty string states nothing (`absent` — no field,
|
|
87
|
+
* nothing counted); a string in {@link isProviderEchoShape} is `carried`; any other string is `refused` (dropped and
|
|
88
|
+
* counted as `echo_dropped`). */
|
|
89
|
+
export declare function providerEchoReading(value: unknown): "absent" | "carried" | "refused";
|
|
73
90
|
/**
|
|
74
91
|
* Lift the provider's own request identifier off a response, when it stated one in a shape worth
|
|
75
|
-
* carrying (
|
|
92
|
+
* carrying ({@link isProviderEchoShape}). This is the handle a provider's support channel asks for, and
|
|
76
93
|
* without it a failed turn's only evidence is prose the operator cannot correlate upstream.
|
|
77
94
|
*
|
|
95
|
+
* A response whose header values were all refused by the shape yields no id and one `echo_dropped`
|
|
96
|
+
* telemetry event (`field: "requestId"`, bridged to the `brain.echo_dropped` trace frame) — one per
|
|
97
|
+
* response, whichever header was refused; a response that states no id at all (no header, or an empty one:
|
|
98
|
+
* {@link providerEchoReading}) yields none.
|
|
99
|
+
*
|
|
78
100
|
* Duck-typed on `headers.get` rather than requiring a real `Response`: the engine's transport is a
|
|
79
101
|
* caller-injected `fetch`, so a deployment (or a test) may hand back any response-shaped object, and
|
|
80
102
|
* a missing/throwing header bag must degrade to "no id" instead of failing the call it is describing.
|
package/dist/brain/errors.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isErrorLike, readMember, thrownText } from "../core/thrown-value.js";
|
|
2
|
+
import { emitBrainTelemetry } from "./status-sink.js";
|
|
2
3
|
export const ZERO_USAGE = {
|
|
3
4
|
input: 0,
|
|
4
5
|
output: 0,
|
|
@@ -30,20 +31,36 @@ export class BrainError extends Error {
|
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
const REQUEST_ID_HEADERS = ["request-id", "x-request-id"];
|
|
33
|
-
const
|
|
34
|
+
const PROVIDER_ECHO_SOURCE = "^[\\x21-\\x7E]{1,128}$";
|
|
35
|
+
const providerEchoShape = new RegExp(PROVIDER_ECHO_SOURCE);
|
|
36
|
+
export const PROVIDER_ECHO_SHAPE = new RegExp(PROVIDER_ECHO_SOURCE);
|
|
37
|
+
export function isProviderEchoShape(value) {
|
|
38
|
+
return typeof value === "string" && providerEchoShape.test(value);
|
|
39
|
+
}
|
|
40
|
+
export function providerEchoReading(value) {
|
|
41
|
+
if (typeof value !== "string" || value.length === 0)
|
|
42
|
+
return "absent";
|
|
43
|
+
return isProviderEchoShape(value) ? "carried" : "refused";
|
|
44
|
+
}
|
|
34
45
|
export function readProviderRequestId(res) {
|
|
46
|
+
let refused = false;
|
|
35
47
|
try {
|
|
36
48
|
const get = res?.headers?.get;
|
|
37
49
|
if (typeof get !== "function")
|
|
38
50
|
return undefined;
|
|
39
51
|
for (const name of REQUEST_ID_HEADERS) {
|
|
40
52
|
const raw = get.call(res.headers, name);
|
|
41
|
-
|
|
53
|
+
const reading = providerEchoReading(raw);
|
|
54
|
+
if (reading === "carried")
|
|
42
55
|
return raw;
|
|
56
|
+
if (reading === "refused")
|
|
57
|
+
refused = true;
|
|
43
58
|
}
|
|
44
59
|
}
|
|
45
60
|
catch {
|
|
46
61
|
}
|
|
62
|
+
if (refused)
|
|
63
|
+
emitBrainTelemetry({ kind: "echo_dropped", field: "requestId" });
|
|
47
64
|
return undefined;
|
|
48
65
|
}
|
|
49
66
|
export function namesTheFailure(status) {
|
|
@@ -234,6 +234,7 @@ export function createOpenResponsesBrain(config = {}) {
|
|
|
234
234
|
signal: options?.signal,
|
|
235
235
|
config,
|
|
236
236
|
httpLabel: "responses",
|
|
237
|
+
maxRetries: options?.maxRetries,
|
|
237
238
|
stallTimeouts: options?.stallTimeouts,
|
|
238
239
|
buildRequest: (overrides) => {
|
|
239
240
|
const root = resolveRequestRoot(model.baseUrl, config.baseUrl);
|
package/dist/brain/openai.js
CHANGED
|
@@ -297,6 +297,7 @@ export function createOpenAIBrain(config = {}) {
|
|
|
297
297
|
signal: options?.signal,
|
|
298
298
|
config,
|
|
299
299
|
httpLabel: "gateway",
|
|
300
|
+
maxRetries: options?.maxRetries,
|
|
300
301
|
stallTimeouts: options?.stallTimeouts,
|
|
301
302
|
buildRequest: (overrides) => {
|
|
302
303
|
const root = resolveRequestRoot(model.baseUrl, config.baseUrl);
|
|
@@ -31,7 +31,7 @@ export declare function emitBrainStatus(status: BrainStatus): void;
|
|
|
31
31
|
* Silent-fallback telemetry (C1/C4/C5/C6) — the brain→runner TELEMETRY channel, a
|
|
32
32
|
* SECOND ALS sink parallel to the status one. Statuses are user-facing liveness frames (wire
|
|
33
33
|
* `status` events); telemetry is operator-facing fallback accounting the Runner bridges to trace
|
|
34
|
-
* events (`brain.failover` / `breaker.transition` / `brain.retry` / `vision.placeholder`). Kept
|
|
34
|
+
* events (`brain.failover` / `breaker.transition` / `brain.retry` / `vision.placeholder` / `brain.echo_dropped`). Kept
|
|
35
35
|
* separate so widening telemetry never bloats the shell-visible status vocabulary. Same contract:
|
|
36
36
|
* fire-and-forget, no-op outside a {@link runWithBrainTelemetry} scope, MUST NOT throw.
|
|
37
37
|
*/
|
|
@@ -66,6 +66,12 @@ export type BrainTelemetry = {
|
|
|
66
66
|
| {
|
|
67
67
|
kind: "document_placeholder";
|
|
68
68
|
count: number;
|
|
69
|
+
}
|
|
70
|
+
/** A provider echo field ({@link import("./errors.js").PROVIDER_ECHO_SHAPE}) refused by its shape: the value was dropped
|
|
71
|
+
* and the field is absent. One event per provider response per field. */
|
|
72
|
+
| {
|
|
73
|
+
kind: "echo_dropped";
|
|
74
|
+
field: "requestId" | "responseModel";
|
|
69
75
|
};
|
|
70
76
|
/** Run `fn` with a per-task brain-telemetry sink in scope (Runner-side; compose with runWithStatusSink). */
|
|
71
77
|
export declare function runWithBrainTelemetry<T>(emit: (t: BrainTelemetry) => void, fn: () => Promise<T>): Promise<T>;
|
|
@@ -243,4 +243,7 @@ export declare function runStreamingBrain(args: {
|
|
|
243
243
|
firstTokenMs?: number;
|
|
244
244
|
idleMs?: number;
|
|
245
245
|
};
|
|
246
|
+
/** Per-call CAP on the transient retry budget (`StreamOptions.maxRetries`): the call retries at most this many times
|
|
247
|
+
* and never more than the brain's own budget ({@link resolveMaxRetries}); a non-finite or negative value caps nothing. */
|
|
248
|
+
maxRetries?: number;
|
|
246
249
|
}): ReturnType<typeof createAssistantMessageEventStream>;
|
|
@@ -265,6 +265,7 @@ function firstByteTimeoutMessage(windowsMs) {
|
|
|
265
265
|
}
|
|
266
266
|
export function runStreamingBrain(args) {
|
|
267
267
|
const { model, doFetch, signal, config, httpLabel, buildRequest, makeParser, stallTimeouts } = args;
|
|
268
|
+
const callRetryCap = args.maxRetries !== undefined && Number.isFinite(args.maxRetries) && args.maxRetries >= 0 ? Math.floor(args.maxRetries) : Infinity;
|
|
268
269
|
const out = createAssistantMessageEventStream();
|
|
269
270
|
let cleanup;
|
|
270
271
|
let announcedRetry = false;
|
|
@@ -326,7 +327,7 @@ export function runStreamingBrain(args) {
|
|
|
326
327
|
let req = buildRequest();
|
|
327
328
|
req.onCommitted?.();
|
|
328
329
|
let maxOutputTokensOverride;
|
|
329
|
-
const maxRetries = resolveMaxRetries(config.maxRetries);
|
|
330
|
+
const maxRetries = Math.min(resolveMaxRetries(config.maxRetries), callRetryCap);
|
|
330
331
|
const baseDelay = config.retryDelayMs ?? 500;
|
|
331
332
|
const deterministicConnectBudget = Math.min(resolveDeterministicConnectRetries(config.deterministicConnectRetries), maxRetries);
|
|
332
333
|
const deterministicLaneActive = deterministicConnectBudget < maxRetries;
|
|
@@ -47,7 +47,9 @@ export declare function createRepetitionPoll(): RepetitionPoll;
|
|
|
47
47
|
* message every lane spreads `...partial` into) — ONE rule for the three lanes' spellings (`chunk.model` /
|
|
48
48
|
* `message_start.message.model` / `response.model`), WRITE twin of `providerReportedModel`
|
|
49
49
|
* (`core/message-utils.ts`). The LAST frame that NAMES a model decides and the seat carries it only when it
|
|
50
|
-
* differs; naming nothing
|
|
50
|
+
* differs; naming nothing (no name, or the empty string — {@link providerEchoReading}) is not an update, naming the
|
|
51
|
+
* REQUESTED id RETRACTS an earlier substitution. A name outside {@link isProviderEchoShape} is dropped — not an
|
|
52
|
+
* update — and counted once per response (`echo_dropped`, `field: "responseModel"`). */
|
|
51
53
|
export declare function noteResponseModel(partial: {
|
|
52
54
|
responseModel?: string;
|
|
53
55
|
}, reported: unknown, requestedId: string): void;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { isProviderEchoShape, providerEchoReading } from "./errors.js";
|
|
1
2
|
import { inspectDegenerate } from "./repetition.js";
|
|
3
|
+
import { emitBrainTelemetry } from "./status-sink.js";
|
|
2
4
|
export const STREAM_TORN_WARNING = "Connection closed mid-response. The response above may be incomplete.";
|
|
3
5
|
export function parseStreamedToolArgs(json) {
|
|
4
6
|
if (!json)
|
|
@@ -40,11 +42,21 @@ export function createRepetitionPoll() {
|
|
|
40
42
|
},
|
|
41
43
|
};
|
|
42
44
|
}
|
|
45
|
+
const refusedModelCounted = new WeakSet();
|
|
43
46
|
export function noteResponseModel(partial, reported, requestedId) {
|
|
44
|
-
|
|
47
|
+
const reading = providerEchoReading(reported);
|
|
48
|
+
if (reading === "absent")
|
|
45
49
|
return;
|
|
46
|
-
if (reported === requestedId)
|
|
50
|
+
if (reported === requestedId) {
|
|
47
51
|
delete partial.responseModel;
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (reading === "refused") {
|
|
55
|
+
if (!refusedModelCounted.has(partial)) {
|
|
56
|
+
refusedModelCounted.add(partial);
|
|
57
|
+
emitBrainTelemetry({ kind: "echo_dropped", field: "responseModel" });
|
|
58
|
+
}
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
partial.responseModel = reported;
|
|
50
62
|
}
|
package/dist/core/a2a.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export declare const A2A_SKILL_DESCRIPTION_MAX_CHARS = 2048;
|
|
|
8
8
|
*
|
|
9
9
|
* Unlike MCP there is no server-hint leg to merge: the protocol has no per-skill annotation vocabulary,
|
|
10
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`, `
|
|
11
|
+
* starts at the ruled default (`egress:true`, the effect undeclared — read as `write` everywhere) and the CALLER's
|
|
12
12
|
* {@link A2aServerSpec.toolAxes} is the only thing that can lower it (design F: caller = trust root).
|
|
13
13
|
*/
|
|
14
14
|
export interface A2aToolAxis {
|
|
@@ -20,6 +20,8 @@ export interface A2aToolAxis {
|
|
|
20
20
|
/** `false` appears ONLY via an explicit caller override — same posture: enforcement ignores it,
|
|
21
21
|
* the report face consumes it (an explicit negative is a judgment, not silence). */
|
|
22
22
|
egress?: boolean;
|
|
23
|
+
/** Present ONLY when the caller's override declares it; absent is the repeat-unsafe `write` every reader applies (and
|
|
24
|
+
* the roster names `default` provenance — a default is not a declaration). */
|
|
23
25
|
effect?: ToolEffect;
|
|
24
26
|
}
|
|
25
27
|
/** design/99 §E9 equivalent for A2A — a per-peer projection of THIS materialization. A2A holds no
|
package/dist/core/a2a.js
CHANGED
|
@@ -321,7 +321,7 @@ function skillDescription(peerLabel, skill) {
|
|
|
321
321
|
return lines.join("\n");
|
|
322
322
|
}
|
|
323
323
|
function a2aAxisFor(name, override) {
|
|
324
|
-
const axis = { name, egress: true
|
|
324
|
+
const axis = { name, egress: true };
|
|
325
325
|
if (override === undefined)
|
|
326
326
|
return axis;
|
|
327
327
|
if (override.effect !== undefined)
|