@wingman-ai/gateway 0.2.2 → 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.
Files changed (160) hide show
  1. package/.wingman/agents/README.md +7 -1
  2. package/.wingman/agents/coding/agent.md +299 -201
  3. package/.wingman/agents/coding-v2/agent.md +127 -0
  4. package/.wingman/agents/coding-v2/implementor.md +89 -0
  5. package/.wingman/agents/main/agent.md +4 -0
  6. package/README.md +1 -0
  7. package/dist/agent/config/agentConfig.cjs +31 -17
  8. package/dist/agent/config/agentConfig.d.ts +23 -1
  9. package/dist/agent/config/agentConfig.js +30 -19
  10. package/dist/agent/config/agentLoader.cjs +26 -8
  11. package/dist/agent/config/agentLoader.d.ts +4 -2
  12. package/dist/agent/config/agentLoader.js +26 -8
  13. package/dist/agent/config/modelFactory.cjs +95 -25
  14. package/dist/agent/config/modelFactory.d.ts +13 -1
  15. package/dist/agent/config/modelFactory.js +95 -25
  16. package/dist/agent/config/toolRegistry.cjs +19 -6
  17. package/dist/agent/config/toolRegistry.d.ts +5 -2
  18. package/dist/agent/config/toolRegistry.js +19 -6
  19. package/dist/agent/middleware/hooks/types.cjs +13 -13
  20. package/dist/agent/middleware/hooks/types.d.ts +1 -1
  21. package/dist/agent/middleware/hooks/types.js +14 -14
  22. package/dist/agent/tests/agentConfig.test.cjs +22 -2
  23. package/dist/agent/tests/agentConfig.test.js +22 -2
  24. package/dist/agent/tests/agentLoader.test.cjs +38 -1
  25. package/dist/agent/tests/agentLoader.test.js +38 -1
  26. package/dist/agent/tests/backgroundTerminal.test.cjs +70 -0
  27. package/dist/agent/tests/backgroundTerminal.test.d.ts +1 -0
  28. package/dist/agent/tests/backgroundTerminal.test.js +64 -0
  29. package/dist/agent/tests/commandExecuteTool.test.cjs +29 -0
  30. package/dist/agent/tests/commandExecuteTool.test.d.ts +1 -0
  31. package/dist/agent/tests/commandExecuteTool.test.js +23 -0
  32. package/dist/agent/tests/modelFactory.test.cjs +47 -5
  33. package/dist/agent/tests/modelFactory.test.js +47 -5
  34. package/dist/agent/tests/terminalSessionManager.test.cjs +121 -0
  35. package/dist/agent/tests/terminalSessionManager.test.d.ts +1 -0
  36. package/dist/agent/tests/terminalSessionManager.test.js +115 -0
  37. package/dist/agent/tests/toolRegistry.test.cjs +14 -2
  38. package/dist/agent/tests/toolRegistry.test.js +14 -2
  39. package/dist/agent/tools/background_terminal.cjs +128 -0
  40. package/dist/agent/tools/background_terminal.d.ts +41 -0
  41. package/dist/agent/tools/background_terminal.js +94 -0
  42. package/dist/agent/tools/code_search.cjs +6 -6
  43. package/dist/agent/tools/code_search.d.ts +1 -1
  44. package/dist/agent/tools/code_search.js +7 -7
  45. package/dist/agent/tools/command_execute.cjs +22 -7
  46. package/dist/agent/tools/command_execute.d.ts +3 -2
  47. package/dist/agent/tools/command_execute.js +23 -8
  48. package/dist/agent/tools/git_status.cjs +3 -3
  49. package/dist/agent/tools/git_status.d.ts +1 -1
  50. package/dist/agent/tools/git_status.js +4 -4
  51. package/dist/agent/tools/internet_search.cjs +6 -6
  52. package/dist/agent/tools/internet_search.d.ts +1 -1
  53. package/dist/agent/tools/internet_search.js +7 -7
  54. package/dist/agent/tools/terminal_session_manager.cjs +321 -0
  55. package/dist/agent/tools/terminal_session_manager.d.ts +77 -0
  56. package/dist/agent/tools/terminal_session_manager.js +284 -0
  57. package/dist/agent/tools/think.cjs +4 -4
  58. package/dist/agent/tools/think.d.ts +1 -1
  59. package/dist/agent/tools/think.js +5 -5
  60. package/dist/agent/tools/ui_registry.cjs +13 -13
  61. package/dist/agent/tools/ui_registry.d.ts +4 -4
  62. package/dist/agent/tools/ui_registry.js +14 -14
  63. package/dist/agent/tools/web_crawler.cjs +4 -4
  64. package/dist/agent/tools/web_crawler.d.ts +1 -1
  65. package/dist/agent/tools/web_crawler.js +5 -5
  66. package/dist/agent/utils.cjs +2 -1
  67. package/dist/agent/utils.js +2 -1
  68. package/dist/cli/commands/init.cjs +7 -6
  69. package/dist/cli/commands/init.js +7 -6
  70. package/dist/cli/commands/provider.cjs +17 -3
  71. package/dist/cli/commands/provider.js +17 -3
  72. package/dist/cli/config/loader.cjs +27 -0
  73. package/dist/cli/config/loader.js +27 -0
  74. package/dist/cli/config/schema.cjs +146 -68
  75. package/dist/cli/config/schema.d.ts +89 -1
  76. package/dist/cli/config/schema.js +134 -68
  77. package/dist/cli/core/agentInvoker.cjs +344 -17
  78. package/dist/cli/core/agentInvoker.d.ts +63 -3
  79. package/dist/cli/core/agentInvoker.js +303 -12
  80. package/dist/cli/core/sessionManager.cjs +32 -5
  81. package/dist/cli/core/sessionManager.js +32 -5
  82. package/dist/cli/core/streamParser.cjs +15 -0
  83. package/dist/cli/core/streamParser.js +15 -0
  84. package/dist/cli/index.cjs +6 -5
  85. package/dist/cli/index.js +6 -5
  86. package/dist/cli/types.d.ts +32 -0
  87. package/dist/cli/ui/toolDisplayHelpers.cjs +2 -0
  88. package/dist/cli/ui/toolDisplayHelpers.js +2 -0
  89. package/dist/gateway/hooks/registry.cjs +2 -1
  90. package/dist/gateway/hooks/registry.d.ts +1 -1
  91. package/dist/gateway/hooks/registry.js +2 -1
  92. package/dist/gateway/hooks/types.cjs +11 -11
  93. package/dist/gateway/hooks/types.d.ts +1 -1
  94. package/dist/gateway/hooks/types.js +12 -12
  95. package/dist/gateway/http/agents.cjs +67 -4
  96. package/dist/gateway/http/agents.js +67 -4
  97. package/dist/gateway/http/sessions.cjs +7 -7
  98. package/dist/gateway/http/sessions.js +7 -7
  99. package/dist/gateway/http/types.d.ts +5 -3
  100. package/dist/gateway/http/webhooks.cjs +6 -5
  101. package/dist/gateway/http/webhooks.js +6 -5
  102. package/dist/gateway/server.cjs +198 -41
  103. package/dist/gateway/server.d.ts +9 -1
  104. package/dist/gateway/server.js +198 -41
  105. package/dist/gateway/types.d.ts +1 -0
  106. package/dist/gateway/validation.cjs +39 -39
  107. package/dist/gateway/validation.d.ts +1 -1
  108. package/dist/gateway/validation.js +40 -40
  109. package/dist/providers/codex.cjs +167 -0
  110. package/dist/providers/codex.d.ts +15 -0
  111. package/dist/providers/codex.js +127 -0
  112. package/dist/providers/credentials.cjs +8 -0
  113. package/dist/providers/credentials.js +8 -0
  114. package/dist/providers/registry.cjs +11 -0
  115. package/dist/providers/registry.d.ts +1 -1
  116. package/dist/providers/registry.js +11 -0
  117. package/dist/tests/additionalMessageMiddleware.test.cjs +3 -0
  118. package/dist/tests/additionalMessageMiddleware.test.js +3 -0
  119. package/dist/tests/agentInvokerSummarization.test.cjs +455 -0
  120. package/dist/tests/agentInvokerSummarization.test.d.ts +1 -0
  121. package/dist/tests/agentInvokerSummarization.test.js +449 -0
  122. package/dist/tests/agents-api.test.cjs +45 -5
  123. package/dist/tests/agents-api.test.js +45 -5
  124. package/dist/tests/cli-config-loader.test.cjs +88 -0
  125. package/dist/tests/cli-config-loader.test.js +88 -0
  126. package/dist/tests/cli-init.test.cjs +27 -3
  127. package/dist/tests/cli-init.test.js +27 -3
  128. package/dist/tests/codex-credentials-precedence.test.cjs +94 -0
  129. package/dist/tests/codex-credentials-precedence.test.d.ts +1 -0
  130. package/dist/tests/codex-credentials-precedence.test.js +88 -0
  131. package/dist/tests/codex-provider.test.cjs +210 -0
  132. package/dist/tests/codex-provider.test.d.ts +1 -0
  133. package/dist/tests/codex-provider.test.js +204 -0
  134. package/dist/tests/gateway.test.cjs +115 -8
  135. package/dist/tests/gateway.test.js +115 -8
  136. package/dist/tests/provider-command-codex.test.cjs +57 -0
  137. package/dist/tests/provider-command-codex.test.d.ts +1 -0
  138. package/dist/tests/provider-command-codex.test.js +51 -0
  139. package/dist/tests/sessionStateMessages.test.cjs +38 -0
  140. package/dist/tests/sessionStateMessages.test.js +38 -0
  141. package/dist/tests/toolDisplayHelpers.test.cjs +3 -0
  142. package/dist/tests/toolDisplayHelpers.test.js +3 -0
  143. package/dist/tools/mcp-finance.cjs +48 -48
  144. package/dist/tools/mcp-finance.js +48 -48
  145. package/dist/types/mcp.cjs +15 -15
  146. package/dist/types/mcp.d.ts +1 -1
  147. package/dist/types/mcp.js +16 -16
  148. package/dist/types/voice.cjs +21 -21
  149. package/dist/types/voice.d.ts +1 -1
  150. package/dist/types/voice.js +22 -22
  151. package/dist/webui/assets/index-DVWQluit.css +11 -0
  152. package/dist/webui/assets/index-Dlyzwalc.js +270 -0
  153. package/dist/webui/favicon-32x32.png +0 -0
  154. package/dist/webui/favicon-64x64.png +0 -0
  155. package/dist/webui/favicon.webp +0 -0
  156. package/dist/webui/index.html +4 -2
  157. package/package.json +13 -12
  158. package/.wingman/agents/coding/implementor.md +0 -79
  159. package/dist/webui/assets/index-CPhfGPHc.js +0 -182
  160. package/dist/webui/assets/index-DDsMIOTX.css +0 -11
@@ -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 { createLogger } from "../../logger.js";
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
- for (const subagent of config.subAgents)if (subagent?.subagents && !subagent.subAgents) {
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 };
@@ -29,13 +29,22 @@ __webpack_require__.d(__webpack_exports__, {
29
29
  const anthropic_namespaceObject = require("@langchain/anthropic");
30
30
  const openai_namespaceObject = require("@langchain/openai");
31
31
  const xai_namespaceObject = require("@langchain/xai");
32
- const external_logger_cjs_namespaceObject = require("../../logger.cjs");
33
- const credentials_cjs_namespaceObject = require("../../providers/credentials.cjs");
32
+ const codex_cjs_namespaceObject = require("../../providers/codex.cjs");
34
33
  const copilot_cjs_namespaceObject = require("../../providers/copilot.cjs");
34
+ const credentials_cjs_namespaceObject = require("../../providers/credentials.cjs");
35
35
  const registry_cjs_namespaceObject = require("../../providers/registry.cjs");
36
+ const external_logger_cjs_namespaceObject = require("../../logger.cjs");
36
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
+ };
37
46
  class ModelFactory {
38
- static createModel(modelString) {
47
+ static createModel(modelString, options = {}) {
39
48
  const separatorIndex = modelString.indexOf(":");
40
49
  if (-1 === separatorIndex) throw new Error(`Invalid model format: "${modelString}". Expected format: "provider:model-name"`);
41
50
  const provider = modelString.slice(0, separatorIndex);
@@ -50,19 +59,21 @@ class ModelFactory {
50
59
  logger.debug(`Creating model: ${normalizedProvider}:${model}`);
51
60
  switch(providerSpec.name){
52
61
  case "anthropic":
53
- return ModelFactory.createAnthropicModel(model);
62
+ return ModelFactory.createAnthropicModel(model, options);
54
63
  case "openai":
55
- return ModelFactory.createOpenAIModel(model);
64
+ return ModelFactory.createOpenAIModel(model, options);
65
+ case "codex":
66
+ return ModelFactory.createCodexModel(model, options);
56
67
  case "openrouter":
57
- return ModelFactory.createOpenRouterModel(model);
68
+ return ModelFactory.createOpenRouterModel(model, options);
58
69
  case "copilot":
59
- return ModelFactory.createCopilotModel(model);
70
+ return ModelFactory.createCopilotModel(model, options);
60
71
  case "xai":
61
- return ModelFactory.createXAIModel(model);
72
+ return ModelFactory.createXAIModel(model, options);
62
73
  case "lmstudio":
63
- return ModelFactory.createLMStudioModel(model);
74
+ return ModelFactory.createLMStudioModel(model, options);
64
75
  case "ollama":
65
- return ModelFactory.createOllamaModel(model);
76
+ return ModelFactory.createOllamaModel(model, options);
66
77
  }
67
78
  }
68
79
  static validateModelString(modelString) {
@@ -90,16 +101,17 @@ class ModelFactory {
90
101
  valid: true
91
102
  };
92
103
  }
93
- static createAnthropicModel(model) {
104
+ static createAnthropicModel(model, options) {
94
105
  const token = (0, credentials_cjs_namespaceObject.resolveProviderToken)("anthropic").token;
95
106
  const params = {
96
107
  model,
97
108
  temperature: 1
98
109
  };
99
110
  if (token) params.apiKey = token;
111
+ ModelFactory.applyAnthropicThinkingEffort(params, "anthropic", model, options);
100
112
  return new anthropic_namespaceObject.ChatAnthropic(params);
101
113
  }
102
- static createOpenAIModel(model) {
114
+ static createOpenAIModel(model, options) {
103
115
  const token = (0, credentials_cjs_namespaceObject.resolveProviderToken)("openai").token;
104
116
  const params = {
105
117
  model,
@@ -107,23 +119,46 @@ class ModelFactory {
107
119
  useResponsesApi: true
108
120
  };
109
121
  if (token) params.apiKey = token;
122
+ ModelFactory.applyOpenAIReasoningEffort(params, "openai", model, options);
123
+ return new openai_namespaceObject.ChatOpenAI(params);
124
+ }
125
+ static createCodexModel(model, options) {
126
+ const provider = (0, registry_cjs_namespaceObject.getProviderSpec)("codex");
127
+ const token = (0, credentials_cjs_namespaceObject.resolveProviderToken)("codex").token;
128
+ const codexAuth = (0, codex_cjs_namespaceObject.resolveCodexAuthFromFile)();
129
+ const params = {
130
+ model,
131
+ useResponsesApi: true,
132
+ zdrEnabled: true,
133
+ apiKey: token ?? "codex",
134
+ configuration: {
135
+ baseURL: provider?.baseURL,
136
+ fetch: (0, codex_cjs_namespaceObject.createCodexFetch)({
137
+ fallbackToken: token,
138
+ fallbackAccountId: codexAuth.accountId
139
+ })
140
+ }
141
+ };
142
+ ModelFactory.applyOpenAIReasoningEffort(params, "codex", model, options);
110
143
  return new openai_namespaceObject.ChatOpenAI(params);
111
144
  }
112
- static createOpenRouterModel(model) {
145
+ static createOpenRouterModel(model, options) {
113
146
  const token = (0, credentials_cjs_namespaceObject.resolveProviderToken)("openrouter").token ?? "";
114
147
  const provider = (0, registry_cjs_namespaceObject.getProviderSpec)("openrouter");
115
- return new openai_namespaceObject.ChatOpenAI({
148
+ const params = {
116
149
  model,
117
150
  temperature: 1,
118
151
  apiKey: token,
119
152
  configuration: {
120
153
  baseURL: provider?.baseURL
121
154
  }
122
- });
155
+ };
156
+ ModelFactory.applyOpenAIReasoningEffort(params, "openrouter", model, options);
157
+ return new openai_namespaceObject.ChatOpenAI(params);
123
158
  }
124
- static createCopilotModel(model) {
159
+ static createCopilotModel(model, options) {
125
160
  const provider = (0, registry_cjs_namespaceObject.getProviderSpec)("copilot");
126
- return new openai_namespaceObject.ChatOpenAI({
161
+ const params = {
127
162
  model,
128
163
  temperature: 1,
129
164
  apiKey: "copilot",
@@ -131,42 +166,77 @@ class ModelFactory {
131
166
  baseURL: provider?.baseURL,
132
167
  fetch: (0, copilot_cjs_namespaceObject.createCopilotFetch)()
133
168
  }
134
- });
169
+ };
170
+ ModelFactory.applyOpenAIReasoningEffort(params, "copilot", model, options);
171
+ return new openai_namespaceObject.ChatOpenAI(params);
135
172
  }
136
- static createXAIModel(model) {
173
+ static createXAIModel(model, options) {
137
174
  const token = (0, credentials_cjs_namespaceObject.resolveProviderToken)("xai").token;
138
175
  const params = {
139
176
  model,
140
177
  temperature: 1
141
178
  };
142
179
  if (token) params.apiKey = token;
180
+ if (options.reasoningEffort) ModelFactory.warnUnsupportedReasoningEffort("xai", model, options.reasoningEffort, options.ownerLabel);
143
181
  return new xai_namespaceObject.ChatXAI(params);
144
182
  }
145
- static createLMStudioModel(model) {
183
+ static createLMStudioModel(model, options) {
146
184
  const tokenResult = (0, credentials_cjs_namespaceObject.resolveProviderToken)("lmstudio");
147
185
  const provider = (0, registry_cjs_namespaceObject.getProviderSpec)("lmstudio");
148
186
  const apiKey = tokenResult.token ?? "lm-studio";
149
- return new openai_namespaceObject.ChatOpenAI({
187
+ const params = {
150
188
  model,
151
189
  temperature: 1,
152
190
  apiKey: apiKey,
153
191
  configuration: {
154
192
  baseURL: provider?.baseURL
155
193
  }
156
- });
194
+ };
195
+ ModelFactory.applyOpenAIReasoningEffort(params, "lmstudio", model, options);
196
+ return new openai_namespaceObject.ChatOpenAI(params);
157
197
  }
158
- static createOllamaModel(model) {
198
+ static createOllamaModel(model, options) {
159
199
  const tokenResult = (0, credentials_cjs_namespaceObject.resolveProviderToken)("ollama");
160
200
  const provider = (0, registry_cjs_namespaceObject.getProviderSpec)("ollama");
161
201
  const apiKey = tokenResult.token ?? "ollama";
162
- return new openai_namespaceObject.ChatOpenAI({
202
+ const params = {
163
203
  model,
164
204
  temperature: 1,
165
205
  apiKey: apiKey,
166
206
  configuration: {
167
207
  baseURL: provider?.baseURL
168
208
  }
169
- });
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.`);
170
240
  }
171
241
  }
172
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
  *
@@ -8,6 +13,7 @@ import type { BaseLanguageModel, BaseLanguageModelCallOptions } from "@langchain
8
13
  * - "anthropic:claude-sonnet-4-5"
9
14
  * - "openai:gpt-4o"
10
15
  * - "openai:gpt-4-turbo"
16
+ * - "codex:codex-mini-latest"
11
17
  * - "openrouter:openai/gpt-4o"
12
18
  * - "copilot:gpt-4o"
13
19
  */
@@ -15,7 +21,7 @@ export declare class ModelFactory {
15
21
  /**
16
22
  * Parse and create a model from a string specification
17
23
  */
18
- static createModel(modelString: string): string | BaseLanguageModel<any, BaseLanguageModelCallOptions> | undefined;
24
+ static createModel(modelString: string, options?: ModelCreationOptions): string | BaseLanguageModel<any, BaseLanguageModelCallOptions> | undefined;
19
25
  /**
20
26
  * Validate model string format without creating the model
21
27
  */
@@ -25,9 +31,15 @@ export declare class ModelFactory {
25
31
  };
26
32
  private static createAnthropicModel;
27
33
  private static createOpenAIModel;
34
+ private static createCodexModel;
28
35
  private static createOpenRouterModel;
29
36
  private static createCopilotModel;
30
37
  private static createXAIModel;
31
38
  private static createLMStudioModel;
32
39
  private static createOllamaModel;
40
+ private static applyOpenAIReasoningEffort;
41
+ private static applyAnthropicThinkingEffort;
42
+ private static supportsOpenAIReasoningEffort;
43
+ private static supportsAnthropicThinking;
44
+ private static warnUnsupportedReasoningEffort;
33
45
  }
@@ -1,13 +1,22 @@
1
1
  import { ChatAnthropic } from "@langchain/anthropic";
2
2
  import { ChatOpenAI } from "@langchain/openai";
3
3
  import { ChatXAI } from "@langchain/xai";
4
- import { createLogger } from "../../logger.js";
5
- import { resolveProviderToken } from "../../providers/credentials.js";
4
+ import { createCodexFetch, resolveCodexAuthFromFile } from "../../providers/codex.js";
6
5
  import { createCopilotFetch } from "../../providers/copilot.js";
6
+ import { resolveProviderToken } from "../../providers/credentials.js";
7
7
  import { getProviderSpec, listProviderSpecs, normalizeProviderName } from "../../providers/registry.js";
8
+ import { createLogger } from "../../logger.js";
8
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
+ };
9
18
  class ModelFactory {
10
- static createModel(modelString) {
19
+ static createModel(modelString, options = {}) {
11
20
  const separatorIndex = modelString.indexOf(":");
12
21
  if (-1 === separatorIndex) throw new Error(`Invalid model format: "${modelString}". Expected format: "provider:model-name"`);
13
22
  const provider = modelString.slice(0, separatorIndex);
@@ -22,19 +31,21 @@ class ModelFactory {
22
31
  logger.debug(`Creating model: ${normalizedProvider}:${model}`);
23
32
  switch(providerSpec.name){
24
33
  case "anthropic":
25
- return ModelFactory.createAnthropicModel(model);
34
+ return ModelFactory.createAnthropicModel(model, options);
26
35
  case "openai":
27
- return ModelFactory.createOpenAIModel(model);
36
+ return ModelFactory.createOpenAIModel(model, options);
37
+ case "codex":
38
+ return ModelFactory.createCodexModel(model, options);
28
39
  case "openrouter":
29
- return ModelFactory.createOpenRouterModel(model);
40
+ return ModelFactory.createOpenRouterModel(model, options);
30
41
  case "copilot":
31
- return ModelFactory.createCopilotModel(model);
42
+ return ModelFactory.createCopilotModel(model, options);
32
43
  case "xai":
33
- return ModelFactory.createXAIModel(model);
44
+ return ModelFactory.createXAIModel(model, options);
34
45
  case "lmstudio":
35
- return ModelFactory.createLMStudioModel(model);
46
+ return ModelFactory.createLMStudioModel(model, options);
36
47
  case "ollama":
37
- return ModelFactory.createOllamaModel(model);
48
+ return ModelFactory.createOllamaModel(model, options);
38
49
  }
39
50
  }
40
51
  static validateModelString(modelString) {
@@ -62,16 +73,17 @@ class ModelFactory {
62
73
  valid: true
63
74
  };
64
75
  }
65
- static createAnthropicModel(model) {
76
+ static createAnthropicModel(model, options) {
66
77
  const token = resolveProviderToken("anthropic").token;
67
78
  const params = {
68
79
  model,
69
80
  temperature: 1
70
81
  };
71
82
  if (token) params.apiKey = token;
83
+ ModelFactory.applyAnthropicThinkingEffort(params, "anthropic", model, options);
72
84
  return new ChatAnthropic(params);
73
85
  }
74
- static createOpenAIModel(model) {
86
+ static createOpenAIModel(model, options) {
75
87
  const token = resolveProviderToken("openai").token;
76
88
  const params = {
77
89
  model,
@@ -79,23 +91,46 @@ class ModelFactory {
79
91
  useResponsesApi: true
80
92
  };
81
93
  if (token) params.apiKey = token;
94
+ ModelFactory.applyOpenAIReasoningEffort(params, "openai", model, options);
95
+ return new ChatOpenAI(params);
96
+ }
97
+ static createCodexModel(model, options) {
98
+ const provider = getProviderSpec("codex");
99
+ const token = resolveProviderToken("codex").token;
100
+ const codexAuth = resolveCodexAuthFromFile();
101
+ const params = {
102
+ model,
103
+ useResponsesApi: true,
104
+ zdrEnabled: true,
105
+ apiKey: token ?? "codex",
106
+ configuration: {
107
+ baseURL: provider?.baseURL,
108
+ fetch: createCodexFetch({
109
+ fallbackToken: token,
110
+ fallbackAccountId: codexAuth.accountId
111
+ })
112
+ }
113
+ };
114
+ ModelFactory.applyOpenAIReasoningEffort(params, "codex", model, options);
82
115
  return new ChatOpenAI(params);
83
116
  }
84
- static createOpenRouterModel(model) {
117
+ static createOpenRouterModel(model, options) {
85
118
  const token = resolveProviderToken("openrouter").token ?? "";
86
119
  const provider = getProviderSpec("openrouter");
87
- return new ChatOpenAI({
120
+ const params = {
88
121
  model,
89
122
  temperature: 1,
90
123
  apiKey: token,
91
124
  configuration: {
92
125
  baseURL: provider?.baseURL
93
126
  }
94
- });
127
+ };
128
+ ModelFactory.applyOpenAIReasoningEffort(params, "openrouter", model, options);
129
+ return new ChatOpenAI(params);
95
130
  }
96
- static createCopilotModel(model) {
131
+ static createCopilotModel(model, options) {
97
132
  const provider = getProviderSpec("copilot");
98
- return new ChatOpenAI({
133
+ const params = {
99
134
  model,
100
135
  temperature: 1,
101
136
  apiKey: "copilot",
@@ -103,42 +138,77 @@ class ModelFactory {
103
138
  baseURL: provider?.baseURL,
104
139
  fetch: createCopilotFetch()
105
140
  }
106
- });
141
+ };
142
+ ModelFactory.applyOpenAIReasoningEffort(params, "copilot", model, options);
143
+ return new ChatOpenAI(params);
107
144
  }
108
- static createXAIModel(model) {
145
+ static createXAIModel(model, options) {
109
146
  const token = resolveProviderToken("xai").token;
110
147
  const params = {
111
148
  model,
112
149
  temperature: 1
113
150
  };
114
151
  if (token) params.apiKey = token;
152
+ if (options.reasoningEffort) ModelFactory.warnUnsupportedReasoningEffort("xai", model, options.reasoningEffort, options.ownerLabel);
115
153
  return new ChatXAI(params);
116
154
  }
117
- static createLMStudioModel(model) {
155
+ static createLMStudioModel(model, options) {
118
156
  const tokenResult = resolveProviderToken("lmstudio");
119
157
  const provider = getProviderSpec("lmstudio");
120
158
  const apiKey = tokenResult.token ?? "lm-studio";
121
- return new ChatOpenAI({
159
+ const params = {
122
160
  model,
123
161
  temperature: 1,
124
162
  apiKey: apiKey,
125
163
  configuration: {
126
164
  baseURL: provider?.baseURL
127
165
  }
128
- });
166
+ };
167
+ ModelFactory.applyOpenAIReasoningEffort(params, "lmstudio", model, options);
168
+ return new ChatOpenAI(params);
129
169
  }
130
- static createOllamaModel(model) {
170
+ static createOllamaModel(model, options) {
131
171
  const tokenResult = resolveProviderToken("ollama");
132
172
  const provider = getProviderSpec("ollama");
133
173
  const apiKey = tokenResult.token ?? "ollama";
134
- return new ChatOpenAI({
174
+ const params = {
135
175
  model,
136
176
  temperature: 1,
137
177
  apiKey: apiKey,
138
178
  configuration: {
139
179
  baseURL: provider?.baseURL
140
180
  }
141
- });
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.`);
142
212
  }
143
213
  }
144
214
  export { ModelFactory };
@@ -29,14 +29,16 @@ __webpack_require__.d(__webpack_exports__, {
29
29
  getAvailableTools: ()=>getAvailableTools,
30
30
  createTool: ()=>createTool
31
31
  });
32
- const internet_search_cjs_namespaceObject = require("../tools/internet_search.cjs");
33
- const web_crawler_cjs_namespaceObject = require("../tools/web_crawler.cjs");
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 external_logger_cjs_namespaceObject = require("../../logger.cjs");
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;