@deepagents/text2sql 0.10.1 → 0.11.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.
Files changed (98) hide show
  1. package/README.md +32 -41
  2. package/dist/index.d.ts +1 -6
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +2338 -2395
  5. package/dist/index.js.map +4 -4
  6. package/dist/lib/adapters/adapter.d.ts +13 -1
  7. package/dist/lib/adapters/adapter.d.ts.map +1 -1
  8. package/dist/lib/adapters/groundings/abstract.grounding.d.ts +19 -3
  9. package/dist/lib/adapters/groundings/abstract.grounding.d.ts.map +1 -1
  10. package/dist/lib/adapters/groundings/column-stats.grounding.d.ts +1 -2
  11. package/dist/lib/adapters/groundings/column-stats.grounding.d.ts.map +1 -1
  12. package/dist/lib/adapters/groundings/column-values.grounding.d.ts +1 -2
  13. package/dist/lib/adapters/groundings/column-values.grounding.d.ts.map +1 -1
  14. package/dist/lib/adapters/groundings/constraint.grounding.d.ts +1 -1
  15. package/dist/lib/adapters/groundings/constraint.grounding.d.ts.map +1 -1
  16. package/dist/lib/adapters/groundings/index.js +15 -222
  17. package/dist/lib/adapters/groundings/index.js.map +3 -3
  18. package/dist/lib/adapters/groundings/indexes.grounding.d.ts +1 -1
  19. package/dist/lib/adapters/groundings/indexes.grounding.d.ts.map +1 -1
  20. package/dist/lib/adapters/groundings/info.grounding.d.ts +1 -1
  21. package/dist/lib/adapters/groundings/info.grounding.d.ts.map +1 -1
  22. package/dist/lib/adapters/groundings/report.grounding.d.ts +1 -1
  23. package/dist/lib/adapters/groundings/report.grounding.d.ts.map +1 -1
  24. package/dist/lib/adapters/groundings/row-count.grounding.d.ts +1 -1
  25. package/dist/lib/adapters/groundings/row-count.grounding.d.ts.map +1 -1
  26. package/dist/lib/adapters/groundings/table.grounding.d.ts +3 -3
  27. package/dist/lib/adapters/groundings/table.grounding.d.ts.map +1 -1
  28. package/dist/lib/adapters/groundings/view.grounding.d.ts +1 -1
  29. package/dist/lib/adapters/groundings/view.grounding.d.ts.map +1 -1
  30. package/dist/lib/adapters/mysql/index.js +343 -315
  31. package/dist/lib/adapters/mysql/index.js.map +4 -4
  32. package/dist/lib/adapters/postgres/index.js +385 -357
  33. package/dist/lib/adapters/postgres/index.js.map +4 -4
  34. package/dist/lib/adapters/spreadsheet/index.js +290 -223
  35. package/dist/lib/adapters/spreadsheet/index.js.map +4 -4
  36. package/dist/lib/adapters/sqlite/index.js +307 -279
  37. package/dist/lib/adapters/sqlite/index.js.map +4 -4
  38. package/dist/lib/adapters/sqlserver/index.js +383 -355
  39. package/dist/lib/adapters/sqlserver/index.js.map +4 -4
  40. package/dist/lib/agents/developer.agent.d.ts +33 -23
  41. package/dist/lib/agents/developer.agent.d.ts.map +1 -1
  42. package/dist/lib/agents/sql.agent.d.ts +4 -4
  43. package/dist/lib/agents/sql.agent.d.ts.map +1 -1
  44. package/dist/lib/agents/teachables.agent.d.ts +2 -2
  45. package/dist/lib/agents/teachables.agent.d.ts.map +1 -1
  46. package/dist/lib/agents/text2sql.agent.d.ts +18 -71
  47. package/dist/lib/agents/text2sql.agent.d.ts.map +1 -1
  48. package/dist/lib/fragments/schema.d.ts +214 -0
  49. package/dist/lib/fragments/schema.d.ts.map +1 -0
  50. package/dist/lib/instructions.d.ts +29 -2
  51. package/dist/lib/instructions.d.ts.map +1 -1
  52. package/dist/lib/instructions.js +336 -319
  53. package/dist/lib/instructions.js.map +4 -4
  54. package/dist/lib/sql.d.ts +13 -103
  55. package/dist/lib/sql.d.ts.map +1 -1
  56. package/dist/lib/synthesis/extractors/base-contextual-extractor.d.ts +2 -2
  57. package/dist/lib/synthesis/extractors/base-contextual-extractor.d.ts.map +1 -1
  58. package/dist/lib/synthesis/extractors/message-extractor.d.ts +1 -2
  59. package/dist/lib/synthesis/extractors/message-extractor.d.ts.map +1 -1
  60. package/dist/lib/synthesis/extractors/sql-extractor.d.ts.map +1 -1
  61. package/dist/lib/synthesis/index.js +1794 -572
  62. package/dist/lib/synthesis/index.js.map +4 -4
  63. package/dist/lib/synthesis/synthesizers/depth-evolver.d.ts.map +1 -1
  64. package/dist/lib/synthesis/synthesizers/persona-generator.d.ts +7 -17
  65. package/dist/lib/synthesis/synthesizers/persona-generator.d.ts.map +1 -1
  66. package/dist/lib/synthesis/synthesizers/schema-synthesizer.d.ts +2 -2
  67. package/dist/lib/synthesis/synthesizers/schema-synthesizer.d.ts.map +1 -1
  68. package/dist/lib/synthesis/synthesizers/teachings-generator.d.ts +8 -20
  69. package/dist/lib/synthesis/synthesizers/teachings-generator.d.ts.map +1 -1
  70. package/dist/lib/teach/teachings.d.ts +2 -2
  71. package/dist/lib/teach/teachings.d.ts.map +1 -1
  72. package/package.json +4 -3
  73. package/dist/lib/agents/chat1.agent.d.ts +0 -50
  74. package/dist/lib/agents/chat1.agent.d.ts.map +0 -1
  75. package/dist/lib/agents/chat2.agent.d.ts +0 -68
  76. package/dist/lib/agents/chat2.agent.d.ts.map +0 -1
  77. package/dist/lib/agents/chat3.agent.d.ts +0 -80
  78. package/dist/lib/agents/chat3.agent.d.ts.map +0 -1
  79. package/dist/lib/agents/chat4.agent.d.ts +0 -88
  80. package/dist/lib/agents/chat4.agent.d.ts.map +0 -1
  81. package/dist/lib/history/history.d.ts +0 -41
  82. package/dist/lib/history/history.d.ts.map +0 -1
  83. package/dist/lib/history/memory.history.d.ts +0 -5
  84. package/dist/lib/history/memory.history.d.ts.map +0 -1
  85. package/dist/lib/history/sqlite.history.d.ts +0 -15
  86. package/dist/lib/history/sqlite.history.d.ts.map +0 -1
  87. package/dist/lib/memory/memory.prompt.d.ts +0 -3
  88. package/dist/lib/memory/memory.prompt.d.ts.map +0 -1
  89. package/dist/lib/memory/memory.store.d.ts +0 -5
  90. package/dist/lib/memory/memory.store.d.ts.map +0 -1
  91. package/dist/lib/memory/sqlite.store.d.ts +0 -14
  92. package/dist/lib/memory/sqlite.store.d.ts.map +0 -1
  93. package/dist/lib/memory/store.d.ts +0 -40
  94. package/dist/lib/memory/store.d.ts.map +0 -1
  95. package/dist/lib/teach/teachables.d.ts +0 -648
  96. package/dist/lib/teach/teachables.d.ts.map +0 -1
  97. package/dist/lib/teach/xml.d.ts +0 -6
  98. package/dist/lib/teach/xml.d.ts.map +0 -1
@@ -1,3 +1,94 @@
1
+ // packages/text2sql/src/lib/fragments/schema.ts
2
+ function dialectInfo(input) {
3
+ return {
4
+ name: "dialectInfo",
5
+ data: {
6
+ dialect: input.dialect,
7
+ ...input.version && { version: input.version },
8
+ ...input.database && { database: input.database }
9
+ }
10
+ };
11
+ }
12
+ function table(input) {
13
+ return {
14
+ name: "table",
15
+ data: {
16
+ name: input.name,
17
+ ...input.schema && { schema: input.schema },
18
+ ...input.rowCount != null && { rowCount: input.rowCount },
19
+ ...input.sizeHint && { sizeHint: input.sizeHint },
20
+ columns: input.columns,
21
+ ...input.indexes?.length && { indexes: input.indexes },
22
+ ...input.constraints?.length && { constraints: input.constraints }
23
+ }
24
+ };
25
+ }
26
+ function column(input) {
27
+ return {
28
+ name: "column",
29
+ data: {
30
+ name: input.name,
31
+ type: input.type,
32
+ ...input.pk && { pk: true },
33
+ ...input.fk && { fk: input.fk },
34
+ ...input.unique && { unique: true },
35
+ ...input.notNull && { notNull: true },
36
+ ...input.default && { default: input.default },
37
+ ...input.indexed && { indexed: true },
38
+ ...input.values?.length && { values: input.values },
39
+ ...input.stats && { stats: input.stats }
40
+ }
41
+ };
42
+ }
43
+ function index(input) {
44
+ return {
45
+ name: "index",
46
+ data: {
47
+ name: input.name,
48
+ columns: input.columns,
49
+ ...input.unique && { unique: true },
50
+ ...input.type && { type: input.type }
51
+ }
52
+ };
53
+ }
54
+ function constraint(input) {
55
+ return {
56
+ name: "constraint",
57
+ data: {
58
+ name: input.name,
59
+ type: input.type,
60
+ ...input.columns?.length && { columns: input.columns },
61
+ ...input.definition && { definition: input.definition },
62
+ ...input.defaultValue && { defaultValue: input.defaultValue },
63
+ ...input.referencedTable && { referencedTable: input.referencedTable },
64
+ ...input.referencedColumns?.length && {
65
+ referencedColumns: input.referencedColumns
66
+ }
67
+ }
68
+ };
69
+ }
70
+ function view(input) {
71
+ return {
72
+ name: "view",
73
+ data: {
74
+ name: input.name,
75
+ ...input.schema && { schema: input.schema },
76
+ columns: input.columns,
77
+ ...input.definition && { definition: input.definition }
78
+ }
79
+ };
80
+ }
81
+ function relationship(input) {
82
+ return {
83
+ name: "relationship",
84
+ data: {
85
+ from: input.from,
86
+ to: input.to,
87
+ ...input.cardinality && { cardinality: input.cardinality }
88
+ }
89
+ };
90
+ }
91
+
1
92
  // packages/text2sql/src/lib/adapters/groundings/context.ts
2
93
  function createGroundingContext() {
3
94
  return {
@@ -10,24 +101,169 @@ function createGroundingContext() {
10
101
 
11
102
  // packages/text2sql/src/lib/adapters/adapter.ts
12
103
  var Adapter = class {
104
+ /**
105
+ * Introspect the database schema and return context fragments.
106
+ *
107
+ * Executes all configured groundings to populate the context, then
108
+ * generates fragments from the complete context data.
109
+ *
110
+ * @param ctx - Optional grounding context for sharing state between groundings
111
+ * @returns Array of context fragments representing the database schema
112
+ */
13
113
  async introspect(ctx = createGroundingContext()) {
14
- const lines = [];
15
114
  for (const fn of this.grounding) {
16
115
  const grounding = fn(this);
17
- lines.push({
18
- tag: grounding.tag,
19
- fn: await grounding.execute(ctx)
20
- });
116
+ await grounding.execute(ctx);
117
+ }
118
+ return this.#toSchemaFragments(ctx);
119
+ }
120
+ /**
121
+ * Convert complete grounding context to schema fragments.
122
+ * Called after all groundings have populated ctx with data.
123
+ */
124
+ #toSchemaFragments(ctx) {
125
+ const fragments = [];
126
+ if (ctx.info) {
127
+ fragments.push(
128
+ dialectInfo({
129
+ dialect: ctx.info.dialect,
130
+ version: ctx.info.version,
131
+ database: ctx.info.database
132
+ })
133
+ );
134
+ }
135
+ for (const t of ctx.tables) {
136
+ fragments.push(this.#tableToFragment(t));
137
+ }
138
+ for (const v of ctx.views) {
139
+ fragments.push(this.#viewToFragment(v));
140
+ }
141
+ const tableMap = new Map(ctx.tables.map((t) => [t.name, t]));
142
+ for (const rel of ctx.relationships) {
143
+ const sourceTable = tableMap.get(rel.table);
144
+ const targetTable = tableMap.get(rel.referenced_table);
145
+ fragments.push(
146
+ this.#relationshipToFragment(rel, sourceTable, targetTable)
147
+ );
21
148
  }
22
- return lines.map(({ fn, tag }) => {
23
- const description = fn();
24
- if (description === null) {
25
- return "";
149
+ if (ctx.report) {
150
+ fragments.push({ name: "businessContext", data: ctx.report });
151
+ }
152
+ return fragments;
153
+ }
154
+ /**
155
+ * Convert a Table to a table fragment with nested column, index, and constraint fragments.
156
+ */
157
+ #tableToFragment(t) {
158
+ const pkConstraint = t.constraints?.find((c) => c.type === "PRIMARY_KEY");
159
+ const pkColumns = new Set(pkConstraint?.columns ?? []);
160
+ const notNullColumns = new Set(
161
+ t.constraints?.filter((c) => c.type === "NOT_NULL").flatMap((c) => c.columns ?? []) ?? []
162
+ );
163
+ const defaultByColumn = /* @__PURE__ */ new Map();
164
+ for (const c of t.constraints?.filter((c2) => c2.type === "DEFAULT") ?? []) {
165
+ for (const col of c.columns ?? []) {
166
+ if (c.defaultValue != null) {
167
+ defaultByColumn.set(col, c.defaultValue);
168
+ }
169
+ }
170
+ }
171
+ const uniqueColumns = new Set(
172
+ t.constraints?.filter((c) => c.type === "UNIQUE" && c.columns?.length === 1).flatMap((c) => c.columns ?? []) ?? []
173
+ );
174
+ const fkByColumn = /* @__PURE__ */ new Map();
175
+ for (const c of t.constraints?.filter((c2) => c2.type === "FOREIGN_KEY") ?? []) {
176
+ const cols = c.columns ?? [];
177
+ const refCols = c.referencedColumns ?? [];
178
+ for (let i = 0; i < cols.length; i++) {
179
+ const refCol = refCols[i] ?? refCols[0] ?? cols[i];
180
+ fkByColumn.set(cols[i], `${c.referencedTable}.${refCol}`);
181
+ }
182
+ }
183
+ const columnFragments = t.columns.map(
184
+ (col) => column({
185
+ name: col.name,
186
+ type: col.type,
187
+ pk: pkColumns.has(col.name) || void 0,
188
+ fk: fkByColumn.get(col.name),
189
+ unique: uniqueColumns.has(col.name) || void 0,
190
+ notNull: notNullColumns.has(col.name) || void 0,
191
+ default: defaultByColumn.get(col.name),
192
+ indexed: col.isIndexed || void 0,
193
+ values: col.values,
194
+ stats: col.stats
195
+ })
196
+ );
197
+ const indexFragments = (t.indexes ?? []).map(
198
+ (idx) => index({
199
+ name: idx.name,
200
+ columns: idx.columns,
201
+ unique: idx.unique,
202
+ type: idx.type
203
+ })
204
+ );
205
+ const constraintFragments = (t.constraints ?? []).filter(
206
+ (c) => c.type === "CHECK" || c.type === "UNIQUE" && (c.columns?.length ?? 0) > 1
207
+ ).map(
208
+ (c) => constraint({
209
+ name: c.name,
210
+ type: c.type,
211
+ columns: c.columns,
212
+ definition: c.definition
213
+ })
214
+ );
215
+ return table({
216
+ name: t.name,
217
+ schema: t.schema,
218
+ rowCount: t.rowCount,
219
+ sizeHint: t.sizeHint,
220
+ columns: columnFragments,
221
+ indexes: indexFragments.length > 0 ? indexFragments : void 0,
222
+ constraints: constraintFragments.length > 0 ? constraintFragments : void 0
223
+ });
224
+ }
225
+ /**
226
+ * Convert a View to a view fragment with nested column fragments.
227
+ */
228
+ #viewToFragment(v) {
229
+ const columnFragments = v.columns.map(
230
+ (col) => column({
231
+ name: col.name,
232
+ type: col.type,
233
+ values: col.values,
234
+ stats: col.stats
235
+ })
236
+ );
237
+ return view({
238
+ name: v.name,
239
+ schema: v.schema,
240
+ columns: columnFragments,
241
+ definition: v.definition
242
+ });
243
+ }
244
+ /**
245
+ * Convert a Relationship to a relationship fragment.
246
+ * Infers cardinality from row counts if available.
247
+ */
248
+ #relationshipToFragment(rel, sourceTable, targetTable) {
249
+ const sourceCount = sourceTable?.rowCount;
250
+ const targetCount = targetTable?.rowCount;
251
+ let cardinality;
252
+ if (sourceCount != null && targetCount != null && targetCount > 0) {
253
+ const ratio = sourceCount / targetCount;
254
+ if (ratio > 5) {
255
+ cardinality = "many-to-one";
256
+ } else if (ratio < 1.2 && ratio > 0.8) {
257
+ cardinality = "one-to-one";
258
+ } else if (ratio < 0.2) {
259
+ cardinality = "one-to-many";
26
260
  }
27
- return `<${tag}>
28
- ${description}
29
- </${tag}>`;
30
- }).join("\n");
261
+ }
262
+ return relationship({
263
+ from: { table: rel.table, columns: rel.from },
264
+ to: { table: rel.referenced_table, columns: rel.to },
265
+ cardinality
266
+ });
31
267
  }
32
268
  /**
33
269
  * Convert unknown database value to number.
@@ -83,16 +319,19 @@ ${description}
83
319
 
84
320
  // packages/text2sql/src/lib/adapters/groundings/abstract.grounding.ts
85
321
  var AbstractGrounding = class {
86
- tag;
87
- constructor(tag) {
88
- this.tag = tag;
322
+ /**
323
+ * Grounding identifier for debugging/logging.
324
+ */
325
+ name;
326
+ constructor(name) {
327
+ this.name = name;
89
328
  }
90
329
  };
91
330
 
92
331
  // packages/text2sql/src/lib/adapters/groundings/column-stats.grounding.ts
93
332
  var ColumnStatsGrounding = class extends AbstractGrounding {
94
333
  constructor(config = {}) {
95
- super("column_stats");
334
+ super("columnStats");
96
335
  }
97
336
  /**
98
337
  * Execute the grounding process.
@@ -101,79 +340,73 @@ var ColumnStatsGrounding = class extends AbstractGrounding {
101
340
  async execute(ctx) {
102
341
  const allContainers = [...ctx.tables, ...ctx.views];
103
342
  for (const container of allContainers) {
104
- for (const column of container.columns) {
343
+ for (const column2 of container.columns) {
105
344
  try {
106
- const stats = await this.collectStats(container.name, column);
345
+ const stats = await this.collectStats(container.name, column2);
107
346
  if (stats) {
108
- column.stats = stats;
347
+ column2.stats = stats;
109
348
  }
110
349
  } catch (error) {
111
350
  console.warn(
112
351
  "Error collecting stats for",
113
352
  container.name,
114
- column.name,
353
+ column2.name,
115
354
  error
116
355
  );
117
356
  }
118
357
  }
119
358
  }
120
- return () => this.#describe();
121
- }
122
- #describe() {
123
- return null;
124
359
  }
125
360
  };
126
361
 
127
362
  // packages/text2sql/src/lib/adapters/groundings/constraint.grounding.ts
128
363
  var ConstraintGrounding = class extends AbstractGrounding {
129
364
  constructor(config = {}) {
130
- super("constraints");
365
+ super("constraint");
131
366
  }
132
367
  /**
133
368
  * Execute the grounding process.
134
369
  * Annotates tables in ctx.tables with their constraints.
135
370
  */
136
371
  async execute(ctx) {
137
- for (const table of ctx.tables) {
372
+ for (const table2 of ctx.tables) {
138
373
  try {
139
- table.constraints = await this.getConstraints(table.name);
374
+ table2.constraints = await this.getConstraints(table2.name);
140
375
  } catch (error) {
141
- console.warn("Error collecting constraints for", table.name, error);
376
+ console.warn("Error collecting constraints for", table2.name, error);
142
377
  }
143
378
  }
144
- return () => null;
145
379
  }
146
380
  };
147
381
 
148
382
  // packages/text2sql/src/lib/adapters/groundings/indexes.grounding.ts
149
383
  var IndexesGrounding = class extends AbstractGrounding {
150
384
  constructor(config = {}) {
151
- super("indexes");
385
+ super("index");
152
386
  }
153
387
  /**
154
388
  * Execute the grounding process.
155
389
  * Annotates tables in ctx.tables with their indexes and marks indexed columns.
156
390
  */
157
391
  async execute(ctx) {
158
- for (const table of ctx.tables) {
159
- table.indexes = await this.getIndexes(table.name);
160
- for (const index of table.indexes ?? []) {
161
- for (const colName of index.columns) {
162
- const column = table.columns.find((c) => c.name === colName);
163
- if (column) {
164
- column.isIndexed = true;
392
+ for (const table2 of ctx.tables) {
393
+ table2.indexes = await this.getIndexes(table2.name);
394
+ for (const index2 of table2.indexes ?? []) {
395
+ for (const colName of index2.columns) {
396
+ const column2 = table2.columns.find((c) => c.name === colName);
397
+ if (column2) {
398
+ column2.isIndexed = true;
165
399
  }
166
400
  }
167
401
  }
168
402
  }
169
- return () => null;
170
403
  }
171
404
  };
172
405
 
173
406
  // packages/text2sql/src/lib/adapters/groundings/info.grounding.ts
174
407
  var InfoGrounding = class extends AbstractGrounding {
175
408
  constructor(config = {}) {
176
- super("dialect_info");
409
+ super("dialectInfo");
177
410
  }
178
411
  /**
179
412
  * Execute the grounding process.
@@ -181,17 +414,6 @@ var InfoGrounding = class extends AbstractGrounding {
181
414
  */
182
415
  async execute(ctx) {
183
416
  ctx.info = await this.collectInfo();
184
- const lines = [`Dialect: ${ctx.info.dialect ?? "unknown"}`];
185
- if (ctx.info.version) {
186
- lines.push(`Version: ${ctx.info.version}`);
187
- }
188
- if (ctx.info.database) {
189
- lines.push(`Database: ${ctx.info.database}`);
190
- }
191
- if (ctx.info.details && Object.keys(ctx.info.details).length) {
192
- lines.push(`Details: ${JSON.stringify(ctx.info.details)}`);
193
- }
194
- return () => lines.join("\n");
195
417
  }
196
418
  };
197
419
 
@@ -199,7 +421,7 @@ var InfoGrounding = class extends AbstractGrounding {
199
421
  var ColumnValuesGrounding = class extends AbstractGrounding {
200
422
  lowCardinalityLimit;
201
423
  constructor(config = {}) {
202
- super("column_values");
424
+ super("columnValues");
203
425
  this.lowCardinalityLimit = config.lowCardinalityLimit ?? 20;
204
426
  }
205
427
  /**
@@ -217,14 +439,14 @@ var ColumnValuesGrounding = class extends AbstractGrounding {
217
439
  * - CHECK ((status)::text = ANY (ARRAY['a'::text, 'b'::text]))
218
440
  * - CHECK (status = 'active' OR status = 'inactive')
219
441
  */
220
- parseCheckConstraint(constraint, columnName) {
221
- if (constraint.type !== "CHECK" || !constraint.definition) {
442
+ parseCheckConstraint(constraint2, columnName) {
443
+ if (constraint2.type !== "CHECK" || !constraint2.definition) {
222
444
  return void 0;
223
445
  }
224
- if (constraint.columns && !constraint.columns.includes(columnName)) {
446
+ if (constraint2.columns && !constraint2.columns.includes(columnName)) {
225
447
  return void 0;
226
448
  }
227
- const def = constraint.definition;
449
+ const def = constraint2.definition;
228
450
  const escapedCol = this.escapeRegex(columnName);
229
451
  const colPattern = `(?:\\(?\\(?${escapedCol}\\)?(?:::(?:text|varchar|character varying))?\\)?)`;
230
452
  const inMatch = def.match(
@@ -282,55 +504,51 @@ var ColumnValuesGrounding = class extends AbstractGrounding {
282
504
  async execute(ctx) {
283
505
  const allContainers = [...ctx.tables, ...ctx.views];
284
506
  for (const container of allContainers) {
285
- const table = this.getTable(ctx, container.name);
286
- for (const column of container.columns) {
507
+ const table2 = this.getTable(ctx, container.name);
508
+ for (const column2 of container.columns) {
287
509
  try {
288
510
  const result = await this.resolveColumnValues(
289
511
  container.name,
290
- column,
291
- table?.constraints
512
+ column2,
513
+ table2?.constraints
292
514
  );
293
515
  if (result) {
294
- column.kind = result.kind;
295
- column.values = result.values;
516
+ column2.kind = result.kind;
517
+ column2.values = result.values;
296
518
  }
297
519
  } catch (error) {
298
520
  console.warn(
299
521
  "Error collecting column values for",
300
522
  container.name,
301
- column.name,
523
+ column2.name,
302
524
  error
303
525
  );
304
526
  }
305
527
  }
306
528
  }
307
- return () => this.#describe();
308
529
  }
309
530
  /**
310
531
  * Resolve column values from all sources in priority order.
311
532
  */
312
- async resolveColumnValues(tableName, column, constraints2) {
313
- const enumValues = await this.collectEnumValues(tableName, column);
533
+ async resolveColumnValues(tableName, column2, constraints2) {
534
+ const enumValues = await this.collectEnumValues(tableName, column2);
314
535
  if (enumValues?.length) {
315
536
  return { kind: "Enum", values: enumValues };
316
537
  }
317
538
  if (constraints2) {
318
- for (const constraint of constraints2) {
319
- const checkValues = this.parseCheckConstraint(constraint, column.name);
539
+ for (const constraint2 of constraints2) {
540
+ const checkValues = this.parseCheckConstraint(constraint2, column2.name);
320
541
  if (checkValues?.length) {
321
542
  return { kind: "Enum", values: checkValues };
322
543
  }
323
544
  }
324
545
  }
325
- const lowCardValues = await this.collectLowCardinality(tableName, column);
546
+ const lowCardValues = await this.collectLowCardinality(tableName, column2);
326
547
  if (lowCardValues?.length) {
327
548
  return { kind: "LowCardinality", values: lowCardValues };
328
549
  }
329
550
  return void 0;
330
551
  }
331
- #describe() {
332
- return null;
333
- }
334
552
  };
335
553
 
336
554
  // packages/text2sql/src/lib/adapters/groundings/report.grounding.ts
@@ -402,7 +620,7 @@ var ReportGrounding = class extends AbstractGrounding {
402
620
  const cached = await this.#cache.get();
403
621
  if (cached) {
404
622
  ctx.report = cached;
405
- return () => cached;
623
+ return;
406
624
  }
407
625
  }
408
626
  const report2 = await this.#generateReport();
@@ -410,7 +628,6 @@ var ReportGrounding = class extends AbstractGrounding {
410
628
  if (this.#cache) {
411
629
  await this.#cache.set(report2);
412
630
  }
413
- return () => report2;
414
631
  }
415
632
  async #generateReport() {
416
633
  const { text } = await generate(
@@ -429,21 +646,20 @@ var ReportGrounding = class extends AbstractGrounding {
429
646
  // packages/text2sql/src/lib/adapters/groundings/row-count.grounding.ts
430
647
  var RowCountGrounding = class extends AbstractGrounding {
431
648
  constructor(config = {}) {
432
- super("row_counts");
649
+ super("rowCount");
433
650
  }
434
651
  /**
435
652
  * Execute the grounding process.
436
653
  * Annotates tables in ctx.tables with row counts and size hints.
437
654
  */
438
655
  async execute(ctx) {
439
- for (const table of ctx.tables) {
440
- const count = await this.getRowCount(table.name);
656
+ for (const table2 of ctx.tables) {
657
+ const count = await this.getRowCount(table2.name);
441
658
  if (count != null) {
442
- table.rowCount = count;
443
- table.sizeHint = this.#classifyRowCount(count);
659
+ table2.rowCount = count;
660
+ table2.sizeHint = this.#classifyRowCount(count);
444
661
  }
445
662
  }
446
- return () => null;
447
663
  }
448
664
  /**
449
665
  * Classify row count into a size hint category.
@@ -458,13 +674,12 @@ var RowCountGrounding = class extends AbstractGrounding {
458
674
  };
459
675
 
460
676
  // packages/text2sql/src/lib/adapters/groundings/table.grounding.ts
461
- import pluralize from "pluralize";
462
677
  var TableGrounding = class extends AbstractGrounding {
463
678
  #filter;
464
679
  #forward;
465
680
  #backward;
466
681
  constructor(config = {}) {
467
- super("tables");
682
+ super("table");
468
683
  this.#filter = config.filter;
469
684
  this.#forward = config.forward;
470
685
  this.#backward = config.backward;
@@ -482,7 +697,7 @@ var TableGrounding = class extends AbstractGrounding {
482
697
  seedTables.map((name) => this.getTable(name))
483
698
  );
484
699
  ctx.tables.push(...tables3);
485
- return () => this.#describeTables(tables3);
700
+ return;
486
701
  }
487
702
  const tables2 = {};
488
703
  const allRelationships = [];
@@ -538,7 +753,6 @@ var TableGrounding = class extends AbstractGrounding {
538
753
  const tablesList = Object.values(tables2);
539
754
  ctx.tables.push(...tablesList);
540
755
  ctx.relationships.push(...allRelationships);
541
- return () => this.#describeTables(tablesList);
542
756
  }
543
757
  /**
544
758
  * Apply the filter to get seed table names.
@@ -568,156 +782,6 @@ var TableGrounding = class extends AbstractGrounding {
568
782
  all.push(rel);
569
783
  }
570
784
  }
571
- #describeTables(tables2) {
572
- if (!tables2.length) {
573
- return "Schema unavailable.";
574
- }
575
- return tables2.map((table) => {
576
- const rowCountInfo = table.rowCount != null ? ` [rows: ${table.rowCount}${table.sizeHint ? `, size: ${table.sizeHint}` : ""}]` : "";
577
- const pkConstraint = table.constraints?.find(
578
- (c) => c.type === "PRIMARY_KEY"
579
- );
580
- const pkColumns = new Set(pkConstraint?.columns ?? []);
581
- const notNullColumns = new Set(
582
- table.constraints?.filter((c) => c.type === "NOT_NULL").flatMap((c) => c.columns ?? []) ?? []
583
- );
584
- const defaultByColumn = /* @__PURE__ */ new Map();
585
- for (const c of table.constraints?.filter(
586
- (c2) => c2.type === "DEFAULT"
587
- ) ?? []) {
588
- for (const col of c.columns ?? []) {
589
- if (c.defaultValue != null) {
590
- defaultByColumn.set(col, c.defaultValue);
591
- }
592
- }
593
- }
594
- const uniqueColumns = new Set(
595
- table.constraints?.filter((c) => c.type === "UNIQUE" && c.columns?.length === 1).flatMap((c) => c.columns ?? []) ?? []
596
- );
597
- const fkByColumn = /* @__PURE__ */ new Map();
598
- for (const c of table.constraints?.filter(
599
- (c2) => c2.type === "FOREIGN_KEY"
600
- ) ?? []) {
601
- const cols = c.columns ?? [];
602
- const refCols = c.referencedColumns ?? [];
603
- for (let i = 0; i < cols.length; i++) {
604
- const refCol = refCols[i] ?? refCols[0] ?? cols[i];
605
- fkByColumn.set(cols[i], `${c.referencedTable}.${refCol}`);
606
- }
607
- }
608
- const columns = table.columns.map((column) => {
609
- const annotations = [];
610
- const isPrimaryKey = pkColumns.has(column.name);
611
- if (isPrimaryKey) {
612
- annotations.push("PK");
613
- }
614
- if (fkByColumn.has(column.name)) {
615
- annotations.push(`FK -> ${fkByColumn.get(column.name)}`);
616
- }
617
- if (uniqueColumns.has(column.name)) {
618
- annotations.push("UNIQUE");
619
- }
620
- if (notNullColumns.has(column.name)) {
621
- annotations.push("NOT NULL");
622
- }
623
- if (defaultByColumn.has(column.name)) {
624
- annotations.push(`DEFAULT: ${defaultByColumn.get(column.name)}`);
625
- }
626
- if (column.isIndexed && !isPrimaryKey) {
627
- annotations.push("Indexed");
628
- }
629
- if (column.kind === "Enum" && column.values?.length) {
630
- annotations.push(`Enum: ${column.values.join(", ")}`);
631
- } else if (column.kind === "LowCardinality" && column.values?.length) {
632
- annotations.push(`LowCardinality: ${column.values.join(", ")}`);
633
- }
634
- if (column.stats) {
635
- const statParts = [];
636
- if (column.stats.min != null || column.stats.max != null) {
637
- const minText = column.stats.min ?? "n/a";
638
- const maxText = column.stats.max ?? "n/a";
639
- statParts.push(`range ${minText} \u2192 ${maxText}`);
640
- }
641
- if (column.stats.nullFraction != null && Number.isFinite(column.stats.nullFraction)) {
642
- const percent = Math.round(column.stats.nullFraction * 1e3) / 10;
643
- statParts.push(`null\u2248${percent}%`);
644
- }
645
- if (statParts.length) {
646
- annotations.push(statParts.join(", "));
647
- }
648
- }
649
- const annotationText = annotations.length ? ` [${annotations.join(", ")}]` : "";
650
- return ` - ${column.name} (${column.type})${annotationText}`;
651
- }).join("\n");
652
- const indexes2 = table.indexes?.length ? `
653
- Indexes:
654
- ${table.indexes.map((index) => {
655
- const props = [];
656
- if (index.unique) {
657
- props.push("UNIQUE");
658
- }
659
- if (index.type) {
660
- props.push(index.type);
661
- }
662
- const propsText = props.length ? ` (${props.join(", ")})` : "";
663
- const columnsText = index.columns?.length ? index.columns.join(", ") : "expression";
664
- return ` - ${index.name}${propsText}: ${columnsText}`;
665
- }).join("\n")}` : "";
666
- const multiColumnUniques = table.constraints?.filter(
667
- (c) => c.type === "UNIQUE" && (c.columns?.length ?? 0) > 1
668
- ) ?? [];
669
- const uniqueConstraints = multiColumnUniques.length ? `
670
- Unique Constraints:
671
- ${multiColumnUniques.map((c) => ` - ${c.name}: (${c.columns?.join(", ")})`).join("\n")}` : "";
672
- const checkConstraints = table.constraints?.filter((c) => c.type === "CHECK") ?? [];
673
- const checks = checkConstraints.length ? `
674
- Check Constraints:
675
- ${checkConstraints.map((c) => ` - ${c.name}: ${c.definition}`).join("\n")}` : "";
676
- return `- Table: ${table.name}${rowCountInfo}
677
- Columns:
678
- ${columns}${indexes2}${uniqueConstraints}${checks}`;
679
- }).join("\n\n");
680
- }
681
- #formatTableLabel = (tableName) => {
682
- const base = tableName.split(".").pop() ?? tableName;
683
- return base.replace(/_/g, " ");
684
- };
685
- #describeRelationships = (tables2, relationships) => {
686
- if (!relationships.length) {
687
- return "None detected";
688
- }
689
- const tableMap = new Map(tables2.map((table) => [table.name, table]));
690
- return relationships.map((relationship) => {
691
- const sourceLabel = this.#formatTableLabel(relationship.table);
692
- const targetLabel = this.#formatTableLabel(
693
- relationship.referenced_table
694
- );
695
- const singularSource = pluralize.singular(sourceLabel);
696
- const pluralSource = pluralize.plural(sourceLabel);
697
- const singularTarget = pluralize.singular(targetLabel);
698
- const pluralTarget = pluralize.plural(targetLabel);
699
- const sourceTable = tableMap.get(relationship.table);
700
- const targetTable = tableMap.get(relationship.referenced_table);
701
- const sourceCount = sourceTable?.rowCount;
702
- const targetCount = targetTable?.rowCount;
703
- const ratio = sourceCount != null && targetCount != null && targetCount > 0 ? sourceCount / targetCount : null;
704
- let cardinality = "each";
705
- if (ratio != null) {
706
- if (ratio > 5) {
707
- cardinality = `many-to-one (\u2248${sourceCount} vs ${targetCount})`;
708
- } else if (ratio < 1.2 && ratio > 0.8) {
709
- cardinality = `roughly 1:1 (${sourceCount} vs ${targetCount})`;
710
- } else if (ratio < 0.2) {
711
- cardinality = `one-to-many (${sourceCount} vs ${targetCount})`;
712
- }
713
- }
714
- const mappings = relationship.from.map((fromCol, idx) => {
715
- const targetCol = relationship.to[idx] ?? relationship.to[0] ?? fromCol;
716
- return `${relationship.table}.${fromCol} -> ${relationship.referenced_table}.${targetCol}`;
717
- }).join(", ");
718
- return `- ${relationship.table} (${relationship.from.join(", ")}) -> ${relationship.referenced_table} (${relationship.to.join(", ")}) [${cardinality}]`;
719
- }).join("\n");
720
- };
721
785
  };
722
786
 
723
787
  // packages/text2sql/src/lib/adapters/sqlite/column-stats.sqlite.grounding.ts
@@ -727,12 +791,12 @@ var SqliteColumnStatsGrounding = class extends ColumnStatsGrounding {
727
791
  super(config);
728
792
  this.#adapter = adapter;
729
793
  }
730
- async collectStats(tableName, column) {
731
- if (!this.#shouldCollectStats(column.type)) {
794
+ async collectStats(tableName, column2) {
795
+ if (!this.#shouldCollectStats(column2.type)) {
732
796
  return void 0;
733
797
  }
734
798
  const tableIdentifier = this.#adapter.quoteIdentifier(tableName);
735
- const columnIdentifier = this.#adapter.quoteIdentifier(column.name);
799
+ const columnIdentifier = this.#adapter.quoteIdentifier(column2.name);
736
800
  const sql = `
737
801
  SELECT
738
802
  MIN(${columnIdentifier}) AS min_value,
@@ -862,9 +926,9 @@ var SqliteConstraintGrounding = class extends ConstraintGrounding {
862
926
  const constraints2 = [];
863
927
  const checkStartRegex = /(?:CONSTRAINT\s+["'`]?(\w+)["'`]?\s+)?CHECK\s*\(/gi;
864
928
  let startMatch;
865
- let index = 0;
929
+ let index2 = 0;
866
930
  while ((startMatch = checkStartRegex.exec(ddl)) !== null) {
867
- const name = startMatch[1] || `${tableName}_check_${index}`;
931
+ const name = startMatch[1] || `${tableName}_check_${index2}`;
868
932
  const startPos = startMatch.index + startMatch[0].length;
869
933
  let depth = 1;
870
934
  let endPos = startPos;
@@ -886,7 +950,7 @@ var SqliteConstraintGrounding = class extends ConstraintGrounding {
886
950
  definition,
887
951
  columns: constraintColumns.length > 0 ? constraintColumns : void 0
888
952
  });
889
- index++;
953
+ index2++;
890
954
  }
891
955
  }
892
956
  }
@@ -974,9 +1038,9 @@ var SqliteColumnValuesGrounding = class extends ColumnValuesGrounding {
974
1038
  super(config);
975
1039
  this.#adapter = adapter;
976
1040
  }
977
- async collectLowCardinality(tableName, column) {
1041
+ async collectLowCardinality(tableName, column2) {
978
1042
  const tableIdentifier = this.#adapter.quoteIdentifier(tableName);
979
- const columnIdentifier = this.#adapter.quoteIdentifier(column.name);
1043
+ const columnIdentifier = this.#adapter.quoteIdentifier(column2.name);
980
1044
  const limit = this.lowCardinalityLimit + 1;
981
1045
  const sql = `
982
1046
  SELECT DISTINCT ${columnIdentifier} AS value
@@ -1217,7 +1281,7 @@ var SqliteTableGrounding = class extends TableGrounding {
1217
1281
  var ViewGrounding = class extends AbstractGrounding {
1218
1282
  #filter;
1219
1283
  constructor(config = {}) {
1220
- super("views");
1284
+ super("view");
1221
1285
  this.#filter = config.filter;
1222
1286
  }
1223
1287
  /**
@@ -1230,42 +1294,6 @@ var ViewGrounding = class extends AbstractGrounding {
1230
1294
  viewNames.map((name) => this.getView(name))
1231
1295
  );
1232
1296
  ctx.views.push(...views2);
1233
- return () => this.#describe(views2);
1234
- }
1235
- #describe(views2) {
1236
- if (!views2.length) {
1237
- return "No views available.";
1238
- }
1239
- return views2.map((view) => {
1240
- const columns = view.columns.map((column) => {
1241
- const annotations = [];
1242
- if (column.kind === "LowCardinality" && column.values?.length) {
1243
- annotations.push(`LowCardinality: ${column.values.join(", ")}`);
1244
- }
1245
- if (column.stats) {
1246
- const statParts = [];
1247
- if (column.stats.min != null || column.stats.max != null) {
1248
- const minText = column.stats.min ?? "n/a";
1249
- const maxText = column.stats.max ?? "n/a";
1250
- statParts.push(`range ${minText} \u2192 ${maxText}`);
1251
- }
1252
- if (column.stats.nullFraction != null && Number.isFinite(column.stats.nullFraction)) {
1253
- const percent = Math.round(column.stats.nullFraction * 1e3) / 10;
1254
- statParts.push(`null\u2248${percent}%`);
1255
- }
1256
- if (statParts.length) {
1257
- annotations.push(statParts.join(", "));
1258
- }
1259
- }
1260
- const annotationText = annotations.length ? ` [${annotations.join(", ")}]` : "";
1261
- return ` - ${column.name} (${column.type})${annotationText}`;
1262
- }).join("\n");
1263
- const definition = view.definition ? `
1264
- Definition: ${view.definition.length > 200 ? view.definition.slice(0, 200) + "..." : view.definition}` : "";
1265
- return `- View: ${view.name}${definition}
1266
- Columns:
1267
- ${columns}`;
1268
- }).join("\n\n");
1269
1297
  }
1270
1298
  /**
1271
1299
  * Apply the filter to get view names.