@austinthesing/magic-shell 0.2.19 → 0.2.20
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 +10 -3
- package/dist/cli.js +219 -44
- package/dist/index.js +250 -48
- package/dist/tui.js +219 -44
- package/package.json +1 -1
package/dist/tui.js
CHANGED
|
@@ -37000,21 +37000,66 @@ var WORKERS_AI_MODELS = [
|
|
|
37000
37000
|
];
|
|
37001
37001
|
var OPENCODE_ZEN_MODELS = [
|
|
37002
37002
|
{
|
|
37003
|
-
id: "
|
|
37004
|
-
name: "
|
|
37005
|
-
description: "
|
|
37003
|
+
id: "minimax-m2.5-free",
|
|
37004
|
+
name: "MiniMax M2.5 Free",
|
|
37005
|
+
description: "MiniMax's free model (limited time)",
|
|
37006
37006
|
category: "smart",
|
|
37007
37007
|
provider: "opencode-zen",
|
|
37008
|
-
contextLength:
|
|
37008
|
+
contextLength: 196608,
|
|
37009
37009
|
free: true
|
|
37010
37010
|
},
|
|
37011
37011
|
{
|
|
37012
|
-
id: "
|
|
37013
|
-
name: "
|
|
37014
|
-
description: "
|
|
37012
|
+
id: "ling-2.6-flash-free",
|
|
37013
|
+
name: "Ling 2.6 Flash Free",
|
|
37014
|
+
description: "Ling's free flash model (limited time)",
|
|
37015
37015
|
category: "fast",
|
|
37016
37016
|
provider: "opencode-zen",
|
|
37017
|
-
contextLength:
|
|
37017
|
+
contextLength: 131072,
|
|
37018
|
+
free: true
|
|
37019
|
+
},
|
|
37020
|
+
{
|
|
37021
|
+
id: "hy3-preview-free",
|
|
37022
|
+
name: "Hy3 Preview Free",
|
|
37023
|
+
description: "Hy3 preview model (free, limited time)",
|
|
37024
|
+
category: "smart",
|
|
37025
|
+
provider: "opencode-zen",
|
|
37026
|
+
contextLength: 131072,
|
|
37027
|
+
free: true
|
|
37028
|
+
},
|
|
37029
|
+
{
|
|
37030
|
+
id: "nemotron-3-super-free",
|
|
37031
|
+
name: "Nemotron 3 Super Free",
|
|
37032
|
+
description: "NVIDIA Nemotron free trial model",
|
|
37033
|
+
category: "smart",
|
|
37034
|
+
provider: "opencode-zen",
|
|
37035
|
+
contextLength: 131072,
|
|
37036
|
+
free: true
|
|
37037
|
+
},
|
|
37038
|
+
{
|
|
37039
|
+
id: "trinity-large-preview-free",
|
|
37040
|
+
name: "Trinity Large Preview Free",
|
|
37041
|
+
description: "Trinity large preview model (free, limited time)",
|
|
37042
|
+
category: "smart",
|
|
37043
|
+
provider: "opencode-zen",
|
|
37044
|
+
contextLength: 131072,
|
|
37045
|
+
free: true
|
|
37046
|
+
},
|
|
37047
|
+
{
|
|
37048
|
+
id: "big-pickle",
|
|
37049
|
+
name: "Big Pickle",
|
|
37050
|
+
description: "OpenCode stealth model (free, limited time)",
|
|
37051
|
+
category: "smart",
|
|
37052
|
+
provider: "opencode-zen",
|
|
37053
|
+
contextLength: 131072,
|
|
37054
|
+
free: true
|
|
37055
|
+
},
|
|
37056
|
+
{
|
|
37057
|
+
id: "gpt-5-nano",
|
|
37058
|
+
name: "GPT 5 Nano",
|
|
37059
|
+
description: "OpenAI's free lightweight GPT model",
|
|
37060
|
+
category: "fast",
|
|
37061
|
+
provider: "opencode-zen",
|
|
37062
|
+
contextLength: 400000,
|
|
37018
37063
|
free: true
|
|
37019
37064
|
},
|
|
37020
37065
|
{
|
|
@@ -37583,7 +37628,8 @@ var DEFAULT_CONFIG = {
|
|
|
37583
37628
|
workersAiApiKey: "",
|
|
37584
37629
|
cloudflareAccountId: "",
|
|
37585
37630
|
cloudflareAiGatewayId: "default",
|
|
37586
|
-
defaultModel: "
|
|
37631
|
+
defaultModel: "minimax-m2.5-free",
|
|
37632
|
+
thinkingLevel: "low",
|
|
37587
37633
|
safetyLevel: "moderate",
|
|
37588
37634
|
dryRunByDefault: false,
|
|
37589
37635
|
blockedCommands: [
|
|
@@ -76352,7 +76398,94 @@ function cleanCommand(command) {
|
|
|
76352
76398
|
}
|
|
76353
76399
|
return cleaned.trim();
|
|
76354
76400
|
}
|
|
76355
|
-
|
|
76401
|
+
function getThinkingLevel(config2) {
|
|
76402
|
+
return config2?.thinkingLevel || "low";
|
|
76403
|
+
}
|
|
76404
|
+
function supportsThinkingControl(modelId) {
|
|
76405
|
+
return modelId.includes("thinking") || modelId.includes("gpt-5") || modelId.includes("claude-") || modelId.includes("gemini-");
|
|
76406
|
+
}
|
|
76407
|
+
function buildOpenRouterThinkingOptions(modelId, thinkingLevel) {
|
|
76408
|
+
if (thinkingLevel === "off" || !supportsThinkingControl(modelId)) {
|
|
76409
|
+
return {};
|
|
76410
|
+
}
|
|
76411
|
+
return {
|
|
76412
|
+
reasoning: {
|
|
76413
|
+
effort: thinkingLevel
|
|
76414
|
+
}
|
|
76415
|
+
};
|
|
76416
|
+
}
|
|
76417
|
+
function buildOpenAICompatibleThinkingOptions(modelId, thinkingLevel) {
|
|
76418
|
+
if (thinkingLevel === "off" || !supportsThinkingControl(modelId)) {
|
|
76419
|
+
return {};
|
|
76420
|
+
}
|
|
76421
|
+
return {
|
|
76422
|
+
reasoning_effort: thinkingLevel
|
|
76423
|
+
};
|
|
76424
|
+
}
|
|
76425
|
+
function buildAiSdkProviderOptions(modelId, thinkingLevel, providerOptionsName) {
|
|
76426
|
+
if (thinkingLevel === "off" || !supportsThinkingControl(modelId)) {
|
|
76427
|
+
return;
|
|
76428
|
+
}
|
|
76429
|
+
if (modelId.startsWith("gpt-")) {
|
|
76430
|
+
const compatibleOptions = providerOptionsName && providerOptionsName !== "openai" ? {
|
|
76431
|
+
[providerOptionsName]: {
|
|
76432
|
+
reasoningEffort: thinkingLevel
|
|
76433
|
+
}
|
|
76434
|
+
} : {};
|
|
76435
|
+
return {
|
|
76436
|
+
openai: {
|
|
76437
|
+
reasoningEffort: thinkingLevel
|
|
76438
|
+
},
|
|
76439
|
+
openaiCompatible: {
|
|
76440
|
+
reasoningEffort: thinkingLevel
|
|
76441
|
+
},
|
|
76442
|
+
...compatibleOptions
|
|
76443
|
+
};
|
|
76444
|
+
}
|
|
76445
|
+
if (modelId.startsWith("gemini-")) {
|
|
76446
|
+
return {
|
|
76447
|
+
google: {
|
|
76448
|
+
thinkingConfig: {
|
|
76449
|
+
thinkingLevel
|
|
76450
|
+
}
|
|
76451
|
+
}
|
|
76452
|
+
};
|
|
76453
|
+
}
|
|
76454
|
+
if (modelId.startsWith("claude-")) {
|
|
76455
|
+
const budgetByLevel = {
|
|
76456
|
+
low: 1024,
|
|
76457
|
+
medium: 4096,
|
|
76458
|
+
high: 8192
|
|
76459
|
+
};
|
|
76460
|
+
return {
|
|
76461
|
+
anthropic: {
|
|
76462
|
+
thinking: {
|
|
76463
|
+
type: "enabled",
|
|
76464
|
+
budgetTokens: budgetByLevel[thinkingLevel]
|
|
76465
|
+
}
|
|
76466
|
+
}
|
|
76467
|
+
};
|
|
76468
|
+
}
|
|
76469
|
+
if (modelId.includes("thinking")) {
|
|
76470
|
+
return {
|
|
76471
|
+
openaiCompatible: {
|
|
76472
|
+
reasoningEffort: thinkingLevel
|
|
76473
|
+
},
|
|
76474
|
+
...providerOptionsName ? {
|
|
76475
|
+
[providerOptionsName]: {
|
|
76476
|
+
reasoningEffort: thinkingLevel
|
|
76477
|
+
}
|
|
76478
|
+
} : {}
|
|
76479
|
+
};
|
|
76480
|
+
}
|
|
76481
|
+
return;
|
|
76482
|
+
}
|
|
76483
|
+
function shouldOmitTemperature(modelId, thinkingLevel) {
|
|
76484
|
+
return thinkingLevel !== "off" && (modelId.startsWith("claude-") || modelId.includes("gpt-5"));
|
|
76485
|
+
}
|
|
76486
|
+
async function callOpenRouter(apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
|
|
76487
|
+
const thinkingOptions = buildOpenRouterThinkingOptions(modelId, thinkingLevel);
|
|
76488
|
+
const temperatureOptions = shouldOmitTemperature(modelId, thinkingLevel) ? {} : { temperature: 0.1 };
|
|
76356
76489
|
const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
|
|
76357
76490
|
method: "POST",
|
|
76358
76491
|
headers: {
|
|
@@ -76368,7 +76501,8 @@ async function callOpenRouter(apiKey, modelId, systemPrompt, userInput) {
|
|
|
76368
76501
|
{ role: "user", content: userInput }
|
|
76369
76502
|
],
|
|
76370
76503
|
max_tokens: 500,
|
|
76371
|
-
|
|
76504
|
+
...temperatureOptions,
|
|
76505
|
+
...thinkingOptions
|
|
76372
76506
|
})
|
|
76373
76507
|
});
|
|
76374
76508
|
if (!response.ok) {
|
|
@@ -76388,7 +76522,9 @@ async function callOpenRouter(apiKey, modelId, systemPrompt, userInput) {
|
|
|
76388
76522
|
}
|
|
76389
76523
|
return data.choices[0]?.message?.content?.trim() || "";
|
|
76390
76524
|
}
|
|
76391
|
-
async function callOpenAICompatibleFetch(baseURL, apiKey, modelId, systemPrompt, userInput, headers = {}, includeAuthorization = true) {
|
|
76525
|
+
async function callOpenAICompatibleFetch(baseURL, apiKey, modelId, systemPrompt, userInput, thinkingLevel, headers = {}, includeAuthorization = true) {
|
|
76526
|
+
const thinkingOptions = buildOpenAICompatibleThinkingOptions(modelId, thinkingLevel);
|
|
76527
|
+
const temperatureOptions = shouldOmitTemperature(modelId, thinkingLevel) ? {} : { temperature: 0.1 };
|
|
76392
76528
|
const requestHeaders = {
|
|
76393
76529
|
"Content-Type": "application/json",
|
|
76394
76530
|
...headers
|
|
@@ -76406,8 +76542,9 @@ async function callOpenAICompatibleFetch(baseURL, apiKey, modelId, systemPrompt,
|
|
|
76406
76542
|
{ role: "user", content: userInput }
|
|
76407
76543
|
],
|
|
76408
76544
|
max_tokens: 500,
|
|
76409
|
-
|
|
76410
|
-
|
|
76545
|
+
stream: false,
|
|
76546
|
+
...temperatureOptions,
|
|
76547
|
+
...thinkingOptions
|
|
76411
76548
|
})
|
|
76412
76549
|
});
|
|
76413
76550
|
if (!response.ok) {
|
|
@@ -76439,42 +76576,45 @@ function getCloudflareAccountId(config2) {
|
|
|
76439
76576
|
function getCloudflareGatewayId(config2) {
|
|
76440
76577
|
return config2.cloudflareAiGatewayId || process.env.CLOUDFLARE_AI_GATEWAY_ID || process.env.CF_AIG_GATEWAY_ID || "default";
|
|
76441
76578
|
}
|
|
76442
|
-
async function callGatewayProvider(provider, apiKey, modelId, systemPrompt, userInput) {
|
|
76579
|
+
async function callGatewayProvider(provider, apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
|
|
76443
76580
|
const config2 = loadConfig2();
|
|
76444
76581
|
switch (provider) {
|
|
76445
76582
|
case "vercel-ai-gateway":
|
|
76446
|
-
return await callOpenAICompatibleFetch("https://ai-gateway.vercel.sh/v1", apiKey, modelId, systemPrompt, userInput);
|
|
76583
|
+
return await callOpenAICompatibleFetch("https://ai-gateway.vercel.sh/v1", apiKey, modelId, systemPrompt, userInput, thinkingLevel);
|
|
76447
76584
|
case "cloudflare-ai-gateway": {
|
|
76448
76585
|
const accountId = getCloudflareAccountId(config2);
|
|
76449
76586
|
if (!accountId) {
|
|
76450
76587
|
throw new Error("Cloudflare account ID is required. Set cloudflareAccountId in config or CLOUDFLARE_ACCOUNT_ID.");
|
|
76451
76588
|
}
|
|
76452
76589
|
const gatewayId = getCloudflareGatewayId(config2);
|
|
76453
|
-
return await callOpenAICompatibleFetch(`https://gateway.ai.cloudflare.com/v1/${accountId}/${gatewayId}/compat`, apiKey, modelId, systemPrompt, userInput, { "cf-aig-authorization": `Bearer ${apiKey}` }, false);
|
|
76590
|
+
return await callOpenAICompatibleFetch(`https://gateway.ai.cloudflare.com/v1/${accountId}/${gatewayId}/compat`, apiKey, modelId, systemPrompt, userInput, thinkingLevel, { "cf-aig-authorization": `Bearer ${apiKey}` }, false);
|
|
76454
76591
|
}
|
|
76455
76592
|
case "workers-ai": {
|
|
76456
76593
|
const accountId = getCloudflareAccountId(config2);
|
|
76457
76594
|
if (!accountId) {
|
|
76458
76595
|
throw new Error("Cloudflare account ID is required. Set cloudflareAccountId in config or CLOUDFLARE_ACCOUNT_ID.");
|
|
76459
76596
|
}
|
|
76460
|
-
return await callOpenAICompatibleFetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/v1`, apiKey, modelId, systemPrompt, userInput);
|
|
76597
|
+
return await callOpenAICompatibleFetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/v1`, apiKey, modelId, systemPrompt, userInput, thinkingLevel);
|
|
76461
76598
|
}
|
|
76462
76599
|
default:
|
|
76463
76600
|
throw new Error(`Unsupported gateway provider: ${provider}`);
|
|
76464
76601
|
}
|
|
76465
76602
|
}
|
|
76466
76603
|
var DEBUG_API = process.env.DEBUG_API === "1";
|
|
76467
|
-
async function generateZenText(model, systemPrompt, userInput) {
|
|
76604
|
+
async function generateZenText(model, modelId, systemPrompt, userInput, thinkingLevel, providerOptionsName) {
|
|
76605
|
+
const providerOptions = buildAiSdkProviderOptions(modelId, thinkingLevel, providerOptionsName);
|
|
76606
|
+
const temperatureOptions = shouldOmitTemperature(modelId, thinkingLevel) ? {} : { temperature: 0.1 };
|
|
76468
76607
|
const { text: text2 } = await generateText({
|
|
76469
76608
|
model,
|
|
76470
76609
|
system: systemPrompt,
|
|
76471
76610
|
prompt: userInput,
|
|
76472
76611
|
maxOutputTokens: 500,
|
|
76473
|
-
|
|
76612
|
+
...temperatureOptions,
|
|
76613
|
+
...providerOptions ? { providerOptions } : {}
|
|
76474
76614
|
});
|
|
76475
76615
|
return text2.trim();
|
|
76476
76616
|
}
|
|
76477
|
-
async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput) {
|
|
76617
|
+
async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
|
|
76478
76618
|
if (DEBUG_API) {
|
|
76479
76619
|
console.error(`[DEBUG] Calling OpenAI Responses API`);
|
|
76480
76620
|
console.error(`[DEBUG] Model: ${modelId}`);
|
|
@@ -76485,7 +76625,7 @@ async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput)
|
|
|
76485
76625
|
baseURL: ZEN_BASE_URL
|
|
76486
76626
|
});
|
|
76487
76627
|
try {
|
|
76488
|
-
return await generateZenText(openai2(modelId), systemPrompt, userInput);
|
|
76628
|
+
return await generateZenText(openai2(modelId), modelId, systemPrompt, userInput, thinkingLevel);
|
|
76489
76629
|
} catch (error40) {
|
|
76490
76630
|
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
76491
76631
|
if (DEBUG_API) {
|
|
@@ -76494,7 +76634,7 @@ async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput)
|
|
|
76494
76634
|
throw new Error(message);
|
|
76495
76635
|
}
|
|
76496
76636
|
}
|
|
76497
|
-
async function callZenAnthropic(apiKey, modelId, systemPrompt, userInput) {
|
|
76637
|
+
async function callZenAnthropic(apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
|
|
76498
76638
|
if (DEBUG_API) {
|
|
76499
76639
|
console.error(`[DEBUG] Calling Anthropic Messages API`);
|
|
76500
76640
|
console.error(`[DEBUG] Model: ${modelId}`);
|
|
@@ -76505,7 +76645,7 @@ async function callZenAnthropic(apiKey, modelId, systemPrompt, userInput) {
|
|
|
76505
76645
|
baseURL: ZEN_BASE_URL
|
|
76506
76646
|
});
|
|
76507
76647
|
try {
|
|
76508
|
-
return await generateZenText(anthropic2(modelId), systemPrompt, userInput);
|
|
76648
|
+
return await generateZenText(anthropic2(modelId), modelId, systemPrompt, userInput, thinkingLevel);
|
|
76509
76649
|
} catch (error40) {
|
|
76510
76650
|
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
76511
76651
|
if (DEBUG_API) {
|
|
@@ -76514,7 +76654,7 @@ async function callZenAnthropic(apiKey, modelId, systemPrompt, userInput) {
|
|
|
76514
76654
|
throw new Error(message);
|
|
76515
76655
|
}
|
|
76516
76656
|
}
|
|
76517
|
-
async function callZenOpenAICompatible(apiKey, modelId, systemPrompt, userInput) {
|
|
76657
|
+
async function callZenOpenAICompatible(apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
|
|
76518
76658
|
if (DEBUG_API) {
|
|
76519
76659
|
console.error(`[DEBUG] Calling OpenAI-compatible Chat Completions API`);
|
|
76520
76660
|
console.error(`[DEBUG] Model: ${modelId}`);
|
|
@@ -76525,7 +76665,7 @@ async function callZenOpenAICompatible(apiKey, modelId, systemPrompt, userInput)
|
|
|
76525
76665
|
baseURL: ZEN_BASE_URL
|
|
76526
76666
|
});
|
|
76527
76667
|
try {
|
|
76528
|
-
return await generateZenText(openaiCompatible(modelId), systemPrompt, userInput);
|
|
76668
|
+
return await generateZenText(openaiCompatible(modelId), modelId, systemPrompt, userInput, thinkingLevel, "opencodeZen");
|
|
76529
76669
|
} catch (error40) {
|
|
76530
76670
|
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
76531
76671
|
if (DEBUG_API) {
|
|
@@ -76534,7 +76674,7 @@ async function callZenOpenAICompatible(apiKey, modelId, systemPrompt, userInput)
|
|
|
76534
76674
|
throw new Error(message);
|
|
76535
76675
|
}
|
|
76536
76676
|
}
|
|
76537
|
-
async function callCustomModel(model, systemPrompt, userInput) {
|
|
76677
|
+
async function callCustomModel(model, systemPrompt, userInput, thinkingLevel) {
|
|
76538
76678
|
if (DEBUG_API) {
|
|
76539
76679
|
console.error(`[DEBUG] Calling Custom Model`);
|
|
76540
76680
|
console.error(`[DEBUG] Model: ${model.modelId}`);
|
|
@@ -76546,7 +76686,7 @@ async function callCustomModel(model, systemPrompt, userInput) {
|
|
|
76546
76686
|
baseURL: model.baseUrl
|
|
76547
76687
|
});
|
|
76548
76688
|
try {
|
|
76549
|
-
return await generateZenText(openaiCompatible(model.modelId), systemPrompt, userInput);
|
|
76689
|
+
return await generateZenText(openaiCompatible(model.modelId), model.modelId, systemPrompt, userInput, thinkingLevel, "custom");
|
|
76550
76690
|
} catch (error40) {
|
|
76551
76691
|
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
76552
76692
|
if (DEBUG_API) {
|
|
@@ -76555,7 +76695,7 @@ async function callCustomModel(model, systemPrompt, userInput) {
|
|
|
76555
76695
|
throw new Error(message);
|
|
76556
76696
|
}
|
|
76557
76697
|
}
|
|
76558
|
-
async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
|
|
76698
|
+
async function callZenGoogle(apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
|
|
76559
76699
|
if (DEBUG_API) {
|
|
76560
76700
|
console.error(`[DEBUG] Calling Google Gemini API`);
|
|
76561
76701
|
console.error(`[DEBUG] Model: ${modelId}`);
|
|
@@ -76565,7 +76705,7 @@ async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
|
|
|
76565
76705
|
baseURL: `https://opencode.ai/zen/v1/models/${modelId}`
|
|
76566
76706
|
});
|
|
76567
76707
|
try {
|
|
76568
|
-
return await generateZenText(google2(modelId), systemPrompt, userInput);
|
|
76708
|
+
return await generateZenText(google2(modelId), modelId, systemPrompt, userInput, thinkingLevel);
|
|
76569
76709
|
} catch (error40) {
|
|
76570
76710
|
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
76571
76711
|
if (DEBUG_API) {
|
|
@@ -76581,30 +76721,31 @@ function getShellInfo() {
|
|
|
76581
76721
|
}
|
|
76582
76722
|
return cachedShellInfo;
|
|
76583
76723
|
}
|
|
76584
|
-
async function translateToCommand(apiKey, model, userInput, cwd, history = [], repoContextEnabled) {
|
|
76724
|
+
async function translateToCommand(apiKey, model, userInput, cwd, history = [], repoContextEnabled, config2) {
|
|
76585
76725
|
const shellInfo = getShellInfo();
|
|
76586
76726
|
const systemPrompt = buildSystemPrompt(cwd, history, shellInfo, repoContextEnabled);
|
|
76727
|
+
const thinkingLevel = getThinkingLevel(config2);
|
|
76587
76728
|
let rawCommand;
|
|
76588
76729
|
if (isCustomModel(model)) {
|
|
76589
|
-
rawCommand = await callCustomModel(model, systemPrompt, userInput);
|
|
76730
|
+
rawCommand = await callCustomModel(model, systemPrompt, userInput, "off");
|
|
76590
76731
|
} else if (model.provider === "openrouter") {
|
|
76591
|
-
rawCommand = await callOpenRouter(apiKey, model.id, systemPrompt, userInput);
|
|
76732
|
+
rawCommand = await callOpenRouter(apiKey, model.id, systemPrompt, userInput, thinkingLevel);
|
|
76592
76733
|
} else if (model.provider === "vercel-ai-gateway" || model.provider === "cloudflare-ai-gateway" || model.provider === "workers-ai") {
|
|
76593
|
-
rawCommand = await callGatewayProvider(model.provider, apiKey, model.id, systemPrompt, userInput);
|
|
76734
|
+
rawCommand = await callGatewayProvider(model.provider, apiKey, model.id, systemPrompt, userInput, thinkingLevel);
|
|
76594
76735
|
} else {
|
|
76595
76736
|
const apiType = getZenApiType(model.id);
|
|
76596
76737
|
switch (apiType) {
|
|
76597
76738
|
case "openai-responses":
|
|
76598
|
-
rawCommand = await callZenOpenAIResponses(apiKey, model.id, systemPrompt, userInput);
|
|
76739
|
+
rawCommand = await callZenOpenAIResponses(apiKey, model.id, systemPrompt, userInput, thinkingLevel);
|
|
76599
76740
|
break;
|
|
76600
76741
|
case "anthropic":
|
|
76601
|
-
rawCommand = await callZenAnthropic(apiKey, model.id, systemPrompt, userInput);
|
|
76742
|
+
rawCommand = await callZenAnthropic(apiKey, model.id, systemPrompt, userInput, thinkingLevel);
|
|
76602
76743
|
break;
|
|
76603
76744
|
case "google":
|
|
76604
|
-
rawCommand = await callZenGoogle(apiKey, model.id, systemPrompt, userInput);
|
|
76745
|
+
rawCommand = await callZenGoogle(apiKey, model.id, systemPrompt, userInput, thinkingLevel);
|
|
76605
76746
|
break;
|
|
76606
76747
|
case "openai-compatible":
|
|
76607
|
-
rawCommand = await callZenOpenAICompatible(apiKey, model.id, systemPrompt, userInput);
|
|
76748
|
+
rawCommand = await callZenOpenAICompatible(apiKey, model.id, systemPrompt, userInput, thinkingLevel);
|
|
76608
76749
|
break;
|
|
76609
76750
|
}
|
|
76610
76751
|
}
|
|
@@ -77141,15 +77282,16 @@ function getStatusBarContent() {
|
|
|
77141
77282
|
const safeModeIndicator = dryRunMode ? fg(theme.colors.warning)("[DRY RUN]") : "";
|
|
77142
77283
|
const safetyLevelColor = config2.safetyLevel === "strict" ? theme.colors.warning : config2.safetyLevel === "relaxed" ? theme.colors.error : theme.colors.success;
|
|
77143
77284
|
const safetyIndicator = fg(safetyLevelColor)(`[${config2.safetyLevel}]`);
|
|
77285
|
+
const thinkingIndicator = config2.thinkingLevel !== "off" ? fg(theme.colors.secondary)(`[Think:${config2.thinkingLevel}]`) : "";
|
|
77144
77286
|
const repoContextIndicator = config2.repoContext ? fg(theme.colors.info)("[Repo]") : "";
|
|
77145
|
-
return t`${fg(theme.colors.textMuted)("Provider:")} ${fg(theme.colors.text)(providerName)} ${fg(theme.colors.textMuted)("Model:")} ${fg(theme.colors.text)(currentModel.name)} ${safetyIndicator}${safeModeIndicator ? " " : ""}${safeModeIndicator}${repoContextIndicator ? " " : ""}${repoContextIndicator}`;
|
|
77287
|
+
return t`${fg(theme.colors.textMuted)("Provider:")} ${fg(theme.colors.text)(providerName)} ${fg(theme.colors.textMuted)("Model:")} ${fg(theme.colors.text)(currentModel.name)} ${safetyIndicator}${thinkingIndicator ? " " : ""}${thinkingIndicator}${safeModeIndicator ? " " : ""}${safeModeIndicator}${repoContextIndicator ? " " : ""}${repoContextIndicator}`;
|
|
77146
77288
|
}
|
|
77147
77289
|
function getHelpBarContent() {
|
|
77148
77290
|
const theme = getTheme();
|
|
77149
77291
|
if (awaitingConfirmation) {
|
|
77150
77292
|
return t`${fg(theme.colors.warning)(">>> Cmd+Enter or Enter to execute <<<")} ${fg(theme.colors.textMuted)("|")} ${fg(theme.colors.error)("Esc")}${fg(theme.colors.textMuted)(" Cancel")} ${fg(theme.colors.primary)("e")}${fg(theme.colors.textMuted)(" Edit")} ${fg(theme.colors.primary)("c")}${fg(theme.colors.textMuted)(" Copy")}`;
|
|
77151
77293
|
}
|
|
77152
|
-
return t`${fg(theme.colors.primary)("Ctrl+X P")}${fg(theme.colors.textMuted)(" Commands")} ${fg(theme.colors.primary)("Ctrl+Y")}${fg(theme.colors.textMuted)(" Safety")} ${fg(theme.colors.primary)("Ctrl+Z")}${fg(theme.colors.textMuted)(" Exit")}`;
|
|
77294
|
+
return t`${fg(theme.colors.primary)("Ctrl+X P")}${fg(theme.colors.textMuted)(" Commands")} ${fg(theme.colors.primary)("Ctrl+Y")}${fg(theme.colors.textMuted)(" Safety")} ${fg(theme.colors.primary)("Ctrl+K")}${fg(theme.colors.textMuted)(" Think")} ${fg(theme.colors.primary)("Ctrl+Z")}${fg(theme.colors.textMuted)(" Exit")}`;
|
|
77153
77295
|
}
|
|
77154
77296
|
function getInputHintContent() {
|
|
77155
77297
|
const theme = getTheme();
|
|
@@ -77472,7 +77614,7 @@ async function translateAndProcess(input) {
|
|
|
77472
77614
|
}
|
|
77473
77615
|
const loadingMsg = addSystemMessage("Translating...");
|
|
77474
77616
|
try {
|
|
77475
|
-
const command = await translateToCommand(apiKey, currentModel, input, currentCwd, history, config2.repoContext);
|
|
77617
|
+
const command = await translateToCommand(apiKey, currentModel, input, currentCwd, history, config2.repoContext, config2);
|
|
77476
77618
|
chatScrollBox.remove(`msg-${loadingMsg.id}`);
|
|
77477
77619
|
chatMessages = chatMessages.filter((m2) => m2.id !== loadingMsg.id);
|
|
77478
77620
|
const safety = analyzeCommand(command, config2);
|
|
@@ -77602,6 +77744,10 @@ async function handleSpecialCommand(input) {
|
|
|
77602
77744
|
statusBarText.content = getStatusBarContent();
|
|
77603
77745
|
addSystemMessage(`Dry-run mode: ${dryRunMode ? "ON" : "OFF"}`);
|
|
77604
77746
|
break;
|
|
77747
|
+
case "thinking":
|
|
77748
|
+
case "think":
|
|
77749
|
+
cycleThinkingLevel();
|
|
77750
|
+
break;
|
|
77605
77751
|
case "config":
|
|
77606
77752
|
await showConfig();
|
|
77607
77753
|
break;
|
|
@@ -77628,6 +77774,7 @@ function clearChat() {
|
|
|
77628
77774
|
function showHelp() {
|
|
77629
77775
|
const helpText = `Direct Shortcuts:
|
|
77630
77776
|
Ctrl+Y Cycle safety level (strict/moderate/relaxed)
|
|
77777
|
+
Ctrl+K Cycle thinking level (low/medium/high/off)
|
|
77631
77778
|
Ctrl+Z Exit magic-shell
|
|
77632
77779
|
Ctrl+C Cancel / Close popup
|
|
77633
77780
|
|
|
@@ -77636,19 +77783,26 @@ P Command palette M Change model
|
|
|
77636
77783
|
S Switch provider D Toggle dry-run
|
|
77637
77784
|
T Change theme R Toggle repo context
|
|
77638
77785
|
H Show history L Clear chat
|
|
77639
|
-
C Show config
|
|
77786
|
+
C Show config K Thinking level
|
|
77787
|
+
? This help
|
|
77640
77788
|
|
|
77641
77789
|
Commands (type ! or / followed by):
|
|
77642
77790
|
help Show this help model Change model
|
|
77643
77791
|
provider Switch provider dry Toggle dry-run
|
|
77644
|
-
config Show configuration
|
|
77645
|
-
clear Clear chat
|
|
77792
|
+
thinking Cycle thinking config Show configuration
|
|
77793
|
+
history Show history clear Clear chat
|
|
77646
77794
|
|
|
77647
77795
|
Safety Levels:
|
|
77648
77796
|
- strict: Confirm ALL potentially dangerous commands
|
|
77649
77797
|
- moderate: Confirm high/critical severity commands (default)
|
|
77650
77798
|
- relaxed: Only confirm critical commands
|
|
77651
77799
|
|
|
77800
|
+
Thinking Levels:
|
|
77801
|
+
- low: Default low-cost reasoning for supported models
|
|
77802
|
+
- medium: More reasoning for harder translations
|
|
77803
|
+
- high: Maximum reasoning for supported models
|
|
77804
|
+
- off: Do not request provider thinking controls
|
|
77805
|
+
|
|
77652
77806
|
Tips:
|
|
77653
77807
|
- Type naturally: "list all files" -> ls -la
|
|
77654
77808
|
- Use ! or / commands: !help or /help
|
|
@@ -77675,6 +77829,7 @@ Theme: ${theme.name}
|
|
|
77675
77829
|
Shell: ${shellInfo.shell} (${shellInfo.shellPath})
|
|
77676
77830
|
Platform: ${shellInfo.platform}${shellInfo.isWSL ? " (WSL)" : ""}
|
|
77677
77831
|
Safety: ${config2.safetyLevel}
|
|
77832
|
+
Thinking: ${config2.thinkingLevel}
|
|
77678
77833
|
Dry-run: ${dryRunMode ? "ON" : "OFF"}
|
|
77679
77834
|
Repo context: ${config2.repoContext ? "ON" : "OFF"}
|
|
77680
77835
|
API Key: ${apiKeyStatus}
|
|
@@ -77914,6 +78069,15 @@ function showThemeSelector() {
|
|
|
77914
78069
|
}
|
|
77915
78070
|
var commandPalette = null;
|
|
77916
78071
|
var chordMode = "none";
|
|
78072
|
+
function cycleThinkingLevel() {
|
|
78073
|
+
const levels = ["low", "medium", "high", "off"];
|
|
78074
|
+
const currentIndex = levels.indexOf(config2.thinkingLevel);
|
|
78075
|
+
const nextIndex = (currentIndex + 1) % levels.length;
|
|
78076
|
+
config2.thinkingLevel = levels[nextIndex];
|
|
78077
|
+
saveConfig(config2);
|
|
78078
|
+
statusBarText.content = getStatusBarContent();
|
|
78079
|
+
addSystemMessage(`Thinking level: ${config2.thinkingLevel}`);
|
|
78080
|
+
}
|
|
77917
78081
|
function getCommandPaletteOptions() {
|
|
77918
78082
|
return [
|
|
77919
78083
|
{
|
|
@@ -77968,6 +78132,13 @@ function getCommandPaletteOptions() {
|
|
|
77968
78132
|
addSystemMessage(`Safety level: ${config2.safetyLevel} (${descriptions[config2.safetyLevel]})`);
|
|
77969
78133
|
}
|
|
77970
78134
|
},
|
|
78135
|
+
{
|
|
78136
|
+
name: "Cycle Thinking Level",
|
|
78137
|
+
description: `Current: ${config2.thinkingLevel}`,
|
|
78138
|
+
key: "k",
|
|
78139
|
+
chord: "k",
|
|
78140
|
+
action: () => cycleThinkingLevel()
|
|
78141
|
+
},
|
|
77971
78142
|
{
|
|
77972
78143
|
name: "Toggle Project Context",
|
|
77973
78144
|
description: config2.repoContext ? "Currently ON (sends script names to AI)" : "Currently OFF",
|
|
@@ -78104,6 +78275,10 @@ function handleKeypress(key) {
|
|
|
78104
78275
|
addSystemMessage(`Safety level: ${config2.safetyLevel} (${descriptions[config2.safetyLevel]})`);
|
|
78105
78276
|
return;
|
|
78106
78277
|
}
|
|
78278
|
+
if (key.ctrl && key.name === "k") {
|
|
78279
|
+
cycleThinkingLevel();
|
|
78280
|
+
return;
|
|
78281
|
+
}
|
|
78107
78282
|
if (key.ctrl && key.name === "z") {
|
|
78108
78283
|
renderer.destroy();
|
|
78109
78284
|
process.exit(0);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@austinthesing/magic-shell",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.20",
|
|
4
4
|
"description": "Natural language to terminal commands with safety features. Supports OpenCode Zen (with free models) and OpenRouter.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|