@juspay/neurolink
Version:
The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002
489 lines (488 loc) • 19.2 kB
TypeScript
/**
* Codex (OpenAI ChatGPT subscription) proxy types.
*
* Codex authenticates with a ChatGPT account over OAuth and talks to the
* ChatGPT backend Responses API (https://chatgpt.com/backend-api/codex).
* These types describe the on-disk `~/.codex/auth.json` shape we import from,
* the OAuth refresh contract, and the usage/rate-limit payloads we normalise
* into the shared AccountQuota model.
*
* Naming: all exported names carry the `Codex` prefix (rule 9). Codex quota is
* stored through the same AccountQuota shape as Anthropic — its primary window
* maps onto the session fields and its secondary window onto the weekly fields.
*/
import type { AccountCoolingReason, AccountQuota, ClaudeContentBlock, ClaudeTool, InternalResult } from "./proxy.js";
/** Token block inside `~/.codex/auth.json`. */
export type CodexAuthFileTokens = {
id_token?: string;
access_token: string;
refresh_token?: string;
account_id?: string;
};
/** Shape of `~/.codex/auth.json` written by the Codex CLI. */
export type CodexAuthFile = {
auth_mode?: string;
OPENAI_API_KEY?: string | null;
tokens?: CodexAuthFileTokens;
last_refresh?: string;
};
/** Result of importing a Codex credential (from auth.json or the OAuth flow). */
export type CodexImportedCredential = {
accessToken: string;
refreshToken?: string;
idToken?: string;
/** ChatGPT account id (from auth.json or decoded from the access token). */
accountId?: string;
/** Epoch ms when the access token expires (decoded from the JWT `exp`). */
expiresAt?: number;
/** ChatGPT plan type decoded from the token, for display only. */
planType?: string;
/** Account email decoded from the id token, for the account label. */
email?: string;
};
/** Raw OpenAI OAuth token endpoint response. */
export type CodexTokenResponse = {
access_token?: string;
refresh_token?: string;
id_token?: string;
token_type?: string;
expires_in?: number;
};
/** One rate-limit window as reported by the Codex backend (primary/secondary). */
export type CodexRateLimitWindow = {
used_percent?: number | null;
window_minutes?: number | null;
resets_in_seconds?: number | null;
/** Seconds until reset. Observed alias of `resets_in_seconds` on some
* responses; accepted defensively so a cooldown lands on the real reset
* instead of degrading to the transient ceiling. */
reset_after?: number | null;
resets_at?: number | null;
/** Current WHAM usage fields. */
reset_after_seconds?: number | null;
reset_at?: number | null;
};
/** Codex rate-limit block: a primary (short) and secondary (long) window. */
export type CodexRateLimits = {
allowed?: boolean;
limit_reached?: boolean;
primary?: CodexRateLimitWindow | null;
secondary?: CodexRateLimitWindow | null;
};
/** Loose shape of the Codex usage endpoint response. */
export type CodexUsageResponse = {
/** Legacy Codex usage payload. */
rate_limits?: CodexRateLimits | null;
/** Current ChatGPT WHAM account-usage payload. */
rate_limit?: {
allowed?: boolean;
limit_reached?: boolean;
primary_window?: CodexRateLimitWindow | null;
secondary_window?: CodexRateLimitWindow | null;
} | null;
plan_type?: string | null;
};
/** Result of a single Codex usage fetch. */
export type CodexUsageFetchResult = {
ok: true;
quota: AccountQuota;
} | {
ok: false;
reason: "not_oauth" | "auth" | "rate_limited" | "http" | "network" | "parse";
};
/** Explicit plan-exhaustion evidence from a Codex error response. */
export type CodexQuotaError = {
errorCode: string;
resetAt: number;
scope: "session" | "weekly" | "unknown";
};
/** A Codex account with its runtime cooldown/quota state hydrated from disk. */
export type CodexRuntimeAccount = {
key: string;
label: string;
token: string;
refreshToken?: string;
expiresAt?: number;
accountId?: string;
quota?: AccountQuota;
coolingUntil?: number;
coolingReason?: AccountCoolingReason;
/** A persisted cooldown whose window has already passed. Present only when the
* account is therefore eligible again, so the success path can delete the
* spent record — nothing else ever reaps it. */
expiredCooldownUntil?: number;
};
/** Provider-qualified account identity used by proxy status rendering. */
export type CodexProxyStatusAccountIdentity = {
provider: "anthropic";
key: string;
} | {
provider: "codex";
key: string;
} | {
provider: "vertex";
key: string;
} | {
provider: "other";
key: null;
};
/** A text or image content part accepted by the Codex Responses backend. */
export type CodexContentPart = {
type: "input_text";
text: string;
} | {
type: "output_text";
text: string;
} | {
type: "input_image";
image_url: string;
};
/** A single item in a Codex Responses request. */
export type CodexResponsesInputItem = {
role: "user" | "assistant";
content: CodexContentPart[];
} | {
type: "function_call";
call_id: string;
name: string;
arguments: string;
} | {
type: "function_call_output";
call_id: string;
output: string;
};
/** Codex reasoning settings; supported levels depend on the selected model. */
export type CodexReasoningEffort = "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
/** Request shape used to bridge Anthropic Messages traffic to Codex Responses. */
export type CodexResponsesRequest = {
model: string;
input: CodexResponsesInputItem[];
stream: true;
store: false;
/** Pins one conversation to the cache that already holds its prefix. */
prompt_cache_key?: string;
reasoning?: {
effort: CodexReasoningEffort;
};
instructions?: string;
tools?: Array<{
type: "function";
name: string;
description?: string;
parameters: Record<string, unknown>;
}>;
tool_choice?: "auto" | "required" | "none" | {
type: "function";
name: string;
};
};
/** Fully buffered Codex result rendered back as an Anthropic response. */
export type CodexFallbackResult = {
text: string;
toolCalls: NonNullable<InternalResult["toolCalls"]>;
usage?: NonNullable<InternalResult["usage"]> & {
/** Numeric serializer compatibility must not imply provider observation. */
inputTokensObserved?: boolean;
outputTokensObserved?: boolean;
cacheReadTokensObserved?: boolean;
cacheCreationTokensObserved?: boolean;
};
finishReason: "end_turn" | "tool_use";
};
/** Incremental Claude frames and explicit upstream cancellation. */
export type CodexFallbackStream = {
frames: AsyncGenerator<string, CodexFallbackResult>;
cancel: (reason?: unknown) => Promise<void>;
};
/** Role a native Codex `input` message item can carry. */
export type CodexNativeRole = "developer" | "user" | "assistant";
/** A plain message item in a native Codex request's `input` array. */
export type CodexNativeMessageInputItem = {
type: "message";
id?: string;
role: CodexNativeRole;
content: CodexContentPart[];
};
/** A tool declaration backed by a JSON Schema, dispatched as a function call. */
export type CodexNativeFunctionToolDeclaration = {
type: "function";
name: string;
description?: string;
strict: boolean;
parameters: Record<string, unknown>;
};
/** Grammar constraining a custom tool's argument text. */
export type CodexNativeCustomToolFormat = {
type: "grammar";
syntax: "lark" | "regex";
definition: string;
};
/** A tool declaration whose arguments are grammar-constrained free text. */
export type CodexNativeCustomToolDeclaration = {
type: "custom";
name: string;
description?: string;
format: CodexNativeCustomToolFormat;
};
/** A single tool declaration, discriminated by its own `type` field. */
export type CodexNativeToolDeclaration = CodexNativeFunctionToolDeclaration | CodexNativeCustomToolDeclaration;
/**
* A declared tool's own kind, independent of its namespace. Claude's
* `tool_use` block carries only `name` + `input`, with no such discriminator,
* so response serialization threads a name -> kind map (built while flattening
* `additional_tools` on the request side) to decide whether a tool_use's
* `input` is a real JSON-Schema-shaped object (`function`) or the single
* grammar-constrained string a custom tool was wrapped into (`custom`).
*/
export type CodexNativeToolKind = "function" | "custom";
/**
* One declared tool's mapping outcome inside `codexOutboundFallback.ts`:
* the translated Claude tool, its kind (for `toolKindByName`), and any
* degrade reasons collected while flattening its schema (fed to
* `recordCodexOutboundSchemaDegraded` in `proxyTracer.ts`).
*/
export type CodexOutboundToolMappingResult = {
tool: ClaudeTool;
kind: CodexNativeToolKind;
reasons: string[];
};
/** A named group of tool declarations inside one `additional_tools` item. */
export type CodexNativeToolNamespace = {
type: "namespace";
name: string;
description: string;
tools: CodexNativeToolDeclaration[];
};
/** The `input` item carrying every tool declaration for a native Codex request. */
export type CodexNativeAdditionalToolsInputItem = {
type: "additional_tools";
id?: string;
role: "developer";
tools: CodexNativeToolNamespace[];
};
/** A model-emitted tool call replayed in a native Codex request's history. */
export type CodexNativeFunctionCallInputItem = {
type: "function_call";
call_id: string;
name: string;
arguments: string;
};
/** A client-supplied tool result replayed in a native Codex request's history. */
export type CodexNativeFunctionCallOutputInputItem = {
type: "function_call_output";
call_id: string;
output: string;
};
/** A call to a grammar-constrained (`type:"custom"`) tool, replayed in history. */
export type CodexNativeCustomToolCallInputItem = {
type: "custom_tool_call";
id?: string;
call_id: string;
name: string;
input: string;
};
/** A client-supplied result for a `custom_tool_call`, replayed in history. */
export type CodexNativeCustomToolCallOutputInputItem = {
type: "custom_tool_call_output";
call_id: string;
output: string;
};
/**
* A reasoning item the client echoes back with `store:false`. Its content is
* opaque (`encrypted_content` is readable only by the OpenAI backend), so its
* shape is deliberately loose beyond the discriminator.
*/
export type CodexNativeReasoningInputItem = {
type: "reasoning";
id?: string;
encrypted_content?: string | null;
summary?: unknown[];
};
/** A single item in a native Codex request's `input` array. */
export type CodexNativeInputItem = CodexNativeMessageInputItem | CodexNativeAdditionalToolsInputItem | CodexNativeFunctionCallInputItem | CodexNativeFunctionCallOutputInputItem | CodexNativeCustomToolCallInputItem | CodexNativeCustomToolCallOutputInputItem | CodexNativeReasoningInputItem;
/** How a native Codex request constrains which tool the model may call. */
export type CodexNativeToolChoice = "auto" | "required" | "none" | {
type: "function";
name: string;
};
/**
* A native Codex Responses request, as sent by the real Codex CLI.
*
* No top-level `session_id`/`thread_id` — real traffic carries neither at
* top level, only inside `client_metadata`, which the existing
* `Record<string, unknown>` field already covers.
*/
export type CodexNativeRequest = {
model: string;
input: CodexNativeInputItem[];
stream: boolean;
store: boolean;
tool_choice?: CodexNativeToolChoice;
parallel_tool_calls?: boolean;
reasoning?: {
effort: CodexReasoningEffort;
context?: string;
};
include?: string[];
text?: {
verbosity?: string;
};
prompt_cache_key?: string;
client_metadata?: Record<string, unknown>;
};
/**
* A `parseCodexNativeRequest`/`translateCodexRequestToClaude` failure. Never thrown.
* `UNTRANSLATABLE_REQUEST` is a request Codex itself accepts but Anthropic would
* reject, as opposed to one that is invalid on the Codex wire.
* `REQUEST_TOO_LARGE` is a tool-call history over `streamLimits.ts`'s count or
* size ceiling; callers map it to HTTP 413 `request_too_large`.
*/
export type CodexTranslationError = {
code: "MALFORMED_REQUEST";
message: string;
} | {
code: "SUSPECTED_PARTIAL_HISTORY";
message: string;
} | {
code: "UNTRANSLATABLE_REQUEST";
message: string;
} | {
code: "REQUEST_TOO_LARGE";
message: string;
};
/** One coalesced run of same-role content while flattening a native Codex `input` array. */
export type CodexOutboundMessageGroup = {
role: "user" | "assistant";
blocks: ClaudeContentBlock[];
};
/** Lifecycle status of one item inside a Codex Responses `output[]` array. */
export type CodexResponseItemStatus = "in_progress" | "completed" | "incomplete";
/** Wire usage block inside a synthesized response.completed / non-stream response. */
export type CodexResponseUsage = {
input_tokens: number;
output_tokens: number;
total_tokens: number;
/** Omitted entirely when no cache field was observed on the Anthropic side. */
input_tokens_details?: {
cached_tokens?: number;
cache_write_tokens?: number;
/** The 1-hour-TTL share of `cache_write_tokens` (a subset, not additive);
* sourced from `ClaudeUsage.cacheCreation1hTokens`. Omitted when not observed. */
cache_write_1h_tokens?: number;
};
/** Always omitted — ClaudeUsage carries no reasoning-token count to source it from. */
output_tokens_details?: {
reasoning_tokens?: number;
};
};
/** One `output_text` content part inside a Codex `message` output item. */
export type CodexResponseOutputTextPart = {
type: "output_text";
text: string;
annotations: [];
};
/** A synthesized assistant-text item in a Codex `response.output[]` array. */
export type CodexResponseMessageItem = {
id: string;
type: "message";
role: "assistant";
status: CodexResponseItemStatus;
content: CodexResponseOutputTextPart[];
};
/** A synthesized tool-call item in a Codex `response.output[]` array. */
export type CodexResponseFunctionCallItem = {
id: string;
type: "function_call";
status: CodexResponseItemStatus;
call_id: string;
name: string;
/** Concatenation of raw partial_json fragments. Valid JSON when status is
* "completed"; may be a truncated, non-JSON fragment when status is
* "incomplete" (closed early by a mid-stream failure). */
arguments: string;
};
/**
* A synthesized call to a tool the request declared `custom` (grammar-
* constrained), in the item shape the real backend emits for one — the shape
* `codexUsage.ts` reads on the native route and a Codex CLI replays in its
* history. `input` is the bare grammar text, never JSON.
*/
export type CodexResponseCustomToolCallItem = {
id: string;
type: "custom_tool_call";
status: CodexResponseItemStatus;
call_id: string;
name: string;
/** Empty when status is "incomplete" and the wrapped input never parsed. */
input: string;
};
/** One item in a Codex `response.output[]` array, discriminated by `type`. */
export type CodexResponseItem = CodexResponseMessageItem | CodexResponseFunctionCallItem | CodexResponseCustomToolCallItem;
/** A complete Codex Responses envelope — the non-streaming body, and the shape
* carried inside a terminal `response.*` SSE event's `response` field. */
export type CodexResponseEnvelope = {
id: string;
object: "response";
created_at: number;
status: "completed" | "incomplete" | "failed";
model: string;
output: CodexResponseItem[];
usage?: CodexResponseUsage;
incomplete_details: {
reason: "max_output_tokens";
} | null;
error: {
code: string;
message: string;
} | null;
};
/** The Codex Responses SSE event-type vocabulary this codec emits. */
export type CodexResponseSSEEventType = "response.created" | "response.in_progress" | "response.output_item.added" | "response.content_part.added" | "response.output_text.delta" | "response.output_text.done" | "response.content_part.done" | "response.function_call_arguments.delta" | "response.function_call_arguments.done" | "response.custom_tool_call_input.delta" | "response.custom_tool_call_input.done" | "response.output_item.done" | "response.completed" | "response.incomplete" | "response.failed";
/** Incremental Codex-shape SSE frames and the terminal envelope they resolve to. */
export type CodexResponseStream = {
frames: AsyncGenerator<string, CodexResponseEnvelope>;
cancel: (reason?: unknown) => Promise<void>;
};
/** Which output item kind (if any) `CodexResponsesStreamSerializer` currently has open. */
export type CodexResponseOpenItemKind = "message" | "function_call" | "custom_tool_call" | null;
/** The four call sites in `codexProxyRoutes.ts`'s `dispatch()` that can trigger
* an outbound fallback attempt (stage-c-trigger.md §0's corrected line map). */
export type CodexOutboundFailureClass = "no_accounts" | "pool_exhausted" | "non_retryable_transport" | "loop_fallthrough";
/** What a single insertion point in `codexProxyRoutes.ts` observed. */
export type CodexOutboundFailureInput = {
failureClass: CodexOutboundFailureClass;
/** Present only for `non_retryable_transport`: the transport error code
* (e.g. `ECONNREFUSED`) that was NOT in the retryable allow-list. */
transportErrorCode?: string;
/** Present only for `loop_fallthrough`: the raw HTTP status the last
* exhausted account attempt ended on (`lastErrorStatus` at the account-loop
* call site). A 401/403 there is a Codex credential failure and stays
* eligible; any other 4xx except 429 rejects the request itself. */
lastStatus?: number;
/** Present only for `loop_fallthrough`: the error code the last exhausted
* account attempt reported, when it reported one. A code
* `classifyProxyFailureCode` marks non-retryable (content policy, invalid
* request) makes the failure ineligible whatever the status. */
lastErrorCode?: string;
};
/** `classifyCodexOutboundFailure`'s verdict: whether this failure is eligible
* to attempt an outbound fallback, and why (for tracing/logging only — the
* caller still applies its own config/loop-prevention/depth gates). */
export type CodexOutboundFallbackDecision = {
eligible: boolean;
reason: string;
};
/** Outcome of one `attemptCodexOutboundFallback` call. `not_attempted` covers
* every gate failure and every target exhausting without success — the
* caller falls through to its own existing (unchanged) error response in
* every one of those cases, so the flag-off / all-targets-failed paths stay
* byte-identical to today. */
export type CodexOutboundFallbackOutcome = {
kind: "not_attempted";
} | {
kind: "request_too_large";
message: string;
} | {
kind: "success";
response: Response;
};