@duckcodeailabs/dql-cli 1.8.13 → 1.9.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/assets/dql-notebook/assets/{index-DZ5M01EH.js → index-CY3qwACP.js} +312 -312
- package/dist/assets/dql-notebook/index.html +1 -1
- package/dist/llm/providers/dql-agent-provider.d.ts.map +1 -1
- package/dist/llm/providers/dql-agent-provider.js +27 -0
- package/dist/llm/providers/dql-agent-provider.js.map +1 -1
- package/dist/local-runtime.d.ts +1 -1
- package/dist/local-runtime.d.ts.map +1 -1
- package/dist/local-runtime.js +87 -11
- package/dist/local-runtime.js.map +1 -1
- package/dist/metricflow.d.ts +25 -0
- package/dist/metricflow.d.ts.map +1 -1
- package/dist/metricflow.js +75 -1
- package/dist/metricflow.js.map +1 -1
- package/dist/package.json +10 -10
- package/dist/semantic-runtime-settings.d.ts +7 -0
- package/dist/semantic-runtime-settings.d.ts.map +1 -1
- package/dist/semantic-runtime-settings.js +12 -0
- package/dist/semantic-runtime-settings.js.map +1 -1
- package/dist/semantic-runtime.d.ts +54 -2
- package/dist/semantic-runtime.d.ts.map +1 -1
- package/dist/semantic-runtime.js +147 -28
- package/dist/semantic-runtime.js.map +1 -1
- package/package.json +10 -10
package/dist/local-runtime.js
CHANGED
|
@@ -19,7 +19,7 @@ import { fetchLatestPublishedDqlVersion, resolveDqlRuntimeVersionStatus } from '
|
|
|
19
19
|
import { resolveRetrievalHealthStatus } from './retrieval-health.js';
|
|
20
20
|
import { createDqlAgentProviderRunner, resolveAgentFollowUpContext } from './llm/providers/dql-agent-provider.js';
|
|
21
21
|
import { listRemoteMcpSettings, saveRemoteMcpSettings } from './llm/mcp-config.js';
|
|
22
|
-
import { ClaudeProvider, ConversationStore, advanceThreadState, buildConversationSnapshot, recallRelevantTurns, GeminiProvider, MemoryStore, OllamaProvider, OpenAIProvider, buildBlockBusinessFingerprint, buildBlockSqlFingerprints, buildAnalysisQuestionPlan, aggregationIntegrityIssuesForSql, buildLocalContextPack, toAgentRetrievalEvidence, defaultConversationPath, defaultMemoryPath, ensureDefaultMemoryFiles, ensureAgentProjectReady, isAgentProjectIndexReady, currentMetadataFingerprint, ensureMetadataCatalogFresh, readIndexedDomainKnowledge, readIndexedKnowledge360, propose, proposePlan, recordCorrectionTrace, emitCorrectionEvalCase, mineJoinPatterns, reviewHint, AgentRunEngine, SqliteAgentRunStore, defaultAgentRunGates, createLlmAgentRunPlanner, createHybridRouter, computeResultStats, buildDeterministicDashboardStory, synthesizeAnswer, streamOrGenerate, narrateResult, buildProposePreview, buildFromPrompt, defaultAgentRunStorePath, defaultAgentRunSqlitePath, resolveLocalOwner, resolveProposeConfig, recordQueryRun, recordRuntimeSchemaSnapshot, latestRuntimeSchemaSnapshotForProject, loadSkills, migrateLegacySkills, configuredSkillsPath, skillsDir, draftDomainSkillBootstrap, buildDomainSkillBootstrapPrompt, mergeDomainSkillBootstrapEnrichment, writeSkill, deleteSkill, deriveGeneratedDraftSlug, reindexProject, invalidateAgentProjectState, recordAgentRuntimeVersion, resolveDomainContextEnvelope, defaultKgPath, planAppFromPrompt, KGStore, planResearch, loadSemanticMetrics, cascadeTraceToEvidenceRouteSteps, createCascadeAnswerResult, createCascadeTrace, routeReasoningEffort, routeForCascadeAnswerTier, clampReasoningEffort, bumpReasoningEffort, resolveThinkingMode, coerceThinkingMode, upsertGeneratedDqlArtifactDraft, loadAgentSemanticLayer, } from '@duckcodeailabs/dql-agent';
|
|
22
|
+
import { ClaudeProvider, ConversationStore, advanceThreadState, buildConversationSnapshot, recallRelevantTurns, GeminiProvider, MemoryStore, OllamaProvider, OpenAIProvider, buildBlockBusinessFingerprint, buildBlockSqlFingerprints, buildAnalysisQuestionPlan, aggregationIntegrityIssuesForSql, buildLocalContextPack, toAgentRetrievalEvidence, defaultConversationPath, defaultMemoryPath, ensureDefaultMemoryFiles, ensureAgentProjectReady, isAgentProjectIndexReady, currentMetadataFingerprint, ensureMetadataCatalogFresh, readIndexedDomainKnowledge, readIndexedKnowledge360, compactSemanticRuntimeFailure, propose, proposePlan, recordCorrectionTrace, emitCorrectionEvalCase, mineJoinPatterns, reviewHint, AgentRunEngine, SqliteAgentRunStore, defaultAgentRunGates, createLlmAgentRunPlanner, createHybridRouter, computeResultStats, buildDeterministicDashboardStory, synthesizeAnswer, streamOrGenerate, narrateResult, buildProposePreview, buildFromPrompt, defaultAgentRunStorePath, defaultAgentRunSqlitePath, resolveLocalOwner, resolveProposeConfig, recordQueryRun, recordRuntimeSchemaSnapshot, latestRuntimeSchemaSnapshotForProject, loadSkills, migrateLegacySkills, configuredSkillsPath, skillsDir, draftDomainSkillBootstrap, buildDomainSkillBootstrapPrompt, mergeDomainSkillBootstrapEnrichment, writeSkill, deleteSkill, deriveGeneratedDraftSlug, reindexProject, invalidateAgentProjectState, recordAgentRuntimeVersion, resolveDomainContextEnvelope, defaultKgPath, planAppFromPrompt, KGStore, planResearch, loadSemanticMetrics, cascadeTraceToEvidenceRouteSteps, createCascadeAnswerResult, createCascadeTrace, routeReasoningEffort, routeForCascadeAnswerTier, clampReasoningEffort, bumpReasoningEffort, resolveThinkingMode, coerceThinkingMode, upsertGeneratedDqlArtifactDraft, loadAgentSemanticLayer, } from '@duckcodeailabs/dql-agent';
|
|
23
23
|
import { gatherProposeEnrichment } from './propose-enrich.js';
|
|
24
24
|
import { handleAppsApi, proposeAppAiBuild, recommendVisualization } from './apps-api.js';
|
|
25
25
|
import { getActiveProvider, getEffectiveProviderConfig, isProviderSettingsId, listProviderSettings, saveProviderSettings, } from './settings/provider-settings.js';
|
|
@@ -33,8 +33,8 @@ import { buildSemanticObjectDetail, buildSemanticTree, computeSyncDiff, loadSema
|
|
|
33
33
|
import { clearBlockStudioImportSessions, candidateToDqlSource, createBlockStudioImportSession, deleteBlockStudioImportSession, listBlockStudioImportSessions, loadBlockStudioImportSession, readBlockStudioImportCandidate, parameterizeSqlForDqlImport, updateBlockStudioImportCandidate, writeBlockStudioImportSession, writeBlockStudioImportCandidate, } from './block-studio-import.js';
|
|
34
34
|
import { MetricFlowUnavailableError, hasDbtSemanticManifest, } from "./metricflow.js";
|
|
35
35
|
import { ManagedMetricFlowInstaller, isMetricFlowWarehouseAdapter, metricFlowAdapterForDriver, } from './metricflow-installer.js';
|
|
36
|
-
import { compileSemanticRuntimeQuery, getSemanticRuntimeStatus, isSemanticRuntimeError,
|
|
37
|
-
import { getSemanticRuntimeSettings, saveTestedSemanticRuntimeSettings, } from './semantic-runtime-settings.js';
|
|
36
|
+
import { compileSemanticRuntimeQuery, describeRuntimeCompatibility, getSemanticRuntimeStatus, isSemanticRuntimeError, semanticMetricExecutionCapability as runtimeMetricExecutionCapability, SemanticRuntimeRequiredError, testSemanticRuntimeDraft, } from './semantic-runtime.js';
|
|
37
|
+
import { getSemanticRuntimeSettings, saveTestedSemanticRuntimeSettings, saveSemanticRuntimePreference, } from './semantic-runtime-settings.js';
|
|
38
38
|
import { NotebookDatasetWorkspace, } from "./notebook-datasets.js";
|
|
39
39
|
import { prepareBlockInvocation } from './block-invocation.js';
|
|
40
40
|
const NOTEBOOK_EXECUTE_PREVIEW_ROW_LIMIT = 500;
|
|
@@ -204,15 +204,54 @@ function agentColumnDisplayFormats(projectRoot, columns) {
|
|
|
204
204
|
* no env override. The defaults must fit the transport's physics. */
|
|
205
205
|
const AGENT_CLI_LOOKUP_DEADLINE_MS = 150_000;
|
|
206
206
|
const AGENT_CLI_RESEARCH_DEADLINE_MS = 300_000;
|
|
207
|
+
/** High reasoning effort makes every LLM call materially slower, so the same
|
|
208
|
+
* multi-step build that fits a budget at medium effort overruns it at high. The
|
|
209
|
+
* budget must scale with effort or "High · thorough" reliably times out. */
|
|
210
|
+
function reasoningEffortBudgetMultiplier(effort) {
|
|
211
|
+
return effort === 'high' ? 1.8 : effort === 'low' ? 0.9 : 1;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* A ranking/breakdown/filtered question needs LLM SQL generation (the grain
|
|
215
|
+
* dimension usually lives on a joined model the semantic layer can't compose),
|
|
216
|
+
* and that multi-call build does NOT fit the bare lookup budget on a slow or
|
|
217
|
+
* high-effort provider — it dead-ends at the deadline. It is not "research", but
|
|
218
|
+
* it needs research-sized time to finish. Detected from the requested SHAPE (a
|
|
219
|
+
* top-N, a member filter, a breakdown dimension, or a time window) rather than a
|
|
220
|
+
* recognized metric word, since office questions like "top bcm customers from
|
|
221
|
+
* the south region" name no metric the planner knows yet. A bare scalar
|
|
222
|
+
* ("total revenue") has none of these and stays on the short budget.
|
|
223
|
+
*/
|
|
224
|
+
function isAnalyticalBuildQuestion(plan) {
|
|
225
|
+
if (!plan.needsGeneratedSql)
|
|
226
|
+
return false;
|
|
227
|
+
return plan.requestedShape.dimensions.length > 0
|
|
228
|
+
|| plan.dimensionTerms.length > 0
|
|
229
|
+
|| plan.requestedShape.filters.length > 0
|
|
230
|
+
|| plan.timeTerms.length > 0
|
|
231
|
+
|| Boolean(plan.requestedShape.topN);
|
|
232
|
+
}
|
|
207
233
|
export function agentRunDeadlineMs(request, env = process.env, activeProviderId) {
|
|
208
234
|
const cliProvider = activeProviderId === 'claude-code' || activeProviderId === 'codex';
|
|
209
235
|
const lookupDeadline = resolveAgentDeadlineMs('DQL_AGENT_LOOKUP_DEADLINE_MS', cliProvider ? AGENT_CLI_LOOKUP_DEADLINE_MS : AGENT_LOOKUP_DEADLINE_MS, env);
|
|
210
236
|
const researchDeadline = resolveAgentDeadlineMs('DQL_AGENT_RESEARCH_DEADLINE_MS', cliProvider ? AGENT_CLI_RESEARCH_DEADLINE_MS : AGENT_RESEARCH_DEADLINE_MS, env);
|
|
211
|
-
|
|
212
|
-
|
|
237
|
+
// The "Thinking" control sends a thinkingMode; explicit reasoningEffort/
|
|
238
|
+
// analysisDepth (CLI flags) take precedence but the mode is the common case.
|
|
239
|
+
// The deadline MUST see the resolved values — "High" both slows every call
|
|
240
|
+
// AND means deep — or picking High reliably times out at the lookup budget.
|
|
241
|
+
const resolvedMode = request.thinkingMode ? resolveThinkingMode(request.thinkingMode) : {};
|
|
242
|
+
const effectiveEffort = request.reasoningEffort ?? resolvedMode.reasoningEffort;
|
|
243
|
+
const effectiveDepth = request.analysisDepth ?? resolvedMode.analysisDepth;
|
|
244
|
+
// The budget is a CEILING, not a target — a fast answer returns immediately;
|
|
245
|
+
// the larger tiers only matter when the build genuinely needs the time.
|
|
246
|
+
const scale = (ms) => Math.min(600_000, Math.round(ms * reasoningEffortBudgetMultiplier(effectiveEffort)));
|
|
247
|
+
if (request.requestedMode === 'research' || effectiveDepth === 'deep') {
|
|
248
|
+
return scale(researchDeadline);
|
|
213
249
|
}
|
|
214
250
|
const plan = buildAnalysisQuestionPlan(request.question);
|
|
215
|
-
|
|
251
|
+
if (plan.needsResearchWorkspace || isAnalyticalBuildQuestion(plan)) {
|
|
252
|
+
return scale(researchDeadline);
|
|
253
|
+
}
|
|
254
|
+
return scale(lookupDeadline);
|
|
216
255
|
}
|
|
217
256
|
export function shouldSynthesizeAgentRunAnswer(governedAnswer) {
|
|
218
257
|
if (governedAnswer.kind === 'no_answer')
|
|
@@ -344,9 +383,12 @@ export function conversationTurnInputFromRun(run) {
|
|
|
344
383
|
// value window. Deriving dimensions from only the eight preview rows caused a
|
|
345
384
|
// valid row 9/10 member to disappear before the next turn (AGT-012/E2E-010).
|
|
346
385
|
const memberRows = Array.isArray(result?.rows)
|
|
347
|
-
? result.rows.filter((row) => Boolean(row && typeof row === 'object' && !Array.isArray(row))).slice(0,
|
|
386
|
+
? result.rows.filter((row) => Boolean(row && typeof row === 'object' && !Array.isArray(row))).slice(0, 50)
|
|
348
387
|
: [];
|
|
349
|
-
|
|
388
|
+
// The full retained window feeds both member resolution and cross-result
|
|
389
|
+
// follow-up compute ("of the results above, the average"). The store clamps
|
|
390
|
+
// it (MAX_SAMPLE_ROWS); rows are never dumped into the prompt.
|
|
391
|
+
const rows = memberRows;
|
|
350
392
|
const rowsSample = rows.map((row) => columns.map((column) => row[column]));
|
|
351
393
|
const contextPack = agentRunRecord(payload?.contextPack);
|
|
352
394
|
const questionPlan = agentRunRecord(contextPack?.questionPlan);
|
|
@@ -8549,8 +8591,11 @@ export async function startLocalServer(opts) {
|
|
|
8549
8591
|
res.end(serializeJSON(preview));
|
|
8550
8592
|
}
|
|
8551
8593
|
catch (error) {
|
|
8594
|
+
const raw = error instanceof Error ? error.message : String(error);
|
|
8552
8595
|
res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
8553
|
-
|
|
8596
|
+
// `error` stays the full compiler output (the UI shows it in a
|
|
8597
|
+
// collapsible); `friendlyMessage` is the one actionable sentence.
|
|
8598
|
+
res.end(serializeJSON({ error: raw, friendlyMessage: compactSemanticRuntimeFailure(raw) }));
|
|
8554
8599
|
}
|
|
8555
8600
|
return;
|
|
8556
8601
|
}
|
|
@@ -9095,6 +9140,26 @@ export async function startLocalServer(opts) {
|
|
|
9095
9140
|
}
|
|
9096
9141
|
return;
|
|
9097
9142
|
}
|
|
9143
|
+
// Set the runtime preference alone (no dbt Cloud test required), so a user
|
|
9144
|
+
// can prefer Native / Local MetricFlow / dbt Cloud explicitly.
|
|
9145
|
+
if (req.method === 'POST' && path === '/api/semantic-runtime/preference') {
|
|
9146
|
+
try {
|
|
9147
|
+
const body = await readJSON(req);
|
|
9148
|
+
const preference = body.preference;
|
|
9149
|
+
if (preference !== 'auto' && preference !== 'native' && preference !== 'metricflow-cli' && preference !== 'dbt-cloud') {
|
|
9150
|
+
throw new Error('preference must be one of: auto, native, metricflow-cli, dbt-cloud');
|
|
9151
|
+
}
|
|
9152
|
+
const settings = saveSemanticRuntimePreference(projectRoot, preference);
|
|
9153
|
+
const runtime = await getSemanticRuntimeStatus(projectRoot, { probeConfiguredCloud: true });
|
|
9154
|
+
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
9155
|
+
res.end(serializeJSON({ ok: true, ...settings, runtime }));
|
|
9156
|
+
}
|
|
9157
|
+
catch (error) {
|
|
9158
|
+
res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
9159
|
+
res.end(serializeJSON({ ok: false, error: error instanceof Error ? error.message : String(error) }));
|
|
9160
|
+
}
|
|
9161
|
+
return;
|
|
9162
|
+
}
|
|
9098
9163
|
// ── Semantic layer discovery API ─────────────────────────────────────────
|
|
9099
9164
|
if (req.method === 'GET' && path === '/api/semantic-layer') {
|
|
9100
9165
|
const userPrefs = readUserPrefs(userPrefsPath);
|
|
@@ -9588,7 +9653,8 @@ export async function startLocalServer(opts) {
|
|
|
9588
9653
|
.split(',')
|
|
9589
9654
|
.map((value) => value.trim())
|
|
9590
9655
|
.filter(Boolean);
|
|
9591
|
-
const
|
|
9656
|
+
const compat = await describeRuntimeCompatibility(projectRoot, semanticLayer, metrics, projectConfig);
|
|
9657
|
+
const dimensions = compat.dimensions.map((d) => ({
|
|
9592
9658
|
name: d.name,
|
|
9593
9659
|
label: d.label,
|
|
9594
9660
|
description: d.description,
|
|
@@ -9598,9 +9664,19 @@ export async function startLocalServer(opts) {
|
|
|
9598
9664
|
table: d.table,
|
|
9599
9665
|
tags: d.tags ?? [],
|
|
9600
9666
|
owner: d.owner ?? null,
|
|
9667
|
+
// Additive: qualified name, real grains, and time flag (existing fields
|
|
9668
|
+
// above are byte-identical for compatibility).
|
|
9669
|
+
qualifiedName: d.qualifiedName ?? null,
|
|
9670
|
+
granularities: d.granularities ?? d.granularities ?? null,
|
|
9671
|
+
isTimeDimension: Boolean(d.isTimeDimension),
|
|
9601
9672
|
}));
|
|
9602
9673
|
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
9603
|
-
res.end(serializeJSON({
|
|
9674
|
+
res.end(serializeJSON({
|
|
9675
|
+
dimensions,
|
|
9676
|
+
engine: compat.engine,
|
|
9677
|
+
incompatible: compat.incompatible,
|
|
9678
|
+
degraded: compat.degraded ?? null,
|
|
9679
|
+
}));
|
|
9604
9680
|
return;
|
|
9605
9681
|
}
|
|
9606
9682
|
if (req.method === 'GET' && path === '/api/user-prefs/favorites') {
|