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.
- package/.env.example +5 -2
- package/dist/src/config/model-constants.js +83 -73
- 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 +18 -17
- package/dist/src/tools/grok-tools.js +21 -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 +20 -11
- package/dist/src/workflows/tool-mapper.js +41 -14
- package/docs/API_KEYS.md +7 -7
- package/docs/TOOLS_REFERENCE.md +1 -37
- 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/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,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 =
|
|
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
|
-
// Grok 4.1 models (Nov 2025) - LATEST & BEST
|
|
19
|
-
GrokModel["
|
|
20
|
-
GrokModel["GROK_4_1_FAST"] = "grok-4
|
|
21
|
-
//
|
|
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.
|
|
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
|
|
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.
|
|
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.
|
|
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-
|
|
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
|
|
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.
|
|
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
|
|
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.
|
|
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 =
|
|
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
|
-
// Grok 4.1 models (Nov 2025) - LATEST & BEST
|
|
21
|
-
GrokModel["
|
|
22
|
-
GrokModel["GROK_4_1_FAST"] = "grok-4
|
|
23
|
-
//
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
131
|
-
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;
|
|
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,
|
|
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
|
|
217
|
-
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);
|
|
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 (
|
|
249
|
-
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);
|
|
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
|
|
280
|
-
const model = forceHeavy ? GrokModel.GROK_4_HEAVY : GrokModel.
|
|
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
|
|
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
|
|
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)
|