Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/alvarogomezruiz_fitbit-healt-node.json
T

1 line
18 KiB
JSON

{"repo": "alvarogomezruiz/fitbit-healt-node", "files": {"frontend/lib/deepseek-package/deepseek-cascade.ts": {"6458d677f0526c2d981856fec3ba9402ee29ae58": {"t": 1785745601.4552188, "n": 8848, "h": "470735a5a3388e6f", "c": "import { parseDeepSeekChatCompletion } from \"./deepseek-schema.js\";\nimport { loadDeepSeekClientConfigFromEnv } from \"./deepseek-config.js\";\nimport {\n DeepSeekCascadeExhaustedError,\n DeepSeekEmptyContentError,\n DeepSeekHttpError,\n} from \"./errors.js\";\nimport type { RunDeepSeekCascadeParams, RunDeepSeekCascadeResult } from \"./types.js\";\n\nfunction sleep(ms: number, signal: AbortSignal | undefined): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason);\n return;\n }\n const t = setTimeout(resolve, ms);\n const onAbort = (): void => {\n clearTimeout(t);\n reject(signal?.reason ?? new Error(\"Aborted\"));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\nfunction computeBackoffMs(attemptIndex: number, baseMs: number, maxMs: number): number {\n const exp = Math.min(maxMs, baseMs * 2 ** attemptIndex);\n const jitter = Math.floor(Math.random() * Math.max(1, Math.floor(exp * 0.25)));\n return exp + jitter;\n}\n\nfunction parseRetryAfterMs(header: string | null): number | undefined {\n if (header === null || header.trim() === \"\") {\n return undefined;\n }\n const sec = Number.parseInt(header, 10);\n if (!Number.isFinite(sec) || sec < 0) {\n return undefined;\n }\n return sec * 1000;\n}\n\nfunction extractAssistantText(\n data: ReturnType<typeof parseDeepSeekChatCompletion>,\n model: string,\n): string {\n const choices = data.choices;\n const first = choices !== undefined && choices.length > 0 ? choices[0] : undefined;\n const msg = first?.message;\n const content = msg?.content;\n const finish = first?.finish_reason ?? \"UNKNOWN\";\n if (typeof content === \"string\" && content.trim() !== \"\") {\n return content;\n }\n const usage = data.usage;\n const reasoningTokens = usage?.completion_tokens_details?.reasoning_tokens ?? 0;\n const completionTokens = usage?.completion_tokens ?? 0;\n throw new DeepSeekEmptyContentError(\n `Respuesta de ${model} sin texto (finish=${String(finish)}, reasoning_tokens=${String(reasoningTokens)}, completion_tokens=${String(completionTokens)}). Probablemente reasoning agotó budget.`,\n model,\n String(finish),\n );\n}\n\nfunction isRetryableStatus(status: number): boolean {\n return status === 429 || status >= 500;\n}\n\nfunction shouldAbortCascade(status: number): boolean {\n if (status === 401 || status === 402 || status === 403 || status === 404 || status === 400) {\n return true;\n }\n return false;\n}\n\nconst INVALID_DEEPSEEK_API_KEY_USER_MESSAGE =\n \"Clave de API inválida o revocada. Regenera DEEPSEEK_API_KEY en el entorno de frontend y redespliega.\";\n\nfunction compactResponseTextForDiagnostics(\n json: unknown | undefined,\n rawTextSnippet: string | undefined,\n): string {\n if (rawTextSnippet !== undefined && rawTextSnippet.trim() !== \"\") {\n return rawTextSnippet.slice(0, 2000);\n }\n if (json === undefined) {\n return \"\";\n }\n try {\n return JSON.stringify(json).slice(0, 2000);\n } catch {\n return \"\";\n }\n}\n\nfunction bodySuggestsInvalidDeepSeekApiKey(haystackLower: string): boolean {\n if (haystackLower === \"\") {\n return false;\n }\n const needles: readonly string[] = [\n \"invalid_api_key\",\n \"incorrect api key\",\n \"invalid authentication\",\n \"authentication failed\",\n \"api key is invalid\",\n \"invalid bearer token\",\n ];\n return needles.some((needle) => haystackLower.includes(needle));\n}\n\nfunction isInvalidDeepSeekApiKeyCase(\n status: number,\n json: unknown | undefined,\n rawTextSnippet: string | undefined,\n): boolean {\n if (status === 401) {\n return true;\n }\n const haystack = compactResponseTextForDiagnostics(json, rawTextSnippet).toLowerCase();\n return bodySuggestsInvalidDeepSeekApiKey(haystack);\n}\n\nasync function postOnce(params: {\n readonly url: string;\n readonly apiKey: string;\n readonly model: string;\n readonly messages: RunDeepSeekCascadeParams[\"messages\"];\n readonly temperature: number;\n readonly maxTokens: number;\n readonly timeoutMs: number;\n readonly signal: AbortSignal | undefined;\n}): Promise<{\n readonly status: number;\n readonly json: unknown | undefined;\n readonly rawTextSnippet: string | undefined;\n readonly retryAfterMs?: number;\n}> {\n const controller = new AbortController();\n const timer = setTimeout(() => {\n controller.abort(new Error(\"DEEPSEEK_TIMEOUT\"));\n }, params.timeoutMs);\n const outer = params.signal;\n const onParentAbort = (): void => {\n controller.abort(outer?.reason ?? new Error(\"Aborted\"));\n };\n outer?.addEventListener(\"abort\", onParentAbort, { once: true });\n const body = JSON.stringify({\n model: params.model,\n messages: params.messages,\n temperature: params.temperature,\n max_tokens: params.maxTokens,\n top_p: 0.95,\n stream: false,\n });\n try {\n const res = await fetch(params.url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${params.apiKey}`,\n },\n body,\n signal: controller.signal,\n });\n const retryAfterMs = parseRetryAfterMs(res.headers.get(\"retry-after\"));\n const ct = res.headers.get(\"content-type\") ?? \"\";\n if (ct.includes(\"application/json\")) {\n const parsedJson: unknown = await res.json();\n return { status: res.status, json: parsedJson, rawTextSnippet: undefined, retryAfterMs };\n }\n const t = await res.text();\n return {\n status: res.status,\n json: undefined,\n rawTextSnippet: t.slice(0, 500),\n retryAfterMs,\n };\n } finally {\n clearTimeout(timer);\n outer?.removeEventListener(\"abort\", onParentAbort);\n }\n}\n\n/**\n * Invoca la API chat/completions de DeepSeek con lista de modelos en cascada,\n * reintentos con backoff exponencial + jitter en 429/5xx y errores de red.\n */\nexport async function runDeepSeekCascade(\n params: RunDeepSeekCascadeParams,\n): Promise<RunDeepSeekCascadeResult> {\n const cfg = loadDeepSeekClientConfigFromEnv();\n const cascade =\n params.modelCascade !== undefined && params.modelCascade.length > 0\n ? [...params.modelCascade]\n : [...cfg.modelCascadeDefault];\n const temperature = params.temperature ?? 0.15;\n const maxTokens = params.maxTokens ?? 8192;\n const causes: string[] = [];\n let attempts = 0;\n\n for (const model of cascade) {\n for (let r = 0; r < cfg.maxRetriesPerModel; r += 1) {\n attempts += 1;\n try {\n const { status, json, rawTextSnippet, retryAfterMs } = await postOnce({\n url: cfg.chatCompletionsUrl,\n apiKey: cfg.apiKey,\n model,\n messages: params.messages,\n temperature,\n maxTokens,\n timeoutMs: cfg.requestTimeoutMs,\n signal: params.signal,\n });\n if (status >= 200 && status < 300) {\n if (json === undefined) {\n causes.push(`[${model}] 200 sin JSON (texto): ${rawTextSnippet ?? \"\"}`);\n break;\n }\n const parsed = parseDeepSeekChatCompletion(json);\n const text = extractAssistantText(parsed, model);\n return { text, modelUsed: model, attempts };\n }\n const snippet =\n rawTextSnippet !== undefined\n ? rawTextSnippet\n : json === undefined\n ? \"\"\n : JSON.stringify(json).slice(0, 400);\n if (shouldAbortCascade(status)) {\n if (isInvalidDeepSeekApiKeyCase(status, json, rawTextSnippet)) {\n throw new DeepSeekHttpError(INVALID_DEEPSEEK_API_KEY_USER_MESSAGE, status, \"\");\n }\n throw new DeepSeekHttpError(`DeepSeek HTTP ${String(status)}: ${snippet}`, status, snippet);\n }\n if (isRetryableStatus(status)) {\n causes.push(`[${model}] HTTP ${String(status)} intento ${String(r + 1)}: ${snippet}`);\n if (r + 1 < cfg.maxRetriesPerModel) {\n const backoff =\n status === 429 && retryAfterMs !== undefined\n ? retryAfterMs\n : computeBackoffMs(r, cfg.backoffBaseMs, cfg.backoffMaxMs);\n await sleep(backoff, params.signal);\n }\n continue;\n }\n causes.push(`[${model}] HTTP ${String(status)} no reintentable: ${snippet}`);\n break;\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n if (e instanceof DeepSeekHttpError) {\n throw e;\n }\n if (e instanceof DeepSeekEmptyContentError) {\n causes.push(`${e.name}: ${e.message}`);\n break;\n }\n causes.push(`[${model}] ${msg}`);\n if (r + 1 < cfg.maxRetriesPerModel) {\n const backoff = computeBackoffMs(r, cfg.backoffBaseMs, cfg.backoffMaxMs);\n await sleep(backoff, params.signal);\n }\n }\n }\n }\n\n throw new DeepSeekCascadeExhaustedError(\n \"Cascada DeepSeek agotada sin respuesta válida.\",\n attempts,\n causes,\n );\n}\n"}, "8114dadab707b8d4d9891f6954d092bbfea66d94": {"t": 1785754669.304434, "n": 8848, "h": "470735a5a3388e6f", "c": "import { parseDeepSeekChatCompletion } from \"./deepseek-schema.js\";\nimport { loadDeepSeekClientConfigFromEnv } from \"./deepseek-config.js\";\nimport {\n DeepSeekCascadeExhaustedError,\n DeepSeekEmptyContentError,\n DeepSeekHttpError,\n} from \"./errors.js\";\nimport type { RunDeepSeekCascadeParams, RunDeepSeekCascadeResult } from \"./types.js\";\n\nfunction sleep(ms: number, signal: AbortSignal | undefined): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason);\n return;\n }\n const t = setTimeout(resolve, ms);\n const onAbort = (): void => {\n clearTimeout(t);\n reject(signal?.reason ?? new Error(\"Aborted\"));\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\nfunction computeBackoffMs(attemptIndex: number, baseMs: number, maxMs: number): number {\n const exp = Math.min(maxMs, baseMs * 2 ** attemptIndex);\n const jitter = Math.floor(Math.random() * Math.max(1, Math.floor(exp * 0.25)));\n return exp + jitter;\n}\n\nfunction parseRetryAfterMs(header: string | null): number | undefined {\n if (header === null || header.trim() === \"\") {\n return undefined;\n }\n const sec = Number.parseInt(header, 10);\n if (!Number.isFinite(sec) || sec < 0) {\n return undefined;\n }\n return sec * 1000;\n}\n\nfunction extractAssistantText(\n data: ReturnType<typeof parseDeepSeekChatCompletion>,\n model: string,\n): string {\n const choices = data.choices;\n const first = choices !== undefined && choices.length > 0 ? choices[0] : undefined;\n const msg = first?.message;\n const content = msg?.content;\n const finish = first?.finish_reason ?? \"UNKNOWN\";\n if (typeof content === \"string\" && content.trim() !== \"\") {\n return content;\n }\n const usage = data.usage;\n const reasoningTokens = usage?.completion_tokens_details?.reasoning_tokens ?? 0;\n const completionTokens = usage?.completion_tokens ?? 0;\n throw new DeepSeekEmptyContentError(\n `Respuesta de ${model} sin texto (finish=${String(finish)}, reasoning_tokens=${String(reasoningTokens)}, completion_tokens=${String(completionTokens)}). Probablemente reasoning agotó budget.`,\n model,\n String(finish),\n );\n}\n\nfunction isRetryableStatus(status: number): boolean {\n return status === 429 || status >= 500;\n}\n\nfunction shouldAbortCascade(status: number): boolean {\n if (status === 401 || status === 402 || status === 403 || status === 404 || status === 400) {\n return true;\n }\n return false;\n}\n\nconst INVALID_DEEPSEEK_API_KEY_USER_MESSAGE =\n \"Clave de API inválida o revocada. Regenera DEEPSEEK_API_KEY en el entorno de frontend y redespliega.\";\n\nfunction compactResponseTextForDiagnostics(\n json: unknown | undefined,\n rawTextSnippet: string | undefined,\n): string {\n if (rawTextSnippet !== undefined && rawTextSnippet.trim() !== \"\") {\n return rawTextSnippet.slice(0, 2000);\n }\n if (json === undefined) {\n return \"\";\n }\n try {\n return JSON.stringify(json).slice(0, 2000);\n } catch {\n return \"\";\n }\n}\n\nfunction bodySuggestsInvalidDeepSeekApiKey(haystackLower: string): boolean {\n if (haystackLower === \"\") {\n return false;\n }\n const needles: readonly string[] = [\n \"invalid_api_key\",\n \"incorrect api key\",\n \"invalid authentication\",\n \"authentication failed\",\n \"api key is invalid\",\n \"invalid bearer token\",\n ];\n return needles.some((needle) => haystackLower.includes(needle));\n}\n\nfunction isInvalidDeepSeekApiKeyCase(\n status: number,\n json: unknown | undefined,\n rawTextSnippet: string | undefined,\n): boolean {\n if (status === 401) {\n return true;\n }\n const haystack = compactResponseTextForDiagnostics(json, rawTextSnippet).toLowerCase();\n return bodySuggestsInvalidDeepSeekApiKey(haystack);\n}\n\nasync function postOnce(params: {\n readonly url: string;\n readonly apiKey: string;\n readonly model: string;\n readonly messages: RunDeepSeekCascadeParams[\"messages\"];\n readonly temperature: number;\n readonly maxTokens: number;\n readonly timeoutMs: number;\n readonly signal: AbortSignal | undefined;\n}): Promise<{\n readonly status: number;\n readonly json: unknown | undefined;\n readonly rawTextSnippet: string | undefined;\n readonly retryAfterMs?: number;\n}> {\n const controller = new AbortController();\n const timer = setTimeout(() => {\n controller.abort(new Error(\"DEEPSEEK_TIMEOUT\"));\n }, params.timeoutMs);\n const outer = params.signal;\n const onParentAbort = (): void => {\n controller.abort(outer?.reason ?? new Error(\"Aborted\"));\n };\n outer?.addEventListener(\"abort\", onParentAbort, { once: true });\n const body = JSON.stringify({\n model: params.model,\n messages: params.messages,\n temperature: params.temperature,\n max_tokens: params.maxTokens,\n top_p: 0.95,\n stream: false,\n });\n try {\n const res = await fetch(params.url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${params.apiKey}`,\n },\n body,\n signal: controller.signal,\n });\n const retryAfterMs = parseRetryAfterMs(res.headers.get(\"retry-after\"));\n const ct = res.headers.get(\"content-type\") ?? \"\";\n if (ct.includes(\"application/json\")) {\n const parsedJson: unknown = await res.json();\n return { status: res.status, json: parsedJson, rawTextSnippet: undefined, retryAfterMs };\n }\n const t = await res.text();\n return {\n status: res.status,\n json: undefined,\n rawTextSnippet: t.slice(0, 500),\n retryAfterMs,\n };\n } finally {\n clearTimeout(timer);\n outer?.removeEventListener(\"abort\", onParentAbort);\n }\n}\n\n/**\n * Invoca la API chat/completions de DeepSeek con lista de modelos en cascada,\n * reintentos con backoff exponencial + jitter en 429/5xx y errores de red.\n */\nexport async function runDeepSeekCascade(\n params: RunDeepSeekCascadeParams,\n): Promise<RunDeepSeekCascadeResult> {\n const cfg = loadDeepSeekClientConfigFromEnv();\n const cascade =\n params.modelCascade !== undefined && params.modelCascade.length > 0\n ? [...params.modelCascade]\n : [...cfg.modelCascadeDefault];\n const temperature = params.temperature ?? 0.15;\n const maxTokens = params.maxTokens ?? 8192;\n const causes: string[] = [];\n let attempts = 0;\n\n for (const model of cascade) {\n for (let r = 0; r < cfg.maxRetriesPerModel; r += 1) {\n attempts += 1;\n try {\n const { status, json, rawTextSnippet, retryAfterMs } = await postOnce({\n url: cfg.chatCompletionsUrl,\n apiKey: cfg.apiKey,\n model,\n messages: params.messages,\n temperature,\n maxTokens,\n timeoutMs: cfg.requestTimeoutMs,\n signal: params.signal,\n });\n if (status >= 200 && status < 300) {\n if (json === undefined) {\n causes.push(`[${model}] 200 sin JSON (texto): ${rawTextSnippet ?? \"\"}`);\n break;\n }\n const parsed = parseDeepSeekChatCompletion(json);\n const text = extractAssistantText(parsed, model);\n return { text, modelUsed: model, attempts };\n }\n const snippet =\n rawTextSnippet !== undefined\n ? rawTextSnippet\n : json === undefined\n ? \"\"\n : JSON.stringify(json).slice(0, 400);\n if (shouldAbortCascade(status)) {\n if (isInvalidDeepSeekApiKeyCase(status, json, rawTextSnippet)) {\n throw new DeepSeekHttpError(INVALID_DEEPSEEK_API_KEY_USER_MESSAGE, status, \"\");\n }\n throw new DeepSeekHttpError(`DeepSeek HTTP ${String(status)}: ${snippet}`, status, snippet);\n }\n if (isRetryableStatus(status)) {\n causes.push(`[${model}] HTTP ${String(status)} intento ${String(r + 1)}: ${snippet}`);\n if (r + 1 < cfg.maxRetriesPerModel) {\n const backoff =\n status === 429 && retryAfterMs !== undefined\n ? retryAfterMs\n : computeBackoffMs(r, cfg.backoffBaseMs, cfg.backoffMaxMs);\n await sleep(backoff, params.signal);\n }\n continue;\n }\n causes.push(`[${model}] HTTP ${String(status)} no reintentable: ${snippet}`);\n break;\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n if (e instanceof DeepSeekHttpError) {\n throw e;\n }\n if (e instanceof DeepSeekEmptyContentError) {\n causes.push(`${e.name}: ${e.message}`);\n break;\n }\n causes.push(`[${model}] ${msg}`);\n if (r + 1 < cfg.maxRetriesPerModel) {\n const backoff = computeBackoffMs(r, cfg.backoffBaseMs, cfg.backoffMaxMs);\n await sleep(backoff, params.signal);\n }\n }\n }\n }\n\n throw new DeepSeekCascadeExhaustedError(\n \"Cascada DeepSeek agotada sin respuesta válida.\",\n attempts,\n causes,\n );\n}\n"}}}}