@deepstrike/sdk 0.2.52 → 0.2.60
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/README.md +28 -28
- package/dist/agent-ir.d.ts +103 -0
- package/dist/agent-ir.js +134 -0
- package/dist/agent.d.ts +67 -0
- package/dist/agent.js +36 -0
- package/dist/collaboration/harness.js +1 -1
- package/dist/collaboration/modes/creator-verifier.d.ts +2 -7
- package/dist/collaboration/modes/creator-verifier.js +4 -6
- package/dist/collaboration/pool.d.ts +8 -20
- package/dist/collaboration/pool.js +27 -97
- package/dist/compat/anthropic/mcp.d.ts +15 -0
- package/dist/compat/anthropic/mcp.js +10 -0
- package/dist/compat/openai/agent.d.ts +34 -0
- package/dist/compat/openai/agent.js +24 -0
- package/dist/governance.d.ts +1 -17
- package/dist/governance.js +1 -34
- package/dist/guardrail.d.ts +6 -0
- package/dist/guardrail.js +1 -0
- package/dist/handoff-target.d.ts +12 -0
- package/dist/handoff-target.js +1 -0
- package/dist/harness/manifest.js +0 -4
- package/dist/index.d.ts +19 -7
- package/dist/index.js +8 -5
- package/dist/kernel.d.ts +2 -20
- package/dist/knowledge/public.d.ts +29 -0
- package/dist/knowledge/public.js +1 -0
- package/dist/mcp-server.d.ts +28 -0
- package/dist/mcp-server.js +1 -0
- package/dist/memory/agent.d.ts +2 -2
- package/dist/memory/agent.js +2 -2
- package/dist/memory/durable.d.ts +16 -0
- package/dist/memory/durable.js +46 -0
- package/dist/memory/in-memory-store.d.ts +9 -7
- package/dist/memory/in-memory-store.js +8 -2
- package/dist/memory/protocols.d.ts +22 -4
- package/dist/memory/public.d.ts +4 -3
- package/dist/memory/public.js +3 -2
- package/dist/providers/anthropic-adapter.d.ts +47 -0
- package/dist/providers/anthropic-adapter.js +444 -0
- package/dist/providers/anthropic-compatible.d.ts +2 -3
- package/dist/providers/anthropic-compatible.js +8 -5
- package/dist/providers/anthropic.d.ts +19 -23
- package/dist/providers/anthropic.js +169 -395
- package/dist/providers/base.js +43 -3
- package/dist/providers/capability-router.d.ts +29 -0
- package/dist/providers/capability-router.js +43 -0
- package/dist/providers/catalog.d.ts +16 -4
- package/dist/providers/catalog.js +112 -21
- package/dist/providers/content-normalization.d.ts +57 -0
- package/dist/providers/content-normalization.js +238 -0
- package/dist/providers/content-policy.d.ts +16 -0
- package/dist/providers/content-policy.js +39 -0
- package/dist/providers/credentials.d.ts +83 -0
- package/dist/providers/credentials.js +190 -0
- package/dist/providers/endpoints.d.ts +137 -0
- package/dist/providers/endpoints.js +128 -0
- package/dist/providers/factories.js +9 -3
- package/dist/providers/gemini-adapter.d.ts +33 -0
- package/dist/providers/gemini-adapter.js +272 -0
- package/dist/providers/gemini.d.ts +16 -3
- package/dist/providers/gemini.js +97 -195
- package/dist/providers/model-catalog.d.ts +37 -0
- package/dist/providers/model-catalog.js +62 -0
- package/dist/providers/model-registry.d.ts +98 -0
- package/dist/providers/model-registry.js +315 -0
- package/dist/providers/ollama-adapter.d.ts +65 -0
- package/dist/providers/ollama-adapter.js +188 -0
- package/dist/providers/ollama.d.ts +9 -4
- package/dist/providers/ollama.js +96 -109
- package/dist/providers/openai-chat-dialects.d.ts +154 -0
- package/dist/providers/openai-chat-dialects.js +179 -0
- package/dist/providers/openai-chat.d.ts +46 -18
- package/dist/providers/openai-chat.js +418 -51
- package/dist/providers/openai-responses-adapter.d.ts +42 -0
- package/dist/providers/openai-responses-adapter.js +341 -0
- package/dist/providers/openai-responses.d.ts +14 -33
- package/dist/providers/openai-responses.js +131 -264
- package/dist/providers/openai.d.ts +29 -76
- package/dist/providers/openai.js +195 -292
- package/dist/providers/protocol-adapter.d.ts +34 -0
- package/dist/providers/protocol-adapter.js +9 -0
- package/dist/providers/protocol-capabilities.d.ts +34 -0
- package/dist/providers/protocol-capabilities.js +44 -0
- package/dist/providers/provider-error.d.ts +31 -0
- package/dist/providers/provider-error.js +149 -0
- package/dist/providers/public.d.ts +26 -3
- package/dist/providers/public.js +13 -1
- package/dist/providers/registry.d.ts +7 -6
- package/dist/providers/registry.js +47 -20
- package/dist/providers/request-plan.d.ts +86 -0
- package/dist/providers/request-plan.js +175 -0
- package/dist/providers/usage-normalizer.d.ts +48 -0
- package/dist/providers/usage-normalizer.js +96 -0
- package/dist/providers/vendor-profiles.d.ts +2 -15
- package/dist/providers/vendor-profiles.js +14 -60
- package/dist/runtime/canonical-kernel-step.d.ts +1 -2
- package/dist/runtime/canonical-kernel-step.js +47 -12
- package/dist/runtime/context-policy.d.ts +10 -12
- package/dist/runtime/context-policy.js +6 -8
- package/dist/runtime/durable-content.d.ts +50 -0
- package/dist/runtime/durable-content.js +159 -0
- package/dist/runtime/execution-plane.d.ts +2 -2
- package/dist/runtime/execution-plane.js +2 -2
- package/dist/runtime/kernel-event-log.js +0 -1
- package/dist/runtime/kernel-step.d.ts +0 -1
- package/dist/runtime/kernel-step.js +4 -2
- package/dist/runtime/mcp-proxy-plane.d.ts +25 -1
- package/dist/runtime/mcp-proxy-plane.js +44 -6
- package/dist/runtime/output-schema.d.ts +1 -2
- package/dist/runtime/provider-replay.d.ts +1 -1
- package/dist/runtime/provider-replay.js +12 -27
- package/dist/runtime/reactive-session.d.ts +1 -1
- package/dist/runtime/reactive-session.js +2 -3
- package/dist/runtime/run-group.d.ts +1 -1
- package/dist/runtime/runner.d.ts +26 -40
- package/dist/runtime/runner.js +145 -63
- package/dist/runtime/session-log.d.ts +8 -1
- package/dist/runtime/session-log.js +42 -2
- package/dist/runtime/session-repair.d.ts +1 -1
- package/dist/runtime/session-repair.js +1 -1
- package/dist/runtime/sub-agent-orchestrator.d.ts +1 -1
- package/dist/runtime/sub-agent-orchestrator.js +8 -11
- package/dist/runtime/workflow-control-flow.d.ts +0 -4
- package/dist/runtime/workflow-control-flow.js +0 -16
- package/dist/session.d.ts +11 -0
- package/dist/session.js +1 -0
- package/dist/skill.d.ts +17 -0
- package/dist/skill.js +16 -0
- package/dist/skills/loader.d.ts +3 -0
- package/dist/tools/errors.d.ts +1 -3
- package/dist/tools/errors.js +1 -3
- package/dist/tools/index.d.ts +3 -0
- package/dist/types/agent.d.ts +21 -9
- package/dist/types/agent.js +30 -4
- package/dist/types.d.ts +128 -13
- package/package.json +3 -3
- package/dist/providers/deepseek.d.ts +0 -46
- package/dist/providers/deepseek.js +0 -97
- package/dist/providers/glm.d.ts +0 -25
- package/dist/providers/glm.js +0 -48
- package/dist/providers/kimi.d.ts +0 -23
- package/dist/providers/kimi.js +0 -30
- package/dist/providers/minimax.d.ts +0 -49
- package/dist/providers/minimax.js +0 -98
- package/dist/providers/profiles.d.ts +0 -1992
- package/dist/providers/profiles.js +0 -796
- package/dist/providers/qwen.d.ts +0 -38
- package/dist/providers/qwen.js +0 -97
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/** Provider-neutral durable content ABI.
|
|
2
|
+
*
|
|
3
|
+
* This is deliberately separate from provider-facing ContentPart. Durable records carry only
|
|
4
|
+
* portable content and explicit payload locators; protocol adapters decide how to serialize it.
|
|
5
|
+
*/
|
|
6
|
+
export class DurableContentError extends Error {
|
|
7
|
+
constructor(message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = "DurableContentError";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
const CONTENT_KEYS = new Set(["blocks"]);
|
|
13
|
+
const TOOL_RESULT_KEYS = new Set(["call_id", "is_error", "blocks"]);
|
|
14
|
+
const SOURCE_KEYS = {
|
|
15
|
+
url: new Set(["kind", "url"]),
|
|
16
|
+
base64: new Set(["kind", "data"]),
|
|
17
|
+
file_id: new Set(["kind", "id", "affinity"]),
|
|
18
|
+
object: new Set(["kind", "handle", "owner", "payload_ref"]),
|
|
19
|
+
};
|
|
20
|
+
function object(value, label) {
|
|
21
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
22
|
+
throw new DurableContentError(`${label} must be an object`);
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
function exactKeys(value, allowed, label) {
|
|
26
|
+
for (const key of Object.keys(value))
|
|
27
|
+
if (!allowed.has(key))
|
|
28
|
+
throw new DurableContentError(`${label} has unknown field ${key}`);
|
|
29
|
+
}
|
|
30
|
+
function requiredString(value, label) {
|
|
31
|
+
if (typeof value !== "string" || value.length === 0)
|
|
32
|
+
throw new DurableContentError(`${label} must be a non-empty string`);
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
function requiredBoolean(value, label) {
|
|
36
|
+
if (typeof value !== "boolean")
|
|
37
|
+
throw new DurableContentError(`${label} must be a boolean`);
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
function base64(value, label) {
|
|
41
|
+
const data = requiredString(value, label);
|
|
42
|
+
if (data.length % 4 !== 0 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(data)) {
|
|
43
|
+
throw new DurableContentError(`${label} is not valid base64`);
|
|
44
|
+
}
|
|
45
|
+
return data;
|
|
46
|
+
}
|
|
47
|
+
function source(value, label) {
|
|
48
|
+
const raw = object(value, `${label} source`);
|
|
49
|
+
const kind = raw.kind;
|
|
50
|
+
if (kind !== "url" && kind !== "base64" && kind !== "file_id" && kind !== "object")
|
|
51
|
+
throw new DurableContentError(`${label} source kind is invalid`);
|
|
52
|
+
exactKeys(raw, SOURCE_KEYS[kind], `${label} source`);
|
|
53
|
+
if (kind === "url")
|
|
54
|
+
return { kind, url: requiredString(raw.url, `${label} URL`) };
|
|
55
|
+
if (kind === "base64")
|
|
56
|
+
return { kind, data: base64(raw.data, `${label} base64 data`) };
|
|
57
|
+
if (kind === "file_id") {
|
|
58
|
+
const id = requiredString(raw.id, `${label} file id`);
|
|
59
|
+
const a = object(raw.affinity, `${label} affinity`);
|
|
60
|
+
exactKeys(a, new Set(["provider_id", "endpoint_id"]), `${label} affinity`);
|
|
61
|
+
return {
|
|
62
|
+
kind,
|
|
63
|
+
id,
|
|
64
|
+
affinity: {
|
|
65
|
+
provider_id: requiredString(a.provider_id, `${label} affinity provider_id`),
|
|
66
|
+
endpoint_id: requiredString(a.endpoint_id, `${label} affinity endpoint_id`),
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
kind,
|
|
72
|
+
handle: requiredString(raw.handle, `${label} object handle`),
|
|
73
|
+
owner: requiredString(raw.owner, `${label} object owner`),
|
|
74
|
+
payload_ref: requiredString(raw.payload_ref, `${label} payload_ref`),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function block(value, index) {
|
|
78
|
+
const raw = object(value, `content block ${index}`);
|
|
79
|
+
const type = raw.type;
|
|
80
|
+
if (type === "text") {
|
|
81
|
+
exactKeys(raw, new Set(["type", "text"]), `content block ${index}`);
|
|
82
|
+
return { type, text: typeof raw.text === "string" ? raw.text : (() => { throw new DurableContentError(`content block ${index} text must be a string`); })() };
|
|
83
|
+
}
|
|
84
|
+
if (type === "tool_result")
|
|
85
|
+
throw new DurableContentError("nested tool_result blocks are forbidden");
|
|
86
|
+
if (type !== "image" && type !== "audio" && type !== "video" && type !== "file")
|
|
87
|
+
throw new DurableContentError(`unknown content block type: ${String(type)}`);
|
|
88
|
+
exactKeys(raw, new Set(["type", "source", "media_type", "provider_options"]), `content block ${index}`);
|
|
89
|
+
const mediaType = raw.media_type === undefined ? undefined : requiredString(raw.media_type, `content block ${index} media_type`);
|
|
90
|
+
let providerOptions;
|
|
91
|
+
if (raw.provider_options !== undefined)
|
|
92
|
+
providerOptions = object(raw.provider_options, `content block ${index} provider_options`);
|
|
93
|
+
return {
|
|
94
|
+
type,
|
|
95
|
+
source: source(raw.source, `content block ${index}`),
|
|
96
|
+
...(mediaType === undefined ? {} : { media_type: mediaType }),
|
|
97
|
+
...(providerOptions === undefined ? {} : { provider_options: providerOptions }),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function blocks(value) {
|
|
101
|
+
if (!Array.isArray(value))
|
|
102
|
+
throw new DurableContentError("content blocks must be an array");
|
|
103
|
+
return value.map(block);
|
|
104
|
+
}
|
|
105
|
+
export function decodeDurableContent(value) {
|
|
106
|
+
const raw = object(value, "durable content");
|
|
107
|
+
exactKeys(raw, CONTENT_KEYS, "durable content");
|
|
108
|
+
return { blocks: blocks(raw.blocks) };
|
|
109
|
+
}
|
|
110
|
+
export function decodeDurableToolResult(value) {
|
|
111
|
+
const raw = object(value, "durable tool result");
|
|
112
|
+
exactKeys(raw, TOOL_RESULT_KEYS, "durable tool result");
|
|
113
|
+
return { call_id: requiredString(raw.call_id, "tool result call_id"), is_error: requiredBoolean(raw.is_error, "tool result is_error"), blocks: blocks(raw.blocks) };
|
|
114
|
+
}
|
|
115
|
+
export function encodeDurableContent(content) {
|
|
116
|
+
const decoded = decodeDurableContent(content);
|
|
117
|
+
return { blocks: decoded.blocks };
|
|
118
|
+
}
|
|
119
|
+
export function encodeDurableToolResult(result) {
|
|
120
|
+
const decoded = decodeDurableToolResult(result);
|
|
121
|
+
return { call_id: decoded.call_id, is_error: decoded.is_error, blocks: decoded.blocks };
|
|
122
|
+
}
|
|
123
|
+
export function toolOutputBlocksToDurable(blocks) {
|
|
124
|
+
return blocks.map((part, index) => {
|
|
125
|
+
if (part.type === "text")
|
|
126
|
+
return { type: "text", text: part.text };
|
|
127
|
+
const source = part.source;
|
|
128
|
+
const durableSource = source.kind === "fileId"
|
|
129
|
+
? {
|
|
130
|
+
kind: "file_id",
|
|
131
|
+
id: source.id,
|
|
132
|
+
affinity: source.affinity
|
|
133
|
+
? { provider_id: source.affinity.providerId, endpoint_id: source.affinity.endpointId }
|
|
134
|
+
: (() => { throw new DurableContentError(`tool output block ${index} fileId source requires endpoint affinity`); })(),
|
|
135
|
+
}
|
|
136
|
+
: source.kind === "base64" ? { kind: "base64", data: source.data }
|
|
137
|
+
: source.kind === "url" ? { kind: "url", url: source.url }
|
|
138
|
+
: {
|
|
139
|
+
kind: "object",
|
|
140
|
+
handle: source.handle,
|
|
141
|
+
owner: source.owner ?? (() => { throw new DurableContentError(`tool output block ${index} object source requires owner`); })(),
|
|
142
|
+
payload_ref: source.payloadRef ?? (() => { throw new DurableContentError(`tool output block ${index} object source requires payloadRef`); })(),
|
|
143
|
+
};
|
|
144
|
+
return { type: part.type, source: durableSource, ...(part.mediaType ? { media_type: part.mediaType } : {}), ...(part.providerOptions ? { provider_options: part.providerOptions } : {}) };
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
export function durableBlocksToToolOutput(blocks) {
|
|
148
|
+
return blocks.map((part) => {
|
|
149
|
+
if (part.type === "text")
|
|
150
|
+
return part;
|
|
151
|
+
const source = part.source;
|
|
152
|
+
const sdkSource = source.kind === "file_id"
|
|
153
|
+
? { kind: "fileId", id: source.id, affinity: { providerId: source.affinity.provider_id, endpointId: source.affinity.endpoint_id } }
|
|
154
|
+
: source.kind === "base64" ? source
|
|
155
|
+
: source.kind === "url" ? source
|
|
156
|
+
: { kind: "object", handle: source.handle, owner: source.owner, payloadRef: source.payload_ref };
|
|
157
|
+
return { type: part.type, source: sdkSource, ...(part.media_type ? { mediaType: part.media_type } : {}), ...(part.provider_options ? { providerOptions: part.provider_options } : {}) };
|
|
158
|
+
});
|
|
159
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ToolCall, ToolSchema, StreamEvent, ToolSuspendEvent, PermissionRequestEvent, PermissionResponse } from "../types.js";
|
|
2
2
|
import type { RegisteredTool } from "../tools/index.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { MemoryStore, MemoryScope } from "../memory/protocols.js";
|
|
4
4
|
import type { KnowledgeSource } from "../knowledge/source.js";
|
|
5
5
|
import type { OperationContext } from "./reliability.js";
|
|
6
6
|
export interface RunContext {
|
|
@@ -9,7 +9,7 @@ export interface RunContext {
|
|
|
9
9
|
agentId?: string;
|
|
10
10
|
memoryScope?: MemoryScope;
|
|
11
11
|
skillDir?: string;
|
|
12
|
-
|
|
12
|
+
memoryStore?: MemoryStore;
|
|
13
13
|
knowledgeSource?: KnowledgeSource;
|
|
14
14
|
onToolSuspend?: (event: ToolSuspendEvent) => Promise<unknown> | unknown;
|
|
15
15
|
onPermissionRequest?: (event: PermissionRequestEvent) => Promise<PermissionResponse | boolean> | PermissionResponse | boolean;
|
|
@@ -29,8 +29,8 @@ export class LocalExecutionPlane {
|
|
|
29
29
|
for (const c of memoryCalls) {
|
|
30
30
|
const args = tryParseJson(c.arguments);
|
|
31
31
|
const topK = typeof args?.top_k === "number" ? args.top_k : 5;
|
|
32
|
-
const entries = (ctx.
|
|
33
|
-
? await ctx.
|
|
32
|
+
const entries = (ctx.memoryStore && ctx.agentId && ctx.memoryScope)
|
|
33
|
+
? await ctx.memoryStore.search(ctx.agentId, {
|
|
34
34
|
scope: ctx.memoryScope,
|
|
35
35
|
query: String(args?.query ?? ""),
|
|
36
36
|
top_k: topK,
|
|
@@ -91,7 +91,6 @@ export function kernelObservationToSessionEvent(obs, turn, opts = {}) {
|
|
|
91
91
|
kind: "entropy_sample",
|
|
92
92
|
turn: t,
|
|
93
93
|
score: obs.score ?? 0,
|
|
94
|
-
score_version: obs.score_version ?? 0,
|
|
95
94
|
rho: obs.rho ?? 0,
|
|
96
95
|
repeat_pressure: obs.repeat_pressure ?? 0,
|
|
97
96
|
failure_rate: obs.failure_rate ?? 0,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const CANONICAL_CONTENT_PARTS_PREFIX = "[[deepstrike-content-parts
|
|
1
|
+
const CANONICAL_CONTENT_PARTS_PREFIX = "[[deepstrike-content-parts]]";
|
|
2
2
|
export function encodeCanonicalContentParts(parts) {
|
|
3
3
|
return `${CANONICAL_CONTENT_PARTS_PREFIX}${Buffer.from(JSON.stringify(parts)).toString("base64url")}`;
|
|
4
4
|
}
|
|
@@ -43,6 +43,9 @@ export function skillMetadataToKernel(skill) {
|
|
|
43
43
|
// P1-B: forward declared tool ids (additive; omitted when empty so existing skills' wire is unchanged).
|
|
44
44
|
if (skill.allowedTools?.length)
|
|
45
45
|
out.allowed_tools = skill.allowedTools;
|
|
46
|
+
// SPC-015-01: structured grants are caller-supplied rather than inferred from scalar frontmatter.
|
|
47
|
+
if (skill.capabilityGrants?.length)
|
|
48
|
+
out.capability_grants = skill.capabilityGrants;
|
|
46
49
|
return out;
|
|
47
50
|
}
|
|
48
51
|
export function messageToKernelMessage(message) {
|
|
@@ -153,7 +156,6 @@ export function entropySampleFromObservation(obs) {
|
|
|
153
156
|
return {
|
|
154
157
|
turn: obs.turn ?? 0,
|
|
155
158
|
score: obs.score ?? 0,
|
|
156
|
-
scoreVersion: obs.score_version ?? 0,
|
|
157
159
|
rho: obs.rho ?? 0,
|
|
158
160
|
repeatPressure: obs.repeat_pressure ?? 0,
|
|
159
161
|
failureRate: obs.failure_rate ?? 0,
|
|
@@ -1,7 +1,31 @@
|
|
|
1
|
-
import type { ToolCall, ToolSchema, StreamEvent } from "../types.js";
|
|
1
|
+
import type { ToolCall, ToolSchema, StreamEvent, ToolOutputBlock } from "../types.js";
|
|
2
2
|
import type { RegisteredTool } from "../tools/index.js";
|
|
3
3
|
import type { ExecutionPlane, RunContext } from "./execution-plane.js";
|
|
4
4
|
import type { CredentialVault } from "./credential-vault.js";
|
|
5
|
+
/** Raw MCP `tools/call` response `content` block shapes we accept (text/image/audio). */
|
|
6
|
+
export interface McpContentBlock {
|
|
7
|
+
type: string;
|
|
8
|
+
text?: string;
|
|
9
|
+
data?: string;
|
|
10
|
+
mimeType?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* spc_012-N-02: pure conversion, unit-testable without spawning a subprocess. Prior behavior
|
|
14
|
+
* silently dropped every non-`"text"` block (INV-012-01 violation — an MCP tool returning a
|
|
15
|
+
* screenshot lost the image with no trace). `output` stays the text projection for backward
|
|
16
|
+
* available as the text projection — when non-text blocks exist the projection
|
|
17
|
+
* carries an explicit `[modality]` placeholder, so text-only providers (spc_012-N-04) degrade visibly instead
|
|
18
|
+
* of swallowing the block. `contentParts` is populated (and only populated) when the response
|
|
19
|
+
* actually contains a non-text block, so pure-text tool calls see zero behavior change.
|
|
20
|
+
*/
|
|
21
|
+
export declare function mcpResultToToolOutput(result: {
|
|
22
|
+
content?: McpContentBlock[];
|
|
23
|
+
isError?: boolean;
|
|
24
|
+
}): {
|
|
25
|
+
output: string;
|
|
26
|
+
isError: boolean;
|
|
27
|
+
contentParts?: ToolOutputBlock[];
|
|
28
|
+
};
|
|
5
29
|
export interface McpServerConfig {
|
|
6
30
|
/** Executable to run (e.g. "npx", "python3", "/usr/local/bin/my-mcp-server"). */
|
|
7
31
|
command: string;
|
|
@@ -3,6 +3,41 @@ import { createInterface } from "node:readline";
|
|
|
3
3
|
import { LocalExecutionPlane } from "./execution-plane.js";
|
|
4
4
|
import { formatToolError } from "../tools/errors.js";
|
|
5
5
|
import { operationAbortSignal } from "./reliability.js";
|
|
6
|
+
/**
|
|
7
|
+
* spc_012-N-02: pure conversion, unit-testable without spawning a subprocess. Prior behavior
|
|
8
|
+
* silently dropped every non-`"text"` block (INV-012-01 violation — an MCP tool returning a
|
|
9
|
+
* screenshot lost the image with no trace). `output` stays the text projection for backward
|
|
10
|
+
* available as the text projection — when non-text blocks exist the projection
|
|
11
|
+
* carries an explicit `[modality]` placeholder, so text-only providers (spc_012-N-04) degrade visibly instead
|
|
12
|
+
* of swallowing the block. `contentParts` is populated (and only populated) when the response
|
|
13
|
+
* actually contains a non-text block, so pure-text tool calls see zero behavior change.
|
|
14
|
+
*/
|
|
15
|
+
export function mcpResultToToolOutput(result) {
|
|
16
|
+
const blocks = result.content ?? [];
|
|
17
|
+
const hasNonText = blocks.some(c => c.type !== "text");
|
|
18
|
+
if (!hasNonText) {
|
|
19
|
+
const text = blocks
|
|
20
|
+
.filter(c => c.type === "text")
|
|
21
|
+
.map(c => c.text ?? "")
|
|
22
|
+
.join("\n");
|
|
23
|
+
return { output: text || JSON.stringify(result), isError: result.isError ?? false };
|
|
24
|
+
}
|
|
25
|
+
const output = blocks
|
|
26
|
+
.map(c => (c.type === "text" ? c.text ?? "" : `[${c.type}]`))
|
|
27
|
+
.join("\n");
|
|
28
|
+
const contentParts = blocks.map(c => {
|
|
29
|
+
if (c.type === "text")
|
|
30
|
+
return { type: "text", text: c.text ?? "" };
|
|
31
|
+
if (c.type === "image") {
|
|
32
|
+
return { type: "image", source: { kind: "base64", data: c.data ?? "" }, mediaType: c.mimeType };
|
|
33
|
+
}
|
|
34
|
+
if (c.type === "audio") {
|
|
35
|
+
return { type: "audio", source: { kind: "base64", data: c.data ?? "" }, mediaType: c.mimeType ?? "audio/wav" };
|
|
36
|
+
}
|
|
37
|
+
return { type: "text", text: JSON.stringify(c) };
|
|
38
|
+
});
|
|
39
|
+
return { output, isError: result.isError ?? false, contentParts };
|
|
40
|
+
}
|
|
6
41
|
class McpConnection {
|
|
7
42
|
serverName;
|
|
8
43
|
config;
|
|
@@ -106,11 +141,7 @@ class McpConnection {
|
|
|
106
141
|
try {
|
|
107
142
|
const args = JSON.parse(call.arguments || "{}");
|
|
108
143
|
const result = await this.request("tools/call", { name: call.name, arguments: args }, signal);
|
|
109
|
-
|
|
110
|
-
.filter(c => c.type === "text")
|
|
111
|
-
.map(c => c.text ?? "")
|
|
112
|
-
.join("\n");
|
|
113
|
-
return { output: text || JSON.stringify(result), isError: result.isError ?? false };
|
|
144
|
+
return mcpResultToToolOutput(result);
|
|
114
145
|
}
|
|
115
146
|
catch (err) {
|
|
116
147
|
return { output: formatToolError(err), isError: true };
|
|
@@ -215,7 +246,14 @@ export class McpProxyPlane {
|
|
|
215
246
|
});
|
|
216
247
|
for (const settled of await Promise.all(tasks)) {
|
|
217
248
|
for (const { call, result } of settled) {
|
|
218
|
-
yield {
|
|
249
|
+
yield {
|
|
250
|
+
type: "tool_result",
|
|
251
|
+
callId: call.id,
|
|
252
|
+
name: call.name,
|
|
253
|
+
content: result.output,
|
|
254
|
+
isError: result.isError,
|
|
255
|
+
contentParts: result.contentParts,
|
|
256
|
+
};
|
|
219
257
|
}
|
|
220
258
|
}
|
|
221
259
|
}
|
|
@@ -2,7 +2,7 @@ export interface SchemaValidation {
|
|
|
2
2
|
ok: boolean;
|
|
3
3
|
errors: string[];
|
|
4
4
|
}
|
|
5
|
-
type JsonSchema = Record<string, unknown>;
|
|
5
|
+
export type JsonSchema = Record<string, unknown>;
|
|
6
6
|
/** Validate `value` against `schema` (the supported subset). `path` is for error messages. */
|
|
7
7
|
export declare function validateAgainstSchema(value: unknown, schema: JsonSchema, path?: string): SchemaValidation;
|
|
8
8
|
/** The instruction appended to a node's goal so its agent produces schema-conforming JSON. */
|
|
@@ -11,4 +11,3 @@ export declare function schemaInstruction(schema: JsonSchema): string;
|
|
|
11
11
|
export declare function schemaRetryInstruction(schema: JsonSchema, errors: string[]): string;
|
|
12
12
|
/** Best-effort extraction of a JSON value from agent output (raw, fenced, or embedded). */
|
|
13
13
|
export declare function extractJsonValue(text: string): unknown;
|
|
14
|
-
export {};
|
|
@@ -7,7 +7,7 @@ export declare function assistantReplayKey(message: Pick<Message, "content" | "t
|
|
|
7
7
|
* incompatible envelope is skipped so B re-serializes neutral context instead
|
|
8
8
|
* of replaying A's protocol-specific shape.
|
|
9
9
|
*/
|
|
10
|
-
export declare function isReplayCompatibleWithProvider(replay: ProviderReplay
|
|
10
|
+
export declare function isReplayCompatibleWithProvider(replay: Partial<ProviderReplay>, descriptor: ProviderDescriptor | undefined): boolean;
|
|
11
11
|
export declare function seedProviderReplayFromEvents(provider: LLMProvider, events: Array<{
|
|
12
12
|
event: SessionEvent;
|
|
13
13
|
}>): void;
|
|
@@ -33,22 +33,6 @@ export function assistantReplayKey(message) {
|
|
|
33
33
|
toolCalls,
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
|
-
/**
|
|
37
|
-
* Infer the wire protocol a stored replay envelope belongs to.
|
|
38
|
-
*
|
|
39
|
-
* New envelopes carry an explicit `protocol`. Legacy envelopes are inferred
|
|
40
|
-
* from their shape: Anthropic persisted `native_blocks`, OpenAI-compatible
|
|
41
|
-
* persisted `reasoning_content` / `reasoning_details`.
|
|
42
|
-
*/
|
|
43
|
-
function replayProtocol(replay) {
|
|
44
|
-
if (replay.protocol)
|
|
45
|
-
return replay.protocol;
|
|
46
|
-
if (replay.native_blocks?.length)
|
|
47
|
-
return "anthropic-messages";
|
|
48
|
-
if (replay.reasoning_content != null || replay.reasoning_details !== undefined)
|
|
49
|
-
return "openai-chat";
|
|
50
|
-
return undefined;
|
|
51
|
-
}
|
|
52
36
|
/**
|
|
53
37
|
* A stored replay may only be seeded into a provider speaking the same wire
|
|
54
38
|
* protocol. On a cross-protocol fallback (provider A -> provider B) the
|
|
@@ -56,12 +40,16 @@ function replayProtocol(replay) {
|
|
|
56
40
|
* of replaying A's protocol-specific shape.
|
|
57
41
|
*/
|
|
58
42
|
export function isReplayCompatibleWithProvider(replay, descriptor) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
43
|
+
assertCanonicalReplay(replay);
|
|
44
|
+
return !descriptor || replay.protocol === descriptor.protocol;
|
|
45
|
+
}
|
|
46
|
+
const REPLAY_KEYS = new Set(["protocol", "provider", "model", "native_blocks", "reasoning_content", "reasoning_details", "native_message", "tool_calls"]);
|
|
47
|
+
function assertCanonicalReplay(replay) {
|
|
48
|
+
for (const key of Object.keys(replay))
|
|
49
|
+
if (!REPLAY_KEYS.has(key))
|
|
50
|
+
throw new Error(`provider replay has unknown field ${key}`);
|
|
51
|
+
if (typeof replay.protocol !== "string" || replay.protocol.length === 0)
|
|
52
|
+
throw new Error("provider replay protocol is required");
|
|
65
53
|
}
|
|
66
54
|
export function seedProviderReplayFromEvents(provider, events) {
|
|
67
55
|
if (!provider.seedProviderReplay)
|
|
@@ -72,12 +60,9 @@ export function seedProviderReplayFromEvents(provider, events) {
|
|
|
72
60
|
continue;
|
|
73
61
|
const toolCalls = event.tool_calls ?? [];
|
|
74
62
|
const stored = event.provider_replay;
|
|
75
|
-
if (stored
|
|
63
|
+
if (!stored || !isReplayCompatibleWithProvider(stored, descriptor))
|
|
76
64
|
continue;
|
|
77
|
-
|
|
78
|
-
// reconstruct a legacy replay (e.g. Anthropic native_blocks) from the
|
|
79
|
-
// neutral transcript. Providers that cannot reconstruct simply no-op.
|
|
80
|
-
provider.seedProviderReplay({ content: event.content, toolCalls }, stored ?? {});
|
|
65
|
+
provider.seedProviderReplay({ content: event.content, toolCalls }, stored);
|
|
81
66
|
}
|
|
82
67
|
}
|
|
83
68
|
export function peekProviderReplay(provider, content, toolCalls) {
|
|
@@ -121,7 +121,7 @@ export declare class ReactiveSession {
|
|
|
121
121
|
* blackboard continuity comes from the (persistent) `EventStream`. Turn-policy cursor state is not
|
|
122
122
|
* restored. W-N5: vehicle members (workflow envelopes, `wf-node*` children, loop iterations) share
|
|
123
123
|
* the governance domain but are NOT personas — resuming them as peers would resurrect phantoms.
|
|
124
|
-
*
|
|
124
|
+
* Only explicitly tagged peer memberships are resumable.
|
|
125
125
|
*/
|
|
126
126
|
static resume(opts: ReactiveSessionOptions & {
|
|
127
127
|
peerSpecs?: Record<string, ReactivePeerSpec>;
|
|
@@ -135,14 +135,13 @@ export class ReactiveSession {
|
|
|
135
135
|
* blackboard continuity comes from the (persistent) `EventStream`. Turn-policy cursor state is not
|
|
136
136
|
* restored. W-N5: vehicle members (workflow envelopes, `wf-node*` children, loop iterations) share
|
|
137
137
|
* the governance domain but are NOT personas — resuming them as peers would resurrect phantoms.
|
|
138
|
-
*
|
|
138
|
+
* Only explicitly tagged peer memberships are resumable.
|
|
139
139
|
*/
|
|
140
140
|
static async resume(opts) {
|
|
141
141
|
const session = new ReactiveSession(opts);
|
|
142
142
|
const members = await opts.runGroup.budgetStore.members(opts.runGroup.id);
|
|
143
|
-
const anyTagged = members.some(m => m.kind !== undefined);
|
|
144
143
|
for (const member of members) {
|
|
145
|
-
if (
|
|
144
|
+
if (member.kind !== "peer")
|
|
146
145
|
continue;
|
|
147
146
|
session.peerSpecs.set(member.sessionId, opts.peerSpecs?.[member.sessionId] ?? { role: member.role });
|
|
148
147
|
}
|
|
@@ -34,7 +34,7 @@ export interface GroupMember {
|
|
|
34
34
|
/** W-N5: what this member IS in the lineage — a `"peer"` persona (ReactiveSession.addPeer) vs a
|
|
35
35
|
* `"vehicle"` session (run()/runWorkflow envelopes, workflow-node children, loop iterations).
|
|
36
36
|
* `ReactiveSession.resume()` rebuilds the peer set from `"peer"` members only, so DAG-in-Peer
|
|
37
|
-
* usage can't resurrect phantom `wf-node*` personas. Absent
|
|
37
|
+
* usage can't resurrect phantom `wf-node*` personas. Absent means unknown. */
|
|
38
38
|
kind?: "peer" | "vehicle";
|
|
39
39
|
}
|
|
40
40
|
export interface GroupBudgetStore {
|
package/dist/runtime/runner.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { LLMProvider, Message, ContentPart, ToolSchema, StreamEvent, ToolSuspendEvent, PermissionRequestEvent, PermissionResponse, AsyncSummarizer,
|
|
2
|
-
import type {
|
|
1
|
+
import type { LLMProvider, Message, ContentPart, ToolSchema, StreamEvent, ToolSuspendEvent, PermissionRequestEvent, PermissionResponse, AsyncSummarizer, MemorySummarizer, EntropySample, EntropyWatchOptions } from "../types.js";
|
|
2
|
+
import type { MemoryStore, MemoryRecord, MemoryRecall, MemoryScope, MemoryQuery } from "../memory/protocols.js";
|
|
3
3
|
import type { KnowledgeSource } from "../knowledge/source.js";
|
|
4
4
|
import type { RuntimeSignalUrgency, SignalSource } from "../signals/types.js";
|
|
5
5
|
import type { SessionLog, SessionEvent } from "./session-log.js";
|
|
@@ -15,15 +15,18 @@ import { type GovernancePolicy } from "../governance.js";
|
|
|
15
15
|
import { type NativeOsProfile, type OsProfileId, type SignalPolicy } from "./os-profile.js";
|
|
16
16
|
import { PayloadStore } from "./payload-store.js";
|
|
17
17
|
import type { BackgroundTaskErrorHandler } from "./reliability.js";
|
|
18
|
-
import { type
|
|
18
|
+
import { type ContextPolicyOverrides } from "./context-policy.js";
|
|
19
19
|
import { type InstructionProfile } from "../harness/manifest.js";
|
|
20
20
|
import { type NudgeRule } from "../harness/nudge.js";
|
|
21
21
|
export interface SchedulerPolicy {
|
|
22
|
-
version: 1;
|
|
23
22
|
criticalPathWeight: number;
|
|
24
23
|
fanoutWeight: number;
|
|
25
24
|
ageWeight: number;
|
|
26
25
|
tokenCostWeight: number;
|
|
26
|
+
deadlineWeight?: number;
|
|
27
|
+
processPriorityWeight?: number;
|
|
28
|
+
resourcePressureWeight?: number;
|
|
29
|
+
budgetPressureWeight?: number;
|
|
27
30
|
}
|
|
28
31
|
export declare function schedulerPolicyToKernel(policy: SchedulerPolicy): Record<string, number>;
|
|
29
32
|
/** Host-counted provider envelope and response reserves deducted from the model context window. */
|
|
@@ -117,10 +120,10 @@ export interface RuntimeOptions {
|
|
|
117
120
|
memoryScope?: MemoryScope;
|
|
118
121
|
/** I4: optional run-start memory pre-fetch hook. The runner calls this ONCE per run, before the
|
|
119
122
|
* first LLM turn, with the request's goal and (optional) run-spec. Each returned scoped query
|
|
120
|
-
* becomes a `
|
|
123
|
+
* becomes a `memoryStore.search(agentId, query)` and the resulting hits land in decaying
|
|
121
124
|
* HISTORY as an ordinary user turn before turn 1 (single-use retrieval content — never a
|
|
122
125
|
* permanent knowledge pin; `initialMemory` is the curated CLAUDE.md-analog seed). Returning
|
|
123
|
-
* `undefined` / empty array is a no-op. Requires `
|
|
126
|
+
* `undefined` / empty array is a no-op. Requires `memoryStore` + `agentId`; missing either ⇒
|
|
124
127
|
* silently skipped (errs-open). Default when unset: one query = the run goal (P10). Bench memory-recall shows -57% turns / -55% dollars when
|
|
125
128
|
* relevant memories land on turn 1 instead of being discovered via the meta-tool on turn 3+. */
|
|
126
129
|
preQueryMemory?: (ctx: {
|
|
@@ -150,7 +153,7 @@ export interface RuntimeOptions {
|
|
|
150
153
|
* scanned skills fed); empty array ⇒ no skills (a legitimate narrowing — unlike an empty
|
|
151
154
|
* `allowedToolIds`, which the runner reads as "no gating"). Only takes effect when `skillDir` is set. */
|
|
152
155
|
skillFilter?: string[];
|
|
153
|
-
|
|
156
|
+
memoryStore?: MemoryStore;
|
|
154
157
|
/** M4: advisory callback when a recalled record crosses the promotion threshold. The host/model
|
|
155
158
|
* decides whether to pin the record or promote its content into knowledge. */
|
|
156
159
|
onPromotionSuggested?: (info: {
|
|
@@ -168,13 +171,13 @@ export interface RuntimeOptions {
|
|
|
168
171
|
* AskUser calls surface as `tool_gated` and run through `onPermissionRequest`.
|
|
169
172
|
*/
|
|
170
173
|
governancePolicy?: GovernancePolicy;
|
|
171
|
-
/**
|
|
174
|
+
/** In-kernel signal admission, queue, and expiry policy. */
|
|
172
175
|
signalPolicy?: SignalPolicy;
|
|
173
176
|
/** Provider-envelope overhead plus output and safety reserves journaled before start. */
|
|
174
177
|
promptBudget?: PromptBudget;
|
|
175
178
|
/** Stable replayable context behavior; SDK ratios are normalized to integer ppm on the ABI wire. */
|
|
176
|
-
contextPolicy?:
|
|
177
|
-
/**
|
|
179
|
+
contextPolicy?: ContextPolicyOverrides;
|
|
180
|
+
/** Deterministic DAG scheduling policy installed atomically through ConfigureRun. */
|
|
178
181
|
schedulerPolicy?: SchedulerPolicy;
|
|
179
182
|
/**
|
|
180
183
|
* Optional declarative resource quotas (`set_resource_quota`). Bounds spawn concurrency /
|
|
@@ -231,15 +234,13 @@ export interface RuntimeOptions {
|
|
|
231
234
|
* executes. Return `{ block: true, reason }` to veto — the call never runs and the reason is fed
|
|
232
235
|
* back to the model as a denied tool result. This is the seam for STATEFUL host policy (count
|
|
233
236
|
* repeats, budget writes per resource, project-specific rules); keep static allow/deny in
|
|
234
|
-
* `governancePolicy`. A throwing decision hook fails closed
|
|
237
|
+
* `governancePolicy`. A throwing decision hook always fails closed.
|
|
235
238
|
*/
|
|
236
239
|
onToolCall?: (call: {
|
|
237
240
|
callId: string;
|
|
238
241
|
name: string;
|
|
239
242
|
arguments: string;
|
|
240
243
|
}) => Promise<ToolCallHookDecision | undefined | void> | ToolCallHookDecision | undefined | void;
|
|
241
|
-
/** Failure policy for `onToolCall`. Default `closed`; set `open` only for advisory hooks. */
|
|
242
|
-
onToolCallFailure?: "closed" | "open";
|
|
243
244
|
/**
|
|
244
245
|
* O5 (the PostToolUse-hook analog): called for each executed tool result before it reaches the
|
|
245
246
|
* kernel. Return `{ replaceOutput }` to swap the result the model sees (redact / annotate), and/or
|
|
@@ -271,7 +272,7 @@ export interface RuntimeOptions {
|
|
|
271
272
|
*/
|
|
272
273
|
nestedGroupVehicle?: boolean;
|
|
273
274
|
/**
|
|
274
|
-
* Optional canonical long-term memory policy. Enabling memory still requires `
|
|
275
|
+
* Optional canonical long-term memory policy. Enabling memory still requires `memoryStore` +
|
|
275
276
|
* `agentId`; storage location is configured on that host store, not in the kernel contract.
|
|
276
277
|
*/
|
|
277
278
|
memoryPolicy?: MemoryPolicy;
|
|
@@ -310,8 +311,7 @@ export interface RuntimeOptions {
|
|
|
310
311
|
* synthesizes a minimal run spec. Omitted **or empty** ⇒ no ceiling (all registered tools) — the
|
|
311
312
|
* empty array is NOT a minimal surface here; use `baselineToolIds: []` for that.
|
|
312
313
|
*
|
|
313
|
-
*
|
|
314
|
-
* tool outside the advertised set never executes.
|
|
314
|
+
* Dispatch is always fail-closed: a call outside the advertised set never executes.
|
|
315
315
|
*/
|
|
316
316
|
allowedToolIds?: string[];
|
|
317
317
|
/**
|
|
@@ -322,27 +322,13 @@ export interface RuntimeOptions {
|
|
|
322
322
|
*
|
|
323
323
|
* `exposed = meta ∪ ((baseline ∪ stableCore ∪ ⋃ activeSkills.allowed_tools) ∩ ceiling)`
|
|
324
324
|
*
|
|
325
|
-
* An active skill that declares no `allowed_tools` contributes nothing
|
|
326
|
-
* surface stays narrow (strict; the legacy errs-open widening is deliberately not inherited).
|
|
325
|
+
* An active skill that declares no `allowed_tools` contributes nothing and the surface stays narrow.
|
|
327
326
|
*
|
|
328
|
-
* `undefined`
|
|
329
|
-
* legitimate, distinct value: the minimal surface (meta-tools + `stableCoreToolIds` only) — the
|
|
327
|
+
* `undefined` and `[]` both mean the minimal surface (meta-tools + `stableCoreToolIds` only) — the
|
|
330
328
|
* `allowedToolIds` "empty means no gating" trap does NOT recur here. Entries outside the ceiling
|
|
331
329
|
* silently intersect away (no root-start error), the same fold every id-list surface uses.
|
|
332
330
|
*/
|
|
333
331
|
baselineToolIds?: string[];
|
|
334
|
-
/**
|
|
335
|
-
* Dispatch enforcement for the exposure surface. `"exposed"` (default) is fail-closed: a tool call
|
|
336
|
-
* the model was never advertised this turn never reaches the host — the kernel commits a
|
|
337
|
-
* model-visible `governance_denied` result instead ("Tool 'X' is not part of this run's toolset"),
|
|
338
|
-
* which feeds the repeat fuse like any other denial. Allowed siblings in the same batch still
|
|
339
|
-
* execute; `pace` and the meta-tool family always pass through.
|
|
340
|
-
*
|
|
341
|
-
* `"registered"` is the escape hatch restoring the pre-gate permissive behavior (any registered
|
|
342
|
-
* tool the model names executes, even if it was gated out of the tools schema). Set it only when a
|
|
343
|
-
* host deliberately relies on blind calls to unadvertised tools.
|
|
344
|
-
*/
|
|
345
|
-
toolDispatchGate?: "exposed" | "registered";
|
|
346
332
|
/** P0-C: optional per-turn metrics sink for tool-gating telemetry (see `TurnMetrics`). Pure
|
|
347
333
|
* observation; invoked once per LLM turn. Never throws into the run loop (errors are swallowed). */
|
|
348
334
|
onTurnMetrics?: (metrics: TurnMetrics) => void;
|
|
@@ -366,15 +352,15 @@ export interface RuntimeOptions {
|
|
|
366
352
|
/** G2: custom reducers for `NodeKind::Reduce` workflow nodes, merged over the built-ins
|
|
367
353
|
* (`concat` / `dedupe_lines` / `merge_json_arrays` / `count`). A reduce node runs no LLM. */
|
|
368
354
|
reducers?: ReducerRegistry;
|
|
369
|
-
/** Optional system prompt injected into
|
|
370
|
-
|
|
371
|
-
/** Custom LLM provider used for
|
|
372
|
-
|
|
355
|
+
/** Optional system prompt injected into durable-memory synthesis. */
|
|
356
|
+
memorySystemPrompt?: string;
|
|
357
|
+
/** Custom LLM provider used for durable-memory consolidation. */
|
|
358
|
+
memoryProvider?: LLMProvider;
|
|
373
359
|
/**
|
|
374
|
-
* Optional LLM summarizer for semantic page_out events. When unset, `
|
|
375
|
-
* (or the runtime provider) is used to produce long-term summaries for
|
|
360
|
+
* Optional LLM summarizer for semantic page_out events. When unset, `memoryProvider`
|
|
361
|
+
* (or the runtime provider) is used to produce long-term summaries for MemoryStore.
|
|
376
362
|
*/
|
|
377
|
-
|
|
363
|
+
memorySummarizer?: MemorySummarizer;
|
|
378
364
|
/**
|
|
379
365
|
* Optional async LLM summarizer. When provided, a background call is fired
|
|
380
366
|
* after each compression event to produce a richer semantic summary.
|
|
@@ -429,7 +415,7 @@ export declare class RuntimeRunner {
|
|
|
429
415
|
private retrieveMemoryFromStore;
|
|
430
416
|
/**
|
|
431
417
|
* Route a host-originated renewal prefetch into canonical knowledge commands. This is not an
|
|
432
|
-
* agent syscall: the host selects records from its store, then the kernel owns the
|
|
418
|
+
* agent syscall: the host selects records from its store, then the kernel owns the write
|
|
433
419
|
* of live semantic context. `seenRecordIds` is the prefetch's dedupe horizon.
|
|
434
420
|
*/
|
|
435
421
|
private prefetchMemoryIntoKnowledge;
|