bikky 0.4.2 → 0.4.3
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 +6 -4
- package/dist/config.d.ts +11 -1
- package/dist/config.js +88 -20
- package/dist/daemon/capture-policy.d.ts +0 -1
- package/dist/daemon/capture-policy.js +0 -1
- package/dist/daemon/consolidation.d.ts +2 -1
- package/dist/daemon/consolidation.js +28 -11
- package/dist/daemon/entity-typing.js +10 -0
- package/dist/daemon/episode-summary.d.ts +4 -0
- package/dist/daemon/episode-summary.js +39 -8
- package/dist/daemon/extraction.d.ts +1 -1
- package/dist/daemon/extraction.js +52 -17
- package/dist/daemon/qdrant.d.ts +32 -10
- package/dist/daemon/qdrant.js +177 -60
- package/dist/daemon/relations.d.ts +3 -3
- package/dist/daemon/relations.js +27 -15
- package/dist/daemon/session-index.d.ts +5 -0
- package/dist/daemon/session-index.js +36 -9
- package/dist/daemon/session-summary.d.ts +3 -0
- package/dist/daemon/session-summary.js +48 -15
- package/dist/daemon/staleness.js +2 -2
- package/dist/daemon/transcript-sources.js +3 -2
- package/dist/daemon/watcher.js +2 -0
- package/dist/daemon/workstream-summary.d.ts +4 -0
- package/dist/daemon/workstream-summary.js +58 -16
- package/dist/install.d.ts +11 -0
- package/dist/install.js +38 -0
- package/dist/llm/embedding/index.js +2 -1
- package/dist/llm/embedding/providers/openai.js +8 -2
- package/dist/llm/embedding/providers/portkey.js +9 -2
- package/dist/llm/inference/index.js +2 -1
- package/dist/llm/util.d.ts +12 -0
- package/dist/llm/util.js +18 -0
- package/dist/mcp/helpers.d.ts +5 -0
- package/dist/mcp/helpers.js +27 -3
- package/dist/mcp/taxonomy.js +12 -1
- package/dist/mcp/tools.js +161 -57
- package/dist/mcp/types.d.ts +12 -0
- package/dist/package-verifier.d.ts +19 -0
- package/dist/package-verifier.js +83 -0
- package/dist/provenance/origin.d.ts +57 -0
- package/dist/provenance/origin.js +254 -0
- package/docs/config/fully-hosted.md +33 -13
- package/docs/config/hosted-models.md +33 -13
- package/docs/configuration.md +18 -0
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Events-based memory extraction — reads supported coding-agent transcripts,
|
|
3
|
-
* extracts facts via LLM, and stores them in Qdrant with
|
|
3
|
+
* extracts facts via LLM, and stores them in Qdrant with daemon origin metadata.
|
|
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
|
|
@@ -19,7 +19,7 @@ import { CAPTURE_POLICY_VERSION, CAPTURE_TRIGGERS, DEFAULT_CAPTURE_CONTEXT, QUAL
|
|
|
19
19
|
import { shouldSummarizeEvents, updateSessionSummary } from "./session-summary.js";
|
|
20
20
|
import { redactStorageText } from "../privacy/redaction.js";
|
|
21
21
|
import { compareSubtype, hasTypedToken, verifyGrounding, verifyVolatilityCoherence } from "./extraction-rules.js";
|
|
22
|
-
import {
|
|
22
|
+
import { buildOperationOrigin } from "../provenance/origin.js";
|
|
23
23
|
import { discoverClaudeTranscriptMappings, discoverCopilotTranscriptMappings, extractionStateKey, readNewTranscriptEvents, transcriptLabel, } from "./transcript-sources.js";
|
|
24
24
|
// ── Module state ─────────────────────────────────────────────────────────────
|
|
25
25
|
let logFn = (() => { });
|
|
@@ -415,11 +415,6 @@ const storeFacts = async (facts, sessionId, config, source) => {
|
|
|
415
415
|
};
|
|
416
416
|
if (source)
|
|
417
417
|
baseMeta.extraction_source = source;
|
|
418
|
-
const actor = resolveActorIdentity({ config });
|
|
419
|
-
if (actor.actor_label)
|
|
420
|
-
baseMeta.actor_label = actor.actor_label;
|
|
421
|
-
if (actor.source)
|
|
422
|
-
baseMeta.actor_source = actor.source;
|
|
423
418
|
let stored = 0;
|
|
424
419
|
for (const fact of facts) {
|
|
425
420
|
const redactedContent = redactStorageText(fact.content);
|
|
@@ -429,12 +424,34 @@ const storeFacts = async (facts, sessionId, config, source) => {
|
|
|
429
424
|
entities: fact.entities.map((entity) => entity.toLowerCase()),
|
|
430
425
|
};
|
|
431
426
|
const hash = contentHash(sanitizedFact.content);
|
|
427
|
+
const routeInput = {
|
|
428
|
+
content: sanitizedFact.content,
|
|
429
|
+
entities: sanitizedFact.entities,
|
|
430
|
+
metadata: {
|
|
431
|
+
...baseMeta,
|
|
432
|
+
...(fact.repo ? { repo: fact.repo } : {}),
|
|
433
|
+
...(fact.branch ? { branch: fact.branch } : {}),
|
|
434
|
+
...(fact.task_key ? { task_key: fact.task_key } : {}),
|
|
435
|
+
...(fact.workstream_key ? { workstream_key: fact.workstream_key } : {}),
|
|
436
|
+
category: fact.category,
|
|
437
|
+
},
|
|
438
|
+
};
|
|
432
439
|
try {
|
|
433
|
-
const dedup = await qdrant.dedupCheck(sanitizedFact.content, hash);
|
|
440
|
+
const dedup = await qdrant.dedupCheck(sanitizedFact.content, hash, undefined, undefined, routeInput);
|
|
434
441
|
if (dedup.action === "skip") {
|
|
435
442
|
// Reinforce existing fact
|
|
436
443
|
if (dedup.existingId) {
|
|
437
|
-
await qdrant.reinforceFact(dedup.existingId, dedup.existingCount || 1
|
|
444
|
+
await qdrant.reinforceFact(dedup.existingId, dedup.existingCount || 1, dedup.destination, buildOperationOrigin({
|
|
445
|
+
interface: "daemon",
|
|
446
|
+
action: "reinforce",
|
|
447
|
+
subsystem: "extraction",
|
|
448
|
+
config,
|
|
449
|
+
metadata: {
|
|
450
|
+
session_id: sessionId,
|
|
451
|
+
...(source ? { transcript_source: source } : {}),
|
|
452
|
+
dedup_action: dedup.action,
|
|
453
|
+
},
|
|
454
|
+
}));
|
|
438
455
|
}
|
|
439
456
|
continue;
|
|
440
457
|
}
|
|
@@ -444,6 +461,7 @@ const storeFacts = async (facts, sessionId, config, source) => {
|
|
|
444
461
|
const contradiction = await detectContradiction(sanitizedFact, config, {
|
|
445
462
|
sessionId,
|
|
446
463
|
workstreamKey: sanitizedFact.workstream_key ?? undefined,
|
|
464
|
+
destination: dedup.destination,
|
|
447
465
|
});
|
|
448
466
|
if (contradiction.contradiction && contradiction.existingId) {
|
|
449
467
|
logFn("INFO", `Extraction: contradiction detected for "${fact.content.slice(0, 60)}..." vs ${contradiction.existingId}: ${contradiction.reason}`);
|
|
@@ -533,7 +551,7 @@ const storeFacts = async (facts, sessionId, config, source) => {
|
|
|
533
551
|
// Downgrade to candidate with reduced confidence rather than dropping
|
|
534
552
|
// outright: similarity is a soft signal, not a hard reject.
|
|
535
553
|
try {
|
|
536
|
-
const badMatch = await qdrant.badExemplarCheck(sanitizedFact.content);
|
|
554
|
+
const badMatch = await qdrant.badExemplarCheck(sanitizedFact.content, undefined, routeInput);
|
|
537
555
|
if (badMatch && badMatch.score >= 0.85) {
|
|
538
556
|
effectiveConfidence = clamp01(effectiveConfidence - 0.2);
|
|
539
557
|
reviewStatus = "candidate";
|
|
@@ -553,7 +571,6 @@ const storeFacts = async (facts, sessionId, config, source) => {
|
|
|
553
571
|
domain: DEFAULT_CAPTURE_CONTEXT.domain,
|
|
554
572
|
memory_subtype: effectiveSubtype,
|
|
555
573
|
entities: sanitizedFact.entities,
|
|
556
|
-
source: "system",
|
|
557
574
|
kind: "fact",
|
|
558
575
|
confidence: effectiveConfidence,
|
|
559
576
|
importance: fact.importance,
|
|
@@ -571,17 +588,35 @@ const storeFacts = async (facts, sessionId, config, source) => {
|
|
|
571
588
|
task_key: fact.task_key,
|
|
572
589
|
workstream_key: fact.workstream_key,
|
|
573
590
|
metadata: factMeta,
|
|
591
|
+
origin: buildOperationOrigin({
|
|
592
|
+
interface: "daemon",
|
|
593
|
+
action: "create",
|
|
594
|
+
subsystem: "extraction",
|
|
595
|
+
config,
|
|
596
|
+
metadata: {
|
|
597
|
+
session_id: sessionId,
|
|
598
|
+
...(source ? { transcript_source: source } : {}),
|
|
599
|
+
capture_policy_version: CAPTURE_POLICY_VERSION,
|
|
600
|
+
},
|
|
601
|
+
}),
|
|
574
602
|
};
|
|
575
|
-
if (actor.actor_id) {
|
|
576
|
-
storePayload.actor_id = actor.actor_id;
|
|
577
|
-
}
|
|
578
603
|
if (dedup.action === "supersede" && dedup.existingId) {
|
|
579
|
-
const newId = await qdrant.storeFact(storePayload);
|
|
580
|
-
await qdrant.supersedeFact(dedup.existingId, newId
|
|
604
|
+
const newId = await qdrant.storeFact(storePayload, routeInput);
|
|
605
|
+
await qdrant.supersedeFact(dedup.existingId, newId, dedup.destination, buildOperationOrigin({
|
|
606
|
+
interface: "daemon",
|
|
607
|
+
action: "supersede",
|
|
608
|
+
subsystem: "extraction",
|
|
609
|
+
config,
|
|
610
|
+
metadata: {
|
|
611
|
+
session_id: sessionId,
|
|
612
|
+
new_fact_id: newId,
|
|
613
|
+
...(source ? { transcript_source: source } : {}),
|
|
614
|
+
},
|
|
615
|
+
}));
|
|
581
616
|
stored++;
|
|
582
617
|
}
|
|
583
618
|
else {
|
|
584
|
-
await qdrant.storeFact(storePayload);
|
|
619
|
+
await qdrant.storeFact(storePayload, routeInput);
|
|
585
620
|
stored++;
|
|
586
621
|
}
|
|
587
622
|
}
|
package/dist/daemon/qdrant.d.ts
CHANGED
|
@@ -7,9 +7,12 @@
|
|
|
7
7
|
* `qdrant_api_key` is optional — leave unset for unauthenticated local /
|
|
8
8
|
* self-hosted instances.
|
|
9
9
|
*/
|
|
10
|
+
import { type Destination } from "../config.js";
|
|
10
11
|
import { embed } from "../llm/index.js";
|
|
11
12
|
import type { InitEmbeddingInput } from "../llm/index.js";
|
|
13
|
+
import { type RoutingInput } from "../routing.js";
|
|
12
14
|
import { type RedactionSummary } from "../privacy/redaction.js";
|
|
15
|
+
import { type OperationOrigin } from "../provenance/origin.js";
|
|
13
16
|
export type LogFn = (level: string, ...args: unknown[]) => void;
|
|
14
17
|
export interface QdrantPayload {
|
|
15
18
|
content: string;
|
|
@@ -18,10 +21,15 @@ export interface QdrantPayload {
|
|
|
18
21
|
kind: string;
|
|
19
22
|
layer?: string | null;
|
|
20
23
|
memory_subtype?: string | null;
|
|
24
|
+
origin?: OperationOrigin;
|
|
25
|
+
last_operation_origin?: OperationOrigin;
|
|
26
|
+
/** @deprecated Origin is canonical for new writes. */
|
|
21
27
|
workspace_id?: string;
|
|
28
|
+
/** @deprecated Origin is canonical for new writes. */
|
|
22
29
|
actor_id?: string;
|
|
23
30
|
entities: string[];
|
|
24
|
-
|
|
31
|
+
/** @deprecated Origin is canonical for new writes. */
|
|
32
|
+
source?: string;
|
|
25
33
|
confidence: number;
|
|
26
34
|
importance: number;
|
|
27
35
|
content_hash: string;
|
|
@@ -65,11 +73,15 @@ export interface StoreFact {
|
|
|
65
73
|
layer?: string | null;
|
|
66
74
|
memory_subtype?: string | null;
|
|
67
75
|
entities: string[];
|
|
76
|
+
origin?: OperationOrigin;
|
|
77
|
+
last_operation_origin?: OperationOrigin;
|
|
78
|
+
/** @deprecated Origin is canonical for new writes. */
|
|
68
79
|
source?: string;
|
|
69
80
|
confidence?: number;
|
|
70
81
|
importance?: number;
|
|
71
82
|
content_hash: string;
|
|
72
83
|
workspace_id?: string;
|
|
84
|
+
/** @deprecated Origin is canonical for new writes. */
|
|
73
85
|
actor_id?: string;
|
|
74
86
|
metadata?: Record<string, string | number | boolean | null>;
|
|
75
87
|
session_id?: string | null;
|
|
@@ -100,6 +112,7 @@ export interface StoreFact {
|
|
|
100
112
|
}
|
|
101
113
|
export interface QdrantSearchResult {
|
|
102
114
|
id: string;
|
|
115
|
+
destination?: string;
|
|
103
116
|
score: number;
|
|
104
117
|
content: string;
|
|
105
118
|
category: string;
|
|
@@ -110,6 +123,7 @@ export interface QdrantSearchResult {
|
|
|
110
123
|
}
|
|
111
124
|
export interface QdrantScrollResult {
|
|
112
125
|
id: string;
|
|
126
|
+
destination?: string;
|
|
113
127
|
content: string;
|
|
114
128
|
category: string;
|
|
115
129
|
entities: string[];
|
|
@@ -151,6 +165,7 @@ export interface QdrantScrollFilters {
|
|
|
151
165
|
export type DedupAction = "insert" | "skip" | "supersede";
|
|
152
166
|
export interface DedupResult {
|
|
153
167
|
action: DedupAction;
|
|
168
|
+
destination?: string;
|
|
154
169
|
existingId?: string;
|
|
155
170
|
existingCount?: number;
|
|
156
171
|
score?: number;
|
|
@@ -162,16 +177,23 @@ export interface DedupThresholds {
|
|
|
162
177
|
declare let collection: string;
|
|
163
178
|
declare const setLogger: (fn: LogFn) => void;
|
|
164
179
|
declare const setEmbeddingConfig: (overrides?: Partial<InitEmbeddingInput>) => void;
|
|
180
|
+
type DestinationRef = Destination | string | null | undefined;
|
|
181
|
+
declare const resolveDestination: (input?: RoutingInput) => Destination;
|
|
165
182
|
declare const init: () => boolean;
|
|
166
183
|
declare const isReady: () => boolean;
|
|
167
184
|
declare const ensureCollection: () => Promise<void>;
|
|
168
|
-
declare const qdrantRequest: (method: string, urlPath: string, body?: unknown) => Promise<Record<string, unknown>>;
|
|
169
|
-
declare const
|
|
170
|
-
declare const
|
|
171
|
-
declare const
|
|
172
|
-
declare const
|
|
173
|
-
declare const
|
|
174
|
-
declare const
|
|
185
|
+
declare const qdrantRequest: (method: string, urlPath: string, body?: unknown, destinationRef?: DestinationRef) => Promise<Record<string, unknown>>;
|
|
186
|
+
declare const collectionForDestination: (destinationRef?: DestinationRef) => string;
|
|
187
|
+
declare const destinationNames: () => string[];
|
|
188
|
+
declare const readyDestinations: () => Destination[];
|
|
189
|
+
declare const activeDestinations: () => Destination[];
|
|
190
|
+
declare const searchFacts: (query: string, filters?: QdrantSearchFilters, limit?: number, destinationRef?: DestinationRef) => Promise<QdrantSearchResult[]>;
|
|
191
|
+
declare const scrollFacts: (filters?: QdrantScrollFilters, limit?: number, destinationRef?: DestinationRef) => Promise<QdrantScrollResult[]>;
|
|
192
|
+
declare const scrollFactsAcrossDestinations: (filters?: QdrantScrollFilters, limit?: number) => Promise<QdrantScrollResult[]>;
|
|
193
|
+
declare const storeFact: (fact: StoreFact, routeInput?: RoutingInput) => Promise<string>;
|
|
194
|
+
declare const supersedeFact: (oldFactId: string, newFactId: string, destinationRef?: DestinationRef, origin?: OperationOrigin) => Promise<void>;
|
|
195
|
+
declare const reinforceFact: (factId: string, currentCount: number, destinationRef?: DestinationRef, origin?: OperationOrigin) => Promise<void>;
|
|
196
|
+
declare const dedupCheck: (content: string, contentHashVal: string, { exactThreshold, supersedeThreshold }?: DedupThresholds, workspaceId?: string, routeInput?: RoutingInput) => Promise<DedupResult>;
|
|
175
197
|
/**
|
|
176
198
|
* Check whether incoming content is similar to any fact previously marked as a
|
|
177
199
|
* bad exemplar (via memory_forget). Returns the top similarity score, or null
|
|
@@ -181,10 +203,10 @@ declare const dedupCheck: (content: string, contentHashVal: string, { exactThres
|
|
|
181
203
|
* No hardcoded vocabulary — purely embedding-similarity based, and the
|
|
182
204
|
* exemplar set grows organically every time a user calls memory_forget.
|
|
183
205
|
*/
|
|
184
|
-
declare const badExemplarCheck: (content: string, workspaceId?: string) => Promise<{
|
|
206
|
+
declare const badExemplarCheck: (content: string, workspaceId?: string, routeInput?: RoutingInput) => Promise<{
|
|
185
207
|
score: number;
|
|
186
208
|
exemplarId: string;
|
|
187
209
|
reason?: string;
|
|
188
210
|
} | null>;
|
|
189
|
-
export { init, isReady, ensureCollection, setLogger, setEmbeddingConfig, qdrantRequest, embed, searchFacts, scrollFacts, storeFact, supersedeFact, reinforceFact, dedupCheck, badExemplarCheck, collection, };
|
|
211
|
+
export { init, isReady, ensureCollection, setLogger, setEmbeddingConfig, qdrantRequest, resolveDestination, collectionForDestination, destinationNames, readyDestinations, activeDestinations, embed, searchFacts, scrollFacts, scrollFactsAcrossDestinations, storeFact, supersedeFact, reinforceFact, dedupCheck, badExemplarCheck, collection, };
|
|
190
212
|
//# sourceMappingURL=qdrant.d.ts.map
|