@austinthesing/magic-shell 0.2.18 → 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 +14 -9
- package/dist/cli.js +640 -183
- package/dist/index.js +1119 -424
- package/dist/tui.js +640 -183
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -36767,15 +36767,6 @@ import { cwd as getCwd } from "process";
|
|
|
36767
36767
|
|
|
36768
36768
|
// src/lib/types.ts
|
|
36769
36769
|
var OPENROUTER_MODELS = [
|
|
36770
|
-
{
|
|
36771
|
-
id: "minimax/minimax-m2.5:free",
|
|
36772
|
-
name: "MiniMax M2.5 Free",
|
|
36773
|
-
description: "Free MiniMax model for trying out open-source generation",
|
|
36774
|
-
category: "smart",
|
|
36775
|
-
provider: "openrouter",
|
|
36776
|
-
contextLength: 196608,
|
|
36777
|
-
free: true
|
|
36778
|
-
},
|
|
36779
36770
|
{
|
|
36780
36771
|
id: "xiaomi/mimo-v2.5",
|
|
36781
36772
|
name: "MiMo V2.5",
|
|
@@ -36808,6 +36799,38 @@ var OPENROUTER_MODELS = [
|
|
|
36808
36799
|
provider: "openrouter",
|
|
36809
36800
|
contextLength: 202752
|
|
36810
36801
|
},
|
|
36802
|
+
{
|
|
36803
|
+
id: "openai/gpt-latest",
|
|
36804
|
+
name: "OpenAI GPT Latest",
|
|
36805
|
+
description: "OpenRouter alias that redirects to the latest OpenAI GPT model",
|
|
36806
|
+
category: "smart",
|
|
36807
|
+
provider: "openrouter",
|
|
36808
|
+
contextLength: 1050000
|
|
36809
|
+
},
|
|
36810
|
+
{
|
|
36811
|
+
id: "openai/gpt-5.5",
|
|
36812
|
+
name: "GPT 5.5",
|
|
36813
|
+
description: "OpenAI's latest flagship GPT model",
|
|
36814
|
+
category: "smart",
|
|
36815
|
+
provider: "openrouter",
|
|
36816
|
+
contextLength: 1050000
|
|
36817
|
+
},
|
|
36818
|
+
{
|
|
36819
|
+
id: "anthropic/claude-sonnet-latest",
|
|
36820
|
+
name: "Claude Sonnet Latest",
|
|
36821
|
+
description: "OpenRouter alias that redirects to the latest Claude Sonnet model",
|
|
36822
|
+
category: "smart",
|
|
36823
|
+
provider: "openrouter",
|
|
36824
|
+
contextLength: 1e6
|
|
36825
|
+
},
|
|
36826
|
+
{
|
|
36827
|
+
id: "anthropic/claude-sonnet-4.6",
|
|
36828
|
+
name: "Claude Sonnet 4.6",
|
|
36829
|
+
description: "Anthropic's latest Sonnet model",
|
|
36830
|
+
category: "smart",
|
|
36831
|
+
provider: "openrouter",
|
|
36832
|
+
contextLength: 1e6
|
|
36833
|
+
},
|
|
36811
36834
|
{
|
|
36812
36835
|
id: "moonshotai/kimi-k2.6",
|
|
36813
36836
|
name: "Kimi K2.6",
|
|
@@ -36840,6 +36863,30 @@ var OPENROUTER_MODELS = [
|
|
|
36840
36863
|
provider: "openrouter",
|
|
36841
36864
|
contextLength: 196608
|
|
36842
36865
|
},
|
|
36866
|
+
{
|
|
36867
|
+
id: "anthropic/claude-opus-latest",
|
|
36868
|
+
name: "Claude Opus Latest",
|
|
36869
|
+
description: "OpenRouter alias that redirects to the latest Claude Opus model",
|
|
36870
|
+
category: "reasoning",
|
|
36871
|
+
provider: "openrouter",
|
|
36872
|
+
contextLength: 1e6
|
|
36873
|
+
},
|
|
36874
|
+
{
|
|
36875
|
+
id: "anthropic/claude-opus-4.7",
|
|
36876
|
+
name: "Claude Opus 4.7",
|
|
36877
|
+
description: "Anthropic's latest Opus model",
|
|
36878
|
+
category: "reasoning",
|
|
36879
|
+
provider: "openrouter",
|
|
36880
|
+
contextLength: 1e6
|
|
36881
|
+
},
|
|
36882
|
+
{
|
|
36883
|
+
id: "openai/gpt-5.5-pro",
|
|
36884
|
+
name: "GPT 5.5 Pro",
|
|
36885
|
+
description: "OpenAI's latest high-capability reasoning model",
|
|
36886
|
+
category: "reasoning",
|
|
36887
|
+
provider: "openrouter",
|
|
36888
|
+
contextLength: 1050000
|
|
36889
|
+
},
|
|
36843
36890
|
{
|
|
36844
36891
|
id: "moonshotai/kimi-k2-thinking",
|
|
36845
36892
|
name: "Kimi K2 Thinking",
|
|
@@ -36849,58 +36896,179 @@ var OPENROUTER_MODELS = [
|
|
|
36849
36896
|
contextLength: 262144
|
|
36850
36897
|
}
|
|
36851
36898
|
];
|
|
36899
|
+
var VERCEL_AI_GATEWAY_MODELS = [
|
|
36900
|
+
{
|
|
36901
|
+
id: "openai/gpt-latest",
|
|
36902
|
+
name: "OpenAI GPT Latest",
|
|
36903
|
+
description: "Vercel AI Gateway alias that redirects to the latest OpenAI GPT model",
|
|
36904
|
+
category: "smart",
|
|
36905
|
+
provider: "vercel-ai-gateway",
|
|
36906
|
+
contextLength: 1050000
|
|
36907
|
+
},
|
|
36908
|
+
{
|
|
36909
|
+
id: "openai/gpt-5.5",
|
|
36910
|
+
name: "GPT 5.5",
|
|
36911
|
+
description: "OpenAI's latest flagship GPT model",
|
|
36912
|
+
category: "smart",
|
|
36913
|
+
provider: "vercel-ai-gateway",
|
|
36914
|
+
contextLength: 1050000
|
|
36915
|
+
},
|
|
36916
|
+
{
|
|
36917
|
+
id: "anthropic/claude-sonnet-4.6",
|
|
36918
|
+
name: "Claude Sonnet 4.6",
|
|
36919
|
+
description: "Anthropic's latest Sonnet model",
|
|
36920
|
+
category: "smart",
|
|
36921
|
+
provider: "vercel-ai-gateway",
|
|
36922
|
+
contextLength: 1e6
|
|
36923
|
+
},
|
|
36924
|
+
{
|
|
36925
|
+
id: "anthropic/claude-opus-4.7",
|
|
36926
|
+
name: "Claude Opus 4.7",
|
|
36927
|
+
description: "Anthropic's latest Opus model",
|
|
36928
|
+
category: "reasoning",
|
|
36929
|
+
provider: "vercel-ai-gateway",
|
|
36930
|
+
contextLength: 1e6
|
|
36931
|
+
},
|
|
36932
|
+
{
|
|
36933
|
+
id: "openai/gpt-5.5-pro",
|
|
36934
|
+
name: "GPT 5.5 Pro",
|
|
36935
|
+
description: "OpenAI's latest high-capability reasoning model",
|
|
36936
|
+
category: "reasoning",
|
|
36937
|
+
provider: "vercel-ai-gateway",
|
|
36938
|
+
contextLength: 1050000
|
|
36939
|
+
}
|
|
36940
|
+
];
|
|
36941
|
+
var CLOUDFLARE_AI_GATEWAY_MODELS = [
|
|
36942
|
+
{
|
|
36943
|
+
id: "openai/gpt-5.5",
|
|
36944
|
+
name: "GPT 5.5",
|
|
36945
|
+
description: "OpenAI's latest flagship GPT model through Cloudflare AI Gateway",
|
|
36946
|
+
category: "smart",
|
|
36947
|
+
provider: "cloudflare-ai-gateway",
|
|
36948
|
+
contextLength: 1050000
|
|
36949
|
+
},
|
|
36950
|
+
{
|
|
36951
|
+
id: "anthropic/claude-sonnet-4-6",
|
|
36952
|
+
name: "Claude Sonnet 4.6",
|
|
36953
|
+
description: "Anthropic's latest Sonnet model through Cloudflare AI Gateway",
|
|
36954
|
+
category: "smart",
|
|
36955
|
+
provider: "cloudflare-ai-gateway",
|
|
36956
|
+
contextLength: 1e6
|
|
36957
|
+
},
|
|
36958
|
+
{
|
|
36959
|
+
id: "anthropic/claude-opus-4-7",
|
|
36960
|
+
name: "Claude Opus 4.7",
|
|
36961
|
+
description: "Anthropic's latest Opus model through Cloudflare AI Gateway",
|
|
36962
|
+
category: "reasoning",
|
|
36963
|
+
provider: "cloudflare-ai-gateway",
|
|
36964
|
+
contextLength: 1e6
|
|
36965
|
+
},
|
|
36966
|
+
{
|
|
36967
|
+
id: "workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast",
|
|
36968
|
+
name: "Workers AI Llama 3.3 70B Fast",
|
|
36969
|
+
description: "Cloudflare Workers AI fast Llama model routed through AI Gateway",
|
|
36970
|
+
category: "smart",
|
|
36971
|
+
provider: "cloudflare-ai-gateway",
|
|
36972
|
+
contextLength: 24000
|
|
36973
|
+
}
|
|
36974
|
+
];
|
|
36975
|
+
var WORKERS_AI_MODELS = [
|
|
36976
|
+
{
|
|
36977
|
+
id: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
|
|
36978
|
+
name: "Llama 3.3 70B Fast",
|
|
36979
|
+
description: "Cloudflare Workers AI fast Llama instruct model",
|
|
36980
|
+
category: "smart",
|
|
36981
|
+
provider: "workers-ai",
|
|
36982
|
+
contextLength: 24000
|
|
36983
|
+
},
|
|
36984
|
+
{
|
|
36985
|
+
id: "@cf/meta/llama-3.1-8b-instruct",
|
|
36986
|
+
name: "Llama 3.1 8B Instruct",
|
|
36987
|
+
description: "Cloudflare Workers AI lightweight Llama instruct model",
|
|
36988
|
+
category: "fast",
|
|
36989
|
+
provider: "workers-ai",
|
|
36990
|
+
contextLength: 8000
|
|
36991
|
+
},
|
|
36992
|
+
{
|
|
36993
|
+
id: "@cf/openai/gpt-oss-120b",
|
|
36994
|
+
name: "GPT OSS 120B",
|
|
36995
|
+
description: "OpenAI open-weight model hosted by Cloudflare Workers AI",
|
|
36996
|
+
category: "reasoning",
|
|
36997
|
+
provider: "workers-ai",
|
|
36998
|
+
contextLength: 32000
|
|
36999
|
+
}
|
|
37000
|
+
];
|
|
36852
37001
|
var OPENCODE_ZEN_MODELS = [
|
|
36853
37002
|
{
|
|
36854
37003
|
id: "minimax-m2.5-free",
|
|
36855
37004
|
name: "MiniMax M2.5 Free",
|
|
36856
37005
|
description: "MiniMax's free model (limited time)",
|
|
36857
|
-
category: "
|
|
37006
|
+
category: "smart",
|
|
36858
37007
|
provider: "opencode-zen",
|
|
36859
37008
|
contextLength: 196608,
|
|
36860
37009
|
free: true
|
|
36861
37010
|
},
|
|
36862
37011
|
{
|
|
36863
|
-
id: "
|
|
36864
|
-
name: "
|
|
36865
|
-
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
|
+
category: "fast",
|
|
37016
|
+
provider: "opencode-zen",
|
|
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)",
|
|
36866
37024
|
category: "smart",
|
|
36867
37025
|
provider: "opencode-zen",
|
|
36868
|
-
contextLength:
|
|
37026
|
+
contextLength: 131072,
|
|
36869
37027
|
free: true
|
|
36870
37028
|
},
|
|
36871
37029
|
{
|
|
36872
|
-
id: "
|
|
36873
|
-
name: "
|
|
36874
|
-
description: "
|
|
36875
|
-
category: "
|
|
37030
|
+
id: "nemotron-3-super-free",
|
|
37031
|
+
name: "Nemotron 3 Super Free",
|
|
37032
|
+
description: "NVIDIA Nemotron free trial model",
|
|
37033
|
+
category: "smart",
|
|
36876
37034
|
provider: "opencode-zen",
|
|
36877
|
-
contextLength:
|
|
37035
|
+
contextLength: 131072,
|
|
36878
37036
|
free: true
|
|
36879
37037
|
},
|
|
36880
37038
|
{
|
|
36881
|
-
id: "
|
|
36882
|
-
name: "
|
|
36883
|
-
description: "
|
|
36884
|
-
category: "
|
|
37039
|
+
id: "trinity-large-preview-free",
|
|
37040
|
+
name: "Trinity Large Preview Free",
|
|
37041
|
+
description: "Trinity large preview model (free, limited time)",
|
|
37042
|
+
category: "smart",
|
|
36885
37043
|
provider: "opencode-zen",
|
|
36886
|
-
contextLength:
|
|
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
|
|
36887
37055
|
},
|
|
36888
37056
|
{
|
|
36889
37057
|
id: "gpt-5-nano",
|
|
36890
37058
|
name: "GPT 5 Nano",
|
|
36891
|
-
description: "OpenAI's
|
|
37059
|
+
description: "OpenAI's free lightweight GPT model",
|
|
36892
37060
|
category: "fast",
|
|
36893
37061
|
provider: "opencode-zen",
|
|
36894
|
-
contextLength:
|
|
37062
|
+
contextLength: 400000,
|
|
36895
37063
|
free: true
|
|
36896
37064
|
},
|
|
36897
37065
|
{
|
|
36898
|
-
id: "
|
|
36899
|
-
name: "
|
|
36900
|
-
description: "
|
|
37066
|
+
id: "mimo-v2.5",
|
|
37067
|
+
name: "MiMo V2.5",
|
|
37068
|
+
description: "Xiaomi's latest long-context MiMo model",
|
|
36901
37069
|
category: "fast",
|
|
36902
37070
|
provider: "opencode-zen",
|
|
36903
|
-
contextLength:
|
|
37071
|
+
contextLength: 1048576
|
|
36904
37072
|
},
|
|
36905
37073
|
{
|
|
36906
37074
|
id: "claude-haiku-4-5",
|
|
@@ -36919,84 +37087,68 @@ var OPENCODE_ZEN_MODELS = [
|
|
|
36919
37087
|
contextLength: 200000
|
|
36920
37088
|
},
|
|
36921
37089
|
{
|
|
36922
|
-
id: "gpt-5.
|
|
36923
|
-
name: "GPT 5.
|
|
36924
|
-
description: "OpenAI's fast
|
|
37090
|
+
id: "gpt-5.4-mini",
|
|
37091
|
+
name: "GPT 5.4 Mini",
|
|
37092
|
+
description: "OpenAI's latest fast GPT mini model",
|
|
36925
37093
|
category: "fast",
|
|
36926
37094
|
provider: "opencode-zen",
|
|
36927
|
-
contextLength:
|
|
37095
|
+
contextLength: 400000
|
|
36928
37096
|
},
|
|
36929
37097
|
{
|
|
36930
|
-
id: "
|
|
36931
|
-
name: "
|
|
36932
|
-
description: "
|
|
37098
|
+
id: "gpt-5.4-nano",
|
|
37099
|
+
name: "GPT 5.4 Nano",
|
|
37100
|
+
description: "OpenAI's latest lightweight GPT model",
|
|
36933
37101
|
category: "fast",
|
|
36934
37102
|
provider: "opencode-zen",
|
|
36935
|
-
contextLength:
|
|
37103
|
+
contextLength: 400000
|
|
36936
37104
|
},
|
|
36937
37105
|
{
|
|
36938
|
-
id: "claude-sonnet-4",
|
|
36939
|
-
name: "Claude Sonnet 4",
|
|
36940
|
-
description: "Anthropic's
|
|
37106
|
+
id: "claude-sonnet-4-6",
|
|
37107
|
+
name: "Claude Sonnet 4.6",
|
|
37108
|
+
description: "Anthropic's latest Sonnet model",
|
|
36941
37109
|
category: "smart",
|
|
36942
37110
|
provider: "opencode-zen",
|
|
36943
|
-
contextLength:
|
|
37111
|
+
contextLength: 1e6
|
|
36944
37112
|
},
|
|
36945
37113
|
{
|
|
36946
|
-
id: "gemini-3-pro",
|
|
36947
|
-
name: "Gemini 3 Pro",
|
|
37114
|
+
id: "gemini-3.1-pro",
|
|
37115
|
+
name: "Gemini 3.1 Pro",
|
|
36948
37116
|
description: "Google's high-end Gemini model",
|
|
36949
37117
|
category: "smart",
|
|
36950
37118
|
provider: "opencode-zen",
|
|
36951
37119
|
contextLength: 200000
|
|
36952
37120
|
},
|
|
36953
37121
|
{
|
|
36954
|
-
id: "gpt-5.
|
|
36955
|
-
name: "GPT 5.
|
|
36956
|
-
description: "OpenAI's flagship GPT model",
|
|
36957
|
-
category: "smart",
|
|
36958
|
-
provider: "opencode-zen",
|
|
36959
|
-
contextLength: 200000
|
|
36960
|
-
},
|
|
36961
|
-
{
|
|
36962
|
-
id: "gpt-5.2-codex",
|
|
36963
|
-
name: "GPT 5.2 Codex",
|
|
36964
|
-
description: "OpenAI's coding-focused GPT model",
|
|
37122
|
+
id: "gpt-5.5",
|
|
37123
|
+
name: "GPT 5.5",
|
|
37124
|
+
description: "OpenAI's latest flagship GPT model",
|
|
36965
37125
|
category: "smart",
|
|
36966
37126
|
provider: "opencode-zen",
|
|
36967
|
-
contextLength:
|
|
37127
|
+
contextLength: 1050000
|
|
36968
37128
|
},
|
|
36969
37129
|
{
|
|
36970
|
-
id: "gpt-5.
|
|
36971
|
-
name: "GPT 5.
|
|
36972
|
-
description: "OpenAI's
|
|
37130
|
+
id: "gpt-5.5-pro",
|
|
37131
|
+
name: "GPT 5.5 Pro",
|
|
37132
|
+
description: "OpenAI's latest high-capability reasoning model",
|
|
36973
37133
|
category: "smart",
|
|
36974
37134
|
provider: "opencode-zen",
|
|
36975
|
-
contextLength:
|
|
36976
|
-
},
|
|
36977
|
-
{
|
|
36978
|
-
id: "gpt-5.1-codex",
|
|
36979
|
-
name: "GPT 5.1 Codex",
|
|
36980
|
-
description: "OpenAI's coding model",
|
|
36981
|
-
category: "smart",
|
|
36982
|
-
provider: "opencode-zen",
|
|
36983
|
-
contextLength: 200000
|
|
37135
|
+
contextLength: 1050000
|
|
36984
37136
|
},
|
|
36985
37137
|
{
|
|
36986
|
-
id: "gpt-5",
|
|
36987
|
-
name: "GPT 5",
|
|
36988
|
-
description: "OpenAI's
|
|
37138
|
+
id: "gpt-5.3-codex",
|
|
37139
|
+
name: "GPT 5.3 Codex",
|
|
37140
|
+
description: "OpenAI's latest coding-focused GPT model",
|
|
36989
37141
|
category: "smart",
|
|
36990
37142
|
provider: "opencode-zen",
|
|
36991
|
-
contextLength:
|
|
37143
|
+
contextLength: 400000
|
|
36992
37144
|
},
|
|
36993
37145
|
{
|
|
36994
|
-
id: "gpt-5-codex",
|
|
36995
|
-
name: "GPT 5 Codex",
|
|
36996
|
-
description: "OpenAI's
|
|
37146
|
+
id: "gpt-5.3-codex-spark",
|
|
37147
|
+
name: "GPT 5.3 Codex Spark",
|
|
37148
|
+
description: "OpenAI's latest fast coding-focused GPT model",
|
|
36997
37149
|
category: "smart",
|
|
36998
37150
|
provider: "opencode-zen",
|
|
36999
|
-
contextLength:
|
|
37151
|
+
contextLength: 400000
|
|
37000
37152
|
},
|
|
37001
37153
|
{
|
|
37002
37154
|
id: "minimax-m2.7",
|
|
@@ -37039,44 +37191,12 @@ var OPENCODE_ZEN_MODELS = [
|
|
|
37039
37191
|
contextLength: 202752
|
|
37040
37192
|
},
|
|
37041
37193
|
{
|
|
37042
|
-
id: "claude-
|
|
37043
|
-
name: "Claude
|
|
37044
|
-
description: "Anthropic's
|
|
37045
|
-
category: "reasoning",
|
|
37046
|
-
provider: "opencode-zen",
|
|
37047
|
-
contextLength: 200000
|
|
37048
|
-
},
|
|
37049
|
-
{
|
|
37050
|
-
id: "claude-opus-4-6",
|
|
37051
|
-
name: "Claude Opus 4.6",
|
|
37052
|
-
description: "Anthropic's newest Opus model",
|
|
37053
|
-
category: "reasoning",
|
|
37054
|
-
provider: "opencode-zen",
|
|
37055
|
-
contextLength: 200000
|
|
37056
|
-
},
|
|
37057
|
-
{
|
|
37058
|
-
id: "claude-opus-4-5",
|
|
37059
|
-
name: "Claude Opus 4.5",
|
|
37060
|
-
description: "Anthropic's most capable model",
|
|
37061
|
-
category: "reasoning",
|
|
37062
|
-
provider: "opencode-zen",
|
|
37063
|
-
contextLength: 200000
|
|
37064
|
-
},
|
|
37065
|
-
{
|
|
37066
|
-
id: "claude-opus-4-1",
|
|
37067
|
-
name: "Claude Opus 4.1",
|
|
37068
|
-
description: "Anthropic's powerful reasoning model",
|
|
37069
|
-
category: "reasoning",
|
|
37070
|
-
provider: "opencode-zen",
|
|
37071
|
-
contextLength: 200000
|
|
37072
|
-
},
|
|
37073
|
-
{
|
|
37074
|
-
id: "gpt-5.1-codex-max",
|
|
37075
|
-
name: "GPT 5.1 Codex Max",
|
|
37076
|
-
description: "OpenAI's largest coding model",
|
|
37194
|
+
id: "claude-opus-4-7",
|
|
37195
|
+
name: "Claude Opus 4.7",
|
|
37196
|
+
description: "Anthropic's latest Opus model",
|
|
37077
37197
|
category: "reasoning",
|
|
37078
37198
|
provider: "opencode-zen",
|
|
37079
|
-
contextLength:
|
|
37199
|
+
contextLength: 1e6
|
|
37080
37200
|
},
|
|
37081
37201
|
{
|
|
37082
37202
|
id: "kimi-k2-thinking",
|
|
@@ -37087,7 +37207,45 @@ var OPENCODE_ZEN_MODELS = [
|
|
|
37087
37207
|
contextLength: 262144
|
|
37088
37208
|
}
|
|
37089
37209
|
];
|
|
37090
|
-
var ALL_MODELS = [
|
|
37210
|
+
var ALL_MODELS = [
|
|
37211
|
+
...OPENCODE_ZEN_MODELS,
|
|
37212
|
+
...OPENROUTER_MODELS,
|
|
37213
|
+
...VERCEL_AI_GATEWAY_MODELS,
|
|
37214
|
+
...CLOUDFLARE_AI_GATEWAY_MODELS,
|
|
37215
|
+
...WORKERS_AI_MODELS
|
|
37216
|
+
];
|
|
37217
|
+
function getProviderModels(provider) {
|
|
37218
|
+
switch (provider) {
|
|
37219
|
+
case "opencode-zen":
|
|
37220
|
+
return OPENCODE_ZEN_MODELS;
|
|
37221
|
+
case "openrouter":
|
|
37222
|
+
return OPENROUTER_MODELS;
|
|
37223
|
+
case "vercel-ai-gateway":
|
|
37224
|
+
return VERCEL_AI_GATEWAY_MODELS;
|
|
37225
|
+
case "cloudflare-ai-gateway":
|
|
37226
|
+
return CLOUDFLARE_AI_GATEWAY_MODELS;
|
|
37227
|
+
case "workers-ai":
|
|
37228
|
+
return WORKERS_AI_MODELS;
|
|
37229
|
+
case "custom":
|
|
37230
|
+
return [];
|
|
37231
|
+
}
|
|
37232
|
+
}
|
|
37233
|
+
function getProviderDisplayName(provider) {
|
|
37234
|
+
switch (provider) {
|
|
37235
|
+
case "opencode-zen":
|
|
37236
|
+
return "OpenCode Zen";
|
|
37237
|
+
case "openrouter":
|
|
37238
|
+
return "OpenRouter";
|
|
37239
|
+
case "vercel-ai-gateway":
|
|
37240
|
+
return "Vercel AI Gateway";
|
|
37241
|
+
case "cloudflare-ai-gateway":
|
|
37242
|
+
return "Cloudflare AI Gateway";
|
|
37243
|
+
case "workers-ai":
|
|
37244
|
+
return "Cloudflare Workers AI";
|
|
37245
|
+
case "custom":
|
|
37246
|
+
return "Custom";
|
|
37247
|
+
}
|
|
37248
|
+
}
|
|
37091
37249
|
function isCustomModel(model) {
|
|
37092
37250
|
return "baseUrl" in model;
|
|
37093
37251
|
}
|
|
@@ -37458,11 +37616,20 @@ var CONFIG_FILE = join4(CONFIG_DIR, "config.json");
|
|
|
37458
37616
|
var HISTORY_FILE = join4(CONFIG_DIR, "history.json");
|
|
37459
37617
|
var KEYCHAIN_OPENROUTER = "openrouter-api-key";
|
|
37460
37618
|
var KEYCHAIN_OPENCODE_ZEN = "opencode-zen-api-key";
|
|
37619
|
+
var KEYCHAIN_VERCEL_AI_GATEWAY = "vercel-ai-gateway-api-key";
|
|
37620
|
+
var KEYCHAIN_CLOUDFLARE_AI_GATEWAY = "cloudflare-ai-gateway-api-key";
|
|
37621
|
+
var KEYCHAIN_WORKERS_AI = "workers-ai-api-key";
|
|
37461
37622
|
var DEFAULT_CONFIG = {
|
|
37462
37623
|
provider: "opencode-zen",
|
|
37463
37624
|
openrouterApiKey: "",
|
|
37464
37625
|
opencodeZenApiKey: "",
|
|
37465
|
-
|
|
37626
|
+
vercelAiGatewayApiKey: "",
|
|
37627
|
+
cloudflareAiGatewayApiKey: "",
|
|
37628
|
+
workersAiApiKey: "",
|
|
37629
|
+
cloudflareAccountId: "",
|
|
37630
|
+
cloudflareAiGatewayId: "default",
|
|
37631
|
+
defaultModel: "minimax-m2.5-free",
|
|
37632
|
+
thinkingLevel: "low",
|
|
37466
37633
|
safetyLevel: "moderate",
|
|
37467
37634
|
dryRunByDefault: false,
|
|
37468
37635
|
blockedCommands: [
|
|
@@ -37501,6 +37668,9 @@ function saveConfig(config) {
|
|
|
37501
37668
|
if (isSecureStorageAvailable()) {
|
|
37502
37669
|
configToSave.openrouterApiKey = "";
|
|
37503
37670
|
configToSave.opencodeZenApiKey = "";
|
|
37671
|
+
configToSave.vercelAiGatewayApiKey = "";
|
|
37672
|
+
configToSave.cloudflareAiGatewayApiKey = "";
|
|
37673
|
+
configToSave.workersAiApiKey = "";
|
|
37504
37674
|
}
|
|
37505
37675
|
writeFileSync2(CONFIG_FILE, JSON.stringify(configToSave, null, 2));
|
|
37506
37676
|
}
|
|
@@ -37513,28 +37683,83 @@ async function getApiKey(provider) {
|
|
|
37513
37683
|
const envKey = process.env.OPENCODE_ZEN_API_KEY;
|
|
37514
37684
|
if (envKey)
|
|
37515
37685
|
return envKey;
|
|
37686
|
+
} else if (provider === "vercel-ai-gateway") {
|
|
37687
|
+
const envKey = process.env.AI_GATEWAY_API_KEY || process.env.VERCEL_AI_GATEWAY_API_KEY;
|
|
37688
|
+
if (envKey)
|
|
37689
|
+
return envKey;
|
|
37690
|
+
} else if (provider === "cloudflare-ai-gateway") {
|
|
37691
|
+
const envKey = process.env.CLOUDFLARE_AI_GATEWAY_API_KEY || process.env.CF_AIG_TOKEN;
|
|
37692
|
+
if (envKey)
|
|
37693
|
+
return envKey;
|
|
37694
|
+
} else if (provider === "workers-ai") {
|
|
37695
|
+
const envKey = process.env.CLOUDFLARE_API_TOKEN || process.env.CLOUDFLARE_API_KEY;
|
|
37696
|
+
if (envKey)
|
|
37697
|
+
return envKey;
|
|
37516
37698
|
}
|
|
37517
|
-
const keychainKey = provider
|
|
37699
|
+
const keychainKey = getKeychainKey(provider);
|
|
37518
37700
|
const secureKey = await getSecret(keychainKey);
|
|
37519
37701
|
if (secureKey)
|
|
37520
37702
|
return secureKey;
|
|
37521
37703
|
const config = loadConfig2();
|
|
37522
|
-
|
|
37704
|
+
switch (provider) {
|
|
37705
|
+
case "openrouter":
|
|
37706
|
+
return config.openrouterApiKey;
|
|
37707
|
+
case "opencode-zen":
|
|
37708
|
+
return config.opencodeZenApiKey;
|
|
37709
|
+
case "vercel-ai-gateway":
|
|
37710
|
+
return config.vercelAiGatewayApiKey || "";
|
|
37711
|
+
case "cloudflare-ai-gateway":
|
|
37712
|
+
return config.cloudflareAiGatewayApiKey || "";
|
|
37713
|
+
case "workers-ai":
|
|
37714
|
+
return config.workersAiApiKey || "";
|
|
37715
|
+
case "custom":
|
|
37716
|
+
return "";
|
|
37717
|
+
}
|
|
37523
37718
|
}
|
|
37524
37719
|
async function setApiKey(provider, key) {
|
|
37525
37720
|
const config = loadConfig2();
|
|
37526
37721
|
config.provider = provider;
|
|
37527
|
-
const keychainKey = provider
|
|
37722
|
+
const keychainKey = getKeychainKey(provider);
|
|
37528
37723
|
const stored = await setSecret(keychainKey, key);
|
|
37529
37724
|
if (!stored) {
|
|
37530
|
-
|
|
37531
|
-
|
|
37532
|
-
|
|
37533
|
-
|
|
37725
|
+
switch (provider) {
|
|
37726
|
+
case "openrouter":
|
|
37727
|
+
config.openrouterApiKey = key;
|
|
37728
|
+
break;
|
|
37729
|
+
case "opencode-zen":
|
|
37730
|
+
config.opencodeZenApiKey = key;
|
|
37731
|
+
break;
|
|
37732
|
+
case "vercel-ai-gateway":
|
|
37733
|
+
config.vercelAiGatewayApiKey = key;
|
|
37734
|
+
break;
|
|
37735
|
+
case "cloudflare-ai-gateway":
|
|
37736
|
+
config.cloudflareAiGatewayApiKey = key;
|
|
37737
|
+
break;
|
|
37738
|
+
case "workers-ai":
|
|
37739
|
+
config.workersAiApiKey = key;
|
|
37740
|
+
break;
|
|
37741
|
+
case "custom":
|
|
37742
|
+
break;
|
|
37534
37743
|
}
|
|
37535
37744
|
}
|
|
37536
37745
|
saveConfig(config);
|
|
37537
37746
|
}
|
|
37747
|
+
function getKeychainKey(provider) {
|
|
37748
|
+
switch (provider) {
|
|
37749
|
+
case "openrouter":
|
|
37750
|
+
return KEYCHAIN_OPENROUTER;
|
|
37751
|
+
case "opencode-zen":
|
|
37752
|
+
return KEYCHAIN_OPENCODE_ZEN;
|
|
37753
|
+
case "vercel-ai-gateway":
|
|
37754
|
+
return KEYCHAIN_VERCEL_AI_GATEWAY;
|
|
37755
|
+
case "cloudflare-ai-gateway":
|
|
37756
|
+
return KEYCHAIN_CLOUDFLARE_AI_GATEWAY;
|
|
37757
|
+
case "workers-ai":
|
|
37758
|
+
return KEYCHAIN_WORKERS_AI;
|
|
37759
|
+
case "custom":
|
|
37760
|
+
return "custom-api-key";
|
|
37761
|
+
}
|
|
37762
|
+
}
|
|
37538
37763
|
function loadHistory() {
|
|
37539
37764
|
ensureConfigDir();
|
|
37540
37765
|
if (!existsSync3(HISTORY_FILE)) {
|
|
@@ -76080,9 +76305,6 @@ function formatRepoContext(context2) {
|
|
|
76080
76305
|
|
|
76081
76306
|
// src/lib/api.ts
|
|
76082
76307
|
function getZenApiType(modelId) {
|
|
76083
|
-
if (modelId === "minimax-m2.5-free") {
|
|
76084
|
-
return "anthropic";
|
|
76085
|
-
}
|
|
76086
76308
|
if (modelId.startsWith("gpt-")) {
|
|
76087
76309
|
return "openai-responses";
|
|
76088
76310
|
}
|
|
@@ -76176,7 +76398,94 @@ function cleanCommand(command) {
|
|
|
76176
76398
|
}
|
|
76177
76399
|
return cleaned.trim();
|
|
76178
76400
|
}
|
|
76179
|
-
|
|
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 };
|
|
76180
76489
|
const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
|
|
76181
76490
|
method: "POST",
|
|
76182
76491
|
headers: {
|
|
@@ -76192,7 +76501,8 @@ async function callOpenRouter(apiKey, modelId, systemPrompt, userInput) {
|
|
|
76192
76501
|
{ role: "user", content: userInput }
|
|
76193
76502
|
],
|
|
76194
76503
|
max_tokens: 500,
|
|
76195
|
-
|
|
76504
|
+
...temperatureOptions,
|
|
76505
|
+
...thinkingOptions
|
|
76196
76506
|
})
|
|
76197
76507
|
});
|
|
76198
76508
|
if (!response.ok) {
|
|
@@ -76212,18 +76522,99 @@ async function callOpenRouter(apiKey, modelId, systemPrompt, userInput) {
|
|
|
76212
76522
|
}
|
|
76213
76523
|
return data.choices[0]?.message?.content?.trim() || "";
|
|
76214
76524
|
}
|
|
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 };
|
|
76528
|
+
const requestHeaders = {
|
|
76529
|
+
"Content-Type": "application/json",
|
|
76530
|
+
...headers
|
|
76531
|
+
};
|
|
76532
|
+
if (includeAuthorization) {
|
|
76533
|
+
requestHeaders.Authorization = `Bearer ${apiKey}`;
|
|
76534
|
+
}
|
|
76535
|
+
const response = await fetch(`${baseURL.replace(/\/$/, "")}/chat/completions`, {
|
|
76536
|
+
method: "POST",
|
|
76537
|
+
headers: requestHeaders,
|
|
76538
|
+
body: JSON.stringify({
|
|
76539
|
+
model: modelId,
|
|
76540
|
+
messages: [
|
|
76541
|
+
{ role: "system", content: systemPrompt },
|
|
76542
|
+
{ role: "user", content: userInput }
|
|
76543
|
+
],
|
|
76544
|
+
max_tokens: 500,
|
|
76545
|
+
stream: false,
|
|
76546
|
+
...temperatureOptions,
|
|
76547
|
+
...thinkingOptions
|
|
76548
|
+
})
|
|
76549
|
+
});
|
|
76550
|
+
if (!response.ok) {
|
|
76551
|
+
const errorText = await response.text();
|
|
76552
|
+
let errorMessage = `API request failed: ${response.status}`;
|
|
76553
|
+
try {
|
|
76554
|
+
const errorData = JSON.parse(errorText);
|
|
76555
|
+
if (errorData.error?.message) {
|
|
76556
|
+
errorMessage = errorData.error.message;
|
|
76557
|
+
} else if (errorData.errors?.[0]?.message) {
|
|
76558
|
+
errorMessage = errorData.errors[0].message;
|
|
76559
|
+
}
|
|
76560
|
+
} catch {}
|
|
76561
|
+
throw new Error(errorMessage);
|
|
76562
|
+
}
|
|
76563
|
+
const data = await response.json();
|
|
76564
|
+
if (data.error) {
|
|
76565
|
+
throw new Error(data.error.message);
|
|
76566
|
+
}
|
|
76567
|
+
if (data.errors?.[0]?.message) {
|
|
76568
|
+
throw new Error(data.errors[0].message);
|
|
76569
|
+
}
|
|
76570
|
+
const choices = data.choices || data.result?.choices;
|
|
76571
|
+
return choices?.[0]?.message?.content?.trim() || "";
|
|
76572
|
+
}
|
|
76573
|
+
function getCloudflareAccountId(config2) {
|
|
76574
|
+
return config2.cloudflareAccountId || process.env.CLOUDFLARE_ACCOUNT_ID || process.env.CF_ACCOUNT_ID || "";
|
|
76575
|
+
}
|
|
76576
|
+
function getCloudflareGatewayId(config2) {
|
|
76577
|
+
return config2.cloudflareAiGatewayId || process.env.CLOUDFLARE_AI_GATEWAY_ID || process.env.CF_AIG_GATEWAY_ID || "default";
|
|
76578
|
+
}
|
|
76579
|
+
async function callGatewayProvider(provider, apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
|
|
76580
|
+
const config2 = loadConfig2();
|
|
76581
|
+
switch (provider) {
|
|
76582
|
+
case "vercel-ai-gateway":
|
|
76583
|
+
return await callOpenAICompatibleFetch("https://ai-gateway.vercel.sh/v1", apiKey, modelId, systemPrompt, userInput, thinkingLevel);
|
|
76584
|
+
case "cloudflare-ai-gateway": {
|
|
76585
|
+
const accountId = getCloudflareAccountId(config2);
|
|
76586
|
+
if (!accountId) {
|
|
76587
|
+
throw new Error("Cloudflare account ID is required. Set cloudflareAccountId in config or CLOUDFLARE_ACCOUNT_ID.");
|
|
76588
|
+
}
|
|
76589
|
+
const gatewayId = getCloudflareGatewayId(config2);
|
|
76590
|
+
return await callOpenAICompatibleFetch(`https://gateway.ai.cloudflare.com/v1/${accountId}/${gatewayId}/compat`, apiKey, modelId, systemPrompt, userInput, thinkingLevel, { "cf-aig-authorization": `Bearer ${apiKey}` }, false);
|
|
76591
|
+
}
|
|
76592
|
+
case "workers-ai": {
|
|
76593
|
+
const accountId = getCloudflareAccountId(config2);
|
|
76594
|
+
if (!accountId) {
|
|
76595
|
+
throw new Error("Cloudflare account ID is required. Set cloudflareAccountId in config or CLOUDFLARE_ACCOUNT_ID.");
|
|
76596
|
+
}
|
|
76597
|
+
return await callOpenAICompatibleFetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/v1`, apiKey, modelId, systemPrompt, userInput, thinkingLevel);
|
|
76598
|
+
}
|
|
76599
|
+
default:
|
|
76600
|
+
throw new Error(`Unsupported gateway provider: ${provider}`);
|
|
76601
|
+
}
|
|
76602
|
+
}
|
|
76215
76603
|
var DEBUG_API = process.env.DEBUG_API === "1";
|
|
76216
|
-
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 };
|
|
76217
76607
|
const { text: text2 } = await generateText({
|
|
76218
76608
|
model,
|
|
76219
76609
|
system: systemPrompt,
|
|
76220
76610
|
prompt: userInput,
|
|
76221
76611
|
maxOutputTokens: 500,
|
|
76222
|
-
|
|
76612
|
+
...temperatureOptions,
|
|
76613
|
+
...providerOptions ? { providerOptions } : {}
|
|
76223
76614
|
});
|
|
76224
76615
|
return text2.trim();
|
|
76225
76616
|
}
|
|
76226
|
-
async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput) {
|
|
76617
|
+
async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
|
|
76227
76618
|
if (DEBUG_API) {
|
|
76228
76619
|
console.error(`[DEBUG] Calling OpenAI Responses API`);
|
|
76229
76620
|
console.error(`[DEBUG] Model: ${modelId}`);
|
|
@@ -76234,7 +76625,7 @@ async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput)
|
|
|
76234
76625
|
baseURL: ZEN_BASE_URL
|
|
76235
76626
|
});
|
|
76236
76627
|
try {
|
|
76237
|
-
return await generateZenText(openai2(modelId), systemPrompt, userInput);
|
|
76628
|
+
return await generateZenText(openai2(modelId), modelId, systemPrompt, userInput, thinkingLevel);
|
|
76238
76629
|
} catch (error40) {
|
|
76239
76630
|
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
76240
76631
|
if (DEBUG_API) {
|
|
@@ -76243,7 +76634,7 @@ async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput)
|
|
|
76243
76634
|
throw new Error(message);
|
|
76244
76635
|
}
|
|
76245
76636
|
}
|
|
76246
|
-
async function callZenAnthropic(apiKey, modelId, systemPrompt, userInput) {
|
|
76637
|
+
async function callZenAnthropic(apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
|
|
76247
76638
|
if (DEBUG_API) {
|
|
76248
76639
|
console.error(`[DEBUG] Calling Anthropic Messages API`);
|
|
76249
76640
|
console.error(`[DEBUG] Model: ${modelId}`);
|
|
@@ -76254,7 +76645,7 @@ async function callZenAnthropic(apiKey, modelId, systemPrompt, userInput) {
|
|
|
76254
76645
|
baseURL: ZEN_BASE_URL
|
|
76255
76646
|
});
|
|
76256
76647
|
try {
|
|
76257
|
-
return await generateZenText(anthropic2(modelId), systemPrompt, userInput);
|
|
76648
|
+
return await generateZenText(anthropic2(modelId), modelId, systemPrompt, userInput, thinkingLevel);
|
|
76258
76649
|
} catch (error40) {
|
|
76259
76650
|
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
76260
76651
|
if (DEBUG_API) {
|
|
@@ -76263,7 +76654,7 @@ async function callZenAnthropic(apiKey, modelId, systemPrompt, userInput) {
|
|
|
76263
76654
|
throw new Error(message);
|
|
76264
76655
|
}
|
|
76265
76656
|
}
|
|
76266
|
-
async function callZenOpenAICompatible(apiKey, modelId, systemPrompt, userInput) {
|
|
76657
|
+
async function callZenOpenAICompatible(apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
|
|
76267
76658
|
if (DEBUG_API) {
|
|
76268
76659
|
console.error(`[DEBUG] Calling OpenAI-compatible Chat Completions API`);
|
|
76269
76660
|
console.error(`[DEBUG] Model: ${modelId}`);
|
|
@@ -76274,7 +76665,7 @@ async function callZenOpenAICompatible(apiKey, modelId, systemPrompt, userInput)
|
|
|
76274
76665
|
baseURL: ZEN_BASE_URL
|
|
76275
76666
|
});
|
|
76276
76667
|
try {
|
|
76277
|
-
return await generateZenText(openaiCompatible(modelId), systemPrompt, userInput);
|
|
76668
|
+
return await generateZenText(openaiCompatible(modelId), modelId, systemPrompt, userInput, thinkingLevel, "opencodeZen");
|
|
76278
76669
|
} catch (error40) {
|
|
76279
76670
|
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
76280
76671
|
if (DEBUG_API) {
|
|
@@ -76283,7 +76674,7 @@ async function callZenOpenAICompatible(apiKey, modelId, systemPrompt, userInput)
|
|
|
76283
76674
|
throw new Error(message);
|
|
76284
76675
|
}
|
|
76285
76676
|
}
|
|
76286
|
-
async function callCustomModel(model, systemPrompt, userInput) {
|
|
76677
|
+
async function callCustomModel(model, systemPrompt, userInput, thinkingLevel) {
|
|
76287
76678
|
if (DEBUG_API) {
|
|
76288
76679
|
console.error(`[DEBUG] Calling Custom Model`);
|
|
76289
76680
|
console.error(`[DEBUG] Model: ${model.modelId}`);
|
|
@@ -76295,7 +76686,7 @@ async function callCustomModel(model, systemPrompt, userInput) {
|
|
|
76295
76686
|
baseURL: model.baseUrl
|
|
76296
76687
|
});
|
|
76297
76688
|
try {
|
|
76298
|
-
return await generateZenText(openaiCompatible(model.modelId), systemPrompt, userInput);
|
|
76689
|
+
return await generateZenText(openaiCompatible(model.modelId), model.modelId, systemPrompt, userInput, thinkingLevel, "custom");
|
|
76299
76690
|
} catch (error40) {
|
|
76300
76691
|
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
76301
76692
|
if (DEBUG_API) {
|
|
@@ -76304,7 +76695,7 @@ async function callCustomModel(model, systemPrompt, userInput) {
|
|
|
76304
76695
|
throw new Error(message);
|
|
76305
76696
|
}
|
|
76306
76697
|
}
|
|
76307
|
-
async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
|
|
76698
|
+
async function callZenGoogle(apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
|
|
76308
76699
|
if (DEBUG_API) {
|
|
76309
76700
|
console.error(`[DEBUG] Calling Google Gemini API`);
|
|
76310
76701
|
console.error(`[DEBUG] Model: ${modelId}`);
|
|
@@ -76314,7 +76705,7 @@ async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
|
|
|
76314
76705
|
baseURL: `https://opencode.ai/zen/v1/models/${modelId}`
|
|
76315
76706
|
});
|
|
76316
76707
|
try {
|
|
76317
|
-
return await generateZenText(google2(modelId), systemPrompt, userInput);
|
|
76708
|
+
return await generateZenText(google2(modelId), modelId, systemPrompt, userInput, thinkingLevel);
|
|
76318
76709
|
} catch (error40) {
|
|
76319
76710
|
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
76320
76711
|
if (DEBUG_API) {
|
|
@@ -76330,28 +76721,31 @@ function getShellInfo() {
|
|
|
76330
76721
|
}
|
|
76331
76722
|
return cachedShellInfo;
|
|
76332
76723
|
}
|
|
76333
|
-
async function translateToCommand(apiKey, model, userInput, cwd, history = [], repoContextEnabled) {
|
|
76724
|
+
async function translateToCommand(apiKey, model, userInput, cwd, history = [], repoContextEnabled, config2) {
|
|
76334
76725
|
const shellInfo = getShellInfo();
|
|
76335
76726
|
const systemPrompt = buildSystemPrompt(cwd, history, shellInfo, repoContextEnabled);
|
|
76727
|
+
const thinkingLevel = getThinkingLevel(config2);
|
|
76336
76728
|
let rawCommand;
|
|
76337
76729
|
if (isCustomModel(model)) {
|
|
76338
|
-
rawCommand = await callCustomModel(model, systemPrompt, userInput);
|
|
76730
|
+
rawCommand = await callCustomModel(model, systemPrompt, userInput, "off");
|
|
76339
76731
|
} else if (model.provider === "openrouter") {
|
|
76340
|
-
rawCommand = await callOpenRouter(apiKey, model.id, systemPrompt, userInput);
|
|
76732
|
+
rawCommand = await callOpenRouter(apiKey, model.id, systemPrompt, userInput, thinkingLevel);
|
|
76733
|
+
} else if (model.provider === "vercel-ai-gateway" || model.provider === "cloudflare-ai-gateway" || model.provider === "workers-ai") {
|
|
76734
|
+
rawCommand = await callGatewayProvider(model.provider, apiKey, model.id, systemPrompt, userInput, thinkingLevel);
|
|
76341
76735
|
} else {
|
|
76342
76736
|
const apiType = getZenApiType(model.id);
|
|
76343
76737
|
switch (apiType) {
|
|
76344
76738
|
case "openai-responses":
|
|
76345
|
-
rawCommand = await callZenOpenAIResponses(apiKey, model.id, systemPrompt, userInput);
|
|
76739
|
+
rawCommand = await callZenOpenAIResponses(apiKey, model.id, systemPrompt, userInput, thinkingLevel);
|
|
76346
76740
|
break;
|
|
76347
76741
|
case "anthropic":
|
|
76348
|
-
rawCommand = await callZenAnthropic(apiKey, model.id, systemPrompt, userInput);
|
|
76742
|
+
rawCommand = await callZenAnthropic(apiKey, model.id, systemPrompt, userInput, thinkingLevel);
|
|
76349
76743
|
break;
|
|
76350
76744
|
case "google":
|
|
76351
|
-
rawCommand = await callZenGoogle(apiKey, model.id, systemPrompt, userInput);
|
|
76745
|
+
rawCommand = await callZenGoogle(apiKey, model.id, systemPrompt, userInput, thinkingLevel);
|
|
76352
76746
|
break;
|
|
76353
76747
|
case "openai-compatible":
|
|
76354
|
-
rawCommand = await callZenOpenAICompatible(apiKey, model.id, systemPrompt, userInput);
|
|
76748
|
+
rawCommand = await callZenOpenAICompatible(apiKey, model.id, systemPrompt, userInput, thinkingLevel);
|
|
76355
76749
|
break;
|
|
76356
76750
|
}
|
|
76357
76751
|
}
|
|
@@ -76570,6 +76964,22 @@ var statusBarText;
|
|
|
76570
76964
|
var chatScrollBox;
|
|
76571
76965
|
var inputField;
|
|
76572
76966
|
var inputContainer;
|
|
76967
|
+
function getApiKeyUrl(provider) {
|
|
76968
|
+
switch (provider) {
|
|
76969
|
+
case "opencode-zen":
|
|
76970
|
+
return "https://opencode.ai/auth";
|
|
76971
|
+
case "openrouter":
|
|
76972
|
+
return "https://openrouter.ai/keys";
|
|
76973
|
+
case "vercel-ai-gateway":
|
|
76974
|
+
return "https://vercel.com/docs/ai-gateway";
|
|
76975
|
+
case "cloudflare-ai-gateway":
|
|
76976
|
+
return "https://developers.cloudflare.com/ai-gateway/";
|
|
76977
|
+
case "workers-ai":
|
|
76978
|
+
return "https://dash.cloudflare.com/profile/api-tokens";
|
|
76979
|
+
case "custom":
|
|
76980
|
+
return "";
|
|
76981
|
+
}
|
|
76982
|
+
}
|
|
76573
76983
|
var inputHintText;
|
|
76574
76984
|
var helpBarText;
|
|
76575
76985
|
var modelSelector = null;
|
|
@@ -76640,12 +77050,27 @@ async function showProviderSetup() {
|
|
|
76640
77050
|
name: "OpenRouter",
|
|
76641
77051
|
description: "Access to many models from various providers",
|
|
76642
77052
|
value: "openrouter"
|
|
77053
|
+
},
|
|
77054
|
+
{
|
|
77055
|
+
name: "Vercel AI Gateway",
|
|
77056
|
+
description: "Unified model gateway using AI_GATEWAY_API_KEY",
|
|
77057
|
+
value: "vercel-ai-gateway"
|
|
77058
|
+
},
|
|
77059
|
+
{
|
|
77060
|
+
name: "Cloudflare AI Gateway",
|
|
77061
|
+
description: "Cloudflare gateway for provider and Workers AI models",
|
|
77062
|
+
value: "cloudflare-ai-gateway"
|
|
77063
|
+
},
|
|
77064
|
+
{
|
|
77065
|
+
name: "Cloudflare Workers AI",
|
|
77066
|
+
description: "Cloudflare-hosted models via Workers AI",
|
|
77067
|
+
value: "workers-ai"
|
|
76643
77068
|
}
|
|
76644
77069
|
];
|
|
76645
77070
|
providerSelector = new SelectRenderable(renderer, {
|
|
76646
77071
|
id: "provider-select",
|
|
76647
77072
|
width: 60,
|
|
76648
|
-
height:
|
|
77073
|
+
height: 10,
|
|
76649
77074
|
options,
|
|
76650
77075
|
backgroundColor: "#1e293b",
|
|
76651
77076
|
focusedBackgroundColor: "#1e293b",
|
|
@@ -76692,11 +77117,11 @@ async function showApiKeyInput(provider) {
|
|
|
76692
77117
|
renderer.root.add(container);
|
|
76693
77118
|
const title = new TextRenderable(renderer, {
|
|
76694
77119
|
id: "apikey-title",
|
|
76695
|
-
content: t`${bold(fg("#60a5fa")(`${provider
|
|
77120
|
+
content: t`${bold(fg("#60a5fa")(`${getProviderDisplayName(provider)} Setup`))}`,
|
|
76696
77121
|
marginBottom: 1
|
|
76697
77122
|
});
|
|
76698
77123
|
container.add(title);
|
|
76699
|
-
const url2 = provider
|
|
77124
|
+
const url2 = getApiKeyUrl(provider);
|
|
76700
77125
|
const instructions = new TextRenderable(renderer, {
|
|
76701
77126
|
id: "apikey-instructions",
|
|
76702
77127
|
content: t`Get your API key from: ${fg("#22c55e")(url2)}
|
|
@@ -76708,7 +77133,7 @@ Enter your API key below:`,
|
|
|
76708
77133
|
const input = new InputRenderable(renderer, {
|
|
76709
77134
|
id: "api-key-input",
|
|
76710
77135
|
width: 70,
|
|
76711
|
-
placeholder: provider === "
|
|
77136
|
+
placeholder: provider === "openrouter" ? "sk-or-v1-..." : "API key or token",
|
|
76712
77137
|
backgroundColor: "#1e293b",
|
|
76713
77138
|
focusedBackgroundColor: "#334155",
|
|
76714
77139
|
textColor: "#f8fafc",
|
|
@@ -76734,11 +77159,8 @@ ${fg("#64748b")("Press Enter to save | Ctrl+C to exit")}`,
|
|
|
76734
77159
|
input.on(InputRenderableEvents.ENTER, (value) => {
|
|
76735
77160
|
if (value.trim()) {
|
|
76736
77161
|
setApiKey(provider, value.trim());
|
|
76737
|
-
|
|
76738
|
-
|
|
76739
|
-
} else {
|
|
76740
|
-
currentModel = OPENROUTER_MODELS[0];
|
|
76741
|
-
}
|
|
77162
|
+
const providerModels = getProviderModels(provider);
|
|
77163
|
+
currentModel = providerModels.find((m2) => !m2.disabled) || providerModels[0] || OPENCODE_ZEN_MODELS[0];
|
|
76742
77164
|
config2.defaultModel = currentModel.id;
|
|
76743
77165
|
saveConfig(config2);
|
|
76744
77166
|
renderer.root.remove("apikey-container");
|
|
@@ -76856,26 +77278,27 @@ function createMainUI() {
|
|
|
76856
77278
|
}
|
|
76857
77279
|
function getStatusBarContent() {
|
|
76858
77280
|
const theme = getTheme();
|
|
76859
|
-
const providerName = config2.provider
|
|
77281
|
+
const providerName = getProviderDisplayName(config2.provider);
|
|
76860
77282
|
const safeModeIndicator = dryRunMode ? fg(theme.colors.warning)("[DRY RUN]") : "";
|
|
76861
77283
|
const safetyLevelColor = config2.safetyLevel === "strict" ? theme.colors.warning : config2.safetyLevel === "relaxed" ? theme.colors.error : theme.colors.success;
|
|
76862
77284
|
const safetyIndicator = fg(safetyLevelColor)(`[${config2.safetyLevel}]`);
|
|
77285
|
+
const thinkingIndicator = config2.thinkingLevel !== "off" ? fg(theme.colors.secondary)(`[Think:${config2.thinkingLevel}]`) : "";
|
|
76863
77286
|
const repoContextIndicator = config2.repoContext ? fg(theme.colors.info)("[Repo]") : "";
|
|
76864
|
-
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}`;
|
|
76865
77288
|
}
|
|
76866
77289
|
function getHelpBarContent() {
|
|
76867
77290
|
const theme = getTheme();
|
|
76868
77291
|
if (awaitingConfirmation) {
|
|
76869
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")}`;
|
|
76870
77293
|
}
|
|
76871
|
-
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")}`;
|
|
76872
77295
|
}
|
|
76873
77296
|
function getInputHintContent() {
|
|
76874
77297
|
const theme = getTheme();
|
|
76875
77298
|
return t`${fg(theme.colors.primary)("Enter")} ${fg(theme.colors.textMuted)("to send")}`;
|
|
76876
77299
|
}
|
|
76877
77300
|
function getWelcomeMessage() {
|
|
76878
|
-
const providerName = config2.provider
|
|
77301
|
+
const providerName = getProviderDisplayName(config2.provider);
|
|
76879
77302
|
return `Ready. Using ${providerName}.
|
|
76880
77303
|
Type what you want to do, or press Ctrl+X P for command palette.`;
|
|
76881
77304
|
}
|
|
@@ -77191,7 +77614,7 @@ async function translateAndProcess(input) {
|
|
|
77191
77614
|
}
|
|
77192
77615
|
const loadingMsg = addSystemMessage("Translating...");
|
|
77193
77616
|
try {
|
|
77194
|
-
const command = await translateToCommand(apiKey, currentModel, input, currentCwd, history, config2.repoContext);
|
|
77617
|
+
const command = await translateToCommand(apiKey, currentModel, input, currentCwd, history, config2.repoContext, config2);
|
|
77195
77618
|
chatScrollBox.remove(`msg-${loadingMsg.id}`);
|
|
77196
77619
|
chatMessages = chatMessages.filter((m2) => m2.id !== loadingMsg.id);
|
|
77197
77620
|
const safety = analyzeCommand(command, config2);
|
|
@@ -77321,6 +77744,10 @@ async function handleSpecialCommand(input) {
|
|
|
77321
77744
|
statusBarText.content = getStatusBarContent();
|
|
77322
77745
|
addSystemMessage(`Dry-run mode: ${dryRunMode ? "ON" : "OFF"}`);
|
|
77323
77746
|
break;
|
|
77747
|
+
case "thinking":
|
|
77748
|
+
case "think":
|
|
77749
|
+
cycleThinkingLevel();
|
|
77750
|
+
break;
|
|
77324
77751
|
case "config":
|
|
77325
77752
|
await showConfig();
|
|
77326
77753
|
break;
|
|
@@ -77347,6 +77774,7 @@ function clearChat() {
|
|
|
77347
77774
|
function showHelp() {
|
|
77348
77775
|
const helpText = `Direct Shortcuts:
|
|
77349
77776
|
Ctrl+Y Cycle safety level (strict/moderate/relaxed)
|
|
77777
|
+
Ctrl+K Cycle thinking level (low/medium/high/off)
|
|
77350
77778
|
Ctrl+Z Exit magic-shell
|
|
77351
77779
|
Ctrl+C Cancel / Close popup
|
|
77352
77780
|
|
|
@@ -77355,19 +77783,26 @@ P Command palette M Change model
|
|
|
77355
77783
|
S Switch provider D Toggle dry-run
|
|
77356
77784
|
T Change theme R Toggle repo context
|
|
77357
77785
|
H Show history L Clear chat
|
|
77358
|
-
C Show config
|
|
77786
|
+
C Show config K Thinking level
|
|
77787
|
+
? This help
|
|
77359
77788
|
|
|
77360
77789
|
Commands (type ! or / followed by):
|
|
77361
77790
|
help Show this help model Change model
|
|
77362
77791
|
provider Switch provider dry Toggle dry-run
|
|
77363
|
-
config Show configuration
|
|
77364
|
-
clear Clear chat
|
|
77792
|
+
thinking Cycle thinking config Show configuration
|
|
77793
|
+
history Show history clear Clear chat
|
|
77365
77794
|
|
|
77366
77795
|
Safety Levels:
|
|
77367
77796
|
- strict: Confirm ALL potentially dangerous commands
|
|
77368
77797
|
- moderate: Confirm high/critical severity commands (default)
|
|
77369
77798
|
- relaxed: Only confirm critical commands
|
|
77370
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
|
+
|
|
77371
77806
|
Tips:
|
|
77372
77807
|
- Type naturally: "list all files" -> ls -la
|
|
77373
77808
|
- Use ! or / commands: !help or /help
|
|
@@ -77377,7 +77812,7 @@ Tips:
|
|
|
77377
77812
|
}
|
|
77378
77813
|
async function showConfig() {
|
|
77379
77814
|
const theme = getTheme();
|
|
77380
|
-
const providerName = config2.provider
|
|
77815
|
+
const providerName = getProviderDisplayName(config2.provider);
|
|
77381
77816
|
const apiKey = await getApiKey(config2.provider);
|
|
77382
77817
|
const apiKeyStatus = apiKey ? "configured" : "not set";
|
|
77383
77818
|
const isCustom = isCustomModel(currentModel);
|
|
@@ -77394,6 +77829,7 @@ Theme: ${theme.name}
|
|
|
77394
77829
|
Shell: ${shellInfo.shell} (${shellInfo.shellPath})
|
|
77395
77830
|
Platform: ${shellInfo.platform}${shellInfo.isWSL ? " (WSL)" : ""}
|
|
77396
77831
|
Safety: ${config2.safetyLevel}
|
|
77832
|
+
Thinking: ${config2.thinkingLevel}
|
|
77397
77833
|
Dry-run: ${dryRunMode ? "ON" : "OFF"}
|
|
77398
77834
|
Repo context: ${config2.repoContext ? "ON" : "OFF"}
|
|
77399
77835
|
API Key: ${apiKeyStatus}
|
|
@@ -77422,7 +77858,7 @@ async function switchProvider() {
|
|
|
77422
77858
|
left: 2,
|
|
77423
77859
|
top: 4,
|
|
77424
77860
|
width: 65,
|
|
77425
|
-
height:
|
|
77861
|
+
height: 15,
|
|
77426
77862
|
backgroundColor: "#1e293b",
|
|
77427
77863
|
border: true,
|
|
77428
77864
|
borderColor: "#60a5fa",
|
|
@@ -77433,24 +77869,25 @@ async function switchProvider() {
|
|
|
77433
77869
|
padding: 1
|
|
77434
77870
|
});
|
|
77435
77871
|
renderer.root.add(container);
|
|
77436
|
-
const
|
|
77437
|
-
|
|
77438
|
-
|
|
77439
|
-
{
|
|
77440
|
-
|
|
77441
|
-
|
|
77442
|
-
value: "opencode-zen"
|
|
77443
|
-
},
|
|
77444
|
-
{
|
|
77445
|
-
name: `OpenRouter${orKey ? " (configured)" : ""}`,
|
|
77446
|
-
description: "Access to many models from various providers",
|
|
77447
|
-
value: "openrouter"
|
|
77448
|
-
}
|
|
77872
|
+
const providers = [
|
|
77873
|
+
{ provider: "opencode-zen", description: "Curated models optimized for coding. Has free models!" },
|
|
77874
|
+
{ provider: "openrouter", description: "Access to many models from various providers" },
|
|
77875
|
+
{ provider: "vercel-ai-gateway", description: "Unified model gateway using AI_GATEWAY_API_KEY" },
|
|
77876
|
+
{ provider: "cloudflare-ai-gateway", description: "Cloudflare gateway for provider and Workers AI models" },
|
|
77877
|
+
{ provider: "workers-ai", description: "Cloudflare-hosted models via Workers AI" }
|
|
77449
77878
|
];
|
|
77879
|
+
const options = await Promise.all(providers.map(async ({ provider, description }) => {
|
|
77880
|
+
const key = await getApiKey(provider);
|
|
77881
|
+
return {
|
|
77882
|
+
name: `${getProviderDisplayName(provider)}${key ? " (configured)" : ""}`,
|
|
77883
|
+
description,
|
|
77884
|
+
value: provider
|
|
77885
|
+
};
|
|
77886
|
+
}));
|
|
77450
77887
|
const selector = new SelectRenderable(renderer, {
|
|
77451
77888
|
id: "provider-switch-select",
|
|
77452
77889
|
width: "100%",
|
|
77453
|
-
height:
|
|
77890
|
+
height: 9,
|
|
77454
77891
|
options,
|
|
77455
77892
|
backgroundColor: "transparent",
|
|
77456
77893
|
focusedBackgroundColor: "transparent",
|
|
@@ -77472,13 +77909,13 @@ async function switchProvider() {
|
|
|
77472
77909
|
const existingKey = await getApiKey(newProvider);
|
|
77473
77910
|
if (existingKey) {
|
|
77474
77911
|
config2.provider = newProvider;
|
|
77475
|
-
const models = newProvider
|
|
77912
|
+
const models = getProviderModels(newProvider);
|
|
77476
77913
|
currentModel = models.find((m2) => m2.id === config2.defaultModel) || models[0];
|
|
77477
77914
|
config2.defaultModel = currentModel.id;
|
|
77478
77915
|
saveConfig(config2);
|
|
77479
77916
|
statusBarText.content = getStatusBarContent();
|
|
77480
77917
|
closeSelector();
|
|
77481
|
-
const providerName = newProvider
|
|
77918
|
+
const providerName = getProviderDisplayName(newProvider);
|
|
77482
77919
|
addSystemMessage(`Switched to ${providerName}. Model: ${currentModel.name}`);
|
|
77483
77920
|
} else {
|
|
77484
77921
|
closeSelector();
|
|
@@ -77510,13 +77947,13 @@ function showModelSelector() {
|
|
|
77510
77947
|
border: true,
|
|
77511
77948
|
borderColor: "#60a5fa",
|
|
77512
77949
|
borderStyle: "single",
|
|
77513
|
-
title: `Select Model (${config2.provider
|
|
77950
|
+
title: `Select Model (${getProviderDisplayName(config2.provider)})`,
|
|
77514
77951
|
titleAlignment: "center",
|
|
77515
77952
|
zIndex: 100,
|
|
77516
77953
|
padding: 1
|
|
77517
77954
|
});
|
|
77518
77955
|
renderer.root.add(container);
|
|
77519
|
-
const allModels = config2.provider
|
|
77956
|
+
const allModels = getProviderModels(config2.provider);
|
|
77520
77957
|
const availableModels = allModels.filter((m2) => !m2.disabled).sort((a, b2) => a.name.localeCompare(b2.name));
|
|
77521
77958
|
const customModels = getCustomModels().sort((a, b2) => a.name.localeCompare(b2.name));
|
|
77522
77959
|
const options = [
|
|
@@ -77632,6 +78069,15 @@ function showThemeSelector() {
|
|
|
77632
78069
|
}
|
|
77633
78070
|
var commandPalette = null;
|
|
77634
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
|
+
}
|
|
77635
78081
|
function getCommandPaletteOptions() {
|
|
77636
78082
|
return [
|
|
77637
78083
|
{
|
|
@@ -77650,7 +78096,7 @@ function getCommandPaletteOptions() {
|
|
|
77650
78096
|
},
|
|
77651
78097
|
{
|
|
77652
78098
|
name: "Switch Provider",
|
|
77653
|
-
description: `Current: ${config2.provider
|
|
78099
|
+
description: `Current: ${getProviderDisplayName(config2.provider)}`,
|
|
77654
78100
|
key: "s",
|
|
77655
78101
|
chord: "s",
|
|
77656
78102
|
action: () => switchProvider()
|
|
@@ -77686,6 +78132,13 @@ function getCommandPaletteOptions() {
|
|
|
77686
78132
|
addSystemMessage(`Safety level: ${config2.safetyLevel} (${descriptions[config2.safetyLevel]})`);
|
|
77687
78133
|
}
|
|
77688
78134
|
},
|
|
78135
|
+
{
|
|
78136
|
+
name: "Cycle Thinking Level",
|
|
78137
|
+
description: `Current: ${config2.thinkingLevel}`,
|
|
78138
|
+
key: "k",
|
|
78139
|
+
chord: "k",
|
|
78140
|
+
action: () => cycleThinkingLevel()
|
|
78141
|
+
},
|
|
77689
78142
|
{
|
|
77690
78143
|
name: "Toggle Project Context",
|
|
77691
78144
|
description: config2.repoContext ? "Currently ON (sends script names to AI)" : "Currently OFF",
|
|
@@ -77822,6 +78275,10 @@ function handleKeypress(key) {
|
|
|
77822
78275
|
addSystemMessage(`Safety level: ${config2.safetyLevel} (${descriptions[config2.safetyLevel]})`);
|
|
77823
78276
|
return;
|
|
77824
78277
|
}
|
|
78278
|
+
if (key.ctrl && key.name === "k") {
|
|
78279
|
+
cycleThinkingLevel();
|
|
78280
|
+
return;
|
|
78281
|
+
}
|
|
77825
78282
|
if (key.ctrl && key.name === "z") {
|
|
77826
78283
|
renderer.destroy();
|
|
77827
78284
|
process.exit(0);
|