@byte_fluffy/nexra-sdk 0.1.0-alpha.52 → 0.1.0-alpha.54
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.
- package/README.md +15 -110
- package/dist/catalog.d.ts +3 -3
- package/dist/catalog.js +2 -2
- package/dist/{chunk-LEZWVFQH.js → chunk-IOGCXMW3.js} +115 -8
- package/dist/{chunk-V3KBU3J5.js → chunk-MLDFBO2A.js} +10828 -11220
- package/dist/chunk-ZTRVMQMH.js +745 -0
- package/dist/{errors-DJZuAKoO.d.ts → errors-BXPUVOh7.d.ts} +2 -2
- package/dist/index.d.ts +12 -11
- package/dist/index.js +16 -466
- package/dist/{json-Cz0MkWQn.d.ts → json-dnsDzk-s.d.ts} +1 -1
- package/dist/language.d.ts +3 -3
- package/dist/language.js +73 -247
- package/dist/{media-DzOxLGs-.d.ts → media-IaOdOMQC.d.ts} +14 -2
- package/dist/{media-geometry-COln1N_2.d.ts → media-geometry-z7fXaDSN.d.ts} +5 -2
- package/dist/media.d.ts +2 -2
- package/dist/media.js +1 -1
- package/dist/node.d.ts +17 -0
- package/dist/node.js +78 -0
- package/dist/types.d.ts +5 -5
- package/dist/{voices-xyPqhQqR.d.ts → voices-BrCaiHnb.d.ts} +53 -5
- package/package.json +13 -7
package/dist/language.js
CHANGED
|
@@ -6,17 +6,18 @@ import {
|
|
|
6
6
|
jsonBody,
|
|
7
7
|
parseServerSentEvents,
|
|
8
8
|
resolveNexraLanguageReasoning
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-MLDFBO2A.js";
|
|
10
10
|
import {
|
|
11
11
|
isPublicErrorCode,
|
|
12
12
|
publicErrorMessage,
|
|
13
13
|
resolvePublicErrorLocale
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-IOGCXMW3.js";
|
|
15
15
|
|
|
16
16
|
// src/language/index.ts
|
|
17
17
|
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
18
18
|
import { getModelCapabilities as getAnthropicModelCapabilities } from "@ai-sdk/anthropic/internal";
|
|
19
19
|
import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
20
|
+
import { createOpenAI } from "@ai-sdk/openai";
|
|
20
21
|
import { mapReasoningToProviderBudget } from "@ai-sdk/provider-utils";
|
|
21
22
|
|
|
22
23
|
// src/language/chat-model.ts
|
|
@@ -71,30 +72,6 @@ function nativeOptions(part) {
|
|
|
71
72
|
const value = part.providerOptions?.nexra;
|
|
72
73
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
73
74
|
}
|
|
74
|
-
function nativeMediaUrlPatterns(binding, kind) {
|
|
75
|
-
const field = kind === "audio" ? "input_audio" : `${kind}_url`;
|
|
76
|
-
const messages2 = asObject(asObject(binding.endpoint.inputSchema?.properties).messages);
|
|
77
|
-
const content = asObject(asObject(asObject(messages2.items).properties).content);
|
|
78
|
-
const patterns = /* @__PURE__ */ new Set();
|
|
79
|
-
const visit = (value) => {
|
|
80
|
-
if (Array.isArray(value)) {
|
|
81
|
-
value.forEach(visit);
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
const node = asObject(value);
|
|
85
|
-
const properties = asObject(node.properties);
|
|
86
|
-
if (asObject(properties.type).const === field) {
|
|
87
|
-
const url = asObject(asObject(asObject(properties[field]).properties).url);
|
|
88
|
-
if (typeof url.pattern === "string") patterns.add(url.pattern);
|
|
89
|
-
}
|
|
90
|
-
for (const child of Object.values(node)) if (child && typeof child === "object") visit(child);
|
|
91
|
-
};
|
|
92
|
-
visit(content);
|
|
93
|
-
return patterns.size ? [...patterns].map((pattern) => new RegExp(pattern)) : void 0;
|
|
94
|
-
}
|
|
95
|
-
function chatSupportedUrls(binding) {
|
|
96
|
-
return Object.fromEntries(binding.spec.capabilities.inputModalities.filter((kind) => ["image", "audio", "video"].includes(kind)).map((kind) => [`${kind}/*`, nativeMediaUrlPatterns(binding, kind) ?? [/^https?:\/\//]]));
|
|
97
|
-
}
|
|
98
75
|
function filePart(part, binding) {
|
|
99
76
|
const kind = part.mediaType.split("/")[0];
|
|
100
77
|
if (["image", "audio", "video"].includes(kind) && !binding.spec.capabilities.inputModalities.includes(kind)) {
|
|
@@ -106,10 +83,6 @@ function filePart(part, binding) {
|
|
|
106
83
|
throw new UnsupportedFunctionalityError({ functionality: "file reference without a Nexra reference" });
|
|
107
84
|
}
|
|
108
85
|
const url = part.data.type === "url" ? part.data.url.toString() : void 0;
|
|
109
|
-
const patterns = nativeMediaUrlPatterns(binding, kind);
|
|
110
|
-
if (url && patterns && !patterns.some((pattern) => pattern.test(url))) {
|
|
111
|
-
throw new UnsupportedFunctionalityError({ functionality: `native media URL for ${binding.spec.id}; provide bytes or a matching data URL` });
|
|
112
|
-
}
|
|
113
86
|
const data = part.data.type === "data" ? convertToBase64(part.data.data) : void 0;
|
|
114
87
|
if (kind === "image" || kind === "video") {
|
|
115
88
|
const field = kind === "image" ? "image_url" : "video_url";
|
|
@@ -268,6 +241,40 @@ var NexraNativeError = class extends APICallError {
|
|
|
268
241
|
return this.statusCode;
|
|
269
242
|
}
|
|
270
243
|
};
|
|
244
|
+
function restoreNativeError(error) {
|
|
245
|
+
const seen = /* @__PURE__ */ new Set();
|
|
246
|
+
let current = error;
|
|
247
|
+
while (current instanceof Error && !seen.has(current)) {
|
|
248
|
+
if (current instanceof NexraNativeError) return current;
|
|
249
|
+
seen.add(current);
|
|
250
|
+
current = current.cause;
|
|
251
|
+
}
|
|
252
|
+
return error;
|
|
253
|
+
}
|
|
254
|
+
function restoreNativeStreamErrors(stream) {
|
|
255
|
+
const reader = stream.getReader();
|
|
256
|
+
return new ReadableStream({
|
|
257
|
+
async pull(controller) {
|
|
258
|
+
try {
|
|
259
|
+
const { value, done } = await reader.read();
|
|
260
|
+
if (done) {
|
|
261
|
+
reader.releaseLock();
|
|
262
|
+
controller.close();
|
|
263
|
+
} else controller.enqueue(value);
|
|
264
|
+
} catch (error) {
|
|
265
|
+
reader.releaseLock();
|
|
266
|
+
controller.error(restoreNativeError(error));
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
async cancel(reason) {
|
|
270
|
+
try {
|
|
271
|
+
await reader.cancel(reason);
|
|
272
|
+
} finally {
|
|
273
|
+
reader.releaseLock();
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}, { highWaterMark: 0 });
|
|
277
|
+
}
|
|
271
278
|
function createNexraNativeFetch(options = {}) {
|
|
272
279
|
const fetch = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
273
280
|
return async (input, init) => {
|
|
@@ -407,7 +414,7 @@ function createChatLanguageModel(binding, transport) {
|
|
|
407
414
|
specificationVersion: "v4",
|
|
408
415
|
provider: "nexra.chat",
|
|
409
416
|
modelId: binding.spec.id,
|
|
410
|
-
supportedUrls:
|
|
417
|
+
supportedUrls: Object.fromEntries(binding.spec.capabilities.inputModalities.filter((kind) => ["image", "audio", "video"].includes(kind)).map((kind) => [`${kind}/*`, [/^https?:\/\//]])),
|
|
411
418
|
async doGenerate(options) {
|
|
412
419
|
const body = chatRequest(binding, options, false);
|
|
413
420
|
const response = await transport.response("/chat/completions", { method: "POST", ...jsonBody(body), headers: combineHeaders(options), signal: options.abortSignal }, { retryable: false });
|
|
@@ -555,190 +562,6 @@ function combineHeaders(options) {
|
|
|
555
562
|
return headers;
|
|
556
563
|
}
|
|
557
564
|
|
|
558
|
-
// src/language/responses-model.ts
|
|
559
|
-
import { createOpenAI } from "@ai-sdk/openai";
|
|
560
|
-
function object3(value) {
|
|
561
|
-
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
562
|
-
}
|
|
563
|
-
function isUnpositionedCitation(value) {
|
|
564
|
-
const node = object3(value);
|
|
565
|
-
return node.type === "url_citation" && typeof node.url === "string" && !Object.hasOwn(node, "start_index") && !Object.hasOwn(node, "end_index");
|
|
566
|
-
}
|
|
567
|
-
function project(value) {
|
|
568
|
-
if (Array.isArray(value)) return value.map(project);
|
|
569
|
-
if (!value || typeof value !== "object") return value;
|
|
570
|
-
const projected = Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
571
|
-
key,
|
|
572
|
-
key === "annotations" && Array.isArray(item) ? item.filter((annotation) => !isUnpositionedCitation(annotation)).map(project) : project(item)
|
|
573
|
-
]));
|
|
574
|
-
if (projected.type === "output_text" && projected.annotations === void 0) projected.annotations = [];
|
|
575
|
-
return projected;
|
|
576
|
-
}
|
|
577
|
-
function citations(value) {
|
|
578
|
-
if (Array.isArray(value)) return value.flatMap(citations);
|
|
579
|
-
const node = object3(value);
|
|
580
|
-
if (isUnpositionedCitation(node)) return [node];
|
|
581
|
-
return Object.values(node).flatMap((item) => item && typeof item === "object" ? citations(item) : []);
|
|
582
|
-
}
|
|
583
|
-
function nativeSearchBody(value, call) {
|
|
584
|
-
const extension = call.providerOptions?.nexra?.web_search;
|
|
585
|
-
if (extension === void 0) return value;
|
|
586
|
-
if (!extension || typeof extension !== "object" || Array.isArray(extension)) throw new Error("Nexra web_search options must be a native tool object");
|
|
587
|
-
const body = object3(value);
|
|
588
|
-
if (!Array.isArray(body.tools) || !body.tools.some((tool) => object3(tool).type === "web_search")) {
|
|
589
|
-
throw new Error("Nexra web_search options require an enabled web_search tool");
|
|
590
|
-
}
|
|
591
|
-
return { ...body, tools: body.tools.map((tool) => object3(tool).type === "web_search" ? { ...object3(tool), ...extension, type: "web_search" } : tool) };
|
|
592
|
-
}
|
|
593
|
-
function nativeSearchRequest(init, call) {
|
|
594
|
-
return typeof init?.body === "string" ? { ...init, body: JSON.stringify(nativeSearchBody(JSON.parse(init.body), call)) } : init;
|
|
595
|
-
}
|
|
596
|
-
function createResponsesLanguageModel(options) {
|
|
597
|
-
const factory = (fetch) => createOpenAI({
|
|
598
|
-
apiKey: options.apiKey,
|
|
599
|
-
headers: options.headers,
|
|
600
|
-
name: "nexra.openai",
|
|
601
|
-
baseURL: options.baseUrl,
|
|
602
|
-
fetch
|
|
603
|
-
}).responses(options.modelId);
|
|
604
|
-
const base = factory(options.fetch);
|
|
605
|
-
return {
|
|
606
|
-
specificationVersion: "v4",
|
|
607
|
-
provider: base.provider,
|
|
608
|
-
modelId: base.modelId,
|
|
609
|
-
supportedUrls: base.supportedUrls,
|
|
610
|
-
async doGenerate(call) {
|
|
611
|
-
let original;
|
|
612
|
-
const fetch = async (input, init) => {
|
|
613
|
-
const response = await options.fetch(input, nativeSearchRequest(init, call));
|
|
614
|
-
if (!response.ok || !response.headers.get("content-type")?.includes("application/json")) return response;
|
|
615
|
-
const text = await response.text();
|
|
616
|
-
try {
|
|
617
|
-
original = JSON.parse(text);
|
|
618
|
-
} catch {
|
|
619
|
-
return new Response(text, response);
|
|
620
|
-
}
|
|
621
|
-
return new Response(JSON.stringify(project(original)), response);
|
|
622
|
-
};
|
|
623
|
-
const result = await factory(fetch).doGenerate(call);
|
|
624
|
-
const seen = /* @__PURE__ */ new Set();
|
|
625
|
-
const sources = sourceParts(original, seen);
|
|
626
|
-
return {
|
|
627
|
-
...result,
|
|
628
|
-
content: [...result.content, ...sources],
|
|
629
|
-
request: result.request ? { ...result.request, body: nativeSearchBody(result.request.body, call) } : void 0,
|
|
630
|
-
response: { ...result.response, ...original === void 0 ? {} : { body: original } }
|
|
631
|
-
};
|
|
632
|
-
},
|
|
633
|
-
async doStream(call) {
|
|
634
|
-
const entries = /* @__PURE__ */ new Map();
|
|
635
|
-
let before = [];
|
|
636
|
-
const canceled = new AbortController();
|
|
637
|
-
const fetch = async (input, init) => {
|
|
638
|
-
const response = await options.fetch(input, nativeSearchRequest(init, call));
|
|
639
|
-
if (!response.ok || !response.headers.get("content-type")?.includes("text/event-stream")) return response;
|
|
640
|
-
const signal = init?.signal ? AbortSignal.any([init.signal, canceled.signal]) : canceled.signal;
|
|
641
|
-
const iterator = parseServerSentEvents(response, { signal });
|
|
642
|
-
const encoder = new TextEncoder();
|
|
643
|
-
const body = new ReadableStream({
|
|
644
|
-
async pull(controller) {
|
|
645
|
-
try {
|
|
646
|
-
while (true) {
|
|
647
|
-
const next = await iterator.next();
|
|
648
|
-
if (next.done) {
|
|
649
|
-
controller.close();
|
|
650
|
-
return;
|
|
651
|
-
}
|
|
652
|
-
const frame = next.value;
|
|
653
|
-
let native;
|
|
654
|
-
try {
|
|
655
|
-
native = JSON.parse(frame.data);
|
|
656
|
-
} catch {
|
|
657
|
-
controller.enqueue(encoder.encode(`${frame.event ? `event: ${frame.event}
|
|
658
|
-
` : ""}data: ${frame.data}
|
|
659
|
-
|
|
660
|
-
`));
|
|
661
|
-
return;
|
|
662
|
-
}
|
|
663
|
-
if (object3(native).type === "response.output_text.annotation.added" && isUnpositionedCitation(object3(native).annotation)) {
|
|
664
|
-
before.push(native);
|
|
665
|
-
continue;
|
|
666
|
-
}
|
|
667
|
-
const projected = project(native);
|
|
668
|
-
const key = JSON.stringify(projected);
|
|
669
|
-
const queue = entries.get(key) ?? [];
|
|
670
|
-
queue.push({ original: native, before });
|
|
671
|
-
before = [];
|
|
672
|
-
entries.set(key, queue);
|
|
673
|
-
controller.enqueue(encoder.encode(`${frame.id ? `id: ${frame.id}
|
|
674
|
-
` : ""}${frame.event ? `event: ${frame.event}
|
|
675
|
-
` : ""}${frame.retry !== void 0 ? `retry: ${frame.retry}
|
|
676
|
-
` : ""}data: ${key}
|
|
677
|
-
|
|
678
|
-
`));
|
|
679
|
-
return;
|
|
680
|
-
}
|
|
681
|
-
} catch (error) {
|
|
682
|
-
controller.error(error);
|
|
683
|
-
await iterator.return(void 0);
|
|
684
|
-
}
|
|
685
|
-
},
|
|
686
|
-
async cancel(reason) {
|
|
687
|
-
canceled.abort(reason);
|
|
688
|
-
await iterator.return(void 0);
|
|
689
|
-
}
|
|
690
|
-
});
|
|
691
|
-
return new Response(body, response);
|
|
692
|
-
};
|
|
693
|
-
const result = await factory(fetch).doStream({ ...call, includeRawChunks: true });
|
|
694
|
-
const seen = /* @__PURE__ */ new Set();
|
|
695
|
-
return {
|
|
696
|
-
...result,
|
|
697
|
-
request: result.request ? { ...result.request, body: nativeSearchBody(result.request.body, call) } : void 0,
|
|
698
|
-
stream: result.stream.pipeThrough(new TransformStream({
|
|
699
|
-
transform(part, controller) {
|
|
700
|
-
if (part.type !== "raw") {
|
|
701
|
-
controller.enqueue(part);
|
|
702
|
-
return;
|
|
703
|
-
}
|
|
704
|
-
const key = JSON.stringify(part.rawValue);
|
|
705
|
-
const queue = entries.get(key);
|
|
706
|
-
const entry = queue?.shift();
|
|
707
|
-
if (queue?.length === 0) entries.delete(key);
|
|
708
|
-
const native = entry?.original ?? part.rawValue;
|
|
709
|
-
for (const frame of [...entry?.before ?? [], native]) {
|
|
710
|
-
for (const source of sourceParts(frame, seen)) controller.enqueue(source);
|
|
711
|
-
if (call.includeRawChunks) controller.enqueue({ type: "raw", rawValue: frame });
|
|
712
|
-
}
|
|
713
|
-
},
|
|
714
|
-
flush(controller) {
|
|
715
|
-
for (const frame of before) {
|
|
716
|
-
for (const source of sourceParts(frame, seen)) controller.enqueue(source);
|
|
717
|
-
if (call.includeRawChunks) controller.enqueue({ type: "raw", rawValue: frame });
|
|
718
|
-
}
|
|
719
|
-
entries.clear();
|
|
720
|
-
before = [];
|
|
721
|
-
}
|
|
722
|
-
}))
|
|
723
|
-
};
|
|
724
|
-
}
|
|
725
|
-
};
|
|
726
|
-
}
|
|
727
|
-
function sourceParts(value, seen) {
|
|
728
|
-
return citations(value).flatMap((annotation) => {
|
|
729
|
-
const key = JSON.stringify([annotation.url, annotation.title]);
|
|
730
|
-
if (seen.has(key)) return [];
|
|
731
|
-
seen.add(key);
|
|
732
|
-
return [{
|
|
733
|
-
type: "source",
|
|
734
|
-
sourceType: "url",
|
|
735
|
-
id: `native-source-${seen.size}`,
|
|
736
|
-
url: annotation.url,
|
|
737
|
-
...typeof annotation.title === "string" ? { title: annotation.title } : {}
|
|
738
|
-
}];
|
|
739
|
-
});
|
|
740
|
-
}
|
|
741
|
-
|
|
742
565
|
// src/language/index.ts
|
|
743
566
|
function createNexraLanguageModel(modelId, options) {
|
|
744
567
|
const binding = getLanguageModelBinding(modelId, options);
|
|
@@ -764,30 +587,30 @@ function createNexraLanguageModel(modelId, options) {
|
|
|
764
587
|
input,
|
|
765
588
|
typeof init?.body === "string" ? { ...init, body: JSON.stringify(explicitResponsesMessages(JSON.parse(init.body))) } : init
|
|
766
589
|
);
|
|
767
|
-
model =
|
|
590
|
+
model = createOpenAI({ ...common, name: "nexra.openai", baseURL: `${root}/v1`, fetch: responsesFetch }).responses(binding.spec.id);
|
|
768
591
|
} else {
|
|
769
592
|
model = createAnthropic({ ...common, name: "nexra.anthropic", baseURL: `${root}/v1` })(binding.spec.id);
|
|
770
593
|
}
|
|
771
594
|
return withNativeContract(model, binding);
|
|
772
595
|
}
|
|
773
|
-
function
|
|
596
|
+
function object3(value) {
|
|
774
597
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
775
598
|
}
|
|
776
599
|
function explicitResponsesMessages(value) {
|
|
777
|
-
const body =
|
|
600
|
+
const body = object3(value);
|
|
778
601
|
if (!Array.isArray(body.input)) return value;
|
|
779
602
|
return { ...body, input: body.input.map((value2) => {
|
|
780
|
-
const item =
|
|
603
|
+
const item = object3(value2);
|
|
781
604
|
return item.type === void 0 && ["system", "developer", "user", "assistant"].includes(String(item.role)) && (typeof item.content === "string" || Array.isArray(item.content)) ? { ...item, type: "message" } : value2;
|
|
782
605
|
}) };
|
|
783
606
|
}
|
|
784
607
|
function googleNativeBody(binding, value) {
|
|
785
|
-
const body =
|
|
786
|
-
const config =
|
|
787
|
-
const thinking =
|
|
788
|
-
const fields =
|
|
789
|
-
const nativeThinking =
|
|
790
|
-
const values =
|
|
608
|
+
const body = object3(value);
|
|
609
|
+
const config = object3(body.generationConfig);
|
|
610
|
+
const thinking = object3(config.thinkingConfig);
|
|
611
|
+
const fields = object3(binding.endpoint.inputSchema?.properties);
|
|
612
|
+
const nativeThinking = object3(object3(object3(object3(fields.generationConfig).properties).thinkingConfig).properties);
|
|
613
|
+
const values = object3(nativeThinking.thinkingLevel).enum;
|
|
791
614
|
const level = typeof thinking.thinkingLevel === "string" && Array.isArray(values) ? values.find((value2) => typeof value2 === "string" && value2.toLowerCase() === String(thinking.thinkingLevel).toLowerCase()) : void 0;
|
|
792
615
|
return level === void 0 || level === thinking.thinkingLevel ? value : { ...body, generationConfig: { ...config, thinkingConfig: { ...thinking, thinkingLevel: level } } };
|
|
793
616
|
}
|
|
@@ -795,29 +618,25 @@ function nativeRequest(binding, request, stream = false) {
|
|
|
795
618
|
if (!request) return request;
|
|
796
619
|
return binding.endpoint.protocol === "openai-responses" ? {
|
|
797
620
|
...request,
|
|
798
|
-
body: explicitResponsesMessages(stream ? { ...
|
|
621
|
+
body: explicitResponsesMessages(stream ? { ...object3(request.body), stream: true } : request.body)
|
|
799
622
|
} : binding.endpoint.protocol === "gemini-generate-content" ? { ...request, body: googleNativeBody(binding, request.body) } : request;
|
|
800
623
|
}
|
|
801
624
|
function prepare(options, binding, stream) {
|
|
802
625
|
binding = getLanguageModelBinding(binding.spec.id, { protocol: binding.endpoint.protocol, stream });
|
|
803
626
|
options = prepareLanguageReasoning(options, binding);
|
|
804
|
-
const properties =
|
|
805
|
-
const
|
|
806
|
-
if (options.toolChoice && Array.isArray(choices2) && !choices2.includes(options.toolChoice.type)) {
|
|
807
|
-
throw new Error(`Nexra tool choice is outside the native contract for ${binding.spec.id}: ${options.toolChoice.type}`);
|
|
808
|
-
}
|
|
809
|
-
const tokenField = object4(binding.endpoint.protocol === "gemini-generate-content" ? object4(object4(properties.generationConfig).properties).maxOutputTokens : properties.max_output_tokens ?? properties.max_tokens);
|
|
627
|
+
const properties = object3(binding.endpoint.inputSchema?.properties);
|
|
628
|
+
const tokenField = object3(binding.endpoint.protocol === "gemini-generate-content" ? object3(object3(properties.generationConfig).properties).maxOutputTokens : properties.max_output_tokens ?? properties.max_tokens);
|
|
810
629
|
if (options.maxOutputTokens !== void 0 && (!Number.isInteger(options.maxOutputTokens) || typeof tokenField.minimum === "number" && options.maxOutputTokens < tokenField.minimum || binding.maxOutputTokens !== void 0 && options.maxOutputTokens > binding.maxOutputTokens)) throw new Error(`Nexra output token limit is outside the native contract for ${binding.spec.id}`);
|
|
811
630
|
if (options.tools?.length && !binding.endpoint.capabilities.includes("tool_call")) throw new Error(`Nexra model does not support tools: ${binding.spec.id}`);
|
|
812
631
|
const providerOptions = { ...options.providerOptions };
|
|
813
632
|
if (binding.endpoint.protocol === "openai-responses") {
|
|
814
|
-
const current =
|
|
633
|
+
const current = object3(providerOptions.openai);
|
|
815
634
|
providerOptions.openai = {
|
|
816
635
|
store: false,
|
|
817
636
|
forceReasoning: binding.endpoint.capabilities.includes("reasoning"),
|
|
818
637
|
...current
|
|
819
638
|
};
|
|
820
|
-
const reasoning =
|
|
639
|
+
const reasoning = object3(providerOptions.openai);
|
|
821
640
|
if (reasoning.forceReasoning === true && (options.temperature !== void 0 || options.topP !== void 0)) {
|
|
822
641
|
throw new Error(`Nexra Responses adapter cannot preserve explicit sampling parameters with reasoning for ${binding.spec.id}`);
|
|
823
642
|
}
|
|
@@ -827,8 +646,8 @@ function prepare(options, binding, stream) {
|
|
|
827
646
|
}
|
|
828
647
|
if (binding.endpoint.protocol === "anthropic-messages") {
|
|
829
648
|
const capabilities = getAnthropicModelCapabilities(binding.spec.id);
|
|
830
|
-
const native = { ...
|
|
831
|
-
let thinking =
|
|
649
|
+
const native = { ...object3(providerOptions.anthropic), ...object3(providerOptions.nexra) };
|
|
650
|
+
let thinking = object3(native.thinking);
|
|
832
651
|
if (!native.thinking && native.effort == null && options.reasoning && options.reasoning !== "provider-default") {
|
|
833
652
|
thinking = options.reasoning === "none" ? { type: "disabled" } : capabilities.supportsAdaptiveThinking ? { type: "adaptive" } : { type: "enabled", budgetTokens: mapReasoningToProviderBudget({
|
|
834
653
|
reasoning: options.reasoning,
|
|
@@ -849,20 +668,20 @@ function prepare(options, binding, stream) {
|
|
|
849
668
|
options = { ...options, maxOutputTokens: visible };
|
|
850
669
|
}
|
|
851
670
|
if (stream && binding.endpoint.protocol === "gemini-generate-content" && binding.endpoint.capabilities.includes("reasoning")) {
|
|
852
|
-
const google =
|
|
853
|
-
providerOptions.google = { ...google, thinkingConfig: { includeThoughts: true, ...
|
|
671
|
+
const google = object3(providerOptions.google);
|
|
672
|
+
providerOptions.google = { ...google, thinkingConfig: { includeThoughts: true, ...object3(google.thinkingConfig) } };
|
|
854
673
|
}
|
|
855
674
|
return { ...options, providerOptions };
|
|
856
675
|
}
|
|
857
676
|
function nativeUsage(protocol, value) {
|
|
858
|
-
const payload =
|
|
859
|
-
const raw = protocol === "gemini-generate-content" ? payload.usageMetadata : protocol === "anthropic-messages" ?
|
|
677
|
+
const payload = object3(value);
|
|
678
|
+
const raw = protocol === "gemini-generate-content" ? payload.usageMetadata : protocol === "anthropic-messages" ? object3(payload.message).usage ?? payload.usage : object3(payload.response).usage ?? payload.usage;
|
|
860
679
|
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : void 0;
|
|
861
680
|
}
|
|
862
681
|
function mergeRecords(previous, next) {
|
|
863
682
|
const merged = { ...previous, ...next };
|
|
864
683
|
for (const [key, value] of Object.entries(next)) {
|
|
865
|
-
if (value && typeof value === "object" && !Array.isArray(value)) merged[key] = { ...
|
|
684
|
+
if (value && typeof value === "object" && !Array.isArray(value)) merged[key] = { ...object3(previous?.[key]), ...object3(value) };
|
|
866
685
|
}
|
|
867
686
|
return merged;
|
|
868
687
|
}
|
|
@@ -873,7 +692,9 @@ function withNativeContract(model, binding) {
|
|
|
873
692
|
modelId: model.modelId,
|
|
874
693
|
supportedUrls: model.supportedUrls,
|
|
875
694
|
async doGenerate(options) {
|
|
876
|
-
const result = await model.doGenerate(prepare(options, binding, false))
|
|
695
|
+
const result = await Promise.resolve(model.doGenerate(prepare(options, binding, false))).catch((error) => {
|
|
696
|
+
throw restoreNativeError(error);
|
|
697
|
+
});
|
|
877
698
|
const raw = nativeUsage(binding.endpoint.protocol, result.response?.body);
|
|
878
699
|
return {
|
|
879
700
|
...result,
|
|
@@ -883,7 +704,9 @@ function withNativeContract(model, binding) {
|
|
|
883
704
|
},
|
|
884
705
|
async doStream(options) {
|
|
885
706
|
if (!binding.supportsStreaming) throw new Error(`Nexra model does not support streaming: ${binding.spec.id}`);
|
|
886
|
-
const result = await model.doStream({ ...prepare(options, binding, true), includeRawChunks: true })
|
|
707
|
+
const result = await Promise.resolve(model.doStream({ ...prepare(options, binding, true), includeRawChunks: true })).catch((error) => {
|
|
708
|
+
throw restoreNativeError(error);
|
|
709
|
+
});
|
|
887
710
|
let raw;
|
|
888
711
|
let terminal = false;
|
|
889
712
|
let failed = false;
|
|
@@ -893,17 +716,20 @@ function withNativeContract(model, binding) {
|
|
|
893
716
|
return {
|
|
894
717
|
...result,
|
|
895
718
|
request: nativeRequest(binding, result.request, true),
|
|
896
|
-
stream: result.stream.pipeThrough(new TransformStream({
|
|
719
|
+
stream: restoreNativeStreamErrors(result.stream).pipeThrough(new TransformStream({
|
|
897
720
|
transform(part, controller) {
|
|
898
721
|
if (part.type === "raw") {
|
|
899
|
-
const payload =
|
|
900
|
-
terminal ||= binding.endpoint.protocol === "anthropic-messages" ? payload.type === "message_stop" : binding.endpoint.protocol === "openai-responses" ? ["response.completed", "response.incomplete", "response.failed"].includes(String(payload.type)) : Array.isArray(payload.candidates) && payload.candidates.some((candidate) => typeof
|
|
722
|
+
const payload = object3(part.rawValue);
|
|
723
|
+
terminal ||= binding.endpoint.protocol === "anthropic-messages" ? payload.type === "message_stop" : binding.endpoint.protocol === "openai-responses" ? ["response.completed", "response.incomplete", "response.failed"].includes(String(payload.type)) : Array.isArray(payload.candidates) && payload.candidates.some((candidate) => typeof object3(candidate).finishReason === "string");
|
|
901
724
|
const next = nativeUsage(binding.endpoint.protocol, part.rawValue);
|
|
902
725
|
if (next) raw = mergeRecords(raw, next);
|
|
903
726
|
if (options.includeRawChunks) controller.enqueue(part);
|
|
904
727
|
} else if (part.type === "finish") finish = part;
|
|
905
728
|
else {
|
|
906
|
-
if (part.type === "error")
|
|
729
|
+
if (part.type === "error") {
|
|
730
|
+
failed = true;
|
|
731
|
+
part = { ...part, error: restoreNativeError(part.error) };
|
|
732
|
+
}
|
|
907
733
|
if (part.type === "text-start" || part.type === "text-delta" || part.type === "text-end" || part.type === "reasoning-start" || part.type === "reasoning-delta" || part.type === "reasoning-end") {
|
|
908
734
|
const metadata = part.type.startsWith("text-") ? textMetadata : reasoningMetadata2;
|
|
909
735
|
if (part.providerMetadata) metadata.set(part.id, mergeRecords(metadata.get(part.id), part.providerMetadata));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { J as JsonObject } from './json-dnsDzk-s.js';
|
|
2
2
|
|
|
3
3
|
declare const MEDIA_KINDS: readonly ["image", "video", "audio", "document", "archive", "other"];
|
|
4
4
|
type MediaKind = (typeof MEDIA_KINDS)[number];
|
|
@@ -161,6 +161,8 @@ type NexraVideoGenerateInput = Readonly<{
|
|
|
161
161
|
duration?: number;
|
|
162
162
|
fit?: "contain" | "cover";
|
|
163
163
|
title?: string;
|
|
164
|
+
/** Audio source for models that expose original-video sound. */
|
|
165
|
+
audio?: "native" | "original";
|
|
164
166
|
generate_audio?: boolean;
|
|
165
167
|
output_format?: string;
|
|
166
168
|
seed?: number;
|
|
@@ -217,8 +219,18 @@ type NexraVideoDepthInput = Readonly<{
|
|
|
217
219
|
resolution?: string;
|
|
218
220
|
}>;
|
|
219
221
|
type NexraVideoSegmentInput = Readonly<{
|
|
220
|
-
content: readonly [NexraVideoContentPart, NexraTextContentPart] | readonly [NexraTextContentPart, NexraVideoContentPart];
|
|
222
|
+
content: readonly [NexraVideoContentPart, NexraTextContentPart] | readonly [NexraTextContentPart, NexraVideoContentPart] | readonly [NexraVideoContentPart];
|
|
221
223
|
resolution?: string;
|
|
224
|
+
mode?: "preview" | "track";
|
|
225
|
+
preview_time_ms?: number;
|
|
226
|
+
prompts?: readonly Readonly<{
|
|
227
|
+
time_ms: number;
|
|
228
|
+
points: readonly Readonly<{
|
|
229
|
+
x: number;
|
|
230
|
+
y: number;
|
|
231
|
+
label: 0 | 1;
|
|
232
|
+
}>[];
|
|
233
|
+
}>[];
|
|
222
234
|
}>;
|
|
223
235
|
type NexraMediaInputByOperation = Readonly<{
|
|
224
236
|
"image.generate": NexraImageGenerateInput;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as JsonPrimitive, J as JsonObject, b as JsonValue } from './json-dnsDzk-s.js';
|
|
2
2
|
|
|
3
3
|
declare const BILLING_METRICS: readonly ["requests", "input_tokens", "cached_input_tokens", "cache_write_tokens", "cache_creation_5m_input_tokens", "cache_creation_1h_input_tokens", "cache_read_input_tokens", "output_tokens", "input_characters", "input_utf8_bytes", "input_images", "output_images", "input_audio_seconds", "output_audio_seconds", "input_video_seconds", "output_video_seconds", "provider_credits", "web_search_requests"];
|
|
4
4
|
type BillingMetric = (typeof BILLING_METRICS)[number];
|
|
@@ -90,6 +90,8 @@ interface TaskModelSummary {
|
|
|
90
90
|
end: string;
|
|
91
91
|
succeeded: number;
|
|
92
92
|
total: number;
|
|
93
|
+
attemptSucceeded?: number;
|
|
94
|
+
attemptTotal?: number;
|
|
93
95
|
}[];
|
|
94
96
|
id: string;
|
|
95
97
|
slug: string;
|
|
@@ -335,6 +337,7 @@ declare class HttpTransport {
|
|
|
335
337
|
private readonly maxRetries;
|
|
336
338
|
constructor(options: NexraClientOptions);
|
|
337
339
|
url(path: string): string;
|
|
340
|
+
headers(additional?: HeadersInit): Headers;
|
|
338
341
|
json<T>(path: string, init?: RequestInit, options?: RequestOptions): Promise<T>;
|
|
339
342
|
response(path: string, init?: RequestInit, options?: RequestOptions): Promise<Response>;
|
|
340
343
|
}
|
|
@@ -366,4 +369,4 @@ declare function decodeMediaGeometry(_inputSchema: JsonObject, input: JsonObject
|
|
|
366
369
|
/** Normalize the SDK convenience alias `ratio` without producing Native fields. */
|
|
367
370
|
declare function applyMediaGeometry(inputSchema: JsonObject, input: JsonObject): JsonObject;
|
|
368
371
|
|
|
369
|
-
export { type
|
|
372
|
+
export { type NexraCatalogChangeParams as A, type NexraCatalogChangePage as B, type CreateNexraDisplayQuoteBatchRequest as C, type NexraCatalogModelState as D, type NexraModelEndpointSpec as E, type FetchLike as F, type NexraCatalogModelIdentity as G, HttpTransport as H, type MediaGeometryField as M, type NexraClientOptions as N, type TaskModel as T, type UnifiedMediaGeometry as U, type CreateNexraQuoteRequest as a, type MediaGeometryProjection as b, type ModelCapabilitySummary as c, type ModelDateVersion as d, type ModelEndpointSummary as e, type ModelModality as f, type ModelResourceList as g, type ModelResourceOption as h, type ModelSchema as i, type ModelSearchParams as j, type NexraBillingCurrency as k, type NexraCatalogRevision as l, type NexraDisplayQuoteBatch as m, type NexraDisplayQuoteBatchEntry as n, type NexraModelOperation as o, type NexraModelSpec as p, type NexraModelSpecFilter as q, type NexraQuote as r, type NexraSalePrice as s, type NexraSalePriceList as t, type NexraSettlement as u, type TaskModelSummary as v, applyMediaGeometry as w, decodeMediaGeometry as x, encodeMediaGeometry as y, projectMediaGeometry as z };
|
package/dist/media.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { k as NEXRA_GENERATION_OPERATIONS, l as NEXRA_MEDIA_API_VERSION, m as NEXRA_MEDIA_FEATURES, n as NEXRA_MEDIA_INPUT_SCHEMAS, o as NEXRA_MEDIA_OPERATIONS, p as NEXRA_MEDIA_OPERATION_DEFINITIONS, q as NEXRA_PUBLISHED_MEDIA_OPERATIONS, r as NexraAudioContentPart, s as NexraAudioGenerateInput, t as NexraAudioTranscribeInput, u as NexraGenerationOperation, v as NexraImageContentPart, w as NexraImageGenerateInput, N as NexraImageLayer, g as NexraImageLayerDecompositionOutput, x as NexraImageUpscaleInput, y as NexraMediaContentPart, z as NexraMediaFeature, B as NexraMediaInputByOperation, C as NexraMediaInputMode, D as NexraMediaInputSlot, E as NexraMediaKind, F as NexraMediaOperation, G as NexraMediaOperationDefinition, H as NexraMediaParameter, I as NexraMediaParameterConstraint, J as NexraMediaSource, K as NexraPublishedMediaOperation, L as NexraResourceContentPart, O as NexraTextContentPart, P as NexraVideoContentPart, Q as NexraVideoDepthInput, R as NexraVideoGenerateInput, S as NexraVideoKeyframeContentPart, T as NexraVideoUpscaleInput, U as isNexraMediaInput, V as nexraMediaInputSchema, W as nexraMediaInputSchemaForMode, X as nexraMediaOperationForMode } from './media-
|
|
2
|
-
import './json-
|
|
1
|
+
export { k as NEXRA_GENERATION_OPERATIONS, l as NEXRA_MEDIA_API_VERSION, m as NEXRA_MEDIA_FEATURES, n as NEXRA_MEDIA_INPUT_SCHEMAS, o as NEXRA_MEDIA_OPERATIONS, p as NEXRA_MEDIA_OPERATION_DEFINITIONS, q as NEXRA_PUBLISHED_MEDIA_OPERATIONS, r as NexraAudioContentPart, s as NexraAudioGenerateInput, t as NexraAudioTranscribeInput, u as NexraGenerationOperation, v as NexraImageContentPart, w as NexraImageGenerateInput, N as NexraImageLayer, g as NexraImageLayerDecompositionOutput, x as NexraImageUpscaleInput, y as NexraMediaContentPart, z as NexraMediaFeature, B as NexraMediaInputByOperation, C as NexraMediaInputMode, D as NexraMediaInputSlot, E as NexraMediaKind, F as NexraMediaOperation, G as NexraMediaOperationDefinition, H as NexraMediaParameter, I as NexraMediaParameterConstraint, J as NexraMediaSource, K as NexraPublishedMediaOperation, L as NexraResourceContentPart, O as NexraTextContentPart, P as NexraVideoContentPart, Q as NexraVideoDepthInput, R as NexraVideoGenerateInput, S as NexraVideoKeyframeContentPart, T as NexraVideoUpscaleInput, U as isNexraMediaInput, V as nexraMediaInputSchema, W as nexraMediaInputSchemaForMode, X as nexraMediaOperationForMode } from './media-IaOdOMQC.js';
|
|
2
|
+
import './json-dnsDzk-s.js';
|
package/dist/media.js
CHANGED
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export { A as AssetImportRequest, a as AssetInput, b as AssetReference, c as AssetUploadOptions, M as MEDIA_KINDS, d as MediaAsset, e as MediaAssetStatus, f as MediaKind, N as NexraImageLayer, g as NexraImageLayerDecompositionOutput } from './media-IaOdOMQC.js';
|
|
2
|
+
import { N as NexraClientOptions } from './media-geometry-z7fXaDSN.js';
|
|
3
|
+
export { C as CreateNexraDisplayQuoteBatchRequest, a as CreateNexraQuoteRequest, F as FetchLike, M as MediaGeometryField, b as MediaGeometryProjection, c as ModelCapabilitySummary, d as ModelDateVersion, e as ModelEndpointSummary, f as ModelModality, g as ModelResourceList, h as ModelResourceOption, i as ModelSchema, j as ModelSearchParams, k as NexraBillingCurrency, l as NexraCatalogRevision, m as NexraDisplayQuoteBatch, n as NexraDisplayQuoteBatchEntry, o as NexraModelOperation, p as NexraModelSpec, q as NexraModelSpecFilter, r as NexraQuote, s as NexraSalePrice, t as NexraSalePriceList, u as NexraSettlement, T as TaskModel, v as TaskModelSummary, U as UnifiedMediaGeometry, w as applyMediaGeometry, x as decodeMediaGeometry, y as encodeMediaGeometry, z as projectMediaGeometry } from './media-geometry-z7fXaDSN.js';
|
|
4
|
+
export { C as CursorPage, J as JsonObject, a as JsonPrimitive, b as JsonValue } from './json-dnsDzk-s.js';
|
|
5
|
+
export { A as ApiErrorPayload, N as NexraError, P as PublicError, a as PublicErrorContext, b as PublicErrorFields, e as extractUpstreamErrorMessage } from './errors-BXPUVOh7.js';
|
|
6
|
+
export { A as AssetsClient, C as CreateTaskOptions, a as CreateTaskRequest, b as CreateVoiceRequest, N as NexraTranscriptionError, R as RequestDetails, c as RunResult, d as RunTaskOptions, T as TASK_STATUSES, e as Task, f as TaskCost, g as TaskError, h as TaskEvent, i as TaskEventType, j as TaskListParams, k as TaskPage, l as TaskProgress, m as TaskReceipt, e as TaskResult, n as TaskStatus, o as TaskTiming, p as TaskUsage, q as TaskWebhookConfig, r as TasksClient, s as TerminalTaskStatus, t as TranscriptionClient, u as TranscriptionEvent, v as TranscriptionResponse, w as TranscriptionStreamOptions, V as VerifyWebhookOptions, x as Voice, y as VoiceCreation, W as WaitTaskOptions, z as WatchTaskOptions, B as isTerminalTaskStatus, D as verifyWebhook } from './voices-BrCaiHnb.js';
|
|
7
|
+
export { CatalogClient, formatModelDisplayName, getModelSpec, listModelSpecs } from './catalog.js';
|
|
8
|
+
import { NexraClient as NexraClient$1 } from './index.js';
|
|
9
|
+
export { CreateVoiceOptions, ModelsClient, NexraApiError, NexraTaskError, NexraWaitTimeoutError, VoicesClient } from './index.js';
|
|
10
|
+
export { ceilDecimal, multiplyDecimal } from './decimal.js';
|
|
11
|
+
|
|
12
|
+
declare class NexraClient extends NexraClient$1 {
|
|
13
|
+
constructor(options?: NexraClientOptions);
|
|
14
|
+
}
|
|
15
|
+
declare function createNexra(options?: NexraClientOptions): NexraClient;
|
|
16
|
+
|
|
17
|
+
export { NexraClient, NexraClientOptions, createNexra };
|
package/dist/node.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AssetsClient,
|
|
3
|
+
ModelsClient,
|
|
4
|
+
NexraClient,
|
|
5
|
+
NexraTranscriptionError,
|
|
6
|
+
TasksClient,
|
|
7
|
+
TranscriptionClient,
|
|
8
|
+
VoicesClient,
|
|
9
|
+
verifyWebhook
|
|
10
|
+
} from "./chunk-ZTRVMQMH.js";
|
|
11
|
+
import {
|
|
12
|
+
ceilDecimal,
|
|
13
|
+
multiplyDecimal
|
|
14
|
+
} from "./chunk-FCH5IQP5.js";
|
|
15
|
+
import {
|
|
16
|
+
CatalogClient,
|
|
17
|
+
NexraApiError,
|
|
18
|
+
NexraTaskError,
|
|
19
|
+
NexraWaitTimeoutError,
|
|
20
|
+
applyMediaGeometry,
|
|
21
|
+
decodeMediaGeometry,
|
|
22
|
+
encodeMediaGeometry,
|
|
23
|
+
formatModelDisplayName,
|
|
24
|
+
getModelSpec,
|
|
25
|
+
listModelSpecs,
|
|
26
|
+
projectMediaGeometry
|
|
27
|
+
} from "./chunk-MLDFBO2A.js";
|
|
28
|
+
import {
|
|
29
|
+
ASR_MAX_FRAME_BYTES,
|
|
30
|
+
MEDIA_KINDS,
|
|
31
|
+
TASK_STATUSES,
|
|
32
|
+
extractUpstreamErrorMessage,
|
|
33
|
+
isTerminalTaskStatus
|
|
34
|
+
} from "./chunk-IOGCXMW3.js";
|
|
35
|
+
|
|
36
|
+
// src/node.ts
|
|
37
|
+
import WebSocket from "ws";
|
|
38
|
+
var NexraClient2 = class extends NexraClient {
|
|
39
|
+
constructor(options = {}) {
|
|
40
|
+
super(options, (url, headers) => new WebSocket(url, {
|
|
41
|
+
headers: Object.fromEntries(headers),
|
|
42
|
+
maxPayload: ASR_MAX_FRAME_BYTES,
|
|
43
|
+
followRedirects: false,
|
|
44
|
+
perMessageDeflate: false
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
function createNexra(options = {}) {
|
|
49
|
+
return new NexraClient2(options);
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
AssetsClient,
|
|
53
|
+
CatalogClient,
|
|
54
|
+
MEDIA_KINDS,
|
|
55
|
+
ModelsClient,
|
|
56
|
+
NexraApiError,
|
|
57
|
+
NexraClient2 as NexraClient,
|
|
58
|
+
NexraTaskError,
|
|
59
|
+
NexraTranscriptionError,
|
|
60
|
+
NexraWaitTimeoutError,
|
|
61
|
+
TASK_STATUSES,
|
|
62
|
+
TasksClient,
|
|
63
|
+
TranscriptionClient,
|
|
64
|
+
VoicesClient,
|
|
65
|
+
applyMediaGeometry,
|
|
66
|
+
ceilDecimal,
|
|
67
|
+
createNexra,
|
|
68
|
+
decodeMediaGeometry,
|
|
69
|
+
encodeMediaGeometry,
|
|
70
|
+
extractUpstreamErrorMessage,
|
|
71
|
+
formatModelDisplayName,
|
|
72
|
+
getModelSpec,
|
|
73
|
+
isTerminalTaskStatus,
|
|
74
|
+
listModelSpecs,
|
|
75
|
+
multiplyDecimal,
|
|
76
|
+
projectMediaGeometry,
|
|
77
|
+
verifyWebhook
|
|
78
|
+
};
|