@duckcodeailabs/dql-cli 1.12.2 → 1.12.3
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/AgentAnswerCard-BEIwKGm4.js +5 -0
- package/dist/assets/dql-notebook/assets/AgentLogPage-CsSC2tOR.js +1 -0
- package/dist/assets/dql-notebook/assets/AiBuildDialog-CjJ-9bQW.js +1 -0
- package/dist/assets/dql-notebook/assets/AiBuildResult-BvTcW9oE.js +33 -0
- package/dist/assets/dql-notebook/assets/AiSidePanel-CxFrOfCE.js +6 -0
- package/dist/assets/dql-notebook/assets/AnalyticsHome-BtXEdJNR.js +6 -0
- package/dist/assets/dql-notebook/assets/AppsView-HjQkbbE6.js +4471 -0
- package/dist/assets/dql-notebook/assets/BlockStudio-oQHTJsXC.js +60 -0
- package/dist/assets/dql-notebook/assets/BusinessArtifactView-Dpsftjs7.js +1 -0
- package/dist/assets/dql-notebook/assets/DbtFirstModelingPage-c6ZteaI6.js +22 -0
- package/dist/assets/dql-notebook/assets/GitPage-Cj6mc-Yv.js +7 -0
- package/dist/assets/dql-notebook/assets/GlobalAiRail-8G_rEyhK.js +1 -0
- package/dist/assets/dql-notebook/assets/GovernedContextPage-BTtzt0Za.js +7 -0
- package/dist/assets/dql-notebook/assets/HelpDocsPage-e2CesE73.js +22 -0
- package/dist/assets/dql-notebook/assets/HomePage-U3ryMLEF.js +117 -0
- package/dist/assets/dql-notebook/assets/LineageDAG-CEmgJzm3.js +1 -0
- package/dist/assets/dql-notebook/assets/LineageDetailView-CeV5QMXS.js +1 -0
- package/dist/assets/dql-notebook/assets/LineageDrawer-B1oAn-N_.js +1 -0
- package/dist/assets/dql-notebook/assets/LineagePathBreadcrumb-fP6RTXut.js +14 -0
- package/dist/assets/dql-notebook/assets/MiniLineageGraph-CBYSTmRC.js +1 -0
- package/dist/assets/dql-notebook/assets/NewBlockModal-ksEwimjl.js +1 -0
- package/dist/assets/dql-notebook/assets/NewNotebookModal-CUx0WmXb.js +46 -0
- package/dist/assets/dql-notebook/assets/NotebookEditor-BdxJL3LX.js +202 -0
- package/dist/assets/dql-notebook/assets/ReadinessPage-DZ9wDW76.js +1 -0
- package/dist/assets/dql-notebook/assets/SetupOnboarding-Bt0AAe0h.js +6 -0
- package/dist/assets/dql-notebook/assets/TrustBadge-DNVJK_mP.js +1 -0
- package/dist/assets/dql-notebook/assets/UnifiedAgentRunPanel-BNqE169i.js +83 -0
- package/dist/assets/dql-notebook/assets/ai-build-bus-1BR770pY.js +1 -0
- package/dist/assets/dql-notebook/assets/answer-to-notebook-B_gE6rsY.js +2 -0
- package/dist/assets/dql-notebook/assets/arrow-left-DnKGhzOR.js +6 -0
- package/dist/assets/dql-notebook/assets/arrow-right-CQ73DG7_.js +6 -0
- package/dist/assets/dql-notebook/assets/book-open-text-CyBV5Nhw.js +6 -0
- package/dist/assets/dql-notebook/assets/bot-UOPtBzCj.js +6 -0
- package/dist/assets/dql-notebook/assets/chevron-up-CDHDU3N3.js +6 -0
- package/dist/assets/dql-notebook/assets/circle-x-DC5nkL_u.js +6 -0
- package/dist/assets/dql-notebook/assets/{codemirror-Co0dCEDr.js → codemirror-1_I9gm6Z.js} +1 -1
- package/dist/assets/dql-notebook/assets/dagre-BZV40eAE.css +1 -0
- package/dist/assets/dql-notebook/assets/dagre.esm-C7ujXipB.js +23 -0
- package/dist/assets/dql-notebook/assets/external-link-BiJ_dtTM.js +6 -0
- package/dist/assets/dql-notebook/assets/grip-vertical-eXvkUerq.js +6 -0
- package/dist/assets/dql-notebook/assets/index-BMVfPaXr.js +644 -0
- package/dist/assets/dql-notebook/assets/{index-DvLT6Kls.css → index-DKu4CZt3.css} +1 -1
- package/dist/assets/dql-notebook/assets/link-2-DkHVJTuH.js +6 -0
- package/dist/assets/dql-notebook/assets/list-tree-8lYW2Itb.js +6 -0
- package/dist/assets/dql-notebook/assets/maximize-2-DjSovOdP.js +6 -0
- package/dist/assets/dql-notebook/assets/minimize-2-DGlmQLES.js +6 -0
- package/dist/assets/dql-notebook/assets/panel-right-open-DPc4gShM.js +6 -0
- package/dist/assets/dql-notebook/assets/pencil-nwaGtOdL.js +6 -0
- package/dist/assets/dql-notebook/assets/{react-BRY8hXab.js → react-CRB3T2We.js} +2 -2
- package/dist/assets/dql-notebook/assets/rotate-ccw-ByjLhAu7.js +6 -0
- package/dist/assets/dql-notebook/assets/semantic-fields-eEhwnQhG.js +3 -0
- package/dist/assets/dql-notebook/assets/triangle-alert-zws0cKhp.js +6 -0
- package/dist/assets/dql-notebook/assets/usePersistedAgentThreadId-hxi1RZDm.js +18 -0
- package/dist/assets/dql-notebook/assets/user-round-CM8xNakq.js +11 -0
- package/dist/assets/dql-notebook/assets/wand-sparkles-CIKc8r-4.js +6 -0
- package/dist/assets/dql-notebook/assets/workflow-6C0ZLbTi.js +6 -0
- package/dist/assets/dql-notebook/assets/wrench-CeU7hF12.js +6 -0
- package/dist/assets/dql-notebook/assets/x-DLWEzvri.js +6 -0
- package/dist/assets/dql-notebook/index.html +3 -4
- package/dist/local-runtime.d.ts +10 -2
- package/dist/local-runtime.d.ts.map +1 -1
- package/dist/local-runtime.js +130 -39
- package/dist/local-runtime.js.map +1 -1
- package/dist/package.json +10 -10
- package/dist/warehouse-metadata.d.ts +1 -1
- package/dist/warehouse-metadata.d.ts.map +1 -1
- package/dist/warehouse-metadata.js +2 -2
- package/dist/warehouse-metadata.js.map +1 -1
- package/package.json +10 -10
- package/dist/assets/dql-notebook/assets/index-BRCtmVPa.js +0 -5952
package/dist/local-runtime.js
CHANGED
|
@@ -968,7 +968,10 @@ export async function startLocalServer(opts) {
|
|
|
968
968
|
return result;
|
|
969
969
|
};
|
|
970
970
|
await reloadSemanticLayer();
|
|
971
|
-
|
|
971
|
+
// Normal startup reuses the fingerprinted local catalog when its inputs are
|
|
972
|
+
// unchanged. Explicit refresh, save, and certification paths still request
|
|
973
|
+
// the default forced rebuild below.
|
|
974
|
+
await refreshLocalMetadataCatalog(projectRoot, undefined, undefined, false);
|
|
972
975
|
const startupDbtManifestPath = resolveDbtManifestPath(projectRoot, projectConfig);
|
|
973
976
|
if (startupDbtManifestPath && !isAgentProjectIndexReady(projectRoot)) {
|
|
974
977
|
try {
|
|
@@ -1338,8 +1341,14 @@ export async function startLocalServer(opts) {
|
|
|
1338
1341
|
throw error;
|
|
1339
1342
|
}
|
|
1340
1343
|
const semanticDriver = semanticConnection?.driver;
|
|
1344
|
+
const defaultExecutionTarget = executionTargetDescriptor({});
|
|
1345
|
+
const semanticConnectionName = request.executionTarget?.target === 'connection'
|
|
1346
|
+
? request.executionTarget.connectionName
|
|
1347
|
+
: defaultExecutionTarget.target === 'connection'
|
|
1348
|
+
? defaultExecutionTarget.connectionName
|
|
1349
|
+
: undefined;
|
|
1341
1350
|
const semanticTableMapping = semanticLayer && semanticConnection
|
|
1342
|
-
? await resolveSemanticTableMapping(executor, semanticConnection, semanticLayer, projectRoot)
|
|
1351
|
+
? await resolveSemanticTableMapping(executor, semanticConnection, semanticLayer, projectRoot, semanticConnectionName)
|
|
1343
1352
|
: undefined;
|
|
1344
1353
|
const requestedDomain = normalizeAgentRunDomain(agentRunWorkspaceValue(request, 'domain'));
|
|
1345
1354
|
const requestedPurpose = agentRunWorkspaceValue(request, 'purpose');
|
|
@@ -1527,9 +1536,9 @@ export async function startLocalServer(opts) {
|
|
|
1527
1536
|
? { resolvedAnalyticalPlan: routeDecision.resolvedAnalyticalPlan }
|
|
1528
1537
|
: {}),
|
|
1529
1538
|
analyticalReferenceInstant: new Date().toISOString(),
|
|
1530
|
-
executeCertifiedBlock: (node, invocation) => executeCertifiedBlockForAgent(node, invocation, semanticConnection),
|
|
1531
|
-
executeGeneratedSql: (sql, artifact) => executeGeneratedArtifactForAgent(request.question, sql, artifact, semanticConnection),
|
|
1532
|
-
executeDqlArtifact: (artifact) => executeArtifactReferenceForAgent(artifact, request.question, semanticConnection),
|
|
1539
|
+
executeCertifiedBlock: (node, invocation) => executeCertifiedBlockForAgent(node, invocation, semanticConnection, semanticConnectionName),
|
|
1540
|
+
executeGeneratedSql: (sql, artifact) => executeGeneratedArtifactForAgent(request.question, sql, artifact, semanticConnection, semanticConnectionName),
|
|
1541
|
+
executeDqlArtifact: (artifact) => executeArtifactReferenceForAgent(artifact, request.question, semanticConnection, semanticConnectionName),
|
|
1533
1542
|
getSchemaContext: (question, preparedContextPack) => getSchemaContextForAgent(question, preparedContextPack, semanticConnection, request.executionTarget?.target === 'connection'
|
|
1534
1543
|
? request.executionTarget.connectionName
|
|
1535
1544
|
: undefined),
|
|
@@ -2713,6 +2722,18 @@ export async function startLocalServer(opts) {
|
|
|
2713
2722
|
const preparedMetadataFingerprint = isAgentProjectIndexReady(projectRoot)
|
|
2714
2723
|
? currentMetadataFingerprint(projectRoot)
|
|
2715
2724
|
: undefined;
|
|
2725
|
+
const targetDescriptor = executionTargetDescriptor(request);
|
|
2726
|
+
const targetConnectionName = targetDescriptor.target === 'connection'
|
|
2727
|
+
? targetDescriptor.connectionName
|
|
2728
|
+
: undefined;
|
|
2729
|
+
let runtimeSchemaSnapshot;
|
|
2730
|
+
if (targetConnectionName) {
|
|
2731
|
+
const targetConnection = resolveNamedConnection(targetConnectionName);
|
|
2732
|
+
const activeScope = targetConnection
|
|
2733
|
+
? optionalActiveConnectionMetadataScope(projectRoot, projectConfig, targetConnection, targetConnectionName)
|
|
2734
|
+
: null;
|
|
2735
|
+
runtimeSchemaSnapshot = runtimeSchemaSnapshotForAgentConnection(projectRoot, targetConnectionName, activeScope?.scopeFingerprint);
|
|
2736
|
+
}
|
|
2716
2737
|
const task = buildLocalContextPack(projectRoot, {
|
|
2717
2738
|
question: request.question,
|
|
2718
2739
|
focusObjectKey: request.selectedEvidenceId,
|
|
@@ -2724,7 +2745,11 @@ export async function startLocalServer(opts) {
|
|
|
2724
2745
|
|| topicRelation === 'shift'
|
|
2725
2746
|
? topicRelation
|
|
2726
2747
|
: undefined,
|
|
2748
|
+
// Reuse remains available for fast follow-ups; the context-pack freshness
|
|
2749
|
+
// contract now binds it to this runtime snapshot's connection/generation.
|
|
2750
|
+
reusePolicy: 'seed',
|
|
2727
2751
|
preparedMetadataFingerprint,
|
|
2752
|
+
...(runtimeSchemaSnapshot ? { runtimeSchemaSnapshot } : {}),
|
|
2728
2753
|
surface: 'notebook',
|
|
2729
2754
|
selectedContext: {
|
|
2730
2755
|
selectedObject: request.selectedObject,
|
|
@@ -2995,7 +3020,7 @@ export async function startLocalServer(opts) {
|
|
|
2995
3020
|
cells: snapshotCells,
|
|
2996
3021
|
});
|
|
2997
3022
|
};
|
|
2998
|
-
const executeDqlArtifactSourceForAgent = async (source, metadata = {}, invocationInput, executionConnection) => {
|
|
3023
|
+
const executeDqlArtifactSourceForAgent = async (source, metadata = {}, invocationInput, executionConnection, executionConnectionName) => {
|
|
2999
3024
|
const invocation = prepareBlockInvocation({
|
|
3000
3025
|
source,
|
|
3001
3026
|
parameters: invocationInput?.parameters,
|
|
@@ -3011,7 +3036,7 @@ export async function startLocalServer(opts) {
|
|
|
3011
3036
|
const activeConnection = requireActiveConnection(executionConnection);
|
|
3012
3037
|
const precompiledSemanticQuery = Boolean(extractBlockStudioSql(source));
|
|
3013
3038
|
const tableMapping = !precompiledSemanticQuery
|
|
3014
|
-
? await resolveSemanticTableMapping(executor, activeConnection, semanticLayer, projectRoot)
|
|
3039
|
+
? await resolveSemanticTableMapping(executor, activeConnection, semanticLayer, projectRoot, executionConnectionName)
|
|
3015
3040
|
: undefined;
|
|
3016
3041
|
const semanticCompose = semanticLayer
|
|
3017
3042
|
? await composeSemanticBlockSqlForRuntime(source, semanticLayer, {
|
|
@@ -3080,7 +3105,7 @@ export async function startLocalServer(opts) {
|
|
|
3080
3105
|
} : {}),
|
|
3081
3106
|
};
|
|
3082
3107
|
};
|
|
3083
|
-
const executeCertifiedBlockByNameForAgent = async (blockName, invocationInput, requireCertified = false, executionConnection) => {
|
|
3108
|
+
const executeCertifiedBlockByNameForAgent = async (blockName, invocationInput, requireCertified = false, executionConnection, executionConnectionName) => {
|
|
3084
3109
|
const manifest = buildManifest({ projectRoot });
|
|
3085
3110
|
const block = manifest.blocks[blockName];
|
|
3086
3111
|
if (!block) {
|
|
@@ -3095,7 +3120,7 @@ export async function startLocalServer(opts) {
|
|
|
3095
3120
|
path: block.filePath,
|
|
3096
3121
|
domain: block.domain,
|
|
3097
3122
|
chartType: block.chartType,
|
|
3098
|
-
}, invocationInput, executionConnection);
|
|
3123
|
+
}, invocationInput, executionConnection, executionConnectionName);
|
|
3099
3124
|
return {
|
|
3100
3125
|
...result,
|
|
3101
3126
|
dqlArtifact: {
|
|
@@ -3114,17 +3139,17 @@ export async function startLocalServer(opts) {
|
|
|
3114
3139
|
},
|
|
3115
3140
|
};
|
|
3116
3141
|
};
|
|
3117
|
-
const executeCertifiedBlockForAgent = async (node, invocationInput, executionConnection) => {
|
|
3142
|
+
const executeCertifiedBlockForAgent = async (node, invocationInput, executionConnection, executionConnectionName) => {
|
|
3118
3143
|
if (node.kind !== 'block') {
|
|
3119
3144
|
throw new Error(`Certified ${node.kind} "${node.name}" is a navigation artifact and cannot be executed as a block.`);
|
|
3120
3145
|
}
|
|
3121
|
-
return executeCertifiedBlockByNameForAgent(node.name || node.nodeId.replace(/^block:/, ''), invocationInput, false, executionConnection);
|
|
3146
|
+
return executeCertifiedBlockByNameForAgent(node.name || node.nodeId.replace(/^block:/, ''), invocationInput, false, executionConnection, executionConnectionName);
|
|
3122
3147
|
};
|
|
3123
3148
|
// Secondary agent surfaces use this compatibility callback. Delegate to the
|
|
3124
3149
|
// same artifact-first path as Ask so research/app/notebook execution cannot
|
|
3125
3150
|
// silently reintroduce a raw-SQL result followed by a different DQL artifact.
|
|
3126
3151
|
const executeGeneratedSqlForAgent = async (sql, artifact) => executeGeneratedArtifactForAgent(artifact?.name ?? 'AI-generated query', sql, artifact);
|
|
3127
|
-
const executeArtifactReferenceForAgent = async (artifact, question, executionConnection) => {
|
|
3152
|
+
const executeArtifactReferenceForAgent = async (artifact, question, executionConnection, executionConnectionName) => {
|
|
3128
3153
|
const invocation = prepareBlockInvocation({
|
|
3129
3154
|
source: artifact.source,
|
|
3130
3155
|
parameters: artifact.parameterValues,
|
|
@@ -3139,7 +3164,7 @@ export async function startLocalServer(opts) {
|
|
|
3139
3164
|
question,
|
|
3140
3165
|
parameters: invocation.values,
|
|
3141
3166
|
rowLimit: artifact.limit ?? 200,
|
|
3142
|
-
}, executionConnection);
|
|
3167
|
+
}, executionConnection, executionConnectionName);
|
|
3143
3168
|
return {
|
|
3144
3169
|
...result,
|
|
3145
3170
|
dqlArtifact: {
|
|
@@ -3151,9 +3176,9 @@ export async function startLocalServer(opts) {
|
|
|
3151
3176
|
},
|
|
3152
3177
|
};
|
|
3153
3178
|
};
|
|
3154
|
-
const executeGeneratedArtifactForAgent = async (question, sql, seed, executionConnection) => {
|
|
3179
|
+
const executeGeneratedArtifactForAgent = async (question, sql, seed, executionConnection, executionConnectionName) => {
|
|
3155
3180
|
const artifact = generatedSqlArtifactContract(question, sql, seed);
|
|
3156
|
-
return executeArtifactReferenceForAgent({ ...artifact, limit: seed?.limit ?? artifact.limit ?? 200 }, question, executionConnection);
|
|
3181
|
+
return executeArtifactReferenceForAgent({ ...artifact, limit: seed?.limit ?? artifact.limit ?? 200 }, question, executionConnection, executionConnectionName);
|
|
3157
3182
|
};
|
|
3158
3183
|
/**
|
|
3159
3184
|
* EXP-001: execution host for the deliberately narrow non-governed lane.
|
|
@@ -3277,7 +3302,7 @@ export async function startLocalServer(opts) {
|
|
|
3277
3302
|
const activeScope = schemaConnection
|
|
3278
3303
|
? optionalActiveConnectionMetadataScope(projectRoot, projectConfig, schemaConnection, executionConnectionName ?? projectConfig.defaultConnectionName ?? 'default')
|
|
3279
3304
|
: null;
|
|
3280
|
-
const activeRuntimeSnapshot = latestRuntimeSchemaSnapshotForProject(projectRoot);
|
|
3305
|
+
const activeRuntimeSnapshot = latestRuntimeSchemaSnapshotForProject(projectRoot, executionConnectionName);
|
|
3281
3306
|
const hasActivatedMetadataGeneration = Boolean(activeScope
|
|
3282
3307
|
&& activeRuntimeSnapshot?.scopeFingerprint === activeScope.scopeFingerprint
|
|
3283
3308
|
&& activeRuntimeSnapshot.status !== 'stale');
|
|
@@ -3289,9 +3314,6 @@ export async function startLocalServer(opts) {
|
|
|
3289
3314
|
// row value must not turn a warm Ask into an information_schema scan over
|
|
3290
3315
|
// thousands of enterprise tables; only field-scoped value probes are live.
|
|
3291
3316
|
const enriched = await enrichAgentSchemaContextWithValueMatches(question, catalogContext, executor, schemaConnection, valueGrounding.searchSafeColumns);
|
|
3292
|
-
if (!hasActivatedMetadataGeneration) {
|
|
3293
|
-
recordAgentRuntimeSchemaSnapshot(projectRoot, catalogContext, 'catalog runtime schema');
|
|
3294
|
-
}
|
|
3295
3317
|
return enriched;
|
|
3296
3318
|
}
|
|
3297
3319
|
// An activated, scope-qualified warehouse generation is the complete warm
|
|
@@ -3307,7 +3329,7 @@ export async function startLocalServer(opts) {
|
|
|
3307
3329
|
const enriched = valueGrounding.mode === 'safe_automatic'
|
|
3308
3330
|
? await enrichAgentSchemaContextWithValueMatches(question, schemaContext.ranked, executor, schemaConnection, valueGrounding.searchSafeColumns)
|
|
3309
3331
|
: schemaContext.ranked;
|
|
3310
|
-
recordAgentRuntimeSchemaSnapshot(projectRoot, schemaContext.snapshot, 'question-scoped information_schema search');
|
|
3332
|
+
recordAgentRuntimeSchemaSnapshot(projectRoot, schemaContext.snapshot, 'question-scoped information_schema search', executionConnectionName);
|
|
3311
3333
|
return enriched;
|
|
3312
3334
|
}
|
|
3313
3335
|
catch {
|
|
@@ -6519,6 +6541,12 @@ export async function startLocalServer(opts) {
|
|
|
6519
6541
|
res.end(serializeJSON({ ok: true }));
|
|
6520
6542
|
return;
|
|
6521
6543
|
}
|
|
6544
|
+
if (req.method === 'DELETE' && !action) {
|
|
6545
|
+
store.deleteThread(threadId);
|
|
6546
|
+
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
6547
|
+
res.end(serializeJSON({ ok: true }));
|
|
6548
|
+
return;
|
|
6549
|
+
}
|
|
6522
6550
|
// Explicit promotion — the ONLY path from conversation into durable
|
|
6523
6551
|
// memory ("remember this"). Deliberate user act, tagged for audit.
|
|
6524
6552
|
if (req.method === 'POST' && action === 'promote') {
|
|
@@ -9884,7 +9912,7 @@ export async function startLocalServer(opts) {
|
|
|
9884
9912
|
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
9885
9913
|
res.end(serializeJSON({
|
|
9886
9914
|
scope,
|
|
9887
|
-
status: warehouseMetadataStatus(projectRoot, scope.scopeFingerprint),
|
|
9915
|
+
status: warehouseMetadataStatus(projectRoot, scope.scopeFingerprint, connectionId),
|
|
9888
9916
|
}));
|
|
9889
9917
|
}
|
|
9890
9918
|
catch (error) {
|
|
@@ -9904,7 +9932,7 @@ export async function startLocalServer(opts) {
|
|
|
9904
9932
|
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
9905
9933
|
res.end(serializeJSON({
|
|
9906
9934
|
scope,
|
|
9907
|
-
status: warehouseMetadataStatus(projectRoot, scope.scopeFingerprint),
|
|
9935
|
+
status: warehouseMetadataStatus(projectRoot, scope.scopeFingerprint, connectionId),
|
|
9908
9936
|
}));
|
|
9909
9937
|
}
|
|
9910
9938
|
catch (error) {
|
|
@@ -9933,7 +9961,7 @@ export async function startLocalServer(opts) {
|
|
|
9933
9961
|
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
9934
9962
|
res.end(serializeJSON({
|
|
9935
9963
|
scope: synced.scope,
|
|
9936
|
-
status: warehouseMetadataStatus(projectRoot, synced.scope.scopeFingerprint),
|
|
9964
|
+
status: warehouseMetadataStatus(projectRoot, synced.scope.scopeFingerprint, connectionId),
|
|
9937
9965
|
}));
|
|
9938
9966
|
}
|
|
9939
9967
|
catch (error) {
|
|
@@ -9959,7 +9987,7 @@ export async function startLocalServer(opts) {
|
|
|
9959
9987
|
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
9960
9988
|
res.end(serializeJSON({
|
|
9961
9989
|
scope: synced.scope,
|
|
9962
|
-
status: warehouseMetadataStatus(projectRoot, synced.scope.scopeFingerprint),
|
|
9990
|
+
status: warehouseMetadataStatus(projectRoot, synced.scope.scopeFingerprint, connectionId),
|
|
9963
9991
|
}));
|
|
9964
9992
|
}
|
|
9965
9993
|
catch (error) {
|
|
@@ -9996,7 +10024,7 @@ export async function startLocalServer(opts) {
|
|
|
9996
10024
|
connectorStatus,
|
|
9997
10025
|
metadataScope,
|
|
9998
10026
|
metadataStatus: metadataScope
|
|
9999
|
-
? warehouseMetadataStatus(projectRoot, metadataScope.scopeFingerprint)
|
|
10027
|
+
? warehouseMetadataStatus(projectRoot, metadataScope.scopeFingerprint, defaultKey)
|
|
10000
10028
|
: warehouseMetadataStatus(projectRoot),
|
|
10001
10029
|
}));
|
|
10002
10030
|
return;
|
|
@@ -12524,7 +12552,11 @@ table: ${table}${tagList}
|
|
|
12524
12552
|
return;
|
|
12525
12553
|
}
|
|
12526
12554
|
const content = readFileSync(filePath);
|
|
12527
|
-
res.writeHead(200, {
|
|
12555
|
+
res.writeHead(200, {
|
|
12556
|
+
'Content-Type': contentTypeFor(filePath),
|
|
12557
|
+
'Cache-Control': staticResponseCacheControl(filePath),
|
|
12558
|
+
'Content-Length': content.byteLength,
|
|
12559
|
+
});
|
|
12528
12560
|
res.end(content);
|
|
12529
12561
|
})().catch((error) => {
|
|
12530
12562
|
// API-007/E2E-014: no rejected request promise may terminate the local
|
|
@@ -13480,10 +13512,10 @@ export function compileBlockStudioManifest(projectRoot, projectConfig = loadProj
|
|
|
13480
13512
|
_lineageCache.delete(projectRoot);
|
|
13481
13513
|
return manifest;
|
|
13482
13514
|
}
|
|
13483
|
-
async function refreshLocalMetadataCatalog(projectRoot, manifest, semanticLayer) {
|
|
13515
|
+
async function refreshLocalMetadataCatalog(projectRoot, manifest, semanticLayer, force = true) {
|
|
13484
13516
|
try {
|
|
13485
13517
|
await ensureMetadataCatalogFresh(projectRoot, {
|
|
13486
|
-
force
|
|
13518
|
+
force,
|
|
13487
13519
|
...(manifest ? { manifest } : {}),
|
|
13488
13520
|
...(semanticLayer ? { semanticLayer } : {}),
|
|
13489
13521
|
});
|
|
@@ -15691,6 +15723,16 @@ function contentTypeFor(filePath) {
|
|
|
15691
15723
|
return 'text/plain; charset=utf-8';
|
|
15692
15724
|
}
|
|
15693
15725
|
}
|
|
15726
|
+
export function staticResponseCacheControl(filePath) {
|
|
15727
|
+
// Vite fingerprints every generated asset filename, so a new DQL build gets
|
|
15728
|
+
// a new URL and the previous file is safe to retain indefinitely. Keep the
|
|
15729
|
+
// HTML shell revalidated so it can point at the current asset hashes.
|
|
15730
|
+
if (extname(filePath).toLowerCase() === '.html')
|
|
15731
|
+
return 'no-cache';
|
|
15732
|
+
return filePath.split(sep).includes('assets')
|
|
15733
|
+
? 'public, max-age=31536000, immutable'
|
|
15734
|
+
: 'no-cache';
|
|
15735
|
+
}
|
|
15694
15736
|
function listProjectFiles(projectRoot) {
|
|
15695
15737
|
const allowed = new Set(['.dql', '.sql', '.md', '.json', '.csv', '.yaml', '.yml', '.dqlnb']);
|
|
15696
15738
|
const files = [];
|
|
@@ -16132,11 +16174,11 @@ function parseSemanticBlockConfig(source) {
|
|
|
16132
16174
|
limit: limitMatch ? Number.parseInt(limitMatch[1], 10) : undefined,
|
|
16133
16175
|
};
|
|
16134
16176
|
}
|
|
16135
|
-
export async function resolveSemanticTableMapping(executor, connection, semanticLayer, projectRoot) {
|
|
16177
|
+
export async function resolveSemanticTableMapping(executor, connection, semanticLayer, projectRoot, connectionId) {
|
|
16136
16178
|
if (!semanticLayer)
|
|
16137
16179
|
return undefined;
|
|
16138
16180
|
if (projectRoot) {
|
|
16139
|
-
const snapshot = latestRuntimeSchemaSnapshotForProject(projectRoot);
|
|
16181
|
+
const snapshot = latestRuntimeSchemaSnapshotForProject(projectRoot, connectionId);
|
|
16140
16182
|
if (snapshot?.scopeFingerprint && snapshot.tables.length) {
|
|
16141
16183
|
return buildSemanticTableMapping(semanticLayer, snapshot.tables.map((table) => ({
|
|
16142
16184
|
table_catalog: table.catalogOrDatabase,
|
|
@@ -16158,16 +16200,30 @@ export async function resolveSemanticTableMapping(executor, connection, semantic
|
|
|
16158
16200
|
}
|
|
16159
16201
|
}
|
|
16160
16202
|
export function buildSemanticTableMapping(semanticLayer, rows) {
|
|
16161
|
-
const
|
|
16162
|
-
|
|
16203
|
+
const normalizeIdentifierPart = (value) => value
|
|
16204
|
+
.trim()
|
|
16205
|
+
.replace(/^["'`\[]|["'`\]]$/g, '')
|
|
16206
|
+
.toLowerCase();
|
|
16207
|
+
const normalizeRelation = (value) => value
|
|
16208
|
+
.split('.')
|
|
16209
|
+
.map(normalizeIdentifierPart)
|
|
16210
|
+
.filter(Boolean)
|
|
16211
|
+
.join('.');
|
|
16212
|
+
const candidates = [];
|
|
16163
16213
|
for (const row of rows) {
|
|
16214
|
+
const catalog = String(row['table_catalog'] ?? '');
|
|
16164
16215
|
const schema = String(row['table_schema'] ?? '');
|
|
16165
16216
|
const name = String(row['table_name'] ?? '');
|
|
16166
|
-
const relation = typeof row['table_relation'] === 'string'
|
|
16217
|
+
const relation = typeof row['table_relation'] === 'string' && row['table_relation'].trim()
|
|
16218
|
+
? row['table_relation']
|
|
16219
|
+
: [catalog, schema, name].filter(Boolean).join('.');
|
|
16167
16220
|
if (!name)
|
|
16168
16221
|
continue;
|
|
16169
|
-
|
|
16170
|
-
|
|
16222
|
+
candidates.push({
|
|
16223
|
+
name: normalizeIdentifierPart(name),
|
|
16224
|
+
relation,
|
|
16225
|
+
normalizedRelation: normalizeRelation(relation),
|
|
16226
|
+
});
|
|
16171
16227
|
}
|
|
16172
16228
|
const tableMapping = {};
|
|
16173
16229
|
const allSemanticTables = new Set();
|
|
@@ -16182,9 +16238,19 @@ export function buildSemanticTableMapping(semanticLayer, rows) {
|
|
|
16182
16238
|
for (const semTable of allSemanticTables) {
|
|
16183
16239
|
if (!semTable)
|
|
16184
16240
|
continue;
|
|
16185
|
-
|
|
16186
|
-
|
|
16187
|
-
|
|
16241
|
+
const normalizedSemantic = normalizeRelation(semTable);
|
|
16242
|
+
const semanticLeaf = normalizedSemantic.split('.').at(-1);
|
|
16243
|
+
if (!semanticLeaf)
|
|
16244
|
+
continue;
|
|
16245
|
+
const qualifiedMatches = candidates.filter((candidate) => candidate.normalizedRelation === normalizedSemantic
|
|
16246
|
+
|| candidate.normalizedRelation.endsWith(`.${normalizedSemantic}`));
|
|
16247
|
+
const leafMatches = candidates.filter((candidate) => candidate.name === semanticLeaf);
|
|
16248
|
+
const matches = qualifiedMatches.length > 0 ? qualifiedMatches : leafMatches;
|
|
16249
|
+
// Never guess when the same semantic leaf exists in several schemas. A
|
|
16250
|
+
// qualified semantic relation can disambiguate; otherwise the semantic
|
|
16251
|
+
// runtime must surface the modeling gap instead of executing the wrong one.
|
|
16252
|
+
if (matches.length === 1)
|
|
16253
|
+
tableMapping[semTable] = matches[0].relation;
|
|
16188
16254
|
}
|
|
16189
16255
|
return Object.keys(tableMapping).length > 0 ? tableMapping : undefined;
|
|
16190
16256
|
}
|
|
@@ -21433,11 +21499,36 @@ export function runtimeSnapshotStale(projectRoot, maxAgeMs = RUNTIME_SNAPSHOT_MA
|
|
|
21433
21499
|
return false;
|
|
21434
21500
|
}
|
|
21435
21501
|
}
|
|
21436
|
-
|
|
21502
|
+
/**
|
|
21503
|
+
* Resolve only metadata captured for the connection executing this Ask run.
|
|
21504
|
+
* Returning an explicit empty snapshot is a correctness boundary: callers pass
|
|
21505
|
+
* it into the context builder so it cannot silently fall back to another
|
|
21506
|
+
* connection's project-global runtime FTS rows.
|
|
21507
|
+
*/
|
|
21508
|
+
export function runtimeSchemaSnapshotForAgentConnection(projectRoot, connectionId, expectedScopeFingerprint) {
|
|
21509
|
+
const snapshot = latestRuntimeSchemaSnapshotForProject(projectRoot, connectionId);
|
|
21510
|
+
const current = Boolean(snapshot
|
|
21511
|
+
&& snapshot.status !== 'stale'
|
|
21512
|
+
&& (!expectedScopeFingerprint
|
|
21513
|
+
|| !snapshot.scopeFingerprint
|
|
21514
|
+
|| snapshot.scopeFingerprint === expectedScopeFingerprint));
|
|
21515
|
+
return current
|
|
21516
|
+
? snapshot
|
|
21517
|
+
: {
|
|
21518
|
+
version: 1,
|
|
21519
|
+
connectionId,
|
|
21520
|
+
status: 'partial',
|
|
21521
|
+
source: 'selected connection has no current runtime metadata',
|
|
21522
|
+
tables: [],
|
|
21523
|
+
};
|
|
21524
|
+
}
|
|
21525
|
+
function recordAgentRuntimeSchemaSnapshot(projectRoot, schemaContext, source, connectionId) {
|
|
21437
21526
|
if (schemaContext.length === 0)
|
|
21438
21527
|
return;
|
|
21439
21528
|
try {
|
|
21440
21529
|
recordRuntimeSchemaSnapshot(projectRoot, {
|
|
21530
|
+
...(connectionId ? { connectionId } : {}),
|
|
21531
|
+
status: 'partial',
|
|
21441
21532
|
source,
|
|
21442
21533
|
tables: schemaContext.map((table) => ({
|
|
21443
21534
|
relation: table.relation,
|