tachibot-mcp 2.0.5 → 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.
- package/.env.example +5 -2
- package/dist/src/config/model-constants.js +85 -72
- package/dist/src/config/model-preferences.js +5 -4
- package/dist/src/config.js +2 -1
- package/dist/src/mcp-client.js +3 -3
- package/dist/src/modes/scout.js +2 -1
- package/dist/src/optimization/model-router.js +19 -16
- package/dist/src/orchestrator-instructions.js +1 -1
- package/dist/src/orchestrator-lite.js +1 -1
- package/dist/src/orchestrator.js +1 -1
- package/dist/src/profiles/balanced.js +1 -2
- package/dist/src/profiles/code_focus.js +1 -2
- package/dist/src/profiles/full.js +1 -2
- package/dist/src/profiles/minimal.js +1 -2
- package/dist/src/profiles/research_power.js +1 -2
- package/dist/src/server.js +13 -12
- package/dist/src/tools/gemini-tools.js +15 -16
- package/dist/src/tools/grok-enhanced.js +21 -17
- package/dist/src/tools/grok-tools.js +26 -20
- package/dist/src/tools/openai-tools.js +28 -61
- package/dist/src/tools/tool-router.js +53 -52
- package/dist/src/tools/unified-ai-provider.js +1 -1
- package/dist/src/tools/workflow-runner.js +16 -0
- package/dist/src/tools/workflow-validator-tool.js +1 -1
- package/dist/src/utils/api-keys.js +20 -0
- package/dist/src/validators/interpolation-validator.js +4 -0
- package/dist/src/validators/tool-registry-validator.js +1 -1
- package/dist/src/validators/tool-types.js +0 -1
- package/dist/src/workflows/custom-workflows.js +4 -3
- package/dist/src/workflows/engine/VariableInterpolator.js +30 -3
- package/dist/src/workflows/engine/WorkflowExecutionEngine.js +2 -2
- package/dist/src/workflows/engine/WorkflowOutputFormatter.js +27 -4
- package/dist/src/workflows/fallback-strategies.js +2 -2
- package/dist/src/workflows/model-router.js +30 -5
- package/dist/src/workflows/tool-mapper.js +41 -14
- package/docs/API_KEYS.md +10 -6
- package/docs/TOOLS_REFERENCE.md +7 -43
- package/package.json +1 -1
- package/profiles/balanced.json +1 -2
- package/profiles/code_focus.json +1 -2
- package/profiles/debug_intensive.json +0 -1
- package/profiles/full.json +2 -3
- package/profiles/minimal.json +1 -2
- package/profiles/research_power.json +1 -2
- package/profiles/workflow_builder.json +1 -2
- package/smithery.yaml +2 -2
- package/tools.config.json +15 -3
- package/workflows/code-architecture-review.yaml +5 -3
- package/workflows/creative-brainstorm-yaml.yaml +1 -1
- package/workflows/pingpong.yaml +5 -3
- package/workflows/system/README.md +1 -1
- package/workflows/system/verifier.yaml +8 -5
- 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 =
|
|
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("
|
|
140
|
+
model: z.enum(["gemini-3", "pro", "flash"]).optional().default("gemini-3")
|
|
148
141
|
}),
|
|
149
142
|
execute: async (args, { log }) => {
|
|
150
|
-
|
|
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,
|
|
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\`\`\``,
|
|
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}`,
|
|
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}`,
|
|
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,
|
|
304
|
+
return await callGemini(userPrompt, GEMINI_MODELS.GEMINI_3_PRO, systemPrompt, 0.7);
|
|
306
305
|
}
|
|
307
306
|
};
|
|
308
307
|
/**
|
|
@@ -6,16 +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 =
|
|
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-
|
|
16
|
+
// Grok models - Updated 2025-11-22 with correct API model names
|
|
16
17
|
export var GrokModel;
|
|
17
18
|
(function (GrokModel) {
|
|
18
|
-
//
|
|
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
|
|
19
23
|
GrokModel["CODE_FAST"] = "grok-code-fast-1";
|
|
20
24
|
GrokModel["GROK_4_FAST_REASONING"] = "grok-4-fast-reasoning";
|
|
21
25
|
GrokModel["GROK_4_FAST"] = "grok-4-fast-non-reasoning";
|
|
@@ -35,7 +39,7 @@ export async function callGrokEnhanced(messages, options = {}) {
|
|
|
35
39
|
content: `[Grok API key not configured. Add GROK_API_KEY or XAI_API_KEY to .env file]`
|
|
36
40
|
};
|
|
37
41
|
}
|
|
38
|
-
const { model = GrokModel.
|
|
42
|
+
const { model = GrokModel.GROK_4_1_FAST_REASONING, // Updated 2025-11-22: Use latest Grok 4.1 by default
|
|
39
43
|
temperature = 0.7, maxTokens = options.useHeavy ? 100000 : 4000, enableLiveSearch = false, searchSources = 100, // Default to 100 sources for cost control
|
|
40
44
|
searchDomains = [], structuredOutput = false } = options;
|
|
41
45
|
try {
|
|
@@ -140,9 +144,9 @@ Cite your sources when using web data.`
|
|
|
140
144
|
content: query
|
|
141
145
|
}
|
|
142
146
|
];
|
|
143
|
-
log?.info(`Grok Scout: ${variant} research with ${enableLiveSearch ? 'live search' : 'knowledge base'} (using
|
|
147
|
+
log?.info(`Grok Scout: ${variant} research with ${enableLiveSearch ? 'live search' : 'knowledge base'} (using grok-4-1-fast-reasoning with enhanced reasoning)`);
|
|
144
148
|
const result = await callGrokEnhanced(messages, {
|
|
145
|
-
model: GrokModel.
|
|
149
|
+
model: GrokModel.GROK_4_1_FAST_REASONING, // Updated 2025-11-21: Use latest Grok 4.1
|
|
146
150
|
enableLiveSearch,
|
|
147
151
|
searchSources,
|
|
148
152
|
searchDomains,
|
|
@@ -197,11 +201,11 @@ ${enableLiveSearch ? 'Use live search for current information when needed.' : ''
|
|
|
197
201
|
content: problem
|
|
198
202
|
}
|
|
199
203
|
];
|
|
200
|
-
const modelName = useHeavy ? 'Grok-4-Heavy' : 'Grok-4
|
|
201
|
-
const costInfo = useHeavy ? '$3/$15 (expensive!)' : '$0.20/$0.50 (
|
|
204
|
+
const modelName = useHeavy ? 'Grok-4-Heavy' : 'Grok-4.1';
|
|
205
|
+
const costInfo = useHeavy ? '$3/$15 (expensive!)' : '$0.20/$0.50 (latest!)';
|
|
202
206
|
log?.info(`Using ${modelName} (${approach}) with ${enableLiveSearch ? 'live search' : 'knowledge base'} - Cost: ${costInfo}`);
|
|
203
207
|
const result = await callGrokEnhanced(messages, {
|
|
204
|
-
model: useHeavy ? GrokModel.GROK_4_HEAVY : GrokModel.
|
|
208
|
+
model: useHeavy ? GrokModel.GROK_4_HEAVY : GrokModel.GROK_4_1_FAST_REASONING, // Updated 2025-11-21: Use latest Grok 4.1
|
|
205
209
|
useHeavy,
|
|
206
210
|
enableLiveSearch,
|
|
207
211
|
searchSources: 50,
|
|
@@ -253,14 +257,14 @@ export const grokFunctionTool = {
|
|
|
253
257
|
];
|
|
254
258
|
// Make request with tools
|
|
255
259
|
const requestBody = {
|
|
256
|
-
model: args.useHeavy ? GrokModel.GROK_4_HEAVY : GrokModel.
|
|
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
|
|
257
261
|
messages,
|
|
258
262
|
tools,
|
|
259
263
|
tool_choice: "auto", // Let Grok decide when to call functions
|
|
260
264
|
max_tokens: args.useHeavy ? 50000 : 5000,
|
|
261
265
|
temperature: 0.3 // Lower for function calling
|
|
262
266
|
};
|
|
263
|
-
log?.info(`Function calling with ${args.useHeavy ? 'Grok-4-Heavy ($3/$15)' : 'Grok-4-Fast
|
|
267
|
+
log?.info(`Function calling with ${args.useHeavy ? 'Grok-4-Heavy ($3/$15)' : 'Grok-4.1-Fast ($0.20/$0.50, tool-calling optimized)'}`);
|
|
264
268
|
try {
|
|
265
269
|
const response = await fetch(GROK_API_URL, {
|
|
266
270
|
method: "POST",
|
|
@@ -318,13 +322,13 @@ Limit search to ${max_search_results} sources for cost control.`
|
|
|
318
322
|
content: `Search for: ${query}`
|
|
319
323
|
}
|
|
320
324
|
];
|
|
321
|
-
log?.info(`Grok Search: ${max_search_results} sources, recency: ${recency} (using grok-4-fast-reasoning with
|
|
325
|
+
log?.info(`Grok Search: ${max_search_results} sources, recency: ${recency} (using grok-4-1-fast-reasoning with enhanced reasoning)`);
|
|
322
326
|
// Extract domains from sources if specified
|
|
323
327
|
const domains = sources
|
|
324
328
|
?.filter((s) => s.allowed_websites)
|
|
325
329
|
?.flatMap((s) => s.allowed_websites) || [];
|
|
326
330
|
const result = await callGrokEnhanced(messages, {
|
|
327
|
-
model: GrokModel.
|
|
331
|
+
model: GrokModel.GROK_4_1_FAST_REASONING, // Updated 2025-11-21: Use latest Grok 4.1 with search
|
|
328
332
|
enableLiveSearch: true,
|
|
329
333
|
searchSources: max_search_results,
|
|
330
334
|
searchDomains: domains,
|
|
@@ -340,7 +344,7 @@ Limit search to ${max_search_results} sources for cost control.`
|
|
|
340
344
|
* Check if Grok is available
|
|
341
345
|
*/
|
|
342
346
|
export function isGrokAvailable() {
|
|
343
|
-
return
|
|
347
|
+
return hasGrokApiKey();
|
|
344
348
|
}
|
|
345
349
|
/**
|
|
346
350
|
* Get Grok configuration status
|
|
@@ -348,10 +352,10 @@ export function isGrokAvailable() {
|
|
|
348
352
|
export function getGrokStatus() {
|
|
349
353
|
return {
|
|
350
354
|
available: isGrokAvailable(),
|
|
351
|
-
model: GrokModel.
|
|
355
|
+
model: GrokModel.GROK_4_1_FAST_REASONING,
|
|
352
356
|
features: [
|
|
353
|
-
'Fast
|
|
354
|
-
'
|
|
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)',
|
|
355
359
|
'Heavy mode available (grok-4-0709: $3/$15, use sparingly)',
|
|
356
360
|
'Live web search with citations',
|
|
357
361
|
'Function calling',
|
|
@@ -8,16 +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 =
|
|
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-
|
|
18
|
+
// Available Grok models - Updated 2025-11-22 with correct API model names
|
|
18
19
|
export var GrokModel;
|
|
19
20
|
(function (GrokModel) {
|
|
20
|
-
//
|
|
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
|
|
21
25
|
GrokModel["CODE_FAST"] = "grok-code-fast-1";
|
|
22
26
|
GrokModel["GROK_4_FAST_REASONING"] = "grok-4-fast-reasoning";
|
|
23
27
|
GrokModel["GROK_4_FAST"] = "grok-4-fast-non-reasoning";
|
|
@@ -28,11 +32,11 @@ export var GrokModel;
|
|
|
28
32
|
/**
|
|
29
33
|
* Call Grok API
|
|
30
34
|
*/
|
|
31
|
-
export async function callGrok(messages, model = GrokModel.
|
|
35
|
+
export async function callGrok(messages, model = GrokModel.GROK_4_1_FAST_REASONING, // Updated 2025-11-22: Use latest Grok 4.1 by default
|
|
32
36
|
temperature = 0.7, maxTokens = 16384, // Increased default for comprehensive responses
|
|
33
37
|
forceVisibleOutput = true) {
|
|
34
38
|
if (!GROK_API_KEY) {
|
|
35
|
-
return `[Grok API key not configured. Add
|
|
39
|
+
return `[Grok API key not configured. Add XAI_API_KEY to .env file]`;
|
|
36
40
|
}
|
|
37
41
|
// Validate and sanitize message content
|
|
38
42
|
const validatedMessages = messages.map((msg) => {
|
|
@@ -44,7 +48,9 @@ forceVisibleOutput = true) {
|
|
|
44
48
|
});
|
|
45
49
|
try {
|
|
46
50
|
// For Grok 4 models, we need to handle reasoning tokens specially
|
|
47
|
-
const isGrok4 = model === GrokModel.
|
|
51
|
+
const isGrok4 = model === GrokModel.GROK_4_1_FAST_REASONING ||
|
|
52
|
+
model === GrokModel.GROK_4_1_FAST ||
|
|
53
|
+
model === GrokModel.GROK_4_FAST_REASONING ||
|
|
48
54
|
model === GrokModel.GROK_4_FAST ||
|
|
49
55
|
model === GrokModel.GROK_4_HEAVY;
|
|
50
56
|
// Adjust prompt for Grok 4 to ensure visible output
|
|
@@ -113,7 +119,7 @@ export const grokReasonTool = {
|
|
|
113
119
|
const messages = [
|
|
114
120
|
{
|
|
115
121
|
role: "system",
|
|
116
|
-
content: `You are Grok, an expert at logical reasoning and problem-solving.
|
|
122
|
+
content: `You are Grok 4.1, an expert at logical reasoning and problem-solving with enhanced emotional intelligence.
|
|
117
123
|
${approachPrompts[approach]}.
|
|
118
124
|
${context ? `Context: ${context}` : ''}`
|
|
119
125
|
},
|
|
@@ -122,8 +128,8 @@ ${context ? `Context: ${context}` : ''}`
|
|
|
122
128
|
content: problem
|
|
123
129
|
}
|
|
124
130
|
];
|
|
125
|
-
// Use
|
|
126
|
-
const model = useHeavy ? GrokModel.GROK_4_HEAVY : GrokModel.
|
|
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;
|
|
127
133
|
const maxTokens = useHeavy ? 100000 : 16384; // 100k for heavy, 16k for normal reasoning
|
|
128
134
|
log?.info(`Using Grok model: ${model} for deep reasoning (max tokens: ${maxTokens}, cost: ${useHeavy ? 'expensive $3/$15' : 'cheap $0.20/$0.50'})`);
|
|
129
135
|
return await callGrok(messages, model, 0.7, maxTokens, true);
|
|
@@ -154,7 +160,7 @@ export const grokCodeTool = {
|
|
|
154
160
|
const messages = [
|
|
155
161
|
{
|
|
156
162
|
role: "system",
|
|
157
|
-
content: `You are Grok
|
|
163
|
+
content: `You are Grok 4.1 Fast, an expert programmer and code analyst with advanced tool-calling capabilities.
|
|
158
164
|
Task: ${taskPrompts[task]}
|
|
159
165
|
${language ? `Language: ${language}` : ''}
|
|
160
166
|
${requirements ? `Requirements: ${requirements}` : ''}`
|
|
@@ -164,8 +170,8 @@ ${requirements ? `Requirements: ${requirements}` : ''}`
|
|
|
164
170
|
content: `Code:\n\`\`\`${language || ''}\n${code}\n\`\`\``
|
|
165
171
|
}
|
|
166
172
|
];
|
|
167
|
-
log?.info(`Using Grok
|
|
168
|
-
return await callGrok(messages, GrokModel.
|
|
173
|
+
log?.info(`Using Grok 4.1 Fast Non-Reasoning (2M context, tool-calling optimized, $0.20/$0.50)`);
|
|
174
|
+
return await callGrok(messages, GrokModel.GROK_4_1_FAST, 0.2, 4000, true);
|
|
169
175
|
}
|
|
170
176
|
};
|
|
171
177
|
/**
|
|
@@ -208,8 +214,8 @@ Analyze the issue systematically:
|
|
|
208
214
|
content: prompt
|
|
209
215
|
}
|
|
210
216
|
];
|
|
211
|
-
log?.info(`Using Grok
|
|
212
|
-
return await callGrok(messages, GrokModel.
|
|
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);
|
|
213
219
|
}
|
|
214
220
|
};
|
|
215
221
|
/**
|
|
@@ -240,8 +246,8 @@ ${constraints ? `Constraints: ${constraints}` : ''}`
|
|
|
240
246
|
content: requirements
|
|
241
247
|
}
|
|
242
248
|
];
|
|
243
|
-
log?.info(`Using Grok 4 Fast Reasoning for architecture (
|
|
244
|
-
return await callGrok(messages, GrokModel.
|
|
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);
|
|
245
251
|
}
|
|
246
252
|
};
|
|
247
253
|
/**
|
|
@@ -271,9 +277,9 @@ ${constraints ? `Constraints: ${constraints}` : 'No constraints - think freely!'
|
|
|
271
277
|
content: `Brainstorm creative solutions for: ${topic}`
|
|
272
278
|
}
|
|
273
279
|
];
|
|
274
|
-
// Use
|
|
275
|
-
const model = forceHeavy ? GrokModel.GROK_4_HEAVY : GrokModel.
|
|
276
|
-
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'})`);
|
|
277
283
|
return await callGrok(messages, model, 0.95, 4000); // High temperature for creativity
|
|
278
284
|
}
|
|
279
285
|
};
|
|
@@ -281,7 +287,7 @@ ${constraints ? `Constraints: ${constraints}` : 'No constraints - think freely!'
|
|
|
281
287
|
* Check if Grok is available
|
|
282
288
|
*/
|
|
283
289
|
export function isGrokAvailable() {
|
|
284
|
-
return
|
|
290
|
+
return hasGrokApiKey();
|
|
285
291
|
}
|
|
286
292
|
export function getAllGrokTools() {
|
|
287
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
|
|
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
|
-
//
|
|
115
|
-
const
|
|
116
|
-
const endpoint =
|
|
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
|
-
|
|
119
|
-
|
|
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
|
|
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
|
-
|
|
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 ${
|
|
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
|
|
163
|
+
// Parse based on API type
|
|
163
164
|
let rawContent;
|
|
164
|
-
if (
|
|
165
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
229
|
-
const
|
|
230
|
-
const endpoint =
|
|
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
|
-
|
|
233
|
-
|
|
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
|
-
|
|
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 ${
|
|
256
|
-
console.error(`🔍 TRACE: Model params:
|
|
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 (
|
|
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: "
|
|
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)
|