tachibot-mcp 2.0.6 → 2.0.7

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 (52) hide show
  1. package/.env.example +5 -2
  2. package/dist/src/config/model-constants.js +83 -73
  3. package/dist/src/config/model-preferences.js +5 -4
  4. package/dist/src/config.js +2 -1
  5. package/dist/src/mcp-client.js +3 -3
  6. package/dist/src/modes/scout.js +2 -1
  7. package/dist/src/optimization/model-router.js +19 -16
  8. package/dist/src/orchestrator-instructions.js +1 -1
  9. package/dist/src/orchestrator-lite.js +1 -1
  10. package/dist/src/orchestrator.js +1 -1
  11. package/dist/src/profiles/balanced.js +1 -2
  12. package/dist/src/profiles/code_focus.js +1 -2
  13. package/dist/src/profiles/full.js +1 -2
  14. package/dist/src/profiles/minimal.js +1 -2
  15. package/dist/src/profiles/research_power.js +1 -2
  16. package/dist/src/server.js +13 -12
  17. package/dist/src/tools/gemini-tools.js +15 -16
  18. package/dist/src/tools/grok-enhanced.js +18 -17
  19. package/dist/src/tools/grok-tools.js +21 -20
  20. package/dist/src/tools/openai-tools.js +28 -61
  21. package/dist/src/tools/tool-router.js +53 -52
  22. package/dist/src/tools/unified-ai-provider.js +1 -1
  23. package/dist/src/tools/workflow-runner.js +16 -0
  24. package/dist/src/tools/workflow-validator-tool.js +1 -1
  25. package/dist/src/utils/api-keys.js +20 -0
  26. package/dist/src/validators/interpolation-validator.js +4 -0
  27. package/dist/src/validators/tool-registry-validator.js +1 -1
  28. package/dist/src/validators/tool-types.js +0 -1
  29. package/dist/src/workflows/custom-workflows.js +4 -3
  30. package/dist/src/workflows/engine/VariableInterpolator.js +30 -3
  31. package/dist/src/workflows/engine/WorkflowExecutionEngine.js +2 -2
  32. package/dist/src/workflows/engine/WorkflowOutputFormatter.js +27 -4
  33. package/dist/src/workflows/fallback-strategies.js +2 -2
  34. package/dist/src/workflows/model-router.js +20 -11
  35. package/dist/src/workflows/tool-mapper.js +41 -14
  36. package/docs/API_KEYS.md +7 -7
  37. package/docs/TOOLS_REFERENCE.md +1 -37
  38. package/package.json +1 -1
  39. package/profiles/balanced.json +1 -2
  40. package/profiles/code_focus.json +1 -2
  41. package/profiles/debug_intensive.json +0 -1
  42. package/profiles/full.json +2 -3
  43. package/profiles/minimal.json +1 -2
  44. package/profiles/research_power.json +1 -2
  45. package/profiles/workflow_builder.json +1 -2
  46. package/tools.config.json +15 -3
  47. package/workflows/code-architecture-review.yaml +5 -3
  48. package/workflows/creative-brainstorm-yaml.yaml +1 -1
  49. package/workflows/pingpong.yaml +5 -3
  50. package/workflows/system/README.md +1 -1
  51. package/workflows/system/verifier.yaml +8 -5
  52. package/workflows/ultra-creative-brainstorm.yaml +3 -3
@@ -5,23 +5,16 @@
5
5
  */
6
6
  import { z } from "zod";
7
7
  import { validateToolInput } from "../utils/input-validator.js";
8
+ import { GEMINI_MODELS } from "../config/model-constants.js";
8
9
  // NOTE: dotenv is loaded in server.ts before any imports
9
10
  // No need to reload here - just read from process.env
10
11
  // Gemini API configuration
11
12
  const GEMINI_API_KEY = process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY;
12
13
  const GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta";
13
- // Available Gemini models (2025 - Latest)
14
- export var GeminiModel;
15
- (function (GeminiModel) {
16
- // Primary models (Gemini 2.5 - preferred)
17
- GeminiModel["FLASH"] = "gemini-2.5-flash";
18
- GeminiModel["PRO"] = "gemini-2.5-pro";
19
- GeminiModel["FLASH_LITE"] = "gemini-2.5-flash-lite";
20
- })(GeminiModel || (GeminiModel = {}));
21
14
  /**
22
15
  * Call Gemini API directly
23
16
  */
24
- export async function callGemini(prompt, model = GeminiModel.PRO, systemPrompt, temperature = 0.7, skipValidation = false) {
17
+ export async function callGemini(prompt, model = GEMINI_MODELS.GEMINI_3_PRO, systemPrompt, temperature = 0.7, skipValidation = false) {
25
18
  if (!GEMINI_API_KEY) {
26
19
  return `[Gemini API key not configured. Add GOOGLE_API_KEY to .env file]`;
27
20
  }
@@ -144,10 +137,16 @@ export const geminiQueryTool = {
144
137
  description: "Query Gemini",
145
138
  parameters: z.object({
146
139
  prompt: z.string(),
147
- model: z.enum(["pro", "flash"]).optional().default("pro")
140
+ model: z.enum(["gemini-3", "pro", "flash"]).optional().default("gemini-3")
148
141
  }),
149
142
  execute: async (args, { log }) => {
150
- const model = args.model === "flash" ? GeminiModel.FLASH : GeminiModel.PRO;
143
+ let model = GEMINI_MODELS.GEMINI_3_PRO; // Default to Gemini 3
144
+ if (args.model === "flash") {
145
+ model = GEMINI_MODELS.FLASH;
146
+ }
147
+ else if (args.model === "pro") {
148
+ model = GEMINI_MODELS.PRO;
149
+ }
151
150
  return await callGemini(args.prompt, model);
152
151
  }
153
152
  };
@@ -174,7 +173,7 @@ IMPORTANT: Output a detailed written response with:
174
173
  4. Quick feasibility assessment
175
174
 
176
175
  Provide your complete analysis as visible text output.`;
177
- const response = await callGemini(args.prompt, GeminiModel.PRO, systemPrompt, 0.9);
176
+ const response = await callGemini(args.prompt, GEMINI_MODELS.GEMINI_3_PRO, systemPrompt, 0.9);
178
177
  // If multiple rounds requested, we could iterate here
179
178
  // For now, return the single response
180
179
  return response;
@@ -208,7 +207,7 @@ Provide:
208
207
  2. ${args.focus === 'security' ? 'Security vulnerabilities' : 'Issues found'}
209
208
  3. Specific recommendations for improvement
210
209
  4. Code quality score (1-10) with justification`;
211
- return await callGemini(`Analyze this code:\n\n\`\`\`${args.language || ''}\n${args.code}\n\`\`\``, GeminiModel.PRO, systemPrompt, 0.3);
210
+ return await callGemini(`Analyze this code:\n\n\`\`\`${args.language || ''}\n${args.code}\n\`\`\``, GEMINI_MODELS.GEMINI_3_PRO, systemPrompt, 0.3);
212
211
  }
213
212
  };
214
213
  /**
@@ -236,7 +235,7 @@ Format your response clearly with:
236
235
  ${args.type === 'sentiment' ? '- Overall sentiment\n- Confidence score\n- Emotional indicators' : ''}
237
236
  ${args.type === 'entities' ? '- People\n- Organizations\n- Locations\n- Other entities' : ''}
238
237
  ${args.type === 'key-points' ? '- Main arguments\n- Supporting points\n- Conclusions' : ''}`;
239
- return await callGemini(`Analyze this text:\n\n${args.text}`, GeminiModel.PRO, systemPrompt, 0.3);
238
+ return await callGemini(`Analyze this text:\n\n${args.text}`, GEMINI_MODELS.GEMINI_3_PRO, systemPrompt, 0.3);
240
239
  }
241
240
  };
242
241
  /**
@@ -269,7 +268,7 @@ Focus on:
269
268
  - Main ideas and key arguments
270
269
  - Important facts and figures
271
270
  - Conclusions and implications`;
272
- return await callGemini(`Summarize this content:\n\n${args.content}`, GeminiModel.PRO, systemPrompt, 0.3);
271
+ return await callGemini(`Summarize this content:\n\n${args.content}`, GEMINI_MODELS.GEMINI_3_PRO, systemPrompt, 0.3);
273
272
  }
274
273
  };
275
274
  /**
@@ -302,7 +301,7 @@ Make it specific and visually descriptive.`;
302
301
  ${args.style ? `Style: ${args.style}` : ''}
303
302
  ${args.mood ? `Mood: ${args.mood}` : ''}
304
303
  ${args.details ? `Additional details: ${args.details}` : ''}`;
305
- return await callGemini(userPrompt, GeminiModel.PRO, systemPrompt, 0.7);
304
+ return await callGemini(userPrompt, GEMINI_MODELS.GEMINI_3_PRO, systemPrompt, 0.7);
306
305
  }
307
306
  };
308
307
  /**
@@ -6,19 +6,20 @@ import { z } from "zod";
6
6
  import { config } from "dotenv";
7
7
  import * as path from 'path';
8
8
  import { fileURLToPath } from 'url';
9
+ import { getGrokApiKey, hasGrokApiKey } from "../utils/api-keys.js";
9
10
  const __filename = fileURLToPath(import.meta.url);
10
11
  const __dirname = path.dirname(__filename);
11
12
  config({ path: path.resolve(__dirname, '../../../.env') });
12
13
  // Grok API configuration
13
- const GROK_API_KEY = process.env.GROK_API_KEY || process.env.XAI_API_KEY;
14
+ const GROK_API_KEY = getGrokApiKey();
14
15
  const GROK_API_URL = "https://api.x.ai/v1/chat/completions";
15
- // Grok models - Updated 2025-11-21 with Grok 4.1
16
+ // Grok models - Updated 2025-11-22 with correct API model names
16
17
  export var GrokModel;
17
18
  (function (GrokModel) {
18
- // Grok 4.1 models (Nov 2025) - LATEST & BEST
19
- GrokModel["GROK_4_1"] = "grok-4.1";
20
- GrokModel["GROK_4_1_FAST"] = "grok-4.1-fast";
21
- // Previous fast models (2025) - Still good
19
+ // Grok 4.1 models (Nov 2025) - LATEST & BEST (verified working)
20
+ GrokModel["GROK_4_1_FAST_REASONING"] = "grok-4-1-fast-reasoning";
21
+ GrokModel["GROK_4_1_FAST"] = "grok-4-1-fast-non-reasoning";
22
+ // Grok 4 fast models (2025) - Still good
22
23
  GrokModel["CODE_FAST"] = "grok-code-fast-1";
23
24
  GrokModel["GROK_4_FAST_REASONING"] = "grok-4-fast-reasoning";
24
25
  GrokModel["GROK_4_FAST"] = "grok-4-fast-non-reasoning";
@@ -38,7 +39,7 @@ export async function callGrokEnhanced(messages, options = {}) {
38
39
  content: `[Grok API key not configured. Add GROK_API_KEY or XAI_API_KEY to .env file]`
39
40
  };
40
41
  }
41
- const { model = GrokModel.GROK_4_1, // Updated 2025-11-21: Use latest Grok 4.1 by default
42
+ const { model = GrokModel.GROK_4_1_FAST_REASONING, // Updated 2025-11-22: Use latest Grok 4.1 by default
42
43
  temperature = 0.7, maxTokens = options.useHeavy ? 100000 : 4000, enableLiveSearch = false, searchSources = 100, // Default to 100 sources for cost control
43
44
  searchDomains = [], structuredOutput = false } = options;
44
45
  try {
@@ -143,9 +144,9 @@ Cite your sources when using web data.`
143
144
  content: query
144
145
  }
145
146
  ];
146
- log?.info(`Grok Scout: ${variant} research with ${enableLiveSearch ? 'live search' : 'knowledge base'} (using grok-4.1 with enhanced reasoning)`);
147
+ log?.info(`Grok Scout: ${variant} research with ${enableLiveSearch ? 'live search' : 'knowledge base'} (using grok-4-1-fast-reasoning with enhanced reasoning)`);
147
148
  const result = await callGrokEnhanced(messages, {
148
- model: GrokModel.GROK_4_1, // Updated 2025-11-21: Use latest Grok 4.1
149
+ model: GrokModel.GROK_4_1_FAST_REASONING, // Updated 2025-11-21: Use latest Grok 4.1
149
150
  enableLiveSearch,
150
151
  searchSources,
151
152
  searchDomains,
@@ -204,7 +205,7 @@ ${enableLiveSearch ? 'Use live search for current information when needed.' : ''
204
205
  const costInfo = useHeavy ? '$3/$15 (expensive!)' : '$0.20/$0.50 (latest!)';
205
206
  log?.info(`Using ${modelName} (${approach}) with ${enableLiveSearch ? 'live search' : 'knowledge base'} - Cost: ${costInfo}`);
206
207
  const result = await callGrokEnhanced(messages, {
207
- model: useHeavy ? GrokModel.GROK_4_HEAVY : GrokModel.GROK_4_1, // Updated 2025-11-21: Use latest Grok 4.1
208
+ model: useHeavy ? GrokModel.GROK_4_HEAVY : GrokModel.GROK_4_1_FAST_REASONING, // Updated 2025-11-21: Use latest Grok 4.1
208
209
  useHeavy,
209
210
  enableLiveSearch,
210
211
  searchSources: 50,
@@ -256,7 +257,7 @@ export const grokFunctionTool = {
256
257
  ];
257
258
  // Make request with tools
258
259
  const requestBody = {
259
- model: args.useHeavy ? GrokModel.GROK_4_HEAVY : GrokModel.GROK_4_1_FAST, // Updated 2025-11-21: Use tool-calling optimized Grok 4.1 Fast
260
+ model: args.useHeavy ? GrokModel.GROK_4_HEAVY : GrokModel.GROK_4_1_FAST, // Updated 2025-11-22: Use tool-calling optimized Grok 4.1 Fast Non-Reasoning
260
261
  messages,
261
262
  tools,
262
263
  tool_choice: "auto", // Let Grok decide when to call functions
@@ -321,13 +322,13 @@ Limit search to ${max_search_results} sources for cost control.`
321
322
  content: `Search for: ${query}`
322
323
  }
323
324
  ];
324
- log?.info(`Grok Search: ${max_search_results} sources, recency: ${recency} (using grok-4.1 with enhanced reasoning)`);
325
+ log?.info(`Grok Search: ${max_search_results} sources, recency: ${recency} (using grok-4-1-fast-reasoning with enhanced reasoning)`);
325
326
  // Extract domains from sources if specified
326
327
  const domains = sources
327
328
  ?.filter((s) => s.allowed_websites)
328
329
  ?.flatMap((s) => s.allowed_websites) || [];
329
330
  const result = await callGrokEnhanced(messages, {
330
- model: GrokModel.GROK_4_1, // Updated 2025-11-21: Use latest Grok 4.1 with search
331
+ model: GrokModel.GROK_4_1_FAST_REASONING, // Updated 2025-11-21: Use latest Grok 4.1 with search
331
332
  enableLiveSearch: true,
332
333
  searchSources: max_search_results,
333
334
  searchDomains: domains,
@@ -343,7 +344,7 @@ Limit search to ${max_search_results} sources for cost control.`
343
344
  * Check if Grok is available
344
345
  */
345
346
  export function isGrokAvailable() {
346
- return !!(GROK_API_KEY);
347
+ return hasGrokApiKey();
347
348
  }
348
349
  /**
349
350
  * Get Grok configuration status
@@ -351,10 +352,10 @@ export function isGrokAvailable() {
351
352
  export function getGrokStatus() {
352
353
  return {
353
354
  available: isGrokAvailable(),
354
- model: GrokModel.GROK_4_1,
355
+ model: GrokModel.GROK_4_1_FAST_REASONING,
355
356
  features: [
356
- 'Grok 4.1 (Nov 2025): Enhanced reasoning, creativity & emotional intelligence ($0.20/$0.50, 2M context)',
357
- 'Grok 4.1 Fast: Tool-calling optimized, agentic workflows ($0.20/$0.50, 2M context)',
357
+ 'Grok 4.1 Fast Reasoning (Nov 2025): Enhanced reasoning, creativity & emotional intelligence ($0.20/$0.50, 2M context)',
358
+ 'Grok 4.1 Fast Non-Reasoning: Tool-calling optimized, agentic workflows ($0.20/$0.50, 2M context)',
358
359
  'Heavy mode available (grok-4-0709: $3/$15, use sparingly)',
359
360
  'Live web search with citations',
360
361
  'Function calling',
@@ -8,19 +8,20 @@ import * as path from 'path';
8
8
  import { fileURLToPath } from 'url';
9
9
  import { grokSearchTool } from './grok-enhanced.js';
10
10
  import { validateToolInput } from "../utils/input-validator.js";
11
+ import { getGrokApiKey, hasGrokApiKey } from "../utils/api-keys.js";
11
12
  const __filename = fileURLToPath(import.meta.url);
12
13
  const __dirname = path.dirname(__filename);
13
14
  config({ path: path.resolve(__dirname, '../../../.env') });
14
15
  // Grok API configuration
15
- const GROK_API_KEY = process.env.GROK_API_KEY;
16
+ const GROK_API_KEY = getGrokApiKey();
16
17
  const GROK_API_URL = "https://api.x.ai/v1/chat/completions";
17
- // Available Grok models - Updated 2025-11-21 with Grok 4.1
18
+ // Available Grok models - Updated 2025-11-22 with correct API model names
18
19
  export var GrokModel;
19
20
  (function (GrokModel) {
20
- // Grok 4.1 models (Nov 2025) - LATEST & BEST
21
- GrokModel["GROK_4_1"] = "grok-4.1";
22
- GrokModel["GROK_4_1_FAST"] = "grok-4.1-fast";
23
- // Previous fast models (2025) - Still good
21
+ // Grok 4.1 models (Nov 2025) - LATEST & BEST (verified working)
22
+ GrokModel["GROK_4_1_FAST_REASONING"] = "grok-4-1-fast-reasoning";
23
+ GrokModel["GROK_4_1_FAST"] = "grok-4-1-fast-non-reasoning";
24
+ // Grok 4 fast models (2025) - Still good
24
25
  GrokModel["CODE_FAST"] = "grok-code-fast-1";
25
26
  GrokModel["GROK_4_FAST_REASONING"] = "grok-4-fast-reasoning";
26
27
  GrokModel["GROK_4_FAST"] = "grok-4-fast-non-reasoning";
@@ -31,11 +32,11 @@ export var GrokModel;
31
32
  /**
32
33
  * Call Grok API
33
34
  */
34
- export async function callGrok(messages, model = GrokModel.GROK_4_1, // Updated 2025-11-21: Use latest Grok 4.1 by default
35
+ export async function callGrok(messages, model = GrokModel.GROK_4_1_FAST_REASONING, // Updated 2025-11-22: Use latest Grok 4.1 by default
35
36
  temperature = 0.7, maxTokens = 16384, // Increased default for comprehensive responses
36
37
  forceVisibleOutput = true) {
37
38
  if (!GROK_API_KEY) {
38
- return `[Grok API key not configured. Add GROK_API_KEY to .env file]`;
39
+ return `[Grok API key not configured. Add XAI_API_KEY to .env file]`;
39
40
  }
40
41
  // Validate and sanitize message content
41
42
  const validatedMessages = messages.map((msg) => {
@@ -47,7 +48,7 @@ forceVisibleOutput = true) {
47
48
  });
48
49
  try {
49
50
  // For Grok 4 models, we need to handle reasoning tokens specially
50
- const isGrok4 = model === GrokModel.GROK_4_1 ||
51
+ const isGrok4 = model === GrokModel.GROK_4_1_FAST_REASONING ||
51
52
  model === GrokModel.GROK_4_1_FAST ||
52
53
  model === GrokModel.GROK_4_FAST_REASONING ||
53
54
  model === GrokModel.GROK_4_FAST ||
@@ -127,8 +128,8 @@ ${context ? `Context: ${context}` : ''}`
127
128
  content: problem
128
129
  }
129
130
  ];
130
- // Use GROK_4_1 by default (latest with enhanced reasoning!), GROK_4_HEAVY only if explicitly requested
131
- const model = useHeavy ? GrokModel.GROK_4_HEAVY : GrokModel.GROK_4_1;
131
+ // Use GROK_4_1_FAST_REASONING by default (latest with enhanced reasoning!), GROK_4_HEAVY only if explicitly requested
132
+ const model = useHeavy ? GrokModel.GROK_4_HEAVY : GrokModel.GROK_4_1_FAST_REASONING;
132
133
  const maxTokens = useHeavy ? 100000 : 16384; // 100k for heavy, 16k for normal reasoning
133
134
  log?.info(`Using Grok model: ${model} for deep reasoning (max tokens: ${maxTokens}, cost: ${useHeavy ? 'expensive $3/$15' : 'cheap $0.20/$0.50'})`);
134
135
  return await callGrok(messages, model, 0.7, maxTokens, true);
@@ -169,7 +170,7 @@ ${requirements ? `Requirements: ${requirements}` : ''}`
169
170
  content: `Code:\n\`\`\`${language || ''}\n${code}\n\`\`\``
170
171
  }
171
172
  ];
172
- log?.info(`Using Grok 4.1 Fast (2M context, enhanced reasoning, $0.20/$0.50)`);
173
+ log?.info(`Using Grok 4.1 Fast Non-Reasoning (2M context, tool-calling optimized, $0.20/$0.50)`);
173
174
  return await callGrok(messages, GrokModel.GROK_4_1_FAST, 0.2, 4000, true);
174
175
  }
175
176
  };
@@ -213,8 +214,8 @@ Analyze the issue systematically:
213
214
  content: prompt
214
215
  }
215
216
  ];
216
- log?.info(`Using Grok Code Fast for debugging (specialized code model)`);
217
- return await callGrok(messages, GrokModel.CODE_FAST, 0.3, 3000, true);
217
+ log?.info(`Using Grok 4.1 Fast Non-Reasoning for debugging (tool-calling optimized, $0.20/$0.50)`);
218
+ return await callGrok(messages, GrokModel.GROK_4_1_FAST, 0.3, 3000, true);
218
219
  }
219
220
  };
220
221
  /**
@@ -245,8 +246,8 @@ ${constraints ? `Constraints: ${constraints}` : ''}`
245
246
  content: requirements
246
247
  }
247
248
  ];
248
- log?.info(`Using Grok 4 Fast Reasoning for architecture (cheap reasoning model)`);
249
- return await callGrok(messages, GrokModel.GROK_4_FAST_REASONING, 0.6, 4000, true);
249
+ log?.info(`Using Grok 4.1 Fast Reasoning for architecture (latest model, $0.20/$0.50)`);
250
+ return await callGrok(messages, GrokModel.GROK_4_1_FAST_REASONING, 0.6, 4000, true);
250
251
  }
251
252
  };
252
253
  /**
@@ -276,9 +277,9 @@ ${constraints ? `Constraints: ${constraints}` : 'No constraints - think freely!'
276
277
  content: `Brainstorm creative solutions for: ${topic}`
277
278
  }
278
279
  ];
279
- // Use GROK_4_FAST for creative brainstorming (cheap, fast), GROK_4_HEAVY only if explicitly requested
280
- const model = forceHeavy ? GrokModel.GROK_4_HEAVY : GrokModel.GROK_4_FAST;
281
- log?.info(`Brainstorming with Grok model: ${model} (Heavy: ${forceHeavy}, cost: ${forceHeavy ? 'expensive $3/$15' : 'cheap $0.20/$0.50'})`);
280
+ // Use GROK_4_1_FAST_REASONING for creative brainstorming (needs reasoning for creativity), GROK_4_HEAVY only if explicitly requested
281
+ const model = forceHeavy ? GrokModel.GROK_4_HEAVY : GrokModel.GROK_4_1_FAST_REASONING;
282
+ log?.info(`Brainstorming with Grok model: ${model} (Heavy: ${forceHeavy}, cost: ${forceHeavy ? 'expensive $3/$15' : 'cheap $0.20/$0.50 - latest 4.1'})`);
282
283
  return await callGrok(messages, model, 0.95, 4000); // High temperature for creativity
283
284
  }
284
285
  };
@@ -286,7 +287,7 @@ ${constraints ? `Constraints: ${constraints}` : 'No constraints - think freely!'
286
287
  * Check if Grok is available
287
288
  */
288
289
  export function isGrokAvailable() {
289
- return !!GROK_API_KEY;
290
+ return hasGrokApiKey();
290
291
  }
291
292
  export function getAllGrokTools() {
292
293
  if (!isGrokAvailable()) {
@@ -70,12 +70,14 @@ const ResponsesAPISchema = z.object({
70
70
  total_tokens: z.number().optional()
71
71
  }).optional()
72
72
  });
73
- // Available OpenAI models (GPT-5.1 family)
73
+ // Available OpenAI GPT-5 models (optimized for Claude Code)
74
74
  export var OpenAI51Model;
75
75
  (function (OpenAI51Model) {
76
76
  OpenAI51Model["FULL"] = "gpt-5.1";
77
+ OpenAI51Model["PRO"] = "gpt-5-pro";
77
78
  OpenAI51Model["CODEX_MINI"] = "gpt-5.1-codex-mini";
78
79
  OpenAI51Model["CODEX"] = "gpt-5.1-codex";
80
+ OpenAI51Model["CODEX_MAX"] = "gpt-5.1-codex-max";
79
81
  })(OpenAI51Model || (OpenAI51Model = {}));
80
82
  /**
81
83
  * Call OpenAI API with model fallback support
@@ -111,34 +113,33 @@ reasoningEffort = "low", requireConfirmation = false, skipValidation = false) {
111
113
  for (const currentModel of modelsToTry) {
112
114
  console.error(`🔍 TRACE: Trying model: ${currentModel}`);
113
115
  try {
114
- // GPT-5.1 models use /v1/responses, others use /v1/chat/completions
115
- const isGPT51 = currentModel.startsWith('gpt-5.1');
116
- const endpoint = isGPT51 ? OPENAI_RESPONSES_URL : OPENAI_CHAT_URL;
116
+ // Codex models use /v1/responses, non-codex use /v1/chat/completions
117
+ const isCodex = currentModel.includes('codex');
118
+ const endpoint = isCodex ? OPENAI_RESPONSES_URL : OPENAI_CHAT_URL;
117
119
  let requestBody;
118
- // GPT-5.1 uses Responses API format, others use Chat Completions format
119
- if (isGPT51) {
120
- // Responses API format - NO temperature, use reasoning.effort instead
120
+ if (isCodex) {
121
+ // Responses API format for codex models
121
122
  requestBody = {
122
123
  model: currentModel,
123
124
  input: validatedMessages,
124
125
  max_output_tokens: maxTokens,
125
126
  stream: false,
126
127
  reasoning: {
127
- effort: reasoningEffort // "none", "low", "medium", "high"
128
+ effort: reasoningEffort
128
129
  }
129
130
  };
130
131
  }
131
132
  else {
132
- // Chat Completions format
133
+ // Chat Completions format for non-codex GPT-5 models (gpt-5.1, gpt-5-pro)
133
134
  requestBody = {
134
135
  model: currentModel,
135
136
  messages: validatedMessages,
136
137
  temperature,
137
- max_tokens: maxTokens,
138
+ max_completion_tokens: maxTokens, // GPT-5 requires max_completion_tokens (not max_tokens)
138
139
  stream: false
139
140
  };
140
141
  }
141
- console.error(`🔍 TRACE: Using ${isGPT51 ? '/v1/responses' : '/v1/chat/completions'} endpoint`);
142
+ console.error(`🔍 TRACE: Using ${isCodex ? '/v1/responses' : '/v1/chat/completions'} endpoint`);
142
143
  const response = await fetch(endpoint, {
143
144
  method: "POST",
144
145
  headers: {
@@ -159,16 +160,15 @@ reasoningEffort = "low", requireConfirmation = false, skipValidation = false) {
159
160
  throw new Error(lastError);
160
161
  }
161
162
  const rawData = await response.json();
162
- // Parse based on API type - they have DIFFERENT response formats!
163
+ // Parse based on API type
163
164
  let rawContent;
164
- if (isGPT51) {
165
- // Validate and parse Responses API format
165
+ if (isCodex) {
166
+ // Responses API format
166
167
  const parseResult = ResponsesAPISchema.safeParse(rawData);
167
168
  if (parseResult.success) {
168
169
  const data = parseResult.data;
169
170
  const messageOutput = data.output.find(item => item.type === 'message');
170
171
  rawContent = messageOutput?.content?.[0]?.text;
171
- // Capture reasoning info
172
172
  if (data.reasoning) {
173
173
  console.error(`🔍 TRACE: Reasoning effort: ${data.reasoning.effort}`);
174
174
  }
@@ -178,7 +178,7 @@ reasoningEffort = "low", requireConfirmation = false, skipValidation = false) {
178
178
  }
179
179
  }
180
180
  else {
181
- // Validate and parse Chat Completions API format
181
+ // Chat Completions format
182
182
  const parseResult = ChatCompletionResponseSchema.safeParse(rawData);
183
183
  if (parseResult.success) {
184
184
  const chatData = parseResult.data;
@@ -225,17 +225,16 @@ reasoningEffort = "low", skipValidation = false) {
225
225
  return { ...msg, content: validation.sanitized };
226
226
  });
227
227
  try {
228
- // GPT-5.1 models use /v1/responses, others use /v1/chat/completions
229
- const isGPT51 = model.startsWith('gpt-5.1');
230
- const endpoint = isGPT51 ? OPENAI_RESPONSES_URL : OPENAI_CHAT_URL;
228
+ // Codex models use /v1/responses, non-codex use /v1/chat/completions
229
+ const isCodex = model.includes('codex');
230
+ const endpoint = isCodex ? OPENAI_RESPONSES_URL : OPENAI_CHAT_URL;
231
231
  let requestBody;
232
- // GPT-5.1 uses Responses API format, others use Chat Completions format
233
- if (isGPT51) {
234
- // Responses API format - NO temperature, use reasoning.effort instead
232
+ if (isCodex) {
233
+ // Responses API format for codex models
235
234
  requestBody = {
236
235
  model: model,
237
236
  input: validatedMessages,
238
- max_output_tokens: maxTokens,
237
+ max_output_tokens: maxTokens, // NOT max_completion_tokens or max_tokens!
239
238
  stream: false,
240
239
  reasoning: {
241
240
  effort: reasoningEffort // "none", "low", "medium", "high"
@@ -243,17 +242,17 @@ reasoningEffort = "low", skipValidation = false) {
243
242
  };
244
243
  }
245
244
  else {
246
- // Chat Completions format
245
+ // Chat Completions format for non-codex GPT-5 models (gpt-5.1, gpt-5-pro)
247
246
  requestBody = {
248
247
  model: model,
249
248
  messages: validatedMessages,
250
249
  temperature,
251
- max_tokens: maxTokens,
250
+ max_completion_tokens: maxTokens, // GPT-5 requires max_completion_tokens (not max_tokens)
252
251
  stream: false
253
252
  };
254
253
  }
255
- console.error(`🔍 TRACE: Using ${isGPT51 ? '/v1/responses' : '/v1/chat/completions'} endpoint`);
256
- console.error(`🔍 TRACE: Model params: max_tokens=${maxTokens}, temperature=${temperature}${isGPT51 ? `, reasoning_effort=${reasoningEffort}` : ''}`);
254
+ console.error(`🔍 TRACE: Using ${isCodex ? '/v1/responses' : '/v1/chat/completions'} endpoint`);
255
+ console.error(`🔍 TRACE: Model params: ${isCodex ? `max_output_tokens=${maxTokens}, reasoning_effort=${reasoningEffort}` : `max_completion_tokens=${maxTokens}, temperature=${temperature}`}`);
257
256
  const response = await fetch(endpoint, {
258
257
  method: "POST",
259
258
  headers: {
@@ -270,7 +269,7 @@ reasoningEffort = "low", skipValidation = false) {
270
269
  const rawData = await response.json();
271
270
  // Parse based on API type - they have DIFFERENT response formats!
272
271
  let rawContent;
273
- if (isGPT51) {
272
+ if (isCodex) {
274
273
  // Validate and parse Responses API format
275
274
  const parseResult = ResponsesAPISchema.safeParse(rawData);
276
275
  if (parseResult.success) {
@@ -378,7 +377,7 @@ export const gpt5MiniReasonTool = {
378
377
  }
379
378
  };
380
379
  export const openaiGpt5ReasonTool = {
381
- name: "openai_gpt5_reason",
380
+ name: "openai_reason",
382
381
  description: "Mathematical reasoning using GPT-5.1 with high reasoning effort",
383
382
  parameters: z.object({
384
383
  query: z.string(),
@@ -409,37 +408,6 @@ ${args.context ? `Context: ${args.context}` : ''}`
409
408
  return await callOpenAI(messages, OpenAI51Model.FULL, 0.7, 4000, "high");
410
409
  }
411
410
  };
412
- /**
413
- * OpenAI Compare Tool
414
- * Multi-option comparison and consensus building using GPT-5.1-codex-mini
415
- */
416
- export const openaiCompareTool = {
417
- name: "openai_compare",
418
- description: "Multi-model consensus",
419
- parameters: z.object({
420
- topic: z.string(),
421
- options: z.array(z.string()),
422
- criteria: z.string().optional(),
423
- includeRecommendation: z.boolean().optional().default(true)
424
- }),
425
- execute: async (args, { log }) => {
426
- const optionsList = args.options.map((opt, i) => `${i + 1}. ${opt}`).join('\n');
427
- const messages = [
428
- {
429
- role: "system",
430
- content: `You are an expert at comparative analysis and decision-making.
431
- Compare the given options systematically.
432
- ${args.criteria ? `Criteria: ${args.criteria}` : 'Consider: pros, cons, trade-offs, and suitability'}
433
- ${args.includeRecommendation ? 'Provide a clear recommendation with justification.' : ''}`
434
- },
435
- {
436
- role: "user",
437
- content: `Topic: ${args.topic}\n\nOptions:\n${optionsList}`
438
- }
439
- ];
440
- return await callOpenAI(messages, OpenAI51Model.CODEX_MINI, 0.7, 3000, "low");
441
- }
442
- };
443
411
  /**
444
412
  * OpenAI Brainstorm Tool
445
413
  * Creative ideation and brainstorming
@@ -582,7 +550,6 @@ export function getAllOpenAITools() {
582
550
  }
583
551
  return [
584
552
  openaiGpt5ReasonTool, // GPT-5.1 reasoning (high effort)
585
- openaiCompareTool, // GPT-5.1-codex-mini comparison (low effort)
586
553
  openAIBrainstormTool, // GPT-5.1-codex-mini brainstorming (medium effort)
587
554
  openaiCodeReviewTool, // GPT-5.1-codex-mini code review (medium effort)
588
555
  openaiExplainTool // GPT-5.1-codex-mini explanations (low effort)