@deepstrike/wasm 0.2.35 → 0.2.37
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/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/runtime/facade.js +11 -7
- package/dist/runtime/kernel-event-log.d.ts +0 -6
- package/dist/runtime/kernel-event-log.js +38 -62
- package/dist/runtime/kernel-step.d.ts +9 -0
- package/dist/runtime/kernel-step.js +12 -0
- package/dist/runtime/large-result-spool.d.ts +7 -0
- package/dist/runtime/large-result-spool.js +25 -0
- package/dist/runtime/os-snapshot.d.ts +0 -1
- package/dist/runtime/os-snapshot.js +0 -19
- package/dist/runtime/runner.d.ts +103 -8
- package/dist/runtime/runner.js +415 -100
- package/dist/runtime/session-log.d.ts +15 -54
- package/dist/runtime/session-repair.d.ts +29 -6
- package/dist/runtime/session-repair.js +37 -8
- package/dist/runtime/sub-agent-orchestrator.d.ts +7 -0
- package/dist/runtime/sub-agent-orchestrator.js +39 -4
- package/dist/runtime/types/agent.d.ts +46 -2
- package/dist/runtime/types/agent.js +54 -1
- package/dist/runtime/workflow-control-flow.d.ts +10 -2
- package/dist/runtime/workflow-control-flow.js +27 -6
- package/dist/types.d.ts +2 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export { FilteredExecutionPlane } from "./runtime/filtered-plane.js";
|
|
|
5
5
|
export { SubAgentOrchestrator, defaultSubAgentOrchestrator, spawnStandalone } from "./runtime/sub-agent-orchestrator.js";
|
|
6
6
|
export type { SubAgentRunContext } from "./runtime/sub-agent-orchestrator.js";
|
|
7
7
|
export type { AgentCapabilityFilter, AgentIdentity, AgentIsolation, AgentRunSpec, AgentProcessChangedObservation, ContextInheritance, KernelAgentRole, LoopResult, MilestoneCheckResult, MilestoneContract, MilestonePhase, MilestonePolicy, SubAgentResult, TerminationReason, WorkflowSpec, WorkflowNodeSpec, WorkflowTaskSpec, WorkflowSpawnInfo, } from "./runtime/types/agent.js";
|
|
8
|
-
export { workflowSpecToKernel, workflowNodeSpecToKernel, submitWorkflowNodesToKernel, submitWorkflowToKernel, submitWorkflowNodesTool, startWorkflowTool, fanoutSynthesize, generateAndFilter, verifyRules } from "./runtime/types/agent.js";
|
|
8
|
+
export { workflowSpecToKernel, workflowNodeSpecToKernel, submitWorkflowNodesToKernel, submitWorkflowToKernel, submitWorkflowNodesTool, startWorkflowTool, fanoutSynthesize, generateAndFilter, genEval, verifyRules } from "./runtime/types/agent.js";
|
|
9
9
|
export { loopInstruction, classifyInstruction, judgeGoal, extractLoopContinue, extractClassifyBranch, extractJudgeWinner, } from "./runtime/workflow-control-flow.js";
|
|
10
10
|
export { Governance } from "./governance.js";
|
|
11
11
|
export type { GovernanceVerdict } from "./governance.js";
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { RuntimeRunner, collectText, runAgent, runFanout, InMemorySessionLog, LocalExecutionPlane, DEFAULT_NATIVE_ATTENTION_POLICY, DEFAULT_NATIVE_GOVERNANCE_POLICY, DEFAULT_SANDBOX_POLICY, assertNativeProfile, osProfile, validateDeclarativePolicy, ReplayProvider, extractRecordedMessages, judge, buildEvalMessages, parseVerdict, verdictOutputSchema, } from "./runtime/index.js";
|
|
2
2
|
export { FilteredExecutionPlane } from "./runtime/filtered-plane.js";
|
|
3
3
|
export { SubAgentOrchestrator, defaultSubAgentOrchestrator, spawnStandalone } from "./runtime/sub-agent-orchestrator.js";
|
|
4
|
-
export { workflowSpecToKernel, workflowNodeSpecToKernel, submitWorkflowNodesToKernel, submitWorkflowToKernel, submitWorkflowNodesTool, startWorkflowTool, fanoutSynthesize, generateAndFilter, verifyRules } from "./runtime/types/agent.js";
|
|
4
|
+
export { workflowSpecToKernel, workflowNodeSpecToKernel, submitWorkflowNodesToKernel, submitWorkflowToKernel, submitWorkflowNodesTool, startWorkflowTool, fanoutSynthesize, generateAndFilter, genEval, verifyRules } from "./runtime/types/agent.js";
|
|
5
5
|
export { loopInstruction, classifyInstruction, judgeGoal, extractLoopContinue, extractClassifyBranch, extractJudgeWinner, } from "./runtime/workflow-control-flow.js";
|
|
6
6
|
export { Governance } from "./governance.js";
|
|
7
7
|
export { AnthropicProvider } from "./providers/anthropic.js";
|
package/dist/runtime/facade.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { RuntimeRunner, collectText } from "./runner.js";
|
|
4
4
|
import { LocalExecutionPlane } from "./execution-plane.js";
|
|
5
5
|
import { InMemorySessionLog } from "./session-log.js";
|
|
6
|
+
import { fanoutSynthesize } from "./types/agent.js";
|
|
6
7
|
/** Run a single agent to completion and return its final text. */
|
|
7
8
|
export async function runAgent(opts) {
|
|
8
9
|
const plane = opts.executionPlane ??
|
|
@@ -26,13 +27,16 @@ export async function runFanout(opts) {
|
|
|
26
27
|
maxTokens: opts.maxTokens ?? 32_000,
|
|
27
28
|
...(opts.maxTurns !== undefined ? { maxTurns: opts.maxTurns } : {}),
|
|
28
29
|
});
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
// W-N8: build the spec via the ONE fanout template (it pins the pattern's isolation /
|
|
31
|
+
// context-inheritance choices — read-only system-only workers, full-context synthesizer — which
|
|
32
|
+
// this facade used to silently drop), then apply the caller's role overrides on top.
|
|
33
|
+
const spec = fanoutSynthesize(opts.tasks, opts.synthesize);
|
|
34
|
+
if (opts.workerRole) {
|
|
35
|
+
for (const node of spec.nodes.slice(0, opts.tasks.length))
|
|
36
|
+
node.role = opts.workerRole;
|
|
37
|
+
}
|
|
38
|
+
if (opts.synthesisRole)
|
|
39
|
+
spec.nodes[spec.nodes.length - 1].role = opts.synthesisRole;
|
|
36
40
|
const outcome = await runner.runWorkflow(spec, opts.sessionId ? { sessionId: opts.sessionId } : undefined);
|
|
37
41
|
const synthesisId = `wf-node${opts.tasks.length}`;
|
|
38
42
|
const lastCompleted = outcome.completed[outcome.completed.length - 1];
|
|
@@ -3,12 +3,6 @@ import type { SessionEvent } from "./session-log.js";
|
|
|
3
3
|
/** Agent OS kernel event category (Phase 5). */
|
|
4
4
|
export type KernelEventCategory = "syscall" | "sched" | "mm" | "proc" | "ipc";
|
|
5
5
|
export declare function categoryForKind(kind: string): KernelEventCategory;
|
|
6
|
-
export declare function withCategory<T extends {
|
|
7
|
-
kind: string;
|
|
8
|
-
}>(event: T): T & {
|
|
9
|
-
category: KernelEventCategory;
|
|
10
|
-
primitive: KernelPrimitive;
|
|
11
|
-
};
|
|
12
6
|
type CompressionAction = Extract<SessionEvent, {
|
|
13
7
|
kind: "compressed";
|
|
14
8
|
}>["action"];
|
|
@@ -22,33 +22,16 @@ export function categoryForKind(kind) {
|
|
|
22
22
|
return "sched";
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
export function withCategory(event) {
|
|
26
|
-
const category = categoryForKind(event.kind);
|
|
27
|
-
return {
|
|
28
|
-
...event,
|
|
29
|
-
category,
|
|
30
|
-
primitive: primitiveForCategory(category),
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
25
|
export function kernelObservationToSessionEvent(obs, turn, opts = {}) {
|
|
34
26
|
const t = obs.turn ?? turn;
|
|
35
27
|
const compressionAction = opts.compressionAction ?? (() => undefined);
|
|
36
28
|
switch (obs.kind) {
|
|
37
|
-
case "page_out":
|
|
38
|
-
return withCategory({
|
|
39
|
-
kind: "page_out",
|
|
40
|
-
turn: t,
|
|
41
|
-
action: compressionAction(obs.action),
|
|
42
|
-
summary: obs.summary,
|
|
43
|
-
tier_hint: obs.tier_hint ?? "durable",
|
|
44
|
-
message_count: Array.isArray(obs.archived) ? obs.archived.length : 0,
|
|
45
|
-
});
|
|
46
29
|
case "compressed": {
|
|
47
30
|
const latest = opts.latestSeq ?? -1;
|
|
48
31
|
const start = opts.nextArchiveStart ?? 0;
|
|
49
32
|
if (latest < start)
|
|
50
33
|
return null;
|
|
51
|
-
return
|
|
34
|
+
return {
|
|
52
35
|
kind: "compressed",
|
|
53
36
|
turn: t,
|
|
54
37
|
archived_seq_range: [start, latest],
|
|
@@ -57,24 +40,24 @@ export function kernelObservationToSessionEvent(obs, turn, opts = {}) {
|
|
|
57
40
|
summary_tokens: obs.summary ? Math.max(1, Math.ceil(obs.summary.length / 4)) : undefined,
|
|
58
41
|
archive_ref: opts.archiveRef,
|
|
59
42
|
preserved_refs: opts.preservedRefs ?? [],
|
|
60
|
-
}
|
|
43
|
+
};
|
|
61
44
|
}
|
|
62
45
|
case "renewed":
|
|
63
|
-
return
|
|
46
|
+
return {
|
|
64
47
|
kind: "context_renewed",
|
|
65
48
|
turn: t,
|
|
66
49
|
sprint: obs.sprint ?? 0,
|
|
67
50
|
handoff_ref: "",
|
|
68
|
-
}
|
|
51
|
+
};
|
|
69
52
|
case "rollbacked":
|
|
70
|
-
return
|
|
53
|
+
return {
|
|
71
54
|
kind: "rollbacked",
|
|
72
55
|
turn: t,
|
|
73
56
|
checkpoint_history_len: obs.checkpoint_history_len ?? 0,
|
|
74
57
|
reason: obs.reason,
|
|
75
|
-
}
|
|
58
|
+
};
|
|
76
59
|
case "capability_changed":
|
|
77
|
-
return
|
|
60
|
+
return {
|
|
78
61
|
kind: "capability_changed",
|
|
79
62
|
turn: t,
|
|
80
63
|
added: obs.added ?? [],
|
|
@@ -84,36 +67,29 @@ export function kernelObservationToSessionEvent(obs, turn, opts = {}) {
|
|
|
84
67
|
...(obs.version != null && { version: obs.version }),
|
|
85
68
|
...(obs.mounted_by != null && { mounted_by: obs.mounted_by }),
|
|
86
69
|
...(obs.mount_reason != null && { mount_reason: obs.mount_reason }),
|
|
87
|
-
}
|
|
70
|
+
};
|
|
88
71
|
case "milestone_advanced":
|
|
89
|
-
return
|
|
72
|
+
return {
|
|
90
73
|
kind: "milestone_advanced",
|
|
91
74
|
turn: t,
|
|
92
75
|
phase_id: obs.phase_id ?? "",
|
|
93
76
|
capabilities_unlocked: obs.capabilities_unlocked ?? [],
|
|
94
|
-
}
|
|
77
|
+
};
|
|
95
78
|
case "milestone_blocked":
|
|
96
|
-
return
|
|
79
|
+
return {
|
|
97
80
|
kind: "milestone_blocked",
|
|
98
81
|
turn: t,
|
|
99
82
|
phase_id: obs.phase_id ?? "",
|
|
100
83
|
reason: typeof obs.reason === "string" ? obs.reason : "",
|
|
101
|
-
}
|
|
102
|
-
case "milestone_evidence":
|
|
103
|
-
return withCategory({
|
|
104
|
-
kind: "milestone_evidence",
|
|
105
|
-
turn: t,
|
|
106
|
-
phase_id: obs.phase_id ?? "",
|
|
107
|
-
evidence: obs.evidence ?? [],
|
|
108
|
-
});
|
|
84
|
+
};
|
|
109
85
|
case "checkpoint_taken":
|
|
110
|
-
return
|
|
86
|
+
return {
|
|
111
87
|
kind: "checkpoint_taken",
|
|
112
88
|
turn: t,
|
|
113
89
|
history_len: obs.history_len ?? 0,
|
|
114
|
-
}
|
|
90
|
+
};
|
|
115
91
|
case "agent_process_changed":
|
|
116
|
-
return
|
|
92
|
+
return {
|
|
117
93
|
kind: "agent_process_changed",
|
|
118
94
|
turn: t,
|
|
119
95
|
agent_id: obs.agent_id ?? "",
|
|
@@ -126,47 +102,47 @@ export function kernelObservationToSessionEvent(obs, turn, opts = {}) {
|
|
|
126
102
|
...(obs.result_termination
|
|
127
103
|
? { result_termination: obs.result_termination }
|
|
128
104
|
: {}),
|
|
129
|
-
}
|
|
105
|
+
};
|
|
130
106
|
case "tool_gated":
|
|
131
|
-
return
|
|
107
|
+
return {
|
|
132
108
|
kind: "tool_gated",
|
|
133
109
|
turn: t,
|
|
134
110
|
call_id: obs.call_id ?? "",
|
|
135
111
|
tool: obs.tool ?? "",
|
|
136
112
|
reason: typeof obs.reason === "string" ? obs.reason : "",
|
|
137
|
-
}
|
|
113
|
+
};
|
|
138
114
|
case "signal_disposed":
|
|
139
|
-
return
|
|
115
|
+
return {
|
|
140
116
|
kind: "signal_disposed",
|
|
141
117
|
turn: t,
|
|
142
118
|
signal_id: obs.signal_id ?? "",
|
|
143
119
|
disposition: obs.disposition ?? "",
|
|
144
120
|
queue_depth: obs.queue_depth ?? 0,
|
|
145
|
-
}
|
|
121
|
+
};
|
|
146
122
|
case "budget_exceeded":
|
|
147
|
-
return
|
|
123
|
+
return {
|
|
148
124
|
kind: "budget_exceeded",
|
|
149
125
|
turn: t,
|
|
150
126
|
budget: obs.budget ?? "",
|
|
151
|
-
}
|
|
127
|
+
};
|
|
152
128
|
case "suspended":
|
|
153
|
-
return
|
|
129
|
+
return {
|
|
154
130
|
kind: "suspended",
|
|
155
131
|
turn: t,
|
|
156
132
|
reason: typeof obs.reason === "string" ? obs.reason : "",
|
|
157
133
|
pending_calls: obs.pending_calls ?? [],
|
|
158
|
-
}
|
|
134
|
+
};
|
|
159
135
|
case "resumed":
|
|
160
|
-
return
|
|
136
|
+
return {
|
|
161
137
|
kind: "resumed",
|
|
162
138
|
turn: t,
|
|
163
139
|
approved: obs.approved ?? [],
|
|
164
140
|
denied: obs.denied ?? [],
|
|
165
|
-
}
|
|
141
|
+
};
|
|
166
142
|
case "page_in_requested":
|
|
167
143
|
return null;
|
|
168
144
|
case "large_result_spooled":
|
|
169
|
-
return
|
|
145
|
+
return {
|
|
170
146
|
kind: "large_result_spooled",
|
|
171
147
|
turn: t,
|
|
172
148
|
call_id: obs.call_id ?? "",
|
|
@@ -174,49 +150,49 @@ export function kernelObservationToSessionEvent(obs, turn, opts = {}) {
|
|
|
174
150
|
original_size: obs.original_size ?? 0,
|
|
175
151
|
preview_size: obs.preview_size ?? 0,
|
|
176
152
|
spool_ref: opts.spoolRef,
|
|
177
|
-
}
|
|
153
|
+
};
|
|
178
154
|
case "memory_written":
|
|
179
|
-
return
|
|
155
|
+
return {
|
|
180
156
|
kind: "memory_written",
|
|
181
157
|
turn: t,
|
|
182
158
|
memory_id: obs.memory_id ?? "",
|
|
183
159
|
memory_kind: obs.memory_kind ?? "",
|
|
184
160
|
size_bytes: obs.size_bytes ?? 0,
|
|
185
|
-
}
|
|
161
|
+
};
|
|
186
162
|
case "memory_queried":
|
|
187
|
-
return
|
|
163
|
+
return {
|
|
188
164
|
kind: "memory_queried",
|
|
189
165
|
turn: t,
|
|
190
166
|
query_context: obs.query_context ?? "",
|
|
191
167
|
requested_k: obs.requested_k ?? 0,
|
|
192
168
|
requires_async_response: obs.requires_async_response ?? false,
|
|
193
|
-
}
|
|
169
|
+
};
|
|
194
170
|
case "memory_validation_failed":
|
|
195
|
-
return
|
|
171
|
+
return {
|
|
196
172
|
kind: "memory_validation_failed",
|
|
197
173
|
turn: t,
|
|
198
174
|
memory_id: obs.memory_id ?? "",
|
|
199
175
|
error: obs.error ?? "",
|
|
200
|
-
}
|
|
176
|
+
};
|
|
201
177
|
case "workflow_batch_spawned": {
|
|
202
178
|
const nodes = obs.nodes ?? [];
|
|
203
|
-
return
|
|
179
|
+
return {
|
|
204
180
|
kind: "workflow_batch_spawned",
|
|
205
181
|
turn: t,
|
|
206
182
|
node_count: nodes.length,
|
|
207
183
|
node_ids: nodes.map((n) => n.agent_id ?? ""),
|
|
208
|
-
}
|
|
184
|
+
};
|
|
209
185
|
}
|
|
210
186
|
case "workflow_completed": {
|
|
211
187
|
const completed = obs.completed ?? [];
|
|
212
188
|
const failed = obs.failed ?? [];
|
|
213
|
-
return
|
|
189
|
+
return {
|
|
214
190
|
kind: "workflow_completed",
|
|
215
191
|
turn: t,
|
|
216
192
|
completed,
|
|
217
193
|
failed,
|
|
218
194
|
total_nodes: completed.length + failed.length,
|
|
219
|
-
}
|
|
195
|
+
};
|
|
220
196
|
}
|
|
221
197
|
default:
|
|
222
198
|
return null;
|
|
@@ -28,10 +28,19 @@ export interface KernelRuntimeHandle {
|
|
|
28
28
|
drainNewMessages(): Message[];
|
|
29
29
|
preservedRefs(): string[];
|
|
30
30
|
}
|
|
31
|
+
export interface PaceDecision {
|
|
32
|
+
action: "continue" | "sleep" | "stop";
|
|
33
|
+
delayMs?: number;
|
|
34
|
+
reason: string;
|
|
35
|
+
/** Set when the kernel trap coerced the model's proposal (clamped delay / forced stop). */
|
|
36
|
+
coercedFrom?: string;
|
|
37
|
+
}
|
|
31
38
|
export interface KernelLoopResult {
|
|
32
39
|
termination: string;
|
|
33
40
|
turnsUsed: number;
|
|
34
41
|
totalTokensUsed: number;
|
|
42
|
+
/** ③ loop-agent: the kernel-adjudicated after-round decision (absent on non-loop runs). */
|
|
43
|
+
paceDecision?: PaceDecision;
|
|
35
44
|
}
|
|
36
45
|
export type KernelRunnerAction = {
|
|
37
46
|
kind: "call_provider";
|
|
@@ -159,12 +159,24 @@ function mapKernelAction(raw) {
|
|
|
159
159
|
};
|
|
160
160
|
case "done": {
|
|
161
161
|
const result = raw.result ?? {};
|
|
162
|
+
const pace = result.pace_decision;
|
|
162
163
|
return {
|
|
163
164
|
kind: "done",
|
|
164
165
|
result: {
|
|
165
166
|
termination: String(result.termination ?? "error"),
|
|
166
167
|
turnsUsed: Number(result.turns_used ?? 0),
|
|
167
168
|
totalTokensUsed: Number(result.total_tokens_used ?? 0),
|
|
169
|
+
// ③ loop-agent: the kernel-adjudicated after-round decision (absent on non-loop runs).
|
|
170
|
+
...(pace
|
|
171
|
+
? {
|
|
172
|
+
paceDecision: {
|
|
173
|
+
action: (pace.action ?? "stop"),
|
|
174
|
+
delayMs: pace.delay_ms,
|
|
175
|
+
reason: pace.reason ?? "",
|
|
176
|
+
coercedFrom: pace.coerced_from,
|
|
177
|
+
},
|
|
178
|
+
}
|
|
179
|
+
: {}),
|
|
168
180
|
},
|
|
169
181
|
};
|
|
170
182
|
}
|
|
@@ -45,5 +45,12 @@ export declare class LargeResultSpool {
|
|
|
45
45
|
processToolResult(result: ToolResult): Promise<SpooledToolResult>;
|
|
46
46
|
persistOutput(callId: string, content: string): Promise<string>;
|
|
47
47
|
readSpooledResult(spoolRef: string): Promise<string>;
|
|
48
|
+
/**
|
|
49
|
+
* O7: locate a spooled output by the tool call's id (the `read_result` meta-tool only knows
|
|
50
|
+
* `call_id`, not the content-hashed key `persistOutput` chose). Scans the driver's key list for
|
|
51
|
+
* the `.spool/${callId}-*.txt` naming convention; returns `undefined` if nothing was ever
|
|
52
|
+
* spooled for that call.
|
|
53
|
+
*/
|
|
54
|
+
findByCallId(callId: string): Promise<string | undefined>;
|
|
48
55
|
cleanup(maxAgeMs?: number): Promise<number>;
|
|
49
56
|
}
|
|
@@ -113,6 +113,31 @@ omitted: ${omitted} chars
|
|
|
113
113
|
async readSpooledResult(spoolRef) {
|
|
114
114
|
return this.driver.read(spoolRef);
|
|
115
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* O7: locate a spooled output by the tool call's id (the `read_result` meta-tool only knows
|
|
118
|
+
* `call_id`, not the content-hashed key `persistOutput` chose). Scans the driver's key list for
|
|
119
|
+
* the `.spool/${callId}-*.txt` naming convention; returns `undefined` if nothing was ever
|
|
120
|
+
* spooled for that call.
|
|
121
|
+
*/
|
|
122
|
+
async findByCallId(callId) {
|
|
123
|
+
let keys;
|
|
124
|
+
try {
|
|
125
|
+
keys = await this.driver.list();
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
const prefix = `.spool/${callId}-`;
|
|
131
|
+
const match = keys.find(k => k.startsWith(prefix) && k.endsWith('.txt'));
|
|
132
|
+
if (!match)
|
|
133
|
+
return undefined;
|
|
134
|
+
try {
|
|
135
|
+
return await this.driver.read(match);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
116
141
|
async cleanup(maxAgeMs) {
|
|
117
142
|
const limit = maxAgeMs ?? this.config.maxAgeMs ?? 7 * 24 * 60 * 60 * 1000;
|
|
118
143
|
try {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { categoryForKind, primitiveForKind } from "./kernel-event-log.js";
|
|
2
1
|
const KERNEL_KINDS = new Set([
|
|
3
2
|
"compressed",
|
|
4
3
|
"page_out",
|
|
@@ -16,7 +15,6 @@ const KERNEL_KINDS = new Set([
|
|
|
16
15
|
"agent_process_changed",
|
|
17
16
|
"milestone_advanced",
|
|
18
17
|
"milestone_blocked",
|
|
19
|
-
"milestone_evidence",
|
|
20
18
|
]);
|
|
21
19
|
export function rebuildOsSnapshotFromSessionEvents(events) {
|
|
22
20
|
const snap = {
|
|
@@ -89,20 +87,3 @@ export function rebuildOsSnapshotFromSessionEvents(events) {
|
|
|
89
87
|
}
|
|
90
88
|
return snap;
|
|
91
89
|
}
|
|
92
|
-
export function sessionLogHasRequiredCategories(events) {
|
|
93
|
-
for (const event of events) {
|
|
94
|
-
if (!KERNEL_KINDS.has(event.kind))
|
|
95
|
-
continue;
|
|
96
|
-
const cat = event.category;
|
|
97
|
-
if (!cat)
|
|
98
|
-
return false;
|
|
99
|
-
if (cat !== categoryForKind(event.kind))
|
|
100
|
-
return false;
|
|
101
|
-
const prim = event.primitive;
|
|
102
|
-
if (prim !== undefined) {
|
|
103
|
-
if (prim !== primitiveForKind(event.kind))
|
|
104
|
-
return false;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return true;
|
|
108
|
-
}
|
package/dist/runtime/runner.d.ts
CHANGED
|
@@ -2,10 +2,11 @@ import type { LLMProvider, Message, StreamEvent, PermissionRequestEvent, Permiss
|
|
|
2
2
|
import type { ToolSuspendEvent } from "./execution-plane.js";
|
|
3
3
|
import type { DreamStore, DreamResult } from "../memory/index.js";
|
|
4
4
|
import type { KnowledgeSource } from "../knowledge/index.js";
|
|
5
|
-
import type { SignalSource } from "../signals/index.js";
|
|
5
|
+
import type { SignalSource, RuntimeSignal } from "../signals/index.js";
|
|
6
6
|
import type { SessionLog, SessionEvent } from "./session-log.js";
|
|
7
7
|
import type { ExecutionPlane } from "./execution-plane.js";
|
|
8
8
|
import { type GovernancePolicy } from "../governance.js";
|
|
9
|
+
import { type RecoveredNodeCompletion } from "./session-repair.js";
|
|
9
10
|
import type { AgentRunSpec, SubAgentResult, MilestonePolicy, MilestoneContract, MilestoneCheckResult, WorkflowSpec } from "./types/agent.js";
|
|
10
11
|
import { type SubAgentOrchestrator } from "./sub-agent-orchestrator.js";
|
|
11
12
|
import { type ReducerRegistry } from "./reducers.js";
|
|
@@ -59,6 +60,16 @@ export interface TurnMetrics {
|
|
|
59
60
|
};
|
|
60
61
|
cacheCreationTokens: number;
|
|
61
62
|
}
|
|
63
|
+
/** O5: decision returned by `onToolCall` — `block: true` denies this call before it executes. */
|
|
64
|
+
export interface ToolCallHookDecision {
|
|
65
|
+
block?: boolean;
|
|
66
|
+
reason?: string;
|
|
67
|
+
}
|
|
68
|
+
/** O5: decision returned by `onToolResult` — replace the output and/or inject a signal note. */
|
|
69
|
+
export interface ToolResultHookDecision {
|
|
70
|
+
replaceOutput?: string;
|
|
71
|
+
note?: string;
|
|
72
|
+
}
|
|
62
73
|
export interface RuntimeOptions {
|
|
63
74
|
provider: LLMProvider;
|
|
64
75
|
/** M1/G3 intelligence routing: resolve a per-node provider from a workflow node's `modelHint`.
|
|
@@ -78,6 +89,8 @@ export interface RuntimeOptions {
|
|
|
78
89
|
* the knowledge partition before turn 1. Requires dreamStore + agentId. */
|
|
79
90
|
preQueryMemory?: (ctx: {
|
|
80
91
|
goal: string;
|
|
92
|
+
/** K4: `"initial"` = pre-turn-1 fetch; `"renewal"` = re-fired after a sprint renewal. */
|
|
93
|
+
phase?: "initial" | "renewal";
|
|
81
94
|
}) => Promise<string[] | undefined> | string[] | undefined;
|
|
82
95
|
systemPrompt?: string;
|
|
83
96
|
initialMemory?: string[];
|
|
@@ -95,6 +108,39 @@ export interface RuntimeOptions {
|
|
|
95
108
|
};
|
|
96
109
|
schedulerBudget?: SchedulerBudget;
|
|
97
110
|
resourceQuota?: ResourceQuota;
|
|
111
|
+
/** O6: the in-kernel repeat fuse — identical tool call (same name AND args) `denyAfter` turns in a
|
|
112
|
+
* row ⇒ deny + directive note; `terminateAfter` ⇒ run ends `no_progress`. Defaults 5/8; `false`
|
|
113
|
+
* disables. Same-tool/different-args loops never trip it. */
|
|
114
|
+
repeatFuse?: {
|
|
115
|
+
denyAfter?: number;
|
|
116
|
+
terminateAfter?: number;
|
|
117
|
+
} | false;
|
|
118
|
+
/** O4: turn-end criteria gate — one kernel-injected self-check turn before accepting completion
|
|
119
|
+
* while `criteria` stand. Default enabled; `false` accepts the first finish unconditionally. */
|
|
120
|
+
criteriaGate?: boolean;
|
|
121
|
+
/** K2: max share of `maxTokens` the durable knowledge partition may occupy. Over budget ⇒
|
|
122
|
+
* warn-once observation + oldest unpinned non-skill entries evicted at the next boundary.
|
|
123
|
+
* Pinned/skill entries are exempt. `0` disables. Default: kernel's 0.25. */
|
|
124
|
+
knowledgeBudgetRatio?: number;
|
|
125
|
+
/** K3: default lease (in turns) for every skill activation — auto-deactivates after N turns
|
|
126
|
+
* (toolset re-widens, knowledge pin boundary-swept). Absent ⇒ permanent (default). */
|
|
127
|
+
skillLeaseTurns?: number;
|
|
128
|
+
/** O5 (PreToolUse-hook analog): stateful host veto over each kernel-approved call; return
|
|
129
|
+
* `{ block: true, reason }` to deny — the reason reaches the model as a denied result. Errs-open. */
|
|
130
|
+
onToolCall?: (call: {
|
|
131
|
+
callId: string;
|
|
132
|
+
name: string;
|
|
133
|
+
arguments: string;
|
|
134
|
+
}) => Promise<ToolCallHookDecision | undefined | void> | ToolCallHookDecision | undefined | void;
|
|
135
|
+
/** O5 (PostToolUse-hook analog): inspect each executed result; `{ replaceOutput }` swaps what the
|
|
136
|
+
* model sees, `{ note }` injects a signal note (the `injectNote` channel). Errs-open. */
|
|
137
|
+
onToolResult?: (result: {
|
|
138
|
+
callId: string;
|
|
139
|
+
name: string;
|
|
140
|
+
arguments: string;
|
|
141
|
+
output: string;
|
|
142
|
+
isError: boolean;
|
|
143
|
+
}) => Promise<ToolResultHookDecision | undefined | void> | ToolResultHookDecision | undefined | void;
|
|
98
144
|
memoryPolicy?: MemoryPolicy;
|
|
99
145
|
tokenizer?: string;
|
|
100
146
|
enablePlanTool?: boolean;
|
|
@@ -140,8 +186,15 @@ export declare class RuntimeRunner {
|
|
|
140
186
|
private pendingObservations;
|
|
141
187
|
private activeKernel;
|
|
142
188
|
private currentSessionId;
|
|
189
|
+
/** O2 (system-reminder channel): host-pushed notes awaiting the next turn-boundary drain. */
|
|
190
|
+
private injectedSignals;
|
|
191
|
+
/** Skill names whose content has already been pushed into the durable `knowledge` slot this
|
|
192
|
+
* run — guards against re-pushing a duplicate entry if the model calls `skill(name)` again for
|
|
193
|
+
* an already-active skill (loading is idempotent; the knowledge push should be too). */
|
|
194
|
+
private knowledgePushedSkills;
|
|
195
|
+
/** K4: the active run's goal, kept for the renewal-boundary memory re-query. */
|
|
196
|
+
private currentGoal;
|
|
143
197
|
private nextArchiveStart;
|
|
144
|
-
private localPageOutCache;
|
|
145
198
|
/** M5 v2.1: sub-workflow specs a top-level agent authored via `start_workflow`, awaiting auto-drive
|
|
146
199
|
* at the next safe point (after the tool turn resolves, kernel back in Reason). */
|
|
147
200
|
private pendingAuthoredWorkflows;
|
|
@@ -149,6 +202,15 @@ export declare class RuntimeRunner {
|
|
|
149
202
|
constructor(opts: RuntimeOptions);
|
|
150
203
|
get hostOptions(): RuntimeOptions;
|
|
151
204
|
interrupt(): void;
|
|
205
|
+
/** Push a contextual note into the run's signal stream (the system-reminder channel): it drains at
|
|
206
|
+
* the next turn boundary, routes through the kernel attention policy, and — once acted on — renders
|
|
207
|
+
* as a `[SIGNAL] <text>` line in the volatile state turn plus a durable directive. `urgency` maps to
|
|
208
|
+
* the kernel disposition ladder: `"normal"` queues (default), `"high"` soft-interrupts, `"critical"`
|
|
209
|
+
* preempts. */
|
|
210
|
+
injectNote(text: string, urgency?: RuntimeSignal["urgency"]): void;
|
|
211
|
+
/** Injected-note drain shared with the main loop's per-turn poll: injected notes first (FIFO), then
|
|
212
|
+
* the configured `signalSource` — one code path so the two inbound channels never drift. */
|
|
213
|
+
private nextInboundSignal;
|
|
152
214
|
run(req: {
|
|
153
215
|
sessionId: string;
|
|
154
216
|
goal: string;
|
|
@@ -160,11 +222,29 @@ export declare class RuntimeRunner {
|
|
|
160
222
|
}>;
|
|
161
223
|
}): AsyncIterable<StreamEvent>;
|
|
162
224
|
wake(sessionId: string, extensions?: Record<string, unknown>): AsyncIterable<StreamEvent>;
|
|
163
|
-
/** Push content into Slot 2 (system_knowledge) via add_knowledge_message.
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
225
|
+
/** Push content into Slot 2 (system_knowledge) via add_knowledge_message.
|
|
226
|
+
* K1: `opts.key` gives the entry identity — a same-key push upserts (applied at the next
|
|
227
|
+
* compaction/renewal boundary) instead of appending a duplicate. `opts.pinned` exempts the
|
|
228
|
+
* entry from the knowledge-budget sweep. */
|
|
229
|
+
pushKnowledge(message: Message, tokens?: number, opts?: {
|
|
230
|
+
key?: string;
|
|
231
|
+
pinned?: boolean;
|
|
232
|
+
}): void;
|
|
233
|
+
/** K1: mark a keyed knowledge entry for removal at the next compaction/renewal boundary.
|
|
234
|
+
* Errs-open: an unknown key is a kernel-side no-op. */
|
|
235
|
+
removeKnowledge(key: string): void;
|
|
236
|
+
/** K3: host-driven skill deactivation — toolset re-widens at the next provider call, the
|
|
237
|
+
* skill's knowledge pin drops at the next boundary. Errs-open: not-active is a no-op. */
|
|
238
|
+
deactivateSkill(name: string): void;
|
|
167
239
|
private resolveKernelSuspend;
|
|
240
|
+
/**
|
|
241
|
+
* O7: resolve a `read_result` meta-tool call to the full text of a previously-evicted tool
|
|
242
|
+
* output. Resolution order: (a) this turn's in-memory `pendingSpoolOutputs` map, (b) the result
|
|
243
|
+
* spool (persisted once the kernel observation `large_result_spooled` was processed), (c) a
|
|
244
|
+
* session-log scan for the original `tool_completed` event carrying that `call_id`. Slices the
|
|
245
|
+
* resolved text by `[offset, offset + maxBytes)` (plain string slice — "bytes-ish").
|
|
246
|
+
*/
|
|
247
|
+
private resolveReadResult;
|
|
168
248
|
dream(agentId: string, nowMs?: number): Promise<DreamResult>;
|
|
169
249
|
private execute;
|
|
170
250
|
spawnSubAgent(spec: AgentRunSpec): Promise<SubAgentResult>;
|
|
@@ -202,7 +282,15 @@ export declare class RuntimeRunner {
|
|
|
202
282
|
private bootstrapWorkflowKernel;
|
|
203
283
|
runWorkflow(spec: WorkflowSpec, opts?: {
|
|
204
284
|
resumedCompleted?: string[];
|
|
285
|
+
/** W-1: recovered completions WITH control signals (classify branch / loop stop) — lowered to
|
|
286
|
+
* the kernel's `resumed_results` so control flow replays faithfully. Supersedes
|
|
287
|
+
* `resumedCompleted` for ids present in both. */
|
|
288
|
+
resumedResults?: RecoveredNodeCompletion[];
|
|
205
289
|
resumedSubmissions?: Record<string, unknown>[][];
|
|
290
|
+
/** R3-1: original base index per submission batch (parallel to resumedSubmissions). */
|
|
291
|
+
resumedSubmissionBases?: number[];
|
|
292
|
+
/** W-1: recovered node outputs (agent id → output text) to pre-seed the driver's outputs map. */
|
|
293
|
+
resumedOutputs?: Map<string, string>;
|
|
206
294
|
/** Standalone session id when bootstrapping (no active parent run). Defaults to a fresh uuid. */
|
|
207
295
|
sessionId?: string;
|
|
208
296
|
}): Promise<{
|
|
@@ -246,8 +334,9 @@ export declare class RuntimeRunner {
|
|
|
246
334
|
private driveWorkflow;
|
|
247
335
|
/**
|
|
248
336
|
* Resume a workflow from the parent session's completed nodes.
|
|
249
|
-
* Reads the session log, extracts completed workflow node
|
|
250
|
-
* calls runWorkflow
|
|
337
|
+
* Reads the session log, extracts completed workflow node records (with their W-1 control
|
|
338
|
+
* signals + outputs), and calls runWorkflow so the kernel skips those nodes, replays control
|
|
339
|
+
* flow (classify prune / loop stop), and the driver re-seeds its outputs map.
|
|
251
340
|
*/
|
|
252
341
|
resumeWorkflow(spec: WorkflowSpec, opts?: {
|
|
253
342
|
sessionId?: string;
|
|
@@ -256,6 +345,12 @@ export declare class RuntimeRunner {
|
|
|
256
345
|
failed: string[];
|
|
257
346
|
}>;
|
|
258
347
|
private appendObservations;
|
|
348
|
+
/** I4 + K4: fetch long-term memory hits for the current goal and land them in `history` as an
|
|
349
|
+
* ordinary user turn — single-use retrieval content that decays with the compression pyramid,
|
|
350
|
+
* never pinned into `knowledge`. `phase: "initial"` = once before turn 1; `phase: "renewal"` =
|
|
351
|
+
* re-fired after each sprint renewal (renewal drops the old history INCLUDING earlier memory
|
|
352
|
+
* hits). Errs-open throughout. */
|
|
353
|
+
private prefetchMemoryIntoHistory;
|
|
259
354
|
private archiveSemanticPageOut;
|
|
260
355
|
}
|
|
261
356
|
export declare function collectText(stream: AsyncIterable<StreamEvent>): Promise<string>;
|