@alvin0/ai-agent-sdk-provider-codex 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["AgentSdkError","NULL_LOGGER","positiveSafeInteger","raceAbort","openAiResponsesProtocol"],"sources":["../src/auth.ts","../src/common/store-capture.ts","../src/common/no-follow.ts","../src/oauth.ts","../src/common/response-media.ts","../src/adapter.ts"],"sourcesContent":["/**\n * Universal Codex credential contracts and JWT helpers.\n *\n * Storage is injected. Filesystem/path/environment ownership belongs to the\n * Node auth package, never this Universal provider.\n */\n\nimport { AgentSdkError, MISSING_CREDENTIAL_CODE } from '@alvin0/ai-agent-sdk-core'\nimport {\n defineCredentialStore,\n} from '@alvin0/ai-agent-sdk-core/provider'\nimport type {\n CodexAuthFile,\n CodexAuthStore,\n CodexCredentialStore,\n CodexTokens,\n} from './common/store-types.ts'\n\nexport type { CodexAuthFile, CodexAuthStore, CodexCredentialStore, CodexTokens } from './common/store-types.ts'\n\n/** An in-memory {@link CodexAuthStore}, for tests. */\nexport function memoryCodexAuthStore(initial?: CodexAuthFile): CodexAuthStore {\n let current = initial\n return {\n location: '<memory>',\n read: () => Promise.resolve(current),\n write: (file) => {\n current = file\n return Promise.resolve()\n },\n }\n}\n\n/** In-memory compare-and-swap store for deterministic runtime/tests. */\nexport function memoryCodexCredentialStore(initial?: CodexAuthFile): CodexCredentialStore {\n let current = initial === undefined ? undefined : structuredClone(initial)\n let revision = 0\n return defineCredentialStore<CodexAuthFile>({\n id: 'codex-memory-credentials',\n label: '<memory>',\n async read({ signal }) {\n signal.throwIfAborted()\n return current === undefined\n ? undefined\n : { value: structuredClone(current), revision: String(revision) }\n },\n async commit(input, { signal }) {\n signal.throwIfAborted()\n const expected = current === undefined ? null : String(revision)\n if (input.expectedRevision !== expected) {\n throw new AgentSdkError(\n 'Codex credential revision changed before commit',\n 'CODEX_CREDENTIAL_REVISION_CONFLICT',\n )\n }\n current = structuredClone(input.value)\n revision++\n return { revision: String(revision) }\n },\n })\n}\n\n/** The custom claim namespace OpenAI puts its ChatGPT account fields under. */\nconst AUTH_CLAIM_NAMESPACE = 'https://api.openai.com/auth'\n\n/** Claims this SDK reads out of a Codex JWT. */\nexport interface CodexJwtClaims {\n exp?: number\n email?: string\n accountId?: string\n planType?: string\n isFedramp: boolean\n}\n\n/** Decode a base64url segment without requiring Node's Buffer. */\nfunction decodeBase64Url(segment: string): string {\n const padded = segment.replace(/-/g, '+').replace(/_/g, '/')\n + '='.repeat((4 - (segment.length % 4)) % 4)\n const binary = atob(padded)\n // The payload is UTF-8; `atob` yields latin1, so re-decode to preserve\n // non-ASCII values such as an email with accented characters.\n const bytes = Uint8Array.from(binary, character => character.charCodeAt(0))\n return new TextDecoder().decode(bytes)\n}\n\n/**\n * Read the claims this SDK cares about out of a JWT.\n *\n * The signature is NOT verified, and does not need to be: this token is being\n * read to decide which account id to send and whether to refresh, not to grant\n * anything. The issuer verifies it.\n * @param jwt - a compact-serialization JWT.\n * @returns the claims, or `undefined` when the token is unreadable.\n */\nexport function readJwtClaims(jwt: string): CodexJwtClaims | undefined {\n const parts = jwt.split('.')\n const payload = parts.length === 3 ? parts[1] : undefined\n if (payload === undefined || payload.length === 0) return undefined\n let parsed: Record<string, unknown>\n try {\n parsed = JSON.parse(decodeBase64Url(payload)) as Record<string, unknown>\n } catch {\n return undefined\n }\n const auth = parsed[AUTH_CLAIM_NAMESPACE]\n const authClaims = typeof auth === 'object' && auth !== null\n ? auth as Record<string, unknown>\n : {}\n const exp = parsed.exp\n const email = parsed.email\n const accountId = authClaims.chatgpt_account_id\n const planType = authClaims.chatgpt_plan_type\n return {\n ...typeof exp === 'number' ? { exp } : {},\n ...typeof email === 'string' ? { email } : {},\n ...typeof accountId === 'string' ? { accountId } : {},\n ...typeof planType === 'string' ? { planType } : {},\n isFedramp: authClaims.chatgpt_account_is_fedramp === true,\n }\n}\n\n/**\n * Resolve the account id to send as `ChatGPT-Account-ID`.\n *\n * Prefers the stored value and falls back to the `id_token` claim, because the\n * stored field is legitimately null for personal accounts.\n * @param tokens - the stored tokens.\n * @returns the account id, or `undefined` when neither source has one.\n */\nexport function resolveAccountId(tokens: CodexTokens): string | undefined {\n const stored = tokens.account_id\n if (typeof stored === 'string' && stored.length > 0) return stored\n return readJwtClaims(tokens.id_token)?.accountId\n}\n\n/** Whether this account must be routed through the FedRAMP edge. */\nexport function isFedrampAccount(tokens: CodexTokens): boolean {\n return readJwtClaims(tokens.id_token)?.isFedramp === true\n}\n\n/** Refresh this long before the access token actually expires. */\nexport const ACCESS_TOKEN_REFRESH_WINDOW_MS = 5 * 60 * 1_000\n\n/** Fallback staleness bound, used only when `exp` cannot be read. */\nexport const LAST_REFRESH_MAX_AGE_MS = 8 * 24 * 60 * 60 * 1_000\n\n/**\n * Whether the access token should be refreshed before the next request.\n *\n * Primary signal is the token's own `exp`, with a five-minute margin so a request\n * cannot expire in flight. The `last_refresh` age is only a fallback for a token\n * whose `exp` is unreadable — matching how the Codex CLI decides.\n * @param file - the credential file.\n * @param now - current time in epoch milliseconds; injectable for tests.\n * @returns true when a refresh is due.\n */\nexport function shouldRefresh(file: CodexAuthFile, now = Date.now()): boolean {\n const tokens = file.tokens\n if (tokens === undefined || tokens === null) return false\n const exp = readJwtClaims(tokens.access_token)?.exp\n if (exp !== undefined) return exp * 1_000 <= now + ACCESS_TOKEN_REFRESH_WINDOW_MS\n const lastRefresh = file.last_refresh\n if (lastRefresh === undefined || lastRefresh === null) return false\n const at = Date.parse(lastRefresh)\n return Number.isFinite(at) && at < now - LAST_REFRESH_MAX_AGE_MS\n}\n\n/**\n * Require usable ChatGPT tokens, with a message that says how to get them.\n * @param file - the credential file, or `undefined` when absent.\n * @param location - the path checked, named in the diagnostic.\n * @returns the tokens.\n */\nexport function requireTokens(\n file: CodexAuthFile | undefined,\n location: string,\n): CodexTokens {\n const tokens = file?.tokens\n if (tokens === undefined || tokens === null\n || typeof tokens.access_token !== 'string' || tokens.access_token.length === 0) {\n throw new AgentSdkError(\n `no Codex credentials at ${location}; run \\`npm run provider:codex:login-device\\` to sign in`,\n MISSING_CREDENTIAL_CODE,\n )\n }\n return tokens\n}\n","import {\n AgentSdkError,\n CREDENTIAL_CAPABILITY_API_VERSION,\n type CredentialCommitInput,\n type CredentialCommitResult,\n type CredentialOperationOptions,\n type CredentialRecord,\n} from '@alvin0/ai-agent-sdk-core/provider'\nimport type {\n CodexAuthFile,\n CodexAuthStore,\n CodexCredentialStore,\n} from './store-types.ts'\n\nexport type CapturedCodexStore =\n | { readonly kind: 'legacy'; readonly label: string; readonly store: CodexAuthStore }\n | { readonly kind: 'versioned'; readonly label: string; readonly store: CodexCredentialStore }\n\n/** Capture store identity and methods without invoking accessors or doing storage I/O. */\nexport function captureCodexStore(value: unknown): CapturedCodexStore {\n try {\n if (value === null || typeof value !== 'object') throw new TypeError('store must be an object')\n const marker = dataValue(value, 'kind', false)\n if (marker === undefined) return captureLegacy(value)\n if (marker !== 'credential-store'\n || dataValue(value, 'apiVersion') !== CREDENTIAL_CAPABILITY_API_VERSION) {\n throw new TypeError('unsupported credential-store marker')\n }\n const id = boundedString(dataValue(value, 'id'), 128, 'credential store id')\n const label = boundedString(dataValue(value, 'label'), 256, 'credential store label')\n const read = capturedMethod<\n [CredentialOperationOptions], Promise<CredentialRecord<CodexAuthFile> | undefined>\n >(value, 'read')\n const commit = capturedMethod<\n [CredentialCommitInput<CodexAuthFile>, CredentialOperationOptions], Promise<CredentialCommitResult>\n >(value, 'commit')\n return Object.freeze({\n kind: 'versioned',\n label,\n store: Object.freeze({\n kind: 'credential-store',\n apiVersion: CREDENTIAL_CAPABILITY_API_VERSION,\n id,\n label,\n read,\n commit,\n }),\n })\n } catch (error) {\n throw new AgentSdkError('Codex authStore credential store is invalid', 'CREDENTIAL_STORE_INVALID', { cause: error })\n }\n}\n\nfunction captureLegacy(source: object): CapturedCodexStore {\n const location = boundedString(dataValue(source, 'location'), 1_024, 'Codex auth store location')\n const read = capturedMethod<[], Promise<CodexAuthFile | undefined>>(source, 'read')\n const write = capturedMethod<[CodexAuthFile], Promise<void>>(source, 'write')\n return Object.freeze({\n kind: 'legacy',\n label: location,\n store: Object.freeze({ location, read, write }),\n })\n}\n\nfunction capturedMethod<Args extends readonly unknown[], Result>(\n source: object,\n key: PropertyKey,\n): (...args: Args) => Result {\n const method = dataValue(source, key)\n if (typeof method !== 'function') throw new TypeError(`${String(key)} must be a function`)\n return (...args: Args) => Reflect.apply(method, source, args) as Result\n}\n\nfunction dataValue(source: object, key: PropertyKey, required = true): unknown {\n let owner: object | null = source\n while (owner !== null) {\n const descriptor = Object.getOwnPropertyDescriptor(owner, key)\n if (descriptor !== undefined) {\n if (!('value' in descriptor)) throw new TypeError(`${String(key)} must not be an accessor`)\n return descriptor.value\n }\n owner = Object.getPrototypeOf(owner)\n }\n if (!required) return undefined\n throw new TypeError(`missing ${String(key)}`)\n}\n\nfunction boundedString(value: unknown, maxLength: number, label: string): string {\n if (typeof value !== 'string' || value.length === 0 || value.length > maxLength) {\n throw new TypeError(`${label} must be a bounded non-empty string`)\n }\n return value\n}\n","import { waitForSettlement } from '@alvin0/ai-agent-sdk-core'\n\n/** Reject every redirect shape exposed by Web fetch before any second request. */\nexport async function rejectCodexRedirect(\n response: Response,\n requestedUrl: string,\n operation: 'OAuth' | 'model catalog',\n teardownTimeoutMs: number,\n): Promise<void> {\n const redirectStatus = response.status >= 300 && response.status < 400\n const responseUrlChanged = response.url.length > 0 && response.url !== requestedUrl\n if (response.type !== 'opaqueredirect' && response.redirected !== true\n && !redirectStatus && !responseUrlChanged) return\n if (response.body !== null) {\n await waitForSettlement(response.body.cancel().catch(() => undefined), teardownTimeoutMs)\n }\n throw new TypeError(`Codex ${operation} rejected a redirect before following it`)\n}\n","/**\n * The OAuth flows behind the Codex credential file: device-code sign-in and\n * refresh-token rotation.\n *\n * Device code rather than a browser redirect because this SDK has no business\n * binding a localhost port: the flow works over SSH, in containers, and in CI,\n * and it needs no callback server.\n *\n * One surprise worth flagging: in this flow the SERVER generates the PKCE pair\n * and returns both the verifier and the challenge alongside the authorization\n * code. That inverts normal PKCE, where the client generates the verifier and\n * never transmits it. It is what the endpoint does, so it is what this\n * implements — but it means the device-code leg is only as safe as the TLS\n * channel, and it is why the user-facing prompt carries a phishing warning.\n *\n * @module ai-agent-sdk/providers/codex/oauth\n */\n\nimport { AgentSdkError } from '@alvin0/ai-agent-sdk-core'\nimport { waitForSettlement } from '@alvin0/ai-agent-sdk-core'\nimport type { CredentialOperationOptions, SdkLogger } from '@alvin0/ai-agent-sdk-core/provider'\nimport {\n readJwtClaims,\n resolveAccountId,\n type CodexAuthFile,\n type CodexAuthStore,\n type CodexCredentialStore,\n type CodexTokens,\n} from './auth.ts'\nimport { captureCodexStore, type CapturedCodexStore } from './common/store-capture.ts'\nimport { rejectCodexRedirect } from './common/no-follow.ts'\n\nconst NEVER_ABORTED_SIGNAL = new AbortController().signal\nconst NULL_LOGGER: SdkLogger = Object.freeze({\n child: () => NULL_LOGGER,\n trace: () => undefined,\n debug: () => undefined,\n info: () => undefined,\n warn: () => undefined,\n error: () => undefined,\n fatal: () => undefined,\n})\n\ntype AnyCodexStore = CodexAuthStore | CodexCredentialStore\n\ninterface CodexStoreSnapshot {\n readonly file: CodexAuthFile | undefined\n readonly revision: string | null\n}\n\n/** OpenAI's auth issuer. */\nexport const DEFAULT_CODEX_ISSUER = 'https://auth.openai.com'\n\n/** The public OAuth client id the Codex CLI uses; not a secret. */\nexport const CODEX_CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann'\n\n/** The device code expires server-side after this long. */\nconst DEVICE_CODE_MAX_WAIT_MS = 15 * 60 * 1_000\n\n/** Used when the server does not state a polling interval. */\nconst DEFAULT_POLL_INTERVAL_SECONDS = 5\n\n/** Shared settings for the OAuth calls. */\nexport interface CodexOAuthOptions {\n /** Auth issuer base URL; defaults to {@link DEFAULT_CODEX_ISSUER}. */\n issuer?: string\n /** OAuth client id; defaults to {@link CODEX_CLIENT_ID}. */\n clientId?: string\n /** Cancellation for the whole flow. */\n signal?: AbortSignal\n /** HTTP implementation for tests and non-browser runtimes. */\n fetch?: typeof fetch\n /** Deadline for each auth HTTP request. Defaults to 30 seconds. */\n requestTimeoutMs?: number\n /** Maximum auth response bytes retained or parsed. Defaults to 1 MiB. */\n maxResponseBytes?: number\n /** Maximum auth response chunks accepted. Defaults to 10,000. */\n maxResponseChunks?: number\n /** Permit an http:// issuer for a trusted local test endpoint. Defaults to false. */\n allowInsecureIssuer?: boolean\n}\n\n/** A pending device authorization the user has to approve. */\nexport interface CodexDeviceCode {\n /** URL to open in a browser. */\n verificationUrl: string\n /** One-time code the user types there. */\n userCode: string\n /** Opaque server-side handle for this authorization. */\n deviceAuthId: string\n /** Seconds to wait between polls. */\n intervalSeconds: number\n}\n\n/** Progress reported while a device-code login runs. */\nexport interface CodexLoginProgress {\n /** The code is ready; show it to the user. */\n onPrompt?: (code: CodexDeviceCode) => void\n /** Called before each poll, so a CLI can show that it is still waiting. */\n onPoll?: (elapsedMs: number) => void\n}\n\nfunction issuerOf(options: CodexOAuthOptions): string {\n const url = new URL(options.issuer ?? DEFAULT_CODEX_ISSUER)\n if (url.username.length > 0 || url.password.length > 0) {\n throw new TypeError('Codex OAuth issuer must not contain credentials')\n }\n if (url.protocol !== 'https:' && !(options.allowInsecureIssuer === true && url.protocol === 'http:')) {\n throw new TypeError('Codex OAuth issuer must use https')\n }\n return url.href.replace(/\\/+$/, '')\n}\n\nfunction clientIdOf(options: CodexOAuthOptions): string {\n return options.clientId ?? CODEX_CLIENT_ID\n}\n\nasync function oauthFetch(\n options: CodexOAuthOptions,\n input: string | URL,\n init: RequestInit,\n): Promise<Response> {\n const issuer = new URL(issuerOf(options))\n const url = new URL(input)\n if (url.origin !== issuer.origin) throw new TypeError(`Codex OAuth endpoint origin '${url.origin}' is not allowed`)\n const timeoutMs = positiveSafeInteger(options.requestTimeoutMs ?? 30_000, 'requestTimeoutMs')\n const timeout = AbortSignal.timeout(timeoutMs)\n const signal = options.signal === undefined ? timeout : AbortSignal.any([options.signal, timeout])\n const fetchImpl = options.fetch ?? globalThis.fetch\n if (typeof fetchImpl !== 'function') throw new TypeError('Codex OAuth requires fetch')\n const response = await raceAbort(Promise.resolve(fetchImpl(url, {\n ...init,\n signal,\n redirect: 'manual',\n })), signal)\n await rejectCodexRedirect(response, url.href, 'OAuth', 30_000)\n return response\n}\n\nasync function readResponseText(response: Response, options: CodexOAuthOptions): Promise<string> {\n const maxBytes = positiveSafeInteger(options.maxResponseBytes ?? 1024 * 1024, 'maxResponseBytes')\n const maxChunks = positiveSafeInteger(options.maxResponseChunks ?? 10_000, 'maxResponseChunks')\n const declared = Number(response.headers.get('content-length'))\n if (Number.isFinite(declared) && declared > maxBytes) {\n if (response.body !== null) await waitForSettlement(response.body.cancel().catch(() => undefined), 30_000)\n throw new RangeError(`Codex OAuth response exceeds the ${maxBytes}-byte limit`)\n }\n if (response.body === null) return ''\n const timeout = AbortSignal.timeout(positiveSafeInteger(options.requestTimeoutMs ?? 30_000, 'requestTimeoutMs'))\n const signal = options.signal === undefined ? timeout : AbortSignal.any([options.signal, timeout])\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n let bytes = 0\n let chunks = 0\n let result = ''\n try {\n while (true) {\n const next = await raceAbort(reader.read(), signal)\n if (next.done) return result + decoder.decode()\n if (next.value === undefined) continue\n chunks++\n bytes += next.value.byteLength\n if (chunks > maxChunks || bytes > maxBytes) {\n await waitForSettlement(reader.cancel().catch(() => undefined), 30_000)\n throw new RangeError(`Codex OAuth response exceeds its configured resource limit`)\n }\n result += decoder.decode(next.value, { stream: true })\n }\n } finally {\n reader.releaseLock()\n }\n}\n\nfunction raceAbort<T>(pending: Promise<T>, signal: AbortSignal): Promise<T> {\n if (signal.aborted) return Promise.reject(signal.reason ?? new Error('Codex OAuth operation aborted'))\n return new Promise<T>((resolve, reject) => {\n const abort = () => { cleanup(); reject(signal.reason ?? new Error('Codex OAuth operation aborted')) }\n const cleanup = () => signal.removeEventListener('abort', abort)\n signal.addEventListener('abort', abort, { once: true })\n void pending.then(\n value => { cleanup(); resolve(value) },\n error => { cleanup(); reject(error) },\n )\n })\n}\n\nfunction positiveSafeInteger(value: number, field: string): number {\n if (!Number.isSafeInteger(value) || value < 1) {\n throw new RangeError(`Codex OAuth ${field} must be a positive safe integer`)\n }\n return value\n}\n\n/** Read a JSON body, failing with the status when it is not JSON. */\nasync function readJson(\n response: Response,\n what: string,\n options: CodexOAuthOptions,\n): Promise<Record<string, unknown>> {\n const raw = await readResponseText(response, options)\n try {\n return JSON.parse(raw) as Record<string, unknown>\n } catch (error: unknown) {\n throw new AgentSdkError(\n `${what} returned a non-JSON response (HTTP ${response.status})`,\n 'CODEX_AUTH_MALFORMED',\n { cause: error },\n )\n }\n}\n\nfunction requireString(source: Record<string, unknown>, key: string, what: string): string {\n const value = source[key]\n if (typeof value !== 'string' || value.length === 0) {\n throw new AgentSdkError(`${what} omitted \"${key}\"`, 'CODEX_AUTH_MALFORMED')\n }\n return value\n}\n\n/**\n * Start a device authorization.\n * @param options - issuer, client id, cancellation.\n * @returns the code and URL to show the user.\n */\nexport async function requestDeviceCode(\n options: CodexOAuthOptions = {},\n): Promise<CodexDeviceCode> {\n const issuer = issuerOf(options)\n const response = await oauthFetch(options, `${issuer}/api/accounts/deviceauth/usercode`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ client_id: clientIdOf(options) }),\n })\n if (response.status === 404) {\n throw new AgentSdkError(\n `device-code login is not available at ${issuer}; check the issuer URL`,\n 'CODEX_AUTH_UNAVAILABLE',\n )\n }\n if (!response.ok) {\n throw new AgentSdkError(\n `device-code request failed (HTTP ${response.status})`,\n 'CODEX_AUTH_FAILED',\n { cause: new Error(await readResponseText(response, options)) },\n )\n }\n const body = await readJson(response, 'the device-code endpoint', options)\n // The server sends `interval` as a STRING; tolerate both forms.\n const rawInterval = body.interval\n const parsed = typeof rawInterval === 'string'\n ? Number.parseInt(rawInterval.trim(), 10)\n : typeof rawInterval === 'number' ? rawInterval : Number.NaN\n return {\n verificationUrl: `${issuer}/codex/device`,\n userCode: requireString(body, 'user_code', 'the device-code endpoint'),\n deviceAuthId: requireString(body, 'device_auth_id', 'the device-code endpoint'),\n intervalSeconds: Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_POLL_INTERVAL_SECONDS,\n }\n}\n\n/** What the poll endpoint hands back once the user approves. */\ninterface AuthorizationGrant {\n authorizationCode: string\n codeVerifier: string\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n if (signal?.aborted === true) {\n return Promise.reject(new AgentSdkError('device-code login cancelled', 'ABORTED'))\n }\n return new Promise((resolve, reject) => {\n const onAbort = (): void => {\n clearTimeout(timer)\n reject(new AgentSdkError('device-code login cancelled', 'ABORTED'))\n }\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n signal?.addEventListener('abort', onAbort, { once: true })\n })\n}\n\n/**\n * Poll until the user approves the code, or the authorization expires.\n *\n * `403` and `404` both mean \"not approved yet\" here, which is unusual — most\n * device flows use a `authorization_pending` error code — so anything else is\n * treated as a real failure rather than retried.\n * @param code - the pending authorization.\n * @param options - issuer, client id, cancellation.\n * @param progress - poll notifications.\n * @returns the authorization code and its server-issued PKCE verifier.\n */\nasync function pollForAuthorization(\n code: CodexDeviceCode,\n options: CodexOAuthOptions,\n progress: CodexLoginProgress,\n): Promise<AuthorizationGrant> {\n const issuer = issuerOf(options)\n const url = `${issuer}/api/accounts/deviceauth/token`\n const startedAt = Date.now()\n\n while (true) {\n const elapsed = Date.now() - startedAt\n try { progress.onPoll?.(elapsed) } catch { /* progress observers do not own authentication */ }\n const response = await oauthFetch(options, url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ device_auth_id: code.deviceAuthId, user_code: code.userCode }),\n })\n\n if (response.ok) {\n const body = await readJson(response, 'the device-token endpoint', options)\n return {\n authorizationCode: requireString(body, 'authorization_code', 'the device-token endpoint'),\n codeVerifier: requireString(body, 'code_verifier', 'the device-token endpoint'),\n }\n }\n\n if (response.status === 403 || response.status === 404) {\n const remaining = DEVICE_CODE_MAX_WAIT_MS - (Date.now() - startedAt)\n if (remaining <= 0) {\n throw new AgentSdkError(\n 'device-code login timed out after 15 minutes without approval',\n 'CODEX_AUTH_TIMEOUT',\n )\n }\n await sleep(Math.min(code.intervalSeconds * 1_000, remaining), options.signal)\n continue\n }\n\n throw new AgentSdkError(\n `device-code polling failed (HTTP ${response.status})`,\n 'CODEX_AUTH_FAILED',\n { cause: new Error(await readResponseText(response, options)) },\n )\n }\n}\n\n/**\n * Exchange an approved authorization code for tokens.\n *\n * Form-encoded, not JSON — the token endpoint differs from the device-auth\n * endpoints in this respect, and sending JSON here fails.\n */\nasync function exchangeCodeForTokens(\n grant: AuthorizationGrant,\n options: CodexOAuthOptions,\n): Promise<CodexTokens> {\n const issuer = issuerOf(options)\n const body = new URLSearchParams({\n grant_type: 'authorization_code',\n code: grant.authorizationCode,\n redirect_uri: `${issuer}/deviceauth/callback`,\n client_id: clientIdOf(options),\n code_verifier: grant.codeVerifier,\n })\n const response = await oauthFetch(options, `${issuer}/oauth/token`, {\n method: 'POST',\n headers: { 'content-type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n })\n if (!response.ok) {\n throw new AgentSdkError(\n `token exchange failed (HTTP ${response.status})`,\n 'CODEX_AUTH_FAILED',\n { cause: new Error(await readResponseText(response, options)) },\n )\n }\n const parsed = await readJson(response, 'the token endpoint', options)\n return {\n id_token: requireString(parsed, 'id_token', 'the token endpoint'),\n access_token: requireString(parsed, 'access_token', 'the token endpoint'),\n refresh_token: requireString(parsed, 'refresh_token', 'the token endpoint'),\n }\n}\n\n/** Build the credential file for a freshly issued token set. */\nfunction authFileFor(tokens: CodexTokens): CodexAuthFile {\n const accountId = resolveAccountId(tokens)\n return {\n auth_mode: 'chatgpt',\n OPENAI_API_KEY: null,\n tokens: { ...tokens, account_id: accountId ?? null },\n last_refresh: new Date().toISOString(),\n }\n}\n\n/** Result of a completed device-code login. */\nexport interface CodexLoginResult {\n /** Where the credentials were written. */\n location: string\n /** Signed-in account email, when the token discloses one. */\n email: string | undefined\n /** Workspace/account id that requests will carry. */\n accountId: string | undefined\n /** Plan type, when disclosed. */\n planType: string | undefined\n}\n\n/**\n * Run a full device-code login and persist the result.\n * @param store - where to write the credentials.\n * @param options - issuer, client id, cancellation.\n * @param progress - prompt and poll notifications for a CLI to render.\n * @returns a summary of who signed in and where it was stored.\n */\nexport function runDeviceCodeLogin(\n store: CodexCredentialStore,\n options?: CodexOAuthOptions,\n progress?: CodexLoginProgress,\n): Promise<CodexLoginResult>\nexport function runDeviceCodeLogin(\n store: CodexAuthStore,\n options?: CodexOAuthOptions,\n progress?: CodexLoginProgress,\n): Promise<CodexLoginResult>\nexport async function runDeviceCodeLogin(\n store: AnyCodexStore,\n options: CodexOAuthOptions = {},\n progress: CodexLoginProgress = {},\n): Promise<CodexLoginResult> {\n const captured = captureCodexStore(store)\n const operation = credentialOperation(options.signal)\n const initial = await readStore(captured, operation)\n const code = await requestDeviceCode(options)\n try { progress.onPrompt?.(code) } catch { /* progress observers do not own authentication */ }\n const grant = await pollForAuthorization(code, options, progress)\n const tokens = await exchangeCodeForTokens(grant, options)\n const file = authFileFor(tokens)\n await commitStore(captured, file, initial.revision, operation)\n\n const claims = readJwtClaims(tokens.id_token)\n return {\n location: storeLabel(captured),\n email: claims?.email,\n accountId: file.tokens?.account_id ?? undefined,\n planType: claims?.planType,\n }\n}\n\n/** Why a refresh failed, which decides whether re-login is required. */\nexport type RefreshFailureKind = 'permanent' | 'transient'\n\n/** A refresh that did not succeed. */\nexport class CodexRefreshError extends AgentSdkError {\n readonly kind: RefreshFailureKind\n\n constructor(message: string, kind: RefreshFailureKind, options?: ErrorOptions) {\n super(message, kind === 'permanent' ? 'CODEX_REAUTH_REQUIRED' : 'CODEX_REFRESH_TRANSIENT', options)\n this.kind = kind\n }\n}\n\n/** Error codes that mean the refresh token is gone for good. */\nconst PERMANENT_REFRESH_CODES = new Set([\n 'refresh_token_expired',\n 'refresh_token_reused',\n 'refresh_token_invalidated',\n 'invalid_grant',\n])\n\n/** Pull an OAuth error code out of either body shape the endpoint uses. */\nfunction refreshErrorCode(raw: string): string | undefined {\n try {\n const parsed = JSON.parse(raw) as Record<string, unknown>\n const error = parsed.error\n if (typeof error === 'string') return error\n if (typeof error === 'object' && error !== null) {\n const code = (error as Record<string, unknown>).code\n if (typeof code === 'string') return code\n }\n const code = parsed.code\n return typeof code === 'string' ? code : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Exchange a refresh token for a fresh token set and persist it.\n *\n * Refresh tokens are SINGLE USE and rotate on every call, which is why this\n * writes the result immediately: losing the new token means the next refresh\n * replays a spent one and permanently fails. It is also why this SDK must not\n * share a credential file with the Codex CLI.\n * @param store - the credential store to update in place.\n * @param options - issuer, client id, cancellation.\n * @returns the refreshed tokens.\n */\nexport function refreshCodexTokens(\n store: CodexCredentialStore,\n options?: CodexOAuthOptions,\n): Promise<CodexTokens>\nexport function refreshCodexTokens(\n store: CodexAuthStore,\n options?: CodexOAuthOptions,\n): Promise<CodexTokens>\nexport async function refreshCodexTokens(\n store: AnyCodexStore,\n options: CodexOAuthOptions = {},\n): Promise<CodexTokens> {\n return await refreshCodexTokensWithOperation(store, options, credentialOperation(options.signal))\n}\n\n/** Internal runtime path that preserves the caller's bound credential logger. */\nexport async function refreshCodexTokensWithOperation(\n store: AnyCodexStore,\n options: CodexOAuthOptions,\n operation: CredentialOperationOptions,\n): Promise<CodexTokens> {\n const captured = captureCodexStore(store)\n const snapshot = await readStore(captured, operation)\n const file = snapshot.file\n const current = file?.tokens\n if (current === undefined || current === null || current.refresh_token.length === 0) {\n throw new CodexRefreshError(\n `no refresh token at ${storeLabel(captured)}; run \\`npm run provider:codex:login-device\\``,\n 'permanent',\n )\n }\n\n const issuer = issuerOf(options)\n let response: Response\n try {\n response = await oauthFetch(options, `${issuer}/oauth/token`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n client_id: clientIdOf(options),\n grant_type: 'refresh_token',\n refresh_token: current.refresh_token,\n }),\n })\n } catch (error: unknown) {\n throw new CodexRefreshError('token refresh could not reach the auth service', 'transient', { cause: error })\n }\n\n if (!response.ok) {\n const raw = await readResponseText(response, options)\n const code = refreshErrorCode(raw)\n const permanent = response.status === 401\n || (code !== undefined && PERMANENT_REFRESH_CODES.has(code.toLowerCase()))\n throw new CodexRefreshError(\n permanent\n ? `Codex credentials are no longer valid (${code ?? `HTTP ${response.status}`});`\n + ' run `npm run provider:codex:login-device` to sign in again'\n : `token refresh failed (HTTP ${response.status})`,\n permanent ? 'permanent' : 'transient',\n { cause: new Error(raw) },\n )\n }\n\n const parsed = await readJson(response, 'the token endpoint', options)\n // Every field is optional on refresh; keep the current value when one is absent\n // rather than clobbering it with undefined.\n const next: CodexTokens = {\n id_token: typeof parsed.id_token === 'string' ? parsed.id_token : current.id_token,\n access_token: typeof parsed.access_token === 'string' ? parsed.access_token : current.access_token,\n refresh_token: typeof parsed.refresh_token === 'string' ? parsed.refresh_token : current.refresh_token,\n }\n const accountId = resolveAccountId(next)\n const updated: CodexTokens = { ...next, account_id: accountId ?? null }\n const nextFile: CodexAuthFile = {\n ...file,\n auth_mode: file?.auth_mode ?? 'chatgpt',\n tokens: updated,\n last_refresh: new Date().toISOString(),\n }\n try {\n await commitStore(captured, nextFile, snapshot.revision, operation)\n } catch (error) {\n if (!isRevisionConflict(error) || captured.kind !== 'versioned') throw error\n const winner = await readStore(captured, operation)\n const winnerTokens = winner.file?.tokens\n if (winner.revision === snapshot.revision || winnerTokens === undefined || winnerTokens === null) {\n throw error\n }\n return requireRefreshTokens(winnerTokens, storeLabel(captured))\n }\n return updated\n}\n\nfunction credentialOperation(signal: AbortSignal | undefined): CredentialOperationOptions {\n return { signal: signal ?? NEVER_ABORTED_SIGNAL, logger: NULL_LOGGER }\n}\n\nasync function readStore(\n captured: CapturedCodexStore,\n operation: CredentialOperationOptions,\n): Promise<CodexStoreSnapshot> {\n if (captured.kind === 'versioned') {\n const record = await captured.store.read(operation)\n return record === undefined\n ? { file: undefined, revision: null }\n : { file: record.value, revision: record.revision }\n }\n return { file: await captured.store.read(), revision: null }\n}\n\nasync function commitStore(\n captured: CapturedCodexStore,\n file: CodexAuthFile,\n expectedRevision: string | null,\n operation: CredentialOperationOptions,\n): Promise<void> {\n if (captured.kind === 'versioned') {\n await captured.store.commit({ value: file, expectedRevision }, operation)\n return\n }\n await captured.store.write(file)\n}\n\nfunction storeLabel(captured: CapturedCodexStore): string {\n return captured.label\n}\n\nfunction isRevisionConflict(error: unknown): boolean {\n if (error === null || typeof error !== 'object') return false\n const descriptor = Object.getOwnPropertyDescriptor(error, 'code')\n return descriptor !== undefined && 'value' in descriptor\n && descriptor.value === 'CODEX_CREDENTIAL_REVISION_CONFLICT'\n}\n\nfunction requireRefreshTokens(tokens: CodexTokens, location: string): CodexTokens {\n if (typeof tokens.access_token !== 'string' || tokens.access_token.length === 0\n || typeof tokens.refresh_token !== 'string' || tokens.refresh_token.length === 0) {\n throw new CodexRefreshError(`refreshed credentials at ${location} are incomplete`, 'permanent')\n }\n return tokens\n}\n","export interface CodexResponseMediaFetchOptions {\n readonly baseUrl: string\n readonly officialBaseUrl: string\n readonly fetch?: typeof globalThis.fetch\n}\n\n/**\n * Contain the official ChatGPT Codex endpoint's missing SSE media-type header.\n * Generic HTTP providers and custom Codex gateways remain strict.\n */\nexport function codexResponseMediaFetch(\n options: CodexResponseMediaFetchOptions,\n): typeof globalThis.fetch {\n const officialEndpoint = endpoint(options.officialBaseUrl)\n const configuredEndpoint = endpoint(options.baseUrl)\n const official = configuredEndpoint !== undefined && configuredEndpoint === officialEndpoint\n return async (input, init) => {\n const implementation = options.fetch ?? globalThis.fetch\n const response = await implementation(input, init)\n // HttpModelAdapter dispatches a URL string. Keeping the compatibility path\n // string-only avoids depending on optional Request/URL globals in minimal\n // standards runtimes and refuses to broaden the exception for other inputs.\n if (typeof input !== 'string') return response\n const requestedUrl = input\n if (!official || requestedUrl !== configuredEndpoint\n || response.status !== 200 || response.body === null\n || response.headers.get('content-type') !== null\n || response.redirected || response.type === 'opaqueredirect'\n || (response.url.length > 0 && response.url !== requestedUrl)) return response\n const headers = new Headers(response.headers)\n headers.set('content-type', 'text/event-stream')\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n })\n }\n}\n\nfunction endpoint(value: string): string | undefined {\n try {\n const url = new URL(value)\n if (url.search.length > 0 || url.hash.length > 0) return undefined\n return `${url.href.replace(/\\/+$/u, '')}/responses`\n } catch {\n return undefined\n }\n}\n","/**\n * The Codex provider: the Responses API behind the ChatGPT-backed Codex endpoint,\n * authenticated with this project's own credential store.\n *\n * Useful because it needs no API key and no billing setup — a ChatGPT subscription\n * plus `npm run provider:codex:login-device` is the whole setup, which makes it the\n * cheapest way to run real integration tests.\n *\n * This is also the proof that the configuration path scales: Codex has the most\n * demanding requirements of any provider here — OAuth with proactive token refresh,\n * account-scoped headers, endpoint-driven model discovery, and a reduced request\n * schema — and it still needs no adapter subclass. `auth: { kind: 'dynamic' }` is\n * what makes OAuth expressible as data.\n *\n * One thing to be deliberate about: this endpoint exists to serve the Codex CLI and\n * identifies its client with an `originator` header. Sending `codex_cli_rs` is what\n * makes the backend accept the request, so that is the default — but it IS\n * presenting as another client, so it is a named option rather than a hidden\n * constant. Use your own account, and prefer the `openai` provider for production.\n *\n * @module ai-agent-sdk/providers/codex/adapter\n */\n\nimport type { ModelProviderPlugin, ModelProviderRegistrar, RetryPolicyConfig } from '@alvin0/ai-agent-sdk-core'\nimport { ReasoningEffortId } from '@alvin0/ai-agent-sdk-core'\nimport { waitForSettlement } from '@alvin0/ai-agent-sdk-core'\nimport {\n defineModelProviderPlugin,\n type ComposableModelProviderPlugin,\n type CredentialOperationOptions,\n type ModelTarget,\n type SdkLogger,\n} from '@alvin0/ai-agent-sdk-core/provider'\nimport type {\n HttpModelAdapter,\n ProviderCatalogModel,\n ProviderRequestLogger,\n} from '@alvin0/ai-agent-sdk-provider-http'\nimport {\n createHttpProvider,\n createRuntimeHttpProvider,\n observeCredentialOperation,\n type ModelDiscoveryContext,\n} from '@alvin0/ai-agent-sdk-provider-http'\nimport {\n openAiResponsesProtocol,\n type ResponsesDialect,\n} from '@alvin0/ai-agent-sdk-protocol-responses'\nimport {\n isFedrampAccount,\n requireTokens,\n resolveAccountId,\n shouldRefresh,\n type CodexAuthStore,\n type CodexCredentialStore,\n} from './auth.ts'\nimport {\n refreshCodexTokens,\n refreshCodexTokensWithOperation,\n type CodexOAuthOptions,\n} from './oauth.ts'\nimport { captureCodexStore, type CapturedCodexStore } from './common/store-capture.ts'\nimport { codexResponseMediaFetch } from './common/response-media.ts'\nimport { rejectCodexRedirect } from './common/no-follow.ts'\n\n/** The ChatGPT-backed Codex API base. */\nexport const CODEX_BASE_URL = 'https://chatgpt.com/backend-api/codex'\n\n/** Client identifier this endpoint expects. See the module note. */\nexport const CODEX_ORIGINATOR = 'codex_cli_rs'\n\n/**\n * Client version sent when listing models.\n *\n * NOT cosmetic: the model catalog is gated on it, and an older value returns a\n * shorter list or an empty one. Verified against a live account — `0.45.0` returns\n * `{\"models\":[]}` while `1.0.0` returns the full set.\n */\nexport const CODEX_CLIENT_VERSION = '1.0.0'\n\n/** One entry of the `/models` response. */\ninterface WireCatalogModel {\n slug?: string\n display_name?: string\n description?: string\n input_modalities?: string[]\n output_modalities?: string[]\n context_window?: number\n default_reasoning_level?: string\n supported_reasoning_levels?: Array<{\n effort?: string\n description?: string\n }>\n}\n\n/** Options for {@link codexAdapter}. */\nexport interface CodexAdapterOptions {\n /**\n * Where the credentials live.\n *\n * Required injection. Filesystem/env defaults belong to the Node auth wrapper.\n */\n authStore: CodexAuthStore\n /** Endpoint base; defaults to {@link CODEX_BASE_URL}. */\n baseUrl?: string\n /** Client identifier; defaults to {@link CODEX_ORIGINATOR}. */\n originator?: string\n /**\n * Model catalog.\n *\n * Left undefined, the adapter DISCOVERS it from the endpoint, which is the right\n * default here: the available models depend on the account's plan and on\n * {@link CODEX_CLIENT_VERSION}, so no hardcoded list could be correct for\n * everyone. Discovery also supplies `input_modalities`, without which every model\n * would be assumed text-only and image input silently stripped.\n */\n models?: readonly ProviderCatalogModel[]\n /** Client version used for catalog discovery; defaults to {@link CODEX_CLIENT_VERSION}. */\n clientVersion?: string\n /** Maximum raw model-catalog response bytes. Defaults to 4 MiB. */\n maxCatalogBytes?: number\n /** Maximum model entries accepted from discovery. Defaults to 2,048. */\n maxCatalogModels?: number\n /** Maximum response chunks accepted during discovery. Defaults to 10,000. */\n maxCatalogChunks?: number\n /** Model-catalog request deadline. Defaults to 30 seconds. */\n catalogTimeoutMs?: number\n catalogTtlMs?: number\n catalogStaleTtlMs?: number\n catalogFailureBackoffMs?: number\n /** Output cap when neither caller nor catalog names one. */\n defaultMaxTokens?: number\n /** Context capacity assumed for an uncatalogued model. */\n defaultContextWindow?: number\n /** Idle bound while a stream read is outstanding. */\n streamIdleTimeoutMs?: number\n requestTimeoutMs?: number\n maxRequestBytes?: number\n maxResponseBytes?: number\n maxResponseChunks?: number\n maxSseEvents?: number\n maxSseEventChars?: number\n maxErrorBodyBytes?: number\n requestLoggerTimeoutMs?: number\n /** Retry policy this route owns. */\n retryPolicy?: RetryPolicyConfig\n /** Optional exact wire-request logger; credentials/account ids are redacted. */\n requestLogger?: ProviderRequestLogger\n /** Issuer and client id overrides for token refresh. */\n oauth?: CodexOAuthOptions\n /**\n * Stable key letting the provider reuse a cached prompt prefix across turns.\n *\n * Defaults to one id captured by the adapter/provider-plugin instance. Every\n * conversation routed through that same instance shares the key. Use separate\n * plugin instances (and routes) when cache identity must be isolated; this is\n * not a conversation- or tenant-scoped setting.\n */\n promptCacheKey?: string\n fetch?: typeof globalThis.fetch\n}\n\nexport interface CodexRevisionedAdapterOptions extends Omit<CodexAdapterOptions, 'authStore'> {\n readonly authStore: CodexCredentialStore\n}\n\nfunction randomId(): string {\n return globalThis.crypto?.randomUUID?.() ?? `sdk-${Date.now().toString(36)}`\n}\n\n/** Read `/models`, which requires — and is gated on — a client version. */\nasync function discoverCodexModels(\n context: ModelDiscoveryContext,\n clientVersion: string,\n limits: {\n readonly maxBytes: number\n readonly maxModels: number\n readonly maxChunks: number\n readonly timeoutMs: number\n },\n fetchImpl: typeof globalThis.fetch,\n): Promise<readonly ProviderCatalogModel[]> {\n const url = `${context.baseUrl}/models?client_version=${encodeURIComponent(clientVersion)}`\n const timeout = AbortSignal.timeout(limits.timeoutMs)\n const signal = context.signal === undefined ? timeout : AbortSignal.any([context.signal, timeout])\n const response = await fetchImpl(url, {\n headers: context.headers,\n signal,\n redirect: 'manual',\n })\n await rejectCodexRedirect(response, url, 'model catalog', 30_000)\n if (!response.ok) return []\n const body = await readCatalogJson(response, limits.maxBytes, limits.maxChunks, signal)\n const models = Array.isArray(body.models) ? body.models as WireCatalogModel[] : []\n if (models.length > limits.maxModels) {\n throw new RangeError(`Codex model catalog exceeds the ${limits.maxModels}-model limit`)\n }\n return models.flatMap((entry) => {\n if (typeof entry.slug !== 'string' || entry.slug.length === 0) return []\n const modalities = (entry.input_modalities ?? [])\n .filter((value): value is 'text' | 'image' => value === 'text' || value === 'image')\n const outputModalities = (entry.output_modalities ?? [])\n .filter((value): value is 'text' | 'image' => value === 'text' || value === 'image')\n const efforts = (entry.supported_reasoning_levels ?? []).flatMap((candidate) => {\n if (typeof candidate.effort !== 'string' || candidate.effort.length === 0) return []\n return [{\n id: ReasoningEffortId(candidate.effort),\n name: candidate.effort,\n ...candidate.description === undefined ? {} : { description: candidate.description },\n }]\n })\n const defaultEffort = typeof entry.default_reasoning_level === 'string'\n && efforts.some(effort => effort.id === entry.default_reasoning_level)\n ? ReasoningEffortId(entry.default_reasoning_level)\n : undefined\n return [{\n id: entry.slug,\n ...entry.display_name === undefined ? {} : { name: entry.display_name },\n ...entry.description === undefined ? {} : { description: entry.description },\n ...modalities.length > 0 ? { inputModalities: modalities } : {},\n ...outputModalities.length > 0 ? { outputModalities } : {},\n ...typeof entry.context_window === 'number' && Number.isSafeInteger(entry.context_window) && entry.context_window > 0\n ? { contextWindow: entry.context_window }\n : {},\n ...efforts.length === 0 ? {} : {\n reasoning: {\n efforts,\n ...defaultEffort === undefined ? {} : { defaultEffort },\n },\n },\n }]\n })\n}\n\n/**\n * Create a Codex adapter.\n * @param options - credential store, endpoint, and catalog overrides.\n * @returns the adapter, ready to register.\n */\nexport function codexAdapter(options: CodexRevisionedAdapterOptions): HttpModelAdapter\nexport function codexAdapter(options: CodexAdapterOptions): HttpModelAdapter\nexport function codexAdapter(\n options: CodexAdapterOptions | CodexRevisionedAdapterOptions,\n): HttpModelAdapter {\n const captured = captureCodexStore(options?.authStore)\n return captured.kind === 'versioned'\n ? runtimeCodexAdapter(options as CodexRevisionedAdapterOptions, captured)\n : legacyCodexAdapter(options as CodexAdapterOptions, captured)\n}\n\nfunction legacyCodexAdapter(\n options: CodexAdapterOptions,\n captured = captureCodexStore(options?.authStore),\n): HttpModelAdapter {\n if (captured.kind !== 'legacy') throw new TypeError('Codex legacy adapter requires a read/write auth store')\n const store = captured.store\n const promptCacheKey = options.promptCacheKey ?? randomId()\n const clientVersion = options.clientVersion ?? CODEX_CLIENT_VERSION\n const catalogLimits = Object.freeze({\n maxBytes: positiveSafeInteger(options.maxCatalogBytes ?? 4 * 1024 * 1024, 'maxCatalogBytes'),\n maxModels: positiveSafeInteger(options.maxCatalogModels ?? 2_048, 'maxCatalogModels'),\n maxChunks: positiveSafeInteger(options.maxCatalogChunks ?? 10_000, 'maxCatalogChunks'),\n timeoutMs: positiveSafeInteger(options.catalogTimeoutMs ?? 30_000, 'catalogTimeoutMs'),\n })\n\n /**\n * The Codex request schema has no `temperature`, `top_p`, or\n * `max_output_tokens`, so those knobs are turned off rather than sent and\n * rejected.\n */\n const dialect: Partial<ResponsesDialect> = {\n sampling: false,\n maxOutputTokens: false,\n structuredOutputs: true,\n store: false,\n messagePhase: true,\n promptCacheKey,\n }\n\n return createHttpProvider({\n displayName: 'Codex',\n protocol: openAiResponsesProtocol,\n baseUrl: options.baseUrl ?? CODEX_BASE_URL,\n dialect,\n /**\n * Resolved per operation, which is what lets OAuth live in configuration.\n *\n * Refresh happens HERE, proactively, keyed on the access token's own `exp`\n * with a five-minute margin. Doing it before the request rather than reacting\n * to a 401 keeps `AUTH` correctly non-retryable: by the time a 401 does\n * arrive, the credentials really are dead and the fix is re-login.\n */\n auth: {\n kind: 'dynamic',\n resolve: async (_signal, context) => {\n const file = await store.read()\n let tokens = requireTokens(file, store.location)\n if (file !== undefined && shouldRefresh(file)) {\n tokens = await observeCredentialOperation(\n context,\n 'codex',\n 'refresh',\n async () => await refreshCodexTokens(store, options.oauth ?? {}),\n )\n }\n const accountId = resolveAccountId(tokens)\n return {\n 'authorization': `Bearer ${tokens.access_token}`,\n 'originator': options.originator ?? CODEX_ORIGINATOR,\n ...accountId === undefined ? {} : { 'chatgpt-account-id': accountId },\n ...isFedrampAccount(tokens) ? { 'x-openai-fedramp': 'true' } : {},\n 'session-id': promptCacheKey,\n }\n },\n },\n ...options.models === undefined\n ? { discoverModels: (context) => discoverCodexModels(\n context,\n clientVersion,\n catalogLimits,\n options.fetch ?? globalThis.fetch,\n ) }\n : { models: options.models },\n defaultMaxTokens: options.defaultMaxTokens ?? 32_000,\n defaultContextWindow: options.defaultContextWindow ?? 272_000,\n ...options.streamIdleTimeoutMs === undefined\n ? {}\n : { streamIdleTimeoutMs: options.streamIdleTimeoutMs },\n ...options.catalogTtlMs === undefined ? {} : { catalogTtlMs: options.catalogTtlMs },\n ...options.catalogStaleTtlMs === undefined ? {} : { catalogStaleTtlMs: options.catalogStaleTtlMs },\n ...options.catalogFailureBackoffMs === undefined\n ? {}\n : { catalogFailureBackoffMs: options.catalogFailureBackoffMs },\n ...transportLimits(options),\n ...options.retryPolicy === undefined ? {} : { retryPolicy: options.retryPolicy },\n ...options.requestLogger === undefined ? {} : { requestLogger: options.requestLogger },\n })\n}\n\nconst NULL_LOGGER: SdkLogger = Object.freeze({\n child: () => NULL_LOGGER,\n trace: () => undefined, debug: () => undefined, info: () => undefined,\n warn: () => undefined, error: () => undefined, fatal: () => undefined,\n})\n\nfunction runtimeCodexAdapter(\n options: CodexRevisionedAdapterOptions,\n captured = captureCodexStore(options.authStore),\n): HttpModelAdapter {\n if (captured.kind !== 'versioned') {\n throw new TypeError('Codex runtime authStore must be a versioned credential store')\n }\n const store = captured.store\n const promptCacheKey = options.promptCacheKey ?? randomId()\n const clientVersion = options.clientVersion ?? CODEX_CLIENT_VERSION\n const catalogLimits = Object.freeze({\n maxBytes: positiveSafeInteger(options.maxCatalogBytes ?? 4 * 1024 * 1024, 'maxCatalogBytes'),\n maxModels: positiveSafeInteger(options.maxCatalogModels ?? 2_048, 'maxCatalogModels'),\n maxChunks: positiveSafeInteger(options.maxCatalogChunks ?? 10_000, 'maxCatalogChunks'),\n timeoutMs: positiveSafeInteger(options.catalogTimeoutMs ?? 30_000, 'catalogTimeoutMs'),\n })\n const dialect: Partial<ResponsesDialect> = {\n sampling: false,\n maxOutputTokens: false,\n structuredOutputs: true,\n store: false,\n messagePhase: true,\n promptCacheKey,\n }\n\n return createRuntimeHttpProvider({\n displayName: 'Codex',\n protocol: openAiResponsesProtocol,\n baseUrl: options.baseUrl ?? CODEX_BASE_URL,\n dialect,\n auth: {\n kind: 'dynamic',\n resolve: async ({ provider, signal, context }) => {\n const operation: CredentialOperationOptions = {\n signal,\n logger: context?.logger ?? NULL_LOGGER,\n }\n const record = await store.read(operation)\n const file = record?.value\n let tokens = requireTokens(file, store.label)\n if (file !== undefined && shouldRefresh(file)) {\n tokens = await observeCredentialOperation(\n context,\n provider,\n 'refresh',\n async () => await refreshCodexTokensWithOperation(\n store,\n { ...(options.oauth ?? {}), signal },\n operation,\n ),\n )\n }\n const accountId = resolveAccountId(tokens)\n return {\n authorization: `Bearer ${tokens.access_token}`,\n originator: options.originator ?? CODEX_ORIGINATOR,\n ...(accountId === undefined ? {} : { 'chatgpt-account-id': accountId }),\n ...(isFedrampAccount(tokens) ? { 'x-openai-fedramp': 'true' } : {}),\n 'session-id': promptCacheKey,\n }\n },\n },\n ...(options.models === undefined\n ? { discoverModels: context => discoverCodexModels(\n {\n baseUrl: context.baseUrl.href.replace(/\\/+$/, ''),\n headers: context.headers,\n signal: context.signal,\n provider: context.provider,\n ...(context.context === undefined ? {} : { context: context.context }),\n },\n clientVersion,\n catalogLimits,\n options.fetch ?? globalThis.fetch,\n ) }\n : { models: options.models }),\n ...(options.catalogTtlMs === undefined ? {} : { catalogTtlMs: options.catalogTtlMs }),\n ...(options.catalogStaleTtlMs === undefined ? {} : { catalogStaleTtlMs: options.catalogStaleTtlMs }),\n ...(options.catalogFailureBackoffMs === undefined\n ? {}\n : { catalogFailureBackoffMs: options.catalogFailureBackoffMs }),\n defaultMaxTokens: options.defaultMaxTokens ?? 32_000,\n defaultContextWindow: options.defaultContextWindow ?? 272_000,\n ...(options.streamIdleTimeoutMs === undefined ? {} : { streamIdleTimeoutMs: options.streamIdleTimeoutMs }),\n ...transportLimits(options),\n ...(options.retryPolicy === undefined ? {} : { retryPolicy: options.retryPolicy }),\n ...(options.requestLogger === undefined ? {} : { requestLogger: options.requestLogger }),\n })\n}\n\nexport interface CodexPluginOptions extends CodexAdapterOptions {\n /** Registry routes installed by the plugin. Defaults to `['codex']`. */\n readonly routes?: readonly string[]\n}\n\nexport interface CodexProviderOptions extends CodexRevisionedAdapterOptions {\n readonly defaultModel?: string | ModelTarget\n readonly id?: string\n readonly routes?: readonly string[]\n}\n\n/** Preferred transactional plugin for installing the Universal Codex provider. */\nexport function codexPlugin(\n options: CodexProviderOptions,\n): ComposableModelProviderPlugin & { readonly family: 'codex' }\nexport function codexPlugin(options: CodexPluginOptions): ModelProviderPlugin\nexport function codexPlugin(\n options: CodexProviderOptions | CodexPluginOptions,\n): ModelProviderPlugin | (ComposableModelProviderPlugin & { readonly family: 'codex' }) {\n if (isVersionedStoreInput(options.authStore)) {\n const id = 'id' in options && options.id !== undefined ? options.id : 'codex'\n const routes = Object.freeze([...options.routes ?? [id]])\n return defineModelProviderPlugin({\n id,\n family: 'codex',\n displayName: 'Codex',\n routes,\n ...runtimeDefaultModel(\n 'defaultModel' in options ? options.defaultModel : undefined,\n routes,\n ),\n setup(registrar) {\n const adapter = runtimeCodexAdapter(options as CodexProviderOptions)\n const remove = registrar.registerAdapter(adapter)\n return () => { remove(); return undefined }\n },\n }) as ComposableModelProviderPlugin & { readonly family: 'codex' }\n }\n return legacyCodexPlugin(options as CodexPluginOptions)\n}\n\n/** Marker inspection only; full store capture stays deferred to preferred setup. */\nfunction isVersionedStoreInput(value: unknown): boolean {\n if (typeof value !== 'object' || value === null) return false\n const kind = Object.getOwnPropertyDescriptor(value, 'kind')\n return kind !== undefined && 'value' in kind && kind.value === 'credential-store'\n}\n\nfunction legacyCodexPlugin(\n options: CodexPluginOptions,\n captured?: CapturedCodexStore,\n): ModelProviderPlugin {\n const routes = Object.freeze([...(options.routes ?? ['codex'])])\n const adapter = legacyCodexAdapter(options, captured)\n return Object.freeze({\n id: 'codex',\n displayName: 'Codex',\n setup(registrar: ModelProviderRegistrar) {\n registrar.registerAdapter(routes, adapter)\n },\n })\n}\n\nfunction runtimeDefaultModel(\n value: string | ModelTarget | undefined,\n routes: readonly string[],\n): { readonly defaultModel?: ModelTarget } {\n if (value === undefined) return {}\n if (typeof value !== 'string') return { defaultModel: value }\n if (routes.length !== 1) throw new TypeError('A string defaultModel requires exactly one Codex route')\n return { defaultModel: Object.freeze({ provider: routes[0]!, id: value }) }\n}\n\nasync function readCatalogJson(\n response: Response,\n maxBytes: number,\n maxChunks: number,\n signal: AbortSignal,\n): Promise<Record<string, unknown>> {\n const declared = Number(response.headers.get('content-length'))\n if (Number.isFinite(declared) && declared > maxBytes) {\n if (response.body !== null) await waitForSettlement(response.body.cancel().catch(() => undefined), 30_000)\n throw new RangeError(`Codex model catalog exceeds the ${maxBytes}-byte limit`)\n }\n if (response.body === null) throw new TypeError('Codex model catalog returned no body')\n const reader = response.body.getReader()\n const chunks: Uint8Array[] = []\n let bytes = 0\n let chunkCount = 0\n try {\n while (true) {\n const next = await raceAbort(reader.read(), signal)\n if (next.done) break\n if (next.value === undefined) continue\n chunkCount++\n if (chunkCount > maxChunks) {\n await waitForSettlement(reader.cancel().catch(() => undefined), 30_000)\n throw new RangeError(`Codex model catalog exceeds the ${maxChunks}-chunk limit`)\n }\n bytes += next.value.byteLength\n if (bytes > maxBytes) {\n await waitForSettlement(reader.cancel().catch(() => undefined), 30_000)\n throw new RangeError(`Codex model catalog exceeds the ${maxBytes}-byte limit`)\n }\n chunks.push(next.value)\n }\n } finally {\n reader.releaseLock()\n }\n const merged = new Uint8Array(bytes)\n let offset = 0\n for (const chunk of chunks) { merged.set(chunk, offset); offset += chunk.byteLength }\n const parsed: unknown = JSON.parse(new TextDecoder().decode(merged))\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new TypeError('Codex model catalog must be a JSON object')\n }\n return parsed as Record<string, unknown>\n}\n\nfunction raceAbort<T>(pending: Promise<T>, signal: AbortSignal): Promise<T> {\n if (signal.aborted) return Promise.reject(signal.reason ?? new Error('Codex catalog request aborted'))\n return new Promise<T>((resolve, reject) => {\n const abort = () => { cleanup(); reject(signal.reason ?? new Error('Codex catalog request aborted')) }\n const cleanup = () => signal.removeEventListener('abort', abort)\n signal.addEventListener('abort', abort, { once: true })\n void pending.then(\n value => { cleanup(); resolve(value) },\n error => { cleanup(); reject(error) },\n )\n })\n}\n\nfunction positiveSafeInteger(value: number, field: string): number {\n if (!Number.isSafeInteger(value) || value < 1) throw new RangeError(`Codex ${field} must be a positive safe integer`)\n return value\n}\n\nfunction transportLimits(options: CodexAdapterOptions | CodexRevisionedAdapterOptions) {\n const fetch = codexResponseMediaFetch({\n baseUrl: options.baseUrl ?? CODEX_BASE_URL,\n officialBaseUrl: CODEX_BASE_URL,\n ...(options.fetch === undefined ? {} : { fetch: options.fetch }),\n })\n return {\n ...options.requestTimeoutMs === undefined ? {} : { requestTimeoutMs: options.requestTimeoutMs },\n ...options.maxRequestBytes === undefined ? {} : { maxRequestBytes: options.maxRequestBytes },\n ...options.maxResponseBytes === undefined ? {} : { maxResponseBytes: options.maxResponseBytes },\n ...options.maxResponseChunks === undefined ? {} : { maxResponseChunks: options.maxResponseChunks },\n ...options.maxSseEvents === undefined ? {} : { maxSseEvents: options.maxSseEvents },\n ...options.maxSseEventChars === undefined ? {} : { maxSseEventChars: options.maxSseEventChars },\n ...options.maxErrorBodyBytes === undefined ? {} : { maxErrorBodyBytes: options.maxErrorBodyBytes },\n ...options.requestLoggerTimeoutMs === undefined ? {} : { requestLoggerTimeoutMs: options.requestLoggerTimeoutMs },\n fetch,\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAqBA,SAAgB,qBAAqB,SAAyC;CAC5E,IAAI,UAAU;CACd,OAAO;EACL,UAAU;EACV,YAAY,QAAQ,QAAQ,OAAO;EACnC,QAAQ,SAAS;GACf,UAAU;GACV,OAAO,QAAQ,QAAQ;EACzB;CACF;AACF;;AAGA,SAAgB,2BAA2B,SAA+C;CACxF,IAAI,UAAU,YAAY,SAAY,SAAY,gBAAgB,OAAO;CACzE,IAAI,WAAW;CACf,OAAO,sBAAqC;EAC1C,IAAI;EACJ,OAAO;EACP,MAAM,KAAK,EAAE,UAAU;GACrB,OAAO,eAAe;GACtB,OAAO,YAAY,SACf,SACA;IAAE,OAAO,gBAAgB,OAAO;IAAG,UAAU,OAAO,QAAQ;GAAE;EACpE;EACA,MAAM,OAAO,OAAO,EAAE,UAAU;GAC9B,OAAO,eAAe;GACtB,MAAM,WAAW,YAAY,SAAY,OAAO,OAAO,QAAQ;GAC/D,IAAI,MAAM,qBAAqB,UAC7B,MAAM,IAAI,cACR,mDACA,oCACF;GAEF,UAAU,gBAAgB,MAAM,KAAK;GACrC;GACA,OAAO,EAAE,UAAU,OAAO,QAAQ,EAAE;EACtC;CACF,CAAC;AACH;;AAGA,MAAM,uBAAuB;;AAY7B,SAAS,gBAAgB,SAAyB;CAChD,MAAM,SAAS,QAAQ,QAAQ,MAAM,GAAG,CAAC,CAAC,QAAQ,MAAM,GAAG,IACvD,IAAI,QAAQ,IAAK,QAAQ,SAAS,KAAM,CAAC;CAC7C,MAAM,SAAS,KAAK,MAAM;CAG1B,MAAM,QAAQ,WAAW,KAAK,SAAQ,cAAa,UAAU,WAAW,CAAC,CAAC;CAC1E,OAAO,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK;AACvC;;;;;;;;;;AAWA,SAAgB,cAAc,KAAyC;CACrE,MAAM,QAAQ,IAAI,MAAM,GAAG;CAC3B,MAAM,UAAU,MAAM,WAAW,IAAI,MAAM,KAAK;CAChD,IAAI,YAAY,UAAa,QAAQ,WAAW,GAAG,OAAO;CAC1D,IAAI;CACJ,IAAI;EACF,SAAS,KAAK,MAAM,gBAAgB,OAAO,CAAC;CAC9C,QAAQ;EACN;CACF;CACA,MAAM,OAAO,OAAO;CACpB,MAAM,aAAa,OAAO,SAAS,YAAY,SAAS,OACpD,OACA,CAAC;CACL,MAAM,MAAM,OAAO;CACnB,MAAM,QAAQ,OAAO;CACrB,MAAM,YAAY,WAAW;CAC7B,MAAM,WAAW,WAAW;CAC5B,OAAO;EACL,GAAG,OAAO,QAAQ,WAAW,EAAE,IAAI,IAAI,CAAC;EACxC,GAAG,OAAO,UAAU,WAAW,EAAE,MAAM,IAAI,CAAC;EAC5C,GAAG,OAAO,cAAc,WAAW,EAAE,UAAU,IAAI,CAAC;EACpD,GAAG,OAAO,aAAa,WAAW,EAAE,SAAS,IAAI,CAAC;EAClD,WAAW,WAAW,+BAA+B;CACvD;AACF;;;;;;;;;AAUA,SAAgB,iBAAiB,QAAyC;CACxE,MAAM,SAAS,OAAO;CACtB,IAAI,OAAO,WAAW,YAAY,OAAO,SAAS,GAAG,OAAO;CAC5D,OAAO,cAAc,OAAO,QAAQ,CAAC,EAAE;AACzC;;AAGA,SAAgB,iBAAiB,QAA8B;CAC7D,OAAO,cAAc,OAAO,QAAQ,CAAC,EAAE,cAAc;AACvD;;AAGA,MAAa,iCAAiC;;AAG9C,MAAa,0BAA0B;;;;;;;;;;;AAYvC,SAAgB,cAAc,MAAqB,MAAM,KAAK,IAAI,GAAY;CAC5E,MAAM,SAAS,KAAK;CACpB,IAAI,WAAW,UAAa,WAAW,MAAM,OAAO;CACpD,MAAM,MAAM,cAAc,OAAO,YAAY,CAAC,EAAE;CAChD,IAAI,QAAQ,QAAW,OAAO,MAAM,OAAS,MAAM;CACnD,MAAM,cAAc,KAAK;CACzB,IAAI,gBAAgB,UAAa,gBAAgB,MAAM,OAAO;CAC9D,MAAM,KAAK,KAAK,MAAM,WAAW;CACjC,OAAO,OAAO,SAAS,EAAE,KAAK,KAAK;AACrC;;;;;;;AAQA,SAAgB,cACd,MACA,UACa;CACb,MAAM,SAAS,MAAM;CACrB,IAAI,WAAW,UAAa,WAAW,QAClC,OAAO,OAAO,iBAAiB,YAAY,OAAO,aAAa,WAAW,GAC7E,MAAM,IAAI,cACR,2BAA2B,SAAS,2DACpC,uBACF;CAEF,OAAO;AACT;;;;;ACvKA,SAAgB,kBAAkB,OAAoC;CACpE,IAAI;EACF,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU,MAAM,IAAI,UAAU,yBAAyB;EAC9F,MAAM,SAAS,UAAU,OAAO,QAAQ,KAAK;EAC7C,IAAI,WAAW,QAAW,OAAO,cAAc,KAAK;EACpD,IAAI,WAAW,sBACV,UAAU,OAAO,YAAY,MAAM,mCACtC,MAAM,IAAI,UAAU,qCAAqC;EAE3D,MAAM,KAAK,cAAc,UAAU,OAAO,IAAI,GAAG,KAAK,qBAAqB;EAC3E,MAAM,QAAQ,cAAc,UAAU,OAAO,OAAO,GAAG,KAAK,wBAAwB;EACpF,MAAM,OAAO,eAEX,OAAO,MAAM;EACf,MAAM,SAAS,eAEb,OAAO,QAAQ;EACjB,OAAO,OAAO,OAAO;GACnB,MAAM;GACN;GACA,OAAO,OAAO,OAAO;IACnB,MAAM;IACN,YAAY;IACZ;IACA;IACA;IACA;GACF,CAAC;EACH,CAAC;CACH,SAAS,OAAO;EACd,MAAM,IAAIA,gBAAc,+CAA+C,4BAA4B,EAAE,OAAO,MAAM,CAAC;CACrH;AACF;AAEA,SAAS,cAAc,QAAoC;CACzD,MAAM,WAAW,cAAc,UAAU,QAAQ,UAAU,GAAG,MAAO,2BAA2B;CAChG,MAAM,OAAO,eAAuD,QAAQ,MAAM;CAClF,MAAM,QAAQ,eAA+C,QAAQ,OAAO;CAC5E,OAAO,OAAO,OAAO;EACnB,MAAM;EACN,OAAO;EACP,OAAO,OAAO,OAAO;GAAE;GAAU;GAAM;EAAM,CAAC;CAChD,CAAC;AACH;AAEA,SAAS,eACP,QACA,KAC2B;CAC3B,MAAM,SAAS,UAAU,QAAQ,GAAG;CACpC,IAAI,OAAO,WAAW,YAAY,MAAM,IAAI,UAAU,GAAG,OAAO,GAAG,EAAE,oBAAoB;CACzF,QAAQ,GAAG,SAAe,QAAQ,MAAM,QAAQ,QAAQ,IAAI;AAC9D;AAEA,SAAS,UAAU,QAAgB,KAAkB,WAAW,MAAe;CAC7E,IAAI,QAAuB;CAC3B,OAAO,UAAU,MAAM;EACrB,MAAM,aAAa,OAAO,yBAAyB,OAAO,GAAG;EAC7D,IAAI,eAAe,QAAW;GAC5B,IAAI,EAAE,WAAW,aAAa,MAAM,IAAI,UAAU,GAAG,OAAO,GAAG,EAAE,yBAAyB;GAC1F,OAAO,WAAW;EACpB;EACA,QAAQ,OAAO,eAAe,KAAK;CACrC;CACA,IAAI,CAAC,UAAU,OAAO;CACtB,MAAM,IAAI,UAAU,WAAW,OAAO,GAAG,GAAG;AAC9C;AAEA,SAAS,cAAc,OAAgB,WAAmB,OAAuB;CAC/E,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,KAAK,MAAM,SAAS,WACpE,MAAM,IAAI,UAAU,GAAG,MAAM,oCAAoC;CAEnE,OAAO;AACT;;;;;ACzFA,eAAsB,oBACpB,UACA,cACA,WACA,mBACe;CACf,MAAM,iBAAiB,SAAS,UAAU,OAAO,SAAS,SAAS;CACnE,MAAM,qBAAqB,SAAS,IAAI,SAAS,KAAK,SAAS,QAAQ;CACvE,IAAI,SAAS,SAAS,oBAAoB,SAAS,eAAe,QAC7D,CAAC,kBAAkB,CAAC,oBAAoB;CAC7C,IAAI,SAAS,SAAS,MACpB,MAAM,kBAAkB,SAAS,KAAK,OAAO,CAAC,CAAC,YAAY,MAAS,GAAG,iBAAiB;CAE1F,MAAM,IAAI,UAAU,SAAS,UAAU,yCAAyC;AAClF;;;;;;;;;;;;;;;;;;;;;ACeA,MAAM,uBAAuB,IAAI,gBAAgB,CAAC,CAAC;AACnD,MAAMC,gBAAyB,OAAO,OAAO;CAC3C,aAAaA;CACb,aAAa;CACb,aAAa;CACb,YAAY;CACZ,YAAY;CACZ,aAAa;CACb,aAAa;AACf,CAAC;;AAUD,MAAa,uBAAuB;;AAGpC,MAAa,kBAAkB;;AAG/B,MAAM,0BAA0B;;AAGhC,MAAM,gCAAgC;AA0CtC,SAAS,SAAS,SAAoC;CACpD,MAAM,MAAM,IAAI,IAAI,QAAQ,mCAA8B;CAC1D,IAAI,IAAI,SAAS,SAAS,KAAK,IAAI,SAAS,SAAS,GACnD,MAAM,IAAI,UAAU,iDAAiD;CAEvE,IAAI,IAAI,aAAa,YAAY,EAAE,QAAQ,wBAAwB,QAAQ,IAAI,aAAa,UAC1F,MAAM,IAAI,UAAU,mCAAmC;CAEzD,OAAO,IAAI,KAAK,QAAQ,QAAQ,EAAE;AACpC;AAEA,SAAS,WAAW,SAAoC;CACtD,OAAO,QAAQ;AACjB;AAEA,eAAe,WACb,SACA,OACA,MACmB;CACnB,MAAM,SAAS,IAAI,IAAI,SAAS,OAAO,CAAC;CACxC,MAAM,MAAM,IAAI,IAAI,KAAK;CACzB,IAAI,IAAI,WAAW,OAAO,QAAQ,MAAM,IAAI,UAAU,gCAAgC,IAAI,OAAO,iBAAiB;CAClH,MAAM,YAAYC,sBAAoB,QAAQ,oBAAoB,KAAQ,kBAAkB;CAC5F,MAAM,UAAU,YAAY,QAAQ,SAAS;CAC7C,MAAM,SAAS,QAAQ,WAAW,SAAY,UAAU,YAAY,IAAI,CAAC,QAAQ,QAAQ,OAAO,CAAC;CACjG,MAAM,YAAY,QAAQ,SAAS,WAAW;CAC9C,IAAI,OAAO,cAAc,YAAY,MAAM,IAAI,UAAU,4BAA4B;CACrF,MAAM,WAAW,MAAMC,YAAU,QAAQ,QAAQ,UAAU,KAAK;EAC9D,GAAG;EACH;EACA,UAAU;CACZ,CAAC,CAAC,GAAG,MAAM;CACX,MAAM,oBAAoB,UAAU,IAAI,MAAM,SAAS,GAAM;CAC7D,OAAO;AACT;AAEA,eAAe,iBAAiB,UAAoB,SAA6C;CAC/F,MAAM,WAAWD,sBAAoB,QAAQ,oBAAoB,SAAa,kBAAkB;CAChG,MAAM,YAAYA,sBAAoB,QAAQ,qBAAqB,KAAQ,mBAAmB;CAC9F,MAAM,WAAW,OAAO,SAAS,QAAQ,IAAI,gBAAgB,CAAC;CAC9D,IAAI,OAAO,SAAS,QAAQ,KAAK,WAAW,UAAU;EACpD,IAAI,SAAS,SAAS,MAAM,MAAM,kBAAkB,SAAS,KAAK,OAAO,CAAC,CAAC,YAAY,MAAS,GAAG,GAAM;EACzG,MAAM,IAAI,WAAW,oCAAoC,SAAS,YAAY;CAChF;CACA,IAAI,SAAS,SAAS,MAAM,OAAO;CACnC,MAAM,UAAU,YAAY,QAAQA,sBAAoB,QAAQ,oBAAoB,KAAQ,kBAAkB,CAAC;CAC/G,MAAM,SAAS,QAAQ,WAAW,SAAY,UAAU,YAAY,IAAI,CAAC,QAAQ,QAAQ,OAAO,CAAC;CACjG,MAAM,SAAS,SAAS,KAAK,UAAU;CACvC,MAAM,UAAU,IAAI,YAAY;CAChC,IAAI,QAAQ;CACZ,IAAI,SAAS;CACb,IAAI,SAAS;CACb,IAAI;EACF,OAAO,MAAM;GACX,MAAM,OAAO,MAAMC,YAAU,OAAO,KAAK,GAAG,MAAM;GAClD,IAAI,KAAK,MAAM,OAAO,SAAS,QAAQ,OAAO;GAC9C,IAAI,KAAK,UAAU,QAAW;GAC9B;GACA,SAAS,KAAK,MAAM;GACpB,IAAI,SAAS,aAAa,QAAQ,UAAU;IAC1C,MAAM,kBAAkB,OAAO,OAAO,CAAC,CAAC,YAAY,MAAS,GAAG,GAAM;IACtE,MAAM,IAAI,WAAW,4DAA4D;GACnF;GACA,UAAU,QAAQ,OAAO,KAAK,OAAO,EAAE,QAAQ,KAAK,CAAC;EACvD;CACF,UAAU;EACR,OAAO,YAAY;CACrB;AACF;AAEA,SAASA,YAAa,SAAqB,QAAiC;CAC1E,IAAI,OAAO,SAAS,OAAO,QAAQ,OAAO,OAAO,0BAAU,IAAI,MAAM,+BAA+B,CAAC;CACrG,OAAO,IAAI,SAAY,SAAS,WAAW;EACzC,MAAM,cAAc;GAAE,QAAQ;GAAG,OAAO,OAAO,0BAAU,IAAI,MAAM,+BAA+B,CAAC;EAAE;EACrG,MAAM,gBAAgB,OAAO,oBAAoB,SAAS,KAAK;EAC/D,OAAO,iBAAiB,SAAS,OAAO,EAAE,MAAM,KAAK,CAAC;EACtD,AAAK,QAAQ,MACX,UAAS;GAAE,QAAQ;GAAG,QAAQ,KAAK;EAAE,IACrC,UAAS;GAAE,QAAQ;GAAG,OAAO,KAAK;EAAE,CACtC;CACF,CAAC;AACH;AAEA,SAASD,sBAAoB,OAAe,OAAuB;CACjE,IAAI,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,GAC1C,MAAM,IAAI,WAAW,eAAe,MAAM,iCAAiC;CAE7E,OAAO;AACT;;AAGA,eAAe,SACb,UACA,MACA,SACkC;CAClC,MAAM,MAAM,MAAM,iBAAiB,UAAU,OAAO;CACpD,IAAI;EACF,OAAO,KAAK,MAAM,GAAG;CACvB,SAAS,OAAgB;EACvB,MAAM,IAAI,cACR,GAAG,KAAK,sCAAsC,SAAS,OAAO,IAC9D,wBACA,EAAE,OAAO,MAAM,CACjB;CACF;AACF;AAEA,SAAS,cAAc,QAAiC,KAAa,MAAsB;CACzF,MAAM,QAAQ,OAAO;CACrB,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAChD,MAAM,IAAI,cAAc,GAAG,KAAK,YAAY,IAAI,IAAI,sBAAsB;CAE5E,OAAO;AACT;;;;;;AAOA,eAAsB,kBACpB,UAA6B,CAAC,GACJ;CAC1B,MAAM,SAAS,SAAS,OAAO;CAC/B,MAAM,WAAW,MAAM,WAAW,SAAS,GAAG,OAAO,oCAAoC;EACvF,QAAQ;EACR,SAAS,EAAE,gBAAgB,mBAAmB;EAC9C,MAAM,KAAK,UAAU,EAAE,WAAW,WAAW,OAAO,EAAE,CAAC;CACzD,CAAC;CACD,IAAI,SAAS,WAAW,KACtB,MAAM,IAAI,cACR,yCAAyC,OAAO,yBAChD,wBACF;CAEF,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,cACR,oCAAoC,SAAS,OAAO,IACpD,qBACA,EAAE,OAAO,IAAI,MAAM,MAAM,iBAAiB,UAAU,OAAO,CAAC,EAAE,CAChE;CAEF,MAAM,OAAO,MAAM,SAAS,UAAU,4BAA4B,OAAO;CAEzE,MAAM,cAAc,KAAK;CACzB,MAAM,SAAS,OAAO,gBAAgB,WAClC,OAAO,SAAS,YAAY,KAAK,GAAG,EAAE,IACtC,OAAO,gBAAgB,WAAW,cAAc;CACpD,OAAO;EACL,iBAAiB,GAAG,OAAO;EAC3B,UAAU,cAAc,MAAM,aAAa,0BAA0B;EACrE,cAAc,cAAc,MAAM,kBAAkB,0BAA0B;EAC9E,iBAAiB,OAAO,SAAS,MAAM,KAAK,SAAS,IAAI,SAAS;CACpE;AACF;AAQA,SAAS,MAAM,IAAY,QAAqC;CAC9D,IAAI,QAAQ,YAAY,MACtB,OAAO,QAAQ,OAAO,IAAI,cAAc,+BAA+B,SAAS,CAAC;CAEnF,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,gBAAsB;GAC1B,aAAa,KAAK;GAClB,OAAO,IAAI,cAAc,+BAA+B,SAAS,CAAC;EACpE;EACA,MAAM,QAAQ,iBAAiB;GAC7B,QAAQ,oBAAoB,SAAS,OAAO;GAC5C,QAAQ;EACV,GAAG,EAAE;EACL,QAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;CAC3D,CAAC;AACH;;;;;;;;;;;;AAaA,eAAe,qBACb,MACA,SACA,UAC6B;CAE7B,MAAM,MAAM,GADG,SAAS,OACJ,EAAE;CACtB,MAAM,YAAY,KAAK,IAAI;CAE3B,OAAO,MAAM;EACX,MAAM,UAAU,KAAK,IAAI,IAAI;EAC7B,IAAI;GAAE,SAAS,SAAS,OAAO;EAAE,QAAQ,CAAqD;EAC9F,MAAM,WAAW,MAAM,WAAW,SAAS,KAAK;GAC9C,QAAQ;GACR,SAAS,EAAE,gBAAgB,mBAAmB;GAC9C,MAAM,KAAK,UAAU;IAAE,gBAAgB,KAAK;IAAc,WAAW,KAAK;GAAS,CAAC;EACtF,CAAC;EAED,IAAI,SAAS,IAAI;GACf,MAAM,OAAO,MAAM,SAAS,UAAU,6BAA6B,OAAO;GAC1E,OAAO;IACL,mBAAmB,cAAc,MAAM,sBAAsB,2BAA2B;IACxF,cAAc,cAAc,MAAM,iBAAiB,2BAA2B;GAChF;EACF;EAEA,IAAI,SAAS,WAAW,OAAO,SAAS,WAAW,KAAK;GACtD,MAAM,YAAY,2BAA2B,KAAK,IAAI,IAAI;GAC1D,IAAI,aAAa,GACf,MAAM,IAAI,cACR,iEACA,oBACF;GAEF,MAAM,MAAM,KAAK,IAAI,KAAK,kBAAkB,KAAO,SAAS,GAAG,QAAQ,MAAM;GAC7E;EACF;EAEA,MAAM,IAAI,cACR,oCAAoC,SAAS,OAAO,IACpD,qBACA,EAAE,OAAO,IAAI,MAAM,MAAM,iBAAiB,UAAU,OAAO,CAAC,EAAE,CAChE;CACF;AACF;;;;;;;AAQA,eAAe,sBACb,OACA,SACsB;CACtB,MAAM,SAAS,SAAS,OAAO;CAC/B,MAAM,OAAO,IAAI,gBAAgB;EAC/B,YAAY;EACZ,MAAM,MAAM;EACZ,cAAc,GAAG,OAAO;EACxB,WAAW,WAAW,OAAO;EAC7B,eAAe,MAAM;CACvB,CAAC;CACD,MAAM,WAAW,MAAM,WAAW,SAAS,GAAG,OAAO,eAAe;EAClE,QAAQ;EACR,SAAS,EAAE,gBAAgB,oCAAoC;EAC/D,MAAM,KAAK,SAAS;CACtB,CAAC;CACD,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,cACR,+BAA+B,SAAS,OAAO,IAC/C,qBACA,EAAE,OAAO,IAAI,MAAM,MAAM,iBAAiB,UAAU,OAAO,CAAC,EAAE,CAChE;CAEF,MAAM,SAAS,MAAM,SAAS,UAAU,sBAAsB,OAAO;CACrE,OAAO;EACL,UAAU,cAAc,QAAQ,YAAY,oBAAoB;EAChE,cAAc,cAAc,QAAQ,gBAAgB,oBAAoB;EACxE,eAAe,cAAc,QAAQ,iBAAiB,oBAAoB;CAC5E;AACF;;AAGA,SAAS,YAAY,QAAoC;CACvD,MAAM,YAAY,iBAAiB,MAAM;CACzC,OAAO;EACL,WAAW;EACX,gBAAgB;EAChB,QAAQ;GAAE,GAAG;GAAQ,YAAY,aAAa;EAAK;EACnD,+BAAc,IAAI,KAAK,EAAC,CAAC,YAAY;CACvC;AACF;AA+BA,eAAsB,mBACpB,OACA,UAA6B,CAAC,GAC9B,WAA+B,CAAC,GACL;CAC3B,MAAM,WAAW,kBAAkB,KAAK;CACxC,MAAM,YAAY,oBAAoB,QAAQ,MAAM;CACpD,MAAM,UAAU,MAAM,UAAU,UAAU,SAAS;CACnD,MAAM,OAAO,MAAM,kBAAkB,OAAO;CAC5C,IAAI;EAAE,SAAS,WAAW,IAAI;CAAE,QAAQ,CAAqD;CAE7F,MAAM,SAAS,MAAM,sBAAsB,MADvB,qBAAqB,MAAM,SAAS,QAAQ,GACd,OAAO;CACzD,MAAM,OAAO,YAAY,MAAM;CAC/B,MAAM,YAAY,UAAU,MAAM,QAAQ,UAAU,SAAS;CAE7D,MAAM,SAAS,cAAc,OAAO,QAAQ;CAC5C,OAAO;EACL,UAAU,WAAW,QAAQ;EAC7B,OAAO,QAAQ;EACf,WAAW,KAAK,QAAQ,cAAc;EACtC,UAAU,QAAQ;CACpB;AACF;;AAMA,IAAa,oBAAb,cAAuC,cAAc;CACnD,AAAS;CAET,YAAY,SAAiB,MAA0B,SAAwB;EAC7E,MAAM,SAAS,SAAS,cAAc,0BAA0B,2BAA2B,OAAO;EAClG,KAAK,OAAO;CACd;AACF;;AAGA,MAAM,0CAA0B,IAAI,IAAI;CACtC;CACA;CACA;CACA;AACF,CAAC;;AAGD,SAAS,iBAAiB,KAAiC;CACzD,IAAI;EACF,MAAM,SAAS,KAAK,MAAM,GAAG;EAC7B,MAAM,QAAQ,OAAO;EACrB,IAAI,OAAO,UAAU,UAAU,OAAO;EACtC,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM;GAC/C,MAAM,OAAQ,MAAkC;GAChD,IAAI,OAAO,SAAS,UAAU,OAAO;EACvC;EACA,MAAM,OAAO,OAAO;EACpB,OAAO,OAAO,SAAS,WAAW,OAAO;CAC3C,QAAQ;EACN;CACF;AACF;AAqBA,eAAsB,mBACpB,OACA,UAA6B,CAAC,GACR;CACtB,OAAO,MAAM,gCAAgC,OAAO,SAAS,oBAAoB,QAAQ,MAAM,CAAC;AAClG;;AAGA,eAAsB,gCACpB,OACA,SACA,WACsB;CACtB,MAAM,WAAW,kBAAkB,KAAK;CACxC,MAAM,WAAW,MAAM,UAAU,UAAU,SAAS;CACpD,MAAM,OAAO,SAAS;CACtB,MAAM,UAAU,MAAM;CACtB,IAAI,YAAY,UAAa,YAAY,QAAQ,QAAQ,cAAc,WAAW,GAChF,MAAM,IAAI,kBACR,uBAAuB,WAAW,QAAQ,EAAE,gDAC5C,WACF;CAGF,MAAM,SAAS,SAAS,OAAO;CAC/B,IAAI;CACJ,IAAI;EACF,WAAW,MAAM,WAAW,SAAS,GAAG,OAAO,eAAe;GAC5D,QAAQ;GACR,SAAS,EAAE,gBAAgB,mBAAmB;GAC9C,MAAM,KAAK,UAAU;IACnB,WAAW,WAAW,OAAO;IAC7B,YAAY;IACZ,eAAe,QAAQ;GACzB,CAAC;EACH,CAAC;CACH,SAAS,OAAgB;EACvB,MAAM,IAAI,kBAAkB,kDAAkD,aAAa,EAAE,OAAO,MAAM,CAAC;CAC7G;CAEA,IAAI,CAAC,SAAS,IAAI;EAChB,MAAM,MAAM,MAAM,iBAAiB,UAAU,OAAO;EACpD,MAAM,OAAO,iBAAiB,GAAG;EACjC,MAAM,YAAY,SAAS,WAAW,OAChC,SAAS,UAAa,wBAAwB,IAAI,KAAK,YAAY,CAAC;EAC1E,MAAM,IAAI,kBACR,YACI,0CAA0C,QAAQ,QAAQ,SAAS,SAAS,mEAE5E,8BAA8B,SAAS,OAAO,IAClD,YAAY,cAAc,aAC1B,EAAE,OAAO,IAAI,MAAM,GAAG,EAAE,CAC1B;CACF;CAEA,MAAM,SAAS,MAAM,SAAS,UAAU,sBAAsB,OAAO;CAGrE,MAAM,OAAoB;EACxB,UAAU,OAAO,OAAO,aAAa,WAAW,OAAO,WAAW,QAAQ;EAC1E,cAAc,OAAO,OAAO,iBAAiB,WAAW,OAAO,eAAe,QAAQ;EACtF,eAAe,OAAO,OAAO,kBAAkB,WAAW,OAAO,gBAAgB,QAAQ;CAC3F;CACA,MAAM,YAAY,iBAAiB,IAAI;CACvC,MAAM,UAAuB;EAAE,GAAG;EAAM,YAAY,aAAa;CAAK;CACtE,MAAM,WAA0B;EAC9B,GAAG;EACH,WAAW,MAAM,aAAa;EAC9B,QAAQ;EACR,+BAAc,IAAI,KAAK,EAAC,CAAC,YAAY;CACvC;CACA,IAAI;EACF,MAAM,YAAY,UAAU,UAAU,SAAS,UAAU,SAAS;CACpE,SAAS,OAAO;EACd,IAAI,CAAC,mBAAmB,KAAK,KAAK,SAAS,SAAS,aAAa,MAAM;EACvE,MAAM,SAAS,MAAM,UAAU,UAAU,SAAS;EAClD,MAAM,eAAe,OAAO,MAAM;EAClC,IAAI,OAAO,aAAa,SAAS,YAAY,iBAAiB,UAAa,iBAAiB,MAC1F,MAAM;EAER,OAAO,qBAAqB,cAAc,WAAW,QAAQ,CAAC;CAChE;CACA,OAAO;AACT;AAEA,SAAS,oBAAoB,QAA6D;CACxF,OAAO;EAAE,QAAQ,UAAU;EAAsB,QAAQD;CAAY;AACvE;AAEA,eAAe,UACb,UACA,WAC6B;CAC7B,IAAI,SAAS,SAAS,aAAa;EACjC,MAAM,SAAS,MAAM,SAAS,MAAM,KAAK,SAAS;EAClD,OAAO,WAAW,SACd;GAAE,MAAM;GAAW,UAAU;EAAK,IAClC;GAAE,MAAM,OAAO;GAAO,UAAU,OAAO;EAAS;CACtD;CACA,OAAO;EAAE,MAAM,MAAM,SAAS,MAAM,KAAK;EAAG,UAAU;CAAK;AAC7D;AAEA,eAAe,YACb,UACA,MACA,kBACA,WACe;CACf,IAAI,SAAS,SAAS,aAAa;EACjC,MAAM,SAAS,MAAM,OAAO;GAAE,OAAO;GAAM;EAAiB,GAAG,SAAS;EACxE;CACF;CACA,MAAM,SAAS,MAAM,MAAM,IAAI;AACjC;AAEA,SAAS,WAAW,UAAsC;CACxD,OAAO,SAAS;AAClB;AAEA,SAAS,mBAAmB,OAAyB;CACnD,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU,OAAO;CACxD,MAAM,aAAa,OAAO,yBAAyB,OAAO,MAAM;CAChE,OAAO,eAAe,UAAa,WAAW,cACzC,WAAW,UAAU;AAC5B;AAEA,SAAS,qBAAqB,QAAqB,UAA+B;CAChF,IAAI,OAAO,OAAO,iBAAiB,YAAY,OAAO,aAAa,WAAW,KACzE,OAAO,OAAO,kBAAkB,YAAY,OAAO,cAAc,WAAW,GAC/E,MAAM,IAAI,kBAAkB,4BAA4B,SAAS,kBAAkB,WAAW;CAEhG,OAAO;AACT;;;;;;;;AC7mBA,SAAgB,wBACd,SACyB;CACzB,MAAM,mBAAmB,SAAS,QAAQ,eAAe;CACzD,MAAM,qBAAqB,SAAS,QAAQ,OAAO;CACnD,MAAM,WAAW,uBAAuB,UAAa,uBAAuB;CAC5E,OAAO,OAAO,OAAO,SAAS;EAE5B,MAAM,WAAW,OADM,QAAQ,SAAS,WAAW,MACd,CAAC,OAAO,IAAI;EAIjD,IAAI,OAAO,UAAU,UAAU,OAAO;EACtC,MAAM,eAAe;EACrB,IAAI,CAAC,YAAY,iBAAiB,sBAC7B,SAAS,WAAW,OAAO,SAAS,SAAS,QAC7C,SAAS,QAAQ,IAAI,cAAc,MAAM,QACzC,SAAS,cAAc,SAAS,SAAS,oBACxC,SAAS,IAAI,SAAS,KAAK,SAAS,QAAQ,cAAe,OAAO;EACxE,MAAM,UAAU,IAAI,QAAQ,SAAS,OAAO;EAC5C,QAAQ,IAAI,gBAAgB,mBAAmB;EAC/C,OAAO,IAAI,SAAS,SAAS,MAAM;GACjC,QAAQ,SAAS;GACjB,YAAY,SAAS;GACrB;EACF,CAAC;CACH;AACF;AAEA,SAAS,SAAS,OAAmC;CACnD,IAAI;EACF,MAAM,MAAM,IAAI,IAAI,KAAK;EACzB,IAAI,IAAI,OAAO,SAAS,KAAK,IAAI,KAAK,SAAS,GAAG,OAAO;EACzD,OAAO,GAAG,IAAI,KAAK,QAAQ,SAAS,EAAE,EAAE;CAC1C,QAAQ;EACN;CACF;AACF;;;;;ACmBA,MAAa,iBAAiB;;AAG9B,MAAa,mBAAmB;;;;;;;;AAShC,MAAa,uBAAuB;AAwFpC,SAAS,WAAmB;CAC1B,OAAO,WAAW,QAAQ,aAAa,KAAK,OAAO,KAAK,IAAI,CAAC,CAAC,SAAS,EAAE;AAC3E;;AAGA,eAAe,oBACb,SACA,eACA,QAMA,WAC0C;CAC1C,MAAM,MAAM,GAAG,QAAQ,QAAQ,yBAAyB,mBAAmB,aAAa;CACxF,MAAM,UAAU,YAAY,QAAQ,OAAO,SAAS;CACpD,MAAM,SAAS,QAAQ,WAAW,SAAY,UAAU,YAAY,IAAI,CAAC,QAAQ,QAAQ,OAAO,CAAC;CACjG,MAAM,WAAW,MAAM,UAAU,KAAK;EACpC,SAAS,QAAQ;EACjB;EACA,UAAU;CACZ,CAAC;CACD,MAAM,oBAAoB,UAAU,KAAK,iBAAiB,GAAM;CAChE,IAAI,CAAC,SAAS,IAAI,OAAO,CAAC;CAC1B,MAAM,OAAO,MAAM,gBAAgB,UAAU,OAAO,UAAU,OAAO,WAAW,MAAM;CACtF,MAAM,SAAS,MAAM,QAAQ,KAAK,MAAM,IAAI,KAAK,SAA+B,CAAC;CACjF,IAAI,OAAO,SAAS,OAAO,WACzB,MAAM,IAAI,WAAW,mCAAmC,OAAO,UAAU,aAAa;CAExF,OAAO,OAAO,SAAS,UAAU;EAC/B,IAAI,OAAO,MAAM,SAAS,YAAY,MAAM,KAAK,WAAW,GAAG,OAAO,CAAC;EACvE,MAAM,cAAc,MAAM,oBAAoB,CAAC,EAAC,CAC7C,QAAQ,UAAqC,UAAU,UAAU,UAAU,OAAO;EACrF,MAAM,oBAAoB,MAAM,qBAAqB,CAAC,EAAC,CACpD,QAAQ,UAAqC,UAAU,UAAU,UAAU,OAAO;EACrF,MAAM,WAAW,MAAM,8BAA8B,CAAC,EAAC,CAAE,SAAS,cAAc;GAC9E,IAAI,OAAO,UAAU,WAAW,YAAY,UAAU,OAAO,WAAW,GAAG,OAAO,CAAC;GACnF,OAAO,CAAC;IACN,IAAI,kBAAkB,UAAU,MAAM;IACtC,MAAM,UAAU;IAChB,GAAG,UAAU,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,UAAU,YAAY;GACrF,CAAC;EACH,CAAC;EACD,MAAM,gBAAgB,OAAO,MAAM,4BAA4B,YAC1D,QAAQ,MAAK,WAAU,OAAO,OAAO,MAAM,uBAAuB,IACnE,kBAAkB,MAAM,uBAAuB,IAC/C;EACJ,OAAO,CAAC;GACN,IAAI,MAAM;GACV,GAAG,MAAM,iBAAiB,SAAY,CAAC,IAAI,EAAE,MAAM,MAAM,aAAa;GACtE,GAAG,MAAM,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,MAAM,YAAY;GAC3E,GAAG,WAAW,SAAS,IAAI,EAAE,iBAAiB,WAAW,IAAI,CAAC;GAC9D,GAAG,iBAAiB,SAAS,IAAI,EAAE,iBAAiB,IAAI,CAAC;GACzD,GAAG,OAAO,MAAM,mBAAmB,YAAY,OAAO,cAAc,MAAM,cAAc,KAAK,MAAM,iBAAiB,IAChH,EAAE,eAAe,MAAM,eAAe,IACtC,CAAC;GACL,GAAG,QAAQ,WAAW,IAAI,CAAC,IAAI,EAC7B,WAAW;IACT;IACA,GAAG,kBAAkB,SAAY,CAAC,IAAI,EAAE,cAAc;GACxD,EACF;EACF,CAAC;CACH,CAAC;AACH;AASA,SAAgB,aACd,SACkB;CAClB,MAAM,WAAW,kBAAkB,SAAS,SAAS;CACrD,OAAO,SAAS,SAAS,cACrB,oBAAoB,SAA0C,QAAQ,IACtE,mBAAmB,SAAgC,QAAQ;AACjE;AAEA,SAAS,mBACP,SACA,WAAW,kBAAkB,SAAS,SAAS,GAC7B;CAClB,IAAI,SAAS,SAAS,UAAU,MAAM,IAAI,UAAU,uDAAuD;CAC3G,MAAM,QAAQ,SAAS;CACvB,MAAM,iBAAiB,QAAQ,kBAAkB,SAAS;CAC1D,MAAM,gBAAgB,QAAQ;CAC9B,MAAM,gBAAgB,OAAO,OAAO;EAClC,UAAU,oBAAoB,QAAQ,mBAAmB,SAAiB,iBAAiB;EAC3F,WAAW,oBAAoB,QAAQ,oBAAoB,MAAO,kBAAkB;EACpF,WAAW,oBAAoB,QAAQ,oBAAoB,KAAQ,kBAAkB;EACrF,WAAW,oBAAoB,QAAQ,oBAAoB,KAAQ,kBAAkB;CACvF,CAAC;;;;;;CAOD,MAAM,UAAqC;EACzC,UAAU;EACV,iBAAiB;EACjB,mBAAmB;EACnB,OAAO;EACP,cAAc;EACd;CACF;CAEA,OAAO,mBAAmB;EACxB,aAAa;EACb,UAAUG;EACV,SAAS,QAAQ;EACjB;;;;;;;;;EASA,MAAM;GACJ,MAAM;GACN,SAAS,OAAO,SAAS,YAAY;IACnC,MAAM,OAAO,MAAM,MAAM,KAAK;IAC9B,IAAI,SAAS,cAAc,MAAM,MAAM,QAAQ;IAC/C,IAAI,SAAS,UAAa,cAAc,IAAI,GAC1C,SAAS,MAAM,2BACb,SACA,SACA,WACA,YAAY,MAAM,mBAAmB,OAAO,QAAQ,SAAS,CAAC,CAAC,CACjE;IAEF,MAAM,YAAY,iBAAiB,MAAM;IACzC,OAAO;KACL,iBAAiB,UAAU,OAAO;KAClC,cAAc,QAAQ;KACtB,GAAG,cAAc,SAAY,CAAC,IAAI,EAAE,sBAAsB,UAAU;KACpE,GAAG,iBAAiB,MAAM,IAAI,EAAE,oBAAoB,OAAO,IAAI,CAAC;KAChE,cAAc;IAChB;GACF;EACF;EACA,GAAG,QAAQ,WAAW,SAClB,EAAE,iBAAiB,YAAY,oBAC/B,SACA,eACA,eACA,QAAQ,SAAS,WAAW,KAC9B,EAAE,IACA,EAAE,QAAQ,QAAQ,OAAO;EAC7B,kBAAkB,QAAQ,oBAAoB;EAC9C,sBAAsB,QAAQ,wBAAwB;EACtD,GAAG,QAAQ,wBAAwB,SAC/B,CAAC,IACD,EAAE,qBAAqB,QAAQ,oBAAoB;EACvD,GAAG,QAAQ,iBAAiB,SAAY,CAAC,IAAI,EAAE,cAAc,QAAQ,aAAa;EAClF,GAAG,QAAQ,sBAAsB,SAAY,CAAC,IAAI,EAAE,mBAAmB,QAAQ,kBAAkB;EACjG,GAAG,QAAQ,4BAA4B,SACnC,CAAC,IACD,EAAE,yBAAyB,QAAQ,wBAAwB;EAC/D,GAAG,gBAAgB,OAAO;EAC1B,GAAG,QAAQ,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,QAAQ,YAAY;EAC/E,GAAG,QAAQ,kBAAkB,SAAY,CAAC,IAAI,EAAE,eAAe,QAAQ,cAAc;CACvF,CAAC;AACH;AAEA,MAAM,cAAyB,OAAO,OAAO;CAC3C,aAAa;CACb,aAAa;CAAW,aAAa;CAAW,YAAY;CAC5D,YAAY;CAAW,aAAa;CAAW,aAAa;AAC9D,CAAC;AAED,SAAS,oBACP,SACA,WAAW,kBAAkB,QAAQ,SAAS,GAC5B;CAClB,IAAI,SAAS,SAAS,aACpB,MAAM,IAAI,UAAU,8DAA8D;CAEpF,MAAM,QAAQ,SAAS;CACvB,MAAM,iBAAiB,QAAQ,kBAAkB,SAAS;CAC1D,MAAM,gBAAgB,QAAQ;CAC9B,MAAM,gBAAgB,OAAO,OAAO;EAClC,UAAU,oBAAoB,QAAQ,mBAAmB,SAAiB,iBAAiB;EAC3F,WAAW,oBAAoB,QAAQ,oBAAoB,MAAO,kBAAkB;EACpF,WAAW,oBAAoB,QAAQ,oBAAoB,KAAQ,kBAAkB;EACrF,WAAW,oBAAoB,QAAQ,oBAAoB,KAAQ,kBAAkB;CACvF,CAAC;CACD,MAAM,UAAqC;EACzC,UAAU;EACV,iBAAiB;EACjB,mBAAmB;EACnB,OAAO;EACP,cAAc;EACd;CACF;CAEA,OAAO,0BAA0B;EAC/B,aAAa;EACb,UAAUA;EACV,SAAS,QAAQ;EACjB;EACA,MAAM;GACJ,MAAM;GACN,SAAS,OAAO,EAAE,UAAU,QAAQ,cAAc;IAChD,MAAM,YAAwC;KAC5C;KACA,QAAQ,SAAS,UAAU;IAC7B;IAEA,MAAM,QAAO,MADQ,MAAM,KAAK,SAAS,EACtB,EAAE;IACrB,IAAI,SAAS,cAAc,MAAM,MAAM,KAAK;IAC5C,IAAI,SAAS,UAAa,cAAc,IAAI,GAC1C,SAAS,MAAM,2BACb,SACA,UACA,WACA,YAAY,MAAM,gCAChB,OACA;KAAE,GAAI,QAAQ,SAAS,CAAC;KAAI;IAAO,GACnC,SACF,CACF;IAEF,MAAM,YAAY,iBAAiB,MAAM;IACzC,OAAO;KACL,eAAe,UAAU,OAAO;KAChC,YAAY,QAAQ;KACpB,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,sBAAsB,UAAU;KACrE,GAAI,iBAAiB,MAAM,IAAI,EAAE,oBAAoB,OAAO,IAAI,CAAC;KACjE,cAAc;IAChB;GACF;EACF;EACA,GAAI,QAAQ,WAAW,SACnB,EAAE,iBAAgB,YAAW,oBAC7B;GACE,SAAS,QAAQ,QAAQ,KAAK,QAAQ,QAAQ,EAAE;GAChD,SAAS,QAAQ;GACjB,QAAQ,QAAQ;GAChB,UAAU,QAAQ;GAClB,GAAI,QAAQ,YAAY,SAAY,CAAC,IAAI,EAAE,SAAS,QAAQ,QAAQ;EACtE,GACA,eACA,eACA,QAAQ,SAAS,WAAW,KAC9B,EAAE,IACA,EAAE,QAAQ,QAAQ,OAAO;EAC7B,GAAI,QAAQ,iBAAiB,SAAY,CAAC,IAAI,EAAE,cAAc,QAAQ,aAAa;EACnF,GAAI,QAAQ,sBAAsB,SAAY,CAAC,IAAI,EAAE,mBAAmB,QAAQ,kBAAkB;EAClG,GAAI,QAAQ,4BAA4B,SACpC,CAAC,IACD,EAAE,yBAAyB,QAAQ,wBAAwB;EAC/D,kBAAkB,QAAQ,oBAAoB;EAC9C,sBAAsB,QAAQ,wBAAwB;EACtD,GAAI,QAAQ,wBAAwB,SAAY,CAAC,IAAI,EAAE,qBAAqB,QAAQ,oBAAoB;EACxG,GAAG,gBAAgB,OAAO;EAC1B,GAAI,QAAQ,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,QAAQ,YAAY;EAChF,GAAI,QAAQ,kBAAkB,SAAY,CAAC,IAAI,EAAE,eAAe,QAAQ,cAAc;CACxF,CAAC;AACH;AAkBA,SAAgB,YACd,SACsF;CACtF,IAAI,sBAAsB,QAAQ,SAAS,GAAG;EAC5C,MAAM,KAAK,QAAQ,WAAW,QAAQ,OAAO,SAAY,QAAQ,KAAK;EACtE,MAAM,SAAS,OAAO,OAAO,CAAC,GAAG,QAAQ,UAAU,CAAC,EAAE,CAAC,CAAC;EACxD,OAAO,0BAA0B;GAC/B;GACA,QAAQ;GACR,aAAa;GACb;GACA,GAAG,oBACD,kBAAkB,UAAU,QAAQ,eAAe,QACnD,MACF;GACA,MAAM,WAAW;IACf,MAAM,UAAU,oBAAoB,OAA+B;IACnE,MAAM,SAAS,UAAU,gBAAgB,OAAO;IAChD,aAAa;KAAE,OAAO;IAAoB;GAC5C;EACF,CAAC;CACH;CACA,OAAO,kBAAkB,OAA6B;AACxD;;AAGA,SAAS,sBAAsB,OAAyB;CACtD,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CACxD,MAAM,OAAO,OAAO,yBAAyB,OAAO,MAAM;CAC1D,OAAO,SAAS,UAAa,WAAW,QAAQ,KAAK,UAAU;AACjE;AAEA,SAAS,kBACP,SACA,UACqB;CACrB,MAAM,SAAS,OAAO,OAAO,CAAC,GAAI,QAAQ,UAAU,CAAC,OAAO,CAAE,CAAC;CAC/D,MAAM,UAAU,mBAAmB,SAAS,QAAQ;CACpD,OAAO,OAAO,OAAO;EACnB,IAAI;EACJ,aAAa;EACb,MAAM,WAAmC;GACvC,UAAU,gBAAgB,QAAQ,OAAO;EAC3C;CACF,CAAC;AACH;AAEA,SAAS,oBACP,OACA,QACyC;CACzC,IAAI,UAAU,QAAW,OAAO,CAAC;CACjC,IAAI,OAAO,UAAU,UAAU,OAAO,EAAE,cAAc,MAAM;CAC5D,IAAI,OAAO,WAAW,GAAG,MAAM,IAAI,UAAU,wDAAwD;CACrG,OAAO,EAAE,cAAc,OAAO,OAAO;EAAE,UAAU,OAAO;EAAK,IAAI;CAAM,CAAC,EAAE;AAC5E;AAEA,eAAe,gBACb,UACA,UACA,WACA,QACkC;CAClC,MAAM,WAAW,OAAO,SAAS,QAAQ,IAAI,gBAAgB,CAAC;CAC9D,IAAI,OAAO,SAAS,QAAQ,KAAK,WAAW,UAAU;EACpD,IAAI,SAAS,SAAS,MAAM,MAAM,kBAAkB,SAAS,KAAK,OAAO,CAAC,CAAC,YAAY,MAAS,GAAG,GAAM;EACzG,MAAM,IAAI,WAAW,mCAAmC,SAAS,YAAY;CAC/E;CACA,IAAI,SAAS,SAAS,MAAM,MAAM,IAAI,UAAU,sCAAsC;CACtF,MAAM,SAAS,SAAS,KAAK,UAAU;CACvC,MAAM,SAAuB,CAAC;CAC9B,IAAI,QAAQ;CACZ,IAAI,aAAa;CACjB,IAAI;EACF,OAAO,MAAM;GACX,MAAM,OAAO,MAAM,UAAU,OAAO,KAAK,GAAG,MAAM;GAClD,IAAI,KAAK,MAAM;GACf,IAAI,KAAK,UAAU,QAAW;GAC9B;GACA,IAAI,aAAa,WAAW;IAC1B,MAAM,kBAAkB,OAAO,OAAO,CAAC,CAAC,YAAY,MAAS,GAAG,GAAM;IACtE,MAAM,IAAI,WAAW,mCAAmC,UAAU,aAAa;GACjF;GACA,SAAS,KAAK,MAAM;GACpB,IAAI,QAAQ,UAAU;IACpB,MAAM,kBAAkB,OAAO,OAAO,CAAC,CAAC,YAAY,MAAS,GAAG,GAAM;IACtE,MAAM,IAAI,WAAW,mCAAmC,SAAS,YAAY;GAC/E;GACA,OAAO,KAAK,KAAK,KAAK;EACxB;CACF,UAAU;EACR,OAAO,YAAY;CACrB;CACA,MAAM,SAAS,IAAI,WAAW,KAAK;CACnC,IAAI,SAAS;CACb,KAAK,MAAM,SAAS,QAAQ;EAAE,OAAO,IAAI,OAAO,MAAM;EAAG,UAAU,MAAM;CAAW;CACpF,MAAM,SAAkB,KAAK,MAAM,IAAI,YAAY,CAAC,CAAC,OAAO,MAAM,CAAC;CACnE,IAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAQ,MAAM,GACvE,MAAM,IAAI,UAAU,2CAA2C;CAEjE,OAAO;AACT;AAEA,SAAS,UAAa,SAAqB,QAAiC;CAC1E,IAAI,OAAO,SAAS,OAAO,QAAQ,OAAO,OAAO,0BAAU,IAAI,MAAM,+BAA+B,CAAC;CACrG,OAAO,IAAI,SAAY,SAAS,WAAW;EACzC,MAAM,cAAc;GAAE,QAAQ;GAAG,OAAO,OAAO,0BAAU,IAAI,MAAM,+BAA+B,CAAC;EAAE;EACrG,MAAM,gBAAgB,OAAO,oBAAoB,SAAS,KAAK;EAC/D,OAAO,iBAAiB,SAAS,OAAO,EAAE,MAAM,KAAK,CAAC;EACtD,AAAK,QAAQ,MACX,UAAS;GAAE,QAAQ;GAAG,QAAQ,KAAK;EAAE,IACrC,UAAS;GAAE,QAAQ;GAAG,OAAO,KAAK;EAAE,CACtC;CACF,CAAC;AACH;AAEA,SAAS,oBAAoB,OAAe,OAAuB;CACjE,IAAI,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,GAAG,MAAM,IAAI,WAAW,SAAS,MAAM,iCAAiC;CACpH,OAAO;AACT;AAEA,SAAS,gBAAgB,SAA8D;CACrF,MAAM,QAAQ,wBAAwB;EACpC,SAAS,QAAQ;EACjB,iBAAiB;EACjB,GAAI,QAAQ,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,QAAQ,MAAM;CAChE,CAAC;CACD,OAAO;EACL,GAAG,QAAQ,qBAAqB,SAAY,CAAC,IAAI,EAAE,kBAAkB,QAAQ,iBAAiB;EAC9F,GAAG,QAAQ,oBAAoB,SAAY,CAAC,IAAI,EAAE,iBAAiB,QAAQ,gBAAgB;EAC3F,GAAG,QAAQ,qBAAqB,SAAY,CAAC,IAAI,EAAE,kBAAkB,QAAQ,iBAAiB;EAC9F,GAAG,QAAQ,sBAAsB,SAAY,CAAC,IAAI,EAAE,mBAAmB,QAAQ,kBAAkB;EACjG,GAAG,QAAQ,iBAAiB,SAAY,CAAC,IAAI,EAAE,cAAc,QAAQ,aAAa;EAClF,GAAG,QAAQ,qBAAqB,SAAY,CAAC,IAAI,EAAE,kBAAkB,QAAQ,iBAAiB;EAC9F,GAAG,QAAQ,sBAAsB,SAAY,CAAC,IAAI,EAAE,mBAAmB,QAAQ,kBAAkB;EACjG,GAAG,QAAQ,2BAA2B,SAAY,CAAC,IAAI,EAAE,wBAAwB,QAAQ,uBAAuB;EAChH;CACF;AACF"}
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "@alvin0/ai-agent-sdk-provider-codex",
3
+ "author": {
4
+ "name": "alvin0 - chaulamdinhai",
5
+ "email": "chaulamdinhai@gmail.com"
6
+ },
7
+ "version": "0.1.0",
8
+ "description": "Universal Codex adapter, OAuth, injected auth contracts, and provider plugin for ai-agent-sdk",
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/alvin0/ai-agent-sdk.git",
13
+ "directory": "packages/provider-codex"
14
+ },
15
+ "homepage": "https://github.com/alvin0/ai-agent-sdk/tree/main/packages/provider-codex#readme",
16
+ "bugs": {
17
+ "url": "https://github.com/alvin0/ai-agent-sdk/issues"
18
+ },
19
+ "type": "module",
20
+ "sideEffects": false,
21
+ "files": [
22
+ "dist",
23
+ "README.md",
24
+ "LICENSE"
25
+ ],
26
+ "main": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "import": "./dist/index.js",
32
+ "default": "./dist/index.js"
33
+ },
34
+ "./package.json": "./package.json"
35
+ },
36
+ "publishConfig": {
37
+ "access": "public",
38
+ "provenance": true
39
+ },
40
+ "dependencies": {
41
+ "@alvin0/ai-agent-sdk-provider-http": "^0.1.0",
42
+ "@alvin0/ai-agent-sdk-protocol-responses": "^0.1.0"
43
+ },
44
+ "peerDependencies": {
45
+ "@alvin0/ai-agent-sdk-core": "^0.1.0"
46
+ },
47
+ "devDependencies": {
48
+ "@alvin0/ai-agent-sdk-core": "^0.1.0",
49
+ "@alvin0/ai-agent-sdk-testkit": "^0.1.0",
50
+ "@arethetypeswrong/cli": "0.18.5",
51
+ "playwright": "1.62.1",
52
+ "publint": "0.3.24",
53
+ "tsdown": "0.22.14",
54
+ "typescript": "7.0.2",
55
+ "vitest": "4.1.11",
56
+ "wrangler": "4.127.1"
57
+ },
58
+ "aiAgentSdk": {
59
+ "runtime": "universal",
60
+ "coreApi": 1,
61
+ "roles": [
62
+ "model-provider"
63
+ ]
64
+ },
65
+ "scripts": {
66
+ "build": "tsdown",
67
+ "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true});require('node:fs').rmSync('artifacts',{recursive:true,force:true})\"",
68
+ "typecheck": "tsc --noEmit",
69
+ "test": "vitest run --config vitest.config.ts",
70
+ "pack": "pnpm pack --pack-destination artifacts",
71
+ "test:pack": "node ../../scripts/test-packed-provider.mts provider-codex",
72
+ "check:publint": "publint",
73
+ "check:types": "attw --profile esm-only --pack ."
74
+ }
75
+ }