hebbrix 2.2.0 → 2.3.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.
package/dist/index.mjs CHANGED
@@ -34,7 +34,7 @@ function enforceSearchSafety(response, rowsKey = "results") {
34
34
  reason = "no_match_contains_evidence";
35
35
  }
36
36
  }
37
- if (reason || data.degraded === true || data.no_match === true || data.abstain_recommended === true) {
37
+ if (reason || data.no_match === true) {
38
38
  data[rowsKey] = [];
39
39
  if (rowsKey === "results") data.total = 0;
40
40
  data.no_match = true;
@@ -46,10 +46,78 @@ function enforceSearchSafety(response, rowsKey = "results") {
46
46
  data.sdk_safety_reason = reason;
47
47
  data.grounding = { status: "no_grounded_match", reason };
48
48
  }
49
+ } else if (data.degraded === true || data.abstain_recommended === true) {
50
+ data.sdk_safety_reason = "degraded_evidence_preserved";
49
51
  }
50
52
  return data;
51
53
  }
52
54
 
55
+ // src/errors.ts
56
+ var HebbrixError = class _HebbrixError extends Error {
57
+ constructor(message, statusCode, options = {}) {
58
+ super(message);
59
+ this.name = "HebbrixError";
60
+ this.statusCode = statusCode;
61
+ this.code = options.code;
62
+ this.requestId = options.requestId;
63
+ this.details = options.details;
64
+ Object.setPrototypeOf(this, _HebbrixError.prototype);
65
+ }
66
+ };
67
+ var EntitlementError = class _EntitlementError extends HebbrixError {
68
+ constructor(message, statusCode, options = {}) {
69
+ super(message, statusCode, options);
70
+ this.name = "EntitlementError";
71
+ Object.setPrototypeOf(this, _EntitlementError.prototype);
72
+ }
73
+ };
74
+ var IndexingTimeoutError = class _IndexingTimeoutError extends Error {
75
+ constructor(message, receipt) {
76
+ super(message);
77
+ this.name = "IndexingTimeoutError";
78
+ this.receipt = { ...receipt };
79
+ this.memoryIds = [...receipt.memory_ids || []];
80
+ this.statusUrl = receipt.status_url;
81
+ Object.setPrototypeOf(this, _IndexingTimeoutError.prototype);
82
+ }
83
+ };
84
+ var AuthenticationError = class _AuthenticationError extends HebbrixError {
85
+ constructor(message = "Authentication failed", options = {}) {
86
+ super(message, 401, options);
87
+ this.name = "AuthenticationError";
88
+ Object.setPrototypeOf(this, _AuthenticationError.prototype);
89
+ }
90
+ };
91
+ var ValidationError = class _ValidationError extends HebbrixError {
92
+ constructor(message, errors, options = {}) {
93
+ super(message, 422, options);
94
+ this.name = "ValidationError";
95
+ this.errors = errors;
96
+ Object.setPrototypeOf(this, _ValidationError.prototype);
97
+ }
98
+ };
99
+ var NotFoundError = class _NotFoundError extends HebbrixError {
100
+ constructor(message = "Resource not found", options = {}) {
101
+ super(message, 404, options);
102
+ this.name = "NotFoundError";
103
+ Object.setPrototypeOf(this, _NotFoundError.prototype);
104
+ }
105
+ };
106
+ var RateLimitError = class _RateLimitError extends HebbrixError {
107
+ constructor(message = "Rate limit exceeded", options = {}) {
108
+ super(message, 429, options);
109
+ this.name = "RateLimitError";
110
+ Object.setPrototypeOf(this, _RateLimitError.prototype);
111
+ }
112
+ };
113
+ var ServerError = class _ServerError extends HebbrixError {
114
+ constructor(message = "Internal server error", options = {}) {
115
+ super(message, 500, options);
116
+ this.name = "ServerError";
117
+ Object.setPrototypeOf(this, _ServerError.prototype);
118
+ }
119
+ };
120
+
53
121
  // src/resources.ts
54
122
  var BaseResource = class {
55
123
  constructor(client) {
@@ -144,6 +212,89 @@ var MemoriesResource = class extends BaseResource {
144
212
  })
145
213
  });
146
214
  }
215
+ /**
216
+ * Create up to 100 memories with one unambiguous readiness contract.
217
+ * `wait_for_index=true` resolves only for a fully searchable batch. A durable
218
+ * server-side 202 is polled to the caller's deadline; expiry raises a typed
219
+ * `IndexingTimeoutError` carrying the original durable receipt.
220
+ */
221
+ async createBatch(params) {
222
+ if (!params.memories?.length || params.memories.length > 100) {
223
+ throw new TypeError("memories must contain between 1 and 100 items");
224
+ }
225
+ if (params.memories.some((item) => !item.content?.trim())) {
226
+ throw new TypeError("every batch memory must contain non-empty content");
227
+ }
228
+ const {
229
+ idempotency_key,
230
+ signal,
231
+ index_timeout_ms,
232
+ index_poll_interval_ms,
233
+ ...body
234
+ } = params;
235
+ const receipt = await this.client.request(
236
+ "POST",
237
+ "/v1/memories/batch",
238
+ {
239
+ headers: idempotency_key ? { "Idempotency-Key": idempotency_key } : void 0,
240
+ body: JSON.stringify({ wait_for_index: false, ...body }),
241
+ signal
242
+ }
243
+ );
244
+ if (params.wait_for_index && !receipt.searchable) {
245
+ return this.waitForBatchSearchable(receipt, {
246
+ timeoutMs: index_timeout_ms,
247
+ pollIntervalMs: index_poll_interval_ms,
248
+ signal
249
+ });
250
+ }
251
+ return receipt;
252
+ }
253
+ /** Poll every item in an asynchronous batch receipt until it is searchable. */
254
+ async waitForBatchSearchable(receipt, options = {}) {
255
+ const ids = [...new Set(receipt.memory_ids || [])];
256
+ if (!ids.length) {
257
+ throw new Error("batch receipt does not contain memory_ids");
258
+ }
259
+ const timeoutMs = Math.max(0, options.timeoutMs ?? 6e4);
260
+ const pollIntervalMs = Math.max(50, options.pollIntervalMs ?? 500);
261
+ const deadline = Date.now() + timeoutMs;
262
+ while (true) {
263
+ if (options.signal?.aborted) {
264
+ throw options.signal.reason || new Error("batch readiness polling was aborted");
265
+ }
266
+ const rows = await Promise.all(ids.map((id) => this.get(id)));
267
+ const terminal = rows.find(
268
+ (row) => ["failed", "cancelled", "canceled"].includes(
269
+ String(row.processing_status || "").toLowerCase()
270
+ )
271
+ );
272
+ if (terminal) {
273
+ throw new Error(
274
+ `memory ${terminal.id} indexing reached terminal state ${terminal.processing_status}`
275
+ );
276
+ }
277
+ if (rows.every((row) => row.searchable === true)) {
278
+ return {
279
+ ...receipt,
280
+ processing_status: "completed",
281
+ searchable: true,
282
+ results: ids.map((id) => ({
283
+ id,
284
+ memory_id: id,
285
+ processing_status: "completed"
286
+ }))
287
+ };
288
+ }
289
+ if (Date.now() >= deadline) {
290
+ throw new IndexingTimeoutError(
291
+ `batch was not searchable within ${timeoutMs}ms; the write is durable`,
292
+ receipt
293
+ );
294
+ }
295
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
296
+ }
297
+ }
147
298
  /**
148
299
  * List memories
149
300
  */
@@ -333,8 +484,7 @@ var RLResource = class extends BaseResource {
333
484
  * Train the Memory Manager agent using RL
334
485
  */
335
486
  async trainMemoryManager(params) {
336
- return this.client.post("/rl/train/memory-manager", {
337
- collection_id: params.collection_id,
487
+ return this.client.post("/v1/rl/train/memory-manager", {
338
488
  num_episodes: params.num_episodes || 100,
339
489
  ...params
340
490
  });
@@ -343,8 +493,7 @@ var RLResource = class extends BaseResource {
343
493
  * Train the Answer Agent using RL
344
494
  */
345
495
  async trainAnswerAgent(params) {
346
- return this.client.post("/rl/train/answer-agent", {
347
- collection_id: params.collection_id,
496
+ return this.client.post("/v1/rl/train/answer-agent", {
348
497
  num_episodes: params.num_episodes || 100,
349
498
  ...params
350
499
  });
@@ -353,69 +502,91 @@ var RLResource = class extends BaseResource {
353
502
  * Get RL training metrics
354
503
  */
355
504
  async getMetrics() {
356
- return this.client.get("/rl/metrics");
505
+ return this.client.get("/v1/rl/metrics");
357
506
  }
358
507
  /**
359
508
  * Evaluate a trained RL agent
360
509
  */
361
510
  async evaluate(agentType, collectionId) {
362
- return this.client.post("/rl/evaluate", {
511
+ return this.client.post("/v1/rl/evaluate", {
363
512
  agent_type: agentType,
364
513
  collection_id: collectionId
365
514
  });
366
515
  }
367
516
  };
368
517
  var ProceduralResource = class extends BaseResource {
518
+ unwrapProcedure(response) {
519
+ if (response?.procedure) return response.procedure;
520
+ if (response?.procedure_id && !response?.id) {
521
+ return { ...response, id: response.procedure_id };
522
+ }
523
+ return response;
524
+ }
369
525
  /**
370
526
  * Create a new procedure
371
527
  */
372
528
  async create(params) {
373
- return this.client.post("/procedural", {
529
+ const response = await this.client.post("/v1/procedures", {
374
530
  name: params.name,
375
531
  description: params.description,
376
- trigger_condition: params.trigger_condition,
377
- action_sequence: params.action_sequence,
532
+ condition: { expression: params.trigger_condition },
533
+ action: { steps: params.action_sequence },
378
534
  collection_id: params.collection_id,
379
535
  category: params.category,
380
- metadata: params.metadata || {}
536
+ parameters: params.metadata || {}
381
537
  });
538
+ return this.unwrapProcedure(response);
382
539
  }
383
540
  /**
384
541
  * List procedures
385
542
  */
386
543
  async list(params) {
387
- return this.client.get("/procedural", {
544
+ const response = await this.client.get("/v1/procedures", {
388
545
  collection_id: params?.collection_id,
389
546
  category: params?.category,
390
547
  skip: params?.skip || 0,
391
548
  limit: params?.limit || 100
392
549
  });
550
+ return Array.isArray(response) ? response : response?.procedures || [];
393
551
  }
394
552
  /**
395
553
  * Get a specific procedure
396
554
  */
397
555
  async get(procedureId) {
398
- return this.client.get(`/procedural/${procedureId}`);
556
+ const response = await this.client.get(`/v1/procedures/${procedureId}`);
557
+ return this.unwrapProcedure(response);
399
558
  }
400
559
  /**
401
560
  * Execute a procedure
402
561
  */
403
562
  async execute(procedureId, context) {
404
- return this.client.post(`/procedural/${procedureId}/execute`, {
405
- context: context || {}
563
+ const response = await this.client.post(`/v1/procedures/${procedureId}/execute`, {
564
+ input_state: context || {}
406
565
  });
566
+ return response?.execution_result || response;
407
567
  }
408
568
  /**
409
569
  * Update a procedure
410
570
  */
411
571
  async update(procedureId, params) {
412
- return this.client.patch(`/procedural/${procedureId}`, params);
572
+ const body = {};
573
+ if (params.name !== void 0) body.name = params.name;
574
+ if (params.description !== void 0) body.description = params.description;
575
+ if (params.trigger_condition !== void 0) {
576
+ body.condition = { expression: params.trigger_condition };
577
+ }
578
+ if (params.action_sequence !== void 0) {
579
+ body.action = { steps: params.action_sequence };
580
+ }
581
+ if (params.metadata !== void 0) body.parameters = params.metadata;
582
+ const response = await this.client.patch(`/v1/procedures/${procedureId}`, body);
583
+ return this.unwrapProcedure(response);
413
584
  }
414
585
  /**
415
586
  * Delete a procedure
416
587
  */
417
588
  async delete(procedureId) {
418
- await this.client.delete(`/procedural/${procedureId}`);
589
+ await this.client.delete(`/v1/procedures/${procedureId}`);
419
590
  }
420
591
  };
421
592
  var TemporalResource = class extends BaseResource {
@@ -423,12 +594,15 @@ var TemporalResource = class extends BaseResource {
423
594
  * Add a temporal fact to the knowledge graph
424
595
  */
425
596
  async addFact(params) {
426
- return this.client.post("/temporal/facts", {
597
+ return this.client.post("/v1/temporal/facts", {
427
598
  subject: params.subject,
599
+ subject_type: params.subject_type || "ENTITY",
428
600
  predicate: params.predicate,
429
601
  object: params.object,
602
+ object_type: params.object_type || "ENTITY",
430
603
  valid_from: params.valid_from,
431
604
  valid_until: params.valid_until,
605
+ observed_at: params.observed_at,
432
606
  confidence: params.confidence || 1,
433
607
  source_memory_id: params.source_memory_id,
434
608
  metadata: params.metadata || {}
@@ -438,29 +612,79 @@ var TemporalResource = class extends BaseResource {
438
612
  * Query temporal facts
439
613
  */
440
614
  async queryFacts(params) {
441
- return this.client.get("/temporal/facts", {
442
- subject: params?.subject,
443
- predicate: params?.predicate,
444
- object: params?.object,
445
- at_time: params?.at_time
615
+ if (!params.subject) {
616
+ throw new TypeError("subject is required by the temporal query contract");
617
+ }
618
+ let rows;
619
+ if (params.at_time) {
620
+ const response = await this.queryAtTime({
621
+ subject: params.subject,
622
+ predicate: params.predicate,
623
+ timestamp: params.at_time
624
+ });
625
+ rows = response.facts || [];
626
+ } else if (params.predicate) {
627
+ const response = await this.history(
628
+ params.subject,
629
+ params.predicate
630
+ );
631
+ rows = response.history || [];
632
+ } else {
633
+ throw new TypeError("predicate or at_time is required");
634
+ }
635
+ return params.object === void 0 ? rows : rows.filter((row) => row.object === params.object);
636
+ }
637
+ async queryAtTime(params) {
638
+ return this.client.post("/v1/temporal/facts/query-at-time", params);
639
+ }
640
+ async history(subject, predicate, limit = 50) {
641
+ return this.client.get("/v1/temporal/facts/history", {
642
+ subject,
643
+ predicate,
644
+ limit
645
+ });
646
+ }
647
+ async conflicts(subject, predicate) {
648
+ return this.client.get("/v1/temporal/facts/conflicts", {
649
+ subject,
650
+ predicate
651
+ });
652
+ }
653
+ async invalidate(subject, predicate, object) {
654
+ return this.client.post("/v1/temporal/facts/invalidate", {
655
+ subject,
656
+ predicate,
657
+ object
446
658
  });
447
659
  }
448
660
  /**
449
661
  * Query knowledge state at a specific point in time
450
662
  */
451
663
  async pointInTime(timestamp, entity) {
452
- return this.client.post("/temporal/point-in-time", {
664
+ if (!entity) {
665
+ throw new TypeError("entity is required and maps to the canonical subject");
666
+ }
667
+ return this.queryAtTime({
453
668
  timestamp,
454
- entity
669
+ subject: entity
455
670
  });
456
671
  }
672
+ /** Permanently delete a tenant-scoped temporal fact by stable ID. */
673
+ async deleteFact(factId) {
674
+ return this.client.delete(`/v1/temporal/facts/${factId}`);
675
+ }
457
676
  };
458
677
  var WorkingMemoryResource = class extends BaseResource {
678
+ constructor(client) {
679
+ super(client);
680
+ this.sessionId = `sdk-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
681
+ }
459
682
  /**
460
683
  * Add item to working memory buffer
461
684
  */
462
685
  async add(params) {
463
- return this.client.post("/working-memory", {
686
+ return this.client.post("/v1/working-memory/add", {
687
+ session_id: params.session_id || this.sessionId,
464
688
  role: params.role,
465
689
  content: params.content,
466
690
  metadata: params.metadata || {}
@@ -469,48 +693,40 @@ var WorkingMemoryResource = class extends BaseResource {
469
693
  /**
470
694
  * Get current working memory context
471
695
  */
472
- async getContext() {
473
- return this.client.get("/working-memory/context");
696
+ async getContext(sessionId = this.sessionId, includeCompressed = false) {
697
+ return this.client.get(`/v1/working-memory/context/${sessionId}`, {
698
+ include_compressed: includeCompressed
699
+ });
474
700
  }
475
701
  /**
476
702
  * Compress working memory buffer
477
703
  */
478
- async compress() {
479
- return this.client.post("/working-memory/compress");
704
+ async compress(sessionId = this.sessionId) {
705
+ return this.client.post(`/v1/working-memory/compress/${sessionId}`);
480
706
  }
481
707
  /**
482
708
  * Clear working memory buffer
483
709
  */
484
- async clear() {
485
- return this.client.delete("/working-memory");
710
+ async clear(sessionId = this.sessionId) {
711
+ return this.client.delete(`/v1/working-memory/clear/${sessionId}`);
486
712
  }
487
713
  };
488
714
  var ConsolidationResource = class extends BaseResource {
489
715
  /**
490
716
  * Trigger memory consolidation
491
717
  */
492
- async consolidate(collectionId, threshold = 100) {
493
- return this.client.post("/consolidation/consolidate", {
718
+ async consolidate(collectionId, lookbackDays = 7, utilityThreshold = 0.3) {
719
+ return this.client.post("/v1/consolidation/consolidate", {
494
720
  collection_id: collectionId,
495
- threshold
721
+ lookback_days: lookbackDays,
722
+ utility_threshold: utilityThreshold
496
723
  });
497
724
  }
498
725
  /**
499
726
  * Get consolidation statistics
500
727
  */
501
728
  async getStats(collectionId) {
502
- return this.client.get("/consolidation/stats", {
503
- collection_id: collectionId
504
- });
505
- }
506
- /**
507
- * Archive old memories
508
- */
509
- async archive(collectionId, beforeDate) {
510
- return this.client.post("/consolidation/archive", {
511
- collection_id: collectionId,
512
- before_date: beforeDate
513
- });
729
+ return this.client.get(`/v1/consolidation/stats/${collectionId}`);
514
730
  }
515
731
  };
516
732
  var MemoryToolsResource = class extends BaseResource {
@@ -518,100 +734,38 @@ var MemoryToolsResource = class extends BaseResource {
518
734
  * Replace memory content
519
735
  */
520
736
  async replace(params) {
521
- return this.client.post("/memory-tools/replace", {
737
+ return this.client.post("/v1/memory-tools/replace", {
522
738
  memory_id: params.memory_id,
739
+ old_content: params.old_content,
523
740
  new_content: params.new_content,
524
- reason: params.reason
741
+ collection_id: params.collection_id
525
742
  });
526
743
  }
527
744
  /**
528
745
  * Insert new memory at position
529
746
  */
530
747
  async insert(params) {
531
- return this.client.post("/memory-tools/insert", {
748
+ const metadata = { ...params.metadata || {} };
749
+ if (params.position !== void 0) metadata.requested_position = params.position;
750
+ if (params.reason !== void 0) metadata.reason = params.reason;
751
+ return this.client.post("/v1/memory-tools/insert", {
532
752
  collection_id: params.collection_id,
533
753
  content: params.content,
534
- position: params.position,
535
- reason: params.reason
754
+ importance: params.importance ?? 0.5,
755
+ metadata
536
756
  });
537
757
  }
538
758
  /**
539
759
  * Re-evaluate memory in light of new information
540
760
  */
541
- async rethink(memoryId, query) {
542
- return this.client.post("/memory-tools/rethink", {
761
+ async rethink(memoryId, collectionId) {
762
+ return this.client.post("/v1/memory-tools/rethink", {
543
763
  memory_id: memoryId,
544
- query
545
- });
546
- }
547
- };
548
- var WorldModelResource = class extends BaseResource {
549
- /**
550
- * Simulate retrieval without actually retrieving
551
- */
552
- async imagineRetrieval(query, collectionId) {
553
- return this.client.post("/world-model/imagine-retrieval", {
554
- query,
555
- collection_id: collectionId
556
- });
557
- }
558
- /**
559
- * Plan memory operations to achieve goal
560
- */
561
- async plan(goal, collectionId) {
562
- return this.client.post("/world-model/plan", {
563
- goal,
564
764
  collection_id: collectionId
565
765
  });
566
766
  }
567
767
  };
568
768
 
569
- // src/errors.ts
570
- var HebbrixError = class _HebbrixError extends Error {
571
- constructor(message, statusCode) {
572
- super(message);
573
- this.name = "HebbrixError";
574
- this.statusCode = statusCode;
575
- Object.setPrototypeOf(this, _HebbrixError.prototype);
576
- }
577
- };
578
- var AuthenticationError = class _AuthenticationError extends HebbrixError {
579
- constructor(message = "Authentication failed") {
580
- super(message, 401);
581
- this.name = "AuthenticationError";
582
- Object.setPrototypeOf(this, _AuthenticationError.prototype);
583
- }
584
- };
585
- var ValidationError = class _ValidationError extends HebbrixError {
586
- constructor(message, errors) {
587
- super(message, 422);
588
- this.name = "ValidationError";
589
- this.errors = errors;
590
- Object.setPrototypeOf(this, _ValidationError.prototype);
591
- }
592
- };
593
- var NotFoundError = class _NotFoundError extends HebbrixError {
594
- constructor(message = "Resource not found") {
595
- super(message, 404);
596
- this.name = "NotFoundError";
597
- Object.setPrototypeOf(this, _NotFoundError.prototype);
598
- }
599
- };
600
- var RateLimitError = class _RateLimitError extends HebbrixError {
601
- constructor(message = "Rate limit exceeded") {
602
- super(message, 429);
603
- this.name = "RateLimitError";
604
- Object.setPrototypeOf(this, _RateLimitError.prototype);
605
- }
606
- };
607
- var ServerError = class _ServerError extends HebbrixError {
608
- constructor(message = "Internal server error") {
609
- super(message, 500);
610
- this.name = "ServerError";
611
- Object.setPrototypeOf(this, _ServerError.prototype);
612
- }
613
- };
614
-
615
769
  // src/client.ts
616
770
  var MemoryClient = class {
617
771
  constructor(config = {}) {
@@ -631,13 +785,12 @@ var MemoryClient = class {
631
785
  this.workingMemory = new WorkingMemoryResource(this);
632
786
  this.consolidation = new ConsolidationResource(this);
633
787
  this.memoryTools = new MemoryToolsResource(this);
634
- this.worldModel = new WorldModelResource(this);
635
788
  this.proofloop = new ProofLoopResource(this);
636
789
  }
637
790
  getHeaders() {
638
791
  const headers = {
639
792
  "Content-Type": "application/json",
640
- "User-Agent": "hebbrix-typescript/2.2.0"
793
+ "User-Agent": "hebbrix-typescript/2.3.0"
641
794
  };
642
795
  if (this.apiKey) {
643
796
  headers["Authorization"] = `Bearer ${this.apiKey}`;
@@ -646,39 +799,58 @@ var MemoryClient = class {
646
799
  }
647
800
  handleError(response, data) {
648
801
  const statusCode = response.status;
649
- const message = data?.error?.message || data?.detail || response.statusText;
802
+ const envelope = data?.error || data?.detail || {};
803
+ const nested = envelope?.message;
804
+ const details = nested && typeof nested === "object" ? nested : envelope;
805
+ const message = details?.message || (typeof nested === "string" ? nested : void 0) || response.statusText;
806
+ const code = details?.code || envelope?.code;
807
+ const requestId = details?.request_id || envelope?.request_id || response.headers.get("X-Request-ID") || void 0;
650
808
  if (statusCode === 401) {
651
- throw new AuthenticationError(message);
809
+ throw new AuthenticationError(message, { code, requestId, details });
652
810
  } else if (statusCode === 404) {
653
- throw new NotFoundError(message);
811
+ throw new NotFoundError(message, { code, requestId, details });
654
812
  } else if (statusCode === 422) {
655
813
  const errors = data?.error?.details || [];
656
- throw new ValidationError(message, errors);
814
+ throw new ValidationError(message, errors, { code, requestId, details });
657
815
  } else if (statusCode === 429) {
658
- throw new RateLimitError(message);
816
+ throw new RateLimitError(message, { code, requestId, details });
659
817
  } else if (statusCode >= 500) {
660
- throw new ServerError(message);
818
+ throw new ServerError(message, { code, requestId, details });
819
+ } else if ((statusCode === 402 || statusCode === 403) && (String(code || "").includes("ENTITLEMENT") || ["feature_not_available", "tier_upgrade_required"].includes(details?.error))) {
820
+ throw new EntitlementError(message, statusCode, {
821
+ code,
822
+ requestId,
823
+ details
824
+ });
661
825
  } else {
662
- throw new HebbrixError(message, statusCode);
826
+ throw new HebbrixError(message, statusCode, { code, requestId, details });
663
827
  }
664
828
  }
665
829
  async request(method, path, options = {}) {
666
830
  const url = `${this.baseUrl}${path}`;
831
+ const { headers: requestHeaders, signal: requestSignal, ...requestOptions } = options;
667
832
  const response = await fetch(url, {
833
+ ...requestOptions,
668
834
  method,
669
835
  headers: {
670
836
  ...this.getHeaders(),
671
- ...options.headers || {}
837
+ ...requestHeaders || {}
672
838
  },
673
- ...options,
674
- signal: AbortSignal.timeout(this.timeout)
839
+ signal: requestSignal || AbortSignal.timeout(this.timeout)
675
840
  });
676
- let data;
841
+ let data = void 0;
677
842
  const contentType = response.headers.get("content-type");
678
- if (contentType?.includes("application/json")) {
679
- data = await response.json();
680
- } else {
681
- data = await response.text();
843
+ const responseText = await response.text();
844
+ if (responseText) {
845
+ if (contentType?.includes("application/json")) {
846
+ try {
847
+ data = JSON.parse(responseText);
848
+ } catch {
849
+ data = { detail: responseText };
850
+ }
851
+ } else {
852
+ data = responseText;
853
+ }
682
854
  }
683
855
  if (!response.ok) {
684
856
  this.handleError(response, data);
@@ -732,7 +904,9 @@ export {
732
904
  CollectionsResource,
733
905
  ConsolidationResource,
734
906
  CorrectionsResource,
907
+ EntitlementError,
735
908
  HebbrixError,
909
+ IndexingTimeoutError,
736
910
  MemoriesResource,
737
911
  MemoryClient,
738
912
  MemoryJobsResource,
@@ -747,6 +921,5 @@ export {
747
921
  TemporalResource,
748
922
  ValidationError,
749
923
  WorkingMemoryResource,
750
- WorldModelResource,
751
924
  enforceSearchSafety
752
925
  };