@pgsage/core 0.1.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/README.md +126 -0
- package/dist/corrector/index.d.ts +72 -0
- package/dist/corrector/index.d.ts.map +1 -0
- package/dist/corrector/index.js +113 -0
- package/dist/corrector/index.js.map +1 -0
- package/dist/db/index.d.ts +3 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +2 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/pool.d.ts +46 -0
- package/dist/db/pool.d.ts.map +1 -0
- package/dist/db/pool.js +46 -0
- package/dist/db/pool.js.map +1 -0
- package/dist/embeddings/index.d.ts +4 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +2 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/types.d.ts +39 -0
- package/dist/embeddings/types.d.ts.map +1 -0
- package/dist/embeddings/types.js +16 -0
- package/dist/embeddings/types.js.map +1 -0
- package/dist/embeddings/voyage.d.ts +70 -0
- package/dist/embeddings/voyage.d.ts.map +1 -0
- package/dist/embeddings/voyage.js +163 -0
- package/dist/embeddings/voyage.js.map +1 -0
- package/dist/estimator/index.d.ts +53 -0
- package/dist/estimator/index.d.ts.map +1 -0
- package/dist/estimator/index.js +57 -0
- package/dist/estimator/index.js.map +1 -0
- package/dist/executor/index.d.ts +56 -0
- package/dist/executor/index.d.ts.map +1 -0
- package/dist/executor/index.js +86 -0
- package/dist/executor/index.js.map +1 -0
- package/dist/explainer/index.d.ts +39 -0
- package/dist/explainer/index.d.ts.map +1 -0
- package/dist/explainer/index.js +79 -0
- package/dist/explainer/index.js.map +1 -0
- package/dist/explainer/prompt.d.ts +37 -0
- package/dist/explainer/prompt.d.ts.map +1 -0
- package/dist/explainer/prompt.js +102 -0
- package/dist/explainer/prompt.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/introspector/index.d.ts +127 -0
- package/dist/introspector/index.d.ts.map +1 -0
- package/dist/introspector/index.js +460 -0
- package/dist/introspector/index.js.map +1 -0
- package/dist/orchestrator/index.d.ts +113 -0
- package/dist/orchestrator/index.d.ts.map +1 -0
- package/dist/orchestrator/index.js +126 -0
- package/dist/orchestrator/index.js.map +1 -0
- package/dist/planner/index.d.ts +83 -0
- package/dist/planner/index.d.ts.map +1 -0
- package/dist/planner/index.js +67 -0
- package/dist/planner/index.js.map +1 -0
- package/dist/planner/prompt.d.ts +37 -0
- package/dist/planner/prompt.d.ts.map +1 -0
- package/dist/planner/prompt.js +436 -0
- package/dist/planner/prompt.js.map +1 -0
- package/dist/retriever/index.d.ts +90 -0
- package/dist/retriever/index.d.ts.map +1 -0
- package/dist/retriever/index.js +164 -0
- package/dist/retriever/index.js.map +1 -0
- package/dist/validator/index.d.ts +26 -0
- package/dist/validator/index.d.ts.map +1 -0
- package/dist/validator/index.js +205 -0
- package/dist/validator/index.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Introspector
|
|
3
|
+
*
|
|
4
|
+
* Crawls information_schema and pg_catalog to produce a fully-typed
|
|
5
|
+
* IntrospectedSchema describing every table, view, column, constraint,
|
|
6
|
+
* index, and enum in the target database.
|
|
7
|
+
*
|
|
8
|
+
* All queries run as a single-client transaction (READ ONLY) to give a
|
|
9
|
+
* consistent snapshot. The introspector is deliberately read-only and
|
|
10
|
+
* dataset-agnostic — it works against any Postgres database (Chinook,
|
|
11
|
+
* Census schema, arbitrary user schemas, etc.).
|
|
12
|
+
*/
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Public entry point
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
/**
|
|
17
|
+
* Introspect the target database and return a fully-typed schema description.
|
|
18
|
+
*
|
|
19
|
+
* @param pool A pg Pool connected to the target database.
|
|
20
|
+
* @param options Filtering options.
|
|
21
|
+
*/
|
|
22
|
+
export async function introspect(pool, options = {}) {
|
|
23
|
+
const client = await pool.connect();
|
|
24
|
+
try {
|
|
25
|
+
return await introspectWithClient(client, options);
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
client.release();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Internal implementation
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
const SYSTEM_SCHEMAS = [
|
|
35
|
+
"pg_catalog",
|
|
36
|
+
"information_schema",
|
|
37
|
+
"pg_toast",
|
|
38
|
+
"pg_temp",
|
|
39
|
+
];
|
|
40
|
+
async function introspectWithClient(client, options) {
|
|
41
|
+
const { schemas, includeViews = true } = options;
|
|
42
|
+
await client.query("BEGIN TRANSACTION READ ONLY");
|
|
43
|
+
try {
|
|
44
|
+
// Determine the set of schemas to introspect
|
|
45
|
+
const schemaFilter = await resolveSchemas(client, schemas);
|
|
46
|
+
const tableTypes = includeViews
|
|
47
|
+
? ["BASE TABLE", "VIEW"]
|
|
48
|
+
: ["BASE TABLE"];
|
|
49
|
+
// Run metadata queries sequentially on the single client — pg@8 warns
|
|
50
|
+
// about concurrent queries on one client, and catalog queries are fast
|
|
51
|
+
// enough that sequential is fine.
|
|
52
|
+
const tablesRows = await queryTables(client, schemaFilter, tableTypes);
|
|
53
|
+
const columnsRows = await queryColumns(client, schemaFilter);
|
|
54
|
+
const pkRows = await queryPrimaryKeys(client, schemaFilter);
|
|
55
|
+
const fkRows = await queryForeignKeys(client, schemaFilter);
|
|
56
|
+
const uniqueRows = await queryUniqueConstraints(client, schemaFilter);
|
|
57
|
+
const checkRows = await queryCheckConstraints(client, schemaFilter);
|
|
58
|
+
const indexRows = await queryIndexes(client, schemaFilter);
|
|
59
|
+
const enumRows = await queryEnums(client, schemaFilter);
|
|
60
|
+
const rowCountRows = await queryRowCounts(client, schemaFilter);
|
|
61
|
+
const tableCommentRows = await queryTableComments(client, schemaFilter);
|
|
62
|
+
const columnCommentRows = await queryColumnComments(client, schemaFilter);
|
|
63
|
+
await client.query("COMMIT");
|
|
64
|
+
return assemble({
|
|
65
|
+
tablesRows,
|
|
66
|
+
columnsRows,
|
|
67
|
+
pkRows,
|
|
68
|
+
fkRows,
|
|
69
|
+
uniqueRows,
|
|
70
|
+
checkRows,
|
|
71
|
+
indexRows,
|
|
72
|
+
enumRows,
|
|
73
|
+
rowCountRows,
|
|
74
|
+
tableCommentRows,
|
|
75
|
+
columnCommentRows,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
await client.query("ROLLBACK").catch(() => undefined);
|
|
80
|
+
throw err;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
// Schema resolution
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
async function resolveSchemas(client, requested) {
|
|
87
|
+
if (requested && requested.length > 0)
|
|
88
|
+
return requested;
|
|
89
|
+
// All schemas except system ones and pg_temp_* prefixed schemas
|
|
90
|
+
const result = await client.query(`
|
|
91
|
+
SELECT schema_name
|
|
92
|
+
FROM information_schema.schemata
|
|
93
|
+
WHERE schema_name NOT IN (${SYSTEM_SCHEMAS.map((s) => `'${s}'`).join(", ")})
|
|
94
|
+
AND schema_name NOT LIKE 'pg_temp_%'
|
|
95
|
+
AND schema_name NOT LIKE 'pg_toast_%'
|
|
96
|
+
ORDER BY schema_name
|
|
97
|
+
`);
|
|
98
|
+
return result.rows.map((r) => r.schema_name);
|
|
99
|
+
}
|
|
100
|
+
async function queryTables(client, schemas, tableTypes) {
|
|
101
|
+
const result = await client.query(`SELECT table_schema, table_name, table_type
|
|
102
|
+
FROM information_schema.tables
|
|
103
|
+
WHERE table_schema = ANY($1)
|
|
104
|
+
AND table_type = ANY($2)
|
|
105
|
+
ORDER BY table_schema, table_name`, [schemas, tableTypes]);
|
|
106
|
+
return result.rows;
|
|
107
|
+
}
|
|
108
|
+
async function queryColumns(client, schemas) {
|
|
109
|
+
const result = await client.query(`SELECT
|
|
110
|
+
c.table_schema,
|
|
111
|
+
c.table_name,
|
|
112
|
+
c.column_name,
|
|
113
|
+
c.data_type,
|
|
114
|
+
c.udt_name,
|
|
115
|
+
c.is_nullable,
|
|
116
|
+
c.column_default,
|
|
117
|
+
c.ordinal_position
|
|
118
|
+
FROM information_schema.columns c
|
|
119
|
+
WHERE c.table_schema = ANY($1)
|
|
120
|
+
ORDER BY c.table_schema, c.table_name, c.ordinal_position`, [schemas]);
|
|
121
|
+
return result.rows;
|
|
122
|
+
}
|
|
123
|
+
async function queryPrimaryKeys(client, schemas) {
|
|
124
|
+
const result = await client.query(`SELECT
|
|
125
|
+
tc.table_schema,
|
|
126
|
+
tc.table_name,
|
|
127
|
+
kcu.column_name,
|
|
128
|
+
kcu.ordinal_position
|
|
129
|
+
FROM information_schema.table_constraints tc
|
|
130
|
+
JOIN information_schema.key_column_usage kcu
|
|
131
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
132
|
+
AND tc.table_schema = kcu.table_schema
|
|
133
|
+
AND tc.table_name = kcu.table_name
|
|
134
|
+
WHERE tc.constraint_type = 'PRIMARY KEY'
|
|
135
|
+
AND tc.table_schema = ANY($1)
|
|
136
|
+
ORDER BY tc.table_schema, tc.table_name, kcu.ordinal_position`, [schemas]);
|
|
137
|
+
return result.rows;
|
|
138
|
+
}
|
|
139
|
+
async function queryForeignKeys(client, schemas) {
|
|
140
|
+
const result = await client.query(`SELECT
|
|
141
|
+
tc.table_schema,
|
|
142
|
+
tc.table_name,
|
|
143
|
+
tc.constraint_name,
|
|
144
|
+
kcu.column_name,
|
|
145
|
+
kcu.ordinal_position AS key_ordinal,
|
|
146
|
+
ccu.table_schema AS foreign_table_schema,
|
|
147
|
+
ccu.table_name AS foreign_table_name,
|
|
148
|
+
ccu.column_name AS foreign_column_name
|
|
149
|
+
FROM information_schema.table_constraints tc
|
|
150
|
+
JOIN information_schema.key_column_usage kcu
|
|
151
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
152
|
+
AND tc.table_schema = kcu.table_schema
|
|
153
|
+
AND tc.table_name = kcu.table_name
|
|
154
|
+
JOIN information_schema.referential_constraints rc
|
|
155
|
+
ON tc.constraint_name = rc.constraint_name
|
|
156
|
+
AND tc.table_schema = rc.constraint_schema
|
|
157
|
+
JOIN information_schema.constraint_column_usage ccu
|
|
158
|
+
ON rc.unique_constraint_name = ccu.constraint_name
|
|
159
|
+
AND rc.unique_constraint_schema = ccu.table_schema
|
|
160
|
+
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
161
|
+
AND tc.table_schema = ANY($1)
|
|
162
|
+
ORDER BY tc.table_schema, tc.table_name, tc.constraint_name, kcu.ordinal_position`, [schemas]);
|
|
163
|
+
return result.rows;
|
|
164
|
+
}
|
|
165
|
+
async function queryUniqueConstraints(client, schemas) {
|
|
166
|
+
const result = await client.query(`SELECT
|
|
167
|
+
tc.table_schema,
|
|
168
|
+
tc.table_name,
|
|
169
|
+
tc.constraint_name,
|
|
170
|
+
kcu.column_name,
|
|
171
|
+
kcu.ordinal_position
|
|
172
|
+
FROM information_schema.table_constraints tc
|
|
173
|
+
JOIN information_schema.key_column_usage kcu
|
|
174
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
175
|
+
AND tc.table_schema = kcu.table_schema
|
|
176
|
+
AND tc.table_name = kcu.table_name
|
|
177
|
+
WHERE tc.constraint_type = 'UNIQUE'
|
|
178
|
+
AND tc.table_schema = ANY($1)
|
|
179
|
+
ORDER BY tc.table_schema, tc.table_name, tc.constraint_name, kcu.ordinal_position`, [schemas]);
|
|
180
|
+
return result.rows;
|
|
181
|
+
}
|
|
182
|
+
async function queryCheckConstraints(client, schemas) {
|
|
183
|
+
// Exclude auto-generated NOT NULL checks (they contain 'IS NOT NULL' and
|
|
184
|
+
// the column name only — a good-enough heuristic for v1).
|
|
185
|
+
const result = await client.query(`SELECT
|
|
186
|
+
tc.table_schema,
|
|
187
|
+
tc.table_name,
|
|
188
|
+
cc.constraint_name,
|
|
189
|
+
cc.check_clause
|
|
190
|
+
FROM information_schema.check_constraints cc
|
|
191
|
+
JOIN information_schema.table_constraints tc
|
|
192
|
+
ON cc.constraint_name = tc.constraint_name
|
|
193
|
+
AND cc.constraint_schema = tc.table_schema
|
|
194
|
+
WHERE tc.constraint_type = 'CHECK'
|
|
195
|
+
AND tc.table_schema = ANY($1)
|
|
196
|
+
AND cc.check_clause NOT LIKE '%IS NOT NULL%'
|
|
197
|
+
ORDER BY tc.table_schema, tc.table_name, cc.constraint_name`, [schemas]);
|
|
198
|
+
return result.rows;
|
|
199
|
+
}
|
|
200
|
+
async function queryIndexes(client, schemas) {
|
|
201
|
+
// We join pg_index → pg_class (index) → pg_class (table) → pg_namespace
|
|
202
|
+
// to get the method name and column list. We exclude PK indexes (those
|
|
203
|
+
// are surfaced via primaryKey[]) and indexes on system columns.
|
|
204
|
+
const result = await client.query(`SELECT
|
|
205
|
+
n.nspname AS table_schema,
|
|
206
|
+
t.relname AS table_name,
|
|
207
|
+
i.relname AS index_name,
|
|
208
|
+
ix.indisunique AS is_unique,
|
|
209
|
+
am.amname AS index_type,
|
|
210
|
+
ARRAY(
|
|
211
|
+
SELECT a.attname
|
|
212
|
+
FROM unnest(ix.indkey) WITH ORDINALITY AS u(attnum, ord)
|
|
213
|
+
JOIN pg_attribute a
|
|
214
|
+
ON a.attrelid = t.oid AND a.attnum = u.attnum
|
|
215
|
+
WHERE u.attnum > 0
|
|
216
|
+
ORDER BY u.ord
|
|
217
|
+
)::text[] AS column_names
|
|
218
|
+
FROM pg_index ix
|
|
219
|
+
JOIN pg_class i ON i.oid = ix.indexrelid
|
|
220
|
+
JOIN pg_class t ON t.oid = ix.indrelid
|
|
221
|
+
JOIN pg_namespace n ON n.oid = t.relnamespace
|
|
222
|
+
JOIN pg_am am ON am.oid = i.relam
|
|
223
|
+
WHERE n.nspname = ANY($1)
|
|
224
|
+
AND NOT ix.indisprimary
|
|
225
|
+
AND t.relkind IN ('r', 'v', 'm')
|
|
226
|
+
ORDER BY n.nspname, t.relname, i.relname`, [schemas]);
|
|
227
|
+
return result.rows;
|
|
228
|
+
}
|
|
229
|
+
async function queryEnums(client, schemas) {
|
|
230
|
+
const result = await client.query(`SELECT
|
|
231
|
+
n.nspname AS enum_schema,
|
|
232
|
+
t.typname AS enum_name,
|
|
233
|
+
e.enumlabel AS enum_value
|
|
234
|
+
FROM pg_type t
|
|
235
|
+
JOIN pg_namespace n ON n.oid = t.typnamespace
|
|
236
|
+
JOIN pg_enum e ON e.enumtypid = t.oid
|
|
237
|
+
WHERE t.typtype = 'e'
|
|
238
|
+
AND n.nspname = ANY($1)
|
|
239
|
+
ORDER BY n.nspname, t.typname, e.enumsortorder`, [schemas]);
|
|
240
|
+
return result.rows;
|
|
241
|
+
}
|
|
242
|
+
async function queryRowCounts(client, schemas) {
|
|
243
|
+
const result = await client.query(`SELECT
|
|
244
|
+
n.nspname AS table_schema,
|
|
245
|
+
c.relname AS table_name,
|
|
246
|
+
c.reltuples::bigint AS row_estimate
|
|
247
|
+
FROM pg_class c
|
|
248
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
249
|
+
WHERE n.nspname = ANY($1)
|
|
250
|
+
AND c.relkind IN ('r', 'v', 'm', 'p')
|
|
251
|
+
ORDER BY n.nspname, c.relname`, [schemas]);
|
|
252
|
+
return result.rows;
|
|
253
|
+
}
|
|
254
|
+
async function queryTableComments(client, schemas) {
|
|
255
|
+
const result = await client.query(`SELECT
|
|
256
|
+
n.nspname AS table_schema,
|
|
257
|
+
c.relname AS table_name,
|
|
258
|
+
obj_description(c.oid, 'pg_class') AS comment
|
|
259
|
+
FROM pg_class c
|
|
260
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
261
|
+
WHERE n.nspname = ANY($1)
|
|
262
|
+
AND c.relkind IN ('r', 'v', 'm', 'p')
|
|
263
|
+
AND obj_description(c.oid, 'pg_class') IS NOT NULL
|
|
264
|
+
ORDER BY n.nspname, c.relname`, [schemas]);
|
|
265
|
+
return result.rows;
|
|
266
|
+
}
|
|
267
|
+
async function queryColumnComments(client, schemas) {
|
|
268
|
+
const result = await client.query(`SELECT
|
|
269
|
+
n.nspname AS table_schema,
|
|
270
|
+
c.relname AS table_name,
|
|
271
|
+
a.attname AS column_name,
|
|
272
|
+
col_description(c.oid, a.attnum) AS comment
|
|
273
|
+
FROM pg_attribute a
|
|
274
|
+
JOIN pg_class c ON c.oid = a.attrelid
|
|
275
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
276
|
+
WHERE n.nspname = ANY($1)
|
|
277
|
+
AND a.attnum > 0
|
|
278
|
+
AND NOT a.attisdropped
|
|
279
|
+
AND col_description(c.oid, a.attnum) IS NOT NULL
|
|
280
|
+
ORDER BY n.nspname, c.relname, a.attnum`, [schemas]);
|
|
281
|
+
return result.rows;
|
|
282
|
+
}
|
|
283
|
+
function assemble(raw) {
|
|
284
|
+
// Build lookup maps keyed by "schema.table"
|
|
285
|
+
const pkSet = buildPkSet(raw.pkRows);
|
|
286
|
+
const fkMap = buildFkMap(raw.fkRows);
|
|
287
|
+
const uniqueMap = buildUniqueMap(raw.uniqueRows);
|
|
288
|
+
const checkMap = buildCheckMap(raw.checkRows);
|
|
289
|
+
const indexMap = buildIndexMap(raw.indexRows);
|
|
290
|
+
const rowCountMap = buildRowCountMap(raw.rowCountRows);
|
|
291
|
+
const tableCommentMap = buildTableCommentMap(raw.tableCommentRows);
|
|
292
|
+
const columnCommentMap = buildColumnCommentMap(raw.columnCommentRows);
|
|
293
|
+
// Group columns by table
|
|
294
|
+
const columnMap = new Map();
|
|
295
|
+
for (const col of raw.columnsRows) {
|
|
296
|
+
const key = `${col.table_schema}.${col.table_name}`;
|
|
297
|
+
if (!columnMap.has(key))
|
|
298
|
+
columnMap.set(key, []);
|
|
299
|
+
columnMap.get(key).push(col);
|
|
300
|
+
}
|
|
301
|
+
const tables = raw.tablesRows.map((t) => {
|
|
302
|
+
const key = `${t.table_schema}.${t.table_name}`;
|
|
303
|
+
const pkCols = pkSet.get(key) ?? new Set();
|
|
304
|
+
const rawCols = columnMap.get(key) ?? [];
|
|
305
|
+
const columns = rawCols.map((c) => ({
|
|
306
|
+
name: c.column_name,
|
|
307
|
+
dataType: c.data_type,
|
|
308
|
+
udtName: c.udt_name,
|
|
309
|
+
isNullable: c.is_nullable === "YES",
|
|
310
|
+
defaultValue: c.column_default,
|
|
311
|
+
ordinalPosition: c.ordinal_position,
|
|
312
|
+
isPrimaryKey: pkCols.has(c.column_name),
|
|
313
|
+
comment: columnCommentMap.get(`${key}.${c.column_name}`) ?? null,
|
|
314
|
+
}));
|
|
315
|
+
return {
|
|
316
|
+
name: t.table_name,
|
|
317
|
+
schema: t.table_schema,
|
|
318
|
+
tableType: t.table_type === "VIEW" ? "view" : "table",
|
|
319
|
+
columns,
|
|
320
|
+
primaryKey: [...pkCols].filter((col) => rawCols.some((c) => c.column_name === col)),
|
|
321
|
+
foreignKeys: fkMap.get(key) ?? [],
|
|
322
|
+
indexes: indexMap.get(key) ?? [],
|
|
323
|
+
uniqueConstraints: uniqueMap.get(key) ?? [],
|
|
324
|
+
checkConstraints: checkMap.get(key) ?? [],
|
|
325
|
+
estimatedRowCount: rowCountMap.get(key) ?? -1,
|
|
326
|
+
comment: tableCommentMap.get(key) ?? null,
|
|
327
|
+
};
|
|
328
|
+
});
|
|
329
|
+
// Assemble enums
|
|
330
|
+
const enumMap = new Map();
|
|
331
|
+
for (const row of raw.enumRows) {
|
|
332
|
+
const key = `${row.enum_schema}.${row.enum_name}`;
|
|
333
|
+
if (!enumMap.has(key)) {
|
|
334
|
+
enumMap.set(key, { schema: row.enum_schema, name: row.enum_name, values: [] });
|
|
335
|
+
}
|
|
336
|
+
enumMap.get(key).values.push(row.enum_value);
|
|
337
|
+
}
|
|
338
|
+
return {
|
|
339
|
+
tables,
|
|
340
|
+
enums: [...enumMap.values()].sort((a, b) => `${a.schema}.${a.name}`.localeCompare(`${b.schema}.${b.name}`)),
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
// ---------------------------------------------------------------------------
|
|
344
|
+
// Map builders
|
|
345
|
+
// ---------------------------------------------------------------------------
|
|
346
|
+
function buildPkSet(rows) {
|
|
347
|
+
const map = new Map();
|
|
348
|
+
for (const row of rows) {
|
|
349
|
+
const key = `${row.table_schema}.${row.table_name}`;
|
|
350
|
+
if (!map.has(key))
|
|
351
|
+
map.set(key, new Set());
|
|
352
|
+
map.get(key).add(row.column_name);
|
|
353
|
+
}
|
|
354
|
+
return map;
|
|
355
|
+
}
|
|
356
|
+
function buildFkMap(rows) {
|
|
357
|
+
// Group by table key + constraint name
|
|
358
|
+
const intermediate = new Map();
|
|
359
|
+
for (const row of rows) {
|
|
360
|
+
const tableKey = `${row.table_schema}.${row.table_name}`;
|
|
361
|
+
if (!intermediate.has(tableKey))
|
|
362
|
+
intermediate.set(tableKey, new Map());
|
|
363
|
+
const byConstraint = intermediate.get(tableKey);
|
|
364
|
+
if (!byConstraint.has(row.constraint_name))
|
|
365
|
+
byConstraint.set(row.constraint_name, []);
|
|
366
|
+
byConstraint.get(row.constraint_name).push(row);
|
|
367
|
+
}
|
|
368
|
+
const map = new Map();
|
|
369
|
+
for (const [tableKey, byConstraint] of intermediate) {
|
|
370
|
+
const fks = [];
|
|
371
|
+
for (const [constraintName, constraintRows] of byConstraint) {
|
|
372
|
+
const sorted = constraintRows.sort((a, b) => a.key_ordinal - b.key_ordinal);
|
|
373
|
+
fks.push({
|
|
374
|
+
constraintName,
|
|
375
|
+
columns: sorted.map((r) => r.column_name),
|
|
376
|
+
referencedSchema: sorted[0].foreign_table_schema,
|
|
377
|
+
referencedTable: sorted[0].foreign_table_name,
|
|
378
|
+
referencedColumns: sorted.map((r) => r.foreign_column_name),
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
map.set(tableKey, fks);
|
|
382
|
+
}
|
|
383
|
+
return map;
|
|
384
|
+
}
|
|
385
|
+
function buildUniqueMap(rows) {
|
|
386
|
+
const intermediate = new Map();
|
|
387
|
+
for (const row of rows) {
|
|
388
|
+
const tableKey = `${row.table_schema}.${row.table_name}`;
|
|
389
|
+
if (!intermediate.has(tableKey))
|
|
390
|
+
intermediate.set(tableKey, new Map());
|
|
391
|
+
const byConstraint = intermediate.get(tableKey);
|
|
392
|
+
if (!byConstraint.has(row.constraint_name))
|
|
393
|
+
byConstraint.set(row.constraint_name, []);
|
|
394
|
+
byConstraint.get(row.constraint_name).push(row);
|
|
395
|
+
}
|
|
396
|
+
const map = new Map();
|
|
397
|
+
for (const [tableKey, byConstraint] of intermediate) {
|
|
398
|
+
const uniques = [];
|
|
399
|
+
for (const [name, constraintRows] of byConstraint) {
|
|
400
|
+
uniques.push({
|
|
401
|
+
name,
|
|
402
|
+
columns: constraintRows
|
|
403
|
+
.sort((a, b) => a.ordinal_position - b.ordinal_position)
|
|
404
|
+
.map((r) => r.column_name),
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
map.set(tableKey, uniques);
|
|
408
|
+
}
|
|
409
|
+
return map;
|
|
410
|
+
}
|
|
411
|
+
function buildCheckMap(rows) {
|
|
412
|
+
const map = new Map();
|
|
413
|
+
for (const row of rows) {
|
|
414
|
+
const key = `${row.table_schema}.${row.table_name}`;
|
|
415
|
+
if (!map.has(key))
|
|
416
|
+
map.set(key, []);
|
|
417
|
+
map.get(key).push({ name: row.constraint_name, expression: row.check_clause });
|
|
418
|
+
}
|
|
419
|
+
return map;
|
|
420
|
+
}
|
|
421
|
+
function buildIndexMap(rows) {
|
|
422
|
+
const map = new Map();
|
|
423
|
+
for (const row of rows) {
|
|
424
|
+
const key = `${row.table_schema}.${row.table_name}`;
|
|
425
|
+
if (!map.has(key))
|
|
426
|
+
map.set(key, []);
|
|
427
|
+
map.get(key).push({
|
|
428
|
+
name: row.index_name,
|
|
429
|
+
columns: row.column_names,
|
|
430
|
+
isUnique: row.is_unique,
|
|
431
|
+
indexType: row.index_type,
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
return map;
|
|
435
|
+
}
|
|
436
|
+
function buildRowCountMap(rows) {
|
|
437
|
+
const map = new Map();
|
|
438
|
+
for (const row of rows) {
|
|
439
|
+
map.set(`${row.table_schema}.${row.table_name}`, Number(row.row_estimate));
|
|
440
|
+
}
|
|
441
|
+
return map;
|
|
442
|
+
}
|
|
443
|
+
function buildTableCommentMap(rows) {
|
|
444
|
+
const map = new Map();
|
|
445
|
+
for (const row of rows) {
|
|
446
|
+
if (row.comment)
|
|
447
|
+
map.set(`${row.table_schema}.${row.table_name}`, row.comment);
|
|
448
|
+
}
|
|
449
|
+
return map;
|
|
450
|
+
}
|
|
451
|
+
function buildColumnCommentMap(rows) {
|
|
452
|
+
const map = new Map();
|
|
453
|
+
for (const row of rows) {
|
|
454
|
+
if (row.comment) {
|
|
455
|
+
map.set(`${row.table_schema}.${row.table_name}.${row.column_name}`, row.comment);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return map;
|
|
459
|
+
}
|
|
460
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/introspector/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrator
|
|
3
|
+
*
|
|
4
|
+
* Ties retriever → planner → validator → estimator → executor → corrector
|
|
5
|
+
* into a single agent loop and exposes the SDK's primary entrypoint:
|
|
6
|
+
* `agent.query(question)`.
|
|
7
|
+
*
|
|
8
|
+
* Each stage is composable — callers can import individual stage factories
|
|
9
|
+
* directly if they need finer control. The orchestrator just wires them up
|
|
10
|
+
* with sensible defaults.
|
|
11
|
+
*/
|
|
12
|
+
import type pg from "pg";
|
|
13
|
+
import type { EmbeddingProvider } from "../embeddings/index.js";
|
|
14
|
+
import type { DisplayHint } from "../planner/index.js";
|
|
15
|
+
export interface OrchestratorConfig {
|
|
16
|
+
/**
|
|
17
|
+
* Read-write pg Pool — used for retrieval (pgvector similarity search)
|
|
18
|
+
* and cost estimation (EXPLAIN). Typically connects as the pgsage app role.
|
|
19
|
+
*/
|
|
20
|
+
pool: InstanceType<typeof pg.Pool>;
|
|
21
|
+
/**
|
|
22
|
+
* Read-only pg Pool — used exclusively by the executor. Should connect as
|
|
23
|
+
* the pgsage_readonly role (no write/DDL privileges).
|
|
24
|
+
*/
|
|
25
|
+
readonlyPool: InstanceType<typeof pg.Pool>;
|
|
26
|
+
/** Embedding provider used to embed the question for pgvector retrieval. */
|
|
27
|
+
embedder: EmbeddingProvider;
|
|
28
|
+
/**
|
|
29
|
+
* Mastra model router string for the planner.
|
|
30
|
+
* @default "anthropic/claude-sonnet-4-6"
|
|
31
|
+
*/
|
|
32
|
+
model?: string;
|
|
33
|
+
/** Number of schema chunks to retrieve. Default: 10. */
|
|
34
|
+
topK?: number;
|
|
35
|
+
/** Maximum planner cost threshold for EXPLAIN. Default: 1_000_000. */
|
|
36
|
+
costThreshold?: number;
|
|
37
|
+
/** Maximum estimated rows threshold for EXPLAIN. Default: 500_000. */
|
|
38
|
+
rowThreshold?: number;
|
|
39
|
+
/** Maximum rows returned by the executor. Default: 500. */
|
|
40
|
+
rowLimit?: number;
|
|
41
|
+
/** Per-query statement timeout in ms. Default: 30_000. */
|
|
42
|
+
statementTimeout?: number;
|
|
43
|
+
/** Maximum self-correction retries. Default: 3. */
|
|
44
|
+
maxRetries?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Mastra model router string for the explainer (answer generation).
|
|
47
|
+
* Defaults to the same model used for the planner.
|
|
48
|
+
*/
|
|
49
|
+
explainerModel?: string;
|
|
50
|
+
}
|
|
51
|
+
export interface QueryResponse {
|
|
52
|
+
/** Natural-language answer synthesised from the SQL result. */
|
|
53
|
+
answer: string;
|
|
54
|
+
/** The final SQL that was executed. */
|
|
55
|
+
sql: string;
|
|
56
|
+
/** Assumptions the planner stated about ambiguous terms. */
|
|
57
|
+
assumptions: string[];
|
|
58
|
+
/** The raw rows returned by the executor. */
|
|
59
|
+
rows: Record<string, unknown>[];
|
|
60
|
+
/** Row count of the returned result set. */
|
|
61
|
+
rowCount: number;
|
|
62
|
+
/** Column names in result order. */
|
|
63
|
+
fields: string[];
|
|
64
|
+
/** True when the result was truncated at the row limit. */
|
|
65
|
+
truncated: boolean;
|
|
66
|
+
/** All prior failed attempts (empty when first plan succeeded). */
|
|
67
|
+
attempts: {
|
|
68
|
+
sql: string;
|
|
69
|
+
error: string;
|
|
70
|
+
}[];
|
|
71
|
+
/**
|
|
72
|
+
* Suggested UI visualization layout chosen by the planner.
|
|
73
|
+
* - `"big"` — single scalar answer
|
|
74
|
+
* - `"statrow"` — 2–4 related metrics side by side
|
|
75
|
+
* - `"bar"` — ranked list of one metric across many geographies
|
|
76
|
+
* - `"grouped"` — two-series comparison across geographies
|
|
77
|
+
* - `"table"` — general tabular fallback
|
|
78
|
+
*/
|
|
79
|
+
displayHint: DisplayHint;
|
|
80
|
+
}
|
|
81
|
+
/** Options for a single query() call. */
|
|
82
|
+
export interface QueryOptions {
|
|
83
|
+
/**
|
|
84
|
+
* Optional progress callback, fired before each pipeline stage.
|
|
85
|
+
* The step number and label are provided for display purposes.
|
|
86
|
+
* Steps in order:
|
|
87
|
+
* 0 — Searching schema
|
|
88
|
+
* 1 — Generating SQL
|
|
89
|
+
* 2 — Validating & executing
|
|
90
|
+
* 3 — Correcting query (only emitted when a retry occurs)
|
|
91
|
+
* 4 — Summarizing results
|
|
92
|
+
*/
|
|
93
|
+
onProgress?: (step: number, label: string) => void;
|
|
94
|
+
}
|
|
95
|
+
export interface Agent {
|
|
96
|
+
query(question: string, options?: QueryOptions): Promise<QueryResponse>;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Create the pgsage agent. All stage instances are created once and reused
|
|
100
|
+
* across query() calls.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* const agent = createAgent({
|
|
105
|
+
* pool,
|
|
106
|
+
* readonlyPool,
|
|
107
|
+
* embedder: new VoyageEmbeddingProvider({ apiKey: process.env.VOYAGE_API_KEY }),
|
|
108
|
+
* });
|
|
109
|
+
* const response = await agent.query("What is the median household income in RI?");
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
export declare function createAgent(config: OrchestratorConfig): Agent;
|
|
113
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/orchestrator/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAQhE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAOvD,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,IAAI,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;IACnC;;;OAGG;IACH,YAAY,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;IAC3C,4EAA4E;IAC5E,QAAQ,EAAE,iBAAiB,CAAC;IAC5B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,4DAA4D;IAC5D,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,2DAA2D;IAC3D,SAAS,EAAE,OAAO,CAAC;IACnB,mEAAmE;IACnE,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3C;;;;;;;OAOG;IACH,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,yCAAyC;AACzC,MAAM,WAAW,YAAY;IAC3B;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD;AAED,MAAM,WAAW,KAAK;IACpB,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CACzE;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,kBAAkB,GAAG,KAAK,CAiH7D"}
|