Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
e6e73b4f
Unverified
Commit
e6e73b4f
authored
Apr 16, 2026
by
Wesley Liddick
Committed by
GitHub
Apr 16, 2026
Browse files
Merge pull request #1690 from KnowSky404/fix/ws-codex-scheduler-cache-1662
fix: preserve openai ws flags in scheduler cache
parents
7ea8e7e6
836092a6
Changes
6
Hide whitespace changes
Inline
Side-by-side
backend/internal/repository/scheduler_cache.go
View file @
e6e73b4f
...
@@ -426,6 +426,13 @@ func filterSchedulerExtra(extra map[string]any) map[string]any {
...
@@ -426,6 +426,13 @@ func filterSchedulerExtra(extra map[string]any) map[string]any {
"window_cost_sticky_reserve"
,
"window_cost_sticky_reserve"
,
"max_sessions"
,
"max_sessions"
,
"session_idle_timeout_minutes"
,
"session_idle_timeout_minutes"
,
"openai_oauth_responses_websockets_v2_enabled"
,
"openai_oauth_responses_websockets_v2_mode"
,
"openai_apikey_responses_websockets_v2_enabled"
,
"openai_apikey_responses_websockets_v2_mode"
,
"responses_websockets_v2_enabled"
,
"openai_ws_enabled"
,
"openai_ws_force_http"
,
}
}
filtered
:=
make
(
map
[
string
]
any
)
filtered
:=
make
(
map
[
string
]
any
)
for
_
,
key
:=
range
keys
{
for
_
,
key
:=
range
keys
{
...
...
backend/internal/repository/scheduler_cache_unit_test.go
0 → 100644
View file @
e6e73b4f
//go:build unit
package
repository
import
(
"testing"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/stretchr/testify/require"
)
func
TestBuildSchedulerMetadataAccount_KeepsOpenAIWSFlags
(
t
*
testing
.
T
)
{
account
:=
service
.
Account
{
ID
:
42
,
Platform
:
service
.
PlatformOpenAI
,
Type
:
service
.
AccountTypeOAuth
,
Extra
:
map
[
string
]
any
{
"openai_oauth_responses_websockets_v2_enabled"
:
true
,
"openai_oauth_responses_websockets_v2_mode"
:
service
.
OpenAIWSIngressModePassthrough
,
"openai_ws_force_http"
:
true
,
"mixed_scheduling"
:
true
,
"unused_large_field"
:
"drop-me"
,
},
}
got
:=
buildSchedulerMetadataAccount
(
account
)
require
.
Equal
(
t
,
true
,
got
.
Extra
[
"openai_oauth_responses_websockets_v2_enabled"
])
require
.
Equal
(
t
,
service
.
OpenAIWSIngressModePassthrough
,
got
.
Extra
[
"openai_oauth_responses_websockets_v2_mode"
])
require
.
Equal
(
t
,
true
,
got
.
Extra
[
"openai_ws_force_http"
])
require
.
Equal
(
t
,
true
,
got
.
Extra
[
"mixed_scheduling"
])
require
.
Nil
(
t
,
got
.
Extra
[
"unused_large_field"
])
}
backend/internal/service/openai_account_scheduler_ws_snapshot_test.go
0 → 100644
View file @
e6e73b4f
//go:build unit
package
service
import
(
"context"
"testing"
"github.com/Wei-Shaw/sub2api/internal/config"
"github.com/stretchr/testify/require"
)
func
TestOpenAIGatewayService_SelectAccountWithScheduler_UsesWSPassthroughSnapshotFlags
(
t
*
testing
.
T
)
{
ctx
:=
context
.
Background
()
groupID
:=
int64
(
10105
)
account
:=
&
Account
{
ID
:
35001
,
Platform
:
PlatformOpenAI
,
Type
:
AccountTypeOAuth
,
Status
:
StatusActive
,
Schedulable
:
true
,
Concurrency
:
10
,
Extra
:
map
[
string
]
any
{
"openai_oauth_responses_websockets_v2_mode"
:
OpenAIWSIngressModePassthrough
,
},
}
snapshotCache
:=
&
openAISnapshotCacheStub
{
snapshotAccounts
:
[]
*
Account
{
account
},
accountsByID
:
map
[
int64
]
*
Account
{
account
.
ID
:
account
},
}
cfg
:=
&
config
.
Config
{}
cfg
.
Gateway
.
OpenAIWS
.
Enabled
=
true
cfg
.
Gateway
.
OpenAIWS
.
OAuthEnabled
=
true
cfg
.
Gateway
.
OpenAIWS
.
APIKeyEnabled
=
true
cfg
.
Gateway
.
OpenAIWS
.
ResponsesWebsocketsV2
=
true
cfg
.
Gateway
.
OpenAIWS
.
ModeRouterV2Enabled
=
true
cfg
.
Gateway
.
OpenAIWS
.
IngressModeDefault
=
OpenAIWSIngressModeCtxPool
svc
:=
&
OpenAIGatewayService
{
accountRepo
:
stubOpenAIAccountRepo
{
accounts
:
[]
Account
{
*
account
}},
cache
:
&
stubGatewayCache
{},
cfg
:
cfg
,
schedulerSnapshot
:
&
SchedulerSnapshotService
{
cache
:
snapshotCache
},
concurrencyService
:
NewConcurrencyService
(
stubConcurrencyCache
{}),
}
selection
,
decision
,
err
:=
svc
.
SelectAccountWithScheduler
(
ctx
,
&
groupID
,
""
,
"session_hash_ws_passthrough"
,
"gpt-5.1"
,
nil
,
OpenAIUpstreamTransportResponsesWebsocketV2
,
)
require
.
NoError
(
t
,
err
)
require
.
NotNil
(
t
,
selection
)
require
.
NotNil
(
t
,
selection
.
Account
)
require
.
Equal
(
t
,
account
.
ID
,
selection
.
Account
.
ID
)
require
.
Equal
(
t
,
openAIAccountScheduleLayerLoadBalance
,
decision
.
Layer
)
}
frontend/src/components/account/BulkEditAccountModal.vue
View file @
e6e73b4f
...
@@ -921,6 +921,7 @@ import {
...
@@ -921,6 +921,7 @@ import {
getPresetMappingsByPlatform
getPresetMappingsByPlatform
}
from
'
@/composables/useModelWhitelist
'
}
from
'
@/composables/useModelWhitelist
'
import
{
import
{
OPENAI_WS_MODE_CTX_POOL
,
OPENAI_WS_MODE_OFF
,
OPENAI_WS_MODE_OFF
,
OPENAI_WS_MODE_PASSTHROUGH
,
OPENAI_WS_MODE_PASSTHROUGH
,
isOpenAIWSModeEnabled
,
isOpenAIWSModeEnabled
,
...
@@ -1069,6 +1070,7 @@ const isOpenAIModelRestrictionDisabled = computed(
...
@@ -1069,6 +1070,7 @@ const isOpenAIModelRestrictionDisabled = computed(
const
openAIWSModeOptions
=
computed
(()
=>
[
const
openAIWSModeOptions
=
computed
(()
=>
[
{
value
:
OPENAI_WS_MODE_OFF
,
label
:
t
(
'
admin.accounts.openai.wsModeOff
'
)
}
,
{
value
:
OPENAI_WS_MODE_OFF
,
label
:
t
(
'
admin.accounts.openai.wsModeOff
'
)
}
,
{
value
:
OPENAI_WS_MODE_CTX_POOL
,
label
:
t
(
'
admin.accounts.openai.wsModeCtxPool
'
)
}
,
{
value
:
OPENAI_WS_MODE_PASSTHROUGH
,
label
:
t
(
'
admin.accounts.openai.wsModePassthrough
'
)
}
{
value
:
OPENAI_WS_MODE_PASSTHROUGH
,
label
:
t
(
'
admin.accounts.openai.wsModePassthrough
'
)
}
])
])
const
openAIWSModeConcurrencyHintKey
=
computed
(()
=>
const
openAIWSModeConcurrencyHintKey
=
computed
(()
=>
...
...
frontend/src/components/account/CreateAccountModal.vue
View file @
e6e73b4f
...
@@ -2932,7 +2932,7 @@ import { applyInterceptWarmup } from '@/components/account/credentialsBuilder'
...
@@ -2932,7 +2932,7 @@ import { applyInterceptWarmup } from '@/components/account/credentialsBuilder'
import
{
formatDateTimeLocalInput
,
parseDateTimeLocalInput
}
from
'
@/utils/format
'
import
{
formatDateTimeLocalInput
,
parseDateTimeLocalInput
}
from
'
@/utils/format
'
import
{
createStableObjectKeyResolver
}
from
'
@/utils/stableObjectKey
'
import
{
createStableObjectKeyResolver
}
from
'
@/utils/stableObjectKey
'
import
{
import
{
//
OPENAI_WS_MODE_CTX_POOL,
OPENAI_WS_MODE_CTX_POOL
,
OPENAI_WS_MODE_OFF
,
OPENAI_WS_MODE_OFF
,
OPENAI_WS_MODE_PASSTHROUGH
,
OPENAI_WS_MODE_PASSTHROUGH
,
isOpenAIWSModeEnabled
,
isOpenAIWSModeEnabled
,
...
@@ -3180,8 +3180,7 @@ const geminiSelectedTier = computed(() => {
...
@@ -3180,8 +3180,7 @@ const geminiSelectedTier = computed(() => {
const
openAIWSModeOptions
=
computed
(()
=>
[
const
openAIWSModeOptions
=
computed
(()
=>
[
{
value
:
OPENAI_WS_MODE_OFF
,
label
:
t
(
'
admin.accounts.openai.wsModeOff
'
)
}
,
{
value
:
OPENAI_WS_MODE_OFF
,
label
:
t
(
'
admin.accounts.openai.wsModeOff
'
)
}
,
// TODO: ctx_pool 选项暂时隐藏,待测试完成后恢复
{
value
:
OPENAI_WS_MODE_CTX_POOL
,
label
:
t
(
'
admin.accounts.openai.wsModeCtxPool
'
)
}
,
//
{
value
:
OPENAI_WS_MODE_CTX_POOL
,
label
:
t
(
'
admin.accounts.openai.wsModeCtxPool
'
)
}
,
{
value
:
OPENAI_WS_MODE_PASSTHROUGH
,
label
:
t
(
'
admin.accounts.openai.wsModePassthrough
'
)
}
{
value
:
OPENAI_WS_MODE_PASSTHROUGH
,
label
:
t
(
'
admin.accounts.openai.wsModePassthrough
'
)
}
])
])
...
...
frontend/src/components/account/EditAccountModal.vue
View file @
e6e73b4f
...
@@ -1858,7 +1858,7 @@ import { applyInterceptWarmup } from '@/components/account/credentialsBuilder'
...
@@ -1858,7 +1858,7 @@ import { applyInterceptWarmup } from '@/components/account/credentialsBuilder'
import
{
formatDateTimeLocalInput
,
parseDateTimeLocalInput
}
from
'
@/utils/format
'
import
{
formatDateTimeLocalInput
,
parseDateTimeLocalInput
}
from
'
@/utils/format
'
import
{
createStableObjectKeyResolver
}
from
'
@/utils/stableObjectKey
'
import
{
createStableObjectKeyResolver
}
from
'
@/utils/stableObjectKey
'
import
{
import
{
//
OPENAI_WS_MODE_CTX_POOL,
OPENAI_WS_MODE_CTX_POOL
,
OPENAI_WS_MODE_OFF
,
OPENAI_WS_MODE_OFF
,
OPENAI_WS_MODE_PASSTHROUGH
,
OPENAI_WS_MODE_PASSTHROUGH
,
isOpenAIWSModeEnabled
,
isOpenAIWSModeEnabled
,
...
@@ -2020,8 +2020,7 @@ const editWeeklyResetHour = ref<number | null>(null)
...
@@ -2020,8 +2020,7 @@ const editWeeklyResetHour = ref<number | null>(null)
const
editResetTimezone
=
ref
<
string
|
null
>
(
null
)
const
editResetTimezone
=
ref
<
string
|
null
>
(
null
)
const
openAIWSModeOptions
=
computed
(()
=>
[
const
openAIWSModeOptions
=
computed
(()
=>
[
{
value
:
OPENAI_WS_MODE_OFF
,
label
:
t
(
'
admin.accounts.openai.wsModeOff
'
)
}
,
{
value
:
OPENAI_WS_MODE_OFF
,
label
:
t
(
'
admin.accounts.openai.wsModeOff
'
)
}
,
// TODO: ctx_pool 选项暂时隐藏,待测试完成后恢复
{
value
:
OPENAI_WS_MODE_CTX_POOL
,
label
:
t
(
'
admin.accounts.openai.wsModeCtxPool
'
)
}
,
//
{
value
:
OPENAI_WS_MODE_CTX_POOL
,
label
:
t
(
'
admin.accounts.openai.wsModeCtxPool
'
)
}
,
{
value
:
OPENAI_WS_MODE_PASSTHROUGH
,
label
:
t
(
'
admin.accounts.openai.wsModePassthrough
'
)
}
{
value
:
OPENAI_WS_MODE_PASSTHROUGH
,
label
:
t
(
'
admin.accounts.openai.wsModePassthrough
'
)
}
])
])
const
openaiResponsesWebSocketV2Mode
=
computed
({
const
openaiResponsesWebSocketV2Mode
=
computed
({
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment