@yugabytedb/meko-mcp 2.2.0 → 2.3.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 +106 -38
- package/assets/hooks-handlers/lib/capture-cleanup-cli.js +1473 -0
- package/assets/hooks-handlers/lib/capture-notices.js +131 -14
- package/assets/hooks-handlers/lib/capture-state.js +95 -1
- package/assets/hooks-handlers/lib/capture-status-cli.js +6 -2
- package/assets/hooks-handlers/lib/capture.js +1237 -137
- package/assets/hooks-handlers/lib/checkpoint-timer.js +51 -10
- package/assets/hooks-handlers/lib/journal-bridge.js +218 -0
- package/assets/hooks-handlers/lib/kiro-handler.js +26 -4
- package/assets/hooks-handlers/lib/opencode-handler.js +620 -0
- package/assets/hooks-handlers/lib/opencode-normalizer.js +145 -0
- package/assets/hooks-handlers/lib/terminal-handoff.js +10 -1
- package/assets/opencode-plugin/meko.js +213 -0
- package/assets/scripts/meko-statusline.sh +85 -18
- package/assets/skills/meko-mcp-tools/SKILL.md +57 -14
- package/assets/skills/meko-mcp-tools/references/_sections.md +2 -2
- package/assets/skills/meko-mcp-tools/references/tools-agent-id-conventions.md +15 -7
- package/assets/skills/meko-mcp-tools/references/tools-cookbook.md +86 -14
- package/assets/skills/meko-mcp-tools/references/tools-datapack-workflow.md +1 -1
- package/assets/skills/meko-mcp-tools/references/tools-known-limitations.md +29 -6
- package/assets/skills/meko-mcp-tools/references/tools-memory-vs-conversation.md +8 -4
- package/assets/skills/meko-mcp-tools/references/tools-overview.md +32 -22
- package/assets/skills/meko-mcp-tools/references/tools-rag-workflow.md +14 -8
- package/assets/skills/meko-mcp-tools/references/tools-troubleshooting.md +45 -1
- package/assets/skills/meko-mcp-tools/references/tools-user-id-conventions.md +6 -39
- package/assets/skills/meko-mcp-tools-desktop/SKILL.md +54 -18
- package/assets/skills/meko-mcp-tools-desktop/desktop/README.md +1 -1
- package/assets/skills/meko-mcp-tools-desktop/references/_sections.md +1 -1
- package/assets/skills/meko-mcp-tools-desktop/references/tools-agent-id-conventions.md +8 -6
- package/assets/skills/meko-mcp-tools-desktop/references/tools-cookbook.md +95 -33
- package/assets/skills/meko-mcp-tools-desktop/references/tools-known-limitations.md +22 -5
- package/assets/skills/meko-mcp-tools-desktop/references/tools-memory-vs-conversation.md +14 -10
- package/assets/skills/meko-mcp-tools-desktop/references/tools-overview.md +35 -25
- package/assets/skills/meko-mcp-tools-desktop/references/tools-rag-workflow.md +14 -8
- package/assets/skills/meko-mcp-tools-desktop/references/tools-troubleshooting.md +67 -1
- package/assets/skills/meko-select-datapack-desktop/SKILL.md +4 -4
- package/assets/skills/meko-select-datapack-desktop/references/cookbook.md +5 -5
- package/assets/skills/meko-select-datapack-desktop/references/role-display-future.md +7 -5
- package/assets/skills/meko-select-datapack-desktop/references/troubleshooting.md +4 -4
- package/bin/create-meko-setup.mjs +70 -7
- package/lib/capture-cleanup.mjs +63 -0
- package/lib/clients/claude-code.mjs +1 -0
- package/lib/clients/codex.mjs +80 -35
- package/lib/clients/common.mjs +7 -0
- package/lib/clients/index.mjs +2 -0
- package/lib/clients/kiro.mjs +5 -5
- package/lib/clients/opencode.mjs +532 -0
- package/lib/config.mjs +68 -1
- package/lib/installer.mjs +18 -2
- package/lib/migrate/adapters/claude-code.mjs +11 -2
- package/lib/migrate/adapters/codex.mjs +9 -2
- package/lib/migrate/adapters/memory-md.mjs +27 -8
- package/lib/migrate/adapters/opencode.mjs +148 -0
- package/lib/migrate/claude-parser.mjs +153 -9
- package/lib/migrate/id.mjs +195 -13
- package/lib/migrate/mcp-client.mjs +25 -1
- package/lib/migrate/opencode-normalizer.mjs +132 -0
- package/lib/migrate/orchestrator.mjs +293 -77
- package/lib/migrate/progress.mjs +239 -5
- package/lib/migrate/registry.mjs +72 -0
- package/lib/migrate.mjs +96 -8
- package/package.json +1 -1
- package/scripts/bundle-assets.mjs +4 -0
|
@@ -6,6 +6,47 @@ Every tool example below shows the correct parameters, expected response, and co
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## Retrieval
|
|
10
|
+
|
|
11
|
+
### context_search
|
|
12
|
+
|
|
13
|
+
Default first call for open-ended recall ("what do you know about X?"). One call queries memory, the knowledge base, and the conversation-history cache in parallel.
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
context_search(
|
|
17
|
+
query="auth migration decisions",
|
|
18
|
+
agent_id="claude_desktop",
|
|
19
|
+
conversation_id="<session conversation id>",
|
|
20
|
+
datapack_id="<datapack UUID>")
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Required: `query`, `conversation_id`. `datapack_id` is optional (default datapack if omitted); pass the pinned id when you have one.
|
|
24
|
+
|
|
25
|
+
Response:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
{
|
|
29
|
+
"results": {
|
|
30
|
+
"memory": [{"id": "...", "memory": "...", "score": 0.51, ...}],
|
|
31
|
+
"knowledge_base": [{"id": "...", "chunk_text": "...", "document_id": "...", "distance": 0.31, "match_type": "hybrid", ...}],
|
|
32
|
+
"conversation": {"hits": [...], "thread": [...]}
|
|
33
|
+
},
|
|
34
|
+
"token_savings": {"total_tokens": 49000, "memory": {"tokens_sent": 600, "tokens_saved": 48400}, "tokens_saved": 48400}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
- A bucket is `null` only when that source wasn't queried: `force_source` excluded it, or the server couldn't build a query vector for it.
|
|
39
|
+
- An empty bucket is ambiguous: either that source found nothing relevant, or it failed. `context_search` turns a failed source into an empty list and records the error only in the trace. Before you tell the user nothing is stored about X, confirm with `memory_search` or `knowledgebase_search`, which return errors.
|
|
40
|
+
- The conversation bucket is datapack-wide. It returns embedded turns from every user and agent on the datapack, and each hit carries its author's `user_id`. Don't present a hit as this user's own history.
|
|
41
|
+
- `limit` bounds the memory and KB buckets only; the conversation bucket returns up to 10 hits plus a thread of whole turns.
|
|
42
|
+
- The memory bucket has no similarity floor on the default path. The KB bucket drops chunks above an absolute distance cutoff, so it can be empty even when `knowledgebase_search` would return a weak best match.
|
|
43
|
+
- `force_source="memory" | "knowledge_base" | "conversation"` queries only that source. `force_source="memory"` reapplies the `memory_search` similarity floor.
|
|
44
|
+
- `token_savings` is an estimate for reporting. Don't base decisions on it.
|
|
45
|
+
|
|
46
|
+
**Errors:** `conversation_id_required`, `invalid_force_source`, `datapack_access_denied`, and `free_tier_limit_reached` (Free tier: 1,000 lifetime calls). Treat any error as a failed search (SKILL.md operating contract 1).
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
9
50
|
## Memory Tools
|
|
10
51
|
|
|
11
52
|
**Critical:** Pass your session's `agent_id` on every memory call. For Claude Desktop that's `claude_desktop` for normal attribution, or `meko_agent` when writing genuinely cross-project facts. Writes retain that attribution, while personal memory reads span all of this user's agents.
|
|
@@ -16,6 +57,7 @@ Every tool example below shows the correct parameters, expected response, and co
|
|
|
16
57
|
|
|
17
58
|
```
|
|
18
59
|
memory_add(agent_id="claude_desktop",
|
|
60
|
+
conversation_id="<id from conversation_create>",
|
|
19
61
|
text="Remember: deploy scripts must be run from the repo root, never a subdir.")
|
|
20
62
|
```
|
|
21
63
|
|
|
@@ -24,12 +66,6 @@ memory_add(agent_id="claude_desktop",
|
|
|
24
66
|
{"results": [{"id": "mem-uuid-123", "memory": "User Amiram is VP of Product at YugabyteDB. Prefers concise responses."}]}
|
|
25
67
|
```
|
|
26
68
|
|
|
27
|
-
**With user scoping:**
|
|
28
|
-
```
|
|
29
|
-
memory_add(agent_id="agent", user_id="amiram",
|
|
30
|
-
text="Prefers Python for backend, Go for infrastructure.")
|
|
31
|
-
```
|
|
32
|
-
|
|
33
69
|
**What NOT to store via memory_add:**
|
|
34
70
|
- Full conversations (use `conversation_create` + `conversation_add_message`)
|
|
35
71
|
- Large documents (use the UI's Datapack → Actions → Add Knowledge upload flow)
|
|
@@ -46,35 +82,32 @@ memory_add(agent_id="agent", user_id="amiram",
|
|
|
46
82
|
|
|
47
83
|
**Cross-conversation discovery.** `memory_search` returns hits across every stored conversation for the `(datapack_id, user_id)` pair, across all agents (the tool intentionally passes `meko_agent_id=None` to mem0, so the `agent_id` argument scopes the trace but does not filter results). When a hit references an interesting conversation, follow up with `conversation_list` to browse the associated threads and `conversation_get` to read a specific one — the memory hit's `meko_conversation_id` field is the id to fetch. Pass `run_id` on the search itself to narrow to a single conversation up front.
|
|
48
84
|
|
|
49
|
-
**Relevance floor.**
|
|
85
|
+
**Relevance floor.** `memory_search` drops results whose raw cosine similarity is below the server's `memory_search_min_score` setting (default `0.2`, tunable at runtime). A query can return fewer results than `limit`, or an empty list, when nothing clears the bar. That means no sufficiently relevant memory, not a broken call.
|
|
50
86
|
|
|
51
87
|
```
|
|
52
|
-
memory_search(query="What programming language does the team use?", agent_id="
|
|
88
|
+
memory_search(query="What programming language does the team use?", agent_id="claude_desktop", conversation_id="<id>")
|
|
53
89
|
```
|
|
54
90
|
|
|
55
91
|
**Response:**
|
|
56
92
|
```json
|
|
57
|
-
{"results": [{"id": "mem-uuid-123", "memory": "Team uses Python for backend", "score": 0.89}]}
|
|
93
|
+
{"results": [{"id": "mem-uuid-123", "memory": "Team uses Python for backend", "score": 0.89, "raw_similarity_score": 0.72}]}
|
|
58
94
|
```
|
|
59
95
|
|
|
96
|
+
`score` is the fused hybrid rank (semantic + keyword + entity boost) used to order results; `raw_similarity_score` is the unfused cosine value. A similarity threshold like `MEMORY_SEARCH_MIN_SCORE` gates on `raw_similarity_score` when it is not null, and falls back to `score` when the raw field is absent or null.
|
|
97
|
+
|
|
60
98
|
**With limit:**
|
|
61
99
|
```
|
|
62
|
-
memory_search(query="user preferences", agent_id="
|
|
100
|
+
memory_search(query="user preferences", agent_id="claude_desktop", conversation_id="<id>", limit=5)
|
|
63
101
|
```
|
|
64
102
|
|
|
65
103
|
---
|
|
66
104
|
|
|
67
105
|
### memory_get_all
|
|
68
106
|
|
|
69
|
-
**When to use:**
|
|
107
|
+
**When to use:** See the most recent memories (about 20 rows) across every `agent_id`, plus the true `total`. It is not a complete listing and takes no paging arguments (SKILL.md operating contract 2). Use `memory_search` or `memory_get_by_id` for anything older or specific.
|
|
70
108
|
|
|
71
109
|
```
|
|
72
|
-
memory_get_all(agent_id="
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
**With user scoping:**
|
|
76
|
-
```
|
|
77
|
-
memory_get_all(agent_id="agent", user_id="amiram")
|
|
110
|
+
memory_get_all(agent_id="claude_desktop", conversation_id="<id>")
|
|
78
111
|
```
|
|
79
112
|
|
|
80
113
|
---
|
|
@@ -82,7 +115,7 @@ memory_get_all(agent_id="agent", user_id="amiram")
|
|
|
82
115
|
### memory_get_by_id
|
|
83
116
|
|
|
84
117
|
```
|
|
85
|
-
memory_get_by_id(memory_id="mem-uuid-123", agent_id="
|
|
118
|
+
memory_get_by_id(memory_id="mem-uuid-123", agent_id="claude_desktop", conversation_id="<id>")
|
|
86
119
|
```
|
|
87
120
|
|
|
88
121
|
---
|
|
@@ -92,7 +125,7 @@ memory_get_by_id(memory_id="mem-uuid-123", agent_id="agent")
|
|
|
92
125
|
**When to use:** Overwrite a specific memory's text. Requires the memory UUID.
|
|
93
126
|
|
|
94
127
|
```
|
|
95
|
-
memory_update(memory_id="mem-uuid-123", text="Updated: Team uses Go for all new services", agent_id="
|
|
128
|
+
memory_update(memory_id="mem-uuid-123", text="Updated: Team uses Go for all new services", agent_id="claude_desktop", conversation_id="<id>")
|
|
96
129
|
```
|
|
97
130
|
|
|
98
131
|
---
|
|
@@ -100,17 +133,19 @@ memory_update(memory_id="mem-uuid-123", text="Updated: Team uses Go for all new
|
|
|
100
133
|
### memory_delete_by_id
|
|
101
134
|
|
|
102
135
|
```
|
|
103
|
-
memory_delete_by_id(memory_id="mem-uuid-123", agent_id="
|
|
136
|
+
memory_delete_by_id(memory_id="mem-uuid-123", agent_id="claude_desktop", conversation_id="<id>")
|
|
104
137
|
```
|
|
105
138
|
|
|
139
|
+
`memory_update` and `memory_delete_by_id` return `memory_is_promoted` for a promoted memory, and `not_found` for an id that is missing or belongs to another account.
|
|
140
|
+
|
|
106
141
|
---
|
|
107
142
|
|
|
108
143
|
### memory_delete_all
|
|
109
144
|
|
|
110
|
-
**Destructive.** Deletes all memories
|
|
145
|
+
**Destructive.** Deletes all memories in the passed `agent_id`'s bucket in the datapack. It does not touch other agents' rows, even though `memory_search` shows them; omitting `agent_id` deletes only the `meko_agent` bucket. Pass `run_id=<conversation_id>` to limit it to one conversation. For removing a single memory, prefer `memory_delete_by_id`.
|
|
111
146
|
|
|
112
147
|
```
|
|
113
|
-
memory_delete_all(agent_id="
|
|
148
|
+
memory_delete_all(agent_id="claude_desktop", conversation_id="<id>")
|
|
114
149
|
```
|
|
115
150
|
|
|
116
151
|
---
|
|
@@ -142,10 +177,13 @@ On 403, authentication, or permission failure, report the error and stop — do
|
|
|
142
177
|
**When to use:** Start storing a multi-turn exchange. Do this when the session contains valuable dialog worth preserving.
|
|
143
178
|
|
|
144
179
|
```
|
|
145
|
-
conversation_create(agent_id="
|
|
146
|
-
title="Debugging the auth middleware"
|
|
180
|
+
conversation_create(agent_id="claude_desktop",
|
|
181
|
+
title="Debugging the auth middleware",
|
|
182
|
+
datapack_id="<uuid from datapack_list>")
|
|
147
183
|
```
|
|
148
184
|
|
|
185
|
+
`datapack_id` is required whenever no server-side default resolves for the caller. Omitting it in that state returns `{"error": "datapack_id_required"}` and persists nothing; the same contract applies to `conversation_add_message`, `conversation_get`, `conversation_update`, and `conversation_delete`.
|
|
186
|
+
|
|
149
187
|
**Response:**
|
|
150
188
|
```json
|
|
151
189
|
{"id": "conv-uuid-123", "title": "Debugging the auth middleware"}
|
|
@@ -216,7 +254,7 @@ conversation_delete(conversation_id="conv-uuid-123", agent_id="agent")
|
|
|
216
254
|
|
|
217
255
|
## Knowledge Base Tools
|
|
218
256
|
|
|
219
|
-
**KB ingestion is a UI-only activity.** Users upload files via the datapack's Actions → **Add Knowledge** dialog (PDF/TXT/MD/JSON/MP4, 5MB each, 10/batch). `knowledgebase_search
|
|
257
|
+
**KB ingestion is a UI-only activity.** Users upload files via the datapack's Actions → **Add Knowledge** dialog (PDF/TXT/MD/JSON/MP4, 5MB each, 10/batch). MCP exposes two KB tools: `knowledgebase_search`, and `knowledgebase_delete_document` for removing a single uploaded file.
|
|
220
258
|
|
|
221
259
|
See `tools-rag-workflow.md` for the decision table.
|
|
222
260
|
|
|
@@ -244,6 +282,17 @@ Populated KBs return results with chunk content and similarity scores. An empty/
|
|
|
244
282
|
|
|
245
283
|
---
|
|
246
284
|
|
|
285
|
+
### knowledgebase_delete_document
|
|
286
|
+
|
|
287
|
+
Permanently deletes ONE knowledge-base file — its chunks and metadata in one transaction, plus a best-effort delete of the stored file. Irreversible: confirm with the user before calling, and take `document_id` from `knowledgebase_search` hits — hits carry `document_id` but NOT a filename, so confirm by echoing the id and the matched chunk text (the documents list API / Meko UI is the authoritative name source). Never guess an id; non-UUID values are rejected.
|
|
288
|
+
|
|
289
|
+
```
|
|
290
|
+
knowledgebase_delete_document(document_id="<uuid from a search hit>",
|
|
291
|
+
conversation_id="<session conversation id>")
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Returns `{"document_id", "chunks_deleted", "s3_deleted"}` — if `s3_deleted` is `false`, say so: the index entries are gone but the stored file may remain. Errors include a numeric `status`: `403` means the user is not the datapack owner, a maintainer, or the file's uploader — report it, don't retry; `409` (`DOCUMENT_PROCESSING`) means the file is still being indexed — wait for indexing to finish, then retry.
|
|
295
|
+
|
|
247
296
|
## Artifact Tools
|
|
248
297
|
|
|
249
298
|
### artifact_put
|
|
@@ -326,21 +375,34 @@ For large files use `local_path` to read the file. S3 URLs are never exposed.
|
|
|
326
375
|
### datapack_create / datapack_list / datapack_describe
|
|
327
376
|
|
|
328
377
|
```
|
|
329
|
-
datapack_create(name="analytics_prod")
|
|
378
|
+
datapack_create(name="analytics_prod", conversation_id="<conversation id>")
|
|
330
379
|
datapack_list(conversation_id="<this conversation's id>") # returns datapack_id for each datapack
|
|
331
|
-
datapack_describe(datapack_id="<uuid>", include_status=True)
|
|
380
|
+
datapack_describe(datapack_id="<uuid>", include_status=True, conversation_id="<conversation id>")
|
|
332
381
|
```
|
|
333
382
|
|
|
383
|
+
`datapack_describe` returns these counts:
|
|
384
|
+
|
|
385
|
+
| Field | Meaning |
|
|
386
|
+
|---|---|
|
|
387
|
+
| `memory_count` | All memories stored in the datapack |
|
|
388
|
+
| `collective_memory_count` | Memories promoted to shared knowledge |
|
|
389
|
+
| `learnings_count` | Memories awaiting a promotion decision |
|
|
390
|
+
| `knowledge_base_file_count` | Uploaded KB documents; `null` if the status endpoint is unreachable |
|
|
391
|
+
| `knowledge_chunk_count` | KB chunks across all documents (for debugging retrieval) |
|
|
392
|
+
| `shared_knowledge_count` | `collective_memory_count + knowledge_base_file_count`; `null` when the file count is `null` |
|
|
393
|
+
|
|
394
|
+
`knowledge_count` is a deprecated alias of `knowledge_chunk_count`. `datapack_list` doesn't compute counts; call `datapack_describe` for them.
|
|
395
|
+
|
|
334
396
|
### datapack_update / datapack_delete
|
|
335
397
|
|
|
336
398
|
`datapack_update` renames a datapack, edits its description, and/or opts it in/out of conversation-search embedding. At least one of `name` / `description` / `conversation_search_opt_out` must be provided (or the tool returns `nothing_to_update`). The server refuses to rename `meko_default_datapack` — the error is `"meko_default_datapack cannot be renamed"`. Passing `description=""` does NOT clear an existing description. `conversation_search_opt_out=True` stops future turns from being indexed and is restricted to the datapack's owner or a maintainer. This is best-effort, not a hard guarantee — a transient database error on the live embed path's opt-out check fails open, so a turn can occasionally still get embedded for an opted-out datapack.
|
|
337
399
|
|
|
338
400
|
```
|
|
339
|
-
datapack_update(datapack_id="<uuid>", name="renamed-datapack")
|
|
340
|
-
datapack_update(datapack_id="<uuid>", description="new description")
|
|
341
|
-
datapack_update(datapack_id="<uuid>", name="x", description="y")
|
|
342
|
-
datapack_update(datapack_id="<uuid>", conversation_search_opt_out=True)
|
|
343
|
-
datapack_delete(datapack_id="<uuid>") # Irreversible!
|
|
401
|
+
datapack_update(datapack_id="<uuid>", name="renamed-datapack", conversation_id="<conversation id>")
|
|
402
|
+
datapack_update(datapack_id="<uuid>", description="new description", conversation_id="<conversation id>")
|
|
403
|
+
datapack_update(datapack_id="<uuid>", name="x", description="y", conversation_id="<conversation id>")
|
|
404
|
+
datapack_update(datapack_id="<uuid>", conversation_search_opt_out=True, conversation_id="<conversation id>")
|
|
405
|
+
datapack_delete(datapack_id="<uuid>", conversation_id="<conversation id>") # Irreversible!
|
|
344
406
|
```
|
|
345
407
|
|
|
346
408
|
### Agent and knowledge-base management (NOT MCP — control-plane only)
|
|
@@ -350,4 +412,4 @@ Agent and KB lifecycle does not ship as MCP tools. If the user asks to create/li
|
|
|
350
412
|
- REST: `POST/GET/DELETE /datapacks/:datapack_id/agents` (agents), `POST/GET/DELETE /datapacks/:datapack_id/knowledge-bases` (KB sources).
|
|
351
413
|
- Or the Meko Cloud UI at `cloud.mekodata.ai` → Datapacks → agents / knowledge-bases.
|
|
352
414
|
|
|
353
|
-
KB ingestion specifically lives in the UI today: Datapack → Actions → **Add Knowledge** (PDF/TXT/MD/JSON/MP4, 5 MB each, 10/batch). Agents querying a populated index use `knowledgebase_search` — see `tools-rag-workflow.md`.
|
|
415
|
+
KB ingestion specifically lives in the UI today: Datapack → Actions → **Add Knowledge** (PDF/TXT/MD/JSON/MP4, 5 MB each, 10/batch). Agents querying a populated index use `knowledgebase_search`, and can remove a single uploaded file with `knowledgebase_delete_document` — see `tools-rag-workflow.md`.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
These are current limitations of the Meko MCP tools. Know them upfront to avoid wasted tool calls.
|
|
4
4
|
|
|
5
|
-
## No
|
|
5
|
+
## No MCP tools for index / source / pipeline lifecycle
|
|
6
6
|
|
|
7
7
|
There are no MCP tools to:
|
|
8
8
|
- Delete a vector index
|
|
@@ -10,7 +10,7 @@ There are no MCP tools to:
|
|
|
10
10
|
- Clear stuck work queue entries
|
|
11
11
|
- Reset a failed pipeline
|
|
12
12
|
|
|
13
|
-
KB
|
|
13
|
+
The one exception is a single uploaded **file**: `knowledgebase_delete_document` removes that file's chunks and metadata. KB-**source** deletion (the registered source, not one file) happens via the Meko control plane (REST: `DELETE /datapacks/:datapack_id/knowledge-bases`, or the UI): it unregisters the source from the Meko API but does **not** touch the actual `dist_rag` index, source records, or vector data in the datapack's database.
|
|
14
14
|
|
|
15
15
|
**Workaround:** For stuck or failed indexes, create a new index with a different name. Stale indexes remain in the database until manually cleaned up by an admin.
|
|
16
16
|
|
|
@@ -56,8 +56,25 @@ The skill description is tuned to its 1024-char ceiling; broadening it further d
|
|
|
56
56
|
2. **Server-side guidance** — the `agent_id` tool docstrings and the server's connect-time instructions name `claude_desktop` as this client's bucket, so even a skill-less tool-search call avoids the wrong-bucket (`claude_code`) write.
|
|
57
57
|
3. Nothing is lost when the *user* explicitly recalls or saves — only passive capture of in-passing facts is best-effort.
|
|
58
58
|
|
|
59
|
-
##
|
|
59
|
+
## memory_delete_all is agent-scoped; memory reads are not
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
`memory_search` and `memory_get_all` return every agent's rows for the user. `memory_delete_all` deletes only rows in the `agent_id` you pass, and an omitted `agent_id` means the `meko_agent` bucket. A `memory_search(run_id=X)` preview can therefore list rows that `memory_delete_all(run_id=X)` leaves in place. To clear rows written by several agents, delete them by id with `memory_delete_by_id`, or call `memory_delete_all` once per `agent_id` shown in the preview.
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
## Promoted memories are read-only through MCP
|
|
64
|
+
|
|
65
|
+
`memory_update` and `memory_delete_by_id` return `memory_is_promoted` for a memory that has been promoted to shared knowledge. Edit or remove promoted content in the Cloud UI Learnings tab.
|
|
66
|
+
|
|
67
|
+
## Conversation search covers embedded turns only
|
|
68
|
+
|
|
69
|
+
`context_search` searches past conversation turns by meaning in its `conversation` bucket. Only turns embedded into the conversation-search cache are searchable. Turns are embedded by default, except when:
|
|
70
|
+
|
|
71
|
+
- the datapack opted out with `datapack_update(datapack_id=..., conversation_search_opt_out=True, conversation_id=...)`;
|
|
72
|
+
- the account hit the embedding quota (`conversation_search_skipped: "quota_exceeded"`); or
|
|
73
|
+
- the turn was too short to carry content (the server skips trivial turns); or
|
|
74
|
+
- the turn was stored before conversation search was enabled.
|
|
75
|
+
|
|
76
|
+
To find a conversation by other attributes, browse with `conversation_list` and inspect candidates with `conversation_get`.
|
|
77
|
+
|
|
78
|
+
## Very long conversations can't be read back
|
|
79
|
+
|
|
80
|
+
When a conversation's trace grows too large for Langfuse, `conversation_get` and `conversation_update` return `{"error": "not_found", "detail": "Conversation <id> not found"}` or time out for that conversation, even though `conversation_add_message` and `conversation_delete` still work. Servers without the MEKO-714 fix instead return `not_found` from `conversation_add_message` on these conversations. If read-back or a write fails with `not_found` on a long conversation that you know exists, report the failure as a server-side limit on that conversation. Don't recreate the conversation under the same id or replay its messages; that makes the trace larger.
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
Memory is backed by pgvector. Search is hybrid: semantic similarity, keyword matching, and a boost for memories that mention the entities named in your query (people, projects, tools). It retrieves relevant facts by meaning, not by conversation order.
|
|
12
12
|
|
|
13
13
|
```
|
|
14
|
-
memory_add(agent_id="
|
|
15
|
-
text="Customer Alice (alice@acme.com) prefers email, has Pro plan."
|
|
14
|
+
memory_add(agent_id="claude_desktop", conversation_id="<id>",
|
|
15
|
+
text="Customer Alice (alice@acme.com) prefers email, has Pro plan.")
|
|
16
16
|
|
|
17
|
-
memory_search(query="What plan does Alice have?", agent_id="
|
|
17
|
+
memory_search(query="What plan does Alice have?", agent_id="claude_desktop", conversation_id="<id>")
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
## Use `conversation_create` + `conversation_add_message` when storing:
|
|
@@ -26,22 +26,26 @@ memory_search(query="What plan does Alice have?", agent_id="support_bot")
|
|
|
26
26
|
Conversations are backed by Langfuse sessions and traces. They preserve full structure: who said what, in what order, with what reasoning.
|
|
27
27
|
|
|
28
28
|
```
|
|
29
|
-
conversation_create(agent_id="
|
|
29
|
+
conversation_create(agent_id="claude_desktop", title="Pricing discussion",
|
|
30
|
+
datapack_id="<uuid from datapack_list>")
|
|
30
31
|
-- Returns: {"id": "conv-uuid-here"}
|
|
31
32
|
|
|
32
|
-
conversation_add_message(conversation_id="conv-uuid-here", agent_id="
|
|
33
|
+
conversation_add_message(conversation_id="conv-uuid-here", agent_id="claude_desktop",
|
|
34
|
+
datapack_id="<uuid from datapack_list>",
|
|
33
35
|
input="What are your pricing tiers?",
|
|
34
36
|
output="We offer Starter ($10/mo), Pro ($50/mo), and Enterprise (custom).",
|
|
35
37
|
reasoning="Retrieved pricing page data. No special discounts apply.")
|
|
36
38
|
```
|
|
37
39
|
|
|
40
|
+
`datapack_id` is required for both calls whenever no server-side default resolves for the caller. Omitting it in that state returns `{"error": "datapack_id_required"}` and persists nothing.
|
|
41
|
+
|
|
38
42
|
## Decision Matrix
|
|
39
43
|
|
|
40
44
|
| Signal | Tool |
|
|
41
45
|
|--------|------|
|
|
42
46
|
| "remember that...", "note that...", "keep in mind..." | `memory_add` |
|
|
43
47
|
| "store this conversation", "save this chat" | `conversation_create` + `conversation_add_message` |
|
|
44
|
-
| "what do you know about X?", "recall..." | `
|
|
48
|
+
| "what do you know about X?", "recall..." | `context_search` |
|
|
45
49
|
| "show me our past conversation about..." | `conversation_list` + `conversation_get` |
|
|
46
50
|
| "the user prefers...", "their budget is..." | `memory_add` |
|
|
47
51
|
| "save my query and your response" | `conversation_add_message` |
|
|
@@ -89,14 +93,13 @@ One `memory_search` already spans this user's memories across all agents; no per
|
|
|
89
93
|
|
|
90
94
|
### When the user asks "what do you know about X?"
|
|
91
95
|
|
|
92
|
-
|
|
96
|
+
Call `context_search`:
|
|
93
97
|
|
|
94
98
|
```
|
|
95
|
-
|
|
96
|
-
knowledgebase_search(agent_id="<anything>", datapack_id="<uuid>", query="X", conversation_id=..., ...)
|
|
99
|
+
context_search(agent_id="claude_desktop", query="X", conversation_id=..., datapack_id="<uuid>")
|
|
97
100
|
```
|
|
98
101
|
|
|
99
|
-
|
|
102
|
+
Its memory bucket includes everything this user and their other agents wrote in the datapack. The KB bucket holds team-shared knowledge, and the conversation bucket holds matching past turns from anyone on the datapack. If the memory or KB bucket is empty, confirm with `memory_search` or `knowledgebase_search` before saying nothing is there, because `context_search` returns an empty list for a failed source.
|
|
100
103
|
|
|
101
104
|
When you answer, be explicit about scope so the user knows why something is or isn't there:
|
|
102
105
|
|
|
@@ -146,6 +149,7 @@ The full transcript including:
|
|
|
146
149
|
- **Assistant responses** — all text blocks (the `output` field)
|
|
147
150
|
- **Tool calls** — tool name + input parameters (the `reasoning` field)
|
|
148
151
|
- **Tool results** — output from tool executions (appended to `reasoning`)
|
|
152
|
+
- **Injected context** — skill bodies, background-task notifications, and subagent reports that the client writes into the transcript (appended to `reasoning` of the turn they belong to, never used as `input`)
|
|
149
153
|
|
|
150
154
|
This is more than just text — tool calls and results are critical context for session replay, cross-agent sharing, and compaction.
|
|
151
155
|
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
# Complete Tool Catalog and Decision Tree
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**25 Meko data tools covered by this skill.** These are the tools available in production, grouped as: Retrieval (1), Memory (8), Conversation (6), Knowledge Base (2), Datapack (5), Artifacts (2), Observability (1). Combined Meko + AMP endpoints may expose additional infrastructure tools; those are outside this skill's scope.
|
|
4
4
|
|
|
5
5
|
## Quick health check before using tools
|
|
6
6
|
|
|
7
7
|
Before starting a session, verify that the Meko MCP tools are working:
|
|
8
8
|
|
|
9
|
-
1. `memory_search(query="test", agent_id="
|
|
9
|
+
1. `memory_search(query="test", agent_id="claude_desktop", conversation_id="<id from conversation_create>")` — Confirms memory subsystem is up. May fail with "connection already closed" — see `tools-troubleshooting.md`.
|
|
10
10
|
2. `datapack_list(conversation_id="<this conversation's id>")` — Confirms Meko API connectivity. Returns the datapacks your token has access to.
|
|
11
11
|
|
|
12
12
|
## Decision tree: which tool do I need?
|
|
13
13
|
|
|
14
14
|
```
|
|
15
15
|
User wants to...
|
|
16
|
+
├── Ask "what do you know about X?" --------> context_search (read; memory + KB + past conversations in one call)
|
|
16
17
|
├── Search personal context? ---------------> memory_search (read)
|
|
17
18
|
├── Search shared datapack knowledge? ------> knowledgebase_search (read)
|
|
18
19
|
├── Add documents to a knowledge base? -----> point user at Meko UI: Datapack → Actions → Add Knowledge
|
|
19
|
-
|
|
20
|
+
├── Delete ONE knowledge-base file? --------> knowledgebase_delete_document (destructive — confirm with the user first)
|
|
20
21
|
├── Store or recall information?
|
|
21
22
|
│ ├── Store a fact/preference/entity? -----------> memory_add (write)
|
|
22
23
|
│ ├── Store a full conversation (multi-turn)? ---> conversation_create + conversation_add_message (write)
|
|
@@ -30,47 +31,56 @@ User wants to...
|
|
|
30
31
|
└── CRUD datapack? --------------------> datapack_create/list/describe/update/delete
|
|
31
32
|
```
|
|
32
33
|
|
|
33
|
-
Agent /
|
|
34
|
+
Agent lifecycle and KB **ingestion / index lifecycle** (adding sources, uploads, re-indexing) are managed outside the MCP surface — typically in the Meko control-plane UI. Deleting a single KB file IS exposed here (`knowledgebase_delete_document`).
|
|
34
35
|
|
|
35
|
-
##
|
|
36
|
+
## Retrieval Tools (1)
|
|
36
37
|
|
|
37
38
|
| Tool | Purpose |
|
|
38
39
|
|------|---------|
|
|
39
|
-
| `
|
|
40
|
+
| `context_search(query, conversation_id, agent_id=None, datapack_id=None, limit=10, force_source="auto")` | Default first call for open-ended recall. Queries memory, the knowledge base, and the conversation-history cache in parallel and returns each source in its own bucket: `{"results": {"memory": [...], "knowledge_base": [...], "conversation": {"hits": [...], "thread": [...]}}, "token_savings": {...}}`. A bucket is `null` only when that source wasn't queried: `force_source` excluded it, or the server couldn't build a query vector for it. An empty bucket is ambiguous: either that source found nothing relevant, or it failed. `context_search` turns a failed source into an empty list and records the error only in the trace. Before you tell the user nothing is stored about X, confirm with `memory_search` or `knowledgebase_search`, which return errors. `force_source` is `"auto"` (all three), `"memory"`, `"knowledge_base"`, or `"conversation"`; any other value returns `invalid_force_source`. `limit` bounds the memory and KB buckets only; the conversation bucket returns up to 10 hits plus a thread of whole turns. The conversation bucket is datapack-wide. It returns embedded turns from every user and agent on the datapack, and each hit carries its author's `user_id`. Don't present a hit as this user's own history. |
|
|
41
|
+
|
|
42
|
+
## Knowledge Base Tools (2)
|
|
43
|
+
|
|
44
|
+
| Tool | Purpose |
|
|
45
|
+
|------|---------|
|
|
46
|
+
| `knowledgebase_search(query, conversation_id, datapack_id, agent_id=None, limit=10)` | Hybrid (semantic + keyword) search across KB chunks and promoted memories. `datapack_id` is REQUIRED (no default). Each hit has `id`, `chunk_text`, `document_id`, `metadata_filters`, `distance`, and `match_type` (`semantic`, `keyword`, or `hybrid`). |
|
|
47
|
+
| `knowledgebase_delete_document(document_id, conversation_id, datapack_id="")` | Permanently delete ONE KB file (chunks + metadata; stored-file delete is best-effort — check `s3_deleted`). Irreversible: confirm with the user first. `document_id` comes from `knowledgebase_search` hits (no filename in hits — echo the id + chunk text). Owner/maintainer/uploader only (status 403 otherwise); status 409 while still indexing — wait and retry. |
|
|
40
48
|
|
|
41
49
|
## Memory Tools (8)
|
|
42
50
|
|
|
43
51
|
| Tool | Purpose |
|
|
44
52
|
|------|---------|
|
|
45
|
-
| `memory_add(text,
|
|
46
|
-
| `memory_search(query,
|
|
47
|
-
| `memory_get_by_id(memory_id,
|
|
48
|
-
| `memory_get_all(
|
|
49
|
-
| `memory_update(memory_id, text,
|
|
50
|
-
| `memory_delete_by_id(memory_id,
|
|
51
|
-
| `memory_delete_all(
|
|
52
|
-
| `memory_promote(conversation_id, memory_ids, agent_id=None, datapack_id=None)` | Promote private memories into the datapack's shared knowledge base (moves them out of mem0, then evicts from mem0 — one-way). Owners/maintainers only; viewers/contributors get 403.
|
|
53
|
+
| `memory_add(text, conversation_id, agent_id=None, run_id=None, metadata=None, messages=None, datapack_id=None)` | Store fact/preference/entity as long-term memory |
|
|
54
|
+
| `memory_search(query, conversation_id, agent_id=None, limit=10, datapack_id=None, run_id=None)` | Hybrid search across memories (semantic + keyword + entity boost). Drops rows below a server-configured similarity floor (default 0.2), so a weak query can return an empty list. `conversation_id` is required but only nests the trace. It must be a 32-hex id: `""` currently fails (MEKO-707), so pass a freshly generated one if you have no conversation yet. `run_id` filters to one conversation's memories. |
|
|
55
|
+
| `memory_get_by_id(memory_id, conversation_id, agent_id=None, datapack_id=None)` | Direct pgvector row lookup by UUID. Preferred over `memory_search` for exact-id verification. Returns `not_found` for a missing id and for an id that belongs to another account. |
|
|
56
|
+
| `memory_get_all(conversation_id, agent_id=None, run_id=None, datapack_id=None, promoted=False)` | Recent window (about 20 rows) of the user's memories across every agent, plus the true `total`. Not a complete listing. `promoted=True` returns the recent window of promoted memories instead. `run_id` is ignored. |
|
|
57
|
+
| `memory_update(memory_id, text, conversation_id, agent_id=None, datapack_id=None)` | Overwrite memory text. Returns `memory_is_promoted` for a promoted memory (edit those in the Cloud UI Learnings tab). |
|
|
58
|
+
| `memory_delete_by_id(memory_id, conversation_id, agent_id=None, datapack_id=None)` | Delete a single memory. Returns `memory_is_promoted` for a promoted memory. |
|
|
59
|
+
| `memory_delete_all(conversation_id, agent_id=None, run_id=None, datapack_id=None)` | Delete all memories in the **passed `agent_id`'s bucket** (destructive). Unlike reads, this is agent-scoped: omitting `agent_id` deletes only the `meko_agent` bucket. `run_id` narrows it to one conversation; a malformed value returns `invalid_run_id`. |
|
|
60
|
+
| `memory_promote(conversation_id, memory_ids, agent_id=None, datapack_id=None)` | Promote private memories into the datapack's shared knowledge base (moves them out of mem0, then evicts from mem0 — one-way). Owners/maintainers only; viewers/contributors get 403. |
|
|
53
61
|
|
|
54
62
|
## Conversation Tools (6)
|
|
55
63
|
|
|
56
64
|
| Tool | Purpose |
|
|
57
65
|
|------|---------|
|
|
58
|
-
| `conversation_create(agent_id
|
|
59
|
-
| `conversation_add_message(conversation_id,
|
|
60
|
-
| `conversation_get(conversation_id, agent_id, include_messages=False, limit=100, offset=0)` | Retrieve conversation, optionally with messages |
|
|
61
|
-
| `conversation_list(agent_id=None, limit=20, offset=0, conversation_id="", datapack_id=None)` | List
|
|
62
|
-
| `conversation_update(conversation_id, agent_id, title=None, metadata=None)` | Update title or metadata |
|
|
63
|
-
| `conversation_delete(conversation_id, agent_id)` | Delete entire conversation (destructive) |
|
|
66
|
+
| `conversation_create(agent_id=None, run_id=None, title=None, metadata=None, session_id="", datapack_id=None)` | Create conversation container (Langfuse session) |
|
|
67
|
+
| `conversation_add_message(conversation_id, input, output, agent_id=None, reasoning=None, metadata=None, seed=None, datapack_id=None, plan=None)` | Add a message turn (Langfuse trace). `output` is required. The response may include `extracted_memories` and, when the turn wasn't embedded for conversation search, `conversation_search_skipped` (`quota_exceeded` or `datapack_opted_out`). |
|
|
68
|
+
| `conversation_get(conversation_id, agent_id=None, include_messages=False, limit=100, offset=0, datapack_id=None)` | Retrieve conversation, optionally with messages |
|
|
69
|
+
| `conversation_list(agent_id=None, limit=20, offset=0, conversation_id="", datapack_id=None)` | List the user's conversations within a datapack (`agent_id` does not filter — trace attribution only). `datapack_id` (UUID) is optional — defaults to the pinned/tenant datapack; use `datapack_list` to look it up. `conversation_id` optional (omit for browse). |
|
|
70
|
+
| `conversation_update(conversation_id, agent_id=None, title=None, metadata=None, datapack_id=None)` | Update title or metadata |
|
|
71
|
+
| `conversation_delete(conversation_id, agent_id=None, datapack_id=None)` | Delete entire conversation (destructive) |
|
|
64
72
|
|
|
65
73
|
## Datapack Management Tools (5)
|
|
66
74
|
|
|
67
75
|
| Tool | Purpose |
|
|
68
76
|
|------|---------|
|
|
69
|
-
| `datapack_create(name)` | Create new datapack |
|
|
77
|
+
| `datapack_create(name, conversation_id)` | Create new datapack |
|
|
70
78
|
| `datapack_list(conversation_id, datapack_id=None)` | List all datapacks. `conversation_id` is required for trace nesting; omit `datapack_id` to use the endpoint default. |
|
|
71
|
-
| `datapack_describe(datapack_id, include_status=False)` | Describe datapack by UUID |
|
|
72
|
-
| `datapack_update(datapack_id, name=None, description=None)` | Rename a datapack and/or
|
|
73
|
-
| `datapack_delete(datapack_id)` | Delete datapack by UUID (irreversible) |
|
|
79
|
+
| `datapack_describe(conversation_id, datapack_id="", include_status=False)` | Describe a datapack by UUID (default datapack if omitted). Returns `memory_count`, `collective_memory_count` (promoted), `learnings_count` (awaiting a promotion decision), `knowledge_base_file_count`, `knowledge_chunk_count`, and `shared_knowledge_count`. `knowledge_base_file_count` and `shared_knowledge_count` are `null` when the status endpoint is unreachable; `knowledge_count` is a deprecated alias of `knowledge_chunk_count`. |
|
|
80
|
+
| `datapack_update(datapack_id, conversation_id, name=None, description=None, conversation_search_opt_out=None)` | Rename a datapack, update its description, and/or opt out of (or back into) conversation-search caching. Pass at least one field. Opt-out is owner/maintainer only. |
|
|
81
|
+
| `datapack_delete(datapack_id, conversation_id)` | Delete datapack by UUID (irreversible) |
|
|
82
|
+
|
|
83
|
+
All five datapack tools reject an empty `conversation_id` with `conversation_id_required`.
|
|
74
84
|
|
|
75
85
|
## Artifact Tools (2)
|
|
76
86
|
|
|
@@ -104,4 +114,4 @@ For knowledge-base content on Cloud, the canonical path is **UI upload**: Datapa
|
|
|
104
114
|
|
|
105
115
|
## Common Parameter Patterns
|
|
106
116
|
|
|
107
|
-
Memory and KB tools accept optional `datapack_id` to target a specific datapack.
|
|
117
|
+
Memory and KB tools accept optional `datapack_id` to target a specific datapack. A `datapack_id` your account can't access returns `datapack_access_denied`. `agent_id` attributes writes. Conversations are agent-owned: `conversation_get`, `conversation_add_message`, `conversation_update`, and `conversation_delete` return `agent_id_mismatch` for any value other than the creating agent's. `agent_id` does **not** filter memory reads (`memory_search`/`memory_get_all`) or `conversation_list`, which return all your agents' rows for the user. `memory_delete_all` is the exception on the memory side: it deletes only the passed `agent_id`'s bucket. See `tools-agent-id-conventions.md`.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Knowledge Base / RAG workflow
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
MCP exposes two KB tools: `knowledgebase_search` (retrieval) and
|
|
4
|
+
`knowledgebase_delete_document` (remove ONE uploaded file). Index
|
|
4
5
|
creation and ingestion happen out of band — through the **Meko UI**
|
|
5
6
|
(`cloud.mekodata.ai`).
|
|
6
7
|
|
|
@@ -8,9 +9,10 @@ creation and ingestion happen out of band — through the **Meko UI**
|
|
|
8
9
|
|
|
9
10
|
| Situation | Use this | Why |
|
|
10
11
|
|---|---|---|
|
|
11
|
-
| Search an existing KB | `knowledgebase_search` |
|
|
12
|
+
| Search an existing KB | `knowledgebase_search` | Retrieval over the indexed chunks |
|
|
12
13
|
| Add documents to a KB | **Meko UI** — Datapack → Actions → **Add Knowledge** | File-upload dialog (PDF/TXT/MD/JSON/MP4, 5 MB each, 10/batch). No MCP equivalent |
|
|
13
|
-
|
|
|
14
|
+
| Delete ONE uploaded file | `knowledgebase_delete_document` | Destructive; `document_id` from search hits; confirm with the user first |
|
|
15
|
+
| Anything else (list / rename / re-index / source lifecycle) | **UI** | No MCP tools for the rest of KB lifecycle |
|
|
14
16
|
|
|
15
17
|
## knowledgebase_search — the one you'll actually call
|
|
16
18
|
|
|
@@ -23,7 +25,7 @@ knowledgebase_search(
|
|
|
23
25
|
limit=10)
|
|
24
26
|
```
|
|
25
27
|
|
|
26
|
-
Required: `query`, `
|
|
28
|
+
Required: `query`, `conversation_id`, `datapack_id`.
|
|
27
29
|
Unlike the memory tools, `datapack_id` has no default here — you must
|
|
28
30
|
pass it explicitly. `agent_id` is **ignored for filtering** on this
|
|
29
31
|
tool (KB results are team-shared on the datapack), but you still pass
|
|
@@ -37,10 +39,12 @@ Populated KB:
|
|
|
37
39
|
{
|
|
38
40
|
"results": [
|
|
39
41
|
{
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
42
|
+
"id": "<chunk id>",
|
|
43
|
+
"chunk_text": "<chunk text>",
|
|
44
|
+
"document_id": "<KB document id; pass to knowledgebase_delete_document>",
|
|
45
|
+
"metadata_filters": {},
|
|
46
|
+
"distance": 0.31,
|
|
47
|
+
"match_type": "semantic" | "keyword" | "hybrid",
|
|
44
48
|
...
|
|
45
49
|
},
|
|
46
50
|
...
|
|
@@ -49,6 +53,8 @@ Populated KB:
|
|
|
49
53
|
}
|
|
50
54
|
```
|
|
51
55
|
|
|
56
|
+
Lower `distance` is closer. Promoted memories appear as hits whose `metadata_filters.source` is `"memory"`. Hits carry no filename, so show the user the `document_id` and chunk text when they need to identify a file.
|
|
57
|
+
|
|
52
58
|
Empty or nonexistent KB: `{"results": [], "count": 0}` (no error,
|
|
53
59
|
just an empty array).
|
|
54
60
|
|