@hasna/mementos 0.4.15 → 0.4.17
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 +156 -195
- package/dist/cli/index.js +15 -12
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +17 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# @hasna/mementos
|
|
2
2
|
|
|
3
|
-
Universal memory system for AI agents. SQLite-backed with CLI, MCP server, and library
|
|
3
|
+
Universal memory system for AI agents. SQLite-backed with CLI, MCP server, REST API, and TypeScript library.
|
|
4
4
|
|
|
5
|
-
Agents
|
|
5
|
+
Agents save, recall, search, and share memories across sessions. Memories are scoped (global/shared/private), categorized, importance-ranked, and injected into agent context on demand.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Install
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
bun add -g @hasna/mementos
|
|
@@ -14,261 +14,222 @@ bun add -g @hasna/mementos
|
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
# Save a memory
|
|
17
|
-
mementos save "
|
|
17
|
+
mementos save "project-stack" "Bun + TypeScript + SQLite" --scope shared --importance 8
|
|
18
18
|
|
|
19
19
|
# Recall it
|
|
20
|
-
mementos recall "
|
|
20
|
+
mementos recall "project-stack"
|
|
21
21
|
|
|
22
|
-
# Search
|
|
23
|
-
mementos search "typescript"
|
|
22
|
+
# Search
|
|
23
|
+
mementos search "typescript stack"
|
|
24
24
|
|
|
25
|
-
#
|
|
26
|
-
mementos
|
|
25
|
+
# Inject into agent context (compact = ~60% smaller)
|
|
26
|
+
mementos inject --format compact --project-id <id>
|
|
27
27
|
|
|
28
28
|
# Get stats
|
|
29
29
|
mementos stats
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
##
|
|
33
|
-
|
|
34
|
-
| Scope | Visibility | Use Case |
|
|
35
|
-
|-------|-----------|----------|
|
|
36
|
-
| `global` | All agents, all projects | Org-wide preferences, facts |
|
|
37
|
-
| `shared` | All agents in a project | Project conventions, decisions |
|
|
38
|
-
| `private` | Single agent only | Agent-specific context, history |
|
|
39
|
-
|
|
40
|
-
## Memory Categories
|
|
41
|
-
|
|
42
|
-
| Category | Description |
|
|
43
|
-
|----------|------------|
|
|
44
|
-
| `preference` | Settings, choices, style preferences |
|
|
45
|
-
| `fact` | Verified truths, known information |
|
|
46
|
-
| `knowledge` | Learned patterns, insights, techniques |
|
|
47
|
-
| `history` | Session context, conversation summaries |
|
|
48
|
-
|
|
49
|
-
## CLI Reference
|
|
32
|
+
## MCP Server
|
|
50
33
|
|
|
51
|
-
###
|
|
34
|
+
### Install into Claude Code (recommended)
|
|
52
35
|
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
--
|
|
57
|
-
--session <id> Session context
|
|
36
|
+
```bash
|
|
37
|
+
mementos mcp --claude
|
|
38
|
+
# Or manually:
|
|
39
|
+
claude mcp add --transport stdio --scope user mementos -- mementos-mcp
|
|
58
40
|
```
|
|
59
41
|
|
|
60
|
-
###
|
|
42
|
+
### Install into Codex / Gemini
|
|
61
43
|
|
|
62
44
|
```bash
|
|
63
|
-
mementos
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
--importance <1-10> # Importance score (default: 5)
|
|
67
|
-
--tags <t1,t2> # Comma-separated tags
|
|
68
|
-
--summary <text> # Brief summary
|
|
69
|
-
--ttl <ms> # Time-to-live in milliseconds
|
|
70
|
-
--source <src> # user|agent|system|auto|imported
|
|
71
|
-
|
|
72
|
-
mementos recall <key> # Get memory by key
|
|
73
|
-
mementos list # List memories (with filters)
|
|
74
|
-
mementos update <id> # Update memory fields
|
|
75
|
-
mementos forget <key|id> # Delete a memory
|
|
76
|
-
mementos search <query> # Full-text search
|
|
77
|
-
mementos stats # Memory statistics
|
|
78
|
-
mementos export # Export as JSON
|
|
79
|
-
mementos import <file> # Import from JSON
|
|
80
|
-
mementos clean # Remove expired + enforce quotas
|
|
81
|
-
mementos inject # Output injection context
|
|
82
|
-
mementos init <name> # Register agent
|
|
83
|
-
mementos agents # List agents
|
|
84
|
-
mementos projects # Manage projects
|
|
85
|
-
mementos bulk <action> <ids> # Batch operations
|
|
45
|
+
mementos mcp --codex
|
|
46
|
+
mementos mcp --gemini
|
|
47
|
+
mementos mcp --all # all agents at once
|
|
86
48
|
```
|
|
87
49
|
|
|
88
|
-
|
|
50
|
+
### Available Tools (40+)
|
|
89
51
|
|
|
90
|
-
|
|
52
|
+
**Memory:** `memory_save`, `memory_recall`, `memory_get`, `memory_list`, `memory_update`, `memory_pin`, `memory_archive`, `memory_forget`, `memory_search`, `memory_stats`, `memory_export`, `memory_import`, `memory_inject`, `memory_context`, `session_extract`
|
|
91
53
|
|
|
92
|
-
|
|
54
|
+
**Bulk:** `bulk_forget`, `bulk_update`
|
|
93
55
|
|
|
94
|
-
|
|
95
|
-
{
|
|
96
|
-
"mcpServers": {
|
|
97
|
-
"mementos": {
|
|
98
|
-
"command": "mementos-mcp",
|
|
99
|
-
"args": []
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
```
|
|
56
|
+
**Agents:** `register_agent`, `list_agents`, `list_agents_by_project`, `get_agent`, `update_agent`
|
|
104
57
|
|
|
105
|
-
|
|
58
|
+
**Projects:** `register_project`, `list_projects`, `get_project`
|
|
106
59
|
|
|
107
|
-
|
|
60
|
+
**Knowledge Graph:** `entity_create`, `entity_get`, `entity_list`, `entity_delete`, `entity_merge`, `entity_link`, `relation_create`, `relation_delete`, `relation_list`, `graph_query`, `graph_path`, `graph_stats`
|
|
108
61
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
62
|
+
**Meta:** `search_tools`, `describe_tools` (lean stubs — full docs on demand)
|
|
63
|
+
|
|
64
|
+
**Utility:** `clean_expired`
|
|
65
|
+
|
|
66
|
+
## CLI Reference
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
mementos save <key> <value> # Save/upsert a memory
|
|
70
|
+
mementos recall <key> # Get memory by key
|
|
71
|
+
mementos list # List memories (with filters)
|
|
72
|
+
mementos update <id> # Update memory fields
|
|
73
|
+
mementos pin <key|id> # Pin a memory
|
|
74
|
+
mementos forget <key|id> # Delete a memory
|
|
75
|
+
mementos search <query> # Full-text + fuzzy search
|
|
76
|
+
mementos stats # Memory statistics
|
|
77
|
+
mementos export # Export as JSON
|
|
78
|
+
mementos import <file> # Import from JSON
|
|
79
|
+
mementos clean # Remove expired + enforce quotas
|
|
80
|
+
mementos inject # Output injection context
|
|
81
|
+
mementos init <name> # Register agent
|
|
82
|
+
mementos agents # List agents
|
|
83
|
+
mementos projects # Manage projects
|
|
84
|
+
mementos bulk forget <ids> # Batch delete
|
|
85
|
+
mementos bulk update <ids> # Batch update
|
|
86
|
+
mementos diff <id> # Show memory version history
|
|
87
|
+
mementos doctor # Diagnose DB health
|
|
88
|
+
|
|
89
|
+
# Profiles — isolated DBs per context
|
|
90
|
+
mementos profile set work # Switch to work profile
|
|
91
|
+
mementos profile list # List all profiles
|
|
92
|
+
mementos profile get # Show active profile
|
|
93
|
+
mementos profile unset # Back to default
|
|
117
94
|
```
|
|
118
95
|
|
|
119
|
-
|
|
96
|
+
## Profiles
|
|
120
97
|
|
|
121
|
-
|
|
98
|
+
```bash
|
|
99
|
+
# Each profile is an isolated DB: ~/.mementos/profiles/<name>.db
|
|
100
|
+
mementos profile set work
|
|
101
|
+
MEMENTOS_PROFILE=work mementos list # per-command
|
|
102
|
+
```
|
|
122
103
|
|
|
123
|
-
|
|
104
|
+
## REST API
|
|
124
105
|
|
|
125
|
-
|
|
106
|
+
```bash
|
|
107
|
+
mementos-serve --port 19428
|
|
108
|
+
```
|
|
126
109
|
|
|
127
|
-
**
|
|
110
|
+
Default port: **19428**. Binds to `127.0.0.1` (localhost only). Override with `MEMENTOS_HOST=0.0.0.0`.
|
|
128
111
|
|
|
129
|
-
|
|
112
|
+
### Key Endpoints
|
|
130
113
|
|
|
131
|
-
|
|
114
|
+
| Method | Path | Description |
|
|
115
|
+
|--------|------|-------------|
|
|
116
|
+
| GET | `/api/memories?fields=key,value` | List memories (?fields, ?scope, ?session_id, ?status) |
|
|
117
|
+
| POST | `/api/memories` | Create/upsert memory |
|
|
118
|
+
| PATCH | `/api/memories/:id` | Update (version optional — auto-fetched) |
|
|
119
|
+
| DELETE | `/api/memories/:id` | Delete |
|
|
120
|
+
| POST | `/api/memories/search` | Full-text search |
|
|
121
|
+
| POST | `/api/memories/extract` | Auto-extract memories from session summary |
|
|
122
|
+
| POST | `/api/memories/bulk-forget` | Delete multiple |
|
|
123
|
+
| POST | `/api/memories/bulk-update` | Update multiple |
|
|
124
|
+
| GET | `/api/memories/stats` | Statistics |
|
|
125
|
+
| POST | `/api/memories/export` | Export with filters |
|
|
126
|
+
| GET | `/api/inject?format=compact` | Context injection (compact/markdown/json/xml) |
|
|
127
|
+
| GET/POST | `/api/agents` | Agent registry |
|
|
128
|
+
| PATCH | `/api/agents/:id` | Update agent (including active_project_id) |
|
|
129
|
+
| GET/POST | `/api/projects` | Project registry |
|
|
130
|
+
| GET | `/api/projects/:id/agents` | Agents active on a project |
|
|
131
|
+
| GET | `/api/profile` | Active profile info |
|
|
132
|
+
| GET | `/api/health` | Health check (includes profile, hostname) |
|
|
132
133
|
|
|
133
|
-
|
|
134
|
-
- `mementos://agents` — Registered agents
|
|
135
|
-
- `mementos://projects` — Registered projects
|
|
134
|
+
## SDK
|
|
136
135
|
|
|
137
|
-
|
|
136
|
+
```bash
|
|
137
|
+
bun add @hasna/mementos-sdk
|
|
138
|
+
```
|
|
138
139
|
|
|
139
140
|
```typescript
|
|
140
|
-
import {
|
|
141
|
-
createMemory,
|
|
142
|
-
getMemoryByKey,
|
|
143
|
-
listMemories,
|
|
144
|
-
searchMemories,
|
|
145
|
-
MemoryInjector,
|
|
146
|
-
} from "@hasna/mementos";
|
|
141
|
+
import { MementosClient } from "@hasna/mementos-sdk";
|
|
147
142
|
|
|
148
|
-
|
|
149
|
-
const memory = createMemory({
|
|
150
|
-
key: "db-convention",
|
|
151
|
-
value: "Always use snake_case for column names",
|
|
152
|
-
scope: "shared",
|
|
153
|
-
category: "preference",
|
|
154
|
-
importance: 8,
|
|
155
|
-
tags: ["database", "conventions"],
|
|
156
|
-
});
|
|
143
|
+
const client = new MementosClient({ baseUrl: "http://localhost:19428" });
|
|
157
144
|
|
|
158
|
-
//
|
|
159
|
-
|
|
145
|
+
// Save memory
|
|
146
|
+
await client.saveMemory({ key: "db-convention", value: "snake_case", scope: "shared" });
|
|
160
147
|
|
|
161
148
|
// Search
|
|
162
|
-
const results = searchMemories("database");
|
|
163
|
-
|
|
164
|
-
//
|
|
165
|
-
const
|
|
166
|
-
scope: "global",
|
|
167
|
-
category: "fact",
|
|
168
|
-
min_importance: 5,
|
|
169
|
-
limit: 20,
|
|
170
|
-
});
|
|
149
|
+
const { results } = await client.searchMemories("database conventions");
|
|
150
|
+
|
|
151
|
+
// Context injection (compact format — 60% smaller)
|
|
152
|
+
const { context } = await client.getContext({ project_id: "...", format: "compact" });
|
|
171
153
|
|
|
172
|
-
//
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
154
|
+
// Sessions → mementos integration
|
|
155
|
+
await client.extractFromSession({
|
|
156
|
+
session_id: "abc123",
|
|
157
|
+
title: "Fix auth middleware",
|
|
158
|
+
key_topics: ["jwt", "compliance"],
|
|
159
|
+
project_id: "...",
|
|
178
160
|
});
|
|
179
161
|
```
|
|
180
162
|
|
|
181
|
-
##
|
|
163
|
+
## Agent-Project Binding
|
|
164
|
+
|
|
165
|
+
Track which agent is working on which project:
|
|
182
166
|
|
|
183
|
-
|
|
167
|
+
```typescript
|
|
168
|
+
// On session start
|
|
169
|
+
await client.updateAgent("my-agent", { active_project_id: "project-uuid" });
|
|
170
|
+
|
|
171
|
+
// Query: who's on this project?
|
|
172
|
+
const { agents } = await client.getProjectAgents("open-mementos");
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Context Injection
|
|
184
176
|
|
|
185
177
|
```bash
|
|
186
|
-
|
|
178
|
+
# 60% smaller with compact format
|
|
179
|
+
mementos inject --format compact --project-id <id> --max-tokens 400
|
|
187
180
|
```
|
|
188
181
|
|
|
189
|
-
|
|
182
|
+
MCP: `memory_inject(project_id="...", format="compact", max_tokens=400)`
|
|
190
183
|
|
|
191
|
-
|
|
192
|
-
|--------|------|-------------|
|
|
193
|
-
| GET | `/api/memories` | List memories |
|
|
194
|
-
| POST | `/api/memories` | Create memory |
|
|
195
|
-
| GET | `/api/memories/:id` | Get memory |
|
|
196
|
-
| PATCH | `/api/memories/:id` | Update memory |
|
|
197
|
-
| DELETE | `/api/memories/:id` | Delete memory |
|
|
198
|
-
| POST | `/api/memories/search` | Search |
|
|
199
|
-
| GET | `/api/memories/stats` | Statistics |
|
|
200
|
-
| POST | `/api/memories/export` | Export |
|
|
201
|
-
| POST | `/api/memories/import` | Import |
|
|
202
|
-
| POST | `/api/memories/clean` | Cleanup |
|
|
203
|
-
| GET/POST | `/api/agents` | Agents |
|
|
204
|
-
| GET/POST | `/api/projects` | Projects |
|
|
205
|
-
| GET | `/api/inject` | Injection context |
|
|
184
|
+
## Sessions Integration
|
|
206
185
|
|
|
207
|
-
|
|
186
|
+
After ingesting a session (open-sessions):
|
|
208
187
|
|
|
209
|
-
|
|
188
|
+
```bash
|
|
189
|
+
sessions remember <session-id> --mementos-url http://localhost:19428
|
|
190
|
+
# Creates: session-summary (history), session-topics (knowledge), session-notes (knowledge)
|
|
191
|
+
```
|
|
210
192
|
|
|
193
|
+
REST:
|
|
211
194
|
```json
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
"default_category": "knowledge",
|
|
215
|
-
"default_importance": 5,
|
|
216
|
-
"max_entries": 1000,
|
|
217
|
-
"max_entries_per_scope": {
|
|
218
|
-
"global": 500,
|
|
219
|
-
"shared": 300,
|
|
220
|
-
"private": 200
|
|
221
|
-
},
|
|
222
|
-
"injection": {
|
|
223
|
-
"max_tokens": 500,
|
|
224
|
-
"min_importance": 5,
|
|
225
|
-
"categories": ["preference", "fact"],
|
|
226
|
-
"refresh_interval": 5
|
|
227
|
-
},
|
|
228
|
-
"sync_agents": ["claude", "codex", "gemini"],
|
|
229
|
-
"auto_cleanup": {
|
|
230
|
-
"enabled": true,
|
|
231
|
-
"expired_check_interval": 3600
|
|
232
|
-
}
|
|
233
|
-
}
|
|
195
|
+
POST /api/memories/extract
|
|
196
|
+
{ "session_id": "abc", "title": "Fix auth", "key_topics": ["jwt"] }
|
|
234
197
|
```
|
|
235
198
|
|
|
236
|
-
|
|
199
|
+
## Environment Variables
|
|
237
200
|
|
|
238
|
-
| Variable |
|
|
239
|
-
|
|
240
|
-
| `MEMENTOS_DB_PATH` | Override
|
|
241
|
-
| `
|
|
242
|
-
| `
|
|
201
|
+
| Variable | Purpose | Default |
|
|
202
|
+
|----------|---------|---------|
|
|
203
|
+
| `MEMENTOS_DB_PATH` | Override DB path (bypasses profiles) | `~/.mementos/mementos.db` |
|
|
204
|
+
| `MEMENTOS_PROFILE` | Named profile → `~/.mementos/profiles/<name>.db` | none |
|
|
205
|
+
| `MEMENTOS_DB_SCOPE` | `project` = git root `.mementos/mementos.db` | global |
|
|
206
|
+
| `MEMENTOS_HOST` | Server bind address | `127.0.0.1` |
|
|
207
|
+
| `PORT` | Server port | `19428` |
|
|
243
208
|
|
|
244
|
-
##
|
|
209
|
+
## Library
|
|
245
210
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
211
|
+
```typescript
|
|
212
|
+
import {
|
|
213
|
+
createMemory, getMemoryByKey, listMemories, searchMemories,
|
|
214
|
+
registerAgent, updateAgent, listAgentsByProject,
|
|
215
|
+
registerProject, getProject,
|
|
216
|
+
getActiveProfile, setActiveProfile,
|
|
217
|
+
MemoryInjector,
|
|
218
|
+
} from "@hasna/mementos";
|
|
219
|
+
```
|
|
251
220
|
|
|
252
221
|
## Architecture
|
|
253
222
|
|
|
254
223
|
```
|
|
255
224
|
src/
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
│ ├── search.ts # Full-text search engine
|
|
265
|
-
│ ├── injector.ts # Context injection system
|
|
266
|
-
│ ├── retention.ts # Auto-cleanup & quota enforcement
|
|
267
|
-
│ └── sync.ts # Multi-agent memory sync
|
|
268
|
-
├── cli/index.tsx # CLI (Commander.js + chalk)
|
|
269
|
-
├── mcp/index.ts # MCP server (19 tools, 3 resources)
|
|
270
|
-
├── server/index.ts # REST API server
|
|
271
|
-
└── index.ts # Library exports
|
|
225
|
+
cli/ Commander.js + Ink TUI — 20+ commands
|
|
226
|
+
mcp/ MCP server — 40+ tools (lean stubs)
|
|
227
|
+
server/ REST API — 37+ endpoints (Bun.serve)
|
|
228
|
+
db/ SQLite (bun:sqlite) — memories, agents, projects, entities, relations
|
|
229
|
+
lib/ FTS5 search, injection, extraction, retention, config, profiles
|
|
230
|
+
types/ TypeScript interfaces and errors
|
|
231
|
+
sdk/ @hasna/mementos-sdk — zero-dep fetch client
|
|
232
|
+
dashboard/ React+Vite web UI
|
|
272
233
|
```
|
|
273
234
|
|
|
274
235
|
## License
|
package/dist/cli/index.js
CHANGED
|
@@ -5674,21 +5674,24 @@ program2.command("mcp").description("Install mementos MCP server into Claude Cod
|
|
|
5674
5674
|
for (const target of targets) {
|
|
5675
5675
|
try {
|
|
5676
5676
|
if (target === "claude") {
|
|
5677
|
-
const
|
|
5678
|
-
let config = {};
|
|
5679
|
-
if (fileExists(configPath)) {
|
|
5680
|
-
config = JSON.parse(readFileSync3(configPath, "utf-8"));
|
|
5681
|
-
}
|
|
5682
|
-
const servers = config["mcpServers"] || {};
|
|
5677
|
+
const { execSync } = __require("child_process");
|
|
5683
5678
|
if (opts.uninstall) {
|
|
5684
|
-
|
|
5679
|
+
try {
|
|
5680
|
+
execSync(`claude mcp remove mementos`, { stdio: "pipe" });
|
|
5681
|
+
console.log(chalk.green("Removed mementos from Claude Code MCP"));
|
|
5682
|
+
} catch {
|
|
5683
|
+
console.log(chalk.yellow("mementos was not installed in Claude Code (or claude CLI not found)"));
|
|
5684
|
+
}
|
|
5685
5685
|
} else {
|
|
5686
|
-
|
|
5686
|
+
try {
|
|
5687
|
+
execSync(`claude mcp add --transport stdio --scope user mementos -- ${mementosCmd}`, { stdio: "pipe" });
|
|
5688
|
+
console.log(chalk.green(`Installed mementos into Claude Code (user scope)`));
|
|
5689
|
+
console.log(chalk.gray(" Restart Claude Code for the change to take effect."));
|
|
5690
|
+
} catch (e) {
|
|
5691
|
+
console.log(chalk.yellow("claude CLI not found. Run this manually:"));
|
|
5692
|
+
console.log(chalk.white(` claude mcp add --transport stdio --scope user mementos -- ${mementosCmd}`));
|
|
5693
|
+
}
|
|
5687
5694
|
}
|
|
5688
|
-
config["mcpServers"] = servers;
|
|
5689
|
-
writeFileSync3(configPath, JSON.stringify(config, null, 2) + `
|
|
5690
|
-
`, "utf-8");
|
|
5691
|
-
console.log(chalk.green(`${opts.uninstall ? "Removed from" : "Installed into"} Claude Code: ${configPath}`));
|
|
5692
5695
|
}
|
|
5693
5696
|
if (target === "codex") {
|
|
5694
5697
|
const configPath = pathJoin(home, ".codex", "config.toml");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";AACA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAulCH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAkH9C"}
|
package/dist/server/index.js
CHANGED
|
@@ -2451,6 +2451,11 @@ addRoute("DELETE", "/api/memories/:id", (_req, _url, params) => {
|
|
|
2451
2451
|
addRoute("GET", "/api/agents", (_req, url) => {
|
|
2452
2452
|
const q = getSearchParams(url);
|
|
2453
2453
|
const agents = q["project_id"] ? listAgentsByProject(q["project_id"]) : listAgents();
|
|
2454
|
+
if (q["fields"]) {
|
|
2455
|
+
const fields = q["fields"].split(",").map((f) => f.trim());
|
|
2456
|
+
const filtered = agents.map((a) => Object.fromEntries(fields.map((f) => [f, a[f]]).filter(([, v]) => v !== undefined)));
|
|
2457
|
+
return json({ agents: filtered, count: filtered.length });
|
|
2458
|
+
}
|
|
2454
2459
|
return json({ agents, count: agents.length });
|
|
2455
2460
|
});
|
|
2456
2461
|
addRoute("POST", "/api/agents", async (req) => {
|
|
@@ -2493,8 +2498,14 @@ addRoute("PATCH", "/api/agents/:id", async (req, _url, params) => {
|
|
|
2493
2498
|
return errorResponse(e instanceof Error ? e.message : "Update failed", 400);
|
|
2494
2499
|
}
|
|
2495
2500
|
});
|
|
2496
|
-
addRoute("GET", "/api/projects", () => {
|
|
2501
|
+
addRoute("GET", "/api/projects", (_req, url) => {
|
|
2502
|
+
const q = getSearchParams(url);
|
|
2497
2503
|
const projects = listProjects();
|
|
2504
|
+
if (q["fields"]) {
|
|
2505
|
+
const fields = q["fields"].split(",").map((f) => f.trim());
|
|
2506
|
+
const filtered = projects.map((p) => Object.fromEntries(fields.map((f) => [f, p[f]]).filter(([, v]) => v !== undefined)));
|
|
2507
|
+
return json({ projects: filtered, count: filtered.length });
|
|
2508
|
+
}
|
|
2498
2509
|
return json({ projects, count: projects.length });
|
|
2499
2510
|
});
|
|
2500
2511
|
addRoute("POST", "/api/projects", async (req) => {
|
|
@@ -2626,6 +2637,11 @@ addRoute("GET", "/api/entities", (_req, url) => {
|
|
|
2626
2637
|
if (q["offset"])
|
|
2627
2638
|
filter.offset = parseInt(q["offset"], 10);
|
|
2628
2639
|
const entities = listEntities(filter);
|
|
2640
|
+
if (q["fields"]) {
|
|
2641
|
+
const fields = q["fields"].split(",").map((f) => f.trim());
|
|
2642
|
+
const filtered = entities.map((e) => Object.fromEntries(fields.map((f) => [f, e[f]]).filter(([, v]) => v !== undefined)));
|
|
2643
|
+
return json({ entities: filtered, count: filtered.length });
|
|
2644
|
+
}
|
|
2629
2645
|
return json({ entities, count: entities.length });
|
|
2630
2646
|
});
|
|
2631
2647
|
addRoute("POST", "/api/entities/merge", async (req) => {
|