@devflow-tools/mcp-server 0.17.3 → 0.17.5
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/command-registry.json +5 -5
- package/dist/enforcer/index.d.ts +2 -1
- package/dist/enforcer/index.d.ts.map +1 -1
- package/dist/enforcer/index.js +50 -1
- package/dist/enforcer/index.js.map +1 -1
- package/dist/semantic-sampling-resolver.d.ts +21 -0
- package/dist/semantic-sampling-resolver.d.ts.map +1 -0
- package/dist/semantic-sampling-resolver.js +96 -0
- package/dist/semantic-sampling-resolver.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +3 -1
- package/dist/server.js.map +1 -1
- package/dist/tools.d.ts +24 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +293 -4
- package/dist/tools.js.map +1 -1
- package/package.json +9 -9
package/dist/tools.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type EngineSet } from "@devflow-tools/context-engine";
|
|
2
|
-
import type
|
|
2
|
+
import { type ChannelQueryPlan, type DevFlowPlugin, type ImmutableTaskIntentArtifact } from "@devflow-tools/sdk";
|
|
3
|
+
import type { SemanticSamplingResolver } from './semantic-sampling-resolver.js';
|
|
3
4
|
export interface ToolDef {
|
|
4
5
|
name: string;
|
|
5
6
|
description: string;
|
|
@@ -20,7 +21,28 @@ export declare const GUARDED_CORE_TOOL_NAMES: ReadonlySet<string>;
|
|
|
20
21
|
export declare function getGuardedToolNames(pluginTools: readonly Pick<ToolDef, "name">[]): ReadonlySet<string>;
|
|
21
22
|
export declare function getCoreTools(knowledgeScopes?: string[]): ToolDef[];
|
|
22
23
|
export type ToolHandlers = Record<string, (args: Record<string, unknown>) => Promise<unknown>>;
|
|
23
|
-
|
|
24
|
+
declare function resolveBoundContextTask(input: {
|
|
25
|
+
projectRoot: string;
|
|
26
|
+
sessionId?: string;
|
|
27
|
+
requestId?: string;
|
|
28
|
+
turnId?: string;
|
|
29
|
+
intentArtifactHash?: string;
|
|
30
|
+
agentQuery: string;
|
|
31
|
+
expandedTerms?: string;
|
|
32
|
+
}): {
|
|
33
|
+
query: string;
|
|
34
|
+
expandedTerms?: string;
|
|
35
|
+
requestId?: string;
|
|
36
|
+
turnId?: string;
|
|
37
|
+
intentArtifact?: ImmutableTaskIntentArtifact;
|
|
38
|
+
queryPlan?: ChannelQueryPlan;
|
|
39
|
+
};
|
|
40
|
+
export declare function resolveBoundContextTaskWithSemantics(input: Parameters<typeof resolveBoundContextTask>[0], engines: EngineSet, dependencies: ToolHandlerDependencies): Promise<ReturnType<typeof resolveBoundContextTask>>;
|
|
41
|
+
export interface ToolHandlerDependencies {
|
|
42
|
+
semanticSampling?: SemanticSamplingResolver;
|
|
43
|
+
}
|
|
44
|
+
export declare function createToolHandlers(engines: EngineSet, boundProjectRoot: string, dependencies?: ToolHandlerDependencies): ToolHandlers;
|
|
24
45
|
export declare function getPluginTools(plugins: DevFlowPlugin[]): ToolDef[];
|
|
25
46
|
export declare function createPluginHandlers(engines: EngineSet, plugins: DevFlowPlugin[], boundProjectRoot: string): Record<string, (args: Record<string, unknown>) => Promise<unknown>>;
|
|
47
|
+
export {};
|
|
26
48
|
//# sourceMappingURL=tools.d.ts.map
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
|
package/dist/tools.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { getKnowledgeResult, getMemoryResult, getProjectContextResult, } from "@devflow-tools/context-engine";
|
|
1
|
+
import { buildChannelQueryPlan, buildRetrievalTaskPlan, extractStructuralSemanticEvidence, getKnowledgeResult, getMemoryResult, getProjectContextResult, mergeSemanticAuthority, parseIntent, } from "@devflow-tools/context-engine";
|
|
2
|
+
import { assertTaskSemanticFrameV2, projectSemanticFrameToLegacyIntent, resolveSemanticResolutionMode, } from "@devflow-tools/sdk";
|
|
2
3
|
import { resolveCapabilityRollout } from "@devflow-tools/sdk/capability-rollout";
|
|
3
4
|
import { canonicalizeProjectRoot, wrapHandlerRequireRoot } from "./plugin-guards.js";
|
|
4
5
|
import { getReportResourceUri, readToolReport } from "./report-store.js";
|
|
@@ -640,15 +641,303 @@ function resolveBoundContextTask(input) {
|
|
|
640
641
|
database.close();
|
|
641
642
|
}
|
|
642
643
|
}
|
|
644
|
+
export async function resolveBoundContextTaskWithSemantics(input, engines, dependencies) {
|
|
645
|
+
const legacy = resolveBoundContextTask(input);
|
|
646
|
+
const artifact = legacy.intentArtifact;
|
|
647
|
+
if (!artifact)
|
|
648
|
+
return legacy;
|
|
649
|
+
const semanticMode = resolveSemanticResolutionMode(input.projectRoot);
|
|
650
|
+
if (semanticMode === 'off' || !engines.semanticRouter)
|
|
651
|
+
return legacy;
|
|
652
|
+
const database = openGlobalDevFlowDatabase(undefined, { busyTimeoutMs: 250 });
|
|
653
|
+
try {
|
|
654
|
+
const latest = database.getLatestSemanticResolution(artifact.identity.projectRoot, artifact.identity.sessionId, artifact.identity.turnId);
|
|
655
|
+
if (!latest)
|
|
656
|
+
return legacy;
|
|
657
|
+
if (latest.artifactRevision >= 2) {
|
|
658
|
+
const resolvedArtifact = database.getTaskIntentArtifact(latest.artifactHash);
|
|
659
|
+
const resolvedPlan = resolvedArtifact && database.getChannelQueryPlanForIntent({
|
|
660
|
+
projectRoot: resolvedArtifact.projectRoot,
|
|
661
|
+
sessionId: resolvedArtifact.sessionId,
|
|
662
|
+
turnId: resolvedArtifact.turnId,
|
|
663
|
+
sourceIntentHash: resolvedArtifact.artifactHash,
|
|
664
|
+
});
|
|
665
|
+
if (resolvedArtifact && resolvedPlan && semanticMode !== 'shadow') {
|
|
666
|
+
return boundTaskFromRecords(legacy, resolvedArtifact, resolvedPlan);
|
|
667
|
+
}
|
|
668
|
+
return legacy;
|
|
669
|
+
}
|
|
670
|
+
let provisional;
|
|
671
|
+
try {
|
|
672
|
+
assertTaskSemanticFrameV2(latest.frame, artifact.normalizedPrompt);
|
|
673
|
+
provisional = latest.frame;
|
|
674
|
+
}
|
|
675
|
+
catch {
|
|
676
|
+
return legacy;
|
|
677
|
+
}
|
|
678
|
+
const structural = extractStructuralSemanticEvidence({
|
|
679
|
+
prompt: artifact.normalizedPrompt,
|
|
680
|
+
command: artifact.command,
|
|
681
|
+
targetAnchors: artifact.targetAnchors,
|
|
682
|
+
});
|
|
683
|
+
const route = await engines.semanticRouter.route(structural.normalizedPrompt);
|
|
684
|
+
emitSemanticControlLog({
|
|
685
|
+
event: 'semantic.route.scored',
|
|
686
|
+
identity: { ...artifact.identity, intentArtifactHash: artifact.artifactHash },
|
|
687
|
+
level: route.status === 'unavailable' ? 'warn' : 'info',
|
|
688
|
+
timestamp: Date.now(),
|
|
689
|
+
data: {
|
|
690
|
+
mode: semanticMode,
|
|
691
|
+
status: route.status,
|
|
692
|
+
modelId: route.modelId,
|
|
693
|
+
modelRevision: route.modelRevision,
|
|
694
|
+
thresholdVersion: route.thresholdVersion,
|
|
695
|
+
margin: route.margin,
|
|
696
|
+
candidates: route.candidates.slice(0, 8),
|
|
697
|
+
latencyMs: route.latencyMs,
|
|
698
|
+
reason: route.reason,
|
|
699
|
+
},
|
|
700
|
+
});
|
|
701
|
+
emitSemanticControlLog({
|
|
702
|
+
event: 'semantic.model.profile_evaluated',
|
|
703
|
+
identity: { ...artifact.identity, intentArtifactHash: artifact.artifactHash },
|
|
704
|
+
level: 'debug', timestamp: Date.now(),
|
|
705
|
+
data: {
|
|
706
|
+
mode: semanticMode, modelId: route.modelId, modelRevision: route.modelRevision,
|
|
707
|
+
thresholdVersion: route.thresholdVersion, catalogVersion: provisional.resolver.routeCatalogVersion,
|
|
708
|
+
status: route.status, latencyMs: route.latencyMs,
|
|
709
|
+
},
|
|
710
|
+
});
|
|
711
|
+
let sampled;
|
|
712
|
+
if ((route.status === 'escalation_required' || hasCompositionalStructure(structural))
|
|
713
|
+
&& dependencies.semanticSampling) {
|
|
714
|
+
emitSemanticControlLog({
|
|
715
|
+
event: 'semantic.resolution.escalated', identity: artifact.identity, level: 'info', timestamp: Date.now(),
|
|
716
|
+
data: { mode: semanticMode, frameHash: provisional.frameHash, reason: route.reason },
|
|
717
|
+
});
|
|
718
|
+
sampled = await dependencies.semanticSampling({
|
|
719
|
+
normalizedPrompt: structural.normalizedPrompt,
|
|
720
|
+
sourceHash: artifact.sourceHash,
|
|
721
|
+
structural,
|
|
722
|
+
route,
|
|
723
|
+
provisionalFrame: provisional,
|
|
724
|
+
timeoutMs: 3_000,
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
const resolved = mergeSemanticAuthority({
|
|
728
|
+
sourceHash: artifact.sourceHash,
|
|
729
|
+
structural,
|
|
730
|
+
route,
|
|
731
|
+
...(sampled?.status === 'resolved' && sampled.frame ? { sampledFrame: sampled.frame } : {}),
|
|
732
|
+
provisionalFrame: provisional,
|
|
733
|
+
});
|
|
734
|
+
const finalResolution = withSamplingResult(resolved, sampled);
|
|
735
|
+
const projection = projectSemanticFrameToLegacyIntent(finalResolution.frame);
|
|
736
|
+
const revisedBody = {
|
|
737
|
+
...artifact,
|
|
738
|
+
version: 2,
|
|
739
|
+
supersedesHash: artifact.artifactHash,
|
|
740
|
+
intent: projection.intent,
|
|
741
|
+
action: projection.action,
|
|
742
|
+
entities: finalResolution.frame.entities,
|
|
743
|
+
targetAnchors: finalResolution.frame.targetAnchors,
|
|
744
|
+
policyConstraints: finalResolution.frame.constraints,
|
|
745
|
+
classificationEvidence: finalResolution.frame.evidence.flatMap((evidence) => {
|
|
746
|
+
const field = evidence.field === 'negation' || evidence.field === 'condition'
|
|
747
|
+
? 'constraint'
|
|
748
|
+
: evidence.field;
|
|
749
|
+
if (field !== 'intent' && field !== 'action' && field !== 'entity'
|
|
750
|
+
&& field !== 'target' && field !== 'constraint')
|
|
751
|
+
return [];
|
|
752
|
+
const source = evidence.source === 'structural'
|
|
753
|
+
|| evidence.source === 'lexical_feature'
|
|
754
|
+
? 'deterministic_parser'
|
|
755
|
+
: evidence.source === 'host_sampling'
|
|
756
|
+
? 'host_semantic'
|
|
757
|
+
: evidence.source;
|
|
758
|
+
return [{
|
|
759
|
+
source,
|
|
760
|
+
field,
|
|
761
|
+
value: evidence.value,
|
|
762
|
+
reason: `semantic_frame:${finalResolution.frame.frameHash}`,
|
|
763
|
+
confidence: evidence.confidence,
|
|
764
|
+
}];
|
|
765
|
+
}),
|
|
766
|
+
createdAt: finalResolution.frame.createdAt,
|
|
767
|
+
};
|
|
768
|
+
const { artifactHash: _oldHash, ...unhashedArtifact } = revisedBody;
|
|
769
|
+
const revisedArtifact = {
|
|
770
|
+
...unhashedArtifact,
|
|
771
|
+
artifactHash: hashCanonical(unhashedArtifact),
|
|
772
|
+
};
|
|
773
|
+
const taskPlan = buildRetrievalTaskPlan({
|
|
774
|
+
query: legacy.query,
|
|
775
|
+
parsedIntent: parseIntent(legacy.query),
|
|
776
|
+
targetAnchors: revisedArtifact.targetAnchors,
|
|
777
|
+
activeSkill: revisedArtifact.activeSkill,
|
|
778
|
+
command: revisedArtifact.command,
|
|
779
|
+
authoritativeArtifact: revisedArtifact,
|
|
780
|
+
semanticFrame: finalResolution.frame,
|
|
781
|
+
});
|
|
782
|
+
const revisedPlan = buildChannelQueryPlan({
|
|
783
|
+
artifact: revisedArtifact,
|
|
784
|
+
taskPlan,
|
|
785
|
+
expandedTerms: legacy.expandedTerms,
|
|
786
|
+
generatedBy: 'hybrid',
|
|
787
|
+
});
|
|
788
|
+
database.appendTaskIntentArtifact(toTaskIntentRecord(revisedArtifact));
|
|
789
|
+
database.appendChannelQueryPlan(toChannelQueryPlanRecord(revisedPlan));
|
|
790
|
+
database.appendSemanticResolution({
|
|
791
|
+
frameHash: finalResolution.frame.frameHash,
|
|
792
|
+
...artifact.identity,
|
|
793
|
+
sourceHash: artifact.sourceHash,
|
|
794
|
+
artifactHash: revisedArtifact.artifactHash,
|
|
795
|
+
artifactRevision: 2,
|
|
796
|
+
supersedesFrameHash: provisional.frameHash,
|
|
797
|
+
state: finalResolution.frame.state,
|
|
798
|
+
generatedBy: finalResolution.frame.resolver.generatedBy,
|
|
799
|
+
modelId: finalResolution.frame.resolver.modelId,
|
|
800
|
+
modelRevision: finalResolution.frame.resolver.modelRevision,
|
|
801
|
+
routeCatalogVersion: finalResolution.frame.resolver.routeCatalogVersion,
|
|
802
|
+
thresholdVersion: finalResolution.frame.resolver.thresholdVersion,
|
|
803
|
+
route: finalResolution.route,
|
|
804
|
+
sampling: finalResolution.sampling,
|
|
805
|
+
conflicts: finalResolution.conflicts,
|
|
806
|
+
frame: finalResolution.frame,
|
|
807
|
+
durationMs: Math.round(finalResolution.route.latencyMs + (finalResolution.sampling.latencyMs ?? 0)),
|
|
808
|
+
createdAt: finalResolution.frame.createdAt,
|
|
809
|
+
});
|
|
810
|
+
logSemanticResolution(artifact, semanticMode, finalResolution, projection);
|
|
811
|
+
return semanticMode === 'shadow'
|
|
812
|
+
? legacy
|
|
813
|
+
: { ...legacy, intentArtifact: revisedArtifact, queryPlan: revisedPlan };
|
|
814
|
+
}
|
|
815
|
+
finally {
|
|
816
|
+
database.close();
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
function boundTaskFromRecords(legacy, artifactRecord, planRecord) {
|
|
820
|
+
return {
|
|
821
|
+
...legacy,
|
|
822
|
+
intentArtifact: toSdkIntentArtifact(artifactRecord),
|
|
823
|
+
queryPlan: toSdkChannelQueryPlan(planRecord),
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
function hasCompositionalStructure(structural) {
|
|
827
|
+
return structural.conditions.length > 0 || structural.prohibitions.length > 0
|
|
828
|
+
|| new Set(structural.positiveActionSpans.map(item => item.value)).size > 1;
|
|
829
|
+
}
|
|
830
|
+
function withSamplingResult(resolution, sampled) {
|
|
831
|
+
if (!sampled)
|
|
832
|
+
return resolution;
|
|
833
|
+
return {
|
|
834
|
+
...resolution,
|
|
835
|
+
sampling: {
|
|
836
|
+
attempted: true,
|
|
837
|
+
status: sampled.status,
|
|
838
|
+
...(sampled.model ? { model: sampled.model } : {}),
|
|
839
|
+
latencyMs: sampled.latencyMs,
|
|
840
|
+
...(sampled.responseHash ? { responseHash: sampled.responseHash } : {}),
|
|
841
|
+
},
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
function logSemanticResolution(artifact, mode, resolution, projection) {
|
|
845
|
+
const event = resolution.frame.state === 'resolved'
|
|
846
|
+
? 'semantic.resolution.completed'
|
|
847
|
+
: 'semantic.resolution.abstained';
|
|
848
|
+
emitSemanticControlLog({
|
|
849
|
+
event, identity: { ...artifact.identity, intentArtifactHash: artifact.artifactHash },
|
|
850
|
+
level: resolution.frame.state === 'resolved' ? 'info' : 'warn', timestamp: Date.now(),
|
|
851
|
+
data: {
|
|
852
|
+
mode, frameHash: resolution.frame.frameHash, state: resolution.frame.state,
|
|
853
|
+
permission: resolution.frame.mutationPermission, intent: projection.intent,
|
|
854
|
+
action: projection.action, samplingStatus: resolution.sampling.status,
|
|
855
|
+
conflictCount: resolution.conflicts.length,
|
|
856
|
+
},
|
|
857
|
+
});
|
|
858
|
+
if (resolution.conflicts.length > 0)
|
|
859
|
+
emitSemanticControlLog({
|
|
860
|
+
event: 'semantic.authority.conflicted', identity: artifact.identity, level: 'warn', timestamp: Date.now(),
|
|
861
|
+
data: { frameHash: resolution.frame.frameHash, conflicts: resolution.conflicts },
|
|
862
|
+
});
|
|
863
|
+
if (projection.intent !== artifact.intent || projection.action !== artifact.action)
|
|
864
|
+
emitSemanticControlLog({
|
|
865
|
+
event: 'semantic.regex.shadow_mismatch', identity: artifact.identity, level: 'info', timestamp: Date.now(),
|
|
866
|
+
data: { mode, frameHash: resolution.frame.frameHash, legacyIntent: artifact.intent,
|
|
867
|
+
legacyAction: artifact.action, semanticIntent: projection.intent, semanticAction: projection.action },
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
function toTaskIntentRecord(artifact) {
|
|
871
|
+
return {
|
|
872
|
+
...artifact.identity, version: artifact.version, supersedesHash: artifact.supersedesHash,
|
|
873
|
+
rawPrompt: artifact.rawPrompt, normalizedPrompt: artifact.normalizedPrompt,
|
|
874
|
+
command: artifact.command, slashArgs: artifact.slashArgs, activeSkill: artifact.activeSkill,
|
|
875
|
+
intent: artifact.intent, action: artifact.action, entities: artifact.entities,
|
|
876
|
+
targetAnchors: artifact.targetAnchors, policyConstraints: artifact.policyConstraints,
|
|
877
|
+
classificationEvidence: artifact.classificationEvidence.map(item => ({ ...item })),
|
|
878
|
+
sourceEventIds: artifact.sourceEventIds, sourceHash: artifact.sourceHash,
|
|
879
|
+
artifactHash: artifact.artifactHash, createdAt: artifact.createdAt,
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
function toChannelQueryPlanRecord(plan) {
|
|
883
|
+
return {
|
|
884
|
+
...plan.identity, sourceIntentHash: plan.sourceIntentHash, planHash: plan.planHash,
|
|
885
|
+
code: plan.code.map(item => ({ ...item })), memory: plan.memory.map(item => ({ ...item })),
|
|
886
|
+
knowledge: plan.knowledge.map(item => ({ ...item })), generatedBy: plan.generatedBy,
|
|
887
|
+
...(plan.degradation ? { degradation: { ...plan.degradation } } : {}), createdAt: plan.createdAt,
|
|
888
|
+
};
|
|
889
|
+
}
|
|
890
|
+
function toSdkIntentArtifact(record) {
|
|
891
|
+
return {
|
|
892
|
+
identity: { projectRoot: record.projectRoot, projectId: record.projectId, hostId: record.hostId,
|
|
893
|
+
sessionId: record.sessionId, turnId: record.turnId, requestId: record.requestId,
|
|
894
|
+
...(record.executionId ? { executionId: record.executionId } : {}) },
|
|
895
|
+
version: record.version, ...(record.supersedesHash ? { supersedesHash: record.supersedesHash } : {}),
|
|
896
|
+
rawPrompt: record.rawPrompt, normalizedPrompt: record.normalizedPrompt,
|
|
897
|
+
...(record.command ? { command: record.command } : {}), slashArgs: record.slashArgs,
|
|
898
|
+
...(record.activeSkill ? { activeSkill: record.activeSkill } : {}), intent: record.intent,
|
|
899
|
+
action: record.action, entities: record.entities, targetAnchors: record.targetAnchors,
|
|
900
|
+
policyConstraints: record.policyConstraints, classificationEvidence: record.classificationEvidence,
|
|
901
|
+
sourceEventIds: record.sourceEventIds, sourceHash: record.sourceHash,
|
|
902
|
+
artifactHash: record.artifactHash, createdAt: record.createdAt,
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
function toSdkChannelQueryPlan(record) {
|
|
906
|
+
return { identity: { projectRoot: record.projectRoot, projectId: record.projectId, hostId: record.hostId,
|
|
907
|
+
sessionId: record.sessionId, turnId: record.turnId, requestId: record.requestId,
|
|
908
|
+
...(record.executionId ? { executionId: record.executionId } : {}) },
|
|
909
|
+
sourceIntentHash: record.sourceIntentHash, planHash: record.planHash, code: record.code,
|
|
910
|
+
memory: record.memory, knowledge: record.knowledge, generatedBy: record.generatedBy,
|
|
911
|
+
...(record.degradation ? { degradation: record.degradation } : {}), createdAt: record.createdAt };
|
|
912
|
+
}
|
|
913
|
+
function hashCanonical(value) {
|
|
914
|
+
return createHash('sha256').update(stableCanonicalJson(value)).digest('hex');
|
|
915
|
+
}
|
|
916
|
+
function stableCanonicalJson(value) {
|
|
917
|
+
if (value === null || typeof value === 'string' || typeof value === 'boolean')
|
|
918
|
+
return JSON.stringify(value);
|
|
919
|
+
if (typeof value === 'number')
|
|
920
|
+
return Number.isFinite(value) ? JSON.stringify(value) : 'null';
|
|
921
|
+
if (Array.isArray(value))
|
|
922
|
+
return `[${value.map(stableCanonicalJson).join(',')}]`;
|
|
923
|
+
if (!value || typeof value !== 'object')
|
|
924
|
+
return JSON.stringify(String(value));
|
|
925
|
+
const record = value;
|
|
926
|
+
return `{${Object.keys(record).sort().filter(key => record[key] !== undefined)
|
|
927
|
+
.map(key => `${JSON.stringify(key)}:${stableCanonicalJson(record[key])}`).join(',')}}`;
|
|
928
|
+
}
|
|
643
929
|
function stripArtifactCommand(prompt, command) {
|
|
644
930
|
if (!command)
|
|
645
931
|
return prompt;
|
|
646
932
|
const escaped = command.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
|
|
647
933
|
return prompt.replace(new RegExp(`^\\/${escaped}\\b`, 'iu'), '').trim() || prompt;
|
|
648
934
|
}
|
|
649
|
-
export function createToolHandlers(engines, boundProjectRoot) {
|
|
935
|
+
export function createToolHandlers(engines, boundProjectRoot, dependencies = {}) {
|
|
650
936
|
const hasBoundProjectRoot = typeof boundProjectRoot === 'string' && boundProjectRoot.trim().length > 0;
|
|
651
937
|
const canonicalProjectRoot = canonicalizeProjectRoot(String(boundProjectRoot ?? process.cwd()));
|
|
938
|
+
// Resolution is invoked by the rollout-aware context path in the next stage.
|
|
939
|
+
// Retaining the injected dependency here keeps handler construction backward compatible.
|
|
940
|
+
void dependencies.semanticSampling;
|
|
652
941
|
function getFreshnessMs() {
|
|
653
942
|
try {
|
|
654
943
|
const stats = engines.codegraph.getStats();
|
|
@@ -660,7 +949,7 @@ export function createToolHandlers(engines, boundProjectRoot) {
|
|
|
660
949
|
}
|
|
661
950
|
const handlers = {
|
|
662
951
|
get_project_context: async ({ query, mode, expandedTerms, retrievalSessionId, baselineReceipt, missingContext, _devflow_session_id, _devflow_execution_id, _devflow_request_id, _devflow_turn_id, _devflow_intent_artifact_hash, _devflow_active_skill, activeSkill }) => {
|
|
663
|
-
const boundTask =
|
|
952
|
+
const boundTask = await resolveBoundContextTaskWithSemantics({
|
|
664
953
|
projectRoot: canonicalProjectRoot,
|
|
665
954
|
sessionId: typeof _devflow_session_id === 'string' ? _devflow_session_id : undefined,
|
|
666
955
|
requestId: typeof _devflow_request_id === 'string' ? _devflow_request_id : undefined,
|
|
@@ -668,7 +957,7 @@ export function createToolHandlers(engines, boundProjectRoot) {
|
|
|
668
957
|
intentArtifactHash: typeof _devflow_intent_artifact_hash === 'string' ? _devflow_intent_artifact_hash : undefined,
|
|
669
958
|
agentQuery: query,
|
|
670
959
|
expandedTerms: typeof expandedTerms === 'string' ? expandedTerms : undefined,
|
|
671
|
-
});
|
|
960
|
+
}, engines, dependencies);
|
|
672
961
|
return getProjectContextResult(engines.context, {
|
|
673
962
|
query: boundTask.query,
|
|
674
963
|
mode: mode ?? "fast",
|