@sema-agent/core 7.52.0 → 7.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +194 -0
- package/README.md +3 -1
- package/dist/agents/cross-session-envelope.d.ts +8 -0
- package/dist/agents/cross-session-envelope.js +6 -0
- package/dist/agents/cross-session-judge.d.ts +21 -1
- package/dist/agents/cross-session-judge.js +8 -0
- package/dist/agents/cross-session-ref.d.ts +5 -0
- package/dist/agents/cross-session-ref.js +1 -0
- package/dist/agents/org-delivery-gate.d.ts +122 -0
- package/dist/agents/org-delivery-gate.js +69 -0
- package/dist/agents/peer-held-queue.d.ts +9 -4
- package/dist/agents/peer-held-queue.js +6 -5
- package/dist/agents/peer-session-drain.d.ts +35 -5
- package/dist/agents/peer-session-drain.js +271 -180
- package/dist/agents/read-inbox-tool.d.ts +7 -0
- package/dist/agents/read-inbox-tool.js +5 -1
- package/dist/agents/subagent.d.ts +3 -0
- package/dist/agents/subagent.js +99 -72
- package/dist/agents/tool-filter.d.ts +18 -0
- package/dist/agents/tool-filter.js +6 -0
- package/dist/brain/anthropic.d.ts +6 -1
- package/dist/brain/anthropic.js +4 -4
- package/dist/brain/model-presets.js +2 -1
- package/dist/brain/route-adjudicator.d.ts +6 -0
- package/dist/brain/routing.d.ts +24 -1
- package/dist/brain/routing.js +54 -19
- package/dist/brain/timeout.js +5 -4
- package/dist/core/a2a.d.ts +5 -2
- package/dist/core/a2a.js +30 -13
- package/dist/core/allow-entry.d.ts +2 -1
- package/dist/core/allow-entry.js +2 -2
- package/dist/core/auto-compaction.d.ts +57 -0
- package/dist/core/auto-compaction.js +28 -2
- package/dist/core/checkpoint-store.d.ts +29 -20
- package/dist/core/checkpoint-store.js +3 -3
- package/dist/core/compliance.js +3 -1
- package/dist/core/effective-path-target.d.ts +25 -6
- package/dist/core/effective-path-target.js +24 -2
- package/dist/core/engine-notice.d.ts +13 -2
- package/dist/core/gate-fold.js +3 -2
- package/dist/core/gate-lanes.js +11 -13
- package/dist/core/gate-outcome.d.ts +11 -6
- package/dist/core/governance-codes.d.ts +3 -1
- package/dist/core/governance-codes.js +3 -0
- package/dist/core/hands-band-screen.d.ts +7 -0
- package/dist/core/hands-band-screen.js +32 -0
- package/dist/core/hooks.d.ts +7 -5
- package/dist/core/hooks.js +5 -3
- package/dist/core/locked-config.d.ts +84 -32
- package/dist/core/locked-config.js +128 -42
- package/dist/core/mcp-probe.js +1 -1
- package/dist/core/mcp-server-spec.d.ts +88 -10
- package/dist/core/mcp-server-spec.js +183 -33
- package/dist/core/mcp.d.ts +21 -14
- package/dist/core/mcp.js +55 -51
- package/dist/core/memory-engine/engine.d.ts +14 -19
- package/dist/core/memory-engine/engine.js +7 -5
- package/dist/core/mode-policy.d.ts +3 -18
- package/dist/core/mode-policy.js +2 -16
- package/dist/core/mods/kernel/dispatch.js +13 -15
- package/dist/core/mods/kernel/events.d.ts +9 -6
- package/dist/core/mods/kernel/events.js +2 -2
- package/dist/core/mods/kernel/receive.d.ts +39 -10
- package/dist/core/mods/kernel/receive.js +119 -54
- package/dist/core/mods/kernel/site-rules.d.ts +80 -15
- package/dist/core/mods/kernel/site-rules.js +232 -40
- package/dist/core/mods/stations.d.ts +0 -6
- package/dist/core/mods/stations.js +0 -7
- package/dist/core/mounted-mcp.d.ts +57 -0
- package/dist/core/mounted-mcp.js +71 -2
- package/dist/core/own-property-receipt.d.ts +13 -0
- package/dist/core/own-property-receipt.js +3 -1
- package/dist/core/parent-spec-seat.d.ts +2 -2
- package/dist/core/permission-rule-model.d.ts +58 -9
- package/dist/core/permission-rule-model.js +81 -7
- package/dist/core/permission-rule-org.d.ts +163 -33
- package/dist/core/permission-rule-org.js +205 -71
- package/dist/core/permission-rules.d.ts +7 -1
- package/dist/core/permission-rules.js +37 -8
- package/dist/core/retention.js +7 -2
- package/dist/core/retired-keys.d.ts +8 -2
- package/dist/core/retired-keys.js +12 -1
- package/dist/core/roles.js +60 -10
- package/dist/core/rule-lane-reads.js +1 -1
- package/dist/core/runner/contracts.d.ts +1 -0
- package/dist/core/runner/gate-exit.js +4 -3
- package/dist/core/runner/mcp-redial.d.ts +52 -10
- package/dist/core/runner/mcp-redial.js +38 -9
- package/dist/core/runner/permission-rule-lanes.d.ts +5 -2
- package/dist/core/runner/permission-rule-lanes.js +22 -10
- package/dist/core/runner/person-path-rows.d.ts +3 -1
- package/dist/core/runner/person-path-rows.js +2 -2
- package/dist/core/runner/prepare-config-doors.d.ts +48 -2
- package/dist/core/runner/prepare-config-doors.js +161 -145
- package/dist/core/runner/prepare-defer-classify.js +4 -7
- package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
- package/dist/core/runner/prepare-delegation-surface.js +7 -5
- package/dist/core/runner/prepare-hands-readface.d.ts +1 -1
- package/dist/core/runner/prepare-hands-readface.js +2 -1
- package/dist/core/runner/prepare-inherited-gate.js +2 -2
- package/dist/core/runner/prepare-listings.d.ts +1 -1
- package/dist/core/runner/prepare-listings.js +4 -2
- package/dist/core/runner/prepare-memory-engine-session.d.ts +0 -6
- package/dist/core/runner/prepare-memory-engine-session.js +19 -6
- package/dist/core/runner/prepare-memory.d.ts +3 -2
- package/dist/core/runner/prepare-memory.js +6 -2
- package/dist/core/runner/prepare-offload-wrappers.d.ts +4 -4
- package/dist/core/runner/prepare-offload-wrappers.js +2 -1
- package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
- package/dist/core/runner/prepare-policy-chain.js +12 -12
- package/dist/core/runner/prepare-project-context.d.ts +1 -1
- package/dist/core/runner/prepare-project-context.js +6 -4
- package/dist/core/runner/prepare-prompt-assembly.d.ts +1 -1
- package/dist/core/runner/prepare-prompt-assembly.js +20 -16
- package/dist/core/runner/prepare-prompt-inputs.d.ts +12 -6
- package/dist/core/runner/prepare-prompt-inputs.js +6 -3
- package/dist/core/runner/prepare-protocol-tools.d.ts +7 -5
- package/dist/core/runner/prepare-protocol-tools.js +19 -12
- package/dist/core/runner/prepare-question-face.d.ts +4 -2
- package/dist/core/runner/prepare-question-face.js +4 -3
- package/dist/core/runner/prepare-task.js +10 -10
- package/dist/core/runner/prepare-wiring-manifest.d.ts +8 -3
- package/dist/core/runner/prepare-wiring-manifest.js +8 -5
- package/dist/core/runner/resume-admission.d.ts +4 -1
- package/dist/core/runner/resume-admission.js +7 -5
- package/dist/core/runner/resume-internals-and-config.d.ts +3 -3
- package/dist/core/runner/resume-internals-and-config.js +3 -8
- package/dist/core/runner/retired-runner-deps.d.ts +5 -6
- package/dist/core/runner/retired-runner-deps.js +1 -4
- package/dist/core/runner/run-leg.js +42 -12
- package/dist/core/runner/run-recovery-lanes.js +5 -3
- package/dist/core/runner/run-terminal-adoption.js +6 -5
- package/dist/core/runner/run-turn-boundary.js +9 -3
- package/dist/core/runner/runtask.js +1 -1
- package/dist/core/runner/skills-seat.d.ts +15 -0
- package/dist/core/runner/skills-seat.js +57 -0
- package/dist/core/runner/sub-agent-deny-lists.d.ts +13 -11
- package/dist/core/runner/sub-agent-deny-lists.js +7 -5
- package/dist/core/runner/synthetic-tools.d.ts +5 -2
- package/dist/core/runner/synthetic-tools.js +2 -12
- package/dist/core/runner-deps.d.ts +29 -14
- package/dist/core/session-policy-store.d.ts +19 -0
- package/dist/core/session-policy-store.js +22 -2
- package/dist/core/store-contracts/mailbox-store-contract.js +13 -0
- package/dist/core/task-event.d.ts +38 -2
- package/dist/core/task-notification.js +2 -2
- package/dist/core/task-spec.d.ts +1 -1
- package/dist/core/tool-policy.d.ts +3 -0
- package/dist/core/tool-policy.js +10 -4
- package/dist/core/types.d.ts +2 -2
- package/dist/core/types.js +1 -1
- package/dist/core/untrusted-text.d.ts +16 -0
- package/dist/core/untrusted-text.js +7 -2
- package/dist/core/user-attachment.d.ts +13 -2
- package/dist/core/user-attachment.js +47 -41
- package/dist/core/wiring-manifest.d.ts +4 -2
- package/dist/engine/harness/agent-harness.js +2 -1
- package/dist/engine/harness/types.d.ts +3 -0
- package/dist/engine/loop/agent-loop.d.ts +12 -1
- package/dist/engine/loop/agent-loop.js +17 -5
- package/dist/engine/loop/types.d.ts +7 -1
- package/dist/index.d.ts +15 -9
- package/dist/index.js +12 -6
- package/dist/internal/harness.d.ts +1 -0
- package/dist/internal/harness.js +1 -0
- package/dist/orchestration/goal.d.ts +24 -1
- package/dist/orchestration/goal.js +3 -2
- package/dist/prompt-assembly/artifact-store.d.ts +44 -9
- package/dist/prompt-assembly/artifact-store.js +38 -12
- package/dist/prompt-assembly/artifact.d.ts +12 -11
- package/dist/prompt-assembly/artifact.js +52 -21
- package/dist/prompt-assembly/assemble.d.ts +2 -0
- package/dist/prompt-assembly/assemble.js +2 -1
- package/dist/prompt-assembly/catalog/index.js +2 -1
- package/dist/prompt-assembly/catalog/memory.d.ts +13 -0
- package/dist/prompt-assembly/catalog/memory.js +6 -0
- package/dist/prompt-assembly/catalog/schema.d.ts +16 -2
- package/dist/prompt-assembly/composer.d.ts +2 -0
- package/dist/prompt-assembly/composer.js +1 -1
- package/dist/prompt-assembly/overlay.d.ts +21 -11
- package/dist/prompt-assembly/overlay.js +55 -17
- package/dist/prompt-assembly/select.d.ts +21 -6
- package/dist/prompt-assembly/select.js +39 -2
- package/dist/prompts/default.d.ts +0 -11
- package/dist/prompts/default.js +0 -3
- package/dist/stores/file/permission-rule-store.d.ts +1 -1
- package/dist/stores/file/permission-rule-store.js +2 -1
- package/dist/tools/artifact/artifact-tool.js +4 -3
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +65 -5
- package/wire-changes/core@7.53.0.json +1946 -0
package/dist/core/tool-policy.js
CHANGED
|
@@ -16,7 +16,7 @@ import { boundInputHashOf } from "./canonical-json.js";
|
|
|
16
16
|
import { delimitUntrusted, inlineUntrusted, REVIEWER_NOTE_MAX_BODY } from "./untrusted-text.js";
|
|
17
17
|
import { describeRejectedValue } from "./tool-search-setting.js";
|
|
18
18
|
import { egressText, egressThrownText } from "./untrusted-egress.js";
|
|
19
|
-
import { assertNoRetiredToolPolicyKeys, RETIRED_DECISION_MEMBERS } from "./retired-keys.js";
|
|
19
|
+
import { assertNoRetiredKeys, assertNoRetiredToolPolicyKeys, RETIRED_DECISION_MEMBERS, RETIRED_TOOL_POLICY_KEYS } from "./retired-keys.js";
|
|
20
20
|
import { isEngineRefusal, nestedRecordsOf, receiveContract, receiveNestedRecords, refusedOutOfContract, screenContractValues } from "./decision-receipt.js";
|
|
21
21
|
export { isEngineRefusal } from "./decision-receipt.js";
|
|
22
22
|
import { isNamespacedCoveringRuleName, namespacedRuleNameCovers } from "./permission-rules.js";
|
|
@@ -148,7 +148,7 @@ export function decisionText(d) {
|
|
|
148
148
|
}
|
|
149
149
|
const TOOL_POLICY_CARRIED_MEMBERS = ["projection", "pathRules", "writeGuardRows", "nameSets"];
|
|
150
150
|
export function carriedMembersOf(p) {
|
|
151
|
-
|
|
151
|
+
assertNoRetiredKeys(p, RETIRED_TOOL_POLICY_KEYS, "ToolPolicy");
|
|
152
152
|
const out = {};
|
|
153
153
|
const carry = (k) => {
|
|
154
154
|
const v = p[k];
|
|
@@ -612,8 +612,7 @@ export function combinePolicies(...policies) {
|
|
|
612
612
|
continue;
|
|
613
613
|
}
|
|
614
614
|
if (d.updatedInput !== undefined) {
|
|
615
|
-
|
|
616
|
-
current = Object.freeze(reread !== undefined ? await reread : { ...current, args: d.updatedInput });
|
|
615
|
+
current = Object.freeze(await withArgsReading(current, d.updatedInput, signal));
|
|
617
616
|
rewrite = d;
|
|
618
617
|
stated = d.action === "allow" ? d.decisionReason : undefined;
|
|
619
618
|
}
|
|
@@ -915,6 +914,13 @@ export function ownArgs(v, root = "args") {
|
|
|
915
914
|
const copy = tryCloneArgs(v);
|
|
916
915
|
return copy.ok ? ownedCopy(copy.value, root) : { ...copy, reason: `unclonable value: ${copy.reason}` };
|
|
917
916
|
}
|
|
917
|
+
export function ownedReading(read) {
|
|
918
|
+
return (args) => {
|
|
919
|
+
const out = read(args);
|
|
920
|
+
const owned = ownArgs(out);
|
|
921
|
+
return owned.ok ? owned.value : out;
|
|
922
|
+
};
|
|
923
|
+
}
|
|
918
924
|
function ownedCopy(fresh, root) {
|
|
919
925
|
const pending = [[fresh, root]];
|
|
920
926
|
for (let next = pending.pop(); next !== undefined; next = pending.pop()) {
|
package/dist/core/types.d.ts
CHANGED
|
@@ -18,8 +18,8 @@ export type { PermissionMode } from "./ask-origin.js";
|
|
|
18
18
|
export type { ToolEffect, ToolContentOrigin, ReversibilityVerdict, ReadRootGrantCandidate, ToolSpec, ToolReturn, NestedUsage, NestedUsageAccum, ToolExecuteContext } from "./tool-spec.js";
|
|
19
19
|
export type { BeforeWriteRequest, BeforeWriteResult, BeforeWriteHook, TrackEditRequest, TrackEditResult, TrackFileEditHook, FileEditedNotice, FileEditedHook, HandsBandOptions } from "./hands-band.js";
|
|
20
20
|
export type { AgentDefinition, SkillSpec } from "./agent-definition.js";
|
|
21
|
-
export type { McpServerSpec, A2aServerSpec, McpElicitRequest, McpElicitResponse, OnElicit, McpRevocationLedger, McpMountIdentity,
|
|
22
|
-
export { readMcpToolAxes } from "./mcp-server-spec.js";
|
|
21
|
+
export type { McpServerSpec, A2aServerSpec, McpElicitRequest, McpElicitResponse, OnElicit, McpRevocationLedger, McpMountIdentity, DeclarationFault, DeclarationPathRule, DeclarationRead, ToolAxesRead, ToolAxesSurface } from "./mcp-server-spec.js";
|
|
22
|
+
export { DECLARATION_PATH_RULES, declarationFaultOf, declarerWord, readMcpToolAxes, readToolAxes, receiveDeclaration, toolAxesRefusal } from "./mcp-server-spec.js";
|
|
23
23
|
export type { TaskLimits } from "./task-limits.js";
|
|
24
24
|
export type { TaskStatus, RemoteEnvFailureNote, EffectiveMemoryScopes, TaskResult, HumanReviewGateRow } from "./task-result.js";
|
|
25
25
|
export type { TerminalCause, PausedCause } from "./terminal-cause.js";
|
package/dist/core/types.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { MODEL_ROLES } from "./model-seat.js";
|
|
2
|
-
export { readMcpToolAxes } from "./mcp-server-spec.js";
|
|
2
|
+
export { DECLARATION_PATH_RULES, declarationFaultOf, declarerWord, readMcpToolAxes, readToolAxes, receiveDeclaration, toolAxesRefusal } from "./mcp-server-spec.js";
|
|
3
3
|
export { AUTO_MODE_DENY_SOURCES, isAutoModeDenySource } from "./runtime-caps.js";
|
|
4
4
|
export { __resetMalformedDelegationSeatAnnouncement, backgroundChildTerminal, deliverDelegationLifecycle, emitsChildRowFrames, taskStartedFrame } from "./delegation-frames.js";
|
|
5
5
|
export { __resetMalformedNoticeSeatAnnouncement, deliverEngineNotice, owedUserInputCounts, parentLegIds, settleOwedUserInput, undrainedUserInputNotices, USER_INPUT_UNDRAINED_CAUSES, USER_INPUT_UNDRAINED_FAMILIES } from "./engine-notice.js";
|
|
@@ -397,6 +397,12 @@ export declare function defuseControlChars(text: string): string;
|
|
|
397
397
|
* Defense-in-depth, NOT a guarantee (same posture as the rest of this module).
|
|
398
398
|
*/
|
|
399
399
|
export declare function inlineUntrusted(text: string, maxLen?: number): string;
|
|
400
|
+
/** The mark a cut text ends in: {@link inlineUntrusted}'s, and a notice's machine-read rule text's
|
|
401
|
+
* ({@link import("./permission-rule-model.js").noticeRuleText}) — one ellipsis, spelled once. */
|
|
402
|
+
export declare const INLINE_TRUNCATION_MARK = "\u2026";
|
|
403
|
+
/** The code points {@link inlineUntrusted} may return beyond its content cap: the one truncation mark. The longest result for a cap
|
|
404
|
+
* of `maxLen` is `maxLen` plus this. */
|
|
405
|
+
export declare const INLINE_TRUNCATION_MARK_CODEPOINTS: number;
|
|
400
406
|
/** The per-ENTRY ceiling inside a `ProbeCause` operand family (checkpoint-store's
|
|
401
407
|
* structured probe account), sized like the descriptor's own `touchedPaths` entries (the same thing
|
|
402
408
|
* on the same card). Per entry, not per cause: that is the whole point of the structured shape —
|
|
@@ -414,6 +420,16 @@ export declare const PROBE_CAUSE_PATH_MAX = 200;
|
|
|
414
420
|
* (tools/fs) and must fit every load-bearing part inside this bound, the gate, the persist boundary — and
|
|
415
421
|
* a value import from tools/fs into checkpoint-store closes an ESM cycle. */
|
|
416
422
|
export declare const PROBE_REASON_MAX = 200;
|
|
423
|
+
/**
|
|
424
|
+
* Whether `text` is a probe's one-sentence account the engine itself could have minted: every mint passes the sentence through
|
|
425
|
+
* {@link inlineUntrusted} at {@link PROBE_REASON_MAX}, so the longest one is the cap's content plus the truncation ellipsis
|
|
426
|
+
* ({@link INLINE_TRUNCATION_MARK_CODEPOINTS}), counted in code points. A host that relays the sentence (`RiskDescriptor.probeReason`,
|
|
427
|
+
* `AskRequest.probeReason`) and meets a longer one has met text the engine did not mint (a third-party producer, a generation
|
|
428
|
+
* with another cap) — to be dropped whole, not cut, because a cut is another sentence. The bound lives here once; a host asks, it does not count.
|
|
429
|
+
* The question is total: a value that is not a string is not a sentence the engine mints (every mint is a string), so it answers
|
|
430
|
+
* `false` — the relay's answer to it, dropping it whole, is the same as to an over-long one.
|
|
431
|
+
*/
|
|
432
|
+
export declare function isMintableProbeReason(text: unknown): boolean;
|
|
417
433
|
/** The one body bound every "reviewer note" relay passes to {@link delimitUntrusted} — the decider's
|
|
418
434
|
* free text attached to a deny (sync `AskOutcome.reason` and the durable `ResumeOutcome` `reason`
|
|
419
435
|
* legs alike). A note is steering, not payload: unbounded it can flood the transcript/context the
|
|
@@ -568,18 +568,23 @@ const LABEL_MAX = 160;
|
|
|
568
568
|
export function inlineUntrusted(text, maxLen = LABEL_MAX) {
|
|
569
569
|
const oneLine = text.replace(/[\s\u0000-\u001f\u007f-\u009f]+/g, " ").trim();
|
|
570
570
|
const cps = [...oneLine];
|
|
571
|
-
const capped = cps.length > maxLen ? cps.slice(0, maxLen).join("") +
|
|
571
|
+
const capped = cps.length > maxLen ? cps.slice(0, maxLen).join("") + INLINE_TRUNCATION_MARK : oneLine;
|
|
572
572
|
const out = neutralizeForFence(capped);
|
|
573
573
|
if (maxLen <= 0)
|
|
574
574
|
return "";
|
|
575
575
|
const outCps = [...out];
|
|
576
|
-
return outCps.length > maxLen +
|
|
576
|
+
return outCps.length > maxLen + INLINE_TRUNCATION_MARK_CODEPOINTS ? outCps.slice(0, maxLen).join("") + INLINE_TRUNCATION_MARK : out;
|
|
577
577
|
}
|
|
578
|
+
export const INLINE_TRUNCATION_MARK = "…";
|
|
579
|
+
export const INLINE_TRUNCATION_MARK_CODEPOINTS = [...INLINE_TRUNCATION_MARK].length;
|
|
578
580
|
function sanitizeLabel(label) {
|
|
579
581
|
return inlineUntrusted(label, LABEL_MAX);
|
|
580
582
|
}
|
|
581
583
|
export const PROBE_CAUSE_PATH_MAX = 200;
|
|
582
584
|
export const PROBE_REASON_MAX = 200;
|
|
585
|
+
export function isMintableProbeReason(text) {
|
|
586
|
+
return typeof text === "string" && [...text].length <= PROBE_REASON_MAX + INLINE_TRUNCATION_MARK_CODEPOINTS;
|
|
587
|
+
}
|
|
583
588
|
export const REVIEWER_NOTE_MAX_BODY = 2048;
|
|
584
589
|
export function delimitUntrusted(label, text, maxBody) {
|
|
585
590
|
return delimitUntrustedWithClip(label, text, maxBody).text;
|
|
@@ -73,9 +73,20 @@ export type ScreenedUserAttachment = {
|
|
|
73
73
|
readonly data: string;
|
|
74
74
|
readonly mimeType: string;
|
|
75
75
|
};
|
|
76
|
-
/**
|
|
77
|
-
|
|
76
|
+
/**
|
|
77
|
+
* The field a refusal names, as one value: `path` is the field path the sentence opens with, and `index` the attachment's
|
|
78
|
+
* position in the seat (0-based, the `[i]` of that path) — present exactly when the sentence names one attachment; a refusal of
|
|
79
|
+
* the seat as a whole (not a list, too many, a resume, the window) has no index. Built only by {@link SEAT_REF} /
|
|
80
|
+
* {@link entryRef} / {@link memberRef}, so the index and the path can never name two attachments.
|
|
81
|
+
*/
|
|
82
|
+
export interface UserAttachmentFieldRef {
|
|
83
|
+
readonly path: string;
|
|
84
|
+
readonly index?: number;
|
|
85
|
+
}
|
|
86
|
+
/** The door's refusal: one code, the field named first in the sentence and again in `detail` ({@link UserAttachmentFieldRef}). */
|
|
87
|
+
export declare function userAttachmentRefusal(at: UserAttachmentFieldRef, problem: string): Error & {
|
|
78
88
|
code: "config.user_attachment_invalid";
|
|
89
|
+
detail: UserAttachmentFieldRef;
|
|
79
90
|
};
|
|
80
91
|
/**
|
|
81
92
|
* The door: screen the seat's value (synchronous; the caller's object is read once, member by member, before the
|
|
@@ -24,12 +24,16 @@ export const USER_ATTACHMENT_SEAT = Object.freeze({
|
|
|
24
24
|
supplies: USER_ATTACHMENT_SUPPLIES,
|
|
25
25
|
limits: Object.freeze({ maxEntries: USER_ATTACHMENTS_MAX, maxRenderedTextChars: MAX_READ_OUTPUT_CHARS }),
|
|
26
26
|
});
|
|
27
|
-
export function userAttachmentRefusal(
|
|
28
|
-
const e = new Error(`${
|
|
27
|
+
export function userAttachmentRefusal(at, problem) {
|
|
28
|
+
const e = new Error(`${at.path}: ${problem}`);
|
|
29
29
|
e.code = "config.user_attachment_invalid";
|
|
30
|
+
e.detail = { path: at.path, ...(at.index !== undefined ? { index: at.index } : {}) };
|
|
30
31
|
return e;
|
|
31
32
|
}
|
|
32
33
|
const SEAT_FIELD = "TaskSpec.userAttachments";
|
|
34
|
+
const SEAT_REF = { path: SEAT_FIELD };
|
|
35
|
+
const entryRef = (index) => ({ path: `${SEAT_FIELD}[${index}]`, index });
|
|
36
|
+
const memberRef = (at, member) => ({ ...at, path: `${at.path}.${member}` });
|
|
33
37
|
const isPlainObject = (v) => {
|
|
34
38
|
if (v === null || typeof v !== "object" || Array.isArray(v))
|
|
35
39
|
return false;
|
|
@@ -45,85 +49,87 @@ export function screenUserAttachments(seat, opts) {
|
|
|
45
49
|
if (seat === undefined)
|
|
46
50
|
return undefined;
|
|
47
51
|
if (!Array.isArray(seat))
|
|
48
|
-
throw userAttachmentRefusal(
|
|
52
|
+
throw userAttachmentRefusal(SEAT_REF, "must be an array of attachments.");
|
|
49
53
|
const entries = [...seat];
|
|
50
54
|
if (entries.length === 0)
|
|
51
55
|
return undefined;
|
|
52
56
|
if (entries.length > USER_ATTACHMENTS_MAX)
|
|
53
|
-
throw userAttachmentRefusal(
|
|
57
|
+
throw userAttachmentRefusal(SEAT_REF, `${entries.length} attachments, over the ${USER_ATTACHMENTS_MAX} one objective may carry.`);
|
|
54
58
|
if (opts.resumeLeg)
|
|
55
|
-
throw userAttachmentRefusal(
|
|
56
|
-
return entries.map((raw, i) => screenEntry(raw,
|
|
59
|
+
throw userAttachmentRefusal(SEAT_REF, "a durable resume continues the parked run and sends no new human message, so it cannot carry attachments — declare them on a new objective.");
|
|
60
|
+
return entries.map((raw, i) => screenEntry(raw, entryRef(i)));
|
|
57
61
|
}
|
|
58
|
-
function screenLabel(v,
|
|
62
|
+
function screenLabel(v, at) {
|
|
59
63
|
if (typeof v !== "string" || v.length === 0)
|
|
60
|
-
throw userAttachmentRefusal(
|
|
64
|
+
throw userAttachmentRefusal(at, "must be a non-empty string.");
|
|
61
65
|
if (v.length > USER_ATTACHMENT_LABEL_MAX)
|
|
62
|
-
throw userAttachmentRefusal(
|
|
66
|
+
throw userAttachmentRefusal(at, `${v.length} characters, over the ${USER_ATTACHMENT_LABEL_MAX}-character limit.`);
|
|
63
67
|
return v;
|
|
64
68
|
}
|
|
65
|
-
function screenPositiveInt(v,
|
|
69
|
+
function screenPositiveInt(v, at) {
|
|
66
70
|
if (typeof v !== "number" || !Number.isInteger(v) || v < 1)
|
|
67
|
-
throw userAttachmentRefusal(
|
|
71
|
+
throw userAttachmentRefusal(at, "must be an integer of at least 1.");
|
|
68
72
|
return v;
|
|
69
73
|
}
|
|
70
|
-
function onlyMembers(o, allowed,
|
|
74
|
+
function onlyMembers(o, allowed, at) {
|
|
71
75
|
for (const k of Object.keys(o))
|
|
72
76
|
if (!allowed.includes(k))
|
|
73
|
-
throw userAttachmentRefusal(
|
|
77
|
+
throw userAttachmentRefusal(memberRef(at, k), `is not a member of this attachment (allowed: ${allowed.join(", ")}).`);
|
|
74
78
|
}
|
|
75
|
-
function screenEntry(raw,
|
|
79
|
+
function screenEntry(raw, at) {
|
|
76
80
|
if (!isPlainObject(raw))
|
|
77
|
-
throw userAttachmentRefusal(
|
|
81
|
+
throw userAttachmentRefusal(at, "must be a plain object: { path } (a workspace file), { name, text } (host text) or { name, image } (a host image).");
|
|
78
82
|
const arms = ["path", "text", "image"].filter((k) => Object.prototype.hasOwnProperty.call(raw, k));
|
|
79
83
|
const arm = arms[0];
|
|
80
84
|
if (arm === undefined || arms.length !== 1) {
|
|
81
|
-
throw userAttachmentRefusal(
|
|
85
|
+
throw userAttachmentRefusal(at, arm === undefined ? "names no attachment: give exactly one of `path`, `text` or `image`." : `mixes ${arms.map((a) => `\`${a}\``).join(" and ")}: give exactly one of \`path\`, \`text\` or \`image\`.`);
|
|
82
86
|
}
|
|
83
87
|
switch (arm) {
|
|
84
88
|
case "path": {
|
|
85
|
-
onlyMembers(raw, ["path", "lines"],
|
|
86
|
-
const path = screenLabel(raw.path,
|
|
89
|
+
onlyMembers(raw, ["path", "lines"], at);
|
|
90
|
+
const path = screenLabel(raw.path, memberRef(at, "path"));
|
|
87
91
|
const linesRaw = raw.lines;
|
|
88
92
|
if (linesRaw === undefined)
|
|
89
93
|
return { supply: "path", path };
|
|
94
|
+
const linesAt = memberRef(at, "lines");
|
|
90
95
|
if (!isPlainObject(linesRaw))
|
|
91
|
-
throw userAttachmentRefusal(
|
|
92
|
-
onlyMembers(linesRaw, ["start", "end"],
|
|
93
|
-
const start = screenPositiveInt(linesRaw.start,
|
|
96
|
+
throw userAttachmentRefusal(linesAt, "must be { start, end? }.");
|
|
97
|
+
onlyMembers(linesRaw, ["start", "end"], linesAt);
|
|
98
|
+
const start = screenPositiveInt(linesRaw.start, memberRef(linesAt, "start"));
|
|
94
99
|
const endRaw = linesRaw.end;
|
|
95
100
|
if (endRaw === undefined)
|
|
96
101
|
return { supply: "path", path, lines: { start } };
|
|
97
|
-
const end = screenPositiveInt(endRaw,
|
|
102
|
+
const end = screenPositiveInt(endRaw, memberRef(linesAt, "end"));
|
|
98
103
|
if (end < start)
|
|
99
|
-
throw userAttachmentRefusal(
|
|
104
|
+
throw userAttachmentRefusal(memberRef(linesAt, "end"), `${end} is before the start line ${start}.`);
|
|
100
105
|
return { supply: "path", path, lines: { start, end } };
|
|
101
106
|
}
|
|
102
107
|
case "text": {
|
|
103
|
-
onlyMembers(raw, ["name", "text", "startLine"],
|
|
104
|
-
const name = screenLabel(raw.name,
|
|
108
|
+
onlyMembers(raw, ["name", "text", "startLine"], at);
|
|
109
|
+
const name = screenLabel(raw.name, memberRef(at, "name"));
|
|
105
110
|
const text = raw.text;
|
|
106
111
|
if (typeof text !== "string" || text.length === 0)
|
|
107
|
-
throw userAttachmentRefusal(
|
|
108
|
-
const startLine = raw.startLine === undefined ? 1 : screenPositiveInt(raw.startLine,
|
|
112
|
+
throw userAttachmentRefusal(memberRef(at, "text"), "must be a non-empty string.");
|
|
113
|
+
const startLine = raw.startLine === undefined ? 1 : screenPositiveInt(raw.startLine, memberRef(at, "startLine"));
|
|
109
114
|
const rendered = renderNumbered(text, startLine);
|
|
110
115
|
if (rendered.length > MAX_READ_OUTPUT_CHARS)
|
|
111
|
-
throw userAttachmentRefusal(
|
|
116
|
+
throw userAttachmentRefusal(memberRef(at, "text"), `renders to ${rendered.length} characters with line numbers, over the ${MAX_READ_OUTPUT_CHARS}-character limit a read may deliver — send a part of it.`);
|
|
112
117
|
return { supply: "content_text", name, text, startLine, rendered };
|
|
113
118
|
}
|
|
114
119
|
case "image": {
|
|
115
|
-
onlyMembers(raw, ["name", "image"],
|
|
116
|
-
const name = screenLabel(raw.name,
|
|
120
|
+
onlyMembers(raw, ["name", "image"], at);
|
|
121
|
+
const name = screenLabel(raw.name, memberRef(at, "name"));
|
|
117
122
|
const img = raw.image;
|
|
123
|
+
const imageAt = memberRef(at, "image");
|
|
118
124
|
if (!isPlainObject(img))
|
|
119
|
-
throw userAttachmentRefusal(
|
|
120
|
-
onlyMembers(img, ["data", "mimeType"],
|
|
125
|
+
throw userAttachmentRefusal(imageAt, "must be { data, mimeType } (base64 bytes and the image's type).");
|
|
126
|
+
onlyMembers(img, ["data", "mimeType"], imageAt);
|
|
121
127
|
const data = img.data;
|
|
122
128
|
const mimeType = img.mimeType;
|
|
123
129
|
if (typeof data !== "string" || data.length === 0)
|
|
124
|
-
throw userAttachmentRefusal(
|
|
130
|
+
throw userAttachmentRefusal(memberRef(imageAt, "data"), "must be a non-empty base64 string.");
|
|
125
131
|
if (typeof mimeType !== "string" || !ADMITTED_IMAGE_MIME_TYPES.includes(mimeType)) {
|
|
126
|
-
throw userAttachmentRefusal(
|
|
132
|
+
throw userAttachmentRefusal(memberRef(imageAt, "mimeType"), `must be one of ${ADMITTED_IMAGE_MIME_TYPES.join(", ")}.`);
|
|
127
133
|
}
|
|
128
134
|
return { supply: "content_image", name, data, mimeType };
|
|
129
135
|
}
|
|
@@ -132,7 +138,7 @@ function screenEntry(raw, field) {
|
|
|
132
138
|
export function refuseUserAttachmentPathsWithoutWorkspace(screened) {
|
|
133
139
|
const i = screened?.findIndex((a) => a.supply === "path") ?? -1;
|
|
134
140
|
if (i >= 0)
|
|
135
|
-
throw userAttachmentRefusal(
|
|
141
|
+
throw userAttachmentRefusal(memberRef(entryRef(i), "path"), "this run has no workspace (its hand tools are off), so the engine has no file to read — send the file's bytes as a `text` or `image` entry instead.");
|
|
136
142
|
}
|
|
137
143
|
export function userAttachmentDeclarations(screened) {
|
|
138
144
|
return screened.map((a, i) => a.supply === "path"
|
|
@@ -149,16 +155,16 @@ export async function admitUserAttachmentImages(screened) {
|
|
|
149
155
|
out.set(i + 1, admitted.block);
|
|
150
156
|
continue;
|
|
151
157
|
}
|
|
152
|
-
const
|
|
158
|
+
const imageAt = memberRef(entryRef(i), "image");
|
|
153
159
|
switch (admitted.reason) {
|
|
154
160
|
case "mime_unsupported":
|
|
155
|
-
throw userAttachmentRefusal(
|
|
161
|
+
throw userAttachmentRefusal(memberRef(imageAt, "mimeType"), `must be one of ${ADMITTED_IMAGE_MIME_TYPES.join(", ")}.`);
|
|
156
162
|
case "magic_mismatch":
|
|
157
|
-
throw userAttachmentRefusal(
|
|
163
|
+
throw userAttachmentRefusal(memberRef(imageAt, "data"), `does not begin with a ${a.mimeType} signature (empty, mis-declared, or not base64) — refused rather than sent.`);
|
|
158
164
|
case "raw_too_large":
|
|
159
|
-
throw userAttachmentRefusal(
|
|
165
|
+
throw userAttachmentRefusal(memberRef(imageAt, "data"), `${admitted.rawBytes} bytes, over the ${admitted.cap}-byte cap.`);
|
|
160
166
|
case "base64_too_large":
|
|
161
|
-
throw userAttachmentRefusal(
|
|
167
|
+
throw userAttachmentRefusal(memberRef(imageAt, "data"), `base64 of ${admitted.base64.length} characters, over the API's 5 MB image limit — shrink the image first.`);
|
|
162
168
|
}
|
|
163
169
|
}
|
|
164
170
|
return out;
|
|
@@ -395,7 +401,7 @@ function refuseFramesOverWindow(frames, model, window) {
|
|
|
395
401
|
if (tokens <= budget)
|
|
396
402
|
return;
|
|
397
403
|
const n = frames.length;
|
|
398
|
-
throw userAttachmentRefusal(
|
|
404
|
+
throw userAttachmentRefusal(SEAT_REF, `the ${n} ${n === 1 ? "attachment" : "attachments"} and the objective come to about ${tokens} tokens, over the ${budget} tokens one request can hold on this model — to send it the engine would have to drop the objective or some of the attachments. Nothing was sent; attach fewer or smaller parts.`);
|
|
399
405
|
}
|
|
400
406
|
export async function readObjectiveAttachments(prepared, inputId, blocked, window) {
|
|
401
407
|
if (blocked || prepared.userAttachments === undefined)
|
|
@@ -113,8 +113,7 @@ export interface AutoModeArmFact {
|
|
|
113
113
|
* One declared MCP server's materialization result for THIS leg — the per-server connection-state
|
|
114
114
|
* read face on {@link WiringManifest.mcp}. `status` is the connect-time verdict of this leg's
|
|
115
115
|
* materialize (a snapshot, never a heartbeat — the same semantics as `MaterializedMcp.statuses`,
|
|
116
|
-
* which it is projected from): `connected` (tools listed; `toolCount` = the
|
|
117
|
-
* intake), `failed` (the connect or the tool listing threw — `errorCode`/`delivered`/`httpStatus` are the
|
|
116
|
+
* which it is projected from): `connected` (tools listed; `toolCount` = see the field), `failed` (the connect or the tool listing threw — `errorCode`/`delivered`/`httpStatus` are the
|
|
118
117
|
* failure record spread flat (see the MCP failure vocabulary's `McpFailure`), `error` the
|
|
119
118
|
* neutralized, length-bounded remote text), `skipped` (declared on the spec but this leg produced no
|
|
120
119
|
* status for it — the materialization did not reach it). `source` is the DECLARING side's own label
|
|
@@ -130,6 +129,9 @@ export interface WiringManifestMcpEntry {
|
|
|
130
129
|
delivered?: McpDelivered;
|
|
131
130
|
httpStatus?: number;
|
|
132
131
|
error?: string;
|
|
132
|
+
/** How many of the server's tools the roster the row is read against holds: a run's roster (the valve and the deployment's
|
|
133
|
+
* `toolFaces` overlay applied — a tool either one leaves off is not counted), or, for `probeMcpServers` (no run, so no lists),
|
|
134
|
+
* what its own dial would mount. `0` on `failed` and on `skipped` (no connection, so nothing held). */
|
|
133
135
|
toolCount: number;
|
|
134
136
|
/**
|
|
135
137
|
* The engine's last liveness OBSERVATION about this server as of this leg's materialize — a per-leg
|
|
@@ -670,13 +670,14 @@ export class AgentHarness {
|
|
|
670
670
|
},
|
|
671
671
|
};
|
|
672
672
|
},
|
|
673
|
-
beforeToolCall: async ({ toolCall, args }, signal) => {
|
|
673
|
+
beforeToolCall: async ({ toolCall, args, readArguments }, signal) => {
|
|
674
674
|
const result = await this.emitHook({
|
|
675
675
|
type: "tool_call",
|
|
676
676
|
toolCallId: toolCall.id,
|
|
677
677
|
toolName: toolCall.name,
|
|
678
678
|
input: args,
|
|
679
679
|
...(signal !== undefined ? { signal } : {}),
|
|
680
|
+
...(readArguments !== undefined ? { readArguments } : {}),
|
|
680
681
|
});
|
|
681
682
|
return result;
|
|
682
683
|
},
|
|
@@ -1185,6 +1185,9 @@ export interface ToolCallEvent {
|
|
|
1185
1185
|
* emits that carry no per-call signal; a subscriber gating a wait on it must then fall back to
|
|
1186
1186
|
* whatever run-level signal it already holds (the historical shape, byte-identical). */
|
|
1187
1187
|
signal?: AbortSignal;
|
|
1188
|
+
/** The loop's reading of this call's arguments ({@link BeforeToolCallContext.readArguments}), handed on verbatim: a
|
|
1189
|
+
* subscriber that rewrites the call reads the rewrite through it before judging it. */
|
|
1190
|
+
readArguments?: (args: unknown) => unknown;
|
|
1188
1191
|
}
|
|
1189
1192
|
export interface ToolResultEvent {
|
|
1190
1193
|
type: "tool_result";
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
import type { AssistantMessage, ToolResultMessage } from "../llm/index.js";
|
|
25
25
|
import { type AgentCoreStreamRuntimeDeps } from "./runtime-deps.js";
|
|
26
|
-
import type { AfterToolCallResult, AgentContext, AgentEvent, AgentLoopConfig, AgentMessage, AgentToolResult, HaltRemainingDirective, StreamFn } from "./types.js";
|
|
26
|
+
import type { AfterToolCallResult, AgentContext, AgentEvent, AgentLoopConfig, AgentMessage, AgentTool, AgentToolCall, AgentToolResult, HaltRemainingDirective, StreamFn } from "./types.js";
|
|
27
27
|
/** Callback used by synchronous loop runners to publish agent lifecycle events. */
|
|
28
28
|
export type AgentEventSink = (event: AgentEvent) => Promise<void> | void;
|
|
29
29
|
/** Named reasons the loop goes around again. Assertable in tests via the trace sink. */
|
|
@@ -159,6 +159,17 @@ export type ExecutedToolCallOutcome = {
|
|
|
159
159
|
result: AgentToolResult<unknown>;
|
|
160
160
|
isError: boolean;
|
|
161
161
|
};
|
|
162
|
+
/**
|
|
163
|
+
* THE reading a value gets on its way to becoming a call's arguments: the tool's own preparation (`prepareArguments` —
|
|
164
|
+
* a default filled in, an alias folded), then the schema's coercions ({@link validateToolArguments}). The loop reads the
|
|
165
|
+
* model's call through it before the gate, hands the same reading to the gate (`BeforeToolCallContext.readArguments`)
|
|
166
|
+
* so every rewrite is judged as it will run, and reads the gate's output through the same two steps once more — refusing
|
|
167
|
+
* an output they would move. A preparation that throws throws here too (the value cannot be read: whoever adopts it
|
|
168
|
+
* refuses it, as the loop refuses a model call whose preparation throws). A value that does not VALIDATE is handed back as
|
|
169
|
+
* given: nothing invalid runs (the loop's own reading of the gate's output throws on it), and a judge of it judges bytes
|
|
170
|
+
* that never execute.
|
|
171
|
+
*/
|
|
172
|
+
export declare function readToolCallArguments(tool: AgentTool, toolCall: AgentToolCall, args: unknown): unknown;
|
|
162
173
|
/**
|
|
163
174
|
* How many tool names an unknown-tool miss spells out. A miss is a NAME problem: seeing a couple of dozen
|
|
164
175
|
* real names is what lets a model spot the one it meant, while a full listing grows with the deployment
|
|
@@ -1215,6 +1215,15 @@ function prepareToolCallArguments(tool, toolCall) {
|
|
|
1215
1215
|
arguments: preparedArguments,
|
|
1216
1216
|
};
|
|
1217
1217
|
}
|
|
1218
|
+
export function readToolCallArguments(tool, toolCall, args) {
|
|
1219
|
+
const prepared = prepareToolCallArguments(tool, { ...toolCall, arguments: structuredClone(args) });
|
|
1220
|
+
try {
|
|
1221
|
+
return validateToolArguments(tool, prepared);
|
|
1222
|
+
}
|
|
1223
|
+
catch {
|
|
1224
|
+
return args;
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1218
1227
|
export const ROSTER_LISTING_MAX = 25;
|
|
1219
1228
|
export const ROSTER_SEARCH_HINT_NAME = "ToolSearch";
|
|
1220
1229
|
function formatRosterRecovery(availableTools) {
|
|
@@ -1332,6 +1341,7 @@ async function prepareToolCall(currentContext, assistantMessage, toolCall, confi
|
|
|
1332
1341
|
toolCall,
|
|
1333
1342
|
args: finalArgs,
|
|
1334
1343
|
context: currentContext,
|
|
1344
|
+
readArguments: (args) => readToolCallArguments(tool, toolCall, args),
|
|
1335
1345
|
}, signal);
|
|
1336
1346
|
if (signal?.aborted) {
|
|
1337
1347
|
return {
|
|
@@ -1347,11 +1357,13 @@ async function prepareToolCall(currentContext, assistantMessage, toolCall, confi
|
|
|
1347
1357
|
}
|
|
1348
1358
|
return { kind: "immediate", result: blocked, isError: true };
|
|
1349
1359
|
}
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1360
|
+
const rewritten = beforeResult?.updatedInput;
|
|
1361
|
+
if (rewritten !== undefined) {
|
|
1362
|
+
const judged = structuredClone(rewritten);
|
|
1363
|
+
finalArgs = validateToolArguments(tool, prepareToolCallArguments(tool, { ...preparedToolCall, arguments: structuredClone(judged) }));
|
|
1364
|
+
if (!sameToolArgs(finalArgs, judged)) {
|
|
1365
|
+
throw new Error(`the arguments cleared for "${tool.name}" are not the ones it would run: its reading of them (argument preparation, schema coercions) changes them, and that form was never judged — not executed`);
|
|
1366
|
+
}
|
|
1355
1367
|
if (!sameToolArgs(validatedArgs, finalArgs)) {
|
|
1356
1368
|
const rewrittenRefusal = await runInputValidation(tool, finalArgs, toolCall.id, signal, config.onToolInputValidationFault);
|
|
1357
1369
|
if (rewrittenRefusal !== undefined)
|
|
@@ -64,7 +64,9 @@ export type AgentToolCall = Extract<AssistantMessage["content"][number], {
|
|
|
64
64
|
* loop replaces the validated args with `updatedInput` and **re-runs `validateToolArguments` on it**
|
|
65
65
|
* before execution, so a rewrite can never carry across schema-invalid args into `tool.execute()`. This is
|
|
66
66
|
* the generic carrier the higher layer uses for arg redaction/clamping (design/37); the loop itself
|
|
67
|
-
* stays policy-agnostic. `block` wins over `updatedInput` if both are set.
|
|
67
|
+
* stays policy-agnostic. `block` wins over `updatedInput` if both are set. The rewrite must already be in
|
|
68
|
+
* the form the tool runs (read through {@link BeforeToolCallContext.readArguments}); one that reading would
|
|
69
|
+
* still move is refused, never silently re-read — what runs is what the gate judged.
|
|
68
70
|
*
|
|
69
71
|
* Keep in sync with the harness hook result `ToolCallResult` (harness/types.ts), which the harness's
|
|
70
72
|
* `beforeToolCall` callback returns verbatim.
|
|
@@ -133,6 +135,10 @@ export interface BeforeToolCallContext {
|
|
|
133
135
|
args: unknown;
|
|
134
136
|
/** Current agent context at the time the tool call is prepared. */
|
|
135
137
|
context: AgentContext;
|
|
138
|
+
/** The reading the loop gave `args` and will give any `updatedInput`: the tool's `prepareArguments`, then the schema's
|
|
139
|
+
* coercions (a value that does not validate comes back as given). A gate that rewrites the call reads the rewrite
|
|
140
|
+
* through it before judging it, so what it judges is what runs; the loop refuses an `updatedInput` this reading moves. */
|
|
141
|
+
readArguments?: (args: unknown) => unknown;
|
|
136
142
|
}
|
|
137
143
|
/** Context passed to `afterToolCall`. */
|
|
138
144
|
export interface AfterToolCallContext {
|
package/dist/index.d.ts
CHANGED
|
@@ -112,7 +112,7 @@ export type { RemoteExecutionEnv, WorkspaceHandle, SnapshotId, SessionToken, San
|
|
|
112
112
|
export { addWorktree, pruneWorktrees, WORKTREE_PARENT, type AddWorktreeOptions } from "./core/git-worktree-env.js";
|
|
113
113
|
export { runExecGate } from "./core/exec-gate.js";
|
|
114
114
|
export type { ExecStep, ExecStepResult, ExecGateResult, ExecGateOptions } from "./core/exec-gate.js";
|
|
115
|
-
export { sanitizeUntrustedText, delimitUntrusted, inlineUntrusted } from "./core/untrusted-text.js";
|
|
115
|
+
export { sanitizeUntrustedText, delimitUntrusted, inlineUntrusted, isMintableProbeReason } from "./core/untrusted-text.js";
|
|
116
116
|
export { mintReminderMark, isValidReminderMark, openSystemReminder, mintSystemReminder, reminderMarkDeclaration } from "./core/reminder-mint.js";
|
|
117
117
|
export { deriveInvariants, checkInvariants } from "./core/property-harness.js";
|
|
118
118
|
export type { InvariantKind, FunctionContract, Invariant, InvariantViolation, CheckResult, } from "./core/property-harness.js";
|
|
@@ -144,7 +144,7 @@ export { DEFAULT_FILE_HISTORY_BOUNDARY_KEEP, resolveFileHistoryRetention, fileHi
|
|
|
144
144
|
export type { FileHistoryRetentionPolicy } from "./core/file-history-retention.js";
|
|
145
145
|
export { FileStorageBackend, FileSessionRepo, FileCheckpointStore, FileMemoryStore, FileToolResultStore, FileSessionPolicyStore, FileFileHistoryStore, FileWorkflowJournalStore, MAX_JOURNAL_RESULT_BYTES, oversizeJournalResult, resolveDataRoot, sanitizeScope, sanitizePathComponent, createFileConsolidationLock, atomicWriteFile, writeThenLink, ensureDir, readJsonlRecords, AppendLog, FileStoreLockError, type FileStoreLockErrorCode, processFingerprint, isProcessLive, type ProcessFingerprint, type FileStorageBackendOptions, type FileStorageCorruptReadInfo, type FileFileHistoryStoreOptions, type FileSessionRepoOptions, type FileCheckpointStoreOptions, } from "./stores/file/index.js";
|
|
146
146
|
export { CacheBreakDetector, type CacheBreakFinding, type ToolFingerprintInput } from "./core/cache-break-detector.js";
|
|
147
|
-
export { maybeCompact, type MaybeCompactOptions, type CompactionWindowSafetyInfo } from "./core/auto-compaction.js";
|
|
147
|
+
export { maybeCompact, type MaybeCompactOptions, type CompactionPassStart, type CompactionWindowSafetyInfo } from "./core/auto-compaction.js";
|
|
148
148
|
export type { CompactionEffect } from "./core/frame-settlement.js";
|
|
149
149
|
export { brainToRuntime } from "./core/runtime.js";
|
|
150
150
|
export { createSensitivePathPolicy, RECOMMENDED_SENSITIVE_PATTERNS } from "./core/sensitive-path-policy.js";
|
|
@@ -277,9 +277,10 @@ export { consolidateScope, advanceCursorAfterInline, type ConsolidateScopeDeps,
|
|
|
277
277
|
export { resolveMemoryConsolidationDriver, autoRunOnRecommendationEffective, // the ONE arming reading (`memory.auto_consolidation.arming_has_one_resolver`) — the seat's absence is not "off"
|
|
278
278
|
type MemoryConsolidationDriverDeps, } from "./core/runner/memory-consolidation-driver.js";
|
|
279
279
|
export { DEFAULT_COMPACTION_INSTRUCTIONS } from "./core/auto-compaction.js";
|
|
280
|
-
export { DEFAULT_SYSTEM_PROMPT, CODE_AGENT_PROMPT, SUBAGENT_PROMPT, CODE_SYSTEM_PROMPT, MEMORY_GUIDANCE, MEMORY_SAFETY, MEMORY_HYGIENE,
|
|
280
|
+
export { DEFAULT_SYSTEM_PROMPT, CODE_AGENT_PROMPT, SUBAGENT_PROMPT, CODE_SYSTEM_PROMPT, MEMORY_GUIDANCE, MEMORY_SAFETY, MEMORY_HYGIENE, OUTPUT_EFFICIENCY, CYBER_RISK, HARNESS_SECTION_ANCHOR, URL_SAFETY, SUMMARIZE_TOOL_RESULTS, EXECUTION_ENVIRONMENT, EXECUTION_ENVIRONMENT_OPEN_READS, executionEnvironmentBlockFor, buildEnvironmentContext, buildGitSnapshot, buildScratchpadSection, GIT_STATUS_MAX_CHARS, formatLocalDate, type EnvironmentFacts, type PromptBlock, } from "./prompts/default.js";
|
|
281
281
|
export { SUPERVISOR_PROMPT, ORCHESTRATION_GUIDANCE, ORCHESTRATION_AWARENESS, GOAL_COMPLETION_GUIDANCE } from "./prompts/supervisor.js";
|
|
282
282
|
export { OVERLAY_SOURCE_ORDER, type ChainLink as PromptChainLink, type PromptOverlay, type SupersededOverlay } from "./prompt-assembly/overlay.js";
|
|
283
|
+
export { PROMPT_BINDING_LIST_MAX, PROMPT_BINDING_MAX_CHARS } from "./prompt-assembly/overlay.js";
|
|
283
284
|
export { BANDS as PROMPT_BANDS } from "./prompt-assembly/bands.js";
|
|
284
285
|
export { OVERLAY_OPS, HOST_ROLES, HOST_FORMS, type OverlayOp as PromptOverlayOp, type OverlaySource as PromptOverlaySource, type HostRole as PromptHostRole, type HostForm as PromptHostForm, type VariantWhen as PromptVariantWhen } from "./prompt-assembly/catalog/schema.js";
|
|
285
286
|
export { SEMA_DEFAULT_CATALOG, catalogText } from "./prompt-assembly/catalog/index.js";
|
|
@@ -288,7 +289,7 @@ export { attachToolContract, getToolContract, hasToolContract, computeShapeDiges
|
|
|
288
289
|
export { normalizePromptEpoch, promptIdentityOf, PROMPT_EPOCH_ACTIVATIONS, PROMPT_EPOCH_CHANGES, type PromptEpochDescriptor, type PromptEpochActivation, type PromptEpochChange, type PromptIdentityLayers, type StoredPromptEpoch, } from "./prompt-assembly/epoch.js";
|
|
289
290
|
export { ARTIFACT_LIMITS, buildPromptArtifact, computeArtifactDigest, requiresOf, unmetRequirements, verifyPromptArtifact, type ArtifactVerifyCode, type ArtifactVerifyResult, type PromptArtifact, type PromptArtifactEvidence, type PromptArtifactPayload, type PromptArtifactRequires, type PublishedPromptArtifact, } from "./prompt-assembly/artifact.js";
|
|
290
291
|
export { buildTurnPromptSnapshot, loweringRecordFor, LOWERING_VERSION, PREFIX_INPUT_CLASSIFICATION, type CacheIdentityElements, type LoweringRecord, type PrefixInputClass, type RawPrefixInputs, type TurnPromptSnapshot, } from "./prompt-assembly/turn-snapshot.js";
|
|
291
|
-
export { CenterPromptSource, FilePromptArtifactStore, FilePromptSourceStateStore, MemoryPromptArtifactStore, MemoryPromptSourceStateStore, type PromptArtifactSource, type PromptArtifactStore, type PromptSourceState, type PromptSourceStateStore, } from "./prompt-assembly/artifact-store.js";
|
|
292
|
+
export { CenterPromptSource, FilePromptArtifactStore, FilePromptSourceStateStore, MemoryPromptArtifactStore, MemoryPromptSourceStateStore, type OnArtifactRefused, type PromptArtifactSource, type PromptArtifactStore, type PromptSourceState, type PromptSourceStateStore, type StoredArtifactRefusal, } from "./prompt-assembly/artifact-store.js";
|
|
292
293
|
export { stripEngineMetadata } from "./internal/llm.js";
|
|
293
294
|
export { EVENT_PROMPT_REGISTRY, eventDefaultOn, type CompiledEventPrompt, type EventDedupe, type EventDefaultPolicy } from "./prompt-assembly/event-registry.js";
|
|
294
295
|
export { OUTPUT_STYLE_NAME_MAX } from "./core/output-style.js";
|
|
@@ -366,6 +367,11 @@ export { TEAM_ROLES, DIRECTION_RELATIONS, teamRoleOf, mayDirect, type TeamRole,
|
|
|
366
367
|
export { createListAgentsTool, LIST_AGENTS_TOOL_NAME, LIST_AGENTS_TOOL_ALIAS, LIST_AGENTS_MAX_RESULT_CHARS, PEER_LISTING_FRESH_WINDOW_MS, isFreshPeerRow, type ListAgentsToolOptions, type ListAgentsRow } from "./agents/list-agents-tool.js";
|
|
367
368
|
export { CROSS_SESSION_CLASSIFIER_RULE } from "./agents/cross-session-envelope.js";
|
|
368
369
|
export { PEER_SESSION_ID_UNGRAMMATICAL_CODE, PEER_RESUPPLY_CAP, type PeerLaneMountVerdict, type PeerInboundDisposition } from "./agents/peer-session-drain.js";
|
|
370
|
+
export { ORG_DELIVERY_REFUSAL_CODES, isOrgDeliveryRefusalCode, mintCrossPrincipalRecord, isGateMintedRecord, PRINCIPAL_INBOX_TRIAGE_POLICIES, principalInboxTriagePolicy, principalInboxSideEffectKey, principalInboxConsumerOf, PRINCIPAL_INBOX_CONSUMER_INVALID_CODE, type PrincipalInboxConsumer, type OrgDeliveryGate, type OrgAuthenticatedSender, type CrossPrincipalBody, type OrgDeliveryOutcome, type OrgDeliveryRefusalCode, type PrincipalInboxTriagePolicy, } from "./agents/org-delivery-gate.js";
|
|
371
|
+
export { PRINCIPAL_INBOX_HANDLE } from "./agents/cross-session-ref.js";
|
|
372
|
+
export { CROSS_PRINCIPAL_MESSAGE_NOTICE } from "./agents/cross-session-envelope.js";
|
|
373
|
+
export { principalInboundLayers } from "./agents/cross-session-judge.js";
|
|
374
|
+
export { PRINCIPAL_INBOX_UNMINTED_CAUSE } from "./agents/peer-session-drain.js";
|
|
369
375
|
export { renderCrossSessionMessageFrame, renderCrossSessionNoticeLine } from "./core/task-notification.js";
|
|
370
376
|
export { PEER_HELD_QUEUE_CAP, PEER_IDLE_SUBSCRIPTION_TTL_MS, PEER_IDLE_SUBSCRIBER_TABLE_CAP, PEER_IDLE_OUTSTANDING_CAP, PEER_IDLE_PRIORS_KEPT, PEER_IDLE_FIRE_DEBOUNCE_MS, PEER_IDLE_HELD_BACKOFF_MS, PEER_IDLE_LABEL_MAX, CROSS_SESSION_DIALOG_EXPIRY_VALUES, CROSS_SESSION_DIALOG_EXPIRY_DEFAULT, resolveCrossSessionDialogExpiry, PEER_HELD_REVIEW_CAUSES, PEER_DELIVERY_RECEIPT_STATES, isPeerDeliveryReceiptState, PEER_DROP_REASONS, peerRecipientSuffix, renderCrossSessionDeliveryNotice, describePeerDropReasons, renderCrossSessionDroppedNotice, PEER_IDLE_NOTICE_KINDS, isPeerIdleNoticeKind, PEER_IDLE_UNAVAILABLE_CAUSES, peerIdleNoticeLabel, formatPeerNoticeClock, renderCrossSessionIdleNotice, describePeerIdleSubscription, type CrossSessionDialogExpiry, type ResolvedCrossSessionDialogExpiry, type PeerDeliveryReceiptState, type PeerDropReason, type PeerIdleNoticeKind, type PeerIdleNoticeFields, } from "./agents/peer-notices.js";
|
|
371
377
|
export { createPeerHeldQueue, peerHeldQueueFor, peerHeldQueueIfAny, peerHeldQueueKey, realPeerClock, type PeerInboundHoldCause, type PeerHeldEntry, type PeerHeldSettlement, type PeerHeldSettleReason, type PeerHeldSettleOutcome, type PeerClock, type PeerHeldQueueSink, type PeerHeldQueueConfig, type PeerHeldQueue, } from "./agents/peer-held-queue.js";
|
|
@@ -378,17 +384,17 @@ export { builtinAgentDefinitions, BUILTIN_READONLY_DENY_TOOLS, EXPLORE_WHEN_TO_U
|
|
|
378
384
|
export { createTaskServer, type TaskServerOptions, type TaskRequestBody, } from "./server/http.js";
|
|
379
385
|
export { clearStaleToolResults, editBudget, type ContextEditOptions, } from "./core/context-edit.js";
|
|
380
386
|
export { createOpenAIBrain, type OpenAIBrainConfig } from "./brain/openai.js";
|
|
381
|
-
export { createAnthropicBrain, type AnthropicBrainConfig } from "./brain/anthropic.js";
|
|
387
|
+
export { createAnthropicBrain, ANTHROPIC_DEFAULT_BASE_URL, type AnthropicBrainConfig } from "./brain/anthropic.js";
|
|
382
388
|
export { createOpenResponsesBrain, type OpenResponsesBrainConfig } from "./brain/open-responses.js";
|
|
383
389
|
export { FABLE_5_COMPAT, fable5Model } from "./brain/model-presets.js";
|
|
384
390
|
export { createFailoverBrain } from "./brain/failover.js";
|
|
385
|
-
export { createRoutingBrain, type RoutingBrainOptions } from "./brain/routing.js";
|
|
391
|
+
export { createRoutingBrain, brainLaneOf, type RoutingBrainOptions } from "./brain/routing.js";
|
|
386
392
|
export { repairTextToolCalls } from "./brain/tool-call-repair.js";
|
|
387
393
|
export { createCircuitBreakerBrain, type CircuitBreakerOptions, type BreakerState, type BreakerSnapshot, type BreakerPhase, CIRCUIT_OPEN_MARKER, } from "./brain/circuit-breaker.js";
|
|
388
394
|
export { createDegradingBrain, readDegradation, DEGRADED_DIAGNOSTIC_TYPE, type DegradingBrainOptions, type DegradeReason, type DegradationInfo, } from "./brain/degrading.js";
|
|
389
395
|
export { retryBackoffMs, parseRetryAfter } from "./brain/retry.js";
|
|
390
396
|
export { WAITING_FIRST_TOKEN_AFTER_MS, WAITING_FIRST_TOKEN_EVERY_MS } from "./brain/stream-engine.js";
|
|
391
|
-
export { adjudicateModelRoute, resolveRouteCredential, routeRefusalText, routePairingStatus, routeKeyOf, displayUrlOf, resolveRequestRoot, resolveRequestRootOf, joinRequestUrl, hasAuthCarrier, __resetCredentialOriginBindings, type RoutePairingStatus, } from "./brain/route-adjudicator.js";
|
|
397
|
+
export { adjudicateModelRoute, resolveRouteCredential, admitRouteRequest, routeRefusalText, routePairingStatus, routeKeyOf, displayUrlOf, resolveRequestRoot, resolveRequestRootOf, joinRequestUrl, hasAuthCarrier, __resetCredentialOriginBindings, type RoutePairingStatus, } from "./brain/route-adjudicator.js";
|
|
392
398
|
export { ROUTE_CREDENTIAL_SOURCES, ROUTE_CARRIERS, ROUTE_CARRIER_BAGS, REQUEST_ROOT_ORIGINS, ROUTE_CREDENTIAL_PAIRING, requestRouteOf, routePairingRowOf, type RequestRoute, type RouteCarrier, type RouteCarrierBag, type RequestRootOrigin, type RouteCredentialPairingRow, } from "./brain/request-route.js";
|
|
393
399
|
export type { RouteAdjudication, RouteCredential, RouteCredentialSource, RoutePairingConfig, RoutePairingPosture, RouteRefusalCode, RouteRefusalDetail, } from "./internal/llm.js";
|
|
394
400
|
export { ROUTE_ADJUDICATION_CONFORMANCE_CORPUS, type RouteAdjudicationVector } from "./brain/route-conformance.js";
|
|
@@ -405,5 +411,5 @@ export { RULE_OFFERS_ABSENCES, type RuleOffersAbsence } from "./core/ask-origin.
|
|
|
405
411
|
export { BOUND_GRANT_ABSENCES, type BoundGrantAbsence } from "./core/skill-grant-binding.js";
|
|
406
412
|
export { DISPOSABLE_PROMPT_SECTIONS, type DisposablePromptSection, type PromptSectionEntry, type PromptSectionAuthor, type McpInstructionsEntry } from "./core/prompt-section-seat.js";
|
|
407
413
|
export type { McpRevocationLedger, McpMountIdentity } from "./core/mcp-server-spec.js";
|
|
408
|
-
export { readMcpToolAxes } from "./core/mcp-server-spec.js";
|
|
409
|
-
export type {
|
|
414
|
+
export { readToolAxes, readMcpToolAxes } from "./core/mcp-server-spec.js";
|
|
415
|
+
export type { ToolAxesRead, ToolAxesSurface } from "./core/mcp-server-spec.js";
|