kernl 0.8.4 → 0.9.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 (70) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +30 -0
  3. package/dist/agent/base.d.ts +73 -0
  4. package/dist/agent/base.d.ts.map +1 -0
  5. package/dist/agent/base.js +137 -0
  6. package/dist/agent/index.d.ts +2 -0
  7. package/dist/agent/index.d.ts.map +1 -1
  8. package/dist/agent/index.js +2 -1
  9. package/dist/agent/types.d.ts +4 -0
  10. package/dist/agent/types.d.ts.map +1 -1
  11. package/dist/agent.d.ts +10 -90
  12. package/dist/agent.d.ts.map +1 -1
  13. package/dist/agent.js +5 -171
  14. package/dist/api/resources/agents/agents.d.ts +11 -7
  15. package/dist/api/resources/agents/agents.d.ts.map +1 -1
  16. package/dist/api/resources/agents/agents.js +14 -8
  17. package/dist/kernl/kernl.d.ts +2 -2
  18. package/dist/kernl/kernl.d.ts.map +1 -1
  19. package/dist/kernl/kernl.js +6 -6
  20. package/dist/kernl/types.d.ts +3 -3
  21. package/dist/kernl/types.d.ts.map +1 -1
  22. package/dist/lib/env.d.ts +2 -2
  23. package/dist/mcp/__tests__/utils.test.js +4 -2
  24. package/dist/mcp/utils.d.ts +1 -1
  25. package/dist/mcp/utils.js +1 -1
  26. package/dist/realtime/agent.d.ts +17 -0
  27. package/dist/realtime/agent.d.ts.map +1 -0
  28. package/dist/realtime/agent.js +17 -0
  29. package/dist/realtime/channel.d.ts +30 -0
  30. package/dist/realtime/channel.d.ts.map +1 -0
  31. package/dist/realtime/channel.js +1 -0
  32. package/dist/realtime/index.d.ts +5 -0
  33. package/dist/realtime/index.d.ts.map +1 -0
  34. package/dist/realtime/index.js +4 -0
  35. package/dist/realtime/session.d.ts +98 -0
  36. package/dist/realtime/session.d.ts.map +1 -0
  37. package/dist/realtime/session.js +203 -0
  38. package/dist/realtime/types.d.ts +58 -0
  39. package/dist/realtime/types.d.ts.map +1 -0
  40. package/dist/realtime/types.js +1 -0
  41. package/dist/storage/in-memory.d.ts.map +1 -1
  42. package/dist/storage/in-memory.js +5 -1
  43. package/dist/tool/__tests__/toolkit.test.js +2 -2
  44. package/dist/tool/tool.d.ts +2 -1
  45. package/dist/tool/tool.d.ts.map +1 -1
  46. package/dist/tool/toolkit.d.ts +4 -4
  47. package/dist/tool/toolkit.d.ts.map +1 -1
  48. package/dist/tool/toolkit.js +2 -1
  49. package/dist/tool/types.d.ts +4 -4
  50. package/dist/tool/types.d.ts.map +1 -1
  51. package/package.json +9 -6
  52. package/src/agent/base.ts +220 -0
  53. package/src/agent/index.ts +2 -0
  54. package/src/agent/types.ts +5 -0
  55. package/src/agent.ts +12 -231
  56. package/src/api/resources/agents/agents.ts +19 -13
  57. package/src/kernl/kernl.ts +9 -9
  58. package/src/kernl/types.ts +3 -3
  59. package/src/mcp/__tests__/utils.test.ts +4 -2
  60. package/src/mcp/utils.ts +1 -1
  61. package/src/realtime/agent.ts +24 -0
  62. package/src/realtime/channel.ts +32 -0
  63. package/src/realtime/index.ts +4 -0
  64. package/src/realtime/session.ts +259 -0
  65. package/src/realtime/types.ts +73 -0
  66. package/src/storage/in-memory.ts +9 -1
  67. package/src/tool/__tests__/toolkit.test.ts +2 -2
  68. package/src/tool/tool.ts +2 -1
  69. package/src/tool/toolkit.ts +6 -5
  70. package/src/tool/types.ts +4 -4
@@ -1,4 +1,5 @@
1
- import type { Agent } from "../../../agent.js";
1
+ import { Agent } from "../../../agent.js";
2
+ import type { BaseAgent } from "../../../agent/base.js";
2
3
  import type { AgentOutputType } from "../../../agent/types.js";
3
4
  import type { UnknownContext } from "../../../context.js";
4
5
  import type { TextOutput } from "../../../thread/types.js";
@@ -8,26 +9,29 @@ import type { TextOutput } from "../../../thread/types.js";
8
9
  * Thin facade over the in-process agent registry, returning live Agent instances.
9
10
  *
10
11
  * Note: agents are code, not persisted data; this is process-local.
12
+ *
13
+ * Currently only exposes LLM agents (kind: "llm"). RealtimeAgents are stored
14
+ * in the internal registry but not returned by these methods. If public access
15
+ * to realtime agents is needed, add a separate `kernl.realtimeAgents` resource.
11
16
  */
12
17
  export declare class RAgents {
13
18
  private readonly registry;
14
- constructor(registry: Map<string, Agent>);
19
+ constructor(registry: Map<string, BaseAgent>);
15
20
  /**
16
21
  * Get a live Agent instance by id.
17
22
  *
23
+ * Only returns LLM agents. Returns undefined for realtime agents.
24
+ *
18
25
  * Callers are expected to know the concrete TContext/TOutput types
19
26
  * for their own agents and can specify them via generics.
20
27
  */
21
28
  get<TContext = UnknownContext, TOutput extends AgentOutputType = TextOutput>(id: string): Agent<TContext, TOutput> | undefined;
22
29
  /**
23
- * Check if an agent with the given id is registered.
30
+ * Check if an LLM agent with the given id is registered.
24
31
  */
25
32
  has(id: string): boolean;
26
33
  /**
27
- * List all registered agents as live instances.
28
- *
29
- * Since this is a heterogeneous collection, we expose the widest safe
30
- * type parameters here.
34
+ * List all registered LLM agents as live instances.
31
35
  */
32
36
  list(): Agent<UnknownContext, AgentOutputType>[];
33
37
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../../src/api/resources/agents/agents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD;;;;;;GAMG;AACH,qBAAa,OAAO;IACN,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC;IAEzD;;;;;OAKG;IACH,GAAG,CACD,QAAQ,GAAG,cAAc,EACzB,OAAO,SAAS,eAAe,GAAG,UAAU,EAC5C,EAAE,EAAE,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,SAAS;IAKnD;;OAEG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxB;;;;;OAKG;IACH,IAAI,IAAI,KAAK,CAAC,cAAc,EAAE,eAAe,CAAC,EAAE;IAOhD;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;CAGhC"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../../src/api/resources/agents/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD;;;;;;;;;;GAUG;AACH,qBAAa,OAAO;IACN,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC;IAE7D;;;;;;;OAOG;IACH,GAAG,CACD,QAAQ,GAAG,cAAc,EACzB,OAAO,SAAS,eAAe,GAAG,UAAU,EAC5C,EAAE,EAAE,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,SAAS;IAQnD;;OAEG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxB;;OAEG;IACH,IAAI,IAAI,KAAK,CAAC,cAAc,EAAE,eAAe,CAAC,EAAE;IAMhD;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;CAGhC"}
@@ -4,6 +4,10 @@
4
4
  * Thin facade over the in-process agent registry, returning live Agent instances.
5
5
  *
6
6
  * Note: agents are code, not persisted data; this is process-local.
7
+ *
8
+ * Currently only exposes LLM agents (kind: "llm"). RealtimeAgents are stored
9
+ * in the internal registry but not returned by these methods. If public access
10
+ * to realtime agents is needed, add a separate `kernl.realtimeAgents` resource.
7
11
  */
8
12
  export class RAgents {
9
13
  registry;
@@ -13,27 +17,29 @@ export class RAgents {
13
17
  /**
14
18
  * Get a live Agent instance by id.
15
19
  *
20
+ * Only returns LLM agents. Returns undefined for realtime agents.
21
+ *
16
22
  * Callers are expected to know the concrete TContext/TOutput types
17
23
  * for their own agents and can specify them via generics.
18
24
  */
19
25
  get(id) {
20
26
  const agent = this.registry.get(id);
21
- return agent;
27
+ if (agent?.kind === "llm") {
28
+ return agent;
29
+ }
30
+ return undefined;
22
31
  }
23
32
  /**
24
- * Check if an agent with the given id is registered.
33
+ * Check if an LLM agent with the given id is registered.
25
34
  */
26
35
  has(id) {
27
- return this.registry.has(id);
36
+ return this.registry.get(id)?.kind === "llm";
28
37
  }
29
38
  /**
30
- * List all registered agents as live instances.
31
- *
32
- * Since this is a heterogeneous collection, we expose the widest safe
33
- * type parameters here.
39
+ * List all registered LLM agents as live instances.
34
40
  */
35
41
  list() {
36
- return Array.from(this.registry.values());
42
+ return Array.from(this.registry.values()).filter((a) => a.kind === "llm");
37
43
  }
38
44
  /**
39
45
  * Unregister an agent at runtime.
@@ -1,4 +1,4 @@
1
- import { Agent } from "../agent.js";
1
+ import { BaseAgent } from "../agent/base.js";
2
2
  import { UnknownContext } from "../context.js";
3
3
  import { KernlHooks } from "../lifecycle.js";
4
4
  import type { Thread } from "../thread/index.js";
@@ -31,7 +31,7 @@ export declare class Kernl extends KernlHooks<UnknownContext, AgentOutputType> {
31
31
  /**
32
32
  * Registers a new agent with the kernl instance.
33
33
  */
34
- register(agent: Agent): void;
34
+ register(agent: BaseAgent): void;
35
35
  /**
36
36
  * Spawn a new thread - blocking execution
37
37
  */
@@ -1 +1 @@
1
- {"version":3,"file":"kernl.d.ts","sourceRoot":"","sources":["../../src/kernl/kernl.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,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,CAAC,cAAc,EAAE,eAAe,CAAC;IACpE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IACzD,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,KAAK,GAAG,IAAI;IAgC5B;;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,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,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,CAAC,cAAc,EAAE,eAAe,CAAC;IACpE,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"}
@@ -55,12 +55,12 @@ export class Kernl extends KernlHooks {
55
55
  this.warnings.vector = true;
56
56
  }
57
57
  }
58
- // (TODO): implement exhaustive model registry in protocol/ package
59
- //
60
- // auto-populate model registry for storage hydration
61
- const key = `${agent.model.provider}/${agent.model.modelId}`;
62
- if (!this._models.has(key)) {
63
- this._models.set(key, agent.model);
58
+ // auto-populate model registry for storage hydration (llm agents only - for now)
59
+ if (agent.kind === "llm") {
60
+ const key = `${agent.model.provider}/${agent.model.modelId}`;
61
+ if (!this._models.has(key)) {
62
+ this._models.set(key, agent.model);
63
+ }
64
64
  }
65
65
  }
66
66
  /**
@@ -1,6 +1,6 @@
1
1
  import { LanguageModel, EmbeddingModel } from "@kernl-sdk/protocol";
2
2
  import { SearchIndex } from "@kernl-sdk/retrieval";
3
- import { Agent } from "../agent.js";
3
+ import { BaseAgent } from "../agent/base.js";
4
4
  import { KernlStorage } from "../storage/index.js";
5
5
  /**
6
6
  * Storage configuration for Kernl.
@@ -72,10 +72,10 @@ export interface KernlOptions {
72
72
  /**
73
73
  * Agent registry interface.
74
74
  *
75
- * Satisfied by Map<string, Agent>.
75
+ * Satisfied by Map<string, BaseAgent>.
76
76
  */
77
77
  export interface AgentRegistry {
78
- get(id: string): Agent<any> | undefined;
78
+ get(id: string): BaseAgent<any> | undefined;
79
79
  }
80
80
  /**
81
81
  * Model registry interface.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/kernl/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,EAAE,CAAC,EAAE,YAAY,CAAC;IAElB;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CAKtB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAE5C;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE/C;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,UAAU,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,aAAa,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB;;OAEG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;CACzC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAAC;CAC7C"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/kernl/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,EAAE,CAAC,EAAE,YAAY,CAAC;IAElB;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CAKtB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAE5C;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE/C;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,UAAU,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,aAAa,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB;;OAEG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;CAC7C;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAAC;CAC7C"}
package/dist/lib/env.d.ts CHANGED
@@ -7,11 +7,11 @@ import { z } from "zod";
7
7
  */
8
8
  declare const envSchema: z.ZodObject<{
9
9
  LOG_LEVEL: z.ZodDefault<z.ZodEnum<{
10
+ error: "error";
10
11
  trace: "trace";
11
12
  debug: "debug";
12
13
  info: "info";
13
14
  warn: "warn";
14
- error: "error";
15
15
  fatal: "fatal";
16
16
  }>>;
17
17
  KERNL_LOG_MODEL_DATA: z.ZodPipe<z.ZodOptional<z.ZodEnum<{
@@ -31,7 +31,7 @@ declare const envSchema: z.ZodObject<{
31
31
  * console.log(env.LOG_LEVEL);
32
32
  */
33
33
  export declare const env: {
34
- LOG_LEVEL: "trace" | "debug" | "info" | "warn" | "error" | "fatal";
34
+ LOG_LEVEL: "error" | "trace" | "debug" | "info" | "warn" | "fatal";
35
35
  KERNL_LOG_MODEL_DATA: boolean;
36
36
  KERNL_LOG_TOOL_DATA: boolean;
37
37
  };
@@ -52,7 +52,7 @@ describe("mcpToFunctionTool", () => {
52
52
  expect(functionTool.description).toBe("Performs calculations");
53
53
  expect(functionTool.parameters).toBeDefined();
54
54
  });
55
- it("should handle tools without inputSchema (undefined parameters)", () => {
55
+ it("should handle tools without inputSchema (empty object parameters)", () => {
56
56
  const server = createMockServer();
57
57
  // In practice, MCP SDK tools require inputSchema, but our function handles
58
58
  // the case where it might not be present. We use 'as any' to test this edge case.
@@ -62,7 +62,9 @@ describe("mcpToFunctionTool", () => {
62
62
  };
63
63
  const functionTool = mcpToFunctionTool(server, mcpTool);
64
64
  expect(functionTool.id).toBe("no_params");
65
- expect(functionTool.parameters).toBeUndefined();
65
+ // When no inputSchema, we use an empty z.object({}) to match AI SDK behavior
66
+ expect(functionTool.parameters).toBeDefined();
67
+ expect(functionTool.parameters?.def.type).toBe("object");
66
68
  });
67
69
  it("should invoke server.callTool with correct params", async () => {
68
70
  const server = createMockServer();
@@ -5,7 +5,7 @@ import type { MCPTool, MCPToolFilter } from "./types.js";
5
5
  /**
6
6
  * Converts an MCP tool definition into a function tool usable by the SDK.
7
7
  */
8
- export declare function mcpToFunctionTool(server: MCPServer, mcpTool: MCPTool): import("../tool/index.js").FunctionTool<unknown, z.ZodObject<{}, z.core.$strip>, {
8
+ export declare function mcpToFunctionTool(server: MCPServer, mcpTool: MCPTool): import("../tool/tool.js").FunctionTool<unknown, z.ZodObject<{}, z.core.$strip>, {
9
9
  type: string;
10
10
  text: string;
11
11
  } | {
package/dist/mcp/utils.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { tool } from "../tool/index.js";
2
+ import { tool } from "../tool/tool.js";
3
3
  /**
4
4
  * Converts an MCP tool definition into a function tool usable by the SDK.
5
5
  */
@@ -0,0 +1,17 @@
1
+ import type { RealtimeModel } from "@kernl-sdk/protocol";
2
+ import type { UnknownContext } from "../context.js";
3
+ import { BaseAgent } from "../agent/base.js";
4
+ import type { RealtimeAgentConfig, RealtimeAgentVoiceConfig } from "./types.js";
5
+ /**
6
+ * A realtime agent definition.
7
+ *
8
+ * Stateless configuration that describes what a realtime voice agent does.
9
+ * Create sessions with `new RealtimeSession(agent, options)`.
10
+ */
11
+ export declare class RealtimeAgent<TContext = UnknownContext> extends BaseAgent<TContext> {
12
+ readonly kind = "realtime";
13
+ readonly model: RealtimeModel;
14
+ readonly voice?: RealtimeAgentVoiceConfig;
15
+ constructor(config: RealtimeAgentConfig<TContext>);
16
+ }
17
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/realtime/agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,KAAK,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAE7E;;;;;GAKG;AACH,qBAAa,aAAa,CAAC,QAAQ,GAAG,cAAc,CAAE,SAAQ,SAAS,CAAC,QAAQ,CAAC;IAC/E,QAAQ,CAAC,IAAI,cAAc;IAC3B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,wBAAwB,CAAC;gBAE9B,MAAM,EAAE,mBAAmB,CAAC,QAAQ,CAAC;CAKlD"}
@@ -0,0 +1,17 @@
1
+ import { BaseAgent } from "../agent/base.js";
2
+ /**
3
+ * A realtime agent definition.
4
+ *
5
+ * Stateless configuration that describes what a realtime voice agent does.
6
+ * Create sessions with `new RealtimeSession(agent, options)`.
7
+ */
8
+ export class RealtimeAgent extends BaseAgent {
9
+ kind = "realtime";
10
+ model;
11
+ voice;
12
+ constructor(config) {
13
+ super(config);
14
+ this.model = config.model;
15
+ this.voice = config.voice;
16
+ }
17
+ }
@@ -0,0 +1,30 @@
1
+ import { EventEmitter } from "node:events";
2
+ /**
3
+ * Base interface for audio I/O channels.
4
+ *
5
+ * Channels bridge between audio sources (browser mic, Twilio, Discord)
6
+ * and the realtime session. They handle audio capture/playback and emit
7
+ * events that the session listens to.
8
+ *
9
+ * Events emitted:
10
+ * - 'audio' (audio: string) - Raw audio chunk (base64)
11
+ * - 'commit' () - User finished speaking (VAD or manual)
12
+ * - 'interrupt' () - User started speaking mid-response
13
+ */
14
+ export interface RealtimeChannel extends EventEmitter {
15
+ /**
16
+ * Send audio to be played/transmitted by the channel.
17
+ * Called by session when audio is received from the model.
18
+ */
19
+ sendAudio(audio: string): void;
20
+ /**
21
+ * Interrupt current audio playback.
22
+ * Called by session when response is cancelled.
23
+ */
24
+ interrupt(): void;
25
+ /**
26
+ * Clean up resources and close the channel.
27
+ */
28
+ close(): void;
29
+ }
30
+ //# sourceMappingURL=channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/realtime/channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAE/B;;;OAGG;IACH,SAAS,IAAI,IAAI,CAAC;IAElB;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;CACf"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ export * from "./types.js";
2
+ export * from "./channel.js";
3
+ export * from "./agent.js";
4
+ export * from "./session.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/realtime/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./types.js";
2
+ export * from "./channel.js";
3
+ export * from "./agent.js";
4
+ export * from "./session.js";
@@ -0,0 +1,98 @@
1
+ import { EventEmitter } from "node:events";
2
+ import { RealtimeModel } from "@kernl-sdk/protocol";
3
+ import { Context, UnknownContext } from "../context.js";
4
+ import { RealtimeAgent } from "./agent.js";
5
+ import type { RealtimeChannel } from "./channel.js";
6
+ import type { RealtimeSessionOptions } from "./types.js";
7
+ /**
8
+ * A realtime session manages the connection to a realtime model.
9
+ *
10
+ * Handles the bidirectional communication between an agent and a model,
11
+ * including audio I/O (via channels), tool execution, and event routing.
12
+ */
13
+ export declare class RealtimeSession<TContext = UnknownContext> extends EventEmitter {
14
+ /**
15
+ * Session ID. Null until connected.
16
+ */
17
+ id: string | null;
18
+ /**
19
+ * The agent definition.
20
+ */
21
+ readonly agent: RealtimeAgent<TContext>;
22
+ /**
23
+ * The realtime model.
24
+ */
25
+ readonly model: RealtimeModel;
26
+ /**
27
+ * The audio I/O channel (if any).
28
+ */
29
+ readonly channel: RealtimeChannel | null;
30
+ /**
31
+ * The session context.
32
+ */
33
+ readonly context: Context<TContext>;
34
+ /**
35
+ * The active connection. Null until connected.
36
+ */
37
+ private connection;
38
+ /**
39
+ * Session options.
40
+ */
41
+ private options;
42
+ constructor(agent: RealtimeAgent<TContext>, options?: RealtimeSessionOptions<TContext>);
43
+ /**
44
+ * Connect to the realtime model.
45
+ */
46
+ connect(): Promise<void>;
47
+ /**
48
+ * Initialize event listeners and send session configuration.
49
+ */
50
+ private init;
51
+ /**
52
+ * Build session configuration from agent.
53
+ */
54
+ private buildSessionConfig;
55
+ /**
56
+ * Handle incoming events from the connection.
57
+ *
58
+ * Maps protocol events to simplified user-facing events:
59
+ * - 'audio' - audio output from assistant
60
+ * - 'transcript' - speech transcriptions (user or assistant)
61
+ * - 'text' - text output from assistant
62
+ * - 'error' - errors
63
+ */
64
+ private onEvent;
65
+ /**
66
+ * Execute tool calls from the model.
67
+ */
68
+ private performActions;
69
+ /**
70
+ * Send audio to the model.
71
+ */
72
+ sendAudio(audio: string): void;
73
+ /**
74
+ * Commit the audio buffer (signal end of speech).
75
+ */
76
+ commit(): void;
77
+ /**
78
+ * Send a text message to the model.
79
+ */
80
+ sendMessage(text: string): void;
81
+ /**
82
+ * Interrupt the current response.
83
+ */
84
+ interrupt(): void;
85
+ /**
86
+ * Mute audio input.
87
+ */
88
+ mute(): void;
89
+ /**
90
+ * Unmute audio input.
91
+ */
92
+ unmute(): void;
93
+ /**
94
+ * Close the session and release resources.
95
+ */
96
+ close(): void;
97
+ }
98
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/realtime/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EACL,aAAa,EAMd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGpD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEtD;;;;;GAKG;AACH,qBAAa,eAAe,CAAC,QAAQ,GAAG,cAAc,CAAE,SAAQ,YAAY;IAC1E;;OAEG;IACH,EAAE,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEzB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAExC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAE9B;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CAAC;IAEzC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEpC;;OAEG;IACH,OAAO,CAAC,UAAU,CAAmC;IAErD;;OAEG;IACH,OAAO,CAAC,OAAO,CAAmC;gBAGhD,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,EAC9B,OAAO,GAAE,sBAAsB,CAAC,QAAQ,CAAM;IAiBhD;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB9B;;OAEG;YACW,IAAI;IAalB;;OAEG;YACW,kBAAkB;IAUhC;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO;IAuCf;;OAEG;YACW,cAAc;IAyB5B;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI9B;;OAEG;IACH,MAAM,IAAI,IAAI;IAId;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAO/B;;OAEG;IACH,SAAS,IAAI,IAAI;IAKjB;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;OAEG;IACH,MAAM,IAAI,IAAI;IAId;;OAEG;IACH,KAAK,IAAI,IAAI;CAId"}
@@ -0,0 +1,203 @@
1
+ import { EventEmitter } from "node:events";
2
+ import { message, } from "@kernl-sdk/protocol";
3
+ import { Context } from "../context.js";
4
+ import { MisconfiguredError } from "../lib/error.js";
5
+ /**
6
+ * A realtime session manages the connection to a realtime model.
7
+ *
8
+ * Handles the bidirectional communication between an agent and a model,
9
+ * including audio I/O (via channels), tool execution, and event routing.
10
+ */
11
+ export class RealtimeSession extends EventEmitter {
12
+ /**
13
+ * Session ID. Null until connected.
14
+ */
15
+ id = null;
16
+ /**
17
+ * The agent definition.
18
+ */
19
+ agent;
20
+ /**
21
+ * The realtime model.
22
+ */
23
+ model;
24
+ /**
25
+ * The audio I/O channel (if any).
26
+ */
27
+ channel;
28
+ /**
29
+ * The session context.
30
+ */
31
+ context;
32
+ /**
33
+ * The active connection. Null until connected.
34
+ */
35
+ connection = null;
36
+ /**
37
+ * Session options.
38
+ */
39
+ options;
40
+ constructor(agent, options = {}) {
41
+ super();
42
+ if (options.transport?.handlesAudio && options.channel) {
43
+ throw new MisconfiguredError("Cannot use channel with WebRTC transport - audio is handled by transport");
44
+ }
45
+ this.agent = agent;
46
+ this.model = options.model ?? agent.model;
47
+ this.channel = options.channel ?? null;
48
+ this.context = options.context ?? new Context("kernl", {});
49
+ this.options = options;
50
+ }
51
+ /**
52
+ * Connect to the realtime model.
53
+ */
54
+ async connect() {
55
+ const sessionConfig = await this.buildSessionConfig();
56
+ const options = {
57
+ ...this.options.connectOptions,
58
+ sessionConfig,
59
+ };
60
+ this.connection = this.options.transport
61
+ ? await this.options.transport.connect(this.model, options)
62
+ : await this.model.connect(options);
63
+ this.connection.on("event", this.onEvent.bind(this));
64
+ this.connection.on("error", (e) => this.emit("error", e));
65
+ this.connection.on("status", (s) => this.emit("status", s));
66
+ this.init();
67
+ }
68
+ /**
69
+ * Initialize event listeners and send session configuration.
70
+ */
71
+ async init() {
72
+ if (this.channel) {
73
+ this.channel.on("audio", (audio) => this.sendAudio(audio));
74
+ this.channel.on("commit", () => this.commit());
75
+ this.channel.on("interrupt", () => this.interrupt());
76
+ }
77
+ this.connection?.send({
78
+ kind: "session.update",
79
+ config: await this.buildSessionConfig(),
80
+ });
81
+ }
82
+ /**
83
+ * Build session configuration from agent.
84
+ */
85
+ async buildSessionConfig() {
86
+ const tools = await this.agent.tools(this.context);
87
+ return {
88
+ instructions: await this.agent.instructions(this.context),
89
+ tools: tools.map((t) => t.serialize()),
90
+ voice: this.agent.voice,
91
+ };
92
+ }
93
+ /**
94
+ * Handle incoming events from the connection.
95
+ *
96
+ * Maps protocol events to simplified user-facing events:
97
+ * - 'audio' - audio output from assistant
98
+ * - 'transcript' - speech transcriptions (user or assistant)
99
+ * - 'text' - text output from assistant
100
+ * - 'error' - errors
101
+ */
102
+ onEvent(event) {
103
+ switch (event.kind) {
104
+ // Audio output → 'audio'
105
+ case "audio.output.delta":
106
+ this.channel?.sendAudio(event.audio);
107
+ this.emit("audio", event);
108
+ break;
109
+ case "audio.output.done":
110
+ this.emit("audio", event);
111
+ break;
112
+ // Speech transcriptions → 'transcript'
113
+ case "transcript.input":
114
+ case "transcript.output":
115
+ this.emit("transcript", event);
116
+ break;
117
+ // Text output → 'text'
118
+ case "text.output":
119
+ this.emit("text", event);
120
+ break;
121
+ // Errors → 'error'
122
+ case "session.error":
123
+ this.emit("error", event.error);
124
+ break;
125
+ // Tool calls - handled internally
126
+ case "tool.call":
127
+ this.performActions(event);
128
+ break;
129
+ // Session lifecycle - internal state
130
+ case "session.created":
131
+ this.id = event.session.id;
132
+ break;
133
+ }
134
+ }
135
+ /**
136
+ * Execute tool calls from the model.
137
+ */
138
+ async performActions(event) {
139
+ const tool = this.agent.tool(event.toolId);
140
+ if (!tool || tool.type !== "function") {
141
+ this.connection?.send({
142
+ kind: "tool.result",
143
+ callId: event.callId,
144
+ error: `Unknown tool: ${event.toolId}`,
145
+ });
146
+ return;
147
+ }
148
+ const result = await tool.invoke(this.context, event.arguments, event.callId);
149
+ this.connection?.send({
150
+ kind: "tool.result",
151
+ callId: event.callId,
152
+ result: result.state === "completed" ? String(result.result) : undefined,
153
+ error: result.error ?? undefined,
154
+ });
155
+ }
156
+ /**
157
+ * Send audio to the model.
158
+ */
159
+ sendAudio(audio) {
160
+ this.connection?.send({ kind: "audio.input.append", audio });
161
+ }
162
+ /**
163
+ * Commit the audio buffer (signal end of speech).
164
+ */
165
+ commit() {
166
+ this.connection?.send({ kind: "audio.input.commit" });
167
+ }
168
+ /**
169
+ * Send a text message to the model.
170
+ */
171
+ sendMessage(text) {
172
+ this.connection?.send({
173
+ kind: "item.create",
174
+ item: message({ role: "user", text }),
175
+ });
176
+ }
177
+ /**
178
+ * Interrupt the current response.
179
+ */
180
+ interrupt() {
181
+ this.connection?.send({ kind: "response.cancel" });
182
+ this.channel?.interrupt();
183
+ }
184
+ /**
185
+ * Mute audio input.
186
+ */
187
+ mute() {
188
+ this.connection?.mute();
189
+ }
190
+ /**
191
+ * Unmute audio input.
192
+ */
193
+ unmute() {
194
+ this.connection?.unmute();
195
+ }
196
+ /**
197
+ * Close the session and release resources.
198
+ */
199
+ close() {
200
+ this.channel?.close();
201
+ this.connection?.close();
202
+ }
203
+ }