@shop-os/modelkit 0.1.4 → 0.1.5

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
@@ -117,26 +117,49 @@ The kit keeps its `Warning` type for coercions; the SDK's warning type is `AiWar
117
117
 
118
118
  ## What the package owns
119
119
 
120
- | Concern | Rule |
121
- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
122
- | Ids | `id` is the pro-backend pricing key. Every historical id (`nb-pro`, `veo-3.1-generate-001`, `kling-v2.5-turbo-pro`) is an alias. |
123
- | Options | Image tiers are `512` (Gemini 3.1 Flash only), `1K`, `2K`, `4K`. `resolveOptions` fills catalog defaults, coerces aspect ratio to the nearest supported one, errors on unsupported size or resolution (`onUnsupported: "coerce"` snaps down instead), clamps duration, trims references (audio first, then video), and drops options the model ignores with a warning. |
124
- | Keys | Enterprise keys win only when every key the adapter (and its route, e.g. the cloudflare token for gateway-routed text) needs is set on the enterprise tier. |
125
- | Routing | Cloudflare AI Gateway for text only. Never for Gemini images or Omni. fal passthrough for geo-blocked regions. OpenRouter optional for text. |
126
- | Retry | One classifier. Never on content blocks or 4xx except 429. |
127
- | Errors | `ModelKitError` with `code`, `provider`, `status`, `body`. Gemini `blockReason` and fal `body.detail` are lifted into `body`. |
128
- | Usage | One event per call with the canonical model id. 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. 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. |
129
- | 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. |
120
+ | Concern | Rule |
121
+ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
122
+ | Ids | `id` is the pro-backend pricing key. Every historical id (`nb-pro`, `veo-3.1-generate-001`, `kling-v2.5-turbo-pro`) is an alias. |
123
+ | Options | Image tiers are `512` (Gemini 3.1 Flash only), `1K`, `2K`, `4K`. `resolveOptions` fills catalog defaults, coerces aspect ratio to the nearest supported one, errors on unsupported size or resolution (`onUnsupported: "coerce"` snaps down instead), clamps duration, trims references (audio first, then video), and drops options the model ignores with a warning (a row without `supports` supports nothing). `aspectRatio: "adaptive"` means "send no ratio": it is never coerced or replaced by the row default, and Gemini, Muse, Kling and Kling O1 omit the field so the model infers it from the references. Every coercion is also logged once per call through `logger.warn`. Gemini image `safetySettings` are sent only when the caller passes them. |
124
+ | Keys | Enterprise keys win only when every key the adapter (and its route, e.g. the cloudflare token for gateway-routed text) needs is set on the enterprise tier. |
125
+ | Routing | Cloudflare AI Gateway for text only. Never for Gemini images or Omni. fal passthrough for geo-blocked regions; the fal direct route submits to the queue and polls, so `job.result({ timeoutMs, signal })` is live. OpenRouter optional for text. |
126
+ | Retry | One classifier. Never on content blocks or 4xx except 429. |
127
+ | 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. |
128
+ | 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. 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. |
129
+ | 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. |
130
130
 
131
131
  ## Add a model
132
132
 
133
133
  1. Add a row to `src/catalog/{image,video,text,other}.ts`. Copy `constraints` from the provider docs.
134
134
  2. Run `pnpm test`. The catalog test checks id and alias uniqueness.
135
- 3. Bump `version` in `package.json`. Merging to `dev` publishes.
135
+ 3. Bump `version` in `package.json` in a PR that touches only `packages/modelkit/**`.
136
+ Merging it to `dev` runs `modelkit-publish.yml`, which publishes through the npm
137
+ trusted publisher.
138
+ 4. Once the version is on npm, bump `@shop-os/modelkit` in every consumer in a second PR.
139
+
140
+ ## Consumers
141
+
142
+ Every app takes the published package from npm, not a `workspace:*` link. This is a
143
+ deliberate decision (AGENTS.md §3.1): consumers span three repos and must agree on one
144
+ version, the package bundles provider SDKs the Docker whitelist recipe would have to
145
+ rebuild per app, and the Trigger.dev deploys have no `packages/` in their build context.
146
+ The accepted cost: a kit change and its consumer change never land in one PR, and a
147
+ change here reaches an app only after a publish and a version bump there.
148
+
149
+ | Repo | Apps |
150
+ | ----------------- | -------------------------------------------------------------------------- |
151
+ | shopos-backend-ts | cowork, asset-service, template-service, brand-memory-service, pro-backend |
152
+ | shopos-ui | vibe-api, pro-admin, vibe-triggers |
153
+ | trigger-workflows | the root package (vibe-primitives, geo, model-providers) |
154
+
155
+ Each app owns one lazy kit in a `modelkit.ts` module (`getModelKit()` plus a
156
+ `resetModelKit()` test seam) and reads its keys from the environment. Gemini
157
+ calls go direct everywhere: they need `GOOGLE_API_KEY` (or `GEMINI_API_KEY`) in
158
+ the app's secrets, not a Cloudflare gateway token.
136
159
 
137
160
  ## Adapters
138
161
 
139
- `ai-sdk-text`, `google-image`, `openai-image`, `google-genai` (Veo, Omni, Lyria 3, Files API media parts), `ark` (Seedream, Seedance), `fal`, `replicate` (images, video, Lyria 2, MMAudio), `prodia`, `higgsfield`, `xai-video`. See `src/adapters/`.
162
+ `ai-sdk-text`, `google-image`, `openai-image`, `google-genai` (Veo, Omni with `delivery: "uri"`, Lyria 3, Files API media parts), `ark` (Seedream, Seedance), `fal`, `replicate` (images, video, Lyria 2, MMAudio), `prodia`, `higgsfield`, `xai-video`. See `src/adapters/`.
140
163
 
141
164
  ## Not in the package
142
165