@jmtrin/opencode-kevin 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -9
- package/dist/migrations/005_v04_signal.sql +57 -0
- package/dist/migrations/006_v05_glassbox.sql +118 -0
- package/dist/plugin/Archiver.d.ts +42 -0
- package/dist/plugin/Archiver.js +98 -0
- package/dist/plugin/Archiver.js.map +1 -0
- package/dist/plugin/CausalChain.d.ts +13 -2
- package/dist/plugin/CausalChain.js +83 -13
- package/dist/plugin/CausalChain.js.map +1 -1
- package/dist/plugin/ContextInjector.d.ts +152 -4
- package/dist/plugin/ContextInjector.js +400 -93
- package/dist/plugin/ContextInjector.js.map +1 -1
- package/dist/plugin/Feedback.d.ts +67 -0
- package/dist/plugin/Feedback.js +137 -0
- package/dist/plugin/Feedback.js.map +1 -0
- package/dist/plugin/InjectionLedger.d.ts +92 -0
- package/dist/plugin/InjectionLedger.js +243 -0
- package/dist/plugin/InjectionLedger.js.map +1 -0
- package/dist/plugin/LessonFixer.d.ts +44 -0
- package/dist/plugin/LessonFixer.js +46 -0
- package/dist/plugin/LessonFixer.js.map +1 -0
- package/dist/plugin/MemoryService.d.ts +81 -1
- package/dist/plugin/MemoryService.js +321 -54
- package/dist/plugin/MemoryService.js.map +1 -1
- package/dist/plugin/Migrate.js +31 -0
- package/dist/plugin/Migrate.js.map +1 -1
- package/dist/plugin/QualityGate.d.ts +110 -0
- package/dist/plugin/QualityGate.js +108 -0
- package/dist/plugin/QualityGate.js.map +1 -0
- package/dist/plugin/Reflector.d.ts +17 -0
- package/dist/plugin/Reflector.js +81 -26
- package/dist/plugin/Reflector.js.map +1 -1
- package/dist/plugin/Retrospective.js +22 -1
- package/dist/plugin/Retrospective.js.map +1 -1
- package/dist/plugin/ToolCallObserver.d.ts +1 -0
- package/dist/plugin/ToolCallObserver.js +15 -8
- package/dist/plugin/ToolCallObserver.js.map +1 -1
- package/dist/plugin/confidence.d.ts +8 -0
- package/dist/plugin/confidence.js +35 -0
- package/dist/plugin/confidence.js.map +1 -0
- package/dist/plugin/index.d.ts +5 -0
- package/dist/plugin/index.js +368 -44
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/kevin_audit.d.ts +49 -0
- package/dist/plugin/kevin_audit.js +141 -0
- package/dist/plugin/kevin_audit.js.map +1 -0
- package/dist/plugin/kevin_why.d.ts +4 -0
- package/dist/plugin/kevin_why.js +72 -35
- package/dist/plugin/kevin_why.js.map +1 -1
- package/dist/plugin/memory-format.d.ts +12 -0
- package/dist/plugin/memory-format.js +45 -5
- package/dist/plugin/memory-format.js.map +1 -1
- package/dist/plugin/metrics.d.ts +27 -1
- package/dist/plugin/metrics.js +61 -0
- package/dist/plugin/metrics.js.map +1 -1
- package/dist/plugin/okf-export.js +63 -22
- package/dist/plugin/okf-export.js.map +1 -1
- package/dist/plugin/okf-import.d.ts +4 -1
- package/dist/plugin/okf-import.js +45 -12
- package/dist/plugin/okf-import.js.map +1 -1
- package/dist/plugin/query-tokenizer.d.ts +13 -0
- package/dist/plugin/query-tokenizer.js +86 -0
- package/dist/plugin/query-tokenizer.js.map +1 -0
- package/dist/plugin/replay-types.d.ts +327 -0
- package/dist/plugin/replay-types.js +65 -0
- package/dist/plugin/replay-types.js.map +1 -0
- package/dist/plugin/replay.d.ts +36 -0
- package/dist/plugin/replay.js +193 -0
- package/dist/plugin/replay.js.map +1 -0
- package/migrations/005_v04_signal.sql +57 -0
- package/migrations/006_v05_glassbox.sql +118 -0
- package/package.json +3 -2
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* v0.5.0 (K5-018 / plan §5.8) — replay transcript format.
|
|
4
|
+
*
|
|
5
|
+
* A hermetic, deterministic way to run a recorded session through the
|
|
6
|
+
* plugin's components and read the outcome distribution. `at` is an
|
|
7
|
+
* ISO-8601 string and is the ONLY source of time during replay:
|
|
8
|
+
* `Date.now()` must not be called anywhere in the replay path.
|
|
9
|
+
*/
|
|
10
|
+
export declare const replayEventSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
|
|
11
|
+
kind: z.ZodLiteral<"session.created">;
|
|
12
|
+
at: z.ZodString;
|
|
13
|
+
sessionId: z.ZodString;
|
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
|
15
|
+
at: string;
|
|
16
|
+
sessionId: string;
|
|
17
|
+
kind: "session.created";
|
|
18
|
+
}, {
|
|
19
|
+
at: string;
|
|
20
|
+
sessionId: string;
|
|
21
|
+
kind: "session.created";
|
|
22
|
+
}>, z.ZodObject<{
|
|
23
|
+
kind: z.ZodLiteral<"chat.message">;
|
|
24
|
+
at: z.ZodString;
|
|
25
|
+
sessionId: z.ZodString;
|
|
26
|
+
text: z.ZodString;
|
|
27
|
+
}, "strip", z.ZodTypeAny, {
|
|
28
|
+
at: string;
|
|
29
|
+
sessionId: string;
|
|
30
|
+
text: string;
|
|
31
|
+
kind: "chat.message";
|
|
32
|
+
}, {
|
|
33
|
+
at: string;
|
|
34
|
+
sessionId: string;
|
|
35
|
+
text: string;
|
|
36
|
+
kind: "chat.message";
|
|
37
|
+
}>, z.ZodObject<{
|
|
38
|
+
kind: z.ZodLiteral<"tool.before">;
|
|
39
|
+
at: z.ZodString;
|
|
40
|
+
sessionId: z.ZodString;
|
|
41
|
+
callId: z.ZodString;
|
|
42
|
+
tool: z.ZodString;
|
|
43
|
+
args: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
44
|
+
}, "strip", z.ZodTypeAny, {
|
|
45
|
+
at: string;
|
|
46
|
+
sessionId: string;
|
|
47
|
+
tool: string;
|
|
48
|
+
kind: "tool.before";
|
|
49
|
+
callId: string;
|
|
50
|
+
args: Record<string, unknown>;
|
|
51
|
+
}, {
|
|
52
|
+
at: string;
|
|
53
|
+
sessionId: string;
|
|
54
|
+
tool: string;
|
|
55
|
+
kind: "tool.before";
|
|
56
|
+
callId: string;
|
|
57
|
+
args: Record<string, unknown>;
|
|
58
|
+
}>, z.ZodObject<{
|
|
59
|
+
kind: z.ZodLiteral<"tool.after">;
|
|
60
|
+
at: z.ZodString;
|
|
61
|
+
sessionId: z.ZodString;
|
|
62
|
+
callId: z.ZodString;
|
|
63
|
+
success: z.ZodBoolean;
|
|
64
|
+
stdout: z.ZodOptional<z.ZodString>;
|
|
65
|
+
stderr: z.ZodOptional<z.ZodString>;
|
|
66
|
+
exitCode: z.ZodOptional<z.ZodNumber>;
|
|
67
|
+
}, "strip", z.ZodTypeAny, {
|
|
68
|
+
at: string;
|
|
69
|
+
sessionId: string;
|
|
70
|
+
success: boolean;
|
|
71
|
+
kind: "tool.after";
|
|
72
|
+
callId: string;
|
|
73
|
+
exitCode?: number | undefined;
|
|
74
|
+
stderr?: string | undefined;
|
|
75
|
+
stdout?: string | undefined;
|
|
76
|
+
}, {
|
|
77
|
+
at: string;
|
|
78
|
+
sessionId: string;
|
|
79
|
+
success: boolean;
|
|
80
|
+
kind: "tool.after";
|
|
81
|
+
callId: string;
|
|
82
|
+
exitCode?: number | undefined;
|
|
83
|
+
stderr?: string | undefined;
|
|
84
|
+
stdout?: string | undefined;
|
|
85
|
+
}>, z.ZodObject<{
|
|
86
|
+
kind: z.ZodLiteral<"system.transform">;
|
|
87
|
+
at: z.ZodString;
|
|
88
|
+
sessionId: z.ZodString;
|
|
89
|
+
}, "strip", z.ZodTypeAny, {
|
|
90
|
+
at: string;
|
|
91
|
+
sessionId: string;
|
|
92
|
+
kind: "system.transform";
|
|
93
|
+
}, {
|
|
94
|
+
at: string;
|
|
95
|
+
sessionId: string;
|
|
96
|
+
kind: "system.transform";
|
|
97
|
+
}>, z.ZodObject<{
|
|
98
|
+
kind: z.ZodLiteral<"compacting">;
|
|
99
|
+
at: z.ZodString;
|
|
100
|
+
sessionId: z.ZodString;
|
|
101
|
+
}, "strip", z.ZodTypeAny, {
|
|
102
|
+
at: string;
|
|
103
|
+
sessionId: string;
|
|
104
|
+
kind: "compacting";
|
|
105
|
+
}, {
|
|
106
|
+
at: string;
|
|
107
|
+
sessionId: string;
|
|
108
|
+
kind: "compacting";
|
|
109
|
+
}>, z.ZodObject<{
|
|
110
|
+
kind: z.ZodLiteral<"session.idle">;
|
|
111
|
+
at: z.ZodString;
|
|
112
|
+
sessionId: z.ZodString;
|
|
113
|
+
}, "strip", z.ZodTypeAny, {
|
|
114
|
+
at: string;
|
|
115
|
+
sessionId: string;
|
|
116
|
+
kind: "session.idle";
|
|
117
|
+
}, {
|
|
118
|
+
at: string;
|
|
119
|
+
sessionId: string;
|
|
120
|
+
kind: "session.idle";
|
|
121
|
+
}>]>;
|
|
122
|
+
export type ReplayEvent = z.infer<typeof replayEventSchema>;
|
|
123
|
+
export declare const replayTranscriptSchema: z.ZodObject<{
|
|
124
|
+
version: z.ZodLiteral<1>;
|
|
125
|
+
name: z.ZodString;
|
|
126
|
+
events: z.ZodArray<z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
|
|
127
|
+
kind: z.ZodLiteral<"session.created">;
|
|
128
|
+
at: z.ZodString;
|
|
129
|
+
sessionId: z.ZodString;
|
|
130
|
+
}, "strip", z.ZodTypeAny, {
|
|
131
|
+
at: string;
|
|
132
|
+
sessionId: string;
|
|
133
|
+
kind: "session.created";
|
|
134
|
+
}, {
|
|
135
|
+
at: string;
|
|
136
|
+
sessionId: string;
|
|
137
|
+
kind: "session.created";
|
|
138
|
+
}>, z.ZodObject<{
|
|
139
|
+
kind: z.ZodLiteral<"chat.message">;
|
|
140
|
+
at: z.ZodString;
|
|
141
|
+
sessionId: z.ZodString;
|
|
142
|
+
text: z.ZodString;
|
|
143
|
+
}, "strip", z.ZodTypeAny, {
|
|
144
|
+
at: string;
|
|
145
|
+
sessionId: string;
|
|
146
|
+
text: string;
|
|
147
|
+
kind: "chat.message";
|
|
148
|
+
}, {
|
|
149
|
+
at: string;
|
|
150
|
+
sessionId: string;
|
|
151
|
+
text: string;
|
|
152
|
+
kind: "chat.message";
|
|
153
|
+
}>, z.ZodObject<{
|
|
154
|
+
kind: z.ZodLiteral<"tool.before">;
|
|
155
|
+
at: z.ZodString;
|
|
156
|
+
sessionId: z.ZodString;
|
|
157
|
+
callId: z.ZodString;
|
|
158
|
+
tool: z.ZodString;
|
|
159
|
+
args: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
160
|
+
}, "strip", z.ZodTypeAny, {
|
|
161
|
+
at: string;
|
|
162
|
+
sessionId: string;
|
|
163
|
+
tool: string;
|
|
164
|
+
kind: "tool.before";
|
|
165
|
+
callId: string;
|
|
166
|
+
args: Record<string, unknown>;
|
|
167
|
+
}, {
|
|
168
|
+
at: string;
|
|
169
|
+
sessionId: string;
|
|
170
|
+
tool: string;
|
|
171
|
+
kind: "tool.before";
|
|
172
|
+
callId: string;
|
|
173
|
+
args: Record<string, unknown>;
|
|
174
|
+
}>, z.ZodObject<{
|
|
175
|
+
kind: z.ZodLiteral<"tool.after">;
|
|
176
|
+
at: z.ZodString;
|
|
177
|
+
sessionId: z.ZodString;
|
|
178
|
+
callId: z.ZodString;
|
|
179
|
+
success: z.ZodBoolean;
|
|
180
|
+
stdout: z.ZodOptional<z.ZodString>;
|
|
181
|
+
stderr: z.ZodOptional<z.ZodString>;
|
|
182
|
+
exitCode: z.ZodOptional<z.ZodNumber>;
|
|
183
|
+
}, "strip", z.ZodTypeAny, {
|
|
184
|
+
at: string;
|
|
185
|
+
sessionId: string;
|
|
186
|
+
success: boolean;
|
|
187
|
+
kind: "tool.after";
|
|
188
|
+
callId: string;
|
|
189
|
+
exitCode?: number | undefined;
|
|
190
|
+
stderr?: string | undefined;
|
|
191
|
+
stdout?: string | undefined;
|
|
192
|
+
}, {
|
|
193
|
+
at: string;
|
|
194
|
+
sessionId: string;
|
|
195
|
+
success: boolean;
|
|
196
|
+
kind: "tool.after";
|
|
197
|
+
callId: string;
|
|
198
|
+
exitCode?: number | undefined;
|
|
199
|
+
stderr?: string | undefined;
|
|
200
|
+
stdout?: string | undefined;
|
|
201
|
+
}>, z.ZodObject<{
|
|
202
|
+
kind: z.ZodLiteral<"system.transform">;
|
|
203
|
+
at: z.ZodString;
|
|
204
|
+
sessionId: z.ZodString;
|
|
205
|
+
}, "strip", z.ZodTypeAny, {
|
|
206
|
+
at: string;
|
|
207
|
+
sessionId: string;
|
|
208
|
+
kind: "system.transform";
|
|
209
|
+
}, {
|
|
210
|
+
at: string;
|
|
211
|
+
sessionId: string;
|
|
212
|
+
kind: "system.transform";
|
|
213
|
+
}>, z.ZodObject<{
|
|
214
|
+
kind: z.ZodLiteral<"compacting">;
|
|
215
|
+
at: z.ZodString;
|
|
216
|
+
sessionId: z.ZodString;
|
|
217
|
+
}, "strip", z.ZodTypeAny, {
|
|
218
|
+
at: string;
|
|
219
|
+
sessionId: string;
|
|
220
|
+
kind: "compacting";
|
|
221
|
+
}, {
|
|
222
|
+
at: string;
|
|
223
|
+
sessionId: string;
|
|
224
|
+
kind: "compacting";
|
|
225
|
+
}>, z.ZodObject<{
|
|
226
|
+
kind: z.ZodLiteral<"session.idle">;
|
|
227
|
+
at: z.ZodString;
|
|
228
|
+
sessionId: z.ZodString;
|
|
229
|
+
}, "strip", z.ZodTypeAny, {
|
|
230
|
+
at: string;
|
|
231
|
+
sessionId: string;
|
|
232
|
+
kind: "session.idle";
|
|
233
|
+
}, {
|
|
234
|
+
at: string;
|
|
235
|
+
sessionId: string;
|
|
236
|
+
kind: "session.idle";
|
|
237
|
+
}>]>, "many">;
|
|
238
|
+
}, "strip", z.ZodTypeAny, {
|
|
239
|
+
version: 1;
|
|
240
|
+
name: string;
|
|
241
|
+
events: ({
|
|
242
|
+
at: string;
|
|
243
|
+
sessionId: string;
|
|
244
|
+
kind: "session.created";
|
|
245
|
+
} | {
|
|
246
|
+
at: string;
|
|
247
|
+
sessionId: string;
|
|
248
|
+
text: string;
|
|
249
|
+
kind: "chat.message";
|
|
250
|
+
} | {
|
|
251
|
+
at: string;
|
|
252
|
+
sessionId: string;
|
|
253
|
+
tool: string;
|
|
254
|
+
kind: "tool.before";
|
|
255
|
+
callId: string;
|
|
256
|
+
args: Record<string, unknown>;
|
|
257
|
+
} | {
|
|
258
|
+
at: string;
|
|
259
|
+
sessionId: string;
|
|
260
|
+
success: boolean;
|
|
261
|
+
kind: "tool.after";
|
|
262
|
+
callId: string;
|
|
263
|
+
exitCode?: number | undefined;
|
|
264
|
+
stderr?: string | undefined;
|
|
265
|
+
stdout?: string | undefined;
|
|
266
|
+
} | {
|
|
267
|
+
at: string;
|
|
268
|
+
sessionId: string;
|
|
269
|
+
kind: "system.transform";
|
|
270
|
+
} | {
|
|
271
|
+
at: string;
|
|
272
|
+
sessionId: string;
|
|
273
|
+
kind: "compacting";
|
|
274
|
+
} | {
|
|
275
|
+
at: string;
|
|
276
|
+
sessionId: string;
|
|
277
|
+
kind: "session.idle";
|
|
278
|
+
})[];
|
|
279
|
+
}, {
|
|
280
|
+
version: 1;
|
|
281
|
+
name: string;
|
|
282
|
+
events: ({
|
|
283
|
+
at: string;
|
|
284
|
+
sessionId: string;
|
|
285
|
+
kind: "session.created";
|
|
286
|
+
} | {
|
|
287
|
+
at: string;
|
|
288
|
+
sessionId: string;
|
|
289
|
+
text: string;
|
|
290
|
+
kind: "chat.message";
|
|
291
|
+
} | {
|
|
292
|
+
at: string;
|
|
293
|
+
sessionId: string;
|
|
294
|
+
tool: string;
|
|
295
|
+
kind: "tool.before";
|
|
296
|
+
callId: string;
|
|
297
|
+
args: Record<string, unknown>;
|
|
298
|
+
} | {
|
|
299
|
+
at: string;
|
|
300
|
+
sessionId: string;
|
|
301
|
+
success: boolean;
|
|
302
|
+
kind: "tool.after";
|
|
303
|
+
callId: string;
|
|
304
|
+
exitCode?: number | undefined;
|
|
305
|
+
stderr?: string | undefined;
|
|
306
|
+
stdout?: string | undefined;
|
|
307
|
+
} | {
|
|
308
|
+
at: string;
|
|
309
|
+
sessionId: string;
|
|
310
|
+
kind: "system.transform";
|
|
311
|
+
} | {
|
|
312
|
+
at: string;
|
|
313
|
+
sessionId: string;
|
|
314
|
+
kind: "compacting";
|
|
315
|
+
} | {
|
|
316
|
+
at: string;
|
|
317
|
+
sessionId: string;
|
|
318
|
+
kind: "session.idle";
|
|
319
|
+
})[];
|
|
320
|
+
}>;
|
|
321
|
+
export interface ReplayTranscript {
|
|
322
|
+
readonly version: 1;
|
|
323
|
+
readonly name: string;
|
|
324
|
+
readonly events: readonly ReplayEvent[];
|
|
325
|
+
}
|
|
326
|
+
/** Validates an unknown payload (e.g. a parsed JSON file) as a transcript. */
|
|
327
|
+
export declare function parseTranscript(json: unknown): ReplayTranscript;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* v0.5.0 (K5-018 / plan §5.8) — replay transcript format.
|
|
4
|
+
*
|
|
5
|
+
* A hermetic, deterministic way to run a recorded session through the
|
|
6
|
+
* plugin's components and read the outcome distribution. `at` is an
|
|
7
|
+
* ISO-8601 string and is the ONLY source of time during replay:
|
|
8
|
+
* `Date.now()` must not be called anywhere in the replay path.
|
|
9
|
+
*/
|
|
10
|
+
export const replayEventSchema = z.discriminatedUnion("kind", [
|
|
11
|
+
z.object({
|
|
12
|
+
kind: z.literal("session.created"),
|
|
13
|
+
at: z.string().datetime(),
|
|
14
|
+
sessionId: z.string().min(1),
|
|
15
|
+
}),
|
|
16
|
+
z.object({
|
|
17
|
+
kind: z.literal("chat.message"),
|
|
18
|
+
at: z.string().datetime(),
|
|
19
|
+
sessionId: z.string().min(1),
|
|
20
|
+
text: z.string().min(1),
|
|
21
|
+
}),
|
|
22
|
+
z.object({
|
|
23
|
+
kind: z.literal("tool.before"),
|
|
24
|
+
at: z.string().datetime(),
|
|
25
|
+
sessionId: z.string().min(1),
|
|
26
|
+
callId: z.string().min(1),
|
|
27
|
+
tool: z.string().min(1),
|
|
28
|
+
args: z.record(z.string(), z.unknown()),
|
|
29
|
+
}),
|
|
30
|
+
z.object({
|
|
31
|
+
kind: z.literal("tool.after"),
|
|
32
|
+
at: z.string().datetime(),
|
|
33
|
+
sessionId: z.string().min(1),
|
|
34
|
+
callId: z.string().min(1),
|
|
35
|
+
success: z.boolean(),
|
|
36
|
+
stdout: z.string().optional(),
|
|
37
|
+
stderr: z.string().optional(),
|
|
38
|
+
exitCode: z.number().int().optional(),
|
|
39
|
+
}),
|
|
40
|
+
z.object({
|
|
41
|
+
kind: z.literal("system.transform"),
|
|
42
|
+
at: z.string().datetime(),
|
|
43
|
+
sessionId: z.string().min(1),
|
|
44
|
+
}),
|
|
45
|
+
z.object({
|
|
46
|
+
kind: z.literal("compacting"),
|
|
47
|
+
at: z.string().datetime(),
|
|
48
|
+
sessionId: z.string().min(1),
|
|
49
|
+
}),
|
|
50
|
+
z.object({
|
|
51
|
+
kind: z.literal("session.idle"),
|
|
52
|
+
at: z.string().datetime(),
|
|
53
|
+
sessionId: z.string().min(1),
|
|
54
|
+
}),
|
|
55
|
+
]);
|
|
56
|
+
export const replayTranscriptSchema = z.object({
|
|
57
|
+
version: z.literal(1),
|
|
58
|
+
name: z.string().min(1),
|
|
59
|
+
events: z.array(replayEventSchema).min(1),
|
|
60
|
+
});
|
|
61
|
+
/** Validates an unknown payload (e.g. a parsed JSON file) as a transcript. */
|
|
62
|
+
export function parseTranscript(json) {
|
|
63
|
+
return replayTranscriptSchema.parse(json);
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=replay-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay-types.js","sourceRoot":"","sources":["../../plugin/replay-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ReplayTranscript } from "./replay-types.js";
|
|
2
|
+
/**
|
|
3
|
+
* v0.5.0 (K5-019 / plan §5.8, D5-12) — replay harness.
|
|
4
|
+
*
|
|
5
|
+
* Hermetic, deterministic driver: runs a recorded transcript through the
|
|
6
|
+
* plugin's components against an in-memory database with a frozen clock,
|
|
7
|
+
* then reports the outcome distribution. This is an artifact, not a
|
|
8
|
+
* release gate.
|
|
9
|
+
*
|
|
10
|
+
* The components are instantiated directly — NOT through `KevinPlugin`,
|
|
11
|
+
* which resolves a home-directory database path and registers tools.
|
|
12
|
+
* `Date.now()` must never be called in this path; every clock need is
|
|
13
|
+
* satisfied by the event's `at` timestamp (retrieval is frozen by the
|
|
14
|
+
* `deterministic_retrieval` setting; the Archiver clock is injected).
|
|
15
|
+
*/
|
|
16
|
+
export interface ReplayResult {
|
|
17
|
+
readonly transcript: string;
|
|
18
|
+
readonly memoriesCreated: number;
|
|
19
|
+
readonly injections: {
|
|
20
|
+
total: number;
|
|
21
|
+
effective: number;
|
|
22
|
+
ineffective: number;
|
|
23
|
+
inconclusive: number;
|
|
24
|
+
unmeasured: number;
|
|
25
|
+
};
|
|
26
|
+
readonly precisionRate: number;
|
|
27
|
+
readonly coverageRate: number;
|
|
28
|
+
readonly tokensInjected: {
|
|
29
|
+
prePrompt: number;
|
|
30
|
+
compacting: number;
|
|
31
|
+
};
|
|
32
|
+
readonly blocked: Record<string, number>;
|
|
33
|
+
}
|
|
34
|
+
export declare function replay(transcript: ReplayTranscript, opts?: {
|
|
35
|
+
dbPath?: string;
|
|
36
|
+
}): Promise<ReplayResult>;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { dirname, join } from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { Archiver } from "./Archiver.js";
|
|
4
|
+
import { CausalChain } from "./CausalChain.js";
|
|
5
|
+
import { ContextInjector } from "./ContextInjector.js";
|
|
6
|
+
import { InjectionLedger } from "./InjectionLedger.js";
|
|
7
|
+
import { MemoryService } from "./MemoryService.js";
|
|
8
|
+
import { Migrate } from "./Migrate.js";
|
|
9
|
+
import { Reflector } from "./Reflector.js";
|
|
10
|
+
import { Store } from "./Store.js";
|
|
11
|
+
import { ToolCallObserver } from "./ToolCallObserver.js";
|
|
12
|
+
import { Metrics } from "./metrics.js";
|
|
13
|
+
const MIGRATIONS_DIR = join(dirname(fileURLToPath(import.meta.url)), "..", "migrations");
|
|
14
|
+
export async function replay(transcript, opts) {
|
|
15
|
+
const store = new Store({ path: opts?.dbPath ?? ":memory:" });
|
|
16
|
+
await new Migrate(store, MIGRATIONS_DIR).run();
|
|
17
|
+
// Freeze retrieval BEFORE any query happens (K5-008): deterministic
|
|
18
|
+
// mode uses the DATE_NOW sentinel, ignores recency and never bumps.
|
|
19
|
+
store
|
|
20
|
+
.prepare("INSERT OR IGNORE INTO kevin_settings (key, value) VALUES ('deterministic_retrieval', '1')")
|
|
21
|
+
.run();
|
|
22
|
+
store
|
|
23
|
+
.prepare("UPDATE kevin_settings SET value = '1' WHERE key = 'deterministic_retrieval'")
|
|
24
|
+
.run();
|
|
25
|
+
const metrics = new Metrics(store);
|
|
26
|
+
const memoryService = new MemoryService(store, metrics);
|
|
27
|
+
const observer = new ToolCallObserver(store, metrics);
|
|
28
|
+
// v0.3.0 fix (mirrors index.ts) — the Reflector stamps
|
|
29
|
+
// tool_calls.error_fingerprint with the stderr-based fingerprint the
|
|
30
|
+
// error memory uses; without it the recurrence queries in settle and
|
|
31
|
+
// the feedback loop never match (tool_calls.fingerprint is keyed on
|
|
32
|
+
// `${tool}|${args}|${success}`, memories on a hash of stderr/stdout).
|
|
33
|
+
const linkErrorStmt = store.prepare("UPDATE tool_calls SET error_fingerprint = ? WHERE id = ?");
|
|
34
|
+
const reflector = new Reflector(memoryService, {
|
|
35
|
+
throttleMs: 0,
|
|
36
|
+
onLinkError: (callID, fp) => {
|
|
37
|
+
linkErrorStmt.run(fp, callID);
|
|
38
|
+
},
|
|
39
|
+
}, metrics);
|
|
40
|
+
const ledger = new InjectionLedger(store, metrics);
|
|
41
|
+
const injector = new ContextInjector(memoryService, metrics, ledger);
|
|
42
|
+
const causalChain = new CausalChain(store, memoryService, metrics);
|
|
43
|
+
// The Archiver reads the clock through this accessor, which is updated
|
|
44
|
+
// to the current event's `at` before each event is processed.
|
|
45
|
+
let currentAt = new Date(transcript.events[0]?.at ?? Date.now());
|
|
46
|
+
const archiver = new Archiver(store, memoryService, metrics, () => currentAt);
|
|
47
|
+
const lastUserQueryBySession = new Map();
|
|
48
|
+
const callCache = new Map();
|
|
49
|
+
function resolveQuery(sessionId) {
|
|
50
|
+
return lastUserQueryBySession.get(sessionId) ?? "";
|
|
51
|
+
}
|
|
52
|
+
for (const event of transcript.events) {
|
|
53
|
+
currentAt = new Date(event.at);
|
|
54
|
+
await handleEvent(event);
|
|
55
|
+
}
|
|
56
|
+
metrics.flush();
|
|
57
|
+
const outcomeRows = store
|
|
58
|
+
.prepare("SELECT outcome, COUNT(*) AS n FROM kevin_injections GROUP BY outcome")
|
|
59
|
+
.all();
|
|
60
|
+
const counts = {
|
|
61
|
+
unmeasured: 0,
|
|
62
|
+
effective: 0,
|
|
63
|
+
ineffective: 0,
|
|
64
|
+
inconclusive: 0,
|
|
65
|
+
};
|
|
66
|
+
for (const r of outcomeRows) {
|
|
67
|
+
counts[r.outcome] = r.n;
|
|
68
|
+
}
|
|
69
|
+
const total = outcomeRows.reduce((acc, r) => acc + r.n, 0);
|
|
70
|
+
const tokenValue = (key) => {
|
|
71
|
+
const row = store
|
|
72
|
+
.prepare("SELECT value FROM kevin_metrics WHERE key = ?")
|
|
73
|
+
.get(key);
|
|
74
|
+
return row?.value ?? 0;
|
|
75
|
+
};
|
|
76
|
+
return {
|
|
77
|
+
transcript: transcript.name,
|
|
78
|
+
memoriesCreated: totalMemories(store),
|
|
79
|
+
injections: {
|
|
80
|
+
total,
|
|
81
|
+
effective: counts.effective,
|
|
82
|
+
ineffective: counts.ineffective,
|
|
83
|
+
inconclusive: counts.inconclusive,
|
|
84
|
+
unmeasured: counts.unmeasured,
|
|
85
|
+
},
|
|
86
|
+
precisionRate: metrics.precisionRate(),
|
|
87
|
+
coverageRate: metrics.coverageRate(),
|
|
88
|
+
tokensInjected: {
|
|
89
|
+
prePrompt: tokenValue("tokens_injected_pre_prompt"),
|
|
90
|
+
compacting: tokenValue("tokens_injected_compacting"),
|
|
91
|
+
},
|
|
92
|
+
blocked: metrics.blockedSnapshot(),
|
|
93
|
+
};
|
|
94
|
+
async function handleEvent(event) {
|
|
95
|
+
switch (event.kind) {
|
|
96
|
+
case "session.created":
|
|
97
|
+
// Mirror of the live wiring (index.ts): a fresh session must
|
|
98
|
+
// not inherit the previous session's injection seen-set
|
|
99
|
+
// (plan §5.1 rule 3). Without this, a multi-session
|
|
100
|
+
// transcript would block every memory in session 2 with
|
|
101
|
+
// `seen_this_session` while the live plugin would admit it.
|
|
102
|
+
injector.onSessionCreated(event.sessionId);
|
|
103
|
+
return;
|
|
104
|
+
case "chat.message": {
|
|
105
|
+
const derived = injector.deriveQuery([
|
|
106
|
+
{ role: "user", content: event.text },
|
|
107
|
+
]);
|
|
108
|
+
if (derived.length > 0) {
|
|
109
|
+
lastUserQueryBySession.set(event.sessionId, derived);
|
|
110
|
+
}
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
case "tool.before": {
|
|
114
|
+
callCache.set(event.callId, {
|
|
115
|
+
tool: event.tool,
|
|
116
|
+
args: event.args,
|
|
117
|
+
});
|
|
118
|
+
observer.onBefore({
|
|
119
|
+
tool: event.tool,
|
|
120
|
+
args: event.args,
|
|
121
|
+
sessionId: event.sessionId,
|
|
122
|
+
callID: event.callId,
|
|
123
|
+
projectId: null,
|
|
124
|
+
}, {});
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
case "tool.after": {
|
|
128
|
+
const cached = callCache.get(event.callId);
|
|
129
|
+
const tool = cached?.tool ?? "unknown";
|
|
130
|
+
const args = cached?.args ?? {};
|
|
131
|
+
const stderr = event.stderr ?? "";
|
|
132
|
+
const stdout = event.stdout ?? "";
|
|
133
|
+
observer.onAfter({
|
|
134
|
+
tool,
|
|
135
|
+
args,
|
|
136
|
+
sessionId: event.sessionId,
|
|
137
|
+
callID: event.callId,
|
|
138
|
+
projectId: null,
|
|
139
|
+
}, { success: event.success, stdout, stderr, exitCode: event.exitCode });
|
|
140
|
+
if (!event.success) {
|
|
141
|
+
await reflector.invoke({
|
|
142
|
+
toolName: tool,
|
|
143
|
+
argsSummary: observer.summarizeArgs(args),
|
|
144
|
+
stderr,
|
|
145
|
+
stdout,
|
|
146
|
+
exitCode: event.exitCode,
|
|
147
|
+
errorType: observer.inferErrorType(stderr, stdout, event.exitCode),
|
|
148
|
+
sessionId: event.sessionId,
|
|
149
|
+
callID: event.callId,
|
|
150
|
+
projectId: null,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
causalChain.onSuccess(tool, args, null, event.sessionId);
|
|
155
|
+
}
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
case "system.transform": {
|
|
159
|
+
const query = resolveQuery(event.sessionId);
|
|
160
|
+
if (!query)
|
|
161
|
+
return;
|
|
162
|
+
const output = { system: [] };
|
|
163
|
+
injector.onSystemTransform({
|
|
164
|
+
sessionID: event.sessionId,
|
|
165
|
+
messages: [{ role: "user", content: query }],
|
|
166
|
+
}, output);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
case "compacting": {
|
|
170
|
+
const query = resolveQuery(event.sessionId);
|
|
171
|
+
if (!query)
|
|
172
|
+
return;
|
|
173
|
+
const output = { context: [] };
|
|
174
|
+
injector.onCompacting({
|
|
175
|
+
sessionID: event.sessionId,
|
|
176
|
+
messages: [{ role: "user", content: query }],
|
|
177
|
+
}, output);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
case "session.idle": {
|
|
181
|
+
ledger.settle(event.sessionId);
|
|
182
|
+
archiver.run();
|
|
183
|
+
metrics.flush();
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function totalMemories(store) {
|
|
190
|
+
const row = store.prepare("SELECT COUNT(*) AS n FROM memories").get();
|
|
191
|
+
return row.n ?? 0;
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=replay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.js","sourceRoot":"","sources":["../../plugin/replay.ts"],"names":[],"mappings":"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"}
|