@duckcodeailabs/dql-agent 1.4.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 +123 -0
- package/dist/answer-loop.d.ts +74 -0
- package/dist/answer-loop.d.ts.map +1 -0
- package/dist/answer-loop.js +170 -0
- package/dist/answer-loop.js.map +1 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +87 -0
- package/dist/index.js.map +1 -0
- package/dist/kg/build.d.ts +17 -0
- package/dist/kg/build.d.ts.map +1 -0
- package/dist/kg/build.js +126 -0
- package/dist/kg/build.js.map +1 -0
- package/dist/kg/sqlite-fts.d.ts +39 -0
- package/dist/kg/sqlite-fts.d.ts.map +1 -0
- package/dist/kg/sqlite-fts.js +257 -0
- package/dist/kg/sqlite-fts.js.map +1 -0
- package/dist/kg/types.d.ts +64 -0
- package/dist/kg/types.d.ts.map +1 -0
- package/dist/kg/types.js +10 -0
- package/dist/kg/types.js.map +1 -0
- package/dist/providers/claude.d.ts +21 -0
- package/dist/providers/claude.d.ts.map +1 -0
- package/dist/providers/claude.js +56 -0
- package/dist/providers/claude.js.map +1 -0
- package/dist/providers/gemini.d.ts +18 -0
- package/dist/providers/gemini.d.ts.map +1 -0
- package/dist/providers/gemini.js +60 -0
- package/dist/providers/gemini.js.map +1 -0
- package/dist/providers/index.d.ts +24 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +43 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/ollama.d.ts +21 -0
- package/dist/providers/ollama.d.ts.map +1 -0
- package/dist/providers/ollama.js +49 -0
- package/dist/providers/ollama.js.map +1 -0
- package/dist/providers/openai.d.ts +19 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +44 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/types.d.ts +39 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +15 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/skills/loader.d.ts +49 -0
- package/dist/skills/loader.d.ts.map +1 -0
- package/dist/skills/loader.js +177 -0
- package/dist/skills/loader.js.map +1 -0
- package/package.json +46 -0
package/dist/kg/build.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build the KG node + edge arrays from a compiled DQL manifest.
|
|
3
|
+
*
|
|
4
|
+
* Inputs:
|
|
5
|
+
* - dql-manifest.json (blocks, dashboards, apps, metrics, dimensions, sources)
|
|
6
|
+
* - dbt manifest (already merged into the DQL manifest's dbtImport.dbtDag)
|
|
7
|
+
* - project Skills folder (loaded separately by the Skills loader)
|
|
8
|
+
*
|
|
9
|
+
* The output is intentionally flat — caller passes it to `KGStore.rebuild()`.
|
|
10
|
+
*/
|
|
11
|
+
export function buildKGFromManifest(manifest) {
|
|
12
|
+
const nodes = [];
|
|
13
|
+
const edges = [];
|
|
14
|
+
// Blocks
|
|
15
|
+
for (const block of Object.values(manifest.blocks)) {
|
|
16
|
+
const nodeId = `block:${block.name}`;
|
|
17
|
+
nodes.push({
|
|
18
|
+
nodeId,
|
|
19
|
+
kind: 'block',
|
|
20
|
+
name: block.name,
|
|
21
|
+
domain: block.domain,
|
|
22
|
+
status: block.status,
|
|
23
|
+
owner: block.owner,
|
|
24
|
+
description: block.description,
|
|
25
|
+
tags: block.tags ?? [],
|
|
26
|
+
llmContext: block.llmContext,
|
|
27
|
+
examples: block.examples,
|
|
28
|
+
sourcePath: block.filePath,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
// Metrics
|
|
32
|
+
for (const m of Object.values(manifest.metrics)) {
|
|
33
|
+
const nodeId = `metric:${m.name}`;
|
|
34
|
+
nodes.push({
|
|
35
|
+
nodeId,
|
|
36
|
+
kind: 'metric',
|
|
37
|
+
name: m.name,
|
|
38
|
+
domain: m.domain,
|
|
39
|
+
description: m.description,
|
|
40
|
+
sourcePath: m.filePath,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
// Dimensions
|
|
44
|
+
for (const d of Object.values(manifest.dimensions)) {
|
|
45
|
+
const nodeId = `dimension:${d.name}`;
|
|
46
|
+
nodes.push({
|
|
47
|
+
nodeId,
|
|
48
|
+
kind: 'dimension',
|
|
49
|
+
name: d.name,
|
|
50
|
+
description: d.description,
|
|
51
|
+
sourcePath: d.filePath,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
// Sources / dbt models
|
|
55
|
+
for (const s of Object.values(manifest.sources)) {
|
|
56
|
+
const isDbt = s.origin === 'dbt';
|
|
57
|
+
const kind = isDbt ? 'dbt_model' : 'dbt_source';
|
|
58
|
+
const nodeId = `${kind}:${s.name}`;
|
|
59
|
+
nodes.push({
|
|
60
|
+
nodeId,
|
|
61
|
+
kind,
|
|
62
|
+
name: s.name,
|
|
63
|
+
description: s.dbtModel?.description,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
// Dashboards
|
|
67
|
+
for (const d of Object.values(manifest.dashboards ?? {})) {
|
|
68
|
+
const nodeId = `dashboard:${d.id}`;
|
|
69
|
+
nodes.push({
|
|
70
|
+
nodeId,
|
|
71
|
+
kind: 'dashboard',
|
|
72
|
+
name: d.title,
|
|
73
|
+
domain: d.domain,
|
|
74
|
+
description: d.description,
|
|
75
|
+
tags: d.tags ?? [],
|
|
76
|
+
sourcePath: d.filePath,
|
|
77
|
+
});
|
|
78
|
+
for (const blockId of d.blockIds) {
|
|
79
|
+
edges.push({ src: `block:${blockId}`, dst: nodeId, kind: 'contains' });
|
|
80
|
+
}
|
|
81
|
+
for (const blockName of d.blockPathRefs) {
|
|
82
|
+
edges.push({ src: `block:${blockName}`, dst: nodeId, kind: 'contains' });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Apps
|
|
86
|
+
for (const a of Object.values(manifest.apps ?? {})) {
|
|
87
|
+
const nodeId = `app:${a.id}`;
|
|
88
|
+
nodes.push({
|
|
89
|
+
nodeId,
|
|
90
|
+
kind: 'app',
|
|
91
|
+
name: a.name,
|
|
92
|
+
domain: a.domain,
|
|
93
|
+
owner: a.owners[0],
|
|
94
|
+
description: a.description,
|
|
95
|
+
tags: a.tags ?? [],
|
|
96
|
+
sourcePath: a.filePath,
|
|
97
|
+
});
|
|
98
|
+
for (const dashboardId of a.dashboards) {
|
|
99
|
+
edges.push({ src: `dashboard:${dashboardId}`, dst: nodeId, kind: 'contains' });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Domains: derive a node per distinct domain seen across blocks/dashboards/apps.
|
|
103
|
+
const domains = new Set();
|
|
104
|
+
for (const block of Object.values(manifest.blocks))
|
|
105
|
+
if (block.domain)
|
|
106
|
+
domains.add(block.domain);
|
|
107
|
+
for (const d of Object.values(manifest.dashboards ?? {}))
|
|
108
|
+
if (d.domain)
|
|
109
|
+
domains.add(d.domain);
|
|
110
|
+
for (const a of Object.values(manifest.apps ?? {}))
|
|
111
|
+
if (a.domain)
|
|
112
|
+
domains.add(a.domain);
|
|
113
|
+
for (const m of Object.values(manifest.metrics))
|
|
114
|
+
if (m.domain)
|
|
115
|
+
domains.add(m.domain);
|
|
116
|
+
for (const d of domains) {
|
|
117
|
+
nodes.push({
|
|
118
|
+
nodeId: `domain:${d}`,
|
|
119
|
+
kind: 'domain',
|
|
120
|
+
name: d,
|
|
121
|
+
domain: d,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return { nodes, edges };
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/kg/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite + FTS5 backing store for the knowledge graph.
|
|
3
|
+
*
|
|
4
|
+
* Schema (created on demand):
|
|
5
|
+
* kg_nodes — structured columns + JSON blobs for tags/examples
|
|
6
|
+
* kg_nodes_fts — virtual FTS5 table over name/description/llm_context/tags
|
|
7
|
+
* kg_edges — adjacency list (src, dst, kind)
|
|
8
|
+
* kg_feedback — feedback events for self-learning ranking
|
|
9
|
+
* kg_meta — last-build timestamp + manifest fingerprint
|
|
10
|
+
*/
|
|
11
|
+
import type { KGNode, KGEdge, KGSearchHit, KGSearchOptions, KGFeedbackRow } from './types.js';
|
|
12
|
+
export declare class KGStore {
|
|
13
|
+
private db;
|
|
14
|
+
constructor(dbPath: string);
|
|
15
|
+
private initSchema;
|
|
16
|
+
/**
|
|
17
|
+
* Wholesale rebuild — clears every node/edge then inserts the supplied
|
|
18
|
+
* arrays inside one transaction. Feedback rows are preserved across
|
|
19
|
+
* rebuilds because they're index inputs.
|
|
20
|
+
*/
|
|
21
|
+
rebuild(nodes: KGNode[], edges: KGEdge[]): void;
|
|
22
|
+
search(options: KGSearchOptions): KGSearchHit[];
|
|
23
|
+
getNode(nodeId: string): KGNode | null;
|
|
24
|
+
getNodesByKind(kind: string, limit?: number): KGNode[];
|
|
25
|
+
recordFeedback(row: KGFeedbackRow): void;
|
|
26
|
+
blockFeedbackScore(blockId: string): {
|
|
27
|
+
up: number;
|
|
28
|
+
down: number;
|
|
29
|
+
};
|
|
30
|
+
/** Surface high-confidence uncertified answers ready for promotion. */
|
|
31
|
+
promotionCandidates(minUps?: number): Array<{
|
|
32
|
+
question: string;
|
|
33
|
+
blockId: string;
|
|
34
|
+
ups: number;
|
|
35
|
+
}>;
|
|
36
|
+
meta(key: string): string | null;
|
|
37
|
+
close(): void;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=sqlite-fts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-fts.d.ts","sourceRoot":"","sources":["../../src/kg/sqlite-fts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EACV,MAAM,EACN,MAAM,EACN,WAAW,EACX,eAAe,EACf,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,qBAAa,OAAO;IAClB,OAAO,CAAC,EAAE,CAAoB;gBAElB,MAAM,EAAE,MAAM;IAQ1B,OAAO,CAAC,UAAU;IA8DlB;;;;OAIG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IA+C/C,MAAM,CAAC,OAAO,EAAE,eAAe,GAAG,WAAW,EAAE;IA2C/C,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAUtC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,MAAM,EAAE;IAYnD,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI;IAUxC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAajE,uEAAuE;IACvE,mBAAmB,CAAC,MAAM,SAAI,GAAG,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAmB1F,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAMhC,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite + FTS5 backing store for the knowledge graph.
|
|
3
|
+
*
|
|
4
|
+
* Schema (created on demand):
|
|
5
|
+
* kg_nodes — structured columns + JSON blobs for tags/examples
|
|
6
|
+
* kg_nodes_fts — virtual FTS5 table over name/description/llm_context/tags
|
|
7
|
+
* kg_edges — adjacency list (src, dst, kind)
|
|
8
|
+
* kg_feedback — feedback events for self-learning ranking
|
|
9
|
+
* kg_meta — last-build timestamp + manifest fingerprint
|
|
10
|
+
*/
|
|
11
|
+
import Database from 'better-sqlite3';
|
|
12
|
+
import { dirname } from 'node:path';
|
|
13
|
+
import { mkdirSync } from 'node:fs';
|
|
14
|
+
export class KGStore {
|
|
15
|
+
db;
|
|
16
|
+
constructor(dbPath) {
|
|
17
|
+
mkdirSync(dirname(dbPath), { recursive: true });
|
|
18
|
+
this.db = new Database(dbPath);
|
|
19
|
+
this.db.pragma('journal_mode = WAL');
|
|
20
|
+
this.db.pragma('foreign_keys = ON');
|
|
21
|
+
this.initSchema();
|
|
22
|
+
}
|
|
23
|
+
initSchema() {
|
|
24
|
+
this.db.exec(`
|
|
25
|
+
CREATE TABLE IF NOT EXISTS kg_nodes (
|
|
26
|
+
node_id TEXT PRIMARY KEY,
|
|
27
|
+
kind TEXT NOT NULL,
|
|
28
|
+
name TEXT NOT NULL,
|
|
29
|
+
domain TEXT,
|
|
30
|
+
status TEXT,
|
|
31
|
+
owner TEXT,
|
|
32
|
+
description TEXT,
|
|
33
|
+
llm_context TEXT,
|
|
34
|
+
tags_json TEXT NOT NULL DEFAULT '[]',
|
|
35
|
+
examples_json TEXT NOT NULL DEFAULT '[]',
|
|
36
|
+
source_path TEXT,
|
|
37
|
+
git_sha TEXT NOT NULL DEFAULT '',
|
|
38
|
+
updated_at TEXT NOT NULL
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
CREATE INDEX IF NOT EXISTS idx_kg_nodes_kind ON kg_nodes(kind);
|
|
42
|
+
CREATE INDEX IF NOT EXISTS idx_kg_nodes_domain ON kg_nodes(domain);
|
|
43
|
+
|
|
44
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS kg_nodes_fts USING fts5(
|
|
45
|
+
node_id UNINDEXED,
|
|
46
|
+
name,
|
|
47
|
+
description,
|
|
48
|
+
llm_context,
|
|
49
|
+
tags,
|
|
50
|
+
kind,
|
|
51
|
+
domain,
|
|
52
|
+
tokenize = 'porter unicode61'
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
CREATE TABLE IF NOT EXISTS kg_edges (
|
|
56
|
+
src TEXT NOT NULL,
|
|
57
|
+
dst TEXT NOT NULL,
|
|
58
|
+
kind TEXT NOT NULL,
|
|
59
|
+
weight REAL NOT NULL DEFAULT 1.0,
|
|
60
|
+
PRIMARY KEY (src, dst, kind)
|
|
61
|
+
);
|
|
62
|
+
CREATE INDEX IF NOT EXISTS idx_kg_edges_src ON kg_edges(src);
|
|
63
|
+
CREATE INDEX IF NOT EXISTS idx_kg_edges_dst ON kg_edges(dst);
|
|
64
|
+
|
|
65
|
+
CREATE TABLE IF NOT EXISTS kg_feedback (
|
|
66
|
+
id TEXT PRIMARY KEY,
|
|
67
|
+
ts TEXT NOT NULL,
|
|
68
|
+
user TEXT NOT NULL,
|
|
69
|
+
question TEXT NOT NULL,
|
|
70
|
+
answer_kind TEXT NOT NULL,
|
|
71
|
+
block_id TEXT,
|
|
72
|
+
rating TEXT NOT NULL CHECK (rating IN ('up', 'down')),
|
|
73
|
+
comment TEXT
|
|
74
|
+
);
|
|
75
|
+
CREATE INDEX IF NOT EXISTS idx_kg_feedback_user ON kg_feedback(user);
|
|
76
|
+
CREATE INDEX IF NOT EXISTS idx_kg_feedback_block ON kg_feedback(block_id);
|
|
77
|
+
|
|
78
|
+
CREATE TABLE IF NOT EXISTS kg_meta (
|
|
79
|
+
key TEXT PRIMARY KEY,
|
|
80
|
+
value TEXT NOT NULL
|
|
81
|
+
);
|
|
82
|
+
`);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Wholesale rebuild — clears every node/edge then inserts the supplied
|
|
86
|
+
* arrays inside one transaction. Feedback rows are preserved across
|
|
87
|
+
* rebuilds because they're index inputs.
|
|
88
|
+
*/
|
|
89
|
+
rebuild(nodes, edges) {
|
|
90
|
+
const insertNode = this.db.prepare(`
|
|
91
|
+
INSERT INTO kg_nodes (
|
|
92
|
+
node_id, kind, name, domain, status, owner, description, llm_context,
|
|
93
|
+
tags_json, examples_json, source_path, git_sha, updated_at
|
|
94
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
95
|
+
`);
|
|
96
|
+
const insertFts = this.db.prepare(`
|
|
97
|
+
INSERT INTO kg_nodes_fts (node_id, name, description, llm_context, tags, kind, domain)
|
|
98
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
99
|
+
`);
|
|
100
|
+
const insertEdge = this.db.prepare(`
|
|
101
|
+
INSERT OR IGNORE INTO kg_edges (src, dst, kind, weight) VALUES (?, ?, ?, ?)
|
|
102
|
+
`);
|
|
103
|
+
const now = new Date().toISOString();
|
|
104
|
+
const txn = this.db.transaction(() => {
|
|
105
|
+
this.db.prepare('DELETE FROM kg_edges').run();
|
|
106
|
+
this.db.prepare('DELETE FROM kg_nodes_fts').run();
|
|
107
|
+
this.db.prepare('DELETE FROM kg_nodes').run();
|
|
108
|
+
for (const n of nodes) {
|
|
109
|
+
insertNode.run(n.nodeId, n.kind, n.name, n.domain ?? null, n.status ?? null, n.owner ?? null, n.description ?? null, n.llmContext ?? null, JSON.stringify(n.tags ?? []), JSON.stringify(n.examples ?? []), n.sourcePath ?? null, n.gitSha ?? '', now);
|
|
110
|
+
insertFts.run(n.nodeId, n.name, n.description ?? '', n.llmContext ?? '', (n.tags ?? []).join(' '), n.kind, n.domain ?? '');
|
|
111
|
+
}
|
|
112
|
+
for (const e of edges) {
|
|
113
|
+
insertEdge.run(e.src, e.dst, e.kind, e.weight ?? 1.0);
|
|
114
|
+
}
|
|
115
|
+
this.db.prepare(`INSERT OR REPLACE INTO kg_meta (key, value) VALUES ('built_at', ?)`).run(now);
|
|
116
|
+
});
|
|
117
|
+
txn();
|
|
118
|
+
}
|
|
119
|
+
search(options) {
|
|
120
|
+
const { query, kinds, domain, limit = 20 } = options;
|
|
121
|
+
if (!query.trim())
|
|
122
|
+
return [];
|
|
123
|
+
const sanitized = sanitizeFtsQuery(query);
|
|
124
|
+
if (!sanitized)
|
|
125
|
+
return [];
|
|
126
|
+
const filters = [];
|
|
127
|
+
const params = [sanitized];
|
|
128
|
+
if (kinds && kinds.length > 0) {
|
|
129
|
+
filters.push(`f.kind IN (${kinds.map(() => '?').join(', ')})`);
|
|
130
|
+
params.push(...kinds);
|
|
131
|
+
}
|
|
132
|
+
if (domain) {
|
|
133
|
+
filters.push(`f.domain = ?`);
|
|
134
|
+
params.push(domain);
|
|
135
|
+
}
|
|
136
|
+
const whereExtra = filters.length > 0 ? ` AND ${filters.join(' AND ')}` : '';
|
|
137
|
+
const rows = this.db.prepare(`
|
|
138
|
+
SELECT n.*,
|
|
139
|
+
bm25(kg_nodes_fts) AS rank,
|
|
140
|
+
snippet(kg_nodes_fts, -1, '<mark>', '</mark>', '…', 12) AS snip
|
|
141
|
+
FROM kg_nodes_fts AS f
|
|
142
|
+
JOIN kg_nodes AS n ON n.node_id = f.node_id
|
|
143
|
+
WHERE kg_nodes_fts MATCH ?${whereExtra}
|
|
144
|
+
ORDER BY rank
|
|
145
|
+
LIMIT ?
|
|
146
|
+
`).all(...params, limit);
|
|
147
|
+
return rows.map((r) => ({
|
|
148
|
+
node: rowToNode(r),
|
|
149
|
+
score: r.rank ? 1 / (1 + Math.max(0, r.rank)) : 0,
|
|
150
|
+
snippet: r.snip ?? undefined,
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
153
|
+
getNode(nodeId) {
|
|
154
|
+
const row = this.db.prepare('SELECT * FROM kg_nodes WHERE node_id = ?').get(nodeId);
|
|
155
|
+
return row ? rowToNode(row) : null;
|
|
156
|
+
}
|
|
157
|
+
getNodesByKind(kind, limit = 100) {
|
|
158
|
+
const rows = this.db.prepare('SELECT * FROM kg_nodes WHERE kind = ? ORDER BY name LIMIT ?').all(kind, limit);
|
|
159
|
+
return rows.map((r) => rowToNode(r));
|
|
160
|
+
}
|
|
161
|
+
recordFeedback(row) {
|
|
162
|
+
this.db.prepare(`
|
|
163
|
+
INSERT INTO kg_feedback (id, ts, user, question, answer_kind, block_id, rating, comment)
|
|
164
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
165
|
+
`).run(row.id, row.ts, row.user, row.question, row.answerKind, row.blockId ?? null, row.rating, row.comment ?? null);
|
|
166
|
+
}
|
|
167
|
+
blockFeedbackScore(blockId) {
|
|
168
|
+
const row = this.db.prepare(`
|
|
169
|
+
SELECT
|
|
170
|
+
SUM(CASE WHEN rating = 'up' THEN 1 ELSE 0 END) AS up,
|
|
171
|
+
SUM(CASE WHEN rating = 'down' THEN 1 ELSE 0 END) AS down
|
|
172
|
+
FROM kg_feedback WHERE block_id = ?
|
|
173
|
+
`).get(blockId);
|
|
174
|
+
return {
|
|
175
|
+
up: row?.up ?? 0,
|
|
176
|
+
down: row?.down ?? 0,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
/** Surface high-confidence uncertified answers ready for promotion. */
|
|
180
|
+
promotionCandidates(minUps = 5) {
|
|
181
|
+
const rows = this.db.prepare(`
|
|
182
|
+
SELECT block_id, question, COUNT(*) AS ups
|
|
183
|
+
FROM kg_feedback
|
|
184
|
+
WHERE answer_kind = 'uncertified' AND rating = 'up' AND block_id IS NOT NULL
|
|
185
|
+
GROUP BY block_id, question
|
|
186
|
+
HAVING ups >= ?
|
|
187
|
+
AND NOT EXISTS (
|
|
188
|
+
SELECT 1 FROM kg_feedback f2
|
|
189
|
+
WHERE f2.block_id = kg_feedback.block_id
|
|
190
|
+
AND f2.answer_kind = 'uncertified'
|
|
191
|
+
AND f2.rating = 'down'
|
|
192
|
+
)
|
|
193
|
+
ORDER BY ups DESC
|
|
194
|
+
LIMIT 50
|
|
195
|
+
`).all(minUps);
|
|
196
|
+
return rows.map((r) => ({ blockId: r.block_id, question: r.question, ups: r.ups }));
|
|
197
|
+
}
|
|
198
|
+
meta(key) {
|
|
199
|
+
const row = this.db.prepare('SELECT value FROM kg_meta WHERE key = ?').get(key);
|
|
200
|
+
return row?.value ?? null;
|
|
201
|
+
}
|
|
202
|
+
close() {
|
|
203
|
+
this.db.close();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function rowToNode(row) {
|
|
207
|
+
return {
|
|
208
|
+
nodeId: row.node_id,
|
|
209
|
+
kind: row.kind,
|
|
210
|
+
name: row.name,
|
|
211
|
+
domain: row.domain ?? undefined,
|
|
212
|
+
status: row.status ?? undefined,
|
|
213
|
+
owner: row.owner ?? undefined,
|
|
214
|
+
description: row.description ?? undefined,
|
|
215
|
+
llmContext: row.llm_context ?? undefined,
|
|
216
|
+
tags: safeJSON(row.tags_json, []),
|
|
217
|
+
examples: safeJSON(row.examples_json, []),
|
|
218
|
+
sourcePath: row.source_path ?? undefined,
|
|
219
|
+
gitSha: row.git_sha ?? undefined,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
function safeJSON(raw, fallback) {
|
|
223
|
+
if (!raw)
|
|
224
|
+
return fallback;
|
|
225
|
+
try {
|
|
226
|
+
return JSON.parse(raw);
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
return fallback;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Defang FTS5 query syntax we don't trust from arbitrary user input.
|
|
234
|
+
* Allows AND/OR/NOT/quotes/parens and column-prefix syntax (`name:foo`).
|
|
235
|
+
* Strips anything else to whitespace, then collapses.
|
|
236
|
+
*/
|
|
237
|
+
function sanitizeFtsQuery(raw) {
|
|
238
|
+
// Drop characters FTS5 might interpret as operators we don't want exposed,
|
|
239
|
+
// except for quotes (allows phrase search) and a couple of column scopers.
|
|
240
|
+
const cleaned = raw
|
|
241
|
+
.replace(/[*]/g, ' ') // strip wildcard injection
|
|
242
|
+
.replace(/\s+/g, ' ')
|
|
243
|
+
.trim();
|
|
244
|
+
if (!cleaned)
|
|
245
|
+
return '';
|
|
246
|
+
// If no quotes and no boolean keyword, fall back to a tokenized OR query
|
|
247
|
+
// for better recall — FTS5 default is implicit AND.
|
|
248
|
+
if (!/["()]|\b(AND|OR|NOT|NEAR)\b/.test(cleaned)) {
|
|
249
|
+
return cleaned
|
|
250
|
+
.split(/\s+/)
|
|
251
|
+
.map((t) => t.replace(/[^\w]/g, ''))
|
|
252
|
+
.filter(Boolean)
|
|
253
|
+
.join(' OR ');
|
|
254
|
+
}
|
|
255
|
+
return cleaned;
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=sqlite-fts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-fts.js","sourceRoot":"","sources":["../../src/kg/sqlite-fts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge graph node + edge shapes for the DQL agent.
|
|
3
|
+
*
|
|
4
|
+
* The KG is built from the compiled `dql-manifest.json` (blocks, dashboards,
|
|
5
|
+
* apps, metrics, dimensions, sources) plus dbt manifest data and the project's
|
|
6
|
+
* Skills folder. It is stored in SQLite at `.dql/cache/agent-kg.sqlite` with
|
|
7
|
+
* an FTS5 index for keyword search and structured filters for domain/kind.
|
|
8
|
+
*/
|
|
9
|
+
export type KGNodeKind = 'block' | 'metric' | 'dimension' | 'domain' | 'dbt_model' | 'dbt_source' | 'dashboard' | 'app' | 'skill';
|
|
10
|
+
export interface KGNode {
|
|
11
|
+
/** Stable identifier — `${kind}:${name}` (lower-cased). */
|
|
12
|
+
nodeId: string;
|
|
13
|
+
kind: KGNodeKind;
|
|
14
|
+
name: string;
|
|
15
|
+
domain?: string;
|
|
16
|
+
status?: string;
|
|
17
|
+
owner?: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
tags?: string[];
|
|
20
|
+
/** Free-form natural-language context for the LLM (block.llmContext, skill body, etc.). */
|
|
21
|
+
llmContext?: string;
|
|
22
|
+
/** Question/SQL pairs the agent can few-shot on. */
|
|
23
|
+
examples?: Array<{
|
|
24
|
+
question: string;
|
|
25
|
+
sql?: string;
|
|
26
|
+
}>;
|
|
27
|
+
/** Path on disk so the UI can deep-link. */
|
|
28
|
+
sourcePath?: string;
|
|
29
|
+
/** Pinned git SHA at index time. */
|
|
30
|
+
gitSha?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface KGEdge {
|
|
33
|
+
src: string;
|
|
34
|
+
dst: string;
|
|
35
|
+
kind: 'feeds_into' | 'reads_from' | 'aggregates' | 'visualizes' | 'depends_on' | 'contains' | 'related_to';
|
|
36
|
+
weight?: number;
|
|
37
|
+
}
|
|
38
|
+
export interface KGSearchHit {
|
|
39
|
+
node: KGNode;
|
|
40
|
+
/** BM25-derived score (lower is better in raw FTS5; we expose 1/(1+rank) so higher is better). */
|
|
41
|
+
score: number;
|
|
42
|
+
/** Match snippets per field, useful for UI surfacing. */
|
|
43
|
+
snippet?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface KGFeedbackRow {
|
|
46
|
+
id: string;
|
|
47
|
+
ts: string;
|
|
48
|
+
user: string;
|
|
49
|
+
question: string;
|
|
50
|
+
answerKind: 'certified' | 'uncertified';
|
|
51
|
+
blockId?: string;
|
|
52
|
+
rating: 'up' | 'down';
|
|
53
|
+
comment?: string;
|
|
54
|
+
}
|
|
55
|
+
export interface KGSearchOptions {
|
|
56
|
+
query: string;
|
|
57
|
+
/** Restrict to specific kinds. Defaults to all. */
|
|
58
|
+
kinds?: KGNodeKind[];
|
|
59
|
+
/** Restrict to a domain. */
|
|
60
|
+
domain?: string;
|
|
61
|
+
/** Maximum hits to return. */
|
|
62
|
+
limit?: number;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/kg/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,UAAU,GAClB,OAAO,GACP,QAAQ,GACR,WAAW,GACX,QAAQ,GACR,WAAW,GACX,YAAY,GACZ,WAAW,GACX,KAAK,GACL,OAAO,CAAC;AAEZ,MAAM,WAAW,MAAM;IACrB,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,2FAA2F;IAC3F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,UAAU,GAAG,YAAY,CAAC;IAC3G,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,kGAAkG;IAClG,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,WAAW,GAAG,aAAa,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,IAAI,GAAG,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
package/dist/kg/types.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge graph node + edge shapes for the DQL agent.
|
|
3
|
+
*
|
|
4
|
+
* The KG is built from the compiled `dql-manifest.json` (blocks, dashboards,
|
|
5
|
+
* apps, metrics, dimensions, sources) plus dbt manifest data and the project's
|
|
6
|
+
* Skills folder. It is stored in SQLite at `.dql/cache/agent-kg.sqlite` with
|
|
7
|
+
* an FTS5 index for keyword search and structured filters for domain/kind.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/kg/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AgentProvider, AgentMessage, ProviderRunOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Anthropic Claude provider via the Messages API. Reads ANTHROPIC_API_KEY.
|
|
4
|
+
*
|
|
5
|
+
* We deliberately avoid `@anthropic-ai/sdk` to keep dql-agent zero-dep —
|
|
6
|
+
* the existing `apps/cli/src/llm/providers/claude-agent-sdk.ts` already
|
|
7
|
+
* uses the SDK for the chat-cell agent loop, and that's a different layer.
|
|
8
|
+
* Here we want a simple "generate from a message list" surface.
|
|
9
|
+
*/
|
|
10
|
+
export declare class ClaudeProvider implements AgentProvider {
|
|
11
|
+
readonly name: "claude";
|
|
12
|
+
private readonly apiKey?;
|
|
13
|
+
private readonly defaultModel;
|
|
14
|
+
constructor(opts?: {
|
|
15
|
+
apiKey?: string;
|
|
16
|
+
model?: string;
|
|
17
|
+
});
|
|
18
|
+
available(): Promise<boolean>;
|
|
19
|
+
generate(messages: AgentMessage[], options?: ProviderRunOptions): Promise<string>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/providers/claude.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB;;;;;;;GAOG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,IAAI,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO;IAKpD,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAI7B,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC;CAoC5F"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic Claude provider via the Messages API. Reads ANTHROPIC_API_KEY.
|
|
3
|
+
*
|
|
4
|
+
* We deliberately avoid `@anthropic-ai/sdk` to keep dql-agent zero-dep —
|
|
5
|
+
* the existing `apps/cli/src/llm/providers/claude-agent-sdk.ts` already
|
|
6
|
+
* uses the SDK for the chat-cell agent loop, and that's a different layer.
|
|
7
|
+
* Here we want a simple "generate from a message list" surface.
|
|
8
|
+
*/
|
|
9
|
+
export class ClaudeProvider {
|
|
10
|
+
name = 'claude';
|
|
11
|
+
apiKey;
|
|
12
|
+
defaultModel;
|
|
13
|
+
constructor(opts = {}) {
|
|
14
|
+
this.apiKey = opts.apiKey ?? process.env.ANTHROPIC_API_KEY;
|
|
15
|
+
this.defaultModel = opts.model ?? 'claude-opus-4-7';
|
|
16
|
+
}
|
|
17
|
+
async available() {
|
|
18
|
+
return Boolean(this.apiKey);
|
|
19
|
+
}
|
|
20
|
+
async generate(messages, options = {}) {
|
|
21
|
+
if (!this.apiKey) {
|
|
22
|
+
throw new Error('claude: ANTHROPIC_API_KEY is not set');
|
|
23
|
+
}
|
|
24
|
+
const system = messages.filter((m) => m.role === 'system').map((m) => m.content).join('\n\n');
|
|
25
|
+
const turns = messages
|
|
26
|
+
.filter((m) => m.role !== 'system')
|
|
27
|
+
.map((m) => ({ role: m.role, content: m.content }));
|
|
28
|
+
const res = await fetch('https://api.anthropic.com/v1/messages', {
|
|
29
|
+
method: 'POST',
|
|
30
|
+
headers: {
|
|
31
|
+
'x-api-key': this.apiKey,
|
|
32
|
+
'anthropic-version': '2023-06-01',
|
|
33
|
+
'content-type': 'application/json',
|
|
34
|
+
},
|
|
35
|
+
body: JSON.stringify({
|
|
36
|
+
model: options.model ?? this.defaultModel,
|
|
37
|
+
max_tokens: options.maxTokens ?? 1024,
|
|
38
|
+
temperature: options.temperature ?? 0.2,
|
|
39
|
+
system: system || undefined,
|
|
40
|
+
messages: turns,
|
|
41
|
+
}),
|
|
42
|
+
signal: options.signal,
|
|
43
|
+
});
|
|
44
|
+
if (!res.ok) {
|
|
45
|
+
const body = await res.text().catch(() => res.statusText);
|
|
46
|
+
throw new Error(`claude: ${res.status} ${body}`);
|
|
47
|
+
}
|
|
48
|
+
const json = (await res.json());
|
|
49
|
+
const blocks = json.content ?? [];
|
|
50
|
+
return blocks
|
|
51
|
+
.filter((b) => b.type === 'text')
|
|
52
|
+
.map((b) => b.text ?? '')
|
|
53
|
+
.join('');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/providers/claude.ts"],"names":[],"mappings":"AAMA;;;;;;;GAOG;AACH,MAAM,OAAO,cAAc;IAChB,IAAI,GAAG,QAAiB,CAAC;IACjB,MAAM,CAAU;IAChB,YAAY,CAAS;IAEtC,YAAY,OAA4C,EAAE;QACxD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAC3D,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,IAAI,iBAAiB,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,SAAS;QACb,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,QAAwB,EAAE,UAA8B,EAAE;QACvE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9F,MAAM,KAAK,GAAG,QAAQ;aACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;aAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAEtD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,uCAAuC,EAAE;YAC/D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,WAAW,EAAE,IAAI,CAAC,MAAM;gBACxB,mBAAmB,EAAE,YAAY;gBACjC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,YAAY;gBACzC,UAAU,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI;gBACrC,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,GAAG;gBACvC,MAAM,EAAE,MAAM,IAAI,SAAS;gBAC3B,QAAQ,EAAE,KAAK;aAChB,CAAC;YACF,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC1D,MAAM,IAAI,KAAK,CAAC,WAAW,GAAG,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAyD,CAAC;QACxF,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;QAClC,OAAO,MAAM;aACV,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;aAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;aACxB,IAAI,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AgentProvider, AgentMessage, ProviderRunOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Google Gemini provider via the v1beta REST surface. Reads GEMINI_API_KEY.
|
|
4
|
+
* Maps system messages by prepending them to the first user turn since
|
|
5
|
+
* Gemini's API doesn't have a first-class system role.
|
|
6
|
+
*/
|
|
7
|
+
export declare class GeminiProvider implements AgentProvider {
|
|
8
|
+
readonly name: "gemini";
|
|
9
|
+
private readonly apiKey?;
|
|
10
|
+
private readonly defaultModel;
|
|
11
|
+
constructor(opts?: {
|
|
12
|
+
apiKey?: string;
|
|
13
|
+
model?: string;
|
|
14
|
+
});
|
|
15
|
+
available(): Promise<boolean>;
|
|
16
|
+
generate(messages: AgentMessage[], options?: ProviderRunOptions): Promise<string>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=gemini.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/providers/gemini.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,IAAI,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO;IAKpD,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAI7B,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC;CA4C5F"}
|