@corbat-tech/coco 2.30.0 → 2.31.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/README.md +1 -0
- package/dist/cli/index.js +463 -45
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +40 -5
- package/dist/index.js +167 -40
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
3373
|
-
|
|
3374
|
-
|
|
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
|
|
3403
|
-
max_tokens:
|
|
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
|
|
3437
|
-
max_tokens:
|
|
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
|
|
3499
|
-
max_tokens:
|
|
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
|
-
*
|
|
4178
|
-
*
|
|
4179
|
-
*
|
|
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
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
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,133 @@ 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
|
+
var thinkingCommand = {
|
|
50769
|
+
name: "thinking",
|
|
50770
|
+
aliases: ["think", "reason"],
|
|
50771
|
+
description: "View or change the reasoning/thinking mode for the current model",
|
|
50772
|
+
usage: "/thinking [off|auto|low|medium|high|<budget-tokens>]",
|
|
50773
|
+
async execute(args, session) {
|
|
50774
|
+
const provider = session.config.provider.type;
|
|
50775
|
+
const model = session.config.provider.model;
|
|
50776
|
+
const capability = getThinkingCapability(provider, model);
|
|
50777
|
+
if (args.length === 0) {
|
|
50778
|
+
const current = session.config.provider.thinking;
|
|
50779
|
+
const display = current !== void 0 ? formatThinkingMode(current) : "off";
|
|
50780
|
+
if (!capability.supported) {
|
|
50781
|
+
console.log(
|
|
50782
|
+
chalk.yellow(`
|
|
50783
|
+
\u26A0 Thinking not supported for ${model} on ${provider}.
|
|
50784
|
+
`) + chalk.dim(
|
|
50785
|
+
" Compatible models: claude-3-7+, claude-4+, o3, o4-mini, gpt-5*, gemini-2.5+\n"
|
|
50786
|
+
)
|
|
50787
|
+
);
|
|
50788
|
+
return false;
|
|
50789
|
+
}
|
|
50790
|
+
console.log(chalk.cyan.bold("\n\u2550\u2550\u2550 Thinking Mode \u2550\u2550\u2550\n"));
|
|
50791
|
+
console.log(` Current: ${chalk.magenta(display)}`);
|
|
50792
|
+
console.log(` Provider: ${chalk.dim(provider)} / ${chalk.dim(model)}`);
|
|
50793
|
+
console.log(` Supports: ${capability.kinds.join(", ")}`);
|
|
50794
|
+
if (capability.budgetRange) {
|
|
50795
|
+
const { min, max, default: def } = capability.budgetRange;
|
|
50796
|
+
console.log(` Budget range: ${chalk.dim(`${min}\u2013${max} tokens (default ${def})`)}`);
|
|
50797
|
+
}
|
|
50798
|
+
console.log(`
|
|
50799
|
+
${chalk.dim("Available modes:")}`);
|
|
50800
|
+
for (const level of capability.levels) {
|
|
50801
|
+
const label = formatThinkingMode(level);
|
|
50802
|
+
const isCurrent = label === display;
|
|
50803
|
+
console.log(
|
|
50804
|
+
` ${isCurrent ? chalk.green("\u2192") : " "} ${isCurrent ? chalk.green(label) : chalk.dim(label)}`
|
|
50805
|
+
);
|
|
50806
|
+
}
|
|
50807
|
+
if (capability.kinds.includes("budget")) {
|
|
50808
|
+
console.log(chalk.dim(`
|
|
50809
|
+
You can also pass a token budget: /thinking 8000
|
|
50810
|
+
`));
|
|
50811
|
+
} else {
|
|
50812
|
+
console.log();
|
|
50813
|
+
}
|
|
50814
|
+
return false;
|
|
50815
|
+
}
|
|
50816
|
+
const rawArg = args[0].toLowerCase();
|
|
50817
|
+
const parsed = parseThinkingArg(rawArg);
|
|
50818
|
+
if (parsed === null) {
|
|
50819
|
+
console.log(chalk.red(`
|
|
50820
|
+
\u2717 Unknown thinking mode: "${args[0]}"`));
|
|
50821
|
+
console.log(
|
|
50822
|
+
chalk.dim(" Valid options: off, auto, low, medium, high, or a token budget number\n")
|
|
50823
|
+
);
|
|
50824
|
+
return false;
|
|
50825
|
+
}
|
|
50826
|
+
if (!capability.supported && parsed !== "off") {
|
|
50827
|
+
console.log(
|
|
50828
|
+
chalk.yellow(`
|
|
50829
|
+
\u26A0 Thinking not supported for ${model} on ${provider}.
|
|
50830
|
+
`) + chalk.dim(
|
|
50831
|
+
" Compatible models: claude-3-7+, claude-4+, o3, o4-mini, gpt-5*, gemini-2.5+\n"
|
|
50832
|
+
)
|
|
50833
|
+
);
|
|
50834
|
+
return false;
|
|
50835
|
+
}
|
|
50836
|
+
if (typeof parsed === "object" && !capability.kinds.includes("budget")) {
|
|
50837
|
+
console.log(
|
|
50838
|
+
chalk.red(`
|
|
50839
|
+
\u2717 ${provider}/${model} uses effort levels, not token budgets.`) + chalk.dim("\n Use: off, auto, low, medium, or high\n")
|
|
50840
|
+
);
|
|
50841
|
+
return false;
|
|
50842
|
+
}
|
|
50843
|
+
if (typeof parsed === "object" && capability.budgetRange) {
|
|
50844
|
+
const { min, max } = capability.budgetRange;
|
|
50845
|
+
if (parsed.budget < min || parsed.budget > max) {
|
|
50846
|
+
console.log(
|
|
50847
|
+
chalk.red(`
|
|
50848
|
+
\u2717 Budget ${parsed.budget} is out of range.`) + chalk.dim(`
|
|
50849
|
+
Valid range for ${model}: ${min}\u2013${max} tokens
|
|
50850
|
+
`)
|
|
50851
|
+
);
|
|
50852
|
+
return false;
|
|
50853
|
+
}
|
|
50854
|
+
}
|
|
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
|
+
console.log(chalk.green(`
|
|
50875
|
+
\u2713 Thinking: ${previousLabel} \u2192 ${newLabel}
|
|
50876
|
+
`));
|
|
50877
|
+
}
|
|
50878
|
+
return false;
|
|
50879
|
+
}
|
|
50880
|
+
};
|
|
50881
|
+
|
|
50470
50882
|
// src/cli/repl/output/renderer.ts
|
|
50471
50883
|
init_syntax();
|
|
50472
50884
|
var lineBuffer = "";
|
|
@@ -51498,7 +51910,8 @@ var commands = [
|
|
|
51498
51910
|
buildAppCommand,
|
|
51499
51911
|
contextCommand,
|
|
51500
51912
|
bestOfNCommand,
|
|
51501
|
-
doctorCommand
|
|
51913
|
+
doctorCommand,
|
|
51914
|
+
thinkingCommand
|
|
51502
51915
|
];
|
|
51503
51916
|
function isSlashCommand(input) {
|
|
51504
51917
|
return input.startsWith("/");
|
|
@@ -53868,6 +54281,7 @@ ${tail}`;
|
|
|
53868
54281
|
tools: [],
|
|
53869
54282
|
maxTokens: session.config.provider.maxTokens,
|
|
53870
54283
|
signal: options.signal
|
|
54284
|
+
// Omit thinking for the final explanation turn to avoid unnecessary cost
|
|
53871
54285
|
})) {
|
|
53872
54286
|
if (options.signal?.aborted) break;
|
|
53873
54287
|
if (chunk.type === "text" && chunk.text) {
|
|
@@ -53922,7 +54336,8 @@ ${tail}`;
|
|
|
53922
54336
|
for await (const chunk of provider.streamWithTools(messages, {
|
|
53923
54337
|
tools,
|
|
53924
54338
|
maxTokens: session.config.provider.maxTokens,
|
|
53925
|
-
signal: options.signal
|
|
54339
|
+
signal: options.signal,
|
|
54340
|
+
thinking: session.config.provider.thinking
|
|
53926
54341
|
})) {
|
|
53927
54342
|
if (options.signal?.aborted) {
|
|
53928
54343
|
break;
|
|
@@ -55034,6 +55449,7 @@ init_allowed_paths();
|
|
|
55034
55449
|
// src/cli/repl/status-bar.ts
|
|
55035
55450
|
init_env();
|
|
55036
55451
|
init_full_access_mode();
|
|
55452
|
+
init_thinking();
|
|
55037
55453
|
function formatContextUsage(percent) {
|
|
55038
55454
|
const label = `ctx ${percent.toFixed(0)}%`;
|
|
55039
55455
|
if (percent >= 90) return chalk.red(label);
|
|
@@ -55053,7 +55469,9 @@ function formatStatusBar(projectPath, config, gitCtx, contextUsagePercent) {
|
|
|
55053
55469
|
parts.push(chalk.dim("\u{1F4C1} ") + chalk.magenta(projectName));
|
|
55054
55470
|
const providerName = config.provider.type;
|
|
55055
55471
|
const modelName = getDisplayModel(config);
|
|
55056
|
-
|
|
55472
|
+
const thinkingMode = config.provider.thinking;
|
|
55473
|
+
const thinkingSuffix = thinkingMode !== void 0 ? chalk.dim(" [") + chalk.magenta(formatThinkingMode(thinkingMode)) + chalk.dim("]") : "";
|
|
55474
|
+
parts.push(chalk.dim(`${providerName}/`) + chalk.cyan(modelName) + thinkingSuffix);
|
|
55057
55475
|
if (isQualityLoop()) {
|
|
55058
55476
|
parts.push(chalk.green("\u{1F504} quality loop"));
|
|
55059
55477
|
}
|