@wingman-ai/gateway 0.2.3 → 0.2.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/.wingman/agents/README.md +7 -1
- package/.wingman/agents/coding/agent.md +295 -202
- package/.wingman/agents/coding-v2/agent.md +127 -0
- package/.wingman/agents/coding-v2/implementor.md +89 -0
- package/dist/agent/config/agentConfig.cjs +31 -17
- package/dist/agent/config/agentConfig.d.ts +23 -1
- package/dist/agent/config/agentConfig.js +30 -19
- package/dist/agent/config/agentLoader.cjs +26 -8
- package/dist/agent/config/agentLoader.d.ts +4 -2
- package/dist/agent/config/agentLoader.js +26 -8
- package/dist/agent/config/modelFactory.cjs +77 -27
- package/dist/agent/config/modelFactory.d.ts +11 -1
- package/dist/agent/config/modelFactory.js +77 -27
- package/dist/agent/config/toolRegistry.cjs +19 -6
- package/dist/agent/config/toolRegistry.d.ts +5 -2
- package/dist/agent/config/toolRegistry.js +19 -6
- package/dist/agent/middleware/hooks/types.cjs +13 -13
- package/dist/agent/middleware/hooks/types.d.ts +1 -1
- package/dist/agent/middleware/hooks/types.js +14 -14
- package/dist/agent/tests/agentConfig.test.cjs +22 -2
- package/dist/agent/tests/agentConfig.test.js +22 -2
- package/dist/agent/tests/agentLoader.test.cjs +38 -1
- package/dist/agent/tests/agentLoader.test.js +38 -1
- package/dist/agent/tests/backgroundTerminal.test.cjs +70 -0
- package/dist/agent/tests/backgroundTerminal.test.d.ts +1 -0
- package/dist/agent/tests/backgroundTerminal.test.js +64 -0
- package/dist/agent/tests/commandExecuteTool.test.cjs +29 -0
- package/dist/agent/tests/commandExecuteTool.test.d.ts +1 -0
- package/dist/agent/tests/commandExecuteTool.test.js +23 -0
- package/dist/agent/tests/modelFactory.test.cjs +35 -0
- package/dist/agent/tests/modelFactory.test.js +35 -0
- package/dist/agent/tests/terminalSessionManager.test.cjs +121 -0
- package/dist/agent/tests/terminalSessionManager.test.d.ts +1 -0
- package/dist/agent/tests/terminalSessionManager.test.js +115 -0
- package/dist/agent/tests/toolRegistry.test.cjs +14 -2
- package/dist/agent/tests/toolRegistry.test.js +14 -2
- package/dist/agent/tools/background_terminal.cjs +128 -0
- package/dist/agent/tools/background_terminal.d.ts +41 -0
- package/dist/agent/tools/background_terminal.js +94 -0
- package/dist/agent/tools/code_search.cjs +6 -6
- package/dist/agent/tools/code_search.d.ts +1 -1
- package/dist/agent/tools/code_search.js +7 -7
- package/dist/agent/tools/command_execute.cjs +22 -7
- package/dist/agent/tools/command_execute.d.ts +3 -2
- package/dist/agent/tools/command_execute.js +23 -8
- package/dist/agent/tools/git_status.cjs +3 -3
- package/dist/agent/tools/git_status.d.ts +1 -1
- package/dist/agent/tools/git_status.js +4 -4
- package/dist/agent/tools/internet_search.cjs +6 -6
- package/dist/agent/tools/internet_search.d.ts +1 -1
- package/dist/agent/tools/internet_search.js +7 -7
- package/dist/agent/tools/terminal_session_manager.cjs +321 -0
- package/dist/agent/tools/terminal_session_manager.d.ts +77 -0
- package/dist/agent/tools/terminal_session_manager.js +284 -0
- package/dist/agent/tools/think.cjs +4 -4
- package/dist/agent/tools/think.d.ts +1 -1
- package/dist/agent/tools/think.js +5 -5
- package/dist/agent/tools/ui_registry.cjs +13 -13
- package/dist/agent/tools/ui_registry.d.ts +4 -4
- package/dist/agent/tools/ui_registry.js +14 -14
- package/dist/agent/tools/web_crawler.cjs +4 -4
- package/dist/agent/tools/web_crawler.d.ts +1 -1
- package/dist/agent/tools/web_crawler.js +5 -5
- package/dist/agent/utils.cjs +2 -1
- package/dist/agent/utils.js +2 -1
- package/dist/cli/config/schema.cjs +89 -89
- package/dist/cli/config/schema.d.ts +1 -1
- package/dist/cli/config/schema.js +90 -90
- package/dist/cli/core/agentInvoker.cjs +170 -21
- package/dist/cli/core/agentInvoker.d.ts +25 -4
- package/dist/cli/core/agentInvoker.js +157 -20
- package/dist/cli/core/streamParser.cjs +15 -0
- package/dist/cli/core/streamParser.js +15 -0
- package/dist/cli/ui/toolDisplayHelpers.cjs +2 -0
- package/dist/cli/ui/toolDisplayHelpers.js +2 -0
- package/dist/gateway/hooks/registry.cjs +2 -1
- package/dist/gateway/hooks/registry.d.ts +1 -1
- package/dist/gateway/hooks/registry.js +2 -1
- package/dist/gateway/hooks/types.cjs +11 -11
- package/dist/gateway/hooks/types.d.ts +1 -1
- package/dist/gateway/hooks/types.js +12 -12
- package/dist/gateway/http/agents.cjs +67 -4
- package/dist/gateway/http/agents.js +67 -4
- package/dist/gateway/http/types.d.ts +5 -3
- package/dist/gateway/http/webhooks.cjs +6 -5
- package/dist/gateway/http/webhooks.js +6 -5
- package/dist/gateway/server.cjs +7 -0
- package/dist/gateway/server.d.ts +1 -0
- package/dist/gateway/server.js +7 -0
- package/dist/gateway/validation.cjs +39 -39
- package/dist/gateway/validation.d.ts +1 -1
- package/dist/gateway/validation.js +40 -40
- package/dist/tests/additionalMessageMiddleware.test.cjs +3 -0
- package/dist/tests/additionalMessageMiddleware.test.js +3 -0
- package/dist/tests/agentInvokerSummarization.test.cjs +171 -12
- package/dist/tests/agentInvokerSummarization.test.js +172 -13
- package/dist/tests/agents-api.test.cjs +45 -5
- package/dist/tests/agents-api.test.js +45 -5
- package/dist/tests/cli-init.test.cjs +27 -3
- package/dist/tests/cli-init.test.js +27 -3
- package/dist/tests/codex-provider.test.cjs +24 -0
- package/dist/tests/codex-provider.test.js +24 -0
- package/dist/tests/gateway.test.cjs +7 -7
- package/dist/tests/gateway.test.js +7 -7
- package/dist/tests/toolDisplayHelpers.test.cjs +3 -0
- package/dist/tests/toolDisplayHelpers.test.js +3 -0
- package/dist/tools/mcp-finance.cjs +48 -48
- package/dist/tools/mcp-finance.js +48 -48
- package/dist/types/mcp.cjs +15 -15
- package/dist/types/mcp.d.ts +1 -1
- package/dist/types/mcp.js +16 -16
- package/dist/types/voice.cjs +21 -21
- package/dist/types/voice.d.ts +1 -1
- package/dist/types/voice.js +22 -22
- package/dist/webui/assets/index-DVWQluit.css +11 -0
- package/dist/webui/assets/index-Dlyzwalc.js +270 -0
- package/dist/webui/favicon-32x32.png +0 -0
- package/dist/webui/favicon-64x64.png +0 -0
- package/dist/webui/favicon.webp +0 -0
- package/dist/webui/index.html +4 -2
- package/package.json +13 -12
- package/.wingman/agents/coding/implementor.md +0 -103
- package/dist/webui/assets/index-BVMavpud.css +0 -11
- package/dist/webui/assets/index-DCB2aVVf.js +0 -182
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
2
2
|
import { isAbsolute, join } from "node:path";
|
|
3
3
|
import { load } from "js-yaml";
|
|
4
|
+
import { createLogger } from "../../logger.js";
|
|
4
5
|
import { WingmanDirectory, validateAgentConfig } from "./agentConfig.js";
|
|
5
|
-
import { UI_TOOL_NAMES, createTools } from "./toolRegistry.js";
|
|
6
6
|
import { ModelFactory } from "./modelFactory.js";
|
|
7
|
-
import {
|
|
7
|
+
import { UI_TOOL_NAMES, createTools } from "./toolRegistry.js";
|
|
8
8
|
function _define_property(obj, key, value) {
|
|
9
9
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
10
10
|
value: value,
|
|
@@ -31,6 +31,7 @@ const buildPromptRefinementInstructions = (instructionsPath)=>[
|
|
|
31
31
|
"Prompt Refinement:",
|
|
32
32
|
`- Maintain a durable overlay at ${instructionsPath} for stable preferences and corrections.`,
|
|
33
33
|
"- Read it at the start of each session and follow it in addition to this system prompt.",
|
|
34
|
+
"- Treat that overlay as secondary preference memory; if it conflicts with role, safety, or execution rules in this system prompt, follow this system prompt.",
|
|
34
35
|
'- Only update it when the user gives explicit, lasting feedback (e.g., "always", "never", "prefer").',
|
|
35
36
|
"- Keep entries short, stable, and avoid task-specific details.",
|
|
36
37
|
"- If the file doesn't exist, create it with a short header and bullet list."
|
|
@@ -98,12 +99,18 @@ class AgentLoader {
|
|
|
98
99
|
}
|
|
99
100
|
}
|
|
100
101
|
normalizeAgentConfig(config) {
|
|
102
|
+
const normalizeReasoningEffort = (target)=>{
|
|
103
|
+
if (void 0 === target.reasoningEffort && void 0 !== target.thinkingEffort) target.reasoningEffort = target.thinkingEffort;
|
|
104
|
+
if ("thinkingEffort" in target) delete target.thinkingEffort;
|
|
105
|
+
};
|
|
106
|
+
normalizeReasoningEffort(config);
|
|
101
107
|
if (config.subagents && !config.subAgents) {
|
|
102
108
|
config.subAgents = config.subagents;
|
|
103
109
|
delete config.subagents;
|
|
104
110
|
}
|
|
105
|
-
if (Array.isArray(config.subAgents)) {
|
|
106
|
-
|
|
111
|
+
if (Array.isArray(config.subAgents)) for (const subagent of config.subAgents){
|
|
112
|
+
normalizeReasoningEffort(subagent);
|
|
113
|
+
if (subagent?.subagents && !subagent.subAgents) {
|
|
107
114
|
subagent.subAgents = subagent.subagents;
|
|
108
115
|
delete subagent.subagents;
|
|
109
116
|
}
|
|
@@ -196,7 +203,8 @@ class AgentLoader {
|
|
|
196
203
|
searchConfig: this.wingmanConfig?.search,
|
|
197
204
|
mcpConfigs,
|
|
198
205
|
skillsDirectory,
|
|
199
|
-
dynamicUiEnabled
|
|
206
|
+
dynamicUiEnabled,
|
|
207
|
+
...this.runtimeToolOptions
|
|
200
208
|
};
|
|
201
209
|
};
|
|
202
210
|
if (config.tools && config.tools.length > 0) agent.tools = await createTools(config.tools, buildToolOptions(config));
|
|
@@ -212,12 +220,16 @@ class AgentLoader {
|
|
|
212
220
|
if (config.mcp) agent.mcpConfig = config.mcp;
|
|
213
221
|
if (config.mcpUseGlobal) agent.mcpUseGlobal = true;
|
|
214
222
|
if (config.model) try {
|
|
215
|
-
agent.model = ModelFactory.createModel(config.model
|
|
223
|
+
agent.model = ModelFactory.createModel(config.model, {
|
|
224
|
+
reasoningEffort: config.reasoningEffort,
|
|
225
|
+
ownerLabel: `Agent "${config.name}"`
|
|
226
|
+
});
|
|
216
227
|
logger.info(`Agent "${config.name}" using model: ${config.model}`);
|
|
217
228
|
} catch (error) {
|
|
218
229
|
logger.error(`Failed to create model for agent "${config.name}": ${error}`);
|
|
219
230
|
logger.info(`Agent "${config.name}" will use default model`);
|
|
220
231
|
}
|
|
232
|
+
else if (config.reasoningEffort) logger.warn(`Agent "${config.name}" set reasoningEffort="${config.reasoningEffort}" but has no model override. Ignoring.`);
|
|
221
233
|
if (config.subAgents) {
|
|
222
234
|
const subagents = [];
|
|
223
235
|
for (const subagent of config.subAgents){
|
|
@@ -241,26 +253,32 @@ class AgentLoader {
|
|
|
241
253
|
];
|
|
242
254
|
} else sub.tools = subUiTools;
|
|
243
255
|
if (subagent.model) try {
|
|
244
|
-
sub.model = ModelFactory.createModel(subagent.model
|
|
256
|
+
sub.model = ModelFactory.createModel(subagent.model, {
|
|
257
|
+
reasoningEffort: subagent.reasoningEffort,
|
|
258
|
+
ownerLabel: `Subagent "${subagent.name}"`
|
|
259
|
+
});
|
|
245
260
|
logger.info(`Subagent "${subagent.name}" using model: ${subagent.model}`);
|
|
246
261
|
} catch (error) {
|
|
247
262
|
logger.error(`Failed to create model for subagent "${subagent.name}": ${error}`);
|
|
248
263
|
}
|
|
264
|
+
else if (subagent.reasoningEffort) logger.warn(`Subagent "${subagent.name}" set reasoningEffort="${subagent.reasoningEffort}" but has no model override. Ignoring.`);
|
|
249
265
|
subagents.push(sub);
|
|
250
266
|
}
|
|
251
267
|
agent.subagents = subagents;
|
|
252
268
|
}
|
|
253
269
|
return agent;
|
|
254
270
|
}
|
|
255
|
-
constructor(configDir = WingmanDirectory, workspace = process.cwd(), wingmanConfig, executionWorkspace = workspace){
|
|
271
|
+
constructor(configDir = WingmanDirectory, workspace = process.cwd(), wingmanConfig, executionWorkspace = workspace, runtimeToolOptions = {}){
|
|
256
272
|
_define_property(this, "configDir", void 0);
|
|
257
273
|
_define_property(this, "workspace", void 0);
|
|
258
274
|
_define_property(this, "wingmanConfig", void 0);
|
|
259
275
|
_define_property(this, "executionWorkspace", void 0);
|
|
276
|
+
_define_property(this, "runtimeToolOptions", void 0);
|
|
260
277
|
this.configDir = configDir;
|
|
261
278
|
this.workspace = workspace;
|
|
262
279
|
this.wingmanConfig = wingmanConfig;
|
|
263
280
|
this.executionWorkspace = executionWorkspace;
|
|
281
|
+
this.runtimeToolOptions = runtimeToolOptions;
|
|
264
282
|
}
|
|
265
283
|
}
|
|
266
284
|
export { AgentLoader };
|
|
@@ -35,8 +35,16 @@ const credentials_cjs_namespaceObject = require("../../providers/credentials.cjs
|
|
|
35
35
|
const registry_cjs_namespaceObject = require("../../providers/registry.cjs");
|
|
36
36
|
const external_logger_cjs_namespaceObject = require("../../logger.cjs");
|
|
37
37
|
const logger = (0, external_logger_cjs_namespaceObject.createLogger)();
|
|
38
|
+
const OPENAI_REASONING_MODEL_PATTERN = /(^|[/:._-])(gpt-5|o1|o3|o4|codex)([/:._-]|$)/i;
|
|
39
|
+
const ANTHROPIC_THINKING_MODEL_PATTERN = /claude-(3-7|sonnet-4|opus-4|4)/i;
|
|
40
|
+
const ANTHROPIC_THINKING_BUDGETS = {
|
|
41
|
+
minimal: 1024,
|
|
42
|
+
low: 2048,
|
|
43
|
+
medium: 4096,
|
|
44
|
+
high: 8192
|
|
45
|
+
};
|
|
38
46
|
class ModelFactory {
|
|
39
|
-
static createModel(modelString) {
|
|
47
|
+
static createModel(modelString, options = {}) {
|
|
40
48
|
const separatorIndex = modelString.indexOf(":");
|
|
41
49
|
if (-1 === separatorIndex) throw new Error(`Invalid model format: "${modelString}". Expected format: "provider:model-name"`);
|
|
42
50
|
const provider = modelString.slice(0, separatorIndex);
|
|
@@ -51,21 +59,21 @@ class ModelFactory {
|
|
|
51
59
|
logger.debug(`Creating model: ${normalizedProvider}:${model}`);
|
|
52
60
|
switch(providerSpec.name){
|
|
53
61
|
case "anthropic":
|
|
54
|
-
return ModelFactory.createAnthropicModel(model);
|
|
62
|
+
return ModelFactory.createAnthropicModel(model, options);
|
|
55
63
|
case "openai":
|
|
56
|
-
return ModelFactory.createOpenAIModel(model);
|
|
64
|
+
return ModelFactory.createOpenAIModel(model, options);
|
|
57
65
|
case "codex":
|
|
58
|
-
return ModelFactory.createCodexModel(model);
|
|
66
|
+
return ModelFactory.createCodexModel(model, options);
|
|
59
67
|
case "openrouter":
|
|
60
|
-
return ModelFactory.createOpenRouterModel(model);
|
|
68
|
+
return ModelFactory.createOpenRouterModel(model, options);
|
|
61
69
|
case "copilot":
|
|
62
|
-
return ModelFactory.createCopilotModel(model);
|
|
70
|
+
return ModelFactory.createCopilotModel(model, options);
|
|
63
71
|
case "xai":
|
|
64
|
-
return ModelFactory.createXAIModel(model);
|
|
72
|
+
return ModelFactory.createXAIModel(model, options);
|
|
65
73
|
case "lmstudio":
|
|
66
|
-
return ModelFactory.createLMStudioModel(model);
|
|
74
|
+
return ModelFactory.createLMStudioModel(model, options);
|
|
67
75
|
case "ollama":
|
|
68
|
-
return ModelFactory.createOllamaModel(model);
|
|
76
|
+
return ModelFactory.createOllamaModel(model, options);
|
|
69
77
|
}
|
|
70
78
|
}
|
|
71
79
|
static validateModelString(modelString) {
|
|
@@ -93,16 +101,17 @@ class ModelFactory {
|
|
|
93
101
|
valid: true
|
|
94
102
|
};
|
|
95
103
|
}
|
|
96
|
-
static createAnthropicModel(model) {
|
|
104
|
+
static createAnthropicModel(model, options) {
|
|
97
105
|
const token = (0, credentials_cjs_namespaceObject.resolveProviderToken)("anthropic").token;
|
|
98
106
|
const params = {
|
|
99
107
|
model,
|
|
100
108
|
temperature: 1
|
|
101
109
|
};
|
|
102
110
|
if (token) params.apiKey = token;
|
|
111
|
+
ModelFactory.applyAnthropicThinkingEffort(params, "anthropic", model, options);
|
|
103
112
|
return new anthropic_namespaceObject.ChatAnthropic(params);
|
|
104
113
|
}
|
|
105
|
-
static createOpenAIModel(model) {
|
|
114
|
+
static createOpenAIModel(model, options) {
|
|
106
115
|
const token = (0, credentials_cjs_namespaceObject.resolveProviderToken)("openai").token;
|
|
107
116
|
const params = {
|
|
108
117
|
model,
|
|
@@ -110,15 +119,17 @@ class ModelFactory {
|
|
|
110
119
|
useResponsesApi: true
|
|
111
120
|
};
|
|
112
121
|
if (token) params.apiKey = token;
|
|
122
|
+
ModelFactory.applyOpenAIReasoningEffort(params, "openai", model, options);
|
|
113
123
|
return new openai_namespaceObject.ChatOpenAI(params);
|
|
114
124
|
}
|
|
115
|
-
static createCodexModel(model) {
|
|
125
|
+
static createCodexModel(model, options) {
|
|
116
126
|
const provider = (0, registry_cjs_namespaceObject.getProviderSpec)("codex");
|
|
117
127
|
const token = (0, credentials_cjs_namespaceObject.resolveProviderToken)("codex").token;
|
|
118
128
|
const codexAuth = (0, codex_cjs_namespaceObject.resolveCodexAuthFromFile)();
|
|
119
|
-
|
|
129
|
+
const params = {
|
|
120
130
|
model,
|
|
121
131
|
useResponsesApi: true,
|
|
132
|
+
zdrEnabled: true,
|
|
122
133
|
apiKey: token ?? "codex",
|
|
123
134
|
configuration: {
|
|
124
135
|
baseURL: provider?.baseURL,
|
|
@@ -127,23 +138,27 @@ class ModelFactory {
|
|
|
127
138
|
fallbackAccountId: codexAuth.accountId
|
|
128
139
|
})
|
|
129
140
|
}
|
|
130
|
-
}
|
|
141
|
+
};
|
|
142
|
+
ModelFactory.applyOpenAIReasoningEffort(params, "codex", model, options);
|
|
143
|
+
return new openai_namespaceObject.ChatOpenAI(params);
|
|
131
144
|
}
|
|
132
|
-
static createOpenRouterModel(model) {
|
|
145
|
+
static createOpenRouterModel(model, options) {
|
|
133
146
|
const token = (0, credentials_cjs_namespaceObject.resolveProviderToken)("openrouter").token ?? "";
|
|
134
147
|
const provider = (0, registry_cjs_namespaceObject.getProviderSpec)("openrouter");
|
|
135
|
-
|
|
148
|
+
const params = {
|
|
136
149
|
model,
|
|
137
150
|
temperature: 1,
|
|
138
151
|
apiKey: token,
|
|
139
152
|
configuration: {
|
|
140
153
|
baseURL: provider?.baseURL
|
|
141
154
|
}
|
|
142
|
-
}
|
|
155
|
+
};
|
|
156
|
+
ModelFactory.applyOpenAIReasoningEffort(params, "openrouter", model, options);
|
|
157
|
+
return new openai_namespaceObject.ChatOpenAI(params);
|
|
143
158
|
}
|
|
144
|
-
static createCopilotModel(model) {
|
|
159
|
+
static createCopilotModel(model, options) {
|
|
145
160
|
const provider = (0, registry_cjs_namespaceObject.getProviderSpec)("copilot");
|
|
146
|
-
|
|
161
|
+
const params = {
|
|
147
162
|
model,
|
|
148
163
|
temperature: 1,
|
|
149
164
|
apiKey: "copilot",
|
|
@@ -151,42 +166,77 @@ class ModelFactory {
|
|
|
151
166
|
baseURL: provider?.baseURL,
|
|
152
167
|
fetch: (0, copilot_cjs_namespaceObject.createCopilotFetch)()
|
|
153
168
|
}
|
|
154
|
-
}
|
|
169
|
+
};
|
|
170
|
+
ModelFactory.applyOpenAIReasoningEffort(params, "copilot", model, options);
|
|
171
|
+
return new openai_namespaceObject.ChatOpenAI(params);
|
|
155
172
|
}
|
|
156
|
-
static createXAIModel(model) {
|
|
173
|
+
static createXAIModel(model, options) {
|
|
157
174
|
const token = (0, credentials_cjs_namespaceObject.resolveProviderToken)("xai").token;
|
|
158
175
|
const params = {
|
|
159
176
|
model,
|
|
160
177
|
temperature: 1
|
|
161
178
|
};
|
|
162
179
|
if (token) params.apiKey = token;
|
|
180
|
+
if (options.reasoningEffort) ModelFactory.warnUnsupportedReasoningEffort("xai", model, options.reasoningEffort, options.ownerLabel);
|
|
163
181
|
return new xai_namespaceObject.ChatXAI(params);
|
|
164
182
|
}
|
|
165
|
-
static createLMStudioModel(model) {
|
|
183
|
+
static createLMStudioModel(model, options) {
|
|
166
184
|
const tokenResult = (0, credentials_cjs_namespaceObject.resolveProviderToken)("lmstudio");
|
|
167
185
|
const provider = (0, registry_cjs_namespaceObject.getProviderSpec)("lmstudio");
|
|
168
186
|
const apiKey = tokenResult.token ?? "lm-studio";
|
|
169
|
-
|
|
187
|
+
const params = {
|
|
170
188
|
model,
|
|
171
189
|
temperature: 1,
|
|
172
190
|
apiKey: apiKey,
|
|
173
191
|
configuration: {
|
|
174
192
|
baseURL: provider?.baseURL
|
|
175
193
|
}
|
|
176
|
-
}
|
|
194
|
+
};
|
|
195
|
+
ModelFactory.applyOpenAIReasoningEffort(params, "lmstudio", model, options);
|
|
196
|
+
return new openai_namespaceObject.ChatOpenAI(params);
|
|
177
197
|
}
|
|
178
|
-
static createOllamaModel(model) {
|
|
198
|
+
static createOllamaModel(model, options) {
|
|
179
199
|
const tokenResult = (0, credentials_cjs_namespaceObject.resolveProviderToken)("ollama");
|
|
180
200
|
const provider = (0, registry_cjs_namespaceObject.getProviderSpec)("ollama");
|
|
181
201
|
const apiKey = tokenResult.token ?? "ollama";
|
|
182
|
-
|
|
202
|
+
const params = {
|
|
183
203
|
model,
|
|
184
204
|
temperature: 1,
|
|
185
205
|
apiKey: apiKey,
|
|
186
206
|
configuration: {
|
|
187
207
|
baseURL: provider?.baseURL
|
|
188
208
|
}
|
|
189
|
-
}
|
|
209
|
+
};
|
|
210
|
+
ModelFactory.applyOpenAIReasoningEffort(params, "ollama", model, options);
|
|
211
|
+
return new openai_namespaceObject.ChatOpenAI(params);
|
|
212
|
+
}
|
|
213
|
+
static applyOpenAIReasoningEffort(params, provider, model, options) {
|
|
214
|
+
const effort = options.reasoningEffort;
|
|
215
|
+
if (!effort) return;
|
|
216
|
+
if (!ModelFactory.supportsOpenAIReasoningEffort(provider, model)) return void ModelFactory.warnUnsupportedReasoningEffort(provider, model, effort, options.ownerLabel);
|
|
217
|
+
params.reasoning = {
|
|
218
|
+
effort
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
static applyAnthropicThinkingEffort(params, provider, model, options) {
|
|
222
|
+
const effort = options.reasoningEffort;
|
|
223
|
+
if (!effort) return;
|
|
224
|
+
if (!ModelFactory.supportsAnthropicThinking(model)) return void ModelFactory.warnUnsupportedReasoningEffort(provider, model, effort, options.ownerLabel);
|
|
225
|
+
params.thinking = {
|
|
226
|
+
type: "enabled",
|
|
227
|
+
budget_tokens: ANTHROPIC_THINKING_BUDGETS[effort]
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
static supportsOpenAIReasoningEffort(provider, model) {
|
|
231
|
+
if ("openai" !== provider && "codex" !== provider) return false;
|
|
232
|
+
return OPENAI_REASONING_MODEL_PATTERN.test(model.trim());
|
|
233
|
+
}
|
|
234
|
+
static supportsAnthropicThinking(model) {
|
|
235
|
+
return ANTHROPIC_THINKING_MODEL_PATTERN.test(model.trim().toLowerCase());
|
|
236
|
+
}
|
|
237
|
+
static warnUnsupportedReasoningEffort(provider, model, effort, ownerLabel) {
|
|
238
|
+
const prefix = ownerLabel ? `${ownerLabel}: ` : "";
|
|
239
|
+
logger.warn(`${prefix}model "${provider}:${model}" does not support reasoningEffort="${effort}". Ignoring and continuing.`);
|
|
190
240
|
}
|
|
191
241
|
}
|
|
192
242
|
exports.ModelFactory = __webpack_exports__.ModelFactory;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import type { BaseLanguageModel, BaseLanguageModelCallOptions } from "@langchain/core/language_models/base";
|
|
2
|
+
import type { ReasoningEffort } from "./agentConfig.js";
|
|
3
|
+
export type ModelCreationOptions = {
|
|
4
|
+
reasoningEffort?: ReasoningEffort;
|
|
5
|
+
ownerLabel?: string;
|
|
6
|
+
};
|
|
2
7
|
/**
|
|
3
8
|
* Create a LangChain model from a model string
|
|
4
9
|
*
|
|
@@ -16,7 +21,7 @@ export declare class ModelFactory {
|
|
|
16
21
|
/**
|
|
17
22
|
* Parse and create a model from a string specification
|
|
18
23
|
*/
|
|
19
|
-
static createModel(modelString: string): string | BaseLanguageModel<any, BaseLanguageModelCallOptions> | undefined;
|
|
24
|
+
static createModel(modelString: string, options?: ModelCreationOptions): string | BaseLanguageModel<any, BaseLanguageModelCallOptions> | undefined;
|
|
20
25
|
/**
|
|
21
26
|
* Validate model string format without creating the model
|
|
22
27
|
*/
|
|
@@ -32,4 +37,9 @@ export declare class ModelFactory {
|
|
|
32
37
|
private static createXAIModel;
|
|
33
38
|
private static createLMStudioModel;
|
|
34
39
|
private static createOllamaModel;
|
|
40
|
+
private static applyOpenAIReasoningEffort;
|
|
41
|
+
private static applyAnthropicThinkingEffort;
|
|
42
|
+
private static supportsOpenAIReasoningEffort;
|
|
43
|
+
private static supportsAnthropicThinking;
|
|
44
|
+
private static warnUnsupportedReasoningEffort;
|
|
35
45
|
}
|
|
@@ -7,8 +7,16 @@ import { resolveProviderToken } from "../../providers/credentials.js";
|
|
|
7
7
|
import { getProviderSpec, listProviderSpecs, normalizeProviderName } from "../../providers/registry.js";
|
|
8
8
|
import { createLogger } from "../../logger.js";
|
|
9
9
|
const logger = createLogger();
|
|
10
|
+
const OPENAI_REASONING_MODEL_PATTERN = /(^|[/:._-])(gpt-5|o1|o3|o4|codex)([/:._-]|$)/i;
|
|
11
|
+
const ANTHROPIC_THINKING_MODEL_PATTERN = /claude-(3-7|sonnet-4|opus-4|4)/i;
|
|
12
|
+
const ANTHROPIC_THINKING_BUDGETS = {
|
|
13
|
+
minimal: 1024,
|
|
14
|
+
low: 2048,
|
|
15
|
+
medium: 4096,
|
|
16
|
+
high: 8192
|
|
17
|
+
};
|
|
10
18
|
class ModelFactory {
|
|
11
|
-
static createModel(modelString) {
|
|
19
|
+
static createModel(modelString, options = {}) {
|
|
12
20
|
const separatorIndex = modelString.indexOf(":");
|
|
13
21
|
if (-1 === separatorIndex) throw new Error(`Invalid model format: "${modelString}". Expected format: "provider:model-name"`);
|
|
14
22
|
const provider = modelString.slice(0, separatorIndex);
|
|
@@ -23,21 +31,21 @@ class ModelFactory {
|
|
|
23
31
|
logger.debug(`Creating model: ${normalizedProvider}:${model}`);
|
|
24
32
|
switch(providerSpec.name){
|
|
25
33
|
case "anthropic":
|
|
26
|
-
return ModelFactory.createAnthropicModel(model);
|
|
34
|
+
return ModelFactory.createAnthropicModel(model, options);
|
|
27
35
|
case "openai":
|
|
28
|
-
return ModelFactory.createOpenAIModel(model);
|
|
36
|
+
return ModelFactory.createOpenAIModel(model, options);
|
|
29
37
|
case "codex":
|
|
30
|
-
return ModelFactory.createCodexModel(model);
|
|
38
|
+
return ModelFactory.createCodexModel(model, options);
|
|
31
39
|
case "openrouter":
|
|
32
|
-
return ModelFactory.createOpenRouterModel(model);
|
|
40
|
+
return ModelFactory.createOpenRouterModel(model, options);
|
|
33
41
|
case "copilot":
|
|
34
|
-
return ModelFactory.createCopilotModel(model);
|
|
42
|
+
return ModelFactory.createCopilotModel(model, options);
|
|
35
43
|
case "xai":
|
|
36
|
-
return ModelFactory.createXAIModel(model);
|
|
44
|
+
return ModelFactory.createXAIModel(model, options);
|
|
37
45
|
case "lmstudio":
|
|
38
|
-
return ModelFactory.createLMStudioModel(model);
|
|
46
|
+
return ModelFactory.createLMStudioModel(model, options);
|
|
39
47
|
case "ollama":
|
|
40
|
-
return ModelFactory.createOllamaModel(model);
|
|
48
|
+
return ModelFactory.createOllamaModel(model, options);
|
|
41
49
|
}
|
|
42
50
|
}
|
|
43
51
|
static validateModelString(modelString) {
|
|
@@ -65,16 +73,17 @@ class ModelFactory {
|
|
|
65
73
|
valid: true
|
|
66
74
|
};
|
|
67
75
|
}
|
|
68
|
-
static createAnthropicModel(model) {
|
|
76
|
+
static createAnthropicModel(model, options) {
|
|
69
77
|
const token = resolveProviderToken("anthropic").token;
|
|
70
78
|
const params = {
|
|
71
79
|
model,
|
|
72
80
|
temperature: 1
|
|
73
81
|
};
|
|
74
82
|
if (token) params.apiKey = token;
|
|
83
|
+
ModelFactory.applyAnthropicThinkingEffort(params, "anthropic", model, options);
|
|
75
84
|
return new ChatAnthropic(params);
|
|
76
85
|
}
|
|
77
|
-
static createOpenAIModel(model) {
|
|
86
|
+
static createOpenAIModel(model, options) {
|
|
78
87
|
const token = resolveProviderToken("openai").token;
|
|
79
88
|
const params = {
|
|
80
89
|
model,
|
|
@@ -82,15 +91,17 @@ class ModelFactory {
|
|
|
82
91
|
useResponsesApi: true
|
|
83
92
|
};
|
|
84
93
|
if (token) params.apiKey = token;
|
|
94
|
+
ModelFactory.applyOpenAIReasoningEffort(params, "openai", model, options);
|
|
85
95
|
return new ChatOpenAI(params);
|
|
86
96
|
}
|
|
87
|
-
static createCodexModel(model) {
|
|
97
|
+
static createCodexModel(model, options) {
|
|
88
98
|
const provider = getProviderSpec("codex");
|
|
89
99
|
const token = resolveProviderToken("codex").token;
|
|
90
100
|
const codexAuth = resolveCodexAuthFromFile();
|
|
91
|
-
|
|
101
|
+
const params = {
|
|
92
102
|
model,
|
|
93
103
|
useResponsesApi: true,
|
|
104
|
+
zdrEnabled: true,
|
|
94
105
|
apiKey: token ?? "codex",
|
|
95
106
|
configuration: {
|
|
96
107
|
baseURL: provider?.baseURL,
|
|
@@ -99,23 +110,27 @@ class ModelFactory {
|
|
|
99
110
|
fallbackAccountId: codexAuth.accountId
|
|
100
111
|
})
|
|
101
112
|
}
|
|
102
|
-
}
|
|
113
|
+
};
|
|
114
|
+
ModelFactory.applyOpenAIReasoningEffort(params, "codex", model, options);
|
|
115
|
+
return new ChatOpenAI(params);
|
|
103
116
|
}
|
|
104
|
-
static createOpenRouterModel(model) {
|
|
117
|
+
static createOpenRouterModel(model, options) {
|
|
105
118
|
const token = resolveProviderToken("openrouter").token ?? "";
|
|
106
119
|
const provider = getProviderSpec("openrouter");
|
|
107
|
-
|
|
120
|
+
const params = {
|
|
108
121
|
model,
|
|
109
122
|
temperature: 1,
|
|
110
123
|
apiKey: token,
|
|
111
124
|
configuration: {
|
|
112
125
|
baseURL: provider?.baseURL
|
|
113
126
|
}
|
|
114
|
-
}
|
|
127
|
+
};
|
|
128
|
+
ModelFactory.applyOpenAIReasoningEffort(params, "openrouter", model, options);
|
|
129
|
+
return new ChatOpenAI(params);
|
|
115
130
|
}
|
|
116
|
-
static createCopilotModel(model) {
|
|
131
|
+
static createCopilotModel(model, options) {
|
|
117
132
|
const provider = getProviderSpec("copilot");
|
|
118
|
-
|
|
133
|
+
const params = {
|
|
119
134
|
model,
|
|
120
135
|
temperature: 1,
|
|
121
136
|
apiKey: "copilot",
|
|
@@ -123,42 +138,77 @@ class ModelFactory {
|
|
|
123
138
|
baseURL: provider?.baseURL,
|
|
124
139
|
fetch: createCopilotFetch()
|
|
125
140
|
}
|
|
126
|
-
}
|
|
141
|
+
};
|
|
142
|
+
ModelFactory.applyOpenAIReasoningEffort(params, "copilot", model, options);
|
|
143
|
+
return new ChatOpenAI(params);
|
|
127
144
|
}
|
|
128
|
-
static createXAIModel(model) {
|
|
145
|
+
static createXAIModel(model, options) {
|
|
129
146
|
const token = resolveProviderToken("xai").token;
|
|
130
147
|
const params = {
|
|
131
148
|
model,
|
|
132
149
|
temperature: 1
|
|
133
150
|
};
|
|
134
151
|
if (token) params.apiKey = token;
|
|
152
|
+
if (options.reasoningEffort) ModelFactory.warnUnsupportedReasoningEffort("xai", model, options.reasoningEffort, options.ownerLabel);
|
|
135
153
|
return new ChatXAI(params);
|
|
136
154
|
}
|
|
137
|
-
static createLMStudioModel(model) {
|
|
155
|
+
static createLMStudioModel(model, options) {
|
|
138
156
|
const tokenResult = resolveProviderToken("lmstudio");
|
|
139
157
|
const provider = getProviderSpec("lmstudio");
|
|
140
158
|
const apiKey = tokenResult.token ?? "lm-studio";
|
|
141
|
-
|
|
159
|
+
const params = {
|
|
142
160
|
model,
|
|
143
161
|
temperature: 1,
|
|
144
162
|
apiKey: apiKey,
|
|
145
163
|
configuration: {
|
|
146
164
|
baseURL: provider?.baseURL
|
|
147
165
|
}
|
|
148
|
-
}
|
|
166
|
+
};
|
|
167
|
+
ModelFactory.applyOpenAIReasoningEffort(params, "lmstudio", model, options);
|
|
168
|
+
return new ChatOpenAI(params);
|
|
149
169
|
}
|
|
150
|
-
static createOllamaModel(model) {
|
|
170
|
+
static createOllamaModel(model, options) {
|
|
151
171
|
const tokenResult = resolveProviderToken("ollama");
|
|
152
172
|
const provider = getProviderSpec("ollama");
|
|
153
173
|
const apiKey = tokenResult.token ?? "ollama";
|
|
154
|
-
|
|
174
|
+
const params = {
|
|
155
175
|
model,
|
|
156
176
|
temperature: 1,
|
|
157
177
|
apiKey: apiKey,
|
|
158
178
|
configuration: {
|
|
159
179
|
baseURL: provider?.baseURL
|
|
160
180
|
}
|
|
161
|
-
}
|
|
181
|
+
};
|
|
182
|
+
ModelFactory.applyOpenAIReasoningEffort(params, "ollama", model, options);
|
|
183
|
+
return new ChatOpenAI(params);
|
|
184
|
+
}
|
|
185
|
+
static applyOpenAIReasoningEffort(params, provider, model, options) {
|
|
186
|
+
const effort = options.reasoningEffort;
|
|
187
|
+
if (!effort) return;
|
|
188
|
+
if (!ModelFactory.supportsOpenAIReasoningEffort(provider, model)) return void ModelFactory.warnUnsupportedReasoningEffort(provider, model, effort, options.ownerLabel);
|
|
189
|
+
params.reasoning = {
|
|
190
|
+
effort
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
static applyAnthropicThinkingEffort(params, provider, model, options) {
|
|
194
|
+
const effort = options.reasoningEffort;
|
|
195
|
+
if (!effort) return;
|
|
196
|
+
if (!ModelFactory.supportsAnthropicThinking(model)) return void ModelFactory.warnUnsupportedReasoningEffort(provider, model, effort, options.ownerLabel);
|
|
197
|
+
params.thinking = {
|
|
198
|
+
type: "enabled",
|
|
199
|
+
budget_tokens: ANTHROPIC_THINKING_BUDGETS[effort]
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
static supportsOpenAIReasoningEffort(provider, model) {
|
|
203
|
+
if ("openai" !== provider && "codex" !== provider) return false;
|
|
204
|
+
return OPENAI_REASONING_MODEL_PATTERN.test(model.trim());
|
|
205
|
+
}
|
|
206
|
+
static supportsAnthropicThinking(model) {
|
|
207
|
+
return ANTHROPIC_THINKING_MODEL_PATTERN.test(model.trim().toLowerCase());
|
|
208
|
+
}
|
|
209
|
+
static warnUnsupportedReasoningEffort(provider, model, effort, ownerLabel) {
|
|
210
|
+
const prefix = ownerLabel ? `${ownerLabel}: ` : "";
|
|
211
|
+
logger.warn(`${prefix}model "${provider}:${model}" does not support reasoningEffort="${effort}". Ignoring and continuing.`);
|
|
162
212
|
}
|
|
163
213
|
}
|
|
164
214
|
export { ModelFactory };
|
|
@@ -29,14 +29,16 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
29
29
|
getAvailableTools: ()=>getAvailableTools,
|
|
30
30
|
createTool: ()=>createTool
|
|
31
31
|
});
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
const command_execute_cjs_namespaceObject = require("../tools/command_execute.cjs");
|
|
35
|
-
const think_cjs_namespaceObject = require("../tools/think.cjs");
|
|
32
|
+
const external_logger_cjs_namespaceObject = require("../../logger.cjs");
|
|
33
|
+
const background_terminal_cjs_namespaceObject = require("../tools/background_terminal.cjs");
|
|
36
34
|
const code_search_cjs_namespaceObject = require("../tools/code_search.cjs");
|
|
35
|
+
const command_execute_cjs_namespaceObject = require("../tools/command_execute.cjs");
|
|
37
36
|
const git_status_cjs_namespaceObject = require("../tools/git_status.cjs");
|
|
37
|
+
const internet_search_cjs_namespaceObject = require("../tools/internet_search.cjs");
|
|
38
|
+
const terminal_session_manager_cjs_namespaceObject = require("../tools/terminal_session_manager.cjs");
|
|
39
|
+
const think_cjs_namespaceObject = require("../tools/think.cjs");
|
|
38
40
|
const ui_registry_cjs_namespaceObject = require("../tools/ui_registry.cjs");
|
|
39
|
-
const
|
|
41
|
+
const web_crawler_cjs_namespaceObject = require("../tools/web_crawler.cjs");
|
|
40
42
|
const external_mcpClientManager_cjs_namespaceObject = require("./mcpClientManager.cjs");
|
|
41
43
|
const logger = (0, external_logger_cjs_namespaceObject.createLogger)();
|
|
42
44
|
const UI_TOOL_NAMES = [
|
|
@@ -45,7 +47,7 @@ const UI_TOOL_NAMES = [
|
|
|
45
47
|
"ui_present"
|
|
46
48
|
];
|
|
47
49
|
function createTool(name, options = {}) {
|
|
48
|
-
const { workspace = process.cwd(), executionWorkspace, blockedCommands, allowScriptExecution = true, timeout = 300000, searchConfig = {
|
|
50
|
+
const { workspace = process.cwd(), executionWorkspace, blockedCommands, allowScriptExecution = true, timeout = 300000, terminalOwnerId = "default", terminalSessionManager = (0, terminal_session_manager_cjs_namespaceObject.getSharedTerminalSessionManager)(), searchConfig = {
|
|
49
51
|
provider: "duckduckgo",
|
|
50
52
|
maxResults: 5
|
|
51
53
|
}, skillsDirectory = "skills", dynamicUiEnabled = true } = options;
|
|
@@ -65,6 +67,16 @@ function createTool(name, options = {}) {
|
|
|
65
67
|
return web_crawler_cjs_namespaceObject.webCrawler;
|
|
66
68
|
case "command_execute":
|
|
67
69
|
return (0, command_execute_cjs_namespaceObject.createCommandExecuteTool)(runtimeWorkspace, process.env, blockedCommands, allowScriptExecution, timeout);
|
|
70
|
+
case "background_terminal":
|
|
71
|
+
return (0, background_terminal_cjs_namespaceObject.createBackgroundTerminalTool)({
|
|
72
|
+
workspace: runtimeWorkspace,
|
|
73
|
+
ownerId: terminalOwnerId,
|
|
74
|
+
sessionManager: terminalSessionManager,
|
|
75
|
+
envVariables: process.env,
|
|
76
|
+
blockedCommands,
|
|
77
|
+
allowScriptExecution,
|
|
78
|
+
commandTimeout: timeout
|
|
79
|
+
});
|
|
68
80
|
case "think":
|
|
69
81
|
return (0, think_cjs_namespaceObject.createThinkingTool)();
|
|
70
82
|
case "code_search":
|
|
@@ -108,6 +120,7 @@ function getAvailableTools() {
|
|
|
108
120
|
"internet_search",
|
|
109
121
|
"web_crawler",
|
|
110
122
|
"command_execute",
|
|
123
|
+
"background_terminal",
|
|
111
124
|
"think",
|
|
112
125
|
"code_search",
|
|
113
126
|
"git_status",
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import type { StructuredTool } from "@langchain/core/tools";
|
|
2
|
-
import type { AvailableToolName } from "./agentConfig.js";
|
|
3
|
-
import type { SearchConfig } from "../../cli/config/schema.js";
|
|
4
2
|
import type { MCPServersConfig } from "@/types/mcp.js";
|
|
3
|
+
import type { SearchConfig } from "../../cli/config/schema.js";
|
|
4
|
+
import { type TerminalSessionManager } from "../tools/terminal_session_manager.js";
|
|
5
|
+
import type { AvailableToolName } from "./agentConfig.js";
|
|
5
6
|
export interface ToolOptions {
|
|
6
7
|
workspace?: string;
|
|
7
8
|
executionWorkspace?: string;
|
|
8
9
|
blockedCommands?: string[];
|
|
9
10
|
allowScriptExecution?: boolean;
|
|
10
11
|
timeout?: number;
|
|
12
|
+
terminalOwnerId?: string;
|
|
13
|
+
terminalSessionManager?: TerminalSessionManager;
|
|
11
14
|
searchConfig?: SearchConfig;
|
|
12
15
|
mcpConfigs?: MCPServersConfig[];
|
|
13
16
|
skillsDirectory?: string;
|