mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-28 00:35:32 +08:00
fix: make Codex TOML base_url editing section-aware
Rewrite setCodexBaseUrl/extractCodexBaseUrl to understand TOML section boundaries, ensuring base_url is written into the correct [model_providers.<name>] section instead of being appended to file end. - Add section-aware TOML helpers in providerConfigUtils.ts - Extract shared update_codex_toml_field/remove_codex_toml_base_url_if in codex_config.rs, deduplicate proxy.rs TOML editing logic - Replace scattered inline base_url regexes with extractCodexBaseUrl() - Add comprehensive tests for both Rust and TypeScript implementations
This commit is contained in:
@@ -17,6 +17,7 @@ import { UniversalProviderPanel } from "@/components/universal";
|
||||
import { providerPresets } from "@/config/claudeProviderPresets";
|
||||
import { codexProviderPresets } from "@/config/codexProviderPresets";
|
||||
import { geminiProviderPresets } from "@/config/geminiProviderPresets";
|
||||
import { extractCodexBaseUrl } from "@/utils/providerConfigUtils";
|
||||
import type { OpenClawSuggestedDefaults } from "@/config/openclawProviderPresets";
|
||||
import type { UniversalProviderPreset } from "@/config/universalProviderPresets";
|
||||
|
||||
@@ -179,11 +180,9 @@ export function AddProviderDialog({
|
||||
} else if (appId === "codex") {
|
||||
const config = parsedConfig.config as string | undefined;
|
||||
if (config) {
|
||||
const baseUrlMatch = config.match(
|
||||
/base_url\s*=\s*["']([^"']+)["']/,
|
||||
);
|
||||
if (baseUrlMatch?.[1]) {
|
||||
addUrl(baseUrlMatch[1]);
|
||||
const extractedBaseUrl = extractCodexBaseUrl(config);
|
||||
if (extractedBaseUrl) {
|
||||
addUrl(extractedBaseUrl);
|
||||
}
|
||||
}
|
||||
} else if (appId === "gemini") {
|
||||
|
||||
@@ -13,6 +13,7 @@ import { ProviderIcon } from "@/components/ProviderIcon";
|
||||
import UsageFooter from "@/components/UsageFooter";
|
||||
import { ProviderHealthBadge } from "@/components/providers/ProviderHealthBadge";
|
||||
import { FailoverPriorityBadge } from "@/components/providers/FailoverPriorityBadge";
|
||||
import { extractCodexBaseUrl } from "@/utils/providerConfigUtils";
|
||||
import { useProviderHealth } from "@/lib/query/failover";
|
||||
import { useUsageQuery } from "@/lib/query/queries";
|
||||
|
||||
@@ -76,9 +77,9 @@ const extractApiUrl = (provider: Provider, fallbackText: string) => {
|
||||
const baseUrl = (config as Record<string, any>)?.config;
|
||||
|
||||
if (typeof baseUrl === "string" && baseUrl.includes("base_url")) {
|
||||
const match = baseUrl.match(/base_url\s*=\s*['"]([^'"]+)['"]/);
|
||||
if (match?.[1]) {
|
||||
return match[1];
|
||||
const extractedBaseUrl = extractCodexBaseUrl(baseUrl);
|
||||
if (extractedBaseUrl) {
|
||||
return extractedBaseUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,7 +383,9 @@ export function OpenClawFormFields({
|
||||
className="flex items-center gap-1.5 cursor-pointer select-none"
|
||||
>
|
||||
<Checkbox
|
||||
checked={(model.input ?? ["text"]).includes(type)}
|
||||
checked={(model.input ?? ["text"]).includes(
|
||||
type,
|
||||
)}
|
||||
onCheckedChange={(checked) => {
|
||||
const current = model.input ?? ["text"];
|
||||
const next = checked
|
||||
|
||||
@@ -285,7 +285,13 @@ export function useCodexCommonConfig({
|
||||
isUpdatingFromCommonConfig.current = false;
|
||||
}, 0);
|
||||
},
|
||||
[codexConfig, commonConfigSnippet, onConfigChange, parseCommonConfigSnippet, t],
|
||||
[
|
||||
codexConfig,
|
||||
commonConfigSnippet,
|
||||
onConfigChange,
|
||||
parseCommonConfigSnippet,
|
||||
t,
|
||||
],
|
||||
);
|
||||
|
||||
// 处理通用配置片段变化
|
||||
|
||||
@@ -171,18 +171,15 @@ export function useOpenclawFormState({
|
||||
[updateOpenclawConfig],
|
||||
);
|
||||
|
||||
const resetOpenclawState = useCallback(
|
||||
(config?: OpenClawProviderConfig) => {
|
||||
setOpenclawProviderKey("");
|
||||
setOpenclawBaseUrl(config?.baseUrl || "");
|
||||
setOpenclawApiKey(config?.apiKey || "");
|
||||
setOpenclawApi(config?.api || "openai-completions");
|
||||
setOpenclawModels(config?.models || []);
|
||||
const ua = config?.headers ? "User-Agent" in config.headers : false;
|
||||
setOpenclawUserAgent(ua);
|
||||
},
|
||||
[],
|
||||
);
|
||||
const resetOpenclawState = useCallback((config?: OpenClawProviderConfig) => {
|
||||
setOpenclawProviderKey("");
|
||||
setOpenclawBaseUrl(config?.baseUrl || "");
|
||||
setOpenclawApiKey(config?.apiKey || "");
|
||||
setOpenclawApi(config?.api || "openai-completions");
|
||||
setOpenclawModels(config?.models || []);
|
||||
const ua = config?.headers ? "User-Agent" in config.headers : false;
|
||||
setOpenclawUserAgent(ua);
|
||||
}, []);
|
||||
|
||||
return {
|
||||
openclawProviderKey,
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { AppId } from "@/lib/api";
|
||||
import type { ProviderPreset } from "@/config/claudeProviderPresets";
|
||||
import type { CodexProviderPreset } from "@/config/codexProviderPresets";
|
||||
import type { ProviderMeta, EndpointCandidate } from "@/types";
|
||||
import { extractCodexBaseUrl } from "@/utils/providerConfigUtils";
|
||||
|
||||
type PresetEntry = {
|
||||
id: string;
|
||||
@@ -128,10 +129,9 @@ export function useSpeedTestEndpoints({
|
||||
}
|
||||
| undefined;
|
||||
const configStr = initialCodexConfig?.config ?? "";
|
||||
// 从 TOML 中提取 base_url
|
||||
const match = /base_url\s*=\s*["']([^"']+)["']/i.exec(configStr);
|
||||
if (match?.[1]) {
|
||||
add(match[1]);
|
||||
const extractedBaseUrl = extractCodexBaseUrl(configStr);
|
||||
if (extractedBaseUrl) {
|
||||
add(extractedBaseUrl);
|
||||
}
|
||||
|
||||
// 3. 预设中的 endpointCandidates
|
||||
@@ -141,11 +141,9 @@ export function useSpeedTestEndpoints({
|
||||
const preset = entry.preset as CodexProviderPreset;
|
||||
// 添加预设自己的 baseUrl
|
||||
const presetConfig = preset.config || "";
|
||||
const presetMatch = /base_url\s*=\s*["']([^"']+)["']/i.exec(
|
||||
presetConfig,
|
||||
);
|
||||
if (presetMatch?.[1]) {
|
||||
add(presetMatch[1]);
|
||||
const presetBaseUrl = extractCodexBaseUrl(presetConfig);
|
||||
if (presetBaseUrl) {
|
||||
add(presetBaseUrl);
|
||||
}
|
||||
// 添加预设的候选端点
|
||||
if (preset.endpointCandidates) {
|
||||
|
||||
Reference in New Issue
Block a user