@deepstrike/sdk 0.2.4 → 0.2.5
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 +287 -70
- package/dist/collaboration/modes/creator-verifier.d.ts +0 -3
- package/dist/collaboration/modes/creator-verifier.js +2 -6
- package/dist/governance.d.ts +36 -0
- package/dist/governance.js +22 -0
- package/dist/index.d.ts +11 -5
- package/dist/index.js +5 -1
- package/dist/memory/agent.d.ts +111 -0
- package/dist/memory/agent.js +151 -0
- package/dist/memory/protocols.d.ts +56 -0
- package/dist/runtime/execution-plane.d.ts +6 -9
- package/dist/runtime/execution-plane.js +53 -25
- package/dist/runtime/kernel-event-log.d.ts +26 -0
- package/dist/runtime/kernel-event-log.js +220 -0
- package/dist/runtime/kernel-primitives-dashboard.d.ts +44 -0
- package/dist/runtime/kernel-primitives-dashboard.js +135 -0
- package/dist/runtime/kernel-step.d.ts +25 -1
- package/dist/runtime/kernel-step.js +12 -3
- package/dist/runtime/large-result-spool.d.ts +84 -0
- package/dist/runtime/large-result-spool.js +167 -0
- package/dist/runtime/os-profile.d.ts +18 -0
- package/dist/runtime/os-profile.js +47 -0
- package/dist/runtime/os-snapshot.d.ts +35 -0
- package/dist/runtime/os-snapshot.js +128 -0
- package/dist/runtime/runner.d.ts +62 -9
- package/dist/runtime/runner.js +425 -135
- package/dist/runtime/session-log.d.ts +118 -4
- package/dist/runtime/session-log.js +15 -4
- package/dist/runtime/sub-agent-orchestrator.d.ts +2 -2
- package/dist/runtime/sub-agent-orchestrator.js +14 -23
- package/dist/types/agent.d.ts +12 -3
- package/dist/types/agent.js +18 -0
- package/dist/types.d.ts +22 -0
- package/package.json +2 -2
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
export function categoryForKind(kind) {
|
|
2
|
+
switch (kind) {
|
|
3
|
+
case "tool_gated":
|
|
4
|
+
case "capability_changed":
|
|
5
|
+
return "syscall";
|
|
6
|
+
case "compressed":
|
|
7
|
+
case "page_out":
|
|
8
|
+
case "page_in":
|
|
9
|
+
case "page_in_requested":
|
|
10
|
+
case "renewed":
|
|
11
|
+
case "context_renewed":
|
|
12
|
+
case "large_result_spooled":
|
|
13
|
+
case "memory_written":
|
|
14
|
+
case "memory_queried":
|
|
15
|
+
case "memory_validation_failed":
|
|
16
|
+
return "mm";
|
|
17
|
+
case "agent_process_changed":
|
|
18
|
+
return "proc";
|
|
19
|
+
case "signal_disposed":
|
|
20
|
+
return "ipc";
|
|
21
|
+
default:
|
|
22
|
+
return "sched";
|
|
23
|
+
}
|
|
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
|
+
export function kernelObservationToSessionEvent(obs, turn, opts = {}) {
|
|
34
|
+
const t = obs.turn ?? turn;
|
|
35
|
+
const compressionAction = opts.compressionAction ?? (() => undefined);
|
|
36
|
+
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
|
+
case "compressed": {
|
|
47
|
+
const latest = opts.latestSeq ?? -1;
|
|
48
|
+
const start = opts.nextArchiveStart ?? 0;
|
|
49
|
+
if (latest < start)
|
|
50
|
+
return null;
|
|
51
|
+
return withCategory({
|
|
52
|
+
kind: "compressed",
|
|
53
|
+
turn: t,
|
|
54
|
+
archived_seq_range: [start, latest],
|
|
55
|
+
action: compressionAction(obs.action),
|
|
56
|
+
summary: obs.summary,
|
|
57
|
+
summary_tokens: obs.summary ? Math.max(1, Math.ceil(obs.summary.length / 4)) : undefined,
|
|
58
|
+
archive_ref: opts.archiveRef,
|
|
59
|
+
preserved_refs: opts.preservedRefs ?? [],
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
case "renewed":
|
|
63
|
+
return withCategory({
|
|
64
|
+
kind: "context_renewed",
|
|
65
|
+
turn: t,
|
|
66
|
+
sprint: obs.sprint ?? 0,
|
|
67
|
+
handoff_ref: "",
|
|
68
|
+
});
|
|
69
|
+
case "rollbacked":
|
|
70
|
+
return withCategory({
|
|
71
|
+
kind: "rollbacked",
|
|
72
|
+
turn: t,
|
|
73
|
+
checkpoint_history_len: obs.checkpoint_history_len ?? 0,
|
|
74
|
+
reason: obs.reason,
|
|
75
|
+
});
|
|
76
|
+
case "capability_changed":
|
|
77
|
+
return withCategory({
|
|
78
|
+
kind: "capability_changed",
|
|
79
|
+
turn: t,
|
|
80
|
+
added: obs.added ?? [],
|
|
81
|
+
removed: obs.removed ?? [],
|
|
82
|
+
...(obs.change_kind != null && { change_kind: obs.change_kind }),
|
|
83
|
+
...(obs.capability_id != null && { capability_id: obs.capability_id }),
|
|
84
|
+
...(obs.version != null && { version: obs.version }),
|
|
85
|
+
...(obs.mounted_by != null && { mounted_by: obs.mounted_by }),
|
|
86
|
+
...(obs.mount_reason != null && { mount_reason: obs.mount_reason }),
|
|
87
|
+
});
|
|
88
|
+
case "milestone_advanced":
|
|
89
|
+
return withCategory({
|
|
90
|
+
kind: "milestone_advanced",
|
|
91
|
+
turn: t,
|
|
92
|
+
phase_id: obs.phase_id ?? "",
|
|
93
|
+
capabilities_unlocked: obs.capabilities_unlocked ?? [],
|
|
94
|
+
});
|
|
95
|
+
case "milestone_blocked":
|
|
96
|
+
return withCategory({
|
|
97
|
+
kind: "milestone_blocked",
|
|
98
|
+
turn: t,
|
|
99
|
+
phase_id: obs.phase_id ?? "",
|
|
100
|
+
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
|
+
});
|
|
109
|
+
case "checkpoint_taken":
|
|
110
|
+
return withCategory({
|
|
111
|
+
kind: "checkpoint_taken",
|
|
112
|
+
turn: t,
|
|
113
|
+
history_len: obs.history_len ?? 0,
|
|
114
|
+
});
|
|
115
|
+
case "agent_process_changed":
|
|
116
|
+
return withCategory({
|
|
117
|
+
kind: "agent_process_changed",
|
|
118
|
+
turn: t,
|
|
119
|
+
agent_id: obs.agent_id ?? "",
|
|
120
|
+
parent_session_id: obs.parent_session_id ?? "",
|
|
121
|
+
role: obs.role ?? "",
|
|
122
|
+
isolation: obs.isolation ?? "",
|
|
123
|
+
context_inheritance: obs.context_inheritance ?? "",
|
|
124
|
+
state: obs.state ?? "running",
|
|
125
|
+
permitted_capability_ids: obs.permitted_capability_ids ?? [],
|
|
126
|
+
...(obs.result_termination
|
|
127
|
+
? { result_termination: obs.result_termination }
|
|
128
|
+
: {}),
|
|
129
|
+
});
|
|
130
|
+
case "tool_gated":
|
|
131
|
+
return withCategory({
|
|
132
|
+
kind: "tool_gated",
|
|
133
|
+
turn: t,
|
|
134
|
+
call_id: obs.call_id ?? "",
|
|
135
|
+
tool: obs.tool ?? "",
|
|
136
|
+
reason: typeof obs.reason === "string" ? obs.reason : "",
|
|
137
|
+
});
|
|
138
|
+
case "signal_disposed":
|
|
139
|
+
return withCategory({
|
|
140
|
+
kind: "signal_disposed",
|
|
141
|
+
turn: t,
|
|
142
|
+
signal_id: obs.signal_id ?? "",
|
|
143
|
+
disposition: obs.disposition ?? "",
|
|
144
|
+
queue_depth: obs.queue_depth ?? 0,
|
|
145
|
+
});
|
|
146
|
+
case "budget_exceeded":
|
|
147
|
+
return withCategory({
|
|
148
|
+
kind: "budget_exceeded",
|
|
149
|
+
turn: t,
|
|
150
|
+
budget: obs.budget ?? "",
|
|
151
|
+
});
|
|
152
|
+
case "suspended":
|
|
153
|
+
return withCategory({
|
|
154
|
+
kind: "suspended",
|
|
155
|
+
turn: t,
|
|
156
|
+
reason: typeof obs.reason === "string" ? obs.reason : "",
|
|
157
|
+
pending_calls: obs.pending_calls ?? [],
|
|
158
|
+
});
|
|
159
|
+
case "resumed":
|
|
160
|
+
return withCategory({
|
|
161
|
+
kind: "resumed",
|
|
162
|
+
turn: t,
|
|
163
|
+
approved: obs.approved ?? [],
|
|
164
|
+
denied: obs.denied ?? [],
|
|
165
|
+
});
|
|
166
|
+
case "page_in_requested":
|
|
167
|
+
return null;
|
|
168
|
+
case "large_result_spooled":
|
|
169
|
+
return withCategory({
|
|
170
|
+
kind: "large_result_spooled",
|
|
171
|
+
turn: t,
|
|
172
|
+
call_id: obs.call_id ?? "",
|
|
173
|
+
tool: obs.tool ?? "",
|
|
174
|
+
original_size: obs.original_size ?? 0,
|
|
175
|
+
preview_size: obs.preview_size ?? 0,
|
|
176
|
+
spool_ref: opts.spoolRef,
|
|
177
|
+
});
|
|
178
|
+
case "memory_written":
|
|
179
|
+
return withCategory({
|
|
180
|
+
kind: "memory_written",
|
|
181
|
+
turn: t,
|
|
182
|
+
memory_id: obs.memory_id ?? "",
|
|
183
|
+
memory_kind: obs.memory_kind ?? "",
|
|
184
|
+
size_bytes: obs.size_bytes ?? 0,
|
|
185
|
+
});
|
|
186
|
+
case "memory_queried":
|
|
187
|
+
return withCategory({
|
|
188
|
+
kind: "memory_queried",
|
|
189
|
+
turn: t,
|
|
190
|
+
query_context: obs.query_context ?? "",
|
|
191
|
+
requested_k: obs.requested_k ?? 0,
|
|
192
|
+
requires_async_response: obs.requires_async_response ?? false,
|
|
193
|
+
});
|
|
194
|
+
case "memory_validation_failed":
|
|
195
|
+
return withCategory({
|
|
196
|
+
kind: "memory_validation_failed",
|
|
197
|
+
turn: t,
|
|
198
|
+
memory_id: obs.memory_id ?? "",
|
|
199
|
+
error: obs.error ?? "",
|
|
200
|
+
});
|
|
201
|
+
default:
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
export function primitiveForCategory(category) {
|
|
206
|
+
switch (category) {
|
|
207
|
+
case "syscall":
|
|
208
|
+
return "syscall";
|
|
209
|
+
case "mm":
|
|
210
|
+
return "mm";
|
|
211
|
+
case "proc":
|
|
212
|
+
case "ipc":
|
|
213
|
+
case "sched":
|
|
214
|
+
default:
|
|
215
|
+
return "sched";
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
export function primitiveForKind(kind) {
|
|
219
|
+
return primitiveForCategory(categoryForKind(kind));
|
|
220
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { SessionEvent } from "./session-log.js";
|
|
2
|
+
export interface PrimitivesStats {
|
|
3
|
+
syscall: {
|
|
4
|
+
toolGatedCount: number;
|
|
5
|
+
toolDeniedCount: number;
|
|
6
|
+
toolCompletedCount: number;
|
|
7
|
+
capabilityChanges: number;
|
|
8
|
+
};
|
|
9
|
+
sched: {
|
|
10
|
+
turnCount: number;
|
|
11
|
+
suspendedCount: number;
|
|
12
|
+
resumedCount: number;
|
|
13
|
+
signalDisposedCount: number;
|
|
14
|
+
budgetExceededCount: number;
|
|
15
|
+
activeProcesses: Set<string>;
|
|
16
|
+
processState: Map<string, string>;
|
|
17
|
+
lastSuspendReason: string;
|
|
18
|
+
};
|
|
19
|
+
mm: {
|
|
20
|
+
compressedCount: number;
|
|
21
|
+
pageOutCount: number;
|
|
22
|
+
pageInCount: number;
|
|
23
|
+
largeResultSpooledCount: number;
|
|
24
|
+
totalSpooledBytes: number;
|
|
25
|
+
contextRenewedCount: number;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export declare class KernelPrimitivesDashboard {
|
|
29
|
+
private sessionId;
|
|
30
|
+
private stats;
|
|
31
|
+
constructor(sessionId: string);
|
|
32
|
+
/**
|
|
33
|
+
* Ingest a SessionEvent to update the metrics dashboard.
|
|
34
|
+
*/
|
|
35
|
+
ingest(event: SessionEvent): void;
|
|
36
|
+
/**
|
|
37
|
+
* Return a formatted ANSI terminal dashboard representation.
|
|
38
|
+
*/
|
|
39
|
+
render(): string;
|
|
40
|
+
/**
|
|
41
|
+
* Log the dashboard to the console.
|
|
42
|
+
*/
|
|
43
|
+
print(): void;
|
|
44
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { primitiveForKind } from "./kernel-event-log.js";
|
|
2
|
+
export class KernelPrimitivesDashboard {
|
|
3
|
+
sessionId;
|
|
4
|
+
stats = {
|
|
5
|
+
syscall: {
|
|
6
|
+
toolGatedCount: 0,
|
|
7
|
+
toolDeniedCount: 0,
|
|
8
|
+
toolCompletedCount: 0,
|
|
9
|
+
capabilityChanges: 0,
|
|
10
|
+
},
|
|
11
|
+
sched: {
|
|
12
|
+
turnCount: 0,
|
|
13
|
+
suspendedCount: 0,
|
|
14
|
+
resumedCount: 0,
|
|
15
|
+
signalDisposedCount: 0,
|
|
16
|
+
budgetExceededCount: 0,
|
|
17
|
+
activeProcesses: new Set(),
|
|
18
|
+
processState: new Map(),
|
|
19
|
+
lastSuspendReason: "",
|
|
20
|
+
},
|
|
21
|
+
mm: {
|
|
22
|
+
compressedCount: 0,
|
|
23
|
+
pageOutCount: 0,
|
|
24
|
+
pageInCount: 0,
|
|
25
|
+
largeResultSpooledCount: 0,
|
|
26
|
+
totalSpooledBytes: 0,
|
|
27
|
+
contextRenewedCount: 0,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
constructor(sessionId) {
|
|
31
|
+
this.sessionId = sessionId;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Ingest a SessionEvent to update the metrics dashboard.
|
|
35
|
+
*/
|
|
36
|
+
ingest(event) {
|
|
37
|
+
const prim = primitiveForKind(event.kind);
|
|
38
|
+
if ("turn" in event && event.turn !== undefined) {
|
|
39
|
+
this.stats.sched.turnCount = Math.max(this.stats.sched.turnCount, event.turn);
|
|
40
|
+
}
|
|
41
|
+
if (prim === "syscall") {
|
|
42
|
+
if (event.kind === "tool_gated")
|
|
43
|
+
this.stats.syscall.toolGatedCount++;
|
|
44
|
+
else if (event.kind === "tool_denied")
|
|
45
|
+
this.stats.syscall.toolDeniedCount++;
|
|
46
|
+
else if (event.kind === "capability_changed")
|
|
47
|
+
this.stats.syscall.capabilityChanges++;
|
|
48
|
+
}
|
|
49
|
+
else if (prim === "sched") {
|
|
50
|
+
if (event.kind === "suspended") {
|
|
51
|
+
this.stats.sched.suspendedCount++;
|
|
52
|
+
this.stats.sched.lastSuspendReason = event.reason;
|
|
53
|
+
}
|
|
54
|
+
else if (event.kind === "resumed") {
|
|
55
|
+
this.stats.sched.resumedCount++;
|
|
56
|
+
}
|
|
57
|
+
else if (event.kind === "signal_disposed") {
|
|
58
|
+
this.stats.sched.signalDisposedCount++;
|
|
59
|
+
}
|
|
60
|
+
else if (event.kind === "budget_exceeded") {
|
|
61
|
+
this.stats.sched.budgetExceededCount++;
|
|
62
|
+
}
|
|
63
|
+
else if (event.kind === "agent_process_changed") {
|
|
64
|
+
const state = event.state ?? "running";
|
|
65
|
+
this.stats.sched.processState.set(event.agent_id, state);
|
|
66
|
+
if (state === "running") {
|
|
67
|
+
this.stats.sched.activeProcesses.add(event.agent_id);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
this.stats.sched.activeProcesses.delete(event.agent_id);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else if (prim === "mm") {
|
|
75
|
+
if (event.kind === "compressed")
|
|
76
|
+
this.stats.mm.compressedCount++;
|
|
77
|
+
else if (event.kind === "page_out")
|
|
78
|
+
this.stats.mm.pageOutCount++;
|
|
79
|
+
else if (event.kind === "page_in")
|
|
80
|
+
this.stats.mm.pageInCount++;
|
|
81
|
+
else if (event.kind === "context_renewed")
|
|
82
|
+
this.stats.mm.contextRenewedCount++;
|
|
83
|
+
else if (event.kind === "large_result_spooled") {
|
|
84
|
+
this.stats.mm.largeResultSpooledCount++;
|
|
85
|
+
this.stats.mm.totalSpooledBytes += event.original_size;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Special handling for tool completion which logs at outer runner
|
|
89
|
+
if (event.kind === "tool_completed") {
|
|
90
|
+
this.stats.syscall.toolCompletedCount += event.results.length;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Return a formatted ANSI terminal dashboard representation.
|
|
95
|
+
*/
|
|
96
|
+
render() {
|
|
97
|
+
const esc = (code) => `\x1b[${code}m`;
|
|
98
|
+
const reset = esc("0");
|
|
99
|
+
const bold = esc("1");
|
|
100
|
+
const green = esc("32");
|
|
101
|
+
const cyan = esc("36");
|
|
102
|
+
const yellow = esc("33");
|
|
103
|
+
const magenta = esc("35");
|
|
104
|
+
const gray = esc("90");
|
|
105
|
+
const s = this.stats;
|
|
106
|
+
const header = `${bold}${cyan}╔══════════════════════════════════════════════════════════════════════╗${reset}`;
|
|
107
|
+
const footer = `${bold}${cyan}╚══════════════════════════════════════════════════════════════════════╝${reset}`;
|
|
108
|
+
const lines = [
|
|
109
|
+
header,
|
|
110
|
+
`${bold}${cyan}║ DeepStrike Kernel Primitives Diagnostics (Session: ${this.sessionId.slice(0, 8)}) ║${reset}`,
|
|
111
|
+
`${bold}${cyan}╠══════════════════════════════════════════════════════════════════════╣${reset}`,
|
|
112
|
+
`║ ${bold}${green}🔧 SYSCALL (Security & Host Tools)${reset} ║`,
|
|
113
|
+
`║ - Tool Gated: ${s.syscall.toolGatedCount.toString().padEnd(10)} - Tool Completed: ${s.syscall.toolCompletedCount.toString().padEnd(10)} ║`,
|
|
114
|
+
`║ - Tool Denied: ${s.syscall.toolDeniedCount.toString().padEnd(9)} - Cap. Changes: ${s.syscall.capabilityChanges.toString().padEnd(10)} ║`,
|
|
115
|
+
`║ ║`,
|
|
116
|
+
`║ ${bold}${yellow}⏰ SCHED (Task Scheduler & Process Table)${reset} ║`,
|
|
117
|
+
`║ - Current Turn: ${s.sched.turnCount.toString().padEnd(9)} - Suspended/Resumed: ${s.sched.suspendedCount}/${s.sched.resumedCount}`.padEnd(70) + "║",
|
|
118
|
+
`║ - Active Sub-Agents: ${s.sched.activeProcesses.size.toString().padEnd(4)} - Signals Handled: ${s.sched.signalDisposedCount.toString().padEnd(10)} ║`,
|
|
119
|
+
`║ - Last Suspend Reason: ${s.sched.lastSuspendReason.slice(0, 35).padEnd(35)} ║`,
|
|
120
|
+
`║ ║`,
|
|
121
|
+
`║ ${bold}${magenta}💾 MM (Memory Management & Context Paging)${reset} ║`,
|
|
122
|
+
`║ - Compressions: ${s.mm.compressedCount.toString().padEnd(9)} - Page-Outs (Semantic): ${s.mm.pageOutCount.toString().padEnd(10)} ║`,
|
|
123
|
+
`║ - Page-Ins (Cache): ${s.mm.pageInCount.toString().padEnd(7)} - Large Spooled: ${s.mm.largeResultSpooledCount.toString().padEnd(14)} ║`,
|
|
124
|
+
`║ - Total Spooled Bytes: ${(s.mm.totalSpooledBytes / 1024).toFixed(1).toString() + " KB"}`.padEnd(70) + "║",
|
|
125
|
+
footer
|
|
126
|
+
];
|
|
127
|
+
return lines.join("\n");
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Log the dashboard to the console.
|
|
131
|
+
*/
|
|
132
|
+
print() {
|
|
133
|
+
console.log(this.render());
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -65,13 +65,31 @@ export interface KernelObservation {
|
|
|
65
65
|
phase_id?: string;
|
|
66
66
|
capabilities_unlocked?: string[];
|
|
67
67
|
evidence?: string[];
|
|
68
|
-
reason?: RollbackReason;
|
|
68
|
+
reason?: RollbackReason | string;
|
|
69
69
|
agent_id?: string;
|
|
70
70
|
parent_session_id?: string;
|
|
71
71
|
role?: string;
|
|
72
72
|
isolation?: string;
|
|
73
73
|
context_inheritance?: string;
|
|
74
74
|
permitted_capability_ids?: string[];
|
|
75
|
+
call_id?: string;
|
|
76
|
+
tool?: string;
|
|
77
|
+
signal_id?: string;
|
|
78
|
+
disposition?: string;
|
|
79
|
+
queue_depth?: number;
|
|
80
|
+
budget?: string;
|
|
81
|
+
pending_calls?: string[];
|
|
82
|
+
approved?: string[];
|
|
83
|
+
denied?: string[];
|
|
84
|
+
tier_hint?: string;
|
|
85
|
+
memory_id?: string;
|
|
86
|
+
memory_kind?: string;
|
|
87
|
+
size_bytes?: number;
|
|
88
|
+
query_context?: string;
|
|
89
|
+
requested_k?: number;
|
|
90
|
+
requires_async_response?: boolean;
|
|
91
|
+
/** memory_validation_failed (Phase 7). */
|
|
92
|
+
error?: string;
|
|
75
93
|
}
|
|
76
94
|
export declare function toolSchemaToKernel(schema: ToolSchema): Record<string, unknown>;
|
|
77
95
|
export declare function skillMetadataToKernel(skill: SkillMetadata): Record<string, unknown>;
|
|
@@ -85,4 +103,10 @@ export declare function capabilityCommandMount(capability: Record<string, unknow
|
|
|
85
103
|
export declare function capabilityCommandUnmount(capabilityKind: string, id: string): Record<string, unknown>;
|
|
86
104
|
export declare function kernelApply(runtime: KernelRuntimeHandle, pending: KernelObservation[], event: Record<string, unknown>): KernelObservation[];
|
|
87
105
|
export declare function kernelAction(runtime: KernelRuntimeHandle, pending: KernelObservation[], event: Record<string, unknown>): KernelRunnerAction;
|
|
106
|
+
/**
|
|
107
|
+
* Like {@link kernelAction} but tolerates a zero-action step. Used for events
|
|
108
|
+
* whose outcome may not drive a provider call — e.g. a signal the kernel queues
|
|
109
|
+
* or ignores returns no action. Returns `null` in that case.
|
|
110
|
+
*/
|
|
111
|
+
export declare function kernelMaybeAction(runtime: KernelRuntimeHandle, pending: KernelObservation[], event: Record<string, unknown>): KernelRunnerAction | null;
|
|
88
112
|
export declare function forceCompact(runtime: KernelRuntimeHandle, pending: KernelObservation[]): boolean;
|
|
@@ -252,12 +252,21 @@ export function kernelApply(runtime, pending, event) {
|
|
|
252
252
|
return step.observations;
|
|
253
253
|
}
|
|
254
254
|
export function kernelAction(runtime, pending, event) {
|
|
255
|
+
const action = kernelMaybeAction(runtime, pending, event);
|
|
256
|
+
if (!action)
|
|
257
|
+
throw new Error("kernel transition must return one action");
|
|
258
|
+
return action;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Like {@link kernelAction} but tolerates a zero-action step. Used for events
|
|
262
|
+
* whose outcome may not drive a provider call — e.g. a signal the kernel queues
|
|
263
|
+
* or ignores returns no action. Returns `null` in that case.
|
|
264
|
+
*/
|
|
265
|
+
export function kernelMaybeAction(runtime, pending, event) {
|
|
255
266
|
const step = parseStep(runtime.step(stepInput(event)));
|
|
256
267
|
pending.push(...step.observations);
|
|
257
268
|
const raw = step.actions[0];
|
|
258
|
-
|
|
259
|
-
throw new Error("kernel transition must return one action");
|
|
260
|
-
return mapKernelAction(raw);
|
|
269
|
+
return raw ? mapKernelAction(raw) : null;
|
|
261
270
|
}
|
|
262
271
|
export function forceCompact(runtime, pending) {
|
|
263
272
|
return kernelApply(runtime, pending, { kind: "force_compact" }).some(o => o.kind === "compressed");
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Large result spool (Layer 1 of 5-layer compression pyramid).
|
|
3
|
+
*
|
|
4
|
+
* When a single tool result exceeds 50KB, write the full content to disk
|
|
5
|
+
* and keep only a 2KB preview in the message. Zero API overhead.
|
|
6
|
+
*
|
|
7
|
+
* Design principles:
|
|
8
|
+
* - Kernel defines policy (thresholds)
|
|
9
|
+
* - SDK performs I/O (disk write/read)
|
|
10
|
+
* - Model can retrieve full content via Read tool when needed
|
|
11
|
+
*/
|
|
12
|
+
export interface ToolResult {
|
|
13
|
+
callId: string;
|
|
14
|
+
tool: string;
|
|
15
|
+
output: string;
|
|
16
|
+
isError?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface SpooledToolResult {
|
|
19
|
+
originalOutput: string;
|
|
20
|
+
preview: string;
|
|
21
|
+
spoolRef: string;
|
|
22
|
+
wasSpooled: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Large result spool configuration (mirrors kernel ContextConfig).
|
|
26
|
+
*/
|
|
27
|
+
export interface SpoolConfig {
|
|
28
|
+
/** Single result size threshold (bytes) */
|
|
29
|
+
spoolThresholdBytes: number;
|
|
30
|
+
/** Preview token count (~2KB) */
|
|
31
|
+
previewTokens: number;
|
|
32
|
+
/** Total message limit (bytes) */
|
|
33
|
+
totalMessageLimitBytes: number;
|
|
34
|
+
/** Custom spool directory path */
|
|
35
|
+
spoolDir?: string;
|
|
36
|
+
/** Maximum age of spooled files (default 7 days) */
|
|
37
|
+
maxAgeMs?: number;
|
|
38
|
+
}
|
|
39
|
+
export declare const DEFAULT_SPOOL_CONFIG: SpoolConfig;
|
|
40
|
+
/**
|
|
41
|
+
* Large result spool manager.
|
|
42
|
+
*/
|
|
43
|
+
export declare class LargeResultSpool {
|
|
44
|
+
private config;
|
|
45
|
+
private spoolDir;
|
|
46
|
+
private activeWrites;
|
|
47
|
+
constructor(config?: Partial<SpoolConfig>);
|
|
48
|
+
/**
|
|
49
|
+
* Check if a tool result needs spooling.
|
|
50
|
+
*/
|
|
51
|
+
private needsSpool;
|
|
52
|
+
/**
|
|
53
|
+
* Hash content for spool reference.
|
|
54
|
+
*/
|
|
55
|
+
private hashContent;
|
|
56
|
+
/**
|
|
57
|
+
* Get spool file path for a hash.
|
|
58
|
+
*/
|
|
59
|
+
private getSpoolPath;
|
|
60
|
+
/**
|
|
61
|
+
* Write large result to disk.
|
|
62
|
+
*/
|
|
63
|
+
private writeToDisk;
|
|
64
|
+
/**
|
|
65
|
+
* Generate preview for a tool result.
|
|
66
|
+
*/
|
|
67
|
+
private generatePreview;
|
|
68
|
+
/**
|
|
69
|
+
* Process a tool result: spool if large, return spooled result.
|
|
70
|
+
*/
|
|
71
|
+
processToolResult(result: ToolResult): Promise<SpooledToolResult>;
|
|
72
|
+
/**
|
|
73
|
+
* Persist a kernel-spooled tool output to disk. Returns the on-disk path ref.
|
|
74
|
+
*/
|
|
75
|
+
persistOutput(callId: string, content: string): Promise<string>;
|
|
76
|
+
/**
|
|
77
|
+
* Read a spooled result back from disk.
|
|
78
|
+
*/
|
|
79
|
+
readSpooledResult(spoolRef: string): Promise<string>;
|
|
80
|
+
/**
|
|
81
|
+
* Clean up old spool files (optional maintenance).
|
|
82
|
+
*/
|
|
83
|
+
cleanup(maxAgeMs?: number): Promise<number>;
|
|
84
|
+
}
|