kernl 0.11.2 → 0.12.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.
Files changed (41) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +62 -0
  3. package/dist/agent/__tests__/run.test.js +2 -2
  4. package/dist/context.d.ts +2 -1
  5. package/dist/context.d.ts.map +1 -1
  6. package/dist/context.js +1 -0
  7. package/dist/kernl/kernl.d.ts +1 -1
  8. package/dist/kernl/kernl.d.ts.map +1 -1
  9. package/dist/lifecycle/__tests__/hooks.test.js +6 -6
  10. package/dist/storage/__tests__/in-memory.test.js +1 -1
  11. package/dist/thread/__tests__/fixtures/mock-model.js +3 -3
  12. package/dist/thread/__tests__/integration.test.js +14 -14
  13. package/dist/thread/__tests__/thread-persistence.test.js +6 -6
  14. package/dist/thread/__tests__/thread.test.js +22 -22
  15. package/dist/thread/thread.js +5 -5
  16. package/dist/thread/utils.js +5 -5
  17. package/dist/tool/__tests__/tool.test.js +4 -4
  18. package/dist/tool/tool.d.ts +1 -2
  19. package/dist/tool/tool.d.ts.map +1 -1
  20. package/dist/tool/tool.js +2 -2
  21. package/dist/tool/toolkit.d.ts +5 -3
  22. package/dist/tool/toolkit.d.ts.map +1 -1
  23. package/dist/tool/toolkit.js +3 -1
  24. package/dist/tool/types.d.ts +1 -2
  25. package/dist/tool/types.d.ts.map +1 -1
  26. package/package.json +5 -5
  27. package/src/agent/__tests__/run.test.ts +2 -2
  28. package/src/context.ts +2 -1
  29. package/src/kernl/kernl.ts +1 -1
  30. package/src/lifecycle/__tests__/hooks.test.ts +6 -6
  31. package/src/storage/__tests__/in-memory.test.ts +1 -1
  32. package/src/thread/__tests__/fixtures/mock-model.ts +3 -3
  33. package/src/thread/__tests__/integration.test.ts +18 -18
  34. package/src/thread/__tests__/thread-persistence.test.ts +6 -6
  35. package/src/thread/__tests__/thread.test.ts +22 -22
  36. package/src/thread/thread.ts +5 -5
  37. package/src/thread/utils.ts +5 -5
  38. package/src/tool/__tests__/tool.test.ts +4 -8
  39. package/src/tool/tool.ts +3 -3
  40. package/src/tool/toolkit.ts +5 -3
  41. package/src/tool/types.ts +0 -2
@@ -1,4 +1,4 @@
1
1
 
2
- > kernl@0.11.2 build /home/runner/work/kernl/kernl/packages/kernl
2
+ > kernl@0.12.0 build /home/runner/work/kernl/kernl/packages/kernl
3
3
  > tsc && tsc-alias --resolve-full-paths
4
4
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,67 @@
1
1
  # @kernl/core
2
2
 
3
+ ## 0.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 8815744: **BREAKING:** Refactor event kind naming from kebab-case to dot notation
8
+
9
+ This aligns the language model stream/item kinds with the existing realtime events naming convention.
10
+
11
+ ### Kind value changes
12
+
13
+ | Old | New |
14
+ | ------------------ | ------------------ |
15
+ | `tool-call` | `tool.call` |
16
+ | `tool-result` | `tool.result` |
17
+ | `text-start` | `text.start` |
18
+ | `text-delta` | `text.delta` |
19
+ | `text-end` | `text.end` |
20
+ | `reasoning-start` | `reasoning.start` |
21
+ | `reasoning-delta` | `reasoning.delta` |
22
+ | `reasoning-end` | `reasoning.end` |
23
+ | `tool-input-start` | `tool.input.start` |
24
+ | `tool-input-delta` | `tool.input.delta` |
25
+ | `tool-input-end` | `tool.input.end` |
26
+ | `stream-start` | `stream.start` |
27
+
28
+ ### ToolInputStartEvent: `toolName` → `toolId`
29
+
30
+ The `ToolInputStartEvent` now uses `toolId` to match `ToolCall` and `ToolResult`.
31
+
32
+ ### Migration
33
+
34
+ If you have persisted thread events, run:
35
+
36
+ ```sql
37
+ UPDATE thread_events SET kind = 'tool.call' WHERE kind = 'tool-call';
38
+ UPDATE thread_events SET kind = 'tool.result' WHERE kind = 'tool-result';
39
+ ```
40
+
41
+ ### Patch Changes
42
+
43
+ - Updated dependencies [8815744]
44
+ - @kernl-sdk/protocol@0.5.0
45
+ - @kernl-sdk/retrieval@0.1.9
46
+
47
+ ## 0.11.4
48
+
49
+ ### Patch Changes
50
+
51
+ - Updated dependencies [830b52a]
52
+ - @kernl-sdk/shared@0.4.0
53
+ - @kernl-sdk/protocol@0.4.2
54
+ - @kernl-sdk/retrieval@0.1.8
55
+
56
+ ## 0.11.3
57
+
58
+ ### Patch Changes
59
+
60
+ - 97c66df: Fix type variance for toolkit composition
61
+ - Use `any` instead of generic context types in stored agent references to break invariance
62
+ - Allows toolkits with different context types to be composed in the same agent
63
+ - Remove unused agent parameter from isEnabled signature
64
+
3
65
  ## 0.11.2
4
66
 
5
67
  ### Patch Changes
@@ -218,7 +218,7 @@ describe("Agent.stream() lifecycle", () => {
218
218
  for await (const event of agent.stream("Hello")) {
219
219
  events.push(event);
220
220
  }
221
- expect(events[0]).toEqual({ kind: "stream-start" });
221
+ expect(events[0]).toEqual({ kind: "stream.start" });
222
222
  });
223
223
  it("should have same persistence behavior as run()", async () => {
224
224
  const storage = new InMemoryStorage();
@@ -247,7 +247,7 @@ describe("Agent.stream() lifecycle", () => {
247
247
  expect(history.length).toBeGreaterThan(0);
248
248
  // Should have streamed events
249
249
  expect(events).toEqual(expect.arrayContaining([
250
- { kind: "stream-start" },
250
+ { kind: "stream.start" },
251
251
  expect.objectContaining({ kind: "message" }),
252
252
  ]));
253
253
  });
package/dist/context.d.ts CHANGED
@@ -21,8 +21,9 @@ export declare class Context<TContext = UnknownContext> {
21
21
  * Set by the thread during execution.
22
22
  *
23
23
  * NOTE: Primarily used by system tools (e.g., memory) that need agent access.
24
+ * Uses `any` to avoid invariance issues when composing toolkits.
24
25
  */
25
- agent?: Agent<TContext, any>;
26
+ agent?: Agent<any, any>;
26
27
  /**
27
28
  * Map of tool call IDs to their approval status.
28
29
  * (TEMPORARY) Used until the actions system is refined.
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC;AAErC;;;GAGG;AACH,qBAAa,OAAO,CAAC,QAAQ,GAAG,cAAc;IAC5C;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,OAAO,EAAE,QAAQ,CAAC;IAElB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAM7B;;;OAGG;IACH,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAEvC;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI7B;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;gBAwBhB,SAAS,GAAE,MAAgB,EAAE,OAAO,GAAE,QAAyB;IAS3E;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM;IAevC;;;;;;;;;;;;;;OAcG;IACH,EAAE,IAAI,MAAM;IAIZ;;;;;;;;;;OAUG;IACH,IAAI,IAAI,MAAM;IAId,MAAM,IAAI;QACR,OAAO,EAAE,GAAG,CAAC;KAGd;CAOF;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC;AAErC;;;GAGG;AACH,qBAAa,OAAO,CAAC,QAAQ,GAAG,cAAc;IAC5C;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,OAAO,EAAE,QAAQ,CAAC;IAElB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAMxB;;;OAGG;IACH,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAEvC;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI7B;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;gBAwBhB,SAAS,GAAE,MAAgB,EAAE,OAAO,GAAE,QAAyB;IAS3E;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM;IAevC;;;;;;;;;;;;;;OAcG;IACH,EAAE,IAAI,MAAM;IAIZ;;;;;;;;;;OAUG;IACH,IAAI,IAAI,MAAM;IAId,MAAM,IAAI;QACR,OAAO,EAAE,GAAG,CAAC;KAGd;CAOF;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC"}
package/dist/context.js CHANGED
@@ -16,6 +16,7 @@ export class Context {
16
16
  * Set by the thread during execution.
17
17
  *
18
18
  * NOTE: Primarily used by system tools (e.g., memory) that need agent access.
19
+ * Uses `any` to avoid invariance issues when composing toolkits.
19
20
  */
20
21
  agent;
21
22
  // ----------------------
@@ -30,7 +30,7 @@ export declare class Kernl extends KernlHooks {
30
30
  /**
31
31
  * Registers a new agent with the kernl instance.
32
32
  */
33
- register(agent: BaseAgent): void;
33
+ register(agent: BaseAgent<any>): void;
34
34
  /**
35
35
  * Spawn a new thread - blocking execution
36
36
  */
@@ -1 +1 @@
1
- {"version":3,"file":"kernl.d.ts","sourceRoot":"","sources":["../../src/kernl/kernl.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EACL,MAAM,EAIP,MAAM,UAAU,CAAC;AAIlB,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAiC,MAAM,SAAS,CAAC;AAE3E;;;;;GAKG;AACH,qBAAa,KAAM,SAAQ,UAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IAEjE,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAa;IAEpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4B;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;IAEvD,OAAO,CAAC,QAAQ,CAGd;IAGF,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,OAAO,GAAE,YAAiB;IAatC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAgChC;;OAEG;IACG,KAAK,CAAC,QAAQ,EAAE,OAAO,SAAS,eAAe,EACnD,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC;IAS/D;;;;OAIG;IACG,QAAQ,CAAC,QAAQ,EAAE,OAAO,SAAS,eAAe,EACtD,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC;IAS/D;;;;OAIG;IACI,WAAW,CAAC,QAAQ,EAAE,OAAO,SAAS,eAAe,EAC1D,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,GAChC,aAAa,CAAC,iBAAiB,CAAC;IASnC;;;;OAIG;IACI,cAAc,CAAC,QAAQ,EAAE,OAAO,SAAS,eAAe,EAC7D,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,GAChC,aAAa,CAAC,iBAAiB,CAAC;IAWnC;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;CA6BzB"}
1
+ {"version":3,"file":"kernl.d.ts","sourceRoot":"","sources":["../../src/kernl/kernl.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EACL,MAAM,EAIP,MAAM,UAAU,CAAC;AAIlB,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAiC,MAAM,SAAS,CAAC;AAE3E;;;;;GAKG;AACH,qBAAa,KAAM,SAAQ,UAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IAEjE,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAa;IAEpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4B;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;IAEvD,OAAO,CAAC,QAAQ,CAGd;IAGF,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,OAAO,GAAE,YAAiB;IAatC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI;IAgCrC;;OAEG;IACG,KAAK,CAAC,QAAQ,EAAE,OAAO,SAAS,eAAe,EACnD,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC;IAS/D;;;;OAIG;IACG,QAAQ,CAAC,QAAQ,EAAE,OAAO,SAAS,eAAe,EACtD,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC;IAS/D;;;;OAIG;IACI,WAAW,CAAC,QAAQ,EAAE,OAAO,SAAS,eAAe,EAC1D,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,GAChC,aAAa,CAAC,iBAAiB,CAAC;IASnC;;;;OAIG;IACI,cAAc,CAAC,QAAQ,EAAE,OAAO,SAAS,eAAe,EAC7D,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,GAChC,aAAa,CAAC,iBAAiB,CAAC;IAWnC;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;CA6BzB"}
@@ -238,7 +238,7 @@ describe("Lifecycle Hooks", () => {
238
238
  content: [
239
239
  message({ role: "assistant", text: "" }),
240
240
  {
241
- kind: "tool-call",
241
+ kind: "tool.call",
242
242
  toolId: "echo",
243
243
  state: IN_PROGRESS,
244
244
  callId: "call_1",
@@ -302,7 +302,7 @@ describe("Lifecycle Hooks", () => {
302
302
  content: [
303
303
  message({ role: "assistant", text: "" }),
304
304
  {
305
- kind: "tool-call",
305
+ kind: "tool.call",
306
306
  toolId: "add",
307
307
  state: IN_PROGRESS,
308
308
  callId: "call_1",
@@ -359,7 +359,7 @@ describe("Lifecycle Hooks", () => {
359
359
  content: [
360
360
  message({ role: "assistant", text: "" }),
361
361
  {
362
- kind: "tool-call",
362
+ kind: "tool.call",
363
363
  toolId: "add",
364
364
  state: IN_PROGRESS,
365
365
  callId: "call_1",
@@ -415,7 +415,7 @@ describe("Lifecycle Hooks", () => {
415
415
  content: [
416
416
  message({ role: "assistant", text: "" }),
417
417
  {
418
- kind: "tool-call",
418
+ kind: "tool.call",
419
419
  toolId: "failing",
420
420
  state: IN_PROGRESS,
421
421
  callId: "call_1",
@@ -473,14 +473,14 @@ describe("Lifecycle Hooks", () => {
473
473
  content: [
474
474
  message({ role: "assistant", text: "" }),
475
475
  {
476
- kind: "tool-call",
476
+ kind: "tool.call",
477
477
  toolId: "tool1",
478
478
  state: IN_PROGRESS,
479
479
  callId: "call_1",
480
480
  arguments: JSON.stringify({ value: "a" }),
481
481
  },
482
482
  {
483
- kind: "tool-call",
483
+ kind: "tool.call",
484
484
  toolId: "tool2",
485
485
  state: IN_PROGRESS,
486
486
  callId: "call_2",
@@ -312,7 +312,7 @@ describe("InMemoryThreadStore", () => {
312
312
  it("should filter by kinds", async () => {
313
313
  await store.append([
314
314
  {
315
- kind: "tool-call",
315
+ kind: "tool.call",
316
316
  id: "tc-1",
317
317
  tid: "thread-1",
318
318
  seq: 3,
@@ -10,18 +10,18 @@ async function* streamFromResponse(response) {
10
10
  if (contentItem.kind === "text") {
11
11
  // Yield text-start
12
12
  yield {
13
- kind: "text-start",
13
+ kind: "text.start",
14
14
  id: item.id,
15
15
  };
16
16
  // Yield text-delta
17
17
  yield {
18
- kind: "text-delta",
18
+ kind: "text.delta",
19
19
  id: item.id,
20
20
  text: contentItem.text,
21
21
  };
22
22
  // Yield text-end
23
23
  yield {
24
- kind: "text-end",
24
+ kind: "text.end",
25
25
  id: item.id,
26
26
  };
27
27
  }
@@ -48,13 +48,13 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)("Thread streaming integration", () => {
48
48
  }
49
49
  expect(events.length).toBeGreaterThan(0);
50
50
  // Should have text-delta events (for streaming UX)
51
- const textDeltas = events.filter((e) => e.kind === "text-delta");
51
+ const textDeltas = events.filter((e) => e.kind === "text.delta");
52
52
  expect(textDeltas.length).toBeGreaterThan(0);
53
53
  // Should have text-start event
54
- const textStarts = events.filter((e) => e.kind === "text-start");
54
+ const textStarts = events.filter((e) => e.kind === "text.start");
55
55
  expect(textStarts.length).toBeGreaterThan(0);
56
56
  // Should have text-end event
57
- const textEnds = events.filter((e) => e.kind === "text-end");
57
+ const textEnds = events.filter((e) => e.kind === "text.end");
58
58
  expect(textEnds.length).toBeGreaterThan(0);
59
59
  // Should have complete Message item (for history)
60
60
  const messages = events.filter((e) => e.kind === "message");
@@ -103,9 +103,9 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)("Thread streaming integration", () => {
103
103
  expect(["message", "reasoning", "tool-call", "tool-result"]).toContain(event.kind);
104
104
  }
105
105
  // Stream events should include deltas (but history should not)
106
- const streamDeltas = streamEvents.filter((e) => e.kind === "text-delta" ||
107
- e.kind === "text-start" ||
108
- e.kind === "text-end");
106
+ const streamDeltas = streamEvents.filter((e) => e.kind === "text.delta" ||
107
+ e.kind === "text.start" ||
108
+ e.kind === "text.end");
109
109
  expect(streamDeltas.length).toBeGreaterThan(0);
110
110
  // History should contain the input message (with ThreadEvent headers added)
111
111
  expect(history[0]).toMatchObject({
@@ -162,14 +162,14 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)("Thread streaming integration", () => {
162
162
  }
163
163
  expect(events.length).toBeGreaterThan(0);
164
164
  // Should have tool calls
165
- const toolCalls = events.filter((e) => e.kind === "tool-call");
165
+ const toolCalls = events.filter((e) => e.kind === "tool.call");
166
166
  expect(toolCalls.length).toBeGreaterThan(0);
167
167
  // Verify tool was called with correct parameters
168
168
  const addToolCall = toolCalls.find((tc) => tc.toolId === "add");
169
169
  expect(addToolCall).toBeDefined();
170
170
  expect(JSON.parse(addToolCall.arguments)).toEqual({ a: 25, b: 17 });
171
171
  // Should have tool results
172
- const toolResults = events.filter((e) => e.kind === "tool-result");
172
+ const toolResults = events.filter((e) => e.kind === "tool.result");
173
173
  expect(toolResults.length).toBeGreaterThan(0);
174
174
  // Verify tool result is correct
175
175
  const addToolResult = toolResults.find((tr) => tr.callId === addToolCall.callId);
@@ -177,8 +177,8 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)("Thread streaming integration", () => {
177
177
  expect(addToolResult.result).toBe(42);
178
178
  // History should contain tool calls and results
179
179
  const history = thread.history;
180
- const historyToolCalls = history.filter((e) => e.kind === "tool-call");
181
- const historyToolResults = history.filter((e) => e.kind === "tool-result");
180
+ const historyToolCalls = history.filter((e) => e.kind === "tool.call");
181
+ const historyToolResults = history.filter((e) => e.kind === "tool.result");
182
182
  expect(historyToolCalls.length).toBe(toolCalls.length);
183
183
  expect(historyToolResults.length).toBe(toolResults.length);
184
184
  // Verify the assistant's final response references the correct answer
@@ -228,8 +228,8 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)("Thread streaming integration", () => {
228
228
  events.push(event);
229
229
  }
230
230
  // Find the tool call and result
231
- const toolCalls = events.filter((e) => e.kind === "tool-call");
232
- const toolResults = events.filter((e) => e.kind === "tool-result");
231
+ const toolCalls = events.filter((e) => e.kind === "tool.call");
232
+ const toolResults = events.filter((e) => e.kind === "tool.result");
233
233
  expect(toolCalls.length).toBeGreaterThan(0);
234
234
  expect(toolResults.length).toBeGreaterThan(0);
235
235
  const multiplyCall = toolCalls[0];
@@ -244,8 +244,8 @@ describe.skipIf(SKIP_INTEGRATION_TESTS)("Thread streaming integration", () => {
244
244
  expect(multiplyResult.callId.length).toBeGreaterThan(0);
245
245
  // Verify history contains both with matching callIds
246
246
  const history = thread.history;
247
- const historyToolCall = history.find((e) => e.kind === "tool-call" && e.toolId === "multiply");
248
- const historyToolResult = history.find((e) => e.kind === "tool-result" && e.toolId === "multiply");
247
+ const historyToolCall = history.find((e) => e.kind === "tool.call" && e.toolId === "multiply");
248
+ const historyToolResult = history.find((e) => e.kind === "tool.result" && e.toolId === "multiply");
249
249
  expect(historyToolCall).toBeDefined();
250
250
  expect(historyToolResult).toBeDefined();
251
251
  expect(historyToolCall.callId).toBe(historyToolResult.callId);
@@ -67,7 +67,7 @@ describe("Thread Persistence", () => {
67
67
  // return {
68
68
  // content: [
69
69
  // message({ role: "assistant", text: "" }),
70
- // { kind: "tool-call", toolId: "test", callId: "call_1", state: IN_PROGRESS, arguments: "{}" },
70
+ // { kind: "tool.call", toolId: "test", callId: "call_1", state: IN_PROGRESS, arguments: "{}" },
71
71
  // ],
72
72
  // finishReason: "stop",
73
73
  // usage: { inputTokens: 2, outputTokens: 2, totalTokens: 4 },
@@ -127,7 +127,7 @@ describe("Thread Persistence", () => {
127
127
  // return {
128
128
  // content: [
129
129
  // message({ role: "assistant", text: "" }),
130
- // { kind: "tool-call", toolId: "echo", callId: "call_1", state: IN_PROGRESS, arguments: '{"text":"test"}' },
130
+ // { kind: "tool.call", toolId: "echo", callId: "call_1", state: IN_PROGRESS, arguments: '{"text":"test"}' },
131
131
  // ],
132
132
  // finishReason: "stop",
133
133
  // usage: { inputTokens: 2, outputTokens: 2, totalTokens: 4 },
@@ -167,7 +167,7 @@ describe("Thread Persistence", () => {
167
167
  //
168
168
  // // Find the append call for tick 1 (should include model message, tool-call, and tool-result)
169
169
  // const tick1Events = storage.calls.append.find(batch =>
170
- // batch.some(e => e.kind === "tool-result")
170
+ // batch.some(e => e.kind === "tool.result")
171
171
  // );
172
172
  //
173
173
  // expect(tick1Events).toBeDefined();
@@ -177,8 +177,8 @@ describe("Thread Persistence", () => {
177
177
  // expect(tick1Events).toEqual(
178
178
  // expect.arrayContaining([
179
179
  // expect.objectContaining({ kind: "message", role: "assistant" }),
180
- // expect.objectContaining({ kind: "tool-call", toolId: "echo" }),
181
- // expect.objectContaining({ kind: "tool-result", toolId: "echo", result: "Echo: test" }),
180
+ // expect.objectContaining({ kind: "tool.call", toolId: "echo" }),
181
+ // expect.objectContaining({ kind: "tool.result", toolId: "echo", result: "Echo: test" }),
182
182
  // ])
183
183
  // );
184
184
  });
@@ -220,7 +220,7 @@ describe("Thread Persistence", () => {
220
220
  // expect(lastUpdate.patch.state).toBe(STOPPED);
221
221
  //
222
222
  // // Verify stream-start event
223
- // expect(events[0]).toEqual({ kind: "stream-start" });
223
+ // expect(events[0]).toEqual({ kind: "stream.start" });
224
224
  });
225
225
  it.skip("should persist STOPPED state even on model error", async () => {
226
226
  // TODO: Enable once InMemoryStorage is implemented
@@ -164,7 +164,7 @@ describe("Thread", () => {
164
164
  content: [],
165
165
  },
166
166
  {
167
- kind: "tool-call",
167
+ kind: "tool.call",
168
168
  toolId: "echo",
169
169
  state: IN_PROGRESS,
170
170
  callId: "call_1",
@@ -233,7 +233,7 @@ describe("Thread", () => {
233
233
  }),
234
234
  // Tool call (tick 1)
235
235
  expect.objectContaining({
236
- kind: "tool-call",
236
+ kind: "tool.call",
237
237
  toolId: "echo",
238
238
  callId: "call_1",
239
239
  state: IN_PROGRESS,
@@ -241,7 +241,7 @@ describe("Thread", () => {
241
241
  }),
242
242
  // Tool result (executed after tick 1)
243
243
  expect.objectContaining({
244
- kind: "tool-result",
244
+ kind: "tool.result",
245
245
  callId: "call_1",
246
246
  toolId: "echo",
247
247
  state: COMPLETED,
@@ -271,7 +271,7 @@ describe("Thread", () => {
271
271
  content: [],
272
272
  },
273
273
  {
274
- kind: "tool-call",
274
+ kind: "tool.call",
275
275
  toolId: "simple",
276
276
  state: IN_PROGRESS,
277
277
  callId: "call_1",
@@ -297,7 +297,7 @@ describe("Thread", () => {
297
297
  content: [],
298
298
  },
299
299
  {
300
- kind: "tool-call",
300
+ kind: "tool.call",
301
301
  toolId: "simple",
302
302
  state: IN_PROGRESS,
303
303
  callId: "call_2",
@@ -371,7 +371,7 @@ describe("Thread", () => {
371
371
  content: [],
372
372
  },
373
373
  {
374
- kind: "tool-call",
374
+ kind: "tool.call",
375
375
  toolId: "nonexistent",
376
376
  state: IN_PROGRESS,
377
377
  callId: "call_1",
@@ -418,9 +418,9 @@ describe("Thread", () => {
418
418
  await thread.execute();
419
419
  const history = thread.history;
420
420
  // Check that the tool result is an error
421
- const toolResult = history.find((e) => e.kind === "tool-result");
421
+ const toolResult = history.find((e) => e.kind === "tool.result");
422
422
  expect(toolResult).toEqual(expect.objectContaining({
423
- kind: "tool-result",
423
+ kind: "tool.result",
424
424
  callId: "call_1",
425
425
  toolId: "nonexistent",
426
426
  state: FAILED,
@@ -443,7 +443,7 @@ describe("Thread", () => {
443
443
  content: [],
444
444
  },
445
445
  {
446
- kind: "tool-call",
446
+ kind: "tool.call",
447
447
  toolId: "failing",
448
448
  state: IN_PROGRESS,
449
449
  callId: "call_1",
@@ -499,9 +499,9 @@ describe("Thread", () => {
499
499
  const thread = new Thread({ agent, input: userMessage("test") });
500
500
  await thread.execute();
501
501
  const history = thread.history;
502
- const toolResult = history.find((e) => e.kind === "tool-result");
502
+ const toolResult = history.find((e) => e.kind === "tool.result");
503
503
  expect(toolResult).toMatchObject({
504
- kind: "tool-result",
504
+ kind: "tool.result",
505
505
  callId: "call_1",
506
506
  toolId: "failing",
507
507
  state: FAILED,
@@ -524,7 +524,7 @@ describe("Thread", () => {
524
524
  content: [],
525
525
  },
526
526
  {
527
- kind: "tool-call",
527
+ kind: "tool.call",
528
528
  toolId: "add",
529
529
  state: IN_PROGRESS,
530
530
  callId: "call_1",
@@ -577,9 +577,9 @@ describe("Thread", () => {
577
577
  await thread.execute();
578
578
  // @ts-expect-error
579
579
  const history = thread.history;
580
- const toolResult = history.find((e) => e.kind === "tool-result");
580
+ const toolResult = history.find((e) => e.kind === "tool.result");
581
581
  expect(toolResult).toEqual(expect.objectContaining({
582
- kind: "tool-result",
582
+ kind: "tool.result",
583
583
  callId: "call_1",
584
584
  toolId: "add",
585
585
  state: COMPLETED,
@@ -604,14 +604,14 @@ describe("Thread", () => {
604
604
  content: [],
605
605
  },
606
606
  {
607
- kind: "tool-call",
607
+ kind: "tool.call",
608
608
  toolId: "tool1",
609
609
  state: IN_PROGRESS,
610
610
  callId: "call_1",
611
611
  arguments: JSON.stringify({ value: "a" }),
612
612
  },
613
613
  {
614
- kind: "tool-call",
614
+ kind: "tool.call",
615
615
  toolId: "tool2",
616
616
  state: IN_PROGRESS,
617
617
  callId: "call_2",
@@ -672,11 +672,11 @@ describe("Thread", () => {
672
672
  await thread.execute();
673
673
  const history = thread.history;
674
674
  // Should have both tool results in history
675
- const toolResults = history.filter((e) => e.kind === "tool-result");
675
+ const toolResults = history.filter((e) => e.kind === "tool.result");
676
676
  expect(toolResults).toHaveLength(2);
677
677
  expect(toolResults).toEqual(expect.arrayContaining([
678
678
  expect.objectContaining({
679
- kind: "tool-result",
679
+ kind: "tool.result",
680
680
  callId: "call_1",
681
681
  toolId: "tool1",
682
682
  state: COMPLETED,
@@ -684,7 +684,7 @@ describe("Thread", () => {
684
684
  error: null,
685
685
  }),
686
686
  expect.objectContaining({
687
- kind: "tool-result",
687
+ kind: "tool.result",
688
688
  callId: "call_2",
689
689
  toolId: "tool2",
690
690
  state: COMPLETED,
@@ -709,7 +709,7 @@ describe("Thread", () => {
709
709
  content: [],
710
710
  },
711
711
  {
712
- kind: "tool-call",
712
+ kind: "tool.call",
713
713
  toolId: "simple",
714
714
  state: IN_PROGRESS,
715
715
  callId: `call_${callCount}`,
@@ -777,7 +777,7 @@ describe("Thread", () => {
777
777
  content: [],
778
778
  },
779
779
  {
780
- kind: "tool-call",
780
+ kind: "tool.call",
781
781
  toolId: "simple",
782
782
  state: IN_PROGRESS,
783
783
  callId: "call_1",
@@ -880,7 +880,7 @@ describe("Thread", () => {
880
880
  content: [{ kind: "text", text: "Let me use a tool" }],
881
881
  },
882
882
  {
883
- kind: "tool-call",
883
+ kind: "tool.call",
884
884
  toolId: "simple",
885
885
  state: IN_PROGRESS,
886
886
  callId: "call_1",
@@ -127,7 +127,7 @@ export class Thread {
127
127
  namespace: this.namespace,
128
128
  context: this.context,
129
129
  });
130
- yield { kind: "stream-start" }; // always yield start immediately
130
+ yield { kind: "stream.start" }; // always yield start immediately
131
131
  try {
132
132
  yield* this._execute();
133
133
  this.agent.emit("thread.stop", {
@@ -380,7 +380,7 @@ export class Thread {
380
380
  const pendingApprovals = [];
381
381
  // (TODO): clean this - approval tracking should be handled differently
382
382
  for (const e of toolEvents) {
383
- if (e.kind === "tool-result" &&
383
+ if (e.kind === "tool.result" &&
384
384
  e.state === "requires_approval" // (TODO): fix this
385
385
  ) {
386
386
  // find the original tool call for this pending approval
@@ -440,7 +440,7 @@ export class Thread {
440
440
  error: res.error,
441
441
  });
442
442
  return {
443
- kind: "tool-result",
443
+ kind: "tool.result",
444
444
  callId: call.callId,
445
445
  toolId: call.toolId,
446
446
  state: res.state,
@@ -460,7 +460,7 @@ export class Thread {
460
460
  error: error instanceof Error ? error.message : String(error),
461
461
  });
462
462
  return {
463
- kind: "tool-result",
463
+ kind: "tool.result",
464
464
  callId: call.callId,
465
465
  toolId: call.toolId,
466
466
  state: FAILED,
@@ -495,7 +495,7 @@ export class Thread {
495
495
  const filtered = input;
496
496
  // serialize action repertoire
497
497
  const all = await this.agent.tools(this.context);
498
- const enabled = await filter(all, async (tool) => await tool.isEnabled(this.context, this.agent));
498
+ const enabled = await filter(all, async (tool) => await tool.isEnabled(this.context));
499
499
  const tools = enabled.map((tool) => tool.serialize());
500
500
  // derive responseType from agent.output
501
501
  let responseType;
@@ -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;
@@ -138,7 +138,7 @@ describe("FunctionTool", () => {
138
138
  describe("isEnabled", () => {
139
139
  it("should default to enabled", async () => {
140
140
  const ctx = mockContext();
141
- const enabled = await simpleStringTool.isEnabled(ctx, null);
141
+ const enabled = await simpleStringTool.isEnabled(ctx);
142
142
  expect(enabled).toBe(true);
143
143
  });
144
144
  it("should evaluate boolean isEnabled", async () => {
@@ -150,7 +150,7 @@ describe("FunctionTool", () => {
150
150
  execute: async () => "result",
151
151
  });
152
152
  const ctx = mockContext();
153
- const enabled = await disabledTool.isEnabled(ctx, null);
153
+ const enabled = await disabledTool.isEnabled(ctx);
154
154
  expect(enabled).toBe(false);
155
155
  });
156
156
  it("should evaluate function isEnabled with typed context", async () => {
@@ -165,8 +165,8 @@ describe("FunctionTool", () => {
165
165
  });
166
166
  const enabledCtx = mockContext({ enabled: true });
167
167
  const disabledCtx = mockContext({ enabled: false });
168
- expect(await conditionalTool.isEnabled(enabledCtx, null)).toBe(true);
169
- expect(await conditionalTool.isEnabled(disabledCtx, null)).toBe(false);
168
+ expect(await conditionalTool.isEnabled(enabledCtx)).toBe(true);
169
+ expect(await conditionalTool.isEnabled(disabledCtx)).toBe(false);
170
170
  });
171
171
  });
172
172
  });
@@ -1,5 +1,4 @@
1
1
  import { Context, UnknownContext } from "../context.js";
2
- import type { BaseAgent } from "../agent/base.js";
3
2
  import { type LanguageModelTool } from "@kernl-sdk/protocol";
4
3
  import type { ToolConfig, ToolApprovalFunction, ToolEnabledFunction, ToolErrorFunction, ToolInputParameters, ToolResult } from "./types.js";
5
4
  /**
@@ -27,7 +26,7 @@ export declare abstract class BaseTool<TContext = UnknownContext> {
27
26
  /**
28
27
  * Determines whether the tool should be exposed to the model for the current run.
29
28
  */
30
- abstract isEnabled(context: Context<TContext>, agent: BaseAgent<TContext>): Promise<boolean>;
29
+ abstract isEnabled(context: Context<TContext>): Promise<boolean>;
31
30
  /**
32
31
  * Serialize this tool for sending to the model
33
32
  */