@pyxmate/memory 1.15.1 → 1.16.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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  MemoryClient
3
- } from "./chunk-IEBF7BQF.mjs";
3
+ } from "./chunk-672SGW22.mjs";
4
4
 
5
5
  // ../dashboard/src/aggregations/consolidation-analytics.ts
6
6
  function analyzeConsolidationLog(entries) {
@@ -10,6 +10,58 @@ var DEFAULTS = {
10
10
  };
11
11
  var TAXONOMY_MAX_CATEGORIES = 10;
12
12
 
13
+ // ../shared/src/mcp/search-response.ts
14
+ var STRIPPED_ENTRY_FIELDS = /* @__PURE__ */ new Set(["contentHash", "embedding", "tenantId", "userId", "teamId"]);
15
+ function isRecord(value) {
16
+ return value !== null && typeof value === "object" && !Array.isArray(value);
17
+ }
18
+ function compactEntryForMcp(entry, vectorSimilarity) {
19
+ if (!isRecord(entry)) return entry;
20
+ const projected = {};
21
+ for (const [key, value] of Object.entries(entry)) {
22
+ if (!STRIPPED_ENTRY_FIELDS.has(key)) projected[key] = value;
23
+ }
24
+ if (vectorSimilarity !== void 0) projected.vectorSimilarity = vectorSimilarity;
25
+ return projected;
26
+ }
27
+ function vectorSimilarityByEntryId(payload) {
28
+ const similarities = /* @__PURE__ */ new Map();
29
+ const scoredEntries = Array.isArray(payload.scoredEntries) ? payload.scoredEntries : [];
30
+ for (const scored of scoredEntries) {
31
+ if (!isRecord(scored) || !isRecord(scored.entry)) continue;
32
+ const id = scored.entry.id;
33
+ if (typeof id === "string" && typeof scored.vectorSimilarity === "number") {
34
+ similarities.set(id, scored.vectorSimilarity);
35
+ }
36
+ }
37
+ return similarities;
38
+ }
39
+ function projectSearchResultRecord(payload) {
40
+ const similarities = vectorSimilarityByEntryId(payload);
41
+ const projected = {};
42
+ for (const [key, value] of Object.entries(payload)) {
43
+ if (key === "scoredEntries") continue;
44
+ if (key === "entries" && Array.isArray(value)) {
45
+ projected.entries = value.map(
46
+ (entry) => compactEntryForMcp(
47
+ entry,
48
+ isRecord(entry) && typeof entry.id === "string" ? similarities.get(entry.id) : void 0
49
+ )
50
+ );
51
+ } else {
52
+ projected[key] = value;
53
+ }
54
+ }
55
+ return projected;
56
+ }
57
+ function projectSearchResponseForMcp(payload) {
58
+ if (!isRecord(payload)) return payload;
59
+ if (isRecord(payload.data) && ("entries" in payload.data || "scoredEntries" in payload.data)) {
60
+ return { ...payload, data: projectSearchResultRecord(payload.data) };
61
+ }
62
+ return projectSearchResultRecord(payload);
63
+ }
64
+
13
65
  // ../shared/src/types/isolation.ts
14
66
  var NamespaceIsolation = {
15
67
  SHARED: "shared",
@@ -100,8 +152,10 @@ var DisabledMemory = class {
100
152
  return {
101
153
  entries: [],
102
154
  totalCount: 0,
103
- page: params.page ?? 1,
104
- limit: params.limit ?? DEFAULT_PAGE_LIMIT
155
+ // Mirror the real contract's shape: a keyset walk has no page number.
156
+ ...params.cursor == null ? { page: params.page ?? 1 } : {},
157
+ limit: params.limit ?? DEFAULT_PAGE_LIMIT,
158
+ nextCursor: null
105
159
  };
106
160
  }
107
161
  async get() {
@@ -305,6 +359,8 @@ var MemoryClient = class {
305
359
  const searchParams = new URLSearchParams();
306
360
  if (params.page != null) searchParams.set("page", String(params.page));
307
361
  if (params.limit != null) searchParams.set("limit", String(params.limit));
362
+ if (params.cursor != null) searchParams.set("cursor", params.cursor);
363
+ if (params.status != null) searchParams.set("status", params.status);
308
364
  if (params.type) searchParams.set("type", params.type);
309
365
  if (params.agentId) searchParams.set("agentId", params.agentId);
310
366
  if (params.includeKinds && params.includeKinds.length > 0) {
@@ -959,6 +1015,7 @@ var MemoryClient = class {
959
1015
  export {
960
1016
  DEFAULTS,
961
1017
  TAXONOMY_MAX_CATEGORIES,
1018
+ projectSearchResponseForMcp,
962
1019
  NamespaceIsolation,
963
1020
  MemoryType,
964
1021
  SensitivityLevel,
@@ -829,7 +829,7 @@ function createProxyServer(client, version, uploadLocalFile) {
829
829
  return server;
830
830
  }
831
831
  async function runMcpProxyServer(opts) {
832
- const version = opts.version ?? (true ? "1.15.1" : "0.0.0-dev");
832
+ const version = opts.version ?? (true ? "1.16.0" : "0.0.0-dev");
833
833
  const read = await opts.readCredentials();
834
834
  if (!read.ok) {
835
835
  const text = read.result.content.map((c) => c.type === "text" ? c.text : "").join(" ").trim();
@@ -11,8 +11,8 @@ import {
11
11
  toGraphologyFormat,
12
12
  transformGraphData,
13
13
  unreachableHealth
14
- } from "./chunk-3FRA37TI.mjs";
15
- import "./chunk-IEBF7BQF.mjs";
14
+ } from "./chunk-425XJ6JV.mjs";
15
+ import "./chunk-672SGW22.mjs";
16
16
  import "./chunk-A3L46P2G.mjs";
17
17
  export {
18
18
  DashboardClient,
@@ -317,6 +317,16 @@ function normalizeGet(input) {
317
317
  id: requireString(value.id, "input.id", { maxBytes: DATA_PLANE_COMPILER_LIMITS.identityBytes })
318
318
  };
319
319
  }
320
+ function normalizeMcpDelete(input) {
321
+ const value = requireObject(input, "input");
322
+ requireExactKeys(value, ["id", "reason"], "input");
323
+ return {
324
+ id: requireString(value.id, "input.id", {
325
+ maxBytes: DATA_PLANE_COMPILER_LIMITS.identityBytes
326
+ }),
327
+ reason: requireString(value.reason, "input.reason")
328
+ };
329
+ }
320
330
  function normalizeRestGet(input) {
321
331
  const normalized = normalizeGet(input);
322
332
  const id = normalized.id;
@@ -373,15 +383,12 @@ function normalizeProfile(input, write, defaultAgentId) {
373
383
  }
374
384
  return normalized;
375
385
  }
376
- function normalizeDue(input) {
386
+ function normalizeDue(input, context) {
377
387
  const value = requireObject(input, "input");
378
- requireExactKeys(value, ["from", "to", "limit"], "input");
379
- const from = requireCanonicalIso(value.from, "input.from");
380
- const to = requireCanonicalIso(value.to, "input.to");
381
- const duration = Date.parse(to) - Date.parse(from);
382
- if (duration < 864e5 || duration > 370 * 864e5 || duration % 864e5 !== 0) {
383
- throw new Error("input.to must be 1-370 fixed 24-hour periods after input.from");
384
- }
388
+ requireExactKeys(value, ["windowDays", "from", "limit"], "input");
389
+ const windowDays = requireInteger(value.windowDays, "input.windowDays", 1, 370);
390
+ const from = value.from === void 0 ? context.resolvedAt : normalizeIso(value.from, "input.from");
391
+ const to = new Date(Date.parse(from) + windowDays * 864e5).toISOString();
385
392
  const normalized = {
386
393
  from,
387
394
  to,
@@ -416,7 +423,10 @@ function normalizeGraphEntities(value) {
416
423
  requireExactKeys(entity, ["name", "type", "properties"], `input.entities[${index}]`);
417
424
  const normalized = {
418
425
  name: requireString(entity.name, `input.entities[${index}].name`),
419
- type: requireEnum(entity.type, ENTITY_TYPES, `input.entities[${index}].type`)
426
+ type: normalizeGraphLabel(
427
+ requireString(entity.type, `input.entities[${index}].type`, { maxBytes: 100 }),
428
+ "CONCEPT"
429
+ )
420
430
  };
421
431
  if (entity.properties !== void 0) {
422
432
  normalized.properties = canonicalValue(
@@ -472,7 +482,7 @@ function normalizeStore(input, context, mcp) {
472
482
  ];
473
483
  requireExactKeys(
474
484
  value,
475
- mcp ? [...common, "topic", "project", "triples", "entitiesOnly"] : [...common, "metadata", "id"],
485
+ mcp ? [...common, "topic", "project", "triples", "entitiesOnly"] : [...common, "metadata"],
476
486
  "input"
477
487
  );
478
488
  if (value.namespaceId !== void 0 && value.namespaceId !== context.scope.namespaceId) {
@@ -494,7 +504,6 @@ function normalizeStore(input, context, mcp) {
494
504
  ingestTime: context.resolvedAt,
495
505
  extractEntities: false
496
506
  };
497
- if (!mcp && value.id !== void 0) normalized.id = requireString(value.id, "input.id");
498
507
  withOptional(normalized, "source", optionalNonemptyString(value.source, "input.source"));
499
508
  withOptional(normalized, "agentId", optionalNonemptyString(value.agentId, "input.agentId"));
500
509
  withOptional(normalized, "sessionId", optionalNonemptyString(value.sessionId, "input.sessionId"));
@@ -535,7 +544,7 @@ function normalizeStore(input, context, mcp) {
535
544
  }
536
545
  const uniqueEntities = /* @__PURE__ */ new Map();
537
546
  for (const entity of entities) {
538
- const key = normalizeNameKey(entity.name);
547
+ const key = `${normalizeNameKey(entity.name)}\0${entity.type}`;
539
548
  if (!uniqueEntities.has(key)) uniqueEntities.set(key, entity);
540
549
  }
541
550
  const uniqueRelationships = /* @__PURE__ */ new Map();
@@ -547,6 +556,26 @@ function normalizeStore(input, context, mcp) {
547
556
  ].join("\0");
548
557
  if (!uniqueRelationships.has(key)) uniqueRelationships.set(key, relationship);
549
558
  }
559
+ const graphTargeted = normalized.targets.includes(
560
+ "graph"
561
+ );
562
+ const entityNames = new Set(
563
+ [...uniqueEntities.values()].map(
564
+ (entity) => normalizeNameKey(entity.name)
565
+ )
566
+ );
567
+ const hasResolvableRelationship = [...uniqueRelationships.values()].some((relationship) => {
568
+ const value2 = relationship;
569
+ const source = normalizeNameKey(value2.source);
570
+ const target = normalizeNameKey(value2.target);
571
+ return source !== target && entityNames.has(source) && entityNames.has(target);
572
+ });
573
+ const entitiesOnly = mcp && value.entitiesOnly !== void 0 ? requireBoolean(value.entitiesOnly, "input.entitiesOnly") : false;
574
+ if (mcp && graphTargeted && uniqueEntities.size >= 2 && !hasResolvableRelationship && !entitiesOnly) {
575
+ throw new Error(
576
+ "GRAPH_RELATIONSHIPS_REQUIRED: graph stores with two or more entities require a relationship that connects declared entity names, or entitiesOnly=true"
577
+ );
578
+ }
550
579
  if (uniqueEntities.size > 0) normalized.entities = [...uniqueEntities.values()];
551
580
  if (uniqueRelationships.size > 0) {
552
581
  normalized.relationships = [...uniqueRelationships.values()];
@@ -556,14 +585,14 @@ function normalizeStore(input, context, mcp) {
556
585
  function normalizeBatchStore(input, context) {
557
586
  const value = requireObject(input, "input");
558
587
  requireExactKeys(value, ["entries"], "input");
559
- if (!Array.isArray(value.entries) || value.entries.length < 1 || value.entries.length > 32) {
560
- throw new Error("input.entries must contain 1-32 entries");
588
+ if (!Array.isArray(value.entries) || value.entries.length < 1 || value.entries.length > 100) {
589
+ throw new Error("input.entries must contain 1-100 entries");
561
590
  }
562
591
  return {
563
- entries: value.entries.map((entry, index) => {
564
- const normalized = normalizeStore(entry, context, false);
565
- return { ...normalized, batchIndex: index };
566
- })
592
+ entries: value.entries.map((entry, batchIndex) => ({
593
+ ...normalizeStore(entry, context, false),
594
+ batchIndex
595
+ }))
567
596
  };
568
597
  }
569
598
  function normalizeSearch(input, mcp) {
@@ -624,7 +653,7 @@ function normalizeSearch(input, mcp) {
624
653
  }
625
654
  return normalized;
626
655
  }
627
- function normalizeLineage(input) {
656
+ function normalizeLineage(input, mcp) {
628
657
  const value = requireObject(input, "input");
629
658
  requireExactKeys(
630
659
  value,
@@ -657,11 +686,7 @@ function normalizeLineage(input) {
657
686
  normalizeIso(value.eventTimeEnd, "input.eventTimeEnd")
658
687
  ];
659
688
  }
660
- withOptional(
661
- normalized,
662
- "limit",
663
- optionalClampedPositiveInteger(value.limit, "input.limit", 100)
664
- );
689
+ normalized.limit = mcp ? optionalInteger(value.limit, "input.limit", 1, 200) ?? 50 : normalizeRestLimit(value.limit, "input.limit", 200);
665
690
  return normalized;
666
691
  }
667
692
  function normalizeReinforce(input) {
@@ -692,7 +717,7 @@ function normalizeGraphRead(input, operation) {
692
717
  if (operation === "rest:graph_nodes") {
693
718
  requireExactKeys(value, ["name", "type", "limit"], "input");
694
719
  const normalized = {
695
- limit: optionalClampedPositiveInteger(value.limit, "input.limit", 1e5) ?? 50
720
+ limit: optionalClampedPositiveInteger(value.limit, "input.limit", 1e3) ?? 100
696
721
  };
697
722
  withOptional(normalized, "name", optionalNonemptyString(value.name, "input.name"));
698
723
  withOptional(normalized, "type", optionalNonemptyString(value.type, "input.type"));
@@ -704,7 +729,7 @@ function normalizeGraphRead(input, operation) {
704
729
  [field]: optionalClampedPositiveInteger(
705
730
  value[field],
706
731
  `input.${field}`,
707
- operation === "rest:graph_subgraph" ? 1e4 : 5e5
732
+ operation === "rest:graph_subgraph" ? 1e4 : 1e3
708
733
  ) ?? (operation === "rest:graph_subgraph" ? 2e3 : 200)
709
734
  };
710
735
  }
@@ -745,14 +770,16 @@ function normalizeSupportedInput(operation, input, context) {
745
770
  case "mcp:search_memories":
746
771
  return normalizeSearch(input, true);
747
772
  case "rest:lineage":
773
+ return normalizeLineage(input, false);
748
774
  case "mcp:lineage":
749
- return normalizeLineage(input);
775
+ return normalizeLineage(input, true);
750
776
  case "rest:reinforce":
751
777
  case "mcp:reinforce":
752
778
  return normalizeReinforce(input);
753
779
  case "rest:delete":
754
- case "mcp:delete_memory":
755
780
  return normalizeGet(input);
781
+ case "mcp:delete_memory":
782
+ return normalizeMcpDelete(input);
756
783
  case "rest:graph_nodes":
757
784
  case "rest:graph_relationships":
758
785
  case "rest:graph_subgraph":
@@ -793,7 +820,7 @@ function normalizeSupportedInput(operation, input, context) {
793
820
  case "mcp:fetch_applicable_corrections":
794
821
  return normalizeCorrectionFetch(input, false);
795
822
  case "mcp:fetch_due_facts":
796
- return normalizeDue(input);
823
+ return normalizeDue(input, context);
797
824
  case "mcp:summarize_memory_entity":
798
825
  return normalizeEntitySynthesisGet(input, true);
799
826
  }
package/dist/index.d.ts CHANGED
@@ -6,6 +6,20 @@ interface MemoryListParams {
6
6
  page?: number;
7
7
  /** Entries per page (1–100). Default: 20 */
8
8
  limit?: number;
9
+ /**
10
+ * Opaque keyset-pagination token from a previous result's `nextCursor`.
11
+ * Guarantees exactly-once traversal even while strictly-newer entries
12
+ * are being written (offset/page pagination can repeat or skip there).
13
+ * A cursor is only valid for the same filter set that produced it.
14
+ * Mutually exclusive with `page` — supplying both is an error. Not a
15
+ * snapshot: rows backdated behind the cursor position can still appear.
16
+ */
17
+ cursor?: string;
18
+ /**
19
+ * Opt-in lifecycle-status filter. Omitted preserves today's behavior:
20
+ * active, superseded, and archived entries are all returned.
21
+ */
22
+ status?: 'active' | 'superseded' | 'archived';
9
23
  /** Filter by memory type. */
10
24
  type?: MemoryType$1;
11
25
  /** Filter by agent ID. */
@@ -35,8 +49,11 @@ interface MemoryListParams {
35
49
  interface MemoryListResult {
36
50
  entries: MemoryEntry$1[];
37
51
  totalCount: number;
38
- page: number;
52
+ /** Present in page/offset mode only — a keyset traversal has no page number. */
53
+ page?: number;
39
54
  limit: number;
55
+ /** Keyset token for the next page; null when this page is the last. */
56
+ nextCursor: string | null;
40
57
  }
41
58
  /** Filters for temporal queries (queryAsOf, queryByEventTime). */
42
59
  interface TemporalQueryFilters {
@@ -1163,6 +1180,11 @@ interface MemoryStats {
1163
1180
  usageHygiene?: UsageHygieneSnapshot;
1164
1181
  /** Whether the memory service is connected. False when using DisabledMemory. */
1165
1182
  connected?: boolean;
1183
+ /**
1184
+ * Deferred-embed queue depth. The in-process core always reports it (0 when
1185
+ * idle); absent means unknown (older server or disabled client), never 0.
1186
+ */
1187
+ pendingEmbeddings?: number;
1166
1188
  }
1167
1189
  interface GraphRepairResult {
1168
1190
  staleEdgesDeleted: number;
@@ -1271,6 +1293,8 @@ declare function mergeExtractedEntities(callerEntities: IngestEntity[] | undefin
1271
1293
  relationships: IngestRelationship[];
1272
1294
  };
1273
1295
 
1296
+ declare function projectSearchResponseForMcp(payload: unknown): unknown;
1297
+
1274
1298
  interface ApiResponse<T> {
1275
1299
  success: boolean;
1276
1300
  data?: T;
@@ -1557,4 +1581,4 @@ interface CreatePyxMemoryOptions {
1557
1581
  }
1558
1582
  declare function createPyxMemory(opts?: CreatePyxMemoryOptions): MemoryClient;
1559
1583
 
1560
- export { type AgentId, type ApiResponse, type ConsolidationRunResult, type CorrectionInput, type CorrectionRecord, type CreatePyxMemoryOptions, DEFAULTS, DEPRECATED_RAG_STRATEGIES, DisabledMemory, type DroppedGraphRelationship, type DueScanInput, EmbeddingProviderName, type EnrichmentCallbacks, type EntityExtractionResult, type ExtendedMemoryInterface, type FetchCorrectionsInput, type GraphEnrichment, type GraphEnrichmentStatus, type GraphFailureMode, type GraphNode, type GraphRelationship, type GraphRepairResult, type GraphTelemetrySnapshot, type GraphTraversalResult, type IngestEntity, type IngestErrorEvent, type IngestEvent, type IngestFileOptions, type IngestHeartbeatEvent, type IngestProgressEvent, type IngestRelationship, type IngestResultEvent, type IngestStage, type IngestionResult, type LineageParams, type LineageResult, type LineageVersion, MemoryClient, type MemoryClientOptions, type MemoryEntry, type MemoryIngestRequest, type MemoryInterface, type MemoryListParams, type MemoryListResult, type MemoryLogFilters, type MemorySearchParams, type MemorySearchResult, MemoryServerError, type MemoryStats, MemoryType, type MoveEntriesFilter, MoveFailureReason, type MoveResult, type MoveTarget, NamespaceIsolation, type PrincipalContext, RAGStrategy, type ReinforceParams, type ReinforceResult, type ReinforceSignal, SINGLE_TENANT_ID, SensitivityLevel, type SourceEvidence, type StoreInput, StoreTarget, TAXONOMY_MAX_CATEGORIES, type TemporalQueryFilters, type TenantScopeOptions, type Timestamp, type Topology, type TopologyExtractionProvider, type TopologyServiceVariant, type UsageHygieneSnapshot, VectorProvider, type VectorStatus, type WikiLintReport, createPyxMemory, mergeExtractedEntities, normalizeGraphLabel, normalizeNameKey };
1584
+ export { type AgentId, type ApiResponse, type ConsolidationRunResult, type CorrectionInput, type CorrectionRecord, type CreatePyxMemoryOptions, DEFAULTS, DEPRECATED_RAG_STRATEGIES, DisabledMemory, type DroppedGraphRelationship, type DueScanInput, EmbeddingProviderName, type EnrichmentCallbacks, type EntityExtractionResult, type ExtendedMemoryInterface, type FetchCorrectionsInput, type GraphEnrichment, type GraphEnrichmentStatus, type GraphFailureMode, type GraphNode, type GraphRelationship, type GraphRepairResult, type GraphTelemetrySnapshot, type GraphTraversalResult, type IngestEntity, type IngestErrorEvent, type IngestEvent, type IngestFileOptions, type IngestHeartbeatEvent, type IngestProgressEvent, type IngestRelationship, type IngestResultEvent, type IngestStage, type IngestionResult, type LineageParams, type LineageResult, type LineageVersion, MemoryClient, type MemoryClientOptions, type MemoryEntry, type MemoryIngestRequest, type MemoryInterface, type MemoryListParams, type MemoryListResult, type MemoryLogFilters, type MemorySearchParams, type MemorySearchResult, MemoryServerError, type MemoryStats, MemoryType, type MoveEntriesFilter, MoveFailureReason, type MoveResult, type MoveTarget, NamespaceIsolation, type PrincipalContext, RAGStrategy, type ReinforceParams, type ReinforceResult, type ReinforceSignal, SINGLE_TENANT_ID, SensitivityLevel, type SourceEvidence, type StoreInput, StoreTarget, TAXONOMY_MAX_CATEGORIES, type TemporalQueryFilters, type TenantScopeOptions, type Timestamp, type Topology, type TopologyExtractionProvider, type TopologyServiceVariant, type UsageHygieneSnapshot, VectorProvider, type VectorStatus, type WikiLintReport, createPyxMemory, mergeExtractedEntities, normalizeGraphLabel, normalizeNameKey, projectSearchResponseForMcp };
package/dist/index.mjs CHANGED
@@ -13,8 +13,9 @@ import {
13
13
  SensitivityLevel,
14
14
  StoreTarget,
15
15
  TAXONOMY_MAX_CATEGORIES,
16
- VectorProvider
17
- } from "./chunk-IEBF7BQF.mjs";
16
+ VectorProvider,
17
+ projectSearchResponseForMcp
18
+ } from "./chunk-672SGW22.mjs";
18
19
  import {
19
20
  mergeExtractedEntities,
20
21
  normalizeGraphLabel,
@@ -53,5 +54,6 @@ export {
53
54
  createPyxMemory,
54
55
  mergeExtractedEntities,
55
56
  normalizeGraphLabel,
56
- normalizeNameKey
57
+ normalizeNameKey,
58
+ projectSearchResponseForMcp
57
59
  };
package/dist/react.mjs CHANGED
@@ -11,8 +11,8 @@ import {
11
11
  toGraphologyFormat,
12
12
  transformGraphData,
13
13
  unreachableHealth
14
- } from "./chunk-3FRA37TI.mjs";
15
- import "./chunk-IEBF7BQF.mjs";
14
+ } from "./chunk-425XJ6JV.mjs";
15
+ import "./chunk-672SGW22.mjs";
16
16
  import "./chunk-A3L46P2G.mjs";
17
17
 
18
18
  // ../dashboard/src/hooks/use-consolidation-log.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyxmate/memory",
3
- "version": "1.15.1",
3
+ "version": "1.16.0",
4
4
  "type": "module",
5
5
  "description": "SDK for pyx-memory — Memory as a Service for AI agents",
6
6
  "license": "MIT",