@deepagents/text2sql 0.3.1 → 0.7.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 (167) hide show
  1. package/README.md +167 -0
  2. package/dist/finetune/convert-to-gguf.d.ts +18 -0
  3. package/dist/finetune/convert-to-gguf.d.ts.map +1 -0
  4. package/dist/finetune/run-finetune.d.ts +23 -0
  5. package/dist/finetune/run-finetune.d.ts.map +1 -0
  6. package/dist/finetune/run-mlx.d.ts +22 -0
  7. package/dist/finetune/run-mlx.d.ts.map +1 -0
  8. package/dist/index.d.ts +4 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +2500 -318
  11. package/dist/index.js.map +4 -4
  12. package/dist/lib/adapters/adapter.d.ts +3 -3
  13. package/dist/lib/adapters/adapter.d.ts.map +1 -1
  14. package/dist/lib/adapters/{grounding.ticket.d.ts → groundings/abstract.grounding.d.ts} +2 -2
  15. package/dist/lib/adapters/groundings/abstract.grounding.d.ts.map +1 -0
  16. package/dist/lib/adapters/groundings/column-stats.grounding.d.ts +1 -1
  17. package/dist/lib/adapters/groundings/column-stats.grounding.d.ts.map +1 -1
  18. package/dist/lib/adapters/groundings/column-values.grounding.d.ts +76 -0
  19. package/dist/lib/adapters/groundings/column-values.grounding.d.ts.map +1 -0
  20. package/dist/lib/adapters/groundings/constraint.grounding.d.ts +1 -1
  21. package/dist/lib/adapters/groundings/constraint.grounding.d.ts.map +1 -1
  22. package/dist/lib/adapters/groundings/context.d.ts +1 -1
  23. package/dist/lib/adapters/groundings/context.d.ts.map +1 -1
  24. package/dist/lib/adapters/groundings/{grounding.d.ts → index.d.ts} +8 -5
  25. package/dist/lib/adapters/groundings/index.d.ts.map +1 -0
  26. package/dist/lib/adapters/groundings/{grounding.js → index.js} +411 -206
  27. package/dist/lib/adapters/groundings/index.js.map +7 -0
  28. package/dist/lib/adapters/groundings/indexes.grounding.d.ts +1 -1
  29. package/dist/lib/adapters/groundings/indexes.grounding.d.ts.map +1 -1
  30. package/dist/lib/adapters/groundings/info.grounding.d.ts +1 -1
  31. package/dist/lib/adapters/groundings/info.grounding.d.ts.map +1 -1
  32. package/dist/lib/adapters/groundings/report.grounding.d.ts +1 -1
  33. package/dist/lib/adapters/groundings/report.grounding.d.ts.map +1 -1
  34. package/dist/lib/adapters/groundings/row-count.grounding.d.ts +1 -1
  35. package/dist/lib/adapters/groundings/row-count.grounding.d.ts.map +1 -1
  36. package/dist/lib/adapters/groundings/table.grounding.d.ts +1 -1
  37. package/dist/lib/adapters/groundings/table.grounding.d.ts.map +1 -1
  38. package/dist/lib/adapters/groundings/view.grounding.d.ts +1 -1
  39. package/dist/lib/adapters/groundings/view.grounding.d.ts.map +1 -1
  40. package/dist/lib/adapters/mysql/column-stats.mysql.grounding.d.ts +14 -0
  41. package/dist/lib/adapters/mysql/column-stats.mysql.grounding.d.ts.map +1 -0
  42. package/dist/lib/adapters/mysql/column-values.mysql.grounding.d.ts +22 -0
  43. package/dist/lib/adapters/mysql/column-values.mysql.grounding.d.ts.map +1 -0
  44. package/dist/lib/adapters/mysql/constraint.mysql.grounding.d.ts +13 -0
  45. package/dist/lib/adapters/mysql/constraint.mysql.grounding.d.ts.map +1 -0
  46. package/dist/lib/adapters/mysql/index.d.ts +44 -0
  47. package/dist/lib/adapters/mysql/index.d.ts.map +1 -0
  48. package/dist/lib/adapters/mysql/indexes.mysql.grounding.d.ts +13 -0
  49. package/dist/lib/adapters/mysql/indexes.mysql.grounding.d.ts.map +1 -0
  50. package/dist/lib/adapters/mysql/info.mysql.grounding.d.ts +13 -0
  51. package/dist/lib/adapters/mysql/info.mysql.grounding.d.ts.map +1 -0
  52. package/dist/lib/adapters/mysql/mysql.d.ts +33 -0
  53. package/dist/lib/adapters/mysql/mysql.d.ts.map +1 -0
  54. package/dist/lib/adapters/mysql/row-count.mysql.grounding.d.ts +13 -0
  55. package/dist/lib/adapters/mysql/row-count.mysql.grounding.d.ts.map +1 -0
  56. package/dist/lib/adapters/mysql/table.mysql.grounding.d.ts +21 -0
  57. package/dist/lib/adapters/mysql/table.mysql.grounding.d.ts.map +1 -0
  58. package/dist/lib/adapters/mysql/view.mysql.grounding.d.ts +18 -0
  59. package/dist/lib/adapters/mysql/view.mysql.grounding.d.ts.map +1 -0
  60. package/dist/lib/adapters/postgres/column-stats.postgres.grounding.d.ts.map +1 -1
  61. package/dist/lib/adapters/postgres/column-values.postgres.grounding.d.ts +17 -0
  62. package/dist/lib/adapters/postgres/column-values.postgres.grounding.d.ts.map +1 -0
  63. package/dist/lib/adapters/postgres/index.d.ts +4 -4
  64. package/dist/lib/adapters/postgres/index.d.ts.map +1 -1
  65. package/dist/lib/adapters/postgres/index.js +233 -33
  66. package/dist/lib/adapters/postgres/index.js.map +4 -4
  67. package/dist/lib/adapters/sqlite/column-values.sqlite.grounding.d.ts +17 -0
  68. package/dist/lib/adapters/sqlite/column-values.sqlite.grounding.d.ts.map +1 -0
  69. package/dist/lib/adapters/sqlite/constraint.sqlite.grounding.d.ts.map +1 -1
  70. package/dist/lib/adapters/sqlite/index.d.ts +4 -4
  71. package/dist/lib/adapters/sqlite/index.d.ts.map +1 -1
  72. package/dist/lib/adapters/sqlite/index.js +214 -46
  73. package/dist/lib/adapters/sqlite/index.js.map +4 -4
  74. package/dist/lib/adapters/sqlserver/column-values.sqlserver.grounding.d.ts +17 -0
  75. package/dist/lib/adapters/sqlserver/column-values.sqlserver.grounding.d.ts.map +1 -0
  76. package/dist/lib/adapters/sqlserver/index.d.ts +4 -4
  77. package/dist/lib/adapters/sqlserver/index.d.ts.map +1 -1
  78. package/dist/lib/adapters/sqlserver/index.js +179 -32
  79. package/dist/lib/adapters/sqlserver/index.js.map +4 -4
  80. package/dist/lib/agents/bi.agent.d.ts +14 -0
  81. package/dist/lib/agents/bi.agent.d.ts.map +1 -0
  82. package/dist/lib/agents/chat1.agent.d.ts +50 -0
  83. package/dist/lib/agents/chat1.agent.d.ts.map +1 -0
  84. package/dist/lib/agents/chat2.agent.d.ts +68 -0
  85. package/dist/lib/agents/chat2.agent.d.ts.map +1 -0
  86. package/dist/lib/agents/chat3.agent.d.ts +80 -0
  87. package/dist/lib/agents/chat3.agent.d.ts.map +1 -0
  88. package/dist/lib/agents/chat4.agent.d.ts +88 -0
  89. package/dist/lib/agents/chat4.agent.d.ts.map +1 -0
  90. package/dist/lib/agents/developer.agent.d.ts +31 -0
  91. package/dist/lib/agents/developer.agent.d.ts.map +1 -0
  92. package/dist/lib/agents/question.agent.d.ts +23 -0
  93. package/dist/lib/agents/question.agent.d.ts.map +1 -0
  94. package/dist/lib/agents/sql.agent.d.ts +44 -0
  95. package/dist/lib/agents/sql.agent.d.ts.map +1 -0
  96. package/dist/lib/agents/teachables.agent.d.ts +8 -9
  97. package/dist/lib/agents/teachables.agent.d.ts.map +1 -1
  98. package/dist/lib/agents/text2sql.agent.d.ts +0 -1
  99. package/dist/lib/agents/text2sql.agent.d.ts.map +1 -1
  100. package/dist/lib/checkpoint.d.ts +99 -0
  101. package/dist/lib/checkpoint.d.ts.map +1 -0
  102. package/dist/lib/instructions.js +50 -21
  103. package/dist/lib/instructions.js.map +2 -2
  104. package/dist/lib/sql.d.ts +125 -3
  105. package/dist/lib/sql.d.ts.map +1 -1
  106. package/dist/lib/syntheize.d.ts +2 -0
  107. package/dist/lib/syntheize.d.ts.map +1 -0
  108. package/dist/lib/synthesis/decorators/deduplicated-producer.d.ts +26 -0
  109. package/dist/lib/synthesis/decorators/deduplicated-producer.d.ts.map +1 -0
  110. package/dist/lib/synthesis/decorators/filtered-producer.d.ts +26 -0
  111. package/dist/lib/synthesis/decorators/filtered-producer.d.ts.map +1 -0
  112. package/dist/lib/synthesis/decorators/index.d.ts +7 -0
  113. package/dist/lib/synthesis/decorators/index.d.ts.map +1 -0
  114. package/dist/lib/synthesis/decorators/validated-producer.d.ts +33 -0
  115. package/dist/lib/synthesis/decorators/validated-producer.d.ts.map +1 -0
  116. package/dist/lib/synthesis/extractors/base-contextual-extractor.d.ts +76 -0
  117. package/dist/lib/synthesis/extractors/base-contextual-extractor.d.ts.map +1 -0
  118. package/dist/lib/synthesis/extractors/full-context-extractor.d.ts +25 -0
  119. package/dist/lib/synthesis/extractors/full-context-extractor.d.ts.map +1 -0
  120. package/dist/lib/synthesis/extractors/index.d.ts +8 -0
  121. package/dist/lib/synthesis/extractors/index.d.ts.map +1 -0
  122. package/dist/lib/synthesis/extractors/last-query-extractor.d.ts +30 -0
  123. package/dist/lib/synthesis/extractors/last-query-extractor.d.ts.map +1 -0
  124. package/dist/lib/synthesis/extractors/message-extractor.d.ts +27 -0
  125. package/dist/lib/synthesis/extractors/message-extractor.d.ts.map +1 -0
  126. package/dist/lib/synthesis/extractors/segmented-context-extractor.d.ts +48 -0
  127. package/dist/lib/synthesis/extractors/segmented-context-extractor.d.ts.map +1 -0
  128. package/dist/lib/synthesis/extractors/sql-extractor.d.ts +27 -0
  129. package/dist/lib/synthesis/extractors/sql-extractor.d.ts.map +1 -0
  130. package/dist/lib/synthesis/extractors/windowed-context-extractor.d.ts +30 -0
  131. package/dist/lib/synthesis/extractors/windowed-context-extractor.d.ts.map +1 -0
  132. package/dist/lib/synthesis/index.d.ts +6 -0
  133. package/dist/lib/synthesis/index.d.ts.map +1 -0
  134. package/dist/lib/synthesis/index.js +2172 -0
  135. package/dist/lib/synthesis/index.js.map +7 -0
  136. package/dist/lib/synthesis/synthesizers/breadth-evolver.d.ts +34 -0
  137. package/dist/lib/synthesis/synthesizers/breadth-evolver.d.ts.map +1 -0
  138. package/dist/lib/synthesis/synthesizers/depth-evolver.d.ts +41 -0
  139. package/dist/lib/synthesis/synthesizers/depth-evolver.d.ts.map +1 -0
  140. package/dist/lib/synthesis/synthesizers/index.d.ts +7 -0
  141. package/dist/lib/synthesis/synthesizers/index.d.ts.map +1 -0
  142. package/dist/lib/synthesis/synthesizers/persona-generator.d.ts +34 -0
  143. package/dist/lib/synthesis/synthesizers/persona-generator.d.ts.map +1 -0
  144. package/dist/lib/synthesis/synthesizers/schema-synthesizer.d.ts +39 -0
  145. package/dist/lib/synthesis/synthesizers/schema-synthesizer.d.ts.map +1 -0
  146. package/dist/lib/synthesis/synthesizers/styles.d.ts +8 -0
  147. package/dist/lib/synthesis/synthesizers/styles.d.ts.map +1 -0
  148. package/dist/lib/synthesis/synthesizers/teachings-generator.d.ts +32 -0
  149. package/dist/lib/synthesis/synthesizers/teachings-generator.d.ts.map +1 -0
  150. package/dist/lib/synthesis/types.d.ts +26 -0
  151. package/dist/lib/synthesis/types.d.ts.map +1 -0
  152. package/dist/lib/teach/teachables.d.ts +18 -3
  153. package/dist/lib/teach/teachables.d.ts.map +1 -1
  154. package/dist/lib/teach/teachings.d.ts +9 -2
  155. package/dist/lib/teach/teachings.d.ts.map +1 -1
  156. package/package.json +38 -15
  157. package/dist/lib/adapters/grounding.ticket.d.ts.map +0 -1
  158. package/dist/lib/adapters/groundings/grounding.d.ts.map +0 -1
  159. package/dist/lib/adapters/groundings/grounding.js.map +0 -7
  160. package/dist/lib/adapters/groundings/low-cardinality.grounding.d.ts +0 -35
  161. package/dist/lib/adapters/groundings/low-cardinality.grounding.d.ts.map +0 -1
  162. package/dist/lib/adapters/postgres/low-cardinality.postgres.grounding.d.ts +0 -14
  163. package/dist/lib/adapters/postgres/low-cardinality.postgres.grounding.d.ts.map +0 -1
  164. package/dist/lib/adapters/sqlite/low-cardinality.sqlite.grounding.d.ts +0 -14
  165. package/dist/lib/adapters/sqlite/low-cardinality.sqlite.grounding.d.ts.map +0 -1
  166. package/dist/lib/adapters/sqlserver/low-cardinality.sqlserver.grounding.d.ts +0 -14
  167. package/dist/lib/adapters/sqlserver/low-cardinality.sqlserver.grounding.d.ts.map +0 -1
@@ -10,9 +10,8 @@ function createGroundingContext() {
10
10
 
11
11
  // packages/text2sql/src/lib/adapters/adapter.ts
12
12
  var Adapter = class {
13
- async introspect() {
13
+ async introspect(ctx = createGroundingContext()) {
14
14
  const lines = [];
15
- const ctx = createGroundingContext();
16
15
  for (const fn of this.grounding) {
17
16
  const grounding = fn(this);
18
17
  lines.push({
@@ -82,7 +81,7 @@ ${description}
82
81
  }
83
82
  };
84
83
 
85
- // packages/text2sql/src/lib/adapters/grounding.ticket.ts
84
+ // packages/text2sql/src/lib/adapters/groundings/abstract.grounding.ts
86
85
  var AbstractGrounding = class {
87
86
  tag;
88
87
  constructor(tag) {
@@ -196,31 +195,108 @@ var InfoGrounding = class extends AbstractGrounding {
196
195
  }
197
196
  };
198
197
 
199
- // packages/text2sql/src/lib/adapters/groundings/low-cardinality.grounding.ts
200
- var LowCardinalityGrounding = class extends AbstractGrounding {
198
+ // packages/text2sql/src/lib/adapters/groundings/column-values.grounding.ts
199
+ var ColumnValuesGrounding = class extends AbstractGrounding {
200
+ lowCardinalityLimit;
201
201
  constructor(config = {}) {
202
- super("low_cardinality");
202
+ super("column_values");
203
+ this.lowCardinalityLimit = config.lowCardinalityLimit ?? 20;
204
+ }
205
+ /**
206
+ * Get values for native ENUM type columns.
207
+ * Return undefined if column is not an ENUM type.
208
+ * Default implementation returns undefined (no native ENUM support).
209
+ */
210
+ async collectEnumValues(_tableName, _column) {
211
+ return void 0;
212
+ }
213
+ /**
214
+ * Parse CHECK constraint for enum-like IN clause.
215
+ * Extracts values from patterns like:
216
+ * - CHECK (status IN ('active', 'inactive'))
217
+ * - CHECK ((status)::text = ANY (ARRAY['a'::text, 'b'::text]))
218
+ * - CHECK (status = 'active' OR status = 'inactive')
219
+ */
220
+ parseCheckConstraint(constraint, columnName) {
221
+ if (constraint.type !== "CHECK" || !constraint.definition) {
222
+ return void 0;
223
+ }
224
+ if (constraint.columns && !constraint.columns.includes(columnName)) {
225
+ return void 0;
226
+ }
227
+ const def = constraint.definition;
228
+ const escapedCol = this.escapeRegex(columnName);
229
+ const colPattern = `(?:\\(?\\(?${escapedCol}\\)?(?:::(?:text|varchar|character varying))?\\)?)`;
230
+ const inMatch = def.match(
231
+ new RegExp(`${colPattern}\\s+IN\\s*\\(([^)]+)\\)`, "i")
232
+ );
233
+ if (inMatch) {
234
+ return this.extractStringValues(inMatch[1]);
235
+ }
236
+ const anyMatch = def.match(
237
+ new RegExp(
238
+ `${colPattern}\\s*=\\s*ANY\\s*\\(\\s*(?:ARRAY)?\\s*\\[([^\\]]+)\\]`,
239
+ "i"
240
+ )
241
+ );
242
+ if (anyMatch) {
243
+ return this.extractStringValues(anyMatch[1]);
244
+ }
245
+ const orPattern = new RegExp(
246
+ `\\b${this.escapeRegex(columnName)}\\b\\s*=\\s*'([^']*)'`,
247
+ "gi"
248
+ );
249
+ const orMatches = [...def.matchAll(orPattern)];
250
+ if (orMatches.length >= 2) {
251
+ return orMatches.map((m) => m[1]);
252
+ }
253
+ return void 0;
254
+ }
255
+ /**
256
+ * Extract string values from a comma-separated list.
257
+ */
258
+ extractStringValues(input) {
259
+ const values = [];
260
+ const matches = input.matchAll(/'([^']*)'/g);
261
+ for (const match of matches) {
262
+ values.push(match[1]);
263
+ }
264
+ return values.length > 0 ? values : void 0;
265
+ }
266
+ /**
267
+ * Escape special regex characters in a string.
268
+ */
269
+ escapeRegex(str) {
270
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
271
+ }
272
+ /**
273
+ * Get the table from context by name.
274
+ */
275
+ getTable(ctx, name) {
276
+ return ctx.tables.find((t) => t.name === name);
203
277
  }
204
278
  /**
205
279
  * Execute the grounding process.
206
- * Annotates columns in ctx.tables and ctx.views with low cardinality values.
280
+ * Annotates columns in ctx.tables and ctx.views with values.
207
281
  */
208
282
  async execute(ctx) {
209
283
  const allContainers = [...ctx.tables, ...ctx.views];
210
284
  for (const container of allContainers) {
285
+ const table = this.getTable(ctx, container.name);
211
286
  for (const column of container.columns) {
212
287
  try {
213
- const lowCard = await this.collectLowCardinality(
288
+ const result = await this.resolveColumnValues(
214
289
  container.name,
215
- column
290
+ column,
291
+ table?.constraints
216
292
  );
217
- if (lowCard) {
218
- column.kind = lowCard.kind;
219
- column.values = lowCard.values;
293
+ if (result) {
294
+ column.kind = result.kind;
295
+ column.values = result.values;
220
296
  }
221
297
  } catch (error) {
222
298
  console.warn(
223
- "Error collecting low cardinality values for",
299
+ "Error collecting column values for",
224
300
  container.name,
225
301
  column.name,
226
302
  error
@@ -230,6 +306,28 @@ var LowCardinalityGrounding = class extends AbstractGrounding {
230
306
  }
231
307
  return () => this.#describe();
232
308
  }
309
+ /**
310
+ * Resolve column values from all sources in priority order.
311
+ */
312
+ async resolveColumnValues(tableName, column, constraints2) {
313
+ const enumValues = await this.collectEnumValues(tableName, column);
314
+ if (enumValues?.length) {
315
+ return { kind: "Enum", values: enumValues };
316
+ }
317
+ if (constraints2) {
318
+ for (const constraint of constraints2) {
319
+ const checkValues = this.parseCheckConstraint(constraint, column.name);
320
+ if (checkValues?.length) {
321
+ return { kind: "Enum", values: checkValues };
322
+ }
323
+ }
324
+ }
325
+ const lowCardValues = await this.collectLowCardinality(tableName, column);
326
+ if (lowCardValues?.length) {
327
+ return { kind: "LowCardinality", values: lowCardValues };
328
+ }
329
+ return void 0;
330
+ }
233
331
  #describe() {
234
332
  return null;
235
333
  }
@@ -478,18 +576,61 @@ var TableGrounding = class extends AbstractGrounding {
478
576
  }
479
577
  return tables2.map((table) => {
480
578
  const rowCountInfo = table.rowCount != null ? ` [rows: ${table.rowCount}${table.sizeHint ? `, size: ${table.sizeHint}` : ""}]` : "";
481
- const pkConstraint = table.constraints?.find((c) => c.type === "PRIMARY_KEY");
579
+ const pkConstraint = table.constraints?.find(
580
+ (c) => c.type === "PRIMARY_KEY"
581
+ );
482
582
  const pkColumns = new Set(pkConstraint?.columns ?? []);
583
+ const notNullColumns = new Set(
584
+ table.constraints?.filter((c) => c.type === "NOT_NULL").flatMap((c) => c.columns ?? []) ?? []
585
+ );
586
+ const defaultByColumn = /* @__PURE__ */ new Map();
587
+ for (const c of table.constraints?.filter(
588
+ (c2) => c2.type === "DEFAULT"
589
+ ) ?? []) {
590
+ for (const col of c.columns ?? []) {
591
+ if (c.defaultValue != null) {
592
+ defaultByColumn.set(col, c.defaultValue);
593
+ }
594
+ }
595
+ }
596
+ const uniqueColumns = new Set(
597
+ table.constraints?.filter((c) => c.type === "UNIQUE" && c.columns?.length === 1).flatMap((c) => c.columns ?? []) ?? []
598
+ );
599
+ const fkByColumn = /* @__PURE__ */ new Map();
600
+ for (const c of table.constraints?.filter(
601
+ (c2) => c2.type === "FOREIGN_KEY"
602
+ ) ?? []) {
603
+ const cols = c.columns ?? [];
604
+ const refCols = c.referencedColumns ?? [];
605
+ for (let i = 0; i < cols.length; i++) {
606
+ const refCol = refCols[i] ?? refCols[0] ?? cols[i];
607
+ fkByColumn.set(cols[i], `${c.referencedTable}.${refCol}`);
608
+ }
609
+ }
483
610
  const columns = table.columns.map((column) => {
484
611
  const annotations = [];
485
612
  const isPrimaryKey = pkColumns.has(column.name);
486
613
  if (isPrimaryKey) {
487
614
  annotations.push("PK");
488
615
  }
616
+ if (fkByColumn.has(column.name)) {
617
+ annotations.push(`FK -> ${fkByColumn.get(column.name)}`);
618
+ }
619
+ if (uniqueColumns.has(column.name)) {
620
+ annotations.push("UNIQUE");
621
+ }
622
+ if (notNullColumns.has(column.name)) {
623
+ annotations.push("NOT NULL");
624
+ }
625
+ if (defaultByColumn.has(column.name)) {
626
+ annotations.push(`DEFAULT: ${defaultByColumn.get(column.name)}`);
627
+ }
489
628
  if (column.isIndexed && !isPrimaryKey) {
490
629
  annotations.push("Indexed");
491
630
  }
492
- if (column.kind === "LowCardinality" && column.values?.length) {
631
+ if (column.kind === "Enum" && column.values?.length) {
632
+ annotations.push(`Enum: ${column.values.join(", ")}`);
633
+ } else if (column.kind === "LowCardinality" && column.values?.length) {
493
634
  annotations.push(`LowCardinality: ${column.values.join(", ")}`);
494
635
  }
495
636
  if (column.stats) {
@@ -524,9 +665,19 @@ ${table.indexes.map((index) => {
524
665
  const columnsText = index.columns?.length ? index.columns.join(", ") : "expression";
525
666
  return ` - ${index.name}${propsText}: ${columnsText}`;
526
667
  }).join("\n")}` : "";
668
+ const multiColumnUniques = table.constraints?.filter(
669
+ (c) => c.type === "UNIQUE" && (c.columns?.length ?? 0) > 1
670
+ ) ?? [];
671
+ const uniqueConstraints = multiColumnUniques.length ? `
672
+ Unique Constraints:
673
+ ${multiColumnUniques.map((c) => ` - ${c.name}: (${c.columns?.join(", ")})`).join("\n")}` : "";
674
+ const checkConstraints = table.constraints?.filter((c) => c.type === "CHECK") ?? [];
675
+ const checks = checkConstraints.length ? `
676
+ Check Constraints:
677
+ ${checkConstraints.map((c) => ` - ${c.name}: ${c.definition}`).join("\n")}` : "";
527
678
  return `- Table: ${table.name}${rowCountInfo}
528
679
  Columns:
529
- ${columns}${indexes2}`;
680
+ ${columns}${indexes2}${uniqueConstraints}${checks}`;
530
681
  }).join("\n\n");
531
682
  }
532
683
  #formatTableLabel = (tableName) => {
@@ -613,7 +764,7 @@ var PostgresColumnStatsGrounding = class extends ColumnStatsGrounding {
613
764
  return false;
614
765
  }
615
766
  const normalized = type.toLowerCase();
616
- return /int|real|numeric|double|float|decimal|date|time|bool|serial/.test(
767
+ return /int|real|numeric|double|float|decimal|date|time|serial/.test(
617
768
  normalized
618
769
  );
619
770
  }
@@ -808,19 +959,71 @@ var PostgresInfoGrounding = class extends InfoGrounding {
808
959
  }
809
960
  };
810
961
 
811
- // packages/text2sql/src/lib/adapters/postgres/low-cardinality.postgres.grounding.ts
812
- var LOW_CARDINALITY_LIMIT = 20;
813
- var PostgresLowCardinalityGrounding = class extends LowCardinalityGrounding {
962
+ // packages/text2sql/src/lib/adapters/postgres/column-values.postgres.grounding.ts
963
+ var PostgresColumnValuesGrounding = class extends ColumnValuesGrounding {
814
964
  #adapter;
965
+ #enumCache = /* @__PURE__ */ new Map();
966
+ #enumCacheLoaded = false;
815
967
  constructor(adapter, config = {}) {
816
968
  super(config);
817
969
  this.#adapter = adapter;
818
970
  }
971
+ /**
972
+ * Load all ENUM types and their values into cache.
973
+ * This is more efficient than querying per-column.
974
+ */
975
+ async #loadEnumCache() {
976
+ if (this.#enumCacheLoaded) {
977
+ return;
978
+ }
979
+ const rows = await this.#adapter.runQuery(`
980
+ SELECT
981
+ t.typname AS type_name,
982
+ n.nspname AS type_schema,
983
+ e.enumlabel AS enum_value
984
+ FROM pg_type t
985
+ JOIN pg_enum e ON t.oid = e.enumtypid
986
+ JOIN pg_namespace n ON n.oid = t.typnamespace
987
+ ORDER BY t.typname, e.enumsortorder
988
+ `);
989
+ for (const row of rows) {
990
+ const key = `${row.type_schema}.${row.type_name}`;
991
+ const existing = this.#enumCache.get(key) ?? [];
992
+ existing.push(row.enum_value);
993
+ this.#enumCache.set(key, existing);
994
+ const simpleKey = row.type_name;
995
+ const simpleExisting = this.#enumCache.get(simpleKey) ?? [];
996
+ simpleExisting.push(row.enum_value);
997
+ this.#enumCache.set(simpleKey, simpleExisting);
998
+ }
999
+ this.#enumCacheLoaded = true;
1000
+ }
1001
+ async collectEnumValues(tableName, column) {
1002
+ if (column.type.toLowerCase() !== "user-defined") {
1003
+ return void 0;
1004
+ }
1005
+ await this.#loadEnumCache();
1006
+ const { schema, table } = this.#adapter.parseTableName(tableName);
1007
+ const rows = await this.#adapter.runQuery(`
1008
+ SELECT udt_name, udt_schema
1009
+ FROM information_schema.columns
1010
+ WHERE table_schema = '${this.#adapter.escapeString(schema)}'
1011
+ AND table_name = '${this.#adapter.escapeString(table)}'
1012
+ AND column_name = '${this.#adapter.escapeString(column.name)}'
1013
+ `);
1014
+ if (!rows.length) {
1015
+ return void 0;
1016
+ }
1017
+ const { udt_name, udt_schema } = rows[0];
1018
+ const fullKey = `${udt_schema}.${udt_name}`;
1019
+ const values = this.#enumCache.get(fullKey) ?? this.#enumCache.get(udt_name);
1020
+ return values?.length ? values : void 0;
1021
+ }
819
1022
  async collectLowCardinality(tableName, column) {
820
1023
  const { schema, table } = this.#adapter.parseTableName(tableName);
821
1024
  const tableIdentifier = `${this.#adapter.quoteIdentifier(schema)}.${this.#adapter.quoteIdentifier(table)}`;
822
1025
  const columnIdentifier = this.#adapter.quoteIdentifier(column.name);
823
- const limit = LOW_CARDINALITY_LIMIT + 1;
1026
+ const limit = this.lowCardinalityLimit + 1;
824
1027
  const sql = `
825
1028
  SELECT DISTINCT ${columnIdentifier}::text AS value
826
1029
  FROM ${tableIdentifier}
@@ -828,7 +1031,7 @@ var PostgresLowCardinalityGrounding = class extends LowCardinalityGrounding {
828
1031
  LIMIT ${limit}
829
1032
  `;
830
1033
  const rows = await this.#adapter.runQuery(sql);
831
- if (!rows.length || rows.length > LOW_CARDINALITY_LIMIT) {
1034
+ if (!rows.length || rows.length > this.lowCardinalityLimit) {
832
1035
  return void 0;
833
1036
  }
834
1037
  const values = [];
@@ -838,10 +1041,7 @@ var PostgresLowCardinalityGrounding = class extends LowCardinalityGrounding {
838
1041
  }
839
1042
  values.push(row.value);
840
1043
  }
841
- if (!values.length) {
842
- return void 0;
843
- }
844
- return { kind: "LowCardinality", values };
1044
+ return values.length ? values : void 0;
845
1045
  }
846
1046
  };
847
1047
 
@@ -868,7 +1068,7 @@ var POSTGRES_ERROR_MAP = {
868
1068
  hint: "The function or operator you used is not recognized. Confirm its name and argument types."
869
1069
  }
870
1070
  };
871
- var LOW_CARDINALITY_LIMIT2 = 20;
1071
+ var LOW_CARDINALITY_LIMIT = 20;
872
1072
  function isPostgresError(error) {
873
1073
  return typeof error === "object" && error !== null && "code" in error && typeof error.code === "string";
874
1074
  }
@@ -1168,7 +1368,7 @@ var Postgres = class extends Adapter {
1168
1368
  });
1169
1369
  for (const column of table.columns) {
1170
1370
  const columnIdentifier = this.#quoteIdentifier(column.name);
1171
- const limit = LOW_CARDINALITY_LIMIT2 + 1;
1371
+ const limit = LOW_CARDINALITY_LIMIT + 1;
1172
1372
  const sql = `
1173
1373
  SELECT DISTINCT ${columnIdentifier} AS value
1174
1374
  FROM ${tableIdentifier}
@@ -1181,7 +1381,7 @@ var Postgres = class extends Adapter {
1181
1381
  } catch {
1182
1382
  continue;
1183
1383
  }
1184
- if (!rows.length || rows.length > LOW_CARDINALITY_LIMIT2) {
1384
+ if (!rows.length || rows.length > LOW_CARDINALITY_LIMIT) {
1185
1385
  continue;
1186
1386
  }
1187
1387
  const values = [];
@@ -1594,9 +1794,9 @@ function columnStats(config = {}) {
1594
1794
  return new PostgresColumnStatsGrounding(adapter, config);
1595
1795
  };
1596
1796
  }
1597
- function lowCardinality(config = {}) {
1797
+ function columnValues(config = {}) {
1598
1798
  return (adapter) => {
1599
- return new PostgresLowCardinalityGrounding(adapter, config);
1799
+ return new PostgresColumnValuesGrounding(adapter, config);
1600
1800
  };
1601
1801
  }
1602
1802
  function indexes(config = {}) {
@@ -1622,7 +1822,7 @@ var postgres_default = {
1622
1822
  info,
1623
1823
  views,
1624
1824
  columnStats,
1625
- lowCardinality,
1825
+ columnValues,
1626
1826
  indexes,
1627
1827
  rowCount,
1628
1828
  constraints,
@@ -1632,12 +1832,12 @@ var postgres_default = {
1632
1832
  export {
1633
1833
  Postgres,
1634
1834
  columnStats,
1835
+ columnValues,
1635
1836
  constraints,
1636
1837
  postgres_default as default,
1637
1838
  formatPostgresError,
1638
1839
  indexes,
1639
1840
  info,
1640
- lowCardinality,
1641
1841
  report,
1642
1842
  rowCount,
1643
1843
  tables,