@duckcodeailabs/dql-agent 1.6.20 → 1.6.22
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/dist/agent-run-engine.d.ts +287 -0
- package/dist/agent-run-engine.d.ts.map +1 -0
- package/dist/agent-run-engine.js +916 -0
- package/dist/agent-run-engine.js.map +1 -0
- package/dist/agent-run-gates.d.ts +26 -0
- package/dist/agent-run-gates.d.ts.map +1 -0
- package/dist/agent-run-gates.js +170 -0
- package/dist/agent-run-gates.js.map +1 -0
- package/dist/agent-run-planner.d.ts +32 -0
- package/dist/agent-run-planner.d.ts.map +1 -0
- package/dist/agent-run-planner.js +280 -0
- package/dist/agent-run-planner.js.map +1 -0
- package/dist/answer-loop.d.ts +49 -0
- package/dist/answer-loop.d.ts.map +1 -1
- package/dist/answer-loop.js +292 -17
- package/dist/answer-loop.js.map +1 -1
- package/dist/app-builder.d.ts +44 -2
- package/dist/app-builder.d.ts.map +1 -1
- package/dist/app-builder.js +558 -123
- package/dist/app-builder.js.map +1 -1
- package/dist/app-planner.d.ts +78 -0
- package/dist/app-planner.d.ts.map +1 -0
- package/dist/app-planner.js +145 -0
- package/dist/app-planner.js.map +1 -0
- package/dist/embeddings/provider.d.ts +66 -0
- package/dist/embeddings/provider.d.ts.map +1 -0
- package/dist/embeddings/provider.js +105 -0
- package/dist/embeddings/provider.js.map +1 -0
- package/dist/hints/git-store.d.ts +69 -0
- package/dist/hints/git-store.d.ts.map +1 -0
- package/dist/hints/git-store.js +244 -0
- package/dist/hints/git-store.js.map +1 -0
- package/dist/hints/retrieval.d.ts +49 -0
- package/dist/hints/retrieval.d.ts.map +1 -0
- package/dist/hints/retrieval.js +60 -0
- package/dist/hints/retrieval.js.map +1 -0
- package/dist/hints/store.d.ts +39 -0
- package/dist/hints/store.d.ts.map +1 -0
- package/dist/hints/store.js +279 -0
- package/dist/hints/store.js.map +1 -0
- package/dist/hints/types.d.ts +147 -0
- package/dist/hints/types.d.ts.map +1 -0
- package/dist/hints/types.js +92 -0
- package/dist/hints/types.js.map +1 -0
- package/dist/index.d.ts +43 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -3
- package/dist/index.js.map +1 -1
- package/dist/intent-controller.d.ts +63 -0
- package/dist/intent-controller.d.ts.map +1 -0
- package/dist/intent-controller.js +150 -0
- package/dist/intent-controller.js.map +1 -0
- package/dist/kg/build.d.ts.map +1 -1
- package/dist/kg/build.js +2 -0
- package/dist/kg/build.js.map +1 -1
- package/dist/kg/sqlite-fts.js +4 -0
- package/dist/kg/sqlite-fts.js.map +1 -1
- package/dist/kg/types.d.ts +10 -0
- package/dist/kg/types.d.ts.map +1 -1
- package/dist/metadata/catalog.d.ts +81 -4
- package/dist/metadata/catalog.d.ts.map +1 -1
- package/dist/metadata/catalog.js +208 -1
- package/dist/metadata/catalog.js.map +1 -1
- package/dist/metadata/drafts.d.ts +22 -0
- package/dist/metadata/drafts.d.ts.map +1 -1
- package/dist/metadata/drafts.js +126 -2
- package/dist/metadata/drafts.js.map +1 -1
- package/dist/metadata/grain-gate.d.ts +61 -0
- package/dist/metadata/grain-gate.d.ts.map +1 -0
- package/dist/metadata/grain-gate.js +265 -0
- package/dist/metadata/grain-gate.js.map +1 -0
- package/dist/metadata/identity.d.ts +47 -0
- package/dist/metadata/identity.d.ts.map +1 -0
- package/dist/metadata/identity.js +147 -0
- package/dist/metadata/identity.js.map +1 -0
- package/dist/metadata/metric-match.d.ts +93 -0
- package/dist/metadata/metric-match.d.ts.map +1 -0
- package/dist/metadata/metric-match.js +233 -0
- package/dist/metadata/metric-match.js.map +1 -0
- package/dist/metadata/sql-grounding.d.ts +149 -0
- package/dist/metadata/sql-grounding.d.ts.map +1 -0
- package/dist/metadata/sql-grounding.js +397 -0
- package/dist/metadata/sql-grounding.js.map +1 -0
- package/dist/metadata/sql-retrieval.d.ts +29 -0
- package/dist/metadata/sql-retrieval.d.ts.map +1 -0
- package/dist/metadata/sql-retrieval.js +79 -0
- package/dist/metadata/sql-retrieval.js.map +1 -0
- package/dist/narrate.d.ts +52 -0
- package/dist/narrate.d.ts.map +1 -0
- package/dist/narrate.js +263 -0
- package/dist/narrate.js.map +1 -0
- package/dist/propose/build-from-prompt.d.ts +160 -0
- package/dist/propose/build-from-prompt.d.ts.map +1 -0
- package/dist/propose/build-from-prompt.js +815 -0
- package/dist/propose/build-from-prompt.js.map +1 -0
- package/dist/propose/classify.d.ts +55 -0
- package/dist/propose/classify.d.ts.map +1 -0
- package/dist/propose/classify.js +167 -0
- package/dist/propose/classify.js.map +1 -0
- package/dist/propose/config.d.ts +39 -0
- package/dist/propose/config.d.ts.map +1 -0
- package/dist/propose/config.js +52 -0
- package/dist/propose/config.js.map +1 -0
- package/dist/propose/dbt-artifacts.d.ts +134 -0
- package/dist/propose/dbt-artifacts.d.ts.map +1 -0
- package/dist/propose/dbt-artifacts.js +320 -0
- package/dist/propose/dbt-artifacts.js.map +1 -0
- package/dist/propose/edit-block.d.ts +74 -0
- package/dist/propose/edit-block.d.ts.map +1 -0
- package/dist/propose/edit-block.js +133 -0
- package/dist/propose/edit-block.js.map +1 -0
- package/dist/propose/enrich.d.ts +48 -0
- package/dist/propose/enrich.d.ts.map +1 -0
- package/dist/propose/enrich.js +125 -0
- package/dist/propose/enrich.js.map +1 -0
- package/dist/propose/generate-sql.d.ts +61 -0
- package/dist/propose/generate-sql.d.ts.map +1 -0
- package/dist/propose/generate-sql.js +180 -0
- package/dist/propose/generate-sql.js.map +1 -0
- package/dist/propose/index.d.ts +24 -0
- package/dist/propose/index.d.ts.map +1 -0
- package/dist/propose/index.js +15 -0
- package/dist/propose/index.js.map +1 -0
- package/dist/propose/propose.d.ts +226 -0
- package/dist/propose/propose.d.ts.map +1 -0
- package/dist/propose/propose.js +668 -0
- package/dist/propose/propose.js.map +1 -0
- package/dist/propose/reflect-block.d.ts +99 -0
- package/dist/propose/reflect-block.d.ts.map +1 -0
- package/dist/propose/reflect-block.js +220 -0
- package/dist/propose/reflect-block.js.map +1 -0
- package/dist/propose/write-draft.d.ts +90 -0
- package/dist/propose/write-draft.d.ts.map +1 -0
- package/dist/propose/write-draft.js +185 -0
- package/dist/propose/write-draft.js.map +1 -0
- package/dist/providers/claude.d.ts +13 -1
- package/dist/providers/claude.d.ts.map +1 -1
- package/dist/providers/claude.js +20 -2
- package/dist/providers/claude.js.map +1 -1
- package/dist/providers/gemini.d.ts +13 -1
- package/dist/providers/gemini.d.ts.map +1 -1
- package/dist/providers/gemini.js +24 -3
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/index.d.ts +3 -3
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +3 -3
- package/dist/providers/index.js.map +1 -1
- package/dist/research-loop.d.ts +62 -0
- package/dist/research-loop.d.ts.map +1 -0
- package/dist/research-loop.js +210 -0
- package/dist/research-loop.js.map +1 -0
- package/dist/skills/defaults.d.ts +37 -0
- package/dist/skills/defaults.d.ts.map +1 -0
- package/dist/skills/defaults.js +152 -0
- package/dist/skills/defaults.js.map +1 -0
- package/dist/skills/loader.d.ts +60 -0
- package/dist/skills/loader.d.ts.map +1 -1
- package/dist/skills/loader.js +164 -2
- package/dist/skills/loader.js.map +1 -1
- package/package.json +7 -5
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pluggable semantic retrieval (Part B).
|
|
3
|
+
*
|
|
4
|
+
* `EmbeddingProvider` is the interface real providers (a local model, an API)
|
|
5
|
+
* plug into. The DEFAULT provider is a deterministic, offline, hashed-token
|
|
6
|
+
* vector — NO heavy model dependency is added. FTS5/BM25 remains the safe
|
|
7
|
+
* default ranker; hybrid ranking blends FTS relevance with cosine similarity
|
|
8
|
+
* from the configured provider.
|
|
9
|
+
*
|
|
10
|
+
* Determinism matters: the default provider must produce identical vectors for
|
|
11
|
+
* identical text so tests are stable offline.
|
|
12
|
+
*/
|
|
13
|
+
import { createHash } from 'node:crypto';
|
|
14
|
+
/** Cosine similarity in [-1, 1]; 0 for degenerate vectors. */
|
|
15
|
+
export function cosineSimilarity(a, b) {
|
|
16
|
+
if (a.length === 0 || a.length !== b.length)
|
|
17
|
+
return 0;
|
|
18
|
+
let dot = 0;
|
|
19
|
+
let na = 0;
|
|
20
|
+
let nb = 0;
|
|
21
|
+
for (let i = 0; i < a.length; i += 1) {
|
|
22
|
+
dot += a[i] * b[i];
|
|
23
|
+
na += a[i] * a[i];
|
|
24
|
+
nb += b[i] * b[i];
|
|
25
|
+
}
|
|
26
|
+
if (na === 0 || nb === 0)
|
|
27
|
+
return 0;
|
|
28
|
+
return dot / (Math.sqrt(na) * Math.sqrt(nb));
|
|
29
|
+
}
|
|
30
|
+
const TOKEN_RE = /[\p{L}\p{N}_]+/gu;
|
|
31
|
+
function tokenize(text) {
|
|
32
|
+
return (text.toLowerCase().match(TOKEN_RE) ?? []).filter((t) => t.length > 1);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Deterministic, dependency-free embedding via the hashing trick: each token is
|
|
36
|
+
* hashed to a bucket and a sign; counts accumulate into a fixed-width vector,
|
|
37
|
+
* then the vector is L2-normalised. Captures lexical overlap so semantically
|
|
38
|
+
* similar (shared-token) texts score higher under cosine similarity — enough to
|
|
39
|
+
* make hybrid ranking testable offline without any model.
|
|
40
|
+
*/
|
|
41
|
+
export class HashedTokenEmbeddingProvider {
|
|
42
|
+
id = 'hashed-token-v1';
|
|
43
|
+
dimensions;
|
|
44
|
+
constructor(dimensions = 256) {
|
|
45
|
+
this.dimensions = Math.max(16, dimensions);
|
|
46
|
+
}
|
|
47
|
+
async embed(texts) {
|
|
48
|
+
return texts.map((text) => this.embedOne(text));
|
|
49
|
+
}
|
|
50
|
+
embedOne(text) {
|
|
51
|
+
const vec = new Array(this.dimensions).fill(0);
|
|
52
|
+
for (const token of tokenize(text)) {
|
|
53
|
+
const h = hashToken(token);
|
|
54
|
+
const bucket = h % this.dimensions;
|
|
55
|
+
const sign = (h >>> 8) % 2 === 0 ? 1 : -1;
|
|
56
|
+
vec[bucket] += sign;
|
|
57
|
+
}
|
|
58
|
+
// L2 normalise so cosine reduces to a dot product and magnitudes are comparable.
|
|
59
|
+
let norm = 0;
|
|
60
|
+
for (const v of vec)
|
|
61
|
+
norm += v * v;
|
|
62
|
+
norm = Math.sqrt(norm);
|
|
63
|
+
if (norm === 0)
|
|
64
|
+
return vec;
|
|
65
|
+
return vec.map((v) => v / norm);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function hashToken(token) {
|
|
69
|
+
const digest = createHash('sha1').update(token).digest();
|
|
70
|
+
// First 4 bytes as an unsigned int.
|
|
71
|
+
return ((digest[0] << 24) | (digest[1] << 16) | (digest[2] << 8) | digest[3]) >>> 0;
|
|
72
|
+
}
|
|
73
|
+
/** The safe default provider: deterministic + offline. */
|
|
74
|
+
export function defaultEmbeddingProvider() {
|
|
75
|
+
return new HashedTokenEmbeddingProvider();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Blend FTS5 relevance with embedding cosine similarity. When `alpha` is 0 (the
|
|
79
|
+
* default) this is a pure pass-through of the FTS ordering — FTS5 stays the safe
|
|
80
|
+
* default and embeddings are strictly additive/opt-in.
|
|
81
|
+
*/
|
|
82
|
+
export async function hybridRank(query, items, options = {}) {
|
|
83
|
+
const alpha = clamp01(options.alpha ?? 0);
|
|
84
|
+
if (alpha === 0 || items.length === 0) {
|
|
85
|
+
return items
|
|
86
|
+
.map((entry) => ({ item: entry.item, ftsScore: entry.ftsScore, vectorScore: 0, score: entry.ftsScore }))
|
|
87
|
+
.sort((a, b) => b.score - a.score);
|
|
88
|
+
}
|
|
89
|
+
const provider = options.provider ?? defaultEmbeddingProvider();
|
|
90
|
+
const [queryVec, ...itemVecs] = await provider.embed([query, ...items.map((entry) => entry.text)]);
|
|
91
|
+
return items
|
|
92
|
+
.map((entry, index) => {
|
|
93
|
+
const cosine = cosineSimilarity(queryVec, itemVecs[index] ?? []);
|
|
94
|
+
const cosine01 = (cosine + 1) / 2; // map [-1,1] → [0,1]
|
|
95
|
+
const score = (1 - alpha) * entry.ftsScore + alpha * cosine01;
|
|
96
|
+
return { item: entry.item, ftsScore: entry.ftsScore, vectorScore: cosine01, score };
|
|
97
|
+
})
|
|
98
|
+
.sort((a, b) => b.score - a.score);
|
|
99
|
+
}
|
|
100
|
+
function clamp01(value) {
|
|
101
|
+
if (!Number.isFinite(value))
|
|
102
|
+
return 0;
|
|
103
|
+
return Math.max(0, Math.min(1, value));
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/embeddings/provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git-authoritative store for scoped correction memory.
|
|
3
|
+
*
|
|
4
|
+
* Files (the source of truth, consistent with DQL):
|
|
5
|
+
* - `.dql/traces/<id>.trace.json` — correction traces
|
|
6
|
+
* - `.dql/hints/<id>.hint.yaml` — candidate / approved / rejected hints
|
|
7
|
+
* - `.dql/reviews/<id>.review.yaml` — human review decisions
|
|
8
|
+
*
|
|
9
|
+
* `.dql/cache/agent-kg.sqlite` is a rebuildable index (see {@link HintStore}).
|
|
10
|
+
*
|
|
11
|
+
* The lifecycle:
|
|
12
|
+
* recordCorrectionTrace() → derives a `candidate` hint
|
|
13
|
+
* reviewHint('approved') → flips status to `approved`, writes the review,
|
|
14
|
+
* and reindexes SQLite
|
|
15
|
+
* Approved-only is enforced at retrieval; nothing here auto-applies a hint.
|
|
16
|
+
*/
|
|
17
|
+
import type { CorrectionTrace, Hint, HintReview, HintScope } from './types.js';
|
|
18
|
+
export declare function tracesDir(projectRoot: string): string;
|
|
19
|
+
export declare function hintsDir(projectRoot: string): string;
|
|
20
|
+
export declare function reviewsDir(projectRoot: string): string;
|
|
21
|
+
export declare function defaultHintIndexPath(projectRoot: string): string;
|
|
22
|
+
export interface RecordCorrectionTraceInput {
|
|
23
|
+
question: string;
|
|
24
|
+
scope: HintScope;
|
|
25
|
+
wrongAnswer: string;
|
|
26
|
+
correction: string;
|
|
27
|
+
rationale?: string;
|
|
28
|
+
author?: string;
|
|
29
|
+
anchorObjectKey?: string;
|
|
30
|
+
/** Override the derived candidate hint's title. */
|
|
31
|
+
hintTitle?: string;
|
|
32
|
+
/** Override the derived candidate hint's guidance (defaults to the correction). */
|
|
33
|
+
hintGuidance?: string;
|
|
34
|
+
correctedSql?: string;
|
|
35
|
+
tags?: string[];
|
|
36
|
+
}
|
|
37
|
+
export interface RecordCorrectionTraceResult {
|
|
38
|
+
trace: CorrectionTrace;
|
|
39
|
+
hint: Hint;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Record a Tier-2 correction as a Git trace + a derived **candidate** hint.
|
|
43
|
+
* The hint is NOT usable until reviewed/approved.
|
|
44
|
+
*/
|
|
45
|
+
export declare function recordCorrectionTrace(projectRoot: string, input: RecordCorrectionTraceInput): RecordCorrectionTraceResult;
|
|
46
|
+
export declare function hintFilePath(projectRoot: string, hintId: string): string;
|
|
47
|
+
export declare function writeHintFile(projectRoot: string, hint: Hint): void;
|
|
48
|
+
export declare function readHintFile(path: string, sourcePath?: string): Hint | null;
|
|
49
|
+
export declare function listHintsFromGit(projectRoot: string): Hint[];
|
|
50
|
+
export declare function getHintFromGit(projectRoot: string, hintId: string): Hint | null;
|
|
51
|
+
export interface ReviewHintInput {
|
|
52
|
+
hintId: string;
|
|
53
|
+
decision: 'approved' | 'rejected';
|
|
54
|
+
reviewer: string;
|
|
55
|
+
note?: string;
|
|
56
|
+
}
|
|
57
|
+
export interface ReviewHintResult {
|
|
58
|
+
hint: Hint;
|
|
59
|
+
review: HintReview;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Approve or reject a candidate hint. Writes the review record, flips the hint
|
|
63
|
+
* file's status, and reindexes SQLite. Approval is the ONLY path that makes a
|
|
64
|
+
* hint usable in normal retrieval.
|
|
65
|
+
*/
|
|
66
|
+
export declare function reviewHint(projectRoot: string, input: ReviewHintInput): ReviewHintResult | null;
|
|
67
|
+
/** Rebuild the SQLite hint index from the Git-authoritative files. */
|
|
68
|
+
export declare function reindexHints(projectRoot: string, indexPath?: string): number;
|
|
69
|
+
//# sourceMappingURL=git-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-store.d.ts","sourceRoot":"","sources":["../../src/hints/git-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAYH,OAAO,KAAK,EACV,eAAe,EACf,IAAI,EACJ,UAAU,EACV,SAAS,EACV,MAAM,YAAY,CAAC;AAMpB,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAErD;AACD,wBAAgB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEpD;AACD,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhE;AAYD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,eAAe,CAAC;IACvB,IAAI,EAAE,IAAI,CAAC;CACZ;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,0BAA0B,GAChC,2BAA2B,CA6C7B;AAID,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAExE;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAsBnE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAiC3E;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,CAW5D;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAG/E;AAID,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,UAAU,GAAG,UAAU,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,gBAAgB,GAAG,IAAI,CA+B/F;AAID,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,SAAoC,GAAG,MAAM,CASvG"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git-authoritative store for scoped correction memory.
|
|
3
|
+
*
|
|
4
|
+
* Files (the source of truth, consistent with DQL):
|
|
5
|
+
* - `.dql/traces/<id>.trace.json` — correction traces
|
|
6
|
+
* - `.dql/hints/<id>.hint.yaml` — candidate / approved / rejected hints
|
|
7
|
+
* - `.dql/reviews/<id>.review.yaml` — human review decisions
|
|
8
|
+
*
|
|
9
|
+
* `.dql/cache/agent-kg.sqlite` is a rebuildable index (see {@link HintStore}).
|
|
10
|
+
*
|
|
11
|
+
* The lifecycle:
|
|
12
|
+
* recordCorrectionTrace() → derives a `candidate` hint
|
|
13
|
+
* reviewHint('approved') → flips status to `approved`, writes the review,
|
|
14
|
+
* and reindexes SQLite
|
|
15
|
+
* Approved-only is enforced at retrieval; nothing here auto-applies a hint.
|
|
16
|
+
*/
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync, } from 'node:fs';
|
|
19
|
+
import * as yaml from 'js-yaml';
|
|
20
|
+
import { HintStore } from './store.js';
|
|
21
|
+
const TRACES_DIR = ['.dql', 'traces'];
|
|
22
|
+
const HINTS_DIR = ['.dql', 'hints'];
|
|
23
|
+
const REVIEWS_DIR = ['.dql', 'reviews'];
|
|
24
|
+
export function tracesDir(projectRoot) {
|
|
25
|
+
return join(projectRoot, ...TRACES_DIR);
|
|
26
|
+
}
|
|
27
|
+
export function hintsDir(projectRoot) {
|
|
28
|
+
return join(projectRoot, ...HINTS_DIR);
|
|
29
|
+
}
|
|
30
|
+
export function reviewsDir(projectRoot) {
|
|
31
|
+
return join(projectRoot, ...REVIEWS_DIR);
|
|
32
|
+
}
|
|
33
|
+
export function defaultHintIndexPath(projectRoot) {
|
|
34
|
+
return join(projectRoot, '.dql', 'cache', 'agent-kg.sqlite');
|
|
35
|
+
}
|
|
36
|
+
function genId(prefix) {
|
|
37
|
+
return `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
|
|
38
|
+
}
|
|
39
|
+
function nowIso() {
|
|
40
|
+
return new Date().toISOString();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Record a Tier-2 correction as a Git trace + a derived **candidate** hint.
|
|
44
|
+
* The hint is NOT usable until reviewed/approved.
|
|
45
|
+
*/
|
|
46
|
+
export function recordCorrectionTrace(projectRoot, input) {
|
|
47
|
+
const traceId = genId('trace');
|
|
48
|
+
const hintId = genId('hint');
|
|
49
|
+
const createdAt = nowIso();
|
|
50
|
+
const trace = {
|
|
51
|
+
id: traceId,
|
|
52
|
+
createdAt,
|
|
53
|
+
question: input.question,
|
|
54
|
+
scope: cleanScope(input.scope),
|
|
55
|
+
wrongAnswer: input.wrongAnswer,
|
|
56
|
+
correction: input.correction,
|
|
57
|
+
rationale: input.rationale,
|
|
58
|
+
author: input.author,
|
|
59
|
+
anchorObjectKey: input.anchorObjectKey,
|
|
60
|
+
derivedHintId: hintId,
|
|
61
|
+
};
|
|
62
|
+
const hint = {
|
|
63
|
+
id: hintId,
|
|
64
|
+
title: input.hintTitle?.trim() || deriveTitle(input.question, input.scope),
|
|
65
|
+
guidance: (input.hintGuidance ?? input.correction).trim(),
|
|
66
|
+
scope: cleanScope(input.scope),
|
|
67
|
+
status: 'candidate',
|
|
68
|
+
traceId,
|
|
69
|
+
correctedSql: input.correctedSql,
|
|
70
|
+
tags: input.tags,
|
|
71
|
+
author: input.author,
|
|
72
|
+
createdAt,
|
|
73
|
+
updatedAt: createdAt,
|
|
74
|
+
};
|
|
75
|
+
mkdirSync(tracesDir(projectRoot), { recursive: true });
|
|
76
|
+
mkdirSync(hintsDir(projectRoot), { recursive: true });
|
|
77
|
+
writeFileSync(join(tracesDir(projectRoot), `${traceId}.trace.json`), `${JSON.stringify(trace, null, 2)}\n`, 'utf-8');
|
|
78
|
+
writeHintFile(projectRoot, hint);
|
|
79
|
+
// Index the candidate so review/dev mode can find it (status gate keeps it out
|
|
80
|
+
// of normal retrieval).
|
|
81
|
+
reindexHints(projectRoot);
|
|
82
|
+
return { trace, hint };
|
|
83
|
+
}
|
|
84
|
+
// --- Hints ------------------------------------------------------------------
|
|
85
|
+
export function hintFilePath(projectRoot, hintId) {
|
|
86
|
+
return join(hintsDir(projectRoot), `${hintId}.hint.yaml`);
|
|
87
|
+
}
|
|
88
|
+
export function writeHintFile(projectRoot, hint) {
|
|
89
|
+
mkdirSync(hintsDir(projectRoot), { recursive: true });
|
|
90
|
+
const doc = {
|
|
91
|
+
id: hint.id,
|
|
92
|
+
title: hint.title,
|
|
93
|
+
guidance: hint.guidance,
|
|
94
|
+
status: hint.status,
|
|
95
|
+
scope: cleanScope(hint.scope),
|
|
96
|
+
traceId: hint.traceId,
|
|
97
|
+
correctedSql: hint.correctedSql,
|
|
98
|
+
tags: hint.tags,
|
|
99
|
+
author: hint.author,
|
|
100
|
+
reviewer: hint.reviewer,
|
|
101
|
+
supersedes: hint.supersedes,
|
|
102
|
+
createdAt: hint.createdAt,
|
|
103
|
+
updatedAt: hint.updatedAt,
|
|
104
|
+
};
|
|
105
|
+
writeFileSync(hintFilePath(projectRoot, hint.id), yaml.dump(stripUndefined(doc), { lineWidth: 100, noRefs: true }), 'utf-8');
|
|
106
|
+
}
|
|
107
|
+
export function readHintFile(path, sourcePath) {
|
|
108
|
+
try {
|
|
109
|
+
const raw = yaml.load(readFileSync(path, 'utf-8'));
|
|
110
|
+
if (!raw || typeof raw !== 'object')
|
|
111
|
+
return null;
|
|
112
|
+
const scope = (raw.scope ?? {});
|
|
113
|
+
const hint = {
|
|
114
|
+
id: String(raw.id ?? ''),
|
|
115
|
+
title: String(raw.title ?? ''),
|
|
116
|
+
guidance: String(raw.guidance ?? ''),
|
|
117
|
+
status: raw.status ?? 'candidate',
|
|
118
|
+
scope: {
|
|
119
|
+
metric: strOrUndef(scope.metric),
|
|
120
|
+
dbtModel: strOrUndef(scope.dbtModel),
|
|
121
|
+
domain: strOrUndef(scope.domain),
|
|
122
|
+
dialect: strOrUndef(scope.dialect),
|
|
123
|
+
term: strOrUndef(scope.term),
|
|
124
|
+
block: strOrUndef(scope.block),
|
|
125
|
+
},
|
|
126
|
+
traceId: strOrUndef(raw.traceId),
|
|
127
|
+
correctedSql: strOrUndef(raw.correctedSql),
|
|
128
|
+
tags: Array.isArray(raw.tags) ? raw.tags.map(String) : undefined,
|
|
129
|
+
author: strOrUndef(raw.author),
|
|
130
|
+
reviewer: strOrUndef(raw.reviewer),
|
|
131
|
+
supersedes: strOrUndef(raw.supersedes),
|
|
132
|
+
createdAt: String(raw.createdAt ?? nowIso()),
|
|
133
|
+
updatedAt: String(raw.updatedAt ?? nowIso()),
|
|
134
|
+
sourcePath,
|
|
135
|
+
};
|
|
136
|
+
if (!hint.id)
|
|
137
|
+
return null;
|
|
138
|
+
return hint;
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
export function listHintsFromGit(projectRoot) {
|
|
145
|
+
const dir = hintsDir(projectRoot);
|
|
146
|
+
if (!existsSync(dir))
|
|
147
|
+
return [];
|
|
148
|
+
const hints = [];
|
|
149
|
+
for (const file of readdirSync(dir)) {
|
|
150
|
+
if (!file.endsWith('.hint.yaml'))
|
|
151
|
+
continue;
|
|
152
|
+
const path = join(dir, file);
|
|
153
|
+
const hint = readHintFile(path, path);
|
|
154
|
+
if (hint)
|
|
155
|
+
hints.push(hint);
|
|
156
|
+
}
|
|
157
|
+
return hints.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
158
|
+
}
|
|
159
|
+
export function getHintFromGit(projectRoot, hintId) {
|
|
160
|
+
const path = hintFilePath(projectRoot, hintId);
|
|
161
|
+
return existsSync(path) ? readHintFile(path, path) : null;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Approve or reject a candidate hint. Writes the review record, flips the hint
|
|
165
|
+
* file's status, and reindexes SQLite. Approval is the ONLY path that makes a
|
|
166
|
+
* hint usable in normal retrieval.
|
|
167
|
+
*/
|
|
168
|
+
export function reviewHint(projectRoot, input) {
|
|
169
|
+
const hint = getHintFromGit(projectRoot, input.hintId);
|
|
170
|
+
if (!hint)
|
|
171
|
+
return null;
|
|
172
|
+
const reviewId = genId('review');
|
|
173
|
+
const createdAt = nowIso();
|
|
174
|
+
const review = {
|
|
175
|
+
id: reviewId,
|
|
176
|
+
hintId: input.hintId,
|
|
177
|
+
decision: input.decision,
|
|
178
|
+
reviewer: input.reviewer,
|
|
179
|
+
note: input.note,
|
|
180
|
+
createdAt,
|
|
181
|
+
};
|
|
182
|
+
mkdirSync(reviewsDir(projectRoot), { recursive: true });
|
|
183
|
+
writeFileSync(join(reviewsDir(projectRoot), `${reviewId}.review.yaml`), yaml.dump(stripUndefined({ ...review }), { lineWidth: 100, noRefs: true }), 'utf-8');
|
|
184
|
+
const updated = {
|
|
185
|
+
...hint,
|
|
186
|
+
status: input.decision,
|
|
187
|
+
reviewer: input.reviewer,
|
|
188
|
+
updatedAt: createdAt,
|
|
189
|
+
};
|
|
190
|
+
writeHintFile(projectRoot, updated);
|
|
191
|
+
reindexHints(projectRoot);
|
|
192
|
+
return { hint: updated, review };
|
|
193
|
+
}
|
|
194
|
+
// --- Index ------------------------------------------------------------------
|
|
195
|
+
/** Rebuild the SQLite hint index from the Git-authoritative files. */
|
|
196
|
+
export function reindexHints(projectRoot, indexPath = defaultHintIndexPath(projectRoot)) {
|
|
197
|
+
const hints = listHintsFromGit(projectRoot);
|
|
198
|
+
const store = new HintStore(indexPath);
|
|
199
|
+
try {
|
|
200
|
+
store.rebuild(hints);
|
|
201
|
+
return hints.length;
|
|
202
|
+
}
|
|
203
|
+
finally {
|
|
204
|
+
store.close();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// --- helpers ----------------------------------------------------------------
|
|
208
|
+
function deriveTitle(question, scope) {
|
|
209
|
+
const scopeBits = [scope.metric, scope.dbtModel, scope.domain].filter(Boolean).join('/');
|
|
210
|
+
const q = question.trim().replace(/\s+/g, ' ').slice(0, 60);
|
|
211
|
+
return scopeBits ? `Correction for ${scopeBits}: ${q}` : `Correction: ${q}`;
|
|
212
|
+
}
|
|
213
|
+
function cleanScope(scope) {
|
|
214
|
+
return {
|
|
215
|
+
metric: strOrUndef(scope.metric),
|
|
216
|
+
dbtModel: strOrUndef(scope.dbtModel),
|
|
217
|
+
domain: strOrUndef(scope.domain),
|
|
218
|
+
dialect: strOrUndef(scope.dialect),
|
|
219
|
+
term: strOrUndef(scope.term),
|
|
220
|
+
block: strOrUndef(scope.block),
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
function strOrUndef(value) {
|
|
224
|
+
if (value === undefined || value === null)
|
|
225
|
+
return undefined;
|
|
226
|
+
const str = String(value).trim();
|
|
227
|
+
return str.length > 0 ? str : undefined;
|
|
228
|
+
}
|
|
229
|
+
function stripUndefined(obj) {
|
|
230
|
+
const out = {};
|
|
231
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
232
|
+
if (value === undefined)
|
|
233
|
+
continue;
|
|
234
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
235
|
+
const nested = stripUndefined(value);
|
|
236
|
+
if (Object.keys(nested).length > 0)
|
|
237
|
+
out[key] = nested;
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
out[key] = value;
|
|
241
|
+
}
|
|
242
|
+
return out;
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=git-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-store.js","sourceRoot":"","sources":["../../src/hints/git-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fold approved scoped hints into the agent's context, AFTER certified routing.
|
|
3
|
+
*
|
|
4
|
+
* Retrieval order (extended, not replaced):
|
|
5
|
+
* certified artifacts → semantic context → graph anchors → APPROVED HINTS → Tier-2 draft.
|
|
6
|
+
*
|
|
7
|
+
* Approved-only is hard-enforced here: only `status === 'approved'` hints are
|
|
8
|
+
* ever returned in normal mode. A hint is applied only within its declared
|
|
9
|
+
* scope (metric / dbt model / domain / dialect / term / block).
|
|
10
|
+
*/
|
|
11
|
+
import type { QuestionScope } from './types.js';
|
|
12
|
+
import type { EmbeddingProvider } from '../embeddings/provider.js';
|
|
13
|
+
export interface AppliedHint {
|
|
14
|
+
hintId: string;
|
|
15
|
+
title: string;
|
|
16
|
+
guidance: string;
|
|
17
|
+
scopeReason: string;
|
|
18
|
+
score: number;
|
|
19
|
+
correctedSql?: string;
|
|
20
|
+
traceId?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface HintRetrievalResult {
|
|
23
|
+
/** Approved, scoped hints to fold in as advisory context (cited). */
|
|
24
|
+
applied: AppliedHint[];
|
|
25
|
+
/** Approved hints whose scopes overlap and disagree — surfaced for review. */
|
|
26
|
+
conflicts: Array<{
|
|
27
|
+
hintIds: [string, string];
|
|
28
|
+
titles: [string, string];
|
|
29
|
+
reason: string;
|
|
30
|
+
}>;
|
|
31
|
+
}
|
|
32
|
+
export interface RetrieveScopedHintsOptions {
|
|
33
|
+
questionScope: QuestionScope;
|
|
34
|
+
limit?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Hybrid-rank weight. Defaults to 0 (pure FTS5, the safe default). Anything
|
|
37
|
+
* >0 blends the deterministic embedding similarity in.
|
|
38
|
+
*/
|
|
39
|
+
alpha?: number;
|
|
40
|
+
embeddingProvider?: EmbeddingProvider;
|
|
41
|
+
indexPath?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Retrieve approved scoped hints from the SQLite index. Returns an empty result
|
|
45
|
+
* (no error) when the index does not exist yet or no hints match — keeping the
|
|
46
|
+
* whole feature additive and backward-compatible.
|
|
47
|
+
*/
|
|
48
|
+
export declare function retrieveScopedHints(projectRoot: string, options: RetrieveScopedHintsOptions): Promise<HintRetrievalResult>;
|
|
49
|
+
//# sourceMappingURL=retrieval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retrieval.d.ts","sourceRoot":"","sources":["../../src/hints/retrieval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAmB,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,qEAAqE;IACrE,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,8EAA8E;IAC9E,SAAS,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3F;AAED,MAAM,WAAW,0BAA0B;IACzC,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,mBAAmB,CAAC,CA8B9B"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fold approved scoped hints into the agent's context, AFTER certified routing.
|
|
3
|
+
*
|
|
4
|
+
* Retrieval order (extended, not replaced):
|
|
5
|
+
* certified artifacts → semantic context → graph anchors → APPROVED HINTS → Tier-2 draft.
|
|
6
|
+
*
|
|
7
|
+
* Approved-only is hard-enforced here: only `status === 'approved'` hints are
|
|
8
|
+
* ever returned in normal mode. A hint is applied only within its declared
|
|
9
|
+
* scope (metric / dbt model / domain / dialect / term / block).
|
|
10
|
+
*/
|
|
11
|
+
import { existsSync } from 'node:fs';
|
|
12
|
+
import { defaultHintIndexPath } from './git-store.js';
|
|
13
|
+
import { HintStore } from './store.js';
|
|
14
|
+
/**
|
|
15
|
+
* Retrieve approved scoped hints from the SQLite index. Returns an empty result
|
|
16
|
+
* (no error) when the index does not exist yet or no hints match — keeping the
|
|
17
|
+
* whole feature additive and backward-compatible.
|
|
18
|
+
*/
|
|
19
|
+
export async function retrieveScopedHints(projectRoot, options) {
|
|
20
|
+
const indexPath = options.indexPath ?? defaultHintIndexPath(projectRoot);
|
|
21
|
+
if (!existsSync(indexPath))
|
|
22
|
+
return { applied: [], conflicts: [] };
|
|
23
|
+
const store = new HintStore(indexPath);
|
|
24
|
+
try {
|
|
25
|
+
const matches = await store.searchApprovedHints({
|
|
26
|
+
questionScope: options.questionScope,
|
|
27
|
+
limit: options.limit ?? 6,
|
|
28
|
+
alpha: options.alpha,
|
|
29
|
+
embeddingProvider: options.embeddingProvider,
|
|
30
|
+
});
|
|
31
|
+
const applied = matches.map(toAppliedHint);
|
|
32
|
+
// Surface conflicts only among the hints we actually applied, so unrelated
|
|
33
|
+
// overlaps elsewhere in the project do not noise up an answer.
|
|
34
|
+
const appliedIds = new Set(applied.map((hint) => hint.hintId));
|
|
35
|
+
const conflicts = store
|
|
36
|
+
.conflictingApprovedHints()
|
|
37
|
+
.filter(([a, b]) => appliedIds.has(a.id) || appliedIds.has(b.id))
|
|
38
|
+
.map(([a, b]) => ({
|
|
39
|
+
hintIds: [a.id, b.id],
|
|
40
|
+
titles: [a.title, b.title],
|
|
41
|
+
reason: `Approved hints "${a.title}" and "${b.title}" overlap on scope and may disagree; review which is authoritative.`,
|
|
42
|
+
}));
|
|
43
|
+
return { applied, conflicts };
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
store.close();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function toAppliedHint(match) {
|
|
50
|
+
return {
|
|
51
|
+
hintId: match.hint.id,
|
|
52
|
+
title: match.hint.title,
|
|
53
|
+
guidance: match.hint.guidance,
|
|
54
|
+
scopeReason: match.scopeReason,
|
|
55
|
+
score: match.score,
|
|
56
|
+
correctedSql: match.hint.correctedSql,
|
|
57
|
+
traceId: match.hint.traceId,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=retrieval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retrieval.js","sourceRoot":"","sources":["../../src/hints/retrieval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAiCvC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,WAAmB,EACnB,OAAmC;IAEnC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACzE,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IAElE,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,SAAS,CAAC,CAAC;IACvC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,mBAAmB,CAAC;YAC9C,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;YACzB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;SAC7C,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAE3C,2EAA2E;QAC3E,+DAA+D;QAC/D,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/D,MAAM,SAAS,GAAG,KAAK;aACpB,wBAAwB,EAAE;aAC1B,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;aAChE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAChB,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAqB;YACzC,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAqB;YAC9C,MAAM,EAAE,mBAAmB,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,KAAK,qEAAqE;SACzH,CAAC,CAAC,CAAC;QAEN,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IAChC,CAAC;YAAS,CAAC;QACT,KAAK,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAsB;IAC3C,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE;QACrB,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK;QACvB,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ;QAC7B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY;QACrC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO;KAC5B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite index for scoped correction hints.
|
|
3
|
+
*
|
|
4
|
+
* Git is the source of truth (`.dql/hints/*.hint.yaml`); this is a rebuildable
|
|
5
|
+
* FTS5 index living in the SAME file as the KG (`.dql/cache/agent-kg.sqlite`),
|
|
6
|
+
* extending the existing store rather than introducing a second cache file.
|
|
7
|
+
* Approved-only is enforced at the retrieval boundary (`searchApprovedHints`).
|
|
8
|
+
*/
|
|
9
|
+
import { type Hint, type HintStatus, type QuestionScope, type ScopedHintMatch } from './types.js';
|
|
10
|
+
import { type EmbeddingProvider } from '../embeddings/provider.js';
|
|
11
|
+
export interface SearchApprovedHintsOptions {
|
|
12
|
+
questionScope: QuestionScope;
|
|
13
|
+
limit?: number;
|
|
14
|
+
/** Hybrid-rank knobs (Part B). alpha=0 keeps pure FTS5 (the safe default). */
|
|
15
|
+
alpha?: number;
|
|
16
|
+
embeddingProvider?: EmbeddingProvider;
|
|
17
|
+
}
|
|
18
|
+
export declare class HintStore {
|
|
19
|
+
private db;
|
|
20
|
+
constructor(dbPath: string);
|
|
21
|
+
private initSchema;
|
|
22
|
+
/** Replace the whole index from the Git-authoritative hint set. */
|
|
23
|
+
rebuild(hints: Hint[]): void;
|
|
24
|
+
/** Upsert a single hint (keeps Git + SQLite in sync after a record/approve). */
|
|
25
|
+
upsert(hint: Hint): void;
|
|
26
|
+
private insertRow;
|
|
27
|
+
get(id: string): Hint | null;
|
|
28
|
+
list(status?: HintStatus): Hint[];
|
|
29
|
+
/**
|
|
30
|
+
* Retrieve APPROVED hints that apply to a question's scope. This is the only
|
|
31
|
+
* retrieval entry point used outside review/dev mode — draft/candidate hints
|
|
32
|
+
* are never returned here.
|
|
33
|
+
*/
|
|
34
|
+
searchApprovedHints(options: SearchApprovedHintsOptions): Promise<ScopedHintMatch[]>;
|
|
35
|
+
/** Approved hints whose scopes overlap (surfaced as conflicts for review). */
|
|
36
|
+
conflictingApprovedHints(): Array<[Hint, Hint]>;
|
|
37
|
+
close(): void;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/hints/store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EAEL,KAAK,IAAI,EAET,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,eAAe,EACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,2BAA2B,CAAC;AAUnC,MAAM,WAAW,0BAA0B;IACzC,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,EAAE,CAAoB;gBAElB,MAAM,EAAE,MAAM;IAQ1B,OAAO,CAAC,UAAU;IAuClB,mEAAmE;IACnE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI;IAsB5B,gFAAgF;IAChF,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAmBxB,OAAO,CAAC,SAAS;IAmCjB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAK5B,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI,EAAE;IAOjC;;;;OAIG;IACG,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IA0D1F,8EAA8E;IAC9E,wBAAwB,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAc/C,KAAK,IAAI,IAAI;CAGd"}
|