@agentuity/core 0.0.60 → 0.0.62

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 (60) hide show
  1. package/dist/error.d.ts +90 -0
  2. package/dist/error.d.ts.map +1 -0
  3. package/dist/error.js +258 -0
  4. package/dist/error.js.map +1 -0
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/json.d.ts +1 -1
  10. package/dist/json.d.ts.map +1 -1
  11. package/dist/json.js +2 -2
  12. package/dist/json.js.map +1 -1
  13. package/dist/services/_util.d.ts +2 -6
  14. package/dist/services/_util.d.ts.map +1 -1
  15. package/dist/services/_util.js +56 -8
  16. package/dist/services/_util.js.map +1 -1
  17. package/dist/services/adapter.d.ts +2 -1
  18. package/dist/services/adapter.d.ts.map +1 -1
  19. package/dist/services/exception.d.ts +20 -6
  20. package/dist/services/exception.d.ts.map +1 -1
  21. package/dist/services/exception.js +2 -11
  22. package/dist/services/exception.js.map +1 -1
  23. package/dist/services/index.d.ts +0 -1
  24. package/dist/services/index.d.ts.map +1 -1
  25. package/dist/services/keyvalue.d.ts.map +1 -1
  26. package/dist/services/keyvalue.js +5 -1
  27. package/dist/services/keyvalue.js.map +1 -1
  28. package/dist/services/objectstore.d.ts.map +1 -1
  29. package/dist/services/objectstore.js +65 -26
  30. package/dist/services/objectstore.js.map +1 -1
  31. package/dist/services/session.d.ts +2 -0
  32. package/dist/services/session.d.ts.map +1 -1
  33. package/dist/services/session.js +1 -0
  34. package/dist/services/session.js.map +1 -1
  35. package/dist/services/stream.d.ts.map +1 -1
  36. package/dist/services/stream.js +25 -9
  37. package/dist/services/stream.js.map +1 -1
  38. package/dist/services/vector.d.ts.map +1 -1
  39. package/dist/services/vector.js +48 -30
  40. package/dist/services/vector.js.map +1 -1
  41. package/dist/workbench-config.d.ts +38 -0
  42. package/dist/workbench-config.d.ts.map +1 -1
  43. package/dist/workbench-config.js +7 -5
  44. package/dist/workbench-config.js.map +1 -1
  45. package/package.json +1 -1
  46. package/src/__test__/error.test.ts +431 -0
  47. package/src/error.ts +384 -0
  48. package/src/index.ts +1 -0
  49. package/src/json.ts +2 -2
  50. package/src/services/__test__/vector.test.ts +20 -14
  51. package/src/services/_util.ts +56 -18
  52. package/src/services/adapter.ts +3 -1
  53. package/src/services/exception.ts +7 -9
  54. package/src/services/index.ts +0 -1
  55. package/src/services/keyvalue.ts +6 -1
  56. package/src/services/objectstore.ts +79 -44
  57. package/src/services/session.ts +1 -0
  58. package/src/services/stream.ts +45 -11
  59. package/src/services/vector.ts +99 -30
  60. package/src/workbench-config.ts +16 -5
@@ -1,5 +1,6 @@
1
1
  import { FetchAdapter } from './adapter';
2
2
  import { buildUrl, toServiceException, toPayload } from './_util';
3
+ import { StructuredError } from '../error';
3
4
 
4
5
  /**
5
6
  * the result of a data operation when the data is found
@@ -159,6 +160,8 @@ export interface KeyValueStorage {
159
160
  createNamespace(name: string): Promise<void>;
160
161
  }
161
162
 
163
+ const KeyValueInvalidTTLError = StructuredError('KeyValueInvalidTTLError');
164
+
162
165
  export class KeyValueStorageService implements KeyValueStorage {
163
166
  #adapter: FetchAdapter;
164
167
  #baseUrl: string;
@@ -207,7 +210,9 @@ export class KeyValueStorageService implements KeyValueStorage {
207
210
  let ttlstr = '';
208
211
  if (params?.ttl) {
209
212
  if (params.ttl < 60) {
210
- throw new Error(`ttl for keyvalue set must be at least 60 seconds, got ${params.ttl}`);
213
+ throw new KeyValueInvalidTTLError({
214
+ message: `ttl for keyvalue set must be at least 60 seconds, got ${params.ttl}`,
215
+ });
211
216
  }
212
217
  ttlstr = `/${params.ttl}`;
213
218
  }
@@ -1,5 +1,6 @@
1
1
  import type { FetchAdapter, FetchRequest, Body } from './adapter';
2
2
  import { buildUrl, toServiceException } from './_util';
3
+ import { StructuredError } from '../error';
3
4
 
4
5
  /**
5
6
  * Parameters for putting an object into the object store
@@ -280,6 +281,26 @@ export interface ObjectStorage {
280
281
  deleteBucket(bucket: string): Promise<boolean>;
281
282
  }
282
283
 
284
+ const ObjectStoreBucketMissingError = StructuredError(
285
+ 'ObjectStoreBucketMissingError',
286
+ 'bucket is required and cannot be empty'
287
+ );
288
+
289
+ const ObjectStoreKeyMissingError = StructuredError(
290
+ 'ObjectStoreKeyMissingError',
291
+ 'key is required and cannot be empty'
292
+ );
293
+
294
+ const ObjectStoreDataMissingError = StructuredError(
295
+ 'ObjectStoreDataMissingError',
296
+ 'data is required'
297
+ );
298
+
299
+ const ObjectStoreResponseError = StructuredError('ObjectStoreResponseError')<{ status: number }>();
300
+ const ObjectStoreResponseInvalidError = StructuredError('ObjectStoreResponseInvalidError');
301
+
302
+ const ObjectStoreNotFoundError = StructuredError('ObjectStoreNotFoundError', 'object not found');
303
+
283
304
  /**
284
305
  * Implementation of the ObjectStorage interface
285
306
  */
@@ -294,10 +315,10 @@ export class ObjectStorageService implements ObjectStorage {
294
315
 
295
316
  async get(bucket: string, key: string): Promise<ObjectResult> {
296
317
  if (!bucket?.trim()) {
297
- throw new Error('bucket is required and cannot be empty');
318
+ throw new ObjectStoreBucketMissingError();
298
319
  }
299
320
  if (!key?.trim()) {
300
- throw new Error('key is required and cannot be empty');
321
+ throw new ObjectStoreKeyMissingError();
301
322
  }
302
323
 
303
324
  const url = buildUrl(
@@ -326,14 +347,17 @@ export class ObjectStorageService implements ObjectStorage {
326
347
  }
327
348
 
328
349
  if (!result.ok) {
329
- throw new Error(
330
- `Failed to get object: ${result.response.statusText} (${result.response.status})`
331
- );
350
+ throw new ObjectStoreResponseError({
351
+ status: result.response.status,
352
+ message: `Failed to get object: ${result.response.statusText} (${result.response.status})`,
353
+ });
332
354
  }
333
355
 
334
356
  const data = result.data;
335
357
  if (!(data instanceof ArrayBuffer)) {
336
- throw new Error('Expected ArrayBuffer response from object store');
358
+ throw new ObjectStoreResponseInvalidError({
359
+ message: 'Expected ArrayBuffer response from object store',
360
+ });
337
361
  }
338
362
 
339
363
  const contentType =
@@ -359,13 +383,13 @@ export class ObjectStorageService implements ObjectStorage {
359
383
  params?: ObjectStorePutParams
360
384
  ): Promise<void> {
361
385
  if (!bucket?.trim()) {
362
- throw new Error('bucket is required and cannot be empty');
386
+ throw new ObjectStoreBucketMissingError();
363
387
  }
364
388
  if (!key?.trim()) {
365
- throw new Error('key is required and cannot be empty');
389
+ throw new ObjectStoreKeyMissingError();
366
390
  }
367
391
  if (!data) {
368
- throw new Error('data is required');
392
+ throw new ObjectStoreDataMissingError();
369
393
  }
370
394
 
371
395
  const url = buildUrl(
@@ -435,9 +459,10 @@ export class ObjectStorageService implements ObjectStorage {
435
459
  const result = await this.#adapter.invoke(url, options);
436
460
 
437
461
  if (!result.ok || (result.response.status !== 200 && result.response.status !== 201)) {
438
- throw new Error(
439
- `Failed to put object: ${result.response.statusText} (${result.response.status})`
440
- );
462
+ throw new ObjectStoreResponseError({
463
+ status: result.response.status,
464
+ message: `Failed to put object: ${result.response.statusText} (${result.response.status})`,
465
+ });
441
466
  }
442
467
  } catch (err) {
443
468
  if (err instanceof Response) {
@@ -449,10 +474,10 @@ export class ObjectStorageService implements ObjectStorage {
449
474
 
450
475
  async delete(bucket: string, key: string): Promise<boolean> {
451
476
  if (!bucket?.trim()) {
452
- throw new Error('bucket is required and cannot be empty');
477
+ throw new ObjectStoreBucketMissingError();
453
478
  }
454
479
  if (!key?.trim()) {
455
- throw new Error('key is required and cannot be empty');
480
+ throw new ObjectStoreKeyMissingError();
456
481
  }
457
482
 
458
483
  const url = buildUrl(
@@ -484,9 +509,10 @@ export class ObjectStorageService implements ObjectStorage {
484
509
  return true;
485
510
  }
486
511
 
487
- throw new Error(
488
- `Failed to delete object: ${result.response.statusText} (${result.response.status})`
489
- );
512
+ throw new ObjectStoreResponseError({
513
+ status: result.response.status,
514
+ message: `Failed to delete object: ${result.response.statusText} (${result.response.status})`,
515
+ });
490
516
  } catch (err) {
491
517
  if (err instanceof Response) {
492
518
  throw await toServiceException('DELETE', url, err);
@@ -501,10 +527,10 @@ export class ObjectStorageService implements ObjectStorage {
501
527
  params?: CreatePublicURLParams
502
528
  ): Promise<string> {
503
529
  if (!bucket?.trim()) {
504
- throw new Error('bucket is required and cannot be empty');
530
+ throw new ObjectStoreBucketMissingError();
505
531
  }
506
532
  if (!key?.trim()) {
507
- throw new Error('key is required and cannot be empty');
533
+ throw new ObjectStoreKeyMissingError();
508
534
  }
509
535
 
510
536
  const url = buildUrl(
@@ -540,15 +566,19 @@ export class ObjectStorageService implements ObjectStorage {
540
566
  );
541
567
 
542
568
  if (!result.ok) {
543
- throw new Error(
544
- `Failed to create public URL: ${result.response.statusText} (${result.response.status})`
545
- );
569
+ throw new ObjectStoreResponseError({
570
+ status: result.response.status,
571
+ message: `Failed to create public URL: ${result.response.statusText} (${result.response.status})`,
572
+ });
546
573
  }
547
574
 
548
575
  const data = result.data;
549
576
 
550
577
  if (!data.success) {
551
- throw new Error(data.message || 'Failed to create public URL');
578
+ throw new ObjectStoreResponseError({
579
+ status: result.response.status,
580
+ message: data.message || 'Failed to create public URL',
581
+ });
552
582
  }
553
583
 
554
584
  return data.url;
@@ -580,9 +610,10 @@ export class ObjectStorageService implements ObjectStorage {
580
610
  const result = await this.#adapter.invoke<{ buckets: BucketInfo[] }>(url, options);
581
611
 
582
612
  if (!result.ok) {
583
- throw new Error(
584
- `Failed to list buckets: ${result.response.statusText} (${result.response.status})`
585
- );
613
+ throw new ObjectStoreResponseError({
614
+ status: result.response.status,
615
+ message: `Failed to list buckets: ${result.response.statusText} (${result.response.status})`,
616
+ });
586
617
  }
587
618
 
588
619
  return result.data.buckets;
@@ -596,7 +627,7 @@ export class ObjectStorageService implements ObjectStorage {
596
627
 
597
628
  async listKeys(bucket: string): Promise<ObjectInfo[]> {
598
629
  if (!bucket?.trim()) {
599
- throw new Error('bucket is required and cannot be empty');
630
+ throw new ObjectStoreBucketMissingError();
600
631
  }
601
632
 
602
633
  const url = buildUrl(this.#baseUrl, `/object/2025-03-17/keys/${encodeURIComponent(bucket)}`);
@@ -620,9 +651,10 @@ export class ObjectStorageService implements ObjectStorage {
620
651
  );
621
652
 
622
653
  if (!result.ok) {
623
- throw new Error(
624
- `Failed to list keys: ${result.response.statusText} (${result.response.status})`
625
- );
654
+ throw new ObjectStoreResponseError({
655
+ status: result.response.status,
656
+ message: `Failed to list keys: ${result.response.statusText} (${result.response.status})`,
657
+ });
626
658
  }
627
659
 
628
660
  return result.data.objects;
@@ -639,7 +671,7 @@ export class ObjectStorageService implements ObjectStorage {
639
671
  options?: { prefix?: string; limit?: number }
640
672
  ): Promise<ObjectInfo[]> {
641
673
  if (!bucket?.trim()) {
642
- throw new Error('bucket is required and cannot be empty');
674
+ throw new ObjectStoreBucketMissingError();
643
675
  }
644
676
 
645
677
  const params = new URLSearchParams();
@@ -677,9 +709,10 @@ export class ObjectStorageService implements ObjectStorage {
677
709
  );
678
710
 
679
711
  if (!result.ok) {
680
- throw new Error(
681
- `Failed to list objects: ${result.response.statusText} (${result.response.status})`
682
- );
712
+ throw new ObjectStoreResponseError({
713
+ status: result.response.status,
714
+ message: `Failed to list objects: ${result.response.statusText} (${result.response.status})`,
715
+ });
683
716
  }
684
717
 
685
718
  return result.data.objects;
@@ -693,10 +726,10 @@ export class ObjectStorageService implements ObjectStorage {
693
726
 
694
727
  async headObject(bucket: string, key: string): Promise<ObjectInfo> {
695
728
  if (!bucket?.trim()) {
696
- throw new Error('bucket is required and cannot be empty');
729
+ throw new ObjectStoreBucketMissingError();
697
730
  }
698
731
  if (!key?.trim()) {
699
- throw new Error('key is required and cannot be empty');
732
+ throw new ObjectStoreKeyMissingError();
700
733
  }
701
734
 
702
735
  const url = buildUrl(
@@ -722,11 +755,12 @@ export class ObjectStorageService implements ObjectStorage {
722
755
 
723
756
  if (!result.ok) {
724
757
  if (result.response.status === 404) {
725
- throw new Error('Object not found');
758
+ throw new ObjectStoreNotFoundError();
726
759
  }
727
- throw new Error(
728
- `Failed to get object metadata: ${result.response.statusText} (${result.response.status})`
729
- );
760
+ throw new ObjectStoreResponseError({
761
+ status: result.response.status,
762
+ message: `Failed to get object metadata: ${result.response.statusText} (${result.response.status})`,
763
+ });
730
764
  }
731
765
 
732
766
  return result.data;
@@ -740,7 +774,7 @@ export class ObjectStorageService implements ObjectStorage {
740
774
 
741
775
  async deleteBucket(bucket: string): Promise<boolean> {
742
776
  if (!bucket?.trim()) {
743
- throw new Error('bucket is required and cannot be empty');
777
+ throw new ObjectStoreBucketMissingError();
744
778
  }
745
779
 
746
780
  const url = buildUrl(this.#baseUrl, `/object/2025-03-17/${encodeURIComponent(bucket)}`);
@@ -768,9 +802,10 @@ export class ObjectStorageService implements ObjectStorage {
768
802
  return true;
769
803
  }
770
804
 
771
- throw new Error(
772
- `Failed to delete bucket: ${result.response.statusText} (${result.response.status})`
773
- );
805
+ throw new ObjectStoreResponseError({
806
+ status: result.response.status,
807
+ message: `Failed to delete bucket: ${result.response.statusText} (${result.response.status})`,
808
+ });
774
809
  } catch (err) {
775
810
  if (err instanceof Response) {
776
811
  throw await toServiceException('DELETE', url, err);
@@ -29,6 +29,7 @@ export const SessionCompleteEventSchema = z
29
29
  .optional()
30
30
  .describe('optional array of ids for the agents that executed for the session'),
31
31
  statusCode: z.number().describe('the HTTP status code'),
32
+ userData: z.string().optional().describe('optional JSON string of session state data'),
32
33
  })
33
34
  .describe('The event to record a session completed successfully');
34
35
 
@@ -1,6 +1,7 @@
1
1
  import { safeStringify } from '../json';
2
2
  import { FetchAdapter, FetchResponse } from './adapter';
3
3
  import { buildUrl, toServiceException } from './_util';
4
+ import { StructuredError } from '../error';
4
5
 
5
6
  /**
6
7
  * Properties for creating a stream
@@ -262,6 +263,8 @@ export interface StreamStorage {
262
263
 
263
264
  const encoder = new TextEncoder();
264
265
 
266
+ const ReadStreamFailedError = StructuredError('ReadStreamFailedError')<{ status: number }>();
267
+
265
268
  /**
266
269
  * A writable stream implementation that extends WritableStream
267
270
  */
@@ -384,13 +387,21 @@ class StreamImpl extends WritableStream implements Stream {
384
387
 
385
388
  if (!res.ok) {
386
389
  controller.error(
387
- new Error(`Failed to read stream: ${response.status} ${response.statusText}`)
390
+ new ReadStreamFailedError({
391
+ status: response.status,
392
+ message: `Failed to read stream: ${response.status} ${response.statusText}`,
393
+ })
388
394
  );
389
395
  return;
390
396
  }
391
397
 
392
398
  if (!response.body) {
393
- controller.error(new Error('Response body is null'));
399
+ controller.error(
400
+ new ReadStreamFailedError({
401
+ status: response.status,
402
+ message: 'Response body was null',
403
+ })
404
+ );
394
405
  return;
395
406
  }
396
407
 
@@ -420,6 +431,13 @@ class StreamImpl extends WritableStream implements Stream {
420
431
  }
421
432
  }
422
433
 
434
+ const StreamWriterInitializationError = StructuredError(
435
+ 'StreamWriterInitializationError',
436
+ 'Stream writer is not initialized'
437
+ );
438
+
439
+ const StreamAPIError = StructuredError('StreamAPIError')<{ status: number }>();
440
+
423
441
  // Create a WritableStream that writes to the backend stream
424
442
  // Create the underlying sink that will handle the actual streaming
425
443
  class UnderlyingSink {
@@ -498,7 +516,7 @@ class UnderlyingSink {
498
516
 
499
517
  async write(chunk: string | Uint8Array | ArrayBuffer | Buffer | object) {
500
518
  if (!this.writer) {
501
- throw new Error('Stream writer not initialized');
519
+ throw new StreamWriterInitializationError();
502
520
  }
503
521
  // Convert input to Uint8Array if needed
504
522
  let binaryChunk: Uint8Array;
@@ -533,9 +551,10 @@ class UnderlyingSink {
533
551
  try {
534
552
  const res = await this.putRequestPromise;
535
553
  if (!res.ok) {
536
- throw new Error(
537
- `PUT request failed: ${res.response.status} ${res.response.statusText}`
538
- );
554
+ throw new StreamAPIError({
555
+ status: res.response.status,
556
+ message: `PUT request failed: ${res.response.status} ${res.response.statusText}`,
557
+ });
539
558
  }
540
559
  } catch (error) {
541
560
  if (error instanceof Error && error.name !== 'AbortError') {
@@ -560,6 +579,21 @@ class UnderlyingSink {
560
579
  }
561
580
  }
562
581
 
582
+ const StreamNameInvalidError = StructuredError(
583
+ 'StreamNameInvalidError',
584
+ 'Stream name must be between 1 and 254 characters'
585
+ );
586
+
587
+ const StreamLimitInvalidError = StructuredError(
588
+ 'StreamLimitInvalidError',
589
+ 'Stream limit must be greater than 0 and less than or equal to 1000'
590
+ );
591
+
592
+ const StreamIDRequiredError = StructuredError(
593
+ 'StreamIDRequiredError',
594
+ 'Stream id is required and must be a non-empty string'
595
+ );
596
+
563
597
  export class StreamStorageService implements StreamStorage {
564
598
  #adapter: FetchAdapter;
565
599
  #baseUrl: string;
@@ -571,7 +605,7 @@ export class StreamStorageService implements StreamStorage {
571
605
 
572
606
  async create(name: string, props?: CreateStreamProps): Promise<Stream> {
573
607
  if (!name || name.length < 1 || name.length > 254) {
574
- throw new Error('Stream name must be between 1 and 254 characters');
608
+ throw new StreamNameInvalidError();
575
609
  }
576
610
  const url = this.#baseUrl;
577
611
  const signal = AbortSignal.timeout(10_000);
@@ -624,7 +658,7 @@ export class StreamStorageService implements StreamStorage {
624
658
  const attributes: Record<string, string> = {};
625
659
  if (params?.limit !== undefined) {
626
660
  if (params.limit <= 0 || params.limit > 1000) {
627
- throw new Error('limit must be greater than 0 and less than or equal to 1000');
661
+ throw new StreamLimitInvalidError();
628
662
  }
629
663
  attributes['limit'] = String(params.limit);
630
664
  }
@@ -695,7 +729,7 @@ export class StreamStorageService implements StreamStorage {
695
729
 
696
730
  async get(id: string): Promise<StreamInfo> {
697
731
  if (!id || typeof id !== 'string' || id.trim().length === 0) {
698
- throw new Error('Stream id is required and must be a non-empty string');
732
+ throw new StreamIDRequiredError();
699
733
  }
700
734
  const signal = AbortSignal.timeout(30_000);
701
735
  const url = buildUrl(this.#baseUrl, id, 'info');
@@ -731,7 +765,7 @@ export class StreamStorageService implements StreamStorage {
731
765
 
732
766
  async download(id: string): Promise<ReadableStream<Uint8Array>> {
733
767
  if (!id || typeof id !== 'string' || id.trim().length === 0) {
734
- throw new Error('Stream id is required and must be a non-empty string');
768
+ throw new StreamIDRequiredError();
735
769
  }
736
770
  const signal = AbortSignal.timeout(300_000); // 5 minutes for download
737
771
  const url = buildUrl(this.#baseUrl, id);
@@ -754,7 +788,7 @@ export class StreamStorageService implements StreamStorage {
754
788
 
755
789
  async delete(id: string): Promise<void> {
756
790
  if (!id || typeof id !== 'string' || id.trim().length === 0) {
757
- throw new Error('Stream id is required and must be a non-empty string');
791
+ throw new StreamIDRequiredError();
758
792
  }
759
793
  const signal = AbortSignal.timeout(30_000);
760
794
  const url = buildUrl(this.#baseUrl, id);