MCPcopy Create free account
hub / github.com/chainreactors/EvilProxy / Pick

Method Pick

sdk/cliproxy/auth/selector.go:417–470  ·  view source on GitHub ↗

Pick selects an auth with session affinity when possible. Priority for session ID extraction: 1. metadata.user_id (Claude Code format with _session_{uuid}) - highest priority 2. X-Session-ID header 3. Session_id header (Codex) 4. X-Client-Request-Id header (PI) 5. metadata.user_id (non-Claude Code f

(ctx context.Context, provider, model string, opts cliproxyexecutor.Options, auths []*Auth)

Source from the content-addressed store, hash-verified

415// a session uses multiple models (e.g., gemini-2.5-pro and gemini-3-flash-preview)
416// that may be supported by different auth credentials, and to avoid cross-provider conflicts.
417func (s *SessionAffinitySelector) Pick(ctx context.Context, provider, model string, opts cliproxyexecutor.Options, auths []*Auth) (*Auth, error) {
418 entry := selectorLogEntry(ctx)
419 primaryID, fallbackID := extractSessionIDs(opts.Headers, opts.OriginalRequest, opts.Metadata)
420 if primaryID == "" {
421 entry.Debugf("session-affinity: no session ID extracted, falling back to default selector | provider=%s model=%s", provider, model)
422 return s.fallback.Pick(ctx, provider, model, opts, auths)
423 }
424
425 now := time.Now()
426 available, err := getAvailableAuths(auths, provider, model, now)
427 if err != nil {
428 return nil, err
429 }
430
431 cacheKey := provider + "::" + primaryID + "::" + model
432
433 if cachedAuthID, ok := s.cache.GetAndRefresh(cacheKey); ok {
434 for _, auth := range available {
435 if auth.ID == cachedAuthID {
436 entry.Infof("session-affinity: cache hit | session=%s auth=%s provider=%s model=%s", truncateSessionID(primaryID), auth.ID, provider, model)
437 return auth, nil
438 }
439 }
440 // Cached auth not available, reselect via fallback selector for even distribution
441 auth, err := s.fallback.Pick(ctx, provider, model, opts, auths)
442 if err != nil {
443 return nil, err
444 }
445 s.cache.Set(cacheKey, auth.ID)
446 entry.Infof("session-affinity: cache hit but auth unavailable, reselected | session=%s auth=%s provider=%s model=%s", truncateSessionID(primaryID), auth.ID, provider, model)
447 return auth, nil
448 }
449
450 if fallbackID != "" && fallbackID != primaryID {
451 fallbackKey := provider + "::" + fallbackID + "::" + model
452 if cachedAuthID, ok := s.cache.Get(fallbackKey); ok {
453 for _, auth := range available {
454 if auth.ID == cachedAuthID {
455 s.cache.Set(cacheKey, auth.ID)
456 entry.Infof("session-affinity: fallback cache hit | session=%s fallback=%s auth=%s provider=%s model=%s", truncateSessionID(primaryID), truncateSessionID(fallbackID), auth.ID, provider, model)
457 return auth, nil
458 }
459 }
460 }
461 }
462
463 auth, err := s.fallback.Pick(ctx, provider, model, opts, auths)
464 if err != nil {
465 return nil, err
466 }
467 s.cache.Set(cacheKey, auth.ID)
468 entry.Infof("session-affinity: cache miss, new binding | session=%s auth=%s provider=%s model=%s", truncateSessionID(primaryID), auth.ID, provider, model)
469 return auth, nil
470}
471
472func selectorLogEntry(ctx context.Context) *log.Entry {
473 if ctx == nil {

Calls 8

selectorLogEntryFunction · 0.85
extractSessionIDsFunction · 0.85
getAvailableAuthsFunction · 0.85
truncateSessionIDFunction · 0.85
GetAndRefreshMethod · 0.80
PickMethod · 0.65
SetMethod · 0.45
GetMethod · 0.45