@shop-os/modelkit 0.7.4 → 0.7.7

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/CHANGELOG.md CHANGED
@@ -9,6 +9,18 @@ header in the release PR.
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [0.7.7] - Unreleased
13
+
14
+ ### Fixed
15
+ - Google `prepareMediaPart` inlines bytes only up to 10 MiB (was 20 MB) and uploads larger media through the Files API. Inline bytes are base64-encoded, so a 15 MB video made a ~20 MB request and Gemini refused it or timed out; on dev no inline video between 10.9 MB and 20 MB succeeded. Media of 10-20 MB now uploads (a few seconds slower, same tokens) and the returned `cleanup` deletes the file as before.
16
+
17
+ ## [0.7.6] - Unreleased
18
+
19
+ ENG-3323: one xAI reference-mode rule.
20
+
21
+ ### Changed
22
+ - `xaiReferenceResolution` (kit-internal) now owns "is this request in xAI reference mode" and the 720p cap for both the resolver and the `xai-video` adapter. The adapter no longer keeps its own reference-mode check or its own copy of the refuse/lower rule. Requests, refusals and warnings are unchanged.
23
+
12
24
  ## [0.7.4] - Unreleased
13
25
 
14
26
  ENG-3321: one source of truth for each 3D family's options.
package/README.md CHANGED
@@ -309,7 +309,7 @@ const defaultKit = createDefaultModelKit({ keys: { pro: keysFromEnv(process.env)
309
309
  | Retry | One classifier, one policy. Never on content blocks, aborts, or 4xx except 429; SDKs with their own retry (Replicate) run under a single kit attempt; a 429 on a status poll keeps polling unless `CallContext.maxRetries` is `0`. See durable media execution above. |
310
310
  | Errors | `ModelKitError` with `code`, `provider`, `status`, `body`. Gemini `blockReason` and fal `body.detail` are lifted into `body`. A throw with no HTTP status (fetch failed, reset, DNS) is a retryable `network` error on every adapter. An out-of-credit provider account is `provider_billing` and is never retried: HTTP 402, a 4xx whose structured error code is a billing code (`insufficient_quota`, ...), or a 403/429 whose text names the exhausted account ("Exhausted balance", "Insufficient credit"). Text calls go through `ai` and surface the SDK's own error instead. |
311
311
  | Usage | One event per call with the canonical model id and the row's `usage.unit` (adapters supply the quantity in that unit). Gemini image events carry the token counts too (`inputTokens`/`outputTokens`); Google's raw `usageMetadata` rides on `raw.providerMetadata.google`. Video usage is emitted on completion and carries the resolution the provider renders (the default it falls back to when the request has none), because pricing is keyed by it; Seedance keeps `usage`, `duration`, `framespersecond` and `resolution` from the poll on `raw`. Audio: Lyria 3 returns no duration, so it emits `unit: "images", quantity: 1` (token counts ride along as `inputTokens`/`outputTokens`); Replicate audio (Lyria 2, MMAudio) emits `unit: "compute_seconds"` with the prediction time. |
312
- | Media parts | `prepareMediaPart` turns a `MediaRef` into an AI SDK file part. Google inlines bytes up to 20 MB and uploads larger payloads through the Files API; call the returned `cleanup` after the request. Other providers get the reference inline. |
312
+ | Media parts | `prepareMediaPart` turns a `MediaRef` into an AI SDK file part. Google inlines bytes up to 10 MiB (base64 makes them ~4/3 larger inside Gemini's 20 MB request cap) and uploads larger payloads through the Files API; call the returned `cleanup` after the request. Other providers get the reference inline. |
313
313
 
314
314
  ## Add a model
315
315
 
package/dist/catalog.cjs CHANGED
@@ -6401,14 +6401,14 @@ function xaiReferenceMode(model, req) {
6401
6401
  const takesLastFrame = (model.constraints.supports ?? []).includes("lastFrame");
6402
6402
  return (req.referenceImages ?? []).length > 0 || takesLastFrame && req.lastFrame !== void 0;
6403
6403
  }
6404
- function applyXaiVideoRules(model, req, onUnsupported, warnings) {
6405
- if (model.adapter !== "xai-video" || req.resolution !== "1080p") return;
6406
- if (!xaiReferenceMode(model, req)) return;
6404
+ function xaiReferenceResolution(model, req, onUnsupported, warnings, provider) {
6405
+ if (req.resolution !== "1080p" || !xaiReferenceMode(model, req)) return void 0;
6407
6406
  const message = xaiReferenceResolutionMessage(model.id);
6408
6407
  if (onUnsupported === "error") {
6409
6408
  throw new ModelKitError({
6410
6409
  code: "unsupported_option",
6411
6410
  message,
6411
+ ...provider === void 0 ? {} : { provider },
6412
6412
  model: model.id,
6413
6413
  retryable: false
6414
6414
  });
@@ -6420,7 +6420,12 @@ function applyXaiVideoRules(model, req, onUnsupported, warnings) {
6420
6420
  to: XAI_REFERENCE_MAX_RESOLUTION,
6421
6421
  message
6422
6422
  });
6423
- req.resolution = XAI_REFERENCE_MAX_RESOLUTION;
6423
+ return XAI_REFERENCE_MAX_RESOLUTION;
6424
+ }
6425
+ function applyXaiVideoRules(model, req, onUnsupported, warnings) {
6426
+ if (model.adapter !== "xai-video") return;
6427
+ const lowered = xaiReferenceResolution(model, req, onUnsupported, warnings);
6428
+ if (lowered !== void 0) req.resolution = lowered;
6424
6429
  }
6425
6430
  function takesTargetAspectRatio(model) {
6426
6431
  const ratios = model.constraints.aspectRatios ?? [];