@corbat-tech/coco 2.30.0 → 2.32.0

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/cli/index.js CHANGED
@@ -259,6 +259,7 @@ __export(schema_exports, {
259
259
  ShipConfigSchema: () => ShipConfigSchema,
260
260
  SkillsConfigSchema: () => SkillsConfigSchema,
261
261
  StackConfigSchema: () => StackConfigSchema,
262
+ ThinkingModeSchema: () => ThinkingModeSchema,
262
263
  ToolsConfigSchema: () => ToolsConfigSchema,
263
264
  createDefaultConfigObject: () => createDefaultConfigObject,
264
265
  validateConfig: () => validateConfig
@@ -303,9 +304,13 @@ function createDefaultConfigObject(projectName, language = "typescript") {
303
304
  }
304
305
  };
305
306
  }
306
- var ProviderConfigSchema, QualityConfigSchema, PersistenceConfigSchema, StackConfigSchema, ProjectConfigSchema, GitHubConfigSchema, IntegrationsConfigSchema, MCPServerConfigEntrySchema, MCPConfigSchema, ToolsConfigSchema, ShipConfigSchema, SkillsConfigSchema, CocoConfigSchema;
307
+ var ThinkingModeSchema, ProviderConfigSchema, QualityConfigSchema, PersistenceConfigSchema, StackConfigSchema, ProjectConfigSchema, GitHubConfigSchema, IntegrationsConfigSchema, MCPServerConfigEntrySchema, MCPConfigSchema, ToolsConfigSchema, ShipConfigSchema, SkillsConfigSchema, CocoConfigSchema;
307
308
  var init_schema = __esm({
308
309
  "src/config/schema.ts"() {
310
+ ThinkingModeSchema = z.union([
311
+ z.enum(["off", "auto", "low", "medium", "high"]),
312
+ z.object({ budget: z.number().int().min(0).max(2e5) })
313
+ ]);
309
314
  ProviderConfigSchema = z.object({
310
315
  type: z.enum([
311
316
  "anthropic",
@@ -467,6 +472,7 @@ var init_schema = __esm({
467
472
  timeout: 12e4
468
473
  }),
469
474
  providerModels: z.record(z.string(), z.string()).optional(),
475
+ providerThinking: z.record(z.string(), ThinkingModeSchema).optional(),
470
476
  quality: QualityConfigSchema.default({
471
477
  minScore: 85,
472
478
  minCoverage: 80,
@@ -2687,10 +2693,12 @@ __export(env_exports, {
2687
2693
  getInternalProviderId: () => getInternalProviderId,
2688
2694
  getLastUsedModel: () => getLastUsedModel,
2689
2695
  getLastUsedProvider: () => getLastUsedProvider,
2696
+ getLastUsedThinking: () => getLastUsedThinking,
2690
2697
  isOAuthProvider: () => isOAuthProvider,
2691
2698
  migrateOldPreferences: () => migrateOldPreferences,
2692
2699
  removeEnvProvider: () => removeEnvProvider,
2693
- saveProviderPreference: () => saveProviderPreference
2700
+ saveProviderPreference: () => saveProviderPreference,
2701
+ saveThinkingPreference: () => saveThinkingPreference
2694
2702
  });
2695
2703
  function loadGlobalCocoEnv() {
2696
2704
  try {
@@ -2910,6 +2918,51 @@ async function getLastUsedModel(provider) {
2910
2918
  }
2911
2919
  return void 0;
2912
2920
  }
2921
+ async function getLastUsedThinking(provider) {
2922
+ try {
2923
+ const config = await loadConfig(CONFIG_PATHS.config);
2924
+ const mode = config.providerThinking?.[provider];
2925
+ return mode;
2926
+ } catch {
2927
+ return void 0;
2928
+ }
2929
+ }
2930
+ async function saveThinkingPreference(provider, mode) {
2931
+ let config;
2932
+ try {
2933
+ config = await loadConfig(CONFIG_PATHS.config);
2934
+ } catch {
2935
+ config = {
2936
+ project: { name: "global", version: "0.1.0" },
2937
+ provider: {
2938
+ type: "anthropic",
2939
+ model: "claude-sonnet-4-6",
2940
+ maxTokens: 8192,
2941
+ temperature: 0,
2942
+ timeout: 12e4
2943
+ },
2944
+ quality: {
2945
+ minScore: 85,
2946
+ minCoverage: 80,
2947
+ maxIterations: 10,
2948
+ minIterations: 2,
2949
+ convergenceThreshold: 2,
2950
+ securityThreshold: 100
2951
+ },
2952
+ persistence: {
2953
+ checkpointInterval: 3e5,
2954
+ maxCheckpoints: 50,
2955
+ retentionDays: 7,
2956
+ compressOldCheckpoints: true
2957
+ }
2958
+ };
2959
+ }
2960
+ config.providerThinking = {
2961
+ ...config.providerThinking,
2962
+ [provider]: mode
2963
+ };
2964
+ await saveConfig(config, void 0, true);
2965
+ }
2913
2966
  async function saveProviderPreference(provider, model, options) {
2914
2967
  let config;
2915
2968
  try {
@@ -3280,6 +3333,160 @@ var init_logger = __esm({
3280
3333
  globalLogger = null;
3281
3334
  }
3282
3335
  });
3336
+
3337
+ // src/providers/thinking.ts
3338
+ function isAnthropicThinkingModel(model) {
3339
+ const m = model.toLowerCase();
3340
+ if (m === "kimi-for-coding") return false;
3341
+ return m.includes("claude-3-7") || m.includes("claude-opus-4") || m.includes("claude-sonnet-4") || m.includes("claude-haiku-4-5") || m.includes("claude-4");
3342
+ }
3343
+ function isOpenAIReasoningModel(model) {
3344
+ const m = model.toLowerCase();
3345
+ return m.startsWith("o1") || m.startsWith("o3") || m.startsWith("o4") || m.startsWith("gpt-5") || m.includes("codex");
3346
+ }
3347
+ function isGeminiThinkingModel(model) {
3348
+ const m = model.toLowerCase();
3349
+ return m.includes("gemini-2.5-pro") || m.includes("gemini-2.5-flash") || m.includes("gemini-3") && !m.includes("flash-lite") || m.includes("gemini-2.0-flash-thinking");
3350
+ }
3351
+ function isKimiThinkingModel(model) {
3352
+ const m = model.toLowerCase();
3353
+ return m.includes("kimi-k2") || m === "kimi-latest";
3354
+ }
3355
+ function getThinkingCapability(provider, model) {
3356
+ switch (provider) {
3357
+ case "anthropic":
3358
+ case "kimi-code":
3359
+ return isAnthropicThinkingModel(model) ? ANTHROPIC_CAPABILITY : UNSUPPORTED;
3360
+ case "openai":
3361
+ case "copilot":
3362
+ case "groq":
3363
+ case "openrouter":
3364
+ case "mistral":
3365
+ case "deepseek":
3366
+ case "together":
3367
+ case "huggingface":
3368
+ case "qwen":
3369
+ return isOpenAIReasoningModel(model) ? OPENAI_CAPABILITY : UNSUPPORTED;
3370
+ case "kimi":
3371
+ return isKimiThinkingModel(model) ? KIMI_CAPABILITY : UNSUPPORTED;
3372
+ case "gemini":
3373
+ case "vertex":
3374
+ return isGeminiThinkingModel(model) ? GEMINI_CAPABILITY : UNSUPPORTED;
3375
+ case "lmstudio":
3376
+ case "ollama":
3377
+ case "codex":
3378
+ return UNSUPPORTED;
3379
+ default:
3380
+ return UNSUPPORTED;
3381
+ }
3382
+ }
3383
+ function resolveDefaultThinking(provider, model) {
3384
+ return getThinkingCapability(provider, model).defaultMode;
3385
+ }
3386
+ function formatThinkingMode(mode) {
3387
+ if (typeof mode === "object") return `${mode.budget}t`;
3388
+ return mode;
3389
+ }
3390
+ function mapToAnthropic(mode, model) {
3391
+ if (!mode || mode === "off") return void 0;
3392
+ if (!isAnthropicThinkingModel(model)) return void 0;
3393
+ const cap = ANTHROPIC_CAPABILITY;
3394
+ const { min, max } = cap.budgetRange;
3395
+ if (typeof mode === "object") {
3396
+ return { type: "enabled", budget_tokens: Math.min(Math.max(mode.budget, min), max) };
3397
+ }
3398
+ const budgetMap = {
3399
+ auto: cap.budgetRange.default,
3400
+ low: ANTHROPIC_BUDGET.low,
3401
+ medium: ANTHROPIC_BUDGET.medium,
3402
+ high: ANTHROPIC_BUDGET.high
3403
+ };
3404
+ const budget = budgetMap[mode];
3405
+ if (budget === void 0) return void 0;
3406
+ return { type: "enabled", budget_tokens: budget };
3407
+ }
3408
+ function mapToOpenAIEffort(mode, model) {
3409
+ if (!mode || mode === "off") return void 0;
3410
+ if (!isOpenAIReasoningModel(model)) return void 0;
3411
+ if (typeof mode === "object") {
3412
+ const { budget } = mode;
3413
+ if (budget <= 2048) return "low";
3414
+ if (budget <= 8e3) return "medium";
3415
+ return "high";
3416
+ }
3417
+ if (mode === "auto") return "medium";
3418
+ if (mode === "low" || mode === "medium" || mode === "high") return mode;
3419
+ return void 0;
3420
+ }
3421
+ function mapToGeminiBudget(mode, model) {
3422
+ if (!isGeminiThinkingModel(model)) return void 0;
3423
+ if (!mode) return void 0;
3424
+ if (mode === "off") return 0;
3425
+ if (mode === "auto") return -1;
3426
+ const { min, max } = GEMINI_CAPABILITY.budgetRange;
3427
+ if (typeof mode === "object") {
3428
+ return Math.min(Math.max(mode.budget, min), max);
3429
+ }
3430
+ const budgetMap = {
3431
+ low: GEMINI_BUDGET.low,
3432
+ medium: GEMINI_BUDGET.medium,
3433
+ high: GEMINI_BUDGET.high
3434
+ };
3435
+ return budgetMap[mode];
3436
+ }
3437
+ function mapToKimiExtraBody(mode, model) {
3438
+ if (!isKimiThinkingModel(model)) return void 0;
3439
+ const effectiveMode = mode ?? "off";
3440
+ const enabled = effectiveMode !== "off";
3441
+ return { thinking: { type: enabled ? "enabled" : "disabled" } };
3442
+ }
3443
+ var ANTHROPIC_BUDGET, GEMINI_BUDGET, UNSUPPORTED, ANTHROPIC_CAPABILITY, OPENAI_CAPABILITY, GEMINI_CAPABILITY, KIMI_CAPABILITY;
3444
+ var init_thinking = __esm({
3445
+ "src/providers/thinking.ts"() {
3446
+ ANTHROPIC_BUDGET = {
3447
+ low: 2048,
3448
+ medium: 8e3,
3449
+ high: 16e3
3450
+ };
3451
+ GEMINI_BUDGET = {
3452
+ low: 2048,
3453
+ medium: 8e3,
3454
+ high: 16e3
3455
+ };
3456
+ UNSUPPORTED = {
3457
+ supported: false,
3458
+ kinds: [],
3459
+ levels: ["off"],
3460
+ defaultMode: "off"
3461
+ };
3462
+ ANTHROPIC_CAPABILITY = {
3463
+ supported: true,
3464
+ kinds: ["budget"],
3465
+ levels: ["off", "auto", "low", "medium", "high"],
3466
+ budgetRange: { min: 1024, max: 64e3, default: ANTHROPIC_BUDGET.medium },
3467
+ defaultMode: "off"
3468
+ };
3469
+ OPENAI_CAPABILITY = {
3470
+ supported: true,
3471
+ kinds: ["effort"],
3472
+ levels: ["off", "auto", "low", "medium", "high"],
3473
+ defaultMode: "medium"
3474
+ };
3475
+ GEMINI_CAPABILITY = {
3476
+ supported: true,
3477
+ kinds: ["budget"],
3478
+ levels: ["off", "auto", "low", "medium", "high"],
3479
+ budgetRange: { min: 0, max: 32e3, default: GEMINI_BUDGET.medium },
3480
+ defaultMode: "auto"
3481
+ };
3482
+ KIMI_CAPABILITY = {
3483
+ supported: true,
3484
+ kinds: ["effort"],
3485
+ levels: ["off", "auto"],
3486
+ defaultMode: "off"
3487
+ };
3488
+ }
3489
+ });
3283
3490
  function createAnthropicProvider(config) {
3284
3491
  const provider = new AnthropicProvider();
3285
3492
  if (config) {
@@ -3308,6 +3515,7 @@ var init_anthropic = __esm({
3308
3515
  init_errors();
3309
3516
  init_retry();
3310
3517
  init_logger();
3518
+ init_thinking();
3311
3519
  DEFAULT_MODEL = "claude-opus-4-6";
3312
3520
  CONTEXT_WINDOWS = {
3313
3521
  // Kimi Code model (Anthropic-compatible endpoint)
@@ -3368,13 +3576,19 @@ var init_anthropic = __esm({
3368
3576
  this.ensureInitialized();
3369
3577
  return withRetry(async () => {
3370
3578
  try {
3579
+ const model = options?.model ?? this.config.model ?? DEFAULT_MODEL;
3580
+ const thinkingParam = mapToAnthropic(options?.thinking, model);
3581
+ const baseMaxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
3371
3582
  const response = await this.client.messages.create({
3372
- model: options?.model ?? this.config.model ?? DEFAULT_MODEL,
3373
- max_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
3374
- temperature: options?.temperature ?? this.config.temperature ?? 0,
3583
+ model,
3584
+ // Anthropic requires max_tokens > budget_tokens
3585
+ max_tokens: thinkingParam ? Math.max(baseMaxTokens, thinkingParam.budget_tokens + 1024) : baseMaxTokens,
3586
+ // Anthropic requires temperature=1 when thinking is enabled
3587
+ temperature: thinkingParam ? 1 : options?.temperature ?? this.config.temperature ?? 0,
3375
3588
  system: this.extractSystem(messages, options?.system),
3376
3589
  messages: this.convertMessages(messages),
3377
- stop_sequences: options?.stopSequences
3590
+ stop_sequences: options?.stopSequences,
3591
+ ...thinkingParam && { thinking: thinkingParam }
3378
3592
  });
3379
3593
  return {
3380
3594
  id: response.id,
@@ -3398,14 +3612,18 @@ var init_anthropic = __esm({
3398
3612
  this.ensureInitialized();
3399
3613
  return withRetry(async () => {
3400
3614
  try {
3615
+ const model = options?.model ?? this.config.model ?? DEFAULT_MODEL;
3616
+ const thinkingParam = mapToAnthropic(options?.thinking, model);
3617
+ const baseMaxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
3401
3618
  const response = await this.client.messages.create({
3402
- model: options?.model ?? this.config.model ?? DEFAULT_MODEL,
3403
- max_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
3404
- temperature: options?.temperature ?? this.config.temperature ?? 0,
3619
+ model,
3620
+ max_tokens: thinkingParam ? Math.max(baseMaxTokens, thinkingParam.budget_tokens + 1024) : baseMaxTokens,
3621
+ temperature: thinkingParam ? 1 : options?.temperature ?? this.config.temperature ?? 0,
3405
3622
  system: this.extractSystem(messages, options?.system),
3406
3623
  messages: this.convertMessages(messages),
3407
3624
  tools: this.convertTools(options.tools),
3408
- tool_choice: options.toolChoice ? this.convertToolChoice(options.toolChoice) : void 0
3625
+ tool_choice: options.toolChoice ? this.convertToolChoice(options.toolChoice) : void 0,
3626
+ ...thinkingParam && { thinking: thinkingParam }
3409
3627
  });
3410
3628
  const toolCalls = this.extractToolCalls(response.content);
3411
3629
  return {
@@ -3431,13 +3649,17 @@ var init_anthropic = __esm({
3431
3649
  this.ensureInitialized();
3432
3650
  let timeoutTriggered = false;
3433
3651
  try {
3652
+ const model = options?.model ?? this.config.model ?? DEFAULT_MODEL;
3653
+ const thinkingParam = mapToAnthropic(options?.thinking, model);
3654
+ const baseMaxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
3434
3655
  const stream = await this.client.messages.stream(
3435
3656
  {
3436
- model: options?.model ?? this.config.model ?? DEFAULT_MODEL,
3437
- max_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
3438
- temperature: options?.temperature ?? this.config.temperature ?? 0,
3657
+ model,
3658
+ max_tokens: thinkingParam ? Math.max(baseMaxTokens, thinkingParam.budget_tokens + 1024) : baseMaxTokens,
3659
+ temperature: thinkingParam ? 1 : options?.temperature ?? this.config.temperature ?? 0,
3439
3660
  system: this.extractSystem(messages, options?.system),
3440
- messages: this.convertMessages(messages)
3661
+ messages: this.convertMessages(messages),
3662
+ ...thinkingParam && { thinking: thinkingParam }
3441
3663
  },
3442
3664
  { signal: options?.signal }
3443
3665
  );
@@ -3493,15 +3715,19 @@ var init_anthropic = __esm({
3493
3715
  this.ensureInitialized();
3494
3716
  let timeoutTriggered = false;
3495
3717
  try {
3718
+ const model = options?.model ?? this.config.model ?? DEFAULT_MODEL;
3719
+ const thinkingParam = mapToAnthropic(options?.thinking, model);
3720
+ const baseMaxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
3496
3721
  const stream = await this.client.messages.stream(
3497
3722
  {
3498
- model: options?.model ?? this.config.model ?? DEFAULT_MODEL,
3499
- max_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
3500
- temperature: options?.temperature ?? this.config.temperature ?? 0,
3723
+ model,
3724
+ max_tokens: thinkingParam ? Math.max(baseMaxTokens, thinkingParam.budget_tokens + 1024) : baseMaxTokens,
3725
+ temperature: thinkingParam ? 1 : options?.temperature ?? this.config.temperature ?? 0,
3501
3726
  system: this.extractSystem(messages, options?.system),
3502
3727
  messages: this.convertMessages(messages),
3503
3728
  tools: this.convertTools(options.tools),
3504
- tool_choice: options.toolChoice ? this.convertToolChoice(options.toolChoice) : void 0
3729
+ tool_choice: options.toolChoice ? this.convertToolChoice(options.toolChoice) : void 0,
3730
+ ...thinkingParam && { thinking: thinkingParam }
3505
3731
  },
3506
3732
  { signal: options?.signal }
3507
3733
  );
@@ -4022,6 +4248,7 @@ var init_openai = __esm({
4022
4248
  init_errors();
4023
4249
  init_retry();
4024
4250
  init_tool_call_normalizer();
4251
+ init_thinking();
4025
4252
  DEFAULT_MODEL2 = "gpt-5.3-codex";
4026
4253
  CONTEXT_WINDOWS2 = {
4027
4254
  // OpenAI models
@@ -4174,26 +4401,15 @@ var init_openai = __esm({
4174
4401
  return !MODELS_WITHOUT_TEMPERATURE.some((m) => model.toLowerCase().includes(m.toLowerCase()));
4175
4402
  }
4176
4403
  /**
4177
- * Check if a model needs thinking mode disabled for tool use
4178
- * Kimi models have thinking mode enabled by default which requires
4179
- * reasoning_content in multi-turn conversations with tools
4180
- */
4181
- needsThinkingDisabled(model) {
4182
- return MODELS_WITH_THINKING_MODE.some((m) => model.toLowerCase().includes(m.toLowerCase()));
4183
- }
4184
- /**
4185
- * Get extra body parameters for API calls
4186
- * Used to disable thinking mode for Kimi models
4187
- * See: https://huggingface.co/moonshotai/Kimi-K2.5
4188
- *
4189
- * For Official Moonshot API: {'thinking': {'type': 'disabled'}}
4190
- * For vLLM/SGLang: {'chat_template_kwargs': {"thinking": False}}
4404
+ * Get extra body parameters for API calls.
4405
+ * Honors the user's ThinkingMode for Kimi models; defaults to disabled
4406
+ * (preserving existing behavior) when no mode is specified.
4191
4407
  */
4192
- getExtraBody(model) {
4193
- if (this.needsThinkingDisabled(model)) {
4194
- return {
4195
- thinking: { type: "disabled" }
4196
- };
4408
+ getExtraBody(model, thinking) {
4409
+ const kimiBody = mapToKimiExtraBody(thinking, model);
4410
+ if (kimiBody) return kimiBody;
4411
+ if (MODELS_WITH_THINKING_MODE.some((m) => model.toLowerCase().includes(m.toLowerCase()))) {
4412
+ return { thinking: { type: "disabled" } };
4197
4413
  }
4198
4414
  return void 0;
4199
4415
  }
@@ -4210,6 +4426,7 @@ var init_openai = __esm({
4210
4426
  try {
4211
4427
  const supportsTemp = this.supportsTemperature(model);
4212
4428
  const maxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
4429
+ const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
4213
4430
  const response = await this.client.chat.completions.create({
4214
4431
  model,
4215
4432
  ...buildMaxTokensParam(model, maxTokens),
@@ -4217,7 +4434,8 @@ var init_openai = __esm({
4217
4434
  stop: options?.stopSequences,
4218
4435
  ...supportsTemp && {
4219
4436
  temperature: options?.temperature ?? this.config.temperature ?? 0
4220
- }
4437
+ },
4438
+ ...reasoningEffort && { reasoning_effort: reasoningEffort }
4221
4439
  });
4222
4440
  const choice = response.choices[0];
4223
4441
  return {
@@ -4247,7 +4465,8 @@ var init_openai = __esm({
4247
4465
  return withRetry(async () => {
4248
4466
  try {
4249
4467
  const supportsTemp = this.supportsTemperature(model);
4250
- const extraBody = this.getExtraBody(model);
4468
+ const extraBody = this.getExtraBody(model, options?.thinking);
4469
+ const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
4251
4470
  const maxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
4252
4471
  const requestParams = {
4253
4472
  model,
@@ -4259,6 +4478,9 @@ var init_openai = __esm({
4259
4478
  if (supportsTemp) {
4260
4479
  requestParams.temperature = options?.temperature ?? this.config.temperature ?? 0;
4261
4480
  }
4481
+ if (reasoningEffort) {
4482
+ requestParams.reasoning_effort = reasoningEffort;
4483
+ }
4262
4484
  if (extraBody) {
4263
4485
  Object.assign(requestParams, extraBody);
4264
4486
  }
@@ -4296,12 +4518,14 @@ var init_openai = __esm({
4296
4518
  try {
4297
4519
  const supportsTemp = this.supportsTemperature(model);
4298
4520
  const maxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
4521
+ const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
4299
4522
  const stream = await this.client.chat.completions.create({
4300
4523
  model,
4301
4524
  ...buildMaxTokensParam(model, maxTokens),
4302
4525
  messages: this.convertMessages(messages, options?.system),
4303
4526
  stream: true,
4304
- ...supportsTemp && { temperature: options?.temperature ?? this.config.temperature ?? 0 }
4527
+ ...supportsTemp && { temperature: options?.temperature ?? this.config.temperature ?? 0 },
4528
+ ...reasoningEffort && { reasoning_effort: reasoningEffort }
4305
4529
  });
4306
4530
  let streamStopReason;
4307
4531
  for await (const chunk of stream) {
@@ -4332,7 +4556,8 @@ var init_openai = __esm({
4332
4556
  let timeoutTriggered = false;
4333
4557
  try {
4334
4558
  const supportsTemp = this.supportsTemperature(model);
4335
- const extraBody = this.getExtraBody(model);
4559
+ const extraBody = this.getExtraBody(model, options?.thinking);
4560
+ const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
4336
4561
  const maxTokens = options?.maxTokens ?? this.config.maxTokens ?? 8192;
4337
4562
  const requestParams = {
4338
4563
  model,
@@ -4345,6 +4570,9 @@ var init_openai = __esm({
4345
4570
  if (supportsTemp) {
4346
4571
  requestParams.temperature = options?.temperature ?? this.config.temperature ?? 0;
4347
4572
  }
4573
+ if (reasoningEffort) {
4574
+ requestParams.reasoning_effort = reasoningEffort;
4575
+ }
4348
4576
  if (extraBody) {
4349
4577
  Object.assign(requestParams, extraBody);
4350
4578
  }
@@ -4812,6 +5040,7 @@ var init_openai = __esm({
4812
5040
  const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
4813
5041
  const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
4814
5042
  const supportsTemp = this.supportsTemperature(model);
5043
+ const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
4815
5044
  const response = await this.client.responses.create({
4816
5045
  model,
4817
5046
  input,
@@ -4820,6 +5049,8 @@ var init_openai = __esm({
4820
5049
  ...supportsTemp && {
4821
5050
  temperature: options?.temperature ?? this.config.temperature ?? 0
4822
5051
  },
5052
+ // Responses API uses nested reasoning.effort (not top-level reasoning_effort)
5053
+ ...reasoningEffort && { reasoning: { effort: reasoningEffort } },
4823
5054
  store: false
4824
5055
  });
4825
5056
  return {
@@ -4848,6 +5079,7 @@ var init_openai = __esm({
4848
5079
  const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
4849
5080
  const tools = this.convertToolsForResponses(options.tools);
4850
5081
  const supportsTemp = this.supportsTemperature(model);
5082
+ const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
4851
5083
  const response = await this.client.responses.create({
4852
5084
  model,
4853
5085
  input,
@@ -4857,6 +5089,7 @@ var init_openai = __esm({
4857
5089
  ...supportsTemp && {
4858
5090
  temperature: options?.temperature ?? this.config.temperature ?? 0
4859
5091
  },
5092
+ ...reasoningEffort && { reasoning: { effort: reasoningEffort } },
4860
5093
  store: false
4861
5094
  });
4862
5095
  let content = "";
@@ -4902,12 +5135,14 @@ var init_openai = __esm({
4902
5135
  const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
4903
5136
  const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
4904
5137
  const supportsTemp = this.supportsTemperature(model);
5138
+ const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
4905
5139
  const stream = await this.client.responses.create({
4906
5140
  model,
4907
5141
  input,
4908
5142
  instructions: instructions ?? void 0,
4909
5143
  max_output_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
4910
5144
  ...supportsTemp && { temperature: options?.temperature ?? this.config.temperature ?? 0 },
5145
+ ...reasoningEffort && { reasoning: { effort: reasoningEffort } },
4911
5146
  store: false,
4912
5147
  stream: true
4913
5148
  });
@@ -4965,12 +5200,14 @@ var init_openai = __esm({
4965
5200
  const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
4966
5201
  const tools = options.tools.length > 0 ? this.convertToolsForResponses(options.tools) : void 0;
4967
5202
  const supportsTemp = this.supportsTemperature(model);
5203
+ const reasoningEffort = mapToOpenAIEffort(options?.thinking, model);
4968
5204
  const requestParams = {
4969
5205
  model,
4970
5206
  input,
4971
5207
  instructions: instructions ?? void 0,
4972
5208
  max_output_tokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
4973
5209
  ...supportsTemp && { temperature: options?.temperature ?? this.config.temperature ?? 0 },
5210
+ ...reasoningEffort && { reasoning: { effort: reasoningEffort } },
4974
5211
  store: false,
4975
5212
  stream: true
4976
5213
  };
@@ -6010,6 +6247,7 @@ var DEFAULT_MODEL5, SKIP_THOUGHT_SIGNATURE_VALIDATOR, CONTEXT_WINDOWS5, GeminiPr
6010
6247
  var init_gemini = __esm({
6011
6248
  "src/providers/gemini.ts"() {
6012
6249
  init_errors();
6250
+ init_thinking();
6013
6251
  DEFAULT_MODEL5 = "gemini-3.1-pro-preview";
6014
6252
  SKIP_THOUGHT_SIGNATURE_VALIDATOR = "skip_thought_signature_validator";
6015
6253
  CONTEXT_WINDOWS5 = {
@@ -6168,12 +6406,17 @@ var init_gemini = __esm({
6168
6406
  return model ?? this.config.model ?? DEFAULT_MODEL5;
6169
6407
  }
6170
6408
  buildConfig(messages, options, tools, toolChoice) {
6409
+ const model = this.getModel(options?.model);
6410
+ const thinkingBudget = mapToGeminiBudget(options?.thinking, model);
6171
6411
  const config = {
6172
6412
  maxOutputTokens: options?.maxTokens ?? this.config.maxTokens ?? 8192,
6173
6413
  temperature: options?.temperature ?? this.config.temperature ?? 0,
6174
6414
  stopSequences: options?.stopSequences,
6175
6415
  systemInstruction: this.extractSystem(messages, options?.system)
6176
6416
  };
6417
+ if (thinkingBudget !== void 0) {
6418
+ config.thinkingConfig = { thinkingBudget };
6419
+ }
6177
6420
  if (tools && tools.length > 0) {
6178
6421
  config.tools = [{ functionDeclarations: this.convertTools(tools) }];
6179
6422
  config.toolConfig = {
@@ -10541,11 +10784,15 @@ function generateToolCatalog(registry) {
10541
10784
  async function createDefaultReplConfig() {
10542
10785
  const providerType = await getLastUsedProvider();
10543
10786
  const model = await getLastUsedModel(providerType) || getDefaultModel(providerType);
10787
+ const persistedThinking = await getLastUsedThinking(providerType);
10788
+ const thinking = persistedThinking ?? resolveDefaultThinking(providerType, model);
10789
+ const thinkingToStore = thinking === "off" ? void 0 : thinking;
10544
10790
  return {
10545
10791
  provider: {
10546
10792
  type: providerType,
10547
10793
  model,
10548
- maxTokens: 8192
10794
+ maxTokens: 8192,
10795
+ thinking: thinkingToStore
10549
10796
  },
10550
10797
  ui: {
10551
10798
  theme: "auto",
@@ -10980,6 +11227,7 @@ var MAX_SKILL_INSTRUCTIONS_CHARS, TRUST_SETTINGS_DIR, TRUST_SETTINGS_FILE, PROJE
10980
11227
  var init_session = __esm({
10981
11228
  "src/cli/repl/session.ts"() {
10982
11229
  init_env();
11230
+ init_thinking();
10983
11231
  init_manager();
10984
11232
  init_compactor();
10985
11233
  init_memory();
@@ -33683,6 +33931,7 @@ var helpCommand = {
33683
33931
  commands: [
33684
33932
  { cmd: "/model, /m", desc: "View or change the current model" },
33685
33933
  { cmd: "/provider", desc: "View or change the LLM provider" },
33934
+ { cmd: "/thinking, /think", desc: "View or change the reasoning/thinking mode" },
33686
33935
  { cmd: "/doctor, /dr", desc: "Run local diagnostics for config, auth, hooks, and tools" },
33687
33936
  { cmd: "/compact", desc: "Toggle compact mode (less verbose)" },
33688
33937
  { cmd: "/cost, /tokens", desc: "Show token usage and cost" },
@@ -34149,6 +34398,7 @@ function truncate2(str, maxLength, suffix = "...") {
34149
34398
 
34150
34399
  // src/cli/repl/commands/model.ts
34151
34400
  init_env();
34401
+ init_thinking();
34152
34402
  async function fetchLocalModels(providerType) {
34153
34403
  try {
34154
34404
  const baseUrl = getBaseUrl(providerType);
@@ -34330,6 +34580,32 @@ async function persistModelPreference(provider, model) {
34330
34580
  console.log(chalk.dim(" Model changed for this session only.\n"));
34331
34581
  }
34332
34582
  }
34583
+ function reconcileThinkingAfterModelChange(session, newModel) {
34584
+ const provider = session.config.provider.type;
34585
+ const cap = getThinkingCapability(provider, newModel);
34586
+ if (!cap.supported) {
34587
+ if (session.config.provider.thinking !== void 0) {
34588
+ session.config.provider.thinking = void 0;
34589
+ console.log(chalk.dim(" \u2139 Thinking not supported on this model \u2014 turned off."));
34590
+ }
34591
+ return;
34592
+ }
34593
+ const current = session.config.provider.thinking;
34594
+ if (current !== void 0 && typeof current === "object" && !cap.kinds.includes("budget")) {
34595
+ const newDefault = resolveDefaultThinking(provider, newModel);
34596
+ session.config.provider.thinking = newDefault === "off" ? void 0 : newDefault;
34597
+ console.log(
34598
+ chalk.dim(
34599
+ ` \u2139 Thinking reset to ${session.config.provider.thinking ?? "off"} (model uses effort levels).`
34600
+ )
34601
+ );
34602
+ return;
34603
+ }
34604
+ if (current === void 0) {
34605
+ const def = resolveDefaultThinking(provider, newModel);
34606
+ session.config.provider.thinking = def === "off" ? void 0 : def;
34607
+ }
34608
+ }
34333
34609
  var modelCommand = {
34334
34610
  name: "model",
34335
34611
  aliases: ["m"],
@@ -34378,6 +34654,7 @@ var modelCommand = {
34378
34654
  return false;
34379
34655
  }
34380
34656
  session.config.provider.model = selectedModel;
34657
+ reconcileThinkingAfterModelChange(session, selectedModel);
34381
34658
  await persistModelPreference(currentProvider, selectedModel);
34382
34659
  const modelInfo2 = providerDef.models.find((m) => m.id === selectedModel);
34383
34660
  console.log(chalk.green(`\u2713 Switched to ${modelInfo2?.name ?? selectedModel}
@@ -34400,6 +34677,7 @@ var modelCommand = {
34400
34677
  if (!foundInProvider) {
34401
34678
  console.log(chalk.yellow(`Model "${newModel}" not in known list, setting anyway...`));
34402
34679
  session.config.provider.model = newModel;
34680
+ reconcileThinkingAfterModelChange(session, newModel);
34403
34681
  await persistModelPreference(currentProvider, newModel);
34404
34682
  console.log(chalk.green(`\u2713 Model set to: ${newModel}
34405
34683
  `));
@@ -34415,6 +34693,7 @@ var modelCommand = {
34415
34693
  return false;
34416
34694
  }
34417
34695
  session.config.provider.model = newModel;
34696
+ reconcileThinkingAfterModelChange(session, newModel);
34418
34697
  await persistModelPreference(currentProvider, newModel);
34419
34698
  const modelInfo = providerDef.models.find((m) => m.id === newModel);
34420
34699
  console.log(chalk.green(`\u2713 Switched to ${modelInfo?.name ?? newModel}
@@ -36407,6 +36686,7 @@ async function promptVertexSettings2(defaults) {
36407
36686
  // src/cli/repl/commands/status.ts
36408
36687
  init_state();
36409
36688
  init_trust_store();
36689
+ init_thinking();
36410
36690
  function getGitStatus2(projectPath) {
36411
36691
  try {
36412
36692
  execSync("git rev-parse --git-dir", { cwd: projectPath, stdio: "pipe" });
@@ -36532,6 +36812,11 @@ var statusCommand = {
36532
36812
  p26.log.step("Session");
36533
36813
  p26.log.message(` \u{1F4C1} ${session.projectPath}`);
36534
36814
  p26.log.message(` \u{1F916} ${session.config.provider.type} / ${session.config.provider.model}`);
36815
+ const cap = getThinkingCapability(session.config.provider.type, session.config.provider.model);
36816
+ if (cap.supported) {
36817
+ const thinkingLabel = session.config.provider.thinking !== void 0 ? formatThinkingMode(session.config.provider.thinking) : "off";
36818
+ p26.log.message(` \u{1F9E0} thinking: ${thinkingLabel} ${chalk.dim("(/thinking to change)")}`);
36819
+ }
36535
36820
  p26.outro("Done");
36536
36821
  return false;
36537
36822
  }
@@ -50467,6 +50752,209 @@ var doctorCommand = {
50467
50752
  }
50468
50753
  };
50469
50754
 
50755
+ // src/cli/repl/commands/thinking.ts
50756
+ init_thinking();
50757
+ init_env();
50758
+ var EFFORT_LEVELS = ["off", "auto", "low", "medium", "high"];
50759
+ function isEffortLevel(s) {
50760
+ return EFFORT_LEVELS.includes(s);
50761
+ }
50762
+ function parseThinkingArg(arg) {
50763
+ if (isEffortLevel(arg)) return arg;
50764
+ const n = parseInt(arg, 10);
50765
+ if (!isNaN(n) && n >= 0) return { budget: n };
50766
+ return null;
50767
+ }
50768
+ function modeDescription(mode, hasBudget) {
50769
+ if (typeof mode === "object") return `${mode.budget} token budget`;
50770
+ const descs = {
50771
+ off: "No reasoning \u2014 fastest and cheapest",
50772
+ auto: hasBudget ? "Dynamic budget \u2014 provider decides" : "Provider default effort",
50773
+ low: hasBudget ? "~2 048 tokens \u2014 quick reasoning" : "Minimal effort",
50774
+ medium: hasBudget ? "~8 000 tokens \u2014 balanced" : "Balanced effort",
50775
+ high: hasBudget ? "~16 000 tokens \u2014 deep reasoning" : "Maximum effort"
50776
+ };
50777
+ return descs[mode] ?? mode;
50778
+ }
50779
+ async function selectThinkingInteractively(modes, currentMode, hasBudget) {
50780
+ const currentLabel = formatThinkingMode(currentMode);
50781
+ return new Promise((resolve4) => {
50782
+ let selectedIndex = modes.findIndex((m) => formatThinkingMode(m) === currentLabel);
50783
+ if (selectedIndex === -1) selectedIndex = 0;
50784
+ let lastTotalLines = 0;
50785
+ const clearPrevious = () => {
50786
+ if (lastTotalLines === 0) return;
50787
+ process.stdout.write("\x1B[2K\r");
50788
+ for (let i = 0; i < lastTotalLines; i++) {
50789
+ process.stdout.write("\x1B[1A\x1B[2K");
50790
+ }
50791
+ process.stdout.write("\r");
50792
+ };
50793
+ const renderMenu = () => {
50794
+ clearPrevious();
50795
+ let totalLines = 0;
50796
+ for (let i = 0; i < modes.length; i++) {
50797
+ const mode = modes[i];
50798
+ const label = formatThinkingMode(mode);
50799
+ const isCurrent = label === currentLabel;
50800
+ const isSelected = i === selectedIndex;
50801
+ const desc = modeDescription(mode, hasBudget);
50802
+ let line = "";
50803
+ if (isSelected) {
50804
+ line = chalk.bgBlue.white(` \u25B6 ${label.padEnd(8)}`) + chalk.bgBlue.white(` ${desc} `);
50805
+ } else if (isCurrent) {
50806
+ line = chalk.green(` \u25CF ${label.padEnd(8)}`) + chalk.dim(` ${desc}`);
50807
+ } else {
50808
+ line = chalk.dim(` \u25CB ${label.padEnd(8)}`) + chalk.dim(` ${desc}`);
50809
+ }
50810
+ process.stdout.write(line + "\n");
50811
+ totalLines++;
50812
+ }
50813
+ process.stdout.write("\n" + chalk.dim("\u2191/\u2193 navigate \u2022 Enter select \u2022 Esc cancel") + "\n");
50814
+ totalLines += 2;
50815
+ lastTotalLines = totalLines;
50816
+ };
50817
+ const cleanup = () => {
50818
+ if (process.stdin.isTTY) process.stdin.setRawMode(false);
50819
+ process.stdin.pause();
50820
+ process.stdin.removeListener("data", onKeyPress);
50821
+ };
50822
+ const onKeyPress = (data) => {
50823
+ const key = data.toString();
50824
+ if (key === "\r" || key === "\n") {
50825
+ clearPrevious();
50826
+ cleanup();
50827
+ resolve4(modes[selectedIndex] ?? null);
50828
+ return;
50829
+ }
50830
+ if (key === "\x1B" || key === "q" || key === "") {
50831
+ clearPrevious();
50832
+ cleanup();
50833
+ resolve4(null);
50834
+ return;
50835
+ }
50836
+ if (key === "\x1B[A") {
50837
+ selectedIndex = (selectedIndex - 1 + modes.length) % modes.length;
50838
+ renderMenu();
50839
+ return;
50840
+ }
50841
+ if (key === "\x1B[B") {
50842
+ selectedIndex = (selectedIndex + 1) % modes.length;
50843
+ renderMenu();
50844
+ return;
50845
+ }
50846
+ };
50847
+ if (process.stdin.isTTY) process.stdin.setRawMode(true);
50848
+ process.stdin.resume();
50849
+ process.stdin.on("data", onKeyPress);
50850
+ renderMenu();
50851
+ });
50852
+ }
50853
+ async function applyMode(parsed, session, provider, model) {
50854
+ const capability = getThinkingCapability(provider, model);
50855
+ if ((provider === "kimi" || provider === "kimi-code") && parsed !== "off" && parsed !== "auto") {
50856
+ console.log(
50857
+ chalk.yellow(
50858
+ "\n\u26A0 Enabling thinking on Kimi may cause issues with tool calling.\n If you experience errors, run /thinking off to restore default behavior.\n"
50859
+ )
50860
+ );
50861
+ }
50862
+ const previousMode = session.config.provider.thinking;
50863
+ const newMode = parsed === "off" ? void 0 : parsed;
50864
+ session.config.provider.thinking = newMode;
50865
+ const modeToSave = newMode ?? resolveDefaultThinking(provider, model);
50866
+ await saveThinkingPreference(provider, modeToSave);
50867
+ const previousLabel = previousMode !== void 0 ? formatThinkingMode(previousMode) : "off";
50868
+ const newLabel = newMode !== void 0 ? formatThinkingMode(newMode) : "off";
50869
+ if (previousLabel === newLabel) {
50870
+ console.log(chalk.dim(`
50871
+ Already using thinking: ${newLabel}
50872
+ `));
50873
+ } else {
50874
+ const kindLabel = capability.kinds.includes("budget") ? "budget" : "effort";
50875
+ console.log(chalk.green(`
50876
+ \u2713 Thinking (${kindLabel}): ${previousLabel} \u2192 ${newLabel}
50877
+ `));
50878
+ }
50879
+ }
50880
+ var thinkingCommand = {
50881
+ name: "thinking",
50882
+ aliases: ["think", "reason"],
50883
+ description: "View or change the reasoning/thinking mode for the current model",
50884
+ usage: "/thinking [off|auto|low|medium|high|<budget-tokens>]",
50885
+ async execute(args, session) {
50886
+ const provider = session.config.provider.type;
50887
+ const model = session.config.provider.model;
50888
+ const capability = getThinkingCapability(provider, model);
50889
+ if (!capability.supported) {
50890
+ console.log(
50891
+ chalk.yellow(`
50892
+ \u26A0 Thinking not supported for ${model} on ${provider}.
50893
+ `) + chalk.dim(
50894
+ " Compatible models: claude-3-7+, claude-4+, o3, o4-mini, gpt-5*, gemini-2.5+\n"
50895
+ )
50896
+ );
50897
+ return false;
50898
+ }
50899
+ const hasBudget = capability.kinds.includes("budget");
50900
+ const current = session.config.provider.thinking;
50901
+ const currentMode = current ?? "off";
50902
+ if (args.length === 0) {
50903
+ console.log(chalk.cyan.bold("\n\u2550\u2550\u2550 Thinking Mode \u2550\u2550\u2550\n"));
50904
+ console.log(
50905
+ ` ${chalk.dim(provider + "/")}${chalk.cyan(model)} ${chalk.dim("\xB7")} kind: ${chalk.dim(capability.kinds.join(", "))}`
50906
+ );
50907
+ if (hasBudget && capability.budgetRange) {
50908
+ const { min, max } = capability.budgetRange;
50909
+ console.log(
50910
+ chalk.dim(` Budget range: ${min}\u2013${max} tokens (/thinking 8000 for custom)
50911
+ `)
50912
+ );
50913
+ } else {
50914
+ console.log();
50915
+ }
50916
+ const selected = await selectThinkingInteractively(capability.levels, currentMode, hasBudget);
50917
+ if (selected === null) {
50918
+ console.log(chalk.dim(" Cancelled\n"));
50919
+ return false;
50920
+ }
50921
+ await applyMode(selected, session, provider, model);
50922
+ return false;
50923
+ }
50924
+ const rawArg = args[0].toLowerCase();
50925
+ const parsed = parseThinkingArg(rawArg);
50926
+ if (parsed === null) {
50927
+ console.log(chalk.red(`
50928
+ \u2717 Unknown thinking mode: "${args[0]}"`));
50929
+ console.log(
50930
+ chalk.dim(" Valid options: off, auto, low, medium, high, or a token budget number\n")
50931
+ );
50932
+ return false;
50933
+ }
50934
+ if (typeof parsed === "object" && !hasBudget) {
50935
+ console.log(
50936
+ chalk.red(`
50937
+ \u2717 ${provider}/${model} uses effort levels, not token budgets.`) + chalk.dim("\n Use: off, auto, low, medium, or high\n")
50938
+ );
50939
+ return false;
50940
+ }
50941
+ if (typeof parsed === "object" && capability.budgetRange) {
50942
+ const { min, max } = capability.budgetRange;
50943
+ if (parsed.budget < min || parsed.budget > max) {
50944
+ console.log(
50945
+ chalk.red(`
50946
+ \u2717 Budget ${parsed.budget} is out of range.`) + chalk.dim(`
50947
+ Valid range for ${model}: ${min}\u2013${max} tokens
50948
+ `)
50949
+ );
50950
+ return false;
50951
+ }
50952
+ }
50953
+ await applyMode(parsed, session, provider, model);
50954
+ return false;
50955
+ }
50956
+ };
50957
+
50470
50958
  // src/cli/repl/output/renderer.ts
50471
50959
  init_syntax();
50472
50960
  var lineBuffer = "";
@@ -51498,7 +51986,8 @@ var commands = [
51498
51986
  buildAppCommand,
51499
51987
  contextCommand,
51500
51988
  bestOfNCommand,
51501
- doctorCommand
51989
+ doctorCommand,
51990
+ thinkingCommand
51502
51991
  ];
51503
51992
  function isSlashCommand(input) {
51504
51993
  return input.startsWith("/");
@@ -53868,6 +54357,7 @@ ${tail}`;
53868
54357
  tools: [],
53869
54358
  maxTokens: session.config.provider.maxTokens,
53870
54359
  signal: options.signal
54360
+ // Omit thinking for the final explanation turn to avoid unnecessary cost
53871
54361
  })) {
53872
54362
  if (options.signal?.aborted) break;
53873
54363
  if (chunk.type === "text" && chunk.text) {
@@ -53922,7 +54412,8 @@ ${tail}`;
53922
54412
  for await (const chunk of provider.streamWithTools(messages, {
53923
54413
  tools,
53924
54414
  maxTokens: session.config.provider.maxTokens,
53925
- signal: options.signal
54415
+ signal: options.signal,
54416
+ thinking: session.config.provider.thinking
53926
54417
  })) {
53927
54418
  if (options.signal?.aborted) {
53928
54419
  break;
@@ -55034,6 +55525,7 @@ init_allowed_paths();
55034
55525
  // src/cli/repl/status-bar.ts
55035
55526
  init_env();
55036
55527
  init_full_access_mode();
55528
+ init_thinking();
55037
55529
  function formatContextUsage(percent) {
55038
55530
  const label = `ctx ${percent.toFixed(0)}%`;
55039
55531
  if (percent >= 90) return chalk.red(label);
@@ -55053,7 +55545,9 @@ function formatStatusBar(projectPath, config, gitCtx, contextUsagePercent) {
55053
55545
  parts.push(chalk.dim("\u{1F4C1} ") + chalk.magenta(projectName));
55054
55546
  const providerName = config.provider.type;
55055
55547
  const modelName = getDisplayModel(config);
55056
- parts.push(chalk.dim(`${providerName}/`) + chalk.cyan(modelName));
55548
+ const thinkingMode = config.provider.thinking;
55549
+ const thinkingSuffix = thinkingMode !== void 0 ? chalk.dim(" [") + chalk.magenta(formatThinkingMode(thinkingMode)) + chalk.dim("]") : "";
55550
+ parts.push(chalk.dim(`${providerName}/`) + chalk.cyan(modelName) + thinkingSuffix);
55057
55551
  if (isQualityLoop()) {
55058
55552
  parts.push(chalk.green("\u{1F504} quality loop"));
55059
55553
  }