@pyxmate/memory 1.17.16 → 1.17.17

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  MemoryClient
3
- } from "./chunk-MDFUZ3V2.mjs";
3
+ } from "./chunk-JGFDID3B.mjs";
4
4
 
5
5
  // ../dashboard/src/aggregations/consolidation-analytics.ts
6
6
  function analyzeConsolidationLog(entries) {
@@ -178,8 +178,10 @@ var DashboardClient = class extends MemoryClient {
178
178
  * arbitrary N-node sample were silently dropped, collapsing dense graphs to
179
179
  * a handful of rendered links.
180
180
  */
181
- async graphSubgraph(edges = 2e3) {
182
- return this.fetchApi(`/api/memory/graph/subgraph?edges=${edges}`);
181
+ async graphSubgraph(edges = 2e3, nodes = 2e3) {
182
+ return this.fetchApi(
183
+ `/api/memory/graph/subgraph?edges=${edges}&nodes=${nodes}`
184
+ );
183
185
  }
184
186
  async fetchHealthRaw() {
185
187
  return this.fetchApi("/health");
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  assertGraphExtractionPayload,
3
3
  mergeExtractedEntities
4
- } from "./chunk-34MTVIYK.mjs";
4
+ } from "./chunk-3OLH3HYR.mjs";
5
5
 
6
6
  // ../shared/src/constants/defaults.ts
7
7
  var DEFAULTS = {
@@ -11,6 +11,21 @@ var DEFAULTS = {
11
11
  };
12
12
  var TAXONOMY_MAX_CATEGORIES = 10;
13
13
 
14
+ // ../shared/src/document-source.ts
15
+ import { createHash } from "crypto";
16
+ function documentSource(prefix, documentKey) {
17
+ return `${prefix}:${createHash("sha256").update(documentKey).digest("hex")}`;
18
+ }
19
+ function documentGraphSource(documentKey) {
20
+ return documentSource("document-graph", documentKey);
21
+ }
22
+ function documentContentSource(documentKey) {
23
+ return documentSource("document-content", documentKey);
24
+ }
25
+ function documentImageSource(documentKey) {
26
+ return documentSource("document-image", documentKey);
27
+ }
28
+
14
29
  // ../shared/src/mcp/search-response.ts
15
30
  var STRIPPED_ENTRY_FIELDS = /* @__PURE__ */ new Set(["contentHash", "embedding", "tenantId", "userId", "teamId"]);
16
31
  function isRecord(value) {
@@ -228,12 +243,54 @@ var DisabledMemory = class {
228
243
  };
229
244
 
230
245
  // ../client/src/memory-client.ts
246
+ function isRecord3(value) {
247
+ return value !== null && typeof value === "object" && !Array.isArray(value);
248
+ }
249
+ function normalizeRetryAfter(retryAfter, retryAfterSeconds) {
250
+ const exact = typeof retryAfter === "string" ? retryAfter.trim() : "";
251
+ if (exact) {
252
+ const parsed = /^\d+$/.test(exact) ? Number(exact) : Math.ceil((Date.parse(exact) - Date.now()) / 1e3);
253
+ return {
254
+ retryAfter: exact,
255
+ ...Number.isSafeInteger(parsed) && parsed >= 0 ? { retryAfterSeconds: parsed } : {}
256
+ };
257
+ }
258
+ return Number.isSafeInteger(retryAfterSeconds) && retryAfterSeconds >= 0 ? { retryAfterSeconds } : {};
259
+ }
260
+ function structuralHttpStatus(error) {
261
+ if (!isRecord3(error) || typeof error.status !== "number") return void 0;
262
+ return Number.isSafeInteger(error.status) && error.status >= 400 && error.status < 600 ? error.status : void 0;
263
+ }
264
+ function isFileIngestResult(value) {
265
+ if (!isRecord3(value)) return false;
266
+ if (typeof value.filename !== "string" || typeof value.fileType !== "string" || typeof value.chunks !== "number" || !Number.isSafeInteger(value.chunks) || value.chunks < 0 || !Array.isArray(value.entryIds) || !value.entryIds.every((id) => typeof id === "string") || typeof value.totalCharacters !== "number" || !Number.isSafeInteger(value.totalCharacters) || value.totalCharacters < 0) {
267
+ return false;
268
+ }
269
+ if (value.graphAnchorEntryId !== void 0 && typeof value.graphAnchorEntryId !== "string") {
270
+ return false;
271
+ }
272
+ if (value.enrichment !== void 0 && !isRecord3(value.enrichment)) return false;
273
+ return true;
274
+ }
275
+ function hasEnrichmentCallback(callbacks) {
276
+ return Boolean(callbacks?.describeImage || callbacks?.extractEntitiesV2);
277
+ }
231
278
  var MemoryServerError = class extends Error {
232
279
  status;
233
- constructor(message, status) {
280
+ /** Stable machine-readable discriminator returned by the memory server. */
281
+ code;
282
+ /** Exact HTTP Retry-After value returned by the memory server. */
283
+ retryAfter;
284
+ /** Retry delay normalized to seconds when Retry-After is parseable. */
285
+ retryAfterSeconds;
286
+ constructor(message, status, code, retryAfter) {
234
287
  super(message);
235
288
  this.name = "MemoryServerError";
236
289
  this.status = status;
290
+ this.code = code;
291
+ const retry = normalizeRetryAfter(retryAfter);
292
+ this.retryAfter = retry.retryAfter;
293
+ this.retryAfterSeconds = retry.retryAfterSeconds;
237
294
  }
238
295
  /** True when the server returned HTTP 404 (not found). */
239
296
  get isNotFound() {
@@ -273,12 +330,33 @@ var MemoryClient = class {
273
330
  }
274
331
  authorityHeaders(options) {
275
332
  if (!options) return {};
333
+ const headers = {};
276
334
  const key = options.idempotencyKey;
277
- if (key === void 0) return {};
278
- if (typeof key !== "string" || key.length === 0 || !key.isWellFormed() || new TextEncoder().encode(key).byteLength > 256) {
279
- throw new Error("idempotencyKey must be 1-256 well-formed UTF-8 bytes");
335
+ if (key !== void 0) {
336
+ if (typeof key !== "string" || key.length === 0 || !key.isWellFormed() || new TextEncoder().encode(key).byteLength > 256) {
337
+ throw new Error("idempotencyKey must be 1-256 well-formed UTF-8 bytes");
338
+ }
339
+ headers["Idempotency-Key"] = key;
340
+ }
341
+ for (const [headerName, value] of [
342
+ ["X-Tenant-Id", options.tenantId],
343
+ ["X-Namespace-Id", options.namespaceId]
344
+ ]) {
345
+ if (value === void 0) continue;
346
+ const configured = Object.entries(this._authHeaders).find(
347
+ ([name]) => name.toLowerCase() === headerName.toLowerCase()
348
+ )?.[1];
349
+ if (configured !== void 0) {
350
+ if (configured !== value) {
351
+ throw new Error(
352
+ `${headerName} conflicts with the MemoryClient default scope; create a client for the requested scope`
353
+ );
354
+ }
355
+ continue;
356
+ }
357
+ headers[headerName] = value;
280
358
  }
281
- return { "Idempotency-Key": key };
359
+ return headers;
282
360
  }
283
361
  async initialize() {
284
362
  const response = await fetch(`${this.baseUrl}/health`, {
@@ -426,6 +504,16 @@ var MemoryClient = class {
426
504
  * method by design (one wire format, one SDK method).
427
505
  */
428
506
  async *ingestFileEvents(file, options) {
507
+ if (options?.documentKey !== void 0) {
508
+ if (typeof options.documentKey !== "string" || options.documentKey.trim().length === 0) {
509
+ throw new Error("ingestFileEvents requires a non-empty documentKey when provided");
510
+ }
511
+ if (!options.enrichment?.extractEntitiesV2) {
512
+ throw new Error(
513
+ "ingestFileEvents with documentKey requires enrichment.extractEntitiesV2 so the stable graph replacement can be finalized"
514
+ );
515
+ }
516
+ }
429
517
  const controller = new AbortController();
430
518
  const relayAbort = () => controller.abort(options?.signal?.reason);
431
519
  if (options?.signal?.aborted) relayAbort();
@@ -435,6 +523,12 @@ var MemoryClient = class {
435
523
  formData.append("file", file);
436
524
  if (options?.description) formData.append("description", options.description);
437
525
  if (options?.namespaceId) formData.append("namespaceId", options.namespaceId);
526
+ if (options?.documentKey !== void 0) {
527
+ formData.append("documentKey", options.documentKey);
528
+ }
529
+ if (options?.catalogEntryId !== void 0) {
530
+ formData.append("catalogEntryId", options.catalogEntryId);
531
+ }
438
532
  const wantsTextWindows = Boolean(options?.enrichment?.extractEntitiesV2);
439
533
  const headers = {
440
534
  Accept: "application/x-ndjson",
@@ -490,6 +584,9 @@ var MemoryClient = class {
490
584
  const formData = new FormData();
491
585
  formData.append("file", file);
492
586
  formData.append("documentKey", options.documentKey);
587
+ if (options.catalogEntryId !== void 0) {
588
+ formData.append("catalogEntryId", options.catalogEntryId);
589
+ }
493
590
  if (options.namespaceId) formData.append("namespaceId", options.namespaceId);
494
591
  const headers = {
495
592
  Accept: "application/x-ndjson",
@@ -519,7 +616,7 @@ var MemoryClient = class {
519
616
  "graph-only"
520
617
  );
521
618
  const data = outcome.data;
522
- if (data?.purpose !== "graph-only" || !Array.isArray(data.entryIds)) {
619
+ if (data?.purpose !== "graph-only" || !Array.isArray(data.entryIds) || data.entryIds.length !== 1 || typeof data.entryIds[0] !== "string" || data.entryIds[0].length === 0 || typeof data.graphAnchorEntryId !== "string" || data.graphAnchorEntryId.length === 0) {
523
620
  throw new MemoryServerError(
524
621
  "Graph enrichment finalization returned an unexpected result",
525
622
  0
@@ -557,6 +654,17 @@ var MemoryClient = class {
557
654
  return null;
558
655
  }
559
656
  const contentType = res.headers.get("content-type") ?? "";
657
+ if (!res.ok) {
658
+ let error;
659
+ try {
660
+ await this.parseApiResponse(res);
661
+ error = new MemoryServerError(`Memory server error: ${res.status}`, res.status);
662
+ } catch (cause) {
663
+ error = cause;
664
+ }
665
+ yield this.ingestErrorEvent(error, "parsing");
666
+ return null;
667
+ }
560
668
  if (!contentType.includes("application/x-ndjson")) {
561
669
  yield this.ingestErrorEvent(
562
670
  new MemoryServerError(
@@ -602,6 +710,8 @@ var MemoryClient = class {
602
710
  break;
603
711
  }
604
712
  if (type === "error") {
713
+ const partialResult = isFileIngestResult(raw.partialResult) ? raw.partialResult : void 0;
714
+ const retry = normalizeRetryAfter(raw.retryAfter, raw.retryAfterSeconds);
605
715
  yield {
606
716
  schemaVersion: 1,
607
717
  type: "error",
@@ -609,7 +719,9 @@ var MemoryClient = class {
609
719
  error: typeof raw.error === "string" ? raw.error : "File ingest failed",
610
720
  message: typeof raw.message === "string" ? raw.message : void 0,
611
721
  code: typeof raw.code === "string" || typeof raw.code === "number" ? raw.code : void 0,
612
- status: typeof raw.status === "number" ? raw.status : void 0
722
+ status: typeof raw.status === "number" ? raw.status : void 0,
723
+ ...retry,
724
+ ...partialResult ? { partialResult } : {}
613
725
  };
614
726
  return null;
615
727
  }
@@ -640,26 +752,48 @@ var MemoryClient = class {
640
752
  */
641
753
  async *completeIngestFileEvents(file, result, options, signal) {
642
754
  try {
643
- if (!result.enrichment || !options?.enrichment) {
755
+ const callbacks = options?.enrichment;
756
+ if (options?.documentKey !== void 0 && !result.enrichment) {
757
+ throw new MemoryServerError(
758
+ "documentKey-aware ingest response omitted required enrichment preparation; stable graph finalization did not run",
759
+ 502
760
+ );
761
+ }
762
+ if (!result.enrichment || !hasEnrichmentCallback(callbacks)) {
644
763
  yield { schemaVersion: 1, type: "result", stage: "complete", ...result };
645
764
  return;
646
765
  }
647
766
  const outcome = yield* this.runEnrichmentCallbacks(
648
767
  file,
649
768
  result.enrichment,
650
- options.enrichment,
769
+ callbacks,
651
770
  signal,
652
- "ingest"
771
+ "ingest",
772
+ options?.documentKey !== void 0
653
773
  );
654
774
  if (outcome.posted) {
655
775
  const enrichData = outcome.data;
776
+ if (options?.documentKey !== void 0 && !enrichData.graphAnchorEntryId) {
777
+ throw new MemoryServerError(
778
+ "documentKey-aware enrichment response omitted graphAnchorEntryId; server does not support stable document replacement",
779
+ 502
780
+ );
781
+ }
656
782
  result.entryIds.push(...enrichData.entryIds);
783
+ if (enrichData.graphAnchorEntryId) {
784
+ result.graphAnchorEntryId = enrichData.graphAnchorEntryId;
785
+ }
786
+ if ((enrichData.relationshipsDropped ?? 0) > 0) {
787
+ result.relationshipsDropped = enrichData.relationshipsDropped;
788
+ result.droppedRelationships = enrichData.droppedRelationships;
789
+ }
657
790
  result.chunks += outcome.descriptions.length;
658
791
  result.totalCharacters += outcome.descriptions.reduce(
659
792
  (sum, d) => sum + d.description.length,
660
793
  0
661
794
  );
662
795
  }
796
+ delete result.enrichment;
663
797
  yield { schemaVersion: 1, type: "result", stage: "complete", ...result };
664
798
  } catch (err) {
665
799
  yield this.ingestErrorEvent(err, "enrichment", result);
@@ -673,16 +807,24 @@ var MemoryClient = class {
673
807
  * heartbeat events around each slow step. Throws on any failure; the
674
808
  * purpose-specific wrappers translate that into their terminal error.
675
809
  *
676
- * The purpose controls empty-output semantics: ingest skips an optional
677
- * empty add-on; graph-only finalizes an extractor that ran and found zero
678
- * entities, but refuses to erase prior graph state when no extractable input
679
- * reached the callback at all.
810
+ * Legacy ingest keeps its existing partial add-on behavior. Graph-only and
811
+ * documentKey-aware full ingest may replace a prior graph only from a
812
+ * complete input set (no truncated text windows or undescribed images). A
813
+ * complete extractor result containing zero entities remains a valid clear.
680
814
  */
681
815
  // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: image-describe / extract-entities-v2 / no-op are documented decision branches; the fan-out covers the v0.15.0 enrichment phase + heartbeat plumbing.
682
- async *runEnrichmentCallbacks(file, enrichment, callbacks, signal, purpose) {
816
+ async *runEnrichmentCallbacks(file, enrichment, callbacks, signal, purpose, replaceEmptyGraph = false) {
683
817
  const { fileId, token, expiresAt, images } = enrichment;
684
818
  const isV2 = "version" in enrichment;
685
819
  const textWindows = isV2 ? enrichment.textWindows : [];
820
+ const textWindowsTruncation = isV2 ? enrichment.textWindowsTruncation : void 0;
821
+ const requiresCompleteGraphReplacement = purpose === "graph-only" || replaceEmptyGraph;
822
+ if (requiresCompleteGraphReplacement && textWindowsTruncation?.truncated) {
823
+ throw new MemoryServerError(
824
+ `Graph enrichment input was truncated (${textWindowsTruncation.reason ?? "unknown limit"}); prior graph state was preserved and the pending session remains retryable`,
825
+ 422
826
+ );
827
+ }
686
828
  const descriptions = [];
687
829
  const describeImage = callbacks.describeImage;
688
830
  if (describeImage && images.length > 0) {
@@ -731,6 +873,12 @@ var MemoryClient = class {
731
873
  };
732
874
  }
733
875
  }
876
+ if (requiresCompleteGraphReplacement && descriptions.length < images.length) {
877
+ throw new MemoryServerError(
878
+ `Graph enrichment described only ${descriptions.length}/${images.length} images; prior graph state was preserved and the pending session remains retryable`,
879
+ 422
880
+ );
881
+ }
734
882
  let entities;
735
883
  let relationships;
736
884
  const imageDescriptionTexts = descriptions.map((d) => d.description);
@@ -773,7 +921,7 @@ var MemoryClient = class {
773
921
  }
774
922
  const hasGraph = (entities?.length ?? 0) > 0;
775
923
  const hasImages = descriptions.length > 0;
776
- if (!hasGraph && !hasImages && purpose === "ingest") {
924
+ if (!hasGraph && !hasImages && purpose === "ingest" && !replaceEmptyGraph) {
777
925
  return { posted: false, data: null, descriptions };
778
926
  }
779
927
  yield {
@@ -793,17 +941,14 @@ var MemoryClient = class {
793
941
  ...this._authHeaders
794
942
  },
795
943
  signal,
796
- body: JSON.stringify({ imageDescriptions: descriptions, entities, relationships })
944
+ body: JSON.stringify({
945
+ imageDescriptions: descriptions,
946
+ entities: entities ?? [],
947
+ relationships: relationships ?? []
948
+ })
797
949
  }),
798
950
  signal
799
951
  );
800
- if (!enrichRes.ok) {
801
- const body = await enrichRes.json().catch(() => ({}));
802
- throw new MemoryServerError(
803
- body.error ?? `Enrichment failed: ${enrichRes.status}`,
804
- enrichRes.status
805
- );
806
- }
807
952
  const data = await this.parseApiResponse(enrichRes);
808
953
  return { posted: true, data, descriptions };
809
954
  }
@@ -869,15 +1014,20 @@ var MemoryClient = class {
869
1014
  return result;
870
1015
  }
871
1016
  ingestErrorEvent(error, stage, partialResult) {
872
- const status = error instanceof MemoryServerError ? error.status : error instanceof Error && error.name === "AbortError" ? 499 : void 0;
1017
+ const structuralError = isRecord3(error) ? error : void 0;
1018
+ const status = error instanceof MemoryServerError ? error.status : error instanceof Error && error.name === "AbortError" ? 499 : structuralHttpStatus(error);
873
1019
  const message = error instanceof Error ? error.message : String(error);
1020
+ const code = error instanceof MemoryServerError ? error.code : void 0;
1021
+ const retry = error instanceof MemoryServerError ? { retryAfter: error.retryAfter, retryAfterSeconds: error.retryAfterSeconds } : normalizeRetryAfter(structuralError?.retryAfter, structuralError?.retryAfterSeconds);
874
1022
  return {
875
1023
  schemaVersion: 1,
876
1024
  type: "error",
877
1025
  stage,
878
1026
  error: message,
879
1027
  message,
880
- ...status != null ? { status, code: status } : {},
1028
+ ...status != null ? { status, code: code ?? status } : {},
1029
+ ...retry.retryAfter !== void 0 ? { retryAfter: retry.retryAfter } : {},
1030
+ ...retry.retryAfterSeconds !== void 0 ? { retryAfterSeconds: retry.retryAfterSeconds } : {},
881
1031
  ...partialResult ? { partialResult } : {}
882
1032
  };
883
1033
  }
@@ -885,15 +1035,24 @@ var MemoryClient = class {
885
1035
  * Get the download URL for an uploaded file.
886
1036
  * Returns a URL that serves the original file binary with proper Content-Type.
887
1037
  */
888
- getFileDownloadUrl(filename) {
889
- return `${this.baseUrl}/api/memory/files/download/${encodeURIComponent(filename)}`;
1038
+ getFileDownloadUrl(filename, options) {
1039
+ const url = new URL(
1040
+ `${this.baseUrl}/api/memory/files/download/${encodeURIComponent(filename)}`
1041
+ );
1042
+ if (options?.documentKey !== void 0) {
1043
+ url.searchParams.set("documentKey", options.documentKey);
1044
+ }
1045
+ if (options?.namespaceId !== void 0) {
1046
+ url.searchParams.set("namespaceId", options.namespaceId);
1047
+ }
1048
+ return url.toString();
890
1049
  }
891
1050
  /**
892
1051
  * Download an uploaded file by filename.
893
1052
  * Returns the raw Response (caller handles the body — arrayBuffer, blob, stream, etc.).
894
1053
  */
895
- async downloadFile(filename) {
896
- const url = this.getFileDownloadUrl(filename);
1054
+ async downloadFile(filename, options) {
1055
+ const url = this.getFileDownloadUrl(filename, options);
897
1056
  const res = await fetch(url, { headers: this._authHeaders });
898
1057
  if (!res.ok) {
899
1058
  throw new MemoryServerError(`File download failed: ${res.status}`, res.status);
@@ -971,10 +1130,10 @@ var MemoryClient = class {
971
1130
  async repairGraph() {
972
1131
  return this.fetchApi("/api/memory/graph/repair", { method: "POST" });
973
1132
  }
974
- async deleteBySource(source) {
1133
+ async deleteBySource(source, authority) {
975
1134
  const result = await this.fetchApi(
976
1135
  `/api/memory/source/${this.encodePathSegment(source)}`,
977
- { method: "DELETE" }
1136
+ { method: "DELETE", headers: this.authorityHeaders(authority) }
978
1137
  );
979
1138
  return result.deleted;
980
1139
  }
@@ -987,14 +1146,20 @@ var MemoryClient = class {
987
1146
  }
988
1147
  );
989
1148
  }
990
- async queryAsOf(asOfDate, filters = {}) {
1149
+ async queryAsOf(asOfDate, filters = {}, authority) {
1150
+ if (filters.cursor !== void 0 && filters.offset !== void 0) {
1151
+ throw new Error("queryAsOf cursor and offset are mutually exclusive");
1152
+ }
991
1153
  const params = new URLSearchParams({ asOf: asOfDate });
992
1154
  if (filters.type) params.set("type", filters.type);
993
1155
  if (filters.agentId) params.set("agentId", filters.agentId);
994
1156
  if (filters.source) params.set("source", filters.source);
995
1157
  if (filters.limit) params.set("limit", String(filters.limit));
1158
+ if (filters.offset !== void 0) params.set("offset", String(filters.offset));
1159
+ if (filters.cursor !== void 0) params.set("cursor", filters.cursor);
996
1160
  const result = await this.fetchApi(
997
- `/api/memory/query-as-of?${params}`
1161
+ `/api/memory/query-as-of?${params}`,
1162
+ { headers: this.authorityHeaders(authority) }
998
1163
  );
999
1164
  return result.entries;
1000
1165
  }
@@ -1036,11 +1201,15 @@ var MemoryClient = class {
1036
1201
  return result.entries;
1037
1202
  }
1038
1203
  async queryByEventTime(startTime, endTime, filters = {}) {
1204
+ if (filters.cursor !== void 0) {
1205
+ throw new Error("queryByEventTime does not support a createdAt cursor; use offset");
1206
+ }
1039
1207
  const params = new URLSearchParams({ startTime, endTime });
1040
1208
  if (filters.type) params.set("type", filters.type);
1041
1209
  if (filters.agentId) params.set("agentId", filters.agentId);
1042
1210
  if (filters.source) params.set("source", filters.source);
1043
1211
  if (filters.limit) params.set("limit", String(filters.limit));
1212
+ if (filters.offset !== void 0) params.set("offset", String(filters.offset));
1044
1213
  const result = await this.fetchApi(
1045
1214
  `/api/memory/query-by-event-time?${params}`
1046
1215
  );
@@ -1164,23 +1333,33 @@ var MemoryClient = class {
1164
1333
  }
1165
1334
  /** Parse and validate a JSON API response, throwing MemoryServerError on any failure. */
1166
1335
  async parseApiResponse(res) {
1336
+ const retryAfter = res.headers.get("Retry-After") ?? void 0;
1167
1337
  let body;
1168
1338
  try {
1169
1339
  body = await res.json();
1170
1340
  } catch {
1171
1341
  throw new MemoryServerError(
1172
1342
  `Memory server error: invalid JSON response (${res.status})`,
1173
- res.status
1343
+ res.status,
1344
+ void 0,
1345
+ retryAfter
1174
1346
  );
1175
1347
  }
1176
- if (!body?.success || body.data == null) {
1348
+ if (!res.ok || !body?.success || body.data == null) {
1177
1349
  if (res.ok && body?.error === void 0) {
1178
1350
  throw new MemoryServerError(
1179
1351
  `Memory server returned HTTP ${res.status} without the expected { success, data } API envelope. Check that the base URL points to a pyx-memory instance server; hosted pyx-memory access uses MCP.`,
1180
- res.status
1352
+ res.status,
1353
+ void 0,
1354
+ retryAfter
1181
1355
  );
1182
1356
  }
1183
- throw new MemoryServerError(body?.error ?? `Memory server error: ${res.status}`, res.status);
1357
+ throw new MemoryServerError(
1358
+ body?.error ?? `Memory server error: ${res.status}`,
1359
+ res.status,
1360
+ body?.code,
1361
+ retryAfter
1362
+ );
1184
1363
  }
1185
1364
  return body.data;
1186
1365
  }
@@ -1189,6 +1368,9 @@ var MemoryClient = class {
1189
1368
  export {
1190
1369
  DEFAULTS,
1191
1370
  TAXONOMY_MAX_CATEGORIES,
1371
+ documentGraphSource,
1372
+ documentContentSource,
1373
+ documentImageSource,
1192
1374
  projectSearchResponseForMcp,
1193
1375
  secretElevationNoticeFor,
1194
1376
  withSecretElevationNotice,
@@ -597,6 +597,7 @@ function createHttpClient(credentials, fetchImpl = fetch) {
597
597
  headers.set("Accept", "application/json");
598
598
  if (contentType) headers.set("Content-Type", contentType);
599
599
  if (scope?.tenantId) headers.set("X-Tenant-Id", scope.tenantId);
600
+ if (scope?.namespaceId) headers.set("X-Namespace-Id", scope.namespaceId);
600
601
  if (scope?.userId) headers.set("X-User-Id", scope.userId);
601
602
  if (scope?.teamId) headers.set("X-Team-Id", scope.teamId);
602
603
  if (scope?.callerAccessLevel) headers.set("X-Caller-Access-Level", scope.callerAccessLevel);
@@ -835,7 +836,7 @@ function createProxyServer(client, version, uploadLocalFile) {
835
836
  return server;
836
837
  }
837
838
  async function runMcpProxyServer(opts) {
838
- const version = opts.version ?? (true ? "1.17.16" : "0.0.0-dev");
839
+ const version = opts.version ?? (true ? "1.17.17" : "0.0.0-dev");
839
840
  const read = await opts.readCredentials();
840
841
  if (!read.ok) {
841
842
  const text = read.result.content.map((c) => c.type === "text" ? c.text : "").join(" ").trim();
@@ -21,6 +21,8 @@ interface SubgraphResponse {
21
21
  totalNodes: number;
22
22
  totalEdges: number;
23
23
  truncated: boolean;
24
+ nodesTruncated?: boolean;
25
+ edgesTruncated?: boolean;
24
26
  }
25
27
  interface HealthData {
26
28
  status: 'ok' | 'degraded' | 'unreachable';
@@ -191,7 +193,7 @@ declare class DashboardClient extends MemoryClient {
191
193
  * arbitrary N-node sample were silently dropped, collapsing dense graphs to
192
194
  * a handful of rendered links.
193
195
  */
194
- graphSubgraph(edges?: number): Promise<SubgraphResponse>;
196
+ graphSubgraph(edges?: number, nodes?: number): Promise<SubgraphResponse>;
195
197
  fetchHealthRaw(): Promise<RawHealthResponse>;
196
198
  }
197
199
 
@@ -11,9 +11,9 @@ import {
11
11
  toGraphologyFormat,
12
12
  transformGraphData,
13
13
  unreachableHealth
14
- } from "./chunk-ZVI7DCB4.mjs";
15
- import "./chunk-MDFUZ3V2.mjs";
16
- import "./chunk-34MTVIYK.mjs";
14
+ } from "./chunk-AMKPOPH6.mjs";
15
+ import "./chunk-JGFDID3B.mjs";
16
+ import "./chunk-3OLH3HYR.mjs";
17
17
  export {
18
18
  DashboardClient,
19
19
  Poller,