@sema-agent/core 7.37.1 → 7.38.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 +168 -0
- package/dist/agents/observer.js +1 -1
- package/dist/agents/peer-notices.js +4 -4
- package/dist/agents/subagent.js +1 -1
- package/dist/agents/team-role.js +2 -2
- package/dist/brain/anthropic.js +10 -9
- package/dist/brain/errors.d.ts +26 -0
- package/dist/brain/errors.js +34 -0
- package/dist/brain/input-too-long.d.ts +0 -31
- package/dist/brain/input-too-long.js +1 -18
- package/dist/brain/open-responses.js +10 -9
- package/dist/brain/openai.js +10 -9
- package/dist/brain/status-sink.d.ts +1 -1
- package/dist/brain/stream-engine.js +10 -2
- package/dist/brain/stream-shared.d.ts +11 -3
- package/dist/brain/stream-shared.js +4 -2
- package/dist/brain/tool-call-id.d.ts +29 -8
- package/dist/brain/tool-call-id.js +36 -6
- package/dist/brain/tool-call-repair.js +1 -1
- package/dist/core/a2a-task-state.js +2 -2
- package/dist/core/artifact-host.js +6 -6
- package/dist/core/ask-origin.js +6 -6
- package/dist/core/ask-unresolvable-notice.js +1 -1
- package/dist/core/auto-mode.js +4 -4
- package/dist/core/background-agent-store.js +2 -2
- package/dist/core/checkpoint-execution-record.js +1 -1
- package/dist/core/checkpoint-store.d.ts +2 -2
- package/dist/core/checkpoint-store.js +2 -2
- package/dist/core/child-clamp-seats.js +3 -3
- package/dist/core/compliance.js +1 -1
- package/dist/core/context-edit.js +1 -1
- package/dist/core/context-guard.d.ts +0 -19
- package/dist/core/context-guard.js +0 -38
- package/dist/core/decision-receipt.d.ts +27 -1
- package/dist/core/decision-receipt.js +176 -1
- package/dist/core/engine-notice.d.ts +60 -8
- package/dist/core/engine-notice.js +2 -1
- package/dist/core/gate-fold.js +3 -2
- package/dist/core/gate-outcome.js +4 -4
- package/dist/core/governance-codes.d.ts +221 -13
- package/dist/core/governance-codes.js +104 -4
- package/dist/core/hook-seats.js +2 -2
- package/dist/core/hooks.d.ts +21 -2
- package/dist/core/hooks.js +4 -1
- package/dist/core/mailbox-store.js +3 -3
- package/dist/core/mcp-failure.js +4 -4
- package/dist/core/mcp-injection-drop.js +1 -1
- package/dist/core/memory-engine/consolidation.js +1 -1
- package/dist/core/memory-engine/delegation-settlement.d.ts +8 -0
- package/dist/core/memory-engine/delegation-settlement.js +7 -0
- package/dist/core/memory-engine/engine.d.ts +12 -2
- package/dist/core/memory-engine/engine.js +10 -6
- package/dist/core/memory-engine/export-bundle.js +1 -1
- package/dist/core/memory-engine/layout.d.ts +6 -6
- package/dist/core/memory-engine/layout.js +6 -8
- package/dist/core/memory-engine/session-write-home.d.ts +30 -0
- package/dist/core/memory-engine/session-write-home.js +34 -0
- package/dist/core/memory-engine/tools.js +1 -1
- package/dist/core/memory-engine/types.js +1 -1
- package/dist/core/memory.js +1 -1
- package/dist/core/mode-policy.d.ts +10 -1
- package/dist/core/mode-policy.js +15 -7
- package/dist/core/model-seat.js +1 -1
- package/dist/core/permission-rule-model.js +3 -3
- package/dist/core/permission-rule-store.js +2 -2
- package/dist/core/read-only-shell-table.js +8 -8
- package/dist/core/retention.js +2 -2
- package/dist/core/runner/assemble-result.js +15 -5
- package/dist/core/runner/classifier-ladder.js +1 -1
- package/dist/core/runner/denial-limit-arms.d.ts +2 -0
- package/dist/core/runner/denial-limit-arms.js +6 -2
- package/dist/core/runner/inherited-ask-grants.d.ts +6 -5
- package/dist/core/runner/inherited-ask-grants.js +3 -2
- package/dist/core/runner/prepare-artifact.d.ts +3 -2
- package/dist/core/runner/prepare-context-lane.d.ts +19 -15
- package/dist/core/runner/prepare-context-lane.js +11 -15
- package/dist/core/runner/prepare-gate-stations.js +5 -5
- package/dist/core/runner/prepare-hands-readface.d.ts +4 -3
- package/dist/core/runner/prepare-hands-readface.js +1 -0
- package/dist/core/runner/prepare-inherited-gate.js +1 -1
- package/dist/core/runner/prepare-policy-chain.js +10 -10
- package/dist/core/runner/prepare-turn-wiring.d.ts +2 -2
- package/dist/core/runner/run-harness-handlers.js +3 -0
- package/dist/core/runner/run-identity-wiring.d.ts +1 -1
- package/dist/core/runner/run-identity-wiring.js +0 -2
- package/dist/core/runner/run-leg.js +2 -2
- package/dist/core/runner/run-stop-and-final-verify.js +1 -0
- package/dist/core/runner/run-turn-boundary.js +1 -1
- package/dist/core/runner/session-mode-seats.d.ts +11 -3
- package/dist/core/runner/session-mode-seats.js +6 -0
- package/dist/core/runner/session-rule-policy.js +2 -3
- package/dist/core/runner/stream-steer-verb.js +1 -1
- package/dist/core/runner/tool-call-id-fold-seat.js +16 -9
- package/dist/core/runner/tool-turn-repair-seat.d.ts +11 -1
- package/dist/core/runner/tool-turn-repair-seat.js +35 -0
- package/dist/core/runner/turn-attachments.js +1 -1
- package/dist/core/runtime-caps.js +1 -1
- package/dist/core/safety-axis-vocab.d.ts +5 -0
- package/dist/core/safety-axis-vocab.js +5 -0
- package/dist/core/session-reconcile.d.ts +9 -7
- package/dist/core/session-reconcile.js +21 -1
- package/dist/core/shared-memory/types.js +1 -1
- package/dist/core/side-query.d.ts +6 -1
- package/dist/core/store-contracts/read-back-shape-contract.js +1 -1
- package/dist/core/swappable-deps.js +1 -1
- package/dist/core/task-notification.js +4 -4
- package/dist/core/task-registry-shared.js +1 -1
- package/dist/core/terminal-cause.d.ts +19 -0
- package/dist/core/tool-face.js +6 -6
- package/dist/core/tool-policy.d.ts +17 -11
- package/dist/core/tool-policy.js +38 -72
- package/dist/core/tool-roster.js +1 -1
- package/dist/core/tool-search-setting.js +1 -1
- package/dist/core/trace.d.ts +5 -4
- package/dist/core/types.d.ts +2 -2
- package/dist/core/types.js +1 -1
- package/dist/core/wiring-manifest.js +2 -2
- package/dist/core/write-protect.js +1 -1
- package/dist/engine/harness/agent-harness.js +10 -6
- package/dist/engine/llm/tool-turns.d.ts +93 -4
- package/dist/engine/llm/tool-turns.js +63 -9
- package/dist/engine/llm/types.d.ts +11 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +4 -2
- package/dist/internal/llm.d.ts +2 -2
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/workflow-governance.js +2 -2
- package/dist/orchestration/workflow-types.js +2 -2
- package/dist/shell/lex.js +7 -7
- package/dist/tools/fs/bash-program-position.js +2 -2
- package/dist/tools/fs/fs-shared.d.ts +2 -1
- package/dist/tools/fs/fs-shared.js +1 -1
- package/dist/tools/fs/index.d.ts +13 -6
- package/dist/tools/fs/index.js +12 -4
- package/dist/tools/fs/read-deny-home.d.ts +98 -45
- package/dist/tools/fs/read-deny-home.js +294 -117
- package/dist/tools/fs/read-deny.d.ts +2 -2
- package/dist/tools/fs/read-deny.js +2 -2
- package/dist/tools/fs/safety.d.ts +2 -0
- package/dist/tools/fs/safety.js +2 -2
- package/dist/tools/fs/search.d.ts +4 -3
- package/dist/tools/fs/search.js +3 -3
- package/dist/tools/fs/shell-read-check.d.ts +9 -0
- package/dist/tools/fs/shell-read-check.js +3 -2
- package/dist/tools/fs/shell-read-establish.d.ts +3 -0
- package/dist/tools/fs/shell-read-establish.js +1 -1
- package/dist/tools/fs/shell-read-identity.d.ts +4 -3
- package/dist/tools/fs/shell-read-identity.js +2 -2
- package/dist/tools/fs/shell-read-judge.js +2 -2
- package/dist/tools/fs/shell-read-plan.js +2 -2
- package/dist/tools/fs/shell-read-write-targets.js +1 -1
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +17 -1
- package/wire-changes/core@7.38.0.json +664 -0
- package/wire-changes/core@7.38.1.json +56 -0
|
@@ -2,7 +2,7 @@ import {} from "../internal/llm.js";
|
|
|
2
2
|
import { BrainError } from "./errors.js";
|
|
3
3
|
import { DEGENERATE_MESSAGE, trimDegenerateTail } from "./repetition.js";
|
|
4
4
|
import { STREAM_TORN_WARNING, createRepetitionPoll, noteResponseModel, parseStreamedToolArgs, placeTurnNotes } from "./stream-shared.js";
|
|
5
|
-
import { admitToolCallId, providerResultIds, providerToolCallId } from "./tool-call-id.js";
|
|
5
|
+
import { admitToolCallId, providerResultIds, providerToolCallId, responseToolCallIds } from "./tool-call-id.js";
|
|
6
6
|
import { emitBrainTelemetry } from "./status-sink.js";
|
|
7
7
|
import { errorResultMediaNote, IMAGE_OMITTED_NO_VISION, imagesOmittedNoVisionNote, modelSupportsVision, sendableImages } from "./media-degrade.js";
|
|
8
8
|
import { OUTPUT_CAP_KEYS, RESPONSES_RESERVED, applyExtraBody, effectiveOutputCap, lockHeader, mergeHeaders } from "./request-params.js";
|
|
@@ -199,7 +199,7 @@ function responsesErrorCode(code) {
|
|
|
199
199
|
const INCOMPLETE_MAX_OUTPUT_TOKENS = "max_output_tokens";
|
|
200
200
|
const INCOMPLETE_CONTENT_FILTER = "content_filter";
|
|
201
201
|
const RESPONSE_INCOMPLETE_WARNING = 'The response above may be incomplete: the endpoint reported status "incomplete" with no reason this client recognises.';
|
|
202
|
-
function closeFunctionCall(acc) {
|
|
202
|
+
function closeFunctionCall(acc, responseIds) {
|
|
203
203
|
if (acc.closedTc)
|
|
204
204
|
return acc.closedTc;
|
|
205
205
|
if (!acc.name)
|
|
@@ -207,7 +207,7 @@ function closeFunctionCall(acc) {
|
|
|
207
207
|
const args = parseStreamedToolArgs(acc.args);
|
|
208
208
|
if (args === undefined)
|
|
209
209
|
return undefined;
|
|
210
|
-
const { engineId, wireId } = admitToolCallId(acc.callId, "call_");
|
|
210
|
+
const { engineId, wireId } = admitToolCallId(acc.callId, "call_", responseIds);
|
|
211
211
|
acc.closedTc = { type: "toolCall", id: engineId, ...(wireId !== engineId ? { wireId } : {}), name: acc.name, arguments: args };
|
|
212
212
|
return acc.closedTc;
|
|
213
213
|
}
|
|
@@ -305,6 +305,7 @@ export function createOpenResponsesBrain(config = {}) {
|
|
|
305
305
|
makeParser: (ctrl) => {
|
|
306
306
|
const { out, partial } = ctrl;
|
|
307
307
|
const items = new Map();
|
|
308
|
+
const responseIds = responseToolCallIds();
|
|
308
309
|
let usageRaw;
|
|
309
310
|
let responseId;
|
|
310
311
|
let terminalStatus;
|
|
@@ -412,7 +413,7 @@ export function createOpenResponsesBrain(config = {}) {
|
|
|
412
413
|
out.push({ type: "text_end", contentIndex: index, content: messageFace(acc), partial: { ...partial } });
|
|
413
414
|
}
|
|
414
415
|
else {
|
|
415
|
-
const tc = closeFunctionCall(acc);
|
|
416
|
+
const tc = closeFunctionCall(acc, responseIds);
|
|
416
417
|
if (tc)
|
|
417
418
|
out.push({ type: "toolcall_end", contentIndex: index, toolCall: tc, partial: { ...partial } });
|
|
418
419
|
}
|
|
@@ -650,7 +651,7 @@ export function createOpenResponsesBrain(config = {}) {
|
|
|
650
651
|
}
|
|
651
652
|
}
|
|
652
653
|
else {
|
|
653
|
-
const tc = closeFunctionCall(acc);
|
|
654
|
+
const tc = closeFunctionCall(acc, responseIds);
|
|
654
655
|
if (tc) {
|
|
655
656
|
toolCalls.push(tc);
|
|
656
657
|
finalContent.push(tc);
|
|
@@ -675,15 +676,15 @@ export function createOpenResponsesBrain(config = {}) {
|
|
|
675
676
|
const toolError = toolErrorParts.length > 0 ? toolErrorParts.join(" | ") : undefined;
|
|
676
677
|
const notes = [];
|
|
677
678
|
if (malformed.length > 0) {
|
|
678
|
-
notes.push(`\n[note: ${malformed.length} tool call(s) were truncated (status="${terminalLabel}") and dropped — re-issue them next turn: ${malformed.join("; ")}]`);
|
|
679
|
+
notes.push({ cause: "truncated", count: malformed.length, text: `\n[note: ${malformed.length} tool call(s) were truncated (status="${terminalLabel}") and dropped — re-issue them next turn: ${malformed.join("; ")}]` });
|
|
679
680
|
}
|
|
680
681
|
if (unnamed.length > 0) {
|
|
681
|
-
notes.push(`\n[note: ${unnamed.length} tool call(s) arrived with no tool name and were dropped — re-issue them next turn with an explicit tool name: ${unnamed.join("; ")}]`);
|
|
682
|
+
notes.push({ cause: "unnamed", count: unnamed.length, text: `\n[note: ${unnamed.length} tool call(s) arrived with no tool name and were dropped — re-issue them next turn with an explicit tool name: ${unnamed.join("; ")}]` });
|
|
682
683
|
}
|
|
683
684
|
if (malformedFrames > 0) {
|
|
684
|
-
notes.push(`\n[note: ${malformedFrames} provider stream frame(s) were not valid JSON and were dropped — the streamed output may be missing content (first sample: ${JSON.stringify(malformedSample)})]`);
|
|
685
|
+
notes.push({ cause: "bad_frame", count: malformedFrames, text: `\n[note: ${malformedFrames} provider stream frame(s) were not valid JSON and were dropped — the streamed output may be missing content (first sample: ${JSON.stringify(malformedSample)})]` });
|
|
685
686
|
}
|
|
686
|
-
placeTurnNotes(finalContent, notes);
|
|
687
|
+
placeTurnNotes(partial, finalContent, notes);
|
|
687
688
|
const truncated = incompleteReason === INCOMPLETE_MAX_OUTPUT_TOKENS;
|
|
688
689
|
const truncatedEmpty = truncated && noUsableContent && !toolError;
|
|
689
690
|
const dynamicCut = truncatedEmpty && options?.maxTokensDynamic === true;
|
package/dist/brain/openai.js
CHANGED
|
@@ -2,7 +2,7 @@ import {} from "../internal/llm.js";
|
|
|
2
2
|
import { repairTextToolCalls } from "./tool-call-repair.js";
|
|
3
3
|
import { DEGENERATE_MESSAGE, trimDegenerateTail } from "./repetition.js";
|
|
4
4
|
import { STREAM_TORN_WARNING, createRepetitionPoll, noteResponseModel, parseStreamedToolArgs, placeTurnNotes, truncationCauseClause } from "./stream-shared.js";
|
|
5
|
-
import { admitToolCallId, providerResultIds, providerToolCallId } from "./tool-call-id.js";
|
|
5
|
+
import { admitToolCallId, providerResultIds, providerToolCallId, responseToolCallIds } from "./tool-call-id.js";
|
|
6
6
|
import { emitBrainTelemetry } from "./status-sink.js";
|
|
7
7
|
import { errorResultMediaNote, IMAGE_OMITTED_NO_VISION, imagesOmittedNoVisionNote, modelSupportsVision, sendableImages } from "./media-degrade.js";
|
|
8
8
|
import { OPENAI_RESERVED, OUTPUT_CAP_KEYS, applyExtraBody, effectiveOutputCap, lockHeader, mergeHeaders } from "./request-params.js";
|
|
@@ -12,7 +12,7 @@ import { declaredOffSpelling, mintEffortWireValue, reasoningRequestCarried } fro
|
|
|
12
12
|
import { runStreamingBrain } from "./stream-engine.js";
|
|
13
13
|
import { refuseRetiredTimeoutKnobs } from "./timeout.js";
|
|
14
14
|
import { resolveFetch } from "./transport.js";
|
|
15
|
-
function closeToolCallAccum(acc) {
|
|
15
|
+
function closeToolCallAccum(acc, responseIds) {
|
|
16
16
|
if (acc.closedTc)
|
|
17
17
|
return acc.closedTc;
|
|
18
18
|
if (!acc.name)
|
|
@@ -20,7 +20,7 @@ function closeToolCallAccum(acc) {
|
|
|
20
20
|
const args = parseStreamedToolArgs(acc.args);
|
|
21
21
|
if (args === undefined)
|
|
22
22
|
return undefined;
|
|
23
|
-
const { engineId, wireId } = admitToolCallId(acc.id, "call_");
|
|
23
|
+
const { engineId, wireId } = admitToolCallId(acc.id, "call_", responseIds);
|
|
24
24
|
acc.closedTc = { type: "toolCall", id: engineId, ...(wireId !== engineId ? { wireId } : {}), name: acc.name, arguments: args };
|
|
25
25
|
return acc.closedTc;
|
|
26
26
|
}
|
|
@@ -377,6 +377,7 @@ export function createOpenAIBrain(config = {}) {
|
|
|
377
377
|
let thinkingClosed = false;
|
|
378
378
|
let textIndex = 0;
|
|
379
379
|
const toolAccum = new Map();
|
|
380
|
+
const responseIds = responseToolCallIds();
|
|
380
381
|
let finishReason = null;
|
|
381
382
|
const terminalFrameSeen = () => finishReason != null;
|
|
382
383
|
let usageRaw;
|
|
@@ -495,7 +496,7 @@ export function createOpenAIBrain(config = {}) {
|
|
|
495
496
|
continue;
|
|
496
497
|
if (prevAcc.args === "")
|
|
497
498
|
continue;
|
|
498
|
-
const closed = closeToolCallAccum(prevAcc);
|
|
499
|
+
const closed = closeToolCallAccum(prevAcc, responseIds);
|
|
499
500
|
if (closed) {
|
|
500
501
|
out.push({ type: "toolcall_end", contentIndex: prevIdx, toolCall: closed, partial: { ...partial } });
|
|
501
502
|
}
|
|
@@ -536,7 +537,7 @@ export function createOpenAIBrain(config = {}) {
|
|
|
536
537
|
unnamed.push(`id="${acc.id || "?"}"(${acc.args.slice(0, 200)})`);
|
|
537
538
|
continue;
|
|
538
539
|
}
|
|
539
|
-
const tc = closeToolCallAccum(acc);
|
|
540
|
+
const tc = closeToolCallAccum(acc, responseIds);
|
|
540
541
|
if (tc) {
|
|
541
542
|
toolCalls.push(tc);
|
|
542
543
|
finalContent.push(tc);
|
|
@@ -579,15 +580,15 @@ export function createOpenAIBrain(config = {}) {
|
|
|
579
580
|
const noUsableContent = toolCalls.length === 0 && !accumText.trim();
|
|
580
581
|
const notes = [];
|
|
581
582
|
if (malformed.length > 0) {
|
|
582
|
-
notes.push(`\n[note: ${malformed.length} tool call(s) were truncated (finish_reason="${finishReason ?? "?"}") and dropped — re-issue them next turn: ${malformed.join("; ")}]`);
|
|
583
|
+
notes.push({ cause: "truncated", count: malformed.length, text: `\n[note: ${malformed.length} tool call(s) were truncated (finish_reason="${finishReason ?? "?"}") and dropped — re-issue them next turn: ${malformed.join("; ")}]` });
|
|
583
584
|
}
|
|
584
585
|
if (unnamed.length > 0) {
|
|
585
|
-
notes.push(`\n[note: ${unnamed.length} tool call(s) arrived with no tool name and were dropped — re-issue them next turn with an explicit tool name: ${unnamed.join("; ")}]`);
|
|
586
|
+
notes.push({ cause: "unnamed", count: unnamed.length, text: `\n[note: ${unnamed.length} tool call(s) arrived with no tool name and were dropped — re-issue them next turn with an explicit tool name: ${unnamed.join("; ")}]` });
|
|
586
587
|
}
|
|
587
588
|
if (malformedFrames > 0) {
|
|
588
|
-
notes.push(`\n[note: ${malformedFrames} provider stream frame(s) were not valid JSON and were dropped — the streamed output may be missing content (first sample: ${JSON.stringify(malformedSample)})]`);
|
|
589
|
+
notes.push({ cause: "bad_frame", count: malformedFrames, text: `\n[note: ${malformedFrames} provider stream frame(s) were not valid JSON and were dropped — the streamed output may be missing content (first sample: ${JSON.stringify(malformedSample)})]` });
|
|
589
590
|
}
|
|
590
|
-
placeTurnNotes(finalContent, notes);
|
|
591
|
+
placeTurnNotes(partial, finalContent, notes);
|
|
591
592
|
const truncatedEmpty = finishReason === "length" && noUsableContent && !toolError;
|
|
592
593
|
const dynamicCut = truncatedEmpty && options?.maxTokensDynamic === true;
|
|
593
594
|
const safetyCut = finishReason === "content_filter";
|
|
@@ -71,7 +71,7 @@ export type BrainTelemetry = {
|
|
|
71
71
|
* and the field is absent. One event per provider response per field. */
|
|
72
72
|
| {
|
|
73
73
|
kind: "echo_dropped";
|
|
74
|
-
field: "requestId" | "responseModel";
|
|
74
|
+
field: "requestId" | "responseModel" | "apiErrorCode";
|
|
75
75
|
};
|
|
76
76
|
/** Run `fn` with a per-task brain-telemetry sink in scope (Runner-side; compose with runWithStatusSink). */
|
|
77
77
|
export declare function runWithBrainTelemetry<T>(emit: (t: BrainTelemetry) => void, fn: () => Promise<T>): Promise<T>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createAssistantMessageEventStream, } from "../internal/llm.js";
|
|
2
2
|
import { STREAM_TORN_WARNING } from "./stream-shared.js";
|
|
3
3
|
import { FLOOR_OUTPUT_TOKENS, parseContextOverflow, planOutputCapAdjustment } from "./context-overflow.js";
|
|
4
|
-
import { abortLikeName, BrainError, brainErrorCodeOf, classifyConnectFailure, classifyFetchThrow, classifyHttp, describeNetworkError, namesTheFailure, readProviderRequestId } from "./errors.js";
|
|
4
|
+
import { abortLikeName, BrainError, brainErrorCodeOf, classifyConnectFailure, classifyFetchThrow, classifyHttp, describeNetworkError, isProviderEchoShape, namesTheFailure, readProviderErrorCode, readProviderRequestId, refusedTheRequest } from "./errors.js";
|
|
5
5
|
import { stripUrlCredentials } from "./route-adjudicator.js";
|
|
6
6
|
import { classifyInputTooLong } from "./input-too-long.js";
|
|
7
7
|
import { FAST_MAX_BACKOFF_MS, providerWaitHint, retryBackoffMs } from "./retry.js";
|
|
@@ -304,6 +304,9 @@ export function runStreamingBrain(args) {
|
|
|
304
304
|
errorMsg.apiErrorStatus = statusNum;
|
|
305
305
|
if (requestIdSeen !== undefined)
|
|
306
306
|
errorMsg.requestId = requestIdSeen;
|
|
307
|
+
const providerCode = readMember(err, "providerCode");
|
|
308
|
+
if (refusedTheRequest(statusNum) && typeof providerCode === "string" && isProviderEchoShape(providerCode))
|
|
309
|
+
errorMsg.apiErrorCode = providerCode;
|
|
307
310
|
}
|
|
308
311
|
}
|
|
309
312
|
errorMsg.usageMissing = true;
|
|
@@ -582,7 +585,12 @@ export function runStreamingBrain(args) {
|
|
|
582
585
|
const detail = overflowBody ?? (r ? (await readErrorBody(r, signal)).text : "");
|
|
583
586
|
const status = r?.status ?? 0;
|
|
584
587
|
const itl = classifyInputTooLong(status, detail);
|
|
585
|
-
|
|
588
|
+
const providerCode = refusedTheRequest(status) ? readProviderErrorCode(detail) : undefined;
|
|
589
|
+
throw new BrainError(classifyHttp(status), `${httpLabel} HTTP ${status || "ERR"}: ${detail.slice(0, 500)}${overflowDeclineNote}`, status, {
|
|
590
|
+
apiError: true,
|
|
591
|
+
...(itl === "yes" ? { inputTooLong: true } : itl === "no" ? { inputTooLongRuledOut: true } : {}),
|
|
592
|
+
...(providerCode !== undefined ? { providerCode } : {}),
|
|
593
|
+
});
|
|
586
594
|
}
|
|
587
595
|
finally {
|
|
588
596
|
cc.abort();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type RepetitionEvent } from "./repetition.js";
|
|
2
|
-
import type
|
|
2
|
+
import { type AssistantMessage, type StreamDropCause } from "../internal/llm.js";
|
|
3
3
|
/**
|
|
4
4
|
* design/157 A10 — stream-parser pieces that the anthropic and openai SSE lanes carried BYTE-IDENTICALLY
|
|
5
5
|
* (verified by diff at 1469481: a 16-line repetition-telemetry closure). Provider-agnostic policy, so it
|
|
@@ -29,14 +29,22 @@ import type { AssistantMessage } from "../internal/llm.js";
|
|
|
29
29
|
* mid-stream promotion (the body threw) and by the parsers' own finalize (content arrived, no finish frame). */
|
|
30
30
|
export declare const STREAM_TORN_WARNING = "Connection closed mid-response. The response above may be incomplete.";
|
|
31
31
|
export declare function parseStreamedToolArgs(json: string): Record<string, unknown> | undefined;
|
|
32
|
+
/** One drop note of a turn: what was dropped, how many, and the sentence the model reads. */
|
|
33
|
+
export interface TurnNote {
|
|
34
|
+
readonly cause: StreamDropCause;
|
|
35
|
+
readonly count: number;
|
|
36
|
+
readonly text: string;
|
|
37
|
+
}
|
|
32
38
|
/**
|
|
33
39
|
* Place a turn's engine notes in its final content: AHEAD of the first tool call, in order, or at the end of a turn
|
|
34
40
|
* that has none. Every dropped call (cut arguments, no tool name) and dropped stream frames are stated so the model
|
|
35
41
|
* re-issues them — also when text survived and no call did; a partial batch still executes its valid calls (a brain
|
|
36
42
|
* `error` is a terminal task failure, not a re-prompt). No block may follow the calls: the Anthropic Messages API
|
|
37
|
-
* rejects a `tool_use` followed by anything but another `tool_use`.
|
|
43
|
+
* rejects a `tool_use` followed by anything but another `tool_use`. The same notes are stamped on the turn's message as
|
|
44
|
+
* its stream drops (`stampStreamDrops`), the run's source for the person's line (`task.tool_turn_incomplete`): the
|
|
45
|
+
* model's sentence and the person's line come from one list. One rule for the three lanes.
|
|
38
46
|
*/
|
|
39
|
-
export declare function placeTurnNotes(content: AssistantMessage["content"], notes: readonly
|
|
47
|
+
export declare function placeTurnNotes(message: Pick<AssistantMessage, "diagnostics">, content: AssistantMessage["content"], notes: readonly TurnNote[]): void;
|
|
40
48
|
/**
|
|
41
49
|
* The cause clause of a dropped call's "not valid JSON" message. The output cap is named only when the stream says
|
|
42
50
|
* the cap cut it — the lane's own cap stop, or a counted output at or over the cap on the wire; a stream that ended
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isProviderEchoShape, providerEchoReading } from "./errors.js";
|
|
2
2
|
import { inspectDegenerate } from "./repetition.js";
|
|
3
3
|
import { emitBrainTelemetry } from "./status-sink.js";
|
|
4
|
+
import { stampStreamDrops } from "../internal/llm.js";
|
|
4
5
|
export const STREAM_TORN_WARNING = "Connection closed mid-response. The response above may be incomplete.";
|
|
5
6
|
export function parseStreamedToolArgs(json) {
|
|
6
7
|
if (!json)
|
|
@@ -16,11 +17,12 @@ export function parseStreamedToolArgs(json) {
|
|
|
16
17
|
return undefined;
|
|
17
18
|
return parsed;
|
|
18
19
|
}
|
|
19
|
-
export function placeTurnNotes(content, notes) {
|
|
20
|
+
export function placeTurnNotes(message, content, notes) {
|
|
20
21
|
if (notes.length === 0)
|
|
21
22
|
return;
|
|
22
23
|
const at = content.findIndex((block) => block.type === "toolCall");
|
|
23
|
-
content.splice(at === -1 ? content.length : at, 0, ...notes.map((text) => ({ type: "text", text })));
|
|
24
|
+
content.splice(at === -1 ? content.length : at, 0, ...notes.map(({ text }) => ({ type: "text", text })));
|
|
25
|
+
stampStreamDrops(message, notes);
|
|
24
26
|
}
|
|
25
27
|
export function truncationCauseClause(facts) {
|
|
26
28
|
const { capStop, outputTokens, capTokens, terminalFrameSeen } = facts;
|
|
@@ -12,14 +12,35 @@ export interface AdmittedToolCallId {
|
|
|
12
12
|
readonly engineId: string;
|
|
13
13
|
readonly wireId: string;
|
|
14
14
|
}
|
|
15
|
-
/** Why a
|
|
16
|
-
* a non-ASCII unit, or the fold separator); `"length"` — every character is admitted and it is longer than
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
export
|
|
20
|
-
/**
|
|
21
|
-
*
|
|
22
|
-
export declare function
|
|
15
|
+
/** Why a call's id was folded: `"charset"` — the raw holds a character outside the admitted alphabet (a control byte,
|
|
16
|
+
* a space, a non-ASCII unit, or the fold separator); `"length"` — every character is admitted and it is longer than
|
|
17
|
+
* 128; `"duplicate"` — an earlier call in the same response carried the same raw id, so this one was renamed. */
|
|
18
|
+
export declare const TOOL_CALL_ID_FOLD_REASONS: readonly ["charset", "length", "duplicate"];
|
|
19
|
+
export type ToolCallIdFoldReason = (typeof TOOL_CALL_ID_FOLD_REASONS)[number];
|
|
20
|
+
/** The fold reading of one non-empty raw id on its own: `undefined` ⇒ admitted verbatim; otherwise why its shape is
|
|
21
|
+
* folded (`"duplicate"` is a reading of the response, never of one id). */
|
|
22
|
+
export declare function toolCallIdFoldReason(raw: string): Exclude<ToolCallIdFoldReason, "duplicate"> | undefined;
|
|
23
|
+
/** Why a call carries two ids, read off the call itself (a built-in brain's call and a host brain's alike):
|
|
24
|
+
* `undefined` ⇒ one id, or an in-shape pair the admission did not mint (a host brain's own spelling); a provider id
|
|
25
|
+
* outside the admitted shape ⇒ its shape reason; an in-shape provider id beside an engine id of the rename arm's
|
|
26
|
+
* form ⇒ `"duplicate"`. */
|
|
27
|
+
export declare function toolCallFoldReason(call: {
|
|
28
|
+
readonly id: string;
|
|
29
|
+
readonly wireId?: unknown;
|
|
30
|
+
}): ToolCallIdFoldReason | undefined;
|
|
31
|
+
/** What ONE provider response has admitted so far — the state the rename arm reads: every provider id handed out
|
|
32
|
+
* (`handedOut`) and how many calls each raw id arrived on (`arrivals`). A brain holds one per response attempt
|
|
33
|
+
* ({@link responseToolCallIds}; a retried response starts a new one). */
|
|
34
|
+
export interface ResponseToolCallIds {
|
|
35
|
+
readonly handedOut: Set<string>;
|
|
36
|
+
readonly arrivals: Map<string, number>;
|
|
37
|
+
}
|
|
38
|
+
/** A fresh {@link ResponseToolCallIds} for one response attempt. */
|
|
39
|
+
export declare function responseToolCallIds(): ResponseToolCallIds;
|
|
40
|
+
/** Admit a provider-minted tool-call id (see the module header for the four arms). `response` = the response's
|
|
41
|
+
* {@link ResponseToolCallIds}; absent ⇒ the single-call reading (no rename). Pure apart from recording the call in
|
|
42
|
+
* `response`: announcing a fold is the run's job, read off the call ({@link toolCallFoldReason}). */
|
|
43
|
+
export declare function admitToolCallId(raw: unknown, prefix: string, response?: ResponseToolCallIds): AdmittedToolCallId;
|
|
23
44
|
/** The id a provider is handed for this call: its `wireId` when it carries one (a non-empty string), else its `id`. */
|
|
24
45
|
export declare function providerToolCallId(call: {
|
|
25
46
|
readonly id: string;
|
|
@@ -6,25 +6,55 @@ const FOLD_DIGEST_HEX = 32;
|
|
|
6
6
|
export function mintFallbackToolCallId(prefix) {
|
|
7
7
|
return `${prefix}${Math.random().toString(36).slice(2)}`;
|
|
8
8
|
}
|
|
9
|
+
export const TOOL_CALL_ID_FOLD_REASONS = Object.freeze(["charset", "length", "duplicate"]);
|
|
9
10
|
export function toolCallIdFoldReason(raw) {
|
|
10
11
|
const separated = raw.includes(TOOL_CALL_ID_FOLD_SEPARATOR);
|
|
11
12
|
if (!separated && isProviderEchoShape(raw))
|
|
12
13
|
return undefined;
|
|
13
14
|
return !separated && fitsProviderEchoCharset(raw) ? "length" : "charset";
|
|
14
15
|
}
|
|
15
|
-
export function
|
|
16
|
+
export function toolCallFoldReason(call) {
|
|
17
|
+
const wireId = providerToolCallId(call);
|
|
18
|
+
if (wireId === call.id)
|
|
19
|
+
return undefined;
|
|
20
|
+
return toolCallIdFoldReason(wireId) ?? (RENAMED_ENGINE_ID.test(call.id) ? "duplicate" : undefined);
|
|
21
|
+
}
|
|
22
|
+
const RENAMED_ENGINE_ID = new RegExp(`^[\\x21-\\x7D]{1,${FOLD_BASE_CHARS}}${TOOL_CALL_ID_FOLD_SEPARATOR}[1-9][0-9]*${TOOL_CALL_ID_FOLD_SEPARATOR}[0-9a-f]{${FOLD_DIGEST_HEX}}$`);
|
|
23
|
+
export function responseToolCallIds() {
|
|
24
|
+
return { handedOut: new Set(), arrivals: new Map() };
|
|
25
|
+
}
|
|
26
|
+
export function admitToolCallId(raw, prefix, response) {
|
|
16
27
|
if (typeof raw !== "string" || raw === "") {
|
|
17
|
-
|
|
28
|
+
let id = mintFallbackToolCallId(prefix);
|
|
29
|
+
while (response?.handedOut.has(id) === true)
|
|
30
|
+
id = mintFallbackToolCallId(prefix);
|
|
31
|
+
response?.handedOut.add(id);
|
|
18
32
|
return { engineId: id, wireId: id };
|
|
19
33
|
}
|
|
20
|
-
|
|
34
|
+
if (response === undefined)
|
|
35
|
+
return { engineId: engineIdOf(raw), wireId: raw };
|
|
36
|
+
const arrival = (response.arrivals.get(raw) ?? 0) + 1;
|
|
37
|
+
response.arrivals.set(raw, arrival);
|
|
38
|
+
if (!response.handedOut.has(raw)) {
|
|
39
|
+
response.handedOut.add(raw);
|
|
40
|
+
return { engineId: engineIdOf(raw), wireId: raw };
|
|
41
|
+
}
|
|
42
|
+
let wireId = `${prefix}${digestOf(`${arrival}\u0000${raw}`)}`;
|
|
43
|
+
for (let attempt = 1; response.handedOut.has(wireId); attempt++)
|
|
44
|
+
wireId = `${prefix}${digestOf(`${arrival}\u0000${raw}\u0000${attempt}`)}`;
|
|
45
|
+
response.handedOut.add(wireId);
|
|
46
|
+
return { engineId: `${foldBase(raw)}${TOOL_CALL_ID_FOLD_SEPARATOR}${arrival}${TOOL_CALL_ID_FOLD_SEPARATOR}${digestOf(wireId)}`, wireId };
|
|
21
47
|
}
|
|
22
48
|
function engineIdOf(raw) {
|
|
23
49
|
if (toolCallIdFoldReason(raw) === undefined)
|
|
24
50
|
return raw;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
51
|
+
return `${foldBase(raw)}${TOOL_CALL_ID_FOLD_SEPARATOR}${digestOf(raw)}`;
|
|
52
|
+
}
|
|
53
|
+
function foldBase(raw) {
|
|
54
|
+
return raw.slice(0, FOLD_BASE_CHARS).replace(/[^\x21-\x7D]/g, "-");
|
|
55
|
+
}
|
|
56
|
+
function digestOf(value) {
|
|
57
|
+
return createHash("sha256").update(Buffer.from(value, "utf16le")).digest("hex").slice(0, FOLD_DIGEST_HEX);
|
|
28
58
|
}
|
|
29
59
|
export function providerToolCallId(call) {
|
|
30
60
|
return typeof call.wireId === "string" && call.wireId !== "" ? call.wireId : call.id;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const A2A_TASK_STATES = [
|
|
1
|
+
export const A2A_TASK_STATES = Object.freeze([
|
|
2
2
|
"submitted",
|
|
3
3
|
"working",
|
|
4
4
|
"input-required",
|
|
@@ -8,7 +8,7 @@ export const A2A_TASK_STATES = [
|
|
|
8
8
|
"rejected",
|
|
9
9
|
"auth-required",
|
|
10
10
|
"unknown",
|
|
11
|
-
];
|
|
11
|
+
]);
|
|
12
12
|
const CANCELLING_STOP_SOURCES = new Set(["user", "parent"]);
|
|
13
13
|
export function toA2ATaskState(record) {
|
|
14
14
|
switch (record.status) {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { isAbsoluteForFamily, pathFamilyOf } from "../tools/fs/safety.js";
|
|
2
2
|
import { thrownText } from "./thrown-value.js";
|
|
3
|
-
export const ARTIFACT_ACTIONS = ["publish", "list", "read", "list_files", "read_file"];
|
|
4
|
-
export const ARTIFACT_PLANES = ["hosted", "local-stub"];
|
|
5
|
-
export const ARTIFACT_COMMIT_CERTAINTIES = ["throw_means_uncommitted", "uncertain"];
|
|
3
|
+
export const ARTIFACT_ACTIONS = Object.freeze(["publish", "list", "read", "list_files", "read_file"]);
|
|
4
|
+
export const ARTIFACT_PLANES = Object.freeze(["hosted", "local-stub"]);
|
|
5
|
+
export const ARTIFACT_COMMIT_CERTAINTIES = Object.freeze(["throw_means_uncommitted", "uncertain"]);
|
|
6
6
|
export const ARTIFACT_COMMIT_THROW_OUTCOME = {
|
|
7
7
|
throw_means_uncommitted: "not_executed",
|
|
8
8
|
uncertain: "unknown",
|
|
9
9
|
};
|
|
10
|
-
export const ARTIFACT_PUBLISH_CONTEXTS = ["pr_review", "workshop", "whiteboard", "prototype", "plain"];
|
|
11
|
-
export const ARTIFACT_LIST_SCOPES = ["mine", "shared", "all"];
|
|
10
|
+
export const ARTIFACT_PUBLISH_CONTEXTS = Object.freeze(["pr_review", "workshop", "whiteboard", "prototype", "plain"]);
|
|
11
|
+
export const ARTIFACT_LIST_SCOPES = Object.freeze(["mine", "shared", "all"]);
|
|
12
12
|
export const ARTIFACT_PLANE_CONTENT_ORIGIN = {
|
|
13
13
|
hosted: "external",
|
|
14
14
|
"local-stub": "local",
|
|
@@ -27,7 +27,7 @@ export const ARTIFACT_ACTION_CONCURRENCY_SAFE = {
|
|
|
27
27
|
list_files: true,
|
|
28
28
|
read_file: true,
|
|
29
29
|
};
|
|
30
|
-
export const ARTIFACT_HOST_FAILURE_CODES = ["conflict", "url_foreign", "forbidden", "payload_too_large", "not_found", "force_refused", "refused"];
|
|
30
|
+
export const ARTIFACT_HOST_FAILURE_CODES = Object.freeze(["conflict", "url_foreign", "forbidden", "payload_too_large", "not_found", "force_refused", "refused"]);
|
|
31
31
|
export const ARTIFACT_FAILURE_RESULT_CODE = {
|
|
32
32
|
conflict: "artifact.publish_conflict",
|
|
33
33
|
url_foreign: "artifact.url_foreign",
|
package/dist/core/ask-origin.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const ASK_ORIGINS = ["content_question", "ancestor_marked", "org_unavailable", "org_rule", "rule_store_unavailable", "hook", "ask_rule", "denial_limit_fallback", "shell_gate_tighten", "safety_tighten", "policy"];
|
|
1
|
+
export const ASK_ORIGINS = Object.freeze(["content_question", "ancestor_marked", "org_unavailable", "org_rule", "rule_store_unavailable", "hook", "ask_rule", "denial_limit_fallback", "shell_gate_tighten", "safety_tighten", "policy"]);
|
|
2
2
|
const ASK_ORIGIN_SET = new Set(ASK_ORIGINS);
|
|
3
3
|
export function isAskOrigin(v) {
|
|
4
4
|
return ASK_ORIGIN_SET.has(v);
|
|
@@ -103,7 +103,7 @@ export const ORIGIN_IMPLIES_REAL_APPROVAL = {
|
|
|
103
103
|
safety_tighten: false,
|
|
104
104
|
policy: false,
|
|
105
105
|
};
|
|
106
|
-
export const PERSISTED_RULE_MANDATES = ["operator_always", "tool_marks", "probe_mandate", "probe_unanswered", "write_protection", "write_protection_unresolved"];
|
|
106
|
+
export const PERSISTED_RULE_MANDATES = Object.freeze(["operator_always", "tool_marks", "probe_mandate", "probe_unanswered", "write_protection", "write_protection_unresolved"]);
|
|
107
107
|
const PERSISTED_RULE_MANDATE_SET = new Set(PERSISTED_RULE_MANDATES);
|
|
108
108
|
export function isPersistedRuleMandate(v) {
|
|
109
109
|
return PERSISTED_RULE_MANDATE_SET.has(v);
|
|
@@ -149,7 +149,7 @@ export function safetyAxisOf(marks) {
|
|
|
149
149
|
const shell = raised && marks.shellGated === true;
|
|
150
150
|
return egress || raised ? { egress, irreversible: raised && !shell, ...(shell ? { shell: true } : {}) } : undefined;
|
|
151
151
|
}
|
|
152
|
-
export const PERMISSION_MODES = ["default", "acceptEdits", "plan", "auto", "bypassPermissions", "dontAsk"];
|
|
152
|
+
export const PERMISSION_MODES = Object.freeze(["default", "acceptEdits", "plan", "auto", "bypassPermissions", "dontAsk"]);
|
|
153
153
|
const PERMISSION_MODE_SET = new Set(PERMISSION_MODES);
|
|
154
154
|
export function isPermissionMode(v) {
|
|
155
155
|
return PERMISSION_MODE_SET.has(v);
|
|
@@ -166,7 +166,7 @@ export function clampPermissionMode(declared, ceiling) {
|
|
|
166
166
|
return { effective: ceiling, clamped: true };
|
|
167
167
|
return PERMISSION_MODE_RANK[declared] <= PERMISSION_MODE_RANK[ceiling] ? { effective: declared, clamped: false } : { effective: ceiling, clamped: true };
|
|
168
168
|
}
|
|
169
|
-
export const ASK_CLASSES = [
|
|
169
|
+
export const ASK_CLASSES = Object.freeze([
|
|
170
170
|
"content_question",
|
|
171
171
|
"hook",
|
|
172
172
|
"ancestor",
|
|
@@ -187,7 +187,7 @@ export const ASK_CLASSES = [
|
|
|
187
187
|
"artifact_shared_read",
|
|
188
188
|
"mode",
|
|
189
189
|
"ordinary",
|
|
190
|
-
];
|
|
190
|
+
]);
|
|
191
191
|
const ASK_CLASS_SET = new Set(ASK_CLASSES);
|
|
192
192
|
export function isAskClass(v) {
|
|
193
193
|
return ASK_CLASS_SET.has(v);
|
|
@@ -216,7 +216,7 @@ export const MODE_ARBITRATION = {
|
|
|
216
216
|
};
|
|
217
217
|
export const RRA_EXPLAINERS = new Set(["unverifiable_delete", "transcript_write", "org_rule", "governance_unavailable", "rule_unreadable", "denial_limit_fallback", "ancestor", "artifact_shared_read"]);
|
|
218
218
|
export const RELEASABLE_ASK_CLASSES = ASK_CLASSES.filter((c) => !MODE_ARBITRATION[c].bypassImmune);
|
|
219
|
-
export const MODE_RELEASE_REASONS = ["rule_unreadable"];
|
|
219
|
+
export const MODE_RELEASE_REASONS = Object.freeze(["rule_unreadable"]);
|
|
220
220
|
const MODE_RELEASE_REASON_SET = new Set(MODE_RELEASE_REASONS);
|
|
221
221
|
export function isModeReleaseReason(v) {
|
|
222
222
|
return MODE_RELEASE_REASON_SET.has(v);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const ASK_UNRESOLVABLE_CAUSES = ["approver_unavailable", "no_approver_wired", "mandate_unreconstructible"];
|
|
1
|
+
export const ASK_UNRESOLVABLE_CAUSES = Object.freeze(["approver_unavailable", "no_approver_wired", "mandate_unreconstructible"]);
|
|
2
2
|
Object.freeze(ASK_UNRESOLVABLE_CAUSES);
|
|
3
3
|
const ASK_UNRESOLVABLE_CAUSE_SET = new Set(ASK_UNRESOLVABLE_CAUSES);
|
|
4
4
|
export function isAskUnresolvableCause(v) {
|
package/dist/core/auto-mode.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { AUTO_MODE_DEFAULT_TIMEOUT_MS, AUTO_MODE_DENIAL_AUTO_DENY_DEFAULT_MS, AUTO_MODE_DENIAL_LIMIT_DEFAULTS } from "./auto-mode-defaults.js";
|
|
2
2
|
import { thrownIs } from "./thrown-value.js";
|
|
3
3
|
import { describeRejectedValue } from "./tool-search-setting.js";
|
|
4
|
-
export const AUTO_MODE_UNAVAILABLE_CAUSES = ["error", "timeout"];
|
|
4
|
+
export const AUTO_MODE_UNAVAILABLE_CAUSES = Object.freeze(["error", "timeout"]);
|
|
5
5
|
const AUTO_MODE_UNAVAILABLE_CAUSE_SET = new Set(AUTO_MODE_UNAVAILABLE_CAUSES);
|
|
6
6
|
export function isAutoModeUnavailableCause(v) {
|
|
7
7
|
return AUTO_MODE_UNAVAILABLE_CAUSE_SET.has(v);
|
|
8
8
|
}
|
|
9
|
-
export const AUTO_MODE_PARSE_FAILURES = ["missing", "conflict"];
|
|
9
|
+
export const AUTO_MODE_PARSE_FAILURES = Object.freeze(["missing", "conflict"]);
|
|
10
10
|
const AUTO_MODE_PARSE_FAILURE_SET = new Set(AUTO_MODE_PARSE_FAILURES);
|
|
11
11
|
export function isAutoModeParseFailure(v) {
|
|
12
12
|
return AUTO_MODE_PARSE_FAILURE_SET.has(v);
|
|
13
13
|
}
|
|
14
|
-
export const AUTO_MODE_FALLBACK_CAUSES = ["error", "timeout", "parse_error"];
|
|
14
|
+
export const AUTO_MODE_FALLBACK_CAUSES = Object.freeze(["error", "timeout", "parse_error"]);
|
|
15
15
|
const AUTO_MODE_FALLBACK_CAUSE_SET = new Set(AUTO_MODE_FALLBACK_CAUSES);
|
|
16
16
|
export function isAutoModeFallbackCause(v) {
|
|
17
17
|
return AUTO_MODE_FALLBACK_CAUSE_SET.has(v);
|
|
18
18
|
}
|
|
19
|
-
export const AUTO_MODE_CLASSIFIER_FALLBACKS = ["main", "none"];
|
|
19
|
+
export const AUTO_MODE_CLASSIFIER_FALLBACKS = Object.freeze(["main", "none"]);
|
|
20
20
|
const AUTO_MODE_CLASSIFIER_FALLBACK_SET = new Set(AUTO_MODE_CLASSIFIER_FALLBACKS);
|
|
21
21
|
export function isAutoModeClassifierFallback(v) {
|
|
22
22
|
return AUTO_MODE_CLASSIFIER_FALLBACK_SET.has(v);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { uuidv7 } from "../internal/harness.js";
|
|
2
2
|
import { assertRetentionPolicy } from "./retention-policy.js";
|
|
3
|
-
export const REVIVED_ROW_CLEARED_FIELDS = [
|
|
3
|
+
export const REVIVED_ROW_CLEARED_FIELDS = Object.freeze([
|
|
4
4
|
"settledAt",
|
|
5
5
|
"stoppedBy",
|
|
6
6
|
"completionId",
|
|
@@ -16,7 +16,7 @@ export const REVIVED_ROW_CLEARED_FIELDS = [
|
|
|
16
16
|
"recentSteps",
|
|
17
17
|
"editedFiles",
|
|
18
18
|
"usage",
|
|
19
|
-
];
|
|
19
|
+
]);
|
|
20
20
|
export function clearRevivedRowTerminalPayload(record) {
|
|
21
21
|
for (const field of REVIVED_ROW_CLEARED_FIELDS)
|
|
22
22
|
delete record[field];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {} from "./ask-origin.js";
|
|
2
|
-
export const EXECUTION_OUTCOME_RECORD_WORDS = ["recorded", "already_recorded", "not_resolved", "absent"];
|
|
2
|
+
export const EXECUTION_OUTCOME_RECORD_WORDS = Object.freeze(["recorded", "already_recorded", "not_resolved", "absent"]);
|
|
3
3
|
export const EXECUTION_RECORD_LEAVES_ROW_UNRECORDED = {
|
|
4
4
|
recorded: false,
|
|
5
5
|
already_recorded: false,
|
|
@@ -1135,7 +1135,7 @@ export interface CheckpointState {
|
|
|
1135
1135
|
* revive the mode where the redeeming deployment denies it, and an `auto` row arms only where a face is
|
|
1136
1136
|
* wired. Absent on a task that declared nothing and inherited nothing (`default`). Rows written before this
|
|
1137
1137
|
* member carried `autoModeRequested` / `approverPosture` / a doctrine `shellGate`; the resume leg migrates
|
|
1138
|
-
* them once, announced (`resume.legacy_mode_seed_migrated`), and the next suspend writes this member. The migration is kept through 7.
|
|
1138
|
+
* them once, announced (`resume.legacy_mode_seed_migrated`), and the next suspend writes this member. The migration is kept through 7.38.x and removed in 7.39.0, which refuses a row still carrying these keys. */
|
|
1139
1139
|
permissionMode?: PermissionMode;
|
|
1140
1140
|
/** Beside a recorded `plan`: the declared word the leg had when a steer or the model's `EnterPlanMode` moved it into
|
|
1141
1141
|
* plan — the mode an approved or edited `plan_review` resumes under ({@link import("./mode-policy.js").modeRequestAfterResume}). */
|
|
@@ -3055,6 +3055,6 @@ export interface LegacyModeSeedMigration {
|
|
|
3055
3055
|
* - `shellGate`: absent ⇒ none; `"always"` ⇒ kept (a live key, not a retired encoding); `"off"` / `"classify"` ⇒
|
|
3056
3056
|
* dropped (no floor); anything else ⇒ refused (`resume.legacy_mode_seed`).
|
|
3057
3057
|
* Idempotent: a row the resume leg writes back carries `permissionMode` and the floor only, so a second read migrates nothing ("once" is per row).
|
|
3058
|
-
* Migration precedes any retired-key door, so a window row is read rather than refused. The window: this migration is kept through 7.
|
|
3058
|
+
* Migration precedes any retired-key door, so a window row is read rather than refused. The window: this migration is kept through 7.38.x and removed in 7.39.0, which refuses a row still carrying these keys — resume or abandon a row parked before 7.34.0 before upgrading to 7.39.0.
|
|
3059
3059
|
*/
|
|
3060
3060
|
export declare function migrateLegacyModeSeed(gate: object | undefined): LegacyModeSeedMigration;
|
|
@@ -74,7 +74,7 @@ const BIDI_BACKFILL_MAX_NODES = 512;
|
|
|
74
74
|
export const MAX_PENDING_STEER_CHARS = 16_000;
|
|
75
75
|
export const PENDING_STEER_QUEUE_BYTE_BUDGET_BYTES = 48_000;
|
|
76
76
|
export const MAX_PENDING_STEER_ENTRIES = Math.floor(PENDING_STEER_QUEUE_BYTE_BUDGET_BYTES / MAX_PENDING_STEER_CHARS);
|
|
77
|
-
export const PENDING_STEER_FROZEN_FIELDS = ["text", "trusted", "actor", "seq", "inputId", "priority"];
|
|
77
|
+
export const PENDING_STEER_FROZEN_FIELDS = Object.freeze(["text", "trusted", "actor", "seq", "inputId", "priority"]);
|
|
78
78
|
export function isPlainRecord(x) {
|
|
79
79
|
try {
|
|
80
80
|
if (x === null || typeof x !== "object" || Array.isArray(x))
|
|
@@ -500,7 +500,7 @@ export function validatePendingSteer(steer) {
|
|
|
500
500
|
}
|
|
501
501
|
export const MAX_ACTOR_FIELD_CHARS = 256;
|
|
502
502
|
export const MAX_STEER_INPUT_ID_CHARS = 128;
|
|
503
|
-
export const ACTOR_ASSERTION_FROZEN_FIELDS = ["id", "hostAsserted", "issuer"];
|
|
503
|
+
export const ACTOR_ASSERTION_FROZEN_FIELDS = Object.freeze(["id", "hostAsserted", "issuer"]);
|
|
504
504
|
function captureActorAssertion(actor) {
|
|
505
505
|
if (actor === null || typeof actor !== "object") {
|
|
506
506
|
throw new CheckpointError("steering.invalid_content", `actor must be an object carrying the attribution fields (got ${actor === null ? "null" : typeof actor})`);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const CHILD_CLAMP_SEATS = ["handsReadOnly", "interactiveTools", "readFace", "writeFace", "readDenyPatterns"];
|
|
1
|
+
export const CHILD_CLAMP_SEATS = Object.freeze(["handsReadOnly", "interactiveTools", "readFace", "writeFace", "readDenyPatterns"]);
|
|
2
2
|
export const CHILD_CLAMP_SEATS_NOT_CARRIED = Object.freeze({
|
|
3
3
|
toolPolicy: "not a clamp a child spec copies: a parent's denies reach its children through the ancestor-constraint chain the child's own prepare folds, not by putting the parent's policy object on the child seat",
|
|
4
4
|
shellGate: "travels on the inherited-gate lane (`InheritedGate.shellGate`, a trusted internals seat), not on the child spec — a spec-level copy would be a second source for the same clamp",
|
|
@@ -8,7 +8,7 @@ export const CHILD_CLAMP_SEATS_NOT_CARRIED = Object.freeze({
|
|
|
8
8
|
excludeTools: "roster control rather than containment: the lanes that copy a parent's roster do so beside these seats, and the workflow lane authors its child roster from the governance baseline instead of the host's",
|
|
9
9
|
deferTools: "roster control, same reading as `excludeTools` above",
|
|
10
10
|
});
|
|
11
|
-
export const ENGINE_CHILD_SPEC_CONSTRUCTORS = [
|
|
11
|
+
export const ENGINE_CHILD_SPEC_CONSTRUCTORS = Object.freeze([
|
|
12
12
|
"src/agents/subagent.ts#buildChildSpec",
|
|
13
13
|
"src/agents/subagent.ts#observerSpec",
|
|
14
14
|
"src/agents/subagent.ts#resumeSpec",
|
|
@@ -16,7 +16,7 @@ export const ENGINE_CHILD_SPEC_CONSTRUCTORS = [
|
|
|
16
16
|
"src/agents/verify.ts#verifierSpec",
|
|
17
17
|
"src/agents/verify.ts#fixLegSpec",
|
|
18
18
|
"src/orchestration/workflow-primitives.ts#workflowChildClamps",
|
|
19
|
-
];
|
|
19
|
+
]);
|
|
20
20
|
export function childClampSeats(source) {
|
|
21
21
|
return {
|
|
22
22
|
...(source.handsReadOnly === true ? { handsReadOnly: true } : {}),
|
package/dist/core/compliance.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const COMPLIANCE_CAPABILITIES = ["mcp_servers", "workflows", "web_fetch", "org_memory_mount"];
|
|
1
|
+
export const COMPLIANCE_CAPABILITIES = Object.freeze(["mcp_servers", "workflows", "web_fetch", "org_memory_mount"]);
|
|
2
2
|
export const BUILTIN_COMPLIANCE_DENIES = {
|
|
3
3
|
hipaa: ["web_fetch", "org_memory_mount"],
|
|
4
4
|
zdr: ["org_memory_mount"],
|
|
@@ -33,7 +33,7 @@ export const COMPACTION_TRIGGER_BUFFER_TOKENS = 13000;
|
|
|
33
33
|
export function contextEditFrontier(window) {
|
|
34
34
|
return Math.max(window - (CONTEXT_OUTPUT_RESERVE_TOKENS + COMPACTION_TRIGGER_BUFFER_TOKENS), Math.floor(window * EDIT_FRACTION));
|
|
35
35
|
}
|
|
36
|
-
export const MICRO_COMPACT_MACHINES = ["off", "cc"];
|
|
36
|
+
export const MICRO_COMPACT_MACHINES = Object.freeze(["off", "cc"]);
|
|
37
37
|
export const CC_DEFAULT_KEEP_RECENT_TOOL_RESULTS = 5;
|
|
38
38
|
export const MIN_CLEAR_SAVINGS_TOKENS = 20000;
|
|
39
39
|
const MEDIA_BLOCK_SAVINGS_TOKENS = 2000;
|