@pyxmate/memory 0.35.1 → 0.37.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/{chunk-KQV3VYZO.mjs → chunk-DEMDFWI4.mjs} +10 -16
- package/dist/{chunk-C2KBUNUM.mjs → chunk-EXUSQ2GR.mjs} +1 -0
- package/dist/cli/pyx-mem.mjs +16 -4
- package/dist/dashboard.d.ts +19 -6
- package/dist/dashboard.mjs +2 -2
- package/dist/index.d.ts +9 -0
- package/dist/index.mjs +1 -1
- package/dist/react.d.ts +10 -2
- package/dist/react.mjs +12 -6
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MemoryClient
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-EXUSQ2GR.mjs";
|
|
4
4
|
|
|
5
5
|
// ../dashboard/src/aggregations/consolidation-analytics.ts
|
|
6
6
|
function analyzeConsolidationLog(entries) {
|
|
@@ -171,21 +171,15 @@ var DashboardClient = class extends MemoryClient {
|
|
|
171
171
|
`/api/memory/graph/relationships?limit=${limit}`
|
|
172
172
|
);
|
|
173
173
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}))
|
|
184
|
-
]);
|
|
185
|
-
return {
|
|
186
|
-
nodes: nodesResponse.nodes,
|
|
187
|
-
relationships: relsResponse.relationships
|
|
188
|
-
};
|
|
174
|
+
/**
|
|
175
|
+
* Coherent graph projection (server ≥0.34): edges + ALL their endpoint nodes
|
|
176
|
+
* + true store totals. The former nodes+relationships pair fetch (graphFull)
|
|
177
|
+
* could not feed a graph view — links whose endpoints fell outside the
|
|
178
|
+
* arbitrary N-node sample were silently dropped, collapsing dense graphs to
|
|
179
|
+
* a handful of rendered links.
|
|
180
|
+
*/
|
|
181
|
+
async graphSubgraph(edges = 2e3) {
|
|
182
|
+
return this.fetchApi(`/api/memory/graph/subgraph?edges=${edges}`);
|
|
189
183
|
}
|
|
190
184
|
async fetchHealthRaw() {
|
|
191
185
|
return this.fetchApi("/health");
|
|
@@ -105,6 +105,7 @@ var MemoryClient = class {
|
|
|
105
105
|
searchParams.set("eventTimeEnd", params.eventTimeRange[1]);
|
|
106
106
|
}
|
|
107
107
|
if (params.asOf) searchParams.set("asOf", params.asOf);
|
|
108
|
+
if (params.anchorTime) searchParams.set("anchorTime", params.anchorTime);
|
|
108
109
|
if (params.abstentionThreshold != null)
|
|
109
110
|
searchParams.set("abstentionThreshold", String(params.abstentionThreshold));
|
|
110
111
|
return this.fetchApi(`/api/memory/search?${searchParams}`);
|
package/dist/cli/pyx-mem.mjs
CHANGED
|
@@ -555,7 +555,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
555
555
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
556
556
|
|
|
557
557
|
// src/mcp/instructions.ts
|
|
558
|
-
var PYX_MEMORY_INSTRUCTIONS = `Use pyx-memory to search durable project/user memory before assuming prior decisions, and to store concise facts after corrections, bug fixes, design decisions, integration discoveries, gotchas, explicit preferences, or "remember this" requests. Store decisions, not deliberation. Include topic and project. Pass eventTime (ISO-8601, when the fact happened or took effect) for any fact that can change or go stale \u2014 job/status changes, decisions that supersede earlier ones, dated events; recency ordering, dated ("as of") queries, and stale-vs-current conflict resolution all key off it. When content names people, organizations, tools, places, events, or key concepts, you (the caller) must extract and pass both entities and relationships \u2014 the server does not auto-extract them. Edges matter as much as nodes: without relationships the graph cannot connect related memories. Use file ingest for documents/images worth persisting; images require a description.`;
|
|
558
|
+
var PYX_MEMORY_INSTRUCTIONS = `Use pyx-memory to search durable project/user memory before assuming prior decisions, and to store concise facts after corrections, bug fixes, design decisions, integration discoveries, gotchas, explicit preferences, or "remember this" requests. Store decisions, not deliberation. Include topic and project. Pass eventTime (ISO-8601, when the fact happened or took effect) for any fact that can change or go stale \u2014 job/status changes, decisions that supersede earlier ones, dated events; recency ordering, dated ("as of") queries, and stale-vs-current conflict resolution all key off it. When a question names a time \u2014 explicit or relative ("last year", "\uB450 \uB2EC \uC804") \u2014 resolve it to an absolute ISO-8601 timestamp yourself and pass it as search anchorTime: results then rank by proximity to that time instead of now, without excluding anything. When content names people, organizations, tools, places, events, or key concepts, you (the caller) must extract and pass both entities and relationships \u2014 the server does not auto-extract them. Edges matter as much as nodes: without relationships the graph cannot connect related memories. Use file ingest for documents/images worth persisting; images require a description.`;
|
|
559
559
|
|
|
560
560
|
// src/mcp/sampling.ts
|
|
561
561
|
function createSamplingClient(server) {
|
|
@@ -1024,6 +1024,9 @@ var inputShape5 = {
|
|
|
1024
1024
|
eventTimeStart: z8.string().optional().describe("Inclusive event-time start (ISO-8601); must be paired with eventTimeEnd."),
|
|
1025
1025
|
eventTimeEnd: z8.string().optional().describe("Inclusive event-time end (ISO-8601); must be paired with eventTimeStart."),
|
|
1026
1026
|
asOf: z8.string().optional().describe("Only include memories ingested before this ISO-8601 timestamp."),
|
|
1027
|
+
anchorTime: z8.string().optional().describe(
|
|
1028
|
+
'Soft recency ANCHOR (ISO-8601) \u2014 ranks results by proximity to this time instead of now; never excludes anything. When the question names a relative time ("two months ago", "last year", "3\uB144 \uC804"), resolve it against the current date yourself and pass the absolute timestamp here; prefer this over eventTimeStart/End unless a strict window is required, because hard filters drop last-known-before facts.'
|
|
1029
|
+
),
|
|
1027
1030
|
...scopeShape
|
|
1028
1031
|
};
|
|
1029
1032
|
var searchMemoriesTool = {
|
|
@@ -1055,7 +1058,8 @@ var searchMemoriesTool = {
|
|
|
1055
1058
|
abstentionThreshold: args.abstentionThreshold,
|
|
1056
1059
|
eventTimeStart: args.eventTimeStart,
|
|
1057
1060
|
eventTimeEnd: args.eventTimeEnd,
|
|
1058
|
-
asOf: args.asOf
|
|
1061
|
+
asOf: args.asOf,
|
|
1062
|
+
anchorTime: args.anchorTime
|
|
1059
1063
|
},
|
|
1060
1064
|
scope: args
|
|
1061
1065
|
});
|
|
@@ -1332,7 +1336,7 @@ var ALL_TOOL_NAMES = ALL_TOOLS.map((t) => t.name);
|
|
|
1332
1336
|
// src/mcp/server.ts
|
|
1333
1337
|
async function runMcpServer(opts) {
|
|
1334
1338
|
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
1335
|
-
const version = opts.version ?? (true ? "0.
|
|
1339
|
+
const version = opts.version ?? (true ? "0.37.0" : "0.0.0-dev");
|
|
1336
1340
|
const server = new McpServer(
|
|
1337
1341
|
{ name: "pyx-memory", version },
|
|
1338
1342
|
{ instructions: PYX_MEMORY_INSTRUCTIONS, capabilities: { tools: {} } }
|
|
@@ -1698,6 +1702,13 @@ function mcpInstallPiCommand(opts = {}) {
|
|
|
1698
1702
|
prereq: "pi has no native MCP support \u2014 install the third-party adapter once:\n pi install npm:pi-mcp-adapter"
|
|
1699
1703
|
});
|
|
1700
1704
|
}
|
|
1705
|
+
function mcpInstallOhMyPiCommand(opts = {}) {
|
|
1706
|
+
const scope = opts.scope ?? "user";
|
|
1707
|
+
if (!validateScope(scope)) return EXIT.USAGE;
|
|
1708
|
+
const home = opts._homeDir ?? homedir();
|
|
1709
|
+
const filePath = scope === "user" ? join(home, ".omp", "agent", "mcp.json") : join(process.cwd(), ".omp", "mcp.json");
|
|
1710
|
+
return writeJsonAndReport(filePath, "oh-my-pi");
|
|
1711
|
+
}
|
|
1701
1712
|
function mcpInstallOpenClawCommand(opts = {}) {
|
|
1702
1713
|
const scope = opts.scope ?? "user";
|
|
1703
1714
|
if (!validateScope(scope)) return EXIT.USAGE;
|
|
@@ -1873,7 +1884,7 @@ Commands:
|
|
|
1873
1884
|
mcp Start stdio MCP server.
|
|
1874
1885
|
mcp install <target> [--scope user|local|project]
|
|
1875
1886
|
Install pyx-memory MCP config for your AI agent.
|
|
1876
|
-
Targets: claude-code, codex, cursor, cline, continue, windsurf, gemini-cli, pi, openclaw, hermes.
|
|
1887
|
+
Targets: claude-code, codex, cursor, cline, continue, windsurf, gemini-cli, pi, oh-my-pi, openclaw, hermes.
|
|
1877
1888
|
|
|
1878
1889
|
Notes:
|
|
1879
1890
|
- Credentials are stored only in the OS credential store (Keychain / libsecret / Credential Manager).
|
|
@@ -1935,6 +1946,7 @@ var INSTALL_TARGETS = {
|
|
|
1935
1946
|
windsurf: mcpInstallWindsurfCommand,
|
|
1936
1947
|
"gemini-cli": mcpInstallGeminiCliCommand,
|
|
1937
1948
|
pi: mcpInstallPiCommand,
|
|
1949
|
+
"oh-my-pi": mcpInstallOhMyPiCommand,
|
|
1938
1950
|
openclaw: mcpInstallOpenClawCommand,
|
|
1939
1951
|
hermes: mcpInstallHermesCommand
|
|
1940
1952
|
};
|
package/dist/dashboard.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MemoryType, MemoryEntry,
|
|
1
|
+
import { MemoryType, MemoryEntry, GraphNode, GraphRelationship, MemoryStats } from '@pyx-memory/shared';
|
|
2
2
|
import { MemoryClient } from '@pyx-memory/client';
|
|
3
3
|
|
|
4
4
|
interface RawHealthResponse {
|
|
@@ -13,6 +13,15 @@ interface RawHealthResponse {
|
|
|
13
13
|
storageUsedBytes: number;
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
|
+
/** GET /api/memory/graph/subgraph — edges + ALL their endpoint nodes + true store totals. */
|
|
17
|
+
interface SubgraphResponse {
|
|
18
|
+
nodes: GraphNode[];
|
|
19
|
+
relationships: GraphRelationship[];
|
|
20
|
+
categoryTotals: Record<string, number>;
|
|
21
|
+
totalNodes: number;
|
|
22
|
+
totalEdges: number;
|
|
23
|
+
truncated: boolean;
|
|
24
|
+
}
|
|
16
25
|
interface HealthData {
|
|
17
26
|
status: 'ok' | 'degraded' | 'unreachable';
|
|
18
27
|
uptime: number;
|
|
@@ -175,10 +184,14 @@ declare class DashboardClient extends MemoryClient {
|
|
|
175
184
|
relationships: GraphRelationship[];
|
|
176
185
|
totalCount: number;
|
|
177
186
|
}>;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
187
|
+
/**
|
|
188
|
+
* Coherent graph projection (server ≥0.34): edges + ALL their endpoint nodes
|
|
189
|
+
* + true store totals. The former nodes+relationships pair fetch (graphFull)
|
|
190
|
+
* could not feed a graph view — links whose endpoints fell outside the
|
|
191
|
+
* arbitrary N-node sample were silently dropped, collapsing dense graphs to
|
|
192
|
+
* a handful of rendered links.
|
|
193
|
+
*/
|
|
194
|
+
graphSubgraph(edges?: number): Promise<SubgraphResponse>;
|
|
182
195
|
fetchHealthRaw(): Promise<RawHealthResponse>;
|
|
183
196
|
}
|
|
184
197
|
|
|
@@ -213,4 +226,4 @@ declare class Poller<T> {
|
|
|
213
226
|
private emit;
|
|
214
227
|
}
|
|
215
228
|
|
|
216
|
-
export { type ConsolidationAnalytics, type ConsolidationLogEntry, type D3ForceData, type D3ForceLink, type D3ForceNode, DashboardClient, type EntryFilters, type GraphVizData, type GraphVizEdge, type GraphVizNode, type GraphologyData, type GraphologyEdge, type GraphologyNode, type HealthData, type HookResult, type MemoryMetrics, type PaginatedEntries, Poller, type PollerOptions, type PollerState, type RawHealthResponse, type TransformOptions, type TypeDistribution, analyzeConsolidationLog, computeMetrics, computeTypeDistribution, enrichHealth, formatBytes, formatUptime, toD3ForceFormat, toGraphologyFormat, transformGraphData, unreachableHealth };
|
|
229
|
+
export { type ConsolidationAnalytics, type ConsolidationLogEntry, type D3ForceData, type D3ForceLink, type D3ForceNode, DashboardClient, type EntryFilters, type GraphVizData, type GraphVizEdge, type GraphVizNode, type GraphologyData, type GraphologyEdge, type GraphologyNode, type HealthData, type HookResult, type MemoryMetrics, type PaginatedEntries, Poller, type PollerOptions, type PollerState, type RawHealthResponse, type SubgraphResponse, type TransformOptions, type TypeDistribution, analyzeConsolidationLog, computeMetrics, computeTypeDistribution, enrichHealth, formatBytes, formatUptime, toD3ForceFormat, toGraphologyFormat, transformGraphData, unreachableHealth };
|
package/dist/dashboard.mjs
CHANGED
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
toGraphologyFormat,
|
|
12
12
|
transformGraphData,
|
|
13
13
|
unreachableHealth
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
14
|
+
} from "./chunk-DEMDFWI4.mjs";
|
|
15
|
+
import "./chunk-EXUSQ2GR.mjs";
|
|
16
16
|
import "./chunk-KSTI4M52.mjs";
|
|
17
17
|
export {
|
|
18
18
|
DashboardClient,
|
package/dist/index.d.ts
CHANGED
|
@@ -554,6 +554,15 @@ interface MemorySearchParams {
|
|
|
554
554
|
eventTimeRange?: [string, string];
|
|
555
555
|
/** Filter results to entries ingested before this cutoff (ISO 8601). Falls back to createdAt when ingestTime is null. */
|
|
556
556
|
asOf?: string;
|
|
557
|
+
/**
|
|
558
|
+
* Soft recency ANCHOR (ISO 8601) — never a filter. Candidates are ranked by
|
|
559
|
+
* proximity to this time instead of now, and conflicting assertions
|
|
560
|
+
* re-order around it. Resolving relative-time expressions ("two months
|
|
561
|
+
* ago", "3년 전") to an absolute timestamp is the CALLER's side of the
|
|
562
|
+
* agentic contract — language understanding never enters the engine. Wins
|
|
563
|
+
* over the query-text year parse (hybrid strategy).
|
|
564
|
+
*/
|
|
565
|
+
anchorTime?: string;
|
|
557
566
|
/** Confidence threshold below which the system recommends abstention (0.0–1.0). Default: 0.3. */
|
|
558
567
|
abstentionThreshold?: number;
|
|
559
568
|
/**
|
package/dist/index.mjs
CHANGED
package/dist/react.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HookResult, ConsolidationAnalytics, TransformOptions, GraphVizData, EntryFilters, PaginatedEntries, HealthData, TypeDistribution } from './dashboard.js';
|
|
2
|
-
export { ConsolidationLogEntry, D3ForceData, D3ForceLink, D3ForceNode, DashboardClient, GraphVizEdge, GraphVizNode, GraphologyData, GraphologyEdge, GraphologyNode, MemoryMetrics, Poller, PollerOptions, PollerState, RawHealthResponse, analyzeConsolidationLog, computeMetrics, computeTypeDistribution, enrichHealth, formatBytes, formatUptime, toD3ForceFormat, toGraphologyFormat, transformGraphData, unreachableHealth } from './dashboard.js';
|
|
2
|
+
export { ConsolidationLogEntry, D3ForceData, D3ForceLink, D3ForceNode, DashboardClient, GraphVizEdge, GraphVizNode, GraphologyData, GraphologyEdge, GraphologyNode, MemoryMetrics, Poller, PollerOptions, PollerState, RawHealthResponse, SubgraphResponse, analyzeConsolidationLog, computeMetrics, computeTypeDistribution, enrichHealth, formatBytes, formatUptime, toD3ForceFormat, toGraphologyFormat, transformGraphData, unreachableHealth } from './dashboard.js';
|
|
3
3
|
import { MemoryStats } from '@pyx-memory/shared';
|
|
4
4
|
import '@pyx-memory/client';
|
|
5
5
|
|
|
@@ -7,8 +7,16 @@ declare function useConsolidationLog(serverUrl: string, limit?: number, interval
|
|
|
7
7
|
|
|
8
8
|
interface UseKnowledgeGraphOptions extends TransformOptions {
|
|
9
9
|
intervalMs?: number;
|
|
10
|
-
|
|
10
|
+
/** Edge render budget forwarded to the subgraph endpoint (server caps at 10k). */
|
|
11
|
+
edges?: number;
|
|
11
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Polls the coherent subgraph (server ≥0.34): every relationship arrives with
|
|
15
|
+
* both endpoint nodes hydrated, so no link is dropped for a missing endpoint.
|
|
16
|
+
* nodeCount/edgeCount/nodeTypes report true store totals — including isolated
|
|
17
|
+
* entities the connected projection doesn't render — while nodes/edges are the
|
|
18
|
+
* rendered projection.
|
|
19
|
+
*/
|
|
12
20
|
declare function useKnowledgeGraph(serverUrl: string, opts?: UseKnowledgeGraphOptions): HookResult<GraphVizData>;
|
|
13
21
|
|
|
14
22
|
declare function useMemoryEntries(serverUrl: string, filters?: EntryFilters, intervalMs?: number): HookResult<PaginatedEntries>;
|
package/dist/react.mjs
CHANGED
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
toGraphologyFormat,
|
|
12
12
|
transformGraphData,
|
|
13
13
|
unreachableHealth
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
14
|
+
} from "./chunk-DEMDFWI4.mjs";
|
|
15
|
+
import "./chunk-EXUSQ2GR.mjs";
|
|
16
16
|
import "./chunk-KSTI4M52.mjs";
|
|
17
17
|
|
|
18
18
|
// ../dashboard/src/hooks/use-consolidation-log.ts
|
|
@@ -75,16 +75,22 @@ function useConsolidationLog(serverUrl, limit = 20, intervalMs = DEFAULT_POLL_IN
|
|
|
75
75
|
// ../dashboard/src/hooks/use-knowledge-graph.ts
|
|
76
76
|
import { useCallback as useCallback3, useMemo as useMemo2 } from "react";
|
|
77
77
|
function useKnowledgeGraph(serverUrl, opts = {}) {
|
|
78
|
-
const { intervalMs = DEFAULT_POLL_INTERVAL_MS,
|
|
78
|
+
const { intervalMs = DEFAULT_POLL_INTERVAL_MS, edges, minWeight, maxNodes } = opts;
|
|
79
79
|
const client = useMemo2(() => new DashboardClient(serverUrl), [serverUrl]);
|
|
80
80
|
const stableTransformOpts = useMemo2(
|
|
81
81
|
() => ({ minWeight, maxNodes }),
|
|
82
82
|
[minWeight, maxNodes]
|
|
83
83
|
);
|
|
84
84
|
const fetcher = useCallback3(async () => {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
const subgraph = await client.graphSubgraph(edges);
|
|
86
|
+
const viz = transformGraphData(subgraph.nodes, subgraph.relationships, stableTransformOpts);
|
|
87
|
+
return {
|
|
88
|
+
...viz,
|
|
89
|
+
nodeCount: subgraph.totalNodes,
|
|
90
|
+
edgeCount: subgraph.totalEdges,
|
|
91
|
+
nodeTypes: subgraph.categoryTotals
|
|
92
|
+
};
|
|
93
|
+
}, [client, edges, stableTransformOpts]);
|
|
88
94
|
return usePolling(fetcher, { intervalMs });
|
|
89
95
|
}
|
|
90
96
|
|