瀏覽代碼

fix(session): clear stale provider binding on model mismatch

When a session switches models mid-conversation, the previously bound
provider may not support the new model. Due to SET NX semantics, the
stale binding would persist indefinitely, causing repeated provider
rejection without recovery. Clear the binding on model mismatch so a
new SET NX can rebind to a compatible provider.
ding113 2 月之前
父節點
當前提交
b83ab2af
共有 2 個文件被更改,包括 27 次插入0 次删除
  1. 12 0
      src/app/v1/_lib/proxy/provider-selector.ts
  2. 15 0
      src/lib/session-manager.ts

+ 12 - 0
src/app/v1/_lib/proxy/provider-selector.ts

@@ -558,6 +558,18 @@ export class ProxyProviderResolver {
         requestedModel,
         requestedModel,
         allowedModels: provider.allowedModels,
         allowedModels: provider.allowedModels,
       });
       });
+
+      // 清除过时绑定,避免 SET NX 死锁
+      // 当 session 内请求模型发生变化时,旧绑定已无意义,
+      // 清除后新的成功请求可通过 SET NX 重新绑定匹配的 provider
+      await SessionManager.clearSessionProvider(session.sessionId);
+      logger.info("ProviderSelector: Cleared stale provider binding (model mismatch)", {
+        sessionId: session.sessionId,
+        staleProviderId: provider.id,
+        staleProviderName: provider.name,
+        requestedModel,
+      });
+
       return null;
       return null;
     }
     }
 
 

+ 15 - 0
src/lib/session-manager.ts

@@ -556,6 +556,21 @@ export class SessionManager {
     return null;
     return null;
   }
   }
 
 
+  /**
+   * 清除 session 绑定的 provider(用于跨模型 session 绑定过时时)
+   */
+  static async clearSessionProvider(sessionId: string): Promise<void> {
+    const redis = getRedisClient();
+    if (!redis || redis.status !== "ready") return;
+
+    try {
+      await redis.del(`session:${sessionId}:provider`);
+      logger.trace("SessionManager: Cleared session provider binding", { sessionId });
+    } catch (error) {
+      logger.error("SessionManager: Failed to clear session provider", { error, sessionId });
+    }
+  }
+
   /**
   /**
    * 获取当前绑定供应商的优先级
    * 获取当前绑定供应商的优先级
    *
    *