@jungjaehoon/mama-core 1.4.2 → 1.6.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 +48 -10
- package/db/migrations/026-create-canonical-entity-tables.sql +99 -0
- package/db/migrations/027-create-entity-review-support.sql +44 -0
- package/db/migrations/028-create-entity-audit-tables.sql +45 -0
- package/db/migrations/029-extend-entity-observations-observation-type.sql +60 -0
- package/db/migrations/030-case-first-memory-substrate.sql +901 -0
- package/db/migrations/031-wiki-page-index-provenance-columns.sql +2 -0
- package/db/migrations/032-add-memory-provenance-columns.sql +21 -0
- package/db/migrations/033-create-model-runs-and-tool-traces.sql +53 -0
- package/db/migrations/034-add-connector-event-scope-columns.sql +14 -0
- package/db/migrations/035-create-twin-edges.sql +63 -0
- package/db/migrations/036-create-agent-situation-packets.sql +61 -0
- package/dist/agent-graph/alias-write.d.ts +3 -0
- package/dist/agent-graph/alias-write.js +231 -0
- package/dist/agent-graph/entity-resolve.d.ts +3 -0
- package/dist/agent-graph/entity-resolve.js +275 -0
- package/dist/agent-graph/errors.d.ts +4 -0
- package/dist/agent-graph/errors.js +11 -0
- package/dist/agent-graph/graph-query.d.ts +5 -0
- package/dist/agent-graph/graph-query.js +359 -0
- package/dist/agent-graph/index.d.ts +6 -0
- package/dist/agent-graph/index.js +22 -0
- package/dist/agent-graph/types.d.ts +162 -0
- package/dist/agent-graph/types.js +3 -0
- package/dist/agent-situation/builder.d.ts +8 -0
- package/dist/agent-situation/builder.js +239 -0
- package/dist/agent-situation/cache-key.d.ts +4 -0
- package/dist/agent-situation/cache-key.js +64 -0
- package/dist/agent-situation/index.d.ts +7 -0
- package/dist/agent-situation/index.js +28 -0
- package/dist/agent-situation/packet-store.d.ts +27 -0
- package/dist/agent-situation/packet-store.js +228 -0
- package/dist/agent-situation/ranking-policy.d.ts +18 -0
- package/dist/agent-situation/ranking-policy.js +75 -0
- package/dist/agent-situation/source-readers.d.ts +52 -0
- package/dist/agent-situation/source-readers.js +300 -0
- package/dist/agent-situation/types.d.ts +195 -0
- package/dist/agent-situation/types.js +3 -0
- package/dist/canonicalize.d.ts +38 -0
- package/dist/canonicalize.js +106 -0
- package/dist/cases/case-links.d.ts +116 -0
- package/dist/cases/case-links.js +794 -0
- package/dist/cases/composition-overrides.d.ts +90 -0
- package/dist/cases/composition-overrides.js +724 -0
- package/dist/cases/corrections.d.ts +156 -0
- package/dist/cases/corrections.js +1045 -0
- package/dist/cases/freshness.d.ts +57 -0
- package/dist/cases/freshness.js +283 -0
- package/dist/cases/live-state.d.ts +48 -0
- package/dist/cases/live-state.js +256 -0
- package/dist/cases/membership-explain.d.ts +56 -0
- package/dist/cases/membership-explain.js +140 -0
- package/dist/cases/membership-matcher.d.ts +23 -0
- package/dist/cases/membership-matcher.js +193 -0
- package/dist/cases/merge-split.d.ts +61 -0
- package/dist/cases/merge-split.js +368 -0
- package/dist/cases/role-inference.d.ts +10 -0
- package/dist/cases/role-inference.js +85 -0
- package/dist/cases/search-rollup.d.ts +27 -0
- package/dist/cases/search-rollup.js +309 -0
- package/dist/cases/sqlite-transaction.d.ts +10 -0
- package/dist/cases/sqlite-transaction.js +62 -0
- package/dist/cases/store.d.ts +74 -0
- package/dist/cases/store.js +816 -0
- package/dist/cases/target-ref.d.ts +25 -0
- package/dist/cases/target-ref.js +22 -0
- package/dist/cases/timeline-range.d.ts +6 -0
- package/dist/cases/timeline-range.js +322 -0
- package/dist/cases/tombstone-sweeper.d.ts +13 -0
- package/dist/cases/tombstone-sweeper.js +128 -0
- package/dist/cases/types.d.ts +244 -0
- package/dist/cases/types.js +47 -0
- package/dist/cases/wiki-page-index.d.ts +50 -0
- package/dist/cases/wiki-page-index.js +350 -0
- package/dist/connectors/event-index.d.ts +45 -0
- package/dist/connectors/event-index.js +381 -0
- package/dist/connectors/raw-query.d.ts +18 -0
- package/dist/connectors/raw-query.js +305 -0
- package/dist/connectors/types.d.ts +109 -0
- package/dist/connectors/types.js +3 -0
- package/dist/db-adapter/node-sqlite-adapter.d.ts +6 -0
- package/dist/db-adapter/node-sqlite-adapter.js +131 -0
- package/dist/db-manager.d.ts +12 -1
- package/dist/db-manager.js +60 -5
- package/dist/decision-formatter.d.ts +2 -0
- package/dist/decision-formatter.js +11 -8
- package/dist/edges/ref-validation.d.ts +8 -0
- package/dist/edges/ref-validation.js +262 -0
- package/dist/edges/store.d.ts +10 -0
- package/dist/edges/store.js +343 -0
- package/dist/edges/types.d.ts +86 -0
- package/dist/edges/types.js +18 -0
- package/dist/embedding-server/mobile/daemon.d.ts +1 -0
- package/dist/embedding-server/mobile/daemon.js +11 -1
- package/dist/embeddings.js +13 -0
- package/dist/entities/audit-metrics.d.ts +73 -0
- package/dist/entities/audit-metrics.js +128 -0
- package/dist/entities/candidate-generator.d.ts +9 -0
- package/dist/entities/candidate-generator.js +436 -0
- package/dist/entities/entity-impact.d.ts +41 -0
- package/dist/entities/entity-impact.js +140 -0
- package/dist/entities/entity-linked-decision-counts.d.ts +2 -0
- package/dist/entities/entity-linked-decision-counts.js +29 -0
- package/dist/entities/entity-list.d.ts +23 -0
- package/dist/entities/entity-list.js +99 -0
- package/dist/entities/entity-orphan-list.d.ts +26 -0
- package/dist/entities/entity-orphan-list.js +91 -0
- package/dist/entities/entity-search.d.ts +21 -0
- package/dist/entities/entity-search.js +150 -0
- package/dist/entities/errors.d.ts +65 -0
- package/dist/entities/errors.js +124 -0
- package/dist/entities/exact-merge-backfill.d.ts +11 -0
- package/dist/entities/exact-merge-backfill.js +161 -0
- package/dist/entities/lineage-backfill.d.ts +12 -0
- package/dist/entities/lineage-backfill.js +101 -0
- package/dist/entities/lineage-store.d.ts +51 -0
- package/dist/entities/lineage-store.js +308 -0
- package/dist/entities/normalization.d.ts +14 -0
- package/dist/entities/normalization.js +63 -0
- package/dist/entities/policy-store.d.ts +17 -0
- package/dist/entities/policy-store.js +263 -0
- package/dist/entities/policy-types.d.ts +72 -0
- package/dist/entities/policy-types.js +59 -0
- package/dist/entities/projection.d.ts +8 -0
- package/dist/entities/projection.js +82 -0
- package/dist/entities/provenance-query.d.ts +33 -0
- package/dist/entities/provenance-query.js +167 -0
- package/dist/entities/read-identity.d.ts +31 -0
- package/dist/entities/read-identity.js +264 -0
- package/dist/entities/recall-bridge.d.ts +5 -0
- package/dist/entities/recall-bridge.js +171 -0
- package/dist/entities/resolution-engine.d.ts +15 -0
- package/dist/entities/resolution-engine.js +69 -0
- package/dist/entities/rollback-preview.d.ts +39 -0
- package/dist/entities/rollback-preview.js +235 -0
- package/dist/entities/source-locator.d.ts +3 -0
- package/dist/entities/source-locator.js +32 -0
- package/dist/entities/store.d.ts +75 -0
- package/dist/entities/store.js +465 -0
- package/dist/entities/types.d.ts +162 -0
- package/dist/entities/types.js +30 -0
- package/dist/index.d.ts +62 -3
- package/dist/index.js +116 -26
- package/dist/mama-api.d.ts +53 -35
- package/dist/mama-api.js +437 -78
- package/dist/memory/api.d.ts +26 -38
- package/dist/memory/api.js +772 -68
- package/dist/memory/event-store.d.ts +3 -0
- package/dist/memory/event-store.js +21 -2
- package/dist/memory/provenance-audit.d.ts +22 -0
- package/dist/memory/provenance-audit.js +112 -0
- package/dist/memory/provenance-query.d.ts +11 -0
- package/dist/memory/provenance-query.js +193 -0
- package/dist/memory/provenance.d.ts +29 -0
- package/dist/memory/provenance.js +136 -0
- package/dist/memory/scope-backfill.d.ts +17 -0
- package/dist/memory/scope-backfill.js +77 -0
- package/dist/memory/types.d.ts +97 -16
- package/dist/model-runs/store.d.ts +13 -0
- package/dist/model-runs/store.js +457 -0
- package/dist/model-runs/tool-trace-store.d.ts +4 -0
- package/dist/model-runs/tool-trace-store.js +114 -0
- package/dist/model-runs/types.d.ts +69 -0
- package/dist/model-runs/types.js +5 -0
- package/dist/runtime/trusted-provenance.d.ts +3 -0
- package/dist/runtime/trusted-provenance.js +6 -0
- package/dist/search/feedback-store.d.ts +59 -0
- package/dist/search/feedback-store.js +211 -0
- package/dist/search/question-type.d.ts +5 -0
- package/dist/search/question-type.js +41 -0
- package/dist/search/ranker-features.d.ts +23 -0
- package/dist/search/ranker-features.js +104 -0
- package/dist/search/ranker-rescore.d.ts +31 -0
- package/dist/search/ranker-rescore.js +226 -0
- package/dist/search/ranker-trainer.d.ts +94 -0
- package/dist/search/ranker-trainer.js +860 -0
- package/dist/search/search-quality.d.ts +36 -0
- package/dist/search/search-quality.js +29 -0
- package/dist/test-utils.d.ts +14 -0
- package/dist/test-utils.js +52 -0
- package/package.json +28 -3
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
export declare const CASE_TRUTH_STATUSES: readonly ["active", "blocked", "resolved", "stale", "archived", "merged", "split"];
|
|
2
|
+
export type CaseTruthStatus = (typeof CASE_TRUTH_STATUSES)[number];
|
|
3
|
+
export declare const CASE_FAST_WRITE_STATUSES: readonly ["active", "blocked", "resolved", "stale"];
|
|
4
|
+
export type CaseFastWriteStatus = (typeof CASE_FAST_WRITE_STATUSES)[number];
|
|
5
|
+
export declare const CASE_MEMBERSHIP_SOURCE_TYPES: readonly ["decision", "event", "observation", "artifact"];
|
|
6
|
+
export type CaseMembershipSourceType = (typeof CASE_MEMBERSHIP_SOURCE_TYPES)[number];
|
|
7
|
+
export declare const CASE_MEMBERSHIP_STATUSES: readonly ["active", "candidate", "removed", "excluded", "stale"];
|
|
8
|
+
export type CaseMembershipStatus = (typeof CASE_MEMBERSHIP_STATUSES)[number];
|
|
9
|
+
export declare const CASE_MEMBERSHIP_ADDED_BY: readonly ["wiki-compiler", "memory-agent", "user-correction"];
|
|
10
|
+
export type CaseMembershipAddedBy = (typeof CASE_MEMBERSHIP_ADDED_BY)[number];
|
|
11
|
+
export declare const CASE_CORRECTION_TARGET_KINDS: readonly ["case_field", "membership", "wiki_section"];
|
|
12
|
+
export type CaseCorrectionTargetKind = (typeof CASE_CORRECTION_TARGET_KINDS)[number];
|
|
13
|
+
export declare const CASE_PROPOSAL_KINDS: readonly ["ambiguous_slug", "duplicate_frontmatter", "missing_frontmatter", "unknown_case_id", "stale_case_id", "merged_target", "archived_target", "lock_conflict", "corrupt_frontmatter", "quarantined_accepted_case"];
|
|
14
|
+
export type CaseProposalKind = (typeof CASE_PROPOSAL_KINDS)[number];
|
|
15
|
+
export declare const CASE_PROPOSAL_RESOLUTIONS: readonly ["accepted", "rejected", "modified", "merged"];
|
|
16
|
+
export type CaseProposalResolution = (typeof CASE_PROPOSAL_RESOLUTIONS)[number];
|
|
17
|
+
export declare const CASE_CONFIDENCE_LEVELS: readonly ["high", "medium", "low"];
|
|
18
|
+
export type CaseConfidence = (typeof CASE_CONFIDENCE_LEVELS)[number];
|
|
19
|
+
export interface CaseTruthRecord {
|
|
20
|
+
case_id: string;
|
|
21
|
+
current_wiki_path: string | null;
|
|
22
|
+
title: string;
|
|
23
|
+
status: CaseTruthStatus;
|
|
24
|
+
status_reason: string | null;
|
|
25
|
+
primary_actors: string | null;
|
|
26
|
+
blockers: string | null;
|
|
27
|
+
last_activity_at: string | null;
|
|
28
|
+
canonical_case_id?: string | null;
|
|
29
|
+
split_from_case_id?: string | null;
|
|
30
|
+
wiki_path_history: string | null;
|
|
31
|
+
scope_refs: string | null;
|
|
32
|
+
confidence: CaseConfidence | null;
|
|
33
|
+
compiled_at: string | null;
|
|
34
|
+
state_updated_at: string | null;
|
|
35
|
+
created_at: string;
|
|
36
|
+
updated_at: string;
|
|
37
|
+
}
|
|
38
|
+
export interface CaseMembershipRecord {
|
|
39
|
+
case_id: string;
|
|
40
|
+
source_type: CaseMembershipSourceType;
|
|
41
|
+
source_id: string;
|
|
42
|
+
role: string | null;
|
|
43
|
+
confidence: number | null;
|
|
44
|
+
reason: string | null;
|
|
45
|
+
status: CaseMembershipStatus;
|
|
46
|
+
added_by: CaseMembershipAddedBy;
|
|
47
|
+
added_at: string;
|
|
48
|
+
updated_at: string;
|
|
49
|
+
user_locked: 0 | 1;
|
|
50
|
+
}
|
|
51
|
+
export interface CaseCorrectionRecord {
|
|
52
|
+
correction_id: string;
|
|
53
|
+
case_id: string;
|
|
54
|
+
target_kind: CaseCorrectionTargetKind;
|
|
55
|
+
target_ref_json: string;
|
|
56
|
+
target_ref_hash: Buffer;
|
|
57
|
+
field_name: string | null;
|
|
58
|
+
old_value_json: string | null;
|
|
59
|
+
new_value_json: string;
|
|
60
|
+
reason: string;
|
|
61
|
+
is_lock_active: 0 | 1;
|
|
62
|
+
superseded_by: string | null;
|
|
63
|
+
reverted_at: string | null;
|
|
64
|
+
applied_by: string;
|
|
65
|
+
applied_at: string;
|
|
66
|
+
}
|
|
67
|
+
export interface CaseCorrectionRequiresReconfirmResult {
|
|
68
|
+
kind: 'requires_reconfirm';
|
|
69
|
+
code: 'case.correction_requires_reconfirm';
|
|
70
|
+
case_id: string;
|
|
71
|
+
target_kind: CaseCorrectionTargetKind;
|
|
72
|
+
target_ref_json: string;
|
|
73
|
+
current_value_json: string;
|
|
74
|
+
old_value_json: string | null;
|
|
75
|
+
proposed_new_value_json: string;
|
|
76
|
+
reconfirm_token: string;
|
|
77
|
+
reconfirm_token_expires_at: string;
|
|
78
|
+
message: string;
|
|
79
|
+
}
|
|
80
|
+
export interface CaseProposalQueueRecord {
|
|
81
|
+
proposal_id: string;
|
|
82
|
+
project: string;
|
|
83
|
+
proposal_kind: CaseProposalKind;
|
|
84
|
+
proposed_payload: string;
|
|
85
|
+
payload_fingerprint: Buffer;
|
|
86
|
+
conflicting_case_id: string | null;
|
|
87
|
+
detected_at: string;
|
|
88
|
+
resolved_at: string | null;
|
|
89
|
+
resolution: CaseProposalResolution | null;
|
|
90
|
+
resolution_note: string | null;
|
|
91
|
+
}
|
|
92
|
+
export interface CasePrimaryActor {
|
|
93
|
+
entity_id: string;
|
|
94
|
+
role: string;
|
|
95
|
+
}
|
|
96
|
+
export interface CaseBlocker {
|
|
97
|
+
text: string;
|
|
98
|
+
source_decision_id?: string;
|
|
99
|
+
source_event_id?: string;
|
|
100
|
+
}
|
|
101
|
+
export interface CaseAssemblyMembership {
|
|
102
|
+
source_type: CaseMembershipSourceType;
|
|
103
|
+
source_id: string;
|
|
104
|
+
role: string | null;
|
|
105
|
+
confidence: number | null;
|
|
106
|
+
reason: string | null;
|
|
107
|
+
user_locked: boolean;
|
|
108
|
+
}
|
|
109
|
+
export interface CaseAssemblyDecision {
|
|
110
|
+
id: string;
|
|
111
|
+
topic: string;
|
|
112
|
+
decision: string;
|
|
113
|
+
reasoning: string | null;
|
|
114
|
+
confidence: number | null;
|
|
115
|
+
event_date: string | null;
|
|
116
|
+
}
|
|
117
|
+
export interface CaseAssemblyTimelineEvent {
|
|
118
|
+
event_id: string;
|
|
119
|
+
event_type: string;
|
|
120
|
+
entity_id: string;
|
|
121
|
+
role: string | null;
|
|
122
|
+
observed_at: string;
|
|
123
|
+
summary: string;
|
|
124
|
+
details: string | null;
|
|
125
|
+
}
|
|
126
|
+
export interface CaseAssemblyObservation {
|
|
127
|
+
observation_id: string;
|
|
128
|
+
surface_form: string;
|
|
129
|
+
source_locator: string;
|
|
130
|
+
timestamp_observed: string;
|
|
131
|
+
}
|
|
132
|
+
export interface CaseAssemblyCorrection {
|
|
133
|
+
correction_id: string;
|
|
134
|
+
target_kind: CaseCorrectionTargetKind;
|
|
135
|
+
target_ref: Record<string, unknown>;
|
|
136
|
+
new_value_json: string;
|
|
137
|
+
reason: string;
|
|
138
|
+
applied_at: string;
|
|
139
|
+
}
|
|
140
|
+
export interface CaseAssemblyLinkedCase {
|
|
141
|
+
case_id: string;
|
|
142
|
+
relation: 'merged_from' | 'split_into' | 'wikilink';
|
|
143
|
+
}
|
|
144
|
+
export interface WikiPageAssemblySnapshot {
|
|
145
|
+
title: string | null;
|
|
146
|
+
content: string | null;
|
|
147
|
+
confidence: CaseConfidence | null;
|
|
148
|
+
compiled_at: string | null;
|
|
149
|
+
}
|
|
150
|
+
export interface CaseAssembly {
|
|
151
|
+
case_id: string;
|
|
152
|
+
current_wiki_path: string | null;
|
|
153
|
+
wiki_page: WikiPageAssemblySnapshot | null;
|
|
154
|
+
case_truth: {
|
|
155
|
+
title: string;
|
|
156
|
+
status: CaseTruthStatus;
|
|
157
|
+
status_reason: string | null;
|
|
158
|
+
primary_actors: CasePrimaryActor[];
|
|
159
|
+
blockers: CaseBlocker[];
|
|
160
|
+
last_activity_at: string | null;
|
|
161
|
+
confidence: CaseConfidence | null;
|
|
162
|
+
canonical_case_id: string | null;
|
|
163
|
+
split_from_case_id: string | null;
|
|
164
|
+
} | null;
|
|
165
|
+
memberships: CaseAssemblyMembership[];
|
|
166
|
+
timeline_events: CaseAssemblyTimelineEvent[];
|
|
167
|
+
decisions: CaseAssemblyDecision[];
|
|
168
|
+
recent_evidence: CaseAssemblyObservation[];
|
|
169
|
+
active_corrections: CaseAssemblyCorrection[];
|
|
170
|
+
linked_cases: CaseAssemblyLinkedCase[];
|
|
171
|
+
resolved_via_case_id?: string;
|
|
172
|
+
case_links?: Array<{
|
|
173
|
+
link_id: string;
|
|
174
|
+
case_id_from: string;
|
|
175
|
+
case_id_to: string;
|
|
176
|
+
link_type: string;
|
|
177
|
+
created_at: string;
|
|
178
|
+
created_by: string;
|
|
179
|
+
confidence: number | null;
|
|
180
|
+
reason_json: string | null;
|
|
181
|
+
source_kind: string;
|
|
182
|
+
source_ref: string | null;
|
|
183
|
+
}>;
|
|
184
|
+
promoted_sources?: {
|
|
185
|
+
canonical_decision_id: string | null;
|
|
186
|
+
canonical_event_id: string | null;
|
|
187
|
+
promoted_at: string | null;
|
|
188
|
+
promoted_by: string | null;
|
|
189
|
+
promotion_reason: string | null;
|
|
190
|
+
} | null;
|
|
191
|
+
freshness?: {
|
|
192
|
+
freshness_score: number | null;
|
|
193
|
+
freshness_state: string | null;
|
|
194
|
+
freshness_score_is_drifted: 0 | 1;
|
|
195
|
+
freshness_drift_threshold: number | null;
|
|
196
|
+
freshness_checked_at: string | null;
|
|
197
|
+
freshness_reason_json: string | null;
|
|
198
|
+
} | null;
|
|
199
|
+
membership_explanations?: Record<string, Record<string, unknown>>;
|
|
200
|
+
}
|
|
201
|
+
export interface CanonicalCaseResolution {
|
|
202
|
+
terminal_case_id: string;
|
|
203
|
+
chain: string[];
|
|
204
|
+
resolved_via_case_id: string | null;
|
|
205
|
+
}
|
|
206
|
+
export interface CaseTimelineRangeInput {
|
|
207
|
+
case_id: string;
|
|
208
|
+
from?: string | number;
|
|
209
|
+
to?: string | number;
|
|
210
|
+
order?: 'asc' | 'desc';
|
|
211
|
+
limit?: number;
|
|
212
|
+
include_connector_enrichments?: boolean;
|
|
213
|
+
}
|
|
214
|
+
export interface CaseTimelineRangeItem {
|
|
215
|
+
item_type: CaseMembershipSourceType;
|
|
216
|
+
source_type: CaseMembershipSourceType;
|
|
217
|
+
source_id: string;
|
|
218
|
+
source_locator: string | null;
|
|
219
|
+
event_datetime: number | null;
|
|
220
|
+
event_date: string | null;
|
|
221
|
+
title: string | null;
|
|
222
|
+
summary: string | null;
|
|
223
|
+
role: string | null;
|
|
224
|
+
confidence: number | null;
|
|
225
|
+
membership_reason: string | null;
|
|
226
|
+
connector_event?: {
|
|
227
|
+
event_index_id: string;
|
|
228
|
+
source_connector: string;
|
|
229
|
+
source_id: string;
|
|
230
|
+
source_locator: string | null;
|
|
231
|
+
artifact_locator: string | null;
|
|
232
|
+
title: string | null;
|
|
233
|
+
content: string;
|
|
234
|
+
event_datetime: number | null;
|
|
235
|
+
event_date: string | null;
|
|
236
|
+
} | null;
|
|
237
|
+
}
|
|
238
|
+
export interface CaseTimelineRangeResult {
|
|
239
|
+
terminal_case_id: string;
|
|
240
|
+
resolved_via_case_id: string | null;
|
|
241
|
+
chain: string[];
|
|
242
|
+
items: CaseTimelineRangeItem[];
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CASE_CONFIDENCE_LEVELS = exports.CASE_PROPOSAL_RESOLUTIONS = exports.CASE_PROPOSAL_KINDS = exports.CASE_CORRECTION_TARGET_KINDS = exports.CASE_MEMBERSHIP_ADDED_BY = exports.CASE_MEMBERSHIP_STATUSES = exports.CASE_MEMBERSHIP_SOURCE_TYPES = exports.CASE_FAST_WRITE_STATUSES = exports.CASE_TRUTH_STATUSES = void 0;
|
|
4
|
+
exports.CASE_TRUTH_STATUSES = [
|
|
5
|
+
'active',
|
|
6
|
+
'blocked',
|
|
7
|
+
'resolved',
|
|
8
|
+
'stale',
|
|
9
|
+
'archived',
|
|
10
|
+
'merged',
|
|
11
|
+
'split',
|
|
12
|
+
];
|
|
13
|
+
exports.CASE_FAST_WRITE_STATUSES = ['active', 'blocked', 'resolved', 'stale'];
|
|
14
|
+
exports.CASE_MEMBERSHIP_SOURCE_TYPES = [
|
|
15
|
+
'decision',
|
|
16
|
+
'event',
|
|
17
|
+
'observation',
|
|
18
|
+
'artifact',
|
|
19
|
+
];
|
|
20
|
+
exports.CASE_MEMBERSHIP_STATUSES = [
|
|
21
|
+
'active',
|
|
22
|
+
'candidate',
|
|
23
|
+
'removed',
|
|
24
|
+
'excluded',
|
|
25
|
+
'stale',
|
|
26
|
+
];
|
|
27
|
+
exports.CASE_MEMBERSHIP_ADDED_BY = [
|
|
28
|
+
'wiki-compiler',
|
|
29
|
+
'memory-agent',
|
|
30
|
+
'user-correction',
|
|
31
|
+
];
|
|
32
|
+
exports.CASE_CORRECTION_TARGET_KINDS = ['case_field', 'membership', 'wiki_section'];
|
|
33
|
+
exports.CASE_PROPOSAL_KINDS = [
|
|
34
|
+
'ambiguous_slug',
|
|
35
|
+
'duplicate_frontmatter',
|
|
36
|
+
'missing_frontmatter',
|
|
37
|
+
'unknown_case_id',
|
|
38
|
+
'stale_case_id',
|
|
39
|
+
'merged_target',
|
|
40
|
+
'archived_target',
|
|
41
|
+
'lock_conflict',
|
|
42
|
+
'corrupt_frontmatter',
|
|
43
|
+
'quarantined_accepted_case',
|
|
44
|
+
];
|
|
45
|
+
exports.CASE_PROPOSAL_RESOLUTIONS = ['accepted', 'rejected', 'modified', 'merged'];
|
|
46
|
+
exports.CASE_CONFIDENCE_LEVELS = ['high', 'medium', 'low'];
|
|
47
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { DatabaseAdapter as DBManagerAdapter } from '../db-manager.js';
|
|
2
|
+
export type AdapterLike = Pick<DBManagerAdapter, 'prepare' | 'transaction'>;
|
|
3
|
+
export interface WikiPageIndexRecord {
|
|
4
|
+
id: number;
|
|
5
|
+
source_locator: string;
|
|
6
|
+
page_type: 'entity' | 'lesson' | 'synthesis' | 'process' | 'case';
|
|
7
|
+
title: string;
|
|
8
|
+
content: string;
|
|
9
|
+
case_id: string | null;
|
|
10
|
+
source_ids: string[];
|
|
11
|
+
entity_refs: string[];
|
|
12
|
+
confidence: 'high' | 'medium' | 'low' | null;
|
|
13
|
+
compiled_at: string;
|
|
14
|
+
created_at: string;
|
|
15
|
+
updated_at: string;
|
|
16
|
+
}
|
|
17
|
+
export interface WikiPageSearchHit {
|
|
18
|
+
record: WikiPageIndexRecord;
|
|
19
|
+
rank: number;
|
|
20
|
+
raw_score: number;
|
|
21
|
+
}
|
|
22
|
+
export interface UpsertWikiPageIndexInput {
|
|
23
|
+
source_locator: string;
|
|
24
|
+
page_type: WikiPageIndexRecord['page_type'];
|
|
25
|
+
title: string;
|
|
26
|
+
content: string;
|
|
27
|
+
case_id?: string | null;
|
|
28
|
+
source_ids: string[];
|
|
29
|
+
entity_refs: string[];
|
|
30
|
+
confidence: WikiPageIndexRecord['confidence'];
|
|
31
|
+
compiled_at: string;
|
|
32
|
+
embedding?: Float32Array | null;
|
|
33
|
+
embedding_model?: string;
|
|
34
|
+
}
|
|
35
|
+
export declare function upsertWikiPageIndexEntry(adapter: AdapterLike, input: UpsertWikiPageIndexInput): {
|
|
36
|
+
id: number;
|
|
37
|
+
created: boolean;
|
|
38
|
+
};
|
|
39
|
+
export declare function deleteWikiPageIndexEntry(adapter: AdapterLike, source_locator: string): {
|
|
40
|
+
deleted: boolean;
|
|
41
|
+
};
|
|
42
|
+
export declare function ftsSearchWikiPages(adapter: AdapterLike, query: string, limit: number): WikiPageSearchHit[];
|
|
43
|
+
export declare function vectorSearchWikiPages(adapter: AdapterLike, queryEmbedding: Float32Array, limit: number): WikiPageSearchHit[];
|
|
44
|
+
export declare function searchWikiPages(input: {
|
|
45
|
+
adapter: AdapterLike;
|
|
46
|
+
query: string;
|
|
47
|
+
queryEmbedding?: Float32Array | null;
|
|
48
|
+
limit: number;
|
|
49
|
+
}): WikiPageSearchHit[];
|
|
50
|
+
//# sourceMappingURL=wiki-page-index.d.ts.map
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.upsertWikiPageIndexEntry = upsertWikiPageIndexEntry;
|
|
7
|
+
exports.deleteWikiPageIndexEntry = deleteWikiPageIndexEntry;
|
|
8
|
+
exports.ftsSearchWikiPages = ftsSearchWikiPages;
|
|
9
|
+
exports.vectorSearchWikiPages = vectorSearchWikiPages;
|
|
10
|
+
exports.searchWikiPages = searchWikiPages;
|
|
11
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
12
|
+
const embeddings_js_1 = require("../embeddings.js");
|
|
13
|
+
function tableColumns(adapter, tableName) {
|
|
14
|
+
const rows = adapter.prepare(`PRAGMA table_info(${tableName})`).all();
|
|
15
|
+
return new Set(rows.map((row) => row.name));
|
|
16
|
+
}
|
|
17
|
+
function readSchema(adapter) {
|
|
18
|
+
const indexColumns = tableColumns(adapter, 'wiki_page_index');
|
|
19
|
+
const embeddingColumns = tableColumns(adapter, 'wiki_page_embeddings');
|
|
20
|
+
if (!indexColumns.has('id') && !indexColumns.has('page_id')) {
|
|
21
|
+
throw new Error('wiki_page_index schema is missing both id and page_id columns.');
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
hasIdColumn: indexColumns.has('id'),
|
|
25
|
+
hasPageIdColumn: indexColumns.has('page_id'),
|
|
26
|
+
hasSourceTypeColumn: indexColumns.has('source_type'),
|
|
27
|
+
hasSourceIdsColumn: indexColumns.has('source_ids'),
|
|
28
|
+
hasEntityRefsColumn: indexColumns.has('entity_refs'),
|
|
29
|
+
hasCreatedAtColumn: indexColumns.has('created_at'),
|
|
30
|
+
embeddingUsesWikiPageId: embeddingColumns.has('wiki_page_id'),
|
|
31
|
+
embeddingUsesVector: embeddingColumns.has('vector'),
|
|
32
|
+
embeddingHasModel: embeddingColumns.has('model'),
|
|
33
|
+
embeddingHasDim: embeddingColumns.has('dim'),
|
|
34
|
+
embeddingHasCreatedAt: embeddingColumns.has('created_at'),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function nowIso() {
|
|
38
|
+
return new Date().toISOString();
|
|
39
|
+
}
|
|
40
|
+
function normalizeLimit(limit) {
|
|
41
|
+
if (!Number.isFinite(limit)) {
|
|
42
|
+
return 10;
|
|
43
|
+
}
|
|
44
|
+
return Math.max(0, Math.floor(limit));
|
|
45
|
+
}
|
|
46
|
+
function pageIdForSourceLocator(sourceLocator) {
|
|
47
|
+
const digest = node_crypto_1.default.createHash('sha256').update(sourceLocator).digest('hex').slice(0, 24);
|
|
48
|
+
return `wiki_page_${digest}`;
|
|
49
|
+
}
|
|
50
|
+
function parseJsonArray(value) {
|
|
51
|
+
if (value === null || value === undefined || value === '') {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
if (Array.isArray(value)) {
|
|
55
|
+
return value.map(String);
|
|
56
|
+
}
|
|
57
|
+
if (typeof value !== 'string') {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
const parsed = JSON.parse(value);
|
|
61
|
+
if (!Array.isArray(parsed)) {
|
|
62
|
+
throw new Error('wiki_page_index JSON array column decoded to a non-array value.');
|
|
63
|
+
}
|
|
64
|
+
return parsed.map(String);
|
|
65
|
+
}
|
|
66
|
+
function normalizeConfidence(value) {
|
|
67
|
+
if (value === 'high' || value === 'medium' || value === 'low') {
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
function rowToRecord(row) {
|
|
73
|
+
const id = Number(row.id);
|
|
74
|
+
if (!Number.isFinite(id)) {
|
|
75
|
+
throw new Error('wiki_page_index row is missing a numeric id/rowid.');
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
id,
|
|
79
|
+
source_locator: String(row.source_locator ?? ''),
|
|
80
|
+
page_type: row.page_type,
|
|
81
|
+
title: String(row.title ?? ''),
|
|
82
|
+
content: String(row.content ?? ''),
|
|
83
|
+
case_id: row.case_id === null || row.case_id === undefined ? null : String(row.case_id),
|
|
84
|
+
source_ids: parseJsonArray(row.source_ids),
|
|
85
|
+
entity_refs: parseJsonArray(row.entity_refs),
|
|
86
|
+
confidence: normalizeConfidence(row.confidence),
|
|
87
|
+
compiled_at: String(row.compiled_at ?? ''),
|
|
88
|
+
created_at: String(row.created_at ?? row.updated_at ?? row.compiled_at ?? ''),
|
|
89
|
+
updated_at: String(row.updated_at ?? row.created_at ?? row.compiled_at ?? ''),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function selectByLocator(adapter, schema, sourceLocator) {
|
|
93
|
+
const sql = schema.hasIdColumn
|
|
94
|
+
? 'SELECT * FROM wiki_page_index WHERE source_locator = ?'
|
|
95
|
+
: 'SELECT rowid AS id, * FROM wiki_page_index WHERE source_locator = ?';
|
|
96
|
+
const row = adapter.prepare(sql).get(sourceLocator);
|
|
97
|
+
return row ? rowToRecord(row) : null;
|
|
98
|
+
}
|
|
99
|
+
function selectByFtsPageId(adapter, schema, pageId) {
|
|
100
|
+
const sql = schema.hasIdColumn
|
|
101
|
+
? 'SELECT * FROM wiki_page_index WHERE id = ?'
|
|
102
|
+
: 'SELECT rowid AS id, * FROM wiki_page_index WHERE page_id = ?';
|
|
103
|
+
const lookup = schema.hasIdColumn ? Number(pageId) : String(pageId);
|
|
104
|
+
const row = adapter.prepare(sql).get(lookup);
|
|
105
|
+
return row ? rowToRecord(row) : null;
|
|
106
|
+
}
|
|
107
|
+
function vectorToBuffer(embedding) {
|
|
108
|
+
return Buffer.from(embedding.buffer, embedding.byteOffset, embedding.byteLength);
|
|
109
|
+
}
|
|
110
|
+
function blobToVector(value) {
|
|
111
|
+
if (!(value instanceof Uint8Array)) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
if (value.byteLength % 4 !== 0) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
const buffer = Buffer.isBuffer(value) ? value : Buffer.from(value);
|
|
118
|
+
const arrayBuffer = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
119
|
+
return new Float32Array(arrayBuffer);
|
|
120
|
+
}
|
|
121
|
+
function upsertEmbedding(adapter, schema, record, input) {
|
|
122
|
+
if (!input.embedding) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const vector = vectorToBuffer(input.embedding);
|
|
126
|
+
const model = input.embedding_model ?? embeddings_js_1.MODEL_NAME;
|
|
127
|
+
const dim = input.embedding.length;
|
|
128
|
+
if (schema.embeddingUsesWikiPageId && schema.embeddingUsesVector) {
|
|
129
|
+
adapter
|
|
130
|
+
.prepare(`
|
|
131
|
+
INSERT INTO wiki_page_embeddings(wiki_page_id, vector, model, dim, created_at)
|
|
132
|
+
VALUES (?, ?, ?, ?, ?)
|
|
133
|
+
ON CONFLICT(wiki_page_id) DO UPDATE SET
|
|
134
|
+
vector = excluded.vector,
|
|
135
|
+
model = excluded.model,
|
|
136
|
+
dim = excluded.dim
|
|
137
|
+
`)
|
|
138
|
+
.run(record.id, vector, model, dim, nowIso());
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
adapter
|
|
142
|
+
.prepare(`
|
|
143
|
+
INSERT INTO wiki_page_embeddings(page_id, embedding)
|
|
144
|
+
VALUES (?, ?)
|
|
145
|
+
ON CONFLICT(page_id) DO UPDATE SET
|
|
146
|
+
embedding = excluded.embedding
|
|
147
|
+
`)
|
|
148
|
+
.run(pageIdForSourceLocator(record.source_locator), vector);
|
|
149
|
+
}
|
|
150
|
+
function buildFtsQuery(query) {
|
|
151
|
+
const tokens = query
|
|
152
|
+
.toLowerCase()
|
|
153
|
+
.match(/[\p{L}\p{N}_]+/gu)
|
|
154
|
+
?.filter((token) => token.length > 0);
|
|
155
|
+
if (!tokens || tokens.length === 0) {
|
|
156
|
+
return query;
|
|
157
|
+
}
|
|
158
|
+
return tokens.map((token) => `"${token.replace(/"/g, '""')}"`).join(' OR ');
|
|
159
|
+
}
|
|
160
|
+
function normalizeBm25Score(raw) {
|
|
161
|
+
const value = Number(raw);
|
|
162
|
+
if (!Number.isFinite(value)) {
|
|
163
|
+
return 0;
|
|
164
|
+
}
|
|
165
|
+
if (value < 0) {
|
|
166
|
+
return 1 + Math.abs(value);
|
|
167
|
+
}
|
|
168
|
+
return 1 / (1 + value);
|
|
169
|
+
}
|
|
170
|
+
function searchTableExists(adapter, tableName) {
|
|
171
|
+
const row = adapter
|
|
172
|
+
.prepare("SELECT name FROM sqlite_master WHERE name = ? AND type IN ('table','virtual table')")
|
|
173
|
+
.get(tableName);
|
|
174
|
+
return row !== undefined;
|
|
175
|
+
}
|
|
176
|
+
function upsertWikiPageIndexEntry(adapter, input) {
|
|
177
|
+
const schema = readSchema(adapter);
|
|
178
|
+
const existing = selectByLocator(adapter, schema, input.source_locator);
|
|
179
|
+
const updatedAt = nowIso();
|
|
180
|
+
return adapter.transaction(() => {
|
|
181
|
+
if (schema.hasIdColumn) {
|
|
182
|
+
adapter
|
|
183
|
+
.prepare(`
|
|
184
|
+
INSERT INTO wiki_page_index (
|
|
185
|
+
source_locator, page_type, title, content, case_id, source_ids,
|
|
186
|
+
confidence, entity_refs, compiled_at, created_at, updated_at
|
|
187
|
+
)
|
|
188
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
189
|
+
ON CONFLICT(source_locator) DO UPDATE SET
|
|
190
|
+
page_type = excluded.page_type,
|
|
191
|
+
title = excluded.title,
|
|
192
|
+
content = excluded.content,
|
|
193
|
+
case_id = excluded.case_id,
|
|
194
|
+
source_ids = excluded.source_ids,
|
|
195
|
+
confidence = excluded.confidence,
|
|
196
|
+
entity_refs = excluded.entity_refs,
|
|
197
|
+
compiled_at = excluded.compiled_at,
|
|
198
|
+
updated_at = excluded.updated_at
|
|
199
|
+
`)
|
|
200
|
+
.run(input.source_locator, input.page_type, input.title, input.content, input.case_id ?? null, JSON.stringify(input.source_ids), input.confidence, JSON.stringify(input.entity_refs), input.compiled_at, updatedAt, updatedAt);
|
|
201
|
+
}
|
|
202
|
+
else if (schema.hasSourceIdsColumn && schema.hasEntityRefsColumn) {
|
|
203
|
+
adapter
|
|
204
|
+
.prepare(`
|
|
205
|
+
INSERT INTO wiki_page_index (
|
|
206
|
+
page_id, source_type, source_locator, case_id, title, page_type,
|
|
207
|
+
content, confidence, source_ids, entity_refs, compiled_at, updated_at
|
|
208
|
+
)
|
|
209
|
+
VALUES (?, 'wiki_page', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
210
|
+
ON CONFLICT(source_type, source_locator) DO UPDATE SET
|
|
211
|
+
case_id = excluded.case_id,
|
|
212
|
+
title = excluded.title,
|
|
213
|
+
page_type = excluded.page_type,
|
|
214
|
+
content = excluded.content,
|
|
215
|
+
confidence = excluded.confidence,
|
|
216
|
+
source_ids = excluded.source_ids,
|
|
217
|
+
entity_refs = excluded.entity_refs,
|
|
218
|
+
compiled_at = excluded.compiled_at,
|
|
219
|
+
updated_at = excluded.updated_at
|
|
220
|
+
`)
|
|
221
|
+
.run(pageIdForSourceLocator(input.source_locator), input.source_locator, input.case_id ?? null, input.title, input.page_type, input.content, input.confidence, JSON.stringify(input.source_ids), JSON.stringify(input.entity_refs), input.compiled_at, updatedAt);
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
adapter
|
|
225
|
+
.prepare(`
|
|
226
|
+
INSERT INTO wiki_page_index (
|
|
227
|
+
page_id, source_type, source_locator, case_id, title, page_type,
|
|
228
|
+
content, confidence, compiled_at, updated_at
|
|
229
|
+
)
|
|
230
|
+
VALUES (?, 'wiki_page', ?, ?, ?, ?, ?, ?, ?, ?)
|
|
231
|
+
ON CONFLICT(source_type, source_locator) DO UPDATE SET
|
|
232
|
+
case_id = excluded.case_id,
|
|
233
|
+
title = excluded.title,
|
|
234
|
+
page_type = excluded.page_type,
|
|
235
|
+
content = excluded.content,
|
|
236
|
+
confidence = excluded.confidence,
|
|
237
|
+
compiled_at = excluded.compiled_at,
|
|
238
|
+
updated_at = excluded.updated_at
|
|
239
|
+
`)
|
|
240
|
+
.run(pageIdForSourceLocator(input.source_locator), input.source_locator, input.case_id ?? null, input.title, input.page_type, input.content, input.confidence, input.compiled_at, updatedAt);
|
|
241
|
+
}
|
|
242
|
+
const saved = selectByLocator(adapter, schema, input.source_locator);
|
|
243
|
+
if (!saved) {
|
|
244
|
+
throw new Error(`Failed to load wiki_page_index row for ${input.source_locator}.`);
|
|
245
|
+
}
|
|
246
|
+
upsertEmbedding(adapter, schema, saved, input);
|
|
247
|
+
return {
|
|
248
|
+
id: saved.id,
|
|
249
|
+
created: existing === null,
|
|
250
|
+
};
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
function deleteWikiPageIndexEntry(adapter, source_locator) {
|
|
254
|
+
const result = adapter
|
|
255
|
+
.prepare('DELETE FROM wiki_page_index WHERE source_locator = ?')
|
|
256
|
+
.run(source_locator);
|
|
257
|
+
return { deleted: result.changes > 0 };
|
|
258
|
+
}
|
|
259
|
+
function ftsSearchWikiPages(adapter, query, limit) {
|
|
260
|
+
const boundedLimit = normalizeLimit(limit);
|
|
261
|
+
if (boundedLimit === 0 || !query.trim()) {
|
|
262
|
+
return [];
|
|
263
|
+
}
|
|
264
|
+
if (!searchTableExists(adapter, 'wiki_pages_fts')) {
|
|
265
|
+
return [];
|
|
266
|
+
}
|
|
267
|
+
const schema = readSchema(adapter);
|
|
268
|
+
const rows = adapter
|
|
269
|
+
.prepare(`
|
|
270
|
+
SELECT page_id, bm25(wiki_pages_fts) AS raw
|
|
271
|
+
FROM wiki_pages_fts
|
|
272
|
+
WHERE wiki_pages_fts MATCH ?
|
|
273
|
+
ORDER BY raw
|
|
274
|
+
LIMIT ?
|
|
275
|
+
`)
|
|
276
|
+
.all(buildFtsQuery(query), boundedLimit);
|
|
277
|
+
const hits = [];
|
|
278
|
+
for (const row of rows) {
|
|
279
|
+
const record = selectByFtsPageId(adapter, schema, row.page_id);
|
|
280
|
+
if (!record) {
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
hits.push({
|
|
284
|
+
record,
|
|
285
|
+
rank: hits.length,
|
|
286
|
+
raw_score: normalizeBm25Score(row.raw),
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
return hits;
|
|
290
|
+
}
|
|
291
|
+
function vectorSearchWikiPages(adapter, queryEmbedding, limit) {
|
|
292
|
+
const boundedLimit = normalizeLimit(limit);
|
|
293
|
+
if (boundedLimit === 0) {
|
|
294
|
+
return [];
|
|
295
|
+
}
|
|
296
|
+
const schema = readSchema(adapter);
|
|
297
|
+
const rows = schema.embeddingUsesWikiPageId
|
|
298
|
+
? adapter
|
|
299
|
+
.prepare(`
|
|
300
|
+
SELECT i.*, e.vector
|
|
301
|
+
FROM wiki_page_embeddings e
|
|
302
|
+
JOIN wiki_page_index i ON i.id = e.wiki_page_id
|
|
303
|
+
`)
|
|
304
|
+
.all()
|
|
305
|
+
: adapter
|
|
306
|
+
.prepare(`
|
|
307
|
+
SELECT i.rowid AS id, i.*, e.embedding
|
|
308
|
+
FROM wiki_page_embeddings e
|
|
309
|
+
JOIN wiki_page_index i ON i.page_id = e.page_id
|
|
310
|
+
`)
|
|
311
|
+
.all();
|
|
312
|
+
const scored = [];
|
|
313
|
+
for (const row of rows) {
|
|
314
|
+
const candidate = blobToVector(schema.embeddingUsesVector ? row.vector : row.embedding);
|
|
315
|
+
if (!candidate || candidate.length !== queryEmbedding.length) {
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
const score = (0, embeddings_js_1.cosineSimilarity)(candidate, queryEmbedding);
|
|
319
|
+
if (!Number.isFinite(score)) {
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
scored.push({ record: rowToRecord(row), score });
|
|
323
|
+
}
|
|
324
|
+
return scored
|
|
325
|
+
.sort((left, right) => right.score - left.score)
|
|
326
|
+
.slice(0, boundedLimit)
|
|
327
|
+
.map((entry, rank) => ({
|
|
328
|
+
record: entry.record,
|
|
329
|
+
rank,
|
|
330
|
+
raw_score: entry.score,
|
|
331
|
+
}));
|
|
332
|
+
}
|
|
333
|
+
function searchWikiPages(input) {
|
|
334
|
+
const ftsHits = ftsSearchWikiPages(input.adapter, input.query, input.limit);
|
|
335
|
+
const vectorHits = input.queryEmbedding
|
|
336
|
+
? vectorSearchWikiPages(input.adapter, input.queryEmbedding, input.limit)
|
|
337
|
+
: [];
|
|
338
|
+
const merged = new Map();
|
|
339
|
+
for (const hit of [...ftsHits, ...vectorHits]) {
|
|
340
|
+
const existing = merged.get(hit.record.id);
|
|
341
|
+
if (!existing || hit.raw_score > existing.raw_score) {
|
|
342
|
+
merged.set(hit.record.id, hit);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return Array.from(merged.values())
|
|
346
|
+
.sort((left, right) => right.raw_score - left.raw_score)
|
|
347
|
+
.slice(0, normalizeLimit(input.limit))
|
|
348
|
+
.map((hit, rank) => ({ ...hit, rank }));
|
|
349
|
+
}
|
|
350
|
+
//# sourceMappingURL=wiki-page-index.js.map
|