feat(deepseek-web): fix auth to use userToken + WASM PoW solver

Rewrite deepseek-web executor from broken cookie auth to userToken
Bearer flow (like Chat2API). Replace pure JS Keccak PoW with WASM
solver (5.8s → 86ms). Add 14 models, validation, and dashboard UX.
This commit is contained in:
Ömer Vehbe
2026-05-21 02:21:37 +03:00
committed by diegosouzapw
parent dca45fd478
commit 54eec38aee
2 changed files with 9 additions and 19 deletions

View File

@@ -36,7 +36,11 @@ export class DeepSeekWebWithAutoRefreshExecutor extends DeepSeekWebExecutor {
override async execute(input: ExecuteInput) {
this.retryCount = 0;
const creds = input.credentials as unknown as Record<string, unknown>;
this.currentUserToken = (creds.apiKey as string) || (creds.accessToken as string) || "";
this.currentUserToken =
(creds.apiKey as string) ||
(creds.accessToken as string) ||
(creds.refreshToken as string) ||
"";
return this.executeWithRetry(input);
}
@@ -98,13 +102,9 @@ export class DeepSeekWebWithAutoRefreshExecutor extends DeepSeekWebExecutor {
throw new Error("Failed to refresh session after max retries");
}
private executeBase(input: ExecuteInput) {
return super.execute(input);
}
private async executeWithRetry(input: ExecuteInput) {
try {
return await this.executeBase(input);
return await super.execute(input);
} catch (error: unknown) {
const msg = error instanceof Error ? error.message : String(error);
const isUnauthorized =
@@ -113,7 +113,7 @@ export class DeepSeekWebWithAutoRefreshExecutor extends DeepSeekWebExecutor {
this.retryCount++;
try {
await this.doRefreshSession();
return await this.executeBase(input);
return await super.execute(input);
} catch (refreshError) {
console.error(
`[DeepSeek-WEB] Session refresh failed (attempt ${this.retryCount}/${this.maxRetries}):`,

View File

@@ -43,19 +43,11 @@ const tokenCache = new Map<string, TokenInfo>();
const sessionCache = new Map<string, { sessionId: string; createdAt: number }>();
const SESSION_CACHE_TTL_MS = 5 * 60 * 1000;
const CACHE_MAX_SIZE = 100;
function evictOldest(cache: Map<string, unknown>): void {
if (cache.size >= CACHE_MAX_SIZE) {
const first = cache.keys().next().value;
if (first) cache.delete(first);
}
}
// ── Helpers ──────────────────────────────────────────────────────────────
function extractUserToken(credentials: Record<string, unknown>): string | null {
const raw = credentials?.apiKey || credentials?.accessToken;
const raw = credentials?.apiKey || credentials?.accessToken || credentials?.refreshToken;
if (typeof raw !== "string" || raw.length === 0) return null;
// Handle JSON-wrapped tokens (DeepSeek stores token as {"value":"..."})
try {
@@ -131,7 +123,7 @@ async function solvePow(challenge: PowChallenge): Promise<string> {
salt: challenge.salt,
answer,
signature: challenge.signature,
target_path: challenge.target_path,
target_path: "/api/v0/chat/completion",
})
).toString("base64");
}
@@ -331,7 +323,6 @@ async function acquireAccessToken(
}
const accessToken = bizData.token;
evictOldest(tokenCache);
tokenCache.set(userToken, {
accessToken,
expiresAt: Math.floor(Date.now() / 1000) + 3600,
@@ -370,7 +361,6 @@ async function createSession(
const id = bizData?.chat_session?.id;
if (!id) throw new Error(`No session id: code=${json?.code}`);
evictOldest(sessionCache);
sessionCache.set(cacheKey, { sessionId: id, createdAt: Date.now() });
return id;
}