@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
53 lines (52 loc) • 3.18 kB
TypeScript
import type { ClaudeMessage, ClaudeTextBlock, CodexAnthropicAffinityKey, CodexNativeRequest } from "../types/index.js";
/**
* Thrown by `assertClaudeSystemPrefixShape` and `assertClaudeMessagesAlternate`
* when the translated request does not have the shape breakpoint placement
* (or Anthropic's role-alternation requirement) depends on. Never logged and
* swallowed — a silent violation here defeats caching with no visible
* symptom besides a slow-moving cache-hit-rate metric, or turns into an
* undifferentiated Anthropic 400.
*/
export declare class ClaudeSystemPrefixShapeError extends Error {
}
/**
* Enforces that `system` is exactly the stable developer-block prefix before
* a caller marks breakpoint 1 on its last element. `translateCodexRequestToClaude`
* is contracted to produce `system` containing only the developer-role-derived
* blocks and nothing else — `environment_context` and any other per-turn
* payload belong in `messages`. `system[system.length-1]` is only a safe
* breakpoint-1 anchor while that invariant holds; trusting it silently would
* be exactly the failure this guards against.
*/
export declare function assertClaudeSystemPrefixShape(system: ClaudeTextBlock[] | string | undefined, expectedLength: number): void;
/**
* Throws, naming the offending index, when `messages` is not alternation-safe.
*
* Anthropic requires alternating `user`/`assistant` roles. A native Codex
* request can carry two consecutive `user`-role items (an auto-injected
* notice immediately followed by the literal user turn, or a synthetic
* `environment_context` pair) — mapped 1:1 into `ClaudeMessage` entries that
* would otherwise reach Anthropic as back-to-back `user` messages and get
* rejected on every request that hits it. Merging same-role Codex items into
* one Claude message with multiple content blocks is translation-correctness
* work owned by `translateCodexRequestToClaude`, not this guard's job — this
* only turns a missed merge into an attributable thrown error at the new
* hop's boundary instead of an undifferentiated Anthropic 400.
*/
export declare function assertClaudeMessagesAlternate(messages: ReadonlyArray<ClaudeMessage>): void;
/**
* Derives the session-affinity key a Codex-origin request supplies to the
* Claude pipeline's existing session-affinity machinery, so consecutive
* turns of one conversation route back to the account already holding their
* cache. Preference order mirrors what a real Codex CLI capture carries:
* `prompt_cache_key` (top-level, the client's own pre-computed key — already
* exactly the signal being reconstructed) beats `client_metadata.thread_id`
* beats `client_metadata.session_id`; a genuinely identity-free request
* degrades to a prefix-derived key so at least concurrent turns of the same
* agent config bucket together.
*
* The three-way prefix (`codex-thread:` / `codex-session:` / `codex-prefix:`)
* keeps this namespace from colliding with a Claude-Code `metadata.user_id`-
* derived UUID or with itself across cases.
*/
export declare function codexAnthropicAffinityKey(native: CodexNativeRequest): CodexAnthropicAffinityKey | undefined;