diff --git a/frontend/src/components/account/BulkEditAccountModal.vue b/frontend/src/components/account/BulkEditAccountModal.vue
index b55456ff..05016a6d 100644
--- a/frontend/src/components/account/BulkEditAccountModal.vue
+++ b/frontend/src/components/account/BulkEditAccountModal.vue
@@ -698,6 +698,87 @@
+
+
+
+
+
+
+
+
+ {{ t('admin.accounts.openai.codexCLIOnlyDesc') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('admin.accounts.openai.wsModeDesc') }}
+
+
+ {{ t(openAIAPIKeyWSModeConcurrencyHintKey) }}
+
+
+
+
+
@@ -1032,6 +1113,8 @@ const enableStatus = ref(false)
const enableGroups = ref(false)
const enableOpenAIPassthrough = ref(false)
const enableOpenAIWSMode = ref(false)
+const enableOpenAIAPIKeyWSMode = ref(false)
+const enableCodexCLIOnly = ref(false)
const enableRpmLimit = ref(false)
// State - field values
@@ -1055,6 +1138,8 @@ const status = ref<'active' | 'inactive'>('active')
const groupIds = ref([])
const openaiPassthroughEnabled = ref(false)
const openaiOAuthResponsesWebSocketV2Mode = ref(OPENAI_WS_MODE_OFF)
+const openaiAPIKeyResponsesWebSocketV2Mode = ref(OPENAI_WS_MODE_OFF)
+const codexCLIOnlyEnabled = ref(false)
const rpmLimitEnabled = ref(false)
const bulkBaseRpm = ref(null)
const bulkRpmStrategy = ref<'tiered' | 'sticky_exempt'>('tiered')
@@ -1096,6 +1181,9 @@ const openAIWSModeOptions = computed(() => [
const openAIWSModeConcurrencyHintKey = computed(() =>
resolveOpenAIWSModeConcurrencyHintKey(openaiOAuthResponsesWebSocketV2Mode.value)
)
+const openAIAPIKeyWSModeConcurrencyHintKey = computed(() =>
+ resolveOpenAIWSModeConcurrencyHintKey(openaiAPIKeyResponsesWebSocketV2Mode.value)
+)
// Model mapping helpers
const addModelMapping = () => {
@@ -1274,6 +1362,19 @@ const buildUpdatePayload = (): Record | null => {
)
}
+ if (enableOpenAIAPIKeyWSMode.value) {
+ const extra = ensureExtra()
+ extra.openai_apikey_responses_websockets_v2_mode = openaiAPIKeyResponsesWebSocketV2Mode.value
+ extra.openai_apikey_responses_websockets_v2_enabled = isOpenAIWSModeEnabled(
+ openaiAPIKeyResponsesWebSocketV2Mode.value
+ )
+ }
+
+ if (enableCodexCLIOnly.value) {
+ const extra = ensureExtra()
+ extra.codex_cli_only = codexCLIOnlyEnabled.value
+ }
+
// RPM limit settings (写入 extra 字段)
if (enableRpmLimit.value) {
const extra = ensureExtra()
@@ -1364,6 +1465,8 @@ const handleSubmit = async () => {
enableStatus.value ||
enableGroups.value ||
enableOpenAIWSMode.value ||
+ enableOpenAIAPIKeyWSMode.value ||
+ enableCodexCLIOnly.value ||
enableRpmLimit.value ||
userMsgQueueMode.value !== null
@@ -1462,6 +1565,8 @@ watch(
enableGroups.value = false
enableOpenAIPassthrough.value = false
enableOpenAIWSMode.value = false
+ enableOpenAIAPIKeyWSMode.value = false
+ enableCodexCLIOnly.value = false
enableRpmLimit.value = false
// Reset all values
@@ -1481,6 +1586,8 @@ watch(
status.value = 'active'
groupIds.value = []
openaiOAuthResponsesWebSocketV2Mode.value = OPENAI_WS_MODE_OFF
+ openaiAPIKeyResponsesWebSocketV2Mode.value = OPENAI_WS_MODE_OFF
+ codexCLIOnlyEnabled.value = false
rpmLimitEnabled.value = false
bulkBaseRpm.value = null
bulkRpmStrategy.value = 'tiered'