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.
@@ -7,30 +7,34 @@
7
7
  // OPENAI MODELS (provider-based naming)
8
8
  // =============================================================================
9
9
  // GPT-5.2 released Dec 11, 2025 - CURRENT
10
- // OpenRouter uses prefix: openai/gpt-5.2-pro, openai/gpt-5.2, openai/gpt-5.2-chat
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
- THINKING: "gpt-5.2-thinking", // SOTA reasoning: 293% accuracy boost ($1.75/$14, 400K)
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
- FULL: "gpt-5.2-thinking", // Map old FULL to THINKING
18
- CODEX_MINI: "gpt-5.2-instant", // Map old codex-mini to INSTANT
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-thinking": "openai/",
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, cheapest)
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", // Maximum reasoning (slowest, most thorough)
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 11, 2025: Migrated to GPT-5.2 (PRO for quality, THINKING for reasoning)
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
- reason: OPENAI_MODELS.THINKING, // Deep reasoning (gpt-5.2-thinking - 293% accuracy)
119
- brainstorm: OPENAI_MODELS.PRO, // Creative ideation (gpt-5.2-pro - HIGH IQ)
120
- code: OPENAI_MODELS.PRO, // Code tasks (gpt-5.2-pro - 88.4% GPQA)
121
- explain: OPENAI_MODELS.PRO, // Explanations (gpt-5.2-pro - quality)
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: 500,
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.CODEX_MINI, // gpt-5.1-codex-mini (default)
22
- OPENAI_REASON: OPENAI_MODELS.FULL, // gpt-5.1 (deep reasoning)
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.1 for max reasoning
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.1 Codex Mini
8
- ModelTier["ULTRA_CHEAP"] = "gpt-5.1-codex-mini";
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.1-codex-mini";
12
- // Tier 2: Balanced ($0.001-$0.01 per request)
13
- ModelTier["STANDARD"] = "gpt-5.1-codex";
14
- ModelTier["GPT5_MINI"] = "gpt-5.1-codex-mini";
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.1";
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.1 Models (Nov 2025 pricing) - ACTUAL API MODEL NAMES
22
- "gpt-5.1-codex-mini": { input: 0.002, output: 0.006, latency: 800 }, // CHEAPEST!
23
- "gpt-5.1-codex": { input: 0.015, output: 0.045, latency: 1500 },
24
- "gpt-5.1": { input: 0.010, output: 0.030, latency: 2000 },
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.1-codex-mini
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.1 model capabilities with reasoning_effort control
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
- // Available OpenAI GPT-5 models (optimized for Claude Code)
75
- export var OpenAI51Model;
76
- (function (OpenAI51Model) {
77
- OpenAI51Model["FULL"] = "gpt-5.1";
78
- OpenAI51Model["PRO"] = "gpt-5-pro";
79
- OpenAI51Model["CODEX_MINI"] = "gpt-5.1-codex-mini";
80
- OpenAI51Model["CODEX"] = "gpt-5.1-codex";
81
- OpenAI51Model["CODEX_MAX"] = "gpt-5.1-codex-max";
82
- })(OpenAI51Model || (OpenAI51Model = {}));
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
- * Automatically detects GPT-5.1 models and uses correct endpoint + format
106
+ * GPT-5.2 uses /v1/responses endpoint for all models
86
107
  */
87
- export async function callOpenAI(messages, model = OpenAI51Model.CODEX_MINI, temperature = 0.7, maxTokens = 16384, // Increased default for comprehensive responses
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.1 models have no fallbacks to test actual availability
139
+ // Model fallback chain - GPT-5.2 models have no fallbacks to test actual availability
118
140
  const modelFallbacks = {
119
- [OpenAI51Model.FULL]: [], // No fallback - test actual GPT-5.1
120
- [OpenAI51Model.CODEX_MINI]: [], // No fallback - test actual GPT-5.1-codex-mini
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
- // Codex models use /v1/responses, non-codex use /v1/chat/completions
130
- const isCodex = currentModel.includes('codex');
131
- const endpoint = isCodex ? OPENAI_RESPONSES_URL : OPENAI_CHAT_URL;
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 (isCodex) {
134
- // Responses API format for codex models
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: validatedMessages,
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 non-codex GPT-5 models (gpt-5.1, gpt-5-pro)
171
+ // Chat Completions format for older models
147
172
  requestBody = {
148
173
  model: currentModel,
149
174
  messages: validatedMessages,
150
- temperature,
151
- max_completion_tokens: maxTokens, // GPT-5 requires max_completion_tokens (not max_tokens)
175
+ max_completion_tokens: maxTokens,
176
+ temperature: temperature,
152
177
  stream: false
153
178
  };
154
179
  }
155
- console.error(`🔍 TRACE: Using ${isCodex ? '/v1/responses' : '/v1/chat/completions'} endpoint`);
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 (isCodex) {
179
- // Responses API format
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 data = parseResult.data;
183
- const messageOutput = data.output.find(item => item.type === 'message');
184
- rawContent = messageOutput?.content?.[0]?.text;
185
- if (data.reasoning) {
186
- console.error(`🔍 TRACE: Reasoning effort: ${data.reasoning.effort}`);
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 format
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.1 model "${model}" not available. Error: ${lastError}]`;
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
- * Automatically detects GPT-5.1 models and uses correct endpoint + format
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
- // Codex models use /v1/responses, non-codex use /v1/chat/completions
253
- const isCodex = model.includes('codex');
254
- const endpoint = isCodex ? OPENAI_RESPONSES_URL : OPENAI_CHAT_URL;
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 (isCodex) {
257
- // Responses API format for codex models
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: validatedMessages,
261
- max_output_tokens: maxTokens, // NOT max_completion_tokens or max_tokens!
262
- stream: false,
306
+ input: inputMessages,
263
307
  reasoning: {
264
- effort: reasoningEffort // "none", "low", "medium", "high"
265
- }
308
+ effort: reasoningEffort || 'medium'
309
+ },
310
+ max_output_tokens: maxTokens
266
311
  };
267
312
  }
268
313
  else {
269
- // Chat Completions format for non-codex GPT-5 models (gpt-5.1, gpt-5-pro)
314
+ // Chat Completions format for older models
270
315
  requestBody = {
271
316
  model: model,
272
317
  messages: validatedMessages,
273
- temperature,
274
- max_completion_tokens: maxTokens, // GPT-5 requires max_completion_tokens (not max_tokens)
318
+ max_completion_tokens: maxTokens,
319
+ temperature: temperature,
275
320
  stream: false
276
321
  };
277
322
  }
278
- console.error(`🔍 TRACE: Using ${isCodex ? '/v1/responses' : '/v1/chat/completions'} endpoint`);
279
- console.error(`🔍 TRACE: Model params: ${isCodex ? `max_output_tokens=${maxTokens}, reasoning_effort=${reasoningEffort}` : `max_completion_tokens=${maxTokens}, temperature=${temperature}`}`);
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 - they have DIFFERENT response formats!
339
+ // Parse response based on API type
295
340
  let rawContent;
296
- if (isCodex) {
297
- // Validate and parse Responses API format
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 data = parseResult.data;
301
- const messageOutput = data.output.find(item => item.type === 'message');
302
- rawContent = messageOutput?.content?.[0]?.text;
303
- // Capture reasoning info
304
- if (data.reasoning) {
305
- console.error(`🔍 TRACE: Reasoning effort: ${data.reasoning.effort}`);
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
- // Validate and parse Chat Completions API format
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.1 with high reasoning
368
- return await callOpenAI(messages, OpenAI51Model.FULL, 0.7, 4000, "high");
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.1-codex-mini with medium reasoning
400
- return await callOpenAI(messages, OpenAI51Model.CODEX_MINI, 0.7, 3000, "medium");
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.1 with high reasoning effort",
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.1 with high reasoning effort for complex reasoning
432
- return await callOpenAI(messages, OpenAI51Model.FULL, 0.7, 4000, "high");
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.1", "gpt-5.1-codex-mini", "gpt-5.1-codex"]).optional(),
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 = "gpt-5.1-codex-mini", reasoning_effort = "medium", max_tokens = 4000 } = args;
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, OpenAI51Model.CODEX_MINI, 0.3, 4000, "medium");
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, OpenAI51Model.CODEX_MINI, 0.7, 2500, "low");
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.1 reasoning (high effort)
577
- openAIBrainstormTool, // GPT-5.1-codex-mini brainstorming (medium effort)
578
- openaiCodeReviewTool, // GPT-5.1-codex-mini code review (medium effort)
579
- openaiExplainTool // GPT-5.1-codex-mini explanations (low effort)
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.1', 'gpt-5.1-codex-mini', 'gpt-5.1-codex']
62
+ models: ['gpt-5.2', 'gpt-5.2-pro'] // gpt-5.2 with reasoning.effort for "thinking"
63
63
  },
64
- gpt51: {
65
- base: 'https://api.openai.com/v1', // Uses /responses endpoint internally
64
+ gpt52: {
65
+ base: 'https://api.openai.com/v1', // Uses /responses endpoint
66
66
  key: process.env.OPENAI_API_KEY,
67
- models: ['gpt-5.1', 'gpt-5.1-codex-mini', 'gpt-5.1-codex'],
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 === 'gpt51' && 'special' in providerConfig && providerConfig.special) {
172
- return await handleGPT5(prompt, options);
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 handleGPT5(prompt, options) {
202
- const config = PROVIDER_CONFIGS.gpt51;
201
+ async function handleGPT52(prompt, options) {
202
+ const config = PROVIDER_CONFIGS.gpt52;
203
203
  const endpoint = 'https://api.openai.com/v1/responses';
204
- const model = options.model || 'gpt-5.1-codex-mini'; // Default to cheapest
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: prompt,
216
+ input: inputMessages,
208
217
  reasoning: {
209
- effort: model === 'gpt-5.1' ? 'high' : 'low'
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
- const messageOutput = data.output.find(item => item.type === 'message');
228
- return messageOutput?.content?.[0]?.text || 'No response generated';
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.1-codex-mini",
213
+ model: model || "gpt-5.2-thinking",
214
214
  maxTokens: resolvedParams.maxTokens,
215
215
  });
216
216
  if (optimized.fromCache) {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "tachibot-mcp",
3
3
  "mcpName": "io.github.byPawel/tachibot-mcp",
4
4
  "displayName": "TachiBot MCP - Universal AI Orchestrator",
5
- "version": "2.2.0",
5
+ "version": "2.2.5",
6
6
  "type": "module",
7
7
  "main": "dist/src/server.js",
8
8
  "bin": {
@@ -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.1", "gemini-2.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.1"
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.1-codex-mini", "gemini-2.5-pro", "gemini-2.5-flash", "grok-4-fast-reasoning"]
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.1", "gemini-2.5-flash", "grok-4-1-fast-reasoning"]
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.1"
213
+ model: "gpt-5.2-thinking"
214
214
  context: |
215
215
  COMPREHENSIVE CONTEXT:
216
216