@shop-os/modelkit 0.2.9 → 0.2.11
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 +20 -0
- package/README.md +61 -0
- package/dist/catalog.cjs +26 -4
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +28 -5
- package/dist/catalog.d.ts +28 -5
- package/dist/catalog.js +26 -4
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +238 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -6
- package/dist/index.d.ts +34 -6
- package/dist/index.js +235 -29
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,26 @@ header in the release PR.
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [0.2.11] - 2026-09-17
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- Anthropic on Bedrock transport: InvokeModel via `createBedrockAnthropic`, with the same call surface as the direct route. The transport of a row is its `providerOptions.modelkit.transport` (`"bedrock"` | `"direct"`), then the app's `routing.anthropic`, then `"direct"`. Nothing changes for an app until a row or its routing says `"bedrock"`. The row value moves a model with a catalog edit and no deploy, in either direction, for example back to the Anthropic API during a Bedrock outage.
|
|
16
|
+
- Credential check: when the chosen transport has no credentials in the app and the other one has, the kit uses the other one and warns once, so a catalog edit cannot take an app down. An unknown row transport is ignored with a warning. `CatalogModelSchema` (the write schema) rejects an unknown transport; `CatalogSchema` (the read schema) tolerates it, so a value from a newer kit never makes an older kit reject the catalog.
|
|
17
|
+
- Bedrock model ids are derived: `<routing.bedrockProfile>.anthropic.<providerModelId>`, profile default `"us"`. The dated Haiku 4.5 and Sonnet 4.5 ids are built in. A row overrides with `providerOptions.modelkit.bedrockModelId`, and an already-prefixed `providerModelId` passes through unchanged. A new Claude row needs no kit change.
|
|
18
|
+
- `keys.aws` shape: `region` plus `apiKey` (Bedrock bearer token, wins over SigV4), `accessKeyId`/`secretAccessKey`/`sessionToken`, or `credentialProvider` for task roles and other chains. `hasAwsCredentials` reports whether a tier holds usable credentials, and enterprise-to-pro fallback treats `aws` like every other key. `keysFromEnv` reads `BEDROCK_REGION` (default `us-east-1`, never `AWS_REGION`), `AWS_BEARER_TOKEN_BEDROCK`, `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` plus `AWS_SESSION_TOKEN`, under the bare and `ENTERPRISE_` prefixes. An app that has the AWS key pair for S3 uses that IAM user for Bedrock, so it needs `bedrock:InvokeModel` and `bedrock:InvokeModelWithResponseStream` before a row or the routing moves it to Bedrock.
|
|
19
|
+
- Billing guard: the Bedrock model reports the canonical catalog id with provider `anthropic.messages`, so usage events match the direct route. `response.modelId` is pinned to the same id for `generate` and `stream` calls, because Bedrock echoes its own id for dated models (`anthropic.claude-haiku-4-5-20251001-v1:0`). Call-level `providerOptions.anthropic.cacheControl` is dropped with one warning per handle (Bedrock rejects it); message-level cacheControl and every other Anthropic option pass through.
|
|
20
|
+
|
|
21
|
+
Known Bedrock limits for callers: no `web_search`/`web_fetch` server tools, no Files API, no `anthropic-beta` headers. Image/file URLs are downloaded by the AI SDK in the caller's process and sent as base64 (5 MB per image); the request cap is 20 MB.
|
|
22
|
+
|
|
23
|
+
## [0.2.10] - 2026-09-16
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
- `VideoRequest.taskType` (`reference` | `edit` | `extend`) for Seedance omni-reference subtasks. `edit` sends `duration: -1` and `ratio: adaptive`; `extend` sends `ratio: adaptive`; both need a source or reference video and fail before submit otherwise. `seedance-2.5` also sends `omni_reference_task_type` so BytePlus validates at submit time instead of failing the task later with `InvalidParameter.TaskTypeConstraint`. The 2.0 rows do not list `taskType`.
|
|
27
|
+
- `ReferenceLimits.imagesWithVideo`: a lower image cap when a reference video is sent. `kling-v3-omni-video` declares 7 / 4 per the Replicate schema.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
- Omni usage bills 10 s when the caller sends no duration; the model renders 10 s by default, not 8 (live probe 2026-09-16). The `duration` response_format field is undocumented but honored, so it stays.
|
|
31
|
+
|
|
12
32
|
## [0.2.9] - 2026-09-15
|
|
13
33
|
|
|
14
34
|
### Changed
|
package/README.md
CHANGED
|
@@ -127,6 +127,67 @@ Opt into thinking per call, for example
|
|
|
127
127
|
The kit keeps its `Warning` type for coercions; the SDK's warning type is `AiWarning`.
|
|
128
128
|
`languageModel()` remains the low-level handle for Mastra and custom middleware; its `providerOptions` carry no kit-internal keys.
|
|
129
129
|
|
|
130
|
+
## Anthropic on Bedrock
|
|
131
|
+
|
|
132
|
+
Anthropic catalog rows can go through AWS Bedrock InvokeModel instead of the
|
|
133
|
+
Anthropic API. The call surface is the same, and usage events and
|
|
134
|
+
`response.modelId` still carry the catalog id.
|
|
135
|
+
|
|
136
|
+
The transport of a row is decided in this order:
|
|
137
|
+
|
|
138
|
+
1. The row: `providerOptions.modelkit.transport` = `"bedrock"` or `"direct"`. An
|
|
139
|
+
operator edits it in pro-admin and every app follows at its next catalog
|
|
140
|
+
refresh, with no deploy. It works in both directions, so it is also the
|
|
141
|
+
switch back during a Bedrock outage.
|
|
142
|
+
2. The app: `routing.anthropic`.
|
|
143
|
+
3. The default: `"direct"`, the Anthropic API.
|
|
144
|
+
|
|
145
|
+
A catalog edit can never take an app down. When the chosen transport has no
|
|
146
|
+
credentials in the app and the other one has, the kit uses the other one and
|
|
147
|
+
logs one warning. Keep both `ANTHROPIC_API_KEY` and the AWS credentials set so
|
|
148
|
+
the switch has somewhere to go.
|
|
149
|
+
|
|
150
|
+
Credentials come from `keys.aws` (`region` plus an `apiKey`, a static pair, or
|
|
151
|
+
a `credentialProvider`), or from the environment through `keysFromEnv`
|
|
152
|
+
(`BEDROCK_REGION`, default `us-east-1`; `AWS_BEARER_TOKEN_BEDROCK`, or
|
|
153
|
+
`AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` plus `AWS_SESSION_TOKEN`).
|
|
154
|
+
`keysFromEnv` picks up the AWS key pair an app already has for S3, so that IAM
|
|
155
|
+
user needs `bedrock:InvokeModel` and `bedrock:InvokeModelWithResponseStream`
|
|
156
|
+
before a row or the routing moves it to Bedrock. Bedrock rows never go through
|
|
157
|
+
the Cloudflare gateway.
|
|
158
|
+
|
|
159
|
+
The Bedrock model id is `<routing.bedrockProfile>.anthropic.<providerModelId>`
|
|
160
|
+
(profile default `us`). The older dated models are built in. A model that
|
|
161
|
+
breaks the pattern sets `providerOptions.modelkit.bedrockModelId` on its row.
|
|
162
|
+
See the CHANGELOG entry for the caller-visible Bedrock limits.
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
import { defaultProvider } from "@aws-sdk/credential-provider-node";
|
|
166
|
+
import { createDefaultModelKit, keysFromEnv } from "@shop-os/modelkit";
|
|
167
|
+
|
|
168
|
+
// Task roles and other credential chains. The Anthropic key stays as the fallback.
|
|
169
|
+
const kit = createDefaultModelKit({
|
|
170
|
+
keys: {
|
|
171
|
+
pro: {
|
|
172
|
+
...keysFromEnv(process.env),
|
|
173
|
+
aws: { region: "us-east-1", credentialProvider: defaultProvider() },
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
routing: { anthropic: "bedrock" },
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Static keys or a bearer token from the environment:
|
|
180
|
+
// BEDROCK_REGION=us-east-1 plus AWS_BEARER_TOKEN_BEDROCK, or
|
|
181
|
+
// AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY (+ AWS_SESSION_TOKEN).
|
|
182
|
+
const envKit = createDefaultModelKit({
|
|
183
|
+
keys: { pro: keysFromEnv(process.env) },
|
|
184
|
+
routing: { anthropic: "bedrock" },
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// No routing: the Anthropic API, until a catalog row sets transport "bedrock".
|
|
188
|
+
const defaultKit = createDefaultModelKit({ keys: { pro: keysFromEnv(process.env) } });
|
|
189
|
+
```
|
|
190
|
+
|
|
130
191
|
## What the package owns
|
|
131
192
|
|
|
132
193
|
| Concern | Rule |
|
package/dist/catalog.cjs
CHANGED
|
@@ -1520,6 +1520,7 @@ var VIDEO_MODELS = [
|
|
|
1520
1520
|
},
|
|
1521
1521
|
{
|
|
1522
1522
|
// generateAudio defaults to false here (trigger-workflows); Space Builder defaults it to true.
|
|
1523
|
+
// omni_reference_task_type edit/extend: adaptive ratio, edit sends duration -1.
|
|
1523
1524
|
id: "seedance-2.5",
|
|
1524
1525
|
aliases: ["seedance-2-5", "dreamina-seedance-2-5-260628"],
|
|
1525
1526
|
label: "Seedance 2.5",
|
|
@@ -1534,7 +1535,7 @@ var VIDEO_MODELS = [
|
|
|
1534
1535
|
durations: { min: 4, max: 30 },
|
|
1535
1536
|
references: { images: 30, videos: 10, audios: 10 },
|
|
1536
1537
|
ratioIgnoredWith: ["firstFrame", "sourceVideo"],
|
|
1537
|
-
supports: ["generateAudio", "seed", "lastFrame", "watermark"]
|
|
1538
|
+
supports: ["generateAudio", "seed", "lastFrame", "watermark", "taskType"]
|
|
1538
1539
|
},
|
|
1539
1540
|
defaults: {
|
|
1540
1541
|
durationSeconds: 5,
|
|
@@ -1643,6 +1644,9 @@ var VIDEO_MODELS = [
|
|
|
1643
1644
|
},
|
|
1644
1645
|
{
|
|
1645
1646
|
// mode standard/pro selects 720p/1080p; the endpoint takes no separate resolution.
|
|
1647
|
+
// Replicate: "Max 7 [images] without video, 4 with video"; 4K does not support
|
|
1648
|
+
// reference_video. No `videos` limit yet: the adapter sends no reference video,
|
|
1649
|
+
// so `imagesWithVideo` stays dormant until one is wired through.
|
|
1646
1650
|
id: "kling-v3-omni-video",
|
|
1647
1651
|
aliases: ["kwaivgi/kling-v3-omni-video", "kling-v3-omni"],
|
|
1648
1652
|
label: "Kling V3 Omni",
|
|
@@ -1655,7 +1659,7 @@ var VIDEO_MODELS = [
|
|
|
1655
1659
|
aspectRatios: [...KLING_RATIOS],
|
|
1656
1660
|
resolutions: ["720p", "1080p"],
|
|
1657
1661
|
durations: { min: 3, max: 15 },
|
|
1658
|
-
references: { images: 7 },
|
|
1662
|
+
references: { images: 7, imagesWithVideo: 4 },
|
|
1659
1663
|
supports: ["generateAudio", "lastFrame"]
|
|
1660
1664
|
},
|
|
1661
1665
|
defaults: { durationSeconds: 5, aspectRatio: "16:9", generateAudio: false, mode: "pro" },
|
|
@@ -1931,6 +1935,7 @@ var SupportedOptionSchema = import_zod.z.enum([
|
|
|
1931
1935
|
"upscale",
|
|
1932
1936
|
"watermark",
|
|
1933
1937
|
"safetyChecker",
|
|
1938
|
+
"taskType",
|
|
1934
1939
|
"instrumental"
|
|
1935
1940
|
]);
|
|
1936
1941
|
var UsageUnitSchema = import_zod.z.enum([
|
|
@@ -1953,6 +1958,7 @@ var ProviderOptionValueSchema = import_zod.z.lazy(
|
|
|
1953
1958
|
var ProviderOptionsSchema = import_zod.z.record(import_zod.z.string(), import_zod.z.record(import_zod.z.string(), ProviderOptionValueSchema));
|
|
1954
1959
|
var ReferenceLimitsSchema = import_zod.z.looseObject({
|
|
1955
1960
|
images: import_zod.z.number().optional(),
|
|
1961
|
+
imagesWithVideo: import_zod.z.number().optional(),
|
|
1956
1962
|
videos: import_zod.z.number().optional(),
|
|
1957
1963
|
audios: import_zod.z.number().optional(),
|
|
1958
1964
|
total: import_zod.z.number().optional(),
|
|
@@ -2014,6 +2020,7 @@ var DefaultsSchema = import_zod.z.looseObject({
|
|
|
2014
2020
|
promptExpansion: import_zod.z.enum(["fast", "balanced", "quality"]).optional(),
|
|
2015
2021
|
watermark: import_zod.z.boolean().optional(),
|
|
2016
2022
|
safetyChecker: import_zod.z.boolean().optional(),
|
|
2023
|
+
taskType: import_zod.z.enum(["reference", "edit", "extend"]).optional(),
|
|
2017
2024
|
mode: import_zod.z.enum(["standard", "pro"]).optional(),
|
|
2018
2025
|
instrumental: import_zod.z.boolean().optional()
|
|
2019
2026
|
});
|
|
@@ -2080,7 +2087,18 @@ var CatalogModelSchemaBase = import_zod.z.looseObject({
|
|
|
2080
2087
|
});
|
|
2081
2088
|
}
|
|
2082
2089
|
});
|
|
2083
|
-
var CatalogModelSchema = CatalogModelSchemaBase
|
|
2090
|
+
var CatalogModelSchema = CatalogModelSchemaBase.superRefine(
|
|
2091
|
+
(row, ctx) => {
|
|
2092
|
+
const transport = row.providerOptions?.["modelkit"]?.["transport"];
|
|
2093
|
+
if (transport !== void 0 && transport !== "direct" && transport !== "bedrock") {
|
|
2094
|
+
ctx.addIssue({
|
|
2095
|
+
code: "custom",
|
|
2096
|
+
path: ["providerOptions", "modelkit", "transport"],
|
|
2097
|
+
message: 'transport must be "direct" or "bedrock"'
|
|
2098
|
+
});
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
);
|
|
2084
2102
|
var CatalogSchema = import_zod.z.array(CatalogModelSchemaBase).superRefine((rows, ctx) => {
|
|
2085
2103
|
const seenIds = /* @__PURE__ */ new Map();
|
|
2086
2104
|
rows.forEach((row, index) => {
|
|
@@ -2550,6 +2568,9 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
|
|
|
2550
2568
|
model,
|
|
2551
2569
|
warnings
|
|
2552
2570
|
);
|
|
2571
|
+
if (limits.imagesWithVideo !== void 0 && (limits.videos ?? 0) > 0 && videos.length > 0 && images.length > limits.imagesWithVideo) {
|
|
2572
|
+
images = trim("referenceImages", images, limits.imagesWithVideo, model, warnings);
|
|
2573
|
+
}
|
|
2553
2574
|
if (limits.total !== void 0) {
|
|
2554
2575
|
let over = images.length + videos.length + audios.length - limits.total;
|
|
2555
2576
|
if (over > 0) {
|
|
@@ -2583,7 +2604,8 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
|
|
|
2583
2604
|
"promptExpansion",
|
|
2584
2605
|
"lastFrame",
|
|
2585
2606
|
"watermark",
|
|
2586
|
-
"safetyChecker"
|
|
2607
|
+
"safetyChecker",
|
|
2608
|
+
"taskType"
|
|
2587
2609
|
]);
|
|
2588
2610
|
return { request: merged, warnings };
|
|
2589
2611
|
}
|