stratagem-x7 0.3.30 → 0.3.32

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.
Files changed (2) hide show
  1. package/dist/cli.mjs +759 -711
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -112470,6 +112470,684 @@ var init_modelStrings = __esm(() => {
112470
112470
  });
112471
112471
  });
112472
112472
 
112473
+ // src/providers/providerModels.ts
112474
+ function parseModelList(modelField) {
112475
+ return modelField.split(",").map((part) => part.trim()).filter((part) => part.length > 0);
112476
+ }
112477
+ function getPrimaryModel(modelField) {
112478
+ const models = parseModelList(modelField);
112479
+ return models.length > 0 ? models[0] : modelField;
112480
+ }
112481
+
112482
+ // src/providers/providerProfiles.ts
112483
+ import { randomBytes } from "crypto";
112484
+ function trimValue(value) {
112485
+ return value?.trim() ?? "";
112486
+ }
112487
+ function trimOrUndefined(value) {
112488
+ const trimmed = trimValue(value);
112489
+ return trimmed.length > 0 ? trimmed : undefined;
112490
+ }
112491
+ function normalizeBaseUrl(value) {
112492
+ return trimValue(value).replace(/\/+$/, "");
112493
+ }
112494
+ function sanitizeProfile(profile) {
112495
+ const id = trimValue(profile.id);
112496
+ const name = trimValue(profile.name);
112497
+ const provider = profile.provider === "anthropic" ? "anthropic" : "openai";
112498
+ const baseUrl = normalizeBaseUrl(profile.baseUrl);
112499
+ const model = trimValue(profile.model);
112500
+ if (!id || !name || !baseUrl || !model) {
112501
+ return null;
112502
+ }
112503
+ return {
112504
+ id,
112505
+ name,
112506
+ provider,
112507
+ baseUrl,
112508
+ model,
112509
+ apiKey: trimOrUndefined(profile.apiKey)
112510
+ };
112511
+ }
112512
+ function sanitizeProfiles(profiles) {
112513
+ const seen = new Set;
112514
+ const sanitized = [];
112515
+ for (const profile of profiles ?? []) {
112516
+ const normalized = sanitizeProfile(profile);
112517
+ if (!normalized || seen.has(normalized.id)) {
112518
+ continue;
112519
+ }
112520
+ seen.add(normalized.id);
112521
+ sanitized.push(normalized);
112522
+ }
112523
+ return sanitized;
112524
+ }
112525
+ function nextProfileId() {
112526
+ return `provider_${randomBytes(6).toString("hex")}`;
112527
+ }
112528
+ function toProfile(input, id = nextProfileId()) {
112529
+ return sanitizeProfile({
112530
+ id,
112531
+ provider: input.provider ?? "openai",
112532
+ name: input.name,
112533
+ baseUrl: input.baseUrl,
112534
+ model: input.model,
112535
+ apiKey: input.apiKey
112536
+ });
112537
+ }
112538
+ function getModelCacheByProfile(profileId, config2 = getGlobalConfig()) {
112539
+ return config2.openaiAdditionalModelOptionsCacheByProfile?.[profileId] ?? [];
112540
+ }
112541
+ function getProviderPresetDefaults(preset) {
112542
+ switch (preset) {
112543
+ case "anthropic":
112544
+ return {
112545
+ provider: "anthropic",
112546
+ name: "Anthropic",
112547
+ baseUrl: process.env.ANTHROPIC_BASE_URL ?? "https://api.anthropic.com",
112548
+ model: process.env.ANTHROPIC_MODEL ?? "claude-sonnet-4-6",
112549
+ apiKey: process.env.ANTHROPIC_API_KEY ?? "",
112550
+ requiresApiKey: true
112551
+ };
112552
+ case "openai":
112553
+ return {
112554
+ provider: "openai",
112555
+ name: "OpenAI",
112556
+ baseUrl: "https://api.openai.com/v1",
112557
+ model: "gpt-5.3-codex",
112558
+ apiKey: "",
112559
+ requiresApiKey: true
112560
+ };
112561
+ case "moonshotai":
112562
+ return {
112563
+ provider: "openai",
112564
+ name: "Moonshot AI",
112565
+ baseUrl: "https://api.moonshot.ai/v1",
112566
+ model: "kimi-k2.5",
112567
+ apiKey: "",
112568
+ requiresApiKey: true
112569
+ };
112570
+ case "deepseek":
112571
+ return {
112572
+ provider: "openai",
112573
+ name: "DeepSeek",
112574
+ baseUrl: "https://api.deepseek.com/v1",
112575
+ model: "deepseek-chat",
112576
+ apiKey: "",
112577
+ requiresApiKey: true
112578
+ };
112579
+ case "gemini":
112580
+ return {
112581
+ provider: "openai",
112582
+ name: "Google Gemini",
112583
+ baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai",
112584
+ model: "gemini-3-flash-preview",
112585
+ apiKey: "",
112586
+ requiresApiKey: true
112587
+ };
112588
+ case "mistral":
112589
+ return {
112590
+ provider: "openai",
112591
+ name: "Mistral",
112592
+ baseUrl: "https://api.mistral.ai/v1",
112593
+ model: "devstral-latest",
112594
+ apiKey: "",
112595
+ requiresApiKey: true
112596
+ };
112597
+ case "together":
112598
+ return {
112599
+ provider: "openai",
112600
+ name: "Together AI",
112601
+ baseUrl: "https://api.together.xyz/v1",
112602
+ model: "Qwen/Qwen3.5-9B",
112603
+ apiKey: "",
112604
+ requiresApiKey: true
112605
+ };
112606
+ case "groq":
112607
+ return {
112608
+ provider: "openai",
112609
+ name: "Groq",
112610
+ baseUrl: "https://api.groq.com/openai/v1",
112611
+ model: "llama-3.3-70b-versatile",
112612
+ apiKey: "",
112613
+ requiresApiKey: true
112614
+ };
112615
+ case "azure-openai":
112616
+ return {
112617
+ provider: "openai",
112618
+ name: "Azure OpenAI",
112619
+ baseUrl: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1",
112620
+ model: "YOUR-DEPLOYMENT-NAME",
112621
+ apiKey: "",
112622
+ requiresApiKey: true
112623
+ };
112624
+ case "openrouter":
112625
+ return {
112626
+ provider: "openai",
112627
+ name: "OpenRouter",
112628
+ baseUrl: "https://openrouter.ai/api/v1",
112629
+ model: "openai/gpt-5-mini",
112630
+ apiKey: "",
112631
+ requiresApiKey: true
112632
+ };
112633
+ case "lmstudio":
112634
+ return {
112635
+ provider: "openai",
112636
+ name: "LM Studio",
112637
+ baseUrl: "http://localhost:1234/v1",
112638
+ model: "local-model",
112639
+ apiKey: "",
112640
+ requiresApiKey: false
112641
+ };
112642
+ case "custom":
112643
+ return {
112644
+ provider: "openai",
112645
+ name: "Custom OpenAI-compatible",
112646
+ baseUrl: process.env.OPENAI_BASE_URL ?? process.env.OPENAI_API_BASE ?? DEFAULT_OLLAMA_BASE_URL2,
112647
+ model: process.env.OPENAI_MODEL ?? DEFAULT_OLLAMA_MODEL,
112648
+ apiKey: process.env.OPENAI_API_KEY ?? "",
112649
+ requiresApiKey: false
112650
+ };
112651
+ case "nvidia-nim":
112652
+ return {
112653
+ provider: "openai",
112654
+ name: "NVIDIA NIM",
112655
+ baseUrl: "https://integrate.api.nvidia.com/v1",
112656
+ model: "nvidia/llama-3.1-nemotron-70b-instruct",
112657
+ apiKey: process.env.NVIDIA_API_KEY ?? "",
112658
+ requiresApiKey: true
112659
+ };
112660
+ case "minimax":
112661
+ return {
112662
+ provider: "openai",
112663
+ name: "MiniMax",
112664
+ baseUrl: "https://api.minimax.io/v1",
112665
+ model: "MiniMax-M2.5",
112666
+ apiKey: process.env.MINIMAX_API_KEY ?? "",
112667
+ requiresApiKey: true
112668
+ };
112669
+ case "ollama-cloud":
112670
+ return {
112671
+ provider: "openai",
112672
+ name: "Ollama Cloud",
112673
+ baseUrl: "https://ollama.com/v1",
112674
+ model: process.env.OPENAI_MODEL ?? "deepseek-v3.2",
112675
+ apiKey: process.env.OLLAMA_API_KEY ?? "",
112676
+ requiresApiKey: true
112677
+ };
112678
+ case "deepinfra":
112679
+ return {
112680
+ provider: "openai",
112681
+ name: "DeepInfra",
112682
+ baseUrl: "https://api.deepinfra.com/v1/openai",
112683
+ model: "meta-llama/Llama-4-Maverick-17B-128E-Instruct",
112684
+ apiKey: "",
112685
+ requiresApiKey: true
112686
+ };
112687
+ case "cerebras":
112688
+ return {
112689
+ provider: "openai",
112690
+ name: "Cerebras",
112691
+ baseUrl: "https://api.cerebras.ai/v1",
112692
+ model: "llama-4-scout-17b-16e",
112693
+ apiKey: "",
112694
+ requiresApiKey: true
112695
+ };
112696
+ case "cohere":
112697
+ return {
112698
+ provider: "openai",
112699
+ name: "Cohere",
112700
+ baseUrl: "https://api.cohere.com/v2",
112701
+ model: "command-r-plus",
112702
+ apiKey: "",
112703
+ requiresApiKey: true
112704
+ };
112705
+ case "perplexity":
112706
+ return {
112707
+ provider: "openai",
112708
+ name: "Perplexity",
112709
+ baseUrl: "https://api.perplexity.ai",
112710
+ model: "sonar-pro",
112711
+ apiKey: "",
112712
+ requiresApiKey: true
112713
+ };
112714
+ case "xai":
112715
+ return {
112716
+ provider: "openai",
112717
+ name: "xAI (Grok)",
112718
+ baseUrl: "https://api.x.ai/v1",
112719
+ model: "grok-3",
112720
+ apiKey: "",
112721
+ requiresApiKey: true
112722
+ };
112723
+ case "venice":
112724
+ return {
112725
+ provider: "openai",
112726
+ name: "Venice",
112727
+ baseUrl: "https://api.venice.ai/api/v1",
112728
+ model: "deepseek-r1-671b",
112729
+ apiKey: "",
112730
+ requiresApiKey: true
112731
+ };
112732
+ case "gitlab":
112733
+ return {
112734
+ provider: "openai",
112735
+ name: "GitLab",
112736
+ baseUrl: "https://gitlab.com/api/v4/ai/v1",
112737
+ model: "claude-3-5-sonnet",
112738
+ apiKey: "",
112739
+ requiresApiKey: true
112740
+ };
112741
+ case "cloudflare":
112742
+ return {
112743
+ provider: "openai",
112744
+ name: "Cloudflare Workers AI",
112745
+ baseUrl: "https://api.cloudflare.com/client/v4/accounts/YOUR_ACCOUNT_ID/ai/v1",
112746
+ model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
112747
+ apiKey: "",
112748
+ requiresApiKey: true
112749
+ };
112750
+ case "vercel":
112751
+ return {
112752
+ provider: "openai",
112753
+ name: "Vercel",
112754
+ baseUrl: "https://api.vercel.ai/v1",
112755
+ model: "anthropic:claude-sonnet-4-6",
112756
+ apiKey: "",
112757
+ requiresApiKey: true
112758
+ };
112759
+ case "sap-ai-core":
112760
+ return {
112761
+ provider: "openai",
112762
+ name: "SAP AI Core",
112763
+ baseUrl: "https://api.ai.prod.YOUR_REGION.ml.hana.ondemand.com/v2/inference/deployments/YOUR_DEPLOYMENT_ID",
112764
+ model: "gpt-4o",
112765
+ apiKey: "",
112766
+ requiresApiKey: true
112767
+ };
112768
+ case "opencode":
112769
+ return {
112770
+ provider: "openai",
112771
+ name: "OpenCode Zen",
112772
+ baseUrl: "https://opencode.ai/zen/v1",
112773
+ model: "gpt-5.4",
112774
+ apiKey: process.env.OPENCODE_API_KEY ?? "",
112775
+ requiresApiKey: true
112776
+ };
112777
+ case "opencode-go":
112778
+ return {
112779
+ provider: "openai",
112780
+ name: "OpenCode Go",
112781
+ baseUrl: "https://opencode.ai/zen/go/v1",
112782
+ model: "glm-5",
112783
+ apiKey: process.env.OPENCODE_API_KEY ?? "",
112784
+ requiresApiKey: true
112785
+ };
112786
+ case "ollama":
112787
+ default:
112788
+ return {
112789
+ provider: "openai",
112790
+ name: "Ollama",
112791
+ baseUrl: DEFAULT_OLLAMA_BASE_URL2,
112792
+ model: process.env.OPENAI_MODEL ?? DEFAULT_OLLAMA_MODEL,
112793
+ apiKey: "",
112794
+ requiresApiKey: false
112795
+ };
112796
+ }
112797
+ }
112798
+ function getProviderProfiles(config2 = getGlobalConfig()) {
112799
+ return sanitizeProfiles(config2.providerProfiles);
112800
+ }
112801
+ function hasProviderSelectionFlags(processEnv = process.env) {
112802
+ return processEnv.CLAUDE_CODE_USE_OPENAI !== undefined || processEnv.CLAUDE_CODE_USE_GEMINI !== undefined || processEnv.CLAUDE_CODE_USE_MISTRAL !== undefined || processEnv.CLAUDE_CODE_USE_GITHUB !== undefined || processEnv.CLAUDE_CODE_USE_BEDROCK !== undefined || processEnv.CLAUDE_CODE_USE_VERTEX !== undefined || processEnv.CLAUDE_CODE_USE_FOUNDRY !== undefined;
112803
+ }
112804
+ function hasConflictingProviderFlagsForProfile(processEnv, profile) {
112805
+ if (profile.provider === "anthropic") {
112806
+ return hasProviderSelectionFlags(processEnv);
112807
+ }
112808
+ return processEnv.CLAUDE_CODE_USE_GEMINI !== undefined || processEnv.CLAUDE_CODE_USE_GITHUB !== undefined || processEnv.CLAUDE_CODE_USE_BEDROCK !== undefined || processEnv.CLAUDE_CODE_USE_VERTEX !== undefined || processEnv.CLAUDE_CODE_USE_FOUNDRY !== undefined;
112809
+ }
112810
+ function sameOptionalEnvValue(left, right) {
112811
+ return trimOrUndefined(left) === trimOrUndefined(right);
112812
+ }
112813
+ function isProcessEnvAlignedWithProfile(processEnv, profile, options2) {
112814
+ const includeApiKey = options2?.includeApiKey ?? true;
112815
+ if (processEnv[PROFILE_ENV_APPLIED_FLAG] !== "1") {
112816
+ return false;
112817
+ }
112818
+ if (trimOrUndefined(processEnv[PROFILE_ENV_APPLIED_ID]) !== profile.id) {
112819
+ return false;
112820
+ }
112821
+ if (profile.provider === "anthropic") {
112822
+ return !hasProviderSelectionFlags(processEnv) && sameOptionalEnvValue(processEnv.ANTHROPIC_BASE_URL, profile.baseUrl) && sameOptionalEnvValue(processEnv.ANTHROPIC_MODEL, getPrimaryModel(profile.model)) && (!includeApiKey || sameOptionalEnvValue(processEnv.ANTHROPIC_API_KEY, profile.apiKey));
112823
+ }
112824
+ return processEnv.CLAUDE_CODE_USE_OPENAI !== undefined && processEnv.CLAUDE_CODE_USE_GEMINI === undefined && processEnv.CLAUDE_CODE_USE_MISTRAL === undefined && processEnv.CLAUDE_CODE_USE_GITHUB === undefined && processEnv.CLAUDE_CODE_USE_BEDROCK === undefined && processEnv.CLAUDE_CODE_USE_VERTEX === undefined && processEnv.CLAUDE_CODE_USE_FOUNDRY === undefined && sameOptionalEnvValue(processEnv.OPENAI_BASE_URL, profile.baseUrl) && sameOptionalEnvValue(processEnv.OPENAI_MODEL, getPrimaryModel(profile.model)) && (!includeApiKey || sameOptionalEnvValue(processEnv.OPENAI_API_KEY, profile.apiKey));
112825
+ }
112826
+ function getActiveProviderProfile(config2 = getGlobalConfig()) {
112827
+ const profiles = getProviderProfiles(config2);
112828
+ if (profiles.length === 0) {
112829
+ return;
112830
+ }
112831
+ const activeId = trimOrUndefined(config2.activeProviderProfileId);
112832
+ return profiles.find((profile) => profile.id === activeId) ?? profiles[0];
112833
+ }
112834
+ function clearProviderProfileEnvFromProcessEnv(processEnv = process.env) {
112835
+ delete processEnv.CLAUDE_CODE_USE_OPENAI;
112836
+ delete processEnv.CLAUDE_CODE_USE_GEMINI;
112837
+ delete processEnv.CLAUDE_CODE_USE_MISTRAL;
112838
+ delete processEnv.CLAUDE_CODE_USE_GITHUB;
112839
+ delete processEnv.CLAUDE_CODE_USE_BEDROCK;
112840
+ delete processEnv.CLAUDE_CODE_USE_VERTEX;
112841
+ delete processEnv.CLAUDE_CODE_USE_FOUNDRY;
112842
+ delete processEnv.OPENAI_BASE_URL;
112843
+ delete processEnv.OPENAI_API_BASE;
112844
+ delete processEnv.OPENAI_MODEL;
112845
+ delete processEnv.OPENAI_API_KEY;
112846
+ delete processEnv.ANTHROPIC_BASE_URL;
112847
+ delete processEnv.ANTHROPIC_MODEL;
112848
+ delete processEnv.ANTHROPIC_API_KEY;
112849
+ delete processEnv[PROFILE_ENV_APPLIED_FLAG];
112850
+ delete processEnv[PROFILE_ENV_APPLIED_ID];
112851
+ delete processEnv.MINIMAX_API_KEY;
112852
+ delete processEnv.NVIDIA_API_KEY;
112853
+ delete processEnv.NVIDIA_NIM;
112854
+ delete processEnv.OPENCODE_API_KEY;
112855
+ }
112856
+ function applyProviderProfileToProcessEnv(profile) {
112857
+ clearProviderProfileEnvFromProcessEnv();
112858
+ process.env[PROFILE_ENV_APPLIED_FLAG] = "1";
112859
+ process.env[PROFILE_ENV_APPLIED_ID] = profile.id;
112860
+ process.env.ANTHROPIC_MODEL = getPrimaryModel(profile.model);
112861
+ if (profile.provider === "anthropic") {
112862
+ process.env.ANTHROPIC_BASE_URL = profile.baseUrl;
112863
+ if (profile.apiKey) {
112864
+ process.env.ANTHROPIC_API_KEY = profile.apiKey;
112865
+ } else {
112866
+ delete process.env.ANTHROPIC_API_KEY;
112867
+ }
112868
+ delete process.env.OPENAI_BASE_URL;
112869
+ delete process.env.OPENAI_API_BASE;
112870
+ delete process.env.OPENAI_MODEL;
112871
+ delete process.env.OPENAI_API_KEY;
112872
+ return;
112873
+ }
112874
+ process.env.CLAUDE_CODE_USE_OPENAI = "1";
112875
+ process.env.OPENAI_BASE_URL = profile.baseUrl;
112876
+ process.env.OPENAI_MODEL = getPrimaryModel(profile.model);
112877
+ if (profile.apiKey) {
112878
+ process.env.OPENAI_API_KEY = profile.apiKey;
112879
+ const baseUrl = profile.baseUrl.toLowerCase();
112880
+ if (baseUrl.includes("minimax")) {
112881
+ process.env.MINIMAX_API_KEY = profile.apiKey;
112882
+ }
112883
+ if (baseUrl.includes("nvidia") || baseUrl.includes("integrate.api.nvidia")) {
112884
+ process.env.NVIDIA_API_KEY = profile.apiKey;
112885
+ }
112886
+ } else {
112887
+ delete process.env.OPENAI_API_KEY;
112888
+ }
112889
+ }
112890
+ function applyActiveProviderProfileFromConfig(config2 = getGlobalConfig(), options2) {
112891
+ const processEnv = options2?.processEnv ?? process.env;
112892
+ const activeProfile = getActiveProviderProfile(config2);
112893
+ if (!activeProfile) {
112894
+ return;
112895
+ }
112896
+ const isCurrentEnvProfileManaged = processEnv[PROFILE_ENV_APPLIED_FLAG] === "1" && trimOrUndefined(processEnv[PROFILE_ENV_APPLIED_ID]) === activeProfile.id;
112897
+ if (!options2?.force && (hasProviderSelectionFlags(processEnv) || processEnv[PROFILE_ENV_APPLIED_FLAG] === "1")) {
112898
+ if (!isCurrentEnvProfileManaged) {
112899
+ return;
112900
+ }
112901
+ if (hasConflictingProviderFlagsForProfile(processEnv, activeProfile)) {
112902
+ return;
112903
+ }
112904
+ if (isProcessEnvAlignedWithProfile(processEnv, activeProfile)) {
112905
+ return activeProfile;
112906
+ }
112907
+ }
112908
+ applyProviderProfileToProcessEnv(activeProfile);
112909
+ return activeProfile;
112910
+ }
112911
+ function addProviderProfile(input, options2) {
112912
+ const profile = toProfile(input);
112913
+ if (!profile) {
112914
+ return null;
112915
+ }
112916
+ const makeActive = options2?.makeActive ?? true;
112917
+ saveGlobalConfig((current) => {
112918
+ const currentProfiles = getProviderProfiles(current);
112919
+ const nextProfiles = [...currentProfiles, profile];
112920
+ const currentActive = trimOrUndefined(current.activeProviderProfileId);
112921
+ const nextActiveId = makeActive || !currentActive || !nextProfiles.some((p) => p.id === currentActive) ? profile.id : currentActive;
112922
+ return {
112923
+ ...current,
112924
+ providerProfiles: nextProfiles,
112925
+ activeProviderProfileId: nextActiveId
112926
+ };
112927
+ });
112928
+ const activeProfile = getActiveProviderProfile();
112929
+ if (activeProfile?.id === profile.id) {
112930
+ applyProviderProfileToProcessEnv(profile);
112931
+ clearActiveOpenAIModelOptionsCache();
112932
+ }
112933
+ return profile;
112934
+ }
112935
+ function updateProviderProfile(profileId, input) {
112936
+ const updatedProfile = toProfile(input, profileId);
112937
+ if (!updatedProfile) {
112938
+ return null;
112939
+ }
112940
+ let wasUpdated = false;
112941
+ let shouldApply = false;
112942
+ saveGlobalConfig((current) => {
112943
+ const currentProfiles = getProviderProfiles(current);
112944
+ const profileIndex = currentProfiles.findIndex((profile) => profile.id === profileId);
112945
+ if (profileIndex < 0) {
112946
+ return current;
112947
+ }
112948
+ wasUpdated = true;
112949
+ const nextProfiles = [...currentProfiles];
112950
+ nextProfiles[profileIndex] = updatedProfile;
112951
+ const cacheByProfile = {
112952
+ ...current.openaiAdditionalModelOptionsCacheByProfile ?? {}
112953
+ };
112954
+ delete cacheByProfile[profileId];
112955
+ const currentActive = trimOrUndefined(current.activeProviderProfileId);
112956
+ const nextActiveId = currentActive && nextProfiles.some((profile) => profile.id === currentActive) ? currentActive : nextProfiles[0]?.id;
112957
+ shouldApply = nextActiveId === profileId;
112958
+ return {
112959
+ ...current,
112960
+ providerProfiles: nextProfiles,
112961
+ activeProviderProfileId: nextActiveId,
112962
+ openaiAdditionalModelOptionsCacheByProfile: cacheByProfile,
112963
+ openaiAdditionalModelOptionsCache: shouldApply ? [] : current.openaiAdditionalModelOptionsCache
112964
+ };
112965
+ });
112966
+ if (!wasUpdated) {
112967
+ return null;
112968
+ }
112969
+ if (shouldApply) {
112970
+ applyProviderProfileToProcessEnv(updatedProfile);
112971
+ }
112972
+ return updatedProfile;
112973
+ }
112974
+ function persistActiveProviderProfileModel(model) {
112975
+ const nextModel = trimOrUndefined(model);
112976
+ if (!nextModel) {
112977
+ return null;
112978
+ }
112979
+ const activeProfile = getActiveProviderProfile();
112980
+ if (!activeProfile) {
112981
+ return null;
112982
+ }
112983
+ const existingModels = parseModelList(activeProfile.model);
112984
+ if (existingModels.includes(nextModel)) {
112985
+ return activeProfile;
112986
+ }
112987
+ saveGlobalConfig((current) => {
112988
+ const currentProfiles = getProviderProfiles(current);
112989
+ const profileIndex = currentProfiles.findIndex((profile) => profile.id === activeProfile.id);
112990
+ if (profileIndex < 0) {
112991
+ return current;
112992
+ }
112993
+ const currentProfile = currentProfiles[profileIndex];
112994
+ if (currentProfile.model === nextModel) {
112995
+ return current;
112996
+ }
112997
+ const nextProfiles = [...currentProfiles];
112998
+ nextProfiles[profileIndex] = {
112999
+ ...currentProfile,
113000
+ model: nextModel
113001
+ };
113002
+ return {
113003
+ ...current,
113004
+ providerProfiles: nextProfiles
113005
+ };
113006
+ });
113007
+ const resolvedProfile = getActiveProviderProfile();
113008
+ if (!resolvedProfile || resolvedProfile.id !== activeProfile.id) {
113009
+ return null;
113010
+ }
113011
+ if (process.env[PROFILE_ENV_APPLIED_FLAG] === "1" && trimOrUndefined(process.env[PROFILE_ENV_APPLIED_ID]) === resolvedProfile.id) {
113012
+ applyProviderProfileToProcessEnv(resolvedProfile);
113013
+ }
113014
+ return resolvedProfile;
113015
+ }
113016
+ function getProfileModelOptions(profile) {
113017
+ const models = parseModelList(profile.model);
113018
+ if (models.length === 0) {
113019
+ return [];
113020
+ }
113021
+ return models.map((model) => ({
113022
+ value: model,
113023
+ label: model,
113024
+ description: `Provider: ${profile.name}`
113025
+ }));
113026
+ }
113027
+ function setActiveProviderProfile(profileId) {
113028
+ const current = getGlobalConfig();
113029
+ const profiles = getProviderProfiles(current);
113030
+ const activeProfile = profiles.find((profile) => profile.id === profileId);
113031
+ if (!activeProfile) {
113032
+ return null;
113033
+ }
113034
+ const profileModelOptions = getProfileModelOptions(activeProfile);
113035
+ saveGlobalConfig((config2) => ({
113036
+ ...config2,
113037
+ activeProviderProfileId: profileId,
113038
+ openaiAdditionalModelOptionsCache: profileModelOptions.length > 0 ? profileModelOptions : getModelCacheByProfile(profileId, config2),
113039
+ openaiAdditionalModelOptionsCacheByProfile: {
113040
+ ...config2.openaiAdditionalModelOptionsCacheByProfile ?? {},
113041
+ [profileId]: profileModelOptions.length > 0 ? profileModelOptions : config2.openaiAdditionalModelOptionsCacheByProfile?.[profileId] ?? []
113042
+ }
113043
+ }));
113044
+ applyProviderProfileToProcessEnv(activeProfile);
113045
+ return activeProfile;
113046
+ }
113047
+ function deleteProviderProfile(profileId) {
113048
+ let removed = false;
113049
+ let deletedProfile;
113050
+ let nextActiveProfile;
113051
+ saveGlobalConfig((current) => {
113052
+ const currentProfiles = getProviderProfiles(current);
113053
+ const existing = currentProfiles.find((profile) => profile.id === profileId);
113054
+ if (!existing) {
113055
+ return current;
113056
+ }
113057
+ removed = true;
113058
+ deletedProfile = existing;
113059
+ const nextProfiles = currentProfiles.filter((profile) => profile.id !== profileId);
113060
+ const currentActive = trimOrUndefined(current.activeProviderProfileId);
113061
+ const activeWasDeleted = !currentActive || currentActive === profileId || !nextProfiles.some((profile) => profile.id === currentActive);
113062
+ const nextActiveId = activeWasDeleted ? nextProfiles[0]?.id : currentActive;
113063
+ if (nextActiveId) {
113064
+ nextActiveProfile = nextProfiles.find((profile) => profile.id === nextActiveId) ?? nextProfiles[0];
113065
+ }
113066
+ const cacheByProfile = {
113067
+ ...current.openaiAdditionalModelOptionsCacheByProfile ?? {}
113068
+ };
113069
+ delete cacheByProfile[profileId];
113070
+ return {
113071
+ ...current,
113072
+ providerProfiles: nextProfiles,
113073
+ activeProviderProfileId: nextActiveId,
113074
+ openaiAdditionalModelOptionsCacheByProfile: cacheByProfile,
113075
+ openaiAdditionalModelOptionsCache: nextActiveId ? getModelCacheByProfile(nextActiveId, {
113076
+ ...current,
113077
+ openaiAdditionalModelOptionsCacheByProfile: cacheByProfile
113078
+ }) : []
113079
+ };
113080
+ });
113081
+ if (nextActiveProfile) {
113082
+ applyProviderProfileToProcessEnv(nextActiveProfile);
113083
+ } else if (deletedProfile && isProcessEnvAlignedWithProfile(process.env, deletedProfile, {
113084
+ includeApiKey: false
113085
+ })) {
113086
+ clearProviderProfileEnvFromProcessEnv();
113087
+ }
113088
+ return {
113089
+ removed,
113090
+ activeProfileId: nextActiveProfile?.id
113091
+ };
113092
+ }
113093
+ function getActiveOpenAIModelOptionsCache(config2 = getGlobalConfig()) {
113094
+ const activeProfile = getActiveProviderProfile(config2);
113095
+ if (!activeProfile) {
113096
+ return config2.openaiAdditionalModelOptionsCache ?? [];
113097
+ }
113098
+ const cached2 = config2.openaiAdditionalModelOptionsCacheByProfile?.[activeProfile.id];
113099
+ if (cached2) {
113100
+ return cached2;
113101
+ }
113102
+ if (Object.keys(config2.openaiAdditionalModelOptionsCacheByProfile ?? {}).length === 0) {
113103
+ return config2.openaiAdditionalModelOptionsCache ?? [];
113104
+ }
113105
+ return [];
113106
+ }
113107
+ function setActiveOpenAIModelOptionsCache(options2) {
113108
+ const activeProfile = getActiveProviderProfile();
113109
+ if (!activeProfile) {
113110
+ saveGlobalConfig((current) => ({
113111
+ ...current,
113112
+ openaiAdditionalModelOptionsCache: options2
113113
+ }));
113114
+ return;
113115
+ }
113116
+ saveGlobalConfig((current) => ({
113117
+ ...current,
113118
+ openaiAdditionalModelOptionsCache: options2,
113119
+ openaiAdditionalModelOptionsCacheByProfile: {
113120
+ ...current.openaiAdditionalModelOptionsCacheByProfile ?? {},
113121
+ [activeProfile.id]: options2
113122
+ }
113123
+ }));
113124
+ }
113125
+ function clearActiveOpenAIModelOptionsCache() {
113126
+ const activeProfile = getActiveProviderProfile();
113127
+ if (!activeProfile) {
113128
+ saveGlobalConfig((current) => ({
113129
+ ...current,
113130
+ openaiAdditionalModelOptionsCache: []
113131
+ }));
113132
+ return;
113133
+ }
113134
+ saveGlobalConfig((current) => {
113135
+ const cacheByProfile = {
113136
+ ...current.openaiAdditionalModelOptionsCacheByProfile ?? {}
113137
+ };
113138
+ delete cacheByProfile[activeProfile.id];
113139
+ return {
113140
+ ...current,
113141
+ openaiAdditionalModelOptionsCache: [],
113142
+ openaiAdditionalModelOptionsCacheByProfile: cacheByProfile
113143
+ };
113144
+ });
113145
+ }
113146
+ var DEFAULT_OLLAMA_BASE_URL2 = "http://localhost:11434/v1", DEFAULT_OLLAMA_MODEL = "llama3.1:8b", PROFILE_ENV_APPLIED_FLAG = "CLAUDE_CODE_PROVIDER_PROFILE_ENV_APPLIED", PROFILE_ENV_APPLIED_ID = "CLAUDE_CODE_PROVIDER_PROFILE_ENV_APPLIED_ID";
113147
+ var init_providerProfiles = __esm(() => {
113148
+ init_config8();
113149
+ });
113150
+
112473
113151
  // src/utils/billing.ts
112474
113152
  function hasConsoleBillingAccess() {
112475
113153
  if (isEnvTruthy(process.env.DISABLE_COST_WARNINGS)) {
@@ -113988,6 +114666,12 @@ function isAnthropicAuthEnabled() {
113988
114666
  return !!process.env.CLAUDE_CODE_OAUTH_TOKEN;
113989
114667
  }
113990
114668
  const is3P = isEnvTruthy(process.env.CLAUDE_CODE_USE_BEDROCK) || isEnvTruthy(process.env.CLAUDE_CODE_USE_VERTEX) || isEnvTruthy(process.env.CLAUDE_CODE_USE_FOUNDRY) || isEnvTruthy(process.env.CLAUDE_CODE_USE_OPENAI) || isEnvTruthy(process.env.CLAUDE_CODE_USE_GEMINI) || isEnvTruthy(process.env.CLAUDE_CODE_USE_MISTRAL) || isEnvTruthy(process.env.CLAUDE_CODE_USE_GITHUB);
114669
+ if (!is3P) {
114670
+ const activeProfile = getActiveProviderProfile();
114671
+ if (activeProfile && activeProfile.provider !== "anthropic") {
114672
+ return false;
114673
+ }
114674
+ }
113991
114675
  const settings = getSettings_DEPRECATED() || {};
113992
114676
  const apiKeyHelper = settings.apiKeyHelper;
113993
114677
  const hasExternalAuthToken = process.env.ANTHROPIC_AUTH_TOKEN || apiKeyHelper || process.env.CLAUDE_CODE_API_KEY_FILE_DESCRIPTOR;
@@ -115014,6 +115698,7 @@ var init_auth = __esm(() => {
115014
115698
  init_oauth();
115015
115699
  init_modelStrings();
115016
115700
  init_providers();
115701
+ init_providerProfiles();
115017
115702
  init_state();
115018
115703
  init_mockRateLimits();
115019
115704
  init_client2();
@@ -192256,7 +192941,7 @@ var init_pluginVersioning = __esm(() => {
192256
192941
  });
192257
192942
 
192258
192943
  // src/utils/plugins/zipCache.ts
192259
- import { randomBytes } from "crypto";
192944
+ import { randomBytes as randomBytes2 } from "crypto";
192260
192945
  import {
192261
192946
  chmod as chmod3,
192262
192947
  lstat as lstat3,
@@ -192306,7 +192991,7 @@ async function getSessionPluginCachePath() {
192306
192991
  }
192307
192992
  if (!sessionPluginCachePromise) {
192308
192993
  sessionPluginCachePromise = (async () => {
192309
- const suffix = randomBytes(8).toString("hex");
192994
+ const suffix = randomBytes2(8).toString("hex");
192310
192995
  const dir = join45(tmpdir4(), `claude-plugin-session-${suffix}`);
192311
192996
  await getFsImplementation().mkdir(dir);
192312
192997
  sessionPluginCachePath = dir;
@@ -192333,7 +193018,7 @@ async function cleanupSessionPluginCache() {
192333
193018
  async function atomicWriteToZipCache(targetPath, data) {
192334
193019
  const dir = dirname17(targetPath);
192335
193020
  await getFsImplementation().mkdir(dir);
192336
- const tmpName = `.${basename6(targetPath)}.tmp.${randomBytes(4).toString("hex")}`;
193021
+ const tmpName = `.${basename6(targetPath)}.tmp.${randomBytes2(4).toString("hex")}`;
192337
193022
  const tmpPath = join45(dir, tmpName);
192338
193023
  try {
192339
193024
  if (typeof data === "string") {
@@ -192459,7 +193144,7 @@ var init_zipCache = __esm(() => {
192459
193144
  });
192460
193145
 
192461
193146
  // src/utils/plugins/pluginInstallationHelpers.ts
192462
- import { randomBytes as randomBytes2 } from "crypto";
193147
+ import { randomBytes as randomBytes3 } from "crypto";
192463
193148
  import { rename as rename2, rm as rm3 } from "fs/promises";
192464
193149
  import { dirname as dirname18, join as join46, resolve as resolve17, sep as sep10 } from "path";
192465
193150
  function getCurrentTimestamp() {
@@ -192490,7 +193175,7 @@ async function cacheAndRegisterPlugin(pluginId, entry, scope = "user", projectPa
192490
193175
  const normalizedCachePath = cacheResult.path.endsWith(sep10) ? cacheResult.path : cacheResult.path + sep10;
192491
193176
  const isSubdirectory = versionedPath.startsWith(normalizedCachePath);
192492
193177
  if (isSubdirectory) {
192493
- const tempPath = join46(dirname18(cacheResult.path), `.claude-plugin-temp-${Date.now()}-${randomBytes2(4).toString("hex")}`);
193178
+ const tempPath = join46(dirname18(cacheResult.path), `.claude-plugin-temp-${Date.now()}-${randomBytes3(4).toString("hex")}`);
192494
193179
  await rename2(cacheResult.path, tempPath);
192495
193180
  await getFsImplementation().mkdir(dirname18(versionedPath));
192496
193181
  await rename2(tempPath, versionedPath);
@@ -210769,8 +211454,8 @@ async function random(size) {
210769
211454
  const evenDistCutoff = Math.pow(2, 8) - Math.pow(2, 8) % mask.length;
210770
211455
  let result = "";
210771
211456
  while (result.length < size) {
210772
- const randomBytes3 = await getRandomValues(size - result.length);
210773
- for (const randomByte of randomBytes3) {
211457
+ const randomBytes4 = await getRandomValues(size - result.length);
211458
+ for (const randomByte of randomBytes4) {
210774
211459
  if (randomByte < evenDistCutoff) {
210775
211460
  result += mask[randomByte % mask.length];
210776
211461
  }
@@ -217016,7 +217701,7 @@ var init_xaa = __esm(() => {
217016
217701
  });
217017
217702
 
217018
217703
  // src/services/mcp/xaaIdpLogin.ts
217019
- import { randomBytes as randomBytes3 } from "crypto";
217704
+ import { randomBytes as randomBytes4 } from "crypto";
217020
217705
  import { createServer as createServer2 } from "http";
217021
217706
  import { parse as parse9 } from "url";
217022
217707
  function isXaaEnabled() {
@@ -217241,7 +217926,7 @@ async function acquireIdpIdToken(opts) {
217241
217926
  const metadata = await discoverOidc(idpIssuer);
217242
217927
  const port = opts.callbackPort ?? await findAvailablePort();
217243
217928
  const redirectUri = buildRedirectUri(port);
217244
- const state = randomBytes3(32).toString("base64url");
217929
+ const state = randomBytes4(32).toString("base64url");
217245
217930
  const clientInformation = {
217246
217931
  client_id: idpClientId,
217247
217932
  ...opts.idpClientSecret ? { client_secret: opts.idpClientSecret } : {}
@@ -217300,7 +217985,7 @@ var init_xaaIdpLogin = __esm(() => {
217300
217985
  });
217301
217986
 
217302
217987
  // src/services/mcp/auth.ts
217303
- import { createHash as createHash10, randomBytes as randomBytes4, randomUUID as randomUUID8 } from "crypto";
217988
+ import { createHash as createHash10, randomBytes as randomBytes5, randomUUID as randomUUID8 } from "crypto";
217304
217989
  import { mkdir as mkdir13 } from "fs/promises";
217305
217990
  import { createServer as createServer3 } from "http";
217306
217991
  import { join as join60 } from "path";
@@ -218045,7 +218730,7 @@ class ClaudeAuthProvider {
218045
218730
  }
218046
218731
  async state() {
218047
218732
  if (!this._state) {
218048
- this._state = randomBytes4(32).toString("base64url");
218733
+ this._state = randomBytes5(32).toString("base64url");
218049
218734
  logMCPDebug(this.serverName, "Generated new OAuth state");
218050
218735
  }
218051
218736
  return this._state;
@@ -222035,7 +222720,7 @@ var require_websocket2 = __commonJS((exports, module) => {
222035
222720
  var http3 = __require("http");
222036
222721
  var net = __require("net");
222037
222722
  var tls = __require("tls");
222038
- var { randomBytes: randomBytes5, createHash: createHash11 } = __require("crypto");
222723
+ var { randomBytes: randomBytes6, createHash: createHash11 } = __require("crypto");
222039
222724
  var { Duplex: Duplex4, Readable: Readable6 } = __require("stream");
222040
222725
  var { URL: URL2 } = __require("url");
222041
222726
  var PerMessageDeflate = require_permessage_deflate2();
@@ -222447,7 +223132,7 @@ var require_websocket2 = __commonJS((exports, module) => {
222447
223132
  }
222448
223133
  }
222449
223134
  const defaultPort = isSecure ? 443 : 80;
222450
- const key = randomBytes5(16).toString("base64");
223135
+ const key = randomBytes6(16).toString("base64");
222451
223136
  const request = isSecure ? https2.request : http3.request;
222452
223137
  const protocolSet = new Set;
222453
223138
  let perMessageDeflate;
@@ -234757,14 +235442,14 @@ function resolveAgentProvider(name, subagentType, settings) {
234757
235442
  }
234758
235443
 
234759
235444
  // src/utils/uuid.ts
234760
- import { randomBytes as randomBytes5 } from "crypto";
235445
+ import { randomBytes as randomBytes6 } from "crypto";
234761
235446
  function validateUuid2(maybeUuid) {
234762
235447
  if (typeof maybeUuid !== "string")
234763
235448
  return null;
234764
235449
  return uuidRegex3.test(maybeUuid) ? maybeUuid : null;
234765
235450
  }
234766
235451
  function createAgentId(label) {
234767
- const suffix = randomBytes5(8).toString("hex");
235452
+ const suffix = randomBytes6(8).toString("hex");
234768
235453
  return label ? `a${label}-${suffix}` : `a${suffix}`;
234769
235454
  }
234770
235455
  var uuidRegex3;
@@ -279271,7 +279956,7 @@ var init_policyLimits = __esm(() => {
279271
279956
  });
279272
279957
 
279273
279958
  // src/utils/imagePaste.ts
279274
- import { randomBytes as randomBytes6 } from "crypto";
279959
+ import { randomBytes as randomBytes7 } from "crypto";
279275
279960
  import { basename as basename13, extname as extname5, isAbsolute as isAbsolute11, join as join68 } from "path";
279276
279961
  function buildLinuxClipboardCheckCommand() {
279277
279962
  const mimePattern = LINUX_CLIPBOARD_IMAGE_MIME_TYPES.map((mimeType) => mimeType.replace("/", "\\/")).join("|");
@@ -279392,7 +280077,7 @@ function stripBackslashEscapes(path13) {
279392
280077
  if (platform4 === "win32") {
279393
280078
  return path13;
279394
280079
  }
279395
- const salt = randomBytes6(8).toString("hex");
280080
+ const salt = randomBytes7(8).toString("hex");
279396
280081
  const placeholder = `__DOUBLE_BACKSLASH_${salt}__`;
279397
280082
  const withPlaceholder = path13.replace(/\\\\/g, placeholder);
279398
280083
  const withoutEscapes = withPlaceholder.replace(/\\(.)/g, "$1");
@@ -280172,7 +280857,7 @@ __export(exports_terminalSetup, {
280172
280857
  getNativeCSIuTerminalDisplayName: () => getNativeCSIuTerminalDisplayName,
280173
280858
  call: () => call
280174
280859
  });
280175
- import { randomBytes as randomBytes7 } from "crypto";
280860
+ import { randomBytes as randomBytes8 } from "crypto";
280176
280861
  import { copyFile as copyFile4, mkdir as mkdir17, readFile as readFile19, writeFile as writeFile14 } from "fs/promises";
280177
280862
  import { homedir as homedir23, platform as platform4 } from "os";
280178
280863
  import { dirname as dirname25, join as join72 } from "path";
@@ -280330,7 +281015,7 @@ async function installBindingsForVSCodeTerminal(editor = "VSCode", theme) {
280330
281015
  throw e;
280331
281016
  }
280332
281017
  if (fileExists) {
280333
- const randomSha = randomBytes7(4).toString("hex");
281018
+ const randomSha = randomBytes8(4).toString("hex");
280334
281019
  const backupPath = `${keybindingsPath}.${randomSha}.bak`;
280335
281020
  try {
280336
281021
  await copyFile4(keybindingsPath, backupPath);
@@ -280489,7 +281174,7 @@ chars = "\\u001B\\r"`;
280489
281174
  if (configContent.includes('mods = "Shift"') && configContent.includes('key = "Return"')) {
280490
281175
  return `${color("warning", theme)("Found existing Alacritty Shift+Enter key binding. Remove it to continue.")}${EOL2}${source_default.dim(`See ${formatPathLink(configPath)}`)}${EOL2}`;
280491
281176
  }
280492
- const randomSha = randomBytes7(4).toString("hex");
281177
+ const randomSha = randomBytes8(4).toString("hex");
280493
281178
  const backupPath = `${configPath}.${randomSha}.bak`;
280494
281179
  try {
280495
281180
  await copyFile4(configPath, backupPath);
@@ -280541,7 +281226,7 @@ async function installBindingsForZed(theme) {
280541
281226
  if (keymapContent.includes("shift-enter")) {
280542
281227
  return `${color("warning", theme)("Found existing Zed Shift+Enter key binding. Remove it to continue.")}${EOL2}${source_default.dim(`See ${formatPathLink(keymapPath)}`)}${EOL2}`;
280543
281228
  }
280544
- const randomSha = randomBytes7(4).toString("hex");
281229
+ const randomSha = randomBytes8(4).toString("hex");
280545
281230
  const backupPath = `${keymapPath}.${randomSha}.bak`;
280546
281231
  try {
280547
281232
  await copyFile4(keymapPath, backupPath);
@@ -288219,12 +288904,12 @@ var init_auth_code_listener = __esm(() => {
288219
288904
  });
288220
288905
 
288221
288906
  // src/services/oauth/crypto.ts
288222
- import { randomBytes as randomBytes8, webcrypto } from "crypto";
288907
+ import { randomBytes as randomBytes9, webcrypto } from "crypto";
288223
288908
  function base64URLEncode(buffer) {
288224
288909
  return buffer.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
288225
288910
  }
288226
288911
  function generateCodeVerifier() {
288227
- return base64URLEncode(randomBytes8(32));
288912
+ return base64URLEncode(randomBytes9(32));
288228
288913
  }
288229
288914
  async function generateCodeChallenge(verifier) {
288230
288915
  const encoded = new TextEncoder().encode(verifier);
@@ -288232,7 +288917,7 @@ async function generateCodeChallenge(verifier) {
288232
288917
  return base64URLEncode(Buffer.from(digest));
288233
288918
  }
288234
288919
  function generateState() {
288235
- return base64URLEncode(randomBytes8(32));
288920
+ return base64URLEncode(randomBytes9(32));
288236
288921
  }
288237
288922
  var init_crypto2 = () => {};
288238
288923
 
@@ -291712,684 +292397,6 @@ var init_notifier = __esm(() => {
291712
292397
  init_log3();
291713
292398
  });
291714
292399
 
291715
- // src/providers/providerModels.ts
291716
- function parseModelList(modelField) {
291717
- return modelField.split(",").map((part) => part.trim()).filter((part) => part.length > 0);
291718
- }
291719
- function getPrimaryModel(modelField) {
291720
- const models = parseModelList(modelField);
291721
- return models.length > 0 ? models[0] : modelField;
291722
- }
291723
-
291724
- // src/providers/providerProfiles.ts
291725
- import { randomBytes as randomBytes9 } from "crypto";
291726
- function trimValue(value) {
291727
- return value?.trim() ?? "";
291728
- }
291729
- function trimOrUndefined(value) {
291730
- const trimmed = trimValue(value);
291731
- return trimmed.length > 0 ? trimmed : undefined;
291732
- }
291733
- function normalizeBaseUrl(value) {
291734
- return trimValue(value).replace(/\/+$/, "");
291735
- }
291736
- function sanitizeProfile(profile) {
291737
- const id = trimValue(profile.id);
291738
- const name = trimValue(profile.name);
291739
- const provider = profile.provider === "anthropic" ? "anthropic" : "openai";
291740
- const baseUrl = normalizeBaseUrl(profile.baseUrl);
291741
- const model = trimValue(profile.model);
291742
- if (!id || !name || !baseUrl || !model) {
291743
- return null;
291744
- }
291745
- return {
291746
- id,
291747
- name,
291748
- provider,
291749
- baseUrl,
291750
- model,
291751
- apiKey: trimOrUndefined(profile.apiKey)
291752
- };
291753
- }
291754
- function sanitizeProfiles(profiles) {
291755
- const seen = new Set;
291756
- const sanitized = [];
291757
- for (const profile of profiles ?? []) {
291758
- const normalized = sanitizeProfile(profile);
291759
- if (!normalized || seen.has(normalized.id)) {
291760
- continue;
291761
- }
291762
- seen.add(normalized.id);
291763
- sanitized.push(normalized);
291764
- }
291765
- return sanitized;
291766
- }
291767
- function nextProfileId() {
291768
- return `provider_${randomBytes9(6).toString("hex")}`;
291769
- }
291770
- function toProfile(input, id = nextProfileId()) {
291771
- return sanitizeProfile({
291772
- id,
291773
- provider: input.provider ?? "openai",
291774
- name: input.name,
291775
- baseUrl: input.baseUrl,
291776
- model: input.model,
291777
- apiKey: input.apiKey
291778
- });
291779
- }
291780
- function getModelCacheByProfile(profileId, config2 = getGlobalConfig()) {
291781
- return config2.openaiAdditionalModelOptionsCacheByProfile?.[profileId] ?? [];
291782
- }
291783
- function getProviderPresetDefaults(preset) {
291784
- switch (preset) {
291785
- case "anthropic":
291786
- return {
291787
- provider: "anthropic",
291788
- name: "Anthropic",
291789
- baseUrl: process.env.ANTHROPIC_BASE_URL ?? "https://api.anthropic.com",
291790
- model: process.env.ANTHROPIC_MODEL ?? "claude-sonnet-4-6",
291791
- apiKey: process.env.ANTHROPIC_API_KEY ?? "",
291792
- requiresApiKey: true
291793
- };
291794
- case "openai":
291795
- return {
291796
- provider: "openai",
291797
- name: "OpenAI",
291798
- baseUrl: "https://api.openai.com/v1",
291799
- model: "gpt-5.3-codex",
291800
- apiKey: "",
291801
- requiresApiKey: true
291802
- };
291803
- case "moonshotai":
291804
- return {
291805
- provider: "openai",
291806
- name: "Moonshot AI",
291807
- baseUrl: "https://api.moonshot.ai/v1",
291808
- model: "kimi-k2.5",
291809
- apiKey: "",
291810
- requiresApiKey: true
291811
- };
291812
- case "deepseek":
291813
- return {
291814
- provider: "openai",
291815
- name: "DeepSeek",
291816
- baseUrl: "https://api.deepseek.com/v1",
291817
- model: "deepseek-chat",
291818
- apiKey: "",
291819
- requiresApiKey: true
291820
- };
291821
- case "gemini":
291822
- return {
291823
- provider: "openai",
291824
- name: "Google Gemini",
291825
- baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai",
291826
- model: "gemini-3-flash-preview",
291827
- apiKey: "",
291828
- requiresApiKey: true
291829
- };
291830
- case "mistral":
291831
- return {
291832
- provider: "openai",
291833
- name: "Mistral",
291834
- baseUrl: "https://api.mistral.ai/v1",
291835
- model: "devstral-latest",
291836
- apiKey: "",
291837
- requiresApiKey: true
291838
- };
291839
- case "together":
291840
- return {
291841
- provider: "openai",
291842
- name: "Together AI",
291843
- baseUrl: "https://api.together.xyz/v1",
291844
- model: "Qwen/Qwen3.5-9B",
291845
- apiKey: "",
291846
- requiresApiKey: true
291847
- };
291848
- case "groq":
291849
- return {
291850
- provider: "openai",
291851
- name: "Groq",
291852
- baseUrl: "https://api.groq.com/openai/v1",
291853
- model: "llama-3.3-70b-versatile",
291854
- apiKey: "",
291855
- requiresApiKey: true
291856
- };
291857
- case "azure-openai":
291858
- return {
291859
- provider: "openai",
291860
- name: "Azure OpenAI",
291861
- baseUrl: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1",
291862
- model: "YOUR-DEPLOYMENT-NAME",
291863
- apiKey: "",
291864
- requiresApiKey: true
291865
- };
291866
- case "openrouter":
291867
- return {
291868
- provider: "openai",
291869
- name: "OpenRouter",
291870
- baseUrl: "https://openrouter.ai/api/v1",
291871
- model: "openai/gpt-5-mini",
291872
- apiKey: "",
291873
- requiresApiKey: true
291874
- };
291875
- case "lmstudio":
291876
- return {
291877
- provider: "openai",
291878
- name: "LM Studio",
291879
- baseUrl: "http://localhost:1234/v1",
291880
- model: "local-model",
291881
- apiKey: "",
291882
- requiresApiKey: false
291883
- };
291884
- case "custom":
291885
- return {
291886
- provider: "openai",
291887
- name: "Custom OpenAI-compatible",
291888
- baseUrl: process.env.OPENAI_BASE_URL ?? process.env.OPENAI_API_BASE ?? DEFAULT_OLLAMA_BASE_URL2,
291889
- model: process.env.OPENAI_MODEL ?? DEFAULT_OLLAMA_MODEL,
291890
- apiKey: process.env.OPENAI_API_KEY ?? "",
291891
- requiresApiKey: false
291892
- };
291893
- case "nvidia-nim":
291894
- return {
291895
- provider: "openai",
291896
- name: "NVIDIA NIM",
291897
- baseUrl: "https://integrate.api.nvidia.com/v1",
291898
- model: "nvidia/llama-3.1-nemotron-70b-instruct",
291899
- apiKey: process.env.NVIDIA_API_KEY ?? "",
291900
- requiresApiKey: true
291901
- };
291902
- case "minimax":
291903
- return {
291904
- provider: "openai",
291905
- name: "MiniMax",
291906
- baseUrl: "https://api.minimax.io/v1",
291907
- model: "MiniMax-M2.5",
291908
- apiKey: process.env.MINIMAX_API_KEY ?? "",
291909
- requiresApiKey: true
291910
- };
291911
- case "ollama-cloud":
291912
- return {
291913
- provider: "openai",
291914
- name: "Ollama Cloud",
291915
- baseUrl: "https://ollama.com/v1",
291916
- model: process.env.OPENAI_MODEL ?? "deepseek-v3.2",
291917
- apiKey: process.env.OLLAMA_API_KEY ?? "",
291918
- requiresApiKey: true
291919
- };
291920
- case "deepinfra":
291921
- return {
291922
- provider: "openai",
291923
- name: "DeepInfra",
291924
- baseUrl: "https://api.deepinfra.com/v1/openai",
291925
- model: "meta-llama/Llama-4-Maverick-17B-128E-Instruct",
291926
- apiKey: "",
291927
- requiresApiKey: true
291928
- };
291929
- case "cerebras":
291930
- return {
291931
- provider: "openai",
291932
- name: "Cerebras",
291933
- baseUrl: "https://api.cerebras.ai/v1",
291934
- model: "llama-4-scout-17b-16e",
291935
- apiKey: "",
291936
- requiresApiKey: true
291937
- };
291938
- case "cohere":
291939
- return {
291940
- provider: "openai",
291941
- name: "Cohere",
291942
- baseUrl: "https://api.cohere.com/v2",
291943
- model: "command-r-plus",
291944
- apiKey: "",
291945
- requiresApiKey: true
291946
- };
291947
- case "perplexity":
291948
- return {
291949
- provider: "openai",
291950
- name: "Perplexity",
291951
- baseUrl: "https://api.perplexity.ai",
291952
- model: "sonar-pro",
291953
- apiKey: "",
291954
- requiresApiKey: true
291955
- };
291956
- case "xai":
291957
- return {
291958
- provider: "openai",
291959
- name: "xAI (Grok)",
291960
- baseUrl: "https://api.x.ai/v1",
291961
- model: "grok-3",
291962
- apiKey: "",
291963
- requiresApiKey: true
291964
- };
291965
- case "venice":
291966
- return {
291967
- provider: "openai",
291968
- name: "Venice",
291969
- baseUrl: "https://api.venice.ai/api/v1",
291970
- model: "deepseek-r1-671b",
291971
- apiKey: "",
291972
- requiresApiKey: true
291973
- };
291974
- case "gitlab":
291975
- return {
291976
- provider: "openai",
291977
- name: "GitLab",
291978
- baseUrl: "https://gitlab.com/api/v4/ai/v1",
291979
- model: "claude-3-5-sonnet",
291980
- apiKey: "",
291981
- requiresApiKey: true
291982
- };
291983
- case "cloudflare":
291984
- return {
291985
- provider: "openai",
291986
- name: "Cloudflare Workers AI",
291987
- baseUrl: "https://api.cloudflare.com/client/v4/accounts/YOUR_ACCOUNT_ID/ai/v1",
291988
- model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast",
291989
- apiKey: "",
291990
- requiresApiKey: true
291991
- };
291992
- case "vercel":
291993
- return {
291994
- provider: "openai",
291995
- name: "Vercel",
291996
- baseUrl: "https://api.vercel.ai/v1",
291997
- model: "anthropic:claude-sonnet-4-6",
291998
- apiKey: "",
291999
- requiresApiKey: true
292000
- };
292001
- case "sap-ai-core":
292002
- return {
292003
- provider: "openai",
292004
- name: "SAP AI Core",
292005
- baseUrl: "https://api.ai.prod.YOUR_REGION.ml.hana.ondemand.com/v2/inference/deployments/YOUR_DEPLOYMENT_ID",
292006
- model: "gpt-4o",
292007
- apiKey: "",
292008
- requiresApiKey: true
292009
- };
292010
- case "opencode":
292011
- return {
292012
- provider: "openai",
292013
- name: "OpenCode Zen",
292014
- baseUrl: "https://opencode.ai/zen/v1",
292015
- model: "gpt-5.4",
292016
- apiKey: process.env.OPENCODE_API_KEY ?? "",
292017
- requiresApiKey: true
292018
- };
292019
- case "opencode-go":
292020
- return {
292021
- provider: "openai",
292022
- name: "OpenCode Go",
292023
- baseUrl: "https://opencode.ai/zen/go/v1",
292024
- model: "glm-5",
292025
- apiKey: process.env.OPENCODE_API_KEY ?? "",
292026
- requiresApiKey: true
292027
- };
292028
- case "ollama":
292029
- default:
292030
- return {
292031
- provider: "openai",
292032
- name: "Ollama",
292033
- baseUrl: DEFAULT_OLLAMA_BASE_URL2,
292034
- model: process.env.OPENAI_MODEL ?? DEFAULT_OLLAMA_MODEL,
292035
- apiKey: "",
292036
- requiresApiKey: false
292037
- };
292038
- }
292039
- }
292040
- function getProviderProfiles(config2 = getGlobalConfig()) {
292041
- return sanitizeProfiles(config2.providerProfiles);
292042
- }
292043
- function hasProviderSelectionFlags(processEnv = process.env) {
292044
- return processEnv.CLAUDE_CODE_USE_OPENAI !== undefined || processEnv.CLAUDE_CODE_USE_GEMINI !== undefined || processEnv.CLAUDE_CODE_USE_MISTRAL !== undefined || processEnv.CLAUDE_CODE_USE_GITHUB !== undefined || processEnv.CLAUDE_CODE_USE_BEDROCK !== undefined || processEnv.CLAUDE_CODE_USE_VERTEX !== undefined || processEnv.CLAUDE_CODE_USE_FOUNDRY !== undefined;
292045
- }
292046
- function hasConflictingProviderFlagsForProfile(processEnv, profile) {
292047
- if (profile.provider === "anthropic") {
292048
- return hasProviderSelectionFlags(processEnv);
292049
- }
292050
- return processEnv.CLAUDE_CODE_USE_GEMINI !== undefined || processEnv.CLAUDE_CODE_USE_GITHUB !== undefined || processEnv.CLAUDE_CODE_USE_BEDROCK !== undefined || processEnv.CLAUDE_CODE_USE_VERTEX !== undefined || processEnv.CLAUDE_CODE_USE_FOUNDRY !== undefined;
292051
- }
292052
- function sameOptionalEnvValue(left, right) {
292053
- return trimOrUndefined(left) === trimOrUndefined(right);
292054
- }
292055
- function isProcessEnvAlignedWithProfile(processEnv, profile, options2) {
292056
- const includeApiKey = options2?.includeApiKey ?? true;
292057
- if (processEnv[PROFILE_ENV_APPLIED_FLAG] !== "1") {
292058
- return false;
292059
- }
292060
- if (trimOrUndefined(processEnv[PROFILE_ENV_APPLIED_ID]) !== profile.id) {
292061
- return false;
292062
- }
292063
- if (profile.provider === "anthropic") {
292064
- return !hasProviderSelectionFlags(processEnv) && sameOptionalEnvValue(processEnv.ANTHROPIC_BASE_URL, profile.baseUrl) && sameOptionalEnvValue(processEnv.ANTHROPIC_MODEL, getPrimaryModel(profile.model)) && (!includeApiKey || sameOptionalEnvValue(processEnv.ANTHROPIC_API_KEY, profile.apiKey));
292065
- }
292066
- return processEnv.CLAUDE_CODE_USE_OPENAI !== undefined && processEnv.CLAUDE_CODE_USE_GEMINI === undefined && processEnv.CLAUDE_CODE_USE_MISTRAL === undefined && processEnv.CLAUDE_CODE_USE_GITHUB === undefined && processEnv.CLAUDE_CODE_USE_BEDROCK === undefined && processEnv.CLAUDE_CODE_USE_VERTEX === undefined && processEnv.CLAUDE_CODE_USE_FOUNDRY === undefined && sameOptionalEnvValue(processEnv.OPENAI_BASE_URL, profile.baseUrl) && sameOptionalEnvValue(processEnv.OPENAI_MODEL, getPrimaryModel(profile.model)) && (!includeApiKey || sameOptionalEnvValue(processEnv.OPENAI_API_KEY, profile.apiKey));
292067
- }
292068
- function getActiveProviderProfile(config2 = getGlobalConfig()) {
292069
- const profiles = getProviderProfiles(config2);
292070
- if (profiles.length === 0) {
292071
- return;
292072
- }
292073
- const activeId = trimOrUndefined(config2.activeProviderProfileId);
292074
- return profiles.find((profile) => profile.id === activeId) ?? profiles[0];
292075
- }
292076
- function clearProviderProfileEnvFromProcessEnv(processEnv = process.env) {
292077
- delete processEnv.CLAUDE_CODE_USE_OPENAI;
292078
- delete processEnv.CLAUDE_CODE_USE_GEMINI;
292079
- delete processEnv.CLAUDE_CODE_USE_MISTRAL;
292080
- delete processEnv.CLAUDE_CODE_USE_GITHUB;
292081
- delete processEnv.CLAUDE_CODE_USE_BEDROCK;
292082
- delete processEnv.CLAUDE_CODE_USE_VERTEX;
292083
- delete processEnv.CLAUDE_CODE_USE_FOUNDRY;
292084
- delete processEnv.OPENAI_BASE_URL;
292085
- delete processEnv.OPENAI_API_BASE;
292086
- delete processEnv.OPENAI_MODEL;
292087
- delete processEnv.OPENAI_API_KEY;
292088
- delete processEnv.ANTHROPIC_BASE_URL;
292089
- delete processEnv.ANTHROPIC_MODEL;
292090
- delete processEnv.ANTHROPIC_API_KEY;
292091
- delete processEnv[PROFILE_ENV_APPLIED_FLAG];
292092
- delete processEnv[PROFILE_ENV_APPLIED_ID];
292093
- delete processEnv.MINIMAX_API_KEY;
292094
- delete processEnv.NVIDIA_API_KEY;
292095
- delete processEnv.NVIDIA_NIM;
292096
- delete processEnv.OPENCODE_API_KEY;
292097
- }
292098
- function applyProviderProfileToProcessEnv(profile) {
292099
- clearProviderProfileEnvFromProcessEnv();
292100
- process.env[PROFILE_ENV_APPLIED_FLAG] = "1";
292101
- process.env[PROFILE_ENV_APPLIED_ID] = profile.id;
292102
- process.env.ANTHROPIC_MODEL = getPrimaryModel(profile.model);
292103
- if (profile.provider === "anthropic") {
292104
- process.env.ANTHROPIC_BASE_URL = profile.baseUrl;
292105
- if (profile.apiKey) {
292106
- process.env.ANTHROPIC_API_KEY = profile.apiKey;
292107
- } else {
292108
- delete process.env.ANTHROPIC_API_KEY;
292109
- }
292110
- delete process.env.OPENAI_BASE_URL;
292111
- delete process.env.OPENAI_API_BASE;
292112
- delete process.env.OPENAI_MODEL;
292113
- delete process.env.OPENAI_API_KEY;
292114
- return;
292115
- }
292116
- process.env.CLAUDE_CODE_USE_OPENAI = "1";
292117
- process.env.OPENAI_BASE_URL = profile.baseUrl;
292118
- process.env.OPENAI_MODEL = getPrimaryModel(profile.model);
292119
- if (profile.apiKey) {
292120
- process.env.OPENAI_API_KEY = profile.apiKey;
292121
- const baseUrl = profile.baseUrl.toLowerCase();
292122
- if (baseUrl.includes("minimax")) {
292123
- process.env.MINIMAX_API_KEY = profile.apiKey;
292124
- }
292125
- if (baseUrl.includes("nvidia") || baseUrl.includes("integrate.api.nvidia")) {
292126
- process.env.NVIDIA_API_KEY = profile.apiKey;
292127
- }
292128
- } else {
292129
- delete process.env.OPENAI_API_KEY;
292130
- }
292131
- }
292132
- function applyActiveProviderProfileFromConfig(config2 = getGlobalConfig(), options2) {
292133
- const processEnv = options2?.processEnv ?? process.env;
292134
- const activeProfile = getActiveProviderProfile(config2);
292135
- if (!activeProfile) {
292136
- return;
292137
- }
292138
- const isCurrentEnvProfileManaged = processEnv[PROFILE_ENV_APPLIED_FLAG] === "1" && trimOrUndefined(processEnv[PROFILE_ENV_APPLIED_ID]) === activeProfile.id;
292139
- if (!options2?.force && (hasProviderSelectionFlags(processEnv) || processEnv[PROFILE_ENV_APPLIED_FLAG] === "1")) {
292140
- if (!isCurrentEnvProfileManaged) {
292141
- return;
292142
- }
292143
- if (hasConflictingProviderFlagsForProfile(processEnv, activeProfile)) {
292144
- return;
292145
- }
292146
- if (isProcessEnvAlignedWithProfile(processEnv, activeProfile)) {
292147
- return activeProfile;
292148
- }
292149
- }
292150
- applyProviderProfileToProcessEnv(activeProfile);
292151
- return activeProfile;
292152
- }
292153
- function addProviderProfile(input, options2) {
292154
- const profile = toProfile(input);
292155
- if (!profile) {
292156
- return null;
292157
- }
292158
- const makeActive = options2?.makeActive ?? true;
292159
- saveGlobalConfig((current) => {
292160
- const currentProfiles = getProviderProfiles(current);
292161
- const nextProfiles = [...currentProfiles, profile];
292162
- const currentActive = trimOrUndefined(current.activeProviderProfileId);
292163
- const nextActiveId = makeActive || !currentActive || !nextProfiles.some((p) => p.id === currentActive) ? profile.id : currentActive;
292164
- return {
292165
- ...current,
292166
- providerProfiles: nextProfiles,
292167
- activeProviderProfileId: nextActiveId
292168
- };
292169
- });
292170
- const activeProfile = getActiveProviderProfile();
292171
- if (activeProfile?.id === profile.id) {
292172
- applyProviderProfileToProcessEnv(profile);
292173
- clearActiveOpenAIModelOptionsCache();
292174
- }
292175
- return profile;
292176
- }
292177
- function updateProviderProfile(profileId, input) {
292178
- const updatedProfile = toProfile(input, profileId);
292179
- if (!updatedProfile) {
292180
- return null;
292181
- }
292182
- let wasUpdated = false;
292183
- let shouldApply = false;
292184
- saveGlobalConfig((current) => {
292185
- const currentProfiles = getProviderProfiles(current);
292186
- const profileIndex = currentProfiles.findIndex((profile) => profile.id === profileId);
292187
- if (profileIndex < 0) {
292188
- return current;
292189
- }
292190
- wasUpdated = true;
292191
- const nextProfiles = [...currentProfiles];
292192
- nextProfiles[profileIndex] = updatedProfile;
292193
- const cacheByProfile = {
292194
- ...current.openaiAdditionalModelOptionsCacheByProfile ?? {}
292195
- };
292196
- delete cacheByProfile[profileId];
292197
- const currentActive = trimOrUndefined(current.activeProviderProfileId);
292198
- const nextActiveId = currentActive && nextProfiles.some((profile) => profile.id === currentActive) ? currentActive : nextProfiles[0]?.id;
292199
- shouldApply = nextActiveId === profileId;
292200
- return {
292201
- ...current,
292202
- providerProfiles: nextProfiles,
292203
- activeProviderProfileId: nextActiveId,
292204
- openaiAdditionalModelOptionsCacheByProfile: cacheByProfile,
292205
- openaiAdditionalModelOptionsCache: shouldApply ? [] : current.openaiAdditionalModelOptionsCache
292206
- };
292207
- });
292208
- if (!wasUpdated) {
292209
- return null;
292210
- }
292211
- if (shouldApply) {
292212
- applyProviderProfileToProcessEnv(updatedProfile);
292213
- }
292214
- return updatedProfile;
292215
- }
292216
- function persistActiveProviderProfileModel(model) {
292217
- const nextModel = trimOrUndefined(model);
292218
- if (!nextModel) {
292219
- return null;
292220
- }
292221
- const activeProfile = getActiveProviderProfile();
292222
- if (!activeProfile) {
292223
- return null;
292224
- }
292225
- const existingModels = parseModelList(activeProfile.model);
292226
- if (existingModels.includes(nextModel)) {
292227
- return activeProfile;
292228
- }
292229
- saveGlobalConfig((current) => {
292230
- const currentProfiles = getProviderProfiles(current);
292231
- const profileIndex = currentProfiles.findIndex((profile) => profile.id === activeProfile.id);
292232
- if (profileIndex < 0) {
292233
- return current;
292234
- }
292235
- const currentProfile = currentProfiles[profileIndex];
292236
- if (currentProfile.model === nextModel) {
292237
- return current;
292238
- }
292239
- const nextProfiles = [...currentProfiles];
292240
- nextProfiles[profileIndex] = {
292241
- ...currentProfile,
292242
- model: nextModel
292243
- };
292244
- return {
292245
- ...current,
292246
- providerProfiles: nextProfiles
292247
- };
292248
- });
292249
- const resolvedProfile = getActiveProviderProfile();
292250
- if (!resolvedProfile || resolvedProfile.id !== activeProfile.id) {
292251
- return null;
292252
- }
292253
- if (process.env[PROFILE_ENV_APPLIED_FLAG] === "1" && trimOrUndefined(process.env[PROFILE_ENV_APPLIED_ID]) === resolvedProfile.id) {
292254
- applyProviderProfileToProcessEnv(resolvedProfile);
292255
- }
292256
- return resolvedProfile;
292257
- }
292258
- function getProfileModelOptions(profile) {
292259
- const models = parseModelList(profile.model);
292260
- if (models.length === 0) {
292261
- return [];
292262
- }
292263
- return models.map((model) => ({
292264
- value: model,
292265
- label: model,
292266
- description: `Provider: ${profile.name}`
292267
- }));
292268
- }
292269
- function setActiveProviderProfile(profileId) {
292270
- const current = getGlobalConfig();
292271
- const profiles = getProviderProfiles(current);
292272
- const activeProfile = profiles.find((profile) => profile.id === profileId);
292273
- if (!activeProfile) {
292274
- return null;
292275
- }
292276
- const profileModelOptions = getProfileModelOptions(activeProfile);
292277
- saveGlobalConfig((config2) => ({
292278
- ...config2,
292279
- activeProviderProfileId: profileId,
292280
- openaiAdditionalModelOptionsCache: profileModelOptions.length > 0 ? profileModelOptions : getModelCacheByProfile(profileId, config2),
292281
- openaiAdditionalModelOptionsCacheByProfile: {
292282
- ...config2.openaiAdditionalModelOptionsCacheByProfile ?? {},
292283
- [profileId]: profileModelOptions.length > 0 ? profileModelOptions : config2.openaiAdditionalModelOptionsCacheByProfile?.[profileId] ?? []
292284
- }
292285
- }));
292286
- applyProviderProfileToProcessEnv(activeProfile);
292287
- return activeProfile;
292288
- }
292289
- function deleteProviderProfile(profileId) {
292290
- let removed = false;
292291
- let deletedProfile;
292292
- let nextActiveProfile;
292293
- saveGlobalConfig((current) => {
292294
- const currentProfiles = getProviderProfiles(current);
292295
- const existing = currentProfiles.find((profile) => profile.id === profileId);
292296
- if (!existing) {
292297
- return current;
292298
- }
292299
- removed = true;
292300
- deletedProfile = existing;
292301
- const nextProfiles = currentProfiles.filter((profile) => profile.id !== profileId);
292302
- const currentActive = trimOrUndefined(current.activeProviderProfileId);
292303
- const activeWasDeleted = !currentActive || currentActive === profileId || !nextProfiles.some((profile) => profile.id === currentActive);
292304
- const nextActiveId = activeWasDeleted ? nextProfiles[0]?.id : currentActive;
292305
- if (nextActiveId) {
292306
- nextActiveProfile = nextProfiles.find((profile) => profile.id === nextActiveId) ?? nextProfiles[0];
292307
- }
292308
- const cacheByProfile = {
292309
- ...current.openaiAdditionalModelOptionsCacheByProfile ?? {}
292310
- };
292311
- delete cacheByProfile[profileId];
292312
- return {
292313
- ...current,
292314
- providerProfiles: nextProfiles,
292315
- activeProviderProfileId: nextActiveId,
292316
- openaiAdditionalModelOptionsCacheByProfile: cacheByProfile,
292317
- openaiAdditionalModelOptionsCache: nextActiveId ? getModelCacheByProfile(nextActiveId, {
292318
- ...current,
292319
- openaiAdditionalModelOptionsCacheByProfile: cacheByProfile
292320
- }) : []
292321
- };
292322
- });
292323
- if (nextActiveProfile) {
292324
- applyProviderProfileToProcessEnv(nextActiveProfile);
292325
- } else if (deletedProfile && isProcessEnvAlignedWithProfile(process.env, deletedProfile, {
292326
- includeApiKey: false
292327
- })) {
292328
- clearProviderProfileEnvFromProcessEnv();
292329
- }
292330
- return {
292331
- removed,
292332
- activeProfileId: nextActiveProfile?.id
292333
- };
292334
- }
292335
- function getActiveOpenAIModelOptionsCache(config2 = getGlobalConfig()) {
292336
- const activeProfile = getActiveProviderProfile(config2);
292337
- if (!activeProfile) {
292338
- return config2.openaiAdditionalModelOptionsCache ?? [];
292339
- }
292340
- const cached3 = config2.openaiAdditionalModelOptionsCacheByProfile?.[activeProfile.id];
292341
- if (cached3) {
292342
- return cached3;
292343
- }
292344
- if (Object.keys(config2.openaiAdditionalModelOptionsCacheByProfile ?? {}).length === 0) {
292345
- return config2.openaiAdditionalModelOptionsCache ?? [];
292346
- }
292347
- return [];
292348
- }
292349
- function setActiveOpenAIModelOptionsCache(options2) {
292350
- const activeProfile = getActiveProviderProfile();
292351
- if (!activeProfile) {
292352
- saveGlobalConfig((current) => ({
292353
- ...current,
292354
- openaiAdditionalModelOptionsCache: options2
292355
- }));
292356
- return;
292357
- }
292358
- saveGlobalConfig((current) => ({
292359
- ...current,
292360
- openaiAdditionalModelOptionsCache: options2,
292361
- openaiAdditionalModelOptionsCacheByProfile: {
292362
- ...current.openaiAdditionalModelOptionsCacheByProfile ?? {},
292363
- [activeProfile.id]: options2
292364
- }
292365
- }));
292366
- }
292367
- function clearActiveOpenAIModelOptionsCache() {
292368
- const activeProfile = getActiveProviderProfile();
292369
- if (!activeProfile) {
292370
- saveGlobalConfig((current) => ({
292371
- ...current,
292372
- openaiAdditionalModelOptionsCache: []
292373
- }));
292374
- return;
292375
- }
292376
- saveGlobalConfig((current) => {
292377
- const cacheByProfile = {
292378
- ...current.openaiAdditionalModelOptionsCacheByProfile ?? {}
292379
- };
292380
- delete cacheByProfile[activeProfile.id];
292381
- return {
292382
- ...current,
292383
- openaiAdditionalModelOptionsCache: [],
292384
- openaiAdditionalModelOptionsCacheByProfile: cacheByProfile
292385
- };
292386
- });
292387
- }
292388
- var DEFAULT_OLLAMA_BASE_URL2 = "http://localhost:11434/v1", DEFAULT_OLLAMA_MODEL = "llama3.1:8b", PROFILE_ENV_APPLIED_FLAG = "CLAUDE_CODE_PROVIDER_PROFILE_ENV_APPLIED", PROFILE_ENV_APPLIED_ID = "CLAUDE_CODE_PROVIDER_PROFILE_ENV_APPLIED_ID";
292389
- var init_providerProfiles = __esm(() => {
292390
- init_config8();
292391
- });
292392
-
292393
292400
  // src/services/api/codexOAuth.ts
292394
292401
  function buildCodexAuthorizeUrl(options2) {
292395
292402
  const redirectUri = `http://localhost:${options2.port}/auth/callback`;
@@ -350446,7 +350453,7 @@ function getAnthropicEnvMetadata() {
350446
350453
  function getBuildAgeMinutes() {
350447
350454
  if (false)
350448
350455
  ;
350449
- const buildTime = new Date("2026-05-05T05:08:44.087Z").getTime();
350456
+ const buildTime = new Date("2026-05-05T05:25:24.607Z").getTime();
350450
350457
  if (isNaN(buildTime))
350451
350458
  return;
350452
350459
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -417589,7 +417596,7 @@ function buildPrimarySection() {
417589
417596
  }, undefined, false, undefined, this);
417590
417597
  return [{
417591
417598
  label: "Version",
417592
- value: "0.3.30"
417599
+ value: "0.3.32"
417593
417600
  }, {
417594
417601
  label: "Session name",
417595
417602
  value: nameValue
@@ -457206,10 +457213,34 @@ function detectProvider() {
457206
457213
  }
457207
457214
  return { name, model: displayModel, baseUrl, isLocal };
457208
457215
  }
457216
+ const activeProfile = getActiveProviderProfile();
457217
+ if (activeProfile && activeProfile.provider !== "anthropic") {
457218
+ const baseUrl = activeProfile.baseUrl || "https://api.openai.com/v1";
457219
+ const isLocal = isLocalProviderUrl(baseUrl);
457220
+ let name = activeProfile.name || "OpenAI";
457221
+ const rawModel = activeProfile.model?.split(",")[0]?.trim() || "unknown";
457222
+ const resolvedRequest = resolveProviderRequest({
457223
+ model: rawModel,
457224
+ baseUrl
457225
+ });
457226
+ if (/nvidia/i.test(baseUrl) || /nvidia/i.test(rawModel))
457227
+ name = "NVIDIA NIM";
457228
+ else if (resolvedRequest.transport === "codex_responses" || baseUrl.includes("chatgpt.com/backend-api/codex"))
457229
+ name = "Codex";
457230
+ else if (/deepseek/i.test(baseUrl) || /deepseek/i.test(rawModel))
457231
+ name = "DeepSeek";
457232
+ else if (isLocal)
457233
+ name = getLocalOpenAICompatibleProviderLabel(baseUrl);
457234
+ let displayModel = resolvedRequest.resolvedModel;
457235
+ if (resolvedRequest.reasoning?.effort) {
457236
+ displayModel = `${displayModel} (${resolvedRequest.reasoning.effort})`;
457237
+ }
457238
+ return { name, model: displayModel, baseUrl, isLocal };
457239
+ }
457209
457240
  const settings = getSettings_DEPRECATED() || {};
457210
457241
  const modelSetting = settings.model || process.env.ANTHROPIC_MODEL || process.env.CLAUDE_MODEL || "claude-sonnet-4-6";
457211
457242
  const resolvedModel = parseUserSpecifiedModel(modelSetting);
457212
- return { name: "Anthropic", model: resolvedModel, baseUrl: "https://api.anthropic.com", isLocal: false };
457243
+ return { name: "Anthropic", model: resolvedModel, baseUrl: process.env.ANTHROPIC_BASE_URL || "https://api.anthropic.com", isLocal: false };
457213
457244
  }
457214
457245
  function boxRow(content, width, rawLen) {
457215
457246
  const pad = Math.max(0, width - 2 - rawLen);
@@ -457259,7 +457290,7 @@ function getStartupLines(termWidth) {
457259
457290
  const sLen = ` ● ${sL} buffer ready — /help for breach controls`.length;
457260
457291
  out.push(centerAnsiLine(boxRow(sRow, W2, sLen), tw));
457261
457292
  out.push(centerAnsiLine(`${rgb3(...BORDER)}└${"─".repeat(W2 - 2)}┘${RESET2}`, tw));
457262
- out.push(centerAnsiLine(`${rgb3(...DIMCOL)}STRATAGEM X7${RESET2} ${rgb3(...ACCENT)}v${"0.3.30"}${RESET2} ${rgb3(...CYAN)}// breach link stable${RESET2}`, tw));
457293
+ out.push(centerAnsiLine(`${rgb3(...DIMCOL)}STRATAGEM X7${RESET2} ${rgb3(...ACCENT)}v${"0.3.32"}${RESET2} ${rgb3(...CYAN)}// breach link stable${RESET2}`, tw));
457263
457294
  out.push("");
457264
457295
  return out;
457265
457296
  }
@@ -457267,6 +457298,7 @@ var ESC3 = "\x1B[", RESET2, DIM2, rgb3 = (r, g, b) => `${ESC3}38;2;${r};${g};${b
457267
457298
  var init_StartupScreen = __esm(() => {
457268
457299
  init_providerConfig();
457269
457300
  init_providerDiscovery();
457301
+ init_providerProfiles();
457270
457302
  init_settings2();
457271
457303
  init_model();
457272
457304
  RESET2 = `${ESC3}0m`;
@@ -458645,6 +458677,21 @@ function ScrollIndicator({
458645
458677
  const scrollTop = Number(parts[0]);
458646
458678
  const scrollHeight = Number(parts[1]);
458647
458679
  const viewportHeight = Number(parts[2]);
458680
+ const handleClick = import_react151.useCallback((event) => {
458681
+ const s = scrollRef?.current;
458682
+ if (!s)
458683
+ return;
458684
+ const sh = s.getScrollHeight();
458685
+ const vh = s.getViewportHeight();
458686
+ if (sh <= vh)
458687
+ return;
458688
+ const trackHeight2 = Math.max(3, vh - 1);
458689
+ const clickFraction = trackHeight2 > 1 ? event.localRow / (trackHeight2 - 1) : 0;
458690
+ const maxScroll2 = sh - vh;
458691
+ const targetScroll = Math.round(clickFraction * maxScroll2);
458692
+ s.scrollTo(targetScroll);
458693
+ event.stopImmediatePropagation();
458694
+ }, [scrollRef]);
458648
458695
  if (scrollHeight <= viewportHeight || viewportHeight < 3) {
458649
458696
  return null;
458650
458697
  }
@@ -458670,6 +458717,7 @@ function ScrollIndicator({
458670
458717
  bottom: 0,
458671
458718
  width: 1,
458672
458719
  flexDirection: "column",
458720
+ onClick: handleClick,
458673
458721
  children: track2.map((char, i3) => /* @__PURE__ */ jsx_dev_runtime259.jsxDEV(ThemedText, {
458674
458722
  color: char === "█" ? "cyan" : "#333333",
458675
458723
  children: char
@@ -485914,7 +485962,7 @@ var init_bridge_kick = __esm(() => {
485914
485962
  var call60 = async () => {
485915
485963
  return {
485916
485964
  type: "text",
485917
- value: `${"99.0.0"} (built ${"2026-05-05T05:08:44.087Z"})`
485965
+ value: `${"99.0.0"} (built ${"2026-05-05T05:25:24.607Z"})`
485918
485966
  };
485919
485967
  }, version2, version_default;
485920
485968
  var init_version = __esm(() => {
@@ -554647,7 +554695,7 @@ function WelcomeV2() {
554647
554695
  dimColor: true,
554648
554696
  children: [
554649
554697
  "v",
554650
- "0.3.30",
554698
+ "0.3.32",
554651
554699
  " "
554652
554700
  ]
554653
554701
  }, undefined, true, undefined, this)
@@ -574104,7 +574152,7 @@ Usage: stx7 --remote "your task description"`, () => gracefulShutdown(1));
574104
574152
  pendingHookMessages
574105
574153
  }, renderAndRun);
574106
574154
  }
574107
- }).version("0.3.30 (STRATAGEM X7)", "-v, --version", "Output the version number");
574155
+ }).version("0.3.32 (STRATAGEM X7)", "-v, --version", "Output the version number");
574108
574156
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
574109
574157
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
574110
574158
  if (canUserConfigureAdvisor()) {
@@ -574565,7 +574613,7 @@ if (false) {}
574565
574613
  async function main2() {
574566
574614
  const args = process.argv.slice(2);
574567
574615
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
574568
- console.log(`${"0.3.30"} (STRATAGEM X7)`);
574616
+ console.log(`${"0.3.32"} (STRATAGEM X7)`);
574569
574617
  return;
574570
574618
  }
574571
574619
  if (args.includes("--provider")) {
@@ -574687,4 +574735,4 @@ async function main2() {
574687
574735
  }
574688
574736
  main2();
574689
574737
 
574690
- //# debugId=974B651FA4EE606664756E2164756E21
574738
+ //# debugId=835DE33B0F92D56964756E2164756E21