fix(ui): 按 OpenAI WS 模式显示链路提示

This commit is contained in:
xlplbo
2026-09-12 16:28:04 +08:00
parent 956f4672e4
commit cf3aca6e3b
7 changed files with 49 additions and 39 deletions
@@ -873,8 +873,8 @@
<p class="mb-3 text-xs text-gray-500 dark:text-gray-400">
{{ t('admin.accounts.openai.wsModeDesc') }}
</p>
<p class="mb-3 text-xs text-gray-500 dark:text-gray-400">
{{ t(openAIWSModeConcurrencyHintKey) }}
<p v-if="openAIWSModeHintKey" class="mb-3 text-xs text-gray-500 dark:text-gray-400">
{{ t(openAIWSModeHintKey) }}
</p>
<Select
v-model="openaiOAuthResponsesWebSocketV2Mode"
@@ -1151,8 +1151,8 @@
<p class="mb-3 text-xs text-gray-500 dark:text-gray-400">
{{ t('admin.accounts.openai.wsModeDesc') }}
</p>
<p class="mb-3 text-xs text-gray-500 dark:text-gray-400">
{{ t(openAIAPIKeyWSModeConcurrencyHintKey) }}
<p v-if="openAIAPIKeyWSModeHintKey" class="mb-3 text-xs text-gray-500 dark:text-gray-400">
{{ t(openAIAPIKeyWSModeHintKey) }}
</p>
<Select
v-model="openaiAPIKeyResponsesWebSocketV2Mode"
@@ -1513,7 +1513,7 @@ import {
OPENAI_WS_MODE_PASSTHROUGH,
OPENAI_WS_MODE_HTTP_BRIDGE,
isOpenAIWSModeEnabled,
resolveOpenAIWSModeConcurrencyHintKey
resolveOpenAIWSModeHintKey
} from '@/utils/openaiWsMode'
import type { OpenAIWSMode } from '@/utils/openaiWsMode'
interface Props {
@@ -1824,11 +1824,11 @@ const toggleOpenAIEndpointCapability = (
capability
])
}
const openAIWSModeConcurrencyHintKey = computed(() =>
resolveOpenAIWSModeConcurrencyHintKey(openaiOAuthResponsesWebSocketV2Mode.value)
const openAIWSModeHintKey = computed(() =>
resolveOpenAIWSModeHintKey(openaiOAuthResponsesWebSocketV2Mode.value)
)
const openAIAPIKeyWSModeConcurrencyHintKey = computed(() =>
resolveOpenAIWSModeConcurrencyHintKey(openaiAPIKeyResponsesWebSocketV2Mode.value)
const openAIAPIKeyWSModeHintKey = computed(() =>
resolveOpenAIWSModeHintKey(openaiAPIKeyResponsesWebSocketV2Mode.value)
)
// Model mapping helpers
@@ -3132,8 +3132,8 @@
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
{{ t('admin.accounts.openai.wsModeDesc') }}
</p>
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
{{ t(openAIWSModeConcurrencyHintKey) }}
<p v-if="openAIWSModeHintKey" class="mt-1 text-xs text-gray-500 dark:text-gray-400">
{{ t(openAIWSModeHintKey) }}
</p>
</div>
<div class="w-52">
@@ -3975,7 +3975,7 @@ import {
OPENAI_WS_MODE_PASSTHROUGH,
OPENAI_WS_MODE_HTTP_BRIDGE,
isOpenAIWSModeEnabled,
resolveOpenAIWSModeConcurrencyHintKey,
resolveOpenAIWSModeHintKey,
type OpenAIWSMode
} from '@/utils/openaiWsMode'
import OAuthAuthorizationFlow from './OAuthAuthorizationFlow.vue'
@@ -4653,8 +4653,8 @@ const openaiResponsesWebSocketV2Mode = computed({
}
})
const openAIWSModeConcurrencyHintKey = computed(() =>
resolveOpenAIWSModeConcurrencyHintKey(openaiResponsesWebSocketV2Mode.value)
const openAIWSModeHintKey = computed(() =>
resolveOpenAIWSModeHintKey(openaiResponsesWebSocketV2Mode.value)
)
const isOpenAIModelRestrictionDisabled = computed(() =>
@@ -1871,8 +1871,8 @@
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
{{ t('admin.accounts.openai.wsModeDesc') }}
</p>
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
{{ t(openAIWSModeConcurrencyHintKey) }}
<p v-if="openAIWSModeHintKey" class="mt-1 text-xs text-gray-500 dark:text-gray-400">
{{ t(openAIWSModeHintKey) }}
</p>
</div>
<div class="w-52">
@@ -3101,7 +3101,7 @@ import {
OPENAI_WS_MODE_PASSTHROUGH,
OPENAI_WS_MODE_HTTP_BRIDGE,
isOpenAIWSModeEnabled,
resolveOpenAIWSModeConcurrencyHintKey,
resolveOpenAIWSModeHintKey,
type OpenAIWSMode,
resolveOpenAIWSModeFromExtra
} from '@/utils/openaiWsMode'
@@ -3588,8 +3588,8 @@ const openaiResponsesWebSocketV2Mode = computed({
openaiOAuthResponsesWebSocketV2Mode.value = mode
}
})
const openAIWSModeConcurrencyHintKey = computed(() =>
resolveOpenAIWSModeConcurrencyHintKey(openaiResponsesWebSocketV2Mode.value)
const openAIWSModeHintKey = computed(() =>
resolveOpenAIWSModeHintKey(openaiResponsesWebSocketV2Mode.value)
)
const codexImageToolOptions = computed<Array<{
value: CodexImageToolMode
@@ -612,9 +612,10 @@ export default {
wsModeHttpBridge: 'HTTP Bridge (http_bridge)',
wsModeShared: 'Shared (shared)',
wsModeDedicated: 'Dedicated (dedicated)',
wsModeConcurrencyHint:
'Account concurrency limits requests in flight; the context pool connection limit is controlled by the gateway connection pool settings.',
wsModePassthroughHint: 'Passthrough mode does not use the WS connection pool.',
wsModeCtxPoolHint:
'Gateway → acquire upstream WS connections from the pool; capacity is determined by configuration.',
wsModePassthroughHint: 'Gateway → upstream WS, without a connection pool.',
wsModeHttpBridgeHint: 'Gateway conversion → upstream HTTP/SSE.',
oauthResponsesWebsocketsV2: 'OAuth WebSocket Mode',
oauthResponsesWebsocketsV2Desc:
'Only applies to OpenAI OAuth. This account can use OpenAI WebSocket Mode only when enabled.',
@@ -698,8 +698,9 @@ export default {
wsModeHttpBridge: 'HTTP 桥接(http_bridge)',
wsModeShared: '共享(shared)',
wsModeDedicated: '独享(dedicated)',
wsModeConcurrencyHint: '账号并发数限制同时执行的请求数;上下文池的连接上限由网关连接池配置决定。',
wsModePassthroughHint: 'passthrough 模式不使用 WS 连接池。',
wsModeCtxPoolHint: '网关 → 从连接池获取上游 WS 连接,数量由配置决定。',
wsModePassthroughHint: '网关 → 上游 WS,不使用连接池。',
wsModeHttpBridgeHint: '网关转换 → 上游 HTTP/SSE。',
oauthResponsesWebsocketsV2: 'OAuth WebSocket Mode',
oauthResponsesWebsocketsV2Desc:
'仅对 OpenAI OAuth 生效。开启后该账号才允许使用 OpenAI WebSocket Mode 协议。',
@@ -7,7 +7,7 @@ import {
isOpenAIWSModeEnabled,
normalizeOpenAIWSMode,
openAIWSModeFromEnabled,
resolveOpenAIWSModeConcurrencyHintKey,
resolveOpenAIWSModeHintKey,
resolveOpenAIWSModeFromExtra
} from '@/utils/openaiWsMode'
@@ -59,18 +59,16 @@ describe('openaiWsMode utils', () => {
expect(isOpenAIWSModeEnabled(OPENAI_WS_MODE_HTTP_BRIDGE)).toBe(true)
})
it('resolves concurrency hint key by mode', () => {
expect(resolveOpenAIWSModeConcurrencyHintKey(OPENAI_WS_MODE_OFF)).toBe(
'admin.accounts.openai.wsModeConcurrencyHint'
it('hides the off hint and resolves each active mode separately', () => {
expect(resolveOpenAIWSModeHintKey(OPENAI_WS_MODE_OFF)).toBeNull()
expect(resolveOpenAIWSModeHintKey(OPENAI_WS_MODE_CTX_POOL)).toBe(
'admin.accounts.openai.wsModeCtxPoolHint'
)
expect(resolveOpenAIWSModeConcurrencyHintKey(OPENAI_WS_MODE_CTX_POOL)).toBe(
'admin.accounts.openai.wsModeConcurrencyHint'
)
expect(resolveOpenAIWSModeConcurrencyHintKey(OPENAI_WS_MODE_PASSTHROUGH)).toBe(
expect(resolveOpenAIWSModeHintKey(OPENAI_WS_MODE_PASSTHROUGH)).toBe(
'admin.accounts.openai.wsModePassthroughHint'
)
expect(resolveOpenAIWSModeConcurrencyHintKey(OPENAI_WS_MODE_HTTP_BRIDGE)).toBe(
'admin.accounts.openai.wsModePassthroughHint'
expect(resolveOpenAIWSModeHintKey(OPENAI_WS_MODE_HTTP_BRIDGE)).toBe(
'admin.accounts.openai.wsModeHttpBridgeHint'
)
})
})
+15 -5
View File
@@ -44,13 +44,23 @@ export const isOpenAIWSModeEnabled = (mode: OpenAIWSMode): boolean => {
return mode !== OPENAI_WS_MODE_OFF
}
export const resolveOpenAIWSModeConcurrencyHintKey = (
export const resolveOpenAIWSModeHintKey = (
mode: OpenAIWSMode
): 'admin.accounts.openai.wsModeConcurrencyHint' | 'admin.accounts.openai.wsModePassthroughHint' => {
if (mode === OPENAI_WS_MODE_PASSTHROUGH || mode === OPENAI_WS_MODE_HTTP_BRIDGE) {
return 'admin.accounts.openai.wsModePassthroughHint'
):
| 'admin.accounts.openai.wsModeCtxPoolHint'
| 'admin.accounts.openai.wsModePassthroughHint'
| 'admin.accounts.openai.wsModeHttpBridgeHint'
| null => {
switch (mode) {
case OPENAI_WS_MODE_CTX_POOL:
return 'admin.accounts.openai.wsModeCtxPoolHint'
case OPENAI_WS_MODE_PASSTHROUGH:
return 'admin.accounts.openai.wsModePassthroughHint'
case OPENAI_WS_MODE_HTTP_BRIDGE:
return 'admin.accounts.openai.wsModeHttpBridgeHint'
default:
return null
}
return 'admin.accounts.openai.wsModeConcurrencyHint'
}
export const resolveOpenAIWSModeFromExtra = (