diff --git a/frontend/src/views/accounts/components/AccountQuotaSummaryCell/index.vue b/frontend/src/views/accounts/components/AccountQuotaSummaryCell/index.vue
index be144720f..5633c2ab9 100644
--- a/frontend/src/views/accounts/components/AccountQuotaSummaryCell/index.vue
+++ b/frontend/src/views/accounts/components/AccountQuotaSummaryCell/index.vue
@@ -50,7 +50,7 @@ const additionalEntryCount = computed(() => Math.max(summaryEntries.value.length
class="flex shrink-0 items-baseline gap-1 text-[9px] font-emphasis text-cp-text-quaternary"
title="最近使用额度的当前已用比例"
>
- 消耗比例
+ 使用率
{{ currentUsageDisplay }}
diff --git a/frontend/src/views/api-keys/components/ApiKeyUseModal.vue b/frontend/src/views/api-keys/components/ApiKeyUseModal.vue
index e01dda302..04c83e7ca 100644
--- a/frontend/src/views/api-keys/components/ApiKeyUseModal.vue
+++ b/frontend/src/views/api-keys/components/ApiKeyUseModal.vue
@@ -8,6 +8,10 @@ import BaseModal from '@/components/base/BaseModal/index.vue'
import BaseScrollbar from '@/components/base/BaseScrollbar.vue'
import BaseSegmented from '@/components/base/BaseSegmented.vue'
import BaseSwitch from '@/components/base/BaseSwitch.vue'
+import {
+ buildCodexConfigFiles,
+ CODEX_WEBSOCKET_ENABLED_BY_DEFAULT,
+} from '../utils/codexConfig'
const props = defineProps<{
apiKey: {
@@ -24,7 +28,7 @@ const emit = defineEmits<{
const open = defineModel({ default: false })
const activePlatform = shallowRef('unix')
-const websocketEnabled = shallowRef(true)
+const websocketEnabled = shallowRef(CODEX_WEBSOCKET_ENABLED_BY_DEFAULT)
const platformOptions = [
{ label: 'macOS / Linux', value: 'unix', icon: Apple },
@@ -40,31 +44,15 @@ const configPath = computed(() =>
const authPath = computed(() =>
activePlatform.value === 'windows' ? '%userprofile%\\.codex\\auth.json' : '~/.codex/auth.json',
)
-const codexAuthJson = computed(() => JSON.stringify({ OPENAI_API_KEY: keyValue.value }, null, 2))
-const defaultModel = 'gpt-5.6-terra'
-
-const codexConfigToml = computed(
- () => `model_provider = "OpenAI"
-model = "${defaultModel}"
-review_model = "${defaultModel}"
-model_reasoning_effort = "max"
-service_tier = "default"
-disable_response_storage = true
-network_access = "enabled"
-
-[model_providers.OpenAI]
-name = "OpenAI"
-base_url = "${props.apiBaseUrl}"
-wire_api = "responses"${websocketEnabled.value ? '\nsupports_websockets = true' : ''}
-requires_openai_auth = true
-
-[features]${websocketEnabled.value ? '\nresponses_websockets_v2 = true' : ''}
-goals = true`,
-)
+const codexConfigFiles = computed(() => buildCodexConfigFiles({
+ apiKey: keyValue.value,
+ baseUrl: props.apiBaseUrl,
+ websocketEnabled: websocketEnabled.value,
+}))
const visibleFiles = computed(() => [
- { path: configPath.value, content: codexConfigToml.value, scrollbarHeight: '360px' },
- { path: authPath.value, content: codexAuthJson.value, scrollbarHeight: undefined },
+ { path: configPath.value, content: codexConfigFiles.value.configToml, scrollbarHeight: '360px' },
+ { path: authPath.value, content: codexConfigFiles.value.authJson, scrollbarHeight: undefined },
])
diff --git a/frontend/src/views/api-keys/utils/ccswitchImport.ts b/frontend/src/views/api-keys/utils/ccswitchImport.ts
index faded9851..26df5b2fb 100644
--- a/frontend/src/views/api-keys/utils/ccswitchImport.ts
+++ b/frontend/src/views/api-keys/utils/ccswitchImport.ts
@@ -1,4 +1,8 @@
-const DEFAULT_CC_SWITCH_MODEL = 'gpt-5.5'
+import {
+ buildCodexConfigFiles,
+ CODEX_DEFAULT_MODEL,
+ CODEX_WEBSOCKET_ENABLED_BY_DEFAULT,
+} from './codexConfig'
export interface CodexCcSwitchImportInput {
apiKey: string
@@ -7,18 +11,37 @@ export interface CodexCcSwitchImportInput {
}
export function buildCodexCcSwitchImportDeeplink(input: CodexCcSwitchImportInput): string {
- const baseUrl = input.baseUrl.replace(/\/+$/, '')
+ const configFiles = buildCodexConfigFiles({
+ apiKey: input.apiKey,
+ baseUrl: input.baseUrl,
+ websocketEnabled: CODEX_WEBSOCKET_ENABLED_BY_DEFAULT,
+ })
+ // Carry the complete files shown in the UI; the explicit fields below keep
+ // compatibility with CCSwitch versions that only extract common settings.
+ const config = encodeBase64(JSON.stringify({
+ auth: configFiles.auth,
+ config: configFiles.configToml,
+ }))
const entries: [string, string][] = [
['resource', 'provider'],
['app', 'codex'],
- ['model', DEFAULT_CC_SWITCH_MODEL],
+ ['model', CODEX_DEFAULT_MODEL],
['name', input.providerName],
- ['homepage', baseUrl],
- ['endpoint', baseUrl],
+ ['homepage', configFiles.baseUrl],
+ ['endpoint', configFiles.baseUrl],
['apiKey', input.apiKey],
['configFormat', 'json'],
+ ['config', config],
['usageEnabled', 'false'],
]
return `ccswitch://v1/import?${new URLSearchParams(entries).toString()}`
}
+
+function encodeBase64(value: string) {
+ const bytes = new TextEncoder().encode(value)
+ let binary = ''
+ for (const byte of bytes)
+ binary += String.fromCharCode(byte)
+ return btoa(binary)
+}
diff --git a/frontend/src/views/api-keys/utils/codexConfig.ts b/frontend/src/views/api-keys/utils/codexConfig.ts
new file mode 100644
index 000000000..1cb19229c
--- /dev/null
+++ b/frontend/src/views/api-keys/utils/codexConfig.ts
@@ -0,0 +1,37 @@
+export const CODEX_DEFAULT_MODEL = 'gpt-5.6-terra'
+export const CODEX_WEBSOCKET_ENABLED_BY_DEFAULT = true
+
+export interface CodexConfigInput {
+ apiKey: string
+ baseUrl: string
+ websocketEnabled?: boolean
+}
+
+export function buildCodexConfigFiles(input: CodexConfigInput) {
+ const baseUrl = input.baseUrl.replace(/\/+$/, '')
+ const websocketEnabled = input.websocketEnabled ?? CODEX_WEBSOCKET_ENABLED_BY_DEFAULT
+ const auth = { OPENAI_API_KEY: input.apiKey }
+ const configToml = `model_provider = "OpenAI"
+model = "${CODEX_DEFAULT_MODEL}"
+review_model = "${CODEX_DEFAULT_MODEL}"
+model_reasoning_effort = "max"
+service_tier = "default"
+disable_response_storage = true
+network_access = "enabled"
+
+[model_providers.OpenAI]
+name = "OpenAI"
+base_url = "${baseUrl}"
+wire_api = "responses"${websocketEnabled ? '\nsupports_websockets = true' : ''}
+requires_openai_auth = true
+
+[features]${websocketEnabled ? '\nresponses_websockets_v2 = true' : ''}
+goals = true`
+
+ return {
+ auth,
+ authJson: JSON.stringify(auth, null, 2),
+ baseUrl,
+ configToml,
+ }
+}