comemo 1.0.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/README.md +148 -0
- package/dist/client.d.ts +121 -0
- package/dist/client.js +329 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.js +47 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +11 -0
- package/dist/types.d.ts +113 -0
- package/dist/types.js +2 -0
- package/package.json +28 -0
package/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# CoMemo SDK
|
|
2
|
+
|
|
3
|
+
Node.js SDK for CoMemo — a multi-module hybrid memory system powered by Pinecone and Neo4j.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install comemo
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
Each client requires your own infrastructure credentials. All operations use your own Pinecone index, Neo4j database, and LLM API key.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { MemoryClient } from "comemo";
|
|
17
|
+
|
|
18
|
+
const client = new MemoryClient({
|
|
19
|
+
llmApiKey: "sk-your-openai-key",
|
|
20
|
+
model: "gpt-4o-mini",
|
|
21
|
+
pineconeApiKey: "pc-...",
|
|
22
|
+
pineconeIndex: "my-memory-index",
|
|
23
|
+
neo4jUri: "neo4j+s://xxx.databases.neo4j.io",
|
|
24
|
+
neo4jUsername: "neo4j",
|
|
25
|
+
neo4jPassword: "...",
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Optional fields:
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
const client = new MemoryClient({
|
|
33
|
+
...,
|
|
34
|
+
pineconeNamespace: "tenant-a", // Multi-tenant within one Pinecone index
|
|
35
|
+
neo4jDatabase: "mydb", // Neo4j database name (defaults to "neo4j")
|
|
36
|
+
baseUrl: "https://xvert.io", // API base URL
|
|
37
|
+
timeout: 30000, // Request timeout in ms
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Core Memory
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
// Add a memory
|
|
45
|
+
const result = await client.addMemory("john", "chat_01", "I work at Google as a software engineer");
|
|
46
|
+
console.log(result.status); // "success"
|
|
47
|
+
console.log(result.action); // "NEW"
|
|
48
|
+
console.log(result.memory_id); // "mem_abc123"
|
|
49
|
+
|
|
50
|
+
// Delete all user memories
|
|
51
|
+
await client.deleteUserMemories("john");
|
|
52
|
+
|
|
53
|
+
// Delete session memories
|
|
54
|
+
await client.deleteSessionMemories("john", "chat_01");
|
|
55
|
+
|
|
56
|
+
// Delete a single memory
|
|
57
|
+
await client.deleteMemory("mem_abc123");
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Retrieval
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
// Simple retrieve
|
|
64
|
+
const simple = await client.retrieve("john", "chat_01", "Where does John work?", 5);
|
|
65
|
+
for (const m of simple.memories) {
|
|
66
|
+
console.log(`${m.fact} (score: ${m.score})`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Advanced retrieve with full scoring breakdown
|
|
70
|
+
const result = await client.retrieveAdvanced("john", "chat_01", "career and hobbies", {
|
|
71
|
+
topK: 10,
|
|
72
|
+
expandContext: true,
|
|
73
|
+
expandGraph: true,
|
|
74
|
+
minScore: 0.3,
|
|
75
|
+
reinforce: true,
|
|
76
|
+
});
|
|
77
|
+
for (const m of result.memories) {
|
|
78
|
+
console.log(`${m.fact} | semantic=${m.semantic_similarity} graph=${m.graph_relevance}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// List memories across all sessions
|
|
82
|
+
const list = await client.listMemories("john", "work", 10);
|
|
83
|
+
|
|
84
|
+
// Retrieve with LLM summary
|
|
85
|
+
const summary = await client.retrieveSummary("john", "chat_01", "Tell me about John's career");
|
|
86
|
+
console.log(summary.summary);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Maintenance
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
// Run maintenance tasks (decay, forgetting, summarization)
|
|
93
|
+
const result = await client.runMaintenance("john");
|
|
94
|
+
|
|
95
|
+
// Selective tasks
|
|
96
|
+
const result = await client.runMaintenance("john", {
|
|
97
|
+
decay: true,
|
|
98
|
+
forgetting: true,
|
|
99
|
+
summarization: false,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Dry run
|
|
103
|
+
const result = await client.runMaintenance("john", undefined, true);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### System
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
const health = await client.health();
|
|
110
|
+
console.log(health.status); // "healthy"
|
|
111
|
+
console.log(health.version); // "6.0.0"
|
|
112
|
+
console.log(health.architecture); // "Multi-Module Hybrid Memory (Multi-Tenant)"
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Error Handling
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import { MemoryClient, ValidationError, NotFoundError } from "comemo";
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
await client.retrieve("john", "chat_01", "");
|
|
122
|
+
} catch (e) {
|
|
123
|
+
if (e instanceof ValidationError) {
|
|
124
|
+
console.log(`Bad request: ${e.message}`);
|
|
125
|
+
} else if (e instanceof NotFoundError) {
|
|
126
|
+
console.log(`Not found: ${e.message}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## All Methods
|
|
132
|
+
|
|
133
|
+
| Method | Description |
|
|
134
|
+
|---|---|
|
|
135
|
+
| `addMemory(userId, sessionId, text)` | Extract facts and store as memories |
|
|
136
|
+
| `deleteMemory(memoryId)` | Delete a single memory |
|
|
137
|
+
| `deleteUserMemories(userId)` | Delete all memories for a user |
|
|
138
|
+
| `deleteSessionMemories(userId, sessionId)` | Delete all memories for a session |
|
|
139
|
+
| `retrieve(userId, sessionId, query, topK?)` | Simple retrieval |
|
|
140
|
+
| `retrieveAdvanced(userId, sessionId, query, options?)` | Advanced retrieval with scoring |
|
|
141
|
+
| `listMemories(userId, query, topK?)` | List memories across sessions |
|
|
142
|
+
| `retrieveSummary(userId, sessionId, query, topK?)` | Retrieve with LLM summary |
|
|
143
|
+
| `runMaintenance(userId, tasks?, dryRun?)` | Run tenant-scoped maintenance |
|
|
144
|
+
| `health()` | Health check |
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
|
|
148
|
+
MIT
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type { AddMemoryResult, DeleteResult, DetailedRetrieveResult, HealthResult, MaintenanceResult, MaintenanceTaskOptions, MemoryClientOptions, RetrieveAdvancedOptions, RetrieveResult, RetrieveSummaryResult } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Client for the CogMemo API.
|
|
4
|
+
*
|
|
5
|
+
* Each client instance represents a single tenant with its own infrastructure
|
|
6
|
+
* credentials. All operations are scoped to the tenant's own Pinecone index,
|
|
7
|
+
* Neo4j database, and LLM API key.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const client = new MemoryClient({
|
|
12
|
+
* llmApiKey: "sk-your-openai-key",
|
|
13
|
+
* model: "gpt-4o-mini",
|
|
14
|
+
* pineconeApiKey: "pc-...",
|
|
15
|
+
* pineconeIndex: "user-memory-index",
|
|
16
|
+
* neo4jUri: "neo4j+s://xxx.databases.neo4j.io",
|
|
17
|
+
* neo4jUsername: "neo4j",
|
|
18
|
+
* neo4jPassword: "...",
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* await client.addMemory("john", "chat_01", "I work at Google");
|
|
22
|
+
* const result = await client.retrieve("john", "chat_01", "Where does John work?");
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare class MemoryClient {
|
|
26
|
+
private baseUrl;
|
|
27
|
+
private timeout;
|
|
28
|
+
private config;
|
|
29
|
+
/**
|
|
30
|
+
* Create a new MemoryClient.
|
|
31
|
+
*
|
|
32
|
+
* @param options - Client configuration options including tenant credentials.
|
|
33
|
+
*/
|
|
34
|
+
constructor(options: MemoryClientOptions);
|
|
35
|
+
private request;
|
|
36
|
+
/**
|
|
37
|
+
* Extract facts from text and store them as memories.
|
|
38
|
+
*
|
|
39
|
+
* @param userId - User ID for memory isolation.
|
|
40
|
+
* @param sessionId - Session ID for context grouping.
|
|
41
|
+
* @param text - Input text to extract facts from.
|
|
42
|
+
* @returns Result with status, action, memory_id, links_created, and score.
|
|
43
|
+
*/
|
|
44
|
+
addMemory(userId: string, sessionId: string, text: string): Promise<AddMemoryResult>;
|
|
45
|
+
/**
|
|
46
|
+
* Delete a single memory by ID.
|
|
47
|
+
*
|
|
48
|
+
* @param memoryId - The memory identifier to delete.
|
|
49
|
+
* @returns Object with status, memory_id, and deleted flag.
|
|
50
|
+
*/
|
|
51
|
+
deleteMemory(memoryId: string): Promise<Record<string, unknown>>;
|
|
52
|
+
/**
|
|
53
|
+
* Delete all memories for a user.
|
|
54
|
+
*
|
|
55
|
+
* @param userId - The user whose memories to delete.
|
|
56
|
+
* @returns DeleteResult with count of deleted memories.
|
|
57
|
+
*/
|
|
58
|
+
deleteUserMemories(userId: string): Promise<DeleteResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Delete all memories for a specific session.
|
|
61
|
+
*
|
|
62
|
+
* @param userId - The user ID.
|
|
63
|
+
* @param sessionId - The session whose memories to delete.
|
|
64
|
+
* @returns DeleteResult with count of deleted memories.
|
|
65
|
+
*/
|
|
66
|
+
deleteSessionMemories(userId: string, sessionId: string): Promise<DeleteResult>;
|
|
67
|
+
/**
|
|
68
|
+
* Retrieve top memories matching a query (simple mode).
|
|
69
|
+
*
|
|
70
|
+
* @param userId - User ID for namespace isolation.
|
|
71
|
+
* @param sessionId - Current session ID.
|
|
72
|
+
* @param query - Search query text.
|
|
73
|
+
* @param topK - Maximum number of results (1-50). Defaults to 5.
|
|
74
|
+
* @returns RetrieveResult with query, expanded query, and list of memories.
|
|
75
|
+
*/
|
|
76
|
+
retrieve(userId: string, sessionId: string, query: string, topK?: number): Promise<RetrieveResult>;
|
|
77
|
+
/**
|
|
78
|
+
* Retrieve memories with full scoring details and advanced options.
|
|
79
|
+
*
|
|
80
|
+
* @param userId - User ID for namespace isolation.
|
|
81
|
+
* @param sessionId - Current session ID.
|
|
82
|
+
* @param query - Search query text.
|
|
83
|
+
* @param options - Advanced retrieval options.
|
|
84
|
+
* @returns DetailedRetrieveResult with full scoring breakdown per memory.
|
|
85
|
+
*/
|
|
86
|
+
retrieveAdvanced(userId: string, sessionId: string, query: string, options?: RetrieveAdvancedOptions): Promise<DetailedRetrieveResult>;
|
|
87
|
+
/**
|
|
88
|
+
* Retrieve memories and get an LLM-generated summary.
|
|
89
|
+
*
|
|
90
|
+
* @param userId - User ID for namespace isolation.
|
|
91
|
+
* @param sessionId - Current session ID.
|
|
92
|
+
* @param query - Search query text.
|
|
93
|
+
* @param topK - Number of memories to summarize (1-20). Defaults to 5.
|
|
94
|
+
* @returns RetrieveSummaryResult with summary text and supporting memories.
|
|
95
|
+
*/
|
|
96
|
+
retrieveSummary(userId: string, sessionId: string, query: string, topK?: number): Promise<RetrieveSummaryResult>;
|
|
97
|
+
/**
|
|
98
|
+
* List user memories across all sessions.
|
|
99
|
+
*
|
|
100
|
+
* @param userId - User ID.
|
|
101
|
+
* @param query - Search query text.
|
|
102
|
+
* @param topK - Maximum number of results (1-50). Defaults to 10.
|
|
103
|
+
* @returns RetrieveResult with matching memories across all sessions.
|
|
104
|
+
*/
|
|
105
|
+
listMemories(userId: string, query: string, topK?: number): Promise<RetrieveResult>;
|
|
106
|
+
/**
|
|
107
|
+
* Run tenant-scoped maintenance tasks for a user.
|
|
108
|
+
*
|
|
109
|
+
* @param userId - User ID to scope maintenance to (required).
|
|
110
|
+
* @param tasks - Which tasks to run. Defaults to decay + forgetting + summarization.
|
|
111
|
+
* @param dryRun - If true, only identify but don't modify memories.
|
|
112
|
+
* @returns MaintenanceResult with per-task results.
|
|
113
|
+
*/
|
|
114
|
+
runMaintenance(userId: string, tasks?: MaintenanceTaskOptions, dryRun?: boolean): Promise<MaintenanceResult>;
|
|
115
|
+
/**
|
|
116
|
+
* Check API health and status.
|
|
117
|
+
*
|
|
118
|
+
* @returns HealthResult with status, version, and architecture.
|
|
119
|
+
*/
|
|
120
|
+
health(): Promise<HealthResult>;
|
|
121
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MemoryClient = void 0;
|
|
4
|
+
const errors_1 = require("./errors");
|
|
5
|
+
/**
|
|
6
|
+
* Client for the CogMemo API.
|
|
7
|
+
*
|
|
8
|
+
* Each client instance represents a single tenant with its own infrastructure
|
|
9
|
+
* credentials. All operations are scoped to the tenant's own Pinecone index,
|
|
10
|
+
* Neo4j database, and LLM API key.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const client = new MemoryClient({
|
|
15
|
+
* llmApiKey: "sk-your-openai-key",
|
|
16
|
+
* model: "gpt-4o-mini",
|
|
17
|
+
* pineconeApiKey: "pc-...",
|
|
18
|
+
* pineconeIndex: "user-memory-index",
|
|
19
|
+
* neo4jUri: "neo4j+s://xxx.databases.neo4j.io",
|
|
20
|
+
* neo4jUsername: "neo4j",
|
|
21
|
+
* neo4jPassword: "...",
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* await client.addMemory("john", "chat_01", "I work at Google");
|
|
25
|
+
* const result = await client.retrieve("john", "chat_01", "Where does John work?");
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
class MemoryClient {
|
|
29
|
+
baseUrl;
|
|
30
|
+
timeout;
|
|
31
|
+
config;
|
|
32
|
+
/**
|
|
33
|
+
* Create a new MemoryClient.
|
|
34
|
+
*
|
|
35
|
+
* @param options - Client configuration options including tenant credentials.
|
|
36
|
+
*/
|
|
37
|
+
constructor(options) {
|
|
38
|
+
this.baseUrl = (options.baseUrl ?? "https://xvert.io").replace(/\/+$/, "");
|
|
39
|
+
this.timeout = options.timeout ?? 30000;
|
|
40
|
+
// Tenant config sent with every request
|
|
41
|
+
const cfg = {
|
|
42
|
+
llm_api_key: options.llmApiKey,
|
|
43
|
+
model: options.model ?? "gpt-4o-mini",
|
|
44
|
+
pinecone_api_key: options.pineconeApiKey,
|
|
45
|
+
pinecone_index: options.pineconeIndex,
|
|
46
|
+
neo4j_uri: options.neo4jUri,
|
|
47
|
+
neo4j_username: options.neo4jUsername,
|
|
48
|
+
neo4j_password: options.neo4jPassword,
|
|
49
|
+
};
|
|
50
|
+
if (options.pineconeNamespace)
|
|
51
|
+
cfg.pinecone_namespace = options.pineconeNamespace;
|
|
52
|
+
if (options.neo4jDatabase)
|
|
53
|
+
cfg.neo4j_database = options.neo4jDatabase;
|
|
54
|
+
this.config = cfg;
|
|
55
|
+
}
|
|
56
|
+
async request(method, path, options = {}) {
|
|
57
|
+
let url = `${this.baseUrl}${path}`;
|
|
58
|
+
if (options.params) {
|
|
59
|
+
const search = new URLSearchParams();
|
|
60
|
+
for (const [key, value] of Object.entries(options.params)) {
|
|
61
|
+
search.set(key, String(value));
|
|
62
|
+
}
|
|
63
|
+
url += `?${search.toString()}`;
|
|
64
|
+
}
|
|
65
|
+
const controller = new AbortController();
|
|
66
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
67
|
+
try {
|
|
68
|
+
const fetchOptions = {
|
|
69
|
+
method,
|
|
70
|
+
headers: { "Content-Type": "application/json" },
|
|
71
|
+
signal: controller.signal,
|
|
72
|
+
};
|
|
73
|
+
if (options.body) {
|
|
74
|
+
fetchOptions.body = JSON.stringify(options.body);
|
|
75
|
+
}
|
|
76
|
+
const response = await fetch(url, fetchOptions);
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
let detail;
|
|
79
|
+
try {
|
|
80
|
+
const body = (await response.json());
|
|
81
|
+
detail = body.detail ?? response.statusText;
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
detail = response.statusText;
|
|
85
|
+
}
|
|
86
|
+
if (response.status === 401 || response.status === 403) {
|
|
87
|
+
throw new errors_1.AuthenticationError(detail, response.status);
|
|
88
|
+
}
|
|
89
|
+
if (response.status === 404) {
|
|
90
|
+
throw new errors_1.NotFoundError(detail, response.status);
|
|
91
|
+
}
|
|
92
|
+
if (response.status === 400 || response.status === 422) {
|
|
93
|
+
throw new errors_1.ValidationError(detail, response.status);
|
|
94
|
+
}
|
|
95
|
+
if (response.status >= 500) {
|
|
96
|
+
throw new errors_1.ServerError(detail, response.status);
|
|
97
|
+
}
|
|
98
|
+
throw new errors_1.ComemoError(detail, response.status);
|
|
99
|
+
}
|
|
100
|
+
return (await response.json());
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
clearTimeout(timer);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// ── Core Memory Operations ──────────────────────────────────────────
|
|
107
|
+
/**
|
|
108
|
+
* Extract facts from text and store them as memories.
|
|
109
|
+
*
|
|
110
|
+
* @param userId - User ID for memory isolation.
|
|
111
|
+
* @param sessionId - Session ID for context grouping.
|
|
112
|
+
* @param text - Input text to extract facts from.
|
|
113
|
+
* @returns Result with status, action, memory_id, links_created, and score.
|
|
114
|
+
*/
|
|
115
|
+
async addMemory(userId, sessionId, text) {
|
|
116
|
+
const data = await this.request("POST", "/memory", {
|
|
117
|
+
body: { user_id: userId, session_id: sessionId, input: text, config: this.config },
|
|
118
|
+
});
|
|
119
|
+
return {
|
|
120
|
+
status: data.status ?? "",
|
|
121
|
+
action: data.action ?? "",
|
|
122
|
+
memory_id: data.memory_id ?? null,
|
|
123
|
+
links_created: data.links_created ?? 0,
|
|
124
|
+
score: data.score ?? 0,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Delete a single memory by ID.
|
|
129
|
+
*
|
|
130
|
+
* @param memoryId - The memory identifier to delete.
|
|
131
|
+
* @returns Object with status, memory_id, and deleted flag.
|
|
132
|
+
*/
|
|
133
|
+
async deleteMemory(memoryId) {
|
|
134
|
+
return this.request("DELETE", `/memory/${memoryId}`, { params: {} });
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Delete all memories for a user.
|
|
138
|
+
*
|
|
139
|
+
* @param userId - The user whose memories to delete.
|
|
140
|
+
* @returns DeleteResult with count of deleted memories.
|
|
141
|
+
*/
|
|
142
|
+
async deleteUserMemories(userId) {
|
|
143
|
+
const data = await this.request("DELETE", "/memory", {
|
|
144
|
+
params: { user_id: userId },
|
|
145
|
+
});
|
|
146
|
+
return {
|
|
147
|
+
status: data.status ?? "",
|
|
148
|
+
user_id: data.user_id ?? userId,
|
|
149
|
+
memories_deleted: data.memories_deleted ?? 0,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Delete all memories for a specific session.
|
|
154
|
+
*
|
|
155
|
+
* @param userId - The user ID.
|
|
156
|
+
* @param sessionId - The session whose memories to delete.
|
|
157
|
+
* @returns DeleteResult with count of deleted memories.
|
|
158
|
+
*/
|
|
159
|
+
async deleteSessionMemories(userId, sessionId) {
|
|
160
|
+
const data = await this.request("DELETE", `/memory/session/${sessionId}`, {
|
|
161
|
+
params: { user_id: userId },
|
|
162
|
+
});
|
|
163
|
+
return {
|
|
164
|
+
status: data.status ?? "",
|
|
165
|
+
user_id: data.user_id ?? userId,
|
|
166
|
+
memories_deleted: data.memories_deleted ?? 0,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
// ── Retrieval ───────────────────────────────────────────────────────
|
|
170
|
+
/**
|
|
171
|
+
* Retrieve top memories matching a query (simple mode).
|
|
172
|
+
*
|
|
173
|
+
* @param userId - User ID for namespace isolation.
|
|
174
|
+
* @param sessionId - Current session ID.
|
|
175
|
+
* @param query - Search query text.
|
|
176
|
+
* @param topK - Maximum number of results (1-50). Defaults to 5.
|
|
177
|
+
* @returns RetrieveResult with query, expanded query, and list of memories.
|
|
178
|
+
*/
|
|
179
|
+
async retrieve(userId, sessionId, query, topK = 5) {
|
|
180
|
+
const data = await this.request("POST", "/memories/retrieve", {
|
|
181
|
+
body: { user_id: userId, session_id: sessionId, query, top_k: topK, config: this.config },
|
|
182
|
+
});
|
|
183
|
+
const memories = (data.memories ?? []).map((m) => ({
|
|
184
|
+
memory_id: m.memory_id,
|
|
185
|
+
fact: m.fact,
|
|
186
|
+
score: m.score,
|
|
187
|
+
}));
|
|
188
|
+
return {
|
|
189
|
+
query: data.query ?? query,
|
|
190
|
+
expanded_query: data.expanded_query ?? "",
|
|
191
|
+
memories,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Retrieve memories with full scoring details and advanced options.
|
|
196
|
+
*
|
|
197
|
+
* @param userId - User ID for namespace isolation.
|
|
198
|
+
* @param sessionId - Current session ID.
|
|
199
|
+
* @param query - Search query text.
|
|
200
|
+
* @param options - Advanced retrieval options.
|
|
201
|
+
* @returns DetailedRetrieveResult with full scoring breakdown per memory.
|
|
202
|
+
*/
|
|
203
|
+
async retrieveAdvanced(userId, sessionId, query, options = {}) {
|
|
204
|
+
const data = await this.request("POST", "/memory/retrieve", {
|
|
205
|
+
body: {
|
|
206
|
+
user_id: userId,
|
|
207
|
+
session_id: sessionId,
|
|
208
|
+
query,
|
|
209
|
+
top_k: options.topK ?? 10,
|
|
210
|
+
expand_context: options.expandContext ?? true,
|
|
211
|
+
expand_graph: options.expandGraph ?? true,
|
|
212
|
+
min_score: options.minScore ?? 0.1,
|
|
213
|
+
reinforce: options.reinforce ?? false,
|
|
214
|
+
config: this.config,
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
const memories = (data.memories ?? []).map((m) => ({
|
|
218
|
+
memory_id: m.memory_id,
|
|
219
|
+
fact: m.fact,
|
|
220
|
+
domain: m.domain ?? "",
|
|
221
|
+
final_score: m.final_score ?? 0,
|
|
222
|
+
semantic_similarity: m.semantic_similarity ?? 0,
|
|
223
|
+
graph_relevance: m.graph_relevance ?? 0,
|
|
224
|
+
memory_strength: m.memory_strength ?? 0,
|
|
225
|
+
recency_score: m.recency_score ?? 0,
|
|
226
|
+
session_boost: m.session_boost ?? 0,
|
|
227
|
+
source: m.source ?? "",
|
|
228
|
+
session_id: m.session_id ?? "",
|
|
229
|
+
}));
|
|
230
|
+
return {
|
|
231
|
+
query: data.query ?? query,
|
|
232
|
+
expanded_query: data.expanded_query ?? "",
|
|
233
|
+
user_id: data.user_id ?? userId,
|
|
234
|
+
session_id: data.session_id ?? sessionId,
|
|
235
|
+
memories,
|
|
236
|
+
total_candidates: data.total_candidates ?? 0,
|
|
237
|
+
filtered_count: data.filtered_count ?? 0,
|
|
238
|
+
retrieval_time_ms: data.retrieval_time_ms ?? 0,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Retrieve memories and get an LLM-generated summary.
|
|
243
|
+
*
|
|
244
|
+
* @param userId - User ID for namespace isolation.
|
|
245
|
+
* @param sessionId - Current session ID.
|
|
246
|
+
* @param query - Search query text.
|
|
247
|
+
* @param topK - Number of memories to summarize (1-20). Defaults to 5.
|
|
248
|
+
* @returns RetrieveSummaryResult with summary text and supporting memories.
|
|
249
|
+
*/
|
|
250
|
+
async retrieveSummary(userId, sessionId, query, topK = 5) {
|
|
251
|
+
const data = await this.request("POST", "/memories/retrieve-summary", {
|
|
252
|
+
body: { user_id: userId, session_id: sessionId, query, top_k: topK, config: this.config },
|
|
253
|
+
});
|
|
254
|
+
const memories = (data.supporting_memories ?? []).map((m) => ({
|
|
255
|
+
memory_id: m.memory_id,
|
|
256
|
+
fact: m.fact,
|
|
257
|
+
score: m.score,
|
|
258
|
+
}));
|
|
259
|
+
return {
|
|
260
|
+
query: data.query ?? query,
|
|
261
|
+
summary: data.summary ?? "",
|
|
262
|
+
supporting_memories: memories,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* List user memories across all sessions.
|
|
267
|
+
*
|
|
268
|
+
* @param userId - User ID.
|
|
269
|
+
* @param query - Search query text.
|
|
270
|
+
* @param topK - Maximum number of results (1-50). Defaults to 10.
|
|
271
|
+
* @returns RetrieveResult with matching memories across all sessions.
|
|
272
|
+
*/
|
|
273
|
+
async listMemories(userId, query, topK = 10) {
|
|
274
|
+
const data = await this.request("GET", "/memories", {
|
|
275
|
+
params: { user_id: userId, query, top_k: topK },
|
|
276
|
+
});
|
|
277
|
+
const memories = (data.memories ?? []).map((m) => ({
|
|
278
|
+
memory_id: m.memory_id,
|
|
279
|
+
fact: m.fact,
|
|
280
|
+
score: m.score,
|
|
281
|
+
}));
|
|
282
|
+
return {
|
|
283
|
+
query: data.query ?? query,
|
|
284
|
+
expanded_query: data.expanded_query ?? "",
|
|
285
|
+
memories,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
// ── Maintenance ────────────────────────────────────────────────────
|
|
289
|
+
/**
|
|
290
|
+
* Run tenant-scoped maintenance tasks for a user.
|
|
291
|
+
*
|
|
292
|
+
* @param userId - User ID to scope maintenance to (required).
|
|
293
|
+
* @param tasks - Which tasks to run. Defaults to decay + forgetting + summarization.
|
|
294
|
+
* @param dryRun - If true, only identify but don't modify memories.
|
|
295
|
+
* @returns MaintenanceResult with per-task results.
|
|
296
|
+
*/
|
|
297
|
+
async runMaintenance(userId, tasks, dryRun = false) {
|
|
298
|
+
const body = {
|
|
299
|
+
user_id: userId,
|
|
300
|
+
config: this.config,
|
|
301
|
+
dry_run: dryRun,
|
|
302
|
+
};
|
|
303
|
+
if (tasks) {
|
|
304
|
+
body.tasks = tasks;
|
|
305
|
+
}
|
|
306
|
+
const data = await this.request("POST", "/memory/maintenance", { body });
|
|
307
|
+
return {
|
|
308
|
+
status: data.status ?? "",
|
|
309
|
+
user_id: data.user_id ?? userId,
|
|
310
|
+
dry_run: data.dry_run ?? dryRun,
|
|
311
|
+
results: data.results ?? {},
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
// ── System ──────────────────────────────────────────────────────────
|
|
315
|
+
/**
|
|
316
|
+
* Check API health and status.
|
|
317
|
+
*
|
|
318
|
+
* @returns HealthResult with status, version, and architecture.
|
|
319
|
+
*/
|
|
320
|
+
async health() {
|
|
321
|
+
const data = await this.request("GET", "/health");
|
|
322
|
+
return {
|
|
323
|
+
status: data.status ?? "",
|
|
324
|
+
version: data.version ?? "",
|
|
325
|
+
architecture: data.architecture ?? "",
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
exports.MemoryClient = MemoryClient;
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Base exception for all SDK errors. */
|
|
2
|
+
export declare class ComemoError extends Error {
|
|
3
|
+
statusCode: number | undefined;
|
|
4
|
+
response: Record<string, unknown> | undefined;
|
|
5
|
+
constructor(message: string, statusCode?: number, response?: Record<string, unknown>);
|
|
6
|
+
}
|
|
7
|
+
/** Raised when authentication fails (401/403). */
|
|
8
|
+
export declare class AuthenticationError extends ComemoError {
|
|
9
|
+
constructor(message: string, statusCode?: number, response?: Record<string, unknown>);
|
|
10
|
+
}
|
|
11
|
+
/** Raised when a resource is not found (404). */
|
|
12
|
+
export declare class NotFoundError extends ComemoError {
|
|
13
|
+
constructor(message: string, statusCode?: number, response?: Record<string, unknown>);
|
|
14
|
+
}
|
|
15
|
+
/** Raised when the request is invalid (400/422). */
|
|
16
|
+
export declare class ValidationError extends ComemoError {
|
|
17
|
+
constructor(message: string, statusCode?: number, response?: Record<string, unknown>);
|
|
18
|
+
}
|
|
19
|
+
/** Raised when the server returns a 5xx error. */
|
|
20
|
+
export declare class ServerError extends ComemoError {
|
|
21
|
+
constructor(message: string, statusCode?: number, response?: Record<string, unknown>);
|
|
22
|
+
}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ServerError = exports.ValidationError = exports.NotFoundError = exports.AuthenticationError = exports.ComemoError = void 0;
|
|
4
|
+
/** Base exception for all SDK errors. */
|
|
5
|
+
class ComemoError extends Error {
|
|
6
|
+
statusCode;
|
|
7
|
+
response;
|
|
8
|
+
constructor(message, statusCode, response) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "ComemoError";
|
|
11
|
+
this.statusCode = statusCode;
|
|
12
|
+
this.response = response;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.ComemoError = ComemoError;
|
|
16
|
+
/** Raised when authentication fails (401/403). */
|
|
17
|
+
class AuthenticationError extends ComemoError {
|
|
18
|
+
constructor(message, statusCode, response) {
|
|
19
|
+
super(message, statusCode, response);
|
|
20
|
+
this.name = "AuthenticationError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.AuthenticationError = AuthenticationError;
|
|
24
|
+
/** Raised when a resource is not found (404). */
|
|
25
|
+
class NotFoundError extends ComemoError {
|
|
26
|
+
constructor(message, statusCode, response) {
|
|
27
|
+
super(message, statusCode, response);
|
|
28
|
+
this.name = "NotFoundError";
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.NotFoundError = NotFoundError;
|
|
32
|
+
/** Raised when the request is invalid (400/422). */
|
|
33
|
+
class ValidationError extends ComemoError {
|
|
34
|
+
constructor(message, statusCode, response) {
|
|
35
|
+
super(message, statusCode, response);
|
|
36
|
+
this.name = "ValidationError";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.ValidationError = ValidationError;
|
|
40
|
+
/** Raised when the server returns a 5xx error. */
|
|
41
|
+
class ServerError extends ComemoError {
|
|
42
|
+
constructor(message, statusCode, response) {
|
|
43
|
+
super(message, statusCode, response);
|
|
44
|
+
this.name = "ServerError";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.ServerError = ServerError;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { MemoryClient } from "./client";
|
|
2
|
+
export type { TenantConfig, AddMemoryResult, Memory, DetailedMemory, RetrieveResult, DetailedRetrieveResult, RetrieveSummaryResult, DeleteResult, MaintenanceResult, HealthResult, MemoryClientOptions, RetrieveAdvancedOptions, MaintenanceTaskOptions, } from "./types";
|
|
3
|
+
export { ComemoError, AuthenticationError, NotFoundError, ValidationError, ServerError, } from "./errors";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ServerError = exports.ValidationError = exports.NotFoundError = exports.AuthenticationError = exports.ComemoError = exports.MemoryClient = void 0;
|
|
4
|
+
var client_1 = require("./client");
|
|
5
|
+
Object.defineProperty(exports, "MemoryClient", { enumerable: true, get: function () { return client_1.MemoryClient; } });
|
|
6
|
+
var errors_1 = require("./errors");
|
|
7
|
+
Object.defineProperty(exports, "ComemoError", { enumerable: true, get: function () { return errors_1.ComemoError; } });
|
|
8
|
+
Object.defineProperty(exports, "AuthenticationError", { enumerable: true, get: function () { return errors_1.AuthenticationError; } });
|
|
9
|
+
Object.defineProperty(exports, "NotFoundError", { enumerable: true, get: function () { return errors_1.NotFoundError; } });
|
|
10
|
+
Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return errors_1.ValidationError; } });
|
|
11
|
+
Object.defineProperty(exports, "ServerError", { enumerable: true, get: function () { return errors_1.ServerError; } });
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/** Per-tenant infrastructure configuration. */
|
|
2
|
+
export interface TenantConfig {
|
|
3
|
+
/** LLM API key (e.g. OpenAI key). */
|
|
4
|
+
llmApiKey: string;
|
|
5
|
+
/** LLM model name (e.g. "gpt-4o-mini"). */
|
|
6
|
+
model?: string;
|
|
7
|
+
/** Pinecone API key. */
|
|
8
|
+
pineconeApiKey: string;
|
|
9
|
+
/** Pinecone index name. */
|
|
10
|
+
pineconeIndex: string;
|
|
11
|
+
/** Pinecone namespace (for multi-tenant within one index). */
|
|
12
|
+
pineconeNamespace?: string;
|
|
13
|
+
/** Neo4j connection URI (e.g. "neo4j+s://xxx.databases.neo4j.io"). */
|
|
14
|
+
neo4jUri: string;
|
|
15
|
+
/** Neo4j username. */
|
|
16
|
+
neo4jUsername: string;
|
|
17
|
+
/** Neo4j password. */
|
|
18
|
+
neo4jPassword: string;
|
|
19
|
+
/** Neo4j database name (defaults to "neo4j"). */
|
|
20
|
+
neo4jDatabase?: string;
|
|
21
|
+
}
|
|
22
|
+
/** Result of adding a memory. */
|
|
23
|
+
export interface AddMemoryResult {
|
|
24
|
+
status: string;
|
|
25
|
+
action: string;
|
|
26
|
+
memory_id: string | null;
|
|
27
|
+
links_created: number;
|
|
28
|
+
score: number;
|
|
29
|
+
}
|
|
30
|
+
/** A retrieved memory. */
|
|
31
|
+
export interface Memory {
|
|
32
|
+
memory_id: string;
|
|
33
|
+
fact: string;
|
|
34
|
+
score: number;
|
|
35
|
+
}
|
|
36
|
+
/** A retrieved memory with detailed scoring breakdown. */
|
|
37
|
+
export interface DetailedMemory {
|
|
38
|
+
memory_id: string;
|
|
39
|
+
fact: string;
|
|
40
|
+
domain: string;
|
|
41
|
+
final_score: number;
|
|
42
|
+
semantic_similarity: number;
|
|
43
|
+
graph_relevance: number;
|
|
44
|
+
memory_strength: number;
|
|
45
|
+
recency_score: number;
|
|
46
|
+
session_boost: number;
|
|
47
|
+
source: string;
|
|
48
|
+
session_id: string;
|
|
49
|
+
}
|
|
50
|
+
/** Result of a simple retrieval. */
|
|
51
|
+
export interface RetrieveResult {
|
|
52
|
+
query: string;
|
|
53
|
+
expanded_query: string;
|
|
54
|
+
memories: Memory[];
|
|
55
|
+
}
|
|
56
|
+
/** Result of an advanced retrieval with full scoring details. */
|
|
57
|
+
export interface DetailedRetrieveResult {
|
|
58
|
+
query: string;
|
|
59
|
+
expanded_query: string;
|
|
60
|
+
user_id: string;
|
|
61
|
+
session_id: string;
|
|
62
|
+
memories: DetailedMemory[];
|
|
63
|
+
total_candidates: number;
|
|
64
|
+
filtered_count: number;
|
|
65
|
+
retrieval_time_ms: number;
|
|
66
|
+
}
|
|
67
|
+
/** Result of a retrieval with LLM summary. */
|
|
68
|
+
export interface RetrieveSummaryResult {
|
|
69
|
+
query: string;
|
|
70
|
+
summary: string;
|
|
71
|
+
supporting_memories: Memory[];
|
|
72
|
+
}
|
|
73
|
+
/** Result of a delete operation. */
|
|
74
|
+
export interface DeleteResult {
|
|
75
|
+
status: string;
|
|
76
|
+
user_id: string;
|
|
77
|
+
memories_deleted: number;
|
|
78
|
+
}
|
|
79
|
+
/** Result of a tenant-scoped maintenance run. */
|
|
80
|
+
export interface MaintenanceResult {
|
|
81
|
+
status: string;
|
|
82
|
+
user_id: string;
|
|
83
|
+
dry_run: boolean;
|
|
84
|
+
results: Record<string, unknown>;
|
|
85
|
+
}
|
|
86
|
+
/** Health check result. */
|
|
87
|
+
export interface HealthResult {
|
|
88
|
+
status: string;
|
|
89
|
+
version: string;
|
|
90
|
+
architecture: string;
|
|
91
|
+
}
|
|
92
|
+
/** Options for the MemoryClient constructor. */
|
|
93
|
+
export interface MemoryClientOptions extends TenantConfig {
|
|
94
|
+
/** Base URL of the API. Defaults to "https://xvert.io". */
|
|
95
|
+
baseUrl?: string;
|
|
96
|
+
/** Request timeout in milliseconds. Defaults to 30000. */
|
|
97
|
+
timeout?: number;
|
|
98
|
+
}
|
|
99
|
+
/** Options for advanced retrieval. */
|
|
100
|
+
export interface RetrieveAdvancedOptions {
|
|
101
|
+
topK?: number;
|
|
102
|
+
expandContext?: boolean;
|
|
103
|
+
expandGraph?: boolean;
|
|
104
|
+
minScore?: number;
|
|
105
|
+
reinforce?: boolean;
|
|
106
|
+
}
|
|
107
|
+
/** Options for maintenance tasks. */
|
|
108
|
+
export interface MaintenanceTaskOptions {
|
|
109
|
+
decay?: boolean;
|
|
110
|
+
forgetting?: boolean;
|
|
111
|
+
summarization?: boolean;
|
|
112
|
+
contradiction_check?: boolean;
|
|
113
|
+
}
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "comemo",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Node.js SDK for CoMemo",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"prepublishOnly": "npm run build"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"memory",
|
|
16
|
+
"cognitive",
|
|
17
|
+
"ai",
|
|
18
|
+
"sdk"
|
|
19
|
+
],
|
|
20
|
+
"author": "Hasala",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"typescript": "^5.4.0"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=18.0.0"
|
|
27
|
+
}
|
|
28
|
+
}
|