@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
package/dist/core/trace.d.ts
CHANGED
|
@@ -860,13 +860,14 @@ export type TraceEvent = {
|
|
|
860
860
|
} | {
|
|
861
861
|
/** A provider echo field was refused by {@link import("../brain/errors.js").PROVIDER_ECHO_SHAPE} (visible ASCII,
|
|
862
862
|
* 1–128 characters) and dropped: the response's `request-id` / `x-request-id` header values (`field:
|
|
863
|
-
* "requestId"`, read at connect — the id a failure would carry as `apiFailure.requestId`),
|
|
864
|
-
* its frames report (`field: "responseModel"`)
|
|
865
|
-
*
|
|
863
|
+
* "requestId"`, read at connect — the id a failure would carry as `apiFailure.requestId`), the model name
|
|
864
|
+
* its frames report (`field: "responseModel"`), or the word a refusal's error envelope states (`field:
|
|
865
|
+
* "apiErrorCode"`). One frame per provider response per field; the value itself is never carried
|
|
866
|
+
* (metadata-only). A count of these frames is this engine's drop count. */
|
|
866
867
|
kind: "brain.echo_dropped";
|
|
867
868
|
version: 1;
|
|
868
869
|
taskId: string;
|
|
869
|
-
field: "requestId" | "responseModel";
|
|
870
|
+
field: "requestId" | "responseModel" | "apiErrorCode";
|
|
870
871
|
ts: number;
|
|
871
872
|
} | {
|
|
872
873
|
/** C10 — a `preemptSignal` fired on a task that is NOT resource-suspend-eligible: the preempt is a
|
package/dist/core/types.d.ts
CHANGED
|
@@ -29,6 +29,6 @@ export { AUTO_MODE_DENY_SOURCES, isAutoModeDenySource } from "./runtime-caps.js"
|
|
|
29
29
|
export type { BackgroundChildEvent, DelegationLifecycleEvent } from "./delegation-frames.js";
|
|
30
30
|
export { __resetMalformedDelegationSeatAnnouncement, deliverDelegationLifecycle } from "./delegation-frames.js";
|
|
31
31
|
export type { ProjectMemoryLoad, ResumePreflightInfo, ResumePreflightVerdict, RunnerDeps } from "./runner-deps.js";
|
|
32
|
-
export type { EngineNotice, OwedUserInputAccount } from "./engine-notice.js";
|
|
33
|
-
export { __resetMalformedNoticeSeatAnnouncement, deliverEngineNotice, owedUserInputCounts, settleOwedUserInput, undrainedUserInputNotices } from "./engine-notice.js";
|
|
32
|
+
export type { EngineNotice, OwedUserInputAccount, UserSteerUndrainedCause } from "./engine-notice.js";
|
|
33
|
+
export { __resetMalformedNoticeSeatAnnouncement, deliverEngineNotice, owedUserInputCounts, settleOwedUserInput, undrainedUserInputNotices, USER_STEER_UNDRAINED_CAUSES } from "./engine-notice.js";
|
|
34
34
|
export type { AgentTool, Model, StreamFn, ThinkingLevel, ToolInputValidationContext, ToolInputVerdict };
|
package/dist/core/types.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { MODEL_ROLES } from "./model-seat.js";
|
|
2
2
|
export { AUTO_MODE_DENY_SOURCES, isAutoModeDenySource } from "./runtime-caps.js";
|
|
3
3
|
export { __resetMalformedDelegationSeatAnnouncement, deliverDelegationLifecycle } from "./delegation-frames.js";
|
|
4
|
-
export { __resetMalformedNoticeSeatAnnouncement, deliverEngineNotice, owedUserInputCounts, settleOwedUserInput, undrainedUserInputNotices } from "./engine-notice.js";
|
|
4
|
+
export { __resetMalformedNoticeSeatAnnouncement, deliverEngineNotice, owedUserInputCounts, settleOwedUserInput, undrainedUserInputNotices, USER_STEER_UNDRAINED_CAUSES } from "./engine-notice.js";
|
|
@@ -5,8 +5,8 @@ import { canonicalize } from "./canonical-json.js";
|
|
|
5
5
|
import { resolveCheckpointStore } from "./checkpoint-store.js";
|
|
6
6
|
import { isLiveQuestionFace } from "./ask-question.js";
|
|
7
7
|
import { AUTO_MODE_DENY_SOURCES, isAutoModeDenySource } from "./runtime-caps.js";
|
|
8
|
-
export const AUTO_MODE_ARM_REASONS = ["armed", "no_intent", "no_face", "denied", "resolver_fault"];
|
|
9
|
-
export const LSP_LANES = ["tool", "diagnostics", "tool_and_diagnostics"];
|
|
8
|
+
export const AUTO_MODE_ARM_REASONS = Object.freeze(["armed", "no_intent", "no_face", "denied", "resolver_fault"]);
|
|
9
|
+
export const LSP_LANES = Object.freeze(["tool", "diagnostics", "tool_and_diagnostics"]);
|
|
10
10
|
export function deriveHandsSeam(handsMounted) {
|
|
11
11
|
return handsMounted ? { mounted: true } : { mounted: false, reason: "no_execution_env" };
|
|
12
12
|
}
|
|
@@ -183,7 +183,7 @@ function relativeUnderDataRoot(path, roots) {
|
|
|
183
183
|
}
|
|
184
184
|
return null;
|
|
185
185
|
}
|
|
186
|
-
export const WRITE_PROTECTION_TARGET_VIEWS = ["spelling-only", "target"];
|
|
186
|
+
export const WRITE_PROTECTION_TARGET_VIEWS = Object.freeze(["spelling-only", "target"]);
|
|
187
187
|
export function compileWriteProtection(entries, opts) {
|
|
188
188
|
const rows = resolveWriteProtectedTable(entries);
|
|
189
189
|
if (rows.length === 0)
|
|
@@ -5,7 +5,7 @@ import { normalizeEngineSegments } from "../../core/untrusted-text.js";
|
|
|
5
5
|
import { AUTH_CARRIER_NAMES } from "../../brain/request-params.js";
|
|
6
6
|
import { isProviderEchoShape } from "../../brain/errors.js";
|
|
7
7
|
import { convertToLlm } from "./messages.js";
|
|
8
|
-
import { thrownText } from "../../core/thrown-value.js";
|
|
8
|
+
import { readMember, thrownText } from "../../core/thrown-value.js";
|
|
9
9
|
import { AgentHarnessError, CompactionError, SessionError, SYNTHETIC_MESSAGE_MODEL, toError, } from "./types.js";
|
|
10
10
|
const API_FAILURE_RECORD_MAX_CHARS = 2000;
|
|
11
11
|
function createUserMessage(text, images, provenance) {
|
|
@@ -784,7 +784,11 @@ export class AgentHarness {
|
|
|
784
784
|
}
|
|
785
785
|
}
|
|
786
786
|
async recordApiFailure(failure) {
|
|
787
|
-
const
|
|
787
|
+
const errorMessage = readMember(failure, "errorMessage");
|
|
788
|
+
const apiErrorStatus = readMember(failure, "apiErrorStatus");
|
|
789
|
+
const requestId = readMember(failure, "requestId");
|
|
790
|
+
const errorKind = readMember(failure, "errorKind");
|
|
791
|
+
const raw = typeof errorMessage === "string" ? errorMessage.trim() : undefined;
|
|
788
792
|
const detail = raw !== undefined && raw.length > API_FAILURE_RECORD_MAX_CHARS
|
|
789
793
|
? `${raw.slice(0, API_FAILURE_RECORD_MAX_CHARS)}… (truncated)`
|
|
790
794
|
: raw;
|
|
@@ -795,13 +799,13 @@ export class AgentHarness {
|
|
|
795
799
|
provider: failure.provider,
|
|
796
800
|
model: SYNTHETIC_MESSAGE_MODEL,
|
|
797
801
|
isApiErrorMessage: true,
|
|
798
|
-
...(
|
|
799
|
-
...(typeof
|
|
802
|
+
...(typeof apiErrorStatus === "number" ? { apiErrorStatus } : {}),
|
|
803
|
+
...(typeof requestId === "string" && isProviderEchoShape(requestId) ? { requestId } : {}),
|
|
800
804
|
usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },
|
|
801
805
|
usageMissing: true,
|
|
802
806
|
stopReason: "error",
|
|
803
|
-
...(
|
|
804
|
-
...(
|
|
807
|
+
...(typeof errorMessage === "string" ? { errorMessage } : {}),
|
|
808
|
+
...(errorKind === "length_empty" || errorKind === "degenerate" || errorKind === "input_too_long" ? { errorKind } : {}),
|
|
805
809
|
timestamp: failure.timestamp,
|
|
806
810
|
};
|
|
807
811
|
try {
|
|
@@ -1,12 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The request view's TOOL-TURN LAW — the structure every provider lane requires of a tool turn, restored on the
|
|
3
|
+
* way to the brain (never in the transcript).
|
|
4
|
+
*
|
|
5
|
+
* For every assistant message that carries tool calls:
|
|
6
|
+
* (i) the calls are a CONTIGUOUS TAIL of DISTINCT ids — every block that is not a call and stands after the first
|
|
7
|
+
* call (between two calls or after the last) moves ahead of the calls; blocks ahead of the first call, thinking
|
|
8
|
+
* first, keep their place (a stable partition: non-call blocks in their order, then the calls in theirs); a
|
|
9
|
+
* second call carrying an id the message already used is left out (every lane requires a request's call ids to
|
|
10
|
+
* be unique), so the message keeps the FIRST call per id and every result for that id answers it;
|
|
11
|
+
* (ii) the messages right after it are EXACTLY one result per call — a result recorded later in the transcript
|
|
12
|
+
* (behind a user message, a wake frame, another turn) is moved up into the batch, a second result for the
|
|
13
|
+
* same call is folded into the first (no recorded result is withheld), an interrupted close
|
|
14
|
+
* ({@link isInterruptedClose}) stands in only for a call with no other result (beside a recorded result it
|
|
15
|
+
* is void: it says only that none was recorded), and a call with no result at all is closed with the reconcile
|
|
16
|
+
* family's synthetic interrupted result ({@link interruptedResults}: the same text and `errorKind` a persisted
|
|
17
|
+
* reconcile writes);
|
|
18
|
+
* (iii) every result answers a call — a result with no EARLIER assistant message emitting its id (its call is gone,
|
|
19
|
+
* or it was recorded ahead of its call) answers nothing in this view and is left out. This is the one rule for
|
|
20
|
+
* that shape on every request builder (the harness's request lane and the side query alike).
|
|
21
|
+
*
|
|
22
|
+
* The three lanes carry the same requirement in three spellings — the Anthropic Messages API rejects a `tool_use`
|
|
23
|
+
* followed by any non-`tool_use` block (between two calls as after the last), or whose `tool_result` is not in the
|
|
24
|
+
* very next message; chat completions requires the `tool` messages right after the assistant's `tool_calls`; the
|
|
25
|
+
* Responses API requires a `function_call_output` for every `function_call` — and each brain's own builder only ever
|
|
26
|
+
* merged ADJACENT results. One transcript that
|
|
27
|
+
* breaks the structure (a result recorded late, a note written after the calls) was therefore rejected on every
|
|
28
|
+
* later request of its session. Holding the law here, once, at the provider boundary means the three brains read
|
|
29
|
+
* the canonical form, and a session already carrying a broken turn is repaired on its next request.
|
|
30
|
+
*
|
|
31
|
+
* Attribution (some gateways number calls per request, so an id legitimately recurs across turns): a result belongs
|
|
32
|
+
* to the NEAREST EARLIER assistant message that emitted its id — and to nothing else: its recorded tool name is not a
|
|
33
|
+
* key. That is the persisted reconcile's positional reading (a call is answered by a result standing after it and
|
|
34
|
+
* before the id's next use), so the two readers never disagree about which occurrence a result answers; a name-based
|
|
35
|
+
* reading (7.37.1) reached back past turns the model had already answered.
|
|
36
|
+
* An earlier occurrence of a reused id that has no result before the next use is therefore closed as
|
|
37
|
+
* interrupted (outcome unknown), never handed a later occurrence's success; every result after the last use is that
|
|
38
|
+
* use's (two or more are folded). A result with no earlier call carrying its id is left out (iii). Pure and
|
|
39
|
+
* deterministic (a moved result keeps its object; a synthesized one takes its assistant's timestamp), so the same
|
|
40
|
+
* transcript yields the same request bytes and the prefix cache holds.
|
|
41
|
+
* The close the view synthesizes carries NO tool-effect refinement: the view holds no tool table and no record of
|
|
42
|
+
* which calls started, so every call it closes reads the reconcile family's conservative "outcome unknown — verify"
|
|
43
|
+
* wording, whatever the tool. (The persisted reconcile refines with the run's tool effects — a read-only or
|
|
44
|
+
* idempotent call's close says it may simply be re-issued — and, on a live abort, with the calls it saw start.)
|
|
45
|
+
* Returns the SAME array when nothing needed restoring.
|
|
46
|
+
*/
|
|
47
|
+
import type { AssertAllKeysHandled } from "../../core/ask-origin.js";
|
|
48
|
+
import type { AssistantMessageDiagnostic } from "./diagnostics.js";
|
|
1
49
|
import type { Message } from "./types.js";
|
|
2
50
|
/** What the law restored — the `forms` of a `context.tool_turn_repaired` notice. */
|
|
3
|
-
export declare const TOOL_TURN_REPAIR_FORMS: readonly ["trailing_text", "late_result", "missing_result", "duplicate_result"];
|
|
51
|
+
export declare const TOOL_TURN_REPAIR_FORMS: readonly ["trailing_text", "late_result", "missing_result", "duplicate_result", "duplicate_call", "orphan_result"];
|
|
4
52
|
export type ToolTurnRepairForm = (typeof TOOL_TURN_REPAIR_FORMS)[number];
|
|
5
|
-
/**
|
|
53
|
+
/** Does the form leave recorded content out of the request (a call, a result), rather than move, fold or add it?
|
|
54
|
+
* A request that did is a lossy projection of the session — the harness never seeds a fork summary from it. */
|
|
55
|
+
export declare const TOOL_TURN_REPAIR_DROPS: {
|
|
56
|
+
readonly trailing_text: false;
|
|
57
|
+
readonly late_result: false;
|
|
58
|
+
readonly missing_result: false;
|
|
59
|
+
readonly duplicate_result: false;
|
|
60
|
+
readonly duplicate_call: true;
|
|
61
|
+
readonly orphan_result: true;
|
|
62
|
+
};
|
|
63
|
+
export type DropsTableCoversEveryForm = AssertAllKeysHandled<Exclude<ToolTurnRepairForm, keyof typeof TOOL_TURN_REPAIR_DROPS>>;
|
|
64
|
+
/**
|
|
65
|
+
* Why a tool turn reached the model incomplete — the `task.tool_turn_incomplete` notice's `detail.cause`, the person's
|
|
66
|
+
* view of facts the model is already told in the turn itself. Closed:
|
|
67
|
+
* · `truncated` — calls whose argument bytes were cut before they parsed: dropped, the model asked to re-issue them;
|
|
68
|
+
* · `unnamed` — calls that arrived with no tool name: dropped the same way;
|
|
69
|
+
* · `bad_frame` — provider stream frames that were not valid JSON: dropped, so the response may be missing content;
|
|
70
|
+
* · `missing_result_synthesized` — a call with no recorded result, closed in the request view as interrupted with its
|
|
71
|
+
* outcome unknown (the `missing_result` repair).
|
|
72
|
+
* The first three are a brain's stream facts ({@link StreamDropCause}), stamped on the turn's own message; the fourth is
|
|
73
|
+
* the request view's.
|
|
74
|
+
*/
|
|
75
|
+
export declare const TOOL_TURN_INCOMPLETE_CAUSES: readonly ["truncated", "unnamed", "bad_frame", "missing_result_synthesized"];
|
|
76
|
+
export type ToolTurnIncompleteCause = (typeof TOOL_TURN_INCOMPLETE_CAUSES)[number];
|
|
77
|
+
/** The causes a brain's stream parse finds — what a turn's own message can report. */
|
|
78
|
+
export type StreamDropCause = Exclude<ToolTurnIncompleteCause, "missing_result_synthesized">;
|
|
79
|
+
/** One cause a turn's stream dropped content for, and how many calls (or frames) it dropped. */
|
|
80
|
+
export interface StreamDrop {
|
|
81
|
+
readonly cause: StreamDropCause;
|
|
82
|
+
readonly count: number;
|
|
83
|
+
}
|
|
84
|
+
/** Stamp a turn's stream drops on its message (`AssistantMessage.diagnostics`); nothing for a turn that dropped none. */
|
|
85
|
+
export declare function stampStreamDrops(message: {
|
|
86
|
+
diagnostics?: AssistantMessageDiagnostic[];
|
|
87
|
+
}, drops: readonly StreamDrop[]): void;
|
|
88
|
+
/** The stream drops a message reports. A host brain's message is not trusted to be well-formed: an entry counts only
|
|
89
|
+
* with a closed-set cause and a positive integer count; anything else reads as no drop. */
|
|
90
|
+
export declare function streamDropsOf(message: {
|
|
91
|
+
readonly diagnostics?: unknown;
|
|
92
|
+
}): StreamDrop[];
|
|
93
|
+
/** One restoration: on one assistant message, or — for `orphan_result` — on the view as a whole. */
|
|
6
94
|
export interface ToolTurnRepair {
|
|
7
95
|
readonly form: ToolTurnRepairForm;
|
|
8
|
-
/** The calls concerned, in call order — for `trailing_text` every call of the message;
|
|
9
|
-
*
|
|
96
|
+
/** The calls concerned, in call order — for `trailing_text` every call of the message; for `duplicate_call` the
|
|
97
|
+
* ids a later call of the message repeated; for `orphan_result` the ids of the results left out, once each, in
|
|
98
|
+
* transcript order; otherwise the calls whose result was moved up, synthesized, or folded with a second one. */
|
|
10
99
|
readonly toolCallIds: readonly string[];
|
|
11
100
|
}
|
|
12
101
|
export interface ToolTurnView {
|
|
@@ -1,5 +1,48 @@
|
|
|
1
1
|
import { interruptedResultMessage, interruptedResults, isInterruptedClose } from "../../core/session-reconcile.js";
|
|
2
|
-
export const TOOL_TURN_REPAIR_FORMS = ["trailing_text", "late_result", "missing_result", "duplicate_result"];
|
|
2
|
+
export const TOOL_TURN_REPAIR_FORMS = Object.freeze(["trailing_text", "late_result", "missing_result", "duplicate_result", "duplicate_call", "orphan_result"]);
|
|
3
|
+
export const TOOL_TURN_REPAIR_DROPS = {
|
|
4
|
+
trailing_text: false,
|
|
5
|
+
late_result: false,
|
|
6
|
+
missing_result: false,
|
|
7
|
+
duplicate_result: false,
|
|
8
|
+
duplicate_call: true,
|
|
9
|
+
orphan_result: true,
|
|
10
|
+
};
|
|
11
|
+
export const TOOL_TURN_INCOMPLETE_CAUSES = Object.freeze(["truncated", "unnamed", "bad_frame", "missing_result_synthesized"]);
|
|
12
|
+
const STREAM_DROPS_DIAGNOSTIC = "stream_drops";
|
|
13
|
+
const STREAM_DROP_CAUSES = new Set(["truncated", "unnamed", "bad_frame"]);
|
|
14
|
+
export function stampStreamDrops(message, drops) {
|
|
15
|
+
if (drops.length === 0)
|
|
16
|
+
return;
|
|
17
|
+
message.diagnostics = [...(message.diagnostics ?? []), { type: STREAM_DROPS_DIAGNOSTIC, timestamp: Date.now(), details: { drops: drops.map(({ cause, count }) => ({ cause, count })) } }];
|
|
18
|
+
}
|
|
19
|
+
export function streamDropsOf(message) {
|
|
20
|
+
const out = [];
|
|
21
|
+
try {
|
|
22
|
+
const diagnostics = message.diagnostics;
|
|
23
|
+
if (!Array.isArray(diagnostics))
|
|
24
|
+
return out;
|
|
25
|
+
const entries = diagnostics;
|
|
26
|
+
for (const entry of entries) {
|
|
27
|
+
if (typeof entry !== "object" || entry === null || entry.type !== STREAM_DROPS_DIAGNOSTIC)
|
|
28
|
+
continue;
|
|
29
|
+
const drops = (entry.details ?? {}).drops;
|
|
30
|
+
if (!Array.isArray(drops))
|
|
31
|
+
continue;
|
|
32
|
+
const items = drops;
|
|
33
|
+
for (const d of items) {
|
|
34
|
+
const cause = d?.cause;
|
|
35
|
+
const count = d?.count;
|
|
36
|
+
if (typeof cause === "string" && STREAM_DROP_CAUSES.has(cause) && typeof count === "number" && Number.isInteger(count) && count > 0)
|
|
37
|
+
out.push({ cause: cause, count });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
3
46
|
function callsOf(m) {
|
|
4
47
|
return m.role === "assistant" && Array.isArray(m.content) ? m.content.filter((c) => c?.type === "toolCall") : [];
|
|
5
48
|
}
|
|
@@ -10,6 +53,7 @@ export function ensureToolTurnInvariants(messages) {
|
|
|
10
53
|
const sites = new Map();
|
|
11
54
|
const ownerOf = new Map();
|
|
12
55
|
const resultsOf = new Map();
|
|
56
|
+
const orphans = new Set();
|
|
13
57
|
messages.forEach((m, i) => {
|
|
14
58
|
if (m.role === "assistant") {
|
|
15
59
|
for (const call of callsOf(m)) {
|
|
@@ -23,8 +67,10 @@ export function ensureToolTurnInvariants(messages) {
|
|
|
23
67
|
if (m.role !== "toolResult")
|
|
24
68
|
return;
|
|
25
69
|
const all = sites.get(m.toolCallId) ?? [];
|
|
26
|
-
if (all.length === 0)
|
|
70
|
+
if (all.length === 0) {
|
|
71
|
+
orphans.add(i);
|
|
27
72
|
return;
|
|
73
|
+
}
|
|
28
74
|
const owner = all.at(-1);
|
|
29
75
|
ownerOf.set(i, owner);
|
|
30
76
|
const batch = resultsOf.get(owner);
|
|
@@ -36,7 +82,7 @@ export function ensureToolTurnInvariants(messages) {
|
|
|
36
82
|
const repairs = [];
|
|
37
83
|
const out = [];
|
|
38
84
|
messages.forEach((m, i) => {
|
|
39
|
-
if (ownerOf.has(i))
|
|
85
|
+
if (ownerOf.has(i) || orphans.has(i))
|
|
40
86
|
return;
|
|
41
87
|
const calls = callsOf(m);
|
|
42
88
|
if (calls.length === 0) {
|
|
@@ -44,16 +90,22 @@ export function ensureToolTurnInvariants(messages) {
|
|
|
44
90
|
return;
|
|
45
91
|
}
|
|
46
92
|
const assistant = m;
|
|
47
|
-
const firstCall = assistant.content.findIndex((c) => c?.type === "toolCall");
|
|
48
|
-
const trails = assistant.content.slice(firstCall).some((c) => c?.type !== "toolCall");
|
|
49
|
-
out.push(trails ? { ...assistant, content: [...assistant.content.filter((c) => c?.type !== "toolCall"), ...calls] } : assistant);
|
|
50
|
-
if (trails)
|
|
51
|
-
repairs.push({ form: "trailing_text", toolCallIds: calls.map((c) => c.id) });
|
|
52
93
|
const byId = new Map();
|
|
53
|
-
|
|
94
|
+
const repeated = [];
|
|
95
|
+
for (const call of calls) {
|
|
54
96
|
if (!byId.has(call.id))
|
|
55
97
|
byId.set(call.id, call);
|
|
98
|
+
else if (!repeated.includes(call.id))
|
|
99
|
+
repeated.push(call.id);
|
|
100
|
+
}
|
|
56
101
|
const ids = [...byId.keys()];
|
|
102
|
+
const firstCall = assistant.content.findIndex((c) => c?.type === "toolCall");
|
|
103
|
+
const trails = assistant.content.slice(firstCall).some((c) => c?.type !== "toolCall");
|
|
104
|
+
out.push(trails || repeated.length > 0 ? { ...assistant, content: [...assistant.content.filter((c) => c?.type !== "toolCall"), ...byId.values()] } : assistant);
|
|
105
|
+
if (trails)
|
|
106
|
+
repairs.push({ form: "trailing_text", toolCallIds: ids });
|
|
107
|
+
if (repeated.length > 0)
|
|
108
|
+
repairs.push({ form: "duplicate_call", toolCallIds: repeated });
|
|
57
109
|
const recorded = new Map();
|
|
58
110
|
for (const r of resultsOf.get(i) ?? []) {
|
|
59
111
|
const id = messages[r].toolCallId;
|
|
@@ -84,6 +136,8 @@ export function ensureToolTurnInvariants(messages) {
|
|
|
84
136
|
if (duplicate.length > 0)
|
|
85
137
|
repairs.push({ form: "duplicate_result", toolCallIds: inCallOrder(duplicate) });
|
|
86
138
|
});
|
|
139
|
+
if (orphans.size > 0)
|
|
140
|
+
repairs.push({ form: "orphan_result", toolCallIds: [...new Set([...orphans].map((i) => messages[i].toolCallId))] });
|
|
87
141
|
return repairs.length === 0 ? { messages, repairs } : { messages: out, repairs };
|
|
88
142
|
}
|
|
89
143
|
function foldResults(first, second) {
|
|
@@ -434,6 +434,17 @@ export interface AssistantMessage {
|
|
|
434
434
|
* as `0`.
|
|
435
435
|
*/
|
|
436
436
|
apiErrorStatus?: number;
|
|
437
|
+
/**
|
|
438
|
+
* The provider's own word for a REFUSED request, read structurally from its JSON error envelope (`error.code`, else
|
|
439
|
+
* `error.type`) — e.g. `invalid_request_error`, `context_length_exceeded`. Only meaningful together with
|
|
440
|
+
* {@link isApiErrorMessage}; provider vocabulary, never an engine closed set.
|
|
441
|
+
*
|
|
442
|
+
* PRESENCE: only beside a 4xx {@link apiErrorStatus} (the provider refused the request as sent) whose envelope stated
|
|
443
|
+
* such a word in the provider echo shape (visible ASCII, 1–128 characters). ABSENT otherwise — any other status, a
|
|
444
|
+
* plain-text or torn body, an envelope with neither member, or a word outside the shape (dropped whole, never
|
|
445
|
+
* truncated). The run's `terminal.detail.code` is this value.
|
|
446
|
+
*/
|
|
447
|
+
apiErrorCode?: string;
|
|
437
448
|
diagnostics?: AssistantMessageDiagnostic[];
|
|
438
449
|
usage: Usage;
|
|
439
450
|
/** TB 尸检 T1-5: the provider never delivered a usage frame for this message (e.g. a
|
package/dist/index.d.ts
CHANGED
|
@@ -63,8 +63,10 @@ export { MCP_FAILURE_KINDS, MCP_DELIVERY_VERDICTS, MCP_LIVENESS_STATES, classify
|
|
|
63
63
|
export { MCP_INJECTION_DROP_REASONS, MCP_INJECTION_DROP_TEXT, mcpInjectionDroppedNotice, type McpInjectionDropReason, type McpInjectionDropFacts } from "./core/mcp-injection-drop.js";
|
|
64
64
|
export { askUnresolvableNotice, type AskUnresolvableFacts } from "./core/ask-unresolvable-notice.js";
|
|
65
65
|
export { ASK_UNRESOLVABLE_CAUSES } from "./core/ask-unresolvable-notice.js";
|
|
66
|
+
export { USER_STEER_UNDRAINED_CAUSES, type UserSteerUndrainedCause } from "./core/engine-notice.js";
|
|
67
|
+
export { TOOL_TURN_INCOMPLETE_CAUSES, type ToolTurnIncompleteCause } from "./internal/llm.js";
|
|
66
68
|
export { DURABLE_MANDATE_SOURCES } from "./core/tool-policy.js";
|
|
67
|
-
export { TERMINAL_CAUSE_IS_REPLAYABLE } from "./core/terminal-cause.js";
|
|
69
|
+
export { TERMINAL_CAUSE_IS_REPLAYABLE, type TerminalFailureDetail } from "./core/terminal-cause.js";
|
|
68
70
|
export { RESERVED_AGENT_NAMES } from "./agents/subagent.js";
|
|
69
71
|
export { WORKFLOW_SIZE_GUIDELINE_AGENT_CAPS } from "./orchestration/workflow-size-guideline.js";
|
|
70
72
|
export { ENGINE_AUTHORITY_ENVELOPE_TAGS } from "./core/untrusted-text.js";
|
|
@@ -79,7 +81,7 @@ export { BUILTIN_COMPLIANCE_DENIES, COMPLIANCE_CAPABILITIES, WEB_FETCH_TOOL_NAME
|
|
|
79
81
|
export { admitMemoryScopes, foldAdmissionFreeze, type OwnOrgAdmissionVerdict, type MemoryAdmissionInput, type MemoryAdmissionOutcome, type MemoryAdmissionVerdict, type MemoryScopeAdmission, type MemoryScopeOrigin, type MemoryScopeRequest, } from "./core/memory-admission.js";
|
|
80
82
|
export { assertRetentionCapability, RETENTION_CASCADE_DOMAINS, RETENTION_CASCADE_EXEMPT, type ManagedRetentionCapability, type RetentionDeclaration, type RetentionDeclaring, type RetentionPolicy, type RetentionReceipt, } from "./core/retention.js";
|
|
81
83
|
export { GOVERNANCE_CODES, governanceRetryClass, TOOL_DECLARATION_CODES, type GovernanceCode, type GovernanceRetryClass, type ToolDeclarationCode } from "./core/governance-codes.js";
|
|
82
|
-
export { NOTICE_AUDIENCE, noticeAudienceOf, ENGINE_NOTICE_CODES, type EngineNoticeCode, type NoticeAudience } from "./core/governance-codes.js";
|
|
84
|
+
export { NOTICE_AUDIENCE, noticeAudienceOf, ENGINE_NOTICE_CODES, NOTICE_MINTER, type EngineNoticeCode, type NoticeAudience, type NoticeMinter } from "./core/governance-codes.js";
|
|
83
85
|
export { TtlSessionStore, type TtlSessionStoreOptions, type EvictPolicy } from "./core/session-store.js";
|
|
84
86
|
export { reconcileInterruptedSession, findOrphanToolCalls, type OrphanToolCall, type ReconcileReport, } from "./core/session-reconcile.js";
|
|
85
87
|
export { StoredSession, InMemorySessionRepo, InMemorySessionStorage, BaseSessionStorage, leafIdAfterEntry, validateEntriesForImport, StreamingImportValidator, boundedTail, SessionError, isSessionConflict, hasSessionFork, uuidv7, type Session, type SessionStore, type AcquiredSession, type SessionStoreSummary, type SessionStorage, type SessionRepo, type SessionMetadata, type SessionTreeEntry, type SessionWriteOptions, type SessionPlacement, type SessionPlacementRecord, type PlacedSessionRow, } from "./core/session.js";
|
|
@@ -191,7 +193,7 @@ export { createAllowDenyPolicy, createApprovalPolicy,
|
|
|
191
193
|
* `Parameters<typeof createApprovalPolicy>[0]["approve"]`. */
|
|
192
194
|
type ApprovalSeatOutcome, COARSE_SHELL_TOOLS, createCoarseCommandNamePolicy, createTranscriptIntegrityPolicy, createUnverifiableDeletePolicy, findUnverifiableRecursiveDelete, combinePolicies, wrapToolPolicy, decisionText, resolveAsk, toolPolicyNameSets, toolPolicyPathDenyRules, type ToolPolicyNameSets, type NamedToolPolicy, type ToolPolicyProjection, type ToolPolicyProjectionComponent, type ConstraintChainEntry, checkToolPolicyProjection, constraintChainEntryOf, constraintChainDigest, type ToolPolicy, type ToolCallRequest, type PermissionResult, type DecisionReason, screenApproverAttribution, APPROVER_ATTRIBUTION_MAX_CHARS, type OnAsk, type AskOutcome, type ResolvedAsk, type AskRequest, type AskDelegationProvenance, type AskRuleEvidence, type AskEvidenceAbsence, ASK_EVIDENCE_ABSENCE_VALUES, } from "./core/tool-policy.js";
|
|
193
195
|
export { type ReadRootGrantScreen } from "./core/read-root-grant-screen.js";
|
|
194
|
-
export { type AskOrigin, ASK_ORIGINS, isAskOrigin, ORIGIN_IMPLIES_REAL_APPROVAL, PERSISTED_RULE_MANDATES, type PersistedRuleMandate, isPersistedRuleMandate } from "./core/ask-origin.js";
|
|
196
|
+
export { type AskOrigin, ASK_ORIGINS, isAskOrigin, ORIGIN_IMPLIES_REAL_APPROVAL, PERSISTED_RULE_MANDATES, type PersistedRuleMandate, isPersistedRuleMandate, screenAskClassMembers } from "./core/ask-origin.js";
|
|
195
197
|
export { PERMISSION_MODES, type PermissionMode, isPermissionMode, PERMISSION_MODE_RANK, clampPermissionMode, ASK_CLASSES, type AskClass, isAskClass, MODE_ARBITRATION, type ModeArbitrationRow, RELEASABLE_ASK_CLASSES, MODE_RELEASE_REASONS, type ModeReleaseReason, isModeReleaseReason, RRA_EXPLAINERS, classifyAsk, foldArbitrationRow, type AskClassification, type AskClassFacts, type ToolMarkSource, arbitrateByMode, type Arbitration, fileCommandOptionsSentence } from "./core/ask-origin.js";
|
|
196
198
|
export { modePolicyOf, type ModePolicy, PERMISSION_MODE_FOLD_REASONS, type PermissionModeFoldReason, type PermissionModeReceipt, ACCEPT_EDITS_FILE_COMMANDS, modeAcceptsFileCommand } from "./core/mode-policy.js";
|
|
197
199
|
export { readDenyClassifierRules, renderClassifierDenyRules, type DerivedDenyRule } from "./core/auto-mode-prompt.js";
|
package/dist/index.js
CHANGED
|
@@ -49,6 +49,8 @@ export { MCP_FAILURE_KINDS, MCP_DELIVERY_VERDICTS, MCP_LIVENESS_STATES, classify
|
|
|
49
49
|
export { MCP_INJECTION_DROP_REASONS, MCP_INJECTION_DROP_TEXT, mcpInjectionDroppedNotice } from "./core/mcp-injection-drop.js";
|
|
50
50
|
export { askUnresolvableNotice } from "./core/ask-unresolvable-notice.js";
|
|
51
51
|
export { ASK_UNRESOLVABLE_CAUSES } from "./core/ask-unresolvable-notice.js";
|
|
52
|
+
export { USER_STEER_UNDRAINED_CAUSES } from "./core/engine-notice.js";
|
|
53
|
+
export { TOOL_TURN_INCOMPLETE_CAUSES } from "./internal/llm.js";
|
|
52
54
|
export { DURABLE_MANDATE_SOURCES } from "./core/tool-policy.js";
|
|
53
55
|
export { TERMINAL_CAUSE_IS_REPLAYABLE } from "./core/terminal-cause.js";
|
|
54
56
|
export { RESERVED_AGENT_NAMES } from "./agents/subagent.js";
|
|
@@ -65,7 +67,7 @@ export { BUILTIN_COMPLIANCE_DENIES, COMPLIANCE_CAPABILITIES, WEB_FETCH_TOOL_NAME
|
|
|
65
67
|
export { admitMemoryScopes, foldAdmissionFreeze, } from "./core/memory-admission.js";
|
|
66
68
|
export { assertRetentionCapability, RETENTION_CASCADE_DOMAINS, RETENTION_CASCADE_EXEMPT, } from "./core/retention.js";
|
|
67
69
|
export { GOVERNANCE_CODES, governanceRetryClass, TOOL_DECLARATION_CODES } from "./core/governance-codes.js";
|
|
68
|
-
export { NOTICE_AUDIENCE, noticeAudienceOf, ENGINE_NOTICE_CODES } from "./core/governance-codes.js";
|
|
70
|
+
export { NOTICE_AUDIENCE, noticeAudienceOf, ENGINE_NOTICE_CODES, NOTICE_MINTER } from "./core/governance-codes.js";
|
|
69
71
|
export { TtlSessionStore } from "./core/session-store.js";
|
|
70
72
|
export { reconcileInterruptedSession, findOrphanToolCalls, } from "./core/session-reconcile.js";
|
|
71
73
|
export { StoredSession, InMemorySessionRepo, InMemorySessionStorage, BaseSessionStorage, leafIdAfterEntry, validateEntriesForImport, StreamingImportValidator, boundedTail, SessionError, isSessionConflict, hasSessionFork, uuidv7, } from "./core/session.js";
|
|
@@ -156,7 +158,7 @@ export { resolveAutonomousLoopPrompt, AUTONOMOUS_LOOP_PREAMBLE, AUTONOMOUS_LOOP_
|
|
|
156
158
|
export { tightenTaskSpec, TaskSpecTightenError } from "./core/tighten-task-spec.js";
|
|
157
159
|
export { createAllowDenyPolicy, createApprovalPolicy, COARSE_SHELL_TOOLS, createCoarseCommandNamePolicy, createTranscriptIntegrityPolicy, createUnverifiableDeletePolicy, findUnverifiableRecursiveDelete, combinePolicies, wrapToolPolicy, decisionText, resolveAsk, toolPolicyNameSets, toolPolicyPathDenyRules, checkToolPolicyProjection, constraintChainEntryOf, constraintChainDigest, screenApproverAttribution, APPROVER_ATTRIBUTION_MAX_CHARS, ASK_EVIDENCE_ABSENCE_VALUES, } from "./core/tool-policy.js";
|
|
158
160
|
export {} from "./core/read-root-grant-screen.js";
|
|
159
|
-
export { ASK_ORIGINS, isAskOrigin, ORIGIN_IMPLIES_REAL_APPROVAL, PERSISTED_RULE_MANDATES, isPersistedRuleMandate } from "./core/ask-origin.js";
|
|
161
|
+
export { ASK_ORIGINS, isAskOrigin, ORIGIN_IMPLIES_REAL_APPROVAL, PERSISTED_RULE_MANDATES, isPersistedRuleMandate, screenAskClassMembers } from "./core/ask-origin.js";
|
|
160
162
|
export { PERMISSION_MODES, isPermissionMode, PERMISSION_MODE_RANK, clampPermissionMode, ASK_CLASSES, isAskClass, MODE_ARBITRATION, RELEASABLE_ASK_CLASSES, MODE_RELEASE_REASONS, isModeReleaseReason, RRA_EXPLAINERS, classifyAsk, foldArbitrationRow, arbitrateByMode, fileCommandOptionsSentence } from "./core/ask-origin.js";
|
|
161
163
|
export { modePolicyOf, PERMISSION_MODE_FOLD_REASONS, ACCEPT_EDITS_FILE_COMMANDS, modeAcceptsFileCommand } from "./core/mode-policy.js";
|
|
162
164
|
export { readDenyClassifierRules, renderClassifierDenyRules } from "./core/auto-mode-prompt.js";
|
package/dist/internal/llm.d.ts
CHANGED
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* design/118 ①②: the layer is now first-party (`src/engine/llm/`, naturalized out of the vendored
|
|
5
5
|
* llm-core); the facade stays so consumers never notice which side a symbol lives on.
|
|
6
6
|
*/
|
|
7
|
-
export { createAssistantMessageEventStream, ensureToolTurnInvariants, snapshotActorAssertion, stripEngineMetadata } from "../engine/llm/index.js";
|
|
8
|
-
export type { ActorAssertion, AnthropicMessagesCompat, OpenAICompletionsCompat, OpenAIResponsesCompat, AssistantMessage, AssistantMessageDiagnostic, AssistantMessageEvent, CompleteSimpleFn, Context, DocumentContent, ImageContent, Message, Model, ResilienceOptions, RouteAdjudication, RouteCredential, RouteCredentialSource, RoutePairingConfig, RoutePairingPosture, RouteRefusalCode, RouteRefusalDetail, SimpleStreamOptions, StallTimeouts, StopReason, StreamFn, TextContent, ThinkingContent, Tool, ToolCall, ToolResultMessage, ToolTurnRepair, Usage, UserMessage, } from "../engine/llm/index.js";
|
|
7
|
+
export { createAssistantMessageEventStream, ensureToolTurnInvariants, snapshotActorAssertion, stampStreamDrops, streamDropsOf, stripEngineMetadata, TOOL_TURN_INCOMPLETE_CAUSES, TOOL_TURN_REPAIR_DROPS } from "../engine/llm/index.js";
|
|
8
|
+
export type { ActorAssertion, AnthropicMessagesCompat, OpenAICompletionsCompat, OpenAIResponsesCompat, AssistantMessage, AssistantMessageDiagnostic, AssistantMessageEvent, CompleteSimpleFn, Context, DocumentContent, ImageContent, Message, Model, ResilienceOptions, RouteAdjudication, RouteCredential, RouteCredentialSource, RoutePairingConfig, RoutePairingPosture, RouteRefusalCode, RouteRefusalDetail, SimpleStreamOptions, StallTimeouts, StopReason, StreamFn, TextContent, ThinkingContent, Tool, ToolCall, ToolResultMessage, StreamDrop, StreamDropCause, ToolTurnIncompleteCause, ToolTurnRepair, Usage, UserMessage, } from "../engine/llm/index.js";
|
package/dist/internal/llm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { createAssistantMessageEventStream, ensureToolTurnInvariants, snapshotActorAssertion, stripEngineMetadata } from "../engine/llm/index.js";
|
|
1
|
+
export { createAssistantMessageEventStream, ensureToolTurnInvariants, snapshotActorAssertion, stampStreamDrops, streamDropsOf, stripEngineMetadata, TOOL_TURN_INCOMPLETE_CAUSES, TOOL_TURN_REPAIR_DROPS } from "../engine/llm/index.js";
|
|
@@ -15,7 +15,7 @@ export class WorkflowModelNotAllowedError extends Error {
|
|
|
15
15
|
this.name = "WorkflowModelNotAllowedError";
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
export const WHITELIST_KEYS = [
|
|
18
|
+
export const WHITELIST_KEYS = Object.freeze([
|
|
19
19
|
"objective",
|
|
20
20
|
"modelName",
|
|
21
21
|
"thinking",
|
|
@@ -25,7 +25,7 @@ export const WHITELIST_KEYS = [
|
|
|
25
25
|
"readFace",
|
|
26
26
|
"writeFace",
|
|
27
27
|
"readDenyPatterns",
|
|
28
|
-
];
|
|
28
|
+
]);
|
|
29
29
|
const WHITELIST_KEY_SET = new Set(WHITELIST_KEYS);
|
|
30
30
|
export const SPEC_KEY_ALIASES = new Map([["model", "modelName"]]);
|
|
31
31
|
export const STRIPPED_KEYS_NOTICE_CODE = "workflow.governance_key_stripped";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export const PARK_TRUTH_UNREADABLE_REASONS = ["store_threw", "record_missing", "record_not_terminal", "parks_unreadable", "admission_incomplete", "checkpoint_store_threw", "capability_not_armed"];
|
|
2
|
-
export const PARK_NOT_PENDING_STATUSES = ["resolved", "expired", "absent"];
|
|
1
|
+
export const PARK_TRUTH_UNREADABLE_REASONS = Object.freeze(["store_threw", "record_missing", "record_not_terminal", "parks_unreadable", "admission_incomplete", "checkpoint_store_threw", "capability_not_armed"]);
|
|
2
|
+
export const PARK_NOT_PENDING_STATUSES = Object.freeze(["resolved", "expired", "absent"]);
|
|
3
3
|
export class WorkflowBudgetExceededError extends Error {
|
|
4
4
|
spent;
|
|
5
5
|
total;
|
package/dist/shell/lex.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const SHELL_LEX_DIALECT = "bash";
|
|
2
|
-
export const QUOTE_KINDS = ["'", '"', "$'", '$"', "\\"];
|
|
3
|
-
export const EXPANSION_KINDS = ["parameter", "command", "process", "arithmetic", "tilde", "brace", "glob"];
|
|
4
|
-
export const UNRESOLVED_REASONS = ["ansi_c_escape", "locale_string", "parameter_text", "subscript_text", "compound_array_value"];
|
|
2
|
+
export const QUOTE_KINDS = Object.freeze(["'", '"', "$'", '$"', "\\"]);
|
|
3
|
+
export const EXPANSION_KINDS = Object.freeze(["parameter", "command", "process", "arithmetic", "tilde", "brace", "glob"]);
|
|
4
|
+
export const UNRESOLVED_REASONS = Object.freeze(["ansi_c_escape", "locale_string", "parameter_text", "subscript_text", "compound_array_value"]);
|
|
5
5
|
export const UNRESOLVED_SENTENCE = {
|
|
6
6
|
ansi_c_escape: "an ANSI-C quoted word carries an escape this lexer does not fold",
|
|
7
7
|
locale_string: "a locale-translated string carries text this lexer does not read",
|
|
@@ -9,7 +9,7 @@ export const UNRESOLVED_SENTENCE = {
|
|
|
9
9
|
subscript_text: "a subscript carries text this lexer does not read",
|
|
10
10
|
compound_array_value: "a compound assignment value is a list this lexer does not read",
|
|
11
11
|
};
|
|
12
|
-
export const PARSE_FAILURE_REASONS = [
|
|
12
|
+
export const PARSE_FAILURE_REASONS = Object.freeze([
|
|
13
13
|
"unterminated_single_quote",
|
|
14
14
|
"unterminated_double_quote",
|
|
15
15
|
"unterminated_ansi_c",
|
|
@@ -23,7 +23,7 @@ export const PARSE_FAILURE_REASONS = [
|
|
|
23
23
|
"redirect_without_target",
|
|
24
24
|
"heredoc_without_delimiter",
|
|
25
25
|
"heredoc_delimiter_expands",
|
|
26
|
-
];
|
|
26
|
+
]);
|
|
27
27
|
export const PARSE_FAILURE_SENTENCE = {
|
|
28
28
|
unterminated_single_quote: "a single-quoted word never closes",
|
|
29
29
|
unterminated_double_quote: "a double-quoted word never closes",
|
|
@@ -39,7 +39,7 @@ export const PARSE_FAILURE_SENTENCE = {
|
|
|
39
39
|
heredoc_without_delimiter: "a here-document operator names no delimiter",
|
|
40
40
|
heredoc_delimiter_expands: "a here-document delimiter is not a plain word",
|
|
41
41
|
};
|
|
42
|
-
export const BASH_ONLY_CONSTRUCTS = [
|
|
42
|
+
export const BASH_ONLY_CONSTRUCTS = Object.freeze([
|
|
43
43
|
"ansi_c_quoting",
|
|
44
44
|
"locale_string",
|
|
45
45
|
"append_assignment",
|
|
@@ -50,7 +50,7 @@ export const BASH_ONLY_CONSTRUCTS = [
|
|
|
50
50
|
"redirect_both",
|
|
51
51
|
"pipe_both",
|
|
52
52
|
"brace_expansion",
|
|
53
|
-
];
|
|
53
|
+
]);
|
|
54
54
|
export const ANSI_C_ESCAPES = {
|
|
55
55
|
a: "\x07",
|
|
56
56
|
b: "\b",
|
|
@@ -89,7 +89,7 @@ function launcherOptionStep(row, tok) {
|
|
|
89
89
|
return 1;
|
|
90
90
|
return undefined;
|
|
91
91
|
}
|
|
92
|
-
export const PROGRAM_POSITION_REFUSAL_KINDS = ["option_at_program_position", "control_syntax_at_program_position"];
|
|
92
|
+
export const PROGRAM_POSITION_REFUSAL_KINDS = Object.freeze(["option_at_program_position", "control_syntax_at_program_position"]);
|
|
93
93
|
export function readProgramPosition(words) {
|
|
94
94
|
const folded = words.map((w) => w.folded);
|
|
95
95
|
const controlWords = [];
|
|
@@ -172,7 +172,7 @@ export function argvReentryUnjudged(pos, acceptedTargets) {
|
|
|
172
172
|
const runs = pos.program?.basename ?? (pos.runsDefaultProgram ? ARGV_REENTRY_DEFAULT_PROGRAM : undefined);
|
|
173
173
|
return runs === undefined || !acceptedTargets.has(runs);
|
|
174
174
|
}
|
|
175
|
-
export const SHELL_SCAN_DECLINES = ["unreadable_program_position", "stream_fed_operands"];
|
|
175
|
+
export const SHELL_SCAN_DECLINES = Object.freeze(["unreadable_program_position", "stream_fed_operands"]);
|
|
176
176
|
export function programPositionRunsShell(pos, shellProgram) {
|
|
177
177
|
if (pos.refusal !== undefined)
|
|
178
178
|
return pos.refusal.kind === "control_syntax_at_program_position" && pos.refusal.runsShell === true;
|
|
@@ -2,6 +2,7 @@ import { Type } from "typebox";
|
|
|
2
2
|
import type { ExecutionEnv } from "../../internal/harness-types.js";
|
|
3
3
|
import { type FsViolation, type ReadFileState } from "./safety.js";
|
|
4
4
|
import { type DecodedTextFile } from "./encoding.js";
|
|
5
|
+
import { type HomeViewsCarrier } from "./read-deny-home.js";
|
|
5
6
|
import { type ImageDownsampler } from "../../core/mcp.js";
|
|
6
7
|
import { type EngineNotice } from "../../core/types.js";
|
|
7
8
|
/**
|
|
@@ -543,7 +544,7 @@ export declare function enoentMessage(env: ExecutionEnv, key: string, cwd: strin
|
|
|
543
544
|
matchPath(path: string): {
|
|
544
545
|
pattern: string;
|
|
545
546
|
} | null;
|
|
546
|
-
}): Promise<string>;
|
|
547
|
+
} & HomeViewsCarrier): Promise<string>;
|
|
547
548
|
/** Per-task mutable working directory shared by the shell and the path-taking fs tools.
|
|
548
549
|
* Holds the RAW path (never canonicalized): bash `cd` updates `current`, and the fs tools resolve relative
|
|
549
550
|
* paths against it. Containment is still enforced per-op by resolveKey (canonicalize + within), so a `cd`
|
|
@@ -345,7 +345,7 @@ export function applyContextShrinkToReadFileState(state, shrink) {
|
|
|
345
345
|
export async function enoentMessage(env, key, cwd, signal, readDeny) {
|
|
346
346
|
let msg = `File does not exist. Note: your current working directory is ${cwd}.`;
|
|
347
347
|
const sep = Math.max(key.lastIndexOf("/"), key.lastIndexOf("\\"));
|
|
348
|
-
const views = readDeny !== undefined ? homeViewsOf(env, signal) : undefined;
|
|
348
|
+
const views = readDeny !== undefined ? homeViewsOf(env, readDeny, signal) : undefined;
|
|
349
349
|
const denied = async (path, leaf) => {
|
|
350
350
|
if (readDeny === undefined || views === undefined)
|
|
351
351
|
return false;
|
package/dist/tools/fs/index.d.ts
CHANGED
|
@@ -186,17 +186,24 @@ export interface HandsToolkitOptions {
|
|
|
186
186
|
* time (never silently ignored). Deployment seat ONLY, same clamp argument as the tiers key. */
|
|
187
187
|
readDenyBuiltinExclude?: readonly string[];
|
|
188
188
|
/** The spellings of the execution environment's home a home-anchored deny row (`~/…`) is placed under
|
|
189
|
-
* ({@link import("./read-deny-home.js").readDenyHomesOf}: the declared home and
|
|
190
|
-
* strings only — any other shape throws at wiring time, naming the seat. The Runner passes the
|
|
191
|
-
* was compiled with.
|
|
189
|
+
* ({@link import("./read-deny-home.js").readDenyHomesOf}: the declared home and the account home, each with its canonical
|
|
190
|
+
* spelling). Absolute path strings only — any other shape throws at wiring time, naming the seat. The Runner passes the
|
|
191
|
+
* spellings its own judge was compiled with. A list given here is the band's home set as is: the account database is
|
|
192
|
+
* not asked and no home is added (each listed home is anchored at its spelling and, where the environment answers one,
|
|
193
|
+
* its canonical spelling), and the band's home views (a path spelled through a firmlink or a bind mount of a home,
|
|
194
|
+
* judged at the home) read this list and the environment's declared home; an entry that is not the declared home is probed once,
|
|
195
|
+
* under a short bound of its own, and a probe of it that fails costs that entry alone. */
|
|
192
196
|
readDenyHomes?: readonly string[];
|
|
193
197
|
/** Where each home-anchored row's literal head leads beyond the home's spellings
|
|
194
198
|
* ({@link import("./read-deny-home.js").readDenyHomeLinksOf}, keyed by the row's pattern) — the Runner passes the
|
|
195
199
|
* locations its own judge was compiled with, so the band and the gate judge one placement.
|
|
196
200
|
* Unless a mount carries both, the band resolves the placement itself the way the Runner does (the homes it carries
|
|
197
|
-
* are
|
|
198
|
-
*
|
|
199
|
-
* rows held anywhere.
|
|
201
|
+
* are its home set — the account is not asked and no home is added;
|
|
202
|
+
* {@link import("./read-deny-home.js").placeReadDenyAtHome}), and its read tools (Read / Grep / Glob / RepoMap) wait
|
|
203
|
+
* for that placement before they judge anything. A placement that fails leaves the home-anchored rows held anywhere.
|
|
204
|
+
* Carrying both is the engine's own handoff of ONE placement — its home views travel with it — so
|
|
205
|
+
* `readDenyHomes` must then be the very list that placement returned: any other list (a copy) holds the home-anchored
|
|
206
|
+
* rows at every location and is named on `console.warn`. */
|
|
200
207
|
readDenyHomeLinks?: ReadonlyMap<string, readonly string[]>;
|
|
201
208
|
/** The permission-rule rows of the deny table ({@link import("./read-deny.js").PathRuleDenyRow}, `ToolPolicy.pathDenyRules`):
|
|
202
209
|
* the read-face rows join the structured read faces' judge beside the segment rows. The Runner passes the leg's own. */
|