@pyxmate/memory 1.17.0 → 1.17.2

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.
@@ -835,7 +835,7 @@ function createProxyServer(client, version, uploadLocalFile) {
835
835
  return server;
836
836
  }
837
837
  async function runMcpProxyServer(opts) {
838
- const version = opts.version ?? (true ? "1.17.0" : "0.0.0-dev");
838
+ const version = opts.version ?? (true ? "1.17.2" : "0.0.0-dev");
839
839
  const read = await opts.readCredentials();
840
840
  if (!read.ok) {
841
841
  const text = read.result.content.map((c) => c.type === "text" ? c.text : "").join(" ").trim();
@@ -536,7 +536,38 @@ function normalizeMcpStoreMetadata(value) {
536
536
  }
537
537
  return { ...caller, ...serverOwned };
538
538
  }
539
- function normalizeStore(input, context, mcp) {
539
+ function mergeCanonicalGraphInput(entities, relationships, triples) {
540
+ const uniqueEntities = /* @__PURE__ */ new Map();
541
+ const addEntity = (entity) => {
542
+ const key = `${normalizeNameKey(entity.name)}\0${normalizeGraphLabel(entity.type, "CONCEPT")}`;
543
+ if (!uniqueEntities.has(key)) uniqueEntities.set(key, entity);
544
+ };
545
+ const uniqueRelationships = /* @__PURE__ */ new Map();
546
+ const addRelationship = (relationship) => {
547
+ const key = [
548
+ normalizeNameKey(relationship.source),
549
+ normalizeNameKey(relationship.target),
550
+ normalizeGraphLabel(relationship.type, "RELATED_TO")
551
+ ].join("\0");
552
+ if (!uniqueRelationships.has(key)) uniqueRelationships.set(key, relationship);
553
+ };
554
+ for (const entity of entities) addEntity(entity);
555
+ for (const relationship of relationships) addRelationship(relationship);
556
+ for (const triple of triples) {
557
+ addEntity(triple.subject);
558
+ addEntity(triple.object);
559
+ addRelationship({
560
+ source: triple.subject.name,
561
+ target: triple.object.name,
562
+ type: normalizeGraphLabel(triple.relation, "RELATED_TO")
563
+ });
564
+ }
565
+ return {
566
+ entities: [...uniqueEntities.values()],
567
+ relationships: [...uniqueRelationships.values()]
568
+ };
569
+ }
570
+ function canonicalizeStorePayload(input, resolvedAt, mcp, compileAdmission) {
540
571
  const value = requireObject(input, "input");
541
572
  const common = [
542
573
  "id",
@@ -559,19 +590,14 @@ function normalizeStore(input, context, mcp) {
559
590
  mcp ? [...common, "topic", "project", "metadata", "triples", "entitiesOnly"] : [...common, "metadata"],
560
591
  "input"
561
592
  );
562
- if (value.namespaceId !== void 0 && value.namespaceId !== context.scope.namespaceId) {
563
- throw new Error("input.namespaceId does not match trusted context.scope.namespaceId");
564
- }
565
- if (value.extractEntities === true) {
566
- throw new Error("input.extractEntities=true requires external I/O and is not execution-ready");
567
- }
593
+ compileAdmission?.(value);
568
594
  const normalized = {
569
595
  content: requireString(value.content, "input.content"),
570
596
  type: optionalEnum(value.type, MEMORY_TYPES, "input.type") ?? "long-term",
571
597
  targets: normalizeStoreTargets(value.targets),
572
598
  metadata: mcp ? normalizeMcpStoreMetadata(value) : canonicalValue(value.metadata ?? {}, "input.metadata"),
573
- createdAt: context.resolvedAt,
574
- ingestTime: context.resolvedAt,
599
+ createdAt: resolvedAt,
600
+ ingestTime: resolvedAt,
575
601
  extractEntities: false
576
602
  };
577
603
  withOptional(normalized, "id", optionalCallerEntryId(value.id, "input.id"));
@@ -591,6 +617,7 @@ function normalizeStore(input, context, mcp) {
591
617
  }
592
618
  const entities = normalizeGraphEntities(value.entities) ?? [];
593
619
  const relationships = normalizeGraphRelationships(value.relationships) ?? [];
620
+ const triples = [];
594
621
  if (mcp && value.triples !== void 0) {
595
622
  if (!Array.isArray(value.triples) || value.triples.length > 256) {
596
623
  throw new Error("input.triples must be an array of at most 256 items");
@@ -602,57 +629,45 @@ function normalizeStore(input, context, mcp) {
602
629
  const subject = tripleEntities?.[0];
603
630
  const object = tripleEntities?.[1];
604
631
  if (!subject || !object) throw new Error(`input.triples[${index}] has invalid endpoints`);
605
- entities.push(subject, object);
606
- relationships.push({
607
- source: subject.name,
608
- target: object.name,
609
- type: normalizeGraphLabel(
610
- requireString(triple.relation, `input.triples[${index}].relation`),
611
- "RELATED_TO"
612
- )
632
+ triples.push({
633
+ subject,
634
+ relation: requireString(triple.relation, `input.triples[${index}].relation`),
635
+ object
613
636
  });
614
637
  }
615
638
  }
616
- const uniqueEntities = /* @__PURE__ */ new Map();
617
- for (const entity of entities) {
618
- const key = `${normalizeNameKey(entity.name)}\0${entity.type}`;
619
- if (!uniqueEntities.has(key)) uniqueEntities.set(key, entity);
620
- }
621
- const uniqueRelationships = /* @__PURE__ */ new Map();
622
- for (const relationship of relationships) {
623
- const key = [
624
- normalizeNameKey(relationship.source),
625
- normalizeNameKey(relationship.target),
626
- normalizeGraphLabel(relationship.type, "RELATED_TO")
627
- ].join("\0");
628
- if (!uniqueRelationships.has(key)) uniqueRelationships.set(key, relationship);
629
- }
639
+ const merged = mergeCanonicalGraphInput(entities, relationships, triples);
630
640
  const graphTargeted = normalized.targets.includes(
631
641
  "graph"
632
642
  );
633
- const entityNames = new Set(
634
- [...uniqueEntities.values()].map(
635
- (entity) => normalizeNameKey(entity.name)
636
- )
637
- );
638
- const hasResolvableRelationship = [...uniqueRelationships.values()].some((relationship) => {
639
- const value2 = relationship;
640
- const source = normalizeNameKey(value2.source);
641
- const target = normalizeNameKey(value2.target);
643
+ const entityNames = new Set(merged.entities.map((entity) => normalizeNameKey(entity.name)));
644
+ const hasResolvableRelationship = merged.relationships.some((relationship) => {
645
+ const source = normalizeNameKey(relationship.source);
646
+ const target = normalizeNameKey(relationship.target);
642
647
  return source !== target && entityNames.has(source) && entityNames.has(target);
643
648
  });
644
649
  const entitiesOnly = mcp && value.entitiesOnly !== void 0 ? requireBoolean(value.entitiesOnly, "input.entitiesOnly") : false;
645
- if (mcp && graphTargeted && uniqueEntities.size >= 2 && !hasResolvableRelationship && !entitiesOnly) {
650
+ if (mcp && graphTargeted && merged.entities.length >= 2 && !hasResolvableRelationship && !entitiesOnly) {
646
651
  throw new Error(
647
652
  "GRAPH_RELATIONSHIPS_REQUIRED: graph stores with two or more entities require a relationship that connects declared entity names, or entitiesOnly=true"
648
653
  );
649
654
  }
650
- if (uniqueEntities.size > 0) normalized.entities = [...uniqueEntities.values()];
651
- if (uniqueRelationships.size > 0) {
652
- normalized.relationships = [...uniqueRelationships.values()];
653
- }
655
+ if (merged.entities.length > 0) normalized.entities = merged.entities;
656
+ if (merged.relationships.length > 0) normalized.relationships = merged.relationships;
654
657
  return normalized;
655
658
  }
659
+ function normalizeStore(input, context, mcp) {
660
+ return canonicalizeStorePayload(input, context.resolvedAt, mcp, (value) => {
661
+ if (value.namespaceId !== void 0 && value.namespaceId !== context.scope.namespaceId) {
662
+ throw new Error("input.namespaceId does not match trusted context.scope.namespaceId");
663
+ }
664
+ if (value.extractEntities === true) {
665
+ throw new Error(
666
+ "input.extractEntities=true requires external I/O and is not execution-ready"
667
+ );
668
+ }
669
+ });
670
+ }
656
671
  function normalizeBatchStore(input, context) {
657
672
  const value = requireObject(input, "input");
658
673
  requireExactKeys(value, ["entries"], "input");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyxmate/memory",
3
- "version": "1.17.0",
3
+ "version": "1.17.2",
4
4
  "type": "module",
5
5
  "description": "SDK for pyx-memory — Memory as a Service for AI agents",
6
6
  "license": "MIT",