context-eng 0.1.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/LICENSE +21 -0
- package/README.md +272 -0
- package/dist/categories.d.ts +27 -0
- package/dist/categories.js +71 -0
- package/dist/categories.js.map +1 -0
- package/dist/cli-entry.d.ts +2 -0
- package/dist/cli-entry.js +7 -0
- package/dist/cli-entry.js.map +1 -0
- package/dist/cli.d.ts +30 -0
- package/dist/cli.js +327 -0
- package/dist/cli.js.map +1 -0
- package/dist/db.d.ts +40 -0
- package/dist/db.js +158 -0
- package/dist/db.js.map +1 -0
- package/dist/engine.d.ts +149 -0
- package/dist/engine.js +589 -0
- package/dist/engine.js.map +1 -0
- package/dist/harness.d.ts +56 -0
- package/dist/harness.js +358 -0
- package/dist/harness.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/inspect-cli.d.ts +2 -0
- package/dist/inspect-cli.js +96 -0
- package/dist/inspect-cli.js.map +1 -0
- package/dist/inspect.d.ts +33 -0
- package/dist/inspect.js +149 -0
- package/dist/inspect.js.map +1 -0
- package/dist/map.d.ts +39 -0
- package/dist/map.js +106 -0
- package/dist/map.js.map +1 -0
- package/dist/mcp.d.ts +5 -0
- package/dist/mcp.js +348 -0
- package/dist/mcp.js.map +1 -0
- package/dist/migrate.d.ts +7 -0
- package/dist/migrate.js +107 -0
- package/dist/migrate.js.map +1 -0
- package/dist/paths.d.ts +29 -0
- package/dist/paths.js +69 -0
- package/dist/paths.js.map +1 -0
- package/dist/search.d.ts +144 -0
- package/dist/search.js +449 -0
- package/dist/search.js.map +1 -0
- package/dist/secrets.d.ts +28 -0
- package/dist/secrets.js +135 -0
- package/dist/secrets.js.map +1 -0
- package/dist/text.d.ts +22 -0
- package/dist/text.js +153 -0
- package/dist/text.js.map +1 -0
- package/dist/tokens.d.ts +6 -0
- package/dist/tokens.js +15 -0
- package/dist/tokens.js.map +1 -0
- package/dist/typesafe.d.ts +40 -0
- package/dist/typesafe.js +170 -0
- package/dist/typesafe.js.map +1 -0
- package/package.json +51 -0
- package/system_prompts/AGENTS.md +14 -0
- package/system_prompts/CLAUDE.md +14 -0
- package/system_prompts/rules.md +157 -0
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { type Category, type Scope } from "./categories.js";
|
|
2
|
+
import type { CategoryRecord, Db, MemoryRow } from "./db.js";
|
|
3
|
+
import type { Memory } from "./engine.js";
|
|
4
|
+
export type EngineErrorCode = "INVALID_CATEGORY" | "INVALID_CATEGORIES" | "NEAR_CATEGORY" | "INVALID_SCOPE" | "INVALID_FILTER" | "INVALID_TIME" | "INVALID_SORT" | "EMPTY_CONTENT" | "TOO_LONG" | "NOT_ONE_SENTENCE" | "NOT_FOUND" | "AMBIGUOUS_LINE" | "LINE_ID_MISMATCH" | "NOT_STAGING" | "INVALID_PROJECT_PATH" | "PROJECT_NOT_BOUND" | "INVALID_IMPORTANCE";
|
|
5
|
+
export declare class EngineError extends Error {
|
|
6
|
+
readonly code: EngineErrorCode;
|
|
7
|
+
readonly near?: {
|
|
8
|
+
requested: string;
|
|
9
|
+
existing: string;
|
|
10
|
+
} | undefined;
|
|
11
|
+
constructor(code: EngineErrorCode, message: string, near?: {
|
|
12
|
+
requested: string;
|
|
13
|
+
existing: string;
|
|
14
|
+
} | undefined);
|
|
15
|
+
}
|
|
16
|
+
export interface SearchHit extends Memory {
|
|
17
|
+
score: number;
|
|
18
|
+
}
|
|
19
|
+
export type MatchMode = "any" | "all";
|
|
20
|
+
export interface ListFilter {
|
|
21
|
+
values: string[];
|
|
22
|
+
match?: MatchMode | undefined;
|
|
23
|
+
}
|
|
24
|
+
export interface TimeFilter {
|
|
25
|
+
field?: "created" | "updated" | undefined;
|
|
26
|
+
preset?: "this_week" | "this_month" | undefined;
|
|
27
|
+
from?: string | undefined;
|
|
28
|
+
to?: string | undefined;
|
|
29
|
+
}
|
|
30
|
+
export interface SearchFilters {
|
|
31
|
+
scope?: "both" | Scope | undefined;
|
|
32
|
+
includeStaging?: boolean | undefined;
|
|
33
|
+
minImportance?: number | undefined;
|
|
34
|
+
subject?: string | undefined;
|
|
35
|
+
topics?: ListFilter | undefined;
|
|
36
|
+
tags?: ListFilter | undefined;
|
|
37
|
+
links?: ListFilter | undefined;
|
|
38
|
+
time?: TimeFilter | undefined;
|
|
39
|
+
}
|
|
40
|
+
export interface SearchHints {
|
|
41
|
+
topics?: string[] | undefined;
|
|
42
|
+
tags?: string[] | undefined;
|
|
43
|
+
links?: string[] | undefined;
|
|
44
|
+
categories?: Category[] | undefined;
|
|
45
|
+
}
|
|
46
|
+
export interface SearchSort {
|
|
47
|
+
by: "relevance" | "updated" | "created" | "importance";
|
|
48
|
+
order?: "asc" | "desc" | undefined;
|
|
49
|
+
}
|
|
50
|
+
export interface SearchInput {
|
|
51
|
+
query: string;
|
|
52
|
+
/** Omit to search every category available in the selected scope(s). */
|
|
53
|
+
categories?: Category[] | undefined;
|
|
54
|
+
filters?: SearchFilters;
|
|
55
|
+
hints?: SearchHints;
|
|
56
|
+
sort?: SearchSort;
|
|
57
|
+
limit?: number;
|
|
58
|
+
}
|
|
59
|
+
export interface SearchResult {
|
|
60
|
+
query: string;
|
|
61
|
+
hits: SearchHit[];
|
|
62
|
+
total_tokens: number;
|
|
63
|
+
budget: {
|
|
64
|
+
max_hits: number;
|
|
65
|
+
max_tokens: number;
|
|
66
|
+
};
|
|
67
|
+
sort: Required<SearchSort>;
|
|
68
|
+
eligible_count: number;
|
|
69
|
+
used_fts: boolean;
|
|
70
|
+
retrieval: {
|
|
71
|
+
mode: "small" | "large";
|
|
72
|
+
candidate_count: number;
|
|
73
|
+
eligible_tokens: number;
|
|
74
|
+
channels: RetrievalChannel[];
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export type RetrievalChannel = "all" | "fts" | "labels" | "typo" | "fill";
|
|
78
|
+
export interface SearchCandidate {
|
|
79
|
+
hit: SearchHit;
|
|
80
|
+
channels: RetrievalChannel[];
|
|
81
|
+
matchedLabels: string[];
|
|
82
|
+
categoryHintBoosted: boolean;
|
|
83
|
+
}
|
|
84
|
+
export interface SearchDebugSnapshot {
|
|
85
|
+
result: SearchResult;
|
|
86
|
+
eligible: SearchHit[];
|
|
87
|
+
candidates: SearchCandidate[];
|
|
88
|
+
correctedQuery?: string;
|
|
89
|
+
}
|
|
90
|
+
export interface SearchSource {
|
|
91
|
+
db: Db;
|
|
92
|
+
scope: Scope;
|
|
93
|
+
record: CategoryRecord;
|
|
94
|
+
}
|
|
95
|
+
export interface NormalizedSearch {
|
|
96
|
+
input: SearchInput;
|
|
97
|
+
categories: string[];
|
|
98
|
+
allCategories: boolean;
|
|
99
|
+
filters: SearchFilters;
|
|
100
|
+
hints: {
|
|
101
|
+
topics: string[];
|
|
102
|
+
tags: string[];
|
|
103
|
+
links: string[];
|
|
104
|
+
categories: string[];
|
|
105
|
+
};
|
|
106
|
+
sort: Required<SearchSort>;
|
|
107
|
+
limit: number;
|
|
108
|
+
scopes: Scope[];
|
|
109
|
+
time?: {
|
|
110
|
+
field: "created_at" | "updated_at";
|
|
111
|
+
from?: number;
|
|
112
|
+
to?: number;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
export interface SearchAccess {
|
|
116
|
+
catalogFor(scope: Scope): Db;
|
|
117
|
+
dbForRecord(scope: Scope, record: CategoryRecord): Db;
|
|
118
|
+
recordFor(scope: Scope, category: Category): CategoryRecord | undefined;
|
|
119
|
+
toHit(row: MemoryRow, scope: Scope): SearchHit;
|
|
120
|
+
}
|
|
121
|
+
export declare function normalizeImportance(value: number): number;
|
|
122
|
+
export declare function normalizeSubject(value: string | undefined): string;
|
|
123
|
+
export declare function normalizeStoredLabels(name: string, values: readonly string[] | undefined): string[];
|
|
124
|
+
export declare function normalizeSearch(input: SearchInput): NormalizedSearch;
|
|
125
|
+
export declare function sqlFilter(search: NormalizedSearch, alias: string): {
|
|
126
|
+
sql: string;
|
|
127
|
+
params: unknown[];
|
|
128
|
+
};
|
|
129
|
+
export declare function searchSources(search: NormalizedSearch, access: SearchAccess): SearchSource[];
|
|
130
|
+
export declare function countEligible(source: SearchSource, search: NormalizedSearch): number;
|
|
131
|
+
export declare function readAllEligible(sources: SearchSource[], search: NormalizedSearch, access: SearchAccess): SearchHit[];
|
|
132
|
+
export declare function readFtsCandidates(sources: SearchSource[], search: NormalizedSearch, access: SearchAccess, query?: string): SearchHit[];
|
|
133
|
+
export declare function mergeSearchCandidates(eligible: readonly SearchHit[], ftsHits: readonly SearchHit[], search: NormalizedSearch, options: {
|
|
134
|
+
fill: boolean;
|
|
135
|
+
usedTypo: boolean;
|
|
136
|
+
}): {
|
|
137
|
+
hits: SearchHit[];
|
|
138
|
+
candidates: SearchCandidate[];
|
|
139
|
+
channels: RetrievalChannel[];
|
|
140
|
+
};
|
|
141
|
+
export declare function searchResult(normalized: NormalizedSearch, candidates: SearchHit[], eligibleCount: number, usedFts: boolean, applyBudget: boolean, maxTokens: number, retrieval: Omit<SearchResult["retrieval"], "candidate_count">): SearchResult;
|
|
142
|
+
export declare function sortHits<T extends SearchHit>(hits: readonly T[], sort: Required<SearchSort>): T[];
|
|
143
|
+
export declare function budgetHits<T extends SearchHit>(hits: readonly T[], limit: number, maxTokens: number): T[];
|
|
144
|
+
export declare function matchingHintLabels(hit: SearchHit, hints: NormalizedSearch["hints"]): string[];
|
package/dist/search.js
ADDED
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
import { MAX_FILTER_VALUE_LENGTH, MAX_FILTER_VALUES, MAX_HITS, MAX_JEV_BATCHES, MAX_JEV_CANDIDATES, MAX_SEARCH_CATEGORIES, isCategory, isScope, canonicalCategory, } from "./categories.js";
|
|
2
|
+
import { listCategories } from "./db.js";
|
|
3
|
+
import { buildFtsQuery, keywords, lexicalQueryTerms, normalizeLabel, normalizeLabels } from "./text.js";
|
|
4
|
+
export class EngineError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
near;
|
|
7
|
+
constructor(code, message, near) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.code = code;
|
|
10
|
+
this.near = near;
|
|
11
|
+
this.name = "EngineError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function normalizeImportance(value) {
|
|
15
|
+
if (typeof value !== "number" || Number.isNaN(value) || value < 0 || value > 1) {
|
|
16
|
+
throw new EngineError("INVALID_IMPORTANCE", "importance must be a number between 0 and 1");
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
export function normalizeSubject(value) {
|
|
21
|
+
if (value === undefined)
|
|
22
|
+
return "";
|
|
23
|
+
const normalized = normalizeLabel(value);
|
|
24
|
+
if (normalized.length > MAX_FILTER_VALUE_LENGTH) {
|
|
25
|
+
throw new EngineError("INVALID_FILTER", `subject must be at most ${MAX_FILTER_VALUE_LENGTH} characters`);
|
|
26
|
+
}
|
|
27
|
+
return normalized;
|
|
28
|
+
}
|
|
29
|
+
export function normalizeStoredLabels(name, values) {
|
|
30
|
+
const normalized = normalizeLabels(values);
|
|
31
|
+
if (normalized.length > MAX_FILTER_VALUES) {
|
|
32
|
+
throw new EngineError("INVALID_FILTER", `${name} accepts at most ${MAX_FILTER_VALUES} values`);
|
|
33
|
+
}
|
|
34
|
+
if (normalized.some((value) => value.length > MAX_FILTER_VALUE_LENGTH)) {
|
|
35
|
+
throw new EngineError("INVALID_FILTER", `${name} values must be at most ${MAX_FILTER_VALUE_LENGTH} characters`);
|
|
36
|
+
}
|
|
37
|
+
return normalized;
|
|
38
|
+
}
|
|
39
|
+
export function normalizeSearch(input) {
|
|
40
|
+
const requestedCategories = input.categories;
|
|
41
|
+
const allCategories = requestedCategories === undefined;
|
|
42
|
+
let categories = [];
|
|
43
|
+
if (requestedCategories !== undefined) {
|
|
44
|
+
if (requestedCategories.length < 1 || requestedCategories.length > MAX_SEARCH_CATEGORIES) {
|
|
45
|
+
throw new EngineError("INVALID_CATEGORIES", `categories must contain 1 to ${MAX_SEARCH_CATEGORIES} values when provided`);
|
|
46
|
+
}
|
|
47
|
+
if (!requestedCategories.every(isCategory)) {
|
|
48
|
+
throw new EngineError("INVALID_CATEGORY", "each category must be 1 to 64 characters");
|
|
49
|
+
}
|
|
50
|
+
categories = requestedCategories.map(canonicalCategory);
|
|
51
|
+
if (new Set(categories).size !== categories.length) {
|
|
52
|
+
throw new EngineError("INVALID_CATEGORIES", "categories must be unique after normalization");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const filters = input.filters ?? {};
|
|
56
|
+
const hints = normalizeHints(input.hints);
|
|
57
|
+
const scope = filters.scope ?? "both";
|
|
58
|
+
if (scope !== "both" && !isScope(scope)) {
|
|
59
|
+
throw new EngineError("INVALID_SCOPE", "filter scope must be both, global, or project");
|
|
60
|
+
}
|
|
61
|
+
if (filters.minImportance !== undefined)
|
|
62
|
+
normalizeImportance(filters.minImportance);
|
|
63
|
+
if (filters.subject !== undefined)
|
|
64
|
+
normalizeSubject(filters.subject);
|
|
65
|
+
for (const [name, filter] of [
|
|
66
|
+
["topics", filters.topics],
|
|
67
|
+
["tags", filters.tags],
|
|
68
|
+
["links", filters.links],
|
|
69
|
+
]) {
|
|
70
|
+
if (!filter)
|
|
71
|
+
continue;
|
|
72
|
+
normalizeStoredLabels(name, filter.values);
|
|
73
|
+
if (filter.match !== undefined && filter.match !== "any" && filter.match !== "all") {
|
|
74
|
+
throw new EngineError("INVALID_FILTER", `${name}.match must be any or all`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const sort = {
|
|
78
|
+
by: input.sort?.by ?? "relevance",
|
|
79
|
+
order: input.sort?.order ?? "desc",
|
|
80
|
+
};
|
|
81
|
+
if (!["relevance", "updated", "created", "importance"].includes(sort.by)) {
|
|
82
|
+
throw new EngineError("INVALID_SORT", "invalid sort field");
|
|
83
|
+
}
|
|
84
|
+
if (sort.order !== "asc" && sort.order !== "desc") {
|
|
85
|
+
throw new EngineError("INVALID_SORT", "sort order must be asc or desc");
|
|
86
|
+
}
|
|
87
|
+
const limit = Math.max(1, Math.min(input.limit ?? MAX_HITS, MAX_HITS));
|
|
88
|
+
const scopes = scope === "both" ? ["global", "project"] : [scope];
|
|
89
|
+
const time = normalizeTime(filters.time);
|
|
90
|
+
return {
|
|
91
|
+
input,
|
|
92
|
+
categories,
|
|
93
|
+
allCategories,
|
|
94
|
+
filters,
|
|
95
|
+
hints,
|
|
96
|
+
sort,
|
|
97
|
+
limit,
|
|
98
|
+
scopes,
|
|
99
|
+
...(time !== undefined ? { time } : {}),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function normalizeHints(hints) {
|
|
103
|
+
const topics = normalizeHintLabels("hints.topics", hints?.topics);
|
|
104
|
+
const tags = normalizeHintLabels("hints.tags", hints?.tags);
|
|
105
|
+
const links = normalizeHintLabels("hints.links", hints?.links);
|
|
106
|
+
const rawCategories = hints?.categories;
|
|
107
|
+
let categories = [];
|
|
108
|
+
if (rawCategories !== undefined) {
|
|
109
|
+
if (rawCategories.length < 1 || rawCategories.length > MAX_SEARCH_CATEGORIES) {
|
|
110
|
+
throw new EngineError("INVALID_FILTER", `hints.categories accepts 1 to ${MAX_SEARCH_CATEGORIES} values`);
|
|
111
|
+
}
|
|
112
|
+
if (!rawCategories.every(isCategory)) {
|
|
113
|
+
throw new EngineError("INVALID_FILTER", "hints.categories values must be 1 to 64 characters");
|
|
114
|
+
}
|
|
115
|
+
categories = [...new Set(rawCategories.map(canonicalCategory))];
|
|
116
|
+
if (categories.length !== rawCategories.length) {
|
|
117
|
+
throw new EngineError("INVALID_FILTER", "hints.categories values must be unique after normalization");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return { topics, tags, links, categories };
|
|
121
|
+
}
|
|
122
|
+
function normalizeHintLabels(name, values) {
|
|
123
|
+
if (values === undefined)
|
|
124
|
+
return [];
|
|
125
|
+
if (values.length < 1)
|
|
126
|
+
throw new EngineError("INVALID_FILTER", `${name} must not be empty when provided`);
|
|
127
|
+
const normalized = normalizeStoredLabels(name, values);
|
|
128
|
+
if (normalized.length !== values.length) {
|
|
129
|
+
throw new EngineError("INVALID_FILTER", `${name} values must be unique and non-empty after normalization`);
|
|
130
|
+
}
|
|
131
|
+
return normalized;
|
|
132
|
+
}
|
|
133
|
+
function normalizeTime(time) {
|
|
134
|
+
if (!time)
|
|
135
|
+
return undefined;
|
|
136
|
+
if (time.preset && (time.from || time.to)) {
|
|
137
|
+
throw new EngineError("INVALID_TIME", "time preset cannot be combined with from or to");
|
|
138
|
+
}
|
|
139
|
+
const field = time.field === "created" ? "created_at" : "updated_at";
|
|
140
|
+
if (time.field !== undefined && time.field !== "created" && time.field !== "updated") {
|
|
141
|
+
throw new EngineError("INVALID_TIME", "time field must be created or updated");
|
|
142
|
+
}
|
|
143
|
+
if (time.preset) {
|
|
144
|
+
const now = new Date();
|
|
145
|
+
const start = new Date(now);
|
|
146
|
+
if (time.preset === "this_month") {
|
|
147
|
+
start.setHours(0, 0, 0, 0);
|
|
148
|
+
start.setDate(1);
|
|
149
|
+
}
|
|
150
|
+
else if (time.preset === "this_week") {
|
|
151
|
+
const day = start.getDay();
|
|
152
|
+
start.setDate(start.getDate() - (day === 0 ? 6 : day - 1));
|
|
153
|
+
start.setHours(0, 0, 0, 0);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
throw new EngineError("INVALID_TIME", "time preset must be this_week or this_month");
|
|
157
|
+
}
|
|
158
|
+
return { field, from: Math.floor(start.getTime() / 1000), to: Math.floor(now.getTime() / 1000) };
|
|
159
|
+
}
|
|
160
|
+
const from = parseIsoTime(time.from, "from");
|
|
161
|
+
const to = parseIsoTime(time.to, "to");
|
|
162
|
+
if (from !== undefined && to !== undefined && from > to) {
|
|
163
|
+
throw new EngineError("INVALID_TIME", "time.from must not be after time.to");
|
|
164
|
+
}
|
|
165
|
+
return { field, ...(from !== undefined ? { from } : {}), ...(to !== undefined ? { to } : {}) };
|
|
166
|
+
}
|
|
167
|
+
function parseIsoTime(value, name) {
|
|
168
|
+
if (value === undefined)
|
|
169
|
+
return undefined;
|
|
170
|
+
const milliseconds = Date.parse(value);
|
|
171
|
+
if (!Number.isFinite(milliseconds))
|
|
172
|
+
throw new EngineError("INVALID_TIME", `time.${name} must be ISO-8601`);
|
|
173
|
+
return Math.floor(milliseconds / 1000);
|
|
174
|
+
}
|
|
175
|
+
export function sqlFilter(search, alias) {
|
|
176
|
+
const clauses = [`${alias}.active = 1`];
|
|
177
|
+
const params = [];
|
|
178
|
+
if (!search.filters.includeStaging)
|
|
179
|
+
clauses.push(`${alias}.chat_id IS NULL`);
|
|
180
|
+
if (search.filters.minImportance !== undefined) {
|
|
181
|
+
clauses.push(`${alias}.importance >= ?`);
|
|
182
|
+
params.push(search.filters.minImportance);
|
|
183
|
+
}
|
|
184
|
+
if (search.filters.subject !== undefined) {
|
|
185
|
+
clauses.push(`${alias}.subject = ?`);
|
|
186
|
+
params.push(normalizeSubject(search.filters.subject));
|
|
187
|
+
}
|
|
188
|
+
if (search.time?.from !== undefined) {
|
|
189
|
+
clauses.push(`${alias}.${search.time.field} >= ?`);
|
|
190
|
+
params.push(search.time.from);
|
|
191
|
+
}
|
|
192
|
+
if (search.time?.to !== undefined) {
|
|
193
|
+
clauses.push(`${alias}.${search.time.field} <= ?`);
|
|
194
|
+
params.push(search.time.to);
|
|
195
|
+
}
|
|
196
|
+
for (const [kind, filter] of [
|
|
197
|
+
["topic", search.filters.topics],
|
|
198
|
+
["tag", search.filters.tags],
|
|
199
|
+
["link", search.filters.links],
|
|
200
|
+
]) {
|
|
201
|
+
if (!filter)
|
|
202
|
+
continue;
|
|
203
|
+
const values = normalizeStoredLabels(`${kind}s`, filter.values);
|
|
204
|
+
if (values.length === 0)
|
|
205
|
+
continue;
|
|
206
|
+
const placeholders = values.map(() => "?").join(", ");
|
|
207
|
+
if ((filter.match ?? "any") === "all") {
|
|
208
|
+
clauses.push(`(SELECT COUNT(DISTINCT label.value) FROM memory_labels label
|
|
209
|
+
WHERE label.memory_id = ${alias}.id AND label.kind = ? AND label.value IN (${placeholders})) = ?`);
|
|
210
|
+
params.push(kind, ...values, values.length);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
clauses.push(`EXISTS (SELECT 1 FROM memory_labels label
|
|
214
|
+
WHERE label.memory_id = ${alias}.id AND label.kind = ? AND label.value IN (${placeholders}))`);
|
|
215
|
+
params.push(kind, ...values);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return { sql: clauses.join(" AND "), params };
|
|
219
|
+
}
|
|
220
|
+
export function searchSources(search, access) {
|
|
221
|
+
const sources = [];
|
|
222
|
+
if (search.allCategories) {
|
|
223
|
+
for (const scope of search.scopes) {
|
|
224
|
+
for (const record of listCategories(access.catalogFor(scope))) {
|
|
225
|
+
sources.push({ db: access.dbForRecord(scope, record), scope, record });
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return sources;
|
|
229
|
+
}
|
|
230
|
+
for (const canonical of search.categories) {
|
|
231
|
+
let found = false;
|
|
232
|
+
for (const scope of search.scopes) {
|
|
233
|
+
const record = access.recordFor(scope, canonical);
|
|
234
|
+
if (!record)
|
|
235
|
+
continue;
|
|
236
|
+
found = true;
|
|
237
|
+
sources.push({ db: access.dbForRecord(scope, record), scope, record });
|
|
238
|
+
}
|
|
239
|
+
if (!found)
|
|
240
|
+
throw new EngineError("INVALID_CATEGORY", `unknown category: ${canonical}`);
|
|
241
|
+
}
|
|
242
|
+
return sources;
|
|
243
|
+
}
|
|
244
|
+
export function countEligible(source, search) {
|
|
245
|
+
const filter = sqlFilter(search, "m");
|
|
246
|
+
const row = source.db
|
|
247
|
+
.prepare(`SELECT COUNT(*) AS count FROM memories m WHERE ${filter.sql}`)
|
|
248
|
+
.get(...filter.params);
|
|
249
|
+
return row.count;
|
|
250
|
+
}
|
|
251
|
+
export function readAllEligible(sources, search, access) {
|
|
252
|
+
return sources.flatMap((source) => {
|
|
253
|
+
const filter = sqlFilter(search, "m");
|
|
254
|
+
const rows = source.db
|
|
255
|
+
.prepare(`SELECT m.* FROM memories m WHERE ${filter.sql}`)
|
|
256
|
+
.all(...filter.params);
|
|
257
|
+
return rows.map((row) => ({ ...access.toHit(row, source.scope), score: row.importance }));
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
export function readFtsCandidates(sources, search, access, query = search.input.query) {
|
|
261
|
+
const match = buildFtsQuery(query);
|
|
262
|
+
if (!match)
|
|
263
|
+
return [];
|
|
264
|
+
const queryTerms = lexicalQueryTerms(query);
|
|
265
|
+
const candidates = [];
|
|
266
|
+
for (const source of sources) {
|
|
267
|
+
const filter = sqlFilter(search, "m");
|
|
268
|
+
const rows = source.db
|
|
269
|
+
.prepare(`SELECT m.*, bm25(memories_fts, 1.0, 0.7, 0.5, 0.5, 0.4) AS rank
|
|
270
|
+
FROM memories_fts JOIN memories m ON m.rowid = memories_fts.rowid
|
|
271
|
+
WHERE memories_fts MATCH ? AND ${filter.sql}
|
|
272
|
+
ORDER BY rank`)
|
|
273
|
+
.all(match, ...filter.params);
|
|
274
|
+
for (const { rank, ...row } of rows) {
|
|
275
|
+
const coverage = lexicalCoverage(queryTerms, row);
|
|
276
|
+
if (queryTerms.length >= 4 && coverage < 0.25)
|
|
277
|
+
continue;
|
|
278
|
+
candidates.push({ row, scope: source.scope, lexical: Math.max(0, -rank), coverage });
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
const maxLexical = Math.max(...candidates.map((candidate) => candidate.lexical), 0) || 1;
|
|
282
|
+
const ranked = candidates
|
|
283
|
+
.map(({ row, scope, lexical, coverage }) => ({
|
|
284
|
+
...access.toHit(row, scope),
|
|
285
|
+
score: round(0.75 * (lexical / maxLexical) + 0.15 * coverage + 0.1 * row.importance),
|
|
286
|
+
}))
|
|
287
|
+
.sort((a, b) => b.score - a.score || b.updated_at - a.updated_at);
|
|
288
|
+
return ranked;
|
|
289
|
+
}
|
|
290
|
+
export function mergeSearchCandidates(eligible, ftsHits, search, options) {
|
|
291
|
+
const ftsById = new Map(ftsHits.map((hit) => [hit.id, hit]));
|
|
292
|
+
const totalLabelHints = search.hints.topics.length + search.hints.tags.length + search.hints.links.length;
|
|
293
|
+
const signaled = eligible.flatMap((hit) => {
|
|
294
|
+
const fts = ftsById.get(hit.id);
|
|
295
|
+
const matchedLabels = matchingHintLabels(hit, search.hints);
|
|
296
|
+
if (!fts && matchedLabels.length === 0)
|
|
297
|
+
return [];
|
|
298
|
+
const bucket = fts && matchedLabels.length > 0 ? 3 : matchedLabels.length > 0 ? 2 : 1;
|
|
299
|
+
const signal = fts?.score ?? (totalLabelHints > 0 ? matchedLabels.length / totalLabelHints : 0);
|
|
300
|
+
const categoryHintBoosted = search.hints.categories.includes(canonicalCategory(hit.category));
|
|
301
|
+
const channels = [];
|
|
302
|
+
if (fts)
|
|
303
|
+
channels.push("fts");
|
|
304
|
+
if (matchedLabels.length > 0)
|
|
305
|
+
channels.push("labels");
|
|
306
|
+
if (fts && options.usedTypo)
|
|
307
|
+
channels.push("typo");
|
|
308
|
+
return [{
|
|
309
|
+
hit: { ...hit, score: bucket + signal + (categoryHintBoosted ? 0.05 : 0) },
|
|
310
|
+
channels,
|
|
311
|
+
matchedLabels,
|
|
312
|
+
categoryHintBoosted,
|
|
313
|
+
}];
|
|
314
|
+
});
|
|
315
|
+
signaled.sort((left, right) => candidateOrder(left.hit, right.hit));
|
|
316
|
+
const channels = [];
|
|
317
|
+
if (signaled.some((candidate) => candidate.channels.includes("fts")))
|
|
318
|
+
channels.push("fts");
|
|
319
|
+
if (signaled.some((candidate) => candidate.channels.includes("labels")))
|
|
320
|
+
channels.push("labels");
|
|
321
|
+
if (signaled.some((candidate) => candidate.channels.includes("typo")))
|
|
322
|
+
channels.push("typo");
|
|
323
|
+
if (!options.fill || signaled.length >= MAX_JEV_CANDIDATES * MAX_JEV_BATCHES) {
|
|
324
|
+
return { hits: signaled.map((candidate) => candidate.hit), candidates: signaled, channels };
|
|
325
|
+
}
|
|
326
|
+
const selected = [...signaled];
|
|
327
|
+
const selectedIds = new Set(selected.map((candidate) => candidate.hit.id));
|
|
328
|
+
const remaining = eligible
|
|
329
|
+
.filter((hit) => !selectedIds.has(hit.id))
|
|
330
|
+
.sort((a, b) => compareScope(a, b) ||
|
|
331
|
+
Number(search.hints.categories.includes(canonicalCategory(b.category))) -
|
|
332
|
+
Number(search.hints.categories.includes(canonicalCategory(a.category))) ||
|
|
333
|
+
b.importance - a.importance ||
|
|
334
|
+
b.updated_at - a.updated_at ||
|
|
335
|
+
a.id.localeCompare(b.id));
|
|
336
|
+
const fillCount = MAX_JEV_CANDIDATES * MAX_JEV_BATCHES - selected.length;
|
|
337
|
+
for (const hit of remaining.slice(0, fillCount)) {
|
|
338
|
+
selected.push({
|
|
339
|
+
hit: { ...hit, score: hit.importance * 0.1 },
|
|
340
|
+
channels: ["fill"],
|
|
341
|
+
matchedLabels: [],
|
|
342
|
+
categoryHintBoosted: search.hints.categories.includes(canonicalCategory(hit.category)),
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
if (selected.length > signaled.length)
|
|
346
|
+
channels.push("fill");
|
|
347
|
+
return { hits: selected.map((candidate) => candidate.hit), candidates: selected, channels };
|
|
348
|
+
}
|
|
349
|
+
export function searchResult(normalized, candidates, eligibleCount, usedFts, applyBudget, maxTokens, retrieval) {
|
|
350
|
+
const sorted = sortHits(candidates, normalized.sort);
|
|
351
|
+
const hits = applyBudget ? budgetHits(sorted, normalized.limit, maxTokens) : sorted;
|
|
352
|
+
return {
|
|
353
|
+
query: normalized.input.query,
|
|
354
|
+
hits,
|
|
355
|
+
total_tokens: hits.reduce((sum, hit) => sum + hit.tokens, 0),
|
|
356
|
+
budget: { max_hits: normalized.limit, max_tokens: maxTokens },
|
|
357
|
+
sort: normalized.sort,
|
|
358
|
+
eligible_count: eligibleCount,
|
|
359
|
+
used_fts: usedFts,
|
|
360
|
+
retrieval: { ...retrieval, candidate_count: candidates.length },
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
export function sortHits(hits, sort) {
|
|
364
|
+
const direction = sort.order === "asc" ? 1 : -1;
|
|
365
|
+
const sorted = [...hits].sort((a, b) => {
|
|
366
|
+
const av = sort.by === "relevance" ? a.score
|
|
367
|
+
: sort.by === "updated" ? a.updated_at
|
|
368
|
+
: sort.by === "created" ? a.created_at
|
|
369
|
+
: a.importance;
|
|
370
|
+
const bv = sort.by === "relevance" ? b.score
|
|
371
|
+
: sort.by === "updated" ? b.updated_at
|
|
372
|
+
: sort.by === "created" ? b.created_at
|
|
373
|
+
: b.importance;
|
|
374
|
+
return direction * (av - bv) || compareScope(a, b) || b.updated_at - a.updated_at || a.id.localeCompare(b.id);
|
|
375
|
+
});
|
|
376
|
+
return sort.by === "relevance" ? applySubjectPrecedence(sorted) : sorted;
|
|
377
|
+
}
|
|
378
|
+
export function budgetHits(hits, limit, maxTokens) {
|
|
379
|
+
const selected = [];
|
|
380
|
+
let tokens = 0;
|
|
381
|
+
for (const hit of hits) {
|
|
382
|
+
if (selected.length >= limit)
|
|
383
|
+
break;
|
|
384
|
+
if (tokens + hit.tokens > maxTokens)
|
|
385
|
+
continue;
|
|
386
|
+
selected.push(hit);
|
|
387
|
+
tokens += hit.tokens;
|
|
388
|
+
}
|
|
389
|
+
return selected;
|
|
390
|
+
}
|
|
391
|
+
function round(value) {
|
|
392
|
+
return Math.round(value * 1000) / 1000;
|
|
393
|
+
}
|
|
394
|
+
function lexicalCoverage(queryTerms, row) {
|
|
395
|
+
if (queryTerms.length === 0)
|
|
396
|
+
return 1;
|
|
397
|
+
const searchable = keywords([row.content, row.subject, row.topics, row.tags, row.links].filter(Boolean).join(" "));
|
|
398
|
+
const available = new Set(searchable);
|
|
399
|
+
const matched = queryTerms.filter((term) => available.has(term)).length;
|
|
400
|
+
return matched / queryTerms.length;
|
|
401
|
+
}
|
|
402
|
+
export function matchingHintLabels(hit, hints) {
|
|
403
|
+
return [
|
|
404
|
+
...intersectionValues("topic", hit.topics, hints.topics),
|
|
405
|
+
...intersectionValues("tag", hit.tags, hints.tags),
|
|
406
|
+
...intersectionValues("link", hit.links, hints.links),
|
|
407
|
+
];
|
|
408
|
+
}
|
|
409
|
+
function intersectionValues(kind, values, hints) {
|
|
410
|
+
if (values.length === 0 || hints.length === 0)
|
|
411
|
+
return [];
|
|
412
|
+
const available = new Set(values.map(normalizeLabel));
|
|
413
|
+
return hints.filter((hint) => available.has(hint)).map((hint) => `${kind}:${hint}`);
|
|
414
|
+
}
|
|
415
|
+
function candidateOrder(a, b) {
|
|
416
|
+
return b.score - a.score || compareScope(a, b) || b.importance - a.importance ||
|
|
417
|
+
b.updated_at - a.updated_at || a.id.localeCompare(b.id);
|
|
418
|
+
}
|
|
419
|
+
function applySubjectPrecedence(hits) {
|
|
420
|
+
const indexesBySubject = new Map();
|
|
421
|
+
for (const [index, hit] of hits.entries()) {
|
|
422
|
+
if (!hit.subject)
|
|
423
|
+
continue;
|
|
424
|
+
const subject = normalizeLabel(hit.subject);
|
|
425
|
+
if (subject.length === 0)
|
|
426
|
+
continue;
|
|
427
|
+
const indexes = indexesBySubject.get(subject) ?? [];
|
|
428
|
+
indexes.push(index);
|
|
429
|
+
indexesBySubject.set(subject, indexes);
|
|
430
|
+
}
|
|
431
|
+
const ordered = [...hits];
|
|
432
|
+
for (const indexes of indexesBySubject.values()) {
|
|
433
|
+
if (indexes.length < 2)
|
|
434
|
+
continue;
|
|
435
|
+
const group = indexes
|
|
436
|
+
.map((index) => hits[index])
|
|
437
|
+
.sort((a, b) => compareScope(a, b) || b.updated_at - a.updated_at || b.score - a.score);
|
|
438
|
+
indexes.forEach((index, groupIndex) => {
|
|
439
|
+
ordered[index] = group[groupIndex];
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
return ordered;
|
|
443
|
+
}
|
|
444
|
+
function compareScope(a, b) {
|
|
445
|
+
if (a.scope === b.scope)
|
|
446
|
+
return 0;
|
|
447
|
+
return a.scope === "project" ? -1 : 1;
|
|
448
|
+
}
|
|
449
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const TYPE_SAFE_KEY_PROMPT = "TypeSafe API key (hidden, Enter to skip): ";
|
|
2
|
+
export declare const TYPE_SAFE_KEY_REPLACE_PROMPT = "New TypeSafe API key (hidden, Enter to keep the saved key): ";
|
|
3
|
+
export interface SecretStore {
|
|
4
|
+
get(): string | null;
|
|
5
|
+
set(secret: string): void;
|
|
6
|
+
}
|
|
7
|
+
export type TypeSafeKeyStatus = "present" | "saved" | "skipped";
|
|
8
|
+
export declare function resolveTypeSafeApiKey(env: {
|
|
9
|
+
TYPESAFE_API_KEY?: string;
|
|
10
|
+
}, read: () => string | null): {
|
|
11
|
+
apiKey: string;
|
|
12
|
+
warning?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function loadTypeSafeApiKey(env?: NodeJS.ProcessEnv): Promise<{
|
|
15
|
+
apiKey: string;
|
|
16
|
+
warning?: string;
|
|
17
|
+
}>;
|
|
18
|
+
export declare function openOsKeychain(): Promise<SecretStore>;
|
|
19
|
+
export declare function ensureTypeSafeKey(options: {
|
|
20
|
+
store: SecretStore;
|
|
21
|
+
interactive: boolean;
|
|
22
|
+
prompt?: (label: string) => Promise<string>;
|
|
23
|
+
log?: (line: string) => void;
|
|
24
|
+
}): Promise<TypeSafeKeyStatus>;
|
|
25
|
+
export declare function promptHidden(label: string, io?: {
|
|
26
|
+
input?: NodeJS.ReadStream;
|
|
27
|
+
output?: NodeJS.WriteStream;
|
|
28
|
+
}): Promise<string>;
|