@jungjaehoon/mama-core 1.5.0 → 1.7.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/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/db/migrations/037-create-context-packets.sql +32 -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/cases/search-rollup.d.ts +4 -0
- package/dist/cases/search-rollup.js +84 -0
- package/dist/cases/wiki-page-index.js +6 -2
- package/dist/connectors/event-index.d.ts +1 -0
- package/dist/connectors/event-index.js +19 -4
- package/dist/connectors/raw-query.d.ts +18 -0
- package/dist/connectors/raw-query.js +305 -0
- package/dist/connectors/types.d.ts +40 -0
- package/dist/context-compile/boundary-defaults.d.ts +12 -0
- package/dist/context-compile/boundary-defaults.js +105 -0
- package/dist/context-compile/compiler-policy.d.ts +39 -0
- package/dist/context-compile/compiler-policy.js +147 -0
- package/dist/context-compile/compiler.d.ts +18 -0
- package/dist/context-compile/compiler.js +401 -0
- package/dist/context-compile/index.d.ts +9 -0
- package/dist/context-compile/index.js +25 -0
- package/dist/context-compile/packet-store.d.ts +9 -0
- package/dist/context-compile/packet-store.js +255 -0
- package/dist/context-compile/ref.d.ts +7 -0
- package/dist/context-compile/ref.js +102 -0
- package/dist/context-compile/source-readers.d.ts +69 -0
- package/dist/context-compile/source-readers.js +707 -0
- package/dist/context-compile/types.d.ts +138 -0
- package/dist/context-compile/types.js +11 -0
- package/dist/context-compile/visibility.d.ts +21 -0
- package/dist/context-compile/visibility.js +200 -0
- package/dist/db-adapter/node-sqlite-adapter.d.ts +9 -0
- package/dist/db-adapter/node-sqlite-adapter.js +207 -0
- package/dist/db-manager.d.ts +8 -1
- package/dist/db-manager.js +53 -5
- package/dist/edges/ref-validation.d.ts +8 -0
- package/dist/edges/ref-validation.js +301 -0
- package/dist/edges/store.d.ts +10 -0
- package/dist/edges/store.js +343 -0
- package/dist/edges/types.d.ts +88 -0
- package/dist/edges/types.js +18 -0
- package/dist/embeddings.d.ts +3 -0
- package/dist/embeddings.js +49 -9
- package/dist/entities/store.d.ts +4 -1
- package/dist/entities/store.js +206 -78
- package/dist/entities/types.d.ts +5 -1
- package/dist/entities/types.js +1 -1
- package/dist/index.d.ts +18 -3
- package/dist/index.js +54 -4
- package/dist/mama-api.d.ts +32 -35
- package/dist/mama-api.js +173 -22
- package/dist/memory/api.d.ts +17 -56
- package/dist/memory/api.js +494 -52
- 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 +137 -0
- package/dist/memory/scope-backfill.d.ts +17 -0
- package/dist/memory/scope-backfill.js +77 -0
- package/dist/memory/types.d.ts +87 -14
- 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/search-quality.d.ts +36 -0
- package/dist/search/search-quality.js +29 -0
- package/package.json +11 -3
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import type { MemoryScopeRef } from '../memory/types.js';
|
|
2
|
+
import type { TwinRef } from '../edges/types.js';
|
|
3
|
+
export type SituationFocus = 'decisions' | 'risks' | 'open_questions' | 'cases' | 'raw';
|
|
4
|
+
export type SituationRefKind = TwinRef['kind'] | 'memory';
|
|
5
|
+
export interface SituationRef {
|
|
6
|
+
kind: SituationRefKind;
|
|
7
|
+
id: string;
|
|
8
|
+
}
|
|
9
|
+
export interface SituationProjectRef {
|
|
10
|
+
kind: 'project';
|
|
11
|
+
id: string;
|
|
12
|
+
}
|
|
13
|
+
export interface AgentSituationEffectiveFilters {
|
|
14
|
+
scopes: MemoryScopeRef[];
|
|
15
|
+
connectors: string[];
|
|
16
|
+
project_refs: SituationProjectRef[];
|
|
17
|
+
tenant_id: string;
|
|
18
|
+
as_of?: string | null;
|
|
19
|
+
}
|
|
20
|
+
export interface AgentSituationCacheKeyInput extends AgentSituationEffectiveFilters {
|
|
21
|
+
range_start_ms: number;
|
|
22
|
+
range_end_ms: number;
|
|
23
|
+
focus: SituationFocus[];
|
|
24
|
+
limit: number;
|
|
25
|
+
ranking_policy_version: string;
|
|
26
|
+
}
|
|
27
|
+
export interface AgentSituationCacheKeyResult {
|
|
28
|
+
cacheKey: string;
|
|
29
|
+
canonicalInput: AgentSituationCacheKeyInput;
|
|
30
|
+
canonicalJson: string;
|
|
31
|
+
filtersHash: string;
|
|
32
|
+
scopeHash: string;
|
|
33
|
+
}
|
|
34
|
+
export type SituationCaveatCode = 'connector_stale' | 'some_sources_unavailable' | 'low_confidence_visible_memory' | 'graph_api_unavailable_until_m6' | 'case_visibility_incomplete' | 'no_visible_sources';
|
|
35
|
+
export interface SituationSourceCoverage {
|
|
36
|
+
connector?: string;
|
|
37
|
+
channel_id?: string | null;
|
|
38
|
+
memory_scope?: MemoryScopeRef;
|
|
39
|
+
raw_count: number;
|
|
40
|
+
memory_count: number;
|
|
41
|
+
case_count: number;
|
|
42
|
+
edge_count: number;
|
|
43
|
+
last_seen: string | null;
|
|
44
|
+
stale: boolean;
|
|
45
|
+
}
|
|
46
|
+
export interface SituationBriefing {
|
|
47
|
+
decisions: string[];
|
|
48
|
+
facts: string[];
|
|
49
|
+
open_questions: string[];
|
|
50
|
+
risks: string[];
|
|
51
|
+
}
|
|
52
|
+
export interface SituationRankedItem {
|
|
53
|
+
ref: SituationRef;
|
|
54
|
+
kind: string;
|
|
55
|
+
score: number;
|
|
56
|
+
reasons: string[];
|
|
57
|
+
caveats: string[];
|
|
58
|
+
}
|
|
59
|
+
export interface SituationPendingHumanQuestion {
|
|
60
|
+
memory_id: string;
|
|
61
|
+
title: string;
|
|
62
|
+
summary: string;
|
|
63
|
+
}
|
|
64
|
+
export interface SituationEntityCluster {
|
|
65
|
+
label: string;
|
|
66
|
+
entity_refs: Array<{
|
|
67
|
+
kind: 'entity';
|
|
68
|
+
id: string;
|
|
69
|
+
}>;
|
|
70
|
+
source_refs: Array<{
|
|
71
|
+
kind: 'raw' | 'memory' | 'case';
|
|
72
|
+
id: string;
|
|
73
|
+
}>;
|
|
74
|
+
caveats: string[];
|
|
75
|
+
}
|
|
76
|
+
export interface SituationRecommendedTool {
|
|
77
|
+
tool: 'raw.search' | 'raw.searchAll' | 'raw.window' | 'memory.recall' | 'graph.neighborhood';
|
|
78
|
+
args: Record<string, unknown>;
|
|
79
|
+
reason: string;
|
|
80
|
+
expected_refs: SituationRef[];
|
|
81
|
+
}
|
|
82
|
+
export interface AgentSituationPacket {
|
|
83
|
+
packet_id: string;
|
|
84
|
+
scope: MemoryScopeRef[];
|
|
85
|
+
range_start: string;
|
|
86
|
+
range_end: string;
|
|
87
|
+
generated_at: string;
|
|
88
|
+
freshness: Record<string, unknown>;
|
|
89
|
+
source_coverage: SituationSourceCoverage[];
|
|
90
|
+
briefing: SituationBriefing;
|
|
91
|
+
ranked_items: SituationRankedItem[];
|
|
92
|
+
top_memory_refs: string[];
|
|
93
|
+
pending_human_questions: SituationPendingHumanQuestion[];
|
|
94
|
+
entity_clusters: SituationEntityCluster[];
|
|
95
|
+
recommended_next_tools: SituationRecommendedTool[];
|
|
96
|
+
ranking_policy_version: string;
|
|
97
|
+
ttl_seconds: number;
|
|
98
|
+
generated_from_slice_ids: string[];
|
|
99
|
+
caveats: string[];
|
|
100
|
+
cache: {
|
|
101
|
+
hit: boolean;
|
|
102
|
+
cache_key: string;
|
|
103
|
+
expires_at: string;
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
export interface AgentSituationInput {
|
|
107
|
+
scope: MemoryScopeRef[];
|
|
108
|
+
range_start_ms: number;
|
|
109
|
+
range_end_ms: number;
|
|
110
|
+
focus: SituationFocus[];
|
|
111
|
+
limit: number;
|
|
112
|
+
effective_filters: AgentSituationEffectiveFilters;
|
|
113
|
+
envelope_hash: string;
|
|
114
|
+
agent_id: string;
|
|
115
|
+
model_run_id: string;
|
|
116
|
+
ranking_policy_version?: string;
|
|
117
|
+
refresh?: boolean;
|
|
118
|
+
now_ms?: number;
|
|
119
|
+
}
|
|
120
|
+
export interface AgentSituationPacketRecord {
|
|
121
|
+
packet_id: string;
|
|
122
|
+
cache_key: string;
|
|
123
|
+
scope_json: string;
|
|
124
|
+
scope: MemoryScopeRef[];
|
|
125
|
+
scope_hash: string;
|
|
126
|
+
range_start_ms: number;
|
|
127
|
+
range_end_ms: number;
|
|
128
|
+
focus_json: string;
|
|
129
|
+
focus: SituationFocus[];
|
|
130
|
+
envelope_hash: string;
|
|
131
|
+
envelope_effective_filters_json: string;
|
|
132
|
+
envelope_effective_filters: AgentSituationEffectiveFilters;
|
|
133
|
+
envelope_effective_filters_hash: string;
|
|
134
|
+
ranking_policy_version: string;
|
|
135
|
+
generated_at: number;
|
|
136
|
+
expires_at: number;
|
|
137
|
+
ttl_seconds: number;
|
|
138
|
+
freshness_json: string;
|
|
139
|
+
freshness: Record<string, unknown>;
|
|
140
|
+
source_coverage_json: string;
|
|
141
|
+
source_coverage: SituationSourceCoverage[];
|
|
142
|
+
briefing_json: string;
|
|
143
|
+
briefing: SituationBriefing;
|
|
144
|
+
ranked_items_json: string;
|
|
145
|
+
ranked_items: SituationRankedItem[];
|
|
146
|
+
top_memory_refs_json: string;
|
|
147
|
+
top_memory_refs: string[];
|
|
148
|
+
pending_human_questions_json: string;
|
|
149
|
+
pending_human_questions: SituationPendingHumanQuestion[];
|
|
150
|
+
entity_clusters_json: string;
|
|
151
|
+
entity_clusters: SituationEntityCluster[];
|
|
152
|
+
recommended_next_tools_json: string;
|
|
153
|
+
recommended_next_tools: SituationRecommendedTool[];
|
|
154
|
+
generated_from_slice_ids_json: string;
|
|
155
|
+
generated_from_slice_ids: string[];
|
|
156
|
+
caveats_json: string;
|
|
157
|
+
caveats: string[];
|
|
158
|
+
agent_id: string;
|
|
159
|
+
model_run_id: string;
|
|
160
|
+
input_snapshot_ref: string;
|
|
161
|
+
source_refs_json: string;
|
|
162
|
+
source_refs: SituationRef[];
|
|
163
|
+
tenant_id: string;
|
|
164
|
+
project_id: string;
|
|
165
|
+
memory_scope_kind: MemoryScopeRef['kind'];
|
|
166
|
+
memory_scope_id: string;
|
|
167
|
+
created_at: number;
|
|
168
|
+
}
|
|
169
|
+
export interface AgentSituationLease {
|
|
170
|
+
cache_key: string;
|
|
171
|
+
ranking_policy_version: string;
|
|
172
|
+
lease_owner: string;
|
|
173
|
+
lease_expires_at: number;
|
|
174
|
+
created_at: number;
|
|
175
|
+
}
|
|
176
|
+
export interface AgentSituationCandidate {
|
|
177
|
+
ref: SituationRef;
|
|
178
|
+
kind: string;
|
|
179
|
+
title: string;
|
|
180
|
+
summary: string;
|
|
181
|
+
timestamp_ms: number;
|
|
182
|
+
confidence?: number | null;
|
|
183
|
+
status?: string | null;
|
|
184
|
+
is_open_question?: boolean;
|
|
185
|
+
has_debate_edge?: boolean;
|
|
186
|
+
connector?: string | null;
|
|
187
|
+
channel_id?: string | null;
|
|
188
|
+
scope?: MemoryScopeRef | null;
|
|
189
|
+
}
|
|
190
|
+
export interface SituationScore {
|
|
191
|
+
score: number;
|
|
192
|
+
reasons: string[];
|
|
193
|
+
caveats: string[];
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AdapterLike } from './wiki-page-index.js';
|
|
2
|
+
import type { SearchHitDiagnostics } from '../search/search-quality.js';
|
|
2
3
|
export type { AdapterLike };
|
|
3
4
|
export interface SearchRollupLeafHit {
|
|
4
5
|
source_type: 'decision' | 'checkpoint' | 'wiki_page' | 'connector_event';
|
|
@@ -7,6 +8,7 @@ export interface SearchRollupLeafHit {
|
|
|
7
8
|
page_type?: 'case';
|
|
8
9
|
case_id?: string | null;
|
|
9
10
|
record: unknown;
|
|
11
|
+
retrieval_diagnostics?: SearchHitDiagnostics;
|
|
10
12
|
}
|
|
11
13
|
export interface SearchRollupResult {
|
|
12
14
|
source_type: 'decision' | 'checkpoint' | 'wiki_page' | 'case' | 'standalone_connector_hit';
|
|
@@ -14,6 +16,8 @@ export interface SearchRollupResult {
|
|
|
14
16
|
case_id: string | null;
|
|
15
17
|
score: number;
|
|
16
18
|
contributing_leaves?: string[];
|
|
19
|
+
contributing_leaf_diagnostics?: Record<string, SearchHitDiagnostics>;
|
|
20
|
+
retrieval_diagnostics?: SearchHitDiagnostics;
|
|
17
21
|
record: unknown;
|
|
18
22
|
}
|
|
19
23
|
export declare function rollUpSearchHits(input: {
|
|
@@ -17,6 +17,72 @@ function stringOrNull(value) {
|
|
|
17
17
|
}
|
|
18
18
|
return String(value);
|
|
19
19
|
}
|
|
20
|
+
function searchHitDiagnostics(value) {
|
|
21
|
+
const object = objectRecord(value);
|
|
22
|
+
if (!object) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
if (typeof object.retrieval_source !== 'string' ||
|
|
26
|
+
!(object.vector_similarity === null || typeof object.vector_similarity === 'number') ||
|
|
27
|
+
typeof object.is_vector_only !== 'boolean' ||
|
|
28
|
+
typeof object.lexical_support !== 'boolean' ||
|
|
29
|
+
typeof object.entity_support !== 'boolean' ||
|
|
30
|
+
typeof object.scope_support !== 'boolean' ||
|
|
31
|
+
(object.graph_source !== 'primary' &&
|
|
32
|
+
object.graph_source !== 'expanded' &&
|
|
33
|
+
object.graph_source !== null) ||
|
|
34
|
+
!Array.isArray(object.confirmation_signals) ||
|
|
35
|
+
!Array.isArray(object.metadata_signals) ||
|
|
36
|
+
typeof object.candidate_threshold_used !== 'number') {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
// Type assertion is safe: every required field of SearchHitDiagnostics has been
|
|
40
|
+
// validated above (including the array-typed signals consumed by diagnosticsRank).
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
function leafDiagnostics(leaf) {
|
|
44
|
+
const record = objectRecord(leaf.record);
|
|
45
|
+
return leaf.retrieval_diagnostics ?? searchHitDiagnostics(record?.retrieval_diagnostics);
|
|
46
|
+
}
|
|
47
|
+
function diagnosticsRank(diagnostics) {
|
|
48
|
+
let rank = 0;
|
|
49
|
+
rank += diagnostics.confirmation_signals.length * 100;
|
|
50
|
+
if (diagnostics.lexical_support) {
|
|
51
|
+
rank += 20;
|
|
52
|
+
}
|
|
53
|
+
if (diagnostics.entity_support) {
|
|
54
|
+
rank += 20;
|
|
55
|
+
}
|
|
56
|
+
if (diagnostics.graph_source === 'primary') {
|
|
57
|
+
rank += 10;
|
|
58
|
+
}
|
|
59
|
+
if (!diagnostics.is_vector_only) {
|
|
60
|
+
rank += 1;
|
|
61
|
+
}
|
|
62
|
+
return rank;
|
|
63
|
+
}
|
|
64
|
+
function betterDiagnostics(candidate, current) {
|
|
65
|
+
if (!current) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
return diagnosticsRank(candidate) > diagnosticsRank(current);
|
|
69
|
+
}
|
|
70
|
+
function diagnosticsRecord(diagnosticsByLeaf) {
|
|
71
|
+
if (diagnosticsByLeaf.size === 0) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
return Object.fromEntries(Array.from(diagnosticsByLeaf.entries()).sort(([left], [right]) => left.localeCompare(right)));
|
|
75
|
+
}
|
|
76
|
+
function attachLeafDiagnostics(group, leaf) {
|
|
77
|
+
const diagnostics = leafDiagnostics(leaf);
|
|
78
|
+
if (!diagnostics) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
group.contributing_leaf_diagnostics.set(leaf.source_id, diagnostics);
|
|
82
|
+
if (betterDiagnostics(diagnostics, group.retrieval_diagnostics)) {
|
|
83
|
+
group.retrieval_diagnostics = diagnostics;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
20
86
|
function placeholders(values) {
|
|
21
87
|
if (values.length === 0) {
|
|
22
88
|
throw new Error('Cannot build SQL IN clause for an empty value list.');
|
|
@@ -104,11 +170,17 @@ function upsertOrphan(orphans, leaf) {
|
|
|
104
170
|
if (existing && existing.score >= leaf.fused_rank_score) {
|
|
105
171
|
return;
|
|
106
172
|
}
|
|
173
|
+
const diagnostics = leafDiagnostics(leaf);
|
|
174
|
+
const contributingLeafDiagnostics = diagnostics ? { [leaf.source_id]: diagnostics } : undefined;
|
|
107
175
|
orphans.set(key, {
|
|
108
176
|
source_type: leaf.source_type === 'connector_event' ? 'standalone_connector_hit' : leaf.source_type,
|
|
109
177
|
source_id: leaf.source_id,
|
|
110
178
|
case_id: null,
|
|
111
179
|
score: leaf.fused_rank_score,
|
|
180
|
+
...(diagnostics ? { retrieval_diagnostics: diagnostics } : {}),
|
|
181
|
+
...(contributingLeafDiagnostics
|
|
182
|
+
? { contributing_leaf_diagnostics: contributingLeafDiagnostics }
|
|
183
|
+
: {}),
|
|
112
184
|
record: leaf.record,
|
|
113
185
|
});
|
|
114
186
|
}
|
|
@@ -121,10 +193,15 @@ function upsertDirectCase(directCases, adapter, leaf, caseId) {
|
|
|
121
193
|
score: leaf.fused_rank_score,
|
|
122
194
|
max_leaf_score: leaf.fused_rank_score,
|
|
123
195
|
contributing_leaves: new Set([leaf.source_id]),
|
|
196
|
+
contributing_leaf_diagnostics: new Map(),
|
|
124
197
|
dedupe_keys: new Set([leaf.source_id]),
|
|
125
198
|
record: withCaseId(leaf.record, survivorCaseId),
|
|
126
199
|
});
|
|
127
200
|
}
|
|
201
|
+
const group = directCases.get(survivorCaseId);
|
|
202
|
+
if (group) {
|
|
203
|
+
attachLeafDiagnostics(group, leaf);
|
|
204
|
+
}
|
|
128
205
|
return survivorCaseId;
|
|
129
206
|
}
|
|
130
207
|
function upsertCaseGroup(groups, adapter, leaf, survivorCaseId) {
|
|
@@ -136,6 +213,7 @@ function upsertCaseGroup(groups, adapter, leaf, survivorCaseId) {
|
|
|
136
213
|
score: 0,
|
|
137
214
|
max_leaf_score: 0,
|
|
138
215
|
contributing_leaves: new Set(),
|
|
216
|
+
contributing_leaf_diagnostics: new Map(),
|
|
139
217
|
dedupe_keys: new Set(),
|
|
140
218
|
record: loadCaseRecord(adapter, survivorCaseId),
|
|
141
219
|
};
|
|
@@ -146,6 +224,7 @@ function upsertCaseGroup(groups, adapter, leaf, survivorCaseId) {
|
|
|
146
224
|
}
|
|
147
225
|
group.dedupe_keys.add(dedupeKey);
|
|
148
226
|
group.contributing_leaves.add(leaf.source_id);
|
|
227
|
+
attachLeafDiagnostics(group, leaf);
|
|
149
228
|
group.score += leaf.fused_rank_score;
|
|
150
229
|
group.max_leaf_score = Math.max(group.max_leaf_score, leaf.fused_rank_score);
|
|
151
230
|
}
|
|
@@ -154,12 +233,17 @@ function groupToResult(group) {
|
|
|
154
233
|
case_id: group.case_id,
|
|
155
234
|
};
|
|
156
235
|
const record = { ...baseRecord, max_leaf_score: group.max_leaf_score };
|
|
236
|
+
const contributingLeafDiagnostics = diagnosticsRecord(group.contributing_leaf_diagnostics);
|
|
157
237
|
return {
|
|
158
238
|
source_type: 'case',
|
|
159
239
|
source_id: group.case_id,
|
|
160
240
|
case_id: group.case_id,
|
|
161
241
|
score: group.score,
|
|
162
242
|
contributing_leaves: Array.from(group.contributing_leaves).sort((left, right) => left.localeCompare(right)),
|
|
243
|
+
...(contributingLeafDiagnostics
|
|
244
|
+
? { contributing_leaf_diagnostics: contributingLeafDiagnostics }
|
|
245
|
+
: {}),
|
|
246
|
+
...(group.retrieval_diagnostics ? { retrieval_diagnostics: group.retrieval_diagnostics } : {}),
|
|
163
247
|
record,
|
|
164
248
|
};
|
|
165
249
|
}
|
|
@@ -153,7 +153,7 @@ function buildFtsQuery(query) {
|
|
|
153
153
|
.match(/[\p{L}\p{N}_]+/gu)
|
|
154
154
|
?.filter((token) => token.length > 0);
|
|
155
155
|
if (!tokens || tokens.length === 0) {
|
|
156
|
-
return
|
|
156
|
+
return '';
|
|
157
157
|
}
|
|
158
158
|
return tokens.map((token) => `"${token.replace(/"/g, '""')}"`).join(' OR ');
|
|
159
159
|
}
|
|
@@ -264,6 +264,10 @@ function ftsSearchWikiPages(adapter, query, limit) {
|
|
|
264
264
|
if (!searchTableExists(adapter, 'wiki_pages_fts')) {
|
|
265
265
|
return [];
|
|
266
266
|
}
|
|
267
|
+
const ftsQuery = buildFtsQuery(query);
|
|
268
|
+
if (!ftsQuery) {
|
|
269
|
+
return [];
|
|
270
|
+
}
|
|
267
271
|
const schema = readSchema(adapter);
|
|
268
272
|
const rows = adapter
|
|
269
273
|
.prepare(`
|
|
@@ -273,7 +277,7 @@ function ftsSearchWikiPages(adapter, query, limit) {
|
|
|
273
277
|
ORDER BY raw
|
|
274
278
|
LIMIT ?
|
|
275
279
|
`)
|
|
276
|
-
.all(
|
|
280
|
+
.all(ftsQuery, boundedLimit);
|
|
277
281
|
const hits = [];
|
|
278
282
|
for (const row of rows) {
|
|
279
283
|
const record = selectByFtsPageId(adapter, schema, row.page_id);
|
|
@@ -23,6 +23,7 @@ interface StalenessOptions {
|
|
|
23
23
|
stalenessWarnAfterMs?: number;
|
|
24
24
|
unhealthyAfterMs?: number;
|
|
25
25
|
}
|
|
26
|
+
export declare function mapConnectorEventIndexRecord(row: Record<string, unknown>): ConnectorEventIndexRecord;
|
|
26
27
|
export declare function connectorEventIndexId(sourceConnector: string, sourceId: string): string;
|
|
27
28
|
export declare function connectorEventContentHash(input: {
|
|
28
29
|
source_connector: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mapConnectorEventIndexRecord = mapConnectorEventIndexRecord;
|
|
3
4
|
exports.connectorEventIndexId = connectorEventIndexId;
|
|
4
5
|
exports.connectorEventContentHash = connectorEventContentHash;
|
|
5
6
|
exports.upsertConnectorEventIndex = upsertConnectorEventIndex;
|
|
@@ -89,6 +90,11 @@ function mapConnectorEventIndexRow(row) {
|
|
|
89
90
|
: null,
|
|
90
91
|
event_date: row.event_date === null ? null : String(row.event_date),
|
|
91
92
|
source_timestamp_ms: Number(row.source_timestamp_ms),
|
|
93
|
+
source_cursor: row.source_cursor === null ? null : String(row.source_cursor),
|
|
94
|
+
tenant_id: row.tenant_id === null ? null : String(row.tenant_id),
|
|
95
|
+
project_id: row.project_id === null ? null : String(row.project_id),
|
|
96
|
+
memory_scope_kind: row.memory_scope_kind === null ? null : String(row.memory_scope_kind),
|
|
97
|
+
memory_scope_id: row.memory_scope_id === null ? null : String(row.memory_scope_id),
|
|
92
98
|
metadata_json: row.metadata_json === null ? null : String(row.metadata_json),
|
|
93
99
|
artifact_locator: row.artifact_locator === null ? null : String(row.artifact_locator),
|
|
94
100
|
artifact_title: row.artifact_title === null ? null : String(row.artifact_title),
|
|
@@ -98,6 +104,9 @@ function mapConnectorEventIndexRow(row) {
|
|
|
98
104
|
expires_at: row.expires_at === null ? null : String(row.expires_at),
|
|
99
105
|
};
|
|
100
106
|
}
|
|
107
|
+
function mapConnectorEventIndexRecord(row) {
|
|
108
|
+
return mapConnectorEventIndexRow(row);
|
|
109
|
+
}
|
|
101
110
|
function mapConnectorCursorRow(row) {
|
|
102
111
|
return {
|
|
103
112
|
connector_name: String(row.connector_name),
|
|
@@ -158,10 +167,11 @@ function upsertConnectorEventIndex(adapter, input) {
|
|
|
158
167
|
INSERT INTO connector_event_index (
|
|
159
168
|
event_index_id, source_connector, source_type, source_id, source_locator,
|
|
160
169
|
channel, author, title, content, event_datetime, event_date, source_timestamp_ms,
|
|
161
|
-
|
|
162
|
-
updated_at,
|
|
170
|
+
source_cursor, tenant_id, project_id, memory_scope_kind, memory_scope_id,
|
|
171
|
+
metadata_json, artifact_locator, artifact_title, content_hash, indexed_at, updated_at,
|
|
172
|
+
expires_at
|
|
163
173
|
)
|
|
164
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
174
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
165
175
|
ON CONFLICT(source_connector, source_id) DO UPDATE SET
|
|
166
176
|
source_type = excluded.source_type,
|
|
167
177
|
source_locator = excluded.source_locator,
|
|
@@ -172,6 +182,11 @@ function upsertConnectorEventIndex(adapter, input) {
|
|
|
172
182
|
event_datetime = excluded.event_datetime,
|
|
173
183
|
event_date = excluded.event_date,
|
|
174
184
|
source_timestamp_ms = excluded.source_timestamp_ms,
|
|
185
|
+
source_cursor = excluded.source_cursor,
|
|
186
|
+
tenant_id = excluded.tenant_id,
|
|
187
|
+
project_id = excluded.project_id,
|
|
188
|
+
memory_scope_kind = excluded.memory_scope_kind,
|
|
189
|
+
memory_scope_id = excluded.memory_scope_id,
|
|
175
190
|
metadata_json = excluded.metadata_json,
|
|
176
191
|
artifact_locator = excluded.artifact_locator,
|
|
177
192
|
artifact_title = excluded.artifact_title,
|
|
@@ -179,7 +194,7 @@ function upsertConnectorEventIndex(adapter, input) {
|
|
|
179
194
|
updated_at = excluded.updated_at,
|
|
180
195
|
expires_at = excluded.expires_at
|
|
181
196
|
`)
|
|
182
|
-
.run(eventIndexId, input.source_connector, input.source_type, input.source_id, input.source_locator ?? null, input.channel ?? null, input.author ?? null, input.title ?? null, input.content, eventDatetime, eventDate, sourceTimestampMs, metadataJson, input.artifact_locator ?? null, input.artifact_title ?? null, contentHash, input.indexed_at ?? timestamp, timestamp, input.expires_at ?? null);
|
|
197
|
+
.run(eventIndexId, input.source_connector, input.source_type, input.source_id, input.source_locator ?? null, input.channel ?? null, input.author ?? null, input.title ?? null, input.content, eventDatetime, eventDate, sourceTimestampMs, input.source_cursor ?? null, input.tenant_id ?? null, input.project_id ?? null, input.memory_scope_kind ?? null, input.memory_scope_id ?? null, metadataJson, input.artifact_locator ?? null, input.artifact_title ?? null, contentHash, input.indexed_at ?? timestamp, timestamp, input.expires_at ?? null);
|
|
183
198
|
const saved = getConnectorEventIndexRecord(adapter, input.source_connector, input.source_id);
|
|
184
199
|
if (!saved) {
|
|
185
200
|
throw new Error(`Failed to read connector_event_index row after upsert: ${input.source_connector}/${input.source_id}`);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DatabaseAdapter } from '../db-manager.js';
|
|
2
|
+
import type { RawSearchHit, RawSearchInput, RawSearchResult, RawSearchScopeFilter } from './types.js';
|
|
3
|
+
type RawQueryAdapter = Pick<DatabaseAdapter, 'prepare'>;
|
|
4
|
+
interface RawWindowInput {
|
|
5
|
+
connectors?: string[];
|
|
6
|
+
scopes?: RawSearchScopeFilter[];
|
|
7
|
+
before?: number;
|
|
8
|
+
after?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function searchRaw(adapter: RawQueryAdapter, input: RawSearchInput): RawSearchResult;
|
|
11
|
+
export declare function searchAllRaw(adapter: RawQueryAdapter, input: RawSearchInput): RawSearchResult;
|
|
12
|
+
export declare function getRawById(adapter: RawQueryAdapter, rawId: string, visibility: Pick<RawSearchInput, 'connectors' | 'scopes'>): RawSearchHit | null;
|
|
13
|
+
export declare function getRawWindow(adapter: RawQueryAdapter, rawId: string, input: RawWindowInput): {
|
|
14
|
+
target: RawSearchHit;
|
|
15
|
+
items: RawSearchHit[];
|
|
16
|
+
} | null;
|
|
17
|
+
export type { RawSearchHit, RawSearchInput, RawSearchResult, RawSearchScopeFilter, } from './types.js';
|
|
18
|
+
//# sourceMappingURL=raw-query.d.ts.map
|