tachibot-mcp 2.2.0 → 2.2.5
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/dist/src/config/model-constants.js +23 -15
- package/dist/src/config/model-defaults.js +4 -4
- package/dist/src/optimization/model-router.js +13 -14
- package/dist/src/tools/openai-tools.js +141 -83
- package/dist/src/tools/unified-ai-provider.js +42 -18
- package/dist/src/workflows/engine/WorkflowExecutionEngine.js +1 -1
- package/package.json +1 -1
- package/workflows/core/iterative-problem-solver.yaml +2 -2
- package/workflows/system/scout.yaml +1 -1
- package/workflows/ultra-creative-brainstorm.yaml +2 -2
|
@@ -7,30 +7,34 @@
|
|
|
7
7
|
// OPENAI MODELS (provider-based naming)
|
|
8
8
|
// =============================================================================
|
|
9
9
|
// GPT-5.2 released Dec 11, 2025 - CURRENT
|
|
10
|
-
//
|
|
10
|
+
// Model is "gpt-5.2", "thinking" is controlled by reasoning.effort parameter
|
|
11
|
+
// OpenRouter uses prefix: openai/gpt-5.2-pro, openai/gpt-5.2
|
|
11
12
|
export const OPENAI_MODELS = {
|
|
12
13
|
// GPT-5.2 Models (Dec 2025 - CURRENT)
|
|
13
|
-
|
|
14
|
+
// Note: "gpt-5.2" + reasoning.effort="high"/"xhigh" = "thinking" mode
|
|
15
|
+
DEFAULT: "gpt-5.2", // Main model - use with reasoning.effort for "thinking"
|
|
14
16
|
PRO: "gpt-5.2-pro", // Expert: programming, science, 88.4% GPQA ($21/$168, 400K)
|
|
15
|
-
INSTANT: "gpt-5.2-instant", // Fast: conversations, explanations ($1.75/$14, 400K)
|
|
16
17
|
// Aliases for backward compatibility
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
THINKING: "gpt-5.2", // "Thinking" = gpt-5.2 with high reasoning effort
|
|
19
|
+
INSTANT: "gpt-5.2", // Same model, just use lower reasoning effort
|
|
20
|
+
FULL: "gpt-5.2", // Map old FULL to DEFAULT
|
|
21
|
+
CODEX_MINI: "gpt-5.2", // Map old codex-mini to DEFAULT
|
|
19
22
|
CODEX: "gpt-5.2-pro", // Map old codex to PRO
|
|
20
23
|
CODEX_MAX: "gpt-5.2-pro", // Map old codex-max to PRO
|
|
21
24
|
};
|
|
22
25
|
// OpenRouter model ID mapping (add prefix when using OpenRouter gateway)
|
|
23
26
|
export const OPENROUTER_PREFIX_MAP = {
|
|
24
|
-
"gpt-5.2
|
|
27
|
+
"gpt-5.2": "openai/",
|
|
25
28
|
"gpt-5.2-pro": "openai/",
|
|
26
|
-
"gpt-5.2-instant": "openai/",
|
|
27
29
|
};
|
|
28
30
|
// OpenAI Reasoning Effort Levels (for models that support it)
|
|
31
|
+
// Use with gpt-5.2: none=fast, low/medium=balanced, high/xhigh="thinking" mode
|
|
29
32
|
export const OPENAI_REASONING = {
|
|
30
|
-
NONE: "none", // No extra reasoning (fastest,
|
|
33
|
+
NONE: "none", // No extra reasoning (fastest, allows temperature)
|
|
31
34
|
LOW: "low", // Light reasoning
|
|
32
35
|
MEDIUM: "medium", // Balanced reasoning (default)
|
|
33
|
-
HIGH: "high", //
|
|
36
|
+
HIGH: "high", // Strong reasoning ("thinking" mode)
|
|
37
|
+
XHIGH: "xhigh", // Maximum reasoning (most thorough, slowest)
|
|
34
38
|
};
|
|
35
39
|
// =============================================================================
|
|
36
40
|
// GEMINI MODELS (Google)
|
|
@@ -112,13 +116,17 @@ export const DEFAULT_WORKFLOW_SETTINGS = {
|
|
|
112
116
|
// When new models release, update ONLY this section!
|
|
113
117
|
// All tools automatically use the new models.
|
|
114
118
|
// ============================================================================
|
|
115
|
-
// UPDATED Dec
|
|
119
|
+
// UPDATED Dec 12, 2025: Use gpt-5.2 with reasoning.effort for "thinking" mode
|
|
120
|
+
// PRO available for opt-in when extra quality needed (12x more expensive)
|
|
116
121
|
export const CURRENT_MODELS = {
|
|
117
122
|
openai: {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
123
|
+
default: OPENAI_MODELS.DEFAULT, // gpt-5.2 - use with reasoning.effort
|
|
124
|
+
reason: OPENAI_MODELS.DEFAULT, // Deep reasoning (gpt-5.2 + effort=high)
|
|
125
|
+
brainstorm: OPENAI_MODELS.DEFAULT, // Creative ideation (gpt-5.2 + effort=medium)
|
|
126
|
+
code: OPENAI_MODELS.DEFAULT, // Code tasks (gpt-5.2 + effort=medium)
|
|
127
|
+
explain: OPENAI_MODELS.DEFAULT, // Explanations (gpt-5.2 + effort=low)
|
|
128
|
+
// Premium option for opt-in (use sparingly - 12x more expensive)
|
|
129
|
+
premium: OPENAI_MODELS.PRO, // Expert mode (gpt-5.2-pro - 88.4% GPQA, $21/$168)
|
|
122
130
|
},
|
|
123
131
|
grok: {
|
|
124
132
|
reason: GROK_MODELS._4_1_FAST_REASONING,
|
|
@@ -244,7 +252,7 @@ export const TOOL_DEFAULTS = {
|
|
|
244
252
|
think: {
|
|
245
253
|
model: CURRENT_MODELS.openai.reason,
|
|
246
254
|
reasoning_effort: OPENAI_REASONING.HIGH,
|
|
247
|
-
maxTokens:
|
|
255
|
+
maxTokens: 4000,
|
|
248
256
|
temperature: 0.7,
|
|
249
257
|
},
|
|
250
258
|
focus: {
|
|
@@ -17,9 +17,9 @@ import { GEMINI_MODELS, OPENAI_MODELS, GROK_MODELS, PERPLEXITY_MODELS, KIMI_MODE
|
|
|
17
17
|
const MODELS = {
|
|
18
18
|
// Google Gemini
|
|
19
19
|
GEMINI: GEMINI_MODELS.GEMINI_3_PRO, // gemini-3-pro-preview
|
|
20
|
-
// OpenAI
|
|
21
|
-
OPENAI: OPENAI_MODELS.
|
|
22
|
-
OPENAI_REASON: OPENAI_MODELS.
|
|
20
|
+
// OpenAI (GPT-5.2)
|
|
21
|
+
OPENAI: OPENAI_MODELS.THINKING, // gpt-5.2-thinking (default - SOTA reasoning)
|
|
22
|
+
OPENAI_REASON: OPENAI_MODELS.THINKING, // gpt-5.2-thinking (deep reasoning)
|
|
23
23
|
// xAI Grok
|
|
24
24
|
GROK: GROK_MODELS._4_1_FAST_REASONING, // grok-4-1-fast-reasoning
|
|
25
25
|
// Perplexity
|
|
@@ -50,7 +50,7 @@ export function getChallengerModels() {
|
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
52
|
* Get Verifier model configuration
|
|
53
|
-
* All variants use Gemini 3 Pro; deep uses gpt-5.
|
|
53
|
+
* All variants use Gemini 3 Pro; deep uses gpt-5.2-thinking for max reasoning
|
|
54
54
|
*/
|
|
55
55
|
export function getVerifierModels() {
|
|
56
56
|
const quick = process.env.VERIFIER_QUICK_MODELS?.split(',').map(m => m.trim()) ||
|
|
@@ -4,25 +4,24 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export var ModelTier;
|
|
6
6
|
(function (ModelTier) {
|
|
7
|
-
// Tier 0: Cheapest - GPT-5.
|
|
8
|
-
ModelTier["ULTRA_CHEAP"] = "gpt-5.
|
|
7
|
+
// Tier 0: Cheapest - GPT-5.2 Instant/Thinking (same price!)
|
|
8
|
+
ModelTier["ULTRA_CHEAP"] = "gpt-5.2-instant";
|
|
9
9
|
// Tier 1: Ultra Fast & Cheap (< $0.001 per request)
|
|
10
10
|
ModelTier["ULTRA_EFFICIENT"] = "gemini-2.5-flash";
|
|
11
|
-
ModelTier["EFFICIENT"] = "gpt-5.
|
|
12
|
-
// Tier 2: Balanced
|
|
13
|
-
ModelTier["STANDARD"] = "gpt-5.
|
|
14
|
-
ModelTier["GPT5_MINI"] = "gpt-5.
|
|
11
|
+
ModelTier["EFFICIENT"] = "gpt-5.2-thinking";
|
|
12
|
+
// Tier 2: Balanced - GPT-5.2 Thinking (best value)
|
|
13
|
+
ModelTier["STANDARD"] = "gpt-5.2-thinking";
|
|
14
|
+
ModelTier["GPT5_MINI"] = "gpt-5.2-thinking";
|
|
15
15
|
// Tier 3: Advanced ($0.01-$0.05 per request)
|
|
16
16
|
ModelTier["WEB_SEARCH"] = "perplexity-sonar-pro";
|
|
17
|
-
// Tier 4: Premium (Use with caution)
|
|
18
|
-
ModelTier["GPT5_FULL"] = "gpt-5.
|
|
17
|
+
// Tier 4: Premium (Use with caution - 12x more expensive)
|
|
18
|
+
ModelTier["GPT5_FULL"] = "gpt-5.2-pro";
|
|
19
19
|
})(ModelTier || (ModelTier = {}));
|
|
20
20
|
const MODEL_COSTS = {
|
|
21
|
-
// GPT-5.
|
|
22
|
-
"gpt-5.
|
|
23
|
-
"gpt-5.
|
|
24
|
-
"gpt-5.
|
|
25
|
-
"gpt-5-pro": { input: 0.020, output: 0.060, latency: 3000 },
|
|
21
|
+
// GPT-5.2 Models (Dec 2025 pricing) - ACTUAL API MODEL NAMES
|
|
22
|
+
"gpt-5.2-thinking": { input: 0.00175, output: 0.014, latency: 1500 }, // SOTA reasoning, cheap!
|
|
23
|
+
"gpt-5.2-instant": { input: 0.00175, output: 0.014, latency: 800 }, // Fast, same price
|
|
24
|
+
"gpt-5.2-pro": { input: 0.021, output: 0.168, latency: 2500 }, // Premium (12x more)
|
|
26
25
|
// Gemini models
|
|
27
26
|
"gemini-2.5-flash": { input: 0.000075, output: 0.0003, latency: 500 },
|
|
28
27
|
"gemini-2.5-pro": { input: 0.00015, output: 0.0006, latency: 1000 },
|
|
@@ -103,7 +102,7 @@ export class SmartModelRouter {
|
|
|
103
102
|
const gpt5Enabled = process.env.ENABLE_GPT5 !== "false";
|
|
104
103
|
if (gpt5Enabled) {
|
|
105
104
|
return {
|
|
106
|
-
primary: ModelTier.ULTRA_CHEAP, // gpt-5.
|
|
105
|
+
primary: ModelTier.ULTRA_CHEAP, // gpt-5.2-instant
|
|
107
106
|
fallback: ModelTier.ULTRA_EFFICIENT, // gemini-2.5-flash
|
|
108
107
|
estimatedCost: 0.002,
|
|
109
108
|
estimatedLatency: 800,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OpenAI Tools Implementation
|
|
3
|
-
* Provides GPT-5.
|
|
3
|
+
* Provides GPT-5.2 model capabilities with reasoning_effort control
|
|
4
|
+
* Uses centralized model constants from model-constants.ts
|
|
4
5
|
*/
|
|
5
6
|
import { z } from "zod";
|
|
6
7
|
import { config } from "dotenv";
|
|
@@ -8,6 +9,7 @@ import * as path from 'path';
|
|
|
8
9
|
import { fileURLToPath } from 'url';
|
|
9
10
|
import { validateToolInput } from "../utils/input-validator.js";
|
|
10
11
|
import { tryOpenRouterGateway, isGatewayEnabled } from "../utils/openrouter-gateway.js";
|
|
12
|
+
import { OPENAI_MODELS } from "../config/model-constants.js";
|
|
11
13
|
const __filename = fileURLToPath(import.meta.url);
|
|
12
14
|
const __dirname = path.dirname(__filename);
|
|
13
15
|
config({ path: path.resolve(__dirname, '../../../.env') });
|
|
@@ -71,20 +73,40 @@ const ResponsesAPISchema = z.object({
|
|
|
71
73
|
total_tokens: z.number().optional()
|
|
72
74
|
}).optional()
|
|
73
75
|
});
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
76
|
+
// Type guard for safe fallback extraction
|
|
77
|
+
function isPartialChatCompletion(data) {
|
|
78
|
+
if (typeof data !== 'object' || data === null)
|
|
79
|
+
return false;
|
|
80
|
+
const obj = data;
|
|
81
|
+
return Array.isArray(obj.choices);
|
|
82
|
+
}
|
|
83
|
+
// Type guard for Responses API fallback extraction
|
|
84
|
+
function isPartialResponsesAPI(data) {
|
|
85
|
+
if (typeof data !== 'object' || data === null)
|
|
86
|
+
return false;
|
|
87
|
+
const obj = data;
|
|
88
|
+
return Array.isArray(obj.output);
|
|
89
|
+
}
|
|
90
|
+
// Re-export for backward compatibility (maps to gpt-5.2 models)
|
|
91
|
+
// "Thinking" mode = gpt-5.2 with reasoning.effort="high"/"xhigh"
|
|
92
|
+
export const OpenAI52Model = {
|
|
93
|
+
DEFAULT: OPENAI_MODELS.DEFAULT, // gpt-5.2 (use with reasoning.effort)
|
|
94
|
+
THINKING: OPENAI_MODELS.DEFAULT, // gpt-5.2 + high effort = "thinking"
|
|
95
|
+
PRO: OPENAI_MODELS.PRO, // gpt-5.2-pro (expert mode)
|
|
96
|
+
INSTANT: OPENAI_MODELS.DEFAULT, // gpt-5.2 + low effort = fast
|
|
97
|
+
// Legacy aliases
|
|
98
|
+
FULL: OPENAI_MODELS.DEFAULT,
|
|
99
|
+
CODEX_MINI: OPENAI_MODELS.DEFAULT,
|
|
100
|
+
CODEX: OPENAI_MODELS.PRO,
|
|
101
|
+
};
|
|
102
|
+
// Backward compatibility alias
|
|
103
|
+
export const OpenAI51Model = OpenAI52Model;
|
|
83
104
|
/**
|
|
84
105
|
* Call OpenAI API with model fallback support
|
|
85
|
-
*
|
|
106
|
+
* GPT-5.2 uses /v1/responses endpoint for all models
|
|
86
107
|
*/
|
|
87
|
-
export async function callOpenAI(messages, model =
|
|
108
|
+
export async function callOpenAI(messages, model = OPENAI_MODELS.INSTANT, // Default to fast/cheap model
|
|
109
|
+
temperature = 0.7, maxTokens = 16384, // Increased default for comprehensive responses
|
|
88
110
|
reasoningEffort = "low", requireConfirmation = false, skipValidation = false) {
|
|
89
111
|
console.error(`🔍 TRACE: callOpenAI called with model: ${model}`);
|
|
90
112
|
// Try OpenRouter gateway first if enabled
|
|
@@ -114,11 +136,10 @@ reasoningEffort = "low", requireConfirmation = false, skipValidation = false) {
|
|
|
114
136
|
}
|
|
115
137
|
return { ...msg, content: validation.sanitized };
|
|
116
138
|
});
|
|
117
|
-
// Model fallback chain - GPT-5.
|
|
139
|
+
// Model fallback chain - GPT-5.2 models have no fallbacks to test actual availability
|
|
118
140
|
const modelFallbacks = {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
[OpenAI51Model.CODEX]: [] // No fallback - test actual GPT-5.1-codex
|
|
141
|
+
"gpt-5.2": [], // No fallback - test actual gpt-5.2
|
|
142
|
+
"gpt-5.2-pro": [] // No fallback - test actual gpt-5.2-pro
|
|
122
143
|
};
|
|
123
144
|
const modelsToTry = [model, ...(modelFallbacks[model] || [])];
|
|
124
145
|
console.error(`🔍 TRACE: Models to try: ${modelsToTry.join(', ')}`);
|
|
@@ -126,33 +147,37 @@ reasoningEffort = "low", requireConfirmation = false, skipValidation = false) {
|
|
|
126
147
|
for (const currentModel of modelsToTry) {
|
|
127
148
|
console.error(`🔍 TRACE: Trying model: ${currentModel}`);
|
|
128
149
|
try {
|
|
129
|
-
//
|
|
130
|
-
const
|
|
131
|
-
const endpoint =
|
|
150
|
+
// GPT-5.2 uses Responses API, others use Chat Completions
|
|
151
|
+
const isGPT52 = currentModel.startsWith('gpt-5.2');
|
|
152
|
+
const endpoint = isGPT52 ? OPENAI_RESPONSES_URL : OPENAI_CHAT_URL;
|
|
132
153
|
let requestBody;
|
|
133
|
-
if (
|
|
134
|
-
// Responses API format for
|
|
154
|
+
if (isGPT52) {
|
|
155
|
+
// Responses API format for GPT-5.2
|
|
156
|
+
// Input is array of message objects [{role, content}]
|
|
157
|
+
const inputMessages = validatedMessages.map(m => ({
|
|
158
|
+
role: m.role,
|
|
159
|
+
content: m.content
|
|
160
|
+
}));
|
|
135
161
|
requestBody = {
|
|
136
162
|
model: currentModel,
|
|
137
|
-
input:
|
|
138
|
-
max_output_tokens: maxTokens,
|
|
139
|
-
stream: false,
|
|
163
|
+
input: inputMessages,
|
|
140
164
|
reasoning: {
|
|
141
|
-
effort: reasoningEffort
|
|
142
|
-
}
|
|
165
|
+
effort: reasoningEffort || 'medium'
|
|
166
|
+
},
|
|
167
|
+
max_output_tokens: maxTokens
|
|
143
168
|
};
|
|
144
169
|
}
|
|
145
170
|
else {
|
|
146
|
-
// Chat Completions format for
|
|
171
|
+
// Chat Completions format for older models
|
|
147
172
|
requestBody = {
|
|
148
173
|
model: currentModel,
|
|
149
174
|
messages: validatedMessages,
|
|
150
|
-
|
|
151
|
-
|
|
175
|
+
max_completion_tokens: maxTokens,
|
|
176
|
+
temperature: temperature,
|
|
152
177
|
stream: false
|
|
153
178
|
};
|
|
154
179
|
}
|
|
155
|
-
console.error(`🔍 TRACE: Using ${
|
|
180
|
+
console.error(`🔍 TRACE: Using ${isGPT52 ? '/v1/responses' : '/v1/chat/completions'} endpoint for ${currentModel}`);
|
|
156
181
|
const response = await fetch(endpoint, {
|
|
157
182
|
method: "POST",
|
|
158
183
|
headers: {
|
|
@@ -173,25 +198,37 @@ reasoningEffort = "low", requireConfirmation = false, skipValidation = false) {
|
|
|
173
198
|
throw new Error(lastError);
|
|
174
199
|
}
|
|
175
200
|
const rawData = await response.json();
|
|
176
|
-
// Parse based on API type
|
|
201
|
+
// Parse response based on API type
|
|
177
202
|
let rawContent;
|
|
178
|
-
if (
|
|
179
|
-
// Responses API
|
|
203
|
+
if (isGPT52) {
|
|
204
|
+
// Parse Responses API response for GPT-5.2
|
|
180
205
|
const parseResult = ResponsesAPISchema.safeParse(rawData);
|
|
181
206
|
if (parseResult.success) {
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
207
|
+
const responsesData = parseResult.data;
|
|
208
|
+
// Extract text from output array - find first message with content
|
|
209
|
+
for (const outputItem of responsesData.output) {
|
|
210
|
+
if (outputItem.content) {
|
|
211
|
+
for (const contentItem of outputItem.content) {
|
|
212
|
+
if (contentItem.text) {
|
|
213
|
+
rawContent = contentItem.text;
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (rawContent)
|
|
219
|
+
break;
|
|
187
220
|
}
|
|
188
221
|
}
|
|
189
222
|
else {
|
|
190
223
|
console.error(`🔍 TRACE: Failed to parse Responses API response:`, parseResult.error);
|
|
224
|
+
// Safe fallback using type guard
|
|
225
|
+
if (isPartialResponsesAPI(rawData)) {
|
|
226
|
+
rawContent = rawData.output?.[0]?.content?.[0]?.text;
|
|
227
|
+
}
|
|
191
228
|
}
|
|
192
229
|
}
|
|
193
230
|
else {
|
|
194
|
-
// Chat Completions
|
|
231
|
+
// Parse Chat Completions response for older models
|
|
195
232
|
const parseResult = ChatCompletionResponseSchema.safeParse(rawData);
|
|
196
233
|
if (parseResult.success) {
|
|
197
234
|
const chatData = parseResult.data;
|
|
@@ -199,6 +236,10 @@ reasoningEffort = "low", requireConfirmation = false, skipValidation = false) {
|
|
|
199
236
|
}
|
|
200
237
|
else {
|
|
201
238
|
console.error(`🔍 TRACE: Failed to parse Chat Completions response:`, parseResult.error);
|
|
239
|
+
// Safe fallback using type guard
|
|
240
|
+
if (isPartialChatCompletion(rawData)) {
|
|
241
|
+
rawContent = rawData.choices?.[0]?.message?.content;
|
|
242
|
+
}
|
|
202
243
|
}
|
|
203
244
|
}
|
|
204
245
|
// Ensure result is always a string
|
|
@@ -213,13 +254,13 @@ reasoningEffort = "low", requireConfirmation = false, skipValidation = false) {
|
|
|
213
254
|
}
|
|
214
255
|
}
|
|
215
256
|
console.error(`🔍 TRACE: ALL MODELS FAILED - Last error: ${lastError}`);
|
|
216
|
-
return `[GPT-5.
|
|
257
|
+
return `[GPT-5.2 model "${model}" not available. Error: ${lastError}]`;
|
|
217
258
|
}
|
|
218
259
|
/**
|
|
219
260
|
* Call OpenAI API with custom parameters for specific models
|
|
220
|
-
*
|
|
261
|
+
* GPT-5.2 models use /v1/responses endpoint
|
|
221
262
|
*/
|
|
222
|
-
async function callOpenAIWithCustomParams(messages, model, temperature = 0.7, maxTokens = 16384, // Increased for detailed brainstorming
|
|
263
|
+
async function callOpenAIWithCustomParams(messages, model = OPENAI_MODELS.DEFAULT, temperature = 0.7, maxTokens = 16384, // Increased for detailed brainstorming
|
|
223
264
|
reasoningEffort = "low", skipValidation = false) {
|
|
224
265
|
console.error(`🔍 TRACE: callOpenAIWithCustomParams called with model: ${model}, reasoning_effort: ${reasoningEffort}`);
|
|
225
266
|
// Try OpenRouter gateway first if enabled
|
|
@@ -249,34 +290,38 @@ reasoningEffort = "low", skipValidation = false) {
|
|
|
249
290
|
return { ...msg, content: validation.sanitized };
|
|
250
291
|
});
|
|
251
292
|
try {
|
|
252
|
-
//
|
|
253
|
-
const
|
|
254
|
-
const endpoint =
|
|
293
|
+
// GPT-5.2 uses Responses API, others use Chat Completions
|
|
294
|
+
const isGPT52 = model.startsWith('gpt-5.2');
|
|
295
|
+
const endpoint = isGPT52 ? OPENAI_RESPONSES_URL : OPENAI_CHAT_URL;
|
|
255
296
|
let requestBody;
|
|
256
|
-
if (
|
|
257
|
-
// Responses API format for
|
|
297
|
+
if (isGPT52) {
|
|
298
|
+
// Responses API format for GPT-5.2
|
|
299
|
+
// Input is array of message objects [{role, content}]
|
|
300
|
+
const inputMessages = validatedMessages.map(m => ({
|
|
301
|
+
role: m.role,
|
|
302
|
+
content: m.content
|
|
303
|
+
}));
|
|
258
304
|
requestBody = {
|
|
259
305
|
model: model,
|
|
260
|
-
input:
|
|
261
|
-
max_output_tokens: maxTokens, // NOT max_completion_tokens or max_tokens!
|
|
262
|
-
stream: false,
|
|
306
|
+
input: inputMessages,
|
|
263
307
|
reasoning: {
|
|
264
|
-
effort: reasoningEffort
|
|
265
|
-
}
|
|
308
|
+
effort: reasoningEffort || 'medium'
|
|
309
|
+
},
|
|
310
|
+
max_output_tokens: maxTokens
|
|
266
311
|
};
|
|
267
312
|
}
|
|
268
313
|
else {
|
|
269
|
-
// Chat Completions format for
|
|
314
|
+
// Chat Completions format for older models
|
|
270
315
|
requestBody = {
|
|
271
316
|
model: model,
|
|
272
317
|
messages: validatedMessages,
|
|
273
|
-
|
|
274
|
-
|
|
318
|
+
max_completion_tokens: maxTokens,
|
|
319
|
+
temperature: temperature,
|
|
275
320
|
stream: false
|
|
276
321
|
};
|
|
277
322
|
}
|
|
278
|
-
console.error(`🔍 TRACE: Using ${
|
|
279
|
-
console.error(`🔍 TRACE: Model params:
|
|
323
|
+
console.error(`🔍 TRACE: Using ${isGPT52 ? '/v1/responses' : '/v1/chat/completions'} endpoint for ${model}`);
|
|
324
|
+
console.error(`🔍 TRACE: Model params: max_tokens=${maxTokens}, reasoning_effort=${reasoningEffort}`);
|
|
280
325
|
const response = await fetch(endpoint, {
|
|
281
326
|
method: "POST",
|
|
282
327
|
headers: {
|
|
@@ -291,26 +336,35 @@ reasoningEffort = "low", skipValidation = false) {
|
|
|
291
336
|
return `[${model} failed: ${response.status} - ${error}]`;
|
|
292
337
|
}
|
|
293
338
|
const rawData = await response.json();
|
|
294
|
-
// Parse based on API type
|
|
339
|
+
// Parse response based on API type
|
|
295
340
|
let rawContent;
|
|
296
|
-
if (
|
|
297
|
-
//
|
|
341
|
+
if (isGPT52) {
|
|
342
|
+
// Parse Responses API response for GPT-5.2
|
|
298
343
|
const parseResult = ResponsesAPISchema.safeParse(rawData);
|
|
299
344
|
if (parseResult.success) {
|
|
300
|
-
const
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
345
|
+
const responsesData = parseResult.data;
|
|
346
|
+
for (const outputItem of responsesData.output) {
|
|
347
|
+
if (outputItem.content) {
|
|
348
|
+
for (const contentItem of outputItem.content) {
|
|
349
|
+
if (contentItem.text) {
|
|
350
|
+
rawContent = contentItem.text;
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (rawContent)
|
|
356
|
+
break;
|
|
306
357
|
}
|
|
307
358
|
}
|
|
308
359
|
else {
|
|
309
360
|
console.error(`🔍 TRACE: Failed to parse Responses API response:`, parseResult.error);
|
|
361
|
+
if (isPartialResponsesAPI(rawData)) {
|
|
362
|
+
rawContent = rawData.output?.[0]?.content?.[0]?.text;
|
|
363
|
+
}
|
|
310
364
|
}
|
|
311
365
|
}
|
|
312
366
|
else {
|
|
313
|
-
//
|
|
367
|
+
// Parse Chat Completions response for older models
|
|
314
368
|
const parseResult = ChatCompletionResponseSchema.safeParse(rawData);
|
|
315
369
|
if (parseResult.success) {
|
|
316
370
|
const chatData = parseResult.data;
|
|
@@ -318,6 +372,9 @@ reasoningEffort = "low", skipValidation = false) {
|
|
|
318
372
|
}
|
|
319
373
|
else {
|
|
320
374
|
console.error(`🔍 TRACE: Failed to parse Chat Completions response:`, parseResult.error);
|
|
375
|
+
if (isPartialChatCompletion(rawData)) {
|
|
376
|
+
rawContent = rawData.choices?.[0]?.message?.content;
|
|
377
|
+
}
|
|
321
378
|
}
|
|
322
379
|
}
|
|
323
380
|
// Ensure result is always a string
|
|
@@ -364,8 +421,8 @@ export const gpt5ReasonTool = {
|
|
|
364
421
|
content: args.query
|
|
365
422
|
}
|
|
366
423
|
];
|
|
367
|
-
// Use GPT-5.
|
|
368
|
-
return await callOpenAI(messages,
|
|
424
|
+
// Use GPT-5.2-thinking with high reasoning
|
|
425
|
+
return await callOpenAI(messages, OPENAI_MODELS.DEFAULT, 0.7, 4000, "high");
|
|
369
426
|
}
|
|
370
427
|
};
|
|
371
428
|
/**
|
|
@@ -396,13 +453,13 @@ export const gpt5MiniReasonTool = {
|
|
|
396
453
|
content: args.query
|
|
397
454
|
}
|
|
398
455
|
];
|
|
399
|
-
// Use GPT-5.
|
|
400
|
-
return await callOpenAI(messages,
|
|
456
|
+
// Use GPT-5.2-thinking with medium reasoning (cost-effective)
|
|
457
|
+
return await callOpenAI(messages, OPENAI_MODELS.DEFAULT, 0.7, 3000, "medium");
|
|
401
458
|
}
|
|
402
459
|
};
|
|
403
460
|
export const openaiGpt5ReasonTool = {
|
|
404
461
|
name: "openai_reason",
|
|
405
|
-
description: "Mathematical reasoning using GPT-5.
|
|
462
|
+
description: "Mathematical reasoning using GPT-5.2-thinking with high reasoning effort",
|
|
406
463
|
parameters: z.object({
|
|
407
464
|
query: z.string(),
|
|
408
465
|
context: z.string().optional(),
|
|
@@ -428,8 +485,8 @@ ${args.context ? `Context: ${args.context}` : ''}`
|
|
|
428
485
|
content: args.query
|
|
429
486
|
}
|
|
430
487
|
];
|
|
431
|
-
// Use GPT-5.
|
|
432
|
-
return await callOpenAI(messages,
|
|
488
|
+
// Use GPT-5.2-thinking with high reasoning effort for complex reasoning
|
|
489
|
+
return await callOpenAI(messages, OPENAI_MODELS.DEFAULT, 0.7, 4000, "high");
|
|
433
490
|
}
|
|
434
491
|
};
|
|
435
492
|
/**
|
|
@@ -444,12 +501,13 @@ export const openAIBrainstormTool = {
|
|
|
444
501
|
constraints: z.string().optional(),
|
|
445
502
|
quantity: z.number().optional(),
|
|
446
503
|
style: z.enum(["innovative", "practical", "wild", "systematic"]).optional(),
|
|
447
|
-
model: z.enum(["gpt-5.
|
|
448
|
-
reasoning_effort: z.enum(["none", "low", "medium", "high"]).optional(),
|
|
504
|
+
model: z.enum(["gpt-5.2", "gpt-5.2-pro"]).optional(),
|
|
505
|
+
reasoning_effort: z.enum(["none", "low", "medium", "high", "xhigh"]).optional(),
|
|
449
506
|
max_tokens: z.number().optional()
|
|
450
507
|
}),
|
|
451
508
|
execute: async (args, options = {}) => {
|
|
452
|
-
const { problem, constraints, quantity = 5, style = "innovative", model =
|
|
509
|
+
const { problem, constraints, quantity = 5, style = "innovative", model = OPENAI_MODELS.DEFAULT, // Default to gpt-5.2 (use reasoning.effort for "thinking")
|
|
510
|
+
reasoning_effort = "medium", max_tokens = 4000 } = args;
|
|
453
511
|
console.error('🚀 TOOL CALLED: openai_brainstorm');
|
|
454
512
|
console.error('📥 ARGS RECEIVED:', JSON.stringify(args, null, 2));
|
|
455
513
|
console.error('📥 OPTIONS RECEIVED:', JSON.stringify(options, null, 2));
|
|
@@ -516,7 +574,7 @@ Format: Use sections for different aspects, be specific about line numbers or fu
|
|
|
516
574
|
content: `Review this code:\n\`\`\`${args.language || ''}\n${args.code}\n\`\`\``
|
|
517
575
|
}
|
|
518
576
|
];
|
|
519
|
-
return await callOpenAI(messages,
|
|
577
|
+
return await callOpenAI(messages, OPENAI_MODELS.DEFAULT, 0.3, 4000, "medium");
|
|
520
578
|
}
|
|
521
579
|
};
|
|
522
580
|
/**
|
|
@@ -556,7 +614,7 @@ Make the explanation clear, engaging, and memorable.`
|
|
|
556
614
|
content: `Explain: ${args.topic}`
|
|
557
615
|
}
|
|
558
616
|
];
|
|
559
|
-
return await callOpenAI(messages,
|
|
617
|
+
return await callOpenAI(messages, OPENAI_MODELS.DEFAULT, 0.7, 2500, "low");
|
|
560
618
|
}
|
|
561
619
|
};
|
|
562
620
|
/**
|
|
@@ -573,9 +631,9 @@ export function getAllOpenAITools() {
|
|
|
573
631
|
return [];
|
|
574
632
|
}
|
|
575
633
|
return [
|
|
576
|
-
openaiGpt5ReasonTool, // GPT-5.
|
|
577
|
-
openAIBrainstormTool, // GPT-5.
|
|
578
|
-
openaiCodeReviewTool, // GPT-5.
|
|
579
|
-
openaiExplainTool // GPT-5.
|
|
634
|
+
openaiGpt5ReasonTool, // GPT-5.2-thinking reasoning (high effort)
|
|
635
|
+
openAIBrainstormTool, // GPT-5.2-thinking brainstorming (medium effort)
|
|
636
|
+
openaiCodeReviewTool, // GPT-5.2-thinking code review (medium effort)
|
|
637
|
+
openaiExplainTool // GPT-5.2-thinking explanations (low effort)
|
|
580
638
|
];
|
|
581
639
|
}
|
|
@@ -59,12 +59,12 @@ const PROVIDER_CONFIGS = {
|
|
|
59
59
|
openai: {
|
|
60
60
|
base: 'https://api.openai.com/v1',
|
|
61
61
|
key: process.env.OPENAI_API_KEY,
|
|
62
|
-
models: ['gpt-5.
|
|
62
|
+
models: ['gpt-5.2', 'gpt-5.2-pro'] // gpt-5.2 with reasoning.effort for "thinking"
|
|
63
63
|
},
|
|
64
|
-
|
|
65
|
-
base: 'https://api.openai.com/v1', // Uses /responses endpoint
|
|
64
|
+
gpt52: {
|
|
65
|
+
base: 'https://api.openai.com/v1', // Uses /responses endpoint
|
|
66
66
|
key: process.env.OPENAI_API_KEY,
|
|
67
|
-
models: ['gpt-5.
|
|
67
|
+
models: ['gpt-5.2', 'gpt-5.2-pro'], // reasoning.effort controls "thinking" mode
|
|
68
68
|
special: true // Needs special handling for reasoning_effort
|
|
69
69
|
},
|
|
70
70
|
mistral: {
|
|
@@ -167,9 +167,9 @@ export async function queryAI(prompt, options) {
|
|
|
167
167
|
}
|
|
168
168
|
} // Close else block for openRouterModel check
|
|
169
169
|
}
|
|
170
|
-
// Handle GPT-5 special case (direct API only)
|
|
171
|
-
if (options.provider === '
|
|
172
|
-
return await
|
|
170
|
+
// Handle GPT-5.2 special case (direct API only)
|
|
171
|
+
if (options.provider === 'gpt52' && 'special' in providerConfig && providerConfig.special) {
|
|
172
|
+
return await handleGPT52(prompt, options);
|
|
173
173
|
}
|
|
174
174
|
// Standard OpenAI-compatible handling (direct API)
|
|
175
175
|
const client = new OpenAI({
|
|
@@ -196,19 +196,28 @@ export async function queryAI(prompt, options) {
|
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
198
|
/**
|
|
199
|
-
* Special handling for GPT-5 (uses /responses endpoint)
|
|
199
|
+
* Special handling for GPT-5.2 (uses /v1/responses endpoint)
|
|
200
200
|
*/
|
|
201
|
-
async function
|
|
202
|
-
const config = PROVIDER_CONFIGS.
|
|
201
|
+
async function handleGPT52(prompt, options) {
|
|
202
|
+
const config = PROVIDER_CONFIGS.gpt52;
|
|
203
203
|
const endpoint = 'https://api.openai.com/v1/responses';
|
|
204
|
-
|
|
204
|
+
// Default to gpt-5.2 model (use reasoning.effort for "thinking" mode)
|
|
205
|
+
const model = options.model || 'gpt-5.2';
|
|
206
|
+
// Reasoning effort based on model - "high" for "thinking" mode
|
|
207
|
+
// gpt-5.2-pro gets high effort, gpt-5.2 uses medium by default
|
|
208
|
+
const reasoningEffort = model === 'gpt-5.2-pro' ? 'high' : 'medium';
|
|
209
|
+
// Build input as array of message objects
|
|
210
|
+
const inputMessages = [
|
|
211
|
+
...(options.systemPrompt ? [{ role: 'system', content: options.systemPrompt }] : []),
|
|
212
|
+
{ role: 'user', content: prompt }
|
|
213
|
+
];
|
|
205
214
|
const requestBody = {
|
|
206
215
|
model,
|
|
207
|
-
input:
|
|
216
|
+
input: inputMessages,
|
|
208
217
|
reasoning: {
|
|
209
|
-
effort:
|
|
218
|
+
effort: reasoningEffort
|
|
210
219
|
},
|
|
211
|
-
max_output_tokens: 4000
|
|
220
|
+
max_output_tokens: options.maxTokens || 4000
|
|
212
221
|
};
|
|
213
222
|
try {
|
|
214
223
|
const response = await fetch(endpoint, {
|
|
@@ -221,14 +230,29 @@ async function handleGPT5(prompt, options) {
|
|
|
221
230
|
});
|
|
222
231
|
if (!response.ok) {
|
|
223
232
|
const error = await response.text();
|
|
224
|
-
throw new Error(`GPT-5 API error: ${error}`);
|
|
233
|
+
throw new Error(`GPT-5.2 API error: ${error}`);
|
|
225
234
|
}
|
|
226
235
|
const data = await response.json();
|
|
227
|
-
|
|
228
|
-
|
|
236
|
+
// Extract text from Responses API output
|
|
237
|
+
let result;
|
|
238
|
+
if (data.output) {
|
|
239
|
+
for (const outputItem of data.output) {
|
|
240
|
+
if (outputItem.content) {
|
|
241
|
+
for (const contentItem of outputItem.content) {
|
|
242
|
+
if (contentItem.text) {
|
|
243
|
+
result = contentItem.text;
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (result)
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return result || 'No response generated';
|
|
229
253
|
}
|
|
230
254
|
catch (error) {
|
|
231
|
-
console.error('GPT-5 error:', error);
|
|
255
|
+
console.error('GPT-5.2 error:', error);
|
|
232
256
|
throw error;
|
|
233
257
|
}
|
|
234
258
|
}
|
|
@@ -210,7 +210,7 @@ async function executeWorkflowImpl(parent, workflowName, input, options) {
|
|
|
210
210
|
if (workflow.settings?.optimization?.enabled && typeof stepInput === "string") {
|
|
211
211
|
const optimized = await tokenOptimizer.optimize({
|
|
212
212
|
prompt: stepInput,
|
|
213
|
-
model: model || "gpt-5.
|
|
213
|
+
model: model || "gpt-5.2-thinking",
|
|
214
214
|
maxTokens: resolvedParams.maxTokens,
|
|
215
215
|
});
|
|
216
216
|
if (optimized.fromCache) {
|
package/package.json
CHANGED
|
@@ -87,7 +87,7 @@ steps:
|
|
|
87
87
|
input:
|
|
88
88
|
query: "Synthesize the best solution for: ${input}"
|
|
89
89
|
rounds: 3
|
|
90
|
-
models: ["grok-4-fast-reasoning", "gpt-5.
|
|
90
|
+
models: ["grok-4-1-fast-reasoning", "gpt-5.2-thinking", "gemini-3-pro-preview"]
|
|
91
91
|
context: |
|
|
92
92
|
Research: ${research_context}
|
|
93
93
|
Problem breakdown: ${problem_breakdown}
|
|
@@ -206,7 +206,7 @@ steps:
|
|
|
206
206
|
problem: "Create comprehensive solution for: ${input}"
|
|
207
207
|
style: "systematic"
|
|
208
208
|
reasoning_effort: "high"
|
|
209
|
-
model: "gpt-5.
|
|
209
|
+
model: "gpt-5.2-thinking"
|
|
210
210
|
context: |
|
|
211
211
|
COMPLETE WORKFLOW CONTEXT:
|
|
212
212
|
|
|
@@ -107,7 +107,7 @@ steps:
|
|
|
107
107
|
4. Confidence levels for different claims
|
|
108
108
|
5. Actionable recommendations based on the synthesis
|
|
109
109
|
mode: "analyze"
|
|
110
|
-
models: ["gpt-5.
|
|
110
|
+
models: ["gpt-5.2-thinking", "gemini-3-pro-preview", "grok-4-1-fast-reasoning"]
|
|
111
111
|
rounds: 2
|
|
112
112
|
domain: "research"
|
|
113
113
|
saveToFile: true
|
|
@@ -195,7 +195,7 @@ steps:
|
|
|
195
195
|
input:
|
|
196
196
|
query: "${query} - explore creative applications across domains"
|
|
197
197
|
mode: "code-brainstorm"
|
|
198
|
-
models: ["gpt-5.
|
|
198
|
+
models: ["gpt-5.2-thinking", "gemini-3-pro-preview", "grok-4-1-fast-reasoning"]
|
|
199
199
|
rounds: 3
|
|
200
200
|
context: "Research: ${research_findings}\nIdeas: ${innovative_solutions}\nPatterns: ${patterns}"
|
|
201
201
|
saveToFile: true
|
|
@@ -210,7 +210,7 @@ steps:
|
|
|
210
210
|
problem: "Synthesize all perspectives and ideas for ${query} into coherent solutions"
|
|
211
211
|
style: "systematic"
|
|
212
212
|
reasoning_effort: "high"
|
|
213
|
-
model: "gpt-5.
|
|
213
|
+
model: "gpt-5.2-thinking"
|
|
214
214
|
context: |
|
|
215
215
|
COMPREHENSIVE CONTEXT:
|
|
216
216
|
|