@devflow-tools/context-engine 0.16.34 → 0.17.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/channel-query-planner.d.ts +9 -0
- package/dist/channel-query-planner.d.ts.map +1 -0
- package/dist/channel-query-planner.js +92 -0
- package/dist/channel-query-planner.js.map +1 -0
- package/dist/context-budget-allocator.d.ts +19 -0
- package/dist/context-budget-allocator.d.ts.map +1 -0
- package/dist/context-budget-allocator.js +35 -0
- package/dist/context-budget-allocator.js.map +1 -0
- package/dist/context-engine.d.ts.map +1 -1
- package/dist/context-engine.js +107 -12
- package/dist/context-engine.js.map +1 -1
- package/dist/create-engines.d.ts.map +1 -1
- package/dist/create-engines.js +17 -5
- package/dist/create-engines.js.map +1 -1
- package/dist/graph-adapter.d.ts +2 -0
- package/dist/graph-adapter.d.ts.map +1 -1
- package/dist/graph-adapter.js +14 -1
- package/dist/graph-adapter.js.map +1 -1
- package/dist/graph-evidence-selector.d.ts +26 -0
- package/dist/graph-evidence-selector.d.ts.map +1 -0
- package/dist/graph-evidence-selector.js +77 -0
- package/dist/graph-evidence-selector.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/indexer-adapter.d.ts.map +1 -1
- package/dist/indexer-adapter.js +7 -1
- package/dist/indexer-adapter.js.map +1 -1
- package/dist/intent-parser.d.ts.map +1 -1
- package/dist/intent-parser.js +11 -9
- package/dist/intent-parser.js.map +1 -1
- package/dist/retrieval-handlers.d.ts +3 -0
- package/dist/retrieval-handlers.d.ts.map +1 -1
- package/dist/retrieval-handlers.js +69 -2
- package/dist/retrieval-handlers.js.map +1 -1
- package/dist/retrieval-ledger.d.ts.map +1 -1
- package/dist/retrieval-ledger.js +60 -4
- package/dist/retrieval-ledger.js.map +1 -1
- package/dist/retrieval-task-plan.d.ts +8 -1
- package/dist/retrieval-task-plan.d.ts.map +1 -1
- package/dist/retrieval-task-plan.js +67 -36
- package/dist/retrieval-task-plan.js.map +1 -1
- package/dist/task-retrieval-orchestrator.d.ts +9 -0
- package/dist/task-retrieval-orchestrator.d.ts.map +1 -1
- package/dist/task-retrieval-orchestrator.js +33 -7
- package/dist/task-retrieval-orchestrator.js.map +1 -1
- package/dist/types.d.ts +4 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -7
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ChannelQueryPlan, ImmutableTaskIntentArtifact } from '@devflow-tools/sdk';
|
|
2
|
+
import type { RetrievalTaskPlan } from './retrieval-task-plan.js';
|
|
3
|
+
export declare function buildChannelQueryPlan(input: {
|
|
4
|
+
artifact: ImmutableTaskIntentArtifact;
|
|
5
|
+
taskPlan: RetrievalTaskPlan;
|
|
6
|
+
expandedTerms?: string;
|
|
7
|
+
generatedBy?: ChannelQueryPlan['generatedBy'];
|
|
8
|
+
}): ChannelQueryPlan;
|
|
9
|
+
//# sourceMappingURL=channel-query-planner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel-query-planner.d.ts","sourceRoot":"","sources":["../src/channel-query-planner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAEhB,2BAA2B,EAG5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,QAAQ,EAAE,2BAA2B,CAAC;IACtC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,gBAAgB,CAAC,aAAa,CAAC,CAAC;CAC/C,GAAG,gBAAgB,CA6CnB"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
export function buildChannelQueryPlan(input) {
|
|
3
|
+
const authoritativeQuery = taskQuery(input.artifact);
|
|
4
|
+
const expanded = boundedQuery(input.expandedTerms);
|
|
5
|
+
const retrievalQuery = expanded ? `${authoritativeQuery} ${expanded}` : authoritativeQuery;
|
|
6
|
+
const code = input.artifact.intent === 'memory'
|
|
7
|
+
? []
|
|
8
|
+
: [{
|
|
9
|
+
query: retrievalQuery,
|
|
10
|
+
targetAnchors: [...input.artifact.targetAnchors],
|
|
11
|
+
symbols: [...input.taskPlan.symbols],
|
|
12
|
+
relationKinds: relationKinds(input.taskPlan),
|
|
13
|
+
maxDepth: input.artifact.targetAnchors.length > 0 ? 1 : 2,
|
|
14
|
+
}];
|
|
15
|
+
const memory = [{
|
|
16
|
+
query: authoritativeQuery,
|
|
17
|
+
scopes: input.artifact.activeSkill ? ['project', 'skill', 'session'] : ['project', 'session'],
|
|
18
|
+
entities: [...input.taskPlan.entities],
|
|
19
|
+
facets: [...input.taskPlan.requiredPolicyFacets],
|
|
20
|
+
requireVerifiedEvidence: true,
|
|
21
|
+
}];
|
|
22
|
+
const knowledge = input.taskPlan.knowledgeNeeds.length > 0
|
|
23
|
+
? input.taskPlan.knowledgeNeeds.map(need => ({
|
|
24
|
+
query: queryForKnowledgeNeed(need, authoritativeQuery),
|
|
25
|
+
requirement: need.required ? 'knowledge_required' : 'knowledge_optional',
|
|
26
|
+
kind: need.kind,
|
|
27
|
+
...(need.entity ? { entity: need.entity } : {}),
|
|
28
|
+
...(need.symbol ? { symbol: need.symbol } : {}),
|
|
29
|
+
...(need.version ? { version: need.version } : {}),
|
|
30
|
+
}))
|
|
31
|
+
: [{
|
|
32
|
+
query: '',
|
|
33
|
+
requirement: 'knowledge_not_required',
|
|
34
|
+
kind: 'overview',
|
|
35
|
+
}];
|
|
36
|
+
const createdAt = input.artifact.createdAt;
|
|
37
|
+
const planBody = {
|
|
38
|
+
identity: input.artifact.identity,
|
|
39
|
+
sourceIntentHash: input.artifact.artifactHash,
|
|
40
|
+
code,
|
|
41
|
+
memory,
|
|
42
|
+
knowledge,
|
|
43
|
+
generatedBy: input.generatedBy ?? (expanded ? 'hybrid' : 'deterministic'),
|
|
44
|
+
createdAt,
|
|
45
|
+
};
|
|
46
|
+
return { ...planBody, planHash: stableHash(planBody) };
|
|
47
|
+
}
|
|
48
|
+
function taskQuery(artifact) {
|
|
49
|
+
const withoutCommand = artifact.command
|
|
50
|
+
? artifact.normalizedPrompt.replace(new RegExp(`^\\/${escapeRegExp(artifact.command)}\\b`, 'iu'), '').trim()
|
|
51
|
+
: artifact.normalizedPrompt;
|
|
52
|
+
return boundedQuery(withoutCommand) || boundedQuery(artifact.rawPrompt) || artifact.action;
|
|
53
|
+
}
|
|
54
|
+
function boundedQuery(value) {
|
|
55
|
+
return value?.normalize('NFKC').replace(/\s+/gu, ' ').trim().slice(0, 2_000) ?? '';
|
|
56
|
+
}
|
|
57
|
+
function relationKinds(plan) {
|
|
58
|
+
const kinds = new Set(['dependency']);
|
|
59
|
+
if (['debug', 'modify', 'analyze'].includes(plan.action))
|
|
60
|
+
kinds.add('caller');
|
|
61
|
+
if (plan.intent === 'performance')
|
|
62
|
+
kinds.add('caller');
|
|
63
|
+
if (plan.action === 'create') {
|
|
64
|
+
kinds.add('route');
|
|
65
|
+
kinds.add('config');
|
|
66
|
+
}
|
|
67
|
+
if (plan.action === 'test')
|
|
68
|
+
kinds.add('test');
|
|
69
|
+
return [...kinds];
|
|
70
|
+
}
|
|
71
|
+
function queryForKnowledgeNeed(need, fallback) {
|
|
72
|
+
return [need.entity, need.symbol, need.kind, need.version].filter(Boolean).join(' ') || fallback;
|
|
73
|
+
}
|
|
74
|
+
function stableHash(value) {
|
|
75
|
+
return createHash('sha256').update(stableJson(value)).digest('hex');
|
|
76
|
+
}
|
|
77
|
+
function stableJson(value) {
|
|
78
|
+
if (value === null || typeof value === 'string' || typeof value === 'boolean')
|
|
79
|
+
return JSON.stringify(value);
|
|
80
|
+
if (typeof value === 'number')
|
|
81
|
+
return Number.isFinite(value) ? JSON.stringify(value) : 'null';
|
|
82
|
+
if (Array.isArray(value))
|
|
83
|
+
return `[${value.map(stableJson).join(',')}]`;
|
|
84
|
+
if (!value || typeof value !== 'object')
|
|
85
|
+
return JSON.stringify(String(value));
|
|
86
|
+
const record = value;
|
|
87
|
+
return `{${Object.keys(record).sort().map(key => `${JSON.stringify(key)}:${stableJson(record[key])}`).join(',')}}`;
|
|
88
|
+
}
|
|
89
|
+
function escapeRegExp(value) {
|
|
90
|
+
return value.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=channel-query-planner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel-query-planner.js","sourceRoot":"","sources":["../src/channel-query-planner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface BudgetedContextCandidate {
|
|
2
|
+
path: string;
|
|
3
|
+
score: number;
|
|
4
|
+
source: 'structural' | 'graph';
|
|
5
|
+
}
|
|
6
|
+
export interface ContextBudgetAllocation {
|
|
7
|
+
selectedPaths: Set<string>;
|
|
8
|
+
rejectedPaths: Set<string>;
|
|
9
|
+
maxFiles: number;
|
|
10
|
+
graphFileLimit: number;
|
|
11
|
+
selectedGraphFiles: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function allocateContextFileBudget(input: {
|
|
14
|
+
requiredPaths: Iterable<string>;
|
|
15
|
+
candidates: BudgetedContextCandidate[];
|
|
16
|
+
tokenBudget: number;
|
|
17
|
+
graphRatio?: number;
|
|
18
|
+
}): ContextBudgetAllocation;
|
|
19
|
+
//# sourceMappingURL=context-budget-allocator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-budget-allocator.d.ts","sourceRoot":"","sources":["../src/context-budget-allocator.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,UAAU,EAAE,wBAAwB,EAAE,CAAC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,uBAAuB,CAqB1B"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export function allocateContextFileBudget(input) {
|
|
2
|
+
const required = new Set(input.requiredPaths);
|
|
3
|
+
const maxFiles = Math.max(required.size, Math.max(5, Math.min(24, Math.floor(input.tokenBudget / 280))));
|
|
4
|
+
const remaining = Math.max(0, maxFiles - required.size);
|
|
5
|
+
const graphFileLimit = Math.min(remaining, Math.max(1, Math.floor(maxFiles * (input.graphRatio ?? 0.2))));
|
|
6
|
+
const structural = dedupe(input.candidates.filter(candidate => candidate.source === 'structural'));
|
|
7
|
+
const graph = dedupe(input.candidates.filter(candidate => candidate.source === 'graph'));
|
|
8
|
+
const selectedPaths = new Set(required);
|
|
9
|
+
for (const candidate of structural) {
|
|
10
|
+
if (selectedPaths.size >= maxFiles)
|
|
11
|
+
break;
|
|
12
|
+
selectedPaths.add(candidate.path);
|
|
13
|
+
}
|
|
14
|
+
let selectedGraphFiles = 0;
|
|
15
|
+
for (const candidate of graph) {
|
|
16
|
+
if (selectedPaths.size >= maxFiles || selectedGraphFiles >= graphFileLimit)
|
|
17
|
+
break;
|
|
18
|
+
if (selectedPaths.has(candidate.path))
|
|
19
|
+
continue;
|
|
20
|
+
selectedPaths.add(candidate.path);
|
|
21
|
+
selectedGraphFiles += 1;
|
|
22
|
+
}
|
|
23
|
+
const rejectedPaths = new Set(input.candidates.map(candidate => candidate.path).filter(path => !selectedPaths.has(path)));
|
|
24
|
+
return { selectedPaths, rejectedPaths, maxFiles, graphFileLimit, selectedGraphFiles };
|
|
25
|
+
}
|
|
26
|
+
function dedupe(candidates) {
|
|
27
|
+
const byPath = new Map();
|
|
28
|
+
for (const candidate of candidates) {
|
|
29
|
+
const existing = byPath.get(candidate.path);
|
|
30
|
+
if (!existing || candidate.score > existing.score)
|
|
31
|
+
byPath.set(candidate.path, candidate);
|
|
32
|
+
}
|
|
33
|
+
return [...byPath.values()].sort((left, right) => right.score - left.score || left.path.localeCompare(right.path));
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=context-budget-allocator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-budget-allocator.js","sourceRoot":"","sources":["../src/context-budget-allocator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-engine.d.ts","sourceRoot":"","sources":["../src/context-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAEb,WAAW,EACX,aAAa,EAOb,sBAAsB,EACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAA0B,MAAM,iCAAiC,CAAC;AAC/F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAwB,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAQzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAU3D,OAAO,KAAK,EAKV,kBAAkB,EAClB,+BAA+B,EAChC,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"context-engine.d.ts","sourceRoot":"","sources":["../src/context-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAEb,WAAW,EACX,aAAa,EAOb,sBAAsB,EACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAA0B,MAAM,iCAAiC,CAAC;AAC/F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAwB,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAQzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAU3D,OAAO,KAAK,EAKV,kBAAkB,EAClB,+BAA+B,EAChC,MAAM,YAAY,CAAC;AA0SpB,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,SAAS,CAAC;IACd,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,eAAe,CAAC;IAC3B,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAoCD,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAAY;IACtB,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,CAAoB;IACrC,OAAO,CAAC,WAAW,CAAC,CAAoB;IACxC,OAAO,CAAC,cAAc,CAAC,CAAiB;gBAE5B,IAAI,EAAE,iBAAiB;IAYnC,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,UAAU,CAAkD;IAE9D,gCAAgC,CAAC,KAAK,EAAE;QAC5C,OAAO,EAAE,sBAAsB,EAAE,CAAC;QAClC,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,cAAc,EAAE,MAAM,CAAC;KACxB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIX,KAAK,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,OAAO,CAAC,yBAAyB;YAoCnB,yBAAyB;IAiCvC,OAAO,CAAC,eAAe;IAKjB,KAAK,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAkRtD,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,+BAA+B,CAAC;YA8nB/F,sBAAsB;IAsWpC,OAAO,CAAC,yBAAyB;YAgBnB,2BAA2B;YA4B3B,6BAA6B;IAkB3C,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,sBAAsB;IAM9B,OAAO,CAAC,2BAA2B;IAOnC,SAAS,IAAI,WAAW;CASzB"}
|
package/dist/context-engine.js
CHANGED
|
@@ -11,6 +11,9 @@ import { reachableCodeGraphNodeIds, sanitizeCodeGraphEdges, } from './graph-edge
|
|
|
11
11
|
import { assembleContextFileRoles } from './context-file-roles.js';
|
|
12
12
|
import { buildTaskContextEnvelope } from './task-retrieval-orchestrator.js';
|
|
13
13
|
import { recordTaskEnvelopeLedger } from './retrieval-ledger.js';
|
|
14
|
+
import { selectGraphEvidence } from './graph-evidence-selector.js';
|
|
15
|
+
import { allocateContextFileBudget } from './context-budget-allocator.js';
|
|
16
|
+
import { emitSemanticControlLog } from '@devflow-tools/telemetry';
|
|
14
17
|
const CG = CGModule.default ?? CGModule;
|
|
15
18
|
const SYMBOL_VECTOR_WARNING = "Symbol vector search is not ready; using CodeGraph/BM25 results. Run `devflow doctor` for details.";
|
|
16
19
|
// ── RRF (Reciprocal Rank Fusion) ─────────────────────────────────
|
|
@@ -317,6 +320,12 @@ export class ContextEngine {
|
|
|
317
320
|
relevantFiles: options.relevantFiles,
|
|
318
321
|
action: taskPlan?.action,
|
|
319
322
|
knowledgeNeeds: taskPlan?.knowledgeNeeds,
|
|
323
|
+
sessionId: options.sessionId,
|
|
324
|
+
executionId: options.executionId,
|
|
325
|
+
requestId: options.requestId,
|
|
326
|
+
turnId: options.turnId,
|
|
327
|
+
intentArtifactHash: options.intentArtifact?.artifactHash,
|
|
328
|
+
queryPlanHash: options.queryPlan?.planHash,
|
|
320
329
|
projectSignals: {
|
|
321
330
|
frameworks,
|
|
322
331
|
languages,
|
|
@@ -622,15 +631,27 @@ export class ContextEngine {
|
|
|
622
631
|
}
|
|
623
632
|
const intent = parseIntent(query);
|
|
624
633
|
const taskType = intent.intent;
|
|
625
|
-
const combinedQuery =
|
|
626
|
-
|
|
634
|
+
const combinedQuery = options?.queryPlan?.code[0]?.query
|
|
635
|
+
?? mergeQueries(query, expandQuery(query), options?.expandedTerms);
|
|
636
|
+
const targetAnchors = options?.intentArtifact?.targetAnchors ?? extractTargetAnchors(query);
|
|
627
637
|
const retrievalTaskPlan = buildRetrievalTaskPlan({
|
|
628
638
|
query,
|
|
629
639
|
parsedIntent: intent,
|
|
630
640
|
targetAnchors,
|
|
631
641
|
activeSkill: options?.activeSkill,
|
|
632
642
|
command: options?.command,
|
|
643
|
+
authoritativeArtifact: options?.intentArtifact,
|
|
633
644
|
});
|
|
645
|
+
const projectRoot = this.cg.getProjectRoot?.() ?? process.cwd();
|
|
646
|
+
const logIdentity = {
|
|
647
|
+
projectRoot,
|
|
648
|
+
sessionId: options?.sessionId,
|
|
649
|
+
turnId: options?.turnId,
|
|
650
|
+
requestId: options?.requestId,
|
|
651
|
+
executionId: options?.executionId,
|
|
652
|
+
intentArtifactHash: options?.intentArtifact?.artifactHash,
|
|
653
|
+
queryPlanHash: options?.queryPlan?.planHash,
|
|
654
|
+
};
|
|
634
655
|
const timing = {};
|
|
635
656
|
const t0 = Date.now();
|
|
636
657
|
const [cgResult, knowledgeResult, memoryHits] = await Promise.all([
|
|
@@ -645,7 +666,10 @@ export class ContextEngine {
|
|
|
645
666
|
}),
|
|
646
667
|
new Promise((_, reject) => setTimeout(() => reject(new Error("buildContext timeout")), 15000)),
|
|
647
668
|
]).catch((err) => {
|
|
648
|
-
|
|
669
|
+
emitSemanticControlLog({
|
|
670
|
+
event: 'context.build.degraded', identity: logIdentity, level: 'warn', timestamp: Date.now(),
|
|
671
|
+
data: { stage: 'codegraph_context', reason: err.message, fallback: 'manual_pipeline' },
|
|
672
|
+
});
|
|
649
673
|
return null;
|
|
650
674
|
})
|
|
651
675
|
: Promise.resolve(null),
|
|
@@ -653,7 +677,10 @@ export class ContextEngine {
|
|
|
653
677
|
this.searchKnowledgeWithStatus(combinedQuery, this.getKnowledgeSearchOptions(combinedQuery, 5, options, retrievalTaskPlan, maxTokens)),
|
|
654
678
|
new Promise((_, reject) => setTimeout(() => reject(new Error("knowledge timeout")), 5000)),
|
|
655
679
|
]).catch((err) => {
|
|
656
|
-
|
|
680
|
+
emitSemanticControlLog({
|
|
681
|
+
event: 'knowledge.search.degraded', identity: logIdentity, level: 'warn', timestamp: Date.now(),
|
|
682
|
+
data: { reason: err.message, fallback: 'knowledge_empty' },
|
|
683
|
+
});
|
|
657
684
|
return { entries: [], warnings: [`knowledge-search-failed: ${err.message}`] };
|
|
658
685
|
}),
|
|
659
686
|
typeof this.memory.search === "function"
|
|
@@ -668,18 +695,23 @@ export class ContextEngine {
|
|
|
668
695
|
}),
|
|
669
696
|
new Promise((_, reject) => setTimeout(() => reject(new Error("memory timeout")), 5000)),
|
|
670
697
|
]).catch((err) => {
|
|
671
|
-
|
|
698
|
+
emitSemanticControlLog({
|
|
699
|
+
event: 'memory.search.completed', identity: logIdentity, level: 'warn', timestamp: Date.now(),
|
|
700
|
+
data: { status: 'degraded', reason: err.message, selected: 0, fallback: 'memory_empty' },
|
|
701
|
+
});
|
|
672
702
|
return [];
|
|
673
703
|
})
|
|
674
704
|
: Promise.resolve([]),
|
|
675
705
|
]);
|
|
676
706
|
timing["1_promise_all"] = Date.now() - t0;
|
|
677
|
-
console.error("[devflow:timing] Promise.all:", timing["1_promise_all"], "ms");
|
|
678
707
|
const knowledgeHits = knowledgeResult.entries;
|
|
679
708
|
if (knowledgeResult.warnings.length > 0)
|
|
680
709
|
warnings.push(...knowledgeResult.warnings);
|
|
681
710
|
if (!cgResult) {
|
|
682
|
-
|
|
711
|
+
emitSemanticControlLog({
|
|
712
|
+
event: 'context.build.degraded', identity: logIdentity, level: 'warn', timestamp: Date.now(),
|
|
713
|
+
data: { stage: 'codegraph_context', reason: 'context_unavailable', fallback: 'manual_pipeline' },
|
|
714
|
+
});
|
|
683
715
|
const result = await this.buildTaskContextLegacy(query, options);
|
|
684
716
|
result._devflow = { fallback: "buildContext-unavailable" };
|
|
685
717
|
return result;
|
|
@@ -691,7 +723,10 @@ export class ContextEngine {
|
|
|
691
723
|
ctx = JSON.parse(cgResult);
|
|
692
724
|
}
|
|
693
725
|
catch {
|
|
694
|
-
|
|
726
|
+
emitSemanticControlLog({
|
|
727
|
+
event: 'context.build.degraded', identity: logIdentity, level: 'warn', timestamp: Date.now(),
|
|
728
|
+
data: { stage: 'codegraph_parse', reason: 'unparseable_context', fallback: 'manual_pipeline' },
|
|
729
|
+
});
|
|
695
730
|
return this.buildTaskContextLegacy(query, options);
|
|
696
731
|
}
|
|
697
732
|
}
|
|
@@ -732,7 +767,6 @@ export class ContextEngine {
|
|
|
732
767
|
}
|
|
733
768
|
}
|
|
734
769
|
}
|
|
735
|
-
console.error("[devflow:timing] Fallback searchNodes loop:", Date.now() - tFallback, "ms");
|
|
736
770
|
timing["2_fallback_loop"] = Date.now() - tFallback;
|
|
737
771
|
const fileFreshnessByPath = new Map();
|
|
738
772
|
if (this.indexer?.ensureFilesCurrent) {
|
|
@@ -770,7 +804,24 @@ export class ContextEngine {
|
|
|
770
804
|
const anchoredEntryPoints = targetAnchors.length > 0
|
|
771
805
|
? originalEntryPoints.filter(entry => fileMatchesTargetAnchor(entry.filePath, targetAnchors))
|
|
772
806
|
: originalEntryPoints;
|
|
773
|
-
const
|
|
807
|
+
const graphSelection = selectGraphEvidence({
|
|
808
|
+
codegraph: this.cg,
|
|
809
|
+
candidates: originalEntryPoints,
|
|
810
|
+
symbols: retrievalTaskPlan.symbols,
|
|
811
|
+
targetAnchors,
|
|
812
|
+
});
|
|
813
|
+
const evidenceEntryPoints = graphSelection.selected.length > 0
|
|
814
|
+
? graphSelection.selected
|
|
815
|
+
: originalEntryPoints;
|
|
816
|
+
const selectedAnchoredEntryPoints = targetAnchors.length > 0
|
|
817
|
+
? evidenceEntryPoints.filter(entry => fileMatchesTargetAnchor(entry.filePath, targetAnchors))
|
|
818
|
+
: evidenceEntryPoints;
|
|
819
|
+
const effectiveEntryPoints = selectedAnchoredEntryPoints.length > 0
|
|
820
|
+
? selectedAnchoredEntryPoints
|
|
821
|
+
: anchoredEntryPoints.length > 0 ? anchoredEntryPoints : evidenceEntryPoints;
|
|
822
|
+
if (graphSelection.ambiguities.length > 0) {
|
|
823
|
+
warnings.push(`codegraph-symbol-ambiguity:${graphSelection.ambiguities.length}`);
|
|
824
|
+
}
|
|
774
825
|
const rootIds = new Set(effectiveEntryPoints.map((ep) => ep.id));
|
|
775
826
|
const reachableNodeIds = reachableCodeGraphNodeIds(rootIds, edgeQuality.accepted);
|
|
776
827
|
const entryFiles = new Set(effectiveEntryPoints.map((entry) => entry.filePath));
|
|
@@ -792,6 +843,7 @@ export class ContextEngine {
|
|
|
792
843
|
const perFileCount = new Map();
|
|
793
844
|
const MAX_SYMBOLS_PER_FILE = 5;
|
|
794
845
|
const optionalCandidates = new Map();
|
|
846
|
+
const graphOptionalPaths = new Set();
|
|
795
847
|
const queryTerms = combinedQuery.split(/\s+/).map(term => term.toLowerCase()).filter(term => term.length >= 3);
|
|
796
848
|
for (const node of allNodes) {
|
|
797
849
|
// Skip file wrappers and import edges — they're not actionable symbols
|
|
@@ -831,6 +883,7 @@ export class ContextEngine {
|
|
|
831
883
|
snippet: "",
|
|
832
884
|
distance,
|
|
833
885
|
});
|
|
886
|
+
graphOptionalPaths.add(node.filePath);
|
|
834
887
|
}
|
|
835
888
|
}
|
|
836
889
|
}
|
|
@@ -876,6 +929,21 @@ export class ContextEngine {
|
|
|
876
929
|
}
|
|
877
930
|
}
|
|
878
931
|
let rankedOptionalFiles = rankOptionalContextFiles([...optionalCandidates.values()], taskType);
|
|
932
|
+
const codeBudget = allocateContextFileBudget({
|
|
933
|
+
requiredPaths: requiredFileSet,
|
|
934
|
+
candidates: rankedOptionalFiles.map(candidate => ({
|
|
935
|
+
path: candidate.path,
|
|
936
|
+
score: candidate.score,
|
|
937
|
+
source: fileRoleByPath.has(candidate.path) && fileRoleByPath.get(candidate.path)?.role !== 'dependency'
|
|
938
|
+
? 'structural'
|
|
939
|
+
: graphOptionalPaths.has(candidate.path) ? 'graph' : 'structural',
|
|
940
|
+
})),
|
|
941
|
+
tokenBudget: Math.floor(maxTokens * 0.45),
|
|
942
|
+
graphRatio: 0.2,
|
|
943
|
+
});
|
|
944
|
+
rankedOptionalFiles = rankedOptionalFiles.filter(candidate => codeBudget.selectedPaths.has(candidate.path));
|
|
945
|
+
if (codeBudget.rejectedPaths.size > 0)
|
|
946
|
+
warnings.push(`codegraph-budget-rejected:${codeBudget.rejectedPaths.size}`);
|
|
879
947
|
for (const candidate of rankedOptionalFiles)
|
|
880
948
|
optionalFileSet.add(candidate.path);
|
|
881
949
|
if (this.indexer?.getFileFreshness) {
|
|
@@ -943,7 +1011,6 @@ export class ContextEngine {
|
|
|
943
1011
|
const compressed = compressToTokenLimit(allFileSnippets, Math.floor(maxTokens * 0.45));
|
|
944
1012
|
if (compressed.overBudget)
|
|
945
1013
|
warnings.push("context-compressor-budget-exceeded");
|
|
946
|
-
console.error("[devflow:timing] Snippet building + compress:", Date.now() - tSnippet, "ms");
|
|
947
1014
|
timing["3_snippet_compress"] = Date.now() - tSnippet;
|
|
948
1015
|
const riskHints = generateRiskHints(allNodes.filter(node => node.kind !== "file" && node.kind !== "import"), graphEvidence);
|
|
949
1016
|
const nextActions = generateNextActions(taskType, keySymbols.slice(0, 5));
|
|
@@ -1072,9 +1139,18 @@ export class ContextEngine {
|
|
|
1072
1139
|
requestId: options?.requestId,
|
|
1073
1140
|
host: options?.host,
|
|
1074
1141
|
command: options?.command,
|
|
1142
|
+
turnId: options?.turnId,
|
|
1143
|
+
intentArtifact: options?.intentArtifact,
|
|
1144
|
+
queryPlan: options?.queryPlan,
|
|
1075
1145
|
tokenBudget: maxTokens,
|
|
1076
1146
|
targetAnchors,
|
|
1077
1147
|
taskPlan: retrievalTaskPlan,
|
|
1148
|
+
graphAmbiguities: graphSelection.ambiguities,
|
|
1149
|
+
codeBudget: {
|
|
1150
|
+
maxFiles: codeBudget.maxFiles,
|
|
1151
|
+
graphFileLimit: codeBudget.graphFileLimit,
|
|
1152
|
+
selectedGraphFiles: codeBudget.selectedGraphFiles,
|
|
1153
|
+
},
|
|
1078
1154
|
fileRoles: fileRoleByPath,
|
|
1079
1155
|
fileFreshness: fileFreshnessByPath,
|
|
1080
1156
|
memoryHits,
|
|
@@ -1110,7 +1186,23 @@ export class ContextEngine {
|
|
|
1110
1186
|
this.queryCache.set(cacheKey, result);
|
|
1111
1187
|
}
|
|
1112
1188
|
timing["0_total"] = Date.now() - t0;
|
|
1113
|
-
|
|
1189
|
+
emitSemanticControlLog({
|
|
1190
|
+
event: 'codegraph.selection.completed',
|
|
1191
|
+
identity: {
|
|
1192
|
+
...logIdentity,
|
|
1193
|
+
contextReceipt: result.taskEnvelope?.receipt.contextHash,
|
|
1194
|
+
},
|
|
1195
|
+
level: warnings.length > 0 ? 'warn' : 'info',
|
|
1196
|
+
timestamp: Date.now(),
|
|
1197
|
+
data: {
|
|
1198
|
+
selectedFiles: result.taskEnvelope?.code.files.length ?? 0,
|
|
1199
|
+
selectedSymbols: result.taskEnvelope?.code.symbols.length ?? 0,
|
|
1200
|
+
rejectedRelations: result.taskEnvelope?.quality.code.rejected ?? 0,
|
|
1201
|
+
ambiguityCount: result.taskEnvelope?.code.ambiguities?.length ?? 0,
|
|
1202
|
+
timing,
|
|
1203
|
+
warnings: warnings.map(value => value.split(':')[0]),
|
|
1204
|
+
},
|
|
1205
|
+
});
|
|
1114
1206
|
result._timing = timing;
|
|
1115
1207
|
return result;
|
|
1116
1208
|
}
|
|
@@ -1445,6 +1537,9 @@ export class ContextEngine {
|
|
|
1445
1537
|
requestId: options?.requestId,
|
|
1446
1538
|
host: options?.host,
|
|
1447
1539
|
command: options?.command,
|
|
1540
|
+
turnId: options?.turnId,
|
|
1541
|
+
intentArtifact: options?.intentArtifact,
|
|
1542
|
+
queryPlan: options?.queryPlan,
|
|
1448
1543
|
tokenBudget: maxTokens,
|
|
1449
1544
|
targetAnchors,
|
|
1450
1545
|
fileRoles: fileRoleByPath,
|