mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-20 13:20:52 +08:00
feat(logging, executor): add request logging tests and WebSocket-based Codex executor
- Introduced unit tests for request logging middleware to enhance coverage. - Added WebSocket-based Codex executor to support Responses API upgrade. - Updated middleware logic to selectively capture request bodies for memory efficiency. - Enhanced Codex configuration handling with new WebSocket attributes.
This commit is contained in:
@@ -134,6 +134,62 @@ func canonicalModelKey(model string) string {
|
||||
return modelName
|
||||
}
|
||||
|
||||
func authWebsocketsEnabled(auth *Auth) bool {
|
||||
if auth == nil {
|
||||
return false
|
||||
}
|
||||
if len(auth.Attributes) > 0 {
|
||||
if raw := strings.TrimSpace(auth.Attributes["websockets"]); raw != "" {
|
||||
parsed, errParse := strconv.ParseBool(raw)
|
||||
if errParse == nil {
|
||||
return parsed
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(auth.Metadata) == 0 {
|
||||
return false
|
||||
}
|
||||
raw, ok := auth.Metadata["websockets"]
|
||||
if !ok || raw == nil {
|
||||
return false
|
||||
}
|
||||
switch v := raw.(type) {
|
||||
case bool:
|
||||
return v
|
||||
case string:
|
||||
parsed, errParse := strconv.ParseBool(strings.TrimSpace(v))
|
||||
if errParse == nil {
|
||||
return parsed
|
||||
}
|
||||
default:
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func preferCodexWebsocketAuths(ctx context.Context, provider string, available []*Auth) []*Auth {
|
||||
if len(available) == 0 {
|
||||
return available
|
||||
}
|
||||
if !cliproxyexecutor.DownstreamWebsocket(ctx) {
|
||||
return available
|
||||
}
|
||||
if !strings.EqualFold(strings.TrimSpace(provider), "codex") {
|
||||
return available
|
||||
}
|
||||
|
||||
wsEnabled := make([]*Auth, 0, len(available))
|
||||
for i := 0; i < len(available); i++ {
|
||||
candidate := available[i]
|
||||
if authWebsocketsEnabled(candidate) {
|
||||
wsEnabled = append(wsEnabled, candidate)
|
||||
}
|
||||
}
|
||||
if len(wsEnabled) > 0 {
|
||||
return wsEnabled
|
||||
}
|
||||
return available
|
||||
}
|
||||
|
||||
func collectAvailableByPriority(auths []*Auth, model string, now time.Time) (available map[int][]*Auth, cooldownCount int, earliest time.Time) {
|
||||
available = make(map[int][]*Auth)
|
||||
for i := 0; i < len(auths); i++ {
|
||||
@@ -193,13 +249,13 @@ func getAvailableAuths(auths []*Auth, provider, model string, now time.Time) ([]
|
||||
|
||||
// Pick selects the next available auth for the provider in a round-robin manner.
|
||||
func (s *RoundRobinSelector) Pick(ctx context.Context, provider, model string, opts cliproxyexecutor.Options, auths []*Auth) (*Auth, error) {
|
||||
_ = ctx
|
||||
_ = opts
|
||||
now := time.Now()
|
||||
available, err := getAvailableAuths(auths, provider, model, now)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
available = preferCodexWebsocketAuths(ctx, provider, available)
|
||||
key := provider + ":" + canonicalModelKey(model)
|
||||
s.mu.Lock()
|
||||
if s.cursors == nil {
|
||||
@@ -226,13 +282,13 @@ func (s *RoundRobinSelector) Pick(ctx context.Context, provider, model string, o
|
||||
|
||||
// Pick selects the first available auth for the provider in a deterministic manner.
|
||||
func (s *FillFirstSelector) Pick(ctx context.Context, provider, model string, opts cliproxyexecutor.Options, auths []*Auth) (*Auth, error) {
|
||||
_ = ctx
|
||||
_ = opts
|
||||
now := time.Now()
|
||||
available, err := getAvailableAuths(auths, provider, model, now)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
available = preferCodexWebsocketAuths(ctx, provider, available)
|
||||
return available[0], nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user