@duckcodeailabs/dql-agent 1.12.2 → 1.12.4
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/agent-run-engine.d.ts +9 -0
- package/dist/agent-run-engine.d.ts.map +1 -1
- package/dist/agent-run-engine.js +50 -3
- package/dist/agent-run-engine.js.map +1 -1
- package/dist/agent-run-gates.d.ts.map +1 -1
- package/dist/agent-run-gates.js +17 -2
- package/dist/agent-run-gates.js.map +1 -1
- package/dist/analytical-error.d.ts +95 -0
- package/dist/analytical-error.d.ts.map +1 -0
- package/dist/analytical-error.js +116 -0
- package/dist/analytical-error.js.map +1 -0
- package/dist/analytical-failure-repair.d.ts.map +1 -1
- package/dist/analytical-failure-repair.js +11 -0
- package/dist/analytical-failure-repair.js.map +1 -1
- package/dist/answer-loop.d.ts +23 -0
- package/dist/answer-loop.d.ts.map +1 -1
- package/dist/answer-loop.js +77 -6
- package/dist/answer-loop.js.map +1 -1
- package/dist/conversation/session-store.d.ts +14 -0
- package/dist/conversation/session-store.d.ts.map +1 -1
- package/dist/conversation/session-store.js +28 -7
- package/dist/conversation/session-store.js.map +1 -1
- package/dist/conversation/snapshot.d.ts +12 -0
- package/dist/conversation/snapshot.d.ts.map +1 -1
- package/dist/conversation/snapshot.js +68 -12
- package/dist/conversation/snapshot.js.map +1 -1
- package/dist/conversation/turn-trust.d.ts +64 -0
- package/dist/conversation/turn-trust.d.ts.map +1 -0
- package/dist/conversation/turn-trust.js +73 -0
- package/dist/conversation/turn-trust.js.map +1 -0
- package/dist/grounding/context-ledger.js +1 -1
- package/dist/grounding/context-ledger.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/intent-controller.d.ts +3 -1
- package/dist/intent-controller.d.ts.map +1 -1
- package/dist/intent-controller.js +29 -0
- package/dist/intent-controller.js.map +1 -1
- package/dist/metadata/catalog.d.ts +20 -3
- package/dist/metadata/catalog.d.ts.map +1 -1
- package/dist/metadata/catalog.js +92 -13
- package/dist/metadata/catalog.js.map +1 -1
- package/dist/metadata/sql-grounding.d.ts +8 -0
- package/dist/metadata/sql-grounding.d.ts.map +1 -1
- package/dist/metadata/sql-grounding.js +30 -0
- package/dist/metadata/sql-grounding.js.map +1 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +17 -1
- package/dist/router.js.map +1 -1
- package/package.json +4 -4
package/dist/metadata/catalog.js
CHANGED
|
@@ -516,6 +516,7 @@ export async function buildLocalContextPack(projectRoot, request) {
|
|
|
516
516
|
const runtimeCatalog = openMetadataCatalog(projectRoot);
|
|
517
517
|
try {
|
|
518
518
|
const mode = request.mode ?? 'question';
|
|
519
|
+
const includeDraftBlocks = allowsDraftBlockRetrieval(request);
|
|
519
520
|
const followUp = normalizeFollowUpContext(request.followUp);
|
|
520
521
|
const questionPlan = buildAnalysisQuestionPlan(request.question, followUp ?? undefined);
|
|
521
522
|
if (questionPlan.requestedShape.filters.length > 0) {
|
|
@@ -542,7 +543,18 @@ export async function buildLocalContextPack(projectRoot, request) {
|
|
|
542
543
|
&& request.conversationTopicRelation !== 'shift'
|
|
543
544
|
? runtimeCatalog.getContextPack(request.priorContextPackId)
|
|
544
545
|
: null;
|
|
545
|
-
const
|
|
546
|
+
const runtimeSchemaIdentityMatches = Boolean((priorPack?.freshness.runtimeSchemaConnectionId ?? undefined)
|
|
547
|
+
=== (request.runtimeSchemaSnapshot?.connectionId ?? undefined)
|
|
548
|
+
&& (priorPack?.freshness.runtimeSchemaScopeFingerprint ?? undefined)
|
|
549
|
+
=== (request.runtimeSchemaSnapshot?.scopeFingerprint ?? undefined)
|
|
550
|
+
&& (priorPack?.freshness.runtimeSchemaGenerationId ?? undefined)
|
|
551
|
+
=== (request.runtimeSchemaSnapshot?.generationId ?? undefined)
|
|
552
|
+
&& (priorPack?.freshness.runtimeSchemaCapturedAt ?? undefined)
|
|
553
|
+
=== (request.runtimeSchemaSnapshot?.capturedAt ?? undefined));
|
|
554
|
+
const priorPackFresh = Boolean(priorPack
|
|
555
|
+
&& priorPack.freshness.fingerprint === catalog.state('fingerprint')
|
|
556
|
+
&& runtimeSchemaIdentityMatches
|
|
557
|
+
&& (includeDraftBlocks || !priorPack.objects.some(isUncertifiedDqlBlock)));
|
|
546
558
|
if (priorPack
|
|
547
559
|
&& priorPackFresh
|
|
548
560
|
&& request.conversationTopicRelation === 'refinement'
|
|
@@ -562,6 +574,18 @@ export async function buildLocalContextPack(projectRoot, request) {
|
|
|
562
574
|
catalogPath: snapshotPath,
|
|
563
575
|
builtAt: catalog.state('built_at'),
|
|
564
576
|
fingerprint: catalog.state('fingerprint'),
|
|
577
|
+
...(request.runtimeSchemaSnapshot?.connectionId
|
|
578
|
+
? { runtimeSchemaConnectionId: request.runtimeSchemaSnapshot.connectionId }
|
|
579
|
+
: {}),
|
|
580
|
+
...(request.runtimeSchemaSnapshot?.scopeFingerprint
|
|
581
|
+
? { runtimeSchemaScopeFingerprint: request.runtimeSchemaSnapshot.scopeFingerprint }
|
|
582
|
+
: {}),
|
|
583
|
+
...(request.runtimeSchemaSnapshot?.generationId
|
|
584
|
+
? { runtimeSchemaGenerationId: request.runtimeSchemaSnapshot.generationId }
|
|
585
|
+
: {}),
|
|
586
|
+
...(request.runtimeSchemaSnapshot?.capturedAt
|
|
587
|
+
? { runtimeSchemaCapturedAt: request.runtimeSchemaSnapshot.capturedAt }
|
|
588
|
+
: {}),
|
|
565
589
|
},
|
|
566
590
|
};
|
|
567
591
|
delete reusedPayload.id;
|
|
@@ -599,7 +623,8 @@ export async function buildLocalContextPack(projectRoot, request) {
|
|
|
599
623
|
// Skill guidance is injected only through selectContextPackSkills below.
|
|
600
624
|
// Leaving it in generic FTS results would bypass status/domain/area/exclusion
|
|
601
625
|
// eligibility simply because a word in its body matched the question.
|
|
602
|
-
const retrievalObjects = (rows) => scopeObjects(rows).filter((row) => row.objectType !== 'skill'
|
|
626
|
+
const retrievalObjects = (rows) => scopeObjects(rows).filter((row) => row.objectType !== 'skill'
|
|
627
|
+
&& (includeDraftBlocks || !isUncertifiedDqlBlock(row)));
|
|
603
628
|
const snapshotRetrieval = await retrieveMetadataSnapshotCandidates(catalog, {
|
|
604
629
|
question: request.question,
|
|
605
630
|
searchQueries,
|
|
@@ -793,6 +818,18 @@ export async function buildLocalContextPack(projectRoot, request) {
|
|
|
793
818
|
catalogPath: snapshotPath,
|
|
794
819
|
builtAt: catalog.state('built_at'),
|
|
795
820
|
fingerprint: catalog.state('fingerprint'),
|
|
821
|
+
...(request.runtimeSchemaSnapshot?.connectionId
|
|
822
|
+
? { runtimeSchemaConnectionId: request.runtimeSchemaSnapshot.connectionId }
|
|
823
|
+
: {}),
|
|
824
|
+
...(request.runtimeSchemaSnapshot?.scopeFingerprint
|
|
825
|
+
? { runtimeSchemaScopeFingerprint: request.runtimeSchemaSnapshot.scopeFingerprint }
|
|
826
|
+
: {}),
|
|
827
|
+
...(request.runtimeSchemaSnapshot?.generationId
|
|
828
|
+
? { runtimeSchemaGenerationId: request.runtimeSchemaSnapshot.generationId }
|
|
829
|
+
: {}),
|
|
830
|
+
...(request.runtimeSchemaSnapshot?.capturedAt
|
|
831
|
+
? { runtimeSchemaCapturedAt: request.runtimeSchemaSnapshot.capturedAt }
|
|
832
|
+
: {}),
|
|
796
833
|
},
|
|
797
834
|
};
|
|
798
835
|
const packPayload = { ...payload };
|
|
@@ -916,11 +953,18 @@ export function recordRuntimeSchemaSnapshot(projectRoot, snapshot) {
|
|
|
916
953
|
catalog.close();
|
|
917
954
|
}
|
|
918
955
|
}
|
|
919
|
-
/**
|
|
920
|
-
|
|
956
|
+
/**
|
|
957
|
+
* The most-recent stored live-warehouse schema snapshot for a project.
|
|
958
|
+
*
|
|
959
|
+
* When a connection id is supplied, never fall back to a snapshot captured for
|
|
960
|
+
* another connection. Ask may target a different warehouse connection than the
|
|
961
|
+
* project default, so a project-global "latest" snapshot is not safe evidence
|
|
962
|
+
* for planning or semantic table resolution.
|
|
963
|
+
*/
|
|
964
|
+
export function latestRuntimeSchemaSnapshotForProject(projectRoot, connectionId) {
|
|
921
965
|
const catalog = openMetadataCatalog(projectRoot);
|
|
922
966
|
try {
|
|
923
|
-
return catalog.latestRuntimeSchemaSnapshot();
|
|
967
|
+
return catalog.latestRuntimeSchemaSnapshot(connectionId);
|
|
924
968
|
}
|
|
925
969
|
finally {
|
|
926
970
|
catalog.close();
|
|
@@ -2320,12 +2364,14 @@ export class MetadataCatalog {
|
|
|
2320
2364
|
`);
|
|
2321
2365
|
const txn = this.db.transaction(() => {
|
|
2322
2366
|
insertSnapshot.run(id, cleanSnapshot.source ?? null, JSON.stringify(cleanSnapshot), capturedAt);
|
|
2323
|
-
//
|
|
2324
|
-
//
|
|
2367
|
+
// Preserve a bounded history across multiple named connections. Ask
|
|
2368
|
+
// resolves the latest snapshot for its selected connection, so retaining
|
|
2369
|
+
// only five project-global rows could evict a valid but less-recent
|
|
2370
|
+
// warehouse as soon as another connection was refreshed repeatedly.
|
|
2325
2371
|
this.db.prepare(`
|
|
2326
2372
|
DELETE FROM runtime_schema_snapshots
|
|
2327
2373
|
WHERE id NOT IN (
|
|
2328
|
-
SELECT id FROM runtime_schema_snapshots ORDER BY captured_at DESC LIMIT
|
|
2374
|
+
SELECT id FROM runtime_schema_snapshots ORDER BY captured_at DESC LIMIT 50
|
|
2329
2375
|
)
|
|
2330
2376
|
`).run();
|
|
2331
2377
|
this.db.prepare('DELETE FROM runtime_value_fts').run();
|
|
@@ -2376,14 +2422,21 @@ export class MetadataCatalog {
|
|
|
2376
2422
|
const rows = [...andRows, ...runMatch(match.or).filter((row) => !seen.has(row.object_key))].slice(0, limit);
|
|
2377
2423
|
return rows.map(rowToObject);
|
|
2378
2424
|
}
|
|
2379
|
-
latestRuntimeSchemaSnapshot() {
|
|
2380
|
-
const
|
|
2425
|
+
latestRuntimeSchemaSnapshot(connectionId) {
|
|
2426
|
+
const rows = this.db.prepare(`
|
|
2381
2427
|
SELECT payload_json
|
|
2382
2428
|
FROM runtime_schema_snapshots
|
|
2383
2429
|
ORDER BY captured_at DESC
|
|
2384
|
-
LIMIT
|
|
2385
|
-
`).
|
|
2386
|
-
|
|
2430
|
+
LIMIT 50
|
|
2431
|
+
`).all();
|
|
2432
|
+
for (const row of rows) {
|
|
2433
|
+
const snapshot = safeRuntimeSchemaSnapshot(safeJson(row.payload_json, null));
|
|
2434
|
+
if (!snapshot)
|
|
2435
|
+
continue;
|
|
2436
|
+
if (!connectionId || snapshot.connectionId === connectionId)
|
|
2437
|
+
return snapshot;
|
|
2438
|
+
}
|
|
2439
|
+
return null;
|
|
2387
2440
|
}
|
|
2388
2441
|
getContextPack(id) {
|
|
2389
2442
|
const row = this.db.prepare('SELECT payload_json FROM context_packs WHERE id = ?').get(id);
|
|
@@ -4354,6 +4407,18 @@ function findExactCertifiedObject(question, intent, objects) {
|
|
|
4354
4407
|
function isCertifiedMetadataObject(object) {
|
|
4355
4408
|
return object.status === 'certified' || object.status === 'approved' || object.payload?.certification === 'certified';
|
|
4356
4409
|
}
|
|
4410
|
+
function isUncertifiedDqlBlock(object) {
|
|
4411
|
+
return object.objectType === 'dql_block' && !isCertifiedMetadataObject(object);
|
|
4412
|
+
}
|
|
4413
|
+
function allowsDraftBlockRetrieval(request) {
|
|
4414
|
+
if (request.includeDraftBlocks === true)
|
|
4415
|
+
return true;
|
|
4416
|
+
if (request.surface === 'block')
|
|
4417
|
+
return true;
|
|
4418
|
+
if (request.mode && request.mode !== 'question')
|
|
4419
|
+
return true;
|
|
4420
|
+
return /\b(?:draft|review|edit|certif(?:y|ied|ication)|block studio|this block)\b/i.test(request.question);
|
|
4421
|
+
}
|
|
4357
4422
|
function objectNameInQuestion(question, object) {
|
|
4358
4423
|
const q = normalizeSearchText(question);
|
|
4359
4424
|
const name = normalizeSearchText(object.name);
|
|
@@ -5770,12 +5835,26 @@ export function isFilterOnlyRefinement(prior, next) {
|
|
|
5770
5835
|
return false;
|
|
5771
5836
|
const priorShape = prior.requestedShape;
|
|
5772
5837
|
const nextShape = next.requestedShape;
|
|
5838
|
+
// Every check below is a set comparison, so two plans the planner extracted
|
|
5839
|
+
// NOTHING from compared equal and were declared "the same query with
|
|
5840
|
+
// different filters". Two unrelated questions the vocabulary does not cover
|
|
5841
|
+
// then reused the earlier context pack wholesale — including its committed
|
|
5842
|
+
// route decision. Reuse requires actual evidence of sameness on both sides.
|
|
5843
|
+
if (!hasPlanSignal(prior) || !hasPlanSignal(next))
|
|
5844
|
+
return false;
|
|
5773
5845
|
return setEqual(priorShape.measures, nextShape.measures)
|
|
5774
5846
|
&& setEqual(priorShape.dimensions, nextShape.dimensions)
|
|
5775
5847
|
&& setEqual(priorShape.requiredOutputs, nextShape.requiredOutputs)
|
|
5776
5848
|
&& (priorShape.grain ?? '') === (nextShape.grain ?? '')
|
|
5777
5849
|
&& setEqual(prior.entities.map((entity) => entity.text.toLowerCase()), next.entities.map((entity) => entity.text.toLowerCase()));
|
|
5778
5850
|
}
|
|
5851
|
+
/** Did the planner actually read anything out of this question? */
|
|
5852
|
+
function hasPlanSignal(plan) {
|
|
5853
|
+
return plan.requestedShape.measures.length > 0
|
|
5854
|
+
|| plan.requestedShape.dimensions.length > 0
|
|
5855
|
+
|| plan.requestedShape.requiredOutputs.length > 0
|
|
5856
|
+
|| plan.entities.length > 0;
|
|
5857
|
+
}
|
|
5779
5858
|
function setEqual(a, b) {
|
|
5780
5859
|
const setA = new Set(a.map((value) => value.toLowerCase()));
|
|
5781
5860
|
const setB = new Set(b.map((value) => value.toLowerCase()));
|