bikky 0.3.13 → 0.4.1
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/CHANGELOG.md +20 -0
- package/CODE_OF_CONDUCT.md +80 -0
- package/CONTRIBUTING.md +206 -0
- package/README.md +94 -20
- package/SECURITY.md +58 -0
- package/SUPPORT.md +22 -0
- package/dist/config.d.ts +68 -1
- package/dist/config.js +197 -4
- package/dist/daemon/extraction.d.ts +12 -2
- package/dist/daemon/extraction.js +85 -133
- package/dist/daemon/loop.js +15 -1
- package/dist/daemon/qdrant.js +0 -1
- package/dist/daemon/transcript-sources.d.ts +26 -0
- package/dist/daemon/transcript-sources.js +193 -0
- package/dist/daemon/watcher.d.ts +3 -2
- package/dist/daemon/watcher.js +51 -2
- package/dist/install.d.ts +9 -1
- package/dist/install.js +62 -34
- package/dist/lib/qdrant-pool.d.ts +57 -0
- package/dist/lib/qdrant-pool.js +104 -0
- package/dist/mcp/api.d.ts +57 -19
- package/dist/mcp/api.js +134 -72
- package/dist/mcp/helpers.d.ts +0 -1
- package/dist/mcp/helpers.js +2 -15
- package/dist/mcp/index.js +29 -14
- package/dist/mcp/tools.d.ts +0 -7
- package/dist/mcp/tools.js +618 -276
- package/dist/mcp/types.d.ts +0 -3
- package/dist/routing.d.ts +53 -0
- package/dist/routing.js +129 -0
- package/dist/search-scope.d.ts +24 -0
- package/dist/search-scope.js +174 -0
- package/docs/config/fully-hosted.md +57 -0
- package/docs/config/hosted-models.md +50 -0
- package/docs/config/hosted-qdrant-local-models.md +39 -0
- package/docs/config/local.md +34 -0
- package/docs/configuration.md +403 -0
- package/docs/privacy-first.md +140 -0
- package/docs/screenshots/dashboard.png +0 -0
- package/docs/screenshots/graph.png +0 -0
- package/docs/screenshots/memory.png +0 -0
- package/package.json +28 -7
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/config.test.d.ts +0 -9
- package/dist/config.test.d.ts.map +0 -1
- package/dist/config.test.js +0 -576
- package/dist/config.test.js.map +0 -1
- package/dist/daemon/capture-policy.d.ts.map +0 -1
- package/dist/daemon/capture-policy.js.map +0 -1
- package/dist/daemon/capture-policy.test.d.ts +0 -2
- package/dist/daemon/capture-policy.test.d.ts.map +0 -1
- package/dist/daemon/capture-policy.test.js +0 -48
- package/dist/daemon/capture-policy.test.js.map +0 -1
- package/dist/daemon/consolidation.d.ts.map +0 -1
- package/dist/daemon/consolidation.js.map +0 -1
- package/dist/daemon/entity-typing.d.ts.map +0 -1
- package/dist/daemon/entity-typing.js.map +0 -1
- package/dist/daemon/entity-typing.test.d.ts +0 -2
- package/dist/daemon/entity-typing.test.d.ts.map +0 -1
- package/dist/daemon/entity-typing.test.js +0 -50
- package/dist/daemon/entity-typing.test.js.map +0 -1
- package/dist/daemon/episode-summary.d.ts.map +0 -1
- package/dist/daemon/episode-summary.js.map +0 -1
- package/dist/daemon/episode-summary.test.d.ts +0 -2
- package/dist/daemon/episode-summary.test.d.ts.map +0 -1
- package/dist/daemon/episode-summary.test.js +0 -104
- package/dist/daemon/episode-summary.test.js.map +0 -1
- package/dist/daemon/extraction-quality.test.d.ts +0 -2
- package/dist/daemon/extraction-quality.test.d.ts.map +0 -1
- package/dist/daemon/extraction-quality.test.js +0 -283
- package/dist/daemon/extraction-quality.test.js.map +0 -1
- package/dist/daemon/extraction-rules.d.ts.map +0 -1
- package/dist/daemon/extraction-rules.js.map +0 -1
- package/dist/daemon/extraction-rules.test.d.ts +0 -2
- package/dist/daemon/extraction-rules.test.d.ts.map +0 -1
- package/dist/daemon/extraction-rules.test.js +0 -203
- package/dist/daemon/extraction-rules.test.js.map +0 -1
- package/dist/daemon/extraction.d.ts.map +0 -1
- package/dist/daemon/extraction.js.map +0 -1
- package/dist/daemon/extraction.test.d.ts +0 -2
- package/dist/daemon/extraction.test.d.ts.map +0 -1
- package/dist/daemon/extraction.test.js +0 -225
- package/dist/daemon/extraction.test.js.map +0 -1
- package/dist/daemon/index.d.ts.map +0 -1
- package/dist/daemon/index.js.map +0 -1
- package/dist/daemon/loop.d.ts.map +0 -1
- package/dist/daemon/loop.js.map +0 -1
- package/dist/daemon/loop.test.d.ts +0 -2
- package/dist/daemon/loop.test.d.ts.map +0 -1
- package/dist/daemon/loop.test.js +0 -85
- package/dist/daemon/loop.test.js.map +0 -1
- package/dist/daemon/maintenance-state.d.ts.map +0 -1
- package/dist/daemon/maintenance-state.js.map +0 -1
- package/dist/daemon/maintenance-state.test.d.ts +0 -2
- package/dist/daemon/maintenance-state.test.d.ts.map +0 -1
- package/dist/daemon/maintenance-state.test.js +0 -56
- package/dist/daemon/maintenance-state.test.js.map +0 -1
- package/dist/daemon/qdrant.d.ts.map +0 -1
- package/dist/daemon/qdrant.js.map +0 -1
- package/dist/daemon/qdrant.test.d.ts +0 -8
- package/dist/daemon/qdrant.test.d.ts.map +0 -1
- package/dist/daemon/qdrant.test.js +0 -265
- package/dist/daemon/qdrant.test.js.map +0 -1
- package/dist/daemon/relations-vocab.d.ts.map +0 -1
- package/dist/daemon/relations-vocab.js.map +0 -1
- package/dist/daemon/relations-vocab.test.d.ts +0 -2
- package/dist/daemon/relations-vocab.test.d.ts.map +0 -1
- package/dist/daemon/relations-vocab.test.js +0 -69
- package/dist/daemon/relations-vocab.test.js.map +0 -1
- package/dist/daemon/relations.d.ts.map +0 -1
- package/dist/daemon/relations.js.map +0 -1
- package/dist/daemon/relations.test.d.ts +0 -2
- package/dist/daemon/relations.test.d.ts.map +0 -1
- package/dist/daemon/relations.test.js +0 -36
- package/dist/daemon/relations.test.js.map +0 -1
- package/dist/daemon/session-index.d.ts.map +0 -1
- package/dist/daemon/session-index.js.map +0 -1
- package/dist/daemon/session-index.test.d.ts +0 -2
- package/dist/daemon/session-index.test.d.ts.map +0 -1
- package/dist/daemon/session-index.test.js +0 -60
- package/dist/daemon/session-index.test.js.map +0 -1
- package/dist/daemon/session-summary.d.ts.map +0 -1
- package/dist/daemon/session-summary.js.map +0 -1
- package/dist/daemon/session-summary.test.d.ts +0 -2
- package/dist/daemon/session-summary.test.d.ts.map +0 -1
- package/dist/daemon/session-summary.test.js +0 -162
- package/dist/daemon/session-summary.test.js.map +0 -1
- package/dist/daemon/staleness.d.ts.map +0 -1
- package/dist/daemon/staleness.js.map +0 -1
- package/dist/daemon/staleness.test.d.ts +0 -7
- package/dist/daemon/staleness.test.d.ts.map +0 -1
- package/dist/daemon/staleness.test.js +0 -128
- package/dist/daemon/staleness.test.js.map +0 -1
- package/dist/daemon/watcher-health.d.ts.map +0 -1
- package/dist/daemon/watcher-health.js.map +0 -1
- package/dist/daemon/watcher-health.test.d.ts +0 -5
- package/dist/daemon/watcher-health.test.d.ts.map +0 -1
- package/dist/daemon/watcher-health.test.js +0 -119
- package/dist/daemon/watcher-health.test.js.map +0 -1
- package/dist/daemon/watcher.d.ts.map +0 -1
- package/dist/daemon/watcher.js.map +0 -1
- package/dist/daemon/watcher.test.d.ts +0 -9
- package/dist/daemon/watcher.test.d.ts.map +0 -1
- package/dist/daemon/watcher.test.js +0 -204
- package/dist/daemon/watcher.test.js.map +0 -1
- package/dist/daemon/workstream-resolver.d.ts.map +0 -1
- package/dist/daemon/workstream-resolver.js.map +0 -1
- package/dist/daemon/workstream-resolver.test.d.ts +0 -2
- package/dist/daemon/workstream-resolver.test.d.ts.map +0 -1
- package/dist/daemon/workstream-resolver.test.js +0 -128
- package/dist/daemon/workstream-resolver.test.js.map +0 -1
- package/dist/daemon/workstream-summary.d.ts.map +0 -1
- package/dist/daemon/workstream-summary.js.map +0 -1
- package/dist/daemon/workstream-summary.test.d.ts +0 -2
- package/dist/daemon/workstream-summary.test.d.ts.map +0 -1
- package/dist/daemon/workstream-summary.test.js +0 -89
- package/dist/daemon/workstream-summary.test.js.map +0 -1
- package/dist/install.d.ts.map +0 -1
- package/dist/install.js.map +0 -1
- package/dist/install.test.d.ts +0 -9
- package/dist/install.test.d.ts.map +0 -1
- package/dist/install.test.js +0 -126
- package/dist/install.test.js.map +0 -1
- package/dist/lib/qdrant-client.d.ts.map +0 -1
- package/dist/lib/qdrant-client.js.map +0 -1
- package/dist/lib/qdrant-client.test.d.ts +0 -8
- package/dist/lib/qdrant-client.test.d.ts.map +0 -1
- package/dist/lib/qdrant-client.test.js +0 -274
- package/dist/lib/qdrant-client.test.js.map +0 -1
- package/dist/lifecycle.d.ts.map +0 -1
- package/dist/lifecycle.js.map +0 -1
- package/dist/lifecycle.test.d.ts +0 -8
- package/dist/lifecycle.test.d.ts.map +0 -1
- package/dist/lifecycle.test.js +0 -74
- package/dist/lifecycle.test.js.map +0 -1
- package/dist/llm/embedding/index.d.ts.map +0 -1
- package/dist/llm/embedding/index.js.map +0 -1
- package/dist/llm/embedding/index.test.d.ts +0 -8
- package/dist/llm/embedding/index.test.d.ts.map +0 -1
- package/dist/llm/embedding/index.test.js +0 -100
- package/dist/llm/embedding/index.test.js.map +0 -1
- package/dist/llm/embedding/providers/bedrock.d.ts.map +0 -1
- package/dist/llm/embedding/providers/bedrock.js.map +0 -1
- package/dist/llm/embedding/providers/bedrock.test.d.ts +0 -2
- package/dist/llm/embedding/providers/bedrock.test.d.ts.map +0 -1
- package/dist/llm/embedding/providers/bedrock.test.js +0 -24
- package/dist/llm/embedding/providers/bedrock.test.js.map +0 -1
- package/dist/llm/embedding/providers/index.d.ts.map +0 -1
- package/dist/llm/embedding/providers/index.js.map +0 -1
- package/dist/llm/embedding/providers/ollama.d.ts.map +0 -1
- package/dist/llm/embedding/providers/ollama.js.map +0 -1
- package/dist/llm/embedding/providers/ollama.test.d.ts +0 -2
- package/dist/llm/embedding/providers/ollama.test.d.ts.map +0 -1
- package/dist/llm/embedding/providers/ollama.test.js +0 -54
- package/dist/llm/embedding/providers/ollama.test.js.map +0 -1
- package/dist/llm/embedding/providers/openai.d.ts.map +0 -1
- package/dist/llm/embedding/providers/openai.js.map +0 -1
- package/dist/llm/embedding/providers/openai.test.d.ts +0 -2
- package/dist/llm/embedding/providers/openai.test.d.ts.map +0 -1
- package/dist/llm/embedding/providers/openai.test.js +0 -48
- package/dist/llm/embedding/providers/openai.test.js.map +0 -1
- package/dist/llm/embedding/providers/portkey.d.ts.map +0 -1
- package/dist/llm/embedding/providers/portkey.js.map +0 -1
- package/dist/llm/embedding/providers/portkey.test.d.ts +0 -2
- package/dist/llm/embedding/providers/portkey.test.d.ts.map +0 -1
- package/dist/llm/embedding/providers/portkey.test.js +0 -56
- package/dist/llm/embedding/providers/portkey.test.js.map +0 -1
- package/dist/llm/embedding/registry.d.ts.map +0 -1
- package/dist/llm/embedding/registry.js.map +0 -1
- package/dist/llm/embedding/registry.test.d.ts +0 -7
- package/dist/llm/embedding/registry.test.d.ts.map +0 -1
- package/dist/llm/embedding/registry.test.js +0 -68
- package/dist/llm/embedding/registry.test.js.map +0 -1
- package/dist/llm/embedding/types.d.ts.map +0 -1
- package/dist/llm/embedding/types.js.map +0 -1
- package/dist/llm/errors.d.ts.map +0 -1
- package/dist/llm/errors.js.map +0 -1
- package/dist/llm/errors.test.d.ts +0 -2
- package/dist/llm/errors.test.d.ts.map +0 -1
- package/dist/llm/errors.test.js +0 -103
- package/dist/llm/errors.test.js.map +0 -1
- package/dist/llm/fetch.d.ts.map +0 -1
- package/dist/llm/fetch.js.map +0 -1
- package/dist/llm/index.d.ts.map +0 -1
- package/dist/llm/index.js.map +0 -1
- package/dist/llm/inference/index.d.ts.map +0 -1
- package/dist/llm/inference/index.js.map +0 -1
- package/dist/llm/inference/index.test.d.ts +0 -6
- package/dist/llm/inference/index.test.d.ts.map +0 -1
- package/dist/llm/inference/index.test.js +0 -150
- package/dist/llm/inference/index.test.js.map +0 -1
- package/dist/llm/inference/providers/bedrock.d.ts.map +0 -1
- package/dist/llm/inference/providers/bedrock.js.map +0 -1
- package/dist/llm/inference/providers/bedrock.test.d.ts +0 -2
- package/dist/llm/inference/providers/bedrock.test.d.ts.map +0 -1
- package/dist/llm/inference/providers/bedrock.test.js +0 -68
- package/dist/llm/inference/providers/bedrock.test.js.map +0 -1
- package/dist/llm/inference/providers/index.d.ts.map +0 -1
- package/dist/llm/inference/providers/index.js.map +0 -1
- package/dist/llm/inference/providers/ollama.d.ts.map +0 -1
- package/dist/llm/inference/providers/ollama.js.map +0 -1
- package/dist/llm/inference/providers/ollama.test.d.ts +0 -2
- package/dist/llm/inference/providers/ollama.test.d.ts.map +0 -1
- package/dist/llm/inference/providers/ollama.test.js +0 -57
- package/dist/llm/inference/providers/ollama.test.js.map +0 -1
- package/dist/llm/inference/providers/openai.d.ts.map +0 -1
- package/dist/llm/inference/providers/openai.js.map +0 -1
- package/dist/llm/inference/providers/openai.test.d.ts +0 -2
- package/dist/llm/inference/providers/openai.test.d.ts.map +0 -1
- package/dist/llm/inference/providers/openai.test.js +0 -82
- package/dist/llm/inference/providers/openai.test.js.map +0 -1
- package/dist/llm/inference/providers/portkey.d.ts.map +0 -1
- package/dist/llm/inference/providers/portkey.js.map +0 -1
- package/dist/llm/inference/providers/portkey.test.d.ts +0 -2
- package/dist/llm/inference/providers/portkey.test.d.ts.map +0 -1
- package/dist/llm/inference/providers/portkey.test.js +0 -48
- package/dist/llm/inference/providers/portkey.test.js.map +0 -1
- package/dist/llm/inference/registry.d.ts.map +0 -1
- package/dist/llm/inference/registry.js.map +0 -1
- package/dist/llm/inference/registry.test.d.ts +0 -6
- package/dist/llm/inference/registry.test.d.ts.map +0 -1
- package/dist/llm/inference/registry.test.js +0 -63
- package/dist/llm/inference/registry.test.js.map +0 -1
- package/dist/llm/inference/types.d.ts.map +0 -1
- package/dist/llm/inference/types.js.map +0 -1
- package/dist/llm/telemetry.d.ts.map +0 -1
- package/dist/llm/telemetry.js.map +0 -1
- package/dist/llm/telemetry.test.d.ts +0 -5
- package/dist/llm/telemetry.test.d.ts.map +0 -1
- package/dist/llm/telemetry.test.js +0 -89
- package/dist/llm/telemetry.test.js.map +0 -1
- package/dist/llm/types.d.ts.map +0 -1
- package/dist/llm/types.js.map +0 -1
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js.map +0 -1
- package/dist/logger.test.d.ts +0 -5
- package/dist/logger.test.d.ts.map +0 -1
- package/dist/logger.test.js +0 -103
- package/dist/logger.test.js.map +0 -1
- package/dist/mcp/api.d.ts.map +0 -1
- package/dist/mcp/api.js.map +0 -1
- package/dist/mcp/api.test.d.ts +0 -6
- package/dist/mcp/api.test.d.ts.map +0 -1
- package/dist/mcp/api.test.js +0 -130
- package/dist/mcp/api.test.js.map +0 -1
- package/dist/mcp/helpers.d.ts.map +0 -1
- package/dist/mcp/helpers.js.map +0 -1
- package/dist/mcp/helpers.test.d.ts +0 -5
- package/dist/mcp/helpers.test.d.ts.map +0 -1
- package/dist/mcp/helpers.test.js +0 -548
- package/dist/mcp/helpers.test.js.map +0 -1
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/index.js.map +0 -1
- package/dist/mcp/taxonomy.d.ts.map +0 -1
- package/dist/mcp/taxonomy.js.map +0 -1
- package/dist/mcp/taxonomy.test.d.ts +0 -5
- package/dist/mcp/taxonomy.test.d.ts.map +0 -1
- package/dist/mcp/taxonomy.test.js +0 -215
- package/dist/mcp/taxonomy.test.js.map +0 -1
- package/dist/mcp/tools.d.ts.map +0 -1
- package/dist/mcp/tools.integration.itest.d.ts +0 -23
- package/dist/mcp/tools.integration.itest.d.ts.map +0 -1
- package/dist/mcp/tools.integration.itest.js +0 -171
- package/dist/mcp/tools.integration.itest.js.map +0 -1
- package/dist/mcp/tools.js.map +0 -1
- package/dist/mcp/tools.test.d.ts +0 -16
- package/dist/mcp/tools.test.d.ts.map +0 -1
- package/dist/mcp/tools.test.js +0 -908
- package/dist/mcp/tools.test.js.map +0 -1
- package/dist/mcp/types.d.ts.map +0 -1
- package/dist/mcp/types.js.map +0 -1
- package/dist/postinstall.d.ts.map +0 -1
- package/dist/postinstall.js.map +0 -1
- package/dist/privacy/redaction.d.ts.map +0 -1
- package/dist/privacy/redaction.js.map +0 -1
- package/dist/privacy/redaction.test.d.ts +0 -2
- package/dist/privacy/redaction.test.d.ts.map +0 -1
- package/dist/privacy/redaction.test.js +0 -51
- package/dist/privacy/redaction.test.js.map +0 -1
- package/dist/prompts/brief.d.ts.map +0 -1
- package/dist/prompts/brief.js.map +0 -1
- package/dist/prompts/contradiction.d.ts.map +0 -1
- package/dist/prompts/contradiction.js.map +0 -1
- package/dist/prompts/distill.d.ts.map +0 -1
- package/dist/prompts/distill.js.map +0 -1
- package/dist/prompts/entity-typing.d.ts.map +0 -1
- package/dist/prompts/entity-typing.js.map +0 -1
- package/dist/prompts/episode-summary.d.ts.map +0 -1
- package/dist/prompts/episode-summary.js.map +0 -1
- package/dist/prompts/extraction.d.ts.map +0 -1
- package/dist/prompts/extraction.js.map +0 -1
- package/dist/prompts/index.d.ts.map +0 -1
- package/dist/prompts/index.js.map +0 -1
- package/dist/prompts/prompts.test.d.ts +0 -8
- package/dist/prompts/prompts.test.d.ts.map +0 -1
- package/dist/prompts/prompts.test.js +0 -140
- package/dist/prompts/prompts.test.js.map +0 -1
- package/dist/prompts/relations.d.ts.map +0 -1
- package/dist/prompts/relations.js.map +0 -1
- package/dist/prompts/workstream-summary.d.ts.map +0 -1
- package/dist/prompts/workstream-summary.js.map +0 -1
- package/dist/provenance/actor.d.ts.map +0 -1
- package/dist/provenance/actor.js.map +0 -1
- package/dist/provenance/actor.test.d.ts +0 -2
- package/dist/provenance/actor.test.d.ts.map +0 -1
- package/dist/provenance/actor.test.js +0 -49
- package/dist/provenance/actor.test.js.map +0 -1
- package/dist/render.d.ts.map +0 -1
- package/dist/render.js.map +0 -1
- package/dist/render.test.d.ts +0 -8
- package/dist/render.test.d.ts.map +0 -1
- package/dist/render.test.js +0 -244
- package/dist/render.test.js.map +0 -1
- package/dist/status.d.ts.map +0 -1
- package/dist/status.js.map +0 -1
- package/dist/status.test.d.ts +0 -5
- package/dist/status.test.d.ts.map +0 -1
- package/dist/status.test.js +0 -203
- package/dist/status.test.js.map +0 -1
package/dist/config.d.ts
CHANGED
|
@@ -76,11 +76,67 @@ export interface WatcherConfig {
|
|
|
76
76
|
path: string;
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* One Qdrant routing target. Each destination is fully self-contained: its own
|
|
81
|
+
* URL, API key, collection name, and match rules. All fields in `match` are
|
|
82
|
+
* arrays of regex strings; OR semantics within a destination's match block,
|
|
83
|
+
* first-match-wins across destinations.
|
|
84
|
+
*/
|
|
85
|
+
export interface DestinationMatch {
|
|
86
|
+
/** Match against `process.cwd()`. */
|
|
87
|
+
cwd?: string[];
|
|
88
|
+
/** Match against any of the input `entities`. */
|
|
89
|
+
entity?: string[];
|
|
90
|
+
/** Match against the input `content`. */
|
|
91
|
+
content?: string[];
|
|
92
|
+
/** Per-key match against the input `metadata`. */
|
|
93
|
+
metadata?: Record<string, string[]>;
|
|
94
|
+
}
|
|
95
|
+
export interface Destination {
|
|
96
|
+
/** Stable, unique name. Used as the `destination` override on tool calls. */
|
|
97
|
+
name: string;
|
|
98
|
+
/** Human-readable guidance for LLMs/users about when to use this destination. */
|
|
99
|
+
description?: string;
|
|
100
|
+
qdrant_url: string;
|
|
101
|
+
qdrant_api_key: string | null;
|
|
102
|
+
collection: string;
|
|
103
|
+
/** Marks this destination as the fallback when no rule matches. */
|
|
104
|
+
default?: boolean;
|
|
105
|
+
/** Routing rules. Omit for a destination that is only reachable by override. */
|
|
106
|
+
match?: DestinationMatch;
|
|
107
|
+
}
|
|
108
|
+
export type SearchScopeTarget = "routed" | "all" | string | string[];
|
|
109
|
+
export interface SearchScopeDefinition {
|
|
110
|
+
/** Stable scope name that MCP clients can pass as `search_scope`. */
|
|
111
|
+
name: string;
|
|
112
|
+
/** Guidance for LLMs/users about when this scope should be used. */
|
|
113
|
+
description: string;
|
|
114
|
+
/** Destination selector: "routed", "all", a destination name, or destination names. */
|
|
115
|
+
destinations: SearchScopeTarget;
|
|
116
|
+
}
|
|
79
117
|
export interface BikkyConfig {
|
|
118
|
+
/**
|
|
119
|
+
* Top-level Qdrant fields. When `destinations` is empty, a single default
|
|
120
|
+
* destination is synthesized from these — keeps single-Qdrant configs
|
|
121
|
+
* working without changes.
|
|
122
|
+
*/
|
|
80
123
|
qdrant_url: string | null;
|
|
81
124
|
qdrant_api_key: string | null;
|
|
82
125
|
collection: string;
|
|
83
|
-
|
|
126
|
+
/**
|
|
127
|
+
* One or more Qdrant routing targets. Memory operations resolve to a
|
|
128
|
+
* destination via override → cwd/entity/content/metadata regex match →
|
|
129
|
+
* default flag → first entry.
|
|
130
|
+
*/
|
|
131
|
+
destinations: Destination[];
|
|
132
|
+
/**
|
|
133
|
+
* Default read/search scope. "routed" preserves historical behavior
|
|
134
|
+
* (one destination via routing rules); "all" fans out to every destination;
|
|
135
|
+
* a destination name or list searches only those destinations.
|
|
136
|
+
*/
|
|
137
|
+
default_search_scope: SearchScopeTarget;
|
|
138
|
+
/** Optional named search scopes exposed to MCP clients with descriptions. */
|
|
139
|
+
search_scopes: SearchScopeDefinition[];
|
|
84
140
|
aws_profile: string | null;
|
|
85
141
|
embedding: EmbeddingConfig;
|
|
86
142
|
llm: LLMConfig;
|
|
@@ -107,6 +163,17 @@ export declare function validateConfigObject(raw: unknown): ConfigIssue[];
|
|
|
107
163
|
export declare function inspectConfigFile(configPath?: string): ConfigFileDiagnostics;
|
|
108
164
|
export declare function getActiveConfigEnvOverrides(env?: NodeJS.ProcessEnv): string[];
|
|
109
165
|
export declare function loadConfig(): BikkyConfig;
|
|
166
|
+
/**
|
|
167
|
+
* Resolve the effective list of destinations from the loaded config.
|
|
168
|
+
*
|
|
169
|
+
* - If `destinations` is non-empty, return as-is.
|
|
170
|
+
* - Otherwise synthesize a single fallback destination from the top-level
|
|
171
|
+
* `qdrant_url` / `qdrant_api_key` / `collection` so existing single-Qdrant
|
|
172
|
+
* configs keep working without changes.
|
|
173
|
+
* - If neither is configured, returns an empty array — callers should treat
|
|
174
|
+
* that as "Qdrant not configured" the same way they did before.
|
|
175
|
+
*/
|
|
176
|
+
export declare function getEffectiveDestinations(config?: BikkyConfig): Destination[];
|
|
110
177
|
/** Save config to disk (used by setup command). */
|
|
111
178
|
export declare function saveConfig(config: BikkyConfig): void;
|
|
112
179
|
/** Reset cached config (for testing). */
|
package/dist/config.js
CHANGED
|
@@ -28,7 +28,9 @@ const DEFAULTS = {
|
|
|
28
28
|
qdrant_url: null,
|
|
29
29
|
qdrant_api_key: null,
|
|
30
30
|
collection: "bikky",
|
|
31
|
-
|
|
31
|
+
destinations: [],
|
|
32
|
+
default_search_scope: "routed",
|
|
33
|
+
search_scopes: [],
|
|
32
34
|
aws_profile: null,
|
|
33
35
|
embedding: {
|
|
34
36
|
provider: "ollama",
|
|
@@ -176,11 +178,38 @@ const identityConfigFileSchema = z.object({
|
|
|
176
178
|
actor_id: z.string().nullable().optional(),
|
|
177
179
|
actor_label: z.string().nullable().optional(),
|
|
178
180
|
}).passthrough();
|
|
181
|
+
const regexArrayField = z.array(z.string()).optional();
|
|
182
|
+
const destinationMatchSchema = z.object({
|
|
183
|
+
cwd: regexArrayField,
|
|
184
|
+
entity: regexArrayField,
|
|
185
|
+
content: regexArrayField,
|
|
186
|
+
metadata: z.record(z.array(z.string())).optional(),
|
|
187
|
+
}).passthrough();
|
|
188
|
+
const destinationFileSchema = z.object({
|
|
189
|
+
name: z.string().min(1),
|
|
190
|
+
description: z.string().optional(),
|
|
191
|
+
qdrant_url: z.string().min(1),
|
|
192
|
+
qdrant_api_key: z.string().nullable().optional(),
|
|
193
|
+
collection: z.string().min(1),
|
|
194
|
+
default: z.boolean().optional(),
|
|
195
|
+
match: destinationMatchSchema.optional(),
|
|
196
|
+
}).passthrough();
|
|
197
|
+
const searchScopeTargetSchema = z.union([
|
|
198
|
+
z.string().min(1),
|
|
199
|
+
z.array(z.string().min(1)).min(1),
|
|
200
|
+
]);
|
|
201
|
+
const searchScopeDefinitionFileSchema = z.object({
|
|
202
|
+
name: z.string().min(1),
|
|
203
|
+
description: z.string().min(1),
|
|
204
|
+
destinations: searchScopeTargetSchema,
|
|
205
|
+
}).passthrough();
|
|
179
206
|
const configFileSchema = z.object({
|
|
180
207
|
qdrant_url: z.string().nullable().optional(),
|
|
181
208
|
qdrant_api_key: z.string().nullable().optional(),
|
|
182
209
|
collection: z.string().optional(),
|
|
183
|
-
|
|
210
|
+
destinations: z.array(destinationFileSchema).optional(),
|
|
211
|
+
default_search_scope: searchScopeTargetSchema.optional(),
|
|
212
|
+
search_scopes: z.array(searchScopeDefinitionFileSchema).optional(),
|
|
184
213
|
aws_profile: z.string().nullable().optional(),
|
|
185
214
|
embedding: embeddingConfigFileSchema.optional(),
|
|
186
215
|
llm: llmConfigFileSchema.optional(),
|
|
@@ -267,6 +296,144 @@ export function validateConfigObject(raw) {
|
|
|
267
296
|
});
|
|
268
297
|
}
|
|
269
298
|
validateUrlLike(raw.qdrant_url, "qdrant_url", issues);
|
|
299
|
+
// Destinations validation
|
|
300
|
+
if (Array.isArray(raw.destinations)) {
|
|
301
|
+
const seenNames = new Set();
|
|
302
|
+
let defaultCount = 0;
|
|
303
|
+
raw.destinations.forEach((entry, idx) => {
|
|
304
|
+
const base = `destinations[${idx}]`;
|
|
305
|
+
if (!isObject(entry)) {
|
|
306
|
+
issues.push({ severity: "error", path: base, message: "must be an object" });
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const name = entry.name;
|
|
310
|
+
if (typeof name === "string" && name.trim() !== "") {
|
|
311
|
+
if (seenNames.has(name)) {
|
|
312
|
+
issues.push({ severity: "error", path: `${base}.name`, message: `duplicate destination name '${name}'` });
|
|
313
|
+
}
|
|
314
|
+
seenNames.add(name);
|
|
315
|
+
}
|
|
316
|
+
validateUrlLike(entry.qdrant_url, `${base}.qdrant_url`, issues);
|
|
317
|
+
if (typeof entry.collection === "string" && entry.collection.trim() === "") {
|
|
318
|
+
issues.push({ severity: "error", path: `${base}.collection`, message: "must not be empty" });
|
|
319
|
+
}
|
|
320
|
+
if (entry.default === true)
|
|
321
|
+
defaultCount++;
|
|
322
|
+
const match = childObject(entry, "match");
|
|
323
|
+
if (match) {
|
|
324
|
+
for (const field of ["cwd", "entity", "content"]) {
|
|
325
|
+
const value = match[field];
|
|
326
|
+
if (value === undefined)
|
|
327
|
+
continue;
|
|
328
|
+
if (!Array.isArray(value)) {
|
|
329
|
+
issues.push({ severity: "error", path: `${base}.match.${field}`, message: "must be an array of regex strings" });
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
value.forEach((pattern, pIdx) => {
|
|
333
|
+
if (typeof pattern !== "string") {
|
|
334
|
+
issues.push({ severity: "error", path: `${base}.match.${field}[${pIdx}]`, message: "must be a string" });
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
try {
|
|
338
|
+
new RegExp(pattern);
|
|
339
|
+
}
|
|
340
|
+
catch (e) {
|
|
341
|
+
issues.push({
|
|
342
|
+
severity: "error",
|
|
343
|
+
path: `${base}.match.${field}[${pIdx}]`,
|
|
344
|
+
message: `invalid regex: ${e instanceof Error ? e.message : String(e)}`,
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
const metadata = childObject(match, "metadata");
|
|
350
|
+
if (metadata) {
|
|
351
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
352
|
+
if (!Array.isArray(value)) {
|
|
353
|
+
issues.push({ severity: "error", path: `${base}.match.metadata.${key}`, message: "must be an array of regex strings" });
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
value.forEach((pattern, pIdx) => {
|
|
357
|
+
if (typeof pattern !== "string") {
|
|
358
|
+
issues.push({ severity: "error", path: `${base}.match.metadata.${key}[${pIdx}]`, message: "must be a string" });
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
try {
|
|
362
|
+
new RegExp(pattern);
|
|
363
|
+
}
|
|
364
|
+
catch (e) {
|
|
365
|
+
issues.push({
|
|
366
|
+
severity: "error",
|
|
367
|
+
path: `${base}.match.metadata.${key}[${pIdx}]`,
|
|
368
|
+
message: `invalid regex: ${e instanceof Error ? e.message : String(e)}`,
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
if (defaultCount > 1) {
|
|
377
|
+
issues.push({ severity: "error", path: "destinations", message: `at most one destination may set 'default: true' (found ${defaultCount})` });
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
const destinationNames = new Set();
|
|
381
|
+
if (Array.isArray(raw.destinations)) {
|
|
382
|
+
for (const entry of raw.destinations) {
|
|
383
|
+
if (isObject(entry) && typeof entry.name === "string" && entry.name.trim() !== "") {
|
|
384
|
+
destinationNames.add(entry.name);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
const searchScopeNames = new Set();
|
|
389
|
+
if (Array.isArray(raw.search_scopes)) {
|
|
390
|
+
for (const entry of raw.search_scopes) {
|
|
391
|
+
if (isObject(entry) && typeof entry.name === "string" && entry.name.trim() !== "") {
|
|
392
|
+
searchScopeNames.add(entry.name);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
const validateSearchScopeTarget = (target, pathName) => {
|
|
397
|
+
const values = Array.isArray(target) ? target : [target];
|
|
398
|
+
for (const [idx, value] of values.entries()) {
|
|
399
|
+
const valuePath = Array.isArray(target) ? `${pathName}[${idx}]` : pathName;
|
|
400
|
+
if (typeof value !== "string" || value.trim() === "")
|
|
401
|
+
continue;
|
|
402
|
+
const normalized = value.trim();
|
|
403
|
+
if (normalized === "all" || normalized === "routed" || destinationNames.size === 0)
|
|
404
|
+
continue;
|
|
405
|
+
if (searchScopeNames.has(normalized))
|
|
406
|
+
continue;
|
|
407
|
+
if (!destinationNames.has(normalized)) {
|
|
408
|
+
issues.push({
|
|
409
|
+
severity: "warning",
|
|
410
|
+
path: valuePath,
|
|
411
|
+
message: `references unknown destination '${normalized}'`,
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
if (Object.prototype.hasOwnProperty.call(raw, "default_search_scope")) {
|
|
417
|
+
validateSearchScopeTarget(raw.default_search_scope, "default_search_scope");
|
|
418
|
+
}
|
|
419
|
+
if (Array.isArray(raw.search_scopes)) {
|
|
420
|
+
const seenScopeNames = new Set();
|
|
421
|
+
raw.search_scopes.forEach((entry, idx) => {
|
|
422
|
+
const base = `search_scopes[${idx}]`;
|
|
423
|
+
if (!isObject(entry)) {
|
|
424
|
+
issues.push({ severity: "error", path: base, message: "must be an object" });
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
const name = entry.name;
|
|
428
|
+
if (typeof name === "string" && name.trim() !== "") {
|
|
429
|
+
if (seenScopeNames.has(name)) {
|
|
430
|
+
issues.push({ severity: "error", path: `${base}.name`, message: `duplicate search scope name '${name}'` });
|
|
431
|
+
}
|
|
432
|
+
seenScopeNames.add(name);
|
|
433
|
+
}
|
|
434
|
+
validateSearchScopeTarget(entry.destinations, `${base}.destinations`);
|
|
435
|
+
});
|
|
436
|
+
}
|
|
270
437
|
const embedding = childObject(raw, "embedding");
|
|
271
438
|
if (embedding)
|
|
272
439
|
validateUrlLike(embedding.base_url, "embedding.base_url", issues);
|
|
@@ -345,8 +512,6 @@ export function loadConfig() {
|
|
|
345
512
|
config.qdrant_api_key = process.env.QDRANT_API_KEY;
|
|
346
513
|
if (process.env.BIKKY_COLLECTION)
|
|
347
514
|
config.collection = process.env.BIKKY_COLLECTION;
|
|
348
|
-
if (process.env.BIKKY_DEFAULT_WORKSPACE)
|
|
349
|
-
config.default_workspace = process.env.BIKKY_DEFAULT_WORKSPACE;
|
|
350
515
|
// Embedding env overrides
|
|
351
516
|
if (process.env.EMBEDDING_PROVIDER)
|
|
352
517
|
config.embedding.provider = process.env.EMBEDDING_PROVIDER;
|
|
@@ -481,9 +646,37 @@ export function loadConfig() {
|
|
|
481
646
|
config.qdrant_url = config.qdrant_url.replace(/\/+$/, "");
|
|
482
647
|
config.embedding.base_url = config.embedding.base_url.replace(/\/+$/, "");
|
|
483
648
|
config.llm.base_url = config.llm.base_url.replace(/\/+$/, "");
|
|
649
|
+
for (const dest of config.destinations) {
|
|
650
|
+
if (dest.qdrant_url)
|
|
651
|
+
dest.qdrant_url = dest.qdrant_url.replace(/\/+$/, "");
|
|
652
|
+
}
|
|
484
653
|
_config = config;
|
|
485
654
|
return config;
|
|
486
655
|
}
|
|
656
|
+
/**
|
|
657
|
+
* Resolve the effective list of destinations from the loaded config.
|
|
658
|
+
*
|
|
659
|
+
* - If `destinations` is non-empty, return as-is.
|
|
660
|
+
* - Otherwise synthesize a single fallback destination from the top-level
|
|
661
|
+
* `qdrant_url` / `qdrant_api_key` / `collection` so existing single-Qdrant
|
|
662
|
+
* configs keep working without changes.
|
|
663
|
+
* - If neither is configured, returns an empty array — callers should treat
|
|
664
|
+
* that as "Qdrant not configured" the same way they did before.
|
|
665
|
+
*/
|
|
666
|
+
export function getEffectiveDestinations(config = loadConfig()) {
|
|
667
|
+
if (config.destinations.length > 0)
|
|
668
|
+
return config.destinations;
|
|
669
|
+
if (!config.qdrant_url)
|
|
670
|
+
return [];
|
|
671
|
+
return [{
|
|
672
|
+
name: "default",
|
|
673
|
+
description: "Default Qdrant destination synthesized from the top-level qdrant_url, qdrant_api_key, and collection settings.",
|
|
674
|
+
qdrant_url: config.qdrant_url,
|
|
675
|
+
qdrant_api_key: config.qdrant_api_key,
|
|
676
|
+
collection: config.collection,
|
|
677
|
+
default: true,
|
|
678
|
+
}];
|
|
679
|
+
}
|
|
487
680
|
/** Save config to disk (used by setup command). */
|
|
488
681
|
export function saveConfig(config) {
|
|
489
682
|
fs.mkdirSync(BIKKY_DIR, { recursive: true });
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Events-based memory extraction — reads
|
|
2
|
+
* Events-based memory extraction — reads supported coding-agent transcripts,
|
|
3
3
|
* extracts facts via LLM, and stores them in Qdrant with source: "system".
|
|
4
4
|
*
|
|
5
5
|
* Uses a JSON file for extraction state (high-water byte offsets) instead of SQLite.
|
|
6
|
-
*
|
|
6
|
+
* Copilot session detection uses lock files. Claude Code detection uses
|
|
7
|
+
* top-level JSONL transcripts under ~/.claude/projects.
|
|
7
8
|
*/
|
|
8
9
|
import type { BikkyConfig } from "../config.js";
|
|
9
10
|
import type { LogFn } from "./qdrant.js";
|
|
11
|
+
import { type TranscriptSource } from "./transcript-sources.js";
|
|
10
12
|
export declare const setLogger: (fn: LogFn) => void;
|
|
11
13
|
export declare const DEFAULT_EXTRACTION_PROMPT = "You are Bikky's memory extraction agent for open-source coding agents. Extract durable, reusable facts that help a future agent continue work without rereading the whole transcript.\n\n## Core rule\nExtract fewer, sharper memories. A candidate fact must be independently useful after the session is gone.\n\n## Quality gate\nEvery fact must pass at least one gate:\n1. GREPPABLE: names a file path, package, symbol, config key, CLI flag, issue/PR, service, or API a future agent can search for.\n2. RUNNABLE: contains a command, URL, setting, port, or procedure that can be executed or checked.\n3. NAVIGABLE: tells a future agent where to look and what that location means.\n4. DECISIVE: records a durable decision, rationale, constraint, convention, or preference.\n5. DIAGNOSTIC: captures a repeatable failure mode, root cause, or troubleshooting gotcha.\n\n## Ontology\n- domain is the activity profile. For coding-agent captures use \"software_engineering\".\n- category is subject matter: engineering | product | human | system.\n- kind is object shape. For this prompt, emit only kind=\"fact\".\n- memory_subtype must be one of:\n codebase_map | architecture_decision | infra_topology | access_pattern | operational_procedure | domain_rule | product_decision | product_requirement | user_workflow | roadmap_item | success_metric | market_insight | troubleshooting_gotcha | preference | person_profile | ownership_note | working_agreement | activity_event.\n\n## Examples\nGOOD:\n- \"The UI smoke tests live in packages/ui/tests/smoke.spec.ts and run through npm run test:e2e with mocked /api/memory/* responses.\"\n- \"Use workspace_id as the tenancy/access boundary; domain is reserved for activity profile such as software_engineering.\"\n- \"If Qdrant order_by fails with a missing index error, create a datetime payload index for the sorted field before retrying.\"\n- \"The memory page should show categories and concrete subtype chips directly; a sub-tab layer makes the ontology harder to understand.\"\n- \"Saber prefers Node's built-in test runner for root tests; do not add Jest just for daemon unit tests.\"\n- \"Saber merged PR #85 after approving the subtype UX copy changes.\"\n\nBAD:\n- \"The tests were fixed.\" (status only)\n- \"We reviewed the code.\" (session narration)\n- \"The deployment succeeded.\" (transient and not reusable)\n- \"The agent used npm.\" (tool narration)\n- \"There was an error.\" (no root cause or reusable detail)\n\n## Output format\nReturn strict JSON:\n{\"facts\":[\n {\n \"content\":\"One self-contained durable fact.\",\n \"category\":\"engineering\",\n \"memory_subtype\":\"codebase_map\",\n \"action_actor\":\"optional actor for activity_event only\",\n \"action_type\":\"optional action verb for activity_event only\",\n \"action_object\":\"optional durable object for activity_event only\",\n \"action_outcome\":\"optional durable outcome for activity_event only\",\n \"entities\":[\"repo-or-tool\",\"specific-module\"],\n \"confidence\":0.9,\n \"importance\":0.7,\n \"quality_score\":0.8,\n \"confidence_reason\":\"Explicitly stated in the transcript.\",\n \"repo\":\"optional/repo-or-package\",\n \"branch\":\"optional-branch\",\n \"task_key\":\"optional issue/PR/task key\",\n \"workstream_key\":\"optional stable workstream key\"\n }\n]}\n\nScoring:\n- confidence: 0.9 explicit, 0.7 strong inference, 0.55 weak but useful inference.\n- importance: 0.8+ for decisions, infra, procedures, access, recurring failures, product requirements, ownership, and state-changing activity events; 0.6+ for useful codebase maps/preferences.\n- quality_score: 0.8+ passes multiple gates, 0.6+ passes one strong gate, below 0.6 should usually be omitted.\n\nIf nothing passes the quality gate, return {\"facts\":[]}.";
|
|
12
14
|
export type Volatility = "stable" | "evolving" | "transient" | "ephemeral";
|
|
@@ -60,5 +62,13 @@ export interface ExtractionHealth {
|
|
|
60
62
|
active_session_count: number;
|
|
61
63
|
/** Configured copilot watcher path at the time of the tick. */
|
|
62
64
|
watcher_path: string;
|
|
65
|
+
/** Per-source health, including non-Copilot watchers. */
|
|
66
|
+
sources?: Record<TranscriptSource, ExtractionSourceHealth>;
|
|
67
|
+
}
|
|
68
|
+
export interface ExtractionSourceHealth {
|
|
69
|
+
enabled: boolean;
|
|
70
|
+
watcher_path: string;
|
|
71
|
+
active_session_count: number;
|
|
72
|
+
last_active_session_at: string | null;
|
|
63
73
|
}
|
|
64
74
|
//# sourceMappingURL=extraction.d.ts.map
|