bikky 0.4.3 → 0.4.4
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 +60 -35
- package/dist/config.d.ts +5 -1
- package/dist/config.js +28 -0
- package/dist/daemon/capture-policy.js +0 -1
- package/dist/daemon/consolidation.js +4 -4
- package/dist/daemon/extraction.d.ts +1 -1
- package/dist/daemon/extraction.js +13 -5
- package/dist/daemon/loop.js +8 -0
- package/dist/daemon/maintenance-state.d.ts +1 -1
- package/dist/daemon/maintenance-state.js +2 -0
- package/dist/daemon/qdrant.js +30 -8
- package/dist/daemon/quality-rollups.d.ts +51 -0
- package/dist/daemon/quality-rollups.js +378 -0
- package/dist/daemon/relations.js +1 -1
- package/dist/daemon/staleness.js +1 -1
- package/dist/lifecycle.js +7 -5
- package/dist/mcp/helpers.d.ts +3 -0
- package/dist/mcp/helpers.js +9 -0
- package/dist/mcp/taxonomy.d.ts +9 -13
- package/dist/mcp/taxonomy.js +47 -41
- package/dist/mcp/tools.js +190 -26
- package/dist/mcp/types.d.ts +23 -0
- package/dist/prompts/brief.d.ts +2 -2
- package/dist/prompts/brief.js +0 -1
- package/dist/prompts/extraction.js +9 -11
- package/dist/provenance/origin.d.ts +1 -1
- package/dist/routing-context.d.ts +16 -0
- package/dist/routing-context.js +55 -0
- package/dist/status.d.ts +1 -0
- package/dist/status.js +7 -1
- package/docs/config/hosted-qdrant-local-models.md +1 -0
- package/docs/config/local.md +1 -0
- package/docs/configuration.md +28 -21
- package/package.json +1 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const appendRoutingText = (parts, value) => {
|
|
2
|
+
if (value === null || value === undefined)
|
|
3
|
+
return;
|
|
4
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
5
|
+
const text = String(value).trim();
|
|
6
|
+
if (text)
|
|
7
|
+
parts.push(text);
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (Array.isArray(value)) {
|
|
11
|
+
for (const item of value)
|
|
12
|
+
appendRoutingText(parts, item);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (typeof value === "object") {
|
|
16
|
+
for (const [key, nested] of Object.entries(value)) {
|
|
17
|
+
appendRoutingText(parts, key);
|
|
18
|
+
appendRoutingText(parts, nested);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
export const routingText = (values) => {
|
|
23
|
+
const parts = [];
|
|
24
|
+
for (const value of values)
|
|
25
|
+
appendRoutingText(parts, value);
|
|
26
|
+
return Array.from(new Set(parts)).join("\n");
|
|
27
|
+
};
|
|
28
|
+
export const buildMemoryRoutingInput = (input) => {
|
|
29
|
+
const metadata = {
|
|
30
|
+
...(input.metadata ?? {}),
|
|
31
|
+
...(input.context ?? {}),
|
|
32
|
+
};
|
|
33
|
+
return {
|
|
34
|
+
destination: input.destination,
|
|
35
|
+
cwd: input.cwd,
|
|
36
|
+
content: routingText([input.content, input.entities, metadata, ...(input.extraContent ?? [])]),
|
|
37
|
+
entities: input.entities,
|
|
38
|
+
metadata,
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
export const mergeRoutingInputs = (base, override) => {
|
|
42
|
+
if (!override)
|
|
43
|
+
return base;
|
|
44
|
+
return {
|
|
45
|
+
destination: override.destination ?? base.destination,
|
|
46
|
+
cwd: override.cwd ?? base.cwd,
|
|
47
|
+
content: routingText([base.content, override.content]),
|
|
48
|
+
entities: Array.from(new Set([...(base.entities ?? []), ...(override.entities ?? [])])),
|
|
49
|
+
metadata: {
|
|
50
|
+
...(base.metadata ?? {}),
|
|
51
|
+
...(override.metadata ?? {}),
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=routing-context.js.map
|
package/dist/status.d.ts
CHANGED
|
@@ -58,6 +58,7 @@ export interface MaintenanceStatusReport {
|
|
|
58
58
|
state_path: string;
|
|
59
59
|
relation_inference: MaintenanceJobStatus;
|
|
60
60
|
entity_typing: MaintenanceJobStatus;
|
|
61
|
+
memory_quality_rollups: MaintenanceJobStatus;
|
|
61
62
|
}
|
|
62
63
|
export interface UiStatusReport {
|
|
63
64
|
status: DiagnosticState;
|
package/dist/status.js
CHANGED
|
@@ -235,13 +235,18 @@ function collectMaintenanceStatus() {
|
|
|
235
235
|
last_summary: job.last_summary,
|
|
236
236
|
};
|
|
237
237
|
};
|
|
238
|
-
const summaries = [
|
|
238
|
+
const summaries = [
|
|
239
|
+
state.jobs.relation_inference.last_summary,
|
|
240
|
+
state.jobs.entity_typing.last_summary,
|
|
241
|
+
state.jobs.memory_quality_rollups.last_summary,
|
|
242
|
+
];
|
|
239
243
|
const hasError = summaries.some((summary) => summary?.status === "error");
|
|
240
244
|
return {
|
|
241
245
|
status: hasError ? "warn" : "ok",
|
|
242
246
|
state_path: MAINTENANCE_STATE_PATH,
|
|
243
247
|
relation_inference: jobStatus("relation_inference"),
|
|
244
248
|
entity_typing: jobStatus("entity_typing"),
|
|
249
|
+
memory_quality_rollups: jobStatus("memory_quality_rollups"),
|
|
245
250
|
};
|
|
246
251
|
}
|
|
247
252
|
async function collectUiStatus(opts) {
|
|
@@ -368,6 +373,7 @@ export function formatStatusReport(report) {
|
|
|
368
373
|
lines.push(`Daemon: ${icon(report.daemon.status)} ${report.daemon.running ? `running (PID ${report.daemon.pid})` : "stopped"}`);
|
|
369
374
|
lines.push(`Maint: ${icon(report.maintenance.status)} ${maintenanceJobSummary("relations", report.maintenance.relation_inference)}`);
|
|
370
375
|
lines.push(` ${maintenanceJobSummary("entity typing", report.maintenance.entity_typing)}`);
|
|
376
|
+
lines.push(` ${maintenanceJobSummary("quality rollups", report.maintenance.memory_quality_rollups)}`);
|
|
371
377
|
lines.push(`UI: ${icon(report.ui.status)} ${report.ui.checked ? report.ui.url : "not checked"}${report.ui.error ? ` — ${report.ui.error}` : ""}`);
|
|
372
378
|
lines.push(`MCP: ${icon(report.mcp.status)} ${report.mcp.message}`);
|
|
373
379
|
return lines.join("\n");
|
|
@@ -8,6 +8,7 @@ Use this path when you want memory shared across machines, but you still want em
|
|
|
8
8
|
- A Qdrant API key.
|
|
9
9
|
- Ollama installed locally.
|
|
10
10
|
- The default embedding model pulled with `ollama pull qwen3-embedding:0.6b`.
|
|
11
|
+
- The default LLM model pulled with `ollama pull qwen2.5:7b`.
|
|
11
12
|
|
|
12
13
|
## Config
|
|
13
14
|
|
package/docs/config/local.md
CHANGED
|
@@ -9,6 +9,7 @@ This setup is best for private/free testing rather than long-term team use. Extr
|
|
|
9
9
|
- Qdrant running locally, usually with Docker.
|
|
10
10
|
- Ollama installed locally.
|
|
11
11
|
- The default embedding model pulled with `ollama pull qwen3-embedding:0.6b`.
|
|
12
|
+
- The default LLM model pulled with `ollama pull qwen2.5:7b`.
|
|
12
13
|
|
|
13
14
|
## Config
|
|
14
15
|
|
package/docs/configuration.md
CHANGED
|
@@ -11,7 +11,7 @@ cat > ~/.bikky/config.json <<'JSON'
|
|
|
11
11
|
"embedding": {
|
|
12
12
|
"provider": "openai",
|
|
13
13
|
"model": "text-embedding-3-small",
|
|
14
|
-
"dimensions":
|
|
14
|
+
"dimensions": 1024,
|
|
15
15
|
"api_key": "sk-..."
|
|
16
16
|
},
|
|
17
17
|
"llm": {
|
|
@@ -24,7 +24,7 @@ JSON
|
|
|
24
24
|
bikky status
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
Config lives at `~/.bikky/config.json`, or at `BIKKY_HOME/config.json` when `BIKKY_HOME` is set. Environment variables override the config
|
|
27
|
+
Config lives at `~/.bikky/config.json`, or at `BIKKY_HOME/config.json` when `BIKKY_HOME` is set. Environment variables can supply or override most scalar settings. Provider API key env vars such as `OPENAI_API_KEY` and `PORTKEY_API_KEY` are fallback values when the matching `api_key` field is omitted from config; remove the config value when you want key rotation through the environment.
|
|
28
28
|
|
|
29
29
|
## Origin identity
|
|
30
30
|
|
|
@@ -64,7 +64,7 @@ Best for performance and teams. Qdrant Cloud stores vectors, and hosted embeddin
|
|
|
64
64
|
"embedding": {
|
|
65
65
|
"provider": "openai",
|
|
66
66
|
"model": "text-embedding-3-small",
|
|
67
|
-
"dimensions":
|
|
67
|
+
"dimensions": 1024,
|
|
68
68
|
"api_key": "sk-..."
|
|
69
69
|
},
|
|
70
70
|
"llm": {
|
|
@@ -88,7 +88,7 @@ Best for local vector storage with hosted extraction and embedding quality.
|
|
|
88
88
|
"embedding": {
|
|
89
89
|
"provider": "openai",
|
|
90
90
|
"model": "text-embedding-3-small",
|
|
91
|
-
"dimensions":
|
|
91
|
+
"dimensions": 1024,
|
|
92
92
|
"api_key": "sk-..."
|
|
93
93
|
},
|
|
94
94
|
"llm": {
|
|
@@ -99,7 +99,7 @@ Best for local vector storage with hosted extraction and embedding quality.
|
|
|
99
99
|
}
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
`qdrant_api_key` is optional. Leave it empty or omit it for local or unauthenticated self-hosted Qdrant. Prefer env vars for hosted model auth? Omit `api_key` above and set `OPENAI_API_KEY` instead.
|
|
102
|
+
`qdrant_api_key` is optional. Leave it empty or omit it for local or unauthenticated self-hosted Qdrant. Prefer env vars for hosted model auth? Omit `api_key` above and set `OPENAI_API_KEY` or `PORTKEY_API_KEY` for the selected provider instead.
|
|
103
103
|
|
|
104
104
|
### Local and free
|
|
105
105
|
|
|
@@ -148,15 +148,17 @@ export QDRANT_API_KEY="..." # only needed for Qdrant Cloud or authenticated sel
|
|
|
148
148
|
|
|
149
149
|
Useful basics:
|
|
150
150
|
|
|
151
|
-
| Env var
|
|
152
|
-
|
|
|
153
|
-
| `QDRANT_URL`
|
|
154
|
-
| `QDRANT_API_KEY`
|
|
155
|
-
| `
|
|
156
|
-
| `
|
|
157
|
-
| `
|
|
158
|
-
| `
|
|
159
|
-
| `
|
|
151
|
+
| Env var | Config field | Notes |
|
|
152
|
+
| ------------------ | --------------------- | --------------------------------------------------------------------------------------- |
|
|
153
|
+
| `QDRANT_URL` | `qdrant_url` | Required unless set in config |
|
|
154
|
+
| `QDRANT_API_KEY` | `qdrant_api_key` | Optional for local/unauthenticated Qdrant; usually needed for Qdrant Cloud |
|
|
155
|
+
| `OPENAI_API_KEY` | `embedding.api_key` / `llm.api_key` | Fallback key for `openai` when `api_key` is omitted from config |
|
|
156
|
+
| `PORTKEY_API_KEY` | `embedding.api_key` / `llm.api_key` | Fallback key for `portkey` when `api_key` is omitted from config |
|
|
157
|
+
| `BIKKY_HOME` | — | Moves the config/log/state directory from `~/.bikky` |
|
|
158
|
+
| `BIKKY_USER_ID` | `identity.user_id` | Explicit human user id for origin provisioning |
|
|
159
|
+
| `BIKKY_USER_NAME` | `identity.user_name` | Human-readable human user name for origin provisioning |
|
|
160
|
+
| `BIKKY_AGENT_ID` | — | Optional local automated-agent id stored in `origin.agent` |
|
|
161
|
+
| `BIKKY_AGENT_NAME` | — | Optional local automated-agent label stored in `origin.agent` |
|
|
160
162
|
|
|
161
163
|
## Provider options
|
|
162
164
|
|
|
@@ -167,7 +169,7 @@ Use these exact values in `embedding.provider` and `llm.provider`. Both fields a
|
|
|
167
169
|
| `ollama` | Yes | Yes | Local and free defaults | None |
|
|
168
170
|
| `openai` | Yes | Yes | Simple hosted models | `OPENAI_API_KEY` or `api_key` |
|
|
169
171
|
| `bedrock` | Yes | Yes | AWS-managed models | AWS credentials or IAM role |
|
|
170
|
-
| `portkey` | Yes | Yes | Gateway/routing over other providers |
|
|
172
|
+
| `portkey` | Yes | Yes | Gateway/routing over other providers | `PORTKEY_API_KEY` or `api_key` |
|
|
171
173
|
|
|
172
174
|
## Advanced configuration
|
|
173
175
|
|
|
@@ -193,7 +195,7 @@ These sections are optional references for custom providers, tuning, scoping, an
|
|
|
193
195
|
| `embedding.model` | `EMBEDDING_MODEL` | `qwen3-embedding:0.6b` | Embedding model name |
|
|
194
196
|
| `embedding.dimensions` | `EMBEDDING_DIMENSIONS` | `1024` | Must match the selected model output |
|
|
195
197
|
| `embedding.base_url` | `EMBEDDING_BASE_URL` | `http://localhost:11434` | Used by local or OpenAI-compatible providers |
|
|
196
|
-
| `embedding.api_key` | `OPENAI_API_KEY`
|
|
198
|
+
| `embedding.api_key` | `OPENAI_API_KEY` / `PORTKEY_API_KEY` | — | Provider API key; env vars are fallback when omitted from config |
|
|
197
199
|
|
|
198
200
|
Common model dimensions:
|
|
199
201
|
|
|
@@ -205,7 +207,7 @@ Common model dimensions:
|
|
|
205
207
|
| `openai` | `text-embedding-3-large` | `3072` |
|
|
206
208
|
| `bedrock` | `amazon.titan-embed-text-v2:0` | `1024` |
|
|
207
209
|
|
|
208
|
-
|
|
210
|
+
bikky's examples use `1024` because that is the portable default across supported providers. OpenAI 3-series embedding models can return their larger native dimensions above, but they also support shorter outputs; if you change `embedding.dimensions`, make sure the selected model and every Qdrant collection use the same dimension.
|
|
209
211
|
|
|
210
212
|
#### LLM
|
|
211
213
|
|
|
@@ -216,7 +218,7 @@ The LLM is used by background maintenance features. Ollama is the default.
|
|
|
216
218
|
| `llm.provider` | `LLM_PROVIDER` | `ollama` | One of `ollama`, `openai`, `bedrock`, `portkey` |
|
|
217
219
|
| `llm.model` | `LLM_MODEL` | `qwen2.5:7b` | LLM model name |
|
|
218
220
|
| `llm.base_url` | `LLM_BASE_URL` | `http://localhost:11434` | Used by local or OpenAI-compatible providers |
|
|
219
|
-
| `llm.api_key` | `OPENAI_API_KEY`
|
|
221
|
+
| `llm.api_key` | `OPENAI_API_KEY` / `PORTKEY_API_KEY` | — | Provider API key; env vars are fallback when omitted from config |
|
|
220
222
|
| `llm.extra.region` | `AWS_BEDROCK_REGION` / `AWS_REGION` | `us-east-1` | AWS Bedrock region |
|
|
221
223
|
|
|
222
224
|
#### Timeouts and retries
|
|
@@ -243,7 +245,7 @@ Retries use jittered exponential backoff for transient errors, rate limits, and
|
|
|
243
245
|
"embedding": {
|
|
244
246
|
"provider": "portkey",
|
|
245
247
|
"model": "@openai/text-embedding-3-small",
|
|
246
|
-
"dimensions":
|
|
248
|
+
"dimensions": 1024,
|
|
247
249
|
"api_key": "pk-..."
|
|
248
250
|
},
|
|
249
251
|
"llm": {
|
|
@@ -282,7 +284,7 @@ Most users only need one Qdrant destination. Use `destinations[]` when you want
|
|
|
282
284
|
|
|
283
285
|
Each destination has its own Qdrant credentials and collection. Add `description` when you have more than one destination; MCP tools expose those descriptions so LLM clients can pick the right search scope.
|
|
284
286
|
|
|
285
|
-
Writes still target one destination. A destination can include a `match` block with JavaScript `RegExp` strings for `cwd`, `entity`, `content`, or `metadata`. Destinations are evaluated in array order; the first destination with any matching pattern wins. If no pattern matches, bikky uses the destination marked `default: true`, or the first destination.
|
|
287
|
+
Writes still target one destination. A destination can include a `match` block with JavaScript `RegExp` strings for `cwd`, `entity`, `content`, or `metadata`. For memory writes, `content` matching uses a flattened routing view of the full memory context: stored content, entities, repo, branch, task/workstream keys, metadata, origin, relation fields, and other stored payload fields. Destinations are evaluated in array order; the first destination with any matching pattern wins. If no pattern matches, bikky uses the destination marked `default: true`, or the first destination.
|
|
286
288
|
|
|
287
289
|
Read tools (`memory_recall`, `memory_entity`, and `memory_relations`) can search one destination, the routed destination, or multiple destinations. Configure `default_search_scope` to control the default read behavior:
|
|
288
290
|
|
|
@@ -298,7 +300,7 @@ MCP clients can override this per call with `search_scope`. The value accepts `"
|
|
|
298
300
|
"embedding": {
|
|
299
301
|
"provider": "openai",
|
|
300
302
|
"model": "text-embedding-3-small",
|
|
301
|
-
"dimensions":
|
|
303
|
+
"dimensions": 1024
|
|
302
304
|
},
|
|
303
305
|
"llm": {
|
|
304
306
|
"provider": "openai",
|
|
@@ -351,6 +353,7 @@ MCP clients can override this per call with `search_scope`. The value accepts `"
|
|
|
351
353
|
Matching details:
|
|
352
354
|
|
|
353
355
|
- `match.cwd`, `match.entity`, and `match.content` are lists of JavaScript `RegExp` strings.
|
|
356
|
+
- On memory writes, `match.content` sees the full flattened memory context, so a pattern can match values such as `repo`, `branch`, `task_key`, origin fields, metadata values, or relation endpoints even when the visible memory text does not contain that term.
|
|
354
357
|
- `match.metadata` maps metadata keys to lists of JavaScript `RegExp` strings matched against that key's value.
|
|
355
358
|
- Matching uses OR logic across fields and within each list; any matching pattern selects the destination.
|
|
356
359
|
- Put the most specific destinations first because first match wins.
|
|
@@ -379,6 +382,10 @@ You normally do not need to tune these. `bikky setup` starts the daemon and regi
|
|
|
379
382
|
| `daemon.consolidation_enabled` | `true` | Consolidate summaries into durable patterns |
|
|
380
383
|
| `daemon.relation_inference_enabled` | `true` | Infer entity relationships |
|
|
381
384
|
| `daemon.entity_typing_enabled` | `true` | Classify entities for UI/graph filtering |
|
|
385
|
+
| `daemon.memory_quality_rollups_enabled` | `true` | Aggregate recall, feedback, stale, and confidence quality signals |
|
|
386
|
+
| `daemon.memory_quality_rollups_interval_sec` | `3600` | Seconds between memory quality rollup runs |
|
|
387
|
+
| `daemon.memory_quality_rollups_low_confidence_threshold` | `0.6` | Effective confidence below this value is counted as low-confidence |
|
|
388
|
+
| `daemon.memory_quality_rollups_max_scopes_per_run` | `100` | Maximum rollup scopes written per destination per run |
|
|
382
389
|
| `daemon.staleness_threshold_days` | `30` | Days before a fact is flagged as stale |
|
|
383
390
|
|
|
384
391
|
#### Watcher settings
|