kernl 0.11.4 → 0.12.1

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.
Files changed (36) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +59 -0
  3. package/dist/agent/__tests__/run.test.js +2 -2
  4. package/dist/index.d.ts +1 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/lifecycle/__tests__/hooks.test.js +6 -6
  7. package/dist/storage/__tests__/in-memory.test.js +1 -1
  8. package/dist/thread/__tests__/fixtures/mock-model.js +3 -3
  9. package/dist/thread/__tests__/mock.d.ts +2 -3
  10. package/dist/thread/__tests__/mock.d.ts.map +1 -1
  11. package/dist/thread/__tests__/thread-persistence.test.js +6 -6
  12. package/dist/thread/__tests__/thread.test.js +22 -22
  13. package/dist/thread/thread.d.ts +4 -0
  14. package/dist/thread/thread.d.ts.map +1 -1
  15. package/dist/thread/thread.js +47 -79
  16. package/dist/thread/types.d.ts +18 -3
  17. package/dist/thread/types.d.ts.map +1 -1
  18. package/dist/thread/utils.d.ts +7 -7
  19. package/dist/thread/utils.d.ts.map +1 -1
  20. package/dist/thread/utils.js +6 -6
  21. package/package.json +5 -7
  22. package/src/agent/__tests__/run.test.ts +2 -2
  23. package/src/index.ts +1 -0
  24. package/src/lifecycle/__tests__/hooks.test.ts +6 -6
  25. package/src/storage/__tests__/in-memory.test.ts +1 -1
  26. package/src/thread/__tests__/fixtures/mock-model.ts +3 -3
  27. package/src/thread/__tests__/mock.ts +2 -2
  28. package/src/thread/__tests__/thread-persistence.test.ts +6 -6
  29. package/src/thread/__tests__/thread.test.ts +22 -22
  30. package/src/thread/thread.ts +51 -82
  31. package/src/thread/types.ts +49 -3
  32. package/src/thread/utils.ts +19 -12
  33. package/dist/thread/__tests__/integration.test.d.ts +0 -2
  34. package/dist/thread/__tests__/integration.test.d.ts.map +0 -1
  35. package/dist/thread/__tests__/integration.test.js +0 -320
  36. package/src/thread/__tests__/integration.test.ts +0 -434
@@ -120,33 +120,14 @@ export class Thread {
120
120
  this.abort = new AbortController();
121
121
  this.tickres = undefined; // reset for this run
122
122
  await this.checkpoint(); /* c1: persist RUNNING state + initial input */
123
- this.agent.emit("thread.start", {
124
- kind: "thread.start",
125
- threadId: this.tid,
126
- agentId: this.agent.id,
127
- namespace: this.namespace,
128
- context: this.context,
129
- });
130
- yield { kind: "stream-start" }; // always yield start immediately
123
+ this.emit("thread.start");
124
+ yield { kind: "stream.start" }; // always yield start immediately
131
125
  try {
132
126
  yield* this._execute();
133
- this.agent.emit("thread.stop", {
134
- kind: "thread.stop",
135
- threadId: this.tid,
136
- agentId: this.agent.id,
137
- namespace: this.namespace,
138
- context: this.context,
139
- state: STOPPED,
140
- result: this.tickres,
141
- });
127
+ this.emit("thread.stop", { state: STOPPED, result: this.tickres });
142
128
  }
143
129
  catch (err) {
144
- this.agent.emit("thread.stop", {
145
- kind: "thread.stop",
146
- threadId: this.tid,
147
- agentId: this.agent.id,
148
- namespace: this.namespace,
149
- context: this.context,
130
+ this.emit("thread.stop", {
150
131
  state: STOPPED,
151
132
  error: err instanceof Error ? err.message : String(err),
152
133
  });
@@ -176,12 +157,15 @@ export class Thread {
176
157
  err = e.error;
177
158
  logger.error(e.error); // (TODO): onError callback in options
178
159
  }
179
- // we don't want deltas in the history
160
+ // complete items get persisted with seq, deltas are ephemeral
180
161
  if (notDelta(e)) {
181
- events.push(e);
182
- this.append(e);
162
+ const [seqd] = this.append(e);
163
+ events.push(seqd);
164
+ yield seqd;
165
+ }
166
+ else {
167
+ yield e;
183
168
  }
184
- yield e;
185
169
  }
186
170
  // if an error event occurred → throw it
187
171
  if (err) {
@@ -201,10 +185,10 @@ export class Thread {
201
185
  }
202
186
  // perform intended actions
203
187
  const { actions, pendingApprovals } = await this.performActions(intentions);
204
- // append + yield action events
188
+ // append + yield action events (sequenced)
205
189
  for (const a of actions) {
206
- this.append(a);
207
- yield a;
190
+ const [seqd] = this.append(a);
191
+ yield seqd;
208
192
  }
209
193
  await this.checkpoint(); /* c3: tick complete */
210
194
  if (pendingApprovals.length > 0) {
@@ -228,16 +212,9 @@ export class Thread {
228
212
  this._tick++;
229
213
  // (TODO): check limits (if this._tick > this.limits.maxTicks)
230
214
  // (TODO): run input guardrails on first tick (if this._tick === 1)
215
+ // (TODO): compaction if necessary
231
216
  const req = await this.prepareModelRequest(this.history);
232
- this.agent.emit("model.call.start", {
233
- kind: "model.call.start",
234
- provider: this.model.provider,
235
- modelId: this.model.modelId,
236
- settings: req.settings ?? {},
237
- threadId: this.tid,
238
- agentId: this.agent.id,
239
- context: this.context,
240
- });
217
+ this.emit("model.call.start", { settings: req.settings ?? {} });
241
218
  let usage;
242
219
  let finishReason = "unknown";
243
220
  try {
@@ -259,27 +236,10 @@ export class Thread {
259
236
  yield event;
260
237
  }
261
238
  }
262
- this.agent.emit("model.call.end", {
263
- kind: "model.call.end",
264
- provider: this.model.provider,
265
- modelId: this.model.modelId,
266
- finishReason,
267
- usage,
268
- threadId: this.tid,
269
- agentId: this.agent.id,
270
- context: this.context,
271
- });
239
+ this.emit("model.call.end", { finishReason, usage });
272
240
  }
273
241
  catch (error) {
274
- this.agent.emit("model.call.end", {
275
- kind: "model.call.end",
276
- provider: this.model.provider,
277
- modelId: this.model.modelId,
278
- finishReason: "error",
279
- threadId: this.tid,
280
- agentId: this.agent.id,
281
- context: this.context,
282
- });
242
+ this.emit("model.call.end", { finishReason: "error" });
283
243
  yield {
284
244
  kind: "error",
285
245
  error: error instanceof Error ? error : new Error(String(error)),
@@ -356,9 +316,29 @@ export class Thread {
356
316
  cancel() {
357
317
  this.abort?.abort();
358
318
  }
359
- // ----------------------------
360
- // utils
361
- // ----------------------------
319
+ /**
320
+ * Emit an agent event with common fields auto-filled.
321
+ */
322
+ emit(kind, payload) {
323
+ const base = {
324
+ kind,
325
+ threadId: this.tid,
326
+ agentId: this.agent.id,
327
+ context: this.context,
328
+ };
329
+ let auto = {};
330
+ switch (kind) {
331
+ case "thread.start":
332
+ case "thread.stop":
333
+ auto = { namespace: this.namespace };
334
+ break;
335
+ case "model.call.start":
336
+ case "model.call.end":
337
+ auto = { provider: this.model.provider, modelId: this.model.modelId };
338
+ break;
339
+ }
340
+ this.agent.emit(kind, { ...base, ...auto, ...payload });
341
+ }
362
342
  /**
363
343
  * Perform the actions returned by the model
364
344
  */
@@ -380,7 +360,7 @@ export class Thread {
380
360
  const pendingApprovals = [];
381
361
  // (TODO): clean this - approval tracking should be handled differently
382
362
  for (const e of toolEvents) {
383
- if (e.kind === "tool-result" &&
363
+ if (e.kind === "tool.result" &&
384
364
  e.state === "requires_approval" // (TODO): fix this
385
365
  ) {
386
366
  // find the original tool call for this pending approval
@@ -404,11 +384,7 @@ export class Thread {
404
384
  async executeTools(calls) {
405
385
  return await Promise.all(calls.map(async (call) => {
406
386
  const parsedArgs = JSON.parse(call.arguments || "{}");
407
- this.agent.emit("tool.call.start", {
408
- kind: "tool.call.start",
409
- threadId: this.tid,
410
- agentId: this.agent.id,
411
- context: this.context,
387
+ this.emit("tool.call.start", {
412
388
  toolId: call.toolId,
413
389
  callId: call.callId,
414
390
  args: parsedArgs,
@@ -426,11 +402,7 @@ export class Thread {
426
402
  ctx.agent = this.agent;
427
403
  ctx.approve(call.callId); // mark this call as approved
428
404
  const res = await tool.invoke(ctx, call.arguments, call.callId);
429
- this.agent.emit("tool.call.end", {
430
- kind: "tool.call.end",
431
- threadId: this.tid,
432
- agentId: this.agent.id,
433
- context: this.context,
405
+ this.emit("tool.call.end", {
434
406
  toolId: call.toolId,
435
407
  callId: call.callId,
436
408
  state: res.state,
@@ -440,7 +412,7 @@ export class Thread {
440
412
  error: res.error,
441
413
  });
442
414
  return {
443
- kind: "tool-result",
415
+ kind: "tool.result",
444
416
  callId: call.callId,
445
417
  toolId: call.toolId,
446
418
  state: res.state,
@@ -449,18 +421,14 @@ export class Thread {
449
421
  };
450
422
  }
451
423
  catch (error) {
452
- this.agent.emit("tool.call.end", {
453
- kind: "tool.call.end",
454
- threadId: this.tid,
455
- agentId: this.agent.id,
456
- context: this.context,
424
+ this.emit("tool.call.end", {
457
425
  toolId: call.toolId,
458
426
  callId: call.callId,
459
427
  state: FAILED,
460
428
  error: error instanceof Error ? error.message : String(error),
461
429
  });
462
430
  return {
463
- kind: "tool-result",
431
+ kind: "tool.result",
464
432
  callId: call.callId,
465
433
  toolId: call.toolId,
466
434
  state: FAILED,
@@ -1,4 +1,4 @@
1
- import { ToolCall, LanguageModel, LanguageModelItem, LanguageModelStreamEvent, RUNNING, STOPPED, INTERRUPTIBLE, UNINTERRUPTIBLE, ZOMBIE, DEAD } from "@kernl-sdk/protocol";
1
+ import { ToolCall, LanguageModel, LanguageModelItem, RUNNING, STOPPED, INTERRUPTIBLE, UNINTERRUPTIBLE, ZOMBIE, DEAD, TextStartEvent, TextEndEvent, TextDeltaEvent, ReasoningStartEvent, ReasoningEndEvent, ReasoningDeltaEvent, ToolInputStartEvent, ToolInputEndEvent, ToolInputDeltaEvent, StartEvent, FinishEvent, AbortEvent, ErrorEvent, RawEvent } from "@kernl-sdk/protocol";
2
2
  import { Task } from "../task.js";
3
3
  import { Context } from "../context.js";
4
4
  import { Agent } from "../agent.js";
@@ -79,9 +79,24 @@ export interface ThreadSystemEvent extends ThreadEventBase {
79
79
  */
80
80
  export type ThreadEvent = (LanguageModelItem & ThreadEventBase) | ThreadSystemEvent;
81
81
  /**
82
- * Stream events - use protocol definition directly.
82
+ * Incremental content chunks (ephemeral, not persisted).
83
83
  */
84
- export type ThreadStreamEvent = LanguageModelStreamEvent;
84
+ export type StreamDeltaEvent = TextDeltaEvent | ReasoningDeltaEvent | ToolInputDeltaEvent;
85
+ /**
86
+ * Boundary markers + control flow (ephemeral, not persisted).
87
+ */
88
+ export type StreamControlEvent = TextStartEvent | TextEndEvent | ReasoningStartEvent | ReasoningEndEvent | ToolInputStartEvent | ToolInputEndEvent | StartEvent | FinishEvent | AbortEvent | ErrorEvent | RawEvent;
89
+ /**
90
+ * All ephemeral stream types (not persisted to history).
91
+ */
92
+ export type StreamEvent = StreamDeltaEvent | StreamControlEvent;
93
+ /**
94
+ * Thread stream events = sequenced ThreadEvents + ephemeral StreamEvents.
95
+ *
96
+ * Complete items (Message, ToolCall, etc.) are yielded as ThreadEvents with seq.
97
+ * Deltas and control events are yielded as StreamEvents without seq.
98
+ */
99
+ export type ThreadStreamEvent = ThreadEvent | StreamEvent;
85
100
  /**
86
101
  * Result of thread execution
87
102
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/thread/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/thread/types.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  import type { ResolvedAgentResponse } from "../guardrail.js";
2
- import { ToolCall, LanguageModelItem } from "@kernl-sdk/protocol";
2
+ import { ToolCall, LanguageModelItem, LanguageModelStreamEvent } from "@kernl-sdk/protocol";
3
3
  import type { AgentOutputType } from "../agent/types.js";
4
- import type { ThreadEvent, ThreadStreamEvent, ActionSet, PublicThreadEvent } from "./types.js";
4
+ import type { ThreadEvent, ThreadEventBase, ActionSet, PublicThreadEvent } from "./types.js";
5
5
  /**
6
6
  * Create a ThreadEvent from a LanguageModelItem with thread metadata.
7
7
  *
8
8
  * @example
9
- * ```typescript
9
+ * ```ts
10
10
  * tevent({
11
11
  * kind: "message",
12
12
  * seq: 0,
@@ -28,17 +28,17 @@ export declare function tevent(event: {
28
28
  /**
29
29
  * Check if an event is a tool call
30
30
  */
31
- export declare function isActionIntention(event: LanguageModelItem): event is ToolCall;
31
+ export declare function isActionIntention(event: ThreadEvent): event is ToolCall & ThreadEventBase;
32
32
  /**
33
33
  * Extract action intentions from a list of events.
34
34
  * Returns ActionSet if there are any tool calls, null otherwise.
35
35
  */
36
- export declare function getIntentions(events: LanguageModelItem[]): ActionSet | null;
36
+ export declare function getIntentions(events: ThreadEvent[]): ActionSet | null;
37
37
  /**
38
38
  * Check if an event is NOT a delta/start/end event (i.e., a complete item).
39
39
  * Returns true for complete items: Message, Reasoning, ToolCall, ToolResult
40
40
  */
41
- export declare function notDelta(event: ThreadStreamEvent): event is LanguageModelItem;
41
+ export declare function notDelta(event: LanguageModelStreamEvent): event is LanguageModelItem;
42
42
  /**
43
43
  * Check if an event is public/client-facing (not internal).
44
44
  * Filters out internal system events that clients don't need.
@@ -48,7 +48,7 @@ export declare function isPublicEvent(event: ThreadEvent): event is PublicThread
48
48
  * Extract the final text response from a list of items.
49
49
  * Returns null if no assistant message with text content is found.
50
50
  */
51
- export declare function getFinalResponse(items: LanguageModelItem[]): string | null;
51
+ export declare function getFinalResponse(items: ThreadEvent[]): string | null;
52
52
  /**
53
53
  * Parse the final response according to the output type schema.
54
54
  *
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/thread/utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAIzD,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAIlE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EACV,WAAW,EAEX,iBAAiB,EACjB,SAAS,EACT,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1B,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,GAAG,WAAW,CAad;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,GAAG,KAAK,IAAI,QAAQ,CAE7E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,SAAS,GAAG,IAAI,CAG3E;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,KAAK,IAAI,iBAAiB,CAY7E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,KAAK,IAAI,iBAAiB,CAc5E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,MAAM,GAAG,IAAI,CAa1E;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,SAAS,eAAe,EAChE,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,OAAO,GACd,qBAAqB,CAAC,OAAO,CAAC,CAsBhC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/thread/utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAIzD,OAAO,EACL,QAAQ,EACR,iBAAiB,EACjB,wBAAwB,EACzB,MAAM,qBAAqB,CAAC;AAI7B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EACV,WAAW,EACX,eAAe,EACf,SAAS,EACT,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1B,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,GAAG,WAAW,CAad;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,WAAW,GACjB,KAAK,IAAI,QAAQ,GAAG,eAAe,CAErC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,GAAG,IAAI,CAGrE;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,wBAAwB,GAC9B,KAAK,IAAI,iBAAiB,CAY5B;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,KAAK,IAAI,iBAAiB,CAc5E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,GAAG,IAAI,CAapE;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,SAAS,eAAe,EAChE,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,OAAO,GACd,qBAAqB,CAAC,OAAO,CAAC,CAsBhC"}
@@ -5,7 +5,7 @@ import { ModelBehaviorError } from "../lib/error.js";
5
5
  * Create a ThreadEvent from a LanguageModelItem with thread metadata.
6
6
  *
7
7
  * @example
8
- * ```typescript
8
+ * ```ts
9
9
  * tevent({
10
10
  * kind: "message",
11
11
  * seq: 0,
@@ -32,7 +32,7 @@ export function tevent(event) {
32
32
  * Check if an event is a tool call
33
33
  */
34
34
  export function isActionIntention(event) {
35
- return event.kind === "tool-call";
35
+ return event.kind === "tool.call";
36
36
  }
37
37
  /**
38
38
  * Extract action intentions from a list of events.
@@ -50,8 +50,8 @@ export function notDelta(event) {
50
50
  switch (event.kind) {
51
51
  case "message":
52
52
  case "reasoning":
53
- case "tool-call":
54
- case "tool-result":
53
+ case "tool.call":
54
+ case "tool.result":
55
55
  return true;
56
56
  // all other events are streaming deltas/control events
57
57
  default:
@@ -66,8 +66,8 @@ export function isPublicEvent(event) {
66
66
  switch (event.kind) {
67
67
  case "message":
68
68
  case "reasoning":
69
- case "tool-call":
70
- case "tool-result":
69
+ case "tool.call":
70
+ case "tool.result":
71
71
  return true;
72
72
  case "system":
73
73
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kernl",
3
- "version": "0.11.4",
3
+ "version": "0.12.1",
4
4
  "description": "A modern AI agent framework",
5
5
  "keywords": [
6
6
  "kernl",
@@ -34,21 +34,19 @@
34
34
  "dependencies": {
35
35
  "@modelcontextprotocol/sdk": "^1.20.2",
36
36
  "yaml": "^2.8.2",
37
- "@kernl-sdk/protocol": "0.4.2",
38
- "@kernl-sdk/shared": "^0.4.0",
39
- "@kernl-sdk/retrieval": "0.1.8"
37
+ "@kernl-sdk/protocol": "0.5.0",
38
+ "@kernl-sdk/retrieval": "0.1.9",
39
+ "@kernl-sdk/shared": "^0.4.0"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "zod": "^4.1.8"
43
43
  },
44
44
  "devDependencies": {
45
- "@ai-sdk/openai": "3.0.0-beta.57",
46
45
  "@types/node": "^24.10.0",
47
46
  "tsc-alias": "^1.8.10",
48
47
  "typescript": "5.9.2",
49
48
  "vitest": "^4.0.8",
50
- "zod": "^4.1.8",
51
- "@kernl-sdk/ai": "0.3.5"
49
+ "zod": "^4.1.8"
52
50
  },
53
51
  "scripts": {
54
52
  "clean": "rm -rf dist",
@@ -268,7 +268,7 @@ describe("Agent.stream() lifecycle", () => {
268
268
  events.push(event);
269
269
  }
270
270
 
271
- expect(events[0]).toEqual({ kind: "stream-start" });
271
+ expect(events[0]).toEqual({ kind: "stream.start" });
272
272
  });
273
273
 
274
274
  it("should have same persistence behavior as run()", async () => {
@@ -305,7 +305,7 @@ describe("Agent.stream() lifecycle", () => {
305
305
  // Should have streamed events
306
306
  expect(events).toEqual(
307
307
  expect.arrayContaining([
308
- { kind: "stream-start" },
308
+ { kind: "stream.start" },
309
309
  expect.objectContaining({ kind: "message" }),
310
310
  ]),
311
311
  );
package/src/index.ts CHANGED
@@ -56,6 +56,7 @@ export {
56
56
  THREAD_STATES,
57
57
  type ThreadState,
58
58
  type PublicThreadEvent,
59
+ type ThreadStreamEvent,
59
60
  } from "./thread/types";
60
61
 
61
62
  // --- storage ---
@@ -308,7 +308,7 @@ describe("Lifecycle Hooks", () => {
308
308
  content: [
309
309
  message({ role: "assistant", text: "" }),
310
310
  {
311
- kind: "tool-call" as const,
311
+ kind: "tool.call" as const,
312
312
  toolId: "echo",
313
313
  state: IN_PROGRESS,
314
314
  callId: "call_1",
@@ -381,7 +381,7 @@ describe("Lifecycle Hooks", () => {
381
381
  content: [
382
382
  message({ role: "assistant", text: "" }),
383
383
  {
384
- kind: "tool-call" as const,
384
+ kind: "tool.call" as const,
385
385
  toolId: "add",
386
386
  state: IN_PROGRESS,
387
387
  callId: "call_1",
@@ -446,7 +446,7 @@ describe("Lifecycle Hooks", () => {
446
446
  content: [
447
447
  message({ role: "assistant", text: "" }),
448
448
  {
449
- kind: "tool-call" as const,
449
+ kind: "tool.call" as const,
450
450
  toolId: "add",
451
451
  state: IN_PROGRESS,
452
452
  callId: "call_1",
@@ -510,7 +510,7 @@ describe("Lifecycle Hooks", () => {
510
510
  content: [
511
511
  message({ role: "assistant", text: "" }),
512
512
  {
513
- kind: "tool-call" as const,
513
+ kind: "tool.call" as const,
514
514
  toolId: "failing",
515
515
  state: IN_PROGRESS,
516
516
  callId: "call_1",
@@ -576,14 +576,14 @@ describe("Lifecycle Hooks", () => {
576
576
  content: [
577
577
  message({ role: "assistant", text: "" }),
578
578
  {
579
- kind: "tool-call" as const,
579
+ kind: "tool.call" as const,
580
580
  toolId: "tool1",
581
581
  state: IN_PROGRESS,
582
582
  callId: "call_1",
583
583
  arguments: JSON.stringify({ value: "a" }),
584
584
  },
585
585
  {
586
- kind: "tool-call" as const,
586
+ kind: "tool.call" as const,
587
587
  toolId: "tool2",
588
588
  state: IN_PROGRESS,
589
589
  callId: "call_2",
@@ -367,7 +367,7 @@ describe("InMemoryThreadStore", () => {
367
367
  it("should filter by kinds", async () => {
368
368
  await store.append([
369
369
  {
370
- kind: "tool-call",
370
+ kind: "tool.call",
371
371
  id: "tc-1",
372
372
  tid: "thread-1",
373
373
  seq: 3,
@@ -20,18 +20,18 @@ async function* streamFromResponse(
20
20
  if (contentItem.kind === "text") {
21
21
  // Yield text-start
22
22
  yield {
23
- kind: "text-start" as const,
23
+ kind: "text.start" as const,
24
24
  id: item.id,
25
25
  };
26
26
  // Yield text-delta
27
27
  yield {
28
- kind: "text-delta" as const,
28
+ kind: "text.delta" as const,
29
29
  id: item.id,
30
30
  text: contentItem.text,
31
31
  };
32
32
  // Yield text-end
33
33
  yield {
34
- kind: "text-end" as const,
34
+ kind: "text.end" as const,
35
35
  id: item.id,
36
36
  };
37
37
  }
@@ -4,8 +4,8 @@ import {
4
4
  LanguageModelResponse,
5
5
  LanguageModelResponseItem,
6
6
  LanguageModelItem,
7
+ LanguageModelStreamEvent,
7
8
  } from "@kernl-sdk/protocol";
8
- import type { ThreadStreamEvent } from "@/thread/types";
9
9
 
10
10
  /**
11
11
  * A mock language model that echoes the user input back as an assistant message.
@@ -54,7 +54,7 @@ export class MockLanguageModel implements LanguageModel {
54
54
 
55
55
  async *stream(
56
56
  request: LanguageModelRequest,
57
- ): AsyncIterable<ThreadStreamEvent> {
57
+ ): AsyncIterable<LanguageModelStreamEvent> {
58
58
  // TODO: Implement streaming (not needed for hello world)
59
59
  throw new Error("MockLanguageModel.stream() not implemented yet");
60
60
  }
@@ -77,7 +77,7 @@ describe("Thread Persistence", () => {
77
77
  // return {
78
78
  // content: [
79
79
  // message({ role: "assistant", text: "" }),
80
- // { kind: "tool-call", toolId: "test", callId: "call_1", state: IN_PROGRESS, arguments: "{}" },
80
+ // { kind: "tool.call", toolId: "test", callId: "call_1", state: IN_PROGRESS, arguments: "{}" },
81
81
  // ],
82
82
  // finishReason: "stop",
83
83
  // usage: { inputTokens: 2, outputTokens: 2, totalTokens: 4 },
@@ -138,7 +138,7 @@ describe("Thread Persistence", () => {
138
138
  // return {
139
139
  // content: [
140
140
  // message({ role: "assistant", text: "" }),
141
- // { kind: "tool-call", toolId: "echo", callId: "call_1", state: IN_PROGRESS, arguments: '{"text":"test"}' },
141
+ // { kind: "tool.call", toolId: "echo", callId: "call_1", state: IN_PROGRESS, arguments: '{"text":"test"}' },
142
142
  // ],
143
143
  // finishReason: "stop",
144
144
  // usage: { inputTokens: 2, outputTokens: 2, totalTokens: 4 },
@@ -178,7 +178,7 @@ describe("Thread Persistence", () => {
178
178
  //
179
179
  // // Find the append call for tick 1 (should include model message, tool-call, and tool-result)
180
180
  // const tick1Events = storage.calls.append.find(batch =>
181
- // batch.some(e => e.kind === "tool-result")
181
+ // batch.some(e => e.kind === "tool.result")
182
182
  // );
183
183
  //
184
184
  // expect(tick1Events).toBeDefined();
@@ -188,8 +188,8 @@ describe("Thread Persistence", () => {
188
188
  // expect(tick1Events).toEqual(
189
189
  // expect.arrayContaining([
190
190
  // expect.objectContaining({ kind: "message", role: "assistant" }),
191
- // expect.objectContaining({ kind: "tool-call", toolId: "echo" }),
192
- // expect.objectContaining({ kind: "tool-result", toolId: "echo", result: "Echo: test" }),
191
+ // expect.objectContaining({ kind: "tool.call", toolId: "echo" }),
192
+ // expect.objectContaining({ kind: "tool.result", toolId: "echo", result: "Echo: test" }),
193
193
  // ])
194
194
  // );
195
195
  });
@@ -232,7 +232,7 @@ describe("Thread Persistence", () => {
232
232
  // expect(lastUpdate.patch.state).toBe(STOPPED);
233
233
  //
234
234
  // // Verify stream-start event
235
- // expect(events[0]).toEqual({ kind: "stream-start" });
235
+ // expect(events[0]).toEqual({ kind: "stream.start" });
236
236
  });
237
237
 
238
238
  it.skip("should persist STOPPED state even on model error", async () => {