@sema-agent/core 7.2.0 → 7.3.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 +43 -0
- package/dist/agents/cross-session-envelope.d.ts +7 -0
- package/dist/agents/cross-session-envelope.js +4 -0
- package/dist/agents/list-agents-tool.d.ts +55 -0
- package/dist/agents/list-agents-tool.js +94 -0
- package/dist/agents/peer-admission.d.ts +17 -1
- package/dist/agents/peer-admission.js +19 -2
- package/dist/agents/peer-directory.d.ts +208 -0
- package/dist/agents/peer-directory.js +272 -0
- package/dist/agents/peer-session-drain.d.ts +159 -0
- package/dist/agents/peer-session-drain.js +245 -0
- package/dist/agents/send-message-tool.d.ts +31 -0
- package/dist/agents/send-message-tool.js +145 -4
- package/dist/agents/subagent-steps.d.ts +11 -0
- package/dist/agents/subagent-steps.js +27 -4
- package/dist/brain/status-sink.d.ts +10 -0
- package/dist/brain/status-sink.js +13 -4
- package/dist/brain/stream-engine.d.ts +11 -0
- package/dist/brain/stream-engine.js +39 -3
- package/dist/core/arg-summary.d.ts +13 -3
- package/dist/core/arg-summary.js +138 -7
- package/dist/core/auto-mode-arming.d.ts +11 -0
- package/dist/core/auto-mode-arming.js +7 -1
- package/dist/core/auto-mode-prompt.d.ts +5 -0
- package/dist/core/auto-mode-prompt.js +2 -1
- package/dist/core/auto-mode-rebuild.d.ts +2 -1
- package/dist/core/auto-mode-rebuild.js +2 -0
- package/dist/core/checkpoint-store.d.ts +14 -0
- package/dist/core/checkpoint-store.js +4 -3
- package/dist/core/governance-codes.d.ts +1 -1
- package/dist/core/governance-codes.js +6 -0
- package/dist/core/mailbox-store.d.ts +89 -2
- package/dist/core/mailbox-store.js +77 -2
- package/dist/core/permission-rule-model.d.ts +9 -0
- package/dist/core/permission-rule-model.js +4 -1
- package/dist/core/runner/prepare-task.d.ts +20 -0
- package/dist/core/runner/prepare-task.js +152 -37
- package/dist/core/runner/runtask.js +5 -2
- package/dist/core/runner/tool-output-projection.js +1 -0
- package/dist/core/store-contracts/mailbox-store-contract.d.ts +23 -0
- package/dist/core/store-contracts/mailbox-store-contract.js +157 -1
- package/dist/core/task-notification.d.ts +38 -9
- package/dist/core/task-notification.js +8 -2
- package/dist/core/tools.js +1 -0
- package/dist/core/types.d.ts +176 -26
- package/dist/core/wiring-manifest.d.ts +62 -5
- package/dist/core/wiring-manifest.js +9 -0
- package/dist/engine/harness/agent-harness.d.ts +1 -0
- package/dist/engine/harness/agent-harness.js +3 -0
- package/dist/engine/harness/types.d.ts +3 -0
- package/dist/engine/loop/agent-loop.d.ts +7 -0
- package/dist/engine/loop/agent-loop.js +79 -0
- package/dist/engine/loop/types.d.ts +42 -0
- package/dist/index.d.ts +12 -5
- package/dist/index.js +11 -4
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/stores/cc/mailbox-store.d.ts +1 -1
- package/dist/stores/cc/mailbox-store.js +13 -0
- package/dist/stores/file/adoption/marker.d.ts +1 -1
- package/dist/stores/file/mailbox-store.d.ts +57 -0
- package/dist/stores/file/mailbox-store.js +369 -18
- package/dist/tools/fs/fs-write.js +69 -3
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +121 -1
|
@@ -56,6 +56,28 @@ export type QuestionChannelState = "wired" | "absent" | "stripped_bg_lane";
|
|
|
56
56
|
export type SeamProvenance = "spec" | "deps";
|
|
57
57
|
/** Machine-readable reason codes for a park lane that is not (or not provably) effective. */
|
|
58
58
|
export type ParkLaneReason = "no_checkpoint_store" | "no_durable_approval_opt_in" | "no_force_durable_gate" | "no_armed_safety_vocabulary" | "await_runtime_caps" | "await_tool_vocabulary";
|
|
59
|
+
/**
|
|
60
|
+
* #529 — the closed set of auto-mode ARMING outcomes a leg's manifest reports
|
|
61
|
+
* ({@link WiringManifest.autoMode}). Minted from the arming predicate's own three-arm read, as the
|
|
62
|
+
* FIRST failing arm in predicate order:
|
|
63
|
+
* - `no_intent` — no `TaskSpec.autoModeRequested` seat and no intent inherited on the chain /
|
|
64
|
+
* recorded on the resumed checkpoint (a non-auto run; byte-identical arming).
|
|
65
|
+
* - `no_face` — intent, but no `RunnerDeps.autoMode` deployment face (the trust gate).
|
|
66
|
+
* - `denied` — intent + face, but the organization's deny bit (`RuntimeCaps.autoMode:false`)
|
|
67
|
+
* as the resolver STATED it.
|
|
68
|
+
* - `resolver_fault` — intent + face, and the deny bit was COINED by a resolver fault (a throw, or a
|
|
69
|
+
* marshalled/non-record result the value screen refused) — an outage, not a
|
|
70
|
+
* verdict; the same fail-closed outcome as `denied`, named apart so a consumer
|
|
71
|
+
* can tell "policy said no" from "the entitlement source was unreachable".
|
|
72
|
+
* - `armed` — all three arms held; the classifier decider was minted for this leg.
|
|
73
|
+
* - `latch_open` — the session's one-way "back to non-auto" breaker has tripped. A leg-START
|
|
74
|
+
* manifest never carries it (a decider is minted fresh at prepare and its latch
|
|
75
|
+
* is closed by construction; a tripped ancestor hands no intent forward, which
|
|
76
|
+
* reads as `no_intent`); it is in the vocabulary so a consumer switching on the
|
|
77
|
+
* closed set is complete for a mid-leg re-read face, which nothing mints today.
|
|
78
|
+
*/
|
|
79
|
+
export declare const AUTO_MODE_ARM_REASONS: readonly ["armed", "no_intent", "no_face", "denied", "resolver_fault", "latch_open"];
|
|
80
|
+
export type AutoModeArmReason = (typeof AUTO_MODE_ARM_REASONS)[number];
|
|
59
81
|
/**
|
|
60
82
|
* design/173 §2.2/§8.4 — the wiring manifest. Consumers MUST ignore unknown fields
|
|
61
83
|
* (`schemaVersion` bumps only on a semantic break of an EXISTING field). The TaskEvent face is the
|
|
@@ -175,6 +197,34 @@ export interface WiringManifest {
|
|
|
175
197
|
memoryAdmission: boolean;
|
|
176
198
|
retention: boolean;
|
|
177
199
|
};
|
|
200
|
+
/**
|
|
201
|
+
* EFFECTIVE half only, present iff the model gate trimmed a default-mounted tool from THIS run's
|
|
202
|
+
* roster: the per-session READ face of the same fact `config.tool_model_gate_removed` announces on
|
|
203
|
+
* the operator sink (one notice per sink, not per session — a client that needs "which default tools
|
|
204
|
+
* did MY session lose" reads it here). `class` = the gate class the table keyed the trim on, `removed`
|
|
205
|
+
* = the wire names not mounted, `restore` = the three valves in one sentence. Minted from the SAME
|
|
206
|
+
* gate decision the notice reads (one source, projected twice); absent = no trim on this run. A gate
|
|
207
|
+
* table with several classes trimming at once reports the FIRST class here and every removed name
|
|
208
|
+
* across classes in `removed` (the notice keeps its per-class lines).
|
|
209
|
+
*/
|
|
210
|
+
modelGate?: {
|
|
211
|
+
class: string;
|
|
212
|
+
removed: readonly string[];
|
|
213
|
+
restore: string;
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* #529 — EFFECTIVE half only, and ALWAYS present on an engine-minted effective manifest (unlike
|
|
217
|
+
* `modelGate`, which is present only when a trim happened: auto mode has an answer on every leg,
|
|
218
|
+
* so absence here means an older mint or an external derivation, never "not applicable"). The
|
|
219
|
+
* per-leg READ face of the auto-mode arming decision: `armed` ⇔ `reason === "armed"` (the
|
|
220
|
+
* classifier decider was minted for this leg), and `reason` names the first arm that failed
|
|
221
|
+
* otherwise — see {@link AUTO_MODE_ARM_REASONS}. A serving layer that used to infer the mode from
|
|
222
|
+
* spec shape reads it here instead.
|
|
223
|
+
*/
|
|
224
|
+
autoMode?: {
|
|
225
|
+
armed: boolean;
|
|
226
|
+
reason: AutoModeArmReason;
|
|
227
|
+
};
|
|
178
228
|
/** EFFECTIVE half only — a short, non-sensitive fingerprint (sha256 prefix over the canonical
|
|
179
229
|
* JSON of this manifest's own resolved facts; every field here is an enum/boolean/count, no
|
|
180
230
|
* secrets) so an operator can correlate legs that ran under the same resolved assembly. */
|
|
@@ -231,6 +281,18 @@ export interface WiringFacts {
|
|
|
231
281
|
complianceWired: boolean;
|
|
232
282
|
memoryAdmissionWired: boolean;
|
|
233
283
|
retentionPolicyWired: boolean;
|
|
284
|
+
/** Effective half only — see {@link WiringManifest.modelGate}; the static half has no roster to trim. */
|
|
285
|
+
modelGate?: {
|
|
286
|
+
class: string;
|
|
287
|
+
removed: readonly string[];
|
|
288
|
+
restore: string;
|
|
289
|
+
};
|
|
290
|
+
/** Effective half only — see {@link WiringManifest.autoMode}; the static half has no leg to arm.
|
|
291
|
+
* `armed` must agree with `reason` (`armed ⇔ reason === "armed"`); a contradicting pair is refused. */
|
|
292
|
+
autoMode?: {
|
|
293
|
+
armed: boolean;
|
|
294
|
+
reason: AutoModeArmReason;
|
|
295
|
+
};
|
|
234
296
|
}
|
|
235
297
|
/** Named view of the deps seats the static half reads (a `Pick` of the real {@link RunnerDeps} —
|
|
236
298
|
* single-source shapes, no parallel hand-copied interface). */
|
|
@@ -292,11 +354,6 @@ export declare function resolveSubagentTranscriptTier(agentStoreWired: boolean,
|
|
|
292
354
|
* else the headless degrade `auto_deny`.
|
|
293
355
|
*/
|
|
294
356
|
export declare function deriveAskEffective(form: AskSeamForm, parkEffective: boolean | "unresolved"): AskEffective;
|
|
295
|
-
/**
|
|
296
|
-
* design/173 §2.1 — the SINGLE derivation from facts to manifest, shared by both halves. The static
|
|
297
|
-
* half omits `ask.effective`, `leg` and the fingerprint; the effective half carries all three. Any
|
|
298
|
-
* second construction point for {@link WiringManifest} is a defect (single-mint rule).
|
|
299
|
-
*/
|
|
300
357
|
export declare function deriveWiringManifest(facts: WiringFacts): WiringManifest;
|
|
301
358
|
/** The one ask-seat resolution (`spec` wins over `deps`), shared with the effective half so the
|
|
302
359
|
* form/provenance read cannot fork. Junk values (a JS caller passing something outside the OnAsk
|
|
@@ -2,6 +2,7 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
import { canonicalize } from "./canonical-json.js";
|
|
3
3
|
import { resolveCheckpointStore } from "./checkpoint-store.js";
|
|
4
4
|
import { isLiveQuestionFace } from "./ask-question.js";
|
|
5
|
+
export const AUTO_MODE_ARM_REASONS = ["armed", "no_intent", "no_face", "denied", "resolver_fault", "latch_open"];
|
|
5
6
|
export function resolveDeclaredDurability(store, storeName) {
|
|
6
7
|
const declared = store?.durability;
|
|
7
8
|
if (declared === undefined)
|
|
@@ -66,6 +67,12 @@ function deriveParkLane(facts) {
|
|
|
66
67
|
reasons.push("no_armed_safety_vocabulary");
|
|
67
68
|
return { capable: true, effective: unresolved ? "unresolved" : false, reasons, ...durability };
|
|
68
69
|
}
|
|
70
|
+
function readAutoModeFact(fact) {
|
|
71
|
+
if (!AUTO_MODE_ARM_REASONS.includes(fact.reason) || fact.armed !== (fact.reason === "armed")) {
|
|
72
|
+
throw new Error(`the auto-mode wiring fact is inconsistent (armed=${String(fact.armed)}, reason=${JSON.stringify(fact.reason)}) — armed must hold exactly when reason is "armed", and reason must be one of ${AUTO_MODE_ARM_REASONS.join("|")}`);
|
|
73
|
+
}
|
|
74
|
+
return { armed: fact.armed, reason: fact.reason };
|
|
75
|
+
}
|
|
69
76
|
export function deriveWiringManifest(facts) {
|
|
70
77
|
if (facts.half === "static" && facts.leg !== undefined) {
|
|
71
78
|
throw new Error("a static wiring manifest has no leg — leg identity is an effective-half fact");
|
|
@@ -117,6 +124,8 @@ export function deriveWiringManifest(facts) {
|
|
|
117
124
|
memoryAdmission: facts.memoryAdmissionWired,
|
|
118
125
|
retention: facts.retentionPolicyWired,
|
|
119
126
|
},
|
|
127
|
+
...(facts.half === "effective" && facts.modelGate !== undefined ? { modelGate: { class: facts.modelGate.class, removed: [...facts.modelGate.removed], restore: facts.modelGate.restore } } : {}),
|
|
128
|
+
...(facts.half === "effective" && facts.autoMode !== undefined ? { autoMode: readAutoModeFact(facts.autoMode) } : {}),
|
|
120
129
|
};
|
|
121
130
|
if (facts.half === "effective") {
|
|
122
131
|
const { leg: _leg, ...assembly } = manifest;
|
|
@@ -203,6 +203,7 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
|
|
|
203
203
|
private stallTimeoutsPerCall?;
|
|
204
204
|
private abortResultDetails?;
|
|
205
205
|
private loopTrace?;
|
|
206
|
+
private onToolInputValidationFault?;
|
|
206
207
|
private resilience?;
|
|
207
208
|
private maxToolConcurrency?;
|
|
208
209
|
private streamingToolExecution?;
|
|
@@ -252,6 +252,7 @@ export class AgentHarness {
|
|
|
252
252
|
stallTimeoutsPerCall;
|
|
253
253
|
abortResultDetails;
|
|
254
254
|
loopTrace;
|
|
255
|
+
onToolInputValidationFault;
|
|
255
256
|
resilience;
|
|
256
257
|
maxToolConcurrency;
|
|
257
258
|
streamingToolExecution;
|
|
@@ -285,6 +286,7 @@ export class AgentHarness {
|
|
|
285
286
|
this.stallTimeoutsPerCall = options.stallTimeoutsPerCall;
|
|
286
287
|
this.abortResultDetails = options.abortResultDetails;
|
|
287
288
|
this.loopTrace = options.loopTrace;
|
|
289
|
+
this.onToolInputValidationFault = options.onToolInputValidationFault;
|
|
288
290
|
this.resilience = options.resilience;
|
|
289
291
|
this.maxToolConcurrency = options.maxToolConcurrency;
|
|
290
292
|
this.streamingToolExecution = options.streamingToolExecution;
|
|
@@ -577,6 +579,7 @@ export class AgentHarness {
|
|
|
577
579
|
...(this.maxOutputTokensPerCall !== undefined ? { maxTokensPerCall: this.maxOutputTokensPerCall } : {}),
|
|
578
580
|
...(this.stallTimeoutsPerCall !== undefined ? { stallTimeoutsPerCall: this.stallTimeoutsPerCall } : {}),
|
|
579
581
|
...(this.abortResultDetails !== undefined ? { abortResultDetails: this.abortResultDetails } : {}),
|
|
582
|
+
...(this.onToolInputValidationFault !== undefined ? { onToolInputValidationFault: this.onToolInputValidationFault } : {}),
|
|
580
583
|
...(this.resilience !== undefined ? { resilience: this.resilience } : {}),
|
|
581
584
|
...(this.maxToolConcurrency !== undefined ? { maxToolConcurrency: this.maxToolConcurrency } : {}),
|
|
582
585
|
...(this.streamingToolExecution === true && (this.getHandlers("tool_call")?.size ?? 0) === 0
|
|
@@ -1367,6 +1367,9 @@ export interface AgentHarnessOptions<TSkill extends Skill = Skill, TPromptTempla
|
|
|
1367
1367
|
* recoveries were invisible outside display:false nudge messages). Must not throw; hot path.
|
|
1368
1368
|
*/
|
|
1369
1369
|
loopTrace?: (step: import("../loop/agent-loop.js").LoopStep) => void;
|
|
1370
|
+
/** Loop-config pass-through — see `AgentLoopConfig.onToolInputValidationFault` (a throwing
|
|
1371
|
+
* `AgentTool.validateInput` is read as no verdict and disclosed here). */
|
|
1372
|
+
onToolInputValidationFault?: import("../loop/types.js").AgentLoopConfig["onToolInputValidationFault"];
|
|
1370
1373
|
/**
|
|
1371
1374
|
* design/131 (拍): per-task resilience intent flags, forwarded to every provider
|
|
1372
1375
|
* call (`StreamOptions.resilience`) so the deployment's decorator stack (degrading / failover /
|
|
@@ -103,3 +103,10 @@ export declare const ROSTER_LISTING_MAX = 25;
|
|
|
103
103
|
* core/tool-errors.ts, same reason).
|
|
104
104
|
*/
|
|
105
105
|
export declare const ROSTER_SEARCH_HINT_NAME = "ToolSearch";
|
|
106
|
+
/** The structured `details.code` of a tool result minted by an input pre-validation refusal (lifted onto
|
|
107
|
+
* the wire frame's `errorCode` like every other loop-minted code, e.g. `tool.not_found`). */
|
|
108
|
+
export declare const TOOL_VALIDATION_REFUSED_CODE = "tool.validation_refused";
|
|
109
|
+
/** How long an asynchronous `validateInput` may take to answer before it is read as "no verdict" (and
|
|
110
|
+
* reported on the fault seat): a validator is a precondition read, not a network call, so a single
|
|
111
|
+
* bound serves every tool; a deployment validator that needs longer is a validator doing too much. */
|
|
112
|
+
export declare const TOOL_INPUT_VALIDATION_TIMEOUT_MS = 10000;
|
|
@@ -1122,6 +1122,76 @@ function formatRosterRecovery(availableTools) {
|
|
|
1122
1122
|
: "";
|
|
1123
1123
|
return ` Available tools: ${listing}${hint}`;
|
|
1124
1124
|
}
|
|
1125
|
+
export const TOOL_VALIDATION_REFUSED_CODE = "tool.validation_refused";
|
|
1126
|
+
export const TOOL_INPUT_VALIDATION_TIMEOUT_MS = 10_000;
|
|
1127
|
+
async function runInputValidation(tool, args, toolCallId, signal, onFault) {
|
|
1128
|
+
if (tool.validateInput === undefined)
|
|
1129
|
+
return undefined;
|
|
1130
|
+
try {
|
|
1131
|
+
const verdict = await boundedValidatorCall(() => tool.validateInput(args, signal !== undefined ? { toolCallId, signal } : { toolCallId }), signal);
|
|
1132
|
+
if (verdict !== null && typeof verdict === "object" && verdict.ok === false && typeof verdict.message === "string") {
|
|
1133
|
+
return typeof verdict.code === "string" ? { message: verdict.message, code: verdict.code } : { message: verdict.message };
|
|
1134
|
+
}
|
|
1135
|
+
return undefined;
|
|
1136
|
+
}
|
|
1137
|
+
catch (error) {
|
|
1138
|
+
if (signal?.aborted === true)
|
|
1139
|
+
return undefined;
|
|
1140
|
+
try {
|
|
1141
|
+
const ret = onFault?.({ toolName: tool.name, toolCallId, error });
|
|
1142
|
+
if (ret !== null && typeof ret === "object" && typeof ret.then === "function") {
|
|
1143
|
+
ret.then(undefined, () => undefined);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
catch {
|
|
1147
|
+
}
|
|
1148
|
+
return undefined;
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
function boundedValidatorCall(call, signal) {
|
|
1152
|
+
return new Promise((resolve, reject) => {
|
|
1153
|
+
let settled = false;
|
|
1154
|
+
const finish = (fn) => {
|
|
1155
|
+
if (settled)
|
|
1156
|
+
return;
|
|
1157
|
+
settled = true;
|
|
1158
|
+
clearTimeout(timer);
|
|
1159
|
+
signal?.removeEventListener("abort", onAbort);
|
|
1160
|
+
fn();
|
|
1161
|
+
};
|
|
1162
|
+
const onAbort = () => finish(() => reject(Object.assign(new Error("tool input pre-validation aborted"), { name: "AbortError" })));
|
|
1163
|
+
const timer = setTimeout(() => finish(() => reject(new Error(`tool input pre-validation did not answer within ${TOOL_INPUT_VALIDATION_TIMEOUT_MS}ms`))), TOOL_INPUT_VALIDATION_TIMEOUT_MS);
|
|
1164
|
+
if (signal?.aborted === true) {
|
|
1165
|
+
onAbort();
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
1168
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
1169
|
+
let out;
|
|
1170
|
+
try {
|
|
1171
|
+
out = call();
|
|
1172
|
+
}
|
|
1173
|
+
catch (err) {
|
|
1174
|
+
finish(() => reject(err));
|
|
1175
|
+
return;
|
|
1176
|
+
}
|
|
1177
|
+
Promise.resolve(out).then((v) => finish(() => resolve(v)), (err) => finish(() => reject(err)));
|
|
1178
|
+
});
|
|
1179
|
+
}
|
|
1180
|
+
function sameToolArgs(a, b) {
|
|
1181
|
+
if (a === b)
|
|
1182
|
+
return true;
|
|
1183
|
+
const canon = (v) => JSON.stringify(v, (_k, x) => (x !== null && typeof x === "object" && !Array.isArray(x) ? Object.fromEntries(Object.keys(x).sort().map((k) => [k, x[k]])) : x));
|
|
1184
|
+
return canon(a) === canon(b);
|
|
1185
|
+
}
|
|
1186
|
+
function validationRefusedOutcome(tool, refusal) {
|
|
1187
|
+
return {
|
|
1188
|
+
kind: "immediate",
|
|
1189
|
+
result: createErrorToolResult(refusal.message, {
|
|
1190
|
+
details: { code: TOOL_VALIDATION_REFUSED_CODE, toolName: tool.name, ...(refusal.code !== undefined ? { reason: refusal.code } : {}) },
|
|
1191
|
+
}),
|
|
1192
|
+
isError: true,
|
|
1193
|
+
};
|
|
1194
|
+
}
|
|
1125
1195
|
async function prepareToolCall(currentContext, assistantMessage, toolCall, config, signal) {
|
|
1126
1196
|
const tool = findToolByName(currentContext.tools, toolCall.name);
|
|
1127
1197
|
if (!tool) {
|
|
@@ -1135,6 +1205,10 @@ async function prepareToolCall(currentContext, assistantMessage, toolCall, confi
|
|
|
1135
1205
|
try {
|
|
1136
1206
|
const preparedToolCall = prepareToolCallArguments(tool, toolCall);
|
|
1137
1207
|
let finalArgs = validateToolArguments(tool, preparedToolCall);
|
|
1208
|
+
const refusal = await runInputValidation(tool, finalArgs, toolCall.id, signal, config.onToolInputValidationFault);
|
|
1209
|
+
if (refusal !== undefined)
|
|
1210
|
+
return validationRefusedOutcome(tool, refusal);
|
|
1211
|
+
const validatedArgs = finalArgs;
|
|
1138
1212
|
if (config.beforeToolCall) {
|
|
1139
1213
|
const beforeResult = await config.beforeToolCall({
|
|
1140
1214
|
assistantMessage,
|
|
@@ -1161,6 +1235,11 @@ async function prepareToolCall(currentContext, assistantMessage, toolCall, confi
|
|
|
1161
1235
|
...preparedToolCall,
|
|
1162
1236
|
arguments: beforeResult.updatedInput,
|
|
1163
1237
|
});
|
|
1238
|
+
if (!sameToolArgs(validatedArgs, finalArgs)) {
|
|
1239
|
+
const rewrittenRefusal = await runInputValidation(tool, finalArgs, toolCall.id, signal, config.onToolInputValidationFault);
|
|
1240
|
+
if (rewrittenRefusal !== undefined)
|
|
1241
|
+
return validationRefusedOutcome(tool, rewrittenRefusal);
|
|
1242
|
+
}
|
|
1164
1243
|
}
|
|
1165
1244
|
}
|
|
1166
1245
|
if (signal?.aborted) {
|
|
@@ -19,6 +19,26 @@ export type StreamFn = LlmStreamFn;
|
|
|
19
19
|
* while tool-result message artifacts are emitted later in assistant source order.
|
|
20
20
|
*/
|
|
21
21
|
export type ToolExecutionMode = "sequential" | "parallel";
|
|
22
|
+
/**
|
|
23
|
+
* The verdict a tool's INPUT PRE-VALIDATION returns (see {@link AgentTool.validateInput}). `ok: true`
|
|
24
|
+
* (or an `undefined` return) lets the call proceed to the gate; `ok: false` refuses it BEFORE any
|
|
25
|
+
* permission question is asked — `message` is the model-facing text (the same text the tool's own
|
|
26
|
+
* execution would have produced for the same input, so the refusal reads identically either way) and
|
|
27
|
+
* `code` an optional machine-readable reason that rides the error result's structured details.
|
|
28
|
+
*/
|
|
29
|
+
export type ToolInputVerdict = {
|
|
30
|
+
ok: true;
|
|
31
|
+
} | {
|
|
32
|
+
ok: false;
|
|
33
|
+
message: string;
|
|
34
|
+
code?: string;
|
|
35
|
+
};
|
|
36
|
+
/** The context an input pre-validation hook receives: the call's identity and its abort signal, and
|
|
37
|
+
* nothing else — a validator reads state, it does not act on the run. */
|
|
38
|
+
export interface ToolInputValidationContext {
|
|
39
|
+
toolCallId: string;
|
|
40
|
+
signal?: AbortSignal;
|
|
41
|
+
}
|
|
22
42
|
/**
|
|
23
43
|
* Controls how many queued user messages are injected when the agent loop reaches a queue drain point.
|
|
24
44
|
*
|
|
@@ -527,6 +547,16 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
|
|
|
527
547
|
* signal re-check, which has always minted its abort result with no details.
|
|
528
548
|
*/
|
|
529
549
|
abortResultDetails?: () => Record<string, unknown> | undefined;
|
|
550
|
+
/**
|
|
551
|
+
* Fault seat for a THROWING {@link AgentTool.validateInput}: the loop reads the throw as "no
|
|
552
|
+
* verdict" (the call proceeds to the gate as if the tool had no validator) and reports the fault
|
|
553
|
+
* here so a host can disclose it. Must not throw; a throwing sink is swallowed.
|
|
554
|
+
*/
|
|
555
|
+
onToolInputValidationFault?: (info: {
|
|
556
|
+
toolName: string;
|
|
557
|
+
toolCallId: string;
|
|
558
|
+
error: unknown;
|
|
559
|
+
}) => void;
|
|
530
560
|
/**
|
|
531
561
|
* Called after a tool finishes executing, before `tool_execution_end` and tool-result message events are emitted.
|
|
532
562
|
*
|
|
@@ -684,6 +714,18 @@ export interface AgentTool<TParameters extends TSchema = TSchema, TDetails = unk
|
|
|
684
714
|
* (boundInputHash binds args, never the preview). NEVER adjudication input. Mechanism-neutral:
|
|
685
715
|
* any tool may declare one (run_workflow projects its script meta). */
|
|
686
716
|
approvalPreview?: (args: unknown) => unknown;
|
|
717
|
+
/**
|
|
718
|
+
* OPTIONAL input pre-validation, run by the loop AFTER schema validation and BEFORE the tool-call
|
|
719
|
+
* gate (permission hooks, policy, the human/classifier ask). A refusal is returned to the model as a
|
|
720
|
+
* typed error result and no question is ever asked for the call — the point of the seat: a call the
|
|
721
|
+
* tool would refuse on its own precondition (a file edit whose target was never read this session)
|
|
722
|
+
* must not cost the operator an approval card it can only ever fail on. Pure by contract: reads
|
|
723
|
+
* state (read-tracking, path grammar), never acts. A THROWING validator is read as "no verdict"
|
|
724
|
+
* (the call proceeds to the gate; the fault is disclosed through the loop's fault seat) — a broken
|
|
725
|
+
* validator must not refuse tools. The tool's own execution keeps validating the same precondition
|
|
726
|
+
* (the two reads are not one atomic step, and direct `execute` callers skip this seat).
|
|
727
|
+
*/
|
|
728
|
+
validateInput?: (args: Static<TParameters>, ctx: ToolInputValidationContext) => Promise<ToolInputVerdict | undefined> | ToolInputVerdict | undefined;
|
|
687
729
|
/** Execute the tool call. Throw on failure instead of encoding errors in `content`. */
|
|
688
730
|
execute: (toolCallId: string, params: Static<TParameters>, signal?: AbortSignal, onUpdate?: AgentToolUpdateCallback<TDetails>) => Promise<AgentToolResult<TDetails>>;
|
|
689
731
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -119,13 +119,13 @@ export { createFsWriteGatePolicy, type FsWriteGatePolicyOptions } from "./core/f
|
|
|
119
119
|
export { RETIRED_TOOL_NAMES } from "./core/tool-name-aliases.js";
|
|
120
120
|
export { DEFAULT_SUBAGENT_TOOL_NAME } from "./agents/subagent.js";
|
|
121
121
|
export { renderTaskNotificationXml, taskNotificationDedupKey, isDelegatedAgentTerminal, isTerminalTaskNotification, SystemInjectionQueue, type TaskNotificationPayload, type TaskNotificationStatus, type ExternalNotificationInput, type SystemInjection, type SystemInjectionPriority, SYSTEM_INJECTION_PRIORITIES, isSystemInjectionPriority, AGENT_MESSAGE_TAG, renderAgentMessageFrame, type SemaProvenance, } from "./core/task-notification.js";
|
|
122
|
-
export { describeStaticWiring, deriveWiringManifest, deriveAskEffective, resolveDeclaredDurability, resolveSubagentTranscriptTier, type SubagentTranscriptTier, resolveAskSeamForm, resolveQuestionSeam, countElicitOptIns, type WiringManifest, type WiringFacts, type WiringLegKind, type AskSeamForm, type AskEffective, type QuestionChannelState, type SeamProvenance, type ParkLaneReason, type ManifestDurability, type StaticWiringDeps, type StaticWiringSpec, } from "./core/wiring-manifest.js";
|
|
122
|
+
export { describeStaticWiring, deriveWiringManifest, deriveAskEffective, resolveDeclaredDurability, resolveSubagentTranscriptTier, type SubagentTranscriptTier, resolveAskSeamForm, resolveQuestionSeam, countElicitOptIns, AUTO_MODE_ARM_REASONS, type AutoModeArmReason, type WiringManifest, type WiringFacts, type WiringLegKind, type AskSeamForm, type AskEffective, type QuestionChannelState, type SeamProvenance, type ParkLaneReason, type ManifestDurability, type StaticWiringDeps, type StaticWiringSpec, } from "./core/wiring-manifest.js";
|
|
123
123
|
export { probeParkRoundTrip, durableParkGapOf, durableParkGapFor, PARK_SELFCHECK_SCOPE_PREFIX, type ParkSelfCheckResult, type ParkProbeFinding, type ParkProbeFindingCode, } from "./core/park-selfcheck.js";
|
|
124
124
|
export { type StoreDurability } from "./core/checkpoint-store.js";
|
|
125
125
|
export { type StoreFidelity } from "./core/checkpoint-store.js";
|
|
126
126
|
export { projectHumanInput, buildHumanInputEvent, type HumanInputSource, type HumanInputFrame, type HumanInputEvent, type HumanInputDelivery, } from "./core/human-input-projection.js";
|
|
127
127
|
export { TaskRegistry, defaultTaskRegistry, createTaskOutputTool, createTaskStopTool, type SemaTaskType, type SemaTaskStatus, type SemaTaskHandle, type ParkedClaimTicket, type TaskAccess, type UnifiedTaskOutput, type TaskRetrievalStatus, type StopSource, type RegisterMonitorInput, type MonitorTimers, MONITOR_BATCH_WINDOW_MS, MONITOR_DEFAULT_TIMEOUT_MS, MONITOR_MAX_TIMEOUT_MS, MONITOR_MAX_BATCHES_PER_MINUTE, canAccessWorkflowRun, DURABLE_AGENT_HANDLE_RE, } from "./core/task-registry.js";
|
|
128
|
-
export { InMemoryMailboxStore, type MailboxStore, type MailboxMessage, type MailboxLease, MailboxStoreError, MAILBOX_TOMBSTONED_RECIPIENT_CODE, } from "./core/mailbox-store.js";
|
|
128
|
+
export { InMemoryMailboxStore, type MailboxStore, type MailboxMessage, type MailboxLease, MailboxStoreError, type MailboxStoreErrorCode, MAILBOX_TOMBSTONED_RECIPIENT_CODE, type MailboxAppendMessage, type MailboxPeerMeta, type MailboxPeerFromMode, type MailboxPeerRecordKind, MAILBOX_PEER_FROM_MODES, MAILBOX_PEER_RECORD_KINDS, MAILBOX_INVALID_PEER_META_CODE, MAILBOX_CROSS_PROCESS_UNSAFE_CODE, readMailboxPeerMeta, mailboxCrossProcessMountVerdict, type MailboxCrossProcessVerdict, } from "./core/mailbox-store.js";
|
|
129
129
|
export { FileMailboxStore, type FileMailboxStoreOptions } from "./stores/file/mailbox-store.js";
|
|
130
130
|
export { createFileTaskListStore } from "./stores/file/task-list-store.js";
|
|
131
131
|
export { createCcFileTaskListStore } from "./stores/cc/task-list-store.js";
|
|
@@ -166,7 +166,7 @@ export { createPermissionRulePolicy, validatePermissionRules, parsePermissionRul
|
|
|
166
166
|
* and nothing more. Removal is exported without ceremony, because narrowing on a user's behalf is
|
|
167
167
|
* allowed and widening is not.
|
|
168
168
|
*/
|
|
169
|
-
export { parseAllowRuleText, formatAllowRuleText, ruleAdmitsCommand, findAdmittingRule, suggestRulesForCommand, scopeCoversCwd, pathWithinRoot, isRuleLive, renderUntrustedCommandText, UNCOVERED_SEGMENT_REASON_BASELINE, RULE_OFFERS_ABSENCE_BASELINE, type UncoveredSegmentDetail, type EditedRuleBreadthWarning, directoryRuleAdmits, BARE_INTERPRETER_NAMES, MAX_RULE_TEXT_CHARS, type PersistedAllowRule, type RuleTombstone, type RuleScope, type RuleDot, type RuleAdd, type RuleAddOrigin, type RuleOffer, type RuleOfferBatchMember, type SegmentRuleSuggestion, type SegmentCoverage, type RuleReject, type RuleRejectCode, type ParsedAllowRule, type PersistedRuleTool, type PersistedRuleMatch, } from "./core/permission-rule-model.js";
|
|
169
|
+
export { parseAllowRuleText, formatAllowRuleText, ruleAdmitsCommand, findAdmittingRule, suggestRulesForCommand, scopeCoversCwd, pathWithinRoot, isRuleLive, renderUntrustedCommandText, stripFormatCharacters, UNCOVERED_SEGMENT_REASON_BASELINE, RULE_OFFERS_ABSENCE_BASELINE, type UncoveredSegmentDetail, type EditedRuleBreadthWarning, directoryRuleAdmits, BARE_INTERPRETER_NAMES, MAX_RULE_TEXT_CHARS, type PersistedAllowRule, type RuleTombstone, type RuleScope, type RuleDot, type RuleAdd, type RuleAddOrigin, type RuleOffer, type RuleOfferBatchMember, type SegmentRuleSuggestion, type SegmentCoverage, type RuleReject, type RuleRejectCode, type ParsedAllowRule, type PersistedRuleTool, type PersistedRuleMatch, } from "./core/permission-rule-model.js";
|
|
170
170
|
export { removePersistedRule, applyTombstones, sameScope, isValidConsentScope, isValidDurableScope, InMemoryPermissionRuleStore, EMPTY_RULE_STORE, type PermissionRuleStore, type PermissionRuleStoreProvider, type StoredAllowRules, type RemoveResult, type PutResult, joinRuleStates, screenRuleSyncState, collectBelowFrontier, ruleSyncVector, joinFrontiers, dotAtOrBelowFrontier, sameRuleOwner, type RuleSyncState, type RuleSyncFrontier, type RuleSyncDrop, type RuleSyncLandingReport, type RuleOwner, type QuarantinedRuleAdd, PERMISSION_RULE_WRITER, writerOf, foldDelta, addDotsOf, assertDeleteDeltaCarriesNoAdd, assertRedemptionNotQuarantined, assertWriteDeltaScopeDurable, type PermissionRuleWriter, type WritablePermissionRuleStore, type RuleWriteDelta, type RuleAddDelta, type RuleDeleteDelta, type RuleSyncJoinDelta, type RawRuleSyncState, type RedemptionAuthorization, } from "./core/permission-rule-store.js";
|
|
171
171
|
export { syncPermissionRules, parseRuleSyncResponse, PERMISSION_RULE_SYNC_PATH, LOCAL_OWNER_UNSYNCABLE_CODE, type PermissionRuleSyncTransport, type PermissionRuleSyncResult, type RuleSyncRequestBody, type RuleSyncResponseBody, } from "./core/permission-rule-sync.js";
|
|
172
172
|
export { InMemorySessionRuleOverlay, type SessionRuleOverlay, type SessionRuleOverlayAdd, type SessionRuleOverlayApplyResult, } from "./core/permission-rule-session.js";
|
|
@@ -232,7 +232,7 @@ export { sessionRepoContract } from "./core/store-contracts/session-repo-contrac
|
|
|
232
232
|
export { toolResultStoreContract } from "./core/store-contracts/tool-result-store-contract.js";
|
|
233
233
|
export { fileHistoryStoreContract } from "./core/store-contracts/file-history-store-contract.js";
|
|
234
234
|
export { permissionRuleSyncContract, type PermissionRuleSyncContractHooks } from "./core/store-contracts/permission-rule-sync-contract.js";
|
|
235
|
-
export { MAILBOX_CONTRACT_SCOPE, mailboxStoreContract, mailboxAckOwnershipContract, mailboxBundledOnlyContract, mailboxTombstonedRecipientContract, type MailboxTombstonedRecipientContractHooks, } from "./core/store-contracts/mailbox-store-contract.js";
|
|
235
|
+
export { MAILBOX_CONTRACT_SCOPE, mailboxStoreContract, mailboxAckOwnershipContract, mailboxBundledOnlyContract, mailboxTombstonedRecipientContract, type MailboxTombstonedRecipientContractHooks, mailboxCrossProcessContract, type MailboxCrossProcessContractHooks, } from "./core/store-contracts/mailbox-store-contract.js";
|
|
236
236
|
export { BACKGROUND_AGENT_CONTRACT_SCOPE, backgroundAgentStoreContract, backgroundAgentStoreScopesContract, } from "./core/store-contracts/background-agent-store-contract.js";
|
|
237
237
|
export { type BackgroundAgentStore, type BackgroundAgentRecord, type BackgroundAgentRowSummary, type BackgroundAgentUsage, canAccessAgentRecord, STALE_RUNNING_REAP_ATTRIBUTION, BackgroundAgentStoreError, InMemoryBackgroundAgentStore, reconcileParkedAgents, queryBackgroundAgents, type BackgroundAgentQuery, } from "./core/background-agent-store.js";
|
|
238
238
|
export { serveDurableAgentRowLane, buildAgentPollDetails, type AgentPollDetailsInput, } from "./core/task-registry-agent.js";
|
|
@@ -255,6 +255,12 @@ export { createPeerAdmission, peerAdmissionFor, judgePeerAdmission, resolvePeerA
|
|
|
255
255
|
export { CROSS_SESSION_MESSAGE_TAG, CROSS_SESSION_MESSAGE_NOTICE, PERMISSION_MODE_CLASSES, isPermissionModeClass, CrossSessionCodecError, PEER_HOP_TOKEN_HEX, PEER_HOP_CHAIN_CARRY_WINDOW, encodePeerAddress, isCanonicalPeerAddress, encodeScopeAttribute, decodeScopeAttribute, canonicalPeerDisplayName, buildCrossSessionEnvelope, parseCrossSessionEnvelope, clampHopChain, encodeCcPeerFrame, decodeCcPeerFrame, type PermissionModeClass, type CrossSessionEnvelopeFields, type CrossSessionEnvelopeParse, type CrossSessionEnvelopeRefusal, type CcPeerFrameFields, type CcPeerFrameParse, } from "./agents/cross-session-envelope.js";
|
|
256
256
|
export { CROSS_SESSION_INBOUND_SETTINGS, isCrossSessionInboundSetting, resolveCrossSessionInboundSetting, CROSS_SESSION_HOLD_CAUSES, describeCrossSessionHoldCause, judgeCrossSessionInbound, foldPermissionModeClass, PEER_SEND_VERDICT_CODES, peerSendVerdictSeverity, type CrossSessionInboundSetting, type CrossSessionSettingSource, type CrossSessionInboundSettingLayers, type ResolvedCrossSessionInboundSetting, type CrossSessionHoldCause, type CrossSessionInboundVerdict, type CrossSessionInboundInput, type PeerSendVerdictCode, type PeerSendVerdict, } from "./agents/cross-session-judge.js";
|
|
257
257
|
export { PEER_REF_MIN, PEER_REF_MAX, PEER_REF_RE, mintPeerRef, formatPeerNameRef, parsePeerNameRef, normalizePeerName, PEER_ADDRESS_PREFIXES, reservedPeerNameReason, type PeerRefEntry, } from "./agents/cross-session-ref.js";
|
|
258
|
+
export { PEER_SESSION_RECORD_SCHEMA_VERSION, PEER_SESSION_RECORD_MAX_BYTES, SESSION_BOX_PREFIX, peerSessionBoxHandle, isPeerSessionId, PEER_SESSION_ID_GRAMMAR, parsePeerSessionAddress, readPeerSessionRecord, defaultPeerLivenessProbe, isPeerSessionProcessAlive, mintPeerSessionCandidates, resolvePeerSessions, createInMemoryPeerDirectory, vetPeerRegistryDirectory, judgePeerRecordFile, type PeerSessionRecord, type PeerSessionLiveness, type PeerSessionTempo, type PeerSessionRecordRefusal, type PeerSessionRecordRead, type PeerLivenessProbe, type PeerDirectory, type PeerDirectoryAccess, type PeerSessionCandidate, type PeerSessionResolution, type InMemoryPeerDirectory, type PeerRegistryDirectoryRefusal, type PeerRegistryDirectoryVerdict, } from "./agents/peer-directory.js";
|
|
259
|
+
export { createListAgentsTool, LIST_AGENTS_TOOL_NAME, LIST_AGENTS_TOOL_ALIAS, LIST_AGENTS_MAX_RESULT_CHARS, type ListAgentsToolOptions, type ListAgentsRow } from "./agents/list-agents-tool.js";
|
|
260
|
+
export { CROSS_SESSION_CLASSIFIER_RULE } from "./agents/cross-session-envelope.js";
|
|
261
|
+
export { PEER_SESSION_ID_UNGRAMMATICAL_CODE, type PeerLaneMountVerdict } from "./agents/peer-session-drain.js";
|
|
262
|
+
export { renderCrossSessionMessageFrame } from "./core/task-notification.js";
|
|
263
|
+
export { type PeerAdmissionStage } from "./agents/peer-admission.js";
|
|
258
264
|
export { createAgentTranscriptTool, AGENT_TRANSCRIPT_TOOL_NAME, type AgentTranscriptToolOptions, } from "./agents/agent-transcript-tool.js";
|
|
259
265
|
export { defineAgent } from "./agents/agent-definition.js";
|
|
260
266
|
export { builtinAgentDefinitions, BUILTIN_READONLY_DENY_TOOLS, EXPLORE_WHEN_TO_USE, EXPLORE_WHEN_TO_USE_LEAN, PLAN_WHEN_TO_USE, EXPLORE_SYSTEM_PROMPT, PLAN_SYSTEM_PROMPT, } from "./agents/builtin-agents.js";
|
|
@@ -271,13 +277,14 @@ export { repairTextToolCalls } from "./brain/tool-call-repair.js";
|
|
|
271
277
|
export { createCircuitBreakerBrain, type CircuitBreakerOptions, type BreakerState, type BreakerSnapshot, type BreakerPhase, CIRCUIT_OPEN_MARKER, } from "./brain/circuit-breaker.js";
|
|
272
278
|
export { createDegradingBrain, readDegradation, DEGRADED_DIAGNOSTIC_TYPE, type DegradingBrainOptions, type DegradeReason, type DegradationInfo, } from "./brain/degrading.js";
|
|
273
279
|
export { retryBackoffMs, parseRetryAfter } from "./brain/retry.js";
|
|
280
|
+
export { WAITING_FIRST_TOKEN_AFTER_MS, WAITING_FIRST_TOKEN_EVERY_MS } from "./brain/stream-engine.js";
|
|
274
281
|
export { adjudicateModelRoute, resolveRouteCredential, routeRefusalText, routePairingStatus, normalizeBaseUrl, hasAuthCarrier, type RoutePairingStatus, } from "./brain/route-adjudicator.js";
|
|
275
282
|
export type { RouteAdjudication, RouteCredential, RouteCredentialSource, RoutePairingConfig, RoutePairingPosture, RouteRefusalCode, RouteRefusalDetail, } from "./internal/llm.js";
|
|
276
283
|
export { ROUTE_ADJUDICATION_CONFORMANCE_CORPUS, type RouteAdjudicationVector } from "./brain/route-conformance.js";
|
|
277
284
|
export { type BrainTimeoutConfig } from "./brain/timeout.js";
|
|
278
285
|
export { createAssistantMessageEventStream } from "./internal/llm.js";
|
|
279
286
|
export type { AssistantMessage, AssistantMessageEvent, CompleteSimpleFn, Context, DocumentContent, ImageContent, Message, StopReason, StreamFn, TextContent, ThinkingContent, ToolCall, ToolResultMessage, Usage, UserMessage, } from "./internal/llm.js";
|
|
280
|
-
export type { AgentDefinition, BeforeWriteHook, BeforeWriteRequest, BeforeWriteResult, TrackFileEditHook, TrackEditRequest, TrackEditResult, HandsBandOptions, Brain, BrainStatus, BrainStatusPhase, BrainRetryErrClass, ImageInput, McpElicitRequest, McpElicitResponse, McpServerSpec, A2aServerSpec, OnElicit, Model, ModelRef, ProjectMemoryLoad, RunnerDeps, ResumePreflightInfo, ResumePreflightVerdict, EngineNotice, RuntimeCaps, BackgroundChildEvent, DelegationLifecycleEvent, SkillManifest, SkillSpec, TaskEvent, TaskEventIdentity, ToolActivity, TaskLimits, StaleToolResultOffloadOptions, TaskResult, EffectiveMemoryScopes, RemoteEnvFailureNote, TaskSpec, TaskStatus, TaskStream, CompactOutcome, ThinkingLevel, ToolExecuteContext, ToolReturn, ToolSpec, ReversibilityVerdict, ToolEffect, ToolContentOrigin, WorkflowGovernanceBaseline, DelegationTaskType, } from "./core/types.js";
|
|
287
|
+
export type { AgentDefinition, BeforeWriteHook, BeforeWriteRequest, BeforeWriteResult, TrackFileEditHook, TrackEditRequest, TrackEditResult, HandsBandOptions, Brain, BrainStatus, BrainStatusPhase, BrainRetryErrClass, ImageInput, McpElicitRequest, McpElicitResponse, McpServerSpec, A2aServerSpec, OnElicit, Model, ModelRef, ProjectMemoryLoad, RunnerDeps, ResumePreflightInfo, ResumePreflightVerdict, EngineNotice, RuntimeCaps, BackgroundChildEvent, DelegationLifecycleEvent, SkillManifest, SkillSpec, TaskEvent, TaskEventIdentity, ToolActivity, TaskLimits, StaleToolResultOffloadOptions, TaskResult, EffectiveMemoryScopes, RemoteEnvFailureNote, TaskSpec, TaskStatus, TaskStream, CompactOutcome, ThinkingLevel, ToolExecuteContext, ToolReturn, ToolSpec, ToolInputVerdict, ToolInputValidationContext, ReversibilityVerdict, ToolEffect, ToolContentOrigin, WorkflowGovernanceBaseline, DelegationTaskType, } from "./core/types.js";
|
|
281
288
|
export { Type } from "typebox";
|
|
282
289
|
export type { TSchema, Static } from "typebox";
|
|
283
290
|
export { explainPromptAssembly, describeDefaultPack, type DefaultPackDescription, type ExplainInput } from "./prompt-assembly/explain.js";
|
package/dist/index.js
CHANGED
|
@@ -96,13 +96,13 @@ export { createFsWriteGatePolicy } from "./core/fs-write-gate-policy.js";
|
|
|
96
96
|
export { RETIRED_TOOL_NAMES } from "./core/tool-name-aliases.js";
|
|
97
97
|
export { DEFAULT_SUBAGENT_TOOL_NAME } from "./agents/subagent.js";
|
|
98
98
|
export { renderTaskNotificationXml, taskNotificationDedupKey, isDelegatedAgentTerminal, isTerminalTaskNotification, SystemInjectionQueue, SYSTEM_INJECTION_PRIORITIES, isSystemInjectionPriority, AGENT_MESSAGE_TAG, renderAgentMessageFrame, } from "./core/task-notification.js";
|
|
99
|
-
export { describeStaticWiring, deriveWiringManifest, deriveAskEffective, resolveDeclaredDurability, resolveSubagentTranscriptTier, resolveAskSeamForm, resolveQuestionSeam, countElicitOptIns, } from "./core/wiring-manifest.js";
|
|
99
|
+
export { describeStaticWiring, deriveWiringManifest, deriveAskEffective, resolveDeclaredDurability, resolveSubagentTranscriptTier, resolveAskSeamForm, resolveQuestionSeam, countElicitOptIns, AUTO_MODE_ARM_REASONS, } from "./core/wiring-manifest.js";
|
|
100
100
|
export { probeParkRoundTrip, durableParkGapOf, durableParkGapFor, PARK_SELFCHECK_SCOPE_PREFIX, } from "./core/park-selfcheck.js";
|
|
101
101
|
export {} from "./core/checkpoint-store.js";
|
|
102
102
|
export {} from "./core/checkpoint-store.js";
|
|
103
103
|
export { projectHumanInput, buildHumanInputEvent, } from "./core/human-input-projection.js";
|
|
104
104
|
export { TaskRegistry, defaultTaskRegistry, createTaskOutputTool, createTaskStopTool, MONITOR_BATCH_WINDOW_MS, MONITOR_DEFAULT_TIMEOUT_MS, MONITOR_MAX_TIMEOUT_MS, MONITOR_MAX_BATCHES_PER_MINUTE, canAccessWorkflowRun, DURABLE_AGENT_HANDLE_RE, } from "./core/task-registry.js";
|
|
105
|
-
export { InMemoryMailboxStore, MailboxStoreError, MAILBOX_TOMBSTONED_RECIPIENT_CODE, } from "./core/mailbox-store.js";
|
|
105
|
+
export { InMemoryMailboxStore, MailboxStoreError, MAILBOX_TOMBSTONED_RECIPIENT_CODE, MAILBOX_PEER_FROM_MODES, MAILBOX_PEER_RECORD_KINDS, MAILBOX_INVALID_PEER_META_CODE, MAILBOX_CROSS_PROCESS_UNSAFE_CODE, readMailboxPeerMeta, mailboxCrossProcessMountVerdict, } from "./core/mailbox-store.js";
|
|
106
106
|
export { FileMailboxStore } from "./stores/file/mailbox-store.js";
|
|
107
107
|
export { createFileTaskListStore } from "./stores/file/task-list-store.js";
|
|
108
108
|
export { createCcFileTaskListStore } from "./stores/cc/task-list-store.js";
|
|
@@ -126,7 +126,7 @@ export { AUTO_MODE_BASE_PROMPT, AUTO_MODE_PERMISSIONS_EXTERNAL } from "./core/au
|
|
|
126
126
|
export { AUTO_MODE_ARMING_RECIPE_VERSION, autoModeArmingRecipeOf, sanitizeAutoModeArmingRecipe, foldAutoModeArming, } from "./core/auto-mode-arming.js";
|
|
127
127
|
export { rebuildAutoModeDecider, } from "./core/auto-mode-rebuild.js";
|
|
128
128
|
export { createPermissionRulePolicy, validatePermissionRules, parsePermissionRule, wildcardMatch, isNamespacedCoveringRuleName, namespacedRuleNameCovers, } from "./core/permission-rules.js";
|
|
129
|
-
export { parseAllowRuleText, formatAllowRuleText, ruleAdmitsCommand, findAdmittingRule, suggestRulesForCommand, scopeCoversCwd, pathWithinRoot, isRuleLive, renderUntrustedCommandText, UNCOVERED_SEGMENT_REASON_BASELINE, RULE_OFFERS_ABSENCE_BASELINE, directoryRuleAdmits, BARE_INTERPRETER_NAMES, MAX_RULE_TEXT_CHARS, } from "./core/permission-rule-model.js";
|
|
129
|
+
export { parseAllowRuleText, formatAllowRuleText, ruleAdmitsCommand, findAdmittingRule, suggestRulesForCommand, scopeCoversCwd, pathWithinRoot, isRuleLive, renderUntrustedCommandText, stripFormatCharacters, UNCOVERED_SEGMENT_REASON_BASELINE, RULE_OFFERS_ABSENCE_BASELINE, directoryRuleAdmits, BARE_INTERPRETER_NAMES, MAX_RULE_TEXT_CHARS, } from "./core/permission-rule-model.js";
|
|
130
130
|
export { removePersistedRule, applyTombstones, sameScope, isValidConsentScope, isValidDurableScope, InMemoryPermissionRuleStore, EMPTY_RULE_STORE, joinRuleStates, screenRuleSyncState, collectBelowFrontier, ruleSyncVector, joinFrontiers, dotAtOrBelowFrontier, sameRuleOwner, PERMISSION_RULE_WRITER, writerOf, foldDelta, addDotsOf, assertDeleteDeltaCarriesNoAdd, assertRedemptionNotQuarantined, assertWriteDeltaScopeDurable, } from "./core/permission-rule-store.js";
|
|
131
131
|
export { syncPermissionRules, parseRuleSyncResponse, PERMISSION_RULE_SYNC_PATH, LOCAL_OWNER_UNSYNCABLE_CODE, } from "./core/permission-rule-sync.js";
|
|
132
132
|
export { InMemorySessionRuleOverlay, } from "./core/permission-rule-session.js";
|
|
@@ -191,7 +191,7 @@ export { sessionRepoContract } from "./core/store-contracts/session-repo-contrac
|
|
|
191
191
|
export { toolResultStoreContract } from "./core/store-contracts/tool-result-store-contract.js";
|
|
192
192
|
export { fileHistoryStoreContract } from "./core/store-contracts/file-history-store-contract.js";
|
|
193
193
|
export { permissionRuleSyncContract } from "./core/store-contracts/permission-rule-sync-contract.js";
|
|
194
|
-
export { MAILBOX_CONTRACT_SCOPE, mailboxStoreContract, mailboxAckOwnershipContract, mailboxBundledOnlyContract, mailboxTombstonedRecipientContract, } from "./core/store-contracts/mailbox-store-contract.js";
|
|
194
|
+
export { MAILBOX_CONTRACT_SCOPE, mailboxStoreContract, mailboxAckOwnershipContract, mailboxBundledOnlyContract, mailboxTombstonedRecipientContract, mailboxCrossProcessContract, } from "./core/store-contracts/mailbox-store-contract.js";
|
|
195
195
|
export { BACKGROUND_AGENT_CONTRACT_SCOPE, backgroundAgentStoreContract, backgroundAgentStoreScopesContract, } from "./core/store-contracts/background-agent-store-contract.js";
|
|
196
196
|
export { canAccessAgentRecord, STALE_RUNNING_REAP_ATTRIBUTION, BackgroundAgentStoreError, InMemoryBackgroundAgentStore, reconcileParkedAgents, queryBackgroundAgents, } from "./core/background-agent-store.js";
|
|
197
197
|
export { serveDurableAgentRowLane, buildAgentPollDetails, } from "./core/task-registry-agent.js";
|
|
@@ -212,6 +212,12 @@ export { createPeerAdmission, peerAdmissionFor, judgePeerAdmission, resolvePeerA
|
|
|
212
212
|
export { CROSS_SESSION_MESSAGE_TAG, CROSS_SESSION_MESSAGE_NOTICE, PERMISSION_MODE_CLASSES, isPermissionModeClass, CrossSessionCodecError, PEER_HOP_TOKEN_HEX, PEER_HOP_CHAIN_CARRY_WINDOW, encodePeerAddress, isCanonicalPeerAddress, encodeScopeAttribute, decodeScopeAttribute, canonicalPeerDisplayName, buildCrossSessionEnvelope, parseCrossSessionEnvelope, clampHopChain, encodeCcPeerFrame, decodeCcPeerFrame, } from "./agents/cross-session-envelope.js";
|
|
213
213
|
export { CROSS_SESSION_INBOUND_SETTINGS, isCrossSessionInboundSetting, resolveCrossSessionInboundSetting, CROSS_SESSION_HOLD_CAUSES, describeCrossSessionHoldCause, judgeCrossSessionInbound, foldPermissionModeClass, PEER_SEND_VERDICT_CODES, peerSendVerdictSeverity, } from "./agents/cross-session-judge.js";
|
|
214
214
|
export { PEER_REF_MIN, PEER_REF_MAX, PEER_REF_RE, mintPeerRef, formatPeerNameRef, parsePeerNameRef, normalizePeerName, PEER_ADDRESS_PREFIXES, reservedPeerNameReason, } from "./agents/cross-session-ref.js";
|
|
215
|
+
export { PEER_SESSION_RECORD_SCHEMA_VERSION, PEER_SESSION_RECORD_MAX_BYTES, SESSION_BOX_PREFIX, peerSessionBoxHandle, isPeerSessionId, PEER_SESSION_ID_GRAMMAR, parsePeerSessionAddress, readPeerSessionRecord, defaultPeerLivenessProbe, isPeerSessionProcessAlive, mintPeerSessionCandidates, resolvePeerSessions, createInMemoryPeerDirectory, vetPeerRegistryDirectory, judgePeerRecordFile, } from "./agents/peer-directory.js";
|
|
216
|
+
export { createListAgentsTool, LIST_AGENTS_TOOL_NAME, LIST_AGENTS_TOOL_ALIAS, LIST_AGENTS_MAX_RESULT_CHARS } from "./agents/list-agents-tool.js";
|
|
217
|
+
export { CROSS_SESSION_CLASSIFIER_RULE } from "./agents/cross-session-envelope.js";
|
|
218
|
+
export { PEER_SESSION_ID_UNGRAMMATICAL_CODE } from "./agents/peer-session-drain.js";
|
|
219
|
+
export { renderCrossSessionMessageFrame } from "./core/task-notification.js";
|
|
220
|
+
export {} from "./agents/peer-admission.js";
|
|
215
221
|
export { createAgentTranscriptTool, AGENT_TRANSCRIPT_TOOL_NAME, } from "./agents/agent-transcript-tool.js";
|
|
216
222
|
export { defineAgent } from "./agents/agent-definition.js";
|
|
217
223
|
export { builtinAgentDefinitions, BUILTIN_READONLY_DENY_TOOLS, EXPLORE_WHEN_TO_USE, EXPLORE_WHEN_TO_USE_LEAN, PLAN_WHEN_TO_USE, EXPLORE_SYSTEM_PROMPT, PLAN_SYSTEM_PROMPT, } from "./agents/builtin-agents.js";
|
|
@@ -228,6 +234,7 @@ export { repairTextToolCalls } from "./brain/tool-call-repair.js";
|
|
|
228
234
|
export { createCircuitBreakerBrain, CIRCUIT_OPEN_MARKER, } from "./brain/circuit-breaker.js";
|
|
229
235
|
export { createDegradingBrain, readDegradation, DEGRADED_DIAGNOSTIC_TYPE, } from "./brain/degrading.js";
|
|
230
236
|
export { retryBackoffMs, parseRetryAfter } from "./brain/retry.js";
|
|
237
|
+
export { WAITING_FIRST_TOKEN_AFTER_MS, WAITING_FIRST_TOKEN_EVERY_MS } from "./brain/stream-engine.js";
|
|
231
238
|
export { adjudicateModelRoute, resolveRouteCredential, routeRefusalText, routePairingStatus, normalizeBaseUrl, hasAuthCarrier, } from "./brain/route-adjudicator.js";
|
|
232
239
|
export { ROUTE_ADJUDICATION_CONFORMANCE_CORPUS } from "./brain/route-conformance.js";
|
|
233
240
|
export {} from "./brain/timeout.js";
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
export type { CompactionPreparation, SummarizationClampDryRun } from "../engine/compaction/compaction.js";
|
|
8
8
|
export type { InvokedSkillRetention } from "../engine/compaction/utils.js";
|
|
9
9
|
export type { AgentCoreRuntimeDeps } from "../engine/loop/runtime-deps.js";
|
|
10
|
-
export type { AgentMessage, AgentTool, AgentToolResult, AgentToolUpdateCallback, ThinkingLevel, ToolExecutionMode, } from "../engine/loop/types.js";
|
|
10
|
+
export type { AgentMessage, AgentTool, AgentToolResult, AgentToolUpdateCallback, ThinkingLevel, ToolExecutionMode, ToolInputValidationContext, ToolInputVerdict, } from "../engine/loop/types.js";
|
|
11
11
|
export type { AgentHarnessEvent, CompactionSettings, ExecutionEnv, ExecutionErrorCode, FileError, FileErrorCode, FileInfo, Result, WriteExpectation, WriteReceipt, Session, SessionMetadata, SessionRepo, SessionStorage, SessionTreeEntry, Skill, } from "../engine/harness/types.js";
|
|
12
12
|
export type { ExecutionEnvExecOptions, ExecResult } from "../engine/harness/types.js";
|
|
13
13
|
export type { SessionWriteOptions, CompactionEntry } from "../engine/harness/types.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type MailboxStore } from "../../core/mailbox-store.js";
|
|
2
2
|
/** CC's path-component sanitize rule (README §一 Jeo/UJt): non-alphanumerics → "-", lowercased. */
|
|
3
3
|
export declare function sanitizeCcAgentName(name: string): string;
|
|
4
4
|
export interface CcFileMailboxStoreOptions {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, rmSync, readdirSync } from "node:fs";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
|
+
import { readMailboxPeerMeta } from "../../core/mailbox-store.js";
|
|
4
5
|
import { atomicWriteFile, canonicalStoreKey } from "../file/fs-atomic.js";
|
|
5
6
|
import { withCcLock } from "./lockfile.js";
|
|
6
7
|
const INBOX_FILE_EXT = ".json";
|
|
@@ -94,6 +95,15 @@ export function createCcFileMailboxStore(opts) {
|
|
|
94
95
|
note(path, `${dropped} malformed inbox entries skipped (first: ${firstReason})`);
|
|
95
96
|
return kept;
|
|
96
97
|
};
|
|
98
|
+
const readBackPeerMeta = (raw) => {
|
|
99
|
+
try {
|
|
100
|
+
const meta = readMailboxPeerMeta(raw);
|
|
101
|
+
return meta === undefined ? {} : { peerMeta: meta };
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return {};
|
|
105
|
+
}
|
|
106
|
+
};
|
|
97
107
|
const saveBox = (path, box) => {
|
|
98
108
|
atomicWriteFile(inboxDir, path, JSON.stringify(box, null, 2));
|
|
99
109
|
};
|
|
@@ -136,6 +146,7 @@ export function createCcFileMailboxStore(opts) {
|
|
|
136
146
|
return {
|
|
137
147
|
append: (scope, handle, msg) => {
|
|
138
148
|
requireDefaultScope(scope);
|
|
149
|
+
const peerMeta = readMailboxPeerMeta(msg.peerMeta);
|
|
139
150
|
mkdirSync(inboxDir, { recursive: true });
|
|
140
151
|
const path = inboxPath(handle);
|
|
141
152
|
const notes = deferredNotes();
|
|
@@ -150,6 +161,7 @@ export function createCcFileMailboxStore(opts) {
|
|
|
150
161
|
msg_id: randomUUID(),
|
|
151
162
|
read: false,
|
|
152
163
|
...(msg.hopChain !== undefined ? { hopChain: [...msg.hopChain] } : {}),
|
|
164
|
+
...(peerMeta !== undefined ? { peerMeta } : {}),
|
|
153
165
|
});
|
|
154
166
|
saveBox(path, box);
|
|
155
167
|
return box.length;
|
|
@@ -178,6 +190,7 @@ export function createCcFileMailboxStore(opts) {
|
|
|
178
190
|
...(Array.isArray(e.hopChain) && e.hopChain.every((h) => typeof h === "string")
|
|
179
191
|
? { hopChain: e.hopChain.filter((h) => typeof h === "string") }
|
|
180
192
|
: {}),
|
|
193
|
+
...readBackPeerMeta(e.peerMeta),
|
|
181
194
|
}));
|
|
182
195
|
if (pending.length === 0)
|
|
183
196
|
return Promise.resolve(null);
|
|
@@ -209,7 +209,7 @@ export declare function writeRootAdoptionFile(root: string, content: RootAdoptio
|
|
|
209
209
|
* and it is the ONLY thing this function does — it never reaches an object that already exists. So a
|
|
210
210
|
* store instance constructed BEFORE the marker landed keeps writing for as long as it is held, in
|
|
211
211
|
* ANOTHER OS process (cross-process sharing of one data dir is the file family's documented
|
|
212
|
-
* UNSUPPORTED shape
|
|
212
|
+
* UNSUPPORTED shape for the task-list store — F-14; the mailbox store is the exception since its per-box lock upgrade, see `stores/file/mailbox-store.ts`) and, symmetrically, in THIS one (an independent
|
|
213
213
|
* store face built before the adoption started; the arc's `LOCK` acquisition excludes a live
|
|
214
214
|
* `FileStorageBackend`, which is the only shape that takes that lock). Adoption adds no new promise on
|
|
215
215
|
* either side of that seam — see the freeze note on `adoptLocalDataRoot` for the full division.
|