@nyte-ai/ai 0.0.0-stage → 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +170 -2
- package/THIRD-PARTY-NOTICES.md +866 -0
- package/dist/chunks/account-limits-cache-031vfpt3.js +37 -0
- package/dist/chunks/account-limits-cache-09vs98g6.js +41 -0
- package/dist/chunks/account-limits-cache-0af5gqeg.js +15 -0
- package/dist/chunks/account-limits-cache-0yd6bde8.js +103 -0
- package/dist/chunks/account-limits-cache-1jv43fhh.js +22 -0
- package/dist/chunks/account-limits-cache-3ykqmnj5.js +88 -0
- package/dist/chunks/account-limits-cache-4b8ckwqw.js +293 -0
- package/dist/chunks/account-limits-cache-4fn5w63p.js +295 -0
- package/dist/chunks/account-limits-cache-4hptgd2h.js +49 -0
- package/dist/chunks/account-limits-cache-53e64mhx.js +417 -0
- package/dist/chunks/account-limits-cache-5jdhn0e1.js +562 -0
- package/dist/chunks/account-limits-cache-5rx2pfm5.js +8 -0
- package/dist/chunks/account-limits-cache-5ygxyyss.js +19 -0
- package/dist/chunks/account-limits-cache-6250ykn6.js +21 -0
- package/dist/chunks/account-limits-cache-6x05n06z.js +49 -0
- package/dist/chunks/account-limits-cache-736tdyme.js +6 -0
- package/dist/chunks/account-limits-cache-75smws02.js +213 -0
- package/dist/chunks/account-limits-cache-7z9s8j16.js +139 -0
- package/dist/chunks/account-limits-cache-8137j3zp.js +37 -0
- package/dist/chunks/account-limits-cache-8qzk56vj.js +160 -0
- package/dist/chunks/account-limits-cache-8s8bz4dr.js +36 -0
- package/dist/chunks/account-limits-cache-8vzx8k6r.js +166 -0
- package/dist/chunks/account-limits-cache-8wfqg73s.js +135 -0
- package/dist/chunks/account-limits-cache-90c9c2eb.js +50 -0
- package/dist/chunks/account-limits-cache-9wqk28n5.js +25 -0
- package/dist/chunks/account-limits-cache-a1jyaq00.js +56 -0
- package/dist/chunks/account-limits-cache-a558rjbg.js +138 -0
- package/dist/chunks/account-limits-cache-a55e14fr.js +70 -0
- package/dist/chunks/account-limits-cache-a6cgeagz.js +77 -0
- package/dist/chunks/account-limits-cache-ag5b8dja.js +38 -0
- package/dist/chunks/account-limits-cache-b0x2sfya.js +45 -0
- package/dist/chunks/account-limits-cache-b23sbrke.js +26 -0
- package/dist/chunks/account-limits-cache-b4edaybk.js +8 -0
- package/dist/chunks/account-limits-cache-bsknrh6t.js +74 -0
- package/dist/chunks/account-limits-cache-csbxvam7.js +12 -0
- package/dist/chunks/account-limits-cache-cw7q7vfy.js +293 -0
- package/dist/chunks/account-limits-cache-d1ypzqzp.js +27 -0
- package/dist/chunks/account-limits-cache-d2a51dka.js +17 -0
- package/dist/chunks/account-limits-cache-dejeygdt.js +114 -0
- package/dist/chunks/account-limits-cache-eejm0vth.js +11 -0
- package/dist/chunks/account-limits-cache-ehy0ze2b.js +33 -0
- package/dist/chunks/account-limits-cache-emg5b4hj.js +53 -0
- package/dist/chunks/account-limits-cache-eqwweapz.js +6 -0
- package/dist/chunks/account-limits-cache-eyx1jcxc.js +8 -0
- package/dist/chunks/account-limits-cache-f9z00x8c.js +36 -0
- package/dist/chunks/account-limits-cache-fbkaq46e.js +113 -0
- package/dist/chunks/account-limits-cache-fdwad56n.js +399 -0
- package/dist/chunks/account-limits-cache-fht68jp2.js +22 -0
- package/dist/chunks/account-limits-cache-fp03ztsw.js +17 -0
- package/dist/chunks/account-limits-cache-fsktnetm.js +69 -0
- package/dist/chunks/account-limits-cache-fvadc36m.js +110 -0
- package/dist/chunks/account-limits-cache-gknnm1kv.js +13 -0
- package/dist/chunks/account-limits-cache-gqsrbky9.js +40 -0
- package/dist/chunks/account-limits-cache-gr671dr2.js +0 -0
- package/dist/chunks/account-limits-cache-gs8a3fhw.js +32 -0
- package/dist/chunks/account-limits-cache-gsa5tzck.js +37 -0
- package/dist/chunks/account-limits-cache-h92bzz1j.js +235 -0
- package/dist/chunks/account-limits-cache-hemxtapd.js +142 -0
- package/dist/chunks/account-limits-cache-hj1h48sc.js +92 -0
- package/dist/chunks/account-limits-cache-hj3ek3ty.js +128 -0
- package/dist/chunks/account-limits-cache-hwehc67r.js +509 -0
- package/dist/chunks/account-limits-cache-hyzn1jmk.js +46 -0
- package/dist/chunks/account-limits-cache-j2bt392s.js +63 -0
- package/dist/chunks/account-limits-cache-k0pkzhbx.js +74 -0
- package/dist/chunks/account-limits-cache-kjx405q0.js +277 -0
- package/dist/chunks/account-limits-cache-ks1sjym9.js +37 -0
- package/dist/chunks/account-limits-cache-me1x57bs.js +89 -0
- package/dist/chunks/account-limits-cache-n3yk6g5c.js +314 -0
- package/dist/chunks/account-limits-cache-nbhht7xz.js +72 -0
- package/dist/chunks/account-limits-cache-nbkyhs6v.js +42 -0
- package/dist/chunks/account-limits-cache-nn9jebsj.js +26 -0
- package/dist/chunks/account-limits-cache-nxkprk3g.js +13 -0
- package/dist/chunks/account-limits-cache-nyy770yd.js +38 -0
- package/dist/chunks/account-limits-cache-pfa86y8e.js +45 -0
- package/dist/chunks/account-limits-cache-pfr14mcn.js +59 -0
- package/dist/chunks/account-limits-cache-q1ebtvet.js +8 -0
- package/dist/chunks/account-limits-cache-q63mc41j.js +51 -0
- package/dist/chunks/account-limits-cache-re8hpzwn.js +104 -0
- package/dist/chunks/account-limits-cache-rz8p1g5y.js +9 -0
- package/dist/chunks/account-limits-cache-skbfmzqe.js +7 -0
- package/dist/chunks/account-limits-cache-tc38g0ca.js +20 -0
- package/dist/chunks/account-limits-cache-v4n30az2.js +24 -0
- package/dist/chunks/account-limits-cache-vwgfz727.js +281 -0
- package/dist/chunks/account-limits-cache-wtg64ez7.js +69 -0
- package/dist/chunks/account-limits-cache-x9fvb3s5.js +8 -0
- package/dist/chunks/account-limits-cache-xds88kxd.js +209 -0
- package/dist/chunks/account-limits-cache-xz65wyd1.js +428 -0
- package/dist/chunks/account-limits-cache-ydq8p8qp.js +39 -0
- package/dist/chunks/account-limits-cache-ykbqsvv6.js +134 -0
- package/dist/chunks/account-limits-cache-yzyp0c2h.js +251 -0
- package/dist/chunks/account-limits-cache-za42x8a3.js +25 -0
- package/dist/chunks/account-limits-cache-zcbkmrvy.js +79 -0
- package/dist/chunks/account-limits-cache-zgzptd0z.js +62 -0
- package/dist/chunks/account-limits-cache-zn01kscn.js +252 -0
- package/dist/chunks/account-limits-cache-zpjmeyt0.js +113 -0
- package/dist/chunks/account-limits-cache-zqdb4yh4.js +8 -0
- package/dist/src/account-limits-cache.d.ts +16 -0
- package/dist/src/account-limits-cache.js +7 -0
- package/dist/src/api/anthropic-client.d.ts +25 -0
- package/dist/src/api/anthropic-client.js +30 -0
- package/dist/src/api/anthropic-convert.d.ts +17 -0
- package/dist/src/api/anthropic-convert.js +14 -0
- package/dist/src/api/anthropic-events.d.ts +101 -0
- package/dist/src/api/anthropic-events.js +11 -0
- package/dist/src/api/anthropic-messages.d.ts +88 -0
- package/dist/src/api/anthropic-messages.js +578 -0
- package/dist/src/api/anthropic-messages.lazy.d.ts +2 -0
- package/dist/src/api/anthropic-messages.lazy.js +11 -0
- package/dist/src/api/assistant-stream.d.ts +23 -0
- package/dist/src/api/assistant-stream.js +15 -0
- package/dist/src/api/claude-code.d.ts +12 -0
- package/dist/src/api/claude-code.js +12 -0
- package/dist/src/api/cloudflare.d.ts +8 -0
- package/dist/src/api/cloudflare.js +11 -0
- package/dist/src/api/constrained-sampling.d.ts +24 -0
- package/dist/src/api/constrained-sampling.js +16 -0
- package/dist/src/api/deferred.d.ts +7 -0
- package/dist/src/api/deferred.js +10 -0
- package/dist/src/api/github-copilot-headers.d.ts +15 -0
- package/dist/src/api/github-copilot-headers.js +12 -0
- package/dist/src/api/google-generative-ai.d.ts +22 -0
- package/dist/src/api/google-generative-ai.js +583 -0
- package/dist/src/api/google-generative-ai.lazy.d.ts +2 -0
- package/dist/src/api/google-generative-ai.lazy.js +11 -0
- package/dist/src/api/lazy.d.ts +18 -0
- package/dist/src/api/lazy.js +12 -0
- package/dist/src/api/openai-codex-compact.d.ts +14 -0
- package/dist/src/api/openai-codex-compact.js +389 -0
- package/dist/src/api/openai-codex-compaction-error.d.ts +7 -0
- package/dist/src/api/openai-codex-compaction-error.js +6 -0
- package/dist/src/api/openai-codex-protocol.d.ts +125 -0
- package/dist/src/api/openai-codex-protocol.js +48 -0
- package/dist/src/api/openai-codex-responses.d.ts +4 -0
- package/dist/src/api/openai-codex-responses.js +175 -0
- package/dist/src/api/openai-codex-responses.lazy.d.ts +2 -0
- package/dist/src/api/openai-codex-responses.lazy.js +11 -0
- package/dist/src/api/openai-codex-websocket.d.ts +13 -0
- package/dist/src/api/openai-codex-websocket.js +37 -0
- package/dist/src/api/openai-codex-wire.d.ts +44 -0
- package/dist/src/api/openai-codex-wire.js +34 -0
- package/dist/src/api/openai-compact.d.ts +9 -0
- package/dist/src/api/openai-compact.js +12 -0
- package/dist/src/api/openai-completions-convert.d.ts +58 -0
- package/dist/src/api/openai-completions-convert.js +21 -0
- package/dist/src/api/openai-completions-params.d.ts +29 -0
- package/dist/src/api/openai-completions-params.js +20 -0
- package/dist/src/api/openai-completions-reasoning.d.ts +54 -0
- package/dist/src/api/openai-completions-reasoning.js +22 -0
- package/dist/src/api/openai-completions.d.ts +22 -0
- package/dist/src/api/openai-completions.js +484 -0
- package/dist/src/api/openai-completions.lazy.d.ts +5 -0
- package/dist/src/api/openai-completions.lazy.js +11 -0
- package/dist/src/api/openai-prompt-cache.d.ts +1 -0
- package/dist/src/api/openai-prompt-cache.js +6 -0
- package/dist/src/api/openai-responses-convert.d.ts +58 -0
- package/dist/src/api/openai-responses-convert.js +16 -0
- package/dist/src/api/openai-responses-events.d.ts +379 -0
- package/dist/src/api/openai-responses-events.js +12 -0
- package/dist/src/api/openai-responses-stream.d.ts +36 -0
- package/dist/src/api/openai-responses-stream.js +25 -0
- package/dist/src/api/openai-responses.d.ts +18 -0
- package/dist/src/api/openai-responses.js +276 -0
- package/dist/src/api/openai-responses.lazy.d.ts +2 -0
- package/dist/src/api/openai-responses.lazy.js +11 -0
- package/dist/src/api/simple-options.d.ts +17 -0
- package/dist/src/api/simple-options.js +18 -0
- package/dist/src/api/token-count.d.ts +5 -0
- package/dist/src/api/token-count.js +8 -0
- package/dist/src/api/transform-messages.d.ts +9 -0
- package/dist/src/api/transform-messages.js +6 -0
- package/dist/src/api-options.d.ts +27 -0
- package/dist/src/api-options.js +0 -0
- package/dist/src/auth/context.d.ts +11 -0
- package/dist/src/auth/context.js +6 -0
- package/dist/src/auth/credential-store.d.ts +17 -0
- package/dist/src/auth/credential-store.js +7 -0
- package/dist/src/auth/helpers.d.ts +24 -0
- package/dist/src/auth/helpers.js +8 -0
- package/dist/src/auth/oauth/anthropic.d.ts +7 -0
- package/dist/src/auth/oauth/anthropic.js +12 -0
- package/dist/src/auth/oauth/authorization-input.d.ts +14 -0
- package/dist/src/auth/oauth/authorization-input.js +6 -0
- package/dist/src/auth/oauth/device-code.d.ts +29 -0
- package/dist/src/auth/oauth/device-code.js +9 -0
- package/dist/src/auth/oauth/github-copilot.d.ts +23 -0
- package/dist/src/auth/oauth/github-copilot.js +12 -0
- package/dist/src/auth/oauth/load.d.ts +14 -0
- package/dist/src/auth/oauth/load.js +10 -0
- package/dist/src/auth/oauth/oauth-page.d.ts +13 -0
- package/dist/src/auth/oauth/oauth-page.js +8 -0
- package/dist/src/auth/oauth/openai-codex.d.ts +10 -0
- package/dist/src/auth/oauth/openai-codex.js +18 -0
- package/dist/src/auth/oauth/pkce.d.ts +12 -0
- package/dist/src/auth/oauth/pkce.js +6 -0
- package/dist/src/auth/resolve.d.ts +38 -0
- package/dist/src/auth/resolve.js +12 -0
- package/dist/src/auth/store.d.ts +29 -0
- package/dist/src/auth/store.js +10 -0
- package/dist/src/auth/types.d.ts +291 -0
- package/dist/src/auth/types.js +8 -0
- package/dist/src/auth/verify.d.ts +13 -0
- package/dist/src/auth/verify.js +7 -0
- package/dist/src/bun-oauth.d.ts +2 -0
- package/dist/src/bun-oauth.js +25 -0
- package/dist/src/env-api-keys.d.ts +32 -0
- package/dist/src/env-api-keys.js +27 -0
- package/dist/src/file-models-store.d.ts +18 -0
- package/dist/src/file-models-store.js +9 -0
- package/dist/src/index.d.ts +62 -0
- package/dist/src/index.js +372 -0
- package/dist/src/model-capabilities.d.ts +21 -0
- package/dist/src/model-capabilities.js +14 -0
- package/dist/src/model-pricing.d.ts +6 -0
- package/dist/src/model-pricing.js +10 -0
- package/dist/src/model-variants.d.ts +21 -0
- package/dist/src/model-variants.js +19 -0
- package/dist/src/models-refresh.d.ts +27 -0
- package/dist/src/models-refresh.js +9 -0
- package/dist/src/models-store.d.ts +31 -0
- package/dist/src/models-store.js +6 -0
- package/dist/src/models-types.d.ts +206 -0
- package/dist/src/models-types.js +0 -0
- package/dist/src/models.d.ts +7 -0
- package/dist/src/models.js +44 -0
- package/dist/src/prompt-cache.d.ts +5 -0
- package/dist/src/prompt-cache.js +9 -0
- package/dist/src/provider.d.ts +23 -0
- package/dist/src/provider.js +14 -0
- package/dist/src/providers/account-limits.d.ts +13 -0
- package/dist/src/providers/account-limits.js +8 -0
- package/dist/src/providers/anthropic-limits.d.ts +9 -0
- package/dist/src/providers/anthropic-limits.js +10 -0
- package/dist/src/providers/anthropic.d.ts +2 -0
- package/dist/src/providers/anthropic.js +25 -0
- package/dist/src/providers/github-copilot-catalog.d.ts +5 -0
- package/dist/src/providers/github-copilot-catalog.js +7 -0
- package/dist/src/providers/github-copilot.d.ts +2 -0
- package/dist/src/providers/github-copilot.js +23 -0
- package/dist/src/providers/nyte-catalog.d.ts +15 -0
- package/dist/src/providers/nyte-catalog.js +63 -0
- package/dist/src/providers/openai-codex-limits.d.ts +8 -0
- package/dist/src/providers/openai-codex-limits.js +14 -0
- package/dist/src/providers/openai-codex.d.ts +2 -0
- package/dist/src/providers/openai-codex.js +23 -0
- package/dist/src/providers/openai.d.ts +2 -0
- package/dist/src/providers/openai.js +19 -0
- package/dist/src/providers/opencode-go.d.ts +5 -0
- package/dist/src/providers/opencode-go.js +22 -0
- package/dist/src/providers/opencode-headers.d.ts +5 -0
- package/dist/src/providers/opencode-headers.js +6 -0
- package/dist/src/providers/opencode.d.ts +14 -0
- package/dist/src/providers/opencode.js +23 -0
- package/dist/src/providers/openrouter.d.ts +2 -0
- package/dist/src/providers/openrouter.js +19 -0
- package/dist/src/providers/vercel-ai-gateway.d.ts +3 -0
- package/dist/src/providers/vercel-ai-gateway.js +19 -0
- package/dist/src/session-resources.d.ts +9 -0
- package/dist/src/session-resources.js +10 -0
- package/dist/src/types.d.ts +210 -0
- package/dist/src/types.js +1 -0
- package/dist/src/utils/abort.d.ts +12 -0
- package/dist/src/utils/abort.js +10 -0
- package/dist/src/utils/deferred-tools.d.ts +11 -0
- package/dist/src/utils/deferred-tools.js +6 -0
- package/dist/src/utils/diagnostics.d.ts +11 -0
- package/dist/src/utils/diagnostics.js +12 -0
- package/dist/src/utils/error-body.d.ts +26 -0
- package/dist/src/utils/error-body.js +10 -0
- package/dist/src/utils/estimate.d.ts +20 -0
- package/dist/src/utils/estimate.js +14 -0
- package/dist/src/utils/event-stream.d.ts +22 -0
- package/dist/src/utils/event-stream.js +11 -0
- package/dist/src/utils/failure.d.ts +49 -0
- package/dist/src/utils/failure.js +10 -0
- package/dist/src/utils/fifo-queue.d.ts +11 -0
- package/dist/src/utils/fifo-queue.js +6 -0
- package/dist/src/utils/hash.d.ts +5 -0
- package/dist/src/utils/hash.js +6 -0
- package/dist/src/utils/headers.d.ts +12 -0
- package/dist/src/utils/headers.js +14 -0
- package/dist/src/utils/json-parse.d.ts +33 -0
- package/dist/src/utils/json-parse.js +12 -0
- package/dist/src/utils/node-http-proxy.d.ts +6 -0
- package/dist/src/utils/node-http-proxy.js +9 -0
- package/dist/src/utils/nyte-home.d.ts +2 -0
- package/dist/src/utils/nyte-home.js +6 -0
- package/dist/src/utils/nyte-user-agent.d.ts +1 -0
- package/dist/src/utils/nyte-user-agent.js +6 -0
- package/dist/src/utils/overflow.d.ts +18 -0
- package/dist/src/utils/overflow.js +9 -0
- package/dist/src/utils/provider-env.d.ts +9 -0
- package/dist/src/utils/provider-env.js +6 -0
- package/dist/src/utils/provider-retry.d.ts +22 -0
- package/dist/src/utils/provider-retry.js +9 -0
- package/dist/src/utils/retry.d.ts +66 -0
- package/dist/src/utils/retry.js +18 -0
- package/dist/src/utils/sanitize-unicode.d.ts +24 -0
- package/dist/src/utils/sanitize-unicode.js +6 -0
- package/dist/src/utils/sse.d.ts +21 -0
- package/dist/src/utils/sse.js +6 -0
- package/dist/src/utils/text.d.ts +5 -0
- package/dist/src/utils/text.js +10 -0
- package/dist/src/utils/transcript.d.ts +5 -0
- package/dist/src/utils/transcript.js +36 -0
- package/dist/src/utils/typebox-helpers.d.ts +19 -0
- package/dist/src/utils/typebox-helpers.js +6 -0
- package/dist/src/utils/uuid.d.ts +2 -0
- package/dist/src/utils/uuid.js +6 -0
- package/dist/src/utils/validation.d.ts +13 -0
- package/dist/src/utils/validation.js +8 -0
- package/package.json +152 -3
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// src/utils/failure.ts
|
|
2
|
+
var CONTEXT_WINDOW_PATTERNS = [
|
|
3
|
+
/prompt (?:is )?too long/i,
|
|
4
|
+
/prompt exceeds max length/i,
|
|
5
|
+
/request_too_large/i,
|
|
6
|
+
/input is too long for requested model/i,
|
|
7
|
+
/exceeds the context window/i,
|
|
8
|
+
/exceeds (?:the )?(?:model'?s )?maximum context length(?: of [\d,]+ tokens?|\s*\([\d,]+\))/i,
|
|
9
|
+
/input token count.*exceeds the maximum/i,
|
|
10
|
+
/maximum prompt length is \d+/i,
|
|
11
|
+
/reduce the length of the messages/i,
|
|
12
|
+
/maximum context length is \d+ tokens/i,
|
|
13
|
+
/exceeds (?:the )?maximum allowed input length of [\d,]+ tokens?/i,
|
|
14
|
+
/input \(\d+ tokens\) is longer than the model'?s context length \(\d+ tokens\)/i,
|
|
15
|
+
/exceeds the limit of \d+/i,
|
|
16
|
+
/exceeds the available context size/i,
|
|
17
|
+
/greater than the context length/i,
|
|
18
|
+
/context window exceeds limit/i,
|
|
19
|
+
/exceeded model token limit/i,
|
|
20
|
+
/too large for model with \d+ maximum context length/i,
|
|
21
|
+
/prompt has [\d,]+ tokens?, but the configured context size is [\d,]+ tokens?/i,
|
|
22
|
+
/model_context_window_exceeded/i,
|
|
23
|
+
/prompt too long; exceeded (?:max )?context length/i,
|
|
24
|
+
/range of input length should be/i,
|
|
25
|
+
/context[_ ]length[_ ]exceeded/i,
|
|
26
|
+
/too many tokens/i,
|
|
27
|
+
/token limit exceeded/i
|
|
28
|
+
];
|
|
29
|
+
var CEREBRAS_BODYLESS_CONTEXT_WINDOW_PATTERN = /^4(?:00|13)\s*(?:status code)?\s*\(no body\)/i;
|
|
30
|
+
var NOT_CONTEXT_WINDOW_PATTERN = /^(Throttling error|Service unavailable):|rate limit|too many requests/i;
|
|
31
|
+
function pattern(parts) {
|
|
32
|
+
return new RegExp(parts.join("|"), "i");
|
|
33
|
+
}
|
|
34
|
+
var QUOTA_PATTERN = pattern([
|
|
35
|
+
"GoUsageLimitError",
|
|
36
|
+
"FreeUsageLimitError",
|
|
37
|
+
"Monthly usage limit reached",
|
|
38
|
+
"available balance",
|
|
39
|
+
"insufficient[_ -]?quota",
|
|
40
|
+
"out[_ ]of[_ ]credits",
|
|
41
|
+
"out of budget",
|
|
42
|
+
"quota exceeded",
|
|
43
|
+
"billing"
|
|
44
|
+
]);
|
|
45
|
+
function reportsQuotaExhaustion2(text) {
|
|
46
|
+
return QUOTA_PATTERN.test(text);
|
|
47
|
+
}
|
|
48
|
+
var AUTH_PATTERN = pattern([
|
|
49
|
+
"\\b401\\b",
|
|
50
|
+
"unauthori[sz]ed",
|
|
51
|
+
"invalid (?:x-)?api[ _-]?key",
|
|
52
|
+
"authentication"
|
|
53
|
+
]);
|
|
54
|
+
var RATE_LIMIT_PATTERN = pattern([
|
|
55
|
+
"rate[_ .-]?limit",
|
|
56
|
+
"too many requests",
|
|
57
|
+
"throttl",
|
|
58
|
+
"ResourceExhausted",
|
|
59
|
+
"retry delay"
|
|
60
|
+
]);
|
|
61
|
+
var OVERLOADED_PATTERN = pattern([
|
|
62
|
+
"\\b529\\b",
|
|
63
|
+
"\\b5(?:00|02|03|04|20|24)\\b",
|
|
64
|
+
"overload",
|
|
65
|
+
"currently experiencing high demand",
|
|
66
|
+
"model is at capacity",
|
|
67
|
+
"service.?unavailable",
|
|
68
|
+
"temporarily unavailable",
|
|
69
|
+
"server.?error",
|
|
70
|
+
"internal.?error",
|
|
71
|
+
"provider.?returned.?error",
|
|
72
|
+
"exceeded request buffer limit while retrying upstream",
|
|
73
|
+
"you can retry your request",
|
|
74
|
+
"try your request again",
|
|
75
|
+
"please retry your request"
|
|
76
|
+
]);
|
|
77
|
+
var NETWORK_PATTERN = pattern([
|
|
78
|
+
"network",
|
|
79
|
+
"fetch failed",
|
|
80
|
+
"ECONN",
|
|
81
|
+
"connection.?(?:lost|refused|reset|error)",
|
|
82
|
+
"other side closed",
|
|
83
|
+
"getaddrinfo",
|
|
84
|
+
"ENOTFOUND",
|
|
85
|
+
"EAI_AGAIN",
|
|
86
|
+
"upstream.?connect",
|
|
87
|
+
"reset before headers",
|
|
88
|
+
"socket hang up",
|
|
89
|
+
"socket connection was closed",
|
|
90
|
+
"timed? out",
|
|
91
|
+
"timeout",
|
|
92
|
+
"terminated",
|
|
93
|
+
"websocket.?(?:closed|error)",
|
|
94
|
+
"ended without",
|
|
95
|
+
"stream ended before message_stop",
|
|
96
|
+
"stream ended before a terminal response event",
|
|
97
|
+
"http2 request did not get a response"
|
|
98
|
+
]);
|
|
99
|
+
var RETRY_DELAY_PATTERN = /server requested ([0-9]+(?:\.[0-9]+)?)s retry delay(?: \(max: ([0-9]+(?:\.[0-9]+)?)s\))?/i;
|
|
100
|
+
function classForStatus(status) {
|
|
101
|
+
if (status === 429)
|
|
102
|
+
return "rate_limit";
|
|
103
|
+
if (status === 401 || status === 403)
|
|
104
|
+
return "auth";
|
|
105
|
+
if (status === 402)
|
|
106
|
+
return "quota";
|
|
107
|
+
if (status === 413)
|
|
108
|
+
return "context_window";
|
|
109
|
+
if (status >= 500 && status <= 599)
|
|
110
|
+
return "overloaded";
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
function structuredClass(message) {
|
|
114
|
+
for (const diagnostic of message.diagnostics ?? []) {
|
|
115
|
+
for (const value of [
|
|
116
|
+
diagnostic.details?.status,
|
|
117
|
+
diagnostic.details?.statusCode,
|
|
118
|
+
diagnostic.error?.code
|
|
119
|
+
]) {
|
|
120
|
+
const status = typeof value === "number" ? value : typeof value === "string" && /^\d{3}$/u.test(value) ? Number(value) : Number.NaN;
|
|
121
|
+
if (!Number.isInteger(status))
|
|
122
|
+
continue;
|
|
123
|
+
const failureClass = classForStatus(status);
|
|
124
|
+
if (failureClass !== undefined)
|
|
125
|
+
return failureClass;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
function classifyText(text, provider) {
|
|
131
|
+
if (!NOT_CONTEXT_WINDOW_PATTERN.test(text) && (CONTEXT_WINDOW_PATTERNS.some((p) => p.test(text)) || provider === "cerebras" && CEREBRAS_BODYLESS_CONTEXT_WINDOW_PATTERN.test(text))) {
|
|
132
|
+
return "context_window";
|
|
133
|
+
}
|
|
134
|
+
if (reportsQuotaExhaustion2(text))
|
|
135
|
+
return "quota";
|
|
136
|
+
if (RATE_LIMIT_PATTERN.test(text))
|
|
137
|
+
return "rate_limit";
|
|
138
|
+
if (OVERLOADED_PATTERN.test(text))
|
|
139
|
+
return "overloaded";
|
|
140
|
+
if (NETWORK_PATTERN.test(text))
|
|
141
|
+
return "network";
|
|
142
|
+
if (AUTH_PATTERN.test(text))
|
|
143
|
+
return "auth";
|
|
144
|
+
if (/\b429\b/u.test(text))
|
|
145
|
+
return "rate_limit";
|
|
146
|
+
return "provider";
|
|
147
|
+
}
|
|
148
|
+
function retryAfterMs(message) {
|
|
149
|
+
for (const diagnostic of message.diagnostics ?? []) {
|
|
150
|
+
for (const key of ["retryAfterMs", "retryDelayMs"]) {
|
|
151
|
+
const value = diagnostic.details?.[key];
|
|
152
|
+
if (typeof value === "number" && Number.isFinite(value) && value >= 0)
|
|
153
|
+
return value;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const match = message.errorMessage?.match(RETRY_DELAY_PATTERN);
|
|
157
|
+
const seconds = match === null || match === undefined ? Number.NaN : Number(match[1]);
|
|
158
|
+
const maximum = match === null || match === undefined ? Number.NaN : Number(match[2]);
|
|
159
|
+
if (!Number.isFinite(seconds) || seconds < 0)
|
|
160
|
+
return;
|
|
161
|
+
return Number.isFinite(maximum) && maximum > 0 && seconds > maximum ? undefined : seconds * 1000;
|
|
162
|
+
}
|
|
163
|
+
function silentOverflow(message, contextWindow) {
|
|
164
|
+
if (contextWindow === undefined || contextWindow === 0)
|
|
165
|
+
return false;
|
|
166
|
+
const inputTokens = message.usage.input + message.usage.cacheRead;
|
|
167
|
+
if (message.stopReason === "stop")
|
|
168
|
+
return inputTokens > contextWindow;
|
|
169
|
+
return message.stopReason === "length" && message.usage.output === 0 && inputTokens >= contextWindow * 0.99;
|
|
170
|
+
}
|
|
171
|
+
function classifyAssistantFailure2(message, model) {
|
|
172
|
+
if (message.stopReason === "aborted") {
|
|
173
|
+
return { class: "aborted", message: message.errorMessage ?? "Aborted" };
|
|
174
|
+
}
|
|
175
|
+
if (message.stopReason !== "error") {
|
|
176
|
+
return {
|
|
177
|
+
class: silentOverflow(message, model?.contextWindow) ? "context_window" : "provider",
|
|
178
|
+
message: message.errorMessage ?? ""
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
const text = message.errorMessage ?? "Unknown error";
|
|
182
|
+
const failure = {
|
|
183
|
+
class: reportsQuotaExhaustion2(text) ? "quota" : structuredClass(message) ?? classifyText(text, message.provider),
|
|
184
|
+
message: text
|
|
185
|
+
};
|
|
186
|
+
const delay = retryAfterMs(message);
|
|
187
|
+
return delay === undefined ? failure : { ...failure, retryAfterMs: delay };
|
|
188
|
+
}
|
|
189
|
+
function retryCanHelp2(failureClass) {
|
|
190
|
+
switch (failureClass) {
|
|
191
|
+
case "rate_limit":
|
|
192
|
+
case "overloaded":
|
|
193
|
+
case "network":
|
|
194
|
+
return true;
|
|
195
|
+
case "auth":
|
|
196
|
+
case "quota":
|
|
197
|
+
case "context_window":
|
|
198
|
+
case "aborted":
|
|
199
|
+
case "provider":
|
|
200
|
+
case "runner":
|
|
201
|
+
return false;
|
|
202
|
+
default: {
|
|
203
|
+
const _exhaustive = failureClass;
|
|
204
|
+
return _exhaustive;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export { reportsQuotaExhaustion2, classifyAssistantFailure2, retryCanHelp2 };
|
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getProviderEnvValue2
|
|
3
|
+
} from "./account-limits-cache-b23sbrke.js";
|
|
4
|
+
import {
|
|
5
|
+
OAuthTokenResponseSchema2
|
|
6
|
+
} from "./account-limits-cache-b0x2sfya.js";
|
|
7
|
+
import {
|
|
8
|
+
parseAuthorizationInput2
|
|
9
|
+
} from "./account-limits-cache-d1ypzqzp.js";
|
|
10
|
+
import {
|
|
11
|
+
pollOAuthDeviceCodeFlow2
|
|
12
|
+
} from "./account-limits-cache-4hptgd2h.js";
|
|
13
|
+
import {
|
|
14
|
+
oauthSuccessHtml2,
|
|
15
|
+
oauthErrorHtml2
|
|
16
|
+
} from "./account-limits-cache-8vzx8k6r.js";
|
|
17
|
+
import {
|
|
18
|
+
registerOAuthFlow2
|
|
19
|
+
} from "./account-limits-cache-v4n30az2.js";
|
|
20
|
+
import {
|
|
21
|
+
generatePKCE2
|
|
22
|
+
} from "./account-limits-cache-tc38g0ca.js";
|
|
23
|
+
|
|
24
|
+
// src/auth/oauth/openai-codex.ts
|
|
25
|
+
import { Type } from "typebox";
|
|
26
|
+
import { Value } from "typebox/value";
|
|
27
|
+
var CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
28
|
+
var AUTH_BASE_URL = "https://auth.openai.com";
|
|
29
|
+
var AUTHORIZE_URL = `${AUTH_BASE_URL}/oauth/authorize`;
|
|
30
|
+
var TOKEN_URL = `${AUTH_BASE_URL}/oauth/token`;
|
|
31
|
+
var REDIRECT_URI = "http://localhost:1455/auth/callback";
|
|
32
|
+
var DEVICE_USER_CODE_URL = `${AUTH_BASE_URL}/api/accounts/deviceauth/usercode`;
|
|
33
|
+
var DEVICE_TOKEN_URL = `${AUTH_BASE_URL}/api/accounts/deviceauth/token`;
|
|
34
|
+
var DEVICE_VERIFICATION_URI = `${AUTH_BASE_URL}/codex/device`;
|
|
35
|
+
var DEVICE_REDIRECT_URI = `${AUTH_BASE_URL}/deviceauth/callback`;
|
|
36
|
+
var DEVICE_CODE_TIMEOUT_SECONDS = 15 * 60;
|
|
37
|
+
var OPENAI_CODEX_BROWSER_LOGIN_METHOD = "browser";
|
|
38
|
+
var OPENAI_CODEX_DEVICE_CODE_LOGIN_METHOD = "device_code";
|
|
39
|
+
var SCOPE = "openid profile email offline_access";
|
|
40
|
+
var JWT_CLAIM_PATH = "https://api.openai.com/auth";
|
|
41
|
+
var ORIGINATOR2 = "nyte";
|
|
42
|
+
function getCallbackHost() {
|
|
43
|
+
return getProviderEnvValue2("NYTE_OAUTH_CALLBACK_HOST") || "127.0.0.1";
|
|
44
|
+
}
|
|
45
|
+
var DeviceCodeResponse = Type.Object({
|
|
46
|
+
device_auth_id: Type.String({ minLength: 1 }),
|
|
47
|
+
user_code: Type.String({ minLength: 1 }),
|
|
48
|
+
interval: Type.Union([Type.Number(), Type.String()])
|
|
49
|
+
});
|
|
50
|
+
var DeviceTokenResponse = Type.Object({
|
|
51
|
+
authorization_code: Type.String({ minLength: 1 }),
|
|
52
|
+
code_verifier: Type.String({ minLength: 1 })
|
|
53
|
+
});
|
|
54
|
+
var DeviceErrorCode = Type.Object({ error: Type.String() });
|
|
55
|
+
var NestedDeviceErrorCode = Type.Object({ error: Type.Object({ code: Type.String() }) });
|
|
56
|
+
var JwtClaims = Type.Object({
|
|
57
|
+
[JWT_CLAIM_PATH]: Type.Optional(Type.Object({ chatgpt_account_id: Type.Optional(Type.String()) }))
|
|
58
|
+
});
|
|
59
|
+
function assertNodeRuntime() {
|
|
60
|
+
if (typeof process === "undefined" || !(process.versions?.node || process.versions?.bun)) {
|
|
61
|
+
throw new Error("OpenAI Codex OAuth is only available in Node.js environments");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function createState() {
|
|
65
|
+
assertNodeRuntime();
|
|
66
|
+
return process.getBuiltinModule("node:crypto").randomBytes(16).toString("hex");
|
|
67
|
+
}
|
|
68
|
+
function decodeJwt(token) {
|
|
69
|
+
try {
|
|
70
|
+
const parts = token.split(".");
|
|
71
|
+
if (parts.length !== 3)
|
|
72
|
+
return null;
|
|
73
|
+
const payload = parts[1] ?? "";
|
|
74
|
+
const claims = JSON.parse(atob(payload));
|
|
75
|
+
return Value.Check(JwtClaims, claims) ? claims : null;
|
|
76
|
+
} catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function fetchWithLoginCancellation(input, init) {
|
|
81
|
+
try {
|
|
82
|
+
return await fetch(input, init);
|
|
83
|
+
} catch (error) {
|
|
84
|
+
if (init.signal?.aborted) {
|
|
85
|
+
throw new Error("Login cancelled");
|
|
86
|
+
}
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function readTokenResponse(response, operation) {
|
|
91
|
+
if (!response.ok) {
|
|
92
|
+
const text = await response.text().catch(() => "");
|
|
93
|
+
throw new Error(`OpenAI Codex token ${operation} failed (${response.status}): ${text || response.statusText}`);
|
|
94
|
+
}
|
|
95
|
+
const json = await response.json();
|
|
96
|
+
if (!Value.Check(OAuthTokenResponseSchema2, json)) {
|
|
97
|
+
throw new Error(`OpenAI Codex token ${operation} response missing fields: ${JSON.stringify(json)}`);
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
access: json.access_token,
|
|
101
|
+
refresh: json.refresh_token,
|
|
102
|
+
expires: Date.now() + json.expires_in * 1000
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
async function exchangeAuthorizationCode(code, verifier, redirectUri, signal) {
|
|
106
|
+
const response = await fetchWithLoginCancellation(TOKEN_URL, {
|
|
107
|
+
method: "POST",
|
|
108
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
109
|
+
body: new URLSearchParams({
|
|
110
|
+
grant_type: "authorization_code",
|
|
111
|
+
client_id: CLIENT_ID,
|
|
112
|
+
code,
|
|
113
|
+
code_verifier: verifier,
|
|
114
|
+
redirect_uri: redirectUri
|
|
115
|
+
}),
|
|
116
|
+
signal
|
|
117
|
+
});
|
|
118
|
+
return readTokenResponse(response, "exchange");
|
|
119
|
+
}
|
|
120
|
+
async function refreshAccessToken(refreshToken, signal) {
|
|
121
|
+
let response;
|
|
122
|
+
try {
|
|
123
|
+
response = await fetch(TOKEN_URL, {
|
|
124
|
+
method: "POST",
|
|
125
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
126
|
+
body: new URLSearchParams({
|
|
127
|
+
grant_type: "refresh_token",
|
|
128
|
+
refresh_token: refreshToken,
|
|
129
|
+
client_id: CLIENT_ID
|
|
130
|
+
}),
|
|
131
|
+
signal
|
|
132
|
+
});
|
|
133
|
+
} catch (error) {
|
|
134
|
+
throw new Error(`OpenAI Codex token refresh error: ${error instanceof Error ? error.message : String(error)}`);
|
|
135
|
+
}
|
|
136
|
+
return readTokenResponse(response, "refresh");
|
|
137
|
+
}
|
|
138
|
+
async function startOpenAICodexDeviceAuth(signal) {
|
|
139
|
+
const response = await fetchWithLoginCancellation(DEVICE_USER_CODE_URL, {
|
|
140
|
+
method: "POST",
|
|
141
|
+
headers: { "Content-Type": "application/json" },
|
|
142
|
+
body: JSON.stringify({ client_id: CLIENT_ID }),
|
|
143
|
+
signal
|
|
144
|
+
});
|
|
145
|
+
if (!response.ok) {
|
|
146
|
+
if (response.status === 404) {
|
|
147
|
+
throw new Error("OpenAI Codex device code login is not enabled for this server. Use browser login or verify the server URL.");
|
|
148
|
+
}
|
|
149
|
+
const responseBody = await response.text().catch(() => "");
|
|
150
|
+
throw new Error(`OpenAI Codex device code request failed with status ${response.status}${responseBody ? `: ${responseBody}` : ""}`);
|
|
151
|
+
}
|
|
152
|
+
const json = await response.json();
|
|
153
|
+
const invalid = new Error(`Invalid OpenAI Codex device code response: ${JSON.stringify(json)}`);
|
|
154
|
+
if (!Value.Check(DeviceCodeResponse, json))
|
|
155
|
+
throw invalid;
|
|
156
|
+
const intervalSeconds = Number(json.interval);
|
|
157
|
+
if (!Number.isFinite(intervalSeconds) || intervalSeconds < 0)
|
|
158
|
+
throw invalid;
|
|
159
|
+
return {
|
|
160
|
+
deviceAuthId: json.device_auth_id,
|
|
161
|
+
userCode: json.user_code,
|
|
162
|
+
intervalSeconds
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
async function pollOpenAICodexDeviceAuth(device, signal) {
|
|
166
|
+
return pollOAuthDeviceCodeFlow2({
|
|
167
|
+
intervalSeconds: device.intervalSeconds,
|
|
168
|
+
expiresInSeconds: DEVICE_CODE_TIMEOUT_SECONDS,
|
|
169
|
+
signal,
|
|
170
|
+
poll: async () => {
|
|
171
|
+
const response = await fetchWithLoginCancellation(DEVICE_TOKEN_URL, {
|
|
172
|
+
method: "POST",
|
|
173
|
+
headers: { "Content-Type": "application/json" },
|
|
174
|
+
body: JSON.stringify({
|
|
175
|
+
device_auth_id: device.deviceAuthId,
|
|
176
|
+
user_code: device.userCode
|
|
177
|
+
}),
|
|
178
|
+
signal
|
|
179
|
+
});
|
|
180
|
+
if (response.ok) {
|
|
181
|
+
const json = await response.json();
|
|
182
|
+
if (!Value.Check(DeviceTokenResponse, json)) {
|
|
183
|
+
return {
|
|
184
|
+
status: "failed",
|
|
185
|
+
message: `Invalid OpenAI Codex device auth token response: ${JSON.stringify(json)}`
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
status: "complete",
|
|
190
|
+
value: { authorizationCode: json.authorization_code, codeVerifier: json.code_verifier }
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
if (response.status === 403 || response.status === 404) {
|
|
194
|
+
return { status: "pending" };
|
|
195
|
+
}
|
|
196
|
+
const responseBody = await response.text().catch(() => "");
|
|
197
|
+
let errorCode;
|
|
198
|
+
try {
|
|
199
|
+
const json = JSON.parse(responseBody);
|
|
200
|
+
if (Value.Check(DeviceErrorCode, json))
|
|
201
|
+
errorCode = json.error;
|
|
202
|
+
else if (Value.Check(NestedDeviceErrorCode, json))
|
|
203
|
+
errorCode = json.error.code;
|
|
204
|
+
} catch {}
|
|
205
|
+
if (errorCode === "deviceauth_authorization_pending") {
|
|
206
|
+
return { status: "pending" };
|
|
207
|
+
}
|
|
208
|
+
if (errorCode === "slow_down") {
|
|
209
|
+
return { status: "slow_down" };
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
status: "failed",
|
|
213
|
+
message: `OpenAI Codex device auth failed with status ${response.status}${responseBody ? `: ${responseBody}` : ""}`
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
async function createAuthorizationFlow(originator = ORIGINATOR2) {
|
|
219
|
+
const { verifier, challenge } = await generatePKCE2();
|
|
220
|
+
const state = createState();
|
|
221
|
+
const url = new URL(AUTHORIZE_URL);
|
|
222
|
+
url.searchParams.set("response_type", "code");
|
|
223
|
+
url.searchParams.set("client_id", CLIENT_ID);
|
|
224
|
+
url.searchParams.set("redirect_uri", REDIRECT_URI);
|
|
225
|
+
url.searchParams.set("scope", SCOPE);
|
|
226
|
+
url.searchParams.set("code_challenge", challenge);
|
|
227
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
228
|
+
url.searchParams.set("state", state);
|
|
229
|
+
url.searchParams.set("id_token_add_organizations", "true");
|
|
230
|
+
url.searchParams.set("codex_cli_simplified_flow", "true");
|
|
231
|
+
url.searchParams.set("originator", originator);
|
|
232
|
+
return { verifier, state, url: url.toString() };
|
|
233
|
+
}
|
|
234
|
+
function startLocalOAuthServer(state) {
|
|
235
|
+
assertNodeRuntime();
|
|
236
|
+
let settleWait;
|
|
237
|
+
const waitForCodePromise = new Promise((resolve) => {
|
|
238
|
+
let settled = false;
|
|
239
|
+
settleWait = (value) => {
|
|
240
|
+
if (settled)
|
|
241
|
+
return;
|
|
242
|
+
settled = true;
|
|
243
|
+
resolve(value);
|
|
244
|
+
};
|
|
245
|
+
});
|
|
246
|
+
const server = process.getBuiltinModule("node:http").createServer((req, res) => {
|
|
247
|
+
try {
|
|
248
|
+
const url = new URL(req.url || "", "http://localhost");
|
|
249
|
+
if (url.pathname !== "/auth/callback") {
|
|
250
|
+
res.statusCode = 404;
|
|
251
|
+
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
252
|
+
res.end(oauthErrorHtml2("Nyte is not listening on this path. Run the login command again to retry."));
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (url.searchParams.get("state") !== state) {
|
|
256
|
+
res.statusCode = 400;
|
|
257
|
+
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
258
|
+
res.end(oauthErrorHtml2("The callback's state did not match this login attempt, so Nyte ignored it."));
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const code = url.searchParams.get("code");
|
|
262
|
+
if (!code) {
|
|
263
|
+
res.statusCode = 400;
|
|
264
|
+
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
265
|
+
res.end(oauthErrorHtml2("The callback arrived without an authorization code, so Nyte could not finish sign-in."));
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
res.statusCode = 200;
|
|
269
|
+
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
270
|
+
res.end(oauthSuccessHtml2({ provider: "OpenAI" }));
|
|
271
|
+
settleWait?.({ code });
|
|
272
|
+
} catch {
|
|
273
|
+
res.statusCode = 500;
|
|
274
|
+
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
275
|
+
res.end(oauthErrorHtml2("Nyte hit an internal error while handling the callback. Run the login command again to retry."));
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
return new Promise((resolve) => {
|
|
279
|
+
server.listen(1455, getCallbackHost(), () => {
|
|
280
|
+
resolve({
|
|
281
|
+
close: () => server.close(),
|
|
282
|
+
cancelWait: () => {
|
|
283
|
+
settleWait?.(null);
|
|
284
|
+
},
|
|
285
|
+
waitForCode: () => waitForCodePromise
|
|
286
|
+
});
|
|
287
|
+
}).on("error", (_err) => {
|
|
288
|
+
settleWait?.(null);
|
|
289
|
+
resolve({
|
|
290
|
+
close: () => {
|
|
291
|
+
try {
|
|
292
|
+
server.close();
|
|
293
|
+
} catch {}
|
|
294
|
+
},
|
|
295
|
+
cancelWait: () => {},
|
|
296
|
+
waitForCode: async () => null
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
function getAccountId2(accessToken) {
|
|
302
|
+
return decodeJwt(accessToken)?.[JWT_CLAIM_PATH]?.chatgpt_account_id || null;
|
|
303
|
+
}
|
|
304
|
+
function credentialsFromToken(token) {
|
|
305
|
+
const accountId = getAccountId2(token.access);
|
|
306
|
+
if (!accountId) {
|
|
307
|
+
throw new Error("Failed to extract accountId from token");
|
|
308
|
+
}
|
|
309
|
+
return {
|
|
310
|
+
type: "oauth",
|
|
311
|
+
access: token.access,
|
|
312
|
+
refresh: token.refresh,
|
|
313
|
+
expires: token.expires,
|
|
314
|
+
accountId
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
async function exchangeAuthorizationCodeForCredentials(code, verifier, redirectUri, signal) {
|
|
318
|
+
return credentialsFromToken(await exchangeAuthorizationCode(code, verifier, redirectUri, signal));
|
|
319
|
+
}
|
|
320
|
+
async function loginOpenAICodexDeviceCode(interaction) {
|
|
321
|
+
const device = await startOpenAICodexDeviceAuth(interaction.signal);
|
|
322
|
+
interaction.notify({
|
|
323
|
+
type: "device_code",
|
|
324
|
+
userCode: device.userCode,
|
|
325
|
+
verificationUri: DEVICE_VERIFICATION_URI,
|
|
326
|
+
intervalSeconds: device.intervalSeconds,
|
|
327
|
+
expiresInSeconds: DEVICE_CODE_TIMEOUT_SECONDS
|
|
328
|
+
});
|
|
329
|
+
const code = await pollOpenAICodexDeviceAuth(device, interaction.signal);
|
|
330
|
+
return exchangeAuthorizationCodeForCredentials(code.authorizationCode, code.codeVerifier, DEVICE_REDIRECT_URI, interaction.signal);
|
|
331
|
+
}
|
|
332
|
+
async function loginOpenAICodex(interaction) {
|
|
333
|
+
const { verifier, state, url } = await createAuthorizationFlow();
|
|
334
|
+
const server = await startLocalOAuthServer(state);
|
|
335
|
+
const manualAbort = new AbortController;
|
|
336
|
+
const onAbort = () => server.cancelWait();
|
|
337
|
+
interaction.signal.addEventListener("abort", onAbort, { once: true });
|
|
338
|
+
if (interaction.signal.aborted)
|
|
339
|
+
onAbort();
|
|
340
|
+
let code;
|
|
341
|
+
let manualCode;
|
|
342
|
+
let manualError;
|
|
343
|
+
interaction.notify({
|
|
344
|
+
type: "auth_url",
|
|
345
|
+
url,
|
|
346
|
+
instructions: "A browser window should open. Complete login to finish."
|
|
347
|
+
});
|
|
348
|
+
try {
|
|
349
|
+
const manualPromise = interaction.prompt({
|
|
350
|
+
type: "manual_code",
|
|
351
|
+
message: "Complete login in your browser, or paste the authorization code / redirect URL here:",
|
|
352
|
+
placeholder: REDIRECT_URI,
|
|
353
|
+
signal: manualAbort.signal
|
|
354
|
+
}).then((input) => {
|
|
355
|
+
manualCode = input;
|
|
356
|
+
server.cancelWait();
|
|
357
|
+
}).catch((error) => {
|
|
358
|
+
manualError = error instanceof Error ? error : new Error(String(error));
|
|
359
|
+
server.cancelWait();
|
|
360
|
+
});
|
|
361
|
+
const result = await server.waitForCode();
|
|
362
|
+
if (manualError)
|
|
363
|
+
throw manualError;
|
|
364
|
+
if (result?.code) {
|
|
365
|
+
code = result.code;
|
|
366
|
+
} else if (manualCode) {
|
|
367
|
+
const parsed = parseAuthorizationInput2(manualCode);
|
|
368
|
+
if (parsed.state && parsed.state !== state)
|
|
369
|
+
throw new Error("State mismatch");
|
|
370
|
+
code = parsed.code;
|
|
371
|
+
}
|
|
372
|
+
if (!code) {
|
|
373
|
+
await manualPromise;
|
|
374
|
+
if (manualError)
|
|
375
|
+
throw manualError;
|
|
376
|
+
if (manualCode) {
|
|
377
|
+
const parsed = parseAuthorizationInput2(manualCode);
|
|
378
|
+
if (parsed.state && parsed.state !== state)
|
|
379
|
+
throw new Error("State mismatch");
|
|
380
|
+
code = parsed.code;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
if (!code)
|
|
384
|
+
throw new Error("Missing authorization code");
|
|
385
|
+
return exchangeAuthorizationCodeForCredentials(code, verifier, REDIRECT_URI, interaction.signal);
|
|
386
|
+
} finally {
|
|
387
|
+
interaction.signal.removeEventListener("abort", onAbort);
|
|
388
|
+
manualAbort.abort();
|
|
389
|
+
server.close();
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
async function refreshOpenAICodexToken(refreshToken, signal) {
|
|
393
|
+
return credentialsFromToken(await refreshAccessToken(refreshToken, signal));
|
|
394
|
+
}
|
|
395
|
+
var openaiCodexOAuth2 = {
|
|
396
|
+
name: "OpenAI (ChatGPT Plus/Pro)",
|
|
397
|
+
isSubscription: true,
|
|
398
|
+
async login(interaction) {
|
|
399
|
+
const method = interaction.browser === "host" ? OPENAI_CODEX_BROWSER_LOGIN_METHOD : interaction.browser === "elsewhere" ? OPENAI_CODEX_DEVICE_CODE_LOGIN_METHOD : await interaction.prompt({
|
|
400
|
+
type: "select",
|
|
401
|
+
message: "Select OpenAI Codex login method:",
|
|
402
|
+
options: [
|
|
403
|
+
{ id: OPENAI_CODEX_BROWSER_LOGIN_METHOD, label: "Browser login (default)" },
|
|
404
|
+
{
|
|
405
|
+
id: OPENAI_CODEX_DEVICE_CODE_LOGIN_METHOD,
|
|
406
|
+
label: "Device code login (headless)"
|
|
407
|
+
}
|
|
408
|
+
]
|
|
409
|
+
});
|
|
410
|
+
if (method === OPENAI_CODEX_DEVICE_CODE_LOGIN_METHOD) {
|
|
411
|
+
return loginOpenAICodexDeviceCode(interaction);
|
|
412
|
+
}
|
|
413
|
+
if (method !== OPENAI_CODEX_BROWSER_LOGIN_METHOD) {
|
|
414
|
+
throw new Error(`Unknown OpenAI Codex login method: ${method}`);
|
|
415
|
+
}
|
|
416
|
+
return loginOpenAICodex(interaction);
|
|
417
|
+
},
|
|
418
|
+
refresh: (credential, signal) => refreshOpenAICodexToken(credential.refresh, signal),
|
|
419
|
+
async toAuth(credential) {
|
|
420
|
+
const accountId = getAccountId2(credential.access);
|
|
421
|
+
if (!accountId)
|
|
422
|
+
throw new Error("OpenAI Codex credential missing account id");
|
|
423
|
+
return { apiKey: credential.access, headers: { "chatgpt-account-id": accountId } };
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
registerOAuthFlow2("openaiCodex", openaiCodexOAuth2);
|
|
427
|
+
|
|
428
|
+
export { ORIGINATOR2, getAccountId2, openaiCodexOAuth2 };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {
|
|
2
|
+
providerHeadersToRecord2
|
|
3
|
+
} from "./account-limits-cache-ag5b8dja.js";
|
|
4
|
+
|
|
5
|
+
// src/auth/verify.ts
|
|
6
|
+
async function verifyWithRequest2(input) {
|
|
7
|
+
const response = await globalThis.fetch(input.url, {
|
|
8
|
+
headers: providerHeadersToRecord2(input.headers),
|
|
9
|
+
signal: input.signal,
|
|
10
|
+
redirect: "error"
|
|
11
|
+
});
|
|
12
|
+
if (response.status === 401 || response.status === 403) {
|
|
13
|
+
await response.body?.cancel();
|
|
14
|
+
return {
|
|
15
|
+
ok: false,
|
|
16
|
+
reason: "rejected",
|
|
17
|
+
message: `${input.provider} rejected the credential (HTTP ${String(response.status)})`
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
if (!response.ok) {
|
|
21
|
+
await response.body?.cancel();
|
|
22
|
+
return {
|
|
23
|
+
ok: false,
|
|
24
|
+
reason: "unreachable",
|
|
25
|
+
message: `${input.provider} could not verify the credential (HTTP ${String(response.status)})`
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
if (!input.detail) {
|
|
29
|
+
await response.body?.cancel();
|
|
30
|
+
return { ok: true };
|
|
31
|
+
}
|
|
32
|
+
const body = await response.json().catch(() => {
|
|
33
|
+
return;
|
|
34
|
+
});
|
|
35
|
+
const detail = input.detail(body);
|
|
36
|
+
return detail === undefined ? { ok: true } : { ok: true, detail };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { verifyWithRequest2 };
|