@sema-agent/core 5.13.0 → 5.15.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 +418 -0
- package/dist/agents/send-message-tool.js +1 -0
- package/dist/agents/subagent.d.ts +4 -0
- package/dist/agents/subagent.js +133 -41
- package/dist/brain/anthropic.js +33 -10
- package/dist/brain/context-overflow.d.ts +20 -0
- package/dist/brain/context-overflow.js +58 -0
- package/dist/brain/errors.js +21 -1
- package/dist/brain/open-responses.js +24 -10
- package/dist/brain/openai.js +29 -11
- package/dist/brain/request-params.d.ts +2 -0
- package/dist/brain/request-params.js +16 -0
- package/dist/brain/retry.d.ts +5 -0
- package/dist/brain/retry.js +16 -4
- package/dist/brain/stream-engine.d.ts +9 -1
- package/dist/brain/stream-engine.js +261 -28
- package/dist/brain/timeout.d.ts +1 -0
- package/dist/brain/timeout.js +1 -0
- package/dist/core/a2a.d.ts +2 -2
- package/dist/core/a2a.js +3 -3
- package/dist/core/ask-question.d.ts +47 -2
- package/dist/core/ask-question.js +209 -28
- package/dist/core/background-agent-store.d.ts +2 -0
- package/dist/core/checkpoint-store.d.ts +41 -17
- package/dist/core/checkpoint-store.js +137 -6
- package/dist/core/hooks.d.ts +24 -2
- package/dist/core/hooks.js +97 -10
- package/dist/core/human-input-projection.d.ts +12 -0
- package/dist/core/human-input-projection.js +27 -0
- package/dist/core/mcp.d.ts +7 -2
- package/dist/core/mcp.js +7 -7
- package/dist/core/memory-admission.d.ts +4 -0
- package/dist/core/memory-admission.js +3 -0
- package/dist/core/memory-engine/engine.d.ts +3 -1
- package/dist/core/memory-engine/engine.js +4 -3
- package/dist/core/memory-recall.d.ts +1 -1
- package/dist/core/memory-recall.js +3 -2
- package/dist/core/runner/assemble-result.d.ts +1 -0
- package/dist/core/runner/assemble-result.js +1 -1
- package/dist/core/runner/prepare-memory.d.ts +1 -0
- package/dist/core/runner/prepare-memory.js +3 -3
- package/dist/core/runner/prepare-task.d.ts +19 -6
- package/dist/core/runner/prepare-task.js +343 -35
- package/dist/core/runner/runtask.d.ts +3 -6
- package/dist/core/runner/runtask.js +290 -64
- package/dist/core/runner/tool-disclosure.d.ts +5 -0
- package/dist/core/runner/tool-disclosure.js +65 -16
- package/dist/core/runner/tool-output-projection.js +1 -0
- package/dist/core/runner/turn-attachments.d.ts +4 -0
- package/dist/core/runner/turn-attachments.js +15 -2
- package/dist/core/session-store.d.ts +3 -0
- package/dist/core/session-store.js +4 -0
- package/dist/core/session.d.ts +1 -0
- package/dist/core/store-contracts/background-agent-store-contract.js +19 -0
- package/dist/core/store-contracts/checkpoint-store-contract.js +62 -3
- package/dist/core/task-notification.d.ts +2 -0
- package/dist/core/task-notification.js +5 -3
- package/dist/core/task-registry-agent.d.ts +1 -0
- package/dist/core/task-registry-agent.js +6 -0
- package/dist/core/task-registry.d.ts +1 -0
- package/dist/core/task-registry.js +4 -1
- package/dist/core/task-tool-shape.js +4 -3
- package/dist/core/tool-policy.d.ts +5 -0
- package/dist/core/tool-policy.js +2 -1
- package/dist/core/trace.d.ts +6 -0
- package/dist/core/types.d.ts +32 -1
- package/dist/core/wiring-manifest.d.ts +97 -0
- package/dist/core/wiring-manifest.js +186 -0
- package/dist/engine/compaction/compaction.js +2 -2
- package/dist/engine/harness/agent-harness.d.ts +2 -1
- package/dist/engine/harness/agent-harness.js +8 -1
- package/dist/engine/harness/types.d.ts +3 -1
- package/dist/engine/llm/types.d.ts +7 -0
- package/dist/engine/llm/types.js +8 -1
- package/dist/engine/session/import-validate.d.ts +6 -1
- package/dist/engine/session/import-validate.js +29 -6
- package/dist/engine/session/memory-repo.d.ts +3 -1
- package/dist/engine/session/memory-repo.js +2 -2
- package/dist/index.d.ts +10 -7
- package/dist/index.js +8 -5
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/llm.d.ts +2 -2
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/run-workflow-tool.d.ts +4 -0
- package/dist/orchestration/run-workflow-tool.js +3 -0
- package/dist/orchestration/workflow-types.d.ts +8 -0
- package/dist/orchestration/workflow-types.js +14 -0
- package/dist/orchestration/workflow.d.ts +4 -0
- package/dist/orchestration/workflow.js +134 -5
- package/dist/prompts/default.js +1 -1
- package/dist/prompts/supervisor.d.ts +2 -2
- package/dist/prompts/supervisor.js +5 -4
- package/dist/stores/file/checkpoint-store.d.ts +3 -5
- package/dist/stores/file/checkpoint-store.js +31 -2
- package/dist/stores/file/index.js +1 -1
- package/dist/stores/file/session-store.d.ts +3 -1
- package/dist/stores/file/session-store.js +2 -2
- package/dist/stores/file/shared-ledger.js +8 -1
- package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -0
- package/dist/tools/fs/bash-readonly-classifier.js +94 -0
- package/dist/tools/fs/fs-bash.d.ts +1 -0
- package/dist/tools/fs/fs-bash.js +32 -13
- package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
- package/dist/tools/fs/gh-rate-limit.js +4 -3
- package/dist/tools/fs/index.d.ts +1 -0
- package/dist/tools/fs/index.js +1 -0
- package/dist/tools/fs/safety.js +34 -10
- package/package.json +1 -1
package/dist/core/hooks.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DocumentContent, ImageContent, TextContent } from "../internal/llm.js";
|
|
2
|
-
import type { SessionTreeEntry } from "../internal/harness-types.js";
|
|
2
|
+
import type { ExecutionEnv, FileError, Result, SessionTreeEntry } from "../internal/harness-types.js";
|
|
3
3
|
import type { PermissionResult, ResolvedAsk, ToolCallRequest } from "./tool-policy.js";
|
|
4
4
|
export interface Hooks {
|
|
5
5
|
preToolUse?(toolName: string, input: unknown, ctx: HookToolContext): PreToolUseResult | undefined | Promise<PreToolUseResult | undefined>;
|
|
@@ -72,9 +72,17 @@ export interface StopHookResult {
|
|
|
72
72
|
block?: string;
|
|
73
73
|
additionalContext?: string;
|
|
74
74
|
}
|
|
75
|
+
export interface HookEnvCapabilities {
|
|
76
|
+
canonicalPath?(path: string, abortSignal?: AbortSignal): Promise<Result<string, FileError>>;
|
|
77
|
+
exists?(path: string, abortSignal?: AbortSignal): Promise<Result<boolean, FileError>>;
|
|
78
|
+
readLink?(path: string, abortSignal?: AbortSignal): Promise<Result<string, FileError>>;
|
|
79
|
+
cwd?(): string;
|
|
80
|
+
}
|
|
81
|
+
export declare function createHookEnvCapabilities(env: ExecutionEnv): HookEnvCapabilities;
|
|
75
82
|
export interface HookToolContext {
|
|
76
83
|
toolCallId: string;
|
|
77
84
|
toolName: string;
|
|
85
|
+
env?: HookEnvCapabilities;
|
|
78
86
|
}
|
|
79
87
|
export interface HookToolOutput {
|
|
80
88
|
content: Array<TextContent | ImageContent | DocumentContent>;
|
|
@@ -103,6 +111,18 @@ export interface ToolGateResult {
|
|
|
103
111
|
};
|
|
104
112
|
preToolContext: string[];
|
|
105
113
|
}
|
|
114
|
+
export type ContentAskOutcome = {
|
|
115
|
+
kind: "answered";
|
|
116
|
+
presentedInput: unknown;
|
|
117
|
+
} | {
|
|
118
|
+
kind: "unavailable";
|
|
119
|
+
presentedInput?: unknown;
|
|
120
|
+
parkDeclined: boolean;
|
|
121
|
+
} | {
|
|
122
|
+
kind: "delivery_failure";
|
|
123
|
+
code: string;
|
|
124
|
+
presentedInput?: unknown;
|
|
125
|
+
};
|
|
106
126
|
export interface ToolGateInput {
|
|
107
127
|
onNotifyError?: (failure: import("./safe-notify.js").SafeNotifyFailure) => void;
|
|
108
128
|
event: {
|
|
@@ -111,9 +131,11 @@ export interface ToolGateInput {
|
|
|
111
131
|
input: Record<string, unknown>;
|
|
112
132
|
};
|
|
113
133
|
preToolUse?: Hooks["preToolUse"];
|
|
134
|
+
hookEnv?: HookEnvCapabilities;
|
|
114
135
|
adjudicate?: (req: ToolCallRequest) => Promise<PermissionResult>;
|
|
115
136
|
resolveAsk: (decision: PermissionResult, req: ToolCallRequest) => Promise<ResolvedAsk>;
|
|
116
|
-
suspendAsk?: (req: ToolCallRequest, postHookArgs: unknown, safety?: import("./checkpoint-store.js").SafetyAxis,
|
|
137
|
+
suspendAsk?: (req: ToolCallRequest, postHookArgs: unknown, safety?: import("./checkpoint-store.js").SafetyAxis, liveFaceUnavailable?: boolean) => Promise<ToolGateResult["suspend"] | undefined>;
|
|
138
|
+
resolveContentAsk?: (req: ToolCallRequest) => Promise<ContentAskOutcome>;
|
|
117
139
|
egress?: boolean;
|
|
118
140
|
irreversibility?: "never" | "maybe" | "always";
|
|
119
141
|
reversibilityProbe?: (args: unknown) => {
|
package/dist/core/hooks.js
CHANGED
|
@@ -14,6 +14,67 @@ export function cloneObserverInput(input) {
|
|
|
14
14
|
return input;
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
+
const reflectApply = Reflect.apply;
|
|
18
|
+
const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
|
|
19
|
+
const getPrototypeOf = Object.getPrototypeOf;
|
|
20
|
+
const objectPrototype = Object.prototype;
|
|
21
|
+
function findEnvSlot(env, key) {
|
|
22
|
+
for (let o = env; o !== null && o !== objectPrototype; o = getPrototypeOf(o)) {
|
|
23
|
+
const desc = getOwnPropertyDescriptor(o, key);
|
|
24
|
+
if (desc !== undefined)
|
|
25
|
+
return { holder: o, desc };
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
function readEnvPrimitive(env, key) {
|
|
30
|
+
const slot = findEnvSlot(env, key);
|
|
31
|
+
if (slot === undefined)
|
|
32
|
+
return undefined;
|
|
33
|
+
return slot.desc.get !== undefined ? reflectApply(slot.desc.get, env, []) : slot.desc.value;
|
|
34
|
+
}
|
|
35
|
+
function createCwdReader(env) {
|
|
36
|
+
const slot = findEnvSlot(env, "cwd");
|
|
37
|
+
if (slot === undefined)
|
|
38
|
+
return undefined;
|
|
39
|
+
const getter = slot.desc.get;
|
|
40
|
+
const initial = getter !== undefined ? reflectApply(getter, env, []) : slot.desc.value;
|
|
41
|
+
if (typeof initial !== "string")
|
|
42
|
+
return undefined;
|
|
43
|
+
let last = initial;
|
|
44
|
+
return () => {
|
|
45
|
+
const desc = getOwnPropertyDescriptor(slot.holder, "cwd");
|
|
46
|
+
const value = desc === undefined
|
|
47
|
+
? undefined
|
|
48
|
+
: desc.get !== undefined
|
|
49
|
+
? desc.get === getter
|
|
50
|
+
? reflectApply(desc.get, env, [])
|
|
51
|
+
: undefined
|
|
52
|
+
: desc.value;
|
|
53
|
+
if (typeof value === "string")
|
|
54
|
+
last = value;
|
|
55
|
+
return last;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export function createHookEnvCapabilities(env) {
|
|
59
|
+
const face = Object.create(null);
|
|
60
|
+
const canonicalPath = readEnvPrimitive(env, "canonicalPath");
|
|
61
|
+
const exists = readEnvPrimitive(env, "exists");
|
|
62
|
+
const readLink = readEnvPrimitive(env, "readLink");
|
|
63
|
+
const cwd = createCwdReader(env);
|
|
64
|
+
if (typeof canonicalPath === "function") {
|
|
65
|
+
face.canonicalPath = (path, abortSignal) => reflectApply(canonicalPath, env, [path, abortSignal]);
|
|
66
|
+
}
|
|
67
|
+
if (typeof exists === "function") {
|
|
68
|
+
face.exists = (path, abortSignal) => reflectApply(exists, env, [path, abortSignal]);
|
|
69
|
+
}
|
|
70
|
+
if (typeof readLink === "function") {
|
|
71
|
+
face.readLink = (path, abortSignal) => reflectApply(readLink, env, [path, abortSignal]);
|
|
72
|
+
}
|
|
73
|
+
if (cwd !== undefined) {
|
|
74
|
+
face.cwd = cwd;
|
|
75
|
+
}
|
|
76
|
+
return Object.freeze(face);
|
|
77
|
+
}
|
|
17
78
|
export function formatHookFeedback(text) {
|
|
18
79
|
return `<system-reminder>\n${text}\n</system-reminder>`;
|
|
19
80
|
}
|
|
@@ -61,6 +122,7 @@ function withProbeTimeout(p, ms, signal) {
|
|
|
61
122
|
export async function runToolGate(input) {
|
|
62
123
|
const { event, preToolUse, adjudicate, resolveAsk, suspendAsk } = input;
|
|
63
124
|
const { toolCallId, toolName } = event;
|
|
125
|
+
const hookCtx = () => ({ toolCallId, toolName, ...(input.hookEnv !== undefined ? { env: input.hookEnv } : {}) });
|
|
64
126
|
let currentInput = event.input;
|
|
65
127
|
const preToolContext = [];
|
|
66
128
|
let hookAsk;
|
|
@@ -68,7 +130,7 @@ export async function runToolGate(input) {
|
|
|
68
130
|
if (preToolUse) {
|
|
69
131
|
let r;
|
|
70
132
|
try {
|
|
71
|
-
r = screenPreToolUseResult(await preToolUse(toolName, currentInput,
|
|
133
|
+
r = screenPreToolUseResult(await preToolUse(toolName, currentInput, hookCtx()));
|
|
72
134
|
}
|
|
73
135
|
catch (err) {
|
|
74
136
|
const reason = preToolUseCrashReason(`this call to "${toolName}"`, err);
|
|
@@ -147,7 +209,10 @@ export async function runToolGate(input) {
|
|
|
147
209
|
currentInput = policyRewrite;
|
|
148
210
|
req.args = policyRewrite;
|
|
149
211
|
}
|
|
150
|
-
if (input.autoMode &&
|
|
212
|
+
if (input.autoMode &&
|
|
213
|
+
decision.action === "ask" &&
|
|
214
|
+
req.toolName !== ASK_USER_QUESTION_TOOL_NAME &&
|
|
215
|
+
input.isMarkedUnresolvable?.(input.event.toolCallId) !== true) {
|
|
151
216
|
const verdict = await input.autoMode.decider
|
|
152
217
|
.decide({ req, askMessage: decisionText(decision) }, input.abortSignal)
|
|
153
218
|
.catch(() => ({ kind: "unavailable", cause: "error" }));
|
|
@@ -180,13 +245,35 @@ export async function runToolGate(input) {
|
|
|
180
245
|
}
|
|
181
246
|
}
|
|
182
247
|
if (decision.action === "ask" && req.toolName === ASK_USER_QUESTION_TOOL_NAME) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
248
|
+
const outcome = input.resolveContentAsk !== undefined ? await input.resolveContentAsk(req) : { kind: "unavailable", parkDeclined: false };
|
|
249
|
+
if (outcome.kind === "answered") {
|
|
250
|
+
decision = { action: "allow", updatedInput: outcome.presentedInput };
|
|
251
|
+
}
|
|
252
|
+
else if (outcome.kind === "unavailable") {
|
|
253
|
+
if (outcome.presentedInput !== undefined) {
|
|
254
|
+
currentInput = outcome.presentedInput;
|
|
255
|
+
req.args = outcome.presentedInput;
|
|
256
|
+
}
|
|
257
|
+
if (suspendAsk && outcome.parkDeclined) {
|
|
258
|
+
const suspended = await suspendAsk(req, currentInput, safety, true);
|
|
259
|
+
if (suspended) {
|
|
260
|
+
return { suspend: suspended, preToolContext };
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
decision = {
|
|
264
|
+
action: "deny",
|
|
265
|
+
message: "AskUserQuestion could not be parked for a durable human answer on this path (no checkpoint " +
|
|
266
|
+
"facility, or the suspend failed) and a synchronous permission approver cannot carry an answer — " +
|
|
267
|
+
"the question was NOT shown to anyone. Proceed with your best judgment and state the assumption " +
|
|
268
|
+
"you made.",
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
if (outcome.presentedInput !== undefined)
|
|
273
|
+
decision = { action: "allow", updatedInput: outcome.presentedInput };
|
|
274
|
+
else
|
|
275
|
+
decision = { action: "allow" };
|
|
276
|
+
}
|
|
190
277
|
}
|
|
191
278
|
if (decision.action === "ask") {
|
|
192
279
|
const resolved = await resolveAsk(decision, req);
|
|
@@ -212,7 +299,7 @@ export async function runToolGate(input) {
|
|
|
212
299
|
if (preToolUse) {
|
|
213
300
|
let hr;
|
|
214
301
|
try {
|
|
215
|
-
hr = screenPreToolUseResult(await preToolUse(toolName, editArgs,
|
|
302
|
+
hr = screenPreToolUseResult(await preToolUse(toolName, editArgs, hookCtx()));
|
|
216
303
|
}
|
|
217
304
|
catch (err) {
|
|
218
305
|
traceHookCrash(input, err, notifier);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ActorAssertion } from "../internal/llm.js";
|
|
2
|
+
import type { HumanInputEvent, HumanInputSource, TaskEventIdentity } from "./types.js";
|
|
3
|
+
export type { HumanInputSource, HumanInputDelivery, HumanInputEvent } from "./types.js";
|
|
4
|
+
export interface HumanInputFrame {
|
|
5
|
+
text: string;
|
|
6
|
+
actor?: ActorAssertion;
|
|
7
|
+
source: HumanInputSource;
|
|
8
|
+
}
|
|
9
|
+
export declare function projectHumanInput(frame: HumanInputFrame): string;
|
|
10
|
+
export declare function buildHumanInputEvent(input: Omit<HumanInputEvent, "type" | "inputId" | keyof TaskEventIdentity> & {
|
|
11
|
+
inputId?: string;
|
|
12
|
+
}): HumanInputEvent;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { snapshotActorAssertion } from "../internal/llm.js";
|
|
2
|
+
import { uuidv7 } from "../internal/harness.js";
|
|
3
|
+
import { inlineUntrusted } from "./untrusted-text.js";
|
|
4
|
+
import { attrEscape, EXTERNAL_SOURCE_MAX } from "./task-notification.js";
|
|
5
|
+
export function projectHumanInput(frame) {
|
|
6
|
+
if (frame.actor === undefined || frame.source === "system")
|
|
7
|
+
return frame.text;
|
|
8
|
+
if (frame.text.trim().length === 0)
|
|
9
|
+
return frame.text;
|
|
10
|
+
const label = attrEscape(inlineUntrusted(frame.actor.id, EXTERNAL_SOURCE_MAX));
|
|
11
|
+
const mark = frame.actor.hostAsserted ? "" : " (unverified)";
|
|
12
|
+
return `[from "${label}"${mark}]\n${frame.text}`;
|
|
13
|
+
}
|
|
14
|
+
export function buildHumanInputEvent(input) {
|
|
15
|
+
return {
|
|
16
|
+
type: "human_input",
|
|
17
|
+
inputId: input.inputId ?? uuidv7(),
|
|
18
|
+
sessionSeq: input.sessionSeq,
|
|
19
|
+
carrier: input.carrier,
|
|
20
|
+
source: input.source,
|
|
21
|
+
delivery: input.delivery,
|
|
22
|
+
...(input.issuer !== undefined ? { issuer: input.issuer } : {}),
|
|
23
|
+
...(input.actor !== undefined ? { actor: snapshotActorAssertion(input.actor) } : {}),
|
|
24
|
+
...(input.principal !== undefined ? { principal: input.principal } : {}),
|
|
25
|
+
...(input.entryId !== undefined ? { entryId: input.entryId } : {}),
|
|
26
|
+
};
|
|
27
|
+
}
|
package/dist/core/mcp.d.ts
CHANGED
|
@@ -5,8 +5,8 @@ import { type McpImageResizer } from "./image-downsample.js";
|
|
|
5
5
|
import type { McpServerSpec, OnElicit, ToolEffect } from "./types.js";
|
|
6
6
|
export interface McpToolAxis {
|
|
7
7
|
name: string;
|
|
8
|
-
irreversibility?: "always";
|
|
9
|
-
egress?:
|
|
8
|
+
irreversibility?: "always" | "never";
|
|
9
|
+
egress?: boolean;
|
|
10
10
|
effect?: ToolEffect;
|
|
11
11
|
}
|
|
12
12
|
export interface McpDroppedTool {
|
|
@@ -114,6 +114,11 @@ export type McpSchemaNormalizeResult = {
|
|
|
114
114
|
export declare function normalizeMcpToolSchema(schema: unknown): McpSchemaNormalizeResult;
|
|
115
115
|
export declare function mcpToolSchemaProblem(schema: unknown): string | undefined;
|
|
116
116
|
export declare function materializeMcpTools(specs: McpServerSpec[], principal?: string, onElicit?: OnElicit, imageResizer?: McpImageResizer): Promise<MaterializedMcp>;
|
|
117
|
+
export declare function applyCallerAxisOverride(name: string, hint: McpToolAxis | undefined, override: {
|
|
118
|
+
effect?: ToolEffect;
|
|
119
|
+
egress?: boolean;
|
|
120
|
+
irreversibility?: "always" | "never";
|
|
121
|
+
} | undefined): McpToolAxis | undefined;
|
|
117
122
|
export declare function classifyDirReadInvalidParams(message: string): "not_found" | "not_directory";
|
|
118
123
|
export declare function parseCallToolResultLenient(data: unknown): {
|
|
119
124
|
success: true;
|
package/dist/core/mcp.js
CHANGED
|
@@ -720,7 +720,7 @@ function mcpAxisFor(namespacedName, annotations) {
|
|
|
720
720
|
}
|
|
721
721
|
return any ? axis : undefined;
|
|
722
722
|
}
|
|
723
|
-
function applyCallerAxisOverride(name, hint, override) {
|
|
723
|
+
export function applyCallerAxisOverride(name, hint, override) {
|
|
724
724
|
if (!override)
|
|
725
725
|
return hint;
|
|
726
726
|
let effect = hint?.effect;
|
|
@@ -729,16 +729,16 @@ function applyCallerAxisOverride(name, hint, override) {
|
|
|
729
729
|
if (override.effect !== undefined)
|
|
730
730
|
effect = override.effect;
|
|
731
731
|
if (override.egress !== undefined)
|
|
732
|
-
egress = override.egress
|
|
732
|
+
egress = override.egress;
|
|
733
733
|
if (override.irreversibility !== undefined)
|
|
734
|
-
irrev = override.irreversibility
|
|
734
|
+
irrev = override.irreversibility;
|
|
735
735
|
const axis = { name };
|
|
736
736
|
if (effect !== undefined)
|
|
737
737
|
axis.effect = effect;
|
|
738
|
-
if (egress)
|
|
739
|
-
axis.egress =
|
|
740
|
-
if (irrev)
|
|
741
|
-
axis.irreversibility =
|
|
738
|
+
if (egress !== undefined)
|
|
739
|
+
axis.egress = egress;
|
|
740
|
+
if (irrev !== undefined)
|
|
741
|
+
axis.irreversibility = irrev;
|
|
742
742
|
return axis.effect !== undefined || axis.egress !== undefined || axis.irreversibility !== undefined ? axis : undefined;
|
|
743
743
|
}
|
|
744
744
|
const LIST_MCP_RESOURCES = "ListMcpResourcesTool";
|
|
@@ -44,4 +44,8 @@ export interface OwnOrgAdmissionVerdict {
|
|
|
44
44
|
scopes: readonly string[];
|
|
45
45
|
writeScope: string | null;
|
|
46
46
|
}
|
|
47
|
+
export declare function readDurableOrgAdmission(row: {
|
|
48
|
+
admittedOrgScopes?: readonly string[];
|
|
49
|
+
admittedOrgWriteScope?: string | null;
|
|
50
|
+
}): OwnOrgAdmissionVerdict;
|
|
47
51
|
export declare function admitMemoryScopes(input: MemoryAdmissionInput): Promise<MemoryAdmissionOutcome>;
|
|
@@ -7,6 +7,9 @@ function codedError(code, message) {
|
|
|
7
7
|
export function foldAdmissionFreeze(input) {
|
|
8
8
|
return input.delegated ? (input.inherited ?? []) : input.inherited;
|
|
9
9
|
}
|
|
10
|
+
export function readDurableOrgAdmission(row) {
|
|
11
|
+
return { scopes: row.admittedOrgScopes ?? [], writeScope: row.admittedOrgWriteScope ?? null };
|
|
12
|
+
}
|
|
10
13
|
const ORG_SHAPE = /^org:/;
|
|
11
14
|
function orgScopesOf(spec) {
|
|
12
15
|
if (spec.scopeContract !== "v2")
|
|
@@ -49,7 +49,9 @@ export declare class MemoryEngine {
|
|
|
49
49
|
constructor(opts: MemoryEngineOptions);
|
|
50
50
|
private discloseAnnounceFailure;
|
|
51
51
|
materialize(scopes: readonly string[], writeScope: string | null): Promise<MemorySessionHandle>;
|
|
52
|
-
inject(handle: MemorySessionHandle
|
|
52
|
+
inject(handle: MemorySessionHandle, opts?: {
|
|
53
|
+
writeToolMounted?: boolean;
|
|
54
|
+
}): MemoryInjection;
|
|
53
55
|
gateWrite(handle: MemorySessionHandle, canonicalPath: string, content: string): {
|
|
54
56
|
ok: true;
|
|
55
57
|
} | {
|
|
@@ -188,14 +188,15 @@ export class MemoryEngine {
|
|
|
188
188
|
}
|
|
189
189
|
return handle;
|
|
190
190
|
}
|
|
191
|
-
inject(handle) {
|
|
192
|
-
const
|
|
191
|
+
inject(handle, opts) {
|
|
192
|
+
const writeChannel = handle.writeScope !== null && opts?.writeToolMounted !== false;
|
|
193
|
+
const instruction = writeChannel ? buildMemoryInstruction(handle.writableRoot) : "";
|
|
193
194
|
const indexPath = join(handle.writableRoot, MEMORY_INDEX_FILENAME);
|
|
194
195
|
const onDisk = readSafe(indexPath);
|
|
195
196
|
const indexText = onDisk !== undefined && onDisk.trim() !== "" ? onDisk : handle.indexText;
|
|
196
197
|
const truncated = truncateIndex(indexText);
|
|
197
198
|
const index = composeMemoryBlock(truncated, handle.writeScope ?? handle.scopes[0] ?? "memory");
|
|
198
|
-
const indexSeed =
|
|
199
|
+
const indexSeed = writeChannel && onDisk !== undefined && (onDisk.trim() === "" || truncated === onDisk)
|
|
199
200
|
? { path: indexPath, content: onDisk }
|
|
200
201
|
: undefined;
|
|
201
202
|
let announcements;
|
|
@@ -36,7 +36,7 @@ export type SelectiveRecallResult = {
|
|
|
36
36
|
export declare function resolveLinkedIds(headers: MemoryNoteHeader[], selected: MemoryNoteRecord[], max: number): string[];
|
|
37
37
|
export declare function buildManifestText(headers: MemoryNoteHeader[]): string;
|
|
38
38
|
export declare function validateSelectedIds(headers: MemoryNoteHeader[], ids: string[], max: number): string[];
|
|
39
|
-
export declare function composeSelectiveBody(manifestText: string, selected: MemoryNoteRecord[], nowMs: number, linked?: MemoryNoteRecord[], recallable?: boolean): string;
|
|
39
|
+
export declare function composeSelectiveBody(manifestText: string, selected: MemoryNoteRecord[], nowMs: number, linked?: MemoryNoteRecord[], recallable?: boolean, recallToolName?: string): string;
|
|
40
40
|
export declare function encodeSurfacedKey(scope: string, id: string): string;
|
|
41
41
|
export interface ScopedNoteHeader extends MemoryNoteHeader {
|
|
42
42
|
scope: string;
|
|
@@ -102,7 +102,7 @@ export function validateSelectedIds(headers, ids, max) {
|
|
|
102
102
|
}
|
|
103
103
|
return out;
|
|
104
104
|
}
|
|
105
|
-
export function composeSelectiveBody(manifestText, selected, nowMs, linked = [], recallable = true) {
|
|
105
|
+
export function composeSelectiveBody(manifestText, selected, nowMs, linked = [], recallable = true, recallToolName) {
|
|
106
106
|
const renderNote = (r, label) => {
|
|
107
107
|
const ageMs = nowMs - r.mtimeMs;
|
|
108
108
|
const verify = r.timestampMissing || ageMs > ONE_DAY_MS ? " — verify it's still current" : "";
|
|
@@ -124,8 +124,9 @@ export function composeSelectiveBody(manifestText, selected, nowMs, linked = [],
|
|
|
124
124
|
body = `${buf.subarray(0, cut).toString("utf8")}\n<selected notes truncated to ${SELECTED_BODY_MAX_BYTES} bytes>`;
|
|
125
125
|
}
|
|
126
126
|
const selectedSection = selected.length > 0 ? `\n\nRelevant notes:\n${body}` : "\n\n(no notes selected as relevant to this task)";
|
|
127
|
+
const recallCall = recallToolName !== undefined ? `call ${recallToolName}` : `search the memory-recall tool bound to this scope`;
|
|
127
128
|
const manifestSection = recallable
|
|
128
|
-
? `Memory index — to load a note in full,
|
|
129
|
+
? `Memory index — to load a note in full, ${recallCall} with keywords from its description:\n${sanitizeUntrustedText(manifestText, ["user_memory"])}`
|
|
129
130
|
: "";
|
|
130
131
|
return `${manifestSection}${selectedSection}`;
|
|
131
132
|
}
|
|
@@ -58,6 +58,7 @@ export interface ResultFlags {
|
|
|
58
58
|
model?: string;
|
|
59
59
|
unpricedSpend?: boolean;
|
|
60
60
|
rewindNotes?: TaskResult["rewindNotes"];
|
|
61
|
+
strandedHumanAnswers?: TaskResult["strandedHumanAnswers"];
|
|
61
62
|
remoteEnvFailures?: TaskResult["remoteEnvFailures"];
|
|
62
63
|
retryAfterMs?: number;
|
|
63
64
|
abortedForTimeout: boolean;
|
|
@@ -159,5 +159,5 @@ export function assembleResult(spec, sessionId, final, stats, flags) {
|
|
|
159
159
|
void _internalCompaction;
|
|
160
160
|
if (flags.unpricedSpend)
|
|
161
161
|
delete publicStats.costMicroUsd;
|
|
162
|
-
return { taskId, sessionId, status, ...(flags.model !== undefined ? { model: flags.model } : {}), result: result.trim(), salvagedOutput, blockedReason, errorMessage, errorCode, ...(retryAfterMs !== undefined ? { retryAfterMs } : {}), checkpointToken, checkpointGate, ...(workspaceRestoreMode !== undefined ? { workspaceRestoreMode } : {}), ...(flags.rewindNotes !== undefined && flags.rewindNotes.length > 0 ? { rewindNotes: flags.rewindNotes } : {}), ...(flags.remoteEnvFailures !== undefined && flags.remoteEnvFailures.length > 0 ? { remoteEnvFailures: flags.remoteEnvFailures } : {}), stats: publicStats };
|
|
162
|
+
return { taskId, sessionId, status, ...(flags.model !== undefined ? { model: flags.model } : {}), result: result.trim(), salvagedOutput, blockedReason, errorMessage, errorCode, ...(retryAfterMs !== undefined ? { retryAfterMs } : {}), checkpointToken, checkpointGate, ...(workspaceRestoreMode !== undefined ? { workspaceRestoreMode } : {}), ...(flags.rewindNotes !== undefined && flags.rewindNotes.length > 0 ? { rewindNotes: flags.rewindNotes } : {}), ...(flags.remoteEnvFailures !== undefined && flags.remoteEnvFailures.length > 0 ? { remoteEnvFailures: flags.remoteEnvFailures } : {}), ...(flags.strandedHumanAnswers !== undefined && flags.strandedHumanAnswers.length > 0 ? { strandedHumanAnswers: flags.strandedHumanAnswers } : {}), stats: publicStats };
|
|
163
163
|
}
|
|
@@ -135,7 +135,7 @@ export async function prepareMemory(input) {
|
|
|
135
135
|
const writeIsPersonal = p.writePlane === "personal";
|
|
136
136
|
writeEngine = writeIsPersonal ? personalEngine : projectEngine;
|
|
137
137
|
writeHandle = writeIsPersonal ? personalHandle : projectHandle;
|
|
138
|
-
injectFn = () => mergeInjections(projectEngine.inject(projectHandle), personalEngine.inject(personalHandle));
|
|
138
|
+
injectFn = () => mergeInjections(projectEngine.inject(projectHandle, { writeToolMounted: input.writeToolsMounted }), personalEngine.inject(personalHandle, { writeToolMounted: input.writeToolsMounted }));
|
|
139
139
|
harvestBoth = async () => {
|
|
140
140
|
const writeFirst = writeIsPersonal ? [personalEngine, personalHandle] : [projectEngine, projectHandle];
|
|
141
141
|
const readOther = writeIsPersonal ? [projectEngine, projectHandle] : [personalEngine, personalHandle];
|
|
@@ -159,7 +159,7 @@ export async function prepareMemory(input) {
|
|
|
159
159
|
const handle = await personalEngine.materialize(memorySpec.scopes, memorySpec.writeScope);
|
|
160
160
|
writeEngine = personalEngine;
|
|
161
161
|
writeHandle = handle;
|
|
162
|
-
injectFn = () => personalEngine.inject(handle);
|
|
162
|
+
injectFn = () => personalEngine.inject(handle, { writeToolMounted: input.writeToolsMounted });
|
|
163
163
|
harvestBoth = () => personalEngine.harvest(handle);
|
|
164
164
|
}
|
|
165
165
|
else {
|
|
@@ -171,7 +171,7 @@ export async function prepareMemory(input) {
|
|
|
171
171
|
const handle = await engine.materialize(memorySpec.scopes, memorySpec.writeScope);
|
|
172
172
|
writeEngine = engine;
|
|
173
173
|
writeHandle = handle;
|
|
174
|
-
injectFn = () => engine.inject(handle);
|
|
174
|
+
injectFn = () => engine.inject(handle, { writeToolMounted: input.writeToolsMounted });
|
|
175
175
|
harvestBoth = () => engine.harvest(handle);
|
|
176
176
|
}
|
|
177
177
|
memoryWriteGateRef.current = (w) => writeEngine.gateWrite(writeHandle, w.key, w.content);
|
|
@@ -16,11 +16,13 @@ import { type BrainCallGuardrailRef } from "../../brain/timeout.js";
|
|
|
16
16
|
import { type OutputRef, type BlockedRef, type SkillListingEntry } from "./synthetic-tools.js";
|
|
17
17
|
import type { MemoryEngine } from "../memory-engine/engine.js";
|
|
18
18
|
import { type ToolManifestRow } from "../../prompt-assembly/tool-catalog.js";
|
|
19
|
+
import type { ToolDisclosureManifest } from "../trace.js";
|
|
19
20
|
import type { TaskNotificationPayload } from "../task-notification.js";
|
|
20
21
|
import { type CwdRef } from "../../tools/fs/index.js";
|
|
21
22
|
import { type WorkflowSizeGuideline } from "../../orchestration/workflow-size-guideline.js";
|
|
22
23
|
import type { Runner } from "./runtask.js";
|
|
23
|
-
import { type CheckpointGate, type CheckpointState, type
|
|
24
|
+
import { type CheckpointGate, type CheckpointState, type CheckpointToken, type ResourceLedger, type PlatformLimitReason, type ResourceLimitReason } from "../checkpoint-store.js";
|
|
25
|
+
import { type WiringManifest } from "../wiring-manifest.js";
|
|
24
26
|
import type { ActiveWorktreeSession, AgentMessage, AgentTool, ExecutionEnv } from "../../internal/harness.js";
|
|
25
27
|
import type { NestedUsageAccum, RunnerDeps, TaskEvent, TaskLimits, TaskResult, TaskSpec, ToolActivity, ToolEffect } from "../types.js";
|
|
26
28
|
import type { RepairBundle } from "../../agents/repair-loop.js";
|
|
@@ -44,11 +46,7 @@ export declare function checkpointScopeOf(spec: {
|
|
|
44
46
|
};
|
|
45
47
|
principal?: string;
|
|
46
48
|
}): string;
|
|
47
|
-
export
|
|
48
|
-
checkpointStore?: CheckpointStore | null;
|
|
49
|
-
}, deps: {
|
|
50
|
-
checkpointStore?: CheckpointStore;
|
|
51
|
-
}): CheckpointStore | undefined;
|
|
49
|
+
export { resolveCheckpointStore } from "../checkpoint-store.js";
|
|
52
50
|
export interface Prepared {
|
|
53
51
|
harness: AgentHarness;
|
|
54
52
|
session: StoredSession;
|
|
@@ -81,11 +79,16 @@ export interface Prepared {
|
|
|
81
79
|
denyNarrowingPolicy?: ToolPolicy;
|
|
82
80
|
basePolicyForResumeEdit?: ToolPolicy;
|
|
83
81
|
releaseSignal: () => void;
|
|
82
|
+
settleContentAskBindings: () => ReadonlyArray<{
|
|
83
|
+
deliveryId: string;
|
|
84
|
+
toolCallId: string;
|
|
85
|
+
}>;
|
|
84
86
|
cacheBreakDetector?: CacheBreakDetector;
|
|
85
87
|
cacheFingerprint?: {
|
|
86
88
|
systemPrompt: string;
|
|
87
89
|
tools: ToolFingerprintInput[];
|
|
88
90
|
};
|
|
91
|
+
wiringManifest: WiringManifest;
|
|
89
92
|
promptManifest: {
|
|
90
93
|
constitution: "core" | "replaced" | "provider-assembled";
|
|
91
94
|
blocks: Array<{
|
|
@@ -109,6 +112,7 @@ export interface Prepared {
|
|
|
109
112
|
elements: import("../../prompt-assembly/turn-snapshot.js").CacheIdentityElements;
|
|
110
113
|
};
|
|
111
114
|
lowering?: import("../../prompt-assembly/turn-snapshot.js").LoweringRecord;
|
|
115
|
+
toolDisclosure?: ToolDisclosureManifest;
|
|
112
116
|
};
|
|
113
117
|
epochDeclaredSections: import("../../prompt-assembly/epoch.js").EpochDeclaredSections;
|
|
114
118
|
turnSnapshot?: import("../../prompt-assembly/turn-snapshot.js").TurnPromptSnapshot;
|
|
@@ -123,6 +127,7 @@ export interface Prepared {
|
|
|
123
127
|
activeTools: Set<string>;
|
|
124
128
|
deferredToolNames?: ReadonlySet<string>;
|
|
125
129
|
toolMaterializeStatic: boolean;
|
|
130
|
+
staticFaceFor?: (name: string) => boolean;
|
|
126
131
|
memoryEngineSession?: {
|
|
127
132
|
engine: MemoryEngine;
|
|
128
133
|
handle: MemorySessionHandle;
|
|
@@ -294,6 +299,8 @@ export interface PrepareResume {
|
|
|
294
299
|
}>;
|
|
295
300
|
};
|
|
296
301
|
workspaceHandle?: import("../remote-env.js").WorkspaceHandle;
|
|
302
|
+
redeemedContentAskCallId?: string;
|
|
303
|
+
redeemedContentAskQuestionsHash?: string;
|
|
297
304
|
executesApprovedAction?: boolean;
|
|
298
305
|
}
|
|
299
306
|
export interface InheritedGate {
|
|
@@ -325,8 +332,13 @@ export declare function resolveModelPromptTraits(model: {
|
|
|
325
332
|
};
|
|
326
333
|
export interface RunInternals {
|
|
327
334
|
repairBundle?: RepairBundle;
|
|
335
|
+
questionFaceStripped?: true;
|
|
336
|
+
parentInteractionPosture?: "interactive" | "headless";
|
|
328
337
|
afterCheckpointResolve?: () => Promise<void>;
|
|
329
338
|
inheritedGate?: InheritedGate;
|
|
339
|
+
ownOrgAdmissionRef?: {
|
|
340
|
+
current: import("../memory-admission.js").OwnOrgAdmissionVerdict | undefined;
|
|
341
|
+
};
|
|
330
342
|
workflowDepth?: number;
|
|
331
343
|
insideFork?: boolean;
|
|
332
344
|
isDelegatedChild?: boolean;
|
|
@@ -338,6 +350,7 @@ export interface RunInternals {
|
|
|
338
350
|
explicitAgentName?: string;
|
|
339
351
|
parentTaskId?: string;
|
|
340
352
|
parentSessionId?: string;
|
|
353
|
+
delegationTaskType?: import("../types.js").DelegationTaskType;
|
|
341
354
|
rootSessionId?: string;
|
|
342
355
|
registryScope?: string;
|
|
343
356
|
parentCenterArtifactDigest?: string;
|