UNPKG

@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

51 lines (50 loc) • 2.15 kB
/** * Relocate a non-Claude-Code client's `system` blocks into the message stream. * * Anthropic's subscription/OAuth path rejects any `system` content it does not * recognise as the genuine Claude Code system prompt — anti-abuse fingerprinting * surfaced as a header-less `rate_limit_error: "Error"` (NOT a real rate limit). * Custom clients (Curator/Tara) send their own system prompt, so we move it into * a leading user block and keep only the recognised billing+agent blocks in * `system`. The model still honours the instructions, and any `cache_control` is * carried over so the prompt prefix stays cacheable. * * Shared by both proxy entry points (`oauthFetch.ts` and `claudeProxyRoutes.ts`) * so the OAuth anti-abuse workaround stays in one place and can't drift between * the two paths. */ export function relocateClientSystemIntoMessages(parsed, instructionBlocks) { if (instructionBlocks.length === 0) { return; } const blocks = instructionBlocks.map((b) => { const text = typeof b.text === "string" ? b.text : String(b.text ?? ""); const out = { type: "text", text, }; if (b.cache_control) { out.cache_control = b.cache_control; } return out; }); // Wrap the relocated system in an explicit delimiter so the model treats it // as authoritative instructions, clearly separated from the user's message. blocks[0].text = `<system_instructions>\n${blocks[0].text}`; const last = blocks.length - 1; blocks[last].text = `${blocks[last].text}\n</system_instructions>`; const messages = Array.isArray(parsed.messages) ? parsed.messages : []; const first = messages[0]; if (first && first.role === "user") { const existing = typeof first.content === "string" ? [{ type: "text", text: first.content }] : Array.isArray(first.content) ? first.content : []; first.content = [...blocks, ...existing]; } else { messages.unshift({ role: "user", content: blocks }); } parsed.messages = messages; }