kernl 0.9.1 → 0.11.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 (64) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +34 -0
  3. package/dist/agent/base.d.ts +5 -1
  4. package/dist/agent/base.d.ts.map +1 -1
  5. package/dist/agent/base.js +8 -0
  6. package/dist/agent.d.ts +1 -1
  7. package/dist/agent.d.ts.map +1 -1
  8. package/dist/agent.js +15 -2
  9. package/dist/context.d.ts +2 -0
  10. package/dist/context.d.ts.map +1 -1
  11. package/dist/context.js +2 -0
  12. package/dist/index.d.ts +2 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +2 -1
  15. package/dist/kernl/kernl.d.ts +1 -2
  16. package/dist/kernl/kernl.d.ts.map +1 -1
  17. package/dist/kernl/kernl.js +61 -1
  18. package/dist/lib/env.d.ts.map +1 -1
  19. package/dist/lib/env.js +1 -1
  20. package/dist/lifecycle/__tests__/hooks.test.d.ts +2 -0
  21. package/dist/lifecycle/__tests__/hooks.test.d.ts.map +1 -0
  22. package/dist/lifecycle/__tests__/hooks.test.js +553 -0
  23. package/dist/lifecycle.d.ts +222 -120
  24. package/dist/lifecycle.d.ts.map +1 -1
  25. package/dist/lifecycle.js +5 -23
  26. package/dist/memory/memory.js +1 -1
  27. package/dist/realtime/index.d.ts +1 -1
  28. package/dist/realtime/index.d.ts.map +1 -1
  29. package/dist/realtime/index.js +1 -1
  30. package/dist/realtime/session.d.ts +31 -22
  31. package/dist/realtime/session.d.ts.map +1 -1
  32. package/dist/realtime/session.js +64 -55
  33. package/dist/realtime/transport.d.ts +45 -0
  34. package/dist/realtime/transport.d.ts.map +1 -0
  35. package/dist/realtime/transport.js +32 -0
  36. package/dist/realtime/types.d.ts +8 -2
  37. package/dist/realtime/types.d.ts.map +1 -1
  38. package/dist/thread/__tests__/thread.test.js +2 -2
  39. package/dist/thread/thread.d.ts +2 -2
  40. package/dist/thread/thread.d.ts.map +1 -1
  41. package/dist/thread/thread.js +75 -8
  42. package/dist/thread/types.d.ts +1 -1
  43. package/dist/thread/types.d.ts.map +1 -1
  44. package/package.json +4 -4
  45. package/src/agent/base.ts +13 -1
  46. package/src/agent.ts +17 -3
  47. package/src/context.ts +2 -0
  48. package/src/index.ts +10 -1
  49. package/src/kernl/kernl.ts +67 -3
  50. package/src/lib/env.ts +3 -1
  51. package/src/lifecycle/__tests__/hooks.test.ts +668 -0
  52. package/src/lifecycle.ts +289 -163
  53. package/src/memory/memory.ts +1 -1
  54. package/src/realtime/index.ts +1 -1
  55. package/src/realtime/session.ts +88 -64
  56. package/src/realtime/transport.ts +64 -0
  57. package/src/realtime/types.ts +10 -2
  58. package/src/thread/__tests__/thread.test.ts +2 -2
  59. package/src/thread/thread.ts +88 -10
  60. package/src/thread/types.ts +1 -1
  61. package/dist/realtime/channel.d.ts +0 -30
  62. package/dist/realtime/channel.d.ts.map +0 -1
  63. package/dist/realtime/channel.js +0 -1
  64. package/src/realtime/channel.ts +0 -32
@@ -1,4 +1,4 @@
1
- import { EventEmitter } from "node:events";
1
+ import { Emitter } from "@kernl-sdk/shared";
2
2
  import { message, } from "@kernl-sdk/protocol";
3
3
  import { Context } from "../context.js";
4
4
  import { MisconfiguredError } from "../lib/error.js";
@@ -8,7 +8,7 @@ import { MisconfiguredError } from "../lib/error.js";
8
8
  * Handles the bidirectional communication between an agent and a model,
9
9
  * including audio I/O (via channels), tool execution, and event routing.
10
10
  */
11
- export class RealtimeSession extends EventEmitter {
11
+ export class RealtimeSession extends Emitter {
12
12
  /**
13
13
  * Session ID. Null until connected.
14
14
  */
@@ -56,6 +56,7 @@ export class RealtimeSession extends EventEmitter {
56
56
  const options = {
57
57
  ...this.options.connectOptions,
58
58
  sessionConfig,
59
+ credential: this.options.credential ?? this.options.connectOptions?.credential,
59
60
  };
60
61
  this.connection = this.options.transport
61
62
  ? await this.options.transport.connect(this.model, options)
@@ -63,6 +64,9 @@ export class RealtimeSession extends EventEmitter {
63
64
  this.connection.on("event", this.onEvent.bind(this));
64
65
  this.connection.on("error", (e) => this.emit("error", e));
65
66
  this.connection.on("status", (s) => this.emit("status", s));
67
+ this.connection.on("interrupted", () => this.channel?.interrupt());
68
+ // Emit current status (may have been set before listeners attached)
69
+ this.emit("status", this.connection.status);
66
70
  this.init();
67
71
  }
68
72
  /**
@@ -79,6 +83,53 @@ export class RealtimeSession extends EventEmitter {
79
83
  config: await this.buildSessionConfig(),
80
84
  });
81
85
  }
86
+ /**
87
+ * Send audio to the model.
88
+ */
89
+ sendAudio(audio) {
90
+ this.connection?.send({ kind: "audio.input.append", audio });
91
+ }
92
+ /**
93
+ * Commit the audio buffer (signal end of speech).
94
+ */
95
+ commit() {
96
+ this.connection?.send({ kind: "audio.input.commit" });
97
+ }
98
+ /**
99
+ * Send a text message to the model.
100
+ */
101
+ sendMessage(text) {
102
+ this.connection?.send({
103
+ kind: "item.create",
104
+ item: message({ role: "user", text }),
105
+ });
106
+ }
107
+ /**
108
+ * Interrupt the current response.
109
+ */
110
+ interrupt() {
111
+ this.connection?.send({ kind: "response.cancel" });
112
+ this.channel?.interrupt();
113
+ }
114
+ /**
115
+ * Mute audio input.
116
+ */
117
+ mute() {
118
+ this.connection?.mute();
119
+ }
120
+ /**
121
+ * Unmute audio input.
122
+ */
123
+ unmute() {
124
+ this.connection?.unmute();
125
+ }
126
+ /**
127
+ * Close the session and release resources.
128
+ */
129
+ close() {
130
+ this.channel?.close();
131
+ this.connection?.close();
132
+ }
82
133
  /**
83
134
  * Build session configuration from agent.
84
135
  */
@@ -88,6 +139,11 @@ export class RealtimeSession extends EventEmitter {
88
139
  instructions: await this.agent.instructions(this.context),
89
140
  tools: tools.map((t) => t.serialize()),
90
141
  voice: this.agent.voice,
142
+ turnDetection: { mode: "server_vad" },
143
+ audio: {
144
+ inputFormat: { mimeType: "audio/pcm", sampleRate: 24000 },
145
+ outputFormat: { mimeType: "audio/pcm", sampleRate: 24000 },
146
+ },
91
147
  };
92
148
  }
93
149
  /**
@@ -101,7 +157,7 @@ export class RealtimeSession extends EventEmitter {
101
157
  */
102
158
  onEvent(event) {
103
159
  switch (event.kind) {
104
- // Audio output → 'audio'
160
+ // audio output → 'audio'
105
161
  case "audio.output.delta":
106
162
  this.channel?.sendAudio(event.audio);
107
163
  this.emit("audio", event);
@@ -109,24 +165,24 @@ export class RealtimeSession extends EventEmitter {
109
165
  case "audio.output.done":
110
166
  this.emit("audio", event);
111
167
  break;
112
- // Speech transcriptions → 'transcript'
168
+ // speech transcriptions → 'transcript'
113
169
  case "transcript.input":
114
170
  case "transcript.output":
115
171
  this.emit("transcript", event);
116
172
  break;
117
- // Text output → 'text'
173
+ // text output → 'text'
118
174
  case "text.output":
119
175
  this.emit("text", event);
120
176
  break;
121
- // Errors → 'error'
177
+ // ERrors → 'error'
122
178
  case "session.error":
123
179
  this.emit("error", event.error);
124
180
  break;
125
- // Tool calls - handled internally
181
+ // tool calls - handled internally
126
182
  case "tool.call":
127
183
  this.performActions(event);
128
184
  break;
129
- // Session lifecycle - internal state
185
+ // session lifecycle - internal state
130
186
  case "session.created":
131
187
  this.id = event.session.id;
132
188
  break;
@@ -153,51 +209,4 @@ export class RealtimeSession extends EventEmitter {
153
209
  error: result.error ?? undefined,
154
210
  });
155
211
  }
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
212
  }
@@ -0,0 +1,45 @@
1
+ import type { RealtimeModel, RealtimeConnection, RealtimeTransport, RealtimeConnectOptions, WebSocketConstructor } from "@kernl-sdk/protocol";
2
+ /**
3
+ * Options for creating a WebSocket transport.
4
+ */
5
+ export interface WebSocketTransportOptions {
6
+ /**
7
+ * WebSocket constructor to use.
8
+ *
9
+ * Required in Node.js <22 (provide the 'ws' package).
10
+ * Optional in browsers and Node.js 22+ (uses globalThis.WebSocket).
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import WebSocket from 'ws';
15
+ * new WebSocketTransport({ websocket: WebSocket });
16
+ * ```
17
+ */
18
+ websocket?: WebSocketConstructor;
19
+ }
20
+ /**
21
+ * WebSocket transport for realtime connections.
22
+ *
23
+ * Use this transport when you need to provide a custom WebSocket implementation,
24
+ * such as the 'ws' package in Node.js <22.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * // Node.js <22
29
+ * import WebSocket from 'ws';
30
+ * const session = new RealtimeSession(agent, {
31
+ * transport: new WebSocketTransport({ websocket: WebSocket }),
32
+ * ...
33
+ * });
34
+ *
35
+ * // Browser or Node.js 22+ - no transport needed
36
+ * const session = new RealtimeSession(agent, { ... });
37
+ * ```
38
+ */
39
+ export declare class WebSocketTransport implements RealtimeTransport {
40
+ readonly handlesAudio = false;
41
+ private WS;
42
+ constructor(options?: WebSocketTransportOptions);
43
+ connect(model: RealtimeModel, options?: RealtimeConnectOptions): Promise<RealtimeConnection>;
44
+ }
45
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/realtime/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,qBAAqB,CAAC;AAE7B;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,EAAE,oBAAoB,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,kBAAmB,YAAW,iBAAiB;IAC1D,QAAQ,CAAC,YAAY,SAAS;IAC9B,OAAO,CAAC,EAAE,CAAmC;gBAEjC,OAAO,CAAC,EAAE,yBAAyB;IAIzC,OAAO,CACX,KAAK,EAAE,aAAa,EACpB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,kBAAkB,CAAC;CAM/B"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * WebSocket transport for realtime connections.
3
+ *
4
+ * Use this transport when you need to provide a custom WebSocket implementation,
5
+ * such as the 'ws' package in Node.js <22.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * // Node.js <22
10
+ * import WebSocket from 'ws';
11
+ * const session = new RealtimeSession(agent, {
12
+ * transport: new WebSocketTransport({ websocket: WebSocket }),
13
+ * ...
14
+ * });
15
+ *
16
+ * // Browser or Node.js 22+ - no transport needed
17
+ * const session = new RealtimeSession(agent, { ... });
18
+ * ```
19
+ */
20
+ export class WebSocketTransport {
21
+ handlesAudio = false;
22
+ WS;
23
+ constructor(options) {
24
+ this.WS = options?.websocket;
25
+ }
26
+ async connect(model, options) {
27
+ return model.connect({
28
+ ...options,
29
+ websocket: this.WS ?? options?.websocket,
30
+ });
31
+ }
32
+ }
@@ -1,7 +1,6 @@
1
- import { RealtimeModel, RealtimeTransport, RealtimeConnectOptions } from "@kernl-sdk/protocol";
1
+ import { RealtimeModel, RealtimeTransport, RealtimeConnectOptions, RealtimeChannel, ClientCredential } from "@kernl-sdk/protocol";
2
2
  import { Context, UnknownContext } from "../context.js";
3
3
  import type { BaseAgentConfig } from "../agent/base.js";
4
- import type { RealtimeChannel } from "./channel.js";
5
4
  /**
6
5
  * Configuration for a realtime agent.
7
6
  */
@@ -50,6 +49,13 @@ export interface RealtimeSessionOptions<TContext = UnknownContext> {
50
49
  * Context for this session.
51
50
  */
52
51
  context?: Context<TContext>;
52
+ /**
53
+ * Ephemeral credential for client-side connections.
54
+ *
55
+ * Obtained from model.authenticate() on the server.
56
+ * Shorthand for connectOptions.credential.
57
+ */
58
+ credential?: ClientCredential;
53
59
  /**
54
60
  * Options passed to model.connect() or transport.connect().
55
61
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/realtime/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,QAAQ,GAAG,cAAc,CAC5D,SAAQ,eAAe,CAAC,QAAQ,CAAC;IACjC;;OAEG;IACH,KAAK,EAAE,aAAa,CAAC;IAErB;;OAEG;IACH,KAAK,CAAC,EAAE,wBAAwB,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB,CAAC,QAAQ,GAAG,cAAc;IAC/D;;OAEG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;IAEtB;;;OAGG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC;IAE1B;;;OAGG;IACH,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAE9B;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE5B;;OAEG;IACH,cAAc,CAAC,EAAE,sBAAsB,CAAC;CACzC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/realtime/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EACjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,QAAQ,GAAG,cAAc,CAC5D,SAAQ,eAAe,CAAC,QAAQ,CAAC;IACjC;;OAEG;IACH,KAAK,EAAE,aAAa,CAAC;IAErB;;OAEG;IACH,KAAK,CAAC,EAAE,wBAAwB,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB,CAAC,QAAQ,GAAG,cAAc;IAC/D;;OAEG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;IAEtB;;;OAGG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC;IAE1B;;;OAGG;IACH,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAE9B;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE5B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAE9B;;OAEG;IACH,cAAc,CAAC,EAAE,sBAAsB,CAAC;CACzC"}
@@ -275,7 +275,7 @@ describe("Thread", () => {
275
275
  toolId: "simple",
276
276
  state: IN_PROGRESS,
277
277
  callId: "call_1",
278
- arguments: "first",
278
+ arguments: JSON.stringify({ value: "first" }),
279
279
  },
280
280
  ],
281
281
  finishReason: "stop",
@@ -301,7 +301,7 @@ describe("Thread", () => {
301
301
  toolId: "simple",
302
302
  state: IN_PROGRESS,
303
303
  callId: "call_2",
304
- arguments: "second",
304
+ arguments: JSON.stringify({ value: "second" }),
305
305
  },
306
306
  ],
307
307
  finishReason: "stop",
@@ -49,8 +49,8 @@ export declare class Thread<TContext = unknown, TOutput extends AgentOutputType
49
49
  readonly tid: string;
50
50
  readonly namespace: string;
51
51
  readonly agent: Agent<TContext, TOutput>;
52
- readonly context: Context<TContext>;
53
- readonly model: LanguageModel;
52
+ context: Context<TContext>;
53
+ model: LanguageModel;
54
54
  readonly parent: Task<TContext> | null;
55
55
  readonly createdAt: Date;
56
56
  readonly updatedAt: Date;
@@ -1 +1 @@
1
- {"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../src/thread/thread.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAKzD,OAAO,EAML,aAAa,EAGd,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EAEV,WAAW,EACX,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EAEpB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAWrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qBAAa,MAAM,CACjB,QAAQ,GAAG,OAAO,EAClB,OAAO,SAAS,eAAe,GAAG,MAAM;IAExC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAIlD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,OAAO,CAAwE;IAEvF,OAAO,CAAC,KAAK,CAAC,CAAkB;IAChC,OAAO,CAAC,OAAO,CAAC,CAAc;gBAElB,OAAO,EAAE,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC;IAgCrD;;OAEG;IACG,OAAO,IAAI,OAAO,CACtB,mBAAmB,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CACpD;IAoBD;;OAEG;IACI,MAAM,IAAI,aAAa,CAAC,iBAAiB,CAAC;IAuBjD;;;;;OAKG;YACY,QAAQ;IAgEvB;;;;;OAKG;YACY,IAAI;IA8BnB;;;;;OAKG;YACW,UAAU;IAuCxB;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,KAAK,EAAE,gBAAgB,EAAE,GAAG,WAAW,EAAE;IAiBnD;;OAEG;IACH,MAAM;IAQN;;OAEG;YACW,cAAc;IAyC5B;;;;OAIG;YACW,YAAY;IA4C1B;;OAEG;YACW,mBAAmB;CAsDlC"}
1
+ {"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../src/thread/thread.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAKzD,OAAO,EAML,aAAa,EAKd,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EAEV,WAAW,EACX,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EAEpB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAWrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qBAAa,MAAM,CACjB,QAAQ,GAAG,OAAO,EAClB,OAAO,SAAS,eAAe,GAAG,MAAM;IAExC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACzC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3B,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAIlD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,OAAO,CAAwE;IAEvF,OAAO,CAAC,KAAK,CAAC,CAAkB;IAChC,OAAO,CAAC,OAAO,CAAC,CAAc;gBAElB,OAAO,EAAE,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC;IAgCrD;;OAEG;IACG,OAAO,IAAI,OAAO,CACtB,mBAAmB,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CACpD;IAoBD;;OAEG;IACI,MAAM,IAAI,aAAa,CAAC,iBAAiB,CAAC;IAuBjD;;;;;OAKG;YACY,QAAQ;IAgEvB;;;;;OAKG;YACY,IAAI;IAoEnB;;;;;OAKG;YACW,UAAU;IAuCxB;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,KAAK,EAAE,gBAAgB,EAAE,GAAG,WAAW,EAAE;IAiBnD;;OAEG;IACH,MAAM;IAQN;;OAEG;YACW,cAAc;IAyC5B;;;;OAIG;YACW,YAAY;IAkF1B;;OAEG;YACW,mBAAmB;CAsDlC"}
@@ -143,14 +143,14 @@ export class Thread {
143
143
  */
144
144
  async *_execute() {
145
145
  for (;;) {
146
- let err = false;
146
+ let err = undefined;
147
147
  if (this.abort?.signal.aborted) {
148
148
  return;
149
149
  }
150
150
  const events = [];
151
151
  for await (const e of this.tick()) {
152
152
  if (e.kind === "error") {
153
- err = true;
153
+ err = e.error;
154
154
  logger.error(e.error); // (TODO): onError callback in options
155
155
  }
156
156
  // we don't want deltas in the history
@@ -160,9 +160,9 @@ export class Thread {
160
160
  }
161
161
  yield e;
162
162
  }
163
- // if an error event occurred → terminate
163
+ // if an error event occurred → throw it
164
164
  if (err) {
165
- return;
165
+ throw err;
166
166
  }
167
167
  // if model returns a message with no action intentions → terminal state
168
168
  const intentions = getIntentions(events);
@@ -205,23 +205,57 @@ export class Thread {
205
205
  // (TODO): check limits (if this._tick > this.limits.maxTicks)
206
206
  // (TODO): run input guardrails on first tick (if this._tick === 1)
207
207
  const req = await this.prepareModelRequest(this.history);
208
+ this.agent.emit("model.call.start", {
209
+ kind: "model.call.start",
210
+ provider: this.model.provider,
211
+ modelId: this.model.modelId,
212
+ settings: req.settings ?? {},
213
+ threadId: this.tid,
214
+ agentId: this.agent.id,
215
+ context: this.context,
216
+ });
217
+ let usage;
218
+ let finishReason = "unknown";
208
219
  try {
209
220
  if (this.model.stream) {
210
- const stream = this.model.stream(req);
211
- for await (const event of stream) {
212
- yield event; // [text-delta, tool-call, message, reasoning, ...]
221
+ for await (const event of this.model.stream(req)) {
222
+ if (event.kind === "finish") {
223
+ usage = event.usage;
224
+ finishReason = event.finishReason;
225
+ }
226
+ yield event;
213
227
  }
214
228
  }
215
229
  else {
216
230
  // fallback: blocking generate, yield events as batch
217
231
  const res = await this.model.generate(req);
232
+ usage = res.usage;
233
+ finishReason = res.finishReason;
218
234
  for (const event of res.content) {
219
235
  yield event;
220
236
  }
221
- // (TODO): this.stats.usage.add(res.usage)
222
237
  }
238
+ this.agent.emit("model.call.end", {
239
+ kind: "model.call.end",
240
+ provider: this.model.provider,
241
+ modelId: this.model.modelId,
242
+ finishReason,
243
+ usage,
244
+ threadId: this.tid,
245
+ agentId: this.agent.id,
246
+ context: this.context,
247
+ });
223
248
  }
224
249
  catch (error) {
250
+ this.agent.emit("model.call.end", {
251
+ kind: "model.call.end",
252
+ provider: this.model.provider,
253
+ modelId: this.model.modelId,
254
+ finishReason: "error",
255
+ threadId: this.tid,
256
+ agentId: this.agent.id,
257
+ context: this.context,
258
+ });
225
259
  yield {
226
260
  kind: "error",
227
261
  error: error instanceof Error ? error : new Error(String(error)),
@@ -343,6 +377,16 @@ export class Thread {
343
377
  */
344
378
  async executeTools(calls) {
345
379
  return await Promise.all(calls.map(async (call) => {
380
+ const parsedArgs = JSON.parse(call.arguments || "{}");
381
+ this.agent.emit("tool.call.start", {
382
+ kind: "tool.call.start",
383
+ threadId: this.tid,
384
+ agentId: this.agent.id,
385
+ context: this.context,
386
+ toolId: call.toolId,
387
+ callId: call.callId,
388
+ args: parsedArgs,
389
+ });
346
390
  try {
347
391
  const tool = this.agent.tool(call.toolId);
348
392
  if (!tool) {
@@ -356,6 +400,19 @@ export class Thread {
356
400
  ctx.agent = this.agent;
357
401
  ctx.approve(call.callId); // mark this call as approved
358
402
  const res = await tool.invoke(ctx, call.arguments, call.callId);
403
+ this.agent.emit("tool.call.end", {
404
+ kind: "tool.call.end",
405
+ threadId: this.tid,
406
+ agentId: this.agent.id,
407
+ context: this.context,
408
+ toolId: call.toolId,
409
+ callId: call.callId,
410
+ state: res.state,
411
+ result: typeof res.result === "string"
412
+ ? res.result
413
+ : JSON.stringify(res.result),
414
+ error: res.error,
415
+ });
359
416
  return {
360
417
  kind: "tool-result",
361
418
  callId: call.callId,
@@ -366,6 +423,16 @@ export class Thread {
366
423
  };
367
424
  }
368
425
  catch (error) {
426
+ this.agent.emit("tool.call.end", {
427
+ kind: "tool.call.end",
428
+ threadId: this.tid,
429
+ agentId: this.agent.id,
430
+ context: this.context,
431
+ toolId: call.toolId,
432
+ callId: call.callId,
433
+ state: FAILED,
434
+ error: error instanceof Error ? error.message : String(error),
435
+ });
369
436
  return {
370
437
  kind: "tool-result",
371
438
  callId: call.callId,
@@ -124,7 +124,7 @@ export interface ThreadOptions<TContext = unknown, TOutput extends AgentOutputTy
124
124
  * Options passed to agent.execute() and agent.stream().
125
125
  */
126
126
  export interface ThreadExecuteOptions<TContext> {
127
- context?: Context<TContext>;
127
+ context?: TContext;
128
128
  model?: LanguageModel;
129
129
  task?: Task<TContext>;
130
130
  threadId?: string;
@@ -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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kernl",
3
- "version": "0.9.1",
3
+ "version": "0.11.0",
4
4
  "description": "A modern AI agent framework",
5
5
  "keywords": [
6
6
  "kernl",
@@ -34,8 +34,8 @@
34
34
  "dependencies": {
35
35
  "@modelcontextprotocol/sdk": "^1.20.2",
36
36
  "yaml": "^2.8.2",
37
- "@kernl-sdk/protocol": "0.3.1",
38
- "@kernl-sdk/retrieval": "0.1.5",
37
+ "@kernl-sdk/protocol": "0.4.1",
38
+ "@kernl-sdk/retrieval": "0.1.7",
39
39
  "@kernl-sdk/shared": "^0.3.1"
40
40
  },
41
41
  "peerDependencies": {
@@ -48,7 +48,7 @@
48
48
  "typescript": "5.9.2",
49
49
  "vitest": "^4.0.8",
50
50
  "zod": "^4.1.8",
51
- "@kernl-sdk/ai": "0.3.2"
51
+ "@kernl-sdk/ai": "0.3.4"
52
52
  },
53
53
  "scripts": {
54
54
  "clean": "rm -rf dist",
package/src/agent/base.ts CHANGED
@@ -4,7 +4,7 @@ import type { Context, UnknownContext } from "@/context";
4
4
  import type { Tool, BaseToolkit } from "@/tool";
5
5
  import { memory } from "@/tool";
6
6
  import { MisconfiguredError } from "@/lib/error";
7
- import { AgentHooks } from "@/lifecycle";
7
+ import { AgentHooks, type AgentHookEvents } from "@/lifecycle";
8
8
  import type { Kernl } from "@/kernl";
9
9
  import type {
10
10
  AgentMemoryCreate,
@@ -101,6 +101,18 @@ export abstract class BaseAgent<
101
101
  }
102
102
  }
103
103
 
104
+ /**
105
+ * Emit a lifecycle event to agent and kernl listeners.
106
+ */
107
+ emit<K extends keyof AgentHookEvents<TContext, TOutput>>(
108
+ event: K,
109
+ ...args: AgentHookEvents<TContext, TOutput>[K]
110
+ ): boolean {
111
+ const result = super.emit(event, ...args);
112
+ this.kernl?.emit(event, ...(args as any));
113
+ return result;
114
+ }
115
+
104
116
  /**
105
117
  * Get a specific tool by ID from systools and toolkits.
106
118
  */
package/src/agent.ts CHANGED
@@ -13,7 +13,7 @@ import type {
13
13
  RThreadHistoryParams,
14
14
  RThreadUpdateParams,
15
15
  } from "@/api/resources/threads/types";
16
- import type { Context, UnknownContext } from "./context";
16
+ import { Context, type UnknownContext } from "./context";
17
17
  import {
18
18
  InputGuardrail,
19
19
  OutputGuardrail,
@@ -102,10 +102,14 @@ export class Agent<
102
102
 
103
103
  // create new thread if not found in storage or no tid provided
104
104
  if (!thread) {
105
+ const ctx = options?.context
106
+ ? new Context<TContext>(options?.namespace ?? "kernl", options.context)
107
+ : undefined;
108
+
105
109
  thread = new Thread({
106
110
  agent: this,
107
111
  input: items,
108
- context: options?.context,
112
+ context: ctx,
109
113
  model: options?.model,
110
114
  task: options?.task,
111
115
  tid: options?.threadId,
@@ -116,6 +120,9 @@ export class Agent<
116
120
  }
117
121
 
118
122
  // resume existing thread from storage
123
+ if (options?.context) {
124
+ thread.context.context = options.context;
125
+ }
119
126
  thread.append(...items);
120
127
  return this.kernl.schedule(thread);
121
128
  }
@@ -163,10 +170,14 @@ export class Agent<
163
170
 
164
171
  // create new thread if not found in storage or no tid provided
165
172
  if (!thread) {
173
+ const ctx = options?.context
174
+ ? new Context<TContext>(options?.namespace ?? "kernl", options.context)
175
+ : undefined;
176
+
166
177
  thread = new Thread({
167
178
  agent: this,
168
179
  input: items,
169
- context: options?.context,
180
+ context: ctx,
170
181
  model: options?.model,
171
182
  task: options?.task,
172
183
  tid: options?.threadId,
@@ -178,6 +189,9 @@ export class Agent<
178
189
  }
179
190
 
180
191
  // resume existing thread from storage
192
+ if (options?.context) {
193
+ thread.context.context = options.context;
194
+ }
181
195
  thread.append(...items);
182
196
  yield* this.kernl.scheduleStream(thread);
183
197
  }
package/src/context.ts CHANGED
@@ -23,6 +23,8 @@ export class Context<TContext = UnknownContext> {
23
23
  /**
24
24
  * The agent executing this context.
25
25
  * Set by the thread during execution.
26
+ *
27
+ * NOTE: Primarily used by system tools (e.g., memory) that need agent access.
26
28
  */
27
29
  agent?: Agent<TContext, any>;
28
30
 
package/src/index.ts CHANGED
@@ -8,11 +8,20 @@ export type {
8
8
  export { Agent } from "./agent";
9
9
  export { Context } from "./context";
10
10
 
11
+ // --- realtime ---
12
+
13
+ export { RealtimeAgent, RealtimeSession, WebSocketTransport } from "./realtime";
14
+ export type {
15
+ RealtimeAgentConfig,
16
+ RealtimeAgentVoiceConfig,
17
+ RealtimeSessionOptions,
18
+ WebSocketTransportOptions,
19
+ } from "./realtime";
20
+
11
21
  // --- tools --
12
22
 
13
23
  export { tool, Toolkit, FunctionToolkit, MCPToolkit } from "./tool";
14
24
  export { MCPServerSSE } from "./mcp/sse";
15
- export { MCPServerStdio } from "./mcp/stdio";
16
25
  export { MCPServerStreamableHttp } from "./mcp/http";
17
26
 
18
27
  // --- threads ---