@memoryengine/client 0.1.0 → 0.1.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.
- package/README.md +251 -0
- package/package.json +6 -1
package/README.md
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# @memoryengine/client
|
|
2
|
+
|
|
3
|
+
TypeScript client for memory engine. Full type inference from shared Zod schemas — no manual type duplication.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @memoryengine/client
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { createClient } from "@memoryengine/client";
|
|
15
|
+
|
|
16
|
+
const me = createClient({
|
|
17
|
+
server: "http://localhost:3000",
|
|
18
|
+
apiKey: "me_...",
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Store a memory
|
|
22
|
+
const engram = await me.engram.create({
|
|
23
|
+
content: "The project deadline is March 15th",
|
|
24
|
+
meta: { source: "meeting-notes", priority: "high" },
|
|
25
|
+
tree: "work.projects.launch",
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Search memories (hybrid BM25 + semantic)
|
|
29
|
+
const results = await me.engram.search({
|
|
30
|
+
fulltext: "project deadline",
|
|
31
|
+
semantic: "what are the upcoming deadlines?",
|
|
32
|
+
limit: 10,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Get current user
|
|
36
|
+
const whoami = await me.auth.whoami();
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## API
|
|
40
|
+
|
|
41
|
+
`createClient(options?)` returns a client with namespaced methods:
|
|
42
|
+
|
|
43
|
+
### Options
|
|
44
|
+
|
|
45
|
+
| Option | Type | Default | Description |
|
|
46
|
+
|--------|------|---------|-------------|
|
|
47
|
+
| `server` | `string` | `"http://localhost:3000"` | Server URL |
|
|
48
|
+
| `apiKey` | `string` | — | Bearer token for authentication |
|
|
49
|
+
| `timeout` | `number` | `30000` | Request timeout (ms) |
|
|
50
|
+
| `retries` | `number` | `3` | Max retries with exponential backoff |
|
|
51
|
+
|
|
52
|
+
### engram
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
// Create a memory
|
|
56
|
+
await me.engram.create({
|
|
57
|
+
content: "Remember this",
|
|
58
|
+
meta: { source: "chat" }, // optional JSONB metadata
|
|
59
|
+
tree: "work.projects.me", // optional hierarchical path
|
|
60
|
+
temporal: { start: "2025-03-15" }, // optional time range
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Get by ID
|
|
64
|
+
await me.engram.get({ id: "019..." });
|
|
65
|
+
|
|
66
|
+
// Update content, metadata, tree, or temporal
|
|
67
|
+
await me.engram.update({
|
|
68
|
+
id: "019...",
|
|
69
|
+
content: "Updated content",
|
|
70
|
+
meta: { source: "chat", reviewed: true },
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Delete by ID
|
|
74
|
+
await me.engram.delete({ id: "019..." });
|
|
75
|
+
|
|
76
|
+
// Batch create (up to 1000)
|
|
77
|
+
await me.engram.batchCreate({
|
|
78
|
+
engrams: [
|
|
79
|
+
{ content: "First memory", tree: "notes" },
|
|
80
|
+
{ content: "Second memory", tree: "notes" },
|
|
81
|
+
],
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Search — fulltext (BM25), semantic (vector), or both (hybrid)
|
|
85
|
+
await me.engram.search({ fulltext: "deadline" });
|
|
86
|
+
await me.engram.search({ semantic: "upcoming deadlines" });
|
|
87
|
+
await me.engram.search({
|
|
88
|
+
fulltext: "deadline",
|
|
89
|
+
semantic: "upcoming deadlines",
|
|
90
|
+
meta: { source: "meeting-notes" }, // filter by metadata
|
|
91
|
+
tree: "work.*", // filter by tree path
|
|
92
|
+
limit: 20,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Move memories between tree paths
|
|
96
|
+
await me.engram.mv({
|
|
97
|
+
source: "work.old_project",
|
|
98
|
+
destination: "archive.old_project",
|
|
99
|
+
});
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### auth
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
// Login with email/username + password
|
|
106
|
+
const { key, principal } = await me.auth.login({
|
|
107
|
+
identifier: "alice@example.com",
|
|
108
|
+
password: "secret",
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Get current principal
|
|
112
|
+
const whoami = await me.auth.whoami();
|
|
113
|
+
|
|
114
|
+
// Create an API key
|
|
115
|
+
const { key, id } = await me.auth.createApiKey({ name: "ci-bot" });
|
|
116
|
+
|
|
117
|
+
// List API keys
|
|
118
|
+
const keys = await me.auth.listApiKeys();
|
|
119
|
+
|
|
120
|
+
// Revoke an API key
|
|
121
|
+
await me.auth.revokeApiKey({ keyId: "key_id_here" });
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### principal
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
// Create a user
|
|
128
|
+
await me.principal.create({
|
|
129
|
+
name: "alice",
|
|
130
|
+
email: "alice@example.com",
|
|
131
|
+
password: "securepass",
|
|
132
|
+
can_login: true,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Create an agent (no login, no email)
|
|
136
|
+
await me.principal.create({ name: "indexer-bot" });
|
|
137
|
+
|
|
138
|
+
// Get principal by name
|
|
139
|
+
await me.principal.get({ name: "alice" });
|
|
140
|
+
|
|
141
|
+
// List all principals
|
|
142
|
+
await me.principal.list();
|
|
143
|
+
|
|
144
|
+
// Set password
|
|
145
|
+
await me.principal.setPassword({ name: "alice", password: "newpass123" });
|
|
146
|
+
|
|
147
|
+
// Delete principal
|
|
148
|
+
await me.principal.delete({ name: "alice" });
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### grant
|
|
152
|
+
|
|
153
|
+
Tree-based access control — grant read/create/update/delete on hierarchical paths.
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
// Grant access
|
|
157
|
+
await me.grant.create({
|
|
158
|
+
principal_name: "alice",
|
|
159
|
+
tree_path: "work.projects",
|
|
160
|
+
actions: ["read", "create", "update"],
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// Check access
|
|
164
|
+
await me.grant.check({ tree_path: "work.projects.me", action: "read" });
|
|
165
|
+
|
|
166
|
+
// List grants (optionally filter by principal)
|
|
167
|
+
await me.grant.list();
|
|
168
|
+
await me.grant.list({ principal_name: "alice" });
|
|
169
|
+
|
|
170
|
+
// Revoke access
|
|
171
|
+
await me.grant.revoke({
|
|
172
|
+
principal_name: "alice",
|
|
173
|
+
tree_path: "work.projects",
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### owner
|
|
178
|
+
|
|
179
|
+
Assign ownership of tree paths to principals.
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
// Set owner
|
|
183
|
+
await me.owner.set({
|
|
184
|
+
tree_path: "work.projects.me",
|
|
185
|
+
principal_name: "alice",
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Get owner of a path
|
|
189
|
+
await me.owner.get({ tree_path: "work.projects.me" });
|
|
190
|
+
|
|
191
|
+
// List all ownerships
|
|
192
|
+
await me.owner.list();
|
|
193
|
+
await me.owner.list({ principal_name: "alice" });
|
|
194
|
+
|
|
195
|
+
// Remove ownership
|
|
196
|
+
await me.owner.remove({ tree_path: "work.projects.me" });
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### role
|
|
200
|
+
|
|
201
|
+
Role-based membership for grouping principals.
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
// Add member to role
|
|
205
|
+
await me.role.addMember({
|
|
206
|
+
role_name: "engineers",
|
|
207
|
+
member_name: "alice",
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// List role members
|
|
211
|
+
await me.role.listMembers({ role_name: "engineers" });
|
|
212
|
+
|
|
213
|
+
// List roles for a principal
|
|
214
|
+
await me.role.listForPrincipal({ principal_name: "alice" });
|
|
215
|
+
await me.role.listForPrincipal(); // current principal
|
|
216
|
+
|
|
217
|
+
// Remove member from role
|
|
218
|
+
await me.role.removeMember({
|
|
219
|
+
role_name: "engineers",
|
|
220
|
+
member_name: "alice",
|
|
221
|
+
});
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Schemas
|
|
225
|
+
|
|
226
|
+
Import Zod schemas directly for validation or type extraction:
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
import { createEngramSchema, engramSchema } from "@memoryengine/client/schemas";
|
|
230
|
+
import type { RpcInput, RpcOutput } from "@memoryengine/client/schemas";
|
|
231
|
+
|
|
232
|
+
// Validate input
|
|
233
|
+
const parsed = createEngramSchema.parse(data);
|
|
234
|
+
|
|
235
|
+
// Extract types from any RPC method
|
|
236
|
+
type SearchParams = RpcInput<"engram.search">;
|
|
237
|
+
type SearchResult = RpcOutput<"engram.search">;
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Low-Level API
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
// Typed RPC call
|
|
244
|
+
const result = await me.call("engram.search", { semantic: "test" });
|
|
245
|
+
|
|
246
|
+
// Batch multiple requests in one HTTP round-trip
|
|
247
|
+
const [a, b] = await me.batch([
|
|
248
|
+
{ method: "engram.get", params: { id: "..." } },
|
|
249
|
+
{ method: "auth.whoami" },
|
|
250
|
+
]);
|
|
251
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memoryengine/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Client library for memory engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "src/index.ts",
|
|
@@ -34,5 +34,10 @@
|
|
|
34
34
|
"typescript": {
|
|
35
35
|
"optional": true
|
|
36
36
|
}
|
|
37
|
+
},
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/timescale/me.git",
|
|
41
|
+
"directory": "packages/client"
|
|
37
42
|
}
|
|
38
43
|
}
|