@pyxmate/memory 1.0.0 → 1.1.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,7 +1,68 @@
1
1
  import {
2
+ RAGStrategy,
2
3
  mergeExtractedEntities
3
4
  } from "./chunk-X6AYWXW7.mjs";
4
5
 
6
+ // ../client/src/disabled-memory.ts
7
+ var DEFAULT_PAGE_LIMIT = 20;
8
+ var DisabledMemory = class {
9
+ async initialize() {
10
+ console.warn("[pyx-memory] No memory backend configured \u2014 running without memory.");
11
+ }
12
+ async store(entry) {
13
+ return {
14
+ id: "disabled",
15
+ content: entry.content,
16
+ type: entry.type,
17
+ metadata: {},
18
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
19
+ };
20
+ }
21
+ async search() {
22
+ return { entries: [], totalCount: 0, strategy: RAGStrategy.NAIVE };
23
+ }
24
+ async list(params = {}) {
25
+ return {
26
+ entries: [],
27
+ totalCount: 0,
28
+ page: params.page ?? 1,
29
+ limit: params.limit ?? DEFAULT_PAGE_LIMIT
30
+ };
31
+ }
32
+ async get() {
33
+ return null;
34
+ }
35
+ async delete() {
36
+ return false;
37
+ }
38
+ async clearSession() {
39
+ return 0;
40
+ }
41
+ async stats() {
42
+ return {
43
+ totalEntries: 0,
44
+ storageUsedBytes: 0,
45
+ vectorCount: 0,
46
+ recentAccessCount: 0,
47
+ connected: false
48
+ };
49
+ }
50
+ async queryAsOf() {
51
+ return [];
52
+ }
53
+ async lineage() {
54
+ return { versions: [], source: "chain" };
55
+ }
56
+ async reinforce() {
57
+ return { updated: [] };
58
+ }
59
+ async queryByEventTime() {
60
+ return [];
61
+ }
62
+ async shutdown() {
63
+ }
64
+ };
65
+
5
66
  // ../client/src/memory-client.ts
6
67
  var MemoryServerError = class extends Error {
7
68
  status;
@@ -789,6 +850,7 @@ var MemoryClient = class {
789
850
  };
790
851
 
791
852
  export {
853
+ DisabledMemory,
792
854
  MemoryServerError,
793
855
  MemoryClient
794
856
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  MemoryClient
3
- } from "./chunk-PXQLVQAA.mjs";
3
+ } from "./chunk-U3U4MHWS.mjs";
4
4
 
5
5
  // ../dashboard/src/aggregations/consolidation-analytics.ts
6
6
  function analyzeConsolidationLog(entries) {
@@ -563,9 +563,91 @@ function createReadCredentials(providerFactory) {
563
563
  };
564
564
  }
565
565
 
566
+ // src/mcp/proxy-server.ts
567
+ import { Client as McpClient } from "@modelcontextprotocol/sdk/client/index.js";
568
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
569
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
570
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
571
+ import {
572
+ CallToolRequestSchema,
573
+ GetPromptRequestSchema,
574
+ ListPromptsRequestSchema,
575
+ ListToolsRequestSchema
576
+ } from "@modelcontextprotocol/sdk/types.js";
577
+ var REMOTE_MCP_PATH = "/mcp";
578
+ function createProxyServer(client, version) {
579
+ const caps = client.getServerCapabilities();
580
+ const server = new Server(client.getServerVersion() ?? { name: "pyx-memory", version }, {
581
+ capabilities: {
582
+ // Advertise the PRESENCE of tools/prompts, but NOT their `listChanged`
583
+ // sub-capability: this proxy does not relay the remote's list_changed
584
+ // notifications, so claiming listChanged would be a capability the host
585
+ // could rely on but we never honor (Codex: keep the proxy transparent).
586
+ ...caps?.tools ? { tools: {} } : {},
587
+ ...caps?.prompts ? { prompts: {} } : {}
588
+ },
589
+ instructions: client.getInstructions()
590
+ });
591
+ if (caps?.tools) {
592
+ server.setRequestHandler(
593
+ ListToolsRequestSchema,
594
+ (req) => client.listTools(req.params)
595
+ );
596
+ server.setRequestHandler(
597
+ CallToolRequestSchema,
598
+ (req) => client.callTool(req.params)
599
+ );
600
+ }
601
+ if (caps?.prompts) {
602
+ server.setRequestHandler(
603
+ ListPromptsRequestSchema,
604
+ (req) => client.listPrompts(req.params)
605
+ );
606
+ server.setRequestHandler(
607
+ GetPromptRequestSchema,
608
+ (req) => client.getPrompt(req.params)
609
+ );
610
+ }
611
+ return server;
612
+ }
613
+ async function runMcpProxyServer(opts) {
614
+ const version = opts.version ?? (true ? "1.1.0" : "0.0.0-dev");
615
+ const read = await opts.readCredentials();
616
+ if (!read.ok) {
617
+ const text = read.result.content.map((c) => c.type === "text" ? c.text : "").join(" ").trim();
618
+ throw new Error(text || "pyx-memory credentials are unavailable. Run: pyx-mem login");
619
+ }
620
+ const { endpoint, apiKey } = read.credentials;
621
+ const url = new URL(`${endpoint.replace(/\/+$/, "")}${REMOTE_MCP_PATH}`);
622
+ const client = new McpClient({ name: "pyx-mem-proxy", version }, { capabilities: {} });
623
+ const clientTransport = new StreamableHTTPClientTransport(url, {
624
+ requestInit: { headers: { Authorization: `Bearer ${apiKey}` } }
625
+ });
626
+ try {
627
+ await client.connect(clientTransport);
628
+ } catch (err) {
629
+ const msg = err instanceof Error ? err.message : String(err);
630
+ throw new Error(
631
+ `Could not reach the pyx-memory remote MCP at ${url.href}: ${msg}. Verify the endpoint and key with \`pyx-mem doctor\`, or run the bundled server with \`pyx-mem mcp\`.`
632
+ );
633
+ }
634
+ try {
635
+ const server = createProxyServer(client, version);
636
+ const transport = new StdioServerTransport();
637
+ const closed = new Promise((resolve3) => {
638
+ transport.onclose = () => resolve3();
639
+ });
640
+ await server.connect(transport);
641
+ await closed;
642
+ } finally {
643
+ await client.close().catch(() => {
644
+ });
645
+ }
646
+ }
647
+
566
648
  // src/mcp/server.ts
567
649
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
568
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
650
+ import { StdioServerTransport as StdioServerTransport2 } from "@modelcontextprotocol/sdk/server/stdio.js";
569
651
 
570
652
  // src/mcp/prompts/index.ts
571
653
  import { z } from "zod";
@@ -1377,7 +1459,7 @@ var ALL_TOOL_NAMES = ALL_TOOLS.map((t) => t.name);
1377
1459
  // src/mcp/server.ts
1378
1460
  async function runMcpServer(opts) {
1379
1461
  const fetchImpl = opts.fetchImpl ?? fetch;
1380
- const version = opts.version ?? (true ? "1.0.0" : "0.0.0-dev");
1462
+ const version = opts.version ?? (true ? "1.1.0" : "0.0.0-dev");
1381
1463
  const server = new McpServer(
1382
1464
  { name: "pyx-memory", version },
1383
1465
  { instructions: PYX_MEMORY_INSTRUCTIONS, capabilities: { tools: {}, prompts: {} } }
@@ -1396,7 +1478,7 @@ async function runMcpServer(opts) {
1396
1478
  for (const prompt of ALL_PROMPTS) {
1397
1479
  prompt.register(server);
1398
1480
  }
1399
- const transport = new StdioServerTransport();
1481
+ const transport = new StdioServerTransport2();
1400
1482
  const closed = new Promise((resolve3) => {
1401
1483
  transport.onclose = () => resolve3();
1402
1484
  });
@@ -1405,14 +1487,15 @@ async function runMcpServer(opts) {
1405
1487
  }
1406
1488
 
1407
1489
  // src/cli/commands/mcp.ts
1408
- async function mcpCommand() {
1490
+ async function mcpCommand(opts = {}) {
1409
1491
  const readCredentials = createReadCredentials(() => getDefaultKeychain());
1410
1492
  const onStdinEnd = new Promise((resolve3) => {
1411
1493
  process.stdin.once("end", resolve3);
1412
1494
  process.stdin.once("close", resolve3);
1413
1495
  });
1414
1496
  try {
1415
- await Promise.race([runMcpServer({ readCredentials }), onStdinEnd]);
1497
+ const run = opts.remote ? runMcpProxyServer({ readCredentials }) : runMcpServer({ readCredentials });
1498
+ await Promise.race([run, onStdinEnd]);
1416
1499
  return EXIT.OK;
1417
1500
  } catch (err) {
1418
1501
  process.stderr.write(`Internal error: ${err instanceof Error ? err.message : String(err)}
@@ -2101,7 +2184,9 @@ Commands:
2101
2184
  logout Delete stored pyx-memory credentials.
2102
2185
  doctor [--json] Diagnose keychain, credentials, backend, MCP startup.
2103
2186
  scaffold [--name <dir>] Generate Docker, env, SDK, and memory design-guide starter files.
2104
- mcp Start stdio MCP server.
2187
+ mcp [--remote] Start stdio MCP server. --remote proxies to the hosted
2188
+ server so tools + instructions stay server-owned
2189
+ (zero-touch updates; key stays in the keychain).
2105
2190
  mcp install <target> [--scope user|local|project]
2106
2191
  Install pyx-memory MCP config for your AI agent.
2107
2192
  Targets: claude-code, codex, cursor, cline, continue, windsurf, gemini-cli, pi, oh-my-pi, openclaw, hermes.
@@ -2183,7 +2268,7 @@ function runMcpInstall(target, scope) {
2183
2268
  return handler({ scope });
2184
2269
  }
2185
2270
  function runMcpCommand(parsed) {
2186
- if (parsed.subcommand === void 0) return mcpCommand();
2271
+ if (parsed.subcommand === void 0) return mcpCommand({ remote: parsed.flags.remote === true });
2187
2272
  if (parsed.subcommand === "install") {
2188
2273
  const target = parsed.positional[0];
2189
2274
  const scope = typeof parsed.flags.scope === "string" ? parsed.flags.scope : void 0;
@@ -11,8 +11,8 @@ import {
11
11
  toGraphologyFormat,
12
12
  transformGraphData,
13
13
  unreachableHealth
14
- } from "./chunk-ZCGJGI2O.mjs";
15
- import "./chunk-PXQLVQAA.mjs";
14
+ } from "./chunk-ZILXBWWH.mjs";
15
+ import "./chunk-U3U4MHWS.mjs";
16
16
  import "./chunk-X6AYWXW7.mjs";
17
17
  export {
18
18
  DashboardClient,
package/dist/index.d.ts CHANGED
@@ -149,6 +149,37 @@ interface ExtendedMemoryInterface extends MemoryInterface {
149
149
  getEntitySynthesis(name: string): Promise<MemoryEntry$1 | null>;
150
150
  }
151
151
 
152
+ /**
153
+ * No-op {@link MemoryInterface} for hosts that run without a memory backend
154
+ * (e.g. `MEMORY_URL` is unset). Every method returns a safe default, so the
155
+ * rest of the system functions without branching on `memory == null`.
156
+ *
157
+ * Canonical single source: this lives in the SAME package as `MemoryInterface`,
158
+ * so any method added to the interface fails THIS class's compile in the same
159
+ * build. The null-object can never silently drift behind the contract — the
160
+ * failure mode that left hand-rolled copies in downstream repos missing
161
+ * `lineage`/`reinforce` after the interface grew them.
162
+ *
163
+ * `initialize()` emits a single `console.warn`; pass nothing else — it is a
164
+ * pure null-object. Hosts wanting structured logging should log at the wiring
165
+ * site where they choose `DisabledMemory` over a real client.
166
+ */
167
+ declare class DisabledMemory implements MemoryInterface {
168
+ initialize(): Promise<void>;
169
+ store(entry: StoreInput$1): Promise<MemoryEntry$1>;
170
+ search(): Promise<MemorySearchResult$1>;
171
+ list(params?: MemoryListParams): Promise<MemoryListResult>;
172
+ get(): Promise<MemoryEntry$1 | null>;
173
+ delete(): Promise<boolean>;
174
+ clearSession(): Promise<number>;
175
+ stats(): Promise<MemoryStats$1>;
176
+ queryAsOf(): Promise<MemoryEntry$1[]>;
177
+ lineage(): Promise<LineageResult$1>;
178
+ reinforce(): Promise<ReinforceResult$1>;
179
+ queryByEventTime(): Promise<MemoryEntry$1[]>;
180
+ shutdown(): Promise<void>;
181
+ }
182
+
152
183
  /**
153
184
  * Callbacks for two-phase file enrichment. All callbacks are optional:
154
185
  * - Image-rich PDF + describeImage only → describes images, no entity extraction
@@ -1431,4 +1462,4 @@ interface CreatePyxMemoryOptions {
1431
1462
  }
1432
1463
  declare function createPyxMemory(opts?: CreatePyxMemoryOptions): MemoryClient;
1433
1464
 
1434
- export { type AgentId, type ApiResponse, type ConsolidationRunResult, type CorrectionInput, type CorrectionRecord, type CreatePyxMemoryOptions, DEFAULTS, DEPRECATED_RAG_STRATEGIES, type DroppedGraphRelationship, EmbeddingProviderName, type EnrichmentCallbacks, type EntityExtractionResult, type ExtendedMemoryInterface, type FetchCorrectionsInput, type GraphEnrichment, type GraphEnrichmentStatus, type GraphFailureMode, type GraphNode, type GraphRelationship, type GraphRepairResult, 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, type TemporalQueryFilters, type TenantScopeOptions, type Timestamp, type Topology, type TopologyExtractionProvider, type TopologyServiceVariant, VectorProvider, type WikiLintReport, createPyxMemory, mergeExtractedEntities, normalizeGraphLabel, normalizeNameKey };
1465
+ export { type AgentId, type ApiResponse, type ConsolidationRunResult, type CorrectionInput, type CorrectionRecord, type CreatePyxMemoryOptions, DEFAULTS, DEPRECATED_RAG_STRATEGIES, DisabledMemory, type DroppedGraphRelationship, EmbeddingProviderName, type EnrichmentCallbacks, type EntityExtractionResult, type ExtendedMemoryInterface, type FetchCorrectionsInput, type GraphEnrichment, type GraphEnrichmentStatus, type GraphFailureMode, type GraphNode, type GraphRelationship, type GraphRepairResult, 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, type TemporalQueryFilters, type TenantScopeOptions, type Timestamp, type Topology, type TopologyExtractionProvider, type TopologyServiceVariant, VectorProvider, type WikiLintReport, createPyxMemory, mergeExtractedEntities, normalizeGraphLabel, normalizeNameKey };
package/dist/index.mjs CHANGED
@@ -1,7 +1,8 @@
1
1
  import {
2
+ DisabledMemory,
2
3
  MemoryClient,
3
4
  MemoryServerError
4
- } from "./chunk-PXQLVQAA.mjs";
5
+ } from "./chunk-U3U4MHWS.mjs";
5
6
  import {
6
7
  DEFAULTS,
7
8
  DEPRECATED_RAG_STRATEGIES,
@@ -35,6 +36,7 @@ function createPyxMemory(opts = {}) {
35
36
  export {
36
37
  DEFAULTS,
37
38
  DEPRECATED_RAG_STRATEGIES,
39
+ DisabledMemory,
38
40
  EmbeddingProviderName,
39
41
  MemoryClient,
40
42
  MemoryServerError,
package/dist/react.mjs CHANGED
@@ -11,8 +11,8 @@ import {
11
11
  toGraphologyFormat,
12
12
  transformGraphData,
13
13
  unreachableHealth
14
- } from "./chunk-ZCGJGI2O.mjs";
15
- import "./chunk-PXQLVQAA.mjs";
14
+ } from "./chunk-ZILXBWWH.mjs";
15
+ import "./chunk-U3U4MHWS.mjs";
16
16
  import "./chunk-X6AYWXW7.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.0.0",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "description": "SDK for pyx-memory — Memory as a Service for AI agents",
6
6
  "license": "MIT",