yamchart 0.9.5 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{advisor-SC64RTZO.js → advisor-5TJDNAY7.js} +24 -14
- package/dist/advisor-5TJDNAY7.js.map +1 -0
- package/dist/agent-TZZHNDPK.js +1 -0
- package/dist/{chunk-NXQ6ZO3V.js → chunk-5FHV22X2.js} +7 -6
- package/dist/chunk-5FHV22X2.js.map +1 -0
- package/dist/{dist-MNXSMGV6.js → chunk-64CI3HSY.js} +184 -15
- package/dist/chunk-64CI3HSY.js.map +1 -0
- package/dist/chunk-7D4SUZUM.js +1 -0
- package/dist/chunk-DZVT6PHW.js +1 -0
- package/dist/chunk-EAQXUGP6.js +1 -0
- package/dist/chunk-HJVVHYVN.js +1 -0
- package/dist/chunk-IVD4OP3K.js +1 -0
- package/dist/{chunk-S7YQXEKM.js → chunk-QUIDZO5G.js} +104 -275
- package/dist/chunk-QUIDZO5G.js.map +1 -0
- package/dist/{chunk-RMIDEBHD.js → chunk-S2CH4HUZ.js} +7 -6
- package/dist/chunk-TZKNU5TD.js +1 -0
- package/dist/chunk-UFDQ3C7Q.js +919 -0
- package/dist/chunk-UFDQ3C7Q.js.map +1 -0
- package/dist/chunk-VJC24RKT.js +1 -0
- package/dist/chunk-WYS4ULBE.js +1 -0
- package/dist/{chunk-H4L3FNLS.js → chunk-ZBCQNWVN.js} +3 -2
- package/dist/{chunk-RM6MNDVF.js → chunk-ZIY22VO7.js} +193 -11
- package/dist/chunk-ZIY22VO7.js.map +1 -0
- package/dist/chunk-ZMJPRNOA.js +1 -0
- package/dist/compare-RQFCEZIK.js +1 -0
- package/dist/connection-utils-FEUWER5I.js +20 -0
- package/dist/{describe-X75C2VDU.js → describe-MEP72B56.js} +7 -6
- package/dist/{dev-GWXHBBWB.js → dev-H6SJZ5UA.js} +1315 -73
- package/dist/dev-H6SJZ5UA.js.map +1 -0
- package/dist/dist-5DQO6L2S.js +48 -0
- package/dist/dist-MIKFZKSD.js +1 -0
- package/dist/dist-PPAD6KOM.js +99 -0
- package/dist/{dist-JMLAZUL7.js → dist-XNCED7JW.js} +30 -12
- package/dist/generate-B7FAWVIQ.js +1 -0
- package/dist/index.js +25 -24
- package/dist/init-SECXKD5G.js +1 -0
- package/dist/lineage-HYO4RKZT.js +1 -0
- package/dist/public/assets/DataView-DUCz_96y.js +9 -0
- package/dist/public/assets/{EventManagement-CTuAJ0eF.js → EventManagement-BnmeJDQl.js} +1 -1
- package/dist/public/assets/{ExplorePage-ZJ3zNjNQ.js → ExplorePage-kk4z9ldZ.js} +1 -1
- package/dist/public/assets/{LoginPage-wygea4BI.js → LoginPage-CzaFkkjg.js} +1 -1
- package/dist/public/assets/{PublicViewer-8YqGrVVB.js → PublicViewer-irjxqH6a.js} +1 -1
- package/dist/public/assets/{SetupWizard-DqDBwHrF.js → SetupWizard-ConWIcmy.js} +1 -1
- package/dist/public/assets/{ShareManagement-TAAdI_gY.js → ShareManagement-CP4wdwLR.js} +1 -1
- package/dist/public/assets/SourceDetailView-DZS5518E.js +1 -0
- package/dist/public/assets/{UserManagement-B4kZHyri.js → UserManagement-AubGd9hl.js} +1 -1
- package/dist/public/assets/data-3vtzSuAZ.js +1 -0
- package/dist/public/assets/{index-CfyF2Wf-.css → index-C1X8RW4Z.css} +1 -1
- package/dist/public/assets/{index-BgzSjgIu.js → index-jlfTO7f5.js} +44 -44
- package/dist/public/assets/{index.es-AB-GdGyc.js → index.es-CgnvEWi5.js} +1 -1
- package/dist/public/assets/{jspdf.es.min-ChRx2mOQ.js → jspdf.es.min-Cw5WefMt.js} +3 -3
- package/dist/public/index.html +2 -2
- package/dist/{query-QNRDS74I.js → query-2H3YOPI2.js} +6 -5
- package/dist/reset-password-YVCZKZPC.js +1 -0
- package/dist/rewrite-database-BOA4QPUR.js +1 -0
- package/dist/{sample-SKLHBZBU.js → sample-ODUGGSFA.js} +6 -5
- package/dist/{search-4KMETZVX.js → search-IPE4ISFB.js} +7 -6
- package/dist/{semantic-6WKELH5V.js → semantic-K3MYXXJI.js} +4 -2
- package/dist/{semantic-6WKELH5V.js.map → semantic-K3MYXXJI.js.map} +1 -1
- package/dist/source-resolver-HZQLOODU.js +19 -0
- package/dist/source-resolver-HZQLOODU.js.map +1 -0
- package/dist/sync-dbt-72GVO75P.js +1 -0
- package/dist/{sync-warehouse-UWRNUXE7.js → sync-warehouse-TUNULDUY.js} +6 -5
- package/dist/{tables-V65QUGHK.js → tables-K5NAN2WK.js} +7 -6
- package/dist/templates/default/docs/yamchart-reference.md +42 -0
- package/dist/{test-UE5OWG3E.js → test-SRHVOXZB.js} +9 -7
- package/dist/{test-UE5OWG3E.js.map → test-SRHVOXZB.js.map} +1 -1
- package/dist/update-HWCJNQRP.js +1 -0
- package/package.json +8 -6
- package/dist/advisor-SC64RTZO.js.map +0 -1
- package/dist/chunk-NXQ6ZO3V.js.map +0 -1
- package/dist/chunk-RM6MNDVF.js.map +0 -1
- package/dist/chunk-S7YQXEKM.js.map +0 -1
- package/dist/chunk-UND73EOB.js +0 -449
- package/dist/chunk-UND73EOB.js.map +0 -1
- package/dist/connection-utils-C4FQGBW6.js +0 -19
- package/dist/dev-GWXHBBWB.js.map +0 -1
- package/dist/dist-MNXSMGV6.js.map +0 -1
- package/dist/dist-MX5K2ABB.js +0 -56
- package/dist/source-resolver-R7WBIL7M.js +0 -18
- /package/dist/{chunk-RMIDEBHD.js.map → chunk-S2CH4HUZ.js.map} +0 -0
- /package/dist/{chunk-H4L3FNLS.js.map → chunk-ZBCQNWVN.js.map} +0 -0
- /package/dist/{connection-utils-C4FQGBW6.js.map → connection-utils-FEUWER5I.js.map} +0 -0
- /package/dist/{describe-X75C2VDU.js.map → describe-MEP72B56.js.map} +0 -0
- /package/dist/{dist-JMLAZUL7.js.map → dist-5DQO6L2S.js.map} +0 -0
- /package/dist/{dist-MX5K2ABB.js.map → dist-PPAD6KOM.js.map} +0 -0
- /package/dist/{source-resolver-R7WBIL7M.js.map → dist-XNCED7JW.js.map} +0 -0
- /package/dist/{query-QNRDS74I.js.map → query-2H3YOPI2.js.map} +0 -0
- /package/dist/{sample-SKLHBZBU.js.map → sample-ODUGGSFA.js.map} +0 -0
- /package/dist/{search-4KMETZVX.js.map → search-IPE4ISFB.js.map} +0 -0
- /package/dist/{sync-warehouse-UWRNUXE7.js.map → sync-warehouse-TUNULDUY.js.map} +0 -0
- /package/dist/{tables-V65QUGHK.js.map → tables-K5NAN2WK.js.map} +0 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { createRequire as __yamchartCreateRequire } from 'module'; if (!globalThis.require) globalThis.require = __yamchartCreateRequire(import.meta.url);
|
|
1
2
|
import {
|
|
2
3
|
createConnector,
|
|
4
|
+
loadProjectConfig,
|
|
3
5
|
resolveConnection
|
|
4
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-5FHV22X2.js";
|
|
5
7
|
import {
|
|
6
8
|
detail,
|
|
7
9
|
error,
|
|
@@ -10,9 +12,12 @@ import {
|
|
|
10
12
|
success,
|
|
11
13
|
warning
|
|
12
14
|
} from "./chunk-HJVVHYVN.js";
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
import {
|
|
16
|
+
createProviderForTask
|
|
17
|
+
} from "./chunk-64CI3HSY.js";
|
|
18
|
+
import "./chunk-QUIDZO5G.js";
|
|
19
|
+
import "./chunk-UFDQ3C7Q.js";
|
|
20
|
+
import "./chunk-ZIY22VO7.js";
|
|
16
21
|
import "./chunk-7D4SUZUM.js";
|
|
17
22
|
|
|
18
23
|
// src/commands/advisor.ts
|
|
@@ -44,7 +49,7 @@ async function getDbtProjectPath(projectDir, override) {
|
|
|
44
49
|
return null;
|
|
45
50
|
}
|
|
46
51
|
async function buildContext(projectDir, options) {
|
|
47
|
-
const { parseModelMetadata } = await import("./dist-
|
|
52
|
+
const { parseModelMetadata } = await import("./dist-XNCED7JW.js");
|
|
48
53
|
const modelsDir = join(projectDir, "models");
|
|
49
54
|
const yamchartModels = [];
|
|
50
55
|
try {
|
|
@@ -140,7 +145,7 @@ async function buildContext(projectDir, options) {
|
|
|
140
145
|
};
|
|
141
146
|
if (dbtPath) {
|
|
142
147
|
try {
|
|
143
|
-
const { detectConventions, listDbtModels } = await import("./dist-
|
|
148
|
+
const { detectConventions, listDbtModels } = await import("./dist-5DQO6L2S.js");
|
|
144
149
|
const dbtProjectYml = await readFile(join(dbtPath, "dbt_project.yml"), "utf-8");
|
|
145
150
|
const dbtConfig = parseYaml(dbtProjectYml);
|
|
146
151
|
const conventions = await detectConventions(dbtPath);
|
|
@@ -205,8 +210,13 @@ function formatProposal(proposal, conventions, buildModelPathFn) {
|
|
|
205
210
|
return lines.join("\n");
|
|
206
211
|
}
|
|
207
212
|
async function runAdvisor(projectDir, questionOrMode, options) {
|
|
208
|
-
|
|
209
|
-
|
|
213
|
+
let projectAi;
|
|
214
|
+
try {
|
|
215
|
+
const projectConfig = await loadProjectConfig(projectDir);
|
|
216
|
+
projectAi = projectConfig.ai;
|
|
217
|
+
} catch {
|
|
218
|
+
}
|
|
219
|
+
if (!projectAi && !process.env.ANTHROPIC_API_KEY) {
|
|
210
220
|
error("ANTHROPIC_API_KEY environment variable is required");
|
|
211
221
|
detail("Set it in your .env file or shell environment");
|
|
212
222
|
process.exit(1);
|
|
@@ -236,8 +246,8 @@ async function runAdvisor(projectDir, questionOrMode, options) {
|
|
|
236
246
|
`warehouse: ${context.warehouse ? `connected (${context.warehouse.connectionType})` : "not connected"}`
|
|
237
247
|
);
|
|
238
248
|
console.log("");
|
|
239
|
-
const { AdvisorAgent,
|
|
240
|
-
const provider =
|
|
249
|
+
const { AdvisorAgent, buildModelPath } = await import("./dist-5DQO6L2S.js");
|
|
250
|
+
const provider = createProviderForTask(projectAi, "advisor", process.env);
|
|
241
251
|
const agent = new AdvisorAgent(provider);
|
|
242
252
|
const isAudit = questionOrMode === "audit";
|
|
243
253
|
if (isAudit) {
|
|
@@ -281,7 +291,7 @@ ${pc.bold(`[${i + 1}]`)} ${formatProposal(proposal, context.dbt.conventions, bui
|
|
|
281
291
|
spin2.stop();
|
|
282
292
|
console.log(result.response);
|
|
283
293
|
if (result.proposals.length > 0) {
|
|
284
|
-
const { buildModelPath: bmp } = await import("./dist-
|
|
294
|
+
const { buildModelPath: bmp } = await import("./dist-5DQO6L2S.js");
|
|
285
295
|
for (const proposal of result.proposals) {
|
|
286
296
|
console.log(
|
|
287
297
|
`
|
|
@@ -322,7 +332,7 @@ ${formatProposal(proposal, context.dbt.conventions, bmp)}`
|
|
|
322
332
|
conversationHistory.length = 0;
|
|
323
333
|
conversationHistory.push(...result.messages);
|
|
324
334
|
if (result.proposals.length > 0) {
|
|
325
|
-
const { buildModelPath: bmp } = await import("./dist-
|
|
335
|
+
const { buildModelPath: bmp } = await import("./dist-5DQO6L2S.js");
|
|
326
336
|
for (const proposal of result.proposals) {
|
|
327
337
|
console.log(
|
|
328
338
|
`
|
|
@@ -340,7 +350,7 @@ async function offerApply(context, proposals) {
|
|
|
340
350
|
return;
|
|
341
351
|
}
|
|
342
352
|
const { confirm } = await import("@inquirer/prompts");
|
|
343
|
-
const { writeDbtModel, buildModelPath, formatModelSql, updateSchemaYml } = await import("./dist-
|
|
353
|
+
const { writeDbtModel, buildModelPath, formatModelSql, updateSchemaYml } = await import("./dist-5DQO6L2S.js");
|
|
344
354
|
for (const proposal of proposals) {
|
|
345
355
|
console.log("");
|
|
346
356
|
const shouldApply = await confirm({
|
|
@@ -379,4 +389,4 @@ async function offerApply(context, proposals) {
|
|
|
379
389
|
export {
|
|
380
390
|
runAdvisor
|
|
381
391
|
};
|
|
382
|
-
//# sourceMappingURL=advisor-
|
|
392
|
+
//# sourceMappingURL=advisor-5TJDNAY7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/advisor.ts"],"sourcesContent":["import { readFile, readdir, access } from 'fs/promises';\nimport { join } from 'path';\nimport { parse as parseYaml } from 'yaml';\nimport { createInterface } from 'readline';\nimport pc from 'picocolors';\nimport * as output from '../utils/output.js';\nimport { resolveConnection, createConnector, loadProjectConfig } from './connection-utils.js';\nimport type { Message, AdvisorContext, Proposal, CatalogJsonData } from '@yamchart/advisor';\nimport { createProviderForTask } from '@yamchart/advisor';\n\nexport interface AdvisorOptions {\n top?: number;\n json?: boolean;\n dbtPath?: string;\n connection?: string;\n}\n\nasync function loadCatalogMarkdown(projectDir: string): Promise<string | null> {\n try {\n const catalogPath = join(projectDir, '.yamchart', 'catalog.md');\n await access(catalogPath);\n return readFile(catalogPath, 'utf-8');\n } catch {\n return null;\n }\n}\n\nasync function getDbtProjectPath(projectDir: string, override?: string): Promise<string | null> {\n if (override) return override;\n\n try {\n const dbtSourcePath = join(projectDir, '.yamchart', 'dbt-source.yaml');\n const content = await readFile(dbtSourcePath, 'utf-8');\n const parsed = parseYaml(content) as { path?: string };\n if (parsed.path) {\n return join(projectDir, parsed.path);\n }\n } catch {\n // No saved dbt source config\n }\n\n return null;\n}\n\nasync function buildContext(\n projectDir: string,\n options: AdvisorOptions,\n): Promise<AdvisorContext> {\n // 1. Load yamchart models\n const { parseModelMetadata } = await import('@yamchart/query');\n const modelsDir = join(projectDir, 'models');\n const yamchartModels: AdvisorContext['yamchart']['models'] = [];\n\n try {\n const files = await readdir(modelsDir, { recursive: true });\n for (const file of files) {\n if (!String(file).endsWith('.sql')) continue;\n const content = await readFile(join(modelsDir, String(file)), 'utf-8');\n try {\n const metadata = parseModelMetadata(content);\n yamchartModels.push({\n name: metadata.name,\n description: metadata.description,\n sql: metadata.sql,\n params: metadata.params?.map((p) => ({ name: p.name, type: p.type })),\n returns: metadata.returns?.map((r) => ({ name: r.name, type: r.type })),\n });\n } catch {\n // Skip unparseable models\n }\n }\n } catch {\n // No models dir\n }\n\n // 2. Load yamchart charts\n const chartsDir = join(projectDir, 'charts');\n const yamchartCharts: AdvisorContext['yamchart']['charts'] = [];\n\n try {\n const files = await readdir(chartsDir, { recursive: true });\n for (const file of files) {\n const fname = String(file);\n if (!fname.endsWith('.yaml') && !fname.endsWith('.yml')) continue;\n const content = await readFile(join(chartsDir, fname), 'utf-8');\n try {\n const parsed = parseYaml(content) as {\n name?: string;\n title?: string;\n source?: { model?: string };\n chart?: { type?: string };\n };\n if (parsed.name && parsed.source?.model) {\n yamchartCharts.push({\n name: parsed.name,\n title: parsed.title,\n model: parsed.source.model,\n type: parsed.chart?.type ?? 'unknown',\n });\n }\n } catch {\n // Skip unparseable charts\n }\n }\n } catch {\n // No charts dir\n }\n\n // 3. Load yamchart dashboards\n const dashboardsDir = join(projectDir, 'dashboards');\n const yamchartDashboards: AdvisorContext['yamchart']['dashboards'] = [];\n\n try {\n const files = await readdir(dashboardsDir, { recursive: true });\n for (const file of files) {\n const fname = String(file);\n if (!fname.endsWith('.yaml') && !fname.endsWith('.yml')) continue;\n const content = await readFile(join(dashboardsDir, fname), 'utf-8');\n try {\n const parsed = parseYaml(content) as {\n name?: string;\n title?: string;\n layout?: { rows?: Array<{ widgets?: Array<{ ref?: string }> }> };\n };\n if (parsed.name) {\n const charts: string[] = [];\n for (const row of parsed.layout?.rows ?? []) {\n for (const widget of row.widgets ?? []) {\n if (widget.ref) charts.push(widget.ref);\n }\n }\n yamchartDashboards.push({\n name: parsed.name,\n title: parsed.title,\n charts,\n });\n }\n } catch {\n // Skip\n }\n }\n } catch {\n // No dashboards dir\n }\n\n // 4. Load catalog\n const catalog = await loadCatalogMarkdown(projectDir);\n\n // 4b. Load catalog.json (warehouse table metadata)\n let catalogJson: CatalogJsonData | null = null;\n try {\n const raw = await readFile(join(projectDir, '.yamchart', 'catalog.json'), 'utf-8');\n const parsed = JSON.parse(raw);\n catalogJson = { models: parsed.models || [] };\n } catch {\n // No catalog.json available\n }\n\n // 5. Load dbt project\n const dbtPath = await getDbtProjectPath(projectDir, options.dbtPath);\n let dbt: AdvisorContext['dbt'] = {\n projectPath: dbtPath ?? '',\n projectName: 'unknown',\n conventions: {\n folderStructure: [],\n namingPrefixes: {},\n commonMaterializations: {},\n schemaYmlPattern: 'per-folder',\n testPatterns: [],\n },\n models: [],\n };\n\n if (dbtPath) {\n try {\n const { detectConventions, listDbtModels } = await import('@yamchart/advisor');\n const dbtProjectYml = await readFile(join(dbtPath, 'dbt_project.yml'), 'utf-8');\n const dbtConfig = parseYaml(dbtProjectYml) as { name?: string };\n\n const conventions = await detectConventions(dbtPath);\n const models = await listDbtModels(dbtPath);\n\n dbt = {\n projectPath: dbtPath,\n projectName: dbtConfig.name ?? 'unknown',\n conventions,\n models,\n };\n } catch (err) {\n output.warning(\n `Could not read dbt project: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n // 6. Set up warehouse connection (optional)\n let warehouse: AdvisorContext['warehouse'] = null;\n\n try {\n const connection = await resolveConnection(projectDir, options.connection);\n const connector = createConnector(connection, projectDir);\n await connector.connect();\n\n warehouse = {\n connectionType: connection.type,\n executeSql: async (sql: string) => {\n const result = await connector.execute(sql);\n return {\n columns: result.columns.map((c) => c.name),\n rows: result.rows,\n };\n },\n };\n } catch {\n // No connection available — advisor works without it\n }\n\n return {\n yamchart: {\n models: yamchartModels,\n charts: yamchartCharts,\n dashboards: yamchartDashboards,\n catalog,\n catalogJson,\n },\n dbt,\n warehouse,\n };\n}\n\nfunction formatProposal(\n proposal: Proposal,\n conventions: AdvisorContext['dbt']['conventions'],\n buildModelPathFn: (\n name: string,\n layer: string | undefined,\n conventions: AdvisorContext['dbt']['conventions'],\n subfolder?: string,\n ) => string,\n): string {\n const path = buildModelPathFn(\n proposal.name,\n proposal.layer,\n conventions,\n proposal.subfolder,\n );\n\n const lines = [\n pc.bold(` ${proposal.name}`),\n ` ${pc.dim(proposal.explanation)}`,\n ` Path: ${pc.cyan(path)} (${proposal.materialization})`,\n '',\n pc.dim(' ' + '\\u2500'.repeat(30)),\n proposal.sql\n .split('\\n')\n .map((l: string) => ` ${pc.dim(l)}`)\n .join('\\n'),\n pc.dim(' ' + '\\u2500'.repeat(30)),\n ];\n return lines.join('\\n');\n}\n\nexport async function runAdvisor(\n projectDir: string,\n questionOrMode: string | undefined,\n options: AdvisorOptions,\n): Promise<void> {\n // Load project config to access ai: block (if configured).\n // Gracefully ignore missing yamchart.yaml — advisor can run without it.\n let projectAi: import('@yamchart/schema').AiConfig | undefined;\n try {\n const projectConfig = await loadProjectConfig(projectDir);\n projectAi = projectConfig.ai;\n } catch {\n // No yamchart.yaml or parse error — fall back to Anthropic default\n }\n\n // When no ai: block is configured, the factory requires ANTHROPIC_API_KEY.\n // Surface a helpful message before the factory throws.\n if (!projectAi && !process.env.ANTHROPIC_API_KEY) {\n output.error('ANTHROPIC_API_KEY environment variable is required');\n output.detail('Set it in your .env file or shell environment');\n process.exit(1);\n }\n\n const spin = output.spinner('Loading project context...');\n const context = await buildContext(projectDir, options);\n spin.stop();\n\n // Print startup banner\n console.log('');\n output.header('dbt advisor');\n if (context.dbt.projectPath) {\n output.detail(\n `dbt project: ${context.dbt.projectName} at ${context.dbt.projectPath}`,\n );\n output.detail(\n `dbt models: ${context.dbt.models.length} (layers: ${context.dbt.conventions.folderStructure.join(', ') || 'none'})`,\n );\n } else {\n output.warning(\n 'No dbt project found. Run `yamchart sync-dbt --path <dbt-project>` to connect one.',\n );\n }\n output.detail(\n `yamchart: ${context.yamchart.models.length} models, ${context.yamchart.charts.length} charts, ${context.yamchart.dashboards.length} dashboards`,\n );\n output.detail(`catalog: ${context.yamchart.catalog ? 'loaded' : 'not synced'}`);\n output.detail(\n `warehouse: ${context.warehouse ? `connected (${context.warehouse.connectionType})` : 'not connected'}`,\n );\n console.log('');\n\n // Create agent\n const { AdvisorAgent, buildModelPath } = await import(\n '@yamchart/advisor'\n );\n const provider = createProviderForTask(projectAi, 'advisor', process.env);\n const agent = new AdvisorAgent(provider);\n\n const isAudit = questionOrMode === 'audit';\n\n if (isAudit) {\n // One-shot audit mode\n const top = options.top ?? 5;\n const auditPrompt = `Run a comprehensive audit of this project. Return your top ${top} suggestions ranked by impact. For each, call propose_model with the full SQL.`;\n\n const auditSpin = output.spinner('Running audit...');\n const result = await agent.run(context, [\n { role: 'user', content: auditPrompt },\n ]);\n auditSpin.stop();\n\n if (options.json) {\n console.log(\n JSON.stringify(\n { text: result.response, proposals: result.proposals },\n null,\n 2,\n ),\n );\n return;\n }\n\n console.log(result.response);\n\n if (result.proposals.length > 0) {\n console.log('');\n output.header(`${result.proposals.length} suggestion(s):`);\n\n for (let i = 0; i < result.proposals.length; i++) {\n const proposal = result.proposals[i]!;\n console.log(\n `\\n${pc.bold(`[${i + 1}]`)} ${formatProposal(proposal, context.dbt.conventions, buildModelPath)}`,\n );\n }\n\n // Offer to apply\n await offerApply(context, result.proposals);\n }\n return;\n }\n\n // Interactive mode\n if (questionOrMode) {\n // Single question mode\n const spin2 = output.spinner('Thinking...');\n const result = await agent.run(context, [\n { role: 'user', content: questionOrMode },\n ]);\n spin2.stop();\n\n console.log(result.response);\n\n if (result.proposals.length > 0) {\n const { buildModelPath: bmp } = await import('@yamchart/advisor');\n for (const proposal of result.proposals) {\n console.log(\n `\\n${formatProposal(proposal, context.dbt.conventions, bmp)}`,\n );\n }\n await offerApply(context, result.proposals);\n }\n return;\n }\n\n // Multi-turn interactive mode\n console.log(\n pc.dim(\n ' Ask me anything, or type \"audit\" for a full analysis. Type \"exit\" to quit.\\n',\n ),\n );\n\n const conversationHistory: Message[] = [];\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n\n const prompt = (): Promise<string> =>\n new Promise((resolve) => rl.question(pc.green('> '), resolve));\n\n while (true) {\n const userInput = await prompt();\n if (!userInput.trim()) continue;\n if (userInput.trim().toLowerCase() === 'exit') {\n rl.close();\n break;\n }\n\n if (userInput.trim().toLowerCase() === 'audit') {\n conversationHistory.push({\n role: 'user',\n content: `Run a comprehensive audit. Return your top ${options.top ?? 5} suggestions ranked by impact.`,\n });\n } else {\n conversationHistory.push({ role: 'user', content: userInput });\n }\n\n const spin3 = output.spinner('Thinking...');\n const result = await agent.run(context, conversationHistory);\n spin3.stop();\n\n console.log('\\n' + result.response);\n\n // Update conversation history with the full exchange\n conversationHistory.length = 0;\n conversationHistory.push(...result.messages);\n\n if (result.proposals.length > 0) {\n const { buildModelPath: bmp } = await import('@yamchart/advisor');\n for (const proposal of result.proposals) {\n console.log(\n `\\n${formatProposal(proposal, context.dbt.conventions, bmp)}`,\n );\n }\n await offerApply(context, result.proposals);\n }\n\n console.log('');\n }\n}\n\nasync function offerApply(\n context: AdvisorContext,\n proposals: Proposal[],\n): Promise<void> {\n if (!context.dbt.projectPath) {\n output.warning('No dbt project path configured \\u2014 cannot write files');\n return;\n }\n\n const { confirm } = await import('@inquirer/prompts');\n const { writeDbtModel, buildModelPath, formatModelSql, updateSchemaYml } =\n await import('@yamchart/advisor');\n\n for (const proposal of proposals) {\n console.log('');\n const shouldApply = await confirm({\n message: `Apply ${proposal.name} to dbt project?`,\n default: false,\n });\n\n if (!shouldApply) continue;\n\n const modelPath = buildModelPath(\n proposal.name,\n proposal.layer,\n context.dbt.conventions,\n proposal.subfolder,\n );\n\n const sql = formatModelSql({\n materialization: proposal.materialization,\n sql: proposal.sql,\n });\n\n await writeDbtModel(context.dbt.projectPath, modelPath, sql);\n output.success(`Created ${modelPath}`);\n\n // Update schema.yml\n const schemaDir = modelPath.split('/').slice(0, -1).join('/');\n const schemaPath = `${schemaDir}/schema.yml`;\n\n try {\n await updateSchemaYml(context.dbt.projectPath, schemaPath, {\n name: proposal.name,\n description: proposal.description,\n columns: proposal.columns,\n });\n output.success(`Updated ${schemaPath}`);\n } catch (err) {\n output.warning(\n `Could not update schema.yml: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/agent-TZZHNDPK.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ConnectionSchema
|
|
3
|
-
} from "./chunk-RM6MNDVF.js";
|
|
1
|
+
import { createRequire as __yamchartCreateRequire } from 'module'; if (!globalThis.require) globalThis.require = __yamchartCreateRequire(import.meta.url);
|
|
4
2
|
import {
|
|
5
3
|
BigQueryConnector,
|
|
6
4
|
DuckDBConnector,
|
|
@@ -12,7 +10,10 @@ import {
|
|
|
12
10
|
resolveMySQLAuth,
|
|
13
11
|
resolvePostgresAuth,
|
|
14
12
|
resolveSnowflakeAuth
|
|
15
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-QUIDZO5G.js";
|
|
14
|
+
import {
|
|
15
|
+
ConnectionSchema
|
|
16
|
+
} from "./chunk-ZIY22VO7.js";
|
|
16
17
|
|
|
17
18
|
// src/commands/connection-utils.ts
|
|
18
19
|
import { readFile, access } from "fs/promises";
|
|
@@ -22,7 +23,7 @@ async function loadProjectConfig(projectDir, env) {
|
|
|
22
23
|
const configPath = join(projectDir, "yamchart.yaml");
|
|
23
24
|
const content = await readFile(configPath, "utf-8");
|
|
24
25
|
const raw = parseYaml(content);
|
|
25
|
-
const { resolveProjectConfig, deepMerge } = await import("./dist-
|
|
26
|
+
const { resolveProjectConfig, deepMerge } = await import("./dist-PPAD6KOM.js");
|
|
26
27
|
const resolvedEnv = env || process.env.YAMCHART_ENV || void 0;
|
|
27
28
|
let merged = resolveProjectConfig(raw, resolvedEnv);
|
|
28
29
|
const localPath = join(projectDir, "yamchart.local.yaml");
|
|
@@ -195,4 +196,4 @@ export {
|
|
|
195
196
|
formatTable,
|
|
196
197
|
formatJSON
|
|
197
198
|
};
|
|
198
|
-
//# sourceMappingURL=chunk-
|
|
199
|
+
//# sourceMappingURL=chunk-5FHV22X2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/connection-utils.ts"],"sourcesContent":["import { readFile, access } from 'fs/promises';\nimport { join } from 'path';\nimport { parse as parseYaml } from 'yaml';\nimport {\n DuckDBConnector,\n PostgresConnector,\n MySQLConnector,\n SQLiteConnector,\n SnowflakeConnector,\n BigQueryConnector,\n resolvePostgresAuth,\n resolveMySQLAuth,\n resolveSnowflakeAuth,\n resolveBigQueryAuth,\n type Connector,\n type QueryResult,\n} from '@yamchart/query';\nimport {\n ConnectionSchema,\n type Connection,\n type DuckDBConnection,\n type PostgresConnection,\n type MySQLConnection,\n type SQLiteConnection,\n type SnowflakeConnection,\n type BigQueryConnection,\n type AiConfig,\n} from '@yamchart/schema';\n\nexport interface ProjectConfig {\n name: string;\n version?: string;\n default_connection?: string;\n defaults?: {\n connection?: string;\n };\n ai?: AiConfig;\n}\n\n/**\n * Read and parse yamchart.yaml from a project directory.\n * Resolves environment overrides and merges yamchart.local.yaml if present.\n */\nexport async function loadProjectConfig(\n projectDir: string,\n env?: string,\n): Promise<ProjectConfig> {\n const configPath = join(projectDir, 'yamchart.yaml');\n const content = await readFile(configPath, 'utf-8');\n const raw = parseYaml(content) as Record<string, unknown>;\n\n const { resolveProjectConfig, deepMerge } = await import('@yamchart/schema');\n const resolvedEnv = env || process.env.YAMCHART_ENV || undefined;\n let merged = resolveProjectConfig(raw, resolvedEnv);\n\n // Merge yamchart.local.yaml if it exists\n const localPath = join(projectDir, 'yamchart.local.yaml');\n try {\n await access(localPath);\n const localContent = await readFile(localPath, 'utf-8');\n const localOverrides = parseYaml(localContent) as Record<string, unknown>;\n if (localOverrides && typeof localOverrides === 'object') {\n merged = deepMerge(merged, localOverrides);\n }\n } catch {\n // No local overrides file\n }\n\n return merged as ProjectConfig;\n}\n\n/**\n * Load and validate a connection YAML file.\n * Tries .yaml then .yml extensions.\n * If no overrideName, falls back to defaults.connection from project config.\n */\nexport async function resolveConnection(\n projectDir: string,\n overrideName?: string,\n env?: string,\n): Promise<Connection> {\n const config = await loadProjectConfig(projectDir, env);\n const connName = overrideName || config.defaults?.connection || config.default_connection;\n\n if (!connName) {\n throw new Error(\n 'No connection specified. Use --connection or set defaults.connection in yamchart.yaml.',\n );\n }\n\n const yamlPath = join(projectDir, 'connections', `${connName}.yaml`);\n const ymlPath = join(projectDir, 'connections', `${connName}.yml`);\n\n let connPath = yamlPath;\n try {\n await access(yamlPath);\n } catch {\n try {\n await access(ymlPath);\n connPath = ymlPath;\n } catch {\n throw new Error(`Connection \"${connName}\" not found at connections/${connName}.yaml`);\n }\n }\n\n const content = await readFile(connPath, 'utf-8');\n const raw = parseYaml(content);\n const parsed = ConnectionSchema.parse(raw);\n return parsed;\n}\n\n/**\n * Instantiate the right connector class based on connection.type.\n * Resolves auth and relative paths. Does NOT call connect().\n */\nexport function createConnector(connection: Connection, projectDir: string): Connector {\n switch (connection.type) {\n case 'duckdb': {\n const duckdbConn = connection as DuckDBConnection;\n const dbPath = duckdbConn.config.path.startsWith('/')\n ? duckdbConn.config.path\n : duckdbConn.config.path === ':memory:'\n ? ':memory:'\n : join(projectDir, duckdbConn.config.path);\n return new DuckDBConnector({ path: dbPath });\n }\n\n case 'postgres': {\n const pgConn = connection as PostgresConnection;\n const credentials = resolvePostgresAuth(pgConn);\n return new PostgresConnector({\n host: pgConn.config.host,\n port: pgConn.config.port,\n database: pgConn.config.database,\n schema: pgConn.config.schema,\n ssl: pgConn.config.ssl,\n user: credentials.user,\n password: credentials.password,\n min: pgConn.pool?.min_connections,\n max: pgConn.pool?.max_connections,\n idleTimeoutMillis: pgConn.pool?.idle_timeout,\n statementTimeout: pgConn.query?.timeout,\n });\n }\n\n case 'mysql': {\n const mysqlConn = connection as MySQLConnection;\n const credentials = resolveMySQLAuth(mysqlConn);\n return new MySQLConnector({\n host: mysqlConn.config.host,\n port: mysqlConn.config.port,\n database: mysqlConn.config.database,\n ssl: mysqlConn.config.ssl,\n user: credentials.user,\n password: credentials.password,\n min: mysqlConn.pool?.min_connections,\n max: mysqlConn.pool?.max_connections,\n idleTimeoutMillis: mysqlConn.pool?.idle_timeout,\n statementTimeout: mysqlConn.query?.timeout,\n });\n }\n\n case 'sqlite': {\n const sqliteConn = connection as SQLiteConnection;\n const dbPath = sqliteConn.config.path.startsWith('/')\n ? sqliteConn.config.path\n : sqliteConn.config.path === ':memory:'\n ? ':memory:'\n : join(projectDir, sqliteConn.config.path);\n return new SQLiteConnector({ path: dbPath });\n }\n\n case 'snowflake': {\n const sfConn = connection as SnowflakeConnection;\n const credentials = resolveSnowflakeAuth(sfConn);\n return new SnowflakeConnector({\n account: sfConn.config.account,\n username: credentials.username,\n password: credentials.password,\n privateKey: credentials.privateKey,\n authenticator: credentials.authenticator,\n clientStoreTemporaryCredential: credentials.clientStoreTemporaryCredential,\n warehouse: sfConn.config.warehouse,\n database: sfConn.config.database,\n schema: sfConn.config.schema,\n role: sfConn.config.role,\n statementTimeout: sfConn.query?.timeout,\n });\n }\n\n case 'bigquery': {\n const bqConn = connection as BigQueryConnection;\n const creds = resolveBigQueryAuth(bqConn);\n // Resolve a relative key_file against the project dir (like duckdb/sqlite paths).\n const keyFilename = creds.keyFilename\n ? (creds.keyFilename.startsWith('/') ? creds.keyFilename : join(projectDir, creds.keyFilename))\n : undefined;\n return new BigQueryConnector({\n projectId: bqConn.config.project_id,\n dataset: bqConn.config.dataset,\n location: bqConn.config.location,\n maxBytesBilled: bqConn.config.max_bytes_billed,\n credentials: creds.credentials,\n keyFilename,\n });\n }\n\n default:\n throw new Error(`Unsupported connection type: ${(connection as Connection).type}`);\n }\n}\n\n/**\n * Format a query result as an aligned terminal table.\n * Truncates values longer than 40 characters.\n */\nexport function formatTable(result: QueryResult): string {\n const { columns, rows, rowCount, durationMs } = result;\n const maxWidth = 40;\n\n const truncate = (val: unknown): string => {\n if (val === null || val === undefined) return 'NULL';\n const str = String(val);\n if (str.length > maxWidth) return str.slice(0, maxWidth - 3) + '...';\n return str;\n };\n\n // Calculate column widths\n const headers = columns.map((c) => c.name);\n const formattedRows = rows.map((row) =>\n columns.map((c) => truncate(row[c.name])),\n );\n\n const colWidths = headers.map((h, i) => {\n const dataMax = formattedRows.reduce(\n (max, row) => Math.max(max, row[i]!.length),\n 0,\n );\n return Math.max(h.length, dataMax);\n });\n\n // Build lines\n const lines: string[] = [];\n\n // Header\n const headerLine = headers.map((h, i) => h.padEnd(colWidths[i]!)).join(' ');\n lines.push(headerLine);\n\n // Separator\n const separator = colWidths.map((w) => '-'.repeat(w)).join(' ');\n lines.push(separator);\n\n // Data rows\n for (const row of formattedRows) {\n const line = row.map((val, i) => val.padEnd(colWidths[i]!)).join(' ');\n lines.push(line);\n }\n\n // Footer\n lines.push('');\n lines.push(`${rowCount} row(s) (${Math.round(durationMs)}ms)`);\n\n return lines.join('\\n');\n}\n\n/**\n * Format a query result as a JSON string.\n */\nexport function formatJSON(result: QueryResult): string {\n return JSON.stringify(\n {\n columns: result.columns,\n rows: result.rows,\n rowCount: result.rowCount,\n durationMs: result.durationMs,\n },\n null,\n 2,\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createRequire as __yamchartCreateRequire } from 'module'; if (!globalThis.require) globalThis.require = __yamchartCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
SemanticModelBuilder,
|
|
4
4
|
SemanticQueryCompiler
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-7D4SUZUM.js";
|
|
5
|
+
} from "./chunk-UFDQ3C7Q.js";
|
|
7
6
|
|
|
8
7
|
// ../../packages/advisor/dist/dbt/knowledge.js
|
|
9
8
|
import { readFile } from "fs/promises";
|
|
@@ -680,6 +679,171 @@ var AnthropicProvider = class {
|
|
|
680
679
|
}
|
|
681
680
|
};
|
|
682
681
|
|
|
682
|
+
// ../../packages/advisor/dist/providers/openai-compatible.js
|
|
683
|
+
import OpenAI from "openai";
|
|
684
|
+
var OpenAICompatibleProvider = class {
|
|
685
|
+
client;
|
|
686
|
+
model;
|
|
687
|
+
constructor(opts) {
|
|
688
|
+
this.client = new OpenAI({ baseURL: opts.baseURL, apiKey: opts.apiKey ?? "not-needed" });
|
|
689
|
+
this.model = opts.model;
|
|
690
|
+
}
|
|
691
|
+
async chat(options) {
|
|
692
|
+
const tools = options.tools.map((t) => ({
|
|
693
|
+
type: "function",
|
|
694
|
+
function: {
|
|
695
|
+
name: t.name,
|
|
696
|
+
description: t.description,
|
|
697
|
+
parameters: {
|
|
698
|
+
type: "object",
|
|
699
|
+
properties: t.parameters.properties,
|
|
700
|
+
required: t.parameters.required ?? []
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
}));
|
|
704
|
+
const messages = [
|
|
705
|
+
{ role: "system", content: options.system }
|
|
706
|
+
];
|
|
707
|
+
for (const m of options.messages) {
|
|
708
|
+
if (typeof m.content === "string") {
|
|
709
|
+
messages.push({ role: m.role, content: m.content });
|
|
710
|
+
continue;
|
|
711
|
+
}
|
|
712
|
+
const text = m.content.filter((b) => b.type === "text").map((b) => b.text).join("\n");
|
|
713
|
+
const toolUses = m.content.filter((b) => b.type === "tool_use");
|
|
714
|
+
const toolResults = m.content.filter((b) => b.type === "tool_result");
|
|
715
|
+
if (m.role === "assistant" && toolUses.length) {
|
|
716
|
+
messages.push({
|
|
717
|
+
role: "assistant",
|
|
718
|
+
content: text || null,
|
|
719
|
+
tool_calls: toolUses.map((tu) => ({
|
|
720
|
+
id: tu.id,
|
|
721
|
+
type: "function",
|
|
722
|
+
function: { name: tu.name, arguments: JSON.stringify(tu.input) }
|
|
723
|
+
}))
|
|
724
|
+
});
|
|
725
|
+
} else if (toolResults.length) {
|
|
726
|
+
for (const tr of toolResults) {
|
|
727
|
+
messages.push({ role: "tool", tool_call_id: tr.tool_use_id, content: tr.content });
|
|
728
|
+
}
|
|
729
|
+
if (text)
|
|
730
|
+
messages.push({ role: m.role, content: text });
|
|
731
|
+
} else {
|
|
732
|
+
messages.push({ role: m.role, content: text });
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
const response = await this.client.chat.completions.create({
|
|
736
|
+
model: this.model,
|
|
737
|
+
max_tokens: options.maxTokens ?? 4096,
|
|
738
|
+
messages,
|
|
739
|
+
...tools.length ? { tools } : {}
|
|
740
|
+
});
|
|
741
|
+
const choice = response.choices[0];
|
|
742
|
+
const msg = choice?.message;
|
|
743
|
+
const content = [];
|
|
744
|
+
if (msg?.content) {
|
|
745
|
+
content.push({ type: "text", text: msg.content });
|
|
746
|
+
}
|
|
747
|
+
for (const tc of msg?.tool_calls ?? []) {
|
|
748
|
+
let input = {};
|
|
749
|
+
try {
|
|
750
|
+
input = JSON.parse(tc.function.arguments || "{}");
|
|
751
|
+
} catch {
|
|
752
|
+
input = {};
|
|
753
|
+
}
|
|
754
|
+
content.push({ type: "tool_use", id: tc.id, name: tc.function.name, input });
|
|
755
|
+
}
|
|
756
|
+
return {
|
|
757
|
+
content,
|
|
758
|
+
stopReason: choice?.finish_reason === "tool_calls" ? "tool_use" : "end"
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
// ../../packages/advisor/dist/providers/factory.js
|
|
764
|
+
function requireKey(env, name) {
|
|
765
|
+
const v = env[name];
|
|
766
|
+
if (!v)
|
|
767
|
+
throw new Error(`Missing ${name} for the configured LLM provider.`);
|
|
768
|
+
return v;
|
|
769
|
+
}
|
|
770
|
+
function requireModel(cfg) {
|
|
771
|
+
if (!cfg.model)
|
|
772
|
+
throw new Error(`The "${cfg.provider}" provider requires a model.`);
|
|
773
|
+
return cfg.model;
|
|
774
|
+
}
|
|
775
|
+
function buildProvider(cfg, env) {
|
|
776
|
+
switch (cfg.provider) {
|
|
777
|
+
case "anthropic":
|
|
778
|
+
return new AnthropicProvider(requireKey(env, cfg.api_key_var ?? "ANTHROPIC_API_KEY"), cfg.model);
|
|
779
|
+
case "openai":
|
|
780
|
+
return new OpenAICompatibleProvider({ baseURL: cfg.base_url ?? "https://api.openai.com/v1", apiKey: requireKey(env, cfg.api_key_var ?? "OPENAI_API_KEY"), model: requireModel(cfg) });
|
|
781
|
+
case "gemini":
|
|
782
|
+
return new OpenAICompatibleProvider({ baseURL: cfg.base_url ?? "https://generativelanguage.googleapis.com/v1beta/openai/", apiKey: requireKey(env, cfg.api_key_var ?? (env.GEMINI_API_KEY ? "GEMINI_API_KEY" : "GOOGLE_API_KEY")), model: requireModel(cfg) });
|
|
783
|
+
case "ollama":
|
|
784
|
+
return new OpenAICompatibleProvider({ baseURL: cfg.base_url ?? "http://localhost:11434/v1", apiKey: "ollama", model: requireModel(cfg) });
|
|
785
|
+
case "ollama_cloud":
|
|
786
|
+
return new OpenAICompatibleProvider({ baseURL: cfg.base_url ?? "https://ollama.com/v1", apiKey: requireKey(env, cfg.api_key_var ?? "OLLAMA_API_KEY"), model: requireModel(cfg) });
|
|
787
|
+
case "openai_compatible":
|
|
788
|
+
if (!cfg.base_url)
|
|
789
|
+
throw new Error("openai_compatible requires base_url.");
|
|
790
|
+
return new OpenAICompatibleProvider({ baseURL: cfg.base_url, apiKey: cfg.api_key_var ? requireKey(env, cfg.api_key_var) : "not-needed", model: requireModel(cfg) });
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
function createProviderForTask(config, task, env) {
|
|
794
|
+
if (!config)
|
|
795
|
+
return new AnthropicProvider(requireKey(env, "ANTHROPIC_API_KEY"));
|
|
796
|
+
const name = config.tasks?.[task] ?? config.default;
|
|
797
|
+
const cfg = name ? config.providers?.[name] : void 0;
|
|
798
|
+
if (!cfg)
|
|
799
|
+
return new AnthropicProvider(requireKey(env, "ANTHROPIC_API_KEY"));
|
|
800
|
+
return buildProvider(cfg, env);
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
// ../../packages/advisor/dist/providers/embedder.js
|
|
804
|
+
import OpenAI2 from "openai";
|
|
805
|
+
var PRESET_BASE = {
|
|
806
|
+
ollama: "http://localhost:11434/v1",
|
|
807
|
+
ollama_cloud: "https://ollama.com/v1",
|
|
808
|
+
openai: "https://api.openai.com/v1",
|
|
809
|
+
gemini: "https://generativelanguage.googleapis.com/v1beta/openai/"
|
|
810
|
+
};
|
|
811
|
+
function resolveKey(c, env) {
|
|
812
|
+
if (c.api_key_var)
|
|
813
|
+
return env[c.api_key_var] ?? "not-needed";
|
|
814
|
+
switch (c.provider) {
|
|
815
|
+
case "ollama":
|
|
816
|
+
return "ollama";
|
|
817
|
+
case "gemini":
|
|
818
|
+
return env.GEMINI_API_KEY ?? env.GOOGLE_API_KEY ?? "not-needed";
|
|
819
|
+
case "ollama_cloud":
|
|
820
|
+
return env.OLLAMA_API_KEY ?? "not-needed";
|
|
821
|
+
case "openai":
|
|
822
|
+
return env.OPENAI_API_KEY ?? "not-needed";
|
|
823
|
+
default:
|
|
824
|
+
return env.OPENAI_API_KEY ?? "not-needed";
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
function createEmbedder(cfg, env) {
|
|
828
|
+
const c = cfg ?? { provider: "ollama", model: "nomic-embed-text" };
|
|
829
|
+
const model = c.model ?? "nomic-embed-text";
|
|
830
|
+
const baseURL = c.base_url ?? PRESET_BASE[c.provider] ?? "http://localhost:11434/v1";
|
|
831
|
+
const apiKey = resolveKey(c, env);
|
|
832
|
+
const client = new OpenAI2({ baseURL, apiKey });
|
|
833
|
+
return {
|
|
834
|
+
model,
|
|
835
|
+
baseURL,
|
|
836
|
+
client,
|
|
837
|
+
// `client` is internal; cast in tests
|
|
838
|
+
async embed(texts) {
|
|
839
|
+
if (texts.length === 0)
|
|
840
|
+
return [];
|
|
841
|
+
const res = await this.client.embeddings.create({ model, input: texts });
|
|
842
|
+
return res.data.map((d) => d.embedding);
|
|
843
|
+
}
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
|
|
683
847
|
// ../../packages/advisor/dist/dbt/writer.js
|
|
684
848
|
import { readFile as readFile3, writeFile, mkdir, access } from "fs/promises";
|
|
685
849
|
import { join as join3, dirname as dirname3 } from "path";
|
|
@@ -770,21 +934,26 @@ async function updateSchemaYml(projectPath, schemaPath, entry) {
|
|
|
770
934
|
await writeFile(fullPath, stringifyYaml(existing, { indent: 2 }), "utf-8");
|
|
771
935
|
return fullPath;
|
|
772
936
|
}
|
|
937
|
+
|
|
773
938
|
export {
|
|
774
|
-
AdvisorAgent,
|
|
775
|
-
AnthropicProvider,
|
|
776
939
|
KNOWLEDGE_TOPICS,
|
|
777
|
-
|
|
778
|
-
TOOL_DEFINITIONS,
|
|
779
|
-
buildModelPath,
|
|
780
|
-
buildSchemaYmlEntry,
|
|
781
|
-
detectConventions,
|
|
782
|
-
formatModelSql,
|
|
940
|
+
loadKnowledge,
|
|
783
941
|
getKnowledgeOverview,
|
|
942
|
+
detectConventions,
|
|
784
943
|
listDbtModels,
|
|
785
|
-
loadKnowledge,
|
|
786
944
|
readDbtModel,
|
|
787
|
-
|
|
788
|
-
|
|
945
|
+
TOOL_DEFINITIONS,
|
|
946
|
+
SYSTEM_PROMPT,
|
|
947
|
+
AdvisorAgent,
|
|
948
|
+
AnthropicProvider,
|
|
949
|
+
OpenAICompatibleProvider,
|
|
950
|
+
buildProvider,
|
|
951
|
+
createProviderForTask,
|
|
952
|
+
createEmbedder,
|
|
953
|
+
buildModelPath,
|
|
954
|
+
formatModelSql,
|
|
955
|
+
buildSchemaYmlEntry,
|
|
956
|
+
writeDbtModel,
|
|
957
|
+
updateSchemaYml
|
|
789
958
|
};
|
|
790
|
-
//# sourceMappingURL=
|
|
959
|
+
//# sourceMappingURL=chunk-64CI3HSY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../packages/advisor/src/dbt/knowledge.ts","../../../packages/advisor/src/dbt/project.ts","../../../packages/advisor/src/tools.ts","../../../packages/advisor/src/agent.ts","../../../packages/advisor/src/providers/anthropic.ts","../../../packages/advisor/src/providers/openai-compatible.ts","../../../packages/advisor/src/providers/factory.ts","../../../packages/advisor/src/providers/embedder.ts","../../../packages/advisor/src/dbt/writer.ts"],"sourcesContent":["import { readFile } from 'fs/promises';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst KNOWLEDGE_DIR = join(__dirname, '..', 'knowledge');\n\nexport const KNOWLEDGE_TOPICS = [\n 'materializations',\n 'incremental',\n 'macros',\n 'testing',\n 'naming',\n 'performance',\n 'sources',\n] as const;\n\nexport type KnowledgeTopic = (typeof KNOWLEDGE_TOPICS)[number];\n\nexport async function loadKnowledge(topic: string): Promise<string> {\n if (!KNOWLEDGE_TOPICS.includes(topic as KnowledgeTopic)) {\n return `Unknown topic: \"${topic}\". Available topics: ${KNOWLEDGE_TOPICS.join(', ')}`;\n }\n\n const filePath = join(KNOWLEDGE_DIR, `${topic}.md`);\n return readFile(filePath, 'utf-8');\n}\n\nexport function getKnowledgeOverview(): string {\n return `You have access to a dbt knowledge base via the get_knowledge tool. Available topics:\n${KNOWLEDGE_TOPICS.map((t) => `- ${t}`).join('\\n')}\n\nUse get_knowledge when you need specifics on materializations, incremental strategies, Jinja macros, testing, naming conventions, or performance optimization.`;\n}\n","import { readFile } from 'fs/promises';\nimport { join, basename, relative, dirname } from 'path';\nimport fg from 'fast-glob';\nimport { parse as parseYaml } from 'yaml';\n\nexport interface DbtConventions {\n folderStructure: string[];\n namingPrefixes: Record<string, string>;\n commonMaterializations: Record<string, string>;\n schemaYmlPattern: 'per-folder' | 'per-model' | 'single-file';\n testPatterns: string[];\n}\n\nexport interface DbtModelInfo {\n name: string;\n path: string;\n layer: string;\n materialization: string;\n folder: string;\n}\n\ninterface DbtProjectYml {\n name: string;\n 'model-paths'?: string[];\n model_paths?: string[];\n}\n\nasync function getModelPaths(projectPath: string): Promise<string[]> {\n const content = await readFile(join(projectPath, 'dbt_project.yml'), 'utf-8');\n const parsed = parseYaml(content) as DbtProjectYml;\n return parsed['model-paths'] ?? parsed.model_paths ?? ['models'];\n}\n\nfunction extractMaterialization(sql: string): string {\n const match = sql.match(/materialized\\s*=\\s*['\"](\\w+)['\"]/);\n return match?.[1] ?? 'view';\n}\n\nfunction detectLayer(relativePath: string): string {\n const parts = relativePath.split('/');\n return parts[0] ?? 'unknown';\n}\n\nfunction detectPrefix(\n models: Array<{ name: string; layer: string }>\n): Record<string, string> {\n const prefixesByLayer = new Map<string, Map<string, number>>();\n\n for (const model of models) {\n const underscoreIdx = model.name.indexOf('_');\n if (underscoreIdx === -1) continue;\n const prefix = model.name.slice(0, underscoreIdx + 1);\n\n if (!prefixesByLayer.has(model.layer)) {\n prefixesByLayer.set(model.layer, new Map());\n }\n const counts = prefixesByLayer.get(model.layer)!;\n counts.set(prefix, (counts.get(prefix) ?? 0) + 1);\n }\n\n const result: Record<string, string> = {};\n for (const [layer, counts] of prefixesByLayer) {\n let maxCount = 0;\n let maxPrefix = '';\n for (const [prefix, count] of counts) {\n if (count > maxCount) {\n maxCount = count;\n maxPrefix = prefix;\n }\n }\n if (maxPrefix && maxCount >= 2) {\n result[layer] = maxPrefix;\n }\n }\n\n return result;\n}\n\nfunction detectMaterializations(\n models: Array<{ layer: string; materialization: string }>\n): Record<string, string> {\n const matByLayer = new Map<string, Map<string, number>>();\n\n for (const model of models) {\n if (!matByLayer.has(model.layer)) {\n matByLayer.set(model.layer, new Map());\n }\n const counts = matByLayer.get(model.layer)!;\n counts.set(model.materialization, (counts.get(model.materialization) ?? 0) + 1);\n }\n\n const result: Record<string, string> = {};\n for (const [layer, counts] of matByLayer) {\n let maxCount = 0;\n let maxMat = '';\n for (const [mat, count] of counts) {\n if (count > maxCount) {\n maxCount = count;\n maxMat = mat;\n }\n }\n if (maxMat) result[layer] = maxMat;\n }\n\n return result;\n}\n\nasync function detectSchemaYmlPattern(\n projectPath: string,\n modelPaths: string[]\n): Promise<'per-folder' | 'per-model' | 'single-file'> {\n const ymlFiles: string[] = [];\n for (const mp of modelPaths) {\n const pattern = join(projectPath, mp, '**/*.yml');\n const files = await fg(pattern, { ignore: ['**/node_modules/**'] });\n ymlFiles.push(...files);\n }\n\n if (ymlFiles.length === 0) return 'per-folder';\n if (ymlFiles.length === 1) return 'single-file';\n\n const dirs = new Set(ymlFiles.map((f) => dirname(f)));\n return dirs.size > 1 ? 'per-folder' : 'single-file';\n}\n\nexport async function detectConventions(projectPath: string): Promise<DbtConventions> {\n const modelPaths = await getModelPaths(projectPath);\n const models = await listDbtModels(projectPath);\n\n const folders = [...new Set(models.map((m) => m.layer))].filter((l) => l !== 'unknown');\n\n return {\n folderStructure: folders,\n namingPrefixes: detectPrefix(models),\n commonMaterializations: detectMaterializations(models),\n schemaYmlPattern: await detectSchemaYmlPattern(projectPath, modelPaths),\n testPatterns: [],\n };\n}\n\nexport async function listDbtModels(projectPath: string): Promise<DbtModelInfo[]> {\n const modelPaths = await getModelPaths(projectPath);\n const models: DbtModelInfo[] = [];\n\n for (const mp of modelPaths) {\n const pattern = join(projectPath, mp, '**/*.sql');\n const files = await fg(pattern, { ignore: ['**/node_modules/**'] });\n\n for (const file of files) {\n const relPath = relative(join(projectPath, mp), file);\n const name = basename(file, '.sql');\n const sql = await readFile(file, 'utf-8');\n const materialization = extractMaterialization(sql);\n const layer = detectLayer(relPath);\n const folder = dirname(relPath);\n\n models.push({ name, path: relPath, layer, materialization, folder });\n }\n }\n\n return models;\n}\n\nexport async function readDbtModel(\n projectPath: string,\n modelName: string\n): Promise<string | null> {\n const models = await listDbtModels(projectPath);\n const model = models.find((m) => m.name === modelName);\n if (!model) return null;\n\n const modelPaths = await getModelPaths(projectPath);\n for (const mp of modelPaths) {\n const fullPath = join(projectPath, mp, model.path);\n try {\n return await readFile(fullPath, 'utf-8');\n } catch {\n continue;\n }\n }\n return null;\n}\n","import type { ToolDefinition } from './providers/types.js';\nimport type { AdvisorContext } from './context.js';\nimport { loadKnowledge } from './dbt/knowledge.js';\nimport { readDbtModel } from './dbt/project.js';\nimport { SemanticModelBuilder, SemanticQueryCompiler } from '@yamchart/query';\nimport type { SemanticFilter } from '@yamchart/schema';\n\nexport type { AdvisorContext } from './context.js';\n\nexport const TOOL_DEFINITIONS: ToolDefinition[] = [\n // Read-only tools\n {\n name: 'list_yamchart_models',\n description: 'List all yamchart SQL models with names, descriptions, parameters, and return columns',\n parameters: { type: 'object', properties: {}, required: [] },\n },\n {\n name: 'list_charts',\n description: 'List all yamchart charts showing which models they reference and their chart type',\n parameters: { type: 'object', properties: {}, required: [] },\n },\n {\n name: 'get_catalog',\n description: 'Get the dbt catalog (.yamchart/catalog.md) with upstream table schemas and column metadata',\n parameters: { type: 'object', properties: {}, required: [] },\n },\n {\n name: 'get_warehouse_table',\n description: 'Get detailed column metadata and sample rows for a specific warehouse table from the cached catalog. Instant — reads from local catalog, no live query. Use the fully-qualified name (e.g. RAW.PAYMENTS).',\n parameters: {\n type: 'object',\n properties: {\n table: { type: 'string', description: 'Fully-qualified table name (e.g. RAW.PAYMENTS, STAGING.CUSTOMERS)' },\n },\n required: ['table'],\n },\n },\n {\n name: 'get_warehouse_tables',\n description: 'Get detailed metadata for multiple warehouse tables at once from the cached catalog.',\n parameters: {\n type: 'object',\n properties: {\n tables: { type: 'array', items: { type: 'string' }, description: 'List of fully-qualified table names' },\n },\n required: ['tables'],\n },\n },\n {\n name: 'introspect_warehouse',\n description: 'Query the live warehouse. Use for discovering raw tables not yet modeled in dbt.',\n parameters: {\n type: 'object',\n properties: {\n sql: { type: 'string', description: 'SQL query to execute (e.g. SHOW TABLES, SELECT * FROM information_schema.columns)' },\n },\n required: ['sql'],\n },\n },\n {\n name: 'sample_data',\n description: 'Preview rows from a table in the warehouse',\n parameters: {\n type: 'object',\n properties: {\n table: { type: 'string', description: 'Table name (can be schema-qualified)' },\n limit: { type: 'number', description: 'Number of rows to return (default: 5)' },\n },\n required: ['table'],\n },\n },\n {\n name: 'read_dbt_model',\n description: 'Read the full SQL source of an existing dbt model',\n parameters: {\n type: 'object',\n properties: {\n model_name: { type: 'string', description: 'Name of the dbt model to read' },\n },\n required: ['model_name'],\n },\n },\n {\n name: 'list_dbt_models',\n description: 'List all dbt models with their layer (staging/intermediate/marts), materialization, and folder',\n parameters: { type: 'object', properties: {}, required: [] },\n },\n {\n name: 'get_knowledge',\n description: 'Look up dbt reference documentation on a topic: materializations, incremental, macros, testing, naming, performance',\n parameters: {\n type: 'object',\n properties: {\n topic: { type: 'string', description: 'Topic name: materializations, incremental, macros, testing, naming, performance' },\n },\n required: ['topic'],\n },\n },\n {\n name: 'list_semantic_entities',\n description: 'List all semantic entities (auto-generated from the catalog) with their measures and dimensions. Use this to understand what data is available for structured queries without writing SQL.',\n parameters: { type: 'object', properties: {}, required: [] },\n },\n {\n name: 'semantic_query',\n description: 'Run a structured query against the semantic layer. Specify an entity, measures to aggregate, and optional dimensions to group by. Returns the compiled SQL.',\n parameters: {\n type: 'object',\n properties: {\n entity: { type: 'string', description: 'Entity name (e.g. fct_revenue)' },\n measures: { type: 'array', items: { type: 'string' }, description: 'Measure names to aggregate' },\n dimensions: { type: 'array', items: { type: 'string' }, description: 'Dimension names to group by (optional)' },\n filters: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n dimension: { type: 'string' },\n operator: { type: 'string', description: 'equals, not_equals, contains, gt, gte, lt, lte, in, not_in' },\n value: { description: 'Filter value (string, number, or array for in/not_in)' },\n },\n required: ['dimension', 'operator', 'value'],\n },\n description: 'Optional filters',\n },\n limit: { type: 'number', description: 'Row limit (default: 100)' },\n },\n required: ['entity', 'measures'],\n },\n },\n\n // Action tools\n {\n name: 'propose_model',\n description: 'Propose a new dbt model. Call this when you have a suggestion to present to the user.',\n parameters: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Model name (snake_case)' },\n description: { type: 'string', description: 'One-line description of what this model does' },\n sql: { type: 'string', description: 'Full SQL for the model (may include Jinja)' },\n layer: { type: 'string', description: 'dbt layer: staging, intermediate, or marts' },\n materialization: { type: 'string', description: 'Materialization: view, table, or incremental' },\n explanation: { type: 'string', description: 'Why this model is useful (2-3 sentences)' },\n subfolder: { type: 'string', description: 'Optional subfolder within the layer (e.g. \"stripe\", \"core\")' },\n columns: {\n type: 'array',\n description: 'Column definitions for schema.yml',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n description: { type: 'string' },\n tests: { type: 'array', items: { type: 'string' } },\n },\n required: ['name'],\n },\n },\n },\n required: ['name', 'description', 'sql', 'layer', 'materialization', 'explanation'],\n },\n },\n {\n name: 'write_dbt_model',\n description: 'Write a proposed dbt model SQL file to the dbt project. Only call after proposing and user confirmation.',\n parameters: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Model name (must match a previous proposal)' },\n },\n required: ['name'],\n },\n },\n {\n name: 'update_schema_yml',\n description: 'Add or update the model entry in the appropriate schema.yml file. Only call after writing the model.',\n parameters: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Model name (must match a written model)' },\n },\n required: ['name'],\n },\n },\n];\n\nexport async function executeToolCall(\n context: AdvisorContext,\n toolName: string,\n input: Record<string, unknown>\n): Promise<string> {\n switch (toolName) {\n case 'list_yamchart_models':\n return JSON.stringify(\n context.yamchart.models.map((m) => ({\n name: m.name,\n description: m.description,\n params: m.params,\n returns: m.returns,\n }))\n );\n\n case 'list_charts':\n return JSON.stringify(\n context.yamchart.charts.map((c) => ({\n name: c.name,\n title: c.title,\n model: c.model,\n type: c.type,\n }))\n );\n\n case 'get_catalog':\n return context.yamchart.catalog ?? 'No dbt catalog found. Run `yamchart sync-dbt` to create one.';\n\n case 'get_warehouse_table': {\n if (!context.yamchart.catalogJson) {\n return 'Warehouse catalog not available. Run `yamchart sync-warehouse` to populate it.';\n }\n const tableName = (input.table as string).toUpperCase();\n const match = context.yamchart.catalogJson.models.find(\n (m) => (m.table || '').toUpperCase() === tableName || m.name.toUpperCase() === tableName\n );\n if (!match) {\n return JSON.stringify({ error: `Table not found in catalog: ${input.table}. Use get_catalog to see available tables.` });\n }\n return JSON.stringify({\n name: match.name,\n table: match.table,\n tableType: match.tableType,\n source: match.source,\n columns: match.columns,\n sampleRows: match.sampleRows || [],\n });\n }\n\n case 'get_warehouse_tables': {\n if (!context.yamchart.catalogJson) {\n return 'Warehouse catalog not available. Run `yamchart sync-warehouse` to populate it.';\n }\n const tableNames = (input.tables as string[]).map((t) => t.toUpperCase());\n const results = tableNames.map((name) => {\n const match = context.yamchart.catalogJson!.models.find(\n (m) => (m.table || '').toUpperCase() === name || m.name.toUpperCase() === name\n );\n if (!match) {\n return { error: `Not found: ${name}` };\n }\n return {\n name: match.name,\n table: match.table,\n tableType: match.tableType,\n source: match.source,\n columns: match.columns,\n sampleRows: match.sampleRows || [],\n };\n });\n return JSON.stringify(results);\n }\n\n case 'introspect_warehouse': {\n if (!context.warehouse) {\n return 'Warehouse introspection not available. No database connection configured.';\n }\n const sql = input.sql as string;\n try {\n const result = await context.warehouse.executeSql(sql);\n return JSON.stringify(result);\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n }\n\n case 'sample_data': {\n if (!context.warehouse) {\n return 'Warehouse not available. No database connection configured.';\n }\n const table = input.table as string;\n const limit = (input.limit as number) ?? 5;\n try {\n const result = await context.warehouse.executeSql(\n `SELECT * FROM ${table} LIMIT ${limit}`\n );\n return JSON.stringify(result);\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n }\n\n case 'read_dbt_model': {\n const modelName = input.model_name as string;\n const sql = await readDbtModel(context.dbt.projectPath, modelName);\n if (!sql) {\n return JSON.stringify({ error: `Model not found: ${modelName}` });\n }\n return JSON.stringify({ name: modelName, sql });\n }\n\n case 'list_dbt_models':\n return JSON.stringify(\n context.dbt.models.map((m) => ({\n name: m.name,\n path: m.path,\n layer: m.layer,\n materialization: m.materialization,\n folder: m.folder,\n }))\n );\n\n case 'get_knowledge': {\n const topic = input.topic as string;\n return loadKnowledge(topic);\n }\n\n case 'list_semantic_entities': {\n if (!context.yamchart.catalogJson) {\n return 'No catalog available. Run `yamchart sync-warehouse` or `yamchart sync-dbt` to populate it.';\n }\n const builder = new SemanticModelBuilder();\n const model = builder.build({ catalog: { models: context.yamchart.catalogJson.models } });\n return JSON.stringify(\n model.entities.map((e) => ({\n name: e.name,\n source_table: e.source_table,\n description: e.description,\n measures: e.measures.map((m) => ({ name: m.name, type: m.type })),\n dimensions: e.dimensions.map((d) => ({ name: d.name, type: d.type })),\n }))\n );\n }\n\n case 'semantic_query': {\n if (!context.yamchart.catalogJson) {\n return JSON.stringify({ error: 'No catalog available. Run `yamchart sync-warehouse` or `yamchart sync-dbt` to populate it.' });\n }\n try {\n const builder = new SemanticModelBuilder();\n const model = builder.build({ catalog: { models: context.yamchart.catalogJson.models } });\n const compiler = new SemanticQueryCompiler();\n const sql = compiler.compile(model, {\n model: input.entity as string,\n measures: (input.measures as string[]) || [],\n dimensions: (input.dimensions as string[]) || [],\n filters: (input.filters as SemanticFilter[]) || [],\n limit: (input.limit as number) || 100,\n });\n return JSON.stringify({ sql, entity: input.entity });\n } catch (err) {\n return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });\n }\n }\n\n case 'propose_model':\n return JSON.stringify({\n status: 'proposed',\n name: input.name,\n description: input.description,\n sql: input.sql,\n layer: input.layer,\n materialization: input.materialization,\n explanation: input.explanation,\n subfolder: input.subfolder,\n columns: input.columns,\n });\n\n case 'write_dbt_model':\n // Actual writing happens in the CLI command, not here.\n // The agent tool just signals intent — the CLI confirms with the user.\n return JSON.stringify({\n status: 'pending_confirmation',\n name: input.name,\n message: 'Model write requested. Waiting for user confirmation.',\n });\n\n case 'update_schema_yml':\n return JSON.stringify({\n status: 'pending_confirmation',\n name: input.name,\n message: 'Schema.yml update requested. Waiting for user confirmation.',\n });\n\n default:\n return JSON.stringify({ error: `Unknown tool: ${toolName}` });\n }\n}\n","import type {\n LLMProvider,\n Message,\n ContentBlock,\n TextBlock,\n ToolUseBlock,\n ToolResultBlock,\n} from './providers/types.js';\nimport type { AdvisorContext } from './context.js';\nimport { TOOL_DEFINITIONS, executeToolCall } from './tools.js';\nimport { getKnowledgeOverview } from './dbt/knowledge.js';\n\nexport interface Proposal {\n name: string;\n description: string;\n sql: string;\n layer: string;\n materialization: string;\n explanation: string;\n subfolder?: string;\n columns?: Array<{ name: string; description?: string; tests?: string[] }>;\n}\n\nexport interface AgentResult {\n response: string;\n proposals: Proposal[];\n messages: Message[];\n}\n\nexport const SYSTEM_PROMPT = `You are a dbt advisor for yamchart projects. You analyze the BI layer (yamchart models, charts, dashboards) and the data engineering layer (dbt models, warehouse tables) to suggest improvements to dbt models.\n\nThink like a senior data engineer. Your goals:\n- Understand what the BI layer needs (charts, filters, drill-downs, date ranges)\n- Identify gaps in the dbt project (missing models, incomplete staging, opportunities for pre-aggregation)\n- Suggest new dbt models that serve the BI layer better\n- Follow the project's existing conventions (folder structure, naming, materializations)\n\nWhen proposing models:\n- Match the project's naming conventions (detect and follow existing prefixes like stg_, fct_, dim_)\n- Place models in the correct layer and folder\n- Choose appropriate materializations\n- Include column descriptions and tests in proposals\n- Explain WHY the model helps, not just WHAT it does\n- Use ref() and source() macros correctly\n\nWhen working with cross-database tables:\n- If a table lives outside the primary analytics database, recommend creating a dbt source definition in sources.yml\n- Follow the pattern: source → staging model → downstream refs\n- Use get_knowledge('sources') for detailed source patterns\n- Check the warehouse catalog (get_warehouse_tables) to identify tables in other databases\n\nWhen in audit mode:\n- Evaluate: coverage gaps, convention violations, materialization mismatches, missing tests\n- Rank suggestions by impact\n- Be concise — focus on actionable improvements\n\n${getKnowledgeOverview()}\n\nWhen you have a suggestion, call propose_model with the full SQL and metadata. Do NOT call write_dbt_model or update_schema_yml directly — the user will be prompted to confirm before writing.`;\n\nconst MAX_TOOL_ROUNDS = 15;\n\nexport class AdvisorAgent {\n private provider: LLMProvider;\n\n constructor(provider: LLMProvider) {\n this.provider = provider;\n }\n\n async run(\n context: AdvisorContext,\n userMessages: Message[]\n ): Promise<AgentResult> {\n const proposals: Proposal[] = [];\n const messages: Message[] = [...userMessages];\n\n // Build context-specific system prompt\n const systemPrompt = this.buildSystemPrompt(context);\n\n for (let round = 0; round < MAX_TOOL_ROUNDS; round++) {\n const response = await this.provider.chat({\n system: systemPrompt,\n messages,\n tools: TOOL_DEFINITIONS,\n });\n\n const textBlocks = response.content.filter(\n (b): b is TextBlock => b.type === 'text'\n );\n const toolUseBlocks = response.content.filter(\n (b): b is ToolUseBlock => b.type === 'tool_use'\n );\n\n // No tool calls — return final text response\n if (toolUseBlocks.length === 0) {\n const responseText = textBlocks.map((b) => b.text).join('\\n');\n return { response: responseText, proposals, messages };\n }\n\n // Add assistant message with tool calls\n messages.push({ role: 'assistant', content: response.content });\n\n // Execute each tool call\n const toolResults: ContentBlock[] = [];\n for (const toolUse of toolUseBlocks) {\n const result = await executeToolCall(context, toolUse.name, toolUse.input);\n\n // Collect proposals\n if (toolUse.name === 'propose_model') {\n const parsed = JSON.parse(result) as Record<string, unknown>;\n proposals.push({\n name: parsed.name as string,\n description: parsed.description as string,\n sql: toolUse.input.sql as string,\n layer: toolUse.input.layer as string,\n materialization: toolUse.input.materialization as string,\n explanation: toolUse.input.explanation as string,\n subfolder: toolUse.input.subfolder as string | undefined,\n columns: toolUse.input.columns as Proposal['columns'],\n });\n }\n\n toolResults.push({\n type: 'tool_result',\n tool_use_id: toolUse.id,\n content: result,\n } as ToolResultBlock);\n }\n\n // Add tool results as user message\n messages.push({ role: 'user', content: toolResults });\n }\n\n // Hit max rounds — return what we have\n return {\n response: 'Reached maximum tool call rounds. Here are the suggestions gathered so far.',\n proposals,\n messages,\n };\n }\n\n private buildSystemPrompt(context: AdvisorContext): string {\n const parts = [SYSTEM_PROMPT];\n\n // Add project summary\n parts.push(`\\n## Current Project Summary`);\n parts.push(`- Yamchart: ${context.yamchart.models.length} SQL models, ${context.yamchart.charts.length} charts, ${context.yamchart.dashboards.length} dashboards`);\n parts.push(`- dbt project: \"${context.dbt.projectName}\" at ${context.dbt.projectPath}`);\n parts.push(`- dbt models: ${context.dbt.models.length} (layers: ${context.dbt.conventions.folderStructure.join(', ') || 'none detected'})`);\n\n if (Object.keys(context.dbt.conventions.namingPrefixes).length > 0) {\n const prefixes = Object.entries(context.dbt.conventions.namingPrefixes)\n .map(([layer, prefix]) => `${layer}: ${prefix}`)\n .join(', ');\n parts.push(`- Naming prefixes: ${prefixes}`);\n }\n\n if (Object.keys(context.dbt.conventions.commonMaterializations).length > 0) {\n const mats = Object.entries(context.dbt.conventions.commonMaterializations)\n .map(([layer, mat]) => `${layer}: ${mat}`)\n .join(', ');\n parts.push(`- Materializations: ${mats}`);\n }\n\n parts.push(`- Schema.yml pattern: ${context.dbt.conventions.schemaYmlPattern}`);\n parts.push(`- Catalog: ${context.yamchart.catalog ? 'available' : 'not synced'}`);\n parts.push(`- Warehouse: ${context.warehouse ? `connected (${context.warehouse.connectionType})` : 'not connected'}`);\n\n return parts.join('\\n');\n }\n}\n","import Anthropic from '@anthropic-ai/sdk';\nimport type {\n LLMProvider,\n LLMResponse,\n Message,\n ToolDefinition,\n ContentBlock,\n TextBlock,\n ToolUseBlock,\n} from './types.js';\n\nexport class AnthropicProvider implements LLMProvider {\n private client: Anthropic;\n private model: string;\n\n constructor(apiKey: string, model: string = 'claude-sonnet-4-5-20250929') {\n this.client = new Anthropic({ apiKey });\n this.model = model;\n }\n\n async chat(options: {\n system: string;\n messages: Message[];\n tools: ToolDefinition[];\n maxTokens?: number;\n }): Promise<LLMResponse> {\n const tools: Anthropic.Tool[] = options.tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: {\n type: 'object' as const,\n properties: t.parameters.properties,\n required: t.parameters.required ?? [],\n },\n }));\n\n const messages: Anthropic.MessageParam[] = options.messages.map((m) => {\n if (typeof m.content === 'string') {\n return { role: m.role, content: m.content };\n }\n const blocks: Anthropic.ContentBlockParam[] = m.content.map((block) => {\n if (block.type === 'text') {\n return { type: 'text' as const, text: (block as TextBlock).text };\n }\n if (block.type === 'tool_use') {\n const tu = block as ToolUseBlock;\n return { type: 'tool_use' as const, id: tu.id, name: tu.name, input: tu.input };\n }\n if (block.type === 'tool_result') {\n const tr = block as { type: 'tool_result'; tool_use_id: string; content: string };\n return { type: 'tool_result' as const, tool_use_id: tr.tool_use_id, content: tr.content };\n }\n throw new Error(`Unknown block type: ${block.type}`);\n });\n return { role: m.role, content: blocks };\n });\n\n const response = await this.client.messages.create({\n model: this.model,\n max_tokens: options.maxTokens ?? 4096,\n system: options.system,\n tools,\n messages,\n });\n\n const content: ContentBlock[] = response.content.map((block) => {\n if (block.type === 'text') {\n return { type: 'text', text: block.text } as TextBlock;\n }\n if (block.type === 'tool_use') {\n return {\n type: 'tool_use',\n id: block.id,\n name: block.name,\n input: block.input as Record<string, unknown>,\n } as ToolUseBlock;\n }\n throw new Error(`Unexpected block type: ${block.type}`);\n });\n\n return {\n content,\n stopReason: response.stop_reason === 'tool_use' ? 'tool_use' : 'end',\n };\n }\n}\n","// packages/advisor/src/providers/openai-compatible.ts\nimport OpenAI from 'openai';\nimport type {\n LLMProvider,\n LLMResponse,\n Message,\n ToolDefinition,\n ContentBlock,\n TextBlock,\n ToolUseBlock,\n} from './types.js';\n\nexport interface OpenAICompatibleOptions {\n baseURL: string;\n apiKey?: string;\n model: string;\n}\n\nexport class OpenAICompatibleProvider implements LLMProvider {\n private client: OpenAI;\n private model: string;\n\n constructor(opts: OpenAICompatibleOptions) {\n this.client = new OpenAI({ baseURL: opts.baseURL, apiKey: opts.apiKey ?? 'not-needed' });\n this.model = opts.model;\n }\n\n async chat(options: {\n system: string;\n messages: Message[];\n tools: ToolDefinition[];\n maxTokens?: number;\n }): Promise<LLMResponse> {\n const tools = options.tools.map((t) => ({\n type: 'function' as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: {\n type: 'object',\n properties: t.parameters.properties,\n required: t.parameters.required ?? [],\n },\n },\n }));\n\n const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [\n { role: 'system', content: options.system },\n ];\n\n for (const m of options.messages) {\n if (typeof m.content === 'string') {\n messages.push({ role: m.role, content: m.content });\n continue;\n }\n // Anthropic-style content blocks → OpenAI shape.\n const text = m.content\n .filter((b): b is TextBlock => b.type === 'text')\n .map((b) => b.text)\n .join('\\n');\n const toolUses = m.content.filter((b): b is ToolUseBlock => b.type === 'tool_use');\n const toolResults = m.content.filter(\n (b): b is { type: 'tool_result'; tool_use_id: string; content: string } =>\n b.type === 'tool_result',\n );\n\n if (m.role === 'assistant' && toolUses.length) {\n messages.push({\n role: 'assistant',\n content: text || null,\n tool_calls: toolUses.map((tu) => ({\n id: tu.id,\n type: 'function',\n function: { name: tu.name, arguments: JSON.stringify(tu.input) },\n })),\n });\n } else if (toolResults.length) {\n // tool results become separate `tool` messages\n for (const tr of toolResults) {\n messages.push({ role: 'tool', tool_call_id: tr.tool_use_id, content: tr.content });\n }\n if (text) messages.push({ role: m.role, content: text });\n } else {\n messages.push({ role: m.role, content: text });\n }\n }\n\n const response = await this.client.chat.completions.create({\n model: this.model,\n max_tokens: options.maxTokens ?? 4096,\n messages,\n ...(tools.length ? { tools } : {}),\n });\n\n const choice = response.choices[0];\n const msg = choice?.message;\n const content: ContentBlock[] = [];\n\n if (msg?.content) {\n content.push({ type: 'text', text: msg.content } as TextBlock);\n }\n\n for (const tc of msg?.tool_calls ?? []) {\n let input: Record<string, unknown> = {};\n try {\n input = JSON.parse(tc.function.arguments || '{}');\n } catch {\n input = {};\n }\n content.push({ type: 'tool_use', id: tc.id, name: tc.function.name, input } as ToolUseBlock);\n }\n\n return {\n content,\n stopReason: choice?.finish_reason === 'tool_calls' ? 'tool_use' : 'end',\n };\n }\n}\n","// packages/advisor/src/providers/factory.ts\nimport type { LLMProvider } from './types.js';\nimport { AnthropicProvider } from './anthropic.js';\nimport { OpenAICompatibleProvider } from './openai-compatible.js';\n\nexport type ProviderKind = 'anthropic' | 'openai' | 'gemini' | 'ollama' | 'ollama_cloud' | 'openai_compatible';\nexport interface ProviderConfig { provider: ProviderKind; model?: string; base_url?: string; api_key_var?: string; }\nexport interface AiConfig { default?: string; providers?: Record<string, ProviderConfig>; tasks?: Record<string, string>; }\nexport type AiTask = 'hunch_generation' | 'advisor' | 'blindspot_scan' | 'answer';\n\nfunction requireKey(env: NodeJS.ProcessEnv, name: string): string {\n const v = env[name];\n if (!v) throw new Error(`Missing ${name} for the configured LLM provider.`);\n return v;\n}\nfunction requireModel(cfg: ProviderConfig): string {\n if (!cfg.model) throw new Error(`The \"${cfg.provider}\" provider requires a model.`);\n return cfg.model;\n}\n\nexport function buildProvider(cfg: ProviderConfig, env: NodeJS.ProcessEnv): LLMProvider {\n switch (cfg.provider) {\n case 'anthropic':\n return new AnthropicProvider(requireKey(env, cfg.api_key_var ?? 'ANTHROPIC_API_KEY'), cfg.model);\n case 'openai':\n return new OpenAICompatibleProvider({ baseURL: cfg.base_url ?? 'https://api.openai.com/v1', apiKey: requireKey(env, cfg.api_key_var ?? 'OPENAI_API_KEY'), model: requireModel(cfg) });\n case 'gemini':\n return new OpenAICompatibleProvider({ baseURL: cfg.base_url ?? 'https://generativelanguage.googleapis.com/v1beta/openai/', apiKey: requireKey(env, cfg.api_key_var ?? (env.GEMINI_API_KEY ? 'GEMINI_API_KEY' : 'GOOGLE_API_KEY')), model: requireModel(cfg) });\n case 'ollama':\n return new OpenAICompatibleProvider({ baseURL: cfg.base_url ?? 'http://localhost:11434/v1', apiKey: 'ollama', model: requireModel(cfg) });\n case 'ollama_cloud':\n return new OpenAICompatibleProvider({ baseURL: cfg.base_url ?? 'https://ollama.com/v1', apiKey: requireKey(env, cfg.api_key_var ?? 'OLLAMA_API_KEY'), model: requireModel(cfg) });\n case 'openai_compatible':\n if (!cfg.base_url) throw new Error('openai_compatible requires base_url.');\n return new OpenAICompatibleProvider({ baseURL: cfg.base_url, apiKey: cfg.api_key_var ? requireKey(env, cfg.api_key_var) : 'not-needed', model: requireModel(cfg) });\n }\n}\n\nexport function createProviderForTask(config: AiConfig | undefined, task: AiTask, env: NodeJS.ProcessEnv): LLMProvider {\n if (!config) return new AnthropicProvider(requireKey(env, 'ANTHROPIC_API_KEY'));\n const name = config.tasks?.[task] ?? config.default;\n const cfg = name ? config.providers?.[name] : undefined;\n if (!cfg) return new AnthropicProvider(requireKey(env, 'ANTHROPIC_API_KEY'));\n return buildProvider(cfg, env);\n}\n","import OpenAI from 'openai';\nimport type { ProviderConfig } from './factory.js';\n\nexport interface Embedder { model: string; baseURL: string; embed(texts: string[]): Promise<number[][]>; }\n\nconst PRESET_BASE: Record<string, string> = {\n ollama: 'http://localhost:11434/v1',\n ollama_cloud: 'https://ollama.com/v1',\n openai: 'https://api.openai.com/v1',\n gemini: 'https://generativelanguage.googleapis.com/v1beta/openai/',\n};\n\n// Resolve the API key per provider, mirroring buildProvider's preset logic so\n// e.g. Gemini reads GEMINI_API_KEY (not OPENAI_API_KEY). Ollama (local) needs no key.\nfunction resolveKey(c: ProviderConfig, env: NodeJS.ProcessEnv): string {\n if (c.api_key_var) return env[c.api_key_var] ?? 'not-needed';\n switch (c.provider) {\n case 'ollama': return 'ollama';\n case 'gemini': return env.GEMINI_API_KEY ?? env.GOOGLE_API_KEY ?? 'not-needed';\n case 'ollama_cloud': return env.OLLAMA_API_KEY ?? 'not-needed';\n case 'openai': return env.OPENAI_API_KEY ?? 'not-needed';\n default: return env.OPENAI_API_KEY ?? 'not-needed';\n }\n}\n\nexport function createEmbedder(cfg: ProviderConfig | undefined, env: NodeJS.ProcessEnv): Embedder | undefined {\n const c = cfg ?? { provider: 'ollama' as const, model: 'nomic-embed-text' };\n const model = c.model ?? 'nomic-embed-text';\n const baseURL = c.base_url ?? PRESET_BASE[c.provider] ?? 'http://localhost:11434/v1';\n const apiKey = resolveKey(c, env);\n const client = new OpenAI({ baseURL, apiKey });\n return {\n model, baseURL, client, // `client` is internal; cast in tests\n async embed(texts: string[]): Promise<number[][]> {\n if (texts.length === 0) return [];\n const res = await (this as unknown as { client: OpenAI }).client.embeddings.create({ model, input: texts });\n return res.data.map((d) => d.embedding as number[]);\n },\n } as Embedder & { client: OpenAI };\n}\n","import { readFile, writeFile, mkdir, access } from 'fs/promises';\nimport { join, dirname } from 'path';\nimport { parse as parseYaml, stringify as stringifyYaml } from 'yaml';\nimport type { DbtConventions } from './project.js';\n\nexport function buildModelPath(\n modelName: string,\n layer: string | undefined,\n conventions: DbtConventions,\n subfolder?: string\n): string {\n const effectiveLayer = layer ?? (conventions.folderStructure.includes('marts') ? 'marts' : conventions.folderStructure[0] ?? 'models');\n const parts = ['models', effectiveLayer];\n if (subfolder) parts.push(subfolder);\n parts.push(`${modelName}.sql`);\n return parts.join('/');\n}\n\nexport function formatModelSql(options: {\n materialization: string;\n tags?: string[];\n sql: string;\n description?: string;\n}): string {\n const lines: string[] = [];\n\n // Only add config block for non-default materializations\n if (options.materialization !== 'view') {\n const configParts: string[] = [`materialized='${options.materialization}'`];\n if (options.tags && options.tags.length > 0) {\n configParts.push(`tags=[${options.tags.map((t) => `'${t}'`).join(', ')}]`);\n }\n lines.push(`{{\\n config(\\n ${configParts.join(',\\n ')}\\n )\\n}}\\n`);\n }\n\n lines.push(options.sql);\n return lines.join('\\n');\n}\n\nexport interface SchemaColumn {\n name: string;\n description?: string;\n tests?: string[];\n}\n\nexport function buildSchemaYmlEntry(options: {\n name: string;\n description: string;\n columns?: SchemaColumn[];\n}): string {\n const model: Record<string, unknown> = {\n name: options.name,\n description: options.description,\n };\n\n if (options.columns && options.columns.length > 0) {\n model.columns = options.columns.map((col) => {\n const entry: Record<string, unknown> = { name: col.name };\n if (col.description) entry.description = col.description;\n if (col.tests && col.tests.length > 0) entry.tests = col.tests;\n return entry;\n });\n }\n\n return stringifyYaml({ models: [model] }, { indent: 2 });\n}\n\nexport async function writeDbtModel(\n projectPath: string,\n modelPath: string,\n sql: string\n): Promise<string> {\n const fullPath = join(projectPath, modelPath);\n await mkdir(dirname(fullPath), { recursive: true });\n await writeFile(fullPath, sql + '\\n', 'utf-8');\n return fullPath;\n}\n\nexport async function updateSchemaYml(\n projectPath: string,\n schemaPath: string,\n entry: { name: string; description: string; columns?: SchemaColumn[] }\n): Promise<string> {\n const fullPath = join(projectPath, schemaPath);\n\n let existing: { version?: number; models?: Array<Record<string, unknown>> } = {\n version: 2,\n models: [],\n };\n\n try {\n await access(fullPath);\n const content = await readFile(fullPath, 'utf-8');\n existing = parseYaml(content) as typeof existing;\n if (!existing.models) existing.models = [];\n } catch {\n // File doesn't exist, start fresh\n await mkdir(dirname(fullPath), { recursive: true });\n }\n\n // Check if model already exists\n const idx = existing.models!.findIndex(\n (m) => m.name === entry.name\n );\n\n const modelEntry: Record<string, unknown> = {\n name: entry.name,\n description: entry.description,\n };\n if (entry.columns && entry.columns.length > 0) {\n modelEntry.columns = entry.columns.map((col) => {\n const c: Record<string, unknown> = { name: col.name };\n if (col.description) c.description = col.description;\n if (col.tests && col.tests.length > 0) c.tests = col.tests;\n return c;\n });\n }\n\n if (idx >= 0) {\n existing.models![idx] = modelEntry;\n } else {\n existing.models!.push(modelEntry);\n }\n\n await writeFile(fullPath, stringifyYaml(existing, { indent: 2 }), 'utf-8');\n return fullPath;\n}\n"],"mappings":"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","names":["readFile","join","dirname","OpenAI","readFile","join","dirname","parseYaml"]}
|
package/dist/chunk-7D4SUZUM.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createRequire as __yamchartCreateRequire } from 'module'; if (!globalThis.require) globalThis.require = __yamchartCreateRequire(import.meta.url);
|
|
1
2
|
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
package/dist/chunk-DZVT6PHW.js
CHANGED
package/dist/chunk-EAQXUGP6.js
CHANGED
package/dist/chunk-HJVVHYVN.js
CHANGED