@aliou/pi-neuralwatt 0.16.1 → 0.16.3
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.
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { StreamOptions } from "@earendil-works/pi-ai";
|
|
1
2
|
import { stream, streamSimple } from "@earendil-works/pi-ai/compat";
|
|
2
3
|
import {
|
|
3
4
|
NEURALWATT_BASE_URL,
|
|
@@ -8,9 +9,56 @@ import type { NeuralwattModel } from "../models/catalog";
|
|
|
8
9
|
import type { AnyStreamSimple } from "../stream-simple";
|
|
9
10
|
import type { NeuralwattApiHandler } from "./types";
|
|
10
11
|
|
|
12
|
+
type OpenAiCompletionsBody = {
|
|
13
|
+
messages?: Array<Record<string, unknown>>;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Neuralwatt streams chain-of-thought in the `reasoning` field, and pi-ai
|
|
19
|
+
* replays prior thinking under the field name it recorded from the stream —
|
|
20
|
+
* also `reasoning`. The served chat templates only render `reasoning_content`
|
|
21
|
+
* (verified against the Kimi K3 template), so replayed thinking never reaches
|
|
22
|
+
* the model. Rename the replayed field on the wire. This is a move, not a
|
|
23
|
+
* copy: sending an empty `reasoning_content` next to a populated `reasoning`
|
|
24
|
+
* makes the gateway prefer the empty field and silently drops the replay.
|
|
25
|
+
*/
|
|
26
|
+
function makeReasoningReplayInjector(
|
|
27
|
+
upstream?: StreamOptions["onPayload"],
|
|
28
|
+
): NonNullable<StreamOptions["onPayload"]> {
|
|
29
|
+
return async (payload, model) => {
|
|
30
|
+
const next = await upstream?.(payload, model);
|
|
31
|
+
const body = (next !== undefined ? next : payload) as OpenAiCompletionsBody;
|
|
32
|
+
const messages = body.messages;
|
|
33
|
+
if (!Array.isArray(messages)) return body;
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
...body,
|
|
37
|
+
messages: messages.map((message) => {
|
|
38
|
+
if (message?.role !== "assistant" || !("reasoning" in message)) {
|
|
39
|
+
return message;
|
|
40
|
+
}
|
|
41
|
+
const { reasoning, ...rest } = message;
|
|
42
|
+
// A pre-set non-empty reasoning_content wins; drop the duplicate.
|
|
43
|
+
return typeof rest.reasoning_content === "string" &&
|
|
44
|
+
rest.reasoning_content.length > 0
|
|
45
|
+
? rest
|
|
46
|
+
: { ...rest, reasoning_content: reasoning };
|
|
47
|
+
}),
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
11
52
|
export function createOpenAiCompletionsApi(options?: {
|
|
12
53
|
streamSimple?: AnyStreamSimple;
|
|
13
54
|
}): NeuralwattApiHandler {
|
|
55
|
+
const withReasoningReplay = (options?: {
|
|
56
|
+
onPayload?: StreamOptions["onPayload"];
|
|
57
|
+
}) => ({
|
|
58
|
+
...options,
|
|
59
|
+
onPayload: makeReasoningReplayInjector(options?.onPayload),
|
|
60
|
+
});
|
|
61
|
+
|
|
14
62
|
return {
|
|
15
63
|
stampModels: (models: NeuralwattModel[]) =>
|
|
16
64
|
models.map((model) => {
|
|
@@ -24,7 +72,12 @@ export function createOpenAiCompletionsApi(options?: {
|
|
|
24
72
|
};
|
|
25
73
|
}),
|
|
26
74
|
stream: (model, context, streamOptions) =>
|
|
27
|
-
stream(model, context, streamOptions as never),
|
|
28
|
-
streamSimple:
|
|
75
|
+
stream(model, context, withReasoningReplay(streamOptions) as never),
|
|
76
|
+
streamSimple: (model, context, simpleOptions) =>
|
|
77
|
+
(options?.streamSimple ?? streamSimple)(
|
|
78
|
+
model,
|
|
79
|
+
context,
|
|
80
|
+
withReasoningReplay(simpleOptions) as never,
|
|
81
|
+
),
|
|
29
82
|
};
|
|
30
83
|
}
|
|
@@ -116,6 +116,62 @@ const KIMI_K2_7_CODE: NeuralwattModelFamily = {
|
|
|
116
116
|
},
|
|
117
117
|
};
|
|
118
118
|
|
|
119
|
+
// Xiaomi. MiMo-V2.6-Pro only has two reasoning behaviors: `high` (default)
|
|
120
|
+
// and `none`; the API aliases every other effort onto those, with `minimal`
|
|
121
|
+
// landing on `none`.
|
|
122
|
+
const MIMO_V2_6_PRO: NeuralwattModelFamily = {
|
|
123
|
+
cost: { input: 0.87, output: 1.74, cacheRead: 0.036 },
|
|
124
|
+
vision: true,
|
|
125
|
+
reasoningMetadata: {
|
|
126
|
+
supported_efforts: ["high", "none"],
|
|
127
|
+
mandatory: false,
|
|
128
|
+
effort_aliases: {
|
|
129
|
+
max: "high",
|
|
130
|
+
xhigh: "high",
|
|
131
|
+
medium: "high",
|
|
132
|
+
low: "high",
|
|
133
|
+
minimal: "none",
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// Neuralwatt tracking alias: the current large model, today Kimi K3. The
|
|
139
|
+
// alias moves to newer models over time, so it snapshots K3's contract
|
|
140
|
+
// instead of sharing the KIMI_K3 family.
|
|
141
|
+
const NW_LARGE: NeuralwattModelFamily = {
|
|
142
|
+
cost: { input: 3, output: 15, cacheRead: 0.3 },
|
|
143
|
+
vision: true,
|
|
144
|
+
reasoningMetadata: {
|
|
145
|
+
supported_efforts: ["max", "high", "low", "none"],
|
|
146
|
+
mandatory: false,
|
|
147
|
+
effort_aliases: { xhigh: "max", medium: "high", minimal: "low" },
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// Neuralwatt tracking alias: the current cheap, fast model, today DeepSeek
|
|
152
|
+
// V4.1 Flash. Same moving-alias caveat as NW_LARGE.
|
|
153
|
+
const NW_FLASH: NeuralwattModelFamily = {
|
|
154
|
+
cost: { input: 0.15, output: 0.6, cacheRead: 0.015 },
|
|
155
|
+
vision: true,
|
|
156
|
+
reasoningMetadata: {
|
|
157
|
+
supported_efforts: ["max", "xhigh", "high", "low", "none"],
|
|
158
|
+
mandatory: false,
|
|
159
|
+
effort_aliases: { medium: "high", minimal: "low" },
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// Neuralwatt tracking alias: the current small model, today Qwen3.8-27B.
|
|
164
|
+
// Same moving-alias caveat as NW_LARGE.
|
|
165
|
+
const NW_SMALL: NeuralwattModelFamily = {
|
|
166
|
+
cost: { input: 0.45, output: 3.2, cacheRead: 0.25 },
|
|
167
|
+
vision: true,
|
|
168
|
+
reasoningMetadata: {
|
|
169
|
+
supported_efforts: ["xhigh", "medium", "low", "none"],
|
|
170
|
+
mandatory: false,
|
|
171
|
+
effort_aliases: { max: "xhigh", high: "xhigh", minimal: "low" },
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
|
|
119
175
|
// Qwen. Qwen3.6 35B only advertises `high` and `none`.
|
|
120
176
|
const QWEN_3_6_35B: NeuralwattModelFamily = {
|
|
121
177
|
cost: { input: 0.29, output: 1.15, cacheRead: 0.029 },
|
|
@@ -192,6 +248,13 @@ const FAMILIES: [NeuralwattModelFamily, NeuralwattVariantSpec[]][] = [
|
|
|
192
248
|
reasoning: true,
|
|
193
249
|
costMultiplier: 0.65,
|
|
194
250
|
},
|
|
251
|
+
{
|
|
252
|
+
id: "deepseek-v4.1-flash-speed",
|
|
253
|
+
name: "DeepSeek V4.1 Flash (Speed)",
|
|
254
|
+
contextWindow: 1048560,
|
|
255
|
+
maxOutputTokens: 393216,
|
|
256
|
+
reasoning: true,
|
|
257
|
+
},
|
|
195
258
|
],
|
|
196
259
|
],
|
|
197
260
|
[
|
|
@@ -302,27 +365,99 @@ const FAMILIES: [NeuralwattModelFamily, NeuralwattVariantSpec[]][] = [
|
|
|
302
365
|
},
|
|
303
366
|
],
|
|
304
367
|
],
|
|
368
|
+
[
|
|
369
|
+
MIMO_V2_6_PRO,
|
|
370
|
+
[
|
|
371
|
+
{
|
|
372
|
+
id: "mimo-v2.6-pro",
|
|
373
|
+
name: "MiMo-V2.6-Pro",
|
|
374
|
+
contextWindow: 1048560,
|
|
375
|
+
maxOutputTokens: 393216,
|
|
376
|
+
reasoning: true,
|
|
377
|
+
},
|
|
378
|
+
],
|
|
379
|
+
],
|
|
380
|
+
[
|
|
381
|
+
NW_LARGE,
|
|
382
|
+
[
|
|
383
|
+
{
|
|
384
|
+
id: "nw-large",
|
|
385
|
+
name: "Neuralwatt Large",
|
|
386
|
+
contextWindow: 1048560,
|
|
387
|
+
maxOutputTokens: null,
|
|
388
|
+
reasoning: true,
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
id: "nw-large-flex",
|
|
392
|
+
name: "Neuralwatt Large (flex)",
|
|
393
|
+
contextWindow: 1048560,
|
|
394
|
+
maxOutputTokens: null,
|
|
395
|
+
reasoning: true,
|
|
396
|
+
costMultiplier: 0.65,
|
|
397
|
+
},
|
|
398
|
+
],
|
|
399
|
+
],
|
|
400
|
+
[
|
|
401
|
+
NW_FLASH,
|
|
402
|
+
[
|
|
403
|
+
{
|
|
404
|
+
id: "nw-flash",
|
|
405
|
+
name: "Neuralwatt Flash",
|
|
406
|
+
contextWindow: 1048560,
|
|
407
|
+
maxOutputTokens: 393216,
|
|
408
|
+
reasoning: true,
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
id: "nw-flash-flex",
|
|
412
|
+
name: "Neuralwatt Flash (flex)",
|
|
413
|
+
contextWindow: 1048560,
|
|
414
|
+
maxOutputTokens: 393216,
|
|
415
|
+
reasoning: true,
|
|
416
|
+
costMultiplier: 0.65,
|
|
417
|
+
},
|
|
418
|
+
],
|
|
419
|
+
],
|
|
420
|
+
[
|
|
421
|
+
NW_SMALL,
|
|
422
|
+
[
|
|
423
|
+
{
|
|
424
|
+
id: "nw-small",
|
|
425
|
+
name: "Neuralwatt Small",
|
|
426
|
+
contextWindow: 262128,
|
|
427
|
+
maxOutputTokens: 131072,
|
|
428
|
+
reasoning: true,
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
id: "nw-small-flex",
|
|
432
|
+
name: "Neuralwatt Small (flex)",
|
|
433
|
+
contextWindow: 262128,
|
|
434
|
+
maxOutputTokens: 131072,
|
|
435
|
+
reasoning: true,
|
|
436
|
+
costMultiplier: 0.65,
|
|
437
|
+
},
|
|
438
|
+
],
|
|
439
|
+
],
|
|
305
440
|
[
|
|
306
441
|
QWEN_3_6_35B,
|
|
307
442
|
[
|
|
308
443
|
{
|
|
309
444
|
id: "qwen3.6-35b",
|
|
310
445
|
name: "Qwen3.6 35B",
|
|
311
|
-
contextWindow:
|
|
446
|
+
contextWindow: 262128,
|
|
312
447
|
maxOutputTokens: null,
|
|
313
448
|
reasoning: true,
|
|
314
449
|
},
|
|
315
450
|
{
|
|
316
451
|
id: "qwen3.6-35b-fast",
|
|
317
452
|
name: "Qwen3.6 35B Fast",
|
|
318
|
-
contextWindow:
|
|
453
|
+
contextWindow: 262128,
|
|
319
454
|
maxOutputTokens: null,
|
|
320
455
|
reasoning: false,
|
|
321
456
|
},
|
|
322
457
|
{
|
|
323
458
|
id: "qwen3.6-35b-flex",
|
|
324
459
|
name: "Qwen3.6 35B (flex)",
|
|
325
|
-
contextWindow:
|
|
460
|
+
contextWindow: 262128,
|
|
326
461
|
maxOutputTokens: null,
|
|
327
462
|
reasoning: true,
|
|
328
463
|
costMultiplier: 0.65,
|