@deepagents/text2sql 0.2.2 → 0.3.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/dist/index.d.ts +7 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +929 -2746
- package/dist/index.js.map +4 -4
- package/dist/lib/adapters/adapter.d.ts +67 -10
- package/dist/lib/adapters/adapter.d.ts.map +1 -1
- package/dist/lib/adapters/grounding.ticket.d.ts +21 -0
- package/dist/lib/adapters/grounding.ticket.d.ts.map +1 -0
- package/dist/lib/adapters/groundings/column-stats.grounding.d.ts +32 -0
- package/dist/lib/adapters/groundings/column-stats.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/groundings/constraint.grounding.d.ts +31 -0
- package/dist/lib/adapters/groundings/constraint.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/groundings/context.d.ts +41 -0
- package/dist/lib/adapters/groundings/context.d.ts.map +1 -0
- package/dist/lib/adapters/groundings/grounding.d.ts +8 -0
- package/dist/lib/adapters/groundings/grounding.d.ts.map +1 -0
- package/dist/lib/adapters/groundings/grounding.js +507 -0
- package/dist/lib/adapters/groundings/grounding.js.map +7 -0
- package/dist/lib/adapters/groundings/indexes.grounding.d.ts +30 -0
- package/dist/lib/adapters/groundings/indexes.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/groundings/info.grounding.d.ts +29 -0
- package/dist/lib/adapters/groundings/info.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/groundings/low-cardinality.grounding.d.ts +35 -0
- package/dist/lib/adapters/groundings/low-cardinality.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/groundings/report.grounding.d.ts +38 -0
- package/dist/lib/adapters/groundings/report.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/groundings/row-count.grounding.d.ts +30 -0
- package/dist/lib/adapters/groundings/row-count.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/groundings/table.grounding.d.ts +61 -0
- package/dist/lib/adapters/groundings/table.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/groundings/view.grounding.d.ts +57 -0
- package/dist/lib/adapters/groundings/view.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/postgres/column-stats.postgres.grounding.d.ts +12 -0
- package/dist/lib/adapters/postgres/column-stats.postgres.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/postgres/constraint.postgres.grounding.d.ts +11 -0
- package/dist/lib/adapters/postgres/constraint.postgres.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/postgres/index.d.ts +43 -0
- package/dist/lib/adapters/postgres/index.d.ts.map +1 -0
- package/dist/lib/adapters/postgres/index.js +1640 -0
- package/dist/lib/adapters/postgres/index.js.map +7 -0
- package/dist/lib/adapters/postgres/indexes.postgres.grounding.d.ts +15 -0
- package/dist/lib/adapters/postgres/indexes.postgres.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/postgres/info.postgres.grounding.d.ts +11 -0
- package/dist/lib/adapters/postgres/info.postgres.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/postgres/low-cardinality.postgres.grounding.d.ts +14 -0
- package/dist/lib/adapters/postgres/low-cardinality.postgres.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/postgres/postgres.d.ts +26 -0
- package/dist/lib/adapters/postgres/postgres.d.ts.map +1 -0
- package/dist/lib/adapters/postgres/row-count.postgres.grounding.d.ts +11 -0
- package/dist/lib/adapters/postgres/row-count.postgres.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/postgres/table.postgres.grounding.d.ts +21 -0
- package/dist/lib/adapters/postgres/table.postgres.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/postgres/view.postgres.grounding.d.ts +16 -0
- package/dist/lib/adapters/postgres/view.postgres.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/sqlite/column-stats.sqlite.grounding.d.ts +12 -0
- package/dist/lib/adapters/sqlite/column-stats.sqlite.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/sqlite/constraint.sqlite.grounding.d.ts +15 -0
- package/dist/lib/adapters/sqlite/constraint.sqlite.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/sqlite/index.d.ts +43 -0
- package/dist/lib/adapters/sqlite/index.d.ts.map +1 -0
- package/dist/lib/adapters/sqlite/index.js +1215 -0
- package/dist/lib/adapters/sqlite/index.js.map +7 -0
- package/dist/lib/adapters/sqlite/indexes.sqlite.grounding.d.ts +11 -0
- package/dist/lib/adapters/sqlite/indexes.sqlite.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/sqlite/info.sqlite.grounding.d.ts +11 -0
- package/dist/lib/adapters/sqlite/info.sqlite.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/sqlite/low-cardinality.sqlite.grounding.d.ts +14 -0
- package/dist/lib/adapters/sqlite/low-cardinality.sqlite.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/sqlite/row-count.sqlite.grounding.d.ts +11 -0
- package/dist/lib/adapters/sqlite/row-count.sqlite.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/sqlite/sqlite.d.ts +25 -0
- package/dist/lib/adapters/sqlite/sqlite.d.ts.map +1 -0
- package/dist/lib/adapters/sqlite/table.sqlite.grounding.d.ts +17 -0
- package/dist/lib/adapters/sqlite/table.sqlite.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/sqlite/view.sqlite.grounding.d.ts +12 -0
- package/dist/lib/adapters/sqlite/view.sqlite.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/sqlserver/column-stats.sqlserver.grounding.d.ts +12 -0
- package/dist/lib/adapters/sqlserver/column-stats.sqlserver.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/sqlserver/constraint.sqlserver.grounding.d.ts +11 -0
- package/dist/lib/adapters/sqlserver/constraint.sqlserver.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/sqlserver/index.d.ts +43 -0
- package/dist/lib/adapters/sqlserver/index.d.ts.map +1 -0
- package/dist/lib/adapters/sqlserver/index.js +1693 -0
- package/dist/lib/adapters/sqlserver/index.js.map +7 -0
- package/dist/lib/adapters/sqlserver/indexes.sqlserver.grounding.d.ts +15 -0
- package/dist/lib/adapters/sqlserver/indexes.sqlserver.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/sqlserver/info.sqlserver.grounding.d.ts +11 -0
- package/dist/lib/adapters/sqlserver/info.sqlserver.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/sqlserver/low-cardinality.sqlserver.grounding.d.ts +14 -0
- package/dist/lib/adapters/sqlserver/low-cardinality.sqlserver.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/sqlserver/row-count.sqlserver.grounding.d.ts +11 -0
- package/dist/lib/adapters/sqlserver/row-count.sqlserver.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/sqlserver/sqlserver.d.ts +26 -0
- package/dist/lib/adapters/sqlserver/sqlserver.d.ts.map +1 -0
- package/dist/lib/adapters/sqlserver/table.sqlserver.grounding.d.ts +21 -0
- package/dist/lib/adapters/sqlserver/table.sqlserver.grounding.d.ts.map +1 -0
- package/dist/lib/adapters/sqlserver/view.sqlserver.grounding.d.ts +16 -0
- package/dist/lib/adapters/sqlserver/view.sqlserver.grounding.d.ts.map +1 -0
- package/dist/lib/agents/suggestions.agents.d.ts +0 -2
- package/dist/lib/agents/suggestions.agents.d.ts.map +1 -1
- package/dist/lib/agents/teachables.agent.d.ts +0 -3
- package/dist/lib/agents/teachables.agent.d.ts.map +1 -1
- package/dist/lib/agents/text2sql.agent.d.ts +69 -29
- package/dist/lib/agents/text2sql.agent.d.ts.map +1 -1
- package/dist/lib/file-cache.d.ts +12 -0
- package/dist/lib/file-cache.d.ts.map +1 -0
- package/dist/lib/instructions.d.ts +3 -0
- package/dist/lib/instructions.d.ts.map +1 -0
- package/dist/lib/instructions.js +386 -0
- package/dist/lib/instructions.js.map +7 -0
- package/dist/lib/memory/memory.prompt.d.ts +3 -0
- package/dist/lib/memory/memory.prompt.d.ts.map +1 -0
- package/dist/lib/memory/memory.store.d.ts +5 -0
- package/dist/lib/memory/memory.store.d.ts.map +1 -0
- package/dist/lib/memory/sqlite.store.d.ts +14 -0
- package/dist/lib/memory/sqlite.store.d.ts.map +1 -0
- package/dist/lib/memory/store.d.ts +40 -0
- package/dist/lib/memory/store.d.ts.map +1 -0
- package/dist/lib/prompt.d.ts +1 -6
- package/dist/lib/prompt.d.ts.map +1 -1
- package/dist/lib/sql.d.ts +27 -34
- package/dist/lib/sql.d.ts.map +1 -1
- package/dist/lib/teach/teachables.d.ts +184 -13
- package/dist/lib/teach/teachables.d.ts.map +1 -1
- package/dist/lib/teach/teachings.d.ts.map +1 -1
- package/dist/lib/teach/xml.d.ts.map +1 -1
- package/package.json +38 -4
- package/dist/lib/adapters/postgres.d.ts +0 -31
- package/dist/lib/adapters/postgres.d.ts.map +0 -1
- package/dist/lib/adapters/resolveTables.spec.d.ts +0 -2
- package/dist/lib/adapters/resolveTables.spec.d.ts.map +0 -1
- package/dist/lib/adapters/sqlite.d.ts +0 -30
- package/dist/lib/adapters/sqlite.d.ts.map +0 -1
- package/dist/lib/adapters/sqlserver.d.ts +0 -31
- package/dist/lib/adapters/sqlserver.d.ts.map +0 -1
- package/dist/lib/agents/brief.agent.d.ts +0 -16
- package/dist/lib/agents/brief.agent.d.ts.map +0 -1
- package/dist/lib/memory/user-profile.d.ts +0 -39
- package/dist/lib/memory/user-profile.d.ts.map +0 -1
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
// packages/text2sql/src/lib/adapters/groundings/context.ts
|
|
2
|
+
function createGroundingContext() {
|
|
3
|
+
return {
|
|
4
|
+
tables: [],
|
|
5
|
+
views: [],
|
|
6
|
+
relationships: [],
|
|
7
|
+
info: void 0
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// packages/text2sql/src/lib/adapters/groundings/table.grounding.ts
|
|
12
|
+
import pluralize from "pluralize";
|
|
13
|
+
|
|
14
|
+
// packages/text2sql/src/lib/adapters/grounding.ticket.ts
|
|
15
|
+
var AbstractGrounding = class {
|
|
16
|
+
tag;
|
|
17
|
+
constructor(tag) {
|
|
18
|
+
this.tag = tag;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// packages/text2sql/src/lib/adapters/groundings/table.grounding.ts
|
|
23
|
+
var TableGrounding = class extends AbstractGrounding {
|
|
24
|
+
#filter;
|
|
25
|
+
#forward;
|
|
26
|
+
#backward;
|
|
27
|
+
constructor(config = {}) {
|
|
28
|
+
super("tables");
|
|
29
|
+
this.#filter = config.filter;
|
|
30
|
+
this.#forward = config.forward;
|
|
31
|
+
this.#backward = config.backward;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Execute the grounding process.
|
|
35
|
+
* Writes discovered tables and relationships to the context.
|
|
36
|
+
*/
|
|
37
|
+
async execute(ctx) {
|
|
38
|
+
const seedTables = await this.applyFilter();
|
|
39
|
+
const forward = this.#forward;
|
|
40
|
+
const backward = this.#backward;
|
|
41
|
+
if (!forward && !backward) {
|
|
42
|
+
const tables2 = await Promise.all(
|
|
43
|
+
seedTables.map((name) => this.getTable(name))
|
|
44
|
+
);
|
|
45
|
+
ctx.tables.push(...tables2);
|
|
46
|
+
return () => this.#describeTables(tables2);
|
|
47
|
+
}
|
|
48
|
+
const tables = {};
|
|
49
|
+
const allRelationships = [];
|
|
50
|
+
const seenRelationships = /* @__PURE__ */ new Set();
|
|
51
|
+
const forwardQueue = [];
|
|
52
|
+
const backwardQueue = [];
|
|
53
|
+
const forwardVisited = /* @__PURE__ */ new Set();
|
|
54
|
+
const backwardVisited = /* @__PURE__ */ new Set();
|
|
55
|
+
for (const name of seedTables) {
|
|
56
|
+
if (forward) forwardQueue.push({ name, depth: 0 });
|
|
57
|
+
if (backward) backwardQueue.push({ name, depth: 0 });
|
|
58
|
+
}
|
|
59
|
+
const forwardLimit = forward === true ? Infinity : forward || 0;
|
|
60
|
+
while (forwardQueue.length > 0) {
|
|
61
|
+
const item = forwardQueue.shift();
|
|
62
|
+
if (!item) break;
|
|
63
|
+
const { name, depth } = item;
|
|
64
|
+
if (forwardVisited.has(name)) continue;
|
|
65
|
+
forwardVisited.add(name);
|
|
66
|
+
if (!tables[name]) {
|
|
67
|
+
tables[name] = await this.getTable(name);
|
|
68
|
+
}
|
|
69
|
+
if (depth < forwardLimit) {
|
|
70
|
+
const rels = await this.findOutgoingRelations(name);
|
|
71
|
+
for (const rel of rels) {
|
|
72
|
+
this.addRelationship(rel, allRelationships, seenRelationships);
|
|
73
|
+
if (!forwardVisited.has(rel.referenced_table)) {
|
|
74
|
+
forwardQueue.push({ name: rel.referenced_table, depth: depth + 1 });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const backwardLimit = backward === true ? Infinity : backward || 0;
|
|
80
|
+
while (backwardQueue.length > 0) {
|
|
81
|
+
const item = backwardQueue.shift();
|
|
82
|
+
if (!item) break;
|
|
83
|
+
const { name, depth } = item;
|
|
84
|
+
if (backwardVisited.has(name)) continue;
|
|
85
|
+
backwardVisited.add(name);
|
|
86
|
+
if (!tables[name]) {
|
|
87
|
+
tables[name] = await this.getTable(name);
|
|
88
|
+
}
|
|
89
|
+
if (depth < backwardLimit) {
|
|
90
|
+
const rels = await this.findIncomingRelations(name);
|
|
91
|
+
for (const rel of rels) {
|
|
92
|
+
this.addRelationship(rel, allRelationships, seenRelationships);
|
|
93
|
+
if (!backwardVisited.has(rel.table)) {
|
|
94
|
+
backwardQueue.push({ name: rel.table, depth: depth + 1 });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const tablesList = Object.values(tables);
|
|
100
|
+
ctx.tables.push(...tablesList);
|
|
101
|
+
ctx.relationships.push(...allRelationships);
|
|
102
|
+
return () => this.#describeTables(tablesList);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Apply the filter to get seed table names.
|
|
106
|
+
* If filter is an explicit array, skip querying all table names.
|
|
107
|
+
*/
|
|
108
|
+
async applyFilter() {
|
|
109
|
+
const filter = this.#filter;
|
|
110
|
+
if (Array.isArray(filter)) {
|
|
111
|
+
return filter;
|
|
112
|
+
}
|
|
113
|
+
const names = await this.getAllTableNames();
|
|
114
|
+
if (!filter) {
|
|
115
|
+
return names;
|
|
116
|
+
}
|
|
117
|
+
if (filter instanceof RegExp) {
|
|
118
|
+
return names.filter((name) => filter.test(name));
|
|
119
|
+
}
|
|
120
|
+
return names.filter(filter);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Add a relationship to the collection, deduplicating by key.
|
|
124
|
+
*/
|
|
125
|
+
addRelationship(rel, all, seen) {
|
|
126
|
+
const key = `${rel.table}:${rel.from.join(",")}:${rel.referenced_table}:${rel.to.join(",")}`;
|
|
127
|
+
if (!seen.has(key)) {
|
|
128
|
+
seen.add(key);
|
|
129
|
+
all.push(rel);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
#describeTables(tables) {
|
|
133
|
+
if (!tables.length) {
|
|
134
|
+
return "Schema unavailable.";
|
|
135
|
+
}
|
|
136
|
+
return tables.map((table) => {
|
|
137
|
+
const rowCountInfo = table.rowCount != null ? ` [rows: ${table.rowCount}${table.sizeHint ? `, size: ${table.sizeHint}` : ""}]` : "";
|
|
138
|
+
const pkConstraint = table.constraints?.find((c) => c.type === "PRIMARY_KEY");
|
|
139
|
+
const pkColumns = new Set(pkConstraint?.columns ?? []);
|
|
140
|
+
const columns = table.columns.map((column) => {
|
|
141
|
+
const annotations = [];
|
|
142
|
+
const isPrimaryKey = pkColumns.has(column.name);
|
|
143
|
+
if (isPrimaryKey) {
|
|
144
|
+
annotations.push("PK");
|
|
145
|
+
}
|
|
146
|
+
if (column.isIndexed && !isPrimaryKey) {
|
|
147
|
+
annotations.push("Indexed");
|
|
148
|
+
}
|
|
149
|
+
if (column.kind === "LowCardinality" && column.values?.length) {
|
|
150
|
+
annotations.push(`LowCardinality: ${column.values.join(", ")}`);
|
|
151
|
+
}
|
|
152
|
+
if (column.stats) {
|
|
153
|
+
const statParts = [];
|
|
154
|
+
if (column.stats.min != null || column.stats.max != null) {
|
|
155
|
+
const minText = column.stats.min ?? "n/a";
|
|
156
|
+
const maxText = column.stats.max ?? "n/a";
|
|
157
|
+
statParts.push(`range ${minText} \u2192 ${maxText}`);
|
|
158
|
+
}
|
|
159
|
+
if (column.stats.nullFraction != null && Number.isFinite(column.stats.nullFraction)) {
|
|
160
|
+
const percent = Math.round(column.stats.nullFraction * 1e3) / 10;
|
|
161
|
+
statParts.push(`null\u2248${percent}%`);
|
|
162
|
+
}
|
|
163
|
+
if (statParts.length) {
|
|
164
|
+
annotations.push(statParts.join(", "));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const annotationText = annotations.length ? ` [${annotations.join(", ")}]` : "";
|
|
168
|
+
return ` - ${column.name} (${column.type})${annotationText}`;
|
|
169
|
+
}).join("\n");
|
|
170
|
+
const indexes = table.indexes?.length ? `
|
|
171
|
+
Indexes:
|
|
172
|
+
${table.indexes.map((index) => {
|
|
173
|
+
const props = [];
|
|
174
|
+
if (index.unique) {
|
|
175
|
+
props.push("UNIQUE");
|
|
176
|
+
}
|
|
177
|
+
if (index.type) {
|
|
178
|
+
props.push(index.type);
|
|
179
|
+
}
|
|
180
|
+
const propsText = props.length ? ` (${props.join(", ")})` : "";
|
|
181
|
+
const columnsText = index.columns?.length ? index.columns.join(", ") : "expression";
|
|
182
|
+
return ` - ${index.name}${propsText}: ${columnsText}`;
|
|
183
|
+
}).join("\n")}` : "";
|
|
184
|
+
return `- Table: ${table.name}${rowCountInfo}
|
|
185
|
+
Columns:
|
|
186
|
+
${columns}${indexes}`;
|
|
187
|
+
}).join("\n\n");
|
|
188
|
+
}
|
|
189
|
+
#formatTableLabel = (tableName) => {
|
|
190
|
+
const base = tableName.split(".").pop() ?? tableName;
|
|
191
|
+
return base.replace(/_/g, " ");
|
|
192
|
+
};
|
|
193
|
+
#describeRelationships = (tables, relationships) => {
|
|
194
|
+
if (!relationships.length) {
|
|
195
|
+
return "None detected";
|
|
196
|
+
}
|
|
197
|
+
const tableMap = new Map(tables.map((table) => [table.name, table]));
|
|
198
|
+
return relationships.map((relationship) => {
|
|
199
|
+
const sourceLabel = this.#formatTableLabel(relationship.table);
|
|
200
|
+
const targetLabel = this.#formatTableLabel(
|
|
201
|
+
relationship.referenced_table
|
|
202
|
+
);
|
|
203
|
+
const singularSource = pluralize.singular(sourceLabel);
|
|
204
|
+
const pluralSource = pluralize.plural(sourceLabel);
|
|
205
|
+
const singularTarget = pluralize.singular(targetLabel);
|
|
206
|
+
const pluralTarget = pluralize.plural(targetLabel);
|
|
207
|
+
const sourceTable = tableMap.get(relationship.table);
|
|
208
|
+
const targetTable = tableMap.get(relationship.referenced_table);
|
|
209
|
+
const sourceCount = sourceTable?.rowCount;
|
|
210
|
+
const targetCount = targetTable?.rowCount;
|
|
211
|
+
const ratio = sourceCount != null && targetCount != null && targetCount > 0 ? sourceCount / targetCount : null;
|
|
212
|
+
let cardinality = "each";
|
|
213
|
+
if (ratio != null) {
|
|
214
|
+
if (ratio > 5) {
|
|
215
|
+
cardinality = `many-to-one (\u2248${sourceCount} vs ${targetCount})`;
|
|
216
|
+
} else if (ratio < 1.2 && ratio > 0.8) {
|
|
217
|
+
cardinality = `roughly 1:1 (${sourceCount} vs ${targetCount})`;
|
|
218
|
+
} else if (ratio < 0.2) {
|
|
219
|
+
cardinality = `one-to-many (${sourceCount} vs ${targetCount})`;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const mappings = relationship.from.map((fromCol, idx) => {
|
|
223
|
+
const targetCol = relationship.to[idx] ?? relationship.to[0] ?? fromCol;
|
|
224
|
+
return `${relationship.table}.${fromCol} -> ${relationship.referenced_table}.${targetCol}`;
|
|
225
|
+
}).join(", ");
|
|
226
|
+
return `- ${relationship.table} (${relationship.from.join(", ")}) -> ${relationship.referenced_table} (${relationship.to.join(", ")}) [${cardinality}]`;
|
|
227
|
+
}).join("\n");
|
|
228
|
+
};
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
// packages/text2sql/src/lib/adapters/groundings/column-stats.grounding.ts
|
|
232
|
+
var ColumnStatsGrounding = class extends AbstractGrounding {
|
|
233
|
+
constructor(config = {}) {
|
|
234
|
+
super("column_stats");
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Execute the grounding process.
|
|
238
|
+
* Annotates columns in ctx.tables and ctx.views with statistics.
|
|
239
|
+
*/
|
|
240
|
+
async execute(ctx) {
|
|
241
|
+
const allContainers = [...ctx.tables, ...ctx.views];
|
|
242
|
+
for (const container of allContainers) {
|
|
243
|
+
for (const column of container.columns) {
|
|
244
|
+
try {
|
|
245
|
+
const stats = await this.collectStats(container.name, column);
|
|
246
|
+
if (stats) {
|
|
247
|
+
column.stats = stats;
|
|
248
|
+
}
|
|
249
|
+
} catch (error) {
|
|
250
|
+
console.warn(
|
|
251
|
+
"Error collecting stats for",
|
|
252
|
+
container.name,
|
|
253
|
+
column.name,
|
|
254
|
+
error
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return () => this.#describe();
|
|
260
|
+
}
|
|
261
|
+
#describe() {
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
// packages/text2sql/src/lib/adapters/groundings/low-cardinality.grounding.ts
|
|
267
|
+
var LowCardinalityGrounding = class extends AbstractGrounding {
|
|
268
|
+
constructor(config = {}) {
|
|
269
|
+
super("low_cardinality");
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Execute the grounding process.
|
|
273
|
+
* Annotates columns in ctx.tables and ctx.views with low cardinality values.
|
|
274
|
+
*/
|
|
275
|
+
async execute(ctx) {
|
|
276
|
+
const allContainers = [...ctx.tables, ...ctx.views];
|
|
277
|
+
for (const container of allContainers) {
|
|
278
|
+
for (const column of container.columns) {
|
|
279
|
+
try {
|
|
280
|
+
const lowCard = await this.collectLowCardinality(
|
|
281
|
+
container.name,
|
|
282
|
+
column
|
|
283
|
+
);
|
|
284
|
+
if (lowCard) {
|
|
285
|
+
column.kind = lowCard.kind;
|
|
286
|
+
column.values = lowCard.values;
|
|
287
|
+
}
|
|
288
|
+
} catch (error) {
|
|
289
|
+
console.warn(
|
|
290
|
+
"Error collecting low cardinality values for",
|
|
291
|
+
container.name,
|
|
292
|
+
column.name,
|
|
293
|
+
error
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return () => this.#describe();
|
|
299
|
+
}
|
|
300
|
+
#describe() {
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
// packages/text2sql/src/lib/adapters/groundings/info.grounding.ts
|
|
306
|
+
var InfoGrounding = class extends AbstractGrounding {
|
|
307
|
+
constructor(config = {}) {
|
|
308
|
+
super("dialect_info");
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Execute the grounding process.
|
|
312
|
+
* Writes database info to ctx.info.
|
|
313
|
+
*/
|
|
314
|
+
async execute(ctx) {
|
|
315
|
+
ctx.info = await this.collectInfo();
|
|
316
|
+
const lines = [`Dialect: ${ctx.info.dialect ?? "unknown"}`];
|
|
317
|
+
if (ctx.info.version) {
|
|
318
|
+
lines.push(`Version: ${ctx.info.version}`);
|
|
319
|
+
}
|
|
320
|
+
if (ctx.info.database) {
|
|
321
|
+
lines.push(`Database: ${ctx.info.database}`);
|
|
322
|
+
}
|
|
323
|
+
if (ctx.info.details && Object.keys(ctx.info.details).length) {
|
|
324
|
+
lines.push(`Details: ${JSON.stringify(ctx.info.details)}`);
|
|
325
|
+
}
|
|
326
|
+
return () => lines.join("\n");
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
// packages/text2sql/src/lib/adapters/groundings/view.grounding.ts
|
|
331
|
+
var ViewGrounding = class extends AbstractGrounding {
|
|
332
|
+
#filter;
|
|
333
|
+
constructor(config = {}) {
|
|
334
|
+
super("views");
|
|
335
|
+
this.#filter = config.filter;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Execute the grounding process.
|
|
339
|
+
* Writes discovered views to the context.
|
|
340
|
+
*/
|
|
341
|
+
async execute(ctx) {
|
|
342
|
+
const viewNames = await this.applyFilter();
|
|
343
|
+
const views = await Promise.all(
|
|
344
|
+
viewNames.map((name) => this.getView(name))
|
|
345
|
+
);
|
|
346
|
+
ctx.views.push(...views);
|
|
347
|
+
return () => this.#describe(views);
|
|
348
|
+
}
|
|
349
|
+
#describe(views) {
|
|
350
|
+
if (!views.length) {
|
|
351
|
+
return "No views available.";
|
|
352
|
+
}
|
|
353
|
+
return views.map((view) => {
|
|
354
|
+
const columns = view.columns.map((column) => {
|
|
355
|
+
const annotations = [];
|
|
356
|
+
if (column.kind === "LowCardinality" && column.values?.length) {
|
|
357
|
+
annotations.push(`LowCardinality: ${column.values.join(", ")}`);
|
|
358
|
+
}
|
|
359
|
+
if (column.stats) {
|
|
360
|
+
const statParts = [];
|
|
361
|
+
if (column.stats.min != null || column.stats.max != null) {
|
|
362
|
+
const minText = column.stats.min ?? "n/a";
|
|
363
|
+
const maxText = column.stats.max ?? "n/a";
|
|
364
|
+
statParts.push(`range ${minText} \u2192 ${maxText}`);
|
|
365
|
+
}
|
|
366
|
+
if (column.stats.nullFraction != null && Number.isFinite(column.stats.nullFraction)) {
|
|
367
|
+
const percent = Math.round(column.stats.nullFraction * 1e3) / 10;
|
|
368
|
+
statParts.push(`null\u2248${percent}%`);
|
|
369
|
+
}
|
|
370
|
+
if (statParts.length) {
|
|
371
|
+
annotations.push(statParts.join(", "));
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
const annotationText = annotations.length ? ` [${annotations.join(", ")}]` : "";
|
|
375
|
+
return ` - ${column.name} (${column.type})${annotationText}`;
|
|
376
|
+
}).join("\n");
|
|
377
|
+
const definition = view.definition ? `
|
|
378
|
+
Definition: ${view.definition.length > 200 ? view.definition.slice(0, 200) + "..." : view.definition}` : "";
|
|
379
|
+
return `- View: ${view.name}${definition}
|
|
380
|
+
Columns:
|
|
381
|
+
${columns}`;
|
|
382
|
+
}).join("\n\n");
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Apply the filter to get view names.
|
|
386
|
+
* If filter is an explicit array, skip querying all view names.
|
|
387
|
+
*/
|
|
388
|
+
async applyFilter() {
|
|
389
|
+
const filter = this.#filter;
|
|
390
|
+
if (Array.isArray(filter)) {
|
|
391
|
+
return filter;
|
|
392
|
+
}
|
|
393
|
+
const names = await this.getAllViewNames();
|
|
394
|
+
if (!filter) {
|
|
395
|
+
return names;
|
|
396
|
+
}
|
|
397
|
+
if (filter instanceof RegExp) {
|
|
398
|
+
return names.filter((name) => filter.test(name));
|
|
399
|
+
}
|
|
400
|
+
return names.filter(filter);
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
// packages/text2sql/src/lib/adapters/groundings/report.grounding.ts
|
|
405
|
+
import { groq } from "@ai-sdk/groq";
|
|
406
|
+
import { tool } from "ai";
|
|
407
|
+
import dedent from "dedent";
|
|
408
|
+
import z from "zod";
|
|
409
|
+
import {
|
|
410
|
+
agent,
|
|
411
|
+
generate,
|
|
412
|
+
toState,
|
|
413
|
+
user
|
|
414
|
+
} from "@deepagents/agent";
|
|
415
|
+
var ReportGrounding = class extends AbstractGrounding {
|
|
416
|
+
#adapter;
|
|
417
|
+
#model;
|
|
418
|
+
#cache;
|
|
419
|
+
#forceRefresh;
|
|
420
|
+
constructor(adapter, config = {}) {
|
|
421
|
+
super("business_context");
|
|
422
|
+
this.#adapter = adapter;
|
|
423
|
+
this.#model = config.model ?? groq("openai/gpt-oss-20b");
|
|
424
|
+
this.#cache = config.cache;
|
|
425
|
+
this.#forceRefresh = config.forceRefresh ?? false;
|
|
426
|
+
}
|
|
427
|
+
async execute(ctx) {
|
|
428
|
+
if (!this.#forceRefresh && this.#cache) {
|
|
429
|
+
const cached = await this.#cache.get();
|
|
430
|
+
if (cached) {
|
|
431
|
+
ctx.report = cached;
|
|
432
|
+
return () => cached;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
const report = await this.#generateReport();
|
|
436
|
+
ctx.report = report;
|
|
437
|
+
if (this.#cache) {
|
|
438
|
+
await this.#cache.set(report);
|
|
439
|
+
}
|
|
440
|
+
return () => report;
|
|
441
|
+
}
|
|
442
|
+
async #generateReport() {
|
|
443
|
+
const reportAgent = agent({
|
|
444
|
+
name: "db-report-agent",
|
|
445
|
+
model: this.#model,
|
|
446
|
+
prompt: () => dedent`
|
|
447
|
+
<identity>
|
|
448
|
+
You are a database analyst expert. Your job is to understand what
|
|
449
|
+
a database represents and provide business context about it.
|
|
450
|
+
You have READ-ONLY access to the database.
|
|
451
|
+
</identity>
|
|
452
|
+
|
|
453
|
+
<instructions>
|
|
454
|
+
Write a business context that helps another agent answer questions accurately.
|
|
455
|
+
|
|
456
|
+
For EACH table, do queries ONE AT A TIME:
|
|
457
|
+
1. SELECT COUNT(*) to get row count
|
|
458
|
+
2. SELECT * LIMIT 3 to see sample data
|
|
459
|
+
|
|
460
|
+
Then write a report with:
|
|
461
|
+
- What business this database is for
|
|
462
|
+
- For each table: purpose, row count, and example of what the data looks like
|
|
463
|
+
|
|
464
|
+
Include concrete examples like "Track prices are $0.99",
|
|
465
|
+
"Customer names like 'Luís Gonçalves'", etc.
|
|
466
|
+
|
|
467
|
+
Keep it 400-600 words, conversational style.
|
|
468
|
+
</instructions>
|
|
469
|
+
`,
|
|
470
|
+
tools: {
|
|
471
|
+
query_database: tool({
|
|
472
|
+
description: "Execute a SELECT query to explore the database and gather insights.",
|
|
473
|
+
inputSchema: z.object({
|
|
474
|
+
sql: z.string().describe("The SELECT query to execute"),
|
|
475
|
+
purpose: z.string().describe(
|
|
476
|
+
"What insight you are trying to gather with this query"
|
|
477
|
+
)
|
|
478
|
+
}),
|
|
479
|
+
execute: ({ sql }, options) => {
|
|
480
|
+
const state = toState(options);
|
|
481
|
+
return state.adapter.execute(sql);
|
|
482
|
+
}
|
|
483
|
+
})
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
const { text } = await generate(
|
|
487
|
+
reportAgent,
|
|
488
|
+
[
|
|
489
|
+
user(
|
|
490
|
+
"Please analyze the database and write a contextual report about what this database represents."
|
|
491
|
+
)
|
|
492
|
+
],
|
|
493
|
+
{ adapter: this.#adapter }
|
|
494
|
+
);
|
|
495
|
+
return text;
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
export {
|
|
499
|
+
ColumnStatsGrounding,
|
|
500
|
+
InfoGrounding,
|
|
501
|
+
LowCardinalityGrounding,
|
|
502
|
+
ReportGrounding,
|
|
503
|
+
TableGrounding,
|
|
504
|
+
ViewGrounding,
|
|
505
|
+
createGroundingContext
|
|
506
|
+
};
|
|
507
|
+
//# sourceMappingURL=grounding.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/lib/adapters/groundings/context.ts", "../../../../src/lib/adapters/groundings/table.grounding.ts", "../../../../src/lib/adapters/grounding.ticket.ts", "../../../../src/lib/adapters/groundings/column-stats.grounding.ts", "../../../../src/lib/adapters/groundings/low-cardinality.grounding.ts", "../../../../src/lib/adapters/groundings/info.grounding.ts", "../../../../src/lib/adapters/groundings/view.grounding.ts", "../../../../src/lib/adapters/groundings/report.grounding.ts"],
|
|
4
|
+
"sourcesContent": ["import type { AdapterInfo, ColumnStats, Relationship, Table } from '../adapter.ts';\nimport type { View } from './view.grounding.ts';\n\n/**\n * Column type for grounding operations.\n * Common interface between Table.columns and View.columns.\n */\nexport interface Column {\n name: string;\n type: string;\n kind?: 'LowCardinality';\n values?: string[];\n stats?: ColumnStats;\n}\n\n/**\n * Entity with columns (Table or View).\n */\nexport interface ColumnContainer {\n name: string;\n columns: Column[];\n}\n\n/**\n * Shared context object passed to all groundings.\n * Groundings read from and write to this context.\n */\nexport interface GroundingContext {\n /** Tables discovered by TableGrounding */\n tables: Table[];\n\n /** Views discovered by ViewGrounding */\n views: View[];\n\n /** Relationships discovered by TableGrounding */\n relationships: Relationship[];\n\n /** Database info collected by InfoGrounding */\n info?: AdapterInfo;\n\n /** Business context report generated by ReportGrounding */\n report?: string;\n}\n\n/**\n * Create a new empty grounding context.\n */\nexport function createGroundingContext(): GroundingContext {\n return {\n tables: [],\n views: [],\n relationships: [],\n info: undefined,\n };\n}\n", "import pluralize from 'pluralize';\n\nimport type { Filter, Relationship, Table } from '../adapter.ts';\nimport { AbstractGrounding } from '../grounding.ticket.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for TableGrounding.\n */\nexport interface TableGroundingConfig {\n /** Filter to select seed tables */\n filter?: Filter;\n /**\n * Traverse forward (child\uFFFDparent) following FK direction.\n * - true: unlimited depth\n * - number: maximum depth\n * - false/undefined: no forward traversal\n */\n forward?: boolean | number;\n /**\n * Traverse backward (parent\uFFFDchild) finding tables that reference us.\n * - true: unlimited depth\n * - number: maximum depth\n * - false/undefined: no backward traversal\n */\n backward?: boolean | number;\n}\n\n/**\n * Abstract base class for table grounding.\n *\n * The `execute()` method implements a BFS traversal algorithm that discovers\n * tables and relationships. Subclasses implement the database-specific hooks:\n * - `getAllTableNames()` - list all tables\n * - `getTable()` - get table metadata\n * - `findOutgoingRelations()` - find FKs FROM a table\n * - `findIncomingRelations()` - find FKs TO a table\n */\nexport abstract class TableGrounding extends AbstractGrounding {\n #filter?: Filter;\n #forward?: boolean | number;\n #backward?: boolean | number;\n\n constructor(config: TableGroundingConfig = {}) {\n super('tables');\n this.#filter = config.filter;\n this.#forward = config.forward;\n this.#backward = config.backward;\n }\n\n /** Get all table names in the database */\n protected abstract getAllTableNames(): Promise<string[]>;\n\n /** Get full table metadata for a single table */\n protected abstract getTable(tableName: string): Promise<Table>;\n\n /** Find FKs FROM this table (outgoing relationships) */\n protected abstract findOutgoingRelations(\n tableName: string,\n ): Promise<Relationship[]>;\n\n /** Find FKs TO this table (incoming relationships) */\n protected abstract findIncomingRelations(\n tableName: string,\n ): Promise<Relationship[]>;\n\n /**\n * Execute the grounding process.\n * Writes discovered tables and relationships to the context.\n */\n async execute(ctx: GroundingContext) {\n const seedTables = await this.applyFilter();\n const forward = this.#forward;\n const backward = this.#backward;\n\n // No traversal at all - just add the seed tables\n if (!forward && !backward) {\n const tables = await Promise.all(\n seedTables.map((name) => this.getTable(name)),\n );\n ctx.tables.push(...tables);\n return () => this.#describeTables(tables);\n }\n\n const tables: Record<string, Table> = {};\n const allRelationships: Relationship[] = [];\n const seenRelationships = new Set<string>();\n\n // Track depth separately for forward/backward using BFS\n const forwardQueue: Array<{ name: string; depth: number }> = [];\n const backwardQueue: Array<{ name: string; depth: number }> = [];\n const forwardVisited = new Set<string>();\n const backwardVisited = new Set<string>();\n\n // Initialize queues with seed tables at depth 0\n for (const name of seedTables) {\n if (forward) forwardQueue.push({ name, depth: 0 });\n if (backward) backwardQueue.push({ name, depth: 0 });\n }\n\n // Process forward (child\u2192parent)\n const forwardLimit = forward === true ? Infinity : forward || 0;\n while (forwardQueue.length > 0) {\n const item = forwardQueue.shift();\n if (!item) break;\n const { name, depth } = item;\n\n if (forwardVisited.has(name)) continue;\n forwardVisited.add(name);\n\n if (!tables[name]) {\n tables[name] = await this.getTable(name);\n }\n\n if (depth < forwardLimit) {\n const rels = await this.findOutgoingRelations(name);\n for (const rel of rels) {\n this.addRelationship(rel, allRelationships, seenRelationships);\n if (!forwardVisited.has(rel.referenced_table)) {\n forwardQueue.push({ name: rel.referenced_table, depth: depth + 1 });\n }\n }\n }\n }\n\n // Process backward (parent\u2192child)\n const backwardLimit = backward === true ? Infinity : backward || 0;\n while (backwardQueue.length > 0) {\n const item = backwardQueue.shift();\n if (!item) break;\n const { name, depth } = item;\n\n if (backwardVisited.has(name)) continue;\n backwardVisited.add(name);\n\n if (!tables[name]) {\n tables[name] = await this.getTable(name);\n }\n\n if (depth < backwardLimit) {\n const rels = await this.findIncomingRelations(name);\n for (const rel of rels) {\n this.addRelationship(rel, allRelationships, seenRelationships);\n if (!backwardVisited.has(rel.table)) {\n backwardQueue.push({ name: rel.table, depth: depth + 1 });\n }\n }\n }\n }\n\n // Write to context\n const tablesList = Object.values(tables);\n ctx.tables.push(...tablesList);\n ctx.relationships.push(...allRelationships);\n return () => this.#describeTables(tablesList);\n }\n\n /**\n * Apply the filter to get seed table names.\n * If filter is an explicit array, skip querying all table names.\n */\n protected async applyFilter(): Promise<string[]> {\n const filter = this.#filter;\n if (Array.isArray(filter)) {\n return filter;\n }\n const names = await this.getAllTableNames();\n if (!filter) {\n return names;\n }\n if (filter instanceof RegExp) {\n return names.filter((name) => filter.test(name));\n }\n return names.filter(filter);\n }\n\n /**\n * Add a relationship to the collection, deduplicating by key.\n */\n protected addRelationship(\n rel: Relationship,\n all: Relationship[],\n seen: Set<string>,\n ): void {\n const key = `${rel.table}:${rel.from.join(',')}:${rel.referenced_table}:${rel.to.join(',')}`;\n if (!seen.has(key)) {\n seen.add(key);\n all.push(rel);\n }\n }\n\n #describeTables(tables: Table[]): string {\n if (!tables.length) {\n return 'Schema unavailable.';\n }\n\n return tables\n .map((table) => {\n const rowCountInfo =\n table.rowCount != null\n ? ` [rows: ${table.rowCount}${table.sizeHint ? `, size: ${table.sizeHint}` : ''}]`\n : '';\n // Get primary key columns from constraints\n const pkConstraint = table.constraints?.find((c) => c.type === 'PRIMARY_KEY');\n const pkColumns = new Set(pkConstraint?.columns ?? []);\n\n const columns = table.columns\n .map((column) => {\n const annotations: string[] = [];\n const isPrimaryKey = pkColumns.has(column.name);\n if (isPrimaryKey) {\n annotations.push('PK');\n }\n if (column.isIndexed && !isPrimaryKey) {\n annotations.push('Indexed');\n }\n if (column.kind === 'LowCardinality' && column.values?.length) {\n annotations.push(`LowCardinality: ${column.values.join(', ')}`);\n }\n if (column.stats) {\n const statParts: string[] = [];\n if (column.stats.min != null || column.stats.max != null) {\n const minText = column.stats.min ?? 'n/a';\n const maxText = column.stats.max ?? 'n/a';\n statParts.push(`range ${minText} \u2192 ${maxText}`);\n }\n if (\n column.stats.nullFraction != null &&\n Number.isFinite(column.stats.nullFraction)\n ) {\n const percent =\n Math.round(column.stats.nullFraction * 1000) / 10;\n statParts.push(`null\u2248${percent}%`);\n }\n if (statParts.length) {\n annotations.push(statParts.join(', '));\n }\n }\n const annotationText = annotations.length\n ? ` [${annotations.join(', ')}]`\n : '';\n return ` - ${column.name} (${column.type})${annotationText}`;\n })\n .join('\\n');\n const indexes = table.indexes?.length\n ? `\\n Indexes:\\n${table.indexes\n .map((index) => {\n const props: string[] = [];\n if (index.unique) {\n props.push('UNIQUE');\n }\n if (index.type) {\n props.push(index.type);\n }\n const propsText = props.length ? ` (${props.join(', ')})` : '';\n const columnsText = index.columns?.length\n ? index.columns.join(', ')\n : 'expression';\n return ` - ${index.name}${propsText}: ${columnsText}`;\n })\n .join('\\n')}`\n : '';\n return `- Table: ${table.name}${rowCountInfo}\\n Columns:\\n${columns}${indexes}`;\n })\n .join('\\n\\n');\n }\n\n #formatTableLabel = (tableName: string) => {\n const base = tableName.split('.').pop() ?? tableName;\n return base.replace(/_/g, ' ');\n };\n\n #describeRelationships = (tables: Table[], relationships: Relationship[]) => {\n if (!relationships.length) {\n return 'None detected';\n }\n\n const tableMap = new Map(tables.map((table) => [table.name, table]));\n\n return relationships\n .map((relationship) => {\n const sourceLabel = this.#formatTableLabel(relationship.table);\n const targetLabel = this.#formatTableLabel(\n relationship.referenced_table,\n );\n const singularSource = pluralize.singular(sourceLabel);\n const pluralSource = pluralize.plural(sourceLabel);\n const singularTarget = pluralize.singular(targetLabel);\n const pluralTarget = pluralize.plural(targetLabel);\n const sourceTable = tableMap.get(relationship.table);\n const targetTable = tableMap.get(relationship.referenced_table);\n const sourceCount = sourceTable?.rowCount;\n const targetCount = targetTable?.rowCount;\n const ratio =\n sourceCount != null && targetCount != null && targetCount > 0\n ? sourceCount / targetCount\n : null;\n\n let cardinality = 'each';\n if (ratio != null) {\n if (ratio > 5) {\n cardinality = `many-to-one (\u2248${sourceCount} vs ${targetCount})`;\n } else if (ratio < 1.2 && ratio > 0.8) {\n cardinality = `roughly 1:1 (${sourceCount} vs ${targetCount})`;\n } else if (ratio < 0.2) {\n cardinality = `one-to-many (${sourceCount} vs ${targetCount})`;\n }\n }\n const mappings = relationship.from\n .map((fromCol, idx) => {\n const targetCol =\n relationship.to[idx] ?? relationship.to[0] ?? fromCol;\n return `${relationship.table}.${fromCol} -> ${relationship.referenced_table}.${targetCol}`;\n })\n .join(', ');\n\n return `- ${relationship.table} (${relationship.from.join(', ')}) -> ${relationship.referenced_table} (${relationship.to.join(', ')}) [${cardinality}]`;\n })\n .join('\\n');\n };\n}\n", "import type { Adapter } from './adapter.ts';\nimport type { GroundingContext } from './groundings/context.ts';\n\n/**\n * Filter type for table names.\n * - string[]: explicit list of table names\n * - RegExp: pattern to match table names\n * - function: predicate to filter table names\n */\nexport type Filter = string[] | RegExp | ((tableName: string) => boolean);\n\nexport interface AdapterInfo {\n dialect: string;\n version?: string;\n database?: string;\n details?: Record<string, unknown>;\n}\nexport type AdapterInfoProvider =\n | AdapterInfo\n | (() => Promise<AdapterInfo> | AdapterInfo);\n\nexport abstract class AbstractGrounding {\n tag: string;\n constructor(tag: string) {\n this.tag = tag;\n }\n\n abstract execute(ctx: GroundingContext): Promise<() => string | null>;\n}\n\nclass SampleDataGrounding {\n // this will fetch sample data for tables matching the filter\n}\nclass ExampleQueryGrounding {\n // this will create example queries for tables matching the filter\n}\nclass FunctionGrounding {\n #filter: Filter;\n #adapter: Adapter;\n constructor(adapter: Adapter, filter: Filter) {\n this.#filter = filter;\n this.#adapter = adapter;\n }\n}\n", "import type { ColumnStats } from '../adapter.ts';\nimport { AbstractGrounding } from '../grounding.ticket.ts';\nimport type { Column, ColumnContainer, GroundingContext } from './context.ts';\n\n/**\n * Configuration for ColumnStatsGrounding.\n */\nexport interface ColumnStatsGroundingConfig {\n // Future: filter which tables/columns to collect stats for\n}\n\n/**\n * Abstract base class for column statistics grounding.\n *\n * Reads tables and views from the context and annotates their columns\n * with statistics (min, max, nullFraction).\n *\n * Subclasses implement database-specific hooks:\n * - `collectStats()` - collect min/max/nullFraction for a column\n */\nexport abstract class ColumnStatsGrounding extends AbstractGrounding {\n constructor(config: ColumnStatsGroundingConfig = {}) {\n super('column_stats');\n }\n\n /**\n * Collect min/max/nullFraction statistics for a column.\n * Return undefined to skip this column.\n */\n protected abstract collectStats(\n tableName: string,\n column: Column,\n ): Promise<ColumnStats | undefined>;\n\n /**\n * Execute the grounding process.\n * Annotates columns in ctx.tables and ctx.views with statistics.\n */\n async execute(ctx: GroundingContext) {\n // Process both tables and views\n const allContainers: ColumnContainer[] = [...ctx.tables, ...ctx.views];\n for (const container of allContainers) {\n for (const column of container.columns) {\n // Collect min/max/nullFraction\n try {\n const stats = await this.collectStats(container.name, column);\n if (stats) {\n column.stats = stats;\n }\n } catch (error) {\n // Skip on error\n console.warn(\n 'Error collecting stats for',\n container.name,\n column.name,\n error,\n );\n }\n }\n }\n return () => this.#describe();\n }\n\n #describe() {\n return null;\n }\n}\n", "import { AbstractGrounding } from '../grounding.ticket.ts';\nimport type { Column, ColumnContainer, GroundingContext } from './context.ts';\n\nexport type { Column, ColumnContainer };\n\n/**\n * Configuration for LowCardinalityGrounding.\n */\nexport interface LowCardinalityGroundingConfig {\n // Future: filter which tables/columns to collect low cardinality values for\n}\n\n/**\n * Abstract base class for low cardinality column grounding.\n *\n * Reads tables and views from the context and annotates their columns\n * with low cardinality values (columns with few distinct values).\n *\n * Subclasses implement database-specific hooks:\n * - `collectLowCardinality()` - collect distinct values for low cardinality columns\n */\nexport abstract class LowCardinalityGrounding extends AbstractGrounding {\n constructor(config: LowCardinalityGroundingConfig = {}) {\n super('low_cardinality');\n }\n\n /**\n * Collect distinct values for low cardinality columns.\n * Return undefined if column has too many distinct values.\n */\n protected abstract collectLowCardinality(\n tableName: string,\n column: Column,\n ): Promise<{ kind: 'LowCardinality'; values: string[] } | undefined>;\n\n /**\n * Execute the grounding process.\n * Annotates columns in ctx.tables and ctx.views with low cardinality values.\n */\n async execute(ctx: GroundingContext) {\n // Process both tables and views\n const allContainers: ColumnContainer[] = [...ctx.tables, ...ctx.views];\n for (const container of allContainers) {\n for (const column of container.columns) {\n // Collect low cardinality values\n try {\n const lowCard = await this.collectLowCardinality(\n container.name,\n column,\n );\n if (lowCard) {\n column.kind = lowCard.kind;\n column.values = lowCard.values;\n }\n } catch (error) {\n // Skip on error\n console.warn(\n 'Error collecting low cardinality values for',\n container.name,\n column.name,\n error,\n );\n }\n }\n }\n return () => this.#describe();\n }\n\n #describe() {\n return null;\n }\n}\n", "import type { AdapterInfo } from '../adapter.ts';\nimport { AbstractGrounding } from '../grounding.ticket.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for InfoGrounding.\n */\nexport interface InfoGroundingConfig {\n // Future: options to control what info to collect\n}\n\n/**\n * Abstract base class for database info grounding.\n *\n * Collects database dialect, version, and connection info.\n *\n * Subclasses implement the database-specific hook:\n * - `collectInfo()` - collect database info\n */\nexport abstract class InfoGrounding extends AbstractGrounding {\n constructor(config: InfoGroundingConfig = {}) {\n super('dialect_info');\n }\n\n /**\n * Collect database dialect, version, and other info.\n */\n protected abstract collectInfo(): Promise<AdapterInfo>;\n\n /**\n * Execute the grounding process.\n * Writes database info to ctx.info.\n */\n async execute(ctx: GroundingContext) {\n ctx.info = await this.collectInfo();\n const lines = [`Dialect: ${ctx.info.dialect ?? 'unknown'}`];\n if (ctx.info.version) {\n lines.push(`Version: ${ctx.info.version}`);\n }\n if (ctx.info.database) {\n lines.push(`Database: ${ctx.info.database}`);\n }\n if (ctx.info.details && Object.keys(ctx.info.details).length) {\n lines.push(`Details: ${JSON.stringify(ctx.info.details)}`);\n }\n return () => lines.join('\\n');\n }\n}\n", "import type { ColumnStats, Filter } from '../adapter.ts';\nimport { AbstractGrounding } from '../grounding.ticket.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Represents a database view with its metadata.\n */\nexport interface View {\n name: string;\n schema?: string;\n rawName?: string;\n /** The SQL definition of the view (CREATE VIEW statement or query) */\n definition?: string;\n columns: {\n name: string;\n type: string;\n /** Low cardinality marker */\n kind?: 'LowCardinality';\n /** Distinct values for low cardinality columns */\n values?: string[];\n /** Column statistics (min, max, nullFraction) */\n stats?: ColumnStats;\n }[];\n}\n\n/**\n * Configuration for ViewGrounding.\n */\nexport interface ViewGroundingConfig {\n /** Filter to select views */\n filter?: Filter;\n}\n\n/**\n * Abstract base class for view grounding\n *\n * The `execute()` method implements the algorithm that discovers views.\n * Subclasses implement the database-specific hooks:\n * - `getAllViewNames()` - list all views\n * - `getView()` - get view metadata\n */\nexport abstract class ViewGrounding extends AbstractGrounding {\n #filter?: Filter;\n\n constructor(config: ViewGroundingConfig = {}) {\n super('views');\n this.#filter = config.filter;\n }\n\n /** Get all view names in the database */\n protected abstract getAllViewNames(): Promise<string[]>;\n\n /** Get full view metadata for a single view */\n protected abstract getView(viewName: string): Promise<View>;\n\n /**\n * Execute the grounding process.\n * Writes discovered views to the context.\n */\n async execute(ctx: GroundingContext) {\n const viewNames = await this.applyFilter();\n const views = await Promise.all(\n viewNames.map((name) => this.getView(name)),\n );\n ctx.views.push(...views);\n return () => this.#describe(views);\n }\n\n #describe(views: View[]): string {\n if (!views.length) {\n return 'No views available.';\n }\n\n return views\n .map((view) => {\n const columns = view.columns\n .map((column) => {\n const annotations: string[] = [];\n if (column.kind === 'LowCardinality' && column.values?.length) {\n annotations.push(`LowCardinality: ${column.values.join(', ')}`);\n }\n if (column.stats) {\n const statParts: string[] = [];\n if (column.stats.min != null || column.stats.max != null) {\n const minText = column.stats.min ?? 'n/a';\n const maxText = column.stats.max ?? 'n/a';\n statParts.push(`range ${minText} \u2192 ${maxText}`);\n }\n if (\n column.stats.nullFraction != null &&\n Number.isFinite(column.stats.nullFraction)\n ) {\n const percent =\n Math.round(column.stats.nullFraction * 1000) / 10;\n statParts.push(`null\u2248${percent}%`);\n }\n if (statParts.length) {\n annotations.push(statParts.join(', '));\n }\n }\n const annotationText = annotations.length\n ? ` [${annotations.join(', ')}]`\n : '';\n return ` - ${column.name} (${column.type})${annotationText}`;\n })\n .join('\\n');\n\n const definition = view.definition\n ? `\\n Definition: ${view.definition.length > 200 ? view.definition.slice(0, 200) + '...' : view.definition}`\n : '';\n\n return `- View: ${view.name}${definition}\\n Columns:\\n${columns}`;\n })\n .join('\\n\\n');\n }\n\n /**\n * Apply the filter to get view names.\n * If filter is an explicit array, skip querying all view names.\n */\n protected async applyFilter(): Promise<string[]> {\n const filter = this.#filter;\n if (Array.isArray(filter)) {\n return filter;\n }\n const names = await this.getAllViewNames();\n if (!filter) {\n return names;\n }\n if (filter instanceof RegExp) {\n return names.filter((name) => filter.test(name));\n }\n return names.filter(filter);\n }\n}\n", "import { groq } from '@ai-sdk/groq';\nimport { tool } from 'ai';\nimport dedent from 'dedent';\nimport z from 'zod';\n\nimport {\n type AgentModel,\n agent,\n generate,\n toState,\n user,\n} from '@deepagents/agent';\n\nimport type { Adapter } from '../adapter.ts';\nimport { AbstractGrounding } from '../grounding.ticket.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Cache interface for storing generated reports.\n */\nexport interface ReportCache {\n get(): Promise<string | null>;\n set(value: string): Promise<void>;\n}\n\n/**\n * Configuration for ReportGrounding.\n */\nexport interface ReportGroundingConfig {\n /** LLM model to use for generating the report */\n model?: AgentModel;\n /** Optional cache for storing generated reports */\n cache?: ReportCache;\n /** Force regeneration even if cached */\n forceRefresh?: boolean;\n}\n\n/**\n * Grounding that generates a business context report about the database.\n *\n * Uses an LLM agent to:\n * 1. Query COUNT(*) for each table\n * 2. Query SELECT * LIMIT 3 for sample data\n * 3. Generate a 400-600 word business context report\n *\n * The report helps downstream agents understand what the database represents.\n */\nexport class ReportGrounding extends AbstractGrounding {\n #adapter: Adapter;\n #model: AgentModel;\n #cache?: ReportCache;\n #forceRefresh: boolean;\n\n constructor(adapter: Adapter, config: ReportGroundingConfig={}) {\n super('business_context');\n this.#adapter = adapter;\n this.#model = config.model ?? groq('openai/gpt-oss-20b');\n this.#cache = config.cache;\n this.#forceRefresh = config.forceRefresh ?? false;\n }\n\n async execute(ctx: GroundingContext): Promise<() => string | null> {\n // Check cache first (unless forcing refresh)\n if (!this.#forceRefresh && this.#cache) {\n const cached = await this.#cache.get();\n if (cached) {\n ctx.report = cached;\n return () => cached;\n }\n }\n\n // Generate report using LLM\n const report = await this.#generateReport();\n ctx.report = report;\n\n // Cache the result\n if (this.#cache) {\n await this.#cache.set(report);\n }\n\n return () => report;\n }\n\n async #generateReport(): Promise<string> {\n const reportAgent = agent<unknown, { adapter: Adapter }>({\n name: 'db-report-agent',\n model: this.#model,\n prompt: () => dedent`\n <identity>\n You are a database analyst expert. Your job is to understand what\n a database represents and provide business context about it.\n You have READ-ONLY access to the database.\n </identity>\n\n <instructions>\n Write a business context that helps another agent answer questions accurately.\n\n For EACH table, do queries ONE AT A TIME:\n 1. SELECT COUNT(*) to get row count\n 2. SELECT * LIMIT 3 to see sample data\n\n Then write a report with:\n - What business this database is for\n - For each table: purpose, row count, and example of what the data looks like\n\n Include concrete examples like \"Track prices are $0.99\",\n \"Customer names like 'Lu\u00EDs Gon\u00E7alves'\", etc.\n\n Keep it 400-600 words, conversational style.\n </instructions>\n `,\n tools: {\n query_database: tool({\n description:\n 'Execute a SELECT query to explore the database and gather insights.',\n inputSchema: z.object({\n sql: z.string().describe('The SELECT query to execute'),\n purpose: z\n .string()\n .describe(\n 'What insight you are trying to gather with this query',\n ),\n }),\n execute: ({ sql }, options) => {\n const state = toState<{ adapter: Adapter }>(options);\n return state.adapter.execute(sql);\n },\n }),\n },\n });\n\n const { text } = await generate(\n reportAgent,\n [\n user(\n 'Please analyze the database and write a contextual report about what this database represents.',\n ),\n ],\n { adapter: this.#adapter },\n );\n\n return text;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["tables"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { TableIndex } from '../adapter.ts';
|
|
2
|
+
import { AbstractGrounding } from '../grounding.ticket.ts';
|
|
3
|
+
import type { GroundingContext } from './context.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for IndexesGrounding.
|
|
6
|
+
*/
|
|
7
|
+
export interface IndexesGroundingConfig {
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Abstract base class for indexes grounding.
|
|
11
|
+
*
|
|
12
|
+
* Reads tables from the context and annotates them with index metadata.
|
|
13
|
+
* This grounding must run AFTER TableGrounding since it reads from ctx.tables.
|
|
14
|
+
*
|
|
15
|
+
* Subclasses implement the database-specific hook:
|
|
16
|
+
* - `getIndexes()` - fetch indexes for a table
|
|
17
|
+
*/
|
|
18
|
+
export declare abstract class IndexesGrounding extends AbstractGrounding {
|
|
19
|
+
constructor(config?: IndexesGroundingConfig);
|
|
20
|
+
/**
|
|
21
|
+
* Fetch indexes for a specific table.
|
|
22
|
+
*/
|
|
23
|
+
protected abstract getIndexes(tableName: string): Promise<TableIndex[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Execute the grounding process.
|
|
26
|
+
* Annotates tables in ctx.tables with their indexes and marks indexed columns.
|
|
27
|
+
*/
|
|
28
|
+
execute(ctx: GroundingContext): Promise<() => null>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=indexes.grounding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexes.grounding.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/groundings/indexes.grounding.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,sBAAsB;CAEtC;AAED;;;;;;;;GAQG;AACH,8BAAsB,gBAAiB,SAAQ,iBAAiB;gBAClD,MAAM,GAAE,sBAA2B;IAI/C;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAEvE;;;OAGG;IACG,OAAO,CAAC,GAAG,EAAE,gBAAgB;CAgBpC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { AdapterInfo } from '../adapter.ts';
|
|
2
|
+
import { AbstractGrounding } from '../grounding.ticket.ts';
|
|
3
|
+
import type { GroundingContext } from './context.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for InfoGrounding.
|
|
6
|
+
*/
|
|
7
|
+
export interface InfoGroundingConfig {
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Abstract base class for database info grounding.
|
|
11
|
+
*
|
|
12
|
+
* Collects database dialect, version, and connection info.
|
|
13
|
+
*
|
|
14
|
+
* Subclasses implement the database-specific hook:
|
|
15
|
+
* - `collectInfo()` - collect database info
|
|
16
|
+
*/
|
|
17
|
+
export declare abstract class InfoGrounding extends AbstractGrounding {
|
|
18
|
+
constructor(config?: InfoGroundingConfig);
|
|
19
|
+
/**
|
|
20
|
+
* Collect database dialect, version, and other info.
|
|
21
|
+
*/
|
|
22
|
+
protected abstract collectInfo(): Promise<AdapterInfo>;
|
|
23
|
+
/**
|
|
24
|
+
* Execute the grounding process.
|
|
25
|
+
* Writes database info to ctx.info.
|
|
26
|
+
*/
|
|
27
|
+
execute(ctx: GroundingContext): Promise<() => string>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=info.grounding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"info.grounding.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/groundings/info.grounding.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,mBAAmB;CAEnC;AAED;;;;;;;GAOG;AACH,8BAAsB,aAAc,SAAQ,iBAAiB;gBAC/C,MAAM,GAAE,mBAAwB;IAI5C;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAEtD;;;OAGG;IACG,OAAO,CAAC,GAAG,EAAE,gBAAgB;CAcpC"}
|