@duckcodeailabs/dql-agent 1.6.20 → 1.6.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/dist/agent-run-engine.d.ts +287 -0
  2. package/dist/agent-run-engine.d.ts.map +1 -0
  3. package/dist/agent-run-engine.js +916 -0
  4. package/dist/agent-run-engine.js.map +1 -0
  5. package/dist/agent-run-gates.d.ts +26 -0
  6. package/dist/agent-run-gates.d.ts.map +1 -0
  7. package/dist/agent-run-gates.js +170 -0
  8. package/dist/agent-run-gates.js.map +1 -0
  9. package/dist/agent-run-planner.d.ts +32 -0
  10. package/dist/agent-run-planner.d.ts.map +1 -0
  11. package/dist/agent-run-planner.js +280 -0
  12. package/dist/agent-run-planner.js.map +1 -0
  13. package/dist/answer-loop.d.ts +49 -0
  14. package/dist/answer-loop.d.ts.map +1 -1
  15. package/dist/answer-loop.js +292 -17
  16. package/dist/answer-loop.js.map +1 -1
  17. package/dist/app-builder.d.ts +44 -2
  18. package/dist/app-builder.d.ts.map +1 -1
  19. package/dist/app-builder.js +558 -123
  20. package/dist/app-builder.js.map +1 -1
  21. package/dist/app-planner.d.ts +78 -0
  22. package/dist/app-planner.d.ts.map +1 -0
  23. package/dist/app-planner.js +145 -0
  24. package/dist/app-planner.js.map +1 -0
  25. package/dist/embeddings/provider.d.ts +66 -0
  26. package/dist/embeddings/provider.d.ts.map +1 -0
  27. package/dist/embeddings/provider.js +105 -0
  28. package/dist/embeddings/provider.js.map +1 -0
  29. package/dist/hints/git-store.d.ts +69 -0
  30. package/dist/hints/git-store.d.ts.map +1 -0
  31. package/dist/hints/git-store.js +244 -0
  32. package/dist/hints/git-store.js.map +1 -0
  33. package/dist/hints/retrieval.d.ts +49 -0
  34. package/dist/hints/retrieval.d.ts.map +1 -0
  35. package/dist/hints/retrieval.js +60 -0
  36. package/dist/hints/retrieval.js.map +1 -0
  37. package/dist/hints/store.d.ts +39 -0
  38. package/dist/hints/store.d.ts.map +1 -0
  39. package/dist/hints/store.js +279 -0
  40. package/dist/hints/store.js.map +1 -0
  41. package/dist/hints/types.d.ts +147 -0
  42. package/dist/hints/types.d.ts.map +1 -0
  43. package/dist/hints/types.js +92 -0
  44. package/dist/hints/types.js.map +1 -0
  45. package/dist/index.d.ts +43 -6
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +35 -3
  48. package/dist/index.js.map +1 -1
  49. package/dist/intent-controller.d.ts +63 -0
  50. package/dist/intent-controller.d.ts.map +1 -0
  51. package/dist/intent-controller.js +150 -0
  52. package/dist/intent-controller.js.map +1 -0
  53. package/dist/kg/build.d.ts.map +1 -1
  54. package/dist/kg/build.js +2 -0
  55. package/dist/kg/build.js.map +1 -1
  56. package/dist/kg/sqlite-fts.js +4 -0
  57. package/dist/kg/sqlite-fts.js.map +1 -1
  58. package/dist/kg/types.d.ts +10 -0
  59. package/dist/kg/types.d.ts.map +1 -1
  60. package/dist/metadata/catalog.d.ts +81 -4
  61. package/dist/metadata/catalog.d.ts.map +1 -1
  62. package/dist/metadata/catalog.js +208 -1
  63. package/dist/metadata/catalog.js.map +1 -1
  64. package/dist/metadata/drafts.d.ts +22 -0
  65. package/dist/metadata/drafts.d.ts.map +1 -1
  66. package/dist/metadata/drafts.js +126 -2
  67. package/dist/metadata/drafts.js.map +1 -1
  68. package/dist/metadata/grain-gate.d.ts +61 -0
  69. package/dist/metadata/grain-gate.d.ts.map +1 -0
  70. package/dist/metadata/grain-gate.js +265 -0
  71. package/dist/metadata/grain-gate.js.map +1 -0
  72. package/dist/metadata/identity.d.ts +47 -0
  73. package/dist/metadata/identity.d.ts.map +1 -0
  74. package/dist/metadata/identity.js +147 -0
  75. package/dist/metadata/identity.js.map +1 -0
  76. package/dist/metadata/metric-match.d.ts +93 -0
  77. package/dist/metadata/metric-match.d.ts.map +1 -0
  78. package/dist/metadata/metric-match.js +233 -0
  79. package/dist/metadata/metric-match.js.map +1 -0
  80. package/dist/metadata/sql-grounding.d.ts +149 -0
  81. package/dist/metadata/sql-grounding.d.ts.map +1 -0
  82. package/dist/metadata/sql-grounding.js +397 -0
  83. package/dist/metadata/sql-grounding.js.map +1 -0
  84. package/dist/metadata/sql-retrieval.d.ts +29 -0
  85. package/dist/metadata/sql-retrieval.d.ts.map +1 -0
  86. package/dist/metadata/sql-retrieval.js +79 -0
  87. package/dist/metadata/sql-retrieval.js.map +1 -0
  88. package/dist/narrate.d.ts +52 -0
  89. package/dist/narrate.d.ts.map +1 -0
  90. package/dist/narrate.js +263 -0
  91. package/dist/narrate.js.map +1 -0
  92. package/dist/propose/build-from-prompt.d.ts +160 -0
  93. package/dist/propose/build-from-prompt.d.ts.map +1 -0
  94. package/dist/propose/build-from-prompt.js +815 -0
  95. package/dist/propose/build-from-prompt.js.map +1 -0
  96. package/dist/propose/classify.d.ts +55 -0
  97. package/dist/propose/classify.d.ts.map +1 -0
  98. package/dist/propose/classify.js +167 -0
  99. package/dist/propose/classify.js.map +1 -0
  100. package/dist/propose/config.d.ts +39 -0
  101. package/dist/propose/config.d.ts.map +1 -0
  102. package/dist/propose/config.js +52 -0
  103. package/dist/propose/config.js.map +1 -0
  104. package/dist/propose/dbt-artifacts.d.ts +134 -0
  105. package/dist/propose/dbt-artifacts.d.ts.map +1 -0
  106. package/dist/propose/dbt-artifacts.js +320 -0
  107. package/dist/propose/dbt-artifacts.js.map +1 -0
  108. package/dist/propose/edit-block.d.ts +74 -0
  109. package/dist/propose/edit-block.d.ts.map +1 -0
  110. package/dist/propose/edit-block.js +133 -0
  111. package/dist/propose/edit-block.js.map +1 -0
  112. package/dist/propose/enrich.d.ts +48 -0
  113. package/dist/propose/enrich.d.ts.map +1 -0
  114. package/dist/propose/enrich.js +125 -0
  115. package/dist/propose/enrich.js.map +1 -0
  116. package/dist/propose/generate-sql.d.ts +61 -0
  117. package/dist/propose/generate-sql.d.ts.map +1 -0
  118. package/dist/propose/generate-sql.js +180 -0
  119. package/dist/propose/generate-sql.js.map +1 -0
  120. package/dist/propose/index.d.ts +24 -0
  121. package/dist/propose/index.d.ts.map +1 -0
  122. package/dist/propose/index.js +15 -0
  123. package/dist/propose/index.js.map +1 -0
  124. package/dist/propose/propose.d.ts +226 -0
  125. package/dist/propose/propose.d.ts.map +1 -0
  126. package/dist/propose/propose.js +668 -0
  127. package/dist/propose/propose.js.map +1 -0
  128. package/dist/propose/reflect-block.d.ts +99 -0
  129. package/dist/propose/reflect-block.d.ts.map +1 -0
  130. package/dist/propose/reflect-block.js +220 -0
  131. package/dist/propose/reflect-block.js.map +1 -0
  132. package/dist/propose/write-draft.d.ts +90 -0
  133. package/dist/propose/write-draft.d.ts.map +1 -0
  134. package/dist/propose/write-draft.js +185 -0
  135. package/dist/propose/write-draft.js.map +1 -0
  136. package/dist/providers/claude.d.ts +13 -1
  137. package/dist/providers/claude.d.ts.map +1 -1
  138. package/dist/providers/claude.js +20 -2
  139. package/dist/providers/claude.js.map +1 -1
  140. package/dist/providers/gemini.d.ts +13 -1
  141. package/dist/providers/gemini.d.ts.map +1 -1
  142. package/dist/providers/gemini.js +24 -3
  143. package/dist/providers/gemini.js.map +1 -1
  144. package/dist/providers/index.d.ts +3 -3
  145. package/dist/providers/index.d.ts.map +1 -1
  146. package/dist/providers/index.js +3 -3
  147. package/dist/providers/index.js.map +1 -1
  148. package/dist/research-loop.d.ts +62 -0
  149. package/dist/research-loop.d.ts.map +1 -0
  150. package/dist/research-loop.js +210 -0
  151. package/dist/research-loop.js.map +1 -0
  152. package/dist/skills/defaults.d.ts +37 -0
  153. package/dist/skills/defaults.d.ts.map +1 -0
  154. package/dist/skills/defaults.js +152 -0
  155. package/dist/skills/defaults.js.map +1 -0
  156. package/dist/skills/loader.d.ts +60 -0
  157. package/dist/skills/loader.d.ts.map +1 -1
  158. package/dist/skills/loader.js +164 -2
  159. package/dist/skills/loader.js.map +1 -1
  160. package/package.json +7 -5
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Draft-queue writer for `dql propose`.
3
+ *
4
+ * This reuses the exact draft-writing convention the MCP `suggest_block` and the
5
+ * Tier-2 `upsertGeneratedDraft` paths already use:
6
+ * - Drafts land under `domains/<domain>/blocks/_drafts/<slug>.dql` when the
7
+ * domain dir exists, else `blocks/_drafts/<slug>.dql`.
8
+ * - Files are born `status = "draft"` and are NEVER written as certified.
9
+ * - Re-running is idempotent: if a file already exists at the target path it
10
+ * is left untouched and `created: false` is returned.
11
+ *
12
+ * The renderer emits valid DQL (verified against the parser's accepted field
13
+ * set) including the conservative governance metadata the Certifier reads, plus
14
+ * the stored Certifier verdict as a comment header so a reviewer immediately
15
+ * sees "what's missing to certify".
16
+ */
17
+ import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
18
+ import { dirname, join } from 'node:path';
19
+ /** Slugify a model name into a kebab/snake block id (snake to match dbt). */
20
+ export function blockSlug(name) {
21
+ const slug = name
22
+ .trim()
23
+ .toLowerCase()
24
+ .replace(/[^a-z0-9_]+/g, '_')
25
+ .replace(/^_+|_+$/g, '');
26
+ return slug || 'proposed_block';
27
+ }
28
+ function normalizeDomainFolder(domain) {
29
+ return domain
30
+ .trim()
31
+ .toLowerCase()
32
+ .replace(/[^a-z0-9/_-]+/g, '-')
33
+ .replace(/^[-/]+|[-/]+$/g, '');
34
+ }
35
+ /** Resolve the draft path exactly like suggest_block / upsertGeneratedDraft. */
36
+ function resolveDraftPath(projectRoot, domain, slug) {
37
+ const safeDomain = normalizeDomainFolder(domain);
38
+ const relativePath = safeDomain && existsSync(join(projectRoot, 'domains', safeDomain))
39
+ ? `domains/${safeDomain}/blocks/_drafts/${slug}.dql`
40
+ : `blocks/_drafts/${slug}.dql`;
41
+ return { filePath: join(projectRoot, relativePath), relativePath };
42
+ }
43
+ /**
44
+ * Write the proposed draft. Idempotent: an existing file at the target path is
45
+ * left untouched. We additionally check the canonical (non-draft) domain block
46
+ * path so a re-run never re-proposes a block a human already promoted.
47
+ */
48
+ export function upsertProposedDraft(projectRoot, rec) {
49
+ const { filePath, relativePath } = resolveDraftPath(projectRoot, rec.domain, rec.slug);
50
+ const safeDomain = normalizeDomainFolder(rec.domain);
51
+ // Canonical promoted locations — if the human already certified/moved it,
52
+ // do not re-propose.
53
+ const promotedCandidates = [
54
+ safeDomain ? join(projectRoot, 'domains', safeDomain, 'blocks', `${rec.slug}.dql`) : undefined,
55
+ join(projectRoot, 'blocks', `${rec.slug}.dql`),
56
+ ].filter((p) => Boolean(p));
57
+ if (existsSync(filePath) || promotedCandidates.some((p) => existsSync(p))) {
58
+ return { path: relativePath, created: false };
59
+ }
60
+ mkdirSync(dirname(filePath), { recursive: true });
61
+ writeFileSync(filePath, renderProposedDraft(rec, relativePath), 'utf-8');
62
+ return { path: relativePath, created: true };
63
+ }
64
+ function escapeString(value) {
65
+ return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
66
+ }
67
+ function stringArray(name, values) {
68
+ if (values.length === 0)
69
+ return '';
70
+ return `\n ${name} = [${values.map((v) => `"${escapeString(v)}"`).join(', ')}]`;
71
+ }
72
+ /** Render the full draft block as canonical DQL text. */
73
+ export function renderProposedDraft(rec, draftPath) {
74
+ const header = renderReviewHeader(rec, draftPath);
75
+ const grainLine = rec.grain ? `\n grain = "${escapeString(rec.grain)}"` : '';
76
+ const entitiesLine = stringArray('entities', rec.entities);
77
+ const outputsLine = stringArray('outputs', rec.declaredOutputs);
78
+ const sourceSystemsLine = stringArray('sourceSystems', rec.sourceSystems);
79
+ const tagsLine = stringArray('tags', rec.tags);
80
+ const llmContextLine = rec.llmContext
81
+ ? `\n llmContext = "${escapeString(rec.llmContext)}"`
82
+ : '';
83
+ const reviewCadenceLine = rec.reviewCadence
84
+ ? `\n reviewCadence = "${escapeString(rec.reviewCadence)}"`
85
+ : '';
86
+ const invariantsLine = stringArray('invariants', rec.invariants);
87
+ const examplesBlock = renderExamples(rec.examples);
88
+ const testsBlock = renderTests(rec.invariants);
89
+ const ownerLine = rec.owner ? `\n owner = "${escapeString(rec.owner)}"` : '';
90
+ // Semantic (metric-bound) block: declare the governed metric + dimensions. The
91
+ // pre-compiled `query` below keeps it runnable offline (import-adapter shape).
92
+ const blockType = rec.blockType ?? 'custom';
93
+ const metricLine = blockType === 'semantic' && rec.metricRef
94
+ ? `\n metric = "${escapeString(rec.metricRef)}"`
95
+ : '';
96
+ const dimensionsLine = stringArray('dimensions', rec.dimensions ?? []);
97
+ // App-readiness: declare which business filters a dashboard may apply and map each
98
+ // to its physical column. The runtime injects these as a safe, bound WHERE wrapper
99
+ // — so the same certified block powers many filtered views without re-authoring.
100
+ const allowedFiltersLine = stringArray('allowedFilters', rec.allowedFilters ?? []);
101
+ const filterBindingsBlock = renderFilterBindings(rec.filterBindings ?? []);
102
+ return `// dql-format: 1
103
+ ${header}block "${rec.slug}" {
104
+ domain = "${escapeString(rec.domain)}"
105
+ type = "${blockType}"
106
+ status = "draft"
107
+ description = "${escapeString(rec.description)}"${ownerLine}${metricLine}
108
+ pattern = "${escapeString(rec.pattern)}"${grainLine}${entitiesLine}${outputsLine}${dimensionsLine}${allowedFiltersLine}${sourceSystemsLine}${tagsLine}${llmContextLine}${reviewCadenceLine}${invariantsLine}${filterBindingsBlock}
109
+
110
+ query = """
111
+ ${indent(rec.sql, 4)}
112
+ """${examplesBlock}${testsBlock}
113
+ }
114
+ `;
115
+ }
116
+ /** Emit a `filterBindings { <filter> = "<column>" }` block, or '' when none. */
117
+ function renderFilterBindings(bindings) {
118
+ if (bindings.length === 0)
119
+ return '';
120
+ const lines = bindings
121
+ .map((entry) => ` ${entry.filter} = "${escapeString(entry.binding)}"`)
122
+ .join('\n');
123
+ return `\n\n filterBindings {\n${lines}\n }`;
124
+ }
125
+ /**
126
+ * A comment header that records the stored Certifier verdict so a reviewer sees
127
+ * exactly what is missing before this draft can be promoted to certified.
128
+ */
129
+ function renderReviewHeader(rec, draftPath) {
130
+ const lines = [
131
+ `// Proposed DRAFT from dbt model "${rec.sourceModel}". NOT certified.`,
132
+ `// AI drafts, humans certify — review grain/outputs/invariants/SQL, then:`,
133
+ `// dql certify --from-draft ${draftPath} --owner you@example.com`,
134
+ `//`,
135
+ `// Certifier verdict at proposal time: NOT certifiable.`,
136
+ ];
137
+ if (rec.reflectionFixes && rec.reflectionFixes.length > 0) {
138
+ lines.push(`// Auto-fixed during review (${rec.reflectionFixes.length}):`);
139
+ for (const fix of rec.reflectionFixes) {
140
+ lines.push(`// - ${fix}`);
141
+ }
142
+ }
143
+ if (rec.certification.errors.length > 0) {
144
+ lines.push(`// Blocking (${rec.certification.errors.length}):`);
145
+ for (const err of rec.certification.errors) {
146
+ lines.push(`// - ${err.rule}: ${err.message}`);
147
+ }
148
+ }
149
+ if (rec.certification.warnings.length > 0) {
150
+ lines.push(`// Warnings (${rec.certification.warnings.length}):`);
151
+ for (const warn of rec.certification.warnings) {
152
+ lines.push(`// - ${warn.rule}: ${warn.message}`);
153
+ }
154
+ }
155
+ return lines.join('\n') + '\n';
156
+ }
157
+ function renderExamples(examples) {
158
+ if (examples.length === 0)
159
+ return '';
160
+ const entries = examples
161
+ .map((ex) => {
162
+ const sqlPart = ex.sql ? `, sql = "${escapeString(ex.sql)}"` : '';
163
+ return ` { question = "${escapeString(ex.question)}"${sqlPart} }`;
164
+ })
165
+ .join(',\n');
166
+ return `\n\n examples = [\n${entries}\n ]`;
167
+ }
168
+ /**
169
+ * Emit `tests { assert ... }` mirroring the safe invariants. The parser accepts
170
+ * `assert <field> <op> <number>`; our invariants are of that shape.
171
+ */
172
+ function renderTests(invariants) {
173
+ if (invariants.length === 0)
174
+ return '';
175
+ const asserts = invariants.map((inv) => ` assert ${inv}`).join('\n');
176
+ return `\n\n tests {\n${asserts}\n }`;
177
+ }
178
+ function indent(text, spaces) {
179
+ const pad = ' '.repeat(spaces);
180
+ return text
181
+ .split('\n')
182
+ .map((line) => (line.length > 0 ? pad + line : line))
183
+ .join('\n');
184
+ }
185
+ //# sourceMappingURL=write-draft.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-draft.js","sourceRoot":"","sources":["../../src/propose/write-draft.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,16 @@
1
1
  import type { AgentProvider, AgentMessage, ProviderRunOptions } from './types.js';
2
2
  /**
3
- * Anthropic Claude provider via the Messages API. Reads ANTHROPIC_API_KEY.
3
+ * Normalize an Anthropic base URL to the SDK's "root" convention: the host (and
4
+ * optional gateway path) that `/v1/messages` is appended to. Trailing slashes and
5
+ * a trailing `/v1` are stripped so both `https://gw/anthropic` and
6
+ * `https://gw/anthropic/v1` resolve to the same endpoint. Enterprise gateways
7
+ * (LiteLLM, Portkey, Cloudflare AI Gateway, internal proxies) mirror this path.
8
+ */
9
+ export declare function normalizeAnthropicBaseUrl(baseUrl?: string): string;
10
+ /**
11
+ * Anthropic Claude provider via the Messages API. Reads ANTHROPIC_API_KEY and an
12
+ * optional ANTHROPIC_BASE_URL (or an explicit baseUrl) so enterprise deployments
13
+ * can route through a gateway/proxy.
4
14
  *
5
15
  * We deliberately avoid `@anthropic-ai/sdk` to keep dql-agent zero-dep —
6
16
  * the existing `apps/cli/src/llm/providers/claude-agent-sdk.ts` already
@@ -10,9 +20,11 @@ import type { AgentProvider, AgentMessage, ProviderRunOptions } from './types.js
10
20
  export declare class ClaudeProvider implements AgentProvider {
11
21
  readonly name: "claude";
12
22
  private readonly apiKey?;
23
+ private readonly baseUrl;
13
24
  private readonly defaultModel;
14
25
  constructor(opts?: {
15
26
  apiKey?: string;
27
+ baseUrl?: string;
16
28
  model?: string;
17
29
  });
18
30
  available(): Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/providers/claude.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB;;;;;;;GAOG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,IAAI,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO;IAKpD,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAI7B,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC;CAoC5F"}
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/providers/claude.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAIpB;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAIlE;AAED;;;;;;;;;GASG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,IAAI,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO;IAMtE,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAI7B,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC;CAoC5F"}
@@ -1,5 +1,21 @@
1
+ const DEFAULT_ANTHROPIC_BASE_URL = 'https://api.anthropic.com';
1
2
  /**
2
- * Anthropic Claude provider via the Messages API. Reads ANTHROPIC_API_KEY.
3
+ * Normalize an Anthropic base URL to the SDK's "root" convention: the host (and
4
+ * optional gateway path) that `/v1/messages` is appended to. Trailing slashes and
5
+ * a trailing `/v1` are stripped so both `https://gw/anthropic` and
6
+ * `https://gw/anthropic/v1` resolve to the same endpoint. Enterprise gateways
7
+ * (LiteLLM, Portkey, Cloudflare AI Gateway, internal proxies) mirror this path.
8
+ */
9
+ export function normalizeAnthropicBaseUrl(baseUrl) {
10
+ const raw = (baseUrl ?? '').trim();
11
+ if (!raw)
12
+ return DEFAULT_ANTHROPIC_BASE_URL;
13
+ return raw.replace(/\/+$/, '').replace(/\/v1$/, '');
14
+ }
15
+ /**
16
+ * Anthropic Claude provider via the Messages API. Reads ANTHROPIC_API_KEY and an
17
+ * optional ANTHROPIC_BASE_URL (or an explicit baseUrl) so enterprise deployments
18
+ * can route through a gateway/proxy.
3
19
  *
4
20
  * We deliberately avoid `@anthropic-ai/sdk` to keep dql-agent zero-dep —
5
21
  * the existing `apps/cli/src/llm/providers/claude-agent-sdk.ts` already
@@ -9,9 +25,11 @@
9
25
  export class ClaudeProvider {
10
26
  name = 'claude';
11
27
  apiKey;
28
+ baseUrl;
12
29
  defaultModel;
13
30
  constructor(opts = {}) {
14
31
  this.apiKey = opts.apiKey ?? process.env.ANTHROPIC_API_KEY;
32
+ this.baseUrl = normalizeAnthropicBaseUrl(opts.baseUrl ?? process.env.ANTHROPIC_BASE_URL);
15
33
  this.defaultModel = opts.model ?? 'claude-opus-4-7';
16
34
  }
17
35
  async available() {
@@ -25,7 +43,7 @@ export class ClaudeProvider {
25
43
  const turns = messages
26
44
  .filter((m) => m.role !== 'system')
27
45
  .map((m) => ({ role: m.role, content: m.content }));
28
- const res = await fetch('https://api.anthropic.com/v1/messages', {
46
+ const res = await fetch(`${this.baseUrl}/v1/messages`, {
29
47
  method: 'POST',
30
48
  headers: {
31
49
  'x-api-key': this.apiKey,
@@ -1 +1 @@
1
- {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/providers/claude.ts"],"names":[],"mappings":"AAMA;;;;;;;GAOG;AACH,MAAM,OAAO,cAAc;IAChB,IAAI,GAAG,QAAiB,CAAC;IACjB,MAAM,CAAU;IAChB,YAAY,CAAS;IAEtC,YAAY,OAA4C,EAAE;QACxD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAC3D,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,IAAI,iBAAiB,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,SAAS;QACb,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,QAAwB,EAAE,UAA8B,EAAE;QACvE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9F,MAAM,KAAK,GAAG,QAAQ;aACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;aAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAEtD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,uCAAuC,EAAE;YAC/D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,WAAW,EAAE,IAAI,CAAC,MAAM;gBACxB,mBAAmB,EAAE,YAAY;gBACjC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,YAAY;gBACzC,UAAU,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI;gBACrC,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,GAAG;gBACvC,MAAM,EAAE,MAAM,IAAI,SAAS;gBAC3B,QAAQ,EAAE,KAAK;aAChB,CAAC;YACF,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC1D,MAAM,IAAI,KAAK,CAAC,WAAW,GAAG,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAyD,CAAC;QACxF,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;QAClC,OAAO,MAAM;aACV,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;aAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;aACxB,IAAI,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;CACF"}
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/providers/claude.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,27 @@
1
1
  import type { AgentProvider, AgentMessage, ProviderRunOptions } from './types.js';
2
2
  /**
3
- * Google Gemini provider via the v1beta REST surface. Reads GEMINI_API_KEY.
3
+ * Normalize a Gemini base URL to the path that `/models/<model>:generateContent`
4
+ * is appended to (i.e. it includes the `/v1beta` API-version segment, matching the
5
+ * public default). Trailing slashes are stripped. Enterprise gateways mirror this.
6
+ */
7
+ export declare function normalizeGeminiBaseUrl(baseUrl?: string): string;
8
+ /**
9
+ * Google Gemini provider via the v1beta REST surface. Reads GEMINI_API_KEY (or
10
+ * GOOGLE_API_KEY) and an optional GEMINI_BASE_URL (or explicit baseUrl) so
11
+ * enterprise deployments can route through a gateway/proxy. The API key is sent
12
+ * via the `x-goog-api-key` header rather than a `?key=` query param so it is not
13
+ * leaked into URLs/logs and works with header-auth gateways.
4
14
  * Maps system messages by prepending them to the first user turn since
5
15
  * Gemini's API doesn't have a first-class system role.
6
16
  */
7
17
  export declare class GeminiProvider implements AgentProvider {
8
18
  readonly name: "gemini";
9
19
  private readonly apiKey?;
20
+ private readonly baseUrl;
10
21
  private readonly defaultModel;
11
22
  constructor(opts?: {
12
23
  apiKey?: string;
24
+ baseUrl?: string;
13
25
  model?: string;
14
26
  });
15
27
  available(): Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/providers/gemini.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,IAAI,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO;IAKpD,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAI7B,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC;CA4C5F"}
1
+ {"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/providers/gemini.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAIpB;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAI/D;AAED;;;;;;;;GAQG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,IAAI,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO;IAMtE,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAI7B,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC;CA+C5F"}
@@ -1,14 +1,32 @@
1
+ const DEFAULT_GEMINI_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta';
1
2
  /**
2
- * Google Gemini provider via the v1beta REST surface. Reads GEMINI_API_KEY.
3
+ * Normalize a Gemini base URL to the path that `/models/<model>:generateContent`
4
+ * is appended to (i.e. it includes the `/v1beta` API-version segment, matching the
5
+ * public default). Trailing slashes are stripped. Enterprise gateways mirror this.
6
+ */
7
+ export function normalizeGeminiBaseUrl(baseUrl) {
8
+ const raw = (baseUrl ?? '').trim();
9
+ if (!raw)
10
+ return DEFAULT_GEMINI_BASE_URL;
11
+ return raw.replace(/\/+$/, '');
12
+ }
13
+ /**
14
+ * Google Gemini provider via the v1beta REST surface. Reads GEMINI_API_KEY (or
15
+ * GOOGLE_API_KEY) and an optional GEMINI_BASE_URL (or explicit baseUrl) so
16
+ * enterprise deployments can route through a gateway/proxy. The API key is sent
17
+ * via the `x-goog-api-key` header rather than a `?key=` query param so it is not
18
+ * leaked into URLs/logs and works with header-auth gateways.
3
19
  * Maps system messages by prepending them to the first user turn since
4
20
  * Gemini's API doesn't have a first-class system role.
5
21
  */
6
22
  export class GeminiProvider {
7
23
  name = 'gemini';
8
24
  apiKey;
25
+ baseUrl;
9
26
  defaultModel;
10
27
  constructor(opts = {}) {
11
28
  this.apiKey = opts.apiKey ?? process.env.GEMINI_API_KEY ?? process.env.GOOGLE_API_KEY;
29
+ this.baseUrl = normalizeGeminiBaseUrl(opts.baseUrl ?? process.env.GEMINI_BASE_URL ?? process.env.GOOGLE_GEMINI_BASE_URL);
12
30
  this.defaultModel = opts.model ?? process.env.GEMINI_MODEL ?? 'gemini-2.5-pro';
13
31
  }
14
32
  async available() {
@@ -33,10 +51,13 @@ export class GeminiProvider {
33
51
  }
34
52
  }
35
53
  const model = options.model ?? this.defaultModel;
36
- const url = `https://generativelanguage.googleapis.com/v1beta/models/${encodeURIComponent(model)}:generateContent?key=${encodeURIComponent(this.apiKey)}`;
54
+ const url = `${this.baseUrl}/models/${encodeURIComponent(model)}:generateContent`;
37
55
  const res = await fetch(url, {
38
56
  method: 'POST',
39
- headers: { 'content-type': 'application/json' },
57
+ headers: {
58
+ 'content-type': 'application/json',
59
+ 'x-goog-api-key': this.apiKey,
60
+ },
40
61
  body: JSON.stringify({
41
62
  contents: turns.map((m) => ({
42
63
  role: m.role === 'assistant' ? 'model' : 'user',
@@ -1 +1 @@
1
- {"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/providers/gemini.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/providers/gemini.ts"],"names":[],"mappings":"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"}
@@ -6,12 +6,12 @@
6
6
  * Ollama last as the local-only fallback.
7
7
  */
8
8
  import type { AgentProvider, ProviderName } from './types.js';
9
- import { ClaudeProvider } from './claude.js';
9
+ import { ClaudeProvider, normalizeAnthropicBaseUrl } from './claude.js';
10
10
  import { OpenAIProvider } from './openai.js';
11
- import { GeminiProvider } from './gemini.js';
11
+ import { GeminiProvider, normalizeGeminiBaseUrl } from './gemini.js';
12
12
  import { OllamaProvider } from './ollama.js';
13
13
  export type { AgentProvider, AgentMessage, ProviderName, ProviderRunOptions } from './types.js';
14
- export { ClaudeProvider, OpenAIProvider, GeminiProvider, OllamaProvider };
14
+ export { ClaudeProvider, OpenAIProvider, GeminiProvider, OllamaProvider, normalizeAnthropicBaseUrl, normalizeGeminiBaseUrl };
15
15
  export declare function buildProvider(name: ProviderName): AgentProvider;
16
16
  /**
17
17
  * Pick a provider:
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChG,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,CAAC;AAI1E,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,aAAa,CAW/D;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,SAAS,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAOnF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChG,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,CAAC;AAI7H,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,aAAa,CAW/D;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,SAAS,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAOnF"}
@@ -5,11 +5,11 @@
5
5
  * Order is intentional: closed-source first (Claude → OpenAI → Gemini),
6
6
  * Ollama last as the local-only fallback.
7
7
  */
8
- import { ClaudeProvider } from './claude.js';
8
+ import { ClaudeProvider, normalizeAnthropicBaseUrl } from './claude.js';
9
9
  import { OpenAIProvider } from './openai.js';
10
- import { GeminiProvider } from './gemini.js';
10
+ import { GeminiProvider, normalizeGeminiBaseUrl } from './gemini.js';
11
11
  import { OllamaProvider } from './ollama.js';
12
- export { ClaudeProvider, OpenAIProvider, GeminiProvider, OllamaProvider };
12
+ export { ClaudeProvider, OpenAIProvider, GeminiProvider, OllamaProvider, normalizeAnthropicBaseUrl, normalizeGeminiBaseUrl };
13
13
  const FALLBACK_ORDER = ['claude', 'openai', 'gemini', 'ollama'];
14
14
  export function buildProvider(name) {
15
15
  switch (name) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,CAAC;AAE1E,MAAM,cAAc,GAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAEhF,MAAM,UAAU,aAAa,CAAC,IAAkB;IAC9C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,EAAE,CAAC;QAC9B,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,EAAE,CAAC;QAC9B,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,EAAE,CAAC;QAC9B,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,EAAE,CAAC;IAChC,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAwB;IACzD,IAAI,SAAS;QAAE,OAAO,aAAa,CAAC,SAAS,CAAC,CAAC;IAC/C,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,MAAM,CAAC,CAAC,SAAS,EAAE;YAAE,OAAO,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,aAAa,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,CAAC;AAE7H,MAAM,cAAc,GAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAEhF,MAAM,UAAU,aAAa,CAAC,IAAkB;IAC9C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,EAAE,CAAC;QAC9B,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,EAAE,CAAC;QAC9B,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,EAAE,CAAC;QAC9B,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,EAAE,CAAC;IAChC,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAwB;IACzD,IAAI,SAAS;QAAE,OAAO,aAAa,CAAC,SAAS,CAAC,CAAC;IAC/C,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,MAAM,CAAC,CAAC,SAAS,EAAE;YAAE,OAAO,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,aAAa,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Research loop (P4) — a grounded, ReAct-style planner for "research / follow-up"
3
+ * questions, so the agent behaves like a real assistant: it DECIDES whether to
4
+ * answer, to research across multiple steps, or to ask a smart follow-up — instead
5
+ * of always generating one query.
6
+ *
7
+ * The "tools" the loop reasons over are DQL's own assets: governed metrics, certified
8
+ * blocks, and their dimensions/lineage. Every step is bound to a REAL asset (no
9
+ * hallucinated tool calls), and every follow-up offers concrete options drawn from
10
+ * the catalog. The first decision reuses the P0 intent controller; this module turns
11
+ * that decision into a grounded plan.
12
+ */
13
+ import { type AgentAction } from './intent-controller.js';
14
+ import type { MetadataAgentIntent } from './metadata/catalog.js';
15
+ import type { KGNode } from './kg/types.js';
16
+ import type { PlanBlock } from './app-planner.js';
17
+ /** One ReAct step: a thought, the asset-bound action, and what observing it tells us. */
18
+ export interface ResearchStep {
19
+ thought: string;
20
+ action: {
21
+ kind: 'lookup_metric' | 'lookup_block' | 'breakdown' | 'compare_time' | 'check_lineage' | 'compose_app';
22
+ /** The real asset the action touches (metric/block/dimension name). */
23
+ target: string;
24
+ };
25
+ /** What a successful observation of this step should establish. */
26
+ expectation: string;
27
+ }
28
+ /** A smart follow-up: the question plus concrete, catalog-grounded options. */
29
+ export interface ResearchFollowUp {
30
+ question: string;
31
+ options: string[];
32
+ }
33
+ export interface ResearchPlan {
34
+ decision: AgentAction;
35
+ confidence: number;
36
+ rationale: string;
37
+ /** The grounded ReAct trace (empty for a pure clarify turn). */
38
+ steps: ResearchStep[];
39
+ /** Present when the agent should ask before researching. */
40
+ followUp?: ResearchFollowUp;
41
+ /** Assets the plan cites (metric/block names). */
42
+ sources: string[];
43
+ /** True when the question is answerable directly (single step, no research needed). */
44
+ done: boolean;
45
+ }
46
+ /**
47
+ * Plan how to handle a research / follow-up question. Returns the decision plus a
48
+ * grounded plan: a direct answer, a multi-step research trace, or a follow-up with
49
+ * concrete options. Deterministic + offline; the metric match reuses the spec-17 matcher.
50
+ */
51
+ export declare function planResearch(input: {
52
+ question: string;
53
+ metrics: KGNode[];
54
+ blocks: PlanBlock[];
55
+ intent?: MetadataAgentIntent;
56
+ isFollowUp?: boolean;
57
+ history?: Array<{
58
+ role: 'user' | 'assistant';
59
+ text: string;
60
+ }>;
61
+ }): Promise<ResearchPlan>;
62
+ //# sourceMappingURL=research-loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"research-loop.d.ts","sourceRoot":"","sources":["../src/research-loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,yFAAyF;AACzF,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE;QACN,IAAI,EAAE,eAAe,GAAG,cAAc,GAAG,WAAW,GAAG,cAAc,GAAG,eAAe,GAAG,aAAa,CAAC;QACxG,uEAAuE;QACvE,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,+EAA+E;AAC/E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,kDAAkD;IAClD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,uFAAuF;IACvF,IAAI,EAAE,OAAO,CAAC;CACf;AA8CD;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/D,GAAG,OAAO,CAAC,YAAY,CAAC,CAiIxB"}