@juspay/neurolink 12.34.3 → 12.35.1

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,283 @@
1
+ /**
2
+ * Wire-neutral intermediate representation for proxy protocol translation.
3
+ *
4
+ * Translation between provider wire formats was previously pairwise and ad hoc:
5
+ * `codexFallback.ts` converts an Anthropic request into a Codex one and casts a
6
+ * role to reach Claude Code's inline-system convention inside a converter that is
7
+ * meant to be neutral. Adding the reverse direction pairwise would double that,
8
+ * and a third provider would square it.
9
+ *
10
+ * So each format gets a codec to and from this IR, and adding a provider is a new
11
+ * codec rather than new branching. The IR is deliberately not `ClaudeRequest`:
12
+ * that type is simultaneously the literal Anthropic wire shape, so using it as
13
+ * the hub makes every other provider's quirks leak into the Anthropic hot path.
14
+ * `ClaudeRequest` and `ClaudeResponse` stay untouched.
15
+ *
16
+ * Every union here is discriminated on a literal `kind`, `status` or `source`, so
17
+ * `assertProxyIRExhaustive` turns an unhandled variant into a compile error. That
18
+ * is the point of the IR: a field that cannot be represented must be stated, via
19
+ * `ProxyIRUnmappedPart`, rather than dropped silently.
20
+ */
21
+ import type { CodexReasoningEffort } from "./codex.js";
22
+ import type { UsageContext } from "./proxy.js";
23
+ /**
24
+ * A wire dialect a codec can speak.
25
+ *
26
+ * Distinct from `ProxyFormat` ("claude" | "openai" | "gemini"), which selects a
27
+ * request-translation surface for a different subsystem. These must not be
28
+ * conflated: this one names the two dialects the fallback codecs translate.
29
+ */
30
+ export type ProxyIRWireFormat = "anthropic-messages" | "codex-responses";
31
+ /**
32
+ * Message roles across both dialects.
33
+ *
34
+ * `developer` has no Anthropic equivalent and is native Codex's own role for
35
+ * instruction blocks that sit inside the ordered input array rather than in a
36
+ * leading system field. It is kept distinct from `system` so a codec targeting
37
+ * Anthropic can decide where it belongs instead of inheriting a lossy merge.
38
+ */
39
+ export type ProxyIRRole = "system" | "developer" | "user" | "assistant";
40
+ /**
41
+ * A request to cache the prefix up to and including the annotated element.
42
+ *
43
+ * Only meaningful for Anthropic, whose caching is explicit and breakpoint-driven.
44
+ * A codec targeting a dialect with automatic caching ignores it, which is correct
45
+ * rather than lossy: nothing on that wire can carry it.
46
+ */
47
+ export type ProxyIRCacheHint = {
48
+ ttl?: "5m" | "1h";
49
+ };
50
+ export type ProxyIRTextPart = {
51
+ kind: "text";
52
+ text: string;
53
+ cacheHint?: ProxyIRCacheHint;
54
+ };
55
+ /** `signature` is reserved for Anthropic's signed thinking blocks and unused today. */
56
+ export type ProxyIRThinkingPart = {
57
+ kind: "thinking";
58
+ text: string;
59
+ signature?: string;
60
+ };
61
+ export type ProxyIRImagePart = {
62
+ kind: "image";
63
+ encoding: "base64" | "url";
64
+ mediaType?: string;
65
+ data: string;
66
+ };
67
+ /**
68
+ * A model-emitted call to a tool.
69
+ *
70
+ * `argumentsRaw` is authoritative and always present; `argumentsJson` is a
71
+ * convenience for the common case where the raw text parses. Keeping the raw text
72
+ * means a call whose arguments are streamed in fragments, or are not valid JSON,
73
+ * survives translation instead of being normalised into something the next hop
74
+ * never sent.
75
+ */
76
+ export type ProxyIRToolCallPart = {
77
+ kind: "tool_call";
78
+ callId: string;
79
+ toolName: string;
80
+ argumentsRaw: string;
81
+ argumentsJson?: Record<string, unknown>;
82
+ };
83
+ export type ProxyIRToolResultPart = {
84
+ kind: "tool_result";
85
+ callId: string;
86
+ content: (ProxyIRTextPart | ProxyIRImagePart)[];
87
+ isError?: boolean;
88
+ cacheHint?: ProxyIRCacheHint;
89
+ };
90
+ /**
91
+ * A wire element no codec could represent, carried forward verbatim.
92
+ *
93
+ * The alternative is dropping it, which is how a translation layer loses tool
94
+ * calls: silently, and only visibly as a downstream rejection. `raw` keeps the
95
+ * original so a renderer can pass it through or a test can assert on it, and
96
+ * `reason` records why it could not be mapped.
97
+ */
98
+ export type ProxyIRUnmappedPart = {
99
+ kind: "unmapped";
100
+ sourceKind: string;
101
+ reason: string;
102
+ raw: unknown;
103
+ };
104
+ export type ProxyIRContentPart = ProxyIRTextPart | ProxyIRThinkingPart | ProxyIRImagePart | ProxyIRToolCallPart | ProxyIRToolResultPart | ProxyIRUnmappedPart;
105
+ /**
106
+ * One message, with system and developer messages kept in sequence.
107
+ *
108
+ * There is no separate bucket for leading instructions: native Codex sends
109
+ * instruction blocks as ordered `developer` items inside the input array, and
110
+ * lifting them out would lose their position relative to the conversation. A
111
+ * codec that needs a leading system field extracts it; the IR does not presume
112
+ * one exists.
113
+ */
114
+ export type ProxyIRMessage = {
115
+ role: ProxyIRRole;
116
+ content: ProxyIRContentPart[];
117
+ };
118
+ export type ProxyIRFunctionToolDeclaration = {
119
+ kind: "function";
120
+ name: string;
121
+ description?: string;
122
+ parametersSchema: Record<string, unknown>;
123
+ cacheHint?: ProxyIRCacheHint;
124
+ };
125
+ /** A tool constrained by a grammar rather than a JSON schema; Codex-only today. */
126
+ export type ProxyIRCustomGrammarToolDeclaration = {
127
+ kind: "custom_grammar";
128
+ name: string;
129
+ description?: string;
130
+ grammar: string;
131
+ };
132
+ export type ProxyIRToolDeclaration = ProxyIRFunctionToolDeclaration | ProxyIRCustomGrammarToolDeclaration;
133
+ export type ProxyIRToolChoice = {
134
+ kind: "auto";
135
+ } | {
136
+ kind: "none";
137
+ } | {
138
+ kind: "any";
139
+ } | {
140
+ kind: "named";
141
+ toolName: string;
142
+ };
143
+ /**
144
+ * Reasoning configuration, tagged by the dialect that expressed it.
145
+ *
146
+ * Anthropic budgets thinking in tokens; Codex selects a named effort level. There
147
+ * is no faithful numeric mapping between them, so the source is recorded and each
148
+ * codec decides how to honour the other's form rather than a lossy conversion
149
+ * happening once, invisibly, in the middle.
150
+ */
151
+ export type ProxyIRReasoning = {
152
+ source: "none";
153
+ } | {
154
+ source: "anthropic_thinking";
155
+ type: string;
156
+ budgetTokens?: number;
157
+ } | {
158
+ source: "codex_effort";
159
+ effort: CodexReasoningEffort;
160
+ };
161
+ export type ProxyIRRequest = {
162
+ sourceFormat: ProxyIRWireFormat;
163
+ sourceModel: string;
164
+ originSessionId?: string;
165
+ originThreadId?: string;
166
+ messages: ProxyIRMessage[];
167
+ tools: ProxyIRToolDeclaration[];
168
+ toolChoice?: ProxyIRToolChoice;
169
+ reasoning: ProxyIRReasoning;
170
+ stream: boolean;
171
+ /** Prefix-derived routing hint. Never serialized onto any wire. */
172
+ promptCachePrefixKey?: string;
173
+ };
174
+ export type ProxyIRRequestTargetOptions = {
175
+ model: string;
176
+ reasoningEffort?: CodexReasoningEffort;
177
+ };
178
+ export type ProxyIRProviderError = {
179
+ code: string;
180
+ httpStatus?: number;
181
+ retryable?: boolean;
182
+ message?: string;
183
+ };
184
+ /**
185
+ * How a response ended.
186
+ *
187
+ * `finishReason: "other"` carries `rawFinishReason` because Anthropic's
188
+ * `stop_reason` is typed `string | null` on the wire, deliberately open. A closed
189
+ * union here would make any legitimate but unmodelled stop reason an
190
+ * exhaustiveness throw at runtime, turning a successful upstream response into a
191
+ * proxy failure.
192
+ */
193
+ export type ProxyIRTerminalOutcome = {
194
+ status: "completed";
195
+ finishReason: "end_turn" | "tool_use" | "max_tokens" | "stop_sequence";
196
+ } | {
197
+ status: "completed";
198
+ finishReason: "other";
199
+ rawFinishReason: string;
200
+ } | {
201
+ status: "failed";
202
+ error: ProxyIRProviderError;
203
+ } | {
204
+ status: "incomplete";
205
+ reason: string;
206
+ };
207
+ export type ProxyIRResponseEvent = {
208
+ kind: "text_delta";
209
+ text: string;
210
+ } | {
211
+ kind: "thinking_delta";
212
+ text: string;
213
+ } | {
214
+ kind: "tool_call_start";
215
+ callId: string;
216
+ toolName: string;
217
+ } | {
218
+ kind: "tool_call_arguments_delta";
219
+ callId: string;
220
+ partialArguments: string;
221
+ } | {
222
+ kind: "tool_call_done";
223
+ callId: string;
224
+ } | {
225
+ kind: "item_done";
226
+ } | {
227
+ kind: "usage";
228
+ usage: UsageContext;
229
+ } | {
230
+ kind: "terminal";
231
+ outcome: ProxyIRTerminalOutcome;
232
+ };
233
+ export type ProxyIROutputItem = {
234
+ kind: "text";
235
+ text: string;
236
+ } | {
237
+ kind: "thinking";
238
+ text: string;
239
+ } | {
240
+ kind: "tool_call";
241
+ callId: string;
242
+ toolName: string;
243
+ argumentsRaw: string;
244
+ argumentsJson?: Record<string, unknown>;
245
+ };
246
+ export type ProxyIRResponse = {
247
+ items: ProxyIROutputItem[];
248
+ usage?: UsageContext;
249
+ outcome: ProxyIRTerminalOutcome;
250
+ };
251
+ /**
252
+ * Codec capabilities, kept separate rather than bundled into one interface.
253
+ *
254
+ * No dialect needs all four in every direction: for outbound Codex fallback, the
255
+ * Codex side is only ever parsed from and rendered to, never dispatched to, so a
256
+ * single monolithic codec type would force stub implementations whose only
257
+ * possible body is a throw.
258
+ */
259
+ export type ProxyIRRequestParser<TWireRequest> = {
260
+ format: ProxyIRWireFormat;
261
+ parseRequest(wire: TWireRequest): ProxyIRRequest;
262
+ };
263
+ export type ProxyIRRequestBuilder<TWireRequest> = {
264
+ format: ProxyIRWireFormat;
265
+ buildRequest(ir: ProxyIRRequest, target: ProxyIRRequestTargetOptions): TWireRequest;
266
+ };
267
+ export type ProxyIRResponseParser = {
268
+ format: ProxyIRWireFormat;
269
+ parseBufferedResponse(wireText: string): ProxyIRResponse;
270
+ parseResponseStream(upstream: Response): AsyncGenerator<ProxyIRResponseEvent, ProxyIRResponse>;
271
+ };
272
+ export type ProxyIRResponseRenderer = {
273
+ format: ProxyIRWireFormat;
274
+ renderResponseEvent(event: ProxyIRResponseEvent): string[];
275
+ renderTerminalOutcome(outcome: ProxyIRTerminalOutcome, usage?: UsageContext): string[];
276
+ };
277
+ /** Marks a value a codec refused to map, for callers that collect rather than throw. */
278
+ export type ProxyIRUnmappableValue = {
279
+ proxyIRUnmappable: true;
280
+ sourceKind: string;
281
+ reason: string;
282
+ raw: unknown;
283
+ };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Wire-neutral intermediate representation for proxy protocol translation.
3
+ *
4
+ * Translation between provider wire formats was previously pairwise and ad hoc:
5
+ * `codexFallback.ts` converts an Anthropic request into a Codex one and casts a
6
+ * role to reach Claude Code's inline-system convention inside a converter that is
7
+ * meant to be neutral. Adding the reverse direction pairwise would double that,
8
+ * and a third provider would square it.
9
+ *
10
+ * So each format gets a codec to and from this IR, and adding a provider is a new
11
+ * codec rather than new branching. The IR is deliberately not `ClaudeRequest`:
12
+ * that type is simultaneously the literal Anthropic wire shape, so using it as
13
+ * the hub makes every other provider's quirks leak into the Anthropic hot path.
14
+ * `ClaudeRequest` and `ClaudeResponse` stay untouched.
15
+ *
16
+ * Every union here is discriminated on a literal `kind`, `status` or `source`, so
17
+ * `assertProxyIRExhaustive` turns an unhandled variant into a compile error. That
18
+ * is the point of the IR: a field that cannot be represented must be stated, via
19
+ * `ProxyIRUnmappedPart`, rather than dropped silently.
20
+ */
21
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "12.34.3",
3
+ "version": "12.35.1",
4
4
  "packageManager": "pnpm@10.15.1",
5
5
  "description": "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/call) for routing, tool selection and context budgeting. MCP-native (4 transports), voice TTS/STT/realtime, RAG, agents, memory, compaction, 9 observability exporters. OpenAI · Anthropic · Gemini · Bedrock · Azure · Ollama · TypeSafe Jev and more.",
6
6
  "author": {