@agentuity/runtime 0.0.60 → 0.0.61

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 (61) hide show
  1. package/dist/_context.d.ts +11 -7
  2. package/dist/_context.d.ts.map +1 -1
  3. package/dist/_context.js +9 -2
  4. package/dist/_context.js.map +1 -1
  5. package/dist/_server.d.ts +4 -2
  6. package/dist/_server.d.ts.map +1 -1
  7. package/dist/_server.js +71 -31
  8. package/dist/_server.js.map +1 -1
  9. package/dist/_services.d.ts +1 -1
  10. package/dist/_services.d.ts.map +1 -1
  11. package/dist/_services.js +4 -2
  12. package/dist/_services.js.map +1 -1
  13. package/dist/_waituntil.d.ts.map +1 -1
  14. package/dist/_waituntil.js +5 -2
  15. package/dist/_waituntil.js.map +1 -1
  16. package/dist/agent.d.ts +647 -19
  17. package/dist/agent.d.ts.map +1 -1
  18. package/dist/agent.js +55 -6
  19. package/dist/agent.js.map +1 -1
  20. package/dist/app.d.ts +205 -28
  21. package/dist/app.d.ts.map +1 -1
  22. package/dist/app.js +181 -13
  23. package/dist/app.js.map +1 -1
  24. package/dist/index.d.ts +41 -2
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +2 -2
  27. package/dist/index.js.map +1 -1
  28. package/dist/io/email.d.ts.map +1 -1
  29. package/dist/io/email.js +11 -3
  30. package/dist/io/email.js.map +1 -1
  31. package/dist/router.d.ts +282 -32
  32. package/dist/router.d.ts.map +1 -1
  33. package/dist/router.js +110 -35
  34. package/dist/router.js.map +1 -1
  35. package/dist/services/evalrun/http.d.ts.map +1 -1
  36. package/dist/services/evalrun/http.js +7 -5
  37. package/dist/services/evalrun/http.js.map +1 -1
  38. package/dist/services/local/_util.d.ts.map +1 -1
  39. package/dist/services/local/_util.js +3 -1
  40. package/dist/services/local/_util.js.map +1 -1
  41. package/dist/services/session/http.d.ts.map +1 -1
  42. package/dist/services/session/http.js +4 -3
  43. package/dist/services/session/http.js.map +1 -1
  44. package/dist/session.d.ts +284 -4
  45. package/dist/session.d.ts.map +1 -1
  46. package/dist/session.js +2 -2
  47. package/dist/session.js.map +1 -1
  48. package/package.json +5 -4
  49. package/src/_context.ts +37 -9
  50. package/src/_server.ts +88 -36
  51. package/src/_services.ts +9 -2
  52. package/src/_waituntil.ts +13 -2
  53. package/src/agent.ts +856 -68
  54. package/src/app.ts +238 -38
  55. package/src/index.ts +42 -2
  56. package/src/io/email.ts +23 -5
  57. package/src/router.ts +359 -83
  58. package/src/services/evalrun/http.ts +15 -4
  59. package/src/services/local/_util.ts +7 -1
  60. package/src/services/session/http.ts +5 -2
  61. package/src/session.ts +297 -4
package/src/router.ts CHANGED
@@ -1,6 +1,13 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  /* eslint-disable @typescript-eslint/no-empty-object-type */
3
- import { type Context, Hono, type Input, type MiddlewareHandler, type Schema } from 'hono';
3
+ import {
4
+ type Context,
5
+ Hono,
6
+ type Input,
7
+ type MiddlewareHandler,
8
+ type Schema,
9
+ type Env as HonoEnv,
10
+ } from 'hono';
4
11
  import { stream as honoStream, streamSSE as honoStreamSSE } from 'hono/streaming';
5
12
  import { upgradeWebSocket as honoUpgradeWebSocket } from 'hono/bun';
6
13
  import { hash, returnResponse } from './_util';
@@ -8,6 +15,10 @@ import type { Env } from './app';
8
15
  import { getAgentAsyncLocalStorage } from './_context';
9
16
  import { parseEmail, type Email } from './io/email';
10
17
 
18
+ // Re-export both Env types
19
+ export type { Env };
20
+ export type { HonoEnv };
21
+
11
22
  type AgentHandler<E extends Env = Env, P extends string = string, I extends Input = {}> = (
12
23
  c: Context<E, P, I>
13
24
  ) => any | Promise<any>;
@@ -21,7 +32,7 @@ type StreamHandler<E extends Env = Env, P extends string = string, I extends Inp
21
32
  c: Context<E, P, I>
22
33
  ) => ReadableStream<any> | Promise<ReadableStream<any>>;
23
34
 
24
- interface WebSocketConnection {
35
+ export interface WebSocketConnection {
25
36
  onOpen: (handler: (event: any) => void | Promise<void>) => void;
26
37
  onMessage: (handler: (event: any) => void | Promise<void>) => void;
27
38
  onClose: (handler: (event: any) => void | Promise<void>) => void;
@@ -36,56 +47,314 @@ type SSEHandler<E extends Env = Env, P extends string = string, I extends Input
36
47
  c: Context<E, P, I>
37
48
  ) => (stream: any) => void | Promise<void>;
38
49
 
39
- type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'options';
40
-
41
- type ExtendedHono<E extends Env = Env, S extends Schema = {}> = {
42
- [K in Exclude<keyof Hono<E, S>, HttpMethod>]: Hono<E, S>[K];
43
- } & {
44
- [K in HttpMethod]: {
45
- <P extends string = string>(path: P, handler: AgentHandler<E, P>): Hono<E, S>;
46
- <P extends string = string, I extends Input = {}>(
47
- path: P,
48
- middleware: MiddlewareHandler<E, P, I>,
49
- handler: AgentHandler<E, P, I>
50
- ): Hono<E, S>;
51
- <P extends string = string, I extends Input = {}>(
52
- path: P,
53
- middleware: MiddlewareHandler<E, P, I>
54
- ): Hono<E, S>;
55
- };
56
- } & {
57
- email(address: string, handler: EmailHandler): Hono<E, S>;
58
- email<I extends Input = {}>(
59
- address: string,
60
- middleware: MiddlewareHandler<E, string, I>,
61
- handler: EmailHandler<E, string, I>
62
- ): Hono<E, S>;
63
- sms(params: { number: string }, handler: AgentHandler): Hono<E, S>;
64
- cron(schedule: string, handler: AgentHandler): Hono<E, S>;
65
- stream<P extends string = string>(path: P, handler: StreamHandler<E, P>): Hono<E, S>;
66
- stream<P extends string = string, I extends Input = {}>(
67
- path: P,
68
- middleware: MiddlewareHandler<E, P, I>,
69
- handler: StreamHandler<E, P, I>
70
- ): Hono<E, S>;
71
- websocket<P extends string = string>(path: P, handler: WebSocketHandler<E, P>): Hono<E, S>;
72
- websocket<P extends string = string, I extends Input = {}>(
73
- path: P,
74
- middleware: MiddlewareHandler<E, P, I>,
75
- handler: WebSocketHandler<E, P, I>
76
- ): Hono<E, S>;
77
- sse<P extends string = string>(path: P, handler: SSEHandler<E, P>): Hono<E, S>;
78
- sse<P extends string = string, I extends Input = {}>(
79
- path: P,
80
- middleware: MiddlewareHandler<E, P, I>,
81
- handler: SSEHandler<E, P, I>
82
- ): Hono<E, S>;
83
- };
50
+ // Module augmentation to add custom methods to Hono
51
+ // This avoids wrapper types and type instantiation depth issues
52
+ // Use simplified signatures to avoid type instantiation depth issues
53
+ declare module 'hono' {
54
+ interface Hono {
55
+ /**
56
+ * Register a route to handle incoming emails at a specific address.
57
+ *
58
+ * @param address - The email address to handle (e.g., 'support@example.com')
59
+ * @param handler - Handler function receiving parsed email and context
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * router.email('support@example.com', (email, c) => {
64
+ * console.log('From:', email.fromEmail());
65
+ * console.log('Subject:', email.subject());
66
+ * console.log('Body:', email.text());
67
+ * return c.text('Email received');
68
+ * });
69
+ * ```
70
+ */
71
+ email(address: string, handler: (email: Email, c: Context) => any): this;
72
+
73
+ /**
74
+ * Register a route to handle incoming emails with middleware.
75
+ *
76
+ * @param address - The email address to handle
77
+ * @param middleware - Middleware to run before the handler
78
+ * @param handler - Handler function receiving parsed email and context
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * router.email('support@example.com', authMiddleware, (email, c) => {
83
+ * return c.json({ received: email.subject() });
84
+ * });
85
+ * ```
86
+ */
87
+ email(
88
+ address: string,
89
+ middleware: MiddlewareHandler,
90
+ handler: (email: Email, c: Context) => any
91
+ ): this;
92
+
93
+ /**
94
+ * Register a route to handle incoming SMS messages to a phone number.
95
+ *
96
+ * @param params - Configuration object with phone number
97
+ * @param params.number - Phone number to handle (e.g., '+1234567890')
98
+ * @param handler - Handler function receiving context
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * router.sms({ number: '+1234567890' }, (c) => {
103
+ * const message = c.req.query('message');
104
+ * console.log('SMS received:', message);
105
+ * return c.text('SMS received');
106
+ * });
107
+ * ```
108
+ */
109
+ sms(params: { number: string }, handler: (c: Context) => any): this;
110
+
111
+ /**
112
+ * Schedule a handler to run at specific intervals using cron syntax.
113
+ *
114
+ * @param schedule - Cron expression (e.g., '0 0 * * *' for daily at midnight)
115
+ * @param handler - Handler function to run on schedule
116
+ *
117
+ * @example
118
+ * ```typescript
119
+ * // Run daily at midnight
120
+ * router.cron('0 0 * * *', (c) => {
121
+ * console.log('Daily cleanup running');
122
+ * return c.text('Cleanup complete');
123
+ * });
124
+ *
125
+ * // Run every hour
126
+ * router.cron('0 * * * *', (c) => {
127
+ * console.log('Hourly health check');
128
+ * return c.text('OK');
129
+ * });
130
+ * ```
131
+ */
132
+ cron(schedule: string, handler: (c: Context) => any): this;
133
+
134
+ /**
135
+ * Create a streaming route that returns a ReadableStream.
136
+ *
137
+ * @param path - The route path
138
+ * @param handler - Handler returning a ReadableStream
139
+ *
140
+ * @example
141
+ * ```typescript
142
+ * router.stream('/events', (c) => {
143
+ * return new ReadableStream({
144
+ * start(controller) {
145
+ * controller.enqueue('event 1\n');
146
+ * controller.enqueue('event 2\n');
147
+ * controller.close();
148
+ * }
149
+ * });
150
+ * });
151
+ * ```
152
+ */
153
+ stream(
154
+ path: string,
155
+ handler: (c: Context) => ReadableStream<any> | Promise<ReadableStream<any>>
156
+ ): this;
157
+
158
+ /**
159
+ * Create a streaming route with middleware.
160
+ *
161
+ * @param path - The route path
162
+ * @param middleware - Middleware to run before streaming
163
+ * @param handler - Handler returning a ReadableStream
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * router.stream('/protected-stream', authMiddleware, (c) => {
168
+ * return new ReadableStream({
169
+ * start(controller) {
170
+ * controller.enqueue('secure data\n');
171
+ * controller.close();
172
+ * }
173
+ * });
174
+ * });
175
+ * ```
176
+ */
177
+ stream(
178
+ path: string,
179
+ middleware: MiddlewareHandler,
180
+ handler: (c: Context) => ReadableStream<any> | Promise<ReadableStream<any>>
181
+ ): this;
182
+
183
+ /**
184
+ * Create a WebSocket route for real-time bidirectional communication.
185
+ *
186
+ * @param path - The route path
187
+ * @param handler - Setup function that registers WebSocket event handlers
188
+ *
189
+ * @example
190
+ * ```typescript
191
+ * router.websocket('/ws', (c) => (ws) => {
192
+ * ws.onOpen((event) => {
193
+ * console.log('WebSocket opened');
194
+ * ws.send('Welcome!');
195
+ * });
196
+ *
197
+ * ws.onMessage((event) => {
198
+ * console.log('Received:', event.data);
199
+ * ws.send('Echo: ' + event.data);
200
+ * });
201
+ *
202
+ * ws.onClose((event) => {
203
+ * console.log('WebSocket closed');
204
+ * });
205
+ * });
206
+ * ```
207
+ */
208
+ websocket(path: string, handler: (c: Context) => (ws: WebSocketConnection) => void): this;
209
+
210
+ /**
211
+ * Create a WebSocket route with middleware.
212
+ *
213
+ * @param path - The route path
214
+ * @param middleware - Middleware to run before WebSocket upgrade
215
+ * @param handler - Setup function that registers WebSocket event handlers
216
+ *
217
+ * @example
218
+ * ```typescript
219
+ * router.websocket('/ws', authMiddleware, (c) => (ws) => {
220
+ * ws.onMessage((event) => {
221
+ * ws.send('Authenticated echo: ' + event.data);
222
+ * });
223
+ * });
224
+ * ```
225
+ */
226
+ websocket(
227
+ path: string,
228
+ middleware: MiddlewareHandler,
229
+ handler: (c: Context) => (ws: WebSocketConnection) => void
230
+ ): this;
231
+
232
+ /**
233
+ * Create a Server-Sent Events (SSE) route for streaming updates to clients.
234
+ *
235
+ * @param path - The route path
236
+ * @param handler - Handler receiving SSE stream writer
237
+ *
238
+ * @example
239
+ * ```typescript
240
+ * router.sse('/notifications', (c) => async (stream) => {
241
+ * let count = 0;
242
+ * const interval = setInterval(() => {
243
+ * stream.writeSSE({
244
+ * data: `Notification ${++count}`,
245
+ * event: 'notification'
246
+ * });
247
+ * if (count >= 10) {
248
+ * clearInterval(interval);
249
+ * stream.close();
250
+ * }
251
+ * }, 1000);
252
+ * });
253
+ * ```
254
+ */
255
+ sse(path: string, handler: (c: Context) => (stream: any) => void): this;
256
+
257
+ /**
258
+ * Create an SSE route with middleware.
259
+ *
260
+ * @param path - The route path
261
+ * @param middleware - Middleware to run before SSE streaming
262
+ * @param handler - Handler receiving SSE stream writer
263
+ *
264
+ * @example
265
+ * ```typescript
266
+ * router.sse('/protected-events', authMiddleware, (c) => async (stream) => {
267
+ * stream.writeSSE({ data: 'Secure event', event: 'update' });
268
+ * stream.close();
269
+ * });
270
+ * ```
271
+ */
272
+ sse(
273
+ path: string,
274
+ middleware: MiddlewareHandler,
275
+ handler: (c: Context) => (stream: any) => void
276
+ ): this;
277
+ }
278
+ }
84
279
 
85
- export const createRouter = <E extends Env = Env, S extends Schema = Schema>(): ExtendedHono<
86
- E,
87
- S
88
- > => {
280
+ /**
281
+ * Creates a Hono router with extended methods for Agentuity-specific routing patterns.
282
+ *
283
+ * In addition to standard HTTP methods (get, post, put, delete, patch), the router includes:
284
+ * - **stream()** - Stream responses with ReadableStream
285
+ * - **websocket()** - WebSocket connections
286
+ * - **sse()** - Server-Sent Events
287
+ * - **email()** - Email handler routing
288
+ * - **sms()** - SMS handler routing
289
+ * - **cron()** - Scheduled task routing
290
+ *
291
+ * @template E - Environment type (Hono Env)
292
+ * @template S - Schema type for route definitions
293
+ *
294
+ * @returns Extended Hono router with custom methods
295
+ *
296
+ * @example
297
+ * ```typescript
298
+ * const router = createRouter();
299
+ *
300
+ * // Standard HTTP routes
301
+ * router.get('/hello', (c) => c.text('Hello!'));
302
+ * router.post('/data', async (c) => {
303
+ * const body = await c.req.json();
304
+ * return c.json({ received: body });
305
+ * });
306
+ *
307
+ * // Streaming response
308
+ * router.stream('/events', (c) => {
309
+ * return new ReadableStream({
310
+ * start(controller) {
311
+ * controller.enqueue('event 1\n');
312
+ * controller.enqueue('event 2\n');
313
+ * controller.close();
314
+ * }
315
+ * });
316
+ * });
317
+ *
318
+ * // WebSocket connection
319
+ * router.websocket('/ws', (c) => (ws) => {
320
+ * ws.onMessage((event) => {
321
+ * console.log('Received:', event.data);
322
+ * ws.send('Echo: ' + event.data);
323
+ * });
324
+ * });
325
+ *
326
+ * // Server-Sent Events
327
+ * router.sse('/notifications', (c) => async (stream) => {
328
+ * let count = 0;
329
+ * const interval = setInterval(() => {
330
+ * stream.writeSSE({ data: `Message ${++count}` });
331
+ * if (count >= 10) {
332
+ * clearInterval(interval);
333
+ * stream.close();
334
+ * }
335
+ * }, 1000);
336
+ * });
337
+ *
338
+ * // Email routing
339
+ * router.email('support@example.com', (email, c) => {
340
+ * console.log('From:', email.fromEmail());
341
+ * console.log('Subject:', email.subject());
342
+ * return c.text('Email received');
343
+ * });
344
+ *
345
+ * // SMS routing
346
+ * router.sms({ number: '+1234567890' }, (c) => {
347
+ * return c.text('SMS received');
348
+ * });
349
+ *
350
+ * // Scheduled cron
351
+ * router.cron('0 0 * * *', (c) => {
352
+ * console.log('Daily task running');
353
+ * return c.text('OK');
354
+ * });
355
+ * ```
356
+ */
357
+ export const createRouter = <E extends Env = Env, S extends Schema = Schema>(): Hono<E, S> => {
89
358
  const router = new Hono<E, S>();
90
359
  // tslint:disable-next-line:no-any no-unused-variable
91
360
  // biome-ignore lint:no-any
@@ -94,38 +363,45 @@ export const createRouter = <E extends Env = Env, S extends Schema = Schema>():
94
363
  for (const method of ['get', 'put', 'post', 'delete', 'options', 'patch']) {
95
364
  const _originalInvoker = _router[method].bind(router);
96
365
  _router[method] = (path: string, ...args: any[]) => {
97
- if (args.length === 1) {
98
- const arg = args[0];
99
- // Check if it's a middleware (not our agent handler)
100
- if (typeof arg === 'function' && arg.length === 2) {
101
- // Middleware only: (path, middleware)
102
- return _originalInvoker(path, arg);
103
- }
104
- // 2-arg: (path, handler)
105
- const handler = arg;
106
- const wrapper = async (c: Context): Promise<Response> => {
107
- let result = handler(c);
108
- if (result instanceof Promise) result = await result;
109
- // If handler returns a Response (e.g., websocket upgrade), return it unchanged
110
- if (result instanceof Response) return result;
111
- return returnResponse(c, result);
112
- };
113
- return _originalInvoker(path, wrapper);
114
- } else {
115
- // 3-arg: (path, middleware, handler)
116
- const middleware = args[0];
117
- const handler = args[1];
118
- const wrapper = async (c: Context): Promise<Response> => {
119
- let result = handler(c);
120
- if (result instanceof Promise) result = await result;
121
- // If handler returns a Response (e.g., websocket upgrade), return it unchanged
122
- if (result instanceof Response) {
123
- return result;
124
- }
125
- return returnResponse(c, result);
126
- };
127
- return _originalInvoker(path, middleware, wrapper);
366
+ // Pass through to original Hono - it handles all the complex type inference
367
+ // We'll only wrap the final handler to add our response handling
368
+ if (args.length === 0) {
369
+ return _originalInvoker(path);
370
+ }
371
+
372
+ // Find the last function in args - that's the handler (everything else is middleware)
373
+ let handlerIndex = args.length - 1;
374
+ while (handlerIndex >= 0 && typeof args[handlerIndex] !== 'function') {
375
+ handlerIndex--;
376
+ }
377
+
378
+ if (handlerIndex < 0) {
379
+ // No handler found, pass through as-is
380
+ return _originalInvoker(path, ...args);
381
+ }
382
+
383
+ const handler = args[handlerIndex];
384
+
385
+ // Check if this is middleware (2 params: c, next) vs handler (1 param: c)
386
+ if (handler.length === 2) {
387
+ // This is middleware-only, pass through
388
+ return _originalInvoker(path, ...args);
128
389
  }
390
+
391
+ // Wrap the handler to add our response conversion
392
+ const wrapper = async (c: Context): Promise<Response> => {
393
+ let result = handler(c);
394
+ if (result instanceof Promise) result = await result;
395
+ // If handler returns a Response, return it unchanged
396
+ if (result instanceof Response) return result;
397
+ return returnResponse(c, result);
398
+ };
399
+
400
+ // Replace the handler with our wrapper
401
+ const newArgs = [...args];
402
+ newArgs[handlerIndex] = wrapper;
403
+
404
+ return _originalInvoker(path, ...newArgs);
129
405
  };
130
406
  }
131
407
 
@@ -433,5 +709,5 @@ export const createRouter = <E extends Env = Env, S extends Schema = Schema>():
433
709
  }
434
710
  };
435
711
 
436
- return router as unknown as ExtendedHono<E, S>;
712
+ return router;
437
713
  };
@@ -1,4 +1,9 @@
1
- import { APIClient, APIResponseSchemaNoData, ValidationError } from '@agentuity/server';
1
+ import {
2
+ APIClient,
3
+ APIResponseSchemaNoData,
4
+ ValidationInputError,
5
+ ValidationOutputError,
6
+ } from '@agentuity/server';
2
7
  import {
3
8
  type EvalRunEventProvider,
4
9
  type EvalRunStartEvent,
@@ -6,8 +11,11 @@ import {
6
11
  EvalRunCompleteEventDelayedSchema,
7
12
  type EvalRunCompleteEvent,
8
13
  type Logger,
14
+ StructuredError,
9
15
  } from '@agentuity/core';
10
16
 
17
+ const EvalRunResponseError = StructuredError('EvalRunResponseError');
18
+
11
19
  /**
12
20
  * An implementation of the EvalRunEventProvider which uses HTTP for delivery
13
21
  */
@@ -51,7 +59,7 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
51
59
  }
52
60
  const errorMsg = resp.message || 'Unknown error';
53
61
  this.logger.error('[EVALRUN HTTP] Start event failed: %s, error: %s', event.id, errorMsg);
54
- throw new Error(errorMsg);
62
+ throw new EvalRunResponseError({ message: errorMsg });
55
63
  } catch (error) {
56
64
  this.logger.error(
57
65
  '[EVALRUN HTTP] Start event exception: %s, error: %s',
@@ -59,7 +67,10 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
59
67
  error instanceof Error ? error.message : String(error)
60
68
  );
61
69
  // Log validation errors if available
62
- if (error instanceof ValidationError) {
70
+ if (
71
+ (error instanceof ValidationInputError || error instanceof ValidationOutputError) &&
72
+ error.issues?.length
73
+ ) {
63
74
  this.logger.error(
64
75
  '[EVALRUN HTTP] Validation issues: %s',
65
76
  JSON.stringify(error.issues, null, 2)
@@ -99,7 +110,7 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
99
110
  event.id,
100
111
  errorMsg
101
112
  );
102
- throw new Error(errorMsg);
113
+ throw new EvalRunResponseError({ message: errorMsg });
103
114
  } catch (error) {
104
115
  this.logger.error(
105
116
  '[EVALRUN HTTP] Complete event exception: %s, error: %s',
@@ -1,3 +1,4 @@
1
+ import { StructuredError } from '@agentuity/core';
1
2
  import { resolve } from 'node:path';
2
3
 
3
4
  /**
@@ -26,12 +27,17 @@ export function simpleEmbedding(text: string, dimensions = 128): number[] {
26
27
  return magnitude > 0 ? vec.map((v) => v / magnitude) : vec;
27
28
  }
28
29
 
30
+ const InvalidVectorError = StructuredError(
31
+ 'InvalidVectorError',
32
+ 'Vectors must have the same dimension'
33
+ );
34
+
29
35
  /**
30
36
  * Calculate cosine similarity between two vectors
31
37
  */
32
38
  export function cosineSimilarity(a: number[], b: number[]): number {
33
39
  if (a.length !== b.length) {
34
- throw new Error('Vectors must have the same dimension');
40
+ throw new InvalidVectorError();
35
41
  }
36
42
 
37
43
  const dot = a.reduce((sum, ai, i) => sum + ai * (b[i] ?? 0), 0);
@@ -6,8 +6,11 @@ import {
6
6
  SessionCompleteEventDelayedSchema,
7
7
  type SessionCompleteEvent,
8
8
  type Logger,
9
+ StructuredError,
9
10
  } from '@agentuity/core';
10
11
 
12
+ const SessionResponseError = StructuredError('SessionResponseError');
13
+
11
14
  /**
12
15
  * An implementation of the SessionEventProvider which uses HTTP for delivery
13
16
  */
@@ -38,7 +41,7 @@ export class HTTPSessionEventProvider implements SessionEventProvider {
38
41
  this.logger.debug('Session start event sent successfully: %s', event.id);
39
42
  return;
40
43
  }
41
- throw new Error(resp.message);
44
+ throw new SessionResponseError({ message: resp.message });
42
45
  }
43
46
 
44
47
  /**
@@ -59,6 +62,6 @@ export class HTTPSessionEventProvider implements SessionEventProvider {
59
62
  this.logger.debug('Session complete event sent successfully: %s', event.id);
60
63
  return;
61
64
  }
62
- throw new Error(resp.message);
65
+ throw new SessionResponseError({ message: resp.message });
63
66
  }
64
67
  }