openfox 2.0.14 → 2.0.15
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/{chat-handler-ITXCBFJK.js → chat-handler-RYOG3WJP.js} +8 -6
- package/dist/{chunk-4U45A7B3.js → chunk-2GX5EIIU.js} +111 -45
- package/dist/{chunk-LNEBVOH6.js → chunk-3IKRNKPI.js} +6 -6
- package/dist/{chunk-4W2Z4B5U.js → chunk-EKTGRBDC.js} +36 -41
- package/dist/{chunk-3QB2RMX2.js → chunk-F4PMNP7S.js} +2 -2
- package/dist/{chunk-TIKQWNYK.js → chunk-J7KOV4ST.js} +2 -2
- package/dist/{chunk-4ZTQO5JP.js → chunk-KPKSN362.js} +262 -6
- package/dist/{chunk-PP6VQXQW.js → chunk-SNQT7LNU.js} +2 -1
- package/dist/{chunk-5BDVM6YI.js → chunk-YD6NDTKF.js} +1 -1
- package/dist/{chunk-7GJ6XYAF.js → chunk-Z64KW2HD.js} +20 -16
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/{config-YFHA5MWV.js → config-Z66BQTNX.js} +2 -2
- package/dist/{orchestrator-VP74KOXI.js → orchestrator-KRCVDTZ6.js} +7 -5
- package/dist/package.json +1 -2
- package/dist/{processor-CCXZYLX6.js → processor-JHR3Z42W.js} +8 -6
- package/dist/{protocol-BE5dRtYw.d.ts → protocol-BC1QSQ-Y.d.ts} +7 -1
- package/dist/{protocol-YYWMFR35.js → protocol-BKNLAEPJ.js} +3 -3
- package/dist/{provider-QUJQLVOM.js → provider-YBTRC77Y.js} +3 -3
- package/dist/{serve-GA2UIHHB.js → serve-AV74ODQ6.js} +9 -9
- package/dist/server/index.d.ts +19 -1
- package/dist/server/index.js +8 -7
- package/dist/{server-EA6W7YIC.js → server-P7E2IPVL.js} +10 -8
- package/dist/shared/index.d.ts +2 -2
- package/dist/shared/index.js +1 -1
- package/dist/{tools-DUC54GEH.js → tools-WEE4XDTL.js} +6 -4
- package/dist/web/assets/{index-D0qVcBva.js → index-BMz5-yAf.js} +31 -31
- package/dist/web/index.html +1 -1
- package/dist/web/sw.js +1 -1
- package/package.json +1 -2
|
@@ -2,29 +2,29 @@ import {
|
|
|
2
2
|
appendCompactionPrompt
|
|
3
3
|
} from "./chunk-FWJ6YXGA.js";
|
|
4
4
|
import {
|
|
5
|
-
computeDynamicContextHash,
|
|
6
5
|
injectWorkflowKickoffIfNeeded,
|
|
7
6
|
runAgentTurn,
|
|
8
7
|
runChatTurn
|
|
9
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-Z64KW2HD.js";
|
|
10
9
|
import {
|
|
10
|
+
applyDynamicContext,
|
|
11
11
|
checkAborted,
|
|
12
|
+
computeDynamicContextHash,
|
|
12
13
|
deleteItemFromDir,
|
|
13
14
|
devServerManager,
|
|
14
15
|
executeSubAgent,
|
|
15
16
|
findAgentById,
|
|
16
17
|
getAllInstructions,
|
|
17
18
|
getEnabledSkillMetadata,
|
|
18
|
-
|
|
19
|
+
getToolFingerprint,
|
|
19
20
|
getToolRegistryForAgent,
|
|
20
21
|
jsonSerializer,
|
|
21
22
|
loadAllAgentsDefault,
|
|
22
23
|
saveItemToDir,
|
|
23
24
|
spawnShellProcess
|
|
24
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-KPKSN362.js";
|
|
25
26
|
import {
|
|
26
27
|
TurnMetrics,
|
|
27
|
-
buildTopLevelSystemPrompt,
|
|
28
28
|
createMessageStartEvent
|
|
29
29
|
} from "./chunk-L7TDUIQY.js";
|
|
30
30
|
import {
|
|
@@ -49,7 +49,7 @@ import {
|
|
|
49
49
|
parseClientMessage,
|
|
50
50
|
serializeServerMessage,
|
|
51
51
|
storedEventToServerMessage
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-F4PMNP7S.js";
|
|
53
53
|
import {
|
|
54
54
|
provideAnswer
|
|
55
55
|
} from "./chunk-EU3WWTFH.js";
|
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
} from "./chunk-VUQCQXXJ.js";
|
|
59
59
|
import {
|
|
60
60
|
createServerMessage
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-YD6NDTKF.js";
|
|
62
62
|
import {
|
|
63
63
|
getGlobalConfigDir
|
|
64
64
|
} from "./chunk-CQGTEGKL.js";
|
|
@@ -1173,9 +1173,12 @@ async function isValidToken(token) {
|
|
|
1173
1173
|
}
|
|
1174
1174
|
|
|
1175
1175
|
// src/server/ws/server.ts
|
|
1176
|
-
var
|
|
1177
|
-
|
|
1178
|
-
|
|
1176
|
+
var resolveMcpReady = null;
|
|
1177
|
+
var mcpReadyPromise = new Promise((resolve) => {
|
|
1178
|
+
resolveMcpReady = resolve;
|
|
1179
|
+
});
|
|
1180
|
+
function signalMcpReady() {
|
|
1181
|
+
resolveMcpReady?.();
|
|
1179
1182
|
}
|
|
1180
1183
|
function moduleGitBranch(cwd) {
|
|
1181
1184
|
return new Promise((resolve) => {
|
|
@@ -1687,7 +1690,8 @@ function createWebSocketServer(httpServer, config, getLLMClient, getActiveProvid
|
|
|
1687
1690
|
return false;
|
|
1688
1691
|
},
|
|
1689
1692
|
close: (cb) => wss.close(cb),
|
|
1690
|
-
broadcastForSession
|
|
1693
|
+
broadcastForSession,
|
|
1694
|
+
broadcastAll
|
|
1691
1695
|
};
|
|
1692
1696
|
}
|
|
1693
1697
|
async function handleClientMessage(ws, client, message, _getLLMClient, _getActiveProvider, sessionManager, _broadcastForSession, _providerManager, _getSessionLLMClient, _getSessionStatsIdentity, llmForSession, statsForSession, _startTurnWithCompletionChain, cleanupAfterTurn, enqueueSendFn) {
|
|
@@ -1766,18 +1770,21 @@ async function handleClientMessage(ws, client, message, _getLLMClient, _getActiv
|
|
|
1766
1770
|
;
|
|
1767
1771
|
(async () => {
|
|
1768
1772
|
try {
|
|
1773
|
+
await mcpReadyPromise;
|
|
1769
1774
|
const { content: instructionContent } = await getAllInstructions(session.workdir, session.projectId);
|
|
1770
1775
|
const runtimeConfig = getRuntimeConfig();
|
|
1771
1776
|
const configDir = getGlobalConfigDir(runtimeConfig.mode ?? "production");
|
|
1772
1777
|
const skills = await getEnabledSkillMetadata(configDir, runtimeConfig.workdir);
|
|
1773
|
-
const
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
const currentHash = createHash2("sha256").update(dynamicInputs).digest("hex");
|
|
1778
|
+
const { createToolRegistry } = await import("./tools-WEE4XDTL.js");
|
|
1779
|
+
const allTools = createToolRegistry().definitions;
|
|
1780
|
+
const toolFingerprint = getToolFingerprint(allTools);
|
|
1781
|
+
const currentHash = computeDynamicContextHash(instructionContent, skills, toolFingerprint);
|
|
1778
1782
|
if (currentHash !== cachedHash) {
|
|
1779
1783
|
sessionManager.setDynamicContextChanged(session.id, true);
|
|
1780
1784
|
sendContextState();
|
|
1785
|
+
} else if (sessionManager.getDynamicContextChanged(session.id)) {
|
|
1786
|
+
sessionManager.setDynamicContextChanged(session.id, false);
|
|
1787
|
+
sendContextState();
|
|
1781
1788
|
}
|
|
1782
1789
|
} catch {
|
|
1783
1790
|
}
|
|
@@ -1836,18 +1843,24 @@ async function handleClientMessage(ws, client, message, _getLLMClient, _getActiv
|
|
|
1836
1843
|
const session = sessionManager.requireSession(sessionId);
|
|
1837
1844
|
(async () => {
|
|
1838
1845
|
try {
|
|
1846
|
+
await mcpReadyPromise;
|
|
1839
1847
|
const { content: instructionContent } = await getAllInstructions(session.workdir, session.projectId);
|
|
1840
1848
|
const runtimeConfig = getRuntimeConfig();
|
|
1841
1849
|
const configDir = getGlobalConfigDir(runtimeConfig.mode ?? "production");
|
|
1842
1850
|
const skills = await getEnabledSkillMetadata(configDir, runtimeConfig.workdir);
|
|
1843
|
-
const
|
|
1844
|
-
const
|
|
1845
|
-
|
|
1846
|
-
).sort().join("|");
|
|
1851
|
+
const { createToolRegistry } = await import("./tools-WEE4XDTL.js");
|
|
1852
|
+
const allTools = createToolRegistry().definitions;
|
|
1853
|
+
const toolFingerprint = getToolFingerprint(allTools);
|
|
1847
1854
|
const currentHash = computeDynamicContextHash(instructionContent, skills, toolFingerprint);
|
|
1848
1855
|
const cachedHash = sessionManager.getCachedPrompt(sessionId)?.hash;
|
|
1849
1856
|
if (cachedHash) {
|
|
1850
1857
|
if (currentHash !== cachedHash) {
|
|
1858
|
+
logger.debug("checkDynamic: hash mismatch", {
|
|
1859
|
+
sessionId,
|
|
1860
|
+
cachedHash,
|
|
1861
|
+
currentHash,
|
|
1862
|
+
toolCount: allTools.length
|
|
1863
|
+
});
|
|
1851
1864
|
if (!sessionManager.getDynamicContextChanged(sessionId)) {
|
|
1852
1865
|
sessionManager.setDynamicContextChanged(sessionId, true);
|
|
1853
1866
|
const newContextState = sessionManager.getContextState(sessionId);
|
|
@@ -1881,25 +1894,7 @@ async function handleClientMessage(ws, client, message, _getLLMClient, _getActiv
|
|
|
1881
1894
|
;
|
|
1882
1895
|
(async () => {
|
|
1883
1896
|
try {
|
|
1884
|
-
|
|
1885
|
-
const runtimeConfig = getRuntimeConfig();
|
|
1886
|
-
const configDir = getGlobalConfigDir(runtimeConfig.mode ?? "production");
|
|
1887
|
-
const skills = await getEnabledSkillMetadata(configDir, runtimeConfig.workdir);
|
|
1888
|
-
const mcpTools = _mcpManager ? _mcpManager.getToolDefinitions() : [];
|
|
1889
|
-
const toolFingerprint = mcpTools.map(
|
|
1890
|
-
(t) => `${t.function.name}:${JSON.stringify(t.function.parameters)}`
|
|
1891
|
-
).sort().join("|");
|
|
1892
|
-
const dynamicHash = computeDynamicContextHash(instructionContent, skills, toolFingerprint);
|
|
1893
|
-
const allAgents = await loadAllAgentsDefault();
|
|
1894
|
-
const subAgentDefs = getSubAgents(allAgents);
|
|
1895
|
-
const systemPrompt = buildTopLevelSystemPrompt(
|
|
1896
|
-
session.workdir,
|
|
1897
|
-
instructionContent || void 0,
|
|
1898
|
-
skills,
|
|
1899
|
-
subAgentDefs
|
|
1900
|
-
);
|
|
1901
|
-
sessionManager.setCachedPrompt(sessionId, systemPrompt, mcpTools, dynamicHash);
|
|
1902
|
-
sessionManager.setDynamicContextChanged(sessionId, false);
|
|
1897
|
+
await applyDynamicContext(sessionManager, sessionId);
|
|
1903
1898
|
const newContextState = sessionManager.getContextState(sessionId);
|
|
1904
1899
|
sendForSession(sessionId, createContextStateMessage(newContextState));
|
|
1905
1900
|
send({ type: "ack", payload: {}, id: message.id });
|
|
@@ -2071,7 +2066,7 @@ export {
|
|
|
2071
2066
|
verifyPassword,
|
|
2072
2067
|
tokenFromPassword,
|
|
2073
2068
|
isValidToken,
|
|
2074
|
-
|
|
2069
|
+
signalMcpReady,
|
|
2075
2070
|
createWebSocketServer
|
|
2076
2071
|
};
|
|
2077
|
-
//# sourceMappingURL=chunk-
|
|
2072
|
+
//# sourceMappingURL=chunk-EKTGRBDC.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServerMessage,
|
|
3
3
|
isClientMessage
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-YD6NDTKF.js";
|
|
5
5
|
|
|
6
6
|
// src/server/ws/protocol.ts
|
|
7
7
|
function enrichMessagesWithToolResults(messages) {
|
|
@@ -339,4 +339,4 @@ export {
|
|
|
339
339
|
createQueueStateMessage,
|
|
340
340
|
storedEventToServerMessage
|
|
341
341
|
};
|
|
342
|
-
//# sourceMappingURL=chunk-
|
|
342
|
+
//# sourceMappingURL=chunk-F4PMNP7S.js.map
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
createContextStateMessage,
|
|
11
11
|
createSessionStateMessage
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-F4PMNP7S.js";
|
|
13
13
|
import {
|
|
14
14
|
getPendingQuestionsForSession
|
|
15
15
|
} from "./chunk-EU3WWTFH.js";
|
|
@@ -154,4 +154,4 @@ export {
|
|
|
154
154
|
needsNameGenerationCheck,
|
|
155
155
|
applyGeneratedSessionName
|
|
156
156
|
};
|
|
157
|
-
//# sourceMappingURL=chunk-
|
|
157
|
+
//# sourceMappingURL=chunk-J7KOV4ST.js.map
|
|
@@ -31,6 +31,9 @@ import {
|
|
|
31
31
|
getMaxPerSession,
|
|
32
32
|
getSessionProcessCount
|
|
33
33
|
} from "./chunk-VRGRAQDG.js";
|
|
34
|
+
import {
|
|
35
|
+
createMcpTools
|
|
36
|
+
} from "./chunk-NWO6GRYE.js";
|
|
34
37
|
import {
|
|
35
38
|
getCurrentContextWindowId,
|
|
36
39
|
getCurrentWindowMessageOptions,
|
|
@@ -52,7 +55,7 @@ import {
|
|
|
52
55
|
createChatMessageUpdatedMessage,
|
|
53
56
|
createChatPathConfirmationMessage,
|
|
54
57
|
createQueueStateMessage
|
|
55
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-F4PMNP7S.js";
|
|
56
59
|
import {
|
|
57
60
|
AskUserInterrupt,
|
|
58
61
|
askUserTool
|
|
@@ -62,6 +65,10 @@ import {
|
|
|
62
65
|
deleteSetting,
|
|
63
66
|
getSetting
|
|
64
67
|
} from "./chunk-RFNEDBVO.js";
|
|
68
|
+
import {
|
|
69
|
+
loadGlobalConfig,
|
|
70
|
+
saveGlobalConfig
|
|
71
|
+
} from "./chunk-SNQT7LNU.js";
|
|
65
72
|
import {
|
|
66
73
|
getGlobalConfigDir
|
|
67
74
|
} from "./chunk-CQGTEGKL.js";
|
|
@@ -806,6 +813,14 @@ function formatDiagnosticsForLLM(diagnostics) {
|
|
|
806
813
|
}
|
|
807
814
|
return output;
|
|
808
815
|
}
|
|
816
|
+
function appendLspInstallHint(output, lspManager, path) {
|
|
817
|
+
if (!lspManager) return output;
|
|
818
|
+
const hint = lspManager.getInstallHint(path);
|
|
819
|
+
if (!hint) return output;
|
|
820
|
+
return output + `
|
|
821
|
+
|
|
822
|
+
\u26A0\uFE0F Language server not installed. To enable diagnostics: \`${hint}\``;
|
|
823
|
+
}
|
|
809
824
|
|
|
810
825
|
// src/server/tools/write.ts
|
|
811
826
|
var writeFileTool = createTool(
|
|
@@ -849,6 +864,7 @@ var writeFileTool = createTool(
|
|
|
849
864
|
if (context.lspManager) {
|
|
850
865
|
diagnostics = await context.lspManager.notifyFileChange(fullPath, args.content);
|
|
851
866
|
output += formatDiagnosticsForLLM(diagnostics);
|
|
867
|
+
output = appendLspInstallHint(output, context.lspManager, fullPath);
|
|
852
868
|
}
|
|
853
869
|
const newHash = await computeFileHash(fullPath);
|
|
854
870
|
if (newHash) {
|
|
@@ -1102,6 +1118,7 @@ Make sure whitespace and indentation match exactly.`
|
|
|
1102
1118
|
if (context.lspManager) {
|
|
1103
1119
|
diagnostics = await context.lspManager.notifyFileChange(fullPath, newContent);
|
|
1104
1120
|
output += formatDiagnosticsForLLM(diagnostics);
|
|
1121
|
+
output = appendLspInstallHint(output, context.lspManager, fullPath);
|
|
1105
1122
|
}
|
|
1106
1123
|
const newHash = await computeFileHash(fullPath);
|
|
1107
1124
|
if (newHash) {
|
|
@@ -2677,10 +2694,10 @@ async function describeImageFromDataUrl(dataUrl, visionModel, options) {
|
|
|
2677
2694
|
import { createHash as createHash2 } from "crypto";
|
|
2678
2695
|
async function loadVisionModelFromGlobalConfig() {
|
|
2679
2696
|
try {
|
|
2680
|
-
const { loadGlobalConfig, getVisionFallback } = await import("./config-
|
|
2697
|
+
const { loadGlobalConfig: loadGlobalConfig2, getVisionFallback } = await import("./config-Z66BQTNX.js");
|
|
2681
2698
|
const runtimeConfig = getRuntimeConfig();
|
|
2682
2699
|
const mode = runtimeConfig.mode ?? "production";
|
|
2683
|
-
const globalConfig = await
|
|
2700
|
+
const globalConfig = await loadGlobalConfig2(mode);
|
|
2684
2701
|
const fallback = getVisionFallback(globalConfig);
|
|
2685
2702
|
if (fallback?.enabled && fallback.model) {
|
|
2686
2703
|
return { baseUrl: fallback.url, model: fallback.model, timeout: fallback.timeout * 1e3 };
|
|
@@ -3132,7 +3149,7 @@ var callSubAgentTool = {
|
|
|
3132
3149
|
};
|
|
3133
3150
|
}
|
|
3134
3151
|
try {
|
|
3135
|
-
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-
|
|
3152
|
+
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-WEE4XDTL.js");
|
|
3136
3153
|
const toolRegistry = getToolRegistryForAgent2(agentDef);
|
|
3137
3154
|
const turnMetrics = new TurnMetrics();
|
|
3138
3155
|
const result = await executeSubAgent({
|
|
@@ -3919,6 +3936,238 @@ These processes run independently of agent turns and persist across session comp
|
|
|
3919
3936
|
}
|
|
3920
3937
|
);
|
|
3921
3938
|
|
|
3939
|
+
// src/server/chat/dynamic-context.ts
|
|
3940
|
+
import { createHash as createHash3 } from "crypto";
|
|
3941
|
+
function computeDynamicContextHash(instructionContent, skills, toolFingerprint) {
|
|
3942
|
+
const dynamicInputs = JSON.stringify({
|
|
3943
|
+
instructions: instructionContent,
|
|
3944
|
+
skills: skills.map((s) => s.id).sort(),
|
|
3945
|
+
...toolFingerprint ? { tools: toolFingerprint } : {}
|
|
3946
|
+
});
|
|
3947
|
+
return createHash3("sha256").update(dynamicInputs).digest("hex");
|
|
3948
|
+
}
|
|
3949
|
+
function getToolFingerprint(tools) {
|
|
3950
|
+
return tools.map((t) => `${t.function.name}:${JSON.stringify(t.function.parameters)}`).sort().join("|");
|
|
3951
|
+
}
|
|
3952
|
+
async function computeContextHash(sessionManager, sessionId) {
|
|
3953
|
+
const session = sessionManager.requireSession(sessionId);
|
|
3954
|
+
const { content: instructionContent } = await getAllInstructions(session.workdir, session.projectId);
|
|
3955
|
+
const runtimeConfig = getRuntimeConfig();
|
|
3956
|
+
const configDir = getGlobalConfigDir(runtimeConfig.mode ?? "production");
|
|
3957
|
+
const skills = await getEnabledSkillMetadata(configDir, runtimeConfig.workdir);
|
|
3958
|
+
const { createToolRegistry: createToolRegistry2 } = await import("./tools-WEE4XDTL.js");
|
|
3959
|
+
const allTools = createToolRegistry2().definitions;
|
|
3960
|
+
const toolFingerprint = getToolFingerprint(allTools);
|
|
3961
|
+
const hash = computeDynamicContextHash(instructionContent, skills, toolFingerprint);
|
|
3962
|
+
return { hash, instructionContent, skills, allTools };
|
|
3963
|
+
}
|
|
3964
|
+
async function applyDynamicContext(sessionManager, sessionId) {
|
|
3965
|
+
const { hash, instructionContent, skills, allTools } = await computeContextHash(sessionManager, sessionId);
|
|
3966
|
+
const allAgents = await loadAllAgentsDefault();
|
|
3967
|
+
const subAgentDefs = getSubAgents(allAgents);
|
|
3968
|
+
const systemPrompt = buildTopLevelSystemPrompt(
|
|
3969
|
+
sessionManager.requireSession(sessionId).workdir,
|
|
3970
|
+
instructionContent || void 0,
|
|
3971
|
+
skills,
|
|
3972
|
+
subAgentDefs
|
|
3973
|
+
);
|
|
3974
|
+
sessionManager.setCachedPrompt(sessionId, systemPrompt, allTools, hash);
|
|
3975
|
+
sessionManager.setDynamicContextChanged(sessionId, false);
|
|
3976
|
+
sessionManager.clearDebugDump(sessionId);
|
|
3977
|
+
logger.debug("applyDynamicContext done", { sessionId, hash, toolCount: allTools.length });
|
|
3978
|
+
}
|
|
3979
|
+
|
|
3980
|
+
// src/server/tools/mcp-config.ts
|
|
3981
|
+
var mcpManagerForTools = null;
|
|
3982
|
+
var mcpConfigMode = "production";
|
|
3983
|
+
var mcpNotifyChanged = null;
|
|
3984
|
+
function setMcpManagerForTools(manager) {
|
|
3985
|
+
mcpManagerForTools = manager;
|
|
3986
|
+
}
|
|
3987
|
+
function setMcpConfigMode(mode) {
|
|
3988
|
+
mcpConfigMode = mode;
|
|
3989
|
+
}
|
|
3990
|
+
function setNotifyMcpServersChanged(fn) {
|
|
3991
|
+
mcpNotifyChanged = fn;
|
|
3992
|
+
}
|
|
3993
|
+
var mcpConfigTool = createTool(
|
|
3994
|
+
"mcp_config",
|
|
3995
|
+
{
|
|
3996
|
+
type: "function",
|
|
3997
|
+
function: {
|
|
3998
|
+
name: "mcp_config",
|
|
3999
|
+
description: "Configure MCP servers (Model Context Protocol). Actions: list (show all servers and tools), add (add a server), remove (delete a server), toggle-tool (enable/disable a tool). Use this when the user asks to add, remove, or configure MCP servers or tools.",
|
|
4000
|
+
parameters: {
|
|
4001
|
+
type: "object",
|
|
4002
|
+
properties: {
|
|
4003
|
+
action: {
|
|
4004
|
+
type: "string",
|
|
4005
|
+
enum: ["list", "add", "remove", "toggle-tool"],
|
|
4006
|
+
description: "Action: list (show servers), add (add new server), remove (delete a server), toggle-tool (enable/disable a tool)"
|
|
4007
|
+
},
|
|
4008
|
+
name: {
|
|
4009
|
+
type: "string",
|
|
4010
|
+
description: "Server name (required for: add, remove, toggle-tool)"
|
|
4011
|
+
},
|
|
4012
|
+
transport: {
|
|
4013
|
+
type: "string",
|
|
4014
|
+
enum: ["stdio", "http"],
|
|
4015
|
+
description: "Transport type (for add). Default: stdio"
|
|
4016
|
+
},
|
|
4017
|
+
command: {
|
|
4018
|
+
type: "string",
|
|
4019
|
+
description: 'Command for stdio transport (e.g. "npx")'
|
|
4020
|
+
},
|
|
4021
|
+
args: {
|
|
4022
|
+
type: "array",
|
|
4023
|
+
items: { type: "string" },
|
|
4024
|
+
description: "Command arguments for stdio transport"
|
|
4025
|
+
},
|
|
4026
|
+
env: {
|
|
4027
|
+
type: "object",
|
|
4028
|
+
additionalProperties: { type: "string" },
|
|
4029
|
+
description: "Environment variables for stdio transport"
|
|
4030
|
+
},
|
|
4031
|
+
url: {
|
|
4032
|
+
type: "string",
|
|
4033
|
+
description: 'Server URL for HTTP transport (e.g. "https://mcp.example.com/mcp")'
|
|
4034
|
+
},
|
|
4035
|
+
headers: {
|
|
4036
|
+
type: "object",
|
|
4037
|
+
additionalProperties: { type: "string" },
|
|
4038
|
+
description: 'HTTP headers for HTTP transport (e.g. {"Authorization": "Bearer xxx"})'
|
|
4039
|
+
},
|
|
4040
|
+
toolName: {
|
|
4041
|
+
type: "string",
|
|
4042
|
+
description: "Tool name to toggle (required for: toggle-tool)"
|
|
4043
|
+
},
|
|
4044
|
+
enabled: {
|
|
4045
|
+
type: "boolean",
|
|
4046
|
+
description: "Whether the tool should be enabled (required for: toggle-tool)"
|
|
4047
|
+
}
|
|
4048
|
+
},
|
|
4049
|
+
required: ["action"]
|
|
4050
|
+
}
|
|
4051
|
+
}
|
|
4052
|
+
},
|
|
4053
|
+
async (args, context, helpers) => {
|
|
4054
|
+
const actionError = validateActionWithPermission(
|
|
4055
|
+
args.action,
|
|
4056
|
+
["list", "add", "remove", "toggle-tool"],
|
|
4057
|
+
"mcp_config",
|
|
4058
|
+
context.permittedActions
|
|
4059
|
+
);
|
|
4060
|
+
if (actionError) return actionError;
|
|
4061
|
+
if (!mcpManagerForTools) {
|
|
4062
|
+
return helpers.error("MCP manager not available");
|
|
4063
|
+
}
|
|
4064
|
+
async function persistAndRebuild(updater) {
|
|
4065
|
+
const globalConfig = await loadGlobalConfig(mcpConfigMode);
|
|
4066
|
+
const mcpServers = { ...globalConfig.mcpServers ?? {} };
|
|
4067
|
+
const updated = updater(mcpServers);
|
|
4068
|
+
await saveGlobalConfig(mcpConfigMode, { ...globalConfig, mcpServers: updated });
|
|
4069
|
+
}
|
|
4070
|
+
async function rebuildTools() {
|
|
4071
|
+
const { setMcpTools: setMcpTools2 } = await import("./tools-WEE4XDTL.js");
|
|
4072
|
+
const mcpTools = createMcpTools(mcpManagerForTools);
|
|
4073
|
+
setMcpTools2(mcpTools);
|
|
4074
|
+
}
|
|
4075
|
+
if (args.action === "list") {
|
|
4076
|
+
const servers = mcpManagerForTools.getAllServers();
|
|
4077
|
+
if (servers.length === 0) {
|
|
4078
|
+
return helpers.success("No MCP servers configured.");
|
|
4079
|
+
}
|
|
4080
|
+
const lines = [];
|
|
4081
|
+
for (const server of servers) {
|
|
4082
|
+
const connStr = server.status === "connected" ? "\u25CF" : server.status === "error" ? "\u2717" : "\u25CB";
|
|
4083
|
+
const cmdStr = server.config.command ? `${server.config.command} ${(server.config.args ?? []).join(" ")}` : server.config.url ?? "";
|
|
4084
|
+
lines.push(
|
|
4085
|
+
`${connStr} ${server.name} (${server.config.transport}) \u2014 ${server.status}${server.error ? `: ${server.error}` : ""}`
|
|
4086
|
+
);
|
|
4087
|
+
lines.push(` ${cmdStr}`);
|
|
4088
|
+
lines.push(` ${server.tools.length} tools, ~${server.estimatedTokens} tokens`);
|
|
4089
|
+
const enabledTools = server.tools.filter((t) => t.enabled);
|
|
4090
|
+
const disabledTools = server.tools.filter((t) => !t.enabled);
|
|
4091
|
+
if (enabledTools.length > 0) {
|
|
4092
|
+
lines.push(` Enabled: ${enabledTools.map((t) => t.name).join(", ")}`);
|
|
4093
|
+
}
|
|
4094
|
+
if (disabledTools.length > 0) {
|
|
4095
|
+
lines.push(` Disabled: ${disabledTools.map((t) => t.name).join(", ")}`);
|
|
4096
|
+
}
|
|
4097
|
+
}
|
|
4098
|
+
return helpers.success(lines.join("\n"));
|
|
4099
|
+
}
|
|
4100
|
+
if (args.action === "add") {
|
|
4101
|
+
if (!args.name) return helpers.error("Missing required field: name");
|
|
4102
|
+
if (args.transport === "http") {
|
|
4103
|
+
if (!args.url) return helpers.error("url is required for http transport");
|
|
4104
|
+
} else if (!args.command) {
|
|
4105
|
+
return helpers.error("command is required for stdio transport");
|
|
4106
|
+
}
|
|
4107
|
+
const serverCfg = {
|
|
4108
|
+
transport: args.transport ?? "stdio",
|
|
4109
|
+
...args.command ? { command: args.command } : {},
|
|
4110
|
+
...args.args && args.args.length > 0 ? { args: args.args } : {},
|
|
4111
|
+
...args.env && Object.keys(args.env).length > 0 ? { env: args.env } : {},
|
|
4112
|
+
...args.url ? { url: args.url } : {},
|
|
4113
|
+
...args.headers && Object.keys(args.headers).length > 0 ? { headers: args.headers } : {}
|
|
4114
|
+
};
|
|
4115
|
+
await persistAndRebuild((mcpServers) => {
|
|
4116
|
+
mcpServers[args.name] = serverCfg;
|
|
4117
|
+
return mcpServers;
|
|
4118
|
+
});
|
|
4119
|
+
await mcpManagerForTools.addServer(args.name, serverCfg);
|
|
4120
|
+
await rebuildTools();
|
|
4121
|
+
await applyDynamicContext(context.sessionManager, context.sessionId);
|
|
4122
|
+
mcpNotifyChanged?.(context.sessionId);
|
|
4123
|
+
const server = mcpManagerForTools.getServer(args.name);
|
|
4124
|
+
const toolCount = server?.tools.length ?? 0;
|
|
4125
|
+
return helpers.success(`Added MCP server "${args.name}" (${toolCount} tools discovered).`);
|
|
4126
|
+
}
|
|
4127
|
+
if (args.action === "remove") {
|
|
4128
|
+
if (!args.name) return helpers.error("Missing required field: name");
|
|
4129
|
+
await persistAndRebuild((mcpServers) => {
|
|
4130
|
+
delete mcpServers[args.name];
|
|
4131
|
+
return mcpServers;
|
|
4132
|
+
});
|
|
4133
|
+
mcpManagerForTools.removeServer(args.name);
|
|
4134
|
+
await rebuildTools();
|
|
4135
|
+
await applyDynamicContext(context.sessionManager, context.sessionId);
|
|
4136
|
+
mcpNotifyChanged?.(context.sessionId);
|
|
4137
|
+
return helpers.success(`Removed MCP server "${args.name}".`);
|
|
4138
|
+
}
|
|
4139
|
+
if (args.action === "toggle-tool") {
|
|
4140
|
+
if (!args.name) return helpers.error("Missing required field: name");
|
|
4141
|
+
if (!args.toolName) return helpers.error("Missing required field: toolName");
|
|
4142
|
+
if (args.enabled === void 0) return helpers.error("Missing required field: enabled");
|
|
4143
|
+
const server = mcpManagerForTools.getServer(args.name);
|
|
4144
|
+
const currentDisabled = (server?.tools ?? []).filter((t) => !t.enabled).map((t) => t.name);
|
|
4145
|
+
const afterDisabled = args.enabled ? currentDisabled.filter((n) => n !== args.toolName) : [...currentDisabled, args.toolName];
|
|
4146
|
+
await persistAndRebuild((mcpServers) => {
|
|
4147
|
+
const cfg = mcpServers[args.name];
|
|
4148
|
+
if (cfg) {
|
|
4149
|
+
const updated = { ...cfg };
|
|
4150
|
+
if (afterDisabled.length > 0) {
|
|
4151
|
+
updated.disabledTools = afterDisabled;
|
|
4152
|
+
} else {
|
|
4153
|
+
delete updated.disabledTools;
|
|
4154
|
+
}
|
|
4155
|
+
mcpServers[args.name] = updated;
|
|
4156
|
+
}
|
|
4157
|
+
return mcpServers;
|
|
4158
|
+
});
|
|
4159
|
+
await mcpManagerForTools.setToolEnabled(args.name, args.toolName, args.enabled);
|
|
4160
|
+
await rebuildTools();
|
|
4161
|
+
await applyDynamicContext(context.sessionManager, context.sessionId);
|
|
4162
|
+
mcpNotifyChanged?.(context.sessionId);
|
|
4163
|
+
return helpers.success(
|
|
4164
|
+
`Tool "${args.toolName}" ${args.enabled ? "enabled" : "disabled"} on server "${args.name}".`
|
|
4165
|
+
);
|
|
4166
|
+
}
|
|
4167
|
+
return helpers.error("Unexpected error");
|
|
4168
|
+
}
|
|
4169
|
+
);
|
|
4170
|
+
|
|
3922
4171
|
// src/server/tools/index.ts
|
|
3923
4172
|
function parseToolPermissions(allowedTools) {
|
|
3924
4173
|
const result = {};
|
|
@@ -4075,7 +4324,8 @@ function getAllToolsMap() {
|
|
|
4075
4324
|
webFetchTool,
|
|
4076
4325
|
devServerTool,
|
|
4077
4326
|
stepDoneTool,
|
|
4078
|
-
backgroundProcessTool
|
|
4327
|
+
backgroundProcessTool,
|
|
4328
|
+
mcpConfigTool
|
|
4079
4329
|
].map((t) => [t.name, t]);
|
|
4080
4330
|
const mcpEntries = mcpToolsOverride.map((t) => [t.name, t]);
|
|
4081
4331
|
return new Map([...builtInTools, ...mcpEntries]);
|
|
@@ -4183,6 +4433,12 @@ export {
|
|
|
4183
4433
|
executeSubAgent,
|
|
4184
4434
|
devServerManager,
|
|
4185
4435
|
stepDoneTool,
|
|
4436
|
+
computeDynamicContextHash,
|
|
4437
|
+
getToolFingerprint,
|
|
4438
|
+
applyDynamicContext,
|
|
4439
|
+
setMcpManagerForTools,
|
|
4440
|
+
setMcpConfigMode,
|
|
4441
|
+
setNotifyMcpServersChanged,
|
|
4186
4442
|
parseToolPermissions,
|
|
4187
4443
|
getToolPermissions,
|
|
4188
4444
|
validateToolAction,
|
|
@@ -4192,4 +4448,4 @@ export {
|
|
|
4192
4448
|
getToolRegistryForAgent,
|
|
4193
4449
|
createToolRegistry
|
|
4194
4450
|
};
|
|
4195
|
-
//# sourceMappingURL=chunk-
|
|
4451
|
+
//# sourceMappingURL=chunk-KPKSN362.js.map
|
|
@@ -67,6 +67,7 @@ var mcpServerSchema = z.object({
|
|
|
67
67
|
args: z.array(z.string()).optional(),
|
|
68
68
|
env: z.record(z.string(), z.string()).optional(),
|
|
69
69
|
url: z.string().optional(),
|
|
70
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
70
71
|
disabledTools: z.array(z.string()).optional()
|
|
71
72
|
});
|
|
72
73
|
var defaultVisionFallback = { enabled: false, url: "http://localhost:11434", model: "qwen3.5:0.8b", timeout: 120 };
|
|
@@ -435,4 +436,4 @@ export {
|
|
|
435
436
|
activateProvider,
|
|
436
437
|
mergeConfigs
|
|
437
438
|
};
|
|
438
|
-
//# sourceMappingURL=chunk-
|
|
439
|
+
//# sourceMappingURL=chunk-SNQT7LNU.js.map
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PathAccessDeniedError,
|
|
3
3
|
assembleAgentRequest,
|
|
4
|
+
computeDynamicContextHash,
|
|
4
5
|
createAssemblyResult,
|
|
6
|
+
createToolRegistry,
|
|
5
7
|
findAgentById,
|
|
6
8
|
getAllInstructions,
|
|
7
9
|
getConversationMessages,
|
|
8
10
|
getEnabledSkillMetadata,
|
|
9
11
|
getSubAgents,
|
|
12
|
+
getToolFingerprint,
|
|
10
13
|
getToolRegistryForAgent,
|
|
11
14
|
loadAllAgentsDefault,
|
|
12
15
|
processEventsForConversation,
|
|
13
16
|
runTopLevelAgentLoop
|
|
14
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-KPKSN362.js";
|
|
15
18
|
import {
|
|
16
19
|
TurnMetrics,
|
|
17
20
|
WORKFLOW_KICKOFF_PROMPT,
|
|
@@ -36,17 +39,6 @@ import {
|
|
|
36
39
|
logger
|
|
37
40
|
} from "./chunk-K44MW7JJ.js";
|
|
38
41
|
|
|
39
|
-
// src/server/chat/dynamic-context.ts
|
|
40
|
-
import { createHash } from "crypto";
|
|
41
|
-
function computeDynamicContextHash(instructionContent, skills, toolFingerprint) {
|
|
42
|
-
const dynamicInputs = JSON.stringify({
|
|
43
|
-
instructions: instructionContent,
|
|
44
|
-
skills: skills.map((s) => s.id).sort(),
|
|
45
|
-
...toolFingerprint ? { tools: toolFingerprint } : {}
|
|
46
|
-
});
|
|
47
|
-
return createHash("sha256").update(dynamicInputs).digest("hex");
|
|
48
|
-
}
|
|
49
|
-
|
|
50
42
|
// src/server/chat/orchestrator.ts
|
|
51
43
|
async function buildRetryPatterns() {
|
|
52
44
|
const { getSetting, SETTINGS_KEYS } = await import("./settings-6XX56F3F.js");
|
|
@@ -238,17 +230,30 @@ async function runAgentTurn(options, turnMetrics, agentId, append, callbacks) {
|
|
|
238
230
|
onMessage: options.onMessage,
|
|
239
231
|
assembleRequest: (input) => {
|
|
240
232
|
const cached = options.sessionManager.getCachedPrompt(options.sessionId);
|
|
241
|
-
const
|
|
233
|
+
const liveTools = createToolRegistry().definitions;
|
|
234
|
+
const toolFingerprint = getToolFingerprint(liveTools);
|
|
242
235
|
if (cached) {
|
|
243
236
|
const currentHash = computeDynamicContextHash(instructionContent ?? "", skills, toolFingerprint);
|
|
244
237
|
if (cached.hash !== currentHash) {
|
|
238
|
+
logger.debug("assembleRequest: hash mismatch", {
|
|
239
|
+
sessionId: options.sessionId,
|
|
240
|
+
cachedHash: cached.hash,
|
|
241
|
+
currentHash,
|
|
242
|
+
cachedTools: cached.tools.map((t) => t.function.name),
|
|
243
|
+
liveTools: liveTools.map((t) => t.function.name)
|
|
244
|
+
});
|
|
245
245
|
options.sessionManager.setDynamicContextChanged(options.sessionId, true);
|
|
246
|
+
options.sessionManager.setDebugDump(options.sessionId, {
|
|
247
|
+
cachedPrompt: cached.systemPrompt.slice(0, 5e3),
|
|
248
|
+
cachedTools: cached.tools.map((t) => t.function.name),
|
|
249
|
+
liveTools: liveTools.map((t) => t.function.name)
|
|
250
|
+
});
|
|
246
251
|
}
|
|
247
252
|
return createAssemblyResult({
|
|
248
253
|
systemPrompt: cached.systemPrompt,
|
|
249
254
|
messages: input.messages,
|
|
250
255
|
injectedFiles: input.injectedFiles,
|
|
251
|
-
requestTools: cached.tools.length > 0 ? cached.tools :
|
|
256
|
+
requestTools: cached.tools.length > 0 ? cached.tools : liveTools,
|
|
252
257
|
toolChoice: input.toolChoice
|
|
253
258
|
});
|
|
254
259
|
}
|
|
@@ -311,9 +316,8 @@ function buildSnapshot(sessionManager, sessionId, _lastStats) {
|
|
|
311
316
|
}
|
|
312
317
|
|
|
313
318
|
export {
|
|
314
|
-
computeDynamicContextHash,
|
|
315
319
|
runChatTurn,
|
|
316
320
|
runAgentTurn,
|
|
317
321
|
injectWorkflowKickoffIfNeeded
|
|
318
322
|
};
|
|
319
|
-
//# sourceMappingURL=chunk-
|
|
323
|
+
//# sourceMappingURL=chunk-Z64KW2HD.js.map
|
package/dist/cli/dev.js
CHANGED