@byte_fluffy/nexra-sdk 0.1.0-alpha.27 → 0.1.0-alpha.29

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 CHANGED
@@ -37,6 +37,71 @@ available from `@byte_fluffy/nexra-sdk/media`.
37
37
  The default API base URL is `https://api.nexra-ai.com/v1`. When overriding
38
38
  `baseUrl`, include the `/v1` API prefix.
39
39
 
40
+ ## Model display names
41
+
42
+ `getModelSpec`, `listModelSpecs`, `nexra.models.search`, `nexra.models.get`, and
43
+ `nexra.catalog.model` return display names with spaces between words and
44
+ capitalized initials, such as
45
+ `Grok Imagine Image`, `GPT 5.4`, and `Wan 2.7 Image Pro`. Brand spelling, acronyms,
46
+ and decimal versions are preserved. Model detail family versions follow the same
47
+ format.
48
+
49
+ Use `formatModelDisplayName(name)` to apply this format to other display labels.
50
+ It is available from the package root and `/catalog`. Formatting affects only
51
+ `displayName`: use the static catalog's `id`, model discovery's `slug`, or the
52
+ live catalog's `modelId` for requests, never the formatted display name.
53
+
54
+ ## Live model catalog
55
+
56
+ `getModelSpec` and `listModelSpecs` read the catalog bundled with this SDK release.
57
+ Use `catalog.model(publicId, operation)` to read the currently published database
58
+ input schema, display name, sale prices and actual model revision. A successful
59
+ `available: false` response authoritatively confirms an unavailable or retired
60
+ public identity; HTTP failures throw and must preserve the last successful value.
61
+ An unknown identity returns 404. Model IDs are URL-encoded by the SDK.
62
+
63
+ `catalog.changes` lists lightweight public model/operation identities and their
64
+ latest revisions. Start with `after: "0"` for initial alignment. Keep the first
65
+ page's `revision` as `upper` for every remaining page and pass its opaque
66
+ `nextCursor`. The cursor is bound to that `after`/`upper` window. Revisions are
67
+ 64-bit decimal strings; compare them with `BigInt`, not JavaScript numbers.
68
+
69
+ ```ts
70
+ let after = "0";
71
+ let cursor: string | undefined;
72
+ let upper: string | undefined;
73
+ do {
74
+ const page = await nexra.catalog.changes({ after, upper, cursor });
75
+ upper ??= page.revision;
76
+ // Record changed identities for independent background model reads.
77
+ enqueueChanges(page.data);
78
+ cursor = page.nextCursor;
79
+ } while (cursor);
80
+ after = upper!;
81
+
82
+ for await (const event of nexra.catalog.events({ after, signal })) {
83
+ enqueueChanges(event.data);
84
+ after = event.revision;
85
+ }
86
+ ```
87
+
88
+ `enqueueChanges` is application code that records the affected identities before
89
+ advancing the receiving cursor; it does not block on all model reads. Each model
90
+ response carries its own actual revision. Do not label an older response with the
91
+ requested target revision or let it overwrite newer state. An identity updated
92
+ beyond a page window's fixed upper bound appears in the next window, including
93
+ when its index row was replaced during pagination.
94
+
95
+ `catalog.events` opens one authenticated SSE stream, ignores heartbeats, and
96
+ emits complete `catalog.quote-context.changed` windows with `{ revision,
97
+ changedAt, data }`. Notifications wake the API instance immediately; a per-instance
98
+ 60-second revision check recovers silent notification loss. When a stream ends or
99
+ throws, the application reconnects using its retained `after` cursor; the SDK
100
+ does not reconnect automatically. Abort the supplied signal to stop an active
101
+ read. Leaving the iterator cancels and releases the response stream. Keep cached
102
+ values and cursors separate for different API sources and authorization identities.
103
+ No credentials, channel costs or user discounts are included in the public events.
104
+
40
105
  ## Private ElevenLabs voices
41
106
 
42
107
  Voice design uses `elevenlabs/eleven_multilingual_ttv_v2`, with exactly one prompt
@@ -106,6 +171,77 @@ const flashResult = await nexra.run("agnes/agnes-video-2-5-flash", flashInput, {
106
171
  });
107
172
  ```
108
173
 
174
+ ## Native language models
175
+
176
+ The optional `@byte_fluffy/nexra-sdk/language` entrypoint returns AI SDK
177
+ `LanguageModelV4` models. Install its optional provider peers when using this
178
+ entrypoint; the core SDK and media entrypoints do not load them. These provider
179
+ versions require Node.js 22 or a supported Bun runtime:
180
+
181
+ ```sh
182
+ npm install @ai-sdk/provider@^4.0.2 @ai-sdk/provider-utils@^5.0.21 \
183
+ @ai-sdk/openai@^4.0.11 @ai-sdk/anthropic@^4.0.30 @ai-sdk/google@^4.0.12 ai@^7
184
+ ```
185
+
186
+ ```ts
187
+ import { generateText, streamText } from "ai";
188
+ import { getLanguageModelBinding } from "@byte_fluffy/nexra-sdk/catalog";
189
+ import { createNexraLanguageModel } from "@byte_fluffy/nexra-sdk/language";
190
+
191
+ const modelId = "openai/gpt-6-sol";
192
+ const binding = getLanguageModelBinding(modelId);
193
+ const model = createNexraLanguageModel(modelId, {
194
+ apiKey: process.env.NEXRA_API_KEY!,
195
+ });
196
+
197
+ if (binding.supportsStreaming) {
198
+ const result = streamText({ model, prompt: "Explain a paper boat", maxRetries: 0 });
199
+ for await (const text of result.textStream) process.stdout.write(text);
200
+ } else {
201
+ const result = await generateText({ model, prompt: "Explain a paper boat", maxRetries: 0 });
202
+ console.log(result.text);
203
+ }
204
+ ```
205
+
206
+ The binding selects a declared native endpoint, preferring Gemini, Responses,
207
+ Chat Completions, then Messages. Pass `protocol` to choose another endpoint
208
+ declared by that model. Native endpoint `inputSchema` and `outputSchema` describe
209
+ wire parameters; language operation schemas may describe Playground inputs.
210
+ `binding.maxOutputTokens` is the lower of the model capability and selected
211
+ native endpoint limit. Messages requests validate the combined visible and
212
+ thinking token budget before sending; explicit budgets are never clamped.
213
+ The SDK does not wrap text requests in media Tasks or retry generations.
214
+
215
+ Messages, tool history and ordered content parts use the AI SDK prompt contract.
216
+ Chat Completions supports declared image/video/audio URLs and inline MP3, WAV,
217
+ AAC and M4A audio without downloading URLs or changing codecs. Native model results and stream finish events retain `usage.raw`, including
218
+ cache and modality details. With AI SDK 7, read `result.finalStep.usage.raw`
219
+ or each step callback's usage. Aggregate `result.usage` and `totalUsage` do not
220
+ retain raw records.
221
+
222
+ Chat native extension fields are passed under `providerOptions.nexra`;
223
+ Responses uses `openai`, Messages uses `anthropic`, and Gemini uses `google`.
224
+ Explicit provider options are preserved. Model identity and prompt/stream
225
+ fields stay owned by the SDK. Kimi K2.5 currently declares synchronous Chat
226
+ Completions only, so use `generateText` for that model.
227
+
228
+ Responses defaults to `store: false` in this SDK so each request replays the full
229
+ conversation and encrypted reasoning instead of relying on stored item IDs.
230
+ Pass `providerOptions.openai.store: true` explicitly for a stored conversation.
231
+ The current Responses provider cannot preserve sampling parameters alongside
232
+ reasoning for canonical Nexra IDs. Explicit `temperature` or `topP` therefore
233
+ fails before sending instead of being silently discarded. A caller may select
234
+ `forceReasoning: false` for sampling without explicit reasoning controls.
235
+ The documented provider version floors are tested; Anthropic budget validation
236
+ uses its exported capability helper and the shared provider budget mapper.
237
+
238
+ Use `resolveNexraLanguageReasoning(modelId, { enabled: false })` from `/catalog`
239
+ for a quiet generation policy. Its `providerOptions` select a declared off mode
240
+ or the model's minimum reasoning effort; `canDisable` distinguishes those cases.
241
+ An explicit AI SDK `reasoning: "none"` is rejected when the native model requires
242
+ reasoning, rather than being changed silently. Explicit provider options take
243
+ precedence over shared reasoning defaults.
244
+
109
245
  GPT-6 Sol and GPT-6 Luna are included in the language model catalog. Sale prices
110
246
  are not bundled into the SDK; use the current prices published by the selected
111
247
  Nexra environment:
package/dist/catalog.d.ts CHANGED
@@ -1,10 +1,18 @@
1
- import { H as HttpTransport, N as NexraSalePriceList, C as CreateNexraQuoteRequest, a as NexraQuote, b as CreateNexraDisplayQuoteBatchRequest, c as NexraDisplayQuoteBatch, d as NexraCatalogRevision, e as NexraModelSpec, f as NexraModelSpecFilter } from './media-geometry-B7ip-nrA.js';
2
- export { M as MediaGeometryField, g as MediaGeometryProjection, h as NexraBillingCurrency, i as NexraModelEndpointSpec, j as NexraModelOperation, k as NexraSalePrice, l as NexraSettlement, U as UnifiedMediaGeometry, m as applyMediaGeometry, n as decodeMediaGeometry, o as encodeMediaGeometry, p as projectMediaGeometry } from './media-geometry-B7ip-nrA.js';
3
- import './json-Drjj1OKl.js';
1
+ import { J as JsonObject } from './json-Drjj1OKl.js';
2
+ import { H as HttpTransport, N as NexraCatalogChangeParams, a as NexraCatalogChangePage, b as NexraCatalogModelState, c as NexraSalePriceList, C as CreateNexraQuoteRequest, d as NexraQuote, e as CreateNexraDisplayQuoteBatchRequest, f as NexraDisplayQuoteBatch, g as NexraCatalogRevision, h as NexraModelSpec, i as NexraModelEndpointSpec, j as NexraModelSpecFilter } from './media-geometry-nJ7I7ohO.js';
3
+ export { M as MediaGeometryField, k as MediaGeometryProjection, l as NexraBillingCurrency, m as NexraCatalogModelIdentity, n as NexraModelOperation, o as NexraSalePrice, p as NexraSettlement, U as UnifiedMediaGeometry, q as applyMediaGeometry, r as decodeMediaGeometry, s as encodeMediaGeometry, t as projectMediaGeometry } from './media-geometry-nJ7I7ohO.js';
4
+
5
+ declare function formatModelDisplayName(displayName: string): string;
4
6
 
5
7
  declare class CatalogClient {
6
8
  private readonly transport;
7
9
  constructor(transport: HttpTransport);
10
+ changes(params?: NexraCatalogChangeParams, signal?: AbortSignal): Promise<NexraCatalogChangePage>;
11
+ model(modelId: string, operation: string, signal?: AbortSignal): Promise<NexraCatalogModelState>;
12
+ events(options?: {
13
+ after?: string;
14
+ signal?: AbortSignal;
15
+ }): AsyncGenerator<NexraCatalogChangePage>;
8
16
  listPrices(signal?: AbortSignal): Promise<NexraSalePriceList>;
9
17
  quote(request: CreateNexraQuoteRequest, signal?: AbortSignal): Promise<NexraQuote>;
10
18
  quoteBatch(request: CreateNexraDisplayQuoteBatchRequest, signal?: AbortSignal): Promise<NexraDisplayQuoteBatch>;
@@ -12,5 +20,25 @@ declare class CatalogClient {
12
20
  }
13
21
  declare function getModelSpec(modelId: string): NexraModelSpec | undefined;
14
22
  declare function listModelSpecs(filter?: NexraModelSpecFilter): readonly NexraModelSpec[];
23
+ type NexraLanguageProtocol = "gemini-generate-content" | "openai-responses" | "openai-chat-completions" | "anthropic-messages";
24
+ type NexraLanguageModelBinding = Readonly<{
25
+ spec: NexraModelSpec;
26
+ endpoint: NexraModelEndpointSpec & {
27
+ protocol: NexraLanguageProtocol;
28
+ };
29
+ supportsStreaming: boolean;
30
+ maxOutputTokens?: number;
31
+ }>;
32
+ declare function getLanguageModelBinding(modelId: string, options?: {
33
+ protocol?: NexraLanguageProtocol;
34
+ }): NexraLanguageModelBinding;
35
+ type NexraLanguageReasoning = Readonly<{
36
+ providerOptions: Record<string, JsonObject>;
37
+ canDisable: boolean;
38
+ }>;
39
+ declare function resolveNexraLanguageReasoning(modelId: string, options: {
40
+ enabled: boolean;
41
+ protocol?: NexraLanguageProtocol;
42
+ }): NexraLanguageReasoning;
15
43
 
16
- export { CatalogClient, CreateNexraDisplayQuoteBatchRequest, CreateNexraQuoteRequest, NexraCatalogRevision, NexraDisplayQuoteBatch, NexraModelSpec, NexraModelSpecFilter, NexraQuote, NexraSalePriceList, getModelSpec, listModelSpecs };
44
+ export { CatalogClient, CreateNexraDisplayQuoteBatchRequest, CreateNexraQuoteRequest, NexraCatalogChangePage, NexraCatalogChangeParams, NexraCatalogModelState, NexraCatalogRevision, NexraDisplayQuoteBatch, type NexraLanguageModelBinding, type NexraLanguageProtocol, type NexraLanguageReasoning, NexraModelEndpointSpec, NexraModelSpec, NexraModelSpecFilter, NexraQuote, NexraSalePriceList, formatModelDisplayName, getLanguageModelBinding, getModelSpec, listModelSpecs, resolveNexraLanguageReasoning };
package/dist/catalog.js CHANGED
@@ -3,17 +3,23 @@ import {
3
3
  applyMediaGeometry,
4
4
  decodeMediaGeometry,
5
5
  encodeMediaGeometry,
6
+ formatModelDisplayName,
7
+ getLanguageModelBinding,
6
8
  getModelSpec,
7
9
  listModelSpecs,
8
- projectMediaGeometry
9
- } from "./chunk-N622DGTD.js";
10
- import "./chunk-YQXMWTSV.js";
10
+ projectMediaGeometry,
11
+ resolveNexraLanguageReasoning
12
+ } from "./chunk-ESV6ODRA.js";
13
+ import "./chunk-IEBCNRT4.js";
11
14
  export {
12
15
  CatalogClient,
13
16
  applyMediaGeometry,
14
17
  decodeMediaGeometry,
15
18
  encodeMediaGeometry,
19
+ formatModelDisplayName,
20
+ getLanguageModelBinding,
16
21
  getModelSpec,
17
22
  listModelSpecs,
18
- projectMediaGeometry
23
+ projectMediaGeometry,
24
+ resolveNexraLanguageReasoning
19
25
  };