@sema-agent/core 7.40.1 → 7.41.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 +188 -0
- package/dist/agents/agent-transcript-tool.d.ts +10 -2
- package/dist/agents/agent-transcript-tool.js +52 -26
- package/dist/agents/list-agents-tool.d.ts +17 -2
- package/dist/agents/list-agents-tool.js +28 -16
- package/dist/agents/peer-session-drain.d.ts +3 -1
- package/dist/agents/peer-session-drain.js +1 -0
- package/dist/agents/subagent-steps.d.ts +12 -2
- package/dist/agents/subagent-steps.js +8 -4
- package/dist/agents/subagent.d.ts +1 -17
- package/dist/agents/subagent.js +12 -24
- package/dist/core/agent-definition.d.ts +19 -40
- package/dist/core/agent-state.d.ts +91 -0
- package/dist/core/agent-state.js +79 -0
- package/dist/core/ask-origin.d.ts +28 -6
- package/dist/core/ask-origin.js +9 -5
- package/dist/core/ask-unresolvable-notice.d.ts +27 -4
- package/dist/core/ask-unresolvable-notice.js +8 -0
- package/dist/core/auto-promote.d.ts +14 -27
- package/dist/core/auto-promote.js +5 -5
- package/dist/core/checkpoint-store.d.ts +11 -12
- package/dist/core/decision-receipt.d.ts +5 -2
- package/dist/core/decision-receipt.js +1 -1
- package/dist/core/engine-notice.d.ts +7 -1
- package/dist/core/gate-crash-trace.d.ts +1 -1
- package/dist/core/gate-fold.js +7 -3
- package/dist/core/gate-lanes.js +22 -3
- package/dist/core/governance-codes.d.ts +3 -1
- package/dist/core/governance-codes.js +3 -0
- package/dist/core/hooks.d.ts +20 -6
- package/dist/core/hooks.js +28 -28
- package/dist/core/mcp-tool-meta.d.ts +24 -0
- package/dist/core/mcp-tool-meta.js +17 -0
- package/dist/core/mcp.d.ts +1 -6
- package/dist/core/mcp.js +6 -7
- package/dist/core/mode-policy.d.ts +25 -0
- package/dist/core/mode-policy.js +8 -0
- package/dist/core/protocol-table.d.ts +3 -0
- package/dist/core/protocol-table.js +3 -0
- package/dist/core/reminder-mint.d.ts +21 -1
- package/dist/core/reminder-mint.js +20 -0
- package/dist/core/retired-keys.d.ts +2 -1
- package/dist/core/retired-keys.js +13 -2
- package/dist/core/rule-denial-sentence.d.ts +2 -2
- package/dist/core/runner/call-hook-stations.d.ts +106 -0
- package/dist/core/runner/call-hook-stations.js +118 -0
- package/dist/core/runner/contracts.d.ts +35 -25
- package/dist/core/runner/gate-exit.d.ts +5 -1
- package/dist/core/runner/gate-exit.js +10 -6
- package/dist/core/runner/prepare-delegation-surface.d.ts +1 -0
- package/dist/core/runner/prepare-delegation-surface.js +4 -4
- package/dist/core/runner/prepare-gate-stations.d.ts +8 -3
- package/dist/core/runner/prepare-gate-stations.js +13 -70
- package/dist/core/runner/prepare-inherited-gate.d.ts +6 -3
- package/dist/core/runner/prepare-inherited-gate.js +5 -3
- package/dist/core/runner/prepare-park-ask.d.ts +4 -0
- package/dist/core/runner/prepare-park-ask.js +4 -1
- package/dist/core/runner/prepare-policy-chain.d.ts +6 -5
- package/dist/core/runner/prepare-policy-chain.js +14 -25
- package/dist/core/runner/prepare-project-context.d.ts +15 -16
- package/dist/core/runner/prepare-project-context.js +15 -11
- package/dist/core/runner/prepare-run-refs.d.ts +8 -8
- package/dist/core/runner/prepare-run-refs.js +3 -3
- package/dist/core/runner/prepare-safety-scan.js +3 -3
- package/dist/core/runner/prepare-suspend-saga.d.ts +2 -1
- package/dist/core/runner/prepare-suspend-saga.js +2 -1
- package/dist/core/runner/prepare-task.js +14 -12
- package/dist/core/runner/prepare-turn-wiring.d.ts +3 -1
- package/dist/core/runner/prepare-turn-wiring.js +16 -13
- package/dist/core/runner/resume-admission.js +2 -1
- package/dist/core/runner/resume-apply.js +12 -23
- package/dist/core/runner/resume-checkpoint-screen.js +3 -0
- package/dist/core/runner/run-leg.js +61 -47
- package/dist/core/runner/runtask.d.ts +1 -1
- package/dist/core/runner/session-rule-policy.d.ts +7 -19
- package/dist/core/runner/session-rule-policy.js +1 -2
- package/dist/core/runner/skill-base-dir.d.ts +10 -0
- package/dist/core/runner/skill-base-dir.js +4 -0
- package/dist/core/runner/synthetic-tools.d.ts +11 -17
- package/dist/core/runner/synthetic-tools.js +7 -8
- package/dist/core/safety-axis-vocab.d.ts +2 -2
- package/dist/core/safety-axis-vocab.js +2 -0
- package/dist/core/session-policy-store.d.ts +63 -11
- package/dist/core/session-policy-store.js +52 -6
- package/dist/core/skill-grant.d.ts +239 -0
- package/dist/core/skill-grant.js +313 -0
- package/dist/core/skills-directory.d.ts +5 -34
- package/dist/core/skills-directory.js +9 -58
- package/dist/core/task-registry-agent.d.ts +14 -2
- package/dist/core/task-registry-agent.js +23 -8
- package/dist/core/task-registry-shared.d.ts +6 -0
- package/dist/core/task-registry.d.ts +16 -0
- package/dist/core/task-registry.js +19 -6
- package/dist/core/task-spec.d.ts +10 -0
- package/dist/core/tool-face.d.ts +3 -2
- package/dist/core/tool-name-aliases.d.ts +38 -12
- package/dist/core/tool-name-aliases.js +16 -0
- package/dist/core/tool-name-readings.d.ts +6 -2
- package/dist/core/tool-name-readings.js +6 -4
- package/dist/core/tool-policy.d.ts +2 -2
- package/dist/core/tool-registry.d.ts +1 -4
- package/dist/core/tool-registry.js +0 -3
- package/dist/core/tool-spec.d.ts +11 -13
- package/dist/core/tools.d.ts +1 -1
- package/dist/core/trace.d.ts +15 -0
- package/dist/core/types.d.ts +1 -1
- package/dist/engine/harness/agent-harness.d.ts +12 -1
- package/dist/engine/harness/agent-harness.js +17 -13
- package/dist/engine/loop/agent-loop.d.ts +16 -1
- package/dist/engine/loop/agent-loop.js +9 -15
- package/dist/engine/loop/types.d.ts +2 -0
- package/dist/index.d.ts +9 -4
- package/dist/index.js +4 -2
- package/dist/stores/file/adoption/adopt.js +23 -16
- package/dist/stores/file/index.d.ts +8 -2
- package/dist/stores/file/index.js +2 -2
- package/dist/stores/file/mailbox-store.js +2 -2
- package/dist/stores/file/permission-rule-adopt.js +10 -1
- package/dist/stores/file/permission-rule-store.d.ts +6 -4
- package/dist/stores/file/permission-rule-store.js +127 -59
- package/dist/stores/file/session-policy-store.d.ts +86 -14
- package/dist/stores/file/session-policy-store.js +135 -118
- package/dist/stores/file/task-list-store.d.ts +5 -0
- package/dist/stores/file/task-list-store.js +18 -4
- package/dist/stores/file/usage-window-store.d.ts +9 -1
- package/dist/stores/file/usage-window-store.js +47 -33
- package/dist/tools/fs/safety.d.ts +1 -1
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +45 -5
- package/wire-changes/core@7.41.0.json +1865 -0
- package/dist/core/runner/active-skill-scope.d.ts +0 -58
- package/dist/core/runner/active-skill-scope.js +0 -133
- package/dist/core/skill-tool-specifier.d.ts +0 -80
- package/dist/core/skill-tool-specifier.js +0 -57
package/dist/core/tool-spec.d.ts
CHANGED
|
@@ -501,9 +501,9 @@ export interface ToolSpec<TParams extends TSchema = TSchema> {
|
|
|
501
501
|
* gate all read it off the call's face instead of a name table. ABSENT ⇒ the tool is handled as a
|
|
502
502
|
* write whose target cannot be confirmed (fail-closed under every path-confining face) — exactly how
|
|
503
503
|
* a tool outside the retired name tables was handled. `param` outranks `aliases` (NotebookEdit's
|
|
504
|
-
* `notebook_path` beats a decoy `file_path`). `skillScopeEligible` is a SEPARATE grant
|
|
505
|
-
*
|
|
506
|
-
*
|
|
504
|
+
* `notebook_path` beats a decoy `file_path`). `skillScopeEligible` is a SEPARATE grant whose one reader (the
|
|
505
|
+
* skill-scope write fence) is retired (Write/Edit set it; NotebookEdit deliberately does not; a caller
|
|
506
|
+
* tool that merely takes a built-in's NAME inherits nothing).
|
|
507
507
|
*/
|
|
508
508
|
pathTarget?: ToolPathTarget;
|
|
509
509
|
/**
|
|
@@ -1071,16 +1071,14 @@ export interface ToolExecuteContext {
|
|
|
1071
1071
|
*/
|
|
1072
1072
|
getApiKeyAndHeaders?: TaskSpec["getApiKeyAndHeaders"];
|
|
1073
1073
|
/**
|
|
1074
|
-
*
|
|
1075
|
-
*
|
|
1076
|
-
* (`createSubagentTool`) reads it AT SPAWN TIME and
|
|
1077
|
-
*
|
|
1078
|
-
*
|
|
1079
|
-
*
|
|
1080
|
-
* Undefined when the tool runs outside a Runner task. The returned frame objects are intentionally
|
|
1081
|
-
* opaque to callers other than the Runner internals that re-seed them.
|
|
1074
|
+
* A read-only CAPTURE of this (parent) task's skill grant rows for the run — the tools its active skills list in
|
|
1075
|
+
* `allowed-tools` / `disallowed-tools` ({@link import("./skill-grant.js").SkillGrantRecord}: skill, list, entry),
|
|
1076
|
+
* filled by the Runner. A delegation tool (`createSubagentTool`) reads it AT SPAWN TIME and threads it into the child,
|
|
1077
|
+
* which holds the rows until it ends. A copy: the parent's later activations never reach it. An empty array = no active
|
|
1078
|
+
* skill lists (the common case). The model can neither read nor set it (it is not a tool argument). Undefined when the
|
|
1079
|
+
* tool runs outside a Runner task.
|
|
1082
1080
|
*/
|
|
1083
|
-
|
|
1081
|
+
activeSkillGrants?: () => readonly import("./skill-grant.js").SkillGrantRecord[];
|
|
1084
1082
|
/**
|
|
1085
1083
|
* Parent effective-policy inheritance (tighten-only) — the Runner-filled chain accessor a delegation tool
|
|
1086
1084
|
* (`createSubagentTool` / the `run_workflow` spawn legs) calls AT SPAWN TIME and threads verbatim into the
|
|
@@ -1089,7 +1087,7 @@ export interface ToolExecuteContext {
|
|
|
1089
1087
|
* (`spec.toolPolicy ?? deps.toolPolicy` — the exact slot this task's own gate enforces) with the frozen
|
|
1090
1088
|
* task onAsk (opaque half), and its effective shellGate. The child's prepare folds these as
|
|
1091
1089
|
* ADDITIONAL constraint layers — inheritance can only narrow a child, never widen it. Runner-filled,
|
|
1092
|
-
* read-only, NEVER a model/tool argument (same posture as {@link
|
|
1090
|
+
* read-only, NEVER a model/tool argument (same posture as {@link activeSkillGrants}). Undefined when the
|
|
1093
1091
|
* tool runs outside a Runner task.
|
|
1094
1092
|
*/
|
|
1095
1093
|
inheritedGateForChildren?: () => import("./runner/contracts.js").InheritedGate;
|
package/dist/core/tools.d.ts
CHANGED
|
@@ -54,7 +54,7 @@ export declare function rebindDefineToolCtx(product: AgentTool, enrich: ToolCtxE
|
|
|
54
54
|
* tool read them as `undefined` on every call and its ctx-first arms were structurally dead. This
|
|
55
55
|
* closes the gap at MOUNT time instead: the mount — which does hold the Runner's trusted context —
|
|
56
56
|
* supplies a builder, and the adapter runs it PER CALL, so call-time snapshots (the run's current
|
|
57
|
-
* model, the live skill
|
|
57
|
+
* model, the live skill grants) stay current rather than freezing at factory time.
|
|
58
58
|
*
|
|
59
59
|
* Shape is deliberately the SAME `(ctx) => ctx` one the Runner's `spec.tools` wrapper already applies,
|
|
60
60
|
* so a mount passes THAT builder itself instead of re-listing the axes — one source for the trusted
|
package/dist/core/trace.d.ts
CHANGED
|
@@ -441,6 +441,21 @@ export type TraceEvent = {
|
|
|
441
441
|
toolCallId: string;
|
|
442
442
|
command: string;
|
|
443
443
|
ts: number;
|
|
444
|
+
} | {
|
|
445
|
+
/**
|
|
446
|
+
* An active skill's `allowed-tools` row cleared the call, so no person and no classifier was asked: the allow
|
|
447
|
+
* layer's third attribution channel beside `permission.persisted_rule_allowed` and `permission.read_only_allowed`.
|
|
448
|
+
* `skill` names the skill whose list spoke and `entries` the rows the call stands on, as the skill spells them
|
|
449
|
+
* (deployment text; a consumer rendering it applies its own display sanitizer).
|
|
450
|
+
*/
|
|
451
|
+
kind: "permission.skill_allowed";
|
|
452
|
+
version: 1;
|
|
453
|
+
taskId: string;
|
|
454
|
+
toolName: string;
|
|
455
|
+
toolCallId: string;
|
|
456
|
+
skill: string;
|
|
457
|
+
entries: string[];
|
|
458
|
+
ts: number;
|
|
444
459
|
} | {
|
|
445
460
|
/**
|
|
446
461
|
* design/179 — the person's persisted rule store could not be read (at prepare, or for one call), so
|
package/dist/core/types.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export type { StaleToolResultOffloadOptions, ImageInput, TaskSpec, ShellGateDoct
|
|
|
17
17
|
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
|
-
export type { AgentDefinition,
|
|
20
|
+
export type { AgentDefinition, SkillSpec } from "./agent-definition.js";
|
|
21
21
|
export type { McpServerSpec, A2aServerSpec, McpElicitRequest, McpElicitResponse, OnElicit } from "./mcp-server-spec.js";
|
|
22
22
|
export type { TaskLimits } from "./task-limits.js";
|
|
23
23
|
export type { TaskStatus, RemoteEnvFailureNote, EffectiveMemoryScopes, TaskResult, HumanReviewGateRow } from "./task-result.js";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { ActorAssertion, AssistantMessage, ImageContent, Model, UserMessage } from "../llm/index.js";
|
|
2
2
|
import { type ToolTurnRepair } from "../llm/index.js";
|
|
3
|
+
import { type ExecutedToolCallOutcome } from "../loop/agent-loop.js";
|
|
3
4
|
import type { HaltRemainingDirective } from "../loop/types.js";
|
|
4
|
-
import type { AgentMessage, AgentTool, LoopMalformedToolUseRecovery, LoopThinkingOnlyRecovery, LoopTruncatedOutputRecovery, QueueMode, ThinkingLevel } from "../loop/types.js";
|
|
5
|
+
import type { AgentMessage, AgentTool, AgentToolCall, LoopMalformedToolUseRecovery, LoopThinkingOnlyRecovery, LoopTruncatedOutputRecovery, QueueMode, ThinkingLevel } from "../loop/types.js";
|
|
5
6
|
import { type EngineSegment } from "../../core/untrusted-text.js";
|
|
6
7
|
import type { CommittedFrameCarrier } from "../../core/frame-settlement.js";
|
|
7
8
|
import type { AbortResult, AgentHarnessEvent, AgentHarnessEventResultMap, AgentHarnessOptions, AgentHarnessOwnEvent, AgentHarnessResources, AgentHarnessStreamOptions, ExecutionEnv, PromptTemplate, Skill } from "./types.js";
|
|
@@ -522,6 +523,16 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
|
|
|
522
523
|
images?: ImageContent[];
|
|
523
524
|
} & UserMessageProvenance): Promise<void>;
|
|
524
525
|
appendMessage(message: AgentMessage): Promise<void>;
|
|
526
|
+
/** The loop's `afterToolCall`: one `tool_result` hook emit per executed call (every registered handler, one fold). */
|
|
527
|
+
private afterToolCallHook;
|
|
528
|
+
/**
|
|
529
|
+
* Finalize a call this harness's caller executed OUTSIDE a turn (a resumed, already-approved call) exactly as the
|
|
530
|
+
* loop finalizes its own: the same {@link finalizeToolOutcome} over the same `tool_result` emit, so the call meets the
|
|
531
|
+
* same handlers, the same patch application and the same throwing-hook posture as a live one.
|
|
532
|
+
*/
|
|
533
|
+
finalizeToolCall(toolCall: AgentToolCall, args: unknown, executed: ExecutedToolCallOutcome): Promise<ExecutedToolCallOutcome & {
|
|
534
|
+
toolCall: AgentToolCall;
|
|
535
|
+
}>;
|
|
525
536
|
getModel(): Model;
|
|
526
537
|
/** The ref that chose the CURRENT model — {@link getModel}'s companion (a word re-resolves, an object pins). */
|
|
527
538
|
getModelRef(): import("../../core/model-seat.js").ModelRef;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createAssistantMessageEventStream, ensureToolTurnInvariants, snapshotActorAssertion, stripEngineMetadata } from "../llm/index.js";
|
|
2
|
-
import { runAgentLoop } from "../loop/agent-loop.js";
|
|
2
|
+
import { finalizeToolOutcome, runAgentLoop } from "../loop/agent-loop.js";
|
|
3
3
|
import { resolveAgentCoreStreamFn } from "../loop/runtime-deps.js";
|
|
4
4
|
import { normalizeEngineSegments } from "../../core/untrusted-text.js";
|
|
5
5
|
import { AUTH_CARRIER_NAMES } from "../../brain/request-params.js";
|
|
@@ -674,18 +674,7 @@ export class AgentHarness {
|
|
|
674
674
|
});
|
|
675
675
|
return result;
|
|
676
676
|
},
|
|
677
|
-
afterToolCall:
|
|
678
|
-
const patch = await this.emitHook({
|
|
679
|
-
type: "tool_result",
|
|
680
|
-
toolCallId: toolCall.id,
|
|
681
|
-
toolName: toolCall.name,
|
|
682
|
-
input: args,
|
|
683
|
-
content: result.content,
|
|
684
|
-
details: result.details,
|
|
685
|
-
isError,
|
|
686
|
-
});
|
|
687
|
-
return patch;
|
|
688
|
-
},
|
|
677
|
+
afterToolCall: ({ toolCall, args, result, isError }) => this.afterToolCallHook(toolCall, args, result, isError),
|
|
689
678
|
prepareNextTurn: async () => {
|
|
690
679
|
await this.flushPendingSessionWrites();
|
|
691
680
|
await this.emitHook({ type: "turn_boundary", model: this.model });
|
|
@@ -1217,6 +1206,21 @@ export class AgentHarness {
|
|
|
1217
1206
|
throw normalizeHarnessError(error, "session");
|
|
1218
1207
|
}
|
|
1219
1208
|
}
|
|
1209
|
+
async afterToolCallHook(toolCall, args, result, isError) {
|
|
1210
|
+
const patch = await this.emitHook({
|
|
1211
|
+
type: "tool_result",
|
|
1212
|
+
toolCallId: toolCall.id,
|
|
1213
|
+
toolName: toolCall.name,
|
|
1214
|
+
input: args,
|
|
1215
|
+
content: result.content,
|
|
1216
|
+
details: result.details,
|
|
1217
|
+
isError,
|
|
1218
|
+
});
|
|
1219
|
+
return patch;
|
|
1220
|
+
}
|
|
1221
|
+
finalizeToolCall(toolCall, args, executed) {
|
|
1222
|
+
return finalizeToolOutcome(toolCall, executed, (result, isError) => this.afterToolCallHook(toolCall, args, result, isError));
|
|
1223
|
+
}
|
|
1220
1224
|
getModel() {
|
|
1221
1225
|
return this.model;
|
|
1222
1226
|
}
|
|
@@ -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 { AgentContext, AgentEvent, AgentLoopConfig, AgentMessage, HaltRemainingDirective, StreamFn } from "./types.js";
|
|
26
|
+
import type { AfterToolCallResult, AgentContext, AgentEvent, AgentLoopConfig, AgentMessage, 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. */
|
|
@@ -154,6 +154,11 @@ type ExecutedToolCallBatch = {
|
|
|
154
154
|
messages: ToolResultMessage[];
|
|
155
155
|
terminate: boolean;
|
|
156
156
|
};
|
|
157
|
+
/** An executed call's raw outcome, before (and, from {@link finalizeToolOutcome}, after) the post-execution half. */
|
|
158
|
+
export type ExecutedToolCallOutcome = {
|
|
159
|
+
result: AgentToolResult<unknown>;
|
|
160
|
+
isError: boolean;
|
|
161
|
+
};
|
|
157
162
|
/**
|
|
158
163
|
* How many tool names an unknown-tool miss spells out. A miss is a NAME problem: seeing a couple of dozen
|
|
159
164
|
* real names is what lets a model spot the one it meant, while a full listing grows with the deployment
|
|
@@ -174,4 +179,14 @@ export declare const TOOL_VALIDATION_REFUSED_CODE = "tool.validation_refused";
|
|
|
174
179
|
* reported on the fault seat): a validator is a precondition read, not a network call, so a single
|
|
175
180
|
* bound serves every tool; a deployment validator that needs longer is a validator doing too much. */
|
|
176
181
|
export declare const TOOL_INPUT_VALIDATION_TIMEOUT_MS = 10000;
|
|
182
|
+
/**
|
|
183
|
+
* The post-execution half EVERY executed tool call passes through — the loop's own calls here, and a call
|
|
184
|
+
* the harness executed outside a turn (a resumed approved call, `AgentHarness.finalizeToolCall`) through the
|
|
185
|
+
* same function, so the two cannot drift into two dialects of one finalization: the `afterToolCall` patch
|
|
186
|
+
* (content / details / terminate / isError), the D4 posture on a throwing hook, and the delivery mark.
|
|
187
|
+
* `after` absent ⇒ the executed outcome stands as is (same object).
|
|
188
|
+
*/
|
|
189
|
+
export declare function finalizeToolOutcome<C>(toolCall: C, executed: ExecutedToolCallOutcome, after: ((result: AgentToolResult<unknown>, isError: boolean) => Promise<AfterToolCallResult | undefined>) | undefined): Promise<ExecutedToolCallOutcome & {
|
|
190
|
+
toolCall: C;
|
|
191
|
+
}>;
|
|
177
192
|
export {};
|
|
@@ -1489,20 +1489,18 @@ async function executePreparedWithDisclosure(currentContext, assistantMessage, p
|
|
|
1489
1489
|
}
|
|
1490
1490
|
return finalizeExecutedToolCall(currentContext, assistantMessage, prepared, executed, config, signal);
|
|
1491
1491
|
}
|
|
1492
|
-
|
|
1492
|
+
function finalizeExecutedToolCall(currentContext, assistantMessage, prepared, executed, config, signal) {
|
|
1493
|
+
return finalizeToolOutcome(prepared.toolCall, executed, config.afterToolCall === undefined
|
|
1494
|
+
? undefined
|
|
1495
|
+
: (result, isError) => config.afterToolCall({ assistantMessage, toolCall: prepared.toolCall, args: prepared.args, result, isError, context: currentContext }, signal));
|
|
1496
|
+
}
|
|
1497
|
+
export async function finalizeToolOutcome(toolCall, executed, after) {
|
|
1493
1498
|
let result = executed.result;
|
|
1494
1499
|
let isError = executed.isError;
|
|
1495
1500
|
const deliveryMark = readDeliveryFailureMark(executed.result.details);
|
|
1496
|
-
if (
|
|
1501
|
+
if (after) {
|
|
1497
1502
|
try {
|
|
1498
|
-
const afterResult = await
|
|
1499
|
-
assistantMessage,
|
|
1500
|
-
toolCall: prepared.toolCall,
|
|
1501
|
-
args: prepared.args,
|
|
1502
|
-
result,
|
|
1503
|
-
isError,
|
|
1504
|
-
context: currentContext,
|
|
1505
|
-
}, signal);
|
|
1503
|
+
const afterResult = await after(result, isError);
|
|
1506
1504
|
if (afterResult) {
|
|
1507
1505
|
result = {
|
|
1508
1506
|
content: afterResult.content ?? result.content,
|
|
@@ -1522,11 +1520,7 @@ async function finalizeExecutedToolCall(currentContext, assistantMessage, prepar
|
|
|
1522
1520
|
result = { ...result, details };
|
|
1523
1521
|
}
|
|
1524
1522
|
}
|
|
1525
|
-
return {
|
|
1526
|
-
toolCall: prepared.toolCall,
|
|
1527
|
-
result,
|
|
1528
|
-
isError,
|
|
1529
|
-
};
|
|
1523
|
+
return { toolCall, result, isError };
|
|
1530
1524
|
}
|
|
1531
1525
|
function safeAbortDetails(fn) {
|
|
1532
1526
|
try {
|
|
@@ -772,6 +772,8 @@ export interface AgentTool<TParameters extends TSchema = TSchema, TDetails = unk
|
|
|
772
772
|
* repeat-safety effect below its fail-closed `write` default (only the caller's `toolAxes` does). Absent on non-MCP tools.
|
|
773
773
|
*/
|
|
774
774
|
mcpReadOnlyHint?: true;
|
|
775
|
+
/** The server's own `_meta["anthropic/requiresUserInteraction"] === true` declaration: a call to this tool must be put to a person (read per call off the live mount array; MCP tools only). */
|
|
776
|
+
mcpRequiresUserInteraction?: true;
|
|
775
777
|
/**
|
|
776
778
|
* The tool's permission seat — see `ToolSpec.permissionSeat` (src/core/tool-spec.ts). `"passthrough"` = the tool states no
|
|
777
779
|
* permission of its own; set by the MCP and A2A materializers on a remote peer's tool and carried by `defineTool` from a
|
package/dist/index.d.ts
CHANGED
|
@@ -72,7 +72,7 @@ export { WORKFLOW_SIZE_GUIDELINE_AGENT_CAPS } from "./orchestration/workflow-siz
|
|
|
72
72
|
export { ENGINE_AUTHORITY_ENVELOPE_TAGS } from "./core/untrusted-text.js";
|
|
73
73
|
export { materializeA2aTools, A2aRpcError, type MaterializedA2a, type A2aPeerStatus, type A2aRefreshResult, type A2aToolAxis } from "./core/a2a.js";
|
|
74
74
|
export { PROTOCOL_TABLE, MCP_NAMESPACE, A2A_NAMESPACE, protocolOf, type ProtocolNamespace, type ProtocolId } from "./core/protocol-table.js";
|
|
75
|
-
export { InMemorySessionPolicyStore, SessionPolicyError, loosenReasons, normalizeRules, stripRev, type SessionPolicyStore, type SessionPermissionRules, type StoredSessionRules, type SessionRulesRecord, type PutRulesOptions, } from "./core/session-policy-store.js";
|
|
75
|
+
export { InMemorySessionPolicyStore, SessionPolicyError, loosenReasons, normalizeRules, stripRev, assertSessionRuleNamesCurrent, type SessionPolicyStoreOptions, type SessionRuleNameRefusal, type SessionPolicyStore, type SessionPermissionRules, type StoredSessionRules, type SessionRulesRecord, type PutRulesOptions, } from "./core/session-policy-store.js";
|
|
76
76
|
export { SAFETY_MERGE_CONFORMANCE_CORPUS, type SafetyMergeVector } from "./core/safety-merge-corpus.js";
|
|
77
77
|
export { SAFETY_AXIS_VOCABULARY } from "./core/safety-axis-vocab.js";
|
|
78
78
|
export { createSessionRulePolicy } from "./core/runner/session-rule-policy.js";
|
|
@@ -120,7 +120,7 @@ export { InMemoryCheckpointStore, CheckpointError, mintCheckpointId, mintCheckpo
|
|
|
120
120
|
export { EXECUTION_OUTCOME_RECORD_WORDS, EXECUTION_RECORD_LEAVES_ROW_UNRECORDED, type ExecutionOutcomeRecordWord, type ExecutionRecordRowFacts, type ExecutionVerdict, ExecutionOutcomeConflictError, checkpointExecutionRecorded, executionRecordDisposition, sameExecutionRecord, executionVerdict, } from "./core/checkpoint-execution-record.js";
|
|
121
121
|
export { PAUSE_REGISTRY, type GateKind, type PendingKind, type ResumeGate, isGateKind, resumeGateMatches, type CheckpointPause, type CheckpointFields, pauseOf, checkpointFrom } from "./core/pause-registry.js";
|
|
122
122
|
export { InMemoryUsageWindowStore, GLOBAL_USAGE_KEY, EMPTY_USAGE_WINDOW_RECORD, chargeUsageRecord, readUsageRecord, usageRetryAfterMs, resolveUsageWindows, type UsageWindow, type UsageWindowStore, type UsageWindowReading, type UsageWindowRecord, type UsageSlot, type UsageBucketRow, } from "./core/usage-window-store.js";
|
|
123
|
-
export { FileUsageWindowStore } from "./stores/file/usage-window-store.js";
|
|
123
|
+
export { FileUsageWindowStore, type FileUsageWindowStoreOptions } from "./stores/file/usage-window-store.js";
|
|
124
124
|
export { ENV_LIFETIME_SUSPEND_MARGIN_MS, USAGE_WINDOW_REAP_MARGIN_MS } from "./core/runner/prepare-task.js";
|
|
125
125
|
export { InMemoryFileHistoryStore, boundaryPublishVerdict } from "./core/file-history-store.js";
|
|
126
126
|
export { captureFileBackupViaEnv, applyFileRestoreViaEnv } from "./core/file-history-store.js";
|
|
@@ -141,12 +141,13 @@ export { brainToRuntime } from "./core/runtime.js";
|
|
|
141
141
|
export { createSensitivePathPolicy, RECOMMENDED_SENSITIVE_PATTERNS } from "./core/sensitive-path-policy.js";
|
|
142
142
|
export { createFsWriteGatePolicy, WRITE_EXEMPT_DIR_COVERS_ROOT_CODE, type FsWriteGatePolicyOptions } from "./core/fs-write-gate-policy.js";
|
|
143
143
|
export { RETIRED_TOOL_NAMES } from "./core/tool-name-aliases.js";
|
|
144
|
+
export { judgeRuleToolName, RULE_TOOL_NAME_VERDICTS, type RuleToolNameVerdict } from "./core/tool-name-aliases.js";
|
|
144
145
|
export { DEFAULT_SUBAGENT_TOOL_NAME } from "./agents/subagent.js";
|
|
145
146
|
export { renderTaskNotificationXml, RESUPPLIED_FRAME_PREAMBLE, taskNotificationDedupKey, isDelegatedAgentTerminal, isTerminalTaskNotification, SystemInjectionQueue, type TaskNotificationPayload, type TaskNotificationStatus, type ExternalNotificationInput, type SystemInjection, type SystemInjectionPriority, type NotificationInjectionOutcome, // the injector's outcome words (`parked_durably` = the session's durable box took the frame)
|
|
146
147
|
NOTIFICATION_INJECTION_OUTCOMES, // …and their value half + guard, so a host wiring its own uplink validates a reported outcome without duplicating the vocabulary
|
|
147
148
|
isNotificationInjectionOutcome, SYSTEM_INJECTION_PRIORITIES, isSystemInjectionPriority, AGENT_MESSAGE_TAG, renderAgentMessageFrame, type SemaProvenance, HANDBACK_STATES, type HandbackState, COMPACTION_KINDS, type CompactionKind, handbackStateOf, terminalFrameFacets, } from "./core/task-notification.js";
|
|
148
149
|
export { TOOL_FAMILIES, TOOL_MOUNT_TAGS, TOOL_APPROVAL_CARDS, TOOL_PATH_ACCESSES, TOOL_PATH_BASES, TOOL_PATH_ABSENCES, TOOL_WIRE_NAME_MAX_CHARS, TOOL_CONTRACT_MAX_CHARS, TOOL_CARD_ID_MAX_CHARS, TOOL_KEY_MAX_CHARS, TOOL_KEYS_MAX, RENDER_HINT_MAX_CHARS, RENDER_HINT_ACTIVITY_MAX_CHARS, RENDER_HINT_MAX_LIST, type ToolFamily, type ToolMountTag, type ToolApprovalCard, type ToolPathAccess, type ToolPathBase, type ToolPathAbsence, type ToolPathTarget, type ToolCallPathTarget, type ToolRosterPathTarget, pathTargetSlotOnly, type ToolRuleFace, type ToolRenderHints, type ToolFaceDeclaration, type ToolCatalogEntry, } from "./core/tool-face.js";
|
|
149
|
-
export { describeToolCatalog, catalogEntriesNamed, catalogToolNames, catalogRuleFaceOf, pathTargetOf, pathTargetValue, protectivePathTargetOf, declaredPathTargetOf, BARE_REQUEST_CODE, isProtectedWrite, isDeclaredWrite, fileOpAccessOf, type ToolCallLike, pathConfinableWriteToolNames,
|
|
150
|
+
export { describeToolCatalog, catalogEntriesNamed, catalogToolNames, catalogRuleFaceOf, pathTargetOf, pathTargetValue, protectivePathTargetOf, declaredPathTargetOf, BARE_REQUEST_CODE, isProtectedWrite, isDeclaredWrite, fileOpAccessOf, type ToolCallLike, pathConfinableWriteToolNames, pathTargetingToolNames, compactableToolNames, budgetExemptToolNames, handBandEffects, engineCardTypes, predictMountedToolNames, HANDS_BAND_TAGS, MOUNT_TAG_IN_HANDS_BAND, } from "./core/tool-registry.js";
|
|
150
151
|
export { ToolRosterEntry, ToolRoster, ToolRosterDelta, ToolRosterRenderHints, ROSTER_SOURCES, type RosterSource, type ToolIdentity, toolIdentityOf, mintCapabilityId, diffToolRoster, judgeParkedToolIdentity, ruleFacesFromRoster, toolCallFaceOf, rosterToolName, ruleNamesOf, inputKeysOf, ruleFaceOfInstance, rosterMemberBoundProblem, type RosterBoundMembers, type RosterBoundCode, ToolRosterDeltaSeat, } from "./core/tool-roster.js";
|
|
151
152
|
export { type ToolCallFace } from "./core/tool-policy.js";
|
|
152
153
|
export { effectivePathTargetOf, pathTargetBaseOf, type ToolPathBases, type PathTargetReading } from "./core/effective-path-target.js";
|
|
@@ -196,6 +197,8 @@ export { type ReadRootGrantScreen } from "./core/read-root-grant-screen.js";
|
|
|
196
197
|
export { type AskOrigin, ASK_ORIGINS, isAskOrigin, ORIGIN_IMPLIES_REAL_APPROVAL, PERSISTED_RULE_MANDATES, type PersistedRuleMandate, isPersistedRuleMandate, screenAskClassMembers } from "./core/ask-origin.js";
|
|
197
198
|
export { PERMISSION_MODES, type PermissionMode, isPermissionMode, PERMISSION_MODE_RANK, clampPermissionMode, ASK_CLASSES, type AskClass, isAskClass, MODE_ARBITRATION, type ModeArbitrationRow, RELEASABLE_ASK_CLASSES, MODE_RELEASE_REASONS, type ModeReleaseReason, isModeReleaseReason, RRA_EXPLAINERS, classifyAsk, foldArbitrationRow, type AskClassification, type AskClassFacts, type ToolMarkSource, arbitrateByMode, type Arbitration, fileCommandOptionsSentence } from "./core/ask-origin.js";
|
|
198
199
|
export { modePolicyOf, type ModePolicy, PERMISSION_MODE_FOLD_REASONS, type PermissionModeFoldReason, type PermissionModeReceipt, ACCEPT_EDITS_FILE_COMMANDS, modeAcceptsFileCommand } from "./core/mode-policy.js";
|
|
200
|
+
export type { PermissionSeatInputs, PermissionSeatReading } from "./core/mode-policy.js";
|
|
201
|
+
export type { SkillGateSeats, SkillGrantHit, SkillGrantLane, SkillGrantRecord } from "./core/skill-grant.js";
|
|
199
202
|
export { readDenyClassifierRules, renderClassifierDenyRules, type DerivedDenyRule } from "./core/auto-mode-prompt.js";
|
|
200
203
|
export { AUTO_MODE_DENY_SOURCES, isAutoModeDenySource, type AutoModeDenySource } from "./core/runtime-caps.js";
|
|
201
204
|
export { SETTLEMENT_KINDS, type SettlementKind, isSettlementKind, type Settlement, SETTLEMENT_PARTIES, type SettlementParty, isSettlementParty, SETTLEMENT_IS_REFUSAL, DENIED_BY_VALUES, type DeniedBy, isDeniedBy, DENIED_BY_MAY_VETO, CLASSIFIER_DENY_CAUSES, type ClassifierDenyCause, isClassifierDenyCause, DENIED_BY_MAY_CARRY_CAUSE, type GateDisposition, type GateOutcome, type ModeRelease, type ModeRefusal, screenGateOutcome } from "./core/gate-outcome.js";
|
|
@@ -308,6 +311,8 @@ export { BACKGROUND_AGENT_CONTRACT_SCOPE, backgroundAgentStoreContract, backgrou
|
|
|
308
311
|
export { PEER_DIRECTORY_CONTRACT_SCOPE, peerDirectoryContract, type PeerDirectoryContractHooks } from "./core/store-contracts/peer-directory-contract.js";
|
|
309
312
|
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";
|
|
310
313
|
export { serveDurableAgentRowLane, buildAgentPollDetails, type AgentPollDetailsInput, } from "./core/task-registry-agent.js";
|
|
314
|
+
export { readAgentState, agentStateSourceOfRecord, agentStateSummary, type AgentState, type AgentApproval, type AgentApprovalState, type AgentStateRow, type AgentStateSource, } from "./core/agent-state.js";
|
|
315
|
+
export type { TranscriptStep } from "./agents/subagent-steps.js";
|
|
311
316
|
export type { UnifiedTaskResult } from "./core/task-registry-shared.js";
|
|
312
317
|
export { TASK_OUTPUT_REPLAY_KINDS, type TaskOutputReplay } from "./core/task-registry-shared.js";
|
|
313
318
|
export { REMOVAL_LIVENESS_WORDS, type RemovalLiveness, RULE_WRITE_COMMITTED_WORDS, type RuleWriteCommitted } from "./core/permission-rule-store.js";
|
|
@@ -365,7 +370,7 @@ export { ROUTE_ADJUDICATION_CONFORMANCE_CORPUS, type RouteAdjudicationVector } f
|
|
|
365
370
|
export { type BrainTimeoutConfig } from "./brain/timeout.js";
|
|
366
371
|
export { createAssistantMessageEventStream } from "./internal/llm.js";
|
|
367
372
|
export type { AssistantMessage, AssistantMessageEvent, CompleteSimpleFn, Context, DocumentContent, ImageContent, Message, StopReason, StreamFn, TextContent, ThinkingContent, ToolCall, ToolResultMessage, Usage, UserMessage, } from "./internal/llm.js";
|
|
368
|
-
export type { AgentDefinition, BeforeWriteHook, BeforeWriteRequest, BeforeWriteResult, TrackFileEditHook, TrackEditRequest, TrackEditResult, FileEditedHook, FileEditedNotice, HandsBandOptions, Brain, BrainStatus, BrainStatusPhase, BrainRetryErrClass, ImageInput, McpElicitRequest, McpElicitResponse, McpServerSpec, A2aServerSpec, OnElicit, Model, ModelRef, ProjectMemoryLoad, RunnerDeps, ResumePreflightInfo, ResumePreflightVerdict, EngineNotice, RuntimeCaps, BackgroundChildEvent, DelegationLifecycleEvent,
|
|
373
|
+
export type { AgentDefinition, BeforeWriteHook, BeforeWriteRequest, BeforeWriteResult, TrackFileEditHook, TrackEditRequest, TrackEditResult, FileEditedHook, FileEditedNotice, HandsBandOptions, Brain, BrainStatus, BrainStatusPhase, BrainRetryErrClass, ImageInput, McpElicitRequest, McpElicitResponse, McpServerSpec, A2aServerSpec, OnElicit, Model, ModelRef, ProjectMemoryLoad, RunnerDeps, ResumePreflightInfo, ResumePreflightVerdict, EngineNotice, RuntimeCaps, BackgroundChildEvent, DelegationLifecycleEvent, SkillSpec, TaskEvent, TaskEventIdentity, ToolActivity, TaskLimits, StaleToolResultOffloadOptions, TaskResult, TerminalCause, PausedCause, EffectiveMemoryScopes, RemoteEnvFailureNote, TaskSpec, ShellGateDoctrine, TaskStatus, TaskStream, CompactOutcome, ThinkingLevel, ToolExecuteContext, ToolReturn, ToolSpec, ToolInputVerdict, ToolInputValidationContext, ReversibilityVerdict, ReadRootGrantCandidate, ToolEffect, ToolContentOrigin, WorkflowGovernanceBaseline, DelegationTaskType, } from "./core/types.js";
|
|
369
374
|
export { Type } from "typebox";
|
|
370
375
|
export type { TSchema, Static } from "typebox";
|
|
371
376
|
export { explainPromptAssembly, describeDefaultPack, type DefaultPackDescription, type ExplainInput } from "./prompt-assembly/explain.js";
|
package/dist/index.js
CHANGED
|
@@ -58,7 +58,7 @@ export { WORKFLOW_SIZE_GUIDELINE_AGENT_CAPS } from "./orchestration/workflow-siz
|
|
|
58
58
|
export { ENGINE_AUTHORITY_ENVELOPE_TAGS } from "./core/untrusted-text.js";
|
|
59
59
|
export { materializeA2aTools, A2aRpcError } from "./core/a2a.js";
|
|
60
60
|
export { PROTOCOL_TABLE, MCP_NAMESPACE, A2A_NAMESPACE, protocolOf } from "./core/protocol-table.js";
|
|
61
|
-
export { InMemorySessionPolicyStore, SessionPolicyError, loosenReasons, normalizeRules, stripRev, } from "./core/session-policy-store.js";
|
|
61
|
+
export { InMemorySessionPolicyStore, SessionPolicyError, loosenReasons, normalizeRules, stripRev, assertSessionRuleNamesCurrent, } from "./core/session-policy-store.js";
|
|
62
62
|
export { SAFETY_MERGE_CONFORMANCE_CORPUS } from "./core/safety-merge-corpus.js";
|
|
63
63
|
export { SAFETY_AXIS_VOCABULARY } from "./core/safety-axis-vocab.js";
|
|
64
64
|
export { createSessionRulePolicy } from "./core/runner/session-rule-policy.js";
|
|
@@ -115,10 +115,11 @@ export { brainToRuntime } from "./core/runtime.js";
|
|
|
115
115
|
export { createSensitivePathPolicy, RECOMMENDED_SENSITIVE_PATTERNS } from "./core/sensitive-path-policy.js";
|
|
116
116
|
export { createFsWriteGatePolicy, WRITE_EXEMPT_DIR_COVERS_ROOT_CODE } from "./core/fs-write-gate-policy.js";
|
|
117
117
|
export { RETIRED_TOOL_NAMES } from "./core/tool-name-aliases.js";
|
|
118
|
+
export { judgeRuleToolName, RULE_TOOL_NAME_VERDICTS } from "./core/tool-name-aliases.js";
|
|
118
119
|
export { DEFAULT_SUBAGENT_TOOL_NAME } from "./agents/subagent.js";
|
|
119
120
|
export { renderTaskNotificationXml, RESUPPLIED_FRAME_PREAMBLE, taskNotificationDedupKey, isDelegatedAgentTerminal, isTerminalTaskNotification, SystemInjectionQueue, NOTIFICATION_INJECTION_OUTCOMES, isNotificationInjectionOutcome, SYSTEM_INJECTION_PRIORITIES, isSystemInjectionPriority, AGENT_MESSAGE_TAG, renderAgentMessageFrame, HANDBACK_STATES, COMPACTION_KINDS, handbackStateOf, terminalFrameFacets, } from "./core/task-notification.js";
|
|
120
121
|
export { TOOL_FAMILIES, TOOL_MOUNT_TAGS, TOOL_APPROVAL_CARDS, TOOL_PATH_ACCESSES, TOOL_PATH_BASES, TOOL_PATH_ABSENCES, TOOL_WIRE_NAME_MAX_CHARS, TOOL_CONTRACT_MAX_CHARS, TOOL_CARD_ID_MAX_CHARS, TOOL_KEY_MAX_CHARS, TOOL_KEYS_MAX, RENDER_HINT_MAX_CHARS, RENDER_HINT_ACTIVITY_MAX_CHARS, RENDER_HINT_MAX_LIST, pathTargetSlotOnly, } from "./core/tool-face.js";
|
|
121
|
-
export { describeToolCatalog, catalogEntriesNamed, catalogToolNames, catalogRuleFaceOf, pathTargetOf, pathTargetValue, protectivePathTargetOf, declaredPathTargetOf, BARE_REQUEST_CODE, isProtectedWrite, isDeclaredWrite, fileOpAccessOf, pathConfinableWriteToolNames,
|
|
122
|
+
export { describeToolCatalog, catalogEntriesNamed, catalogToolNames, catalogRuleFaceOf, pathTargetOf, pathTargetValue, protectivePathTargetOf, declaredPathTargetOf, BARE_REQUEST_CODE, isProtectedWrite, isDeclaredWrite, fileOpAccessOf, pathConfinableWriteToolNames, pathTargetingToolNames, compactableToolNames, budgetExemptToolNames, handBandEffects, engineCardTypes, predictMountedToolNames, HANDS_BAND_TAGS, MOUNT_TAG_IN_HANDS_BAND, } from "./core/tool-registry.js";
|
|
122
123
|
export { ToolRosterEntry, ToolRoster, ToolRosterDelta, ToolRosterRenderHints, ROSTER_SOURCES, toolIdentityOf, mintCapabilityId, diffToolRoster, judgeParkedToolIdentity, ruleFacesFromRoster, toolCallFaceOf, rosterToolName, ruleNamesOf, inputKeysOf, ruleFaceOfInstance, rosterMemberBoundProblem, ToolRosterDeltaSeat, } from "./core/tool-roster.js";
|
|
123
124
|
export {} from "./core/tool-policy.js";
|
|
124
125
|
export { effectivePathTargetOf, pathTargetBaseOf } from "./core/effective-path-target.js";
|
|
@@ -255,6 +256,7 @@ export { BACKGROUND_AGENT_CONTRACT_SCOPE, backgroundAgentStoreContract, backgrou
|
|
|
255
256
|
export { PEER_DIRECTORY_CONTRACT_SCOPE, peerDirectoryContract } from "./core/store-contracts/peer-directory-contract.js";
|
|
256
257
|
export { canAccessAgentRecord, STALE_RUNNING_REAP_ATTRIBUTION, BackgroundAgentStoreError, InMemoryBackgroundAgentStore, reconcileParkedAgents, queryBackgroundAgents, } from "./core/background-agent-store.js";
|
|
257
258
|
export { serveDurableAgentRowLane, buildAgentPollDetails, } from "./core/task-registry-agent.js";
|
|
259
|
+
export { readAgentState, agentStateSourceOfRecord, agentStateSummary, } from "./core/agent-state.js";
|
|
258
260
|
export { TASK_OUTPUT_REPLAY_KINDS } from "./core/task-registry-shared.js";
|
|
259
261
|
export { REMOVAL_LIVENESS_WORDS, RULE_WRITE_COMMITTED_WORDS } from "./core/permission-rule-store.js";
|
|
260
262
|
export { normalizeReadRootCandidate, READ_ROOT_CANDIDATE_DIR_MAX } from "./core/read-root-candidate.js";
|
|
@@ -3,7 +3,8 @@ import { existsSync, readdirSync, readFileSync, unlinkSync } from "node:fs";
|
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
4
|
import { adoptFilePermissionRuleStore } from "../permission-rule-adopt.js";
|
|
5
5
|
import { BootLock, atomicWriteFile, ensureDir, sanitizeScope } from "../fs-atomic.js";
|
|
6
|
-
import { SESSION_POLICY_MARK_SUFFIX, judgeSessionPolicyRowObject, readSessionPolicyMark } from "../session-policy-store.js";
|
|
6
|
+
import { SESSION_POLICY_MARK_SUFFIX, attributeSessionPolicyRow, judgeSessionPolicyRowObject, readSessionPolicyMark } from "../session-policy-store.js";
|
|
7
|
+
import { SessionPolicyError } from "../../../core/session-policy-store.js";
|
|
7
8
|
import { thrownText } from "../../../core/thrown-value.js";
|
|
8
9
|
import { AdoptionError, NOT_MIGRATED_BY_DESIGN, readRootAdoptionFile, writeRootAdoptionFile, } from "./marker.js";
|
|
9
10
|
const CONFIG_ACCOUNT_FILE = "adoption-configs.json";
|
|
@@ -193,12 +194,8 @@ function rewriteSessionPolicyRows(root, fromPrincipal, toPrincipal) {
|
|
|
193
194
|
const tmpDir = join(dir, "tmp");
|
|
194
195
|
let rows = 0;
|
|
195
196
|
for (const file of files) {
|
|
196
|
-
if (!file.endsWith(".json"))
|
|
197
|
+
if (!file.endsWith(".json") || file.endsWith(SESSION_POLICY_MARK_SUFFIX))
|
|
197
198
|
continue;
|
|
198
|
-
if (file.endsWith(SESSION_POLICY_MARK_SUFFIX)) {
|
|
199
|
-
carrySessionPolicyMark(dir, tmpDir, file, fromPrincipal, toPrincipal);
|
|
200
|
-
continue;
|
|
201
|
-
}
|
|
202
199
|
const source = join(dir, file);
|
|
203
200
|
let raw;
|
|
204
201
|
try {
|
|
@@ -210,15 +207,14 @@ function rewriteSessionPolicyRows(root, fromPrincipal, toPrincipal) {
|
|
|
210
207
|
throw err;
|
|
211
208
|
}
|
|
212
209
|
const judged = judgeSessionPolicyRowObject(raw);
|
|
213
|
-
|
|
210
|
+
const row = "row" in judged ? judged.row : undefined;
|
|
211
|
+
const { owner } = attributeSessionPolicyRow(dir, file, row);
|
|
212
|
+
if (owner === undefined)
|
|
214
213
|
continue;
|
|
215
|
-
|
|
216
|
-
if (row.__principal !== fromPrincipal)
|
|
214
|
+
if (owner.principal !== fromPrincipal)
|
|
217
215
|
continue;
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
const stem = sanitizeScope(JSON.stringify([row.__sid, toPrincipal]));
|
|
221
|
-
const rewritten = JSON.stringify({ ...row, __principal: toPrincipal });
|
|
216
|
+
const stem = sanitizeScope(JSON.stringify([owner.sessionId, toPrincipal]));
|
|
217
|
+
const rewritten = row !== undefined ? JSON.stringify({ ...row, __principal: toPrincipal }) : raw;
|
|
222
218
|
const target = join(dir, `${stem}.json`);
|
|
223
219
|
if (existsSync(target)) {
|
|
224
220
|
if (readFileSync(target, "utf8") === rewritten) {
|
|
@@ -226,18 +222,22 @@ function rewriteSessionPolicyRows(root, fromPrincipal, toPrincipal) {
|
|
|
226
222
|
rows += 1;
|
|
227
223
|
continue;
|
|
228
224
|
}
|
|
229
|
-
throw new AdoptionError("adoption_row_collision", `a session-policy row for session "${
|
|
225
|
+
throw new AdoptionError("adoption_row_collision", `a session-policy row for session "${owner.sessionId}" already exists under "${toPrincipal}" with different content — ` +
|
|
230
226
|
`merging two existing rows is a sync join, not a rewrite; the adoption marker is left in place for inspection`);
|
|
231
227
|
}
|
|
232
228
|
atomicWriteFile(tmpDir, target, rewritten);
|
|
233
229
|
removeIfPresent(source);
|
|
234
230
|
rows += 1;
|
|
235
231
|
}
|
|
232
|
+
for (const file of files) {
|
|
233
|
+
if (file.endsWith(SESSION_POLICY_MARK_SUFFIX))
|
|
234
|
+
carrySessionPolicyMark(dir, tmpDir, file, fromPrincipal, toPrincipal);
|
|
235
|
+
}
|
|
236
236
|
return rows;
|
|
237
237
|
}
|
|
238
238
|
function carrySessionPolicyMark(dir, tmpDir, file, fromPrincipal, toPrincipal) {
|
|
239
239
|
const source = join(dir, file);
|
|
240
|
-
const mark =
|
|
240
|
+
const mark = readMarkOrRefuse(source);
|
|
241
241
|
if (mark === null)
|
|
242
242
|
return;
|
|
243
243
|
if (mark.__principal !== fromPrincipal)
|
|
@@ -245,12 +245,19 @@ function carrySessionPolicyMark(dir, tmpDir, file, fromPrincipal, toPrincipal) {
|
|
|
245
245
|
if (typeof mark.__sid !== "string")
|
|
246
246
|
return;
|
|
247
247
|
const target = join(dir, `${sanitizeScope(JSON.stringify([mark.__sid, toPrincipal]))}${SESSION_POLICY_MARK_SUFFIX}`);
|
|
248
|
-
const there =
|
|
248
|
+
const there = readMarkOrRefuse(target);
|
|
249
249
|
const merged = there === null ? mark.__hwm : Math.max(mark.__hwm, there.__hwm);
|
|
250
250
|
const mergedGen = Math.max(mark.__gen ?? 0, there?.__gen ?? 0);
|
|
251
251
|
atomicWriteFile(tmpDir, target, JSON.stringify({ ...mark, __principal: toPrincipal, __hwm: merged, __gen: mergedGen }));
|
|
252
252
|
removeIfPresent(source);
|
|
253
253
|
}
|
|
254
|
+
function readMarkOrRefuse(path) {
|
|
255
|
+
const read = readSessionPolicyMark(path);
|
|
256
|
+
if ("corrupt" in read) {
|
|
257
|
+
throw new SessionPolicyError("corrupt", `session rules high-water mark ${read.corrupt.reason}: ${path} — refusing rather than restart this key's rev from zero. Deleting that file is the repair, and it gives up the number it was holding.`);
|
|
258
|
+
}
|
|
259
|
+
return read.mark;
|
|
260
|
+
}
|
|
254
261
|
function removeIfPresent(path) {
|
|
255
262
|
try {
|
|
256
263
|
unlinkSync(path);
|
|
@@ -4,6 +4,7 @@ import type { ToolResultStore } from "../../core/tool-result-store.js";
|
|
|
4
4
|
import { type EvictPolicy } from "../../core/session-store.js";
|
|
5
5
|
import type { SessionStore } from "../../core/session.js";
|
|
6
6
|
import { type FileCheckpointStoreOptions } from "./checkpoint-store.js";
|
|
7
|
+
import { type FileSessionPolicyStoreOptions } from "./session-policy-store.js";
|
|
7
8
|
import { type FileFileHistoryStoreOptions } from "./file-history-store.js";
|
|
8
9
|
import type { CorruptReadInfo } from "./corrupt-read-sink.js";
|
|
9
10
|
import type { FileHistoryStore } from "../../core/file-history-store.js";
|
|
@@ -21,7 +22,7 @@ export { FileToolResultStore } from "./tool-result-store.js";
|
|
|
21
22
|
export { FileSessionPolicyStore, type FileSessionPolicyStoreOptions, type SessionPolicyCorruptReadInfo } from "./session-policy-store.js";
|
|
22
23
|
export { FileFileHistoryStore, type FileFileHistoryStoreOptions } from "./file-history-store.js";
|
|
23
24
|
export { FileWorkflowJournalStore, MAX_JOURNAL_RESULT_BYTES, oversizeJournalResult } from "./workflow-journal-store.js";
|
|
24
|
-
export { FileUsageWindowStore } from "./usage-window-store.js";
|
|
25
|
+
export { FileUsageWindowStore, type FileUsageWindowStoreOptions } from "./usage-window-store.js";
|
|
25
26
|
export { FileStrategyStore, type FileStrategyStoreOptions } from "./strategy-store.js";
|
|
26
27
|
export { resolveDataRoot, sanitizeScope, sanitizePathComponent, createFileConsolidationLock } from "./fs-atomic.js";
|
|
27
28
|
export { FileStoreLockError, type FileStoreLockErrorCode } from "./fs-atomic.js";
|
|
@@ -74,6 +75,10 @@ export interface FileStorageBackendOptions {
|
|
|
74
75
|
* FileStorageBackendOptions.onCorruptRead} above, because one failure grammar takes one sink.
|
|
75
76
|
*/
|
|
76
77
|
fileHistory?: Omit<FileFileHistoryStoreOptions, "onCorruptRead">;
|
|
78
|
+
/** The session-rules store's options — today the names this deployment mounts its own tools under
|
|
79
|
+
* (`mountedToolNames`, the roster its write and loosening checks judge rule names against). The corrupt-read sink is
|
|
80
|
+
* wired from {@link FileStorageBackendOptions.onCorruptRead}, as for {@link fileHistory}. */
|
|
81
|
+
sessionPolicy?: Omit<FileSessionPolicyStoreOptions, "onCorruptRead">;
|
|
77
82
|
/** design/81 Slice 5 — an optional {@link import("../../core/memory.js").Embedder}. Injected ⇒ the memory
|
|
78
83
|
* store does portable (in-process) vector recall over a rebuildable sidecar index (`vectorMode:"portable"`);
|
|
79
84
|
* absent ⇒ the lexical floor, byte-identical to before. Config-driven (the deployment injects it); OFF by
|
|
@@ -93,7 +98,8 @@ export interface FileStorageBackendOptions {
|
|
|
93
98
|
* Reach TODAY: {@link FileStorageBackend.sessionPolicyStore} (an absent file ⇒ no rules; a present but
|
|
94
99
|
* unreadable / unparseable / malformed file ⇒ refused, the disclosure delivered alongside the refusal)
|
|
95
100
|
* and {@link FileStorageBackend.sessionStore}'s repo (a session listing that silently omits what it
|
|
96
|
-
* could not read). The aggregated roster and
|
|
101
|
+
* could not read). The aggregated roster, mailbox and usage-window stores receive the same sink (the
|
|
102
|
+
* usage-window ledger refuses a damaged record and discloses its location here). A store that
|
|
97
103
|
* grows the seat later is wired here in the same constructor.
|
|
98
104
|
*
|
|
99
105
|
* The payload is the UNION shape ({@link FileStorageCorruptReadInfo}): `path` + `reason` always,
|
|
@@ -72,11 +72,11 @@ export class FileStorageBackend {
|
|
|
72
72
|
built.push(() => this.fileMemory.close());
|
|
73
73
|
this.memoryStore = guardedMemoryStore(this.fileMemory, opts.utilityGate);
|
|
74
74
|
this.toolResultStore = new FileToolResultStore(this.root, corruptRead);
|
|
75
|
-
this.sessionPolicyStore = new FileSessionPolicyStore(this.root, corruptRead);
|
|
75
|
+
this.sessionPolicyStore = new FileSessionPolicyStore(this.root, { ...opts.sessionPolicy, ...corruptRead });
|
|
76
76
|
this.fileWorkflowJournal = new FileWorkflowJournalStore(this.root, true, corruptRead);
|
|
77
77
|
built.push(() => this.fileWorkflowJournal.dispose());
|
|
78
78
|
this.workflowJournalStore = this.fileWorkflowJournal;
|
|
79
|
-
this.usageWindowStore = new FileUsageWindowStore(this.root);
|
|
79
|
+
this.usageWindowStore = new FileUsageWindowStore(this.root, corruptRead);
|
|
80
80
|
this.fileAgentRows = new FileBackgroundAgentStore(this.root, corruptRead ?? {});
|
|
81
81
|
built.push(() => this.fileAgentRows.close());
|
|
82
82
|
this.backgroundAgentStore = this.fileAgentRows;
|
|
@@ -145,7 +145,7 @@ export async function acquireMailboxBoxLock(lockPath, waitMs) {
|
|
|
145
145
|
return;
|
|
146
146
|
}
|
|
147
147
|
if (now === undefined || now === "unreadable" || now.nonce !== mine.nonce) {
|
|
148
|
-
const e = new Error(`FileMailboxStore: the box lock
|
|
148
|
+
const e = new Error(`FileMailboxStore: the box lock changed hands while this process held it (a stale reclaim overlapped) — the operation just performed may have raced another process; do not trust it. The lock file's location is on this error's \`lockPath\`, not in this message.`);
|
|
149
149
|
e.code = MAILBOX_BOX_LOCK_COMPROMISED_CODE;
|
|
150
150
|
e.lockPath = lockPath;
|
|
151
151
|
throw e;
|
|
@@ -195,7 +195,7 @@ export async function acquireMailboxBoxLock(lockPath, waitMs) {
|
|
|
195
195
|
sweepLockResidue(join(lockPath, ".."), lockPath.slice(join(lockPath, "..").length + 1));
|
|
196
196
|
}
|
|
197
197
|
if (Date.now() >= deadline) {
|
|
198
|
-
const e = new Error(`FileMailboxStore: the box lock
|
|
198
|
+
const e = new Error(`FileMailboxStore: the box lock was not obtainable within ${waitMs}ms (${holderNote}) — refusing to touch the box without it. The lock file's location is on this error's \`lockPath\`, not in this message.`);
|
|
199
199
|
e.code = MAILBOX_BOX_LOCK_TIMEOUT_CODE;
|
|
200
200
|
e.lockPath = lockPath;
|
|
201
201
|
if (owner !== "unreadable" && owner !== "unobservable")
|
|
@@ -4,6 +4,7 @@ import { writerOf } from "../../core/permission-rule-store.js";
|
|
|
4
4
|
import { createPermissionRuleStoreProvider } from "../../core/permission-rule-provider.js";
|
|
5
5
|
import { syncPermissionRules } from "../../core/permission-rule-sync.js";
|
|
6
6
|
import { thrownText } from "../../core/thrown-value.js";
|
|
7
|
+
import { FileStoreLockError } from "./fs-atomic.js";
|
|
7
8
|
import { FileDurableRulePartitionProvider, LOCAL_OWNER_FILE, principalRuleFileName, readRuleAdoptionFile, writeRuleAdoptionFile, } from "./permission-rule-store.js";
|
|
8
9
|
export async function adoptFilePermissionRuleStore(opts) {
|
|
9
10
|
if (typeof opts.toPrincipal !== "string" || opts.toPrincipal === "") {
|
|
@@ -30,7 +31,15 @@ export async function adoptFilePermissionRuleStore(opts) {
|
|
|
30
31
|
}
|
|
31
32
|
const provider = new FileDurableRulePartitionProvider(opts.dir, opts.onError);
|
|
32
33
|
try {
|
|
33
|
-
|
|
34
|
+
let lockProbe;
|
|
35
|
+
try {
|
|
36
|
+
lockProbe = writerOf(provider.forPrincipal(opts.toPrincipal));
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
if (!(err instanceof FileStoreLockError))
|
|
40
|
+
throw err;
|
|
41
|
+
throw new FileStoreLockError(err.code, `the permission-rule writer lock ${err.lockPath} refuses the adoption (${err.code}${err.ownerPid !== undefined ? `, held by pid ${err.ownerPid}` : ""}) — stop the live writer, then run the adoption again`, err.lockPath, err.ownerPid);
|
|
42
|
+
}
|
|
34
43
|
if (lockProbe === undefined)
|
|
35
44
|
throw new Error("the target store refused a write face");
|
|
36
45
|
let phase = existing !== undefined && "marker" in existing ? existing.marker.phase : 2;
|
|
@@ -108,9 +108,8 @@ export type RuleAdoptionFile = {
|
|
|
108
108
|
atMs: number;
|
|
109
109
|
};
|
|
110
110
|
};
|
|
111
|
-
/**
|
|
112
|
-
*
|
|
113
|
-
* bucket (write fork) or invent an adoption that never happened. */
|
|
111
|
+
/** The ADOPTION voice of {@link judgeRuleAdoptionFile}: the adoption helper's reader is the operator who repairs the
|
|
112
|
+
* marker, so it names the directory. A corrupt marker THROWS. */
|
|
114
113
|
export declare function readRuleAdoptionFile(dir: string): RuleAdoptionFile | undefined;
|
|
115
114
|
/** Atomically publish the adoption marker (same write-temp → fsync → rename discipline as the store). */
|
|
116
115
|
export declare function writeRuleAdoptionFile(dir: string, content: RuleAdoptionFile): void;
|
|
@@ -123,7 +122,8 @@ declare class FileDurableRulePartition implements WritableDurableRulePartition {
|
|
|
123
122
|
readonly durability: StoreDurability;
|
|
124
123
|
readonly fidelity: StoreFidelity;
|
|
125
124
|
constructor(dir: string, file: string, acquireWriteLock: () => void, onError?: ((message: string) => void) | undefined);
|
|
126
|
-
/** Read and validate. Any refusal answers with an empty set AND says so — never a silent empty store.
|
|
125
|
+
/** Read and validate. Any refusal answers with an empty set AND says so — never a silent empty store. The answer's
|
|
126
|
+
* sentence names no location ({@link refusalText}); the disclosure that accompanies it does. */
|
|
127
127
|
private read;
|
|
128
128
|
private disclose;
|
|
129
129
|
/**
|
|
@@ -204,6 +204,8 @@ export declare class FileDurableRulePartitionProvider implements DurableRulePart
|
|
|
204
204
|
});
|
|
205
205
|
/** The org partition's durable home in this directory (design/182 §7.4 contract; `org.json`). Shares
|
|
206
206
|
* this provider's writer lock — an install is a write. */
|
|
207
|
+
/** {@link judgeRuleAdoptionFile} at request time (owner resolution runs on every read), in {@link refusalText}'s voice. */
|
|
208
|
+
private adoptionMarker;
|
|
207
209
|
orgStatePersistence(): OrgRuleStatePersistence;
|
|
208
210
|
private fileOrgPersistence;
|
|
209
211
|
/** Take the writer lock, once, on first use of a write face. Reading never calls this. */
|