@shop-os/modelkit 0.3.8 → 0.4.1
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 +25 -0
- package/README.md +2 -2
- package/dist/catalog.cjs +50 -36
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +12 -1
- package/dist/catalog.d.ts +12 -1
- package/dist/catalog.js +50 -36
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +165 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -2
- package/dist/index.d.ts +13 -2
- package/dist/index.js +165 -70
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -184,6 +184,8 @@ interface VideoToolSubmission {
|
|
|
184
184
|
responseUrl: string;
|
|
185
185
|
cancelUrl: string;
|
|
186
186
|
output: VideoToolOutputSpec;
|
|
187
|
+
/** Epoch ms when the kit submitted the job; the result's usage `latencyMs` is measured from it. */
|
|
188
|
+
submittedAt?: number;
|
|
187
189
|
}
|
|
188
190
|
type VideoToolStatus = "queued" | "running" | "completed";
|
|
189
191
|
interface VideoToolResult {
|
|
@@ -523,6 +525,13 @@ interface UsageEvent {
|
|
|
523
525
|
inputTokens?: number;
|
|
524
526
|
outputTokens?: number;
|
|
525
527
|
reportedCostUsd?: number;
|
|
528
|
+
/**
|
|
529
|
+
* Wall time of the kit call that produced this event, in ms: from dispatch to the
|
|
530
|
+
* provider's final answer (a video's polling included; a multi-step text call's tool
|
|
531
|
+
* steps included). Absent only where the kit never saw the start (a video tool whose
|
|
532
|
+
* submission carries no `submittedAt`).
|
|
533
|
+
*/
|
|
534
|
+
latencyMs?: number;
|
|
526
535
|
raw?: unknown;
|
|
527
536
|
}
|
|
528
537
|
type ProviderKeyName = "openai" | "anthropic" | "google" | "xai" | "perplexity" | "deepseek" | "moonshot" | "minimax" | "ark" | "fal" | "replicate" | "prodia" | "higgsfield" | "cloudflare";
|
|
@@ -605,7 +614,9 @@ interface CallContext {
|
|
|
605
614
|
|
|
606
615
|
/** Provider body or the lifted detail (Gemini blockReason, fal body.detail). */
|
|
607
616
|
type ProviderErrorBody = string | JsonValue;
|
|
608
|
-
type ModelKitErrorCode = "unknown_model" | "unsupported_option" | "missing_input" | "content_blocked" | "provider_rejected"
|
|
617
|
+
type ModelKitErrorCode = "unknown_model" | "unsupported_option" | "missing_input" | "content_blocked" | "provider_rejected"
|
|
618
|
+
/** The provider account is out of credit or quota (HTTP 402 and its body spellings). Never retried. */
|
|
619
|
+
| "provider_billing" | "timeout" | "auth" | "network" | "rate_limited";
|
|
609
620
|
interface ModelKitErrorInit {
|
|
610
621
|
code: ModelKitErrorCode;
|
|
611
622
|
message: string;
|
|
@@ -1230,7 +1241,7 @@ declare function keysFromEnv(env: NodeJS.ProcessEnv, prefix?: string): ProviderK
|
|
|
1230
1241
|
|
|
1231
1242
|
/**
|
|
1232
1243
|
* One classifier for every adapter. Never retry safety blocks,
|
|
1233
|
-
* content_policy_violation, or 4xx other than 429. Retry 429, 5xx, timeouts
|
|
1244
|
+
* content_policy_violation, billing failures, or 4xx other than 429. Retry 429, 5xx, timeouts
|
|
1234
1245
|
* and network failures. Adapters must not stack their own retry loop on top.
|
|
1235
1246
|
*/
|
|
1236
1247
|
declare function classifyHttpError(status: number | undefined, body: ProviderErrorBody, provider: string, model?: string): ModelKitError;
|
package/dist/index.d.ts
CHANGED
|
@@ -184,6 +184,8 @@ interface VideoToolSubmission {
|
|
|
184
184
|
responseUrl: string;
|
|
185
185
|
cancelUrl: string;
|
|
186
186
|
output: VideoToolOutputSpec;
|
|
187
|
+
/** Epoch ms when the kit submitted the job; the result's usage `latencyMs` is measured from it. */
|
|
188
|
+
submittedAt?: number;
|
|
187
189
|
}
|
|
188
190
|
type VideoToolStatus = "queued" | "running" | "completed";
|
|
189
191
|
interface VideoToolResult {
|
|
@@ -523,6 +525,13 @@ interface UsageEvent {
|
|
|
523
525
|
inputTokens?: number;
|
|
524
526
|
outputTokens?: number;
|
|
525
527
|
reportedCostUsd?: number;
|
|
528
|
+
/**
|
|
529
|
+
* Wall time of the kit call that produced this event, in ms: from dispatch to the
|
|
530
|
+
* provider's final answer (a video's polling included; a multi-step text call's tool
|
|
531
|
+
* steps included). Absent only where the kit never saw the start (a video tool whose
|
|
532
|
+
* submission carries no `submittedAt`).
|
|
533
|
+
*/
|
|
534
|
+
latencyMs?: number;
|
|
526
535
|
raw?: unknown;
|
|
527
536
|
}
|
|
528
537
|
type ProviderKeyName = "openai" | "anthropic" | "google" | "xai" | "perplexity" | "deepseek" | "moonshot" | "minimax" | "ark" | "fal" | "replicate" | "prodia" | "higgsfield" | "cloudflare";
|
|
@@ -605,7 +614,9 @@ interface CallContext {
|
|
|
605
614
|
|
|
606
615
|
/** Provider body or the lifted detail (Gemini blockReason, fal body.detail). */
|
|
607
616
|
type ProviderErrorBody = string | JsonValue;
|
|
608
|
-
type ModelKitErrorCode = "unknown_model" | "unsupported_option" | "missing_input" | "content_blocked" | "provider_rejected"
|
|
617
|
+
type ModelKitErrorCode = "unknown_model" | "unsupported_option" | "missing_input" | "content_blocked" | "provider_rejected"
|
|
618
|
+
/** The provider account is out of credit or quota (HTTP 402 and its body spellings). Never retried. */
|
|
619
|
+
| "provider_billing" | "timeout" | "auth" | "network" | "rate_limited";
|
|
609
620
|
interface ModelKitErrorInit {
|
|
610
621
|
code: ModelKitErrorCode;
|
|
611
622
|
message: string;
|
|
@@ -1230,7 +1241,7 @@ declare function keysFromEnv(env: NodeJS.ProcessEnv, prefix?: string): ProviderK
|
|
|
1230
1241
|
|
|
1231
1242
|
/**
|
|
1232
1243
|
* One classifier for every adapter. Never retry safety blocks,
|
|
1233
|
-
* content_policy_violation, or 4xx other than 429. Retry 429, 5xx, timeouts
|
|
1244
|
+
* content_policy_violation, billing failures, or 4xx other than 429. Retry 429, 5xx, timeouts
|
|
1234
1245
|
* and network failures. Adapters must not stack their own retry loop on top.
|
|
1235
1246
|
*/
|
|
1236
1247
|
declare function classifyHttpError(status: number | undefined, body: ProviderErrorBody, provider: string, model?: string): ModelKitError;
|
package/dist/index.js
CHANGED
|
@@ -222,35 +222,43 @@ var IMAGE_MODELS = [
|
|
|
222
222
|
GEMINI_PROMPT_MAX_CHARS,
|
|
223
223
|
NANO_BANANA_2_1_RATIOS
|
|
224
224
|
),
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
225
|
+
// Google retired the -preview endpoints for the GA ids; the catalog ids stay because they
|
|
226
|
+
// are pricing keys and stored model ids.
|
|
227
|
+
{
|
|
228
|
+
...geminiImage(
|
|
229
|
+
"gemini-3-pro-image-preview",
|
|
230
|
+
"Nano Banana Pro",
|
|
231
|
+
["nb-pro"],
|
|
232
|
+
["1K", "2K", "4K"],
|
|
233
|
+
{
|
|
234
|
+
provider: "google",
|
|
235
|
+
description: "Create stunning, production-quality visuals with exceptional realism, detail, and typography. Best for campaigns, e-commerce, product photography, and hero creatives.",
|
|
236
|
+
logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/192485d2-a76a-4657-9c06-930b2c70badd_compressed.png"
|
|
237
|
+
},
|
|
238
|
+
["cowork", "space_builder"],
|
|
239
|
+
{ images: 14 },
|
|
240
|
+
GEMINI_PROMPT_MAX_CHARS
|
|
241
|
+
),
|
|
242
|
+
providerModelId: "gemini-3-pro-image"
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
...geminiImage(
|
|
246
|
+
"gemini-3.1-flash-image-preview",
|
|
247
|
+
"Nano Banana 2",
|
|
248
|
+
["nb-2"],
|
|
249
|
+
// Flash 3.1 is the only Gemini image model with the 512 tier.
|
|
250
|
+
["512", "1K", "2K", "4K"],
|
|
251
|
+
{
|
|
252
|
+
provider: "google",
|
|
253
|
+
description: "Generate high-quality images at speed. Perfect for brainstorming, concept boards, concept testing, creative exploration, and large batch workflows.",
|
|
254
|
+
logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/192485d2-a76a-4657-9c06-930b2c70badd_compressed.png"
|
|
255
|
+
},
|
|
256
|
+
["cowork", "space_builder"],
|
|
257
|
+
{ images: 14 },
|
|
258
|
+
GEMINI_PROMPT_MAX_CHARS
|
|
259
|
+
),
|
|
260
|
+
providerModelId: "gemini-3.1-flash-image"
|
|
261
|
+
},
|
|
254
262
|
geminiImage(
|
|
255
263
|
"gemini-3.1-flash-lite-image",
|
|
256
264
|
"Nano Banana Lite",
|
|
@@ -1384,6 +1392,7 @@ var OMNI_PROMPT = { referenceSyntax: "caption", maxChars: 5e4 };
|
|
|
1384
1392
|
var BYTEDANCE_LOGO = "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/3bba5d81-4e57-4e71-911b-cdfa05acca2c_compressed.png";
|
|
1385
1393
|
var GOOGLE_LOGO2 = "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/192485d2-a76a-4657-9c06-930b2c70badd_compressed.png";
|
|
1386
1394
|
var VIDEO_MODELS = [
|
|
1395
|
+
// Google shuts down the Veo 3.1 previews and Omni Flash 1.0 on 2026-10-22.
|
|
1387
1396
|
{
|
|
1388
1397
|
id: "veo-3.1",
|
|
1389
1398
|
aliases: [
|
|
@@ -1396,8 +1405,9 @@ var VIDEO_MODELS = [
|
|
|
1396
1405
|
type: "video",
|
|
1397
1406
|
adapter: "google-genai",
|
|
1398
1407
|
providerModelId: "veo-3.1-generate-preview",
|
|
1399
|
-
lifecycle: "
|
|
1400
|
-
|
|
1408
|
+
lifecycle: "deprecated",
|
|
1409
|
+
replacedBy: "gemini-omni-1.1-flash",
|
|
1410
|
+
exposure: [],
|
|
1401
1411
|
constraints: {
|
|
1402
1412
|
aspectRatios: [...OMNI_RATIOS],
|
|
1403
1413
|
resolutions: ["720p", "1080p", "4k"],
|
|
@@ -1432,7 +1442,8 @@ var VIDEO_MODELS = [
|
|
|
1432
1442
|
type: "video",
|
|
1433
1443
|
adapter: "google-genai",
|
|
1434
1444
|
providerModelId: "veo-3.1-fast-generate-preview",
|
|
1435
|
-
lifecycle: "
|
|
1445
|
+
lifecycle: "deprecated",
|
|
1446
|
+
replacedBy: "gemini-omni-1.1-flash",
|
|
1436
1447
|
exposure: [],
|
|
1437
1448
|
constraints: {
|
|
1438
1449
|
aspectRatios: [...OMNI_RATIOS],
|
|
@@ -1462,7 +1473,8 @@ var VIDEO_MODELS = [
|
|
|
1462
1473
|
type: "video",
|
|
1463
1474
|
adapter: "google-genai",
|
|
1464
1475
|
providerModelId: "veo-3.1-lite-generate-preview",
|
|
1465
|
-
lifecycle: "
|
|
1476
|
+
lifecycle: "deprecated",
|
|
1477
|
+
replacedBy: "gemini-omni-1.1-flash",
|
|
1466
1478
|
exposure: [],
|
|
1467
1479
|
constraints: {
|
|
1468
1480
|
aspectRatios: [...OMNI_RATIOS],
|
|
@@ -1493,8 +1505,9 @@ var VIDEO_MODELS = [
|
|
|
1493
1505
|
type: "video",
|
|
1494
1506
|
adapter: "google-genai",
|
|
1495
1507
|
providerModelId: "gemini-omni-flash-preview",
|
|
1496
|
-
lifecycle: "
|
|
1497
|
-
|
|
1508
|
+
lifecycle: "deprecated",
|
|
1509
|
+
replacedBy: "gemini-omni-1.1-flash",
|
|
1510
|
+
exposure: [],
|
|
1498
1511
|
constraints: {
|
|
1499
1512
|
// 1.0 rejects `resolution`; it renders 720p. No defaults: the adapter
|
|
1500
1513
|
// sends ratio and duration only when the caller set them, so a
|
|
@@ -2049,7 +2062,8 @@ var VIDEO_MODELS = [
|
|
|
2049
2062
|
},
|
|
2050
2063
|
defaults: {},
|
|
2051
2064
|
usage: { ...VIDEO_USAGE },
|
|
2052
|
-
|
|
2065
|
+
// Higgsfield bills DoP per generation: a fixed-length clip with no duration knob.
|
|
2066
|
+
pricingKind: "flat",
|
|
2053
2067
|
display: {
|
|
2054
2068
|
provider: "higgsfield",
|
|
2055
2069
|
description: "Higgsfield DOP image-to-video model; animates a required first-frame image from a text prompt with an optional last-frame image and motion controls."
|
|
@@ -3285,6 +3299,36 @@ function describeThrown(cause) {
|
|
|
3285
3299
|
|
|
3286
3300
|
// src/retry.ts
|
|
3287
3301
|
var textBody = z6.string();
|
|
3302
|
+
var BILLING_CODES = /* @__PURE__ */ new Set([
|
|
3303
|
+
"insufficient_quota",
|
|
3304
|
+
"billing_hard_limit_reached",
|
|
3305
|
+
"billing_not_active",
|
|
3306
|
+
"payment_required",
|
|
3307
|
+
"insufficient_balance",
|
|
3308
|
+
"insufficient_credits",
|
|
3309
|
+
"insufficient_credit"
|
|
3310
|
+
]);
|
|
3311
|
+
var errorCodes = z6.object({
|
|
3312
|
+
code: z6.string().optional(),
|
|
3313
|
+
type: z6.string().optional(),
|
|
3314
|
+
error: z6.object({ code: z6.string().optional(), type: z6.string().optional() }).optional()
|
|
3315
|
+
});
|
|
3316
|
+
var BILLING_TEXT = /insufficient_quota|payment[ _]required|exhausted balance|insufficient (?:credits?|balance|funds)|billing_hard_limit/i;
|
|
3317
|
+
var BILLING_TEXT_STATUSES = /* @__PURE__ */ new Set([403, 429]);
|
|
3318
|
+
function billingCode(body) {
|
|
3319
|
+
const parsed = errorCodes.safeParse(body);
|
|
3320
|
+
if (!parsed.success) return false;
|
|
3321
|
+
const { code, type, error } = parsed.data;
|
|
3322
|
+
return [code, type, error?.code, error?.type].some(
|
|
3323
|
+
(value) => value !== void 0 && BILLING_CODES.has(value.toLowerCase())
|
|
3324
|
+
);
|
|
3325
|
+
}
|
|
3326
|
+
function isBillingFailure(status, body, text2) {
|
|
3327
|
+
if (status === 402) return true;
|
|
3328
|
+
if (status === void 0 || status < 400 || status >= 500) return false;
|
|
3329
|
+
if (billingCode(body)) return true;
|
|
3330
|
+
return BILLING_TEXT_STATUSES.has(status) && BILLING_TEXT.test(text2);
|
|
3331
|
+
}
|
|
3288
3332
|
function classifyHttpError(status, body, provider, model) {
|
|
3289
3333
|
const asText = textBody.safeParse(body);
|
|
3290
3334
|
const text2 = asText.success ? asText.data : JSON.stringify(body);
|
|
@@ -3293,6 +3337,7 @@ function classifyHttpError(status, body, provider, model) {
|
|
|
3293
3337
|
);
|
|
3294
3338
|
let code = "provider_rejected";
|
|
3295
3339
|
if (blocked) code = "content_blocked";
|
|
3340
|
+
else if (isBillingFailure(status, body, text2)) code = "provider_billing";
|
|
3296
3341
|
else if (status === 401 || status === 403) code = "auth";
|
|
3297
3342
|
else if (status === 429) code = "rate_limited";
|
|
3298
3343
|
else if (status === 408 || status === 504) code = "timeout";
|
|
@@ -3355,12 +3400,11 @@ function sleep(ms, signal) {
|
|
|
3355
3400
|
rejectAborted();
|
|
3356
3401
|
return;
|
|
3357
3402
|
}
|
|
3358
|
-
let timer;
|
|
3359
3403
|
const onAbort = () => {
|
|
3360
|
-
|
|
3404
|
+
clearTimeout(timer);
|
|
3361
3405
|
rejectAborted();
|
|
3362
3406
|
};
|
|
3363
|
-
timer = setTimeout(() => {
|
|
3407
|
+
const timer = setTimeout(() => {
|
|
3364
3408
|
signal?.removeEventListener("abort", onAbort);
|
|
3365
3409
|
resolve();
|
|
3366
3410
|
}, ms);
|
|
@@ -9150,6 +9194,13 @@ function createModelKit(config, adapters) {
|
|
|
9150
9194
|
model: model.id
|
|
9151
9195
|
});
|
|
9152
9196
|
}
|
|
9197
|
+
function timed(event, startedAt) {
|
|
9198
|
+
if (event.latencyMs !== void 0) return event;
|
|
9199
|
+
return { ...event, latencyMs: Math.max(0, Date.now() - startedAt) };
|
|
9200
|
+
}
|
|
9201
|
+
function textTimed(event, stepCount, startedAt) {
|
|
9202
|
+
return stepCount === 1 ? timed(event, startedAt) : event;
|
|
9203
|
+
}
|
|
9153
9204
|
async function emit(event) {
|
|
9154
9205
|
try {
|
|
9155
9206
|
await config.onUsage?.(event);
|
|
@@ -9233,17 +9284,21 @@ function createModelKit(config, adapters) {
|
|
|
9233
9284
|
const abortSignal = combineSignals(req.abortSignal, call.signal);
|
|
9234
9285
|
if (abortSignal) options.abortSignal = abortSignal;
|
|
9235
9286
|
if (call.maxRetries !== void 0) options.maxRetries = call.maxRetries;
|
|
9287
|
+
const startedAt = Date.now();
|
|
9236
9288
|
const result = await aiGenerateImage(options);
|
|
9237
9289
|
const images = result.images.map(
|
|
9238
9290
|
(file) => toGeneratedImage({ bytes: file.uint8Array, mime: file.mediaType })
|
|
9239
9291
|
);
|
|
9240
|
-
const usage2 =
|
|
9241
|
-
|
|
9242
|
-
|
|
9243
|
-
|
|
9244
|
-
|
|
9245
|
-
|
|
9246
|
-
|
|
9292
|
+
const usage2 = timed(
|
|
9293
|
+
{
|
|
9294
|
+
model: model.modelId,
|
|
9295
|
+
provider: model.provider,
|
|
9296
|
+
modality: "IMAGE",
|
|
9297
|
+
unit: "images",
|
|
9298
|
+
quantity: images.length
|
|
9299
|
+
},
|
|
9300
|
+
startedAt
|
|
9301
|
+
);
|
|
9247
9302
|
await emit(usage2);
|
|
9248
9303
|
return { image: images[0], images, usage: usage2, raw: result, warnings };
|
|
9249
9304
|
}
|
|
@@ -9316,18 +9371,22 @@ function createModelKit(config, adapters) {
|
|
|
9316
9371
|
if (providerOptions) options.providerOptions = providerOptions;
|
|
9317
9372
|
if (abortSignal) options.abortSignal = abortSignal;
|
|
9318
9373
|
logCoercions(logger, model.modelId, warnings);
|
|
9374
|
+
const startedAt = Date.now();
|
|
9319
9375
|
const pending = aiGenerateVideo(options);
|
|
9320
9376
|
let settled;
|
|
9321
9377
|
let failed = false;
|
|
9322
9378
|
const done = pending.then(async (result) => {
|
|
9323
|
-
const usage2 =
|
|
9324
|
-
|
|
9325
|
-
|
|
9326
|
-
|
|
9327
|
-
|
|
9328
|
-
|
|
9329
|
-
|
|
9330
|
-
|
|
9379
|
+
const usage2 = timed(
|
|
9380
|
+
{
|
|
9381
|
+
model: model.modelId,
|
|
9382
|
+
provider: model.provider,
|
|
9383
|
+
modality: "VIDEO",
|
|
9384
|
+
unit: "seconds",
|
|
9385
|
+
quantity: seconds2 ?? 0,
|
|
9386
|
+
...seconds2 !== void 0 && { durationSeconds: seconds2 }
|
|
9387
|
+
},
|
|
9388
|
+
startedAt
|
|
9389
|
+
);
|
|
9331
9390
|
settled = {
|
|
9332
9391
|
video: { bytes: result.video.uint8Array, mime: result.video.mediaType },
|
|
9333
9392
|
usage: usage2,
|
|
@@ -9384,8 +9443,12 @@ function createModelKit(config, adapters) {
|
|
|
9384
9443
|
message: `${adapter.id} cannot generate images`,
|
|
9385
9444
|
model: model.id
|
|
9386
9445
|
});
|
|
9446
|
+
const startedAt = Date.now();
|
|
9387
9447
|
const result = await adapter.generateImage(request, ctx);
|
|
9388
|
-
const usage2 =
|
|
9448
|
+
const usage2 = timed(
|
|
9449
|
+
{ ...result.usage, model: model.id, unit: model.usage.unit },
|
|
9450
|
+
startedAt
|
|
9451
|
+
);
|
|
9389
9452
|
await emit(usage2);
|
|
9390
9453
|
const images = result.images.map(toGeneratedImage);
|
|
9391
9454
|
const first = images[0];
|
|
@@ -9428,6 +9491,7 @@ function createModelKit(config, adapters) {
|
|
|
9428
9491
|
message: `${adapter.id} cannot generate video`,
|
|
9429
9492
|
model: model.id
|
|
9430
9493
|
});
|
|
9494
|
+
const startedAt = Date.now();
|
|
9431
9495
|
const job = await adapter.generateVideo(request, ctx);
|
|
9432
9496
|
const result = job.result.bind(job);
|
|
9433
9497
|
let settled;
|
|
@@ -9437,11 +9501,14 @@ function createModelKit(config, adapters) {
|
|
|
9437
9501
|
result(opts) {
|
|
9438
9502
|
if (settled) return settled;
|
|
9439
9503
|
const pending = result(opts).then(
|
|
9440
|
-
(out) =>
|
|
9441
|
-
|
|
9442
|
-
|
|
9443
|
-
|
|
9444
|
-
|
|
9504
|
+
async (out) => {
|
|
9505
|
+
const usage2 = timed(
|
|
9506
|
+
{ ...out.usage, model: model.id, unit: model.usage.unit },
|
|
9507
|
+
startedAt
|
|
9508
|
+
);
|
|
9509
|
+
await emit(usage2);
|
|
9510
|
+
return { ...out, usage: usage2 };
|
|
9511
|
+
},
|
|
9445
9512
|
(cause) => {
|
|
9446
9513
|
settled = void 0;
|
|
9447
9514
|
throw cause;
|
|
@@ -9478,9 +9545,14 @@ function createModelKit(config, adapters) {
|
|
|
9478
9545
|
model: model.id
|
|
9479
9546
|
});
|
|
9480
9547
|
}
|
|
9548
|
+
const startedAt = Date.now();
|
|
9481
9549
|
const result = await adapter.generateAudio(resolved, ctx);
|
|
9482
|
-
|
|
9483
|
-
|
|
9550
|
+
const usage2 = timed(
|
|
9551
|
+
{ ...result.usage, model: model.id, unit: model.usage.unit },
|
|
9552
|
+
startedAt
|
|
9553
|
+
);
|
|
9554
|
+
await emit(usage2);
|
|
9555
|
+
return { ...result, usage: usage2 };
|
|
9484
9556
|
},
|
|
9485
9557
|
async prepareMediaPart(modelId, ref, mediaType, call = {}) {
|
|
9486
9558
|
mediaRetryOptions(call);
|
|
@@ -9509,11 +9581,13 @@ function createModelKit(config, adapters) {
|
|
|
9509
9581
|
const { webhookUrl, ...rest } = call;
|
|
9510
9582
|
const { adapter, ctx } = videoToolTarget(req.model, rest);
|
|
9511
9583
|
if (!adapter.submitVideoTool) throw noVideoTools(adapter, ctx.model);
|
|
9512
|
-
|
|
9584
|
+
const submittedAt = Date.now();
|
|
9585
|
+
const submission = await adapter.submitVideoTool(
|
|
9513
9586
|
req,
|
|
9514
9587
|
ctx,
|
|
9515
9588
|
webhookUrl !== void 0 ? { webhookUrl } : {}
|
|
9516
9589
|
);
|
|
9590
|
+
return { ...submission, submittedAt };
|
|
9517
9591
|
},
|
|
9518
9592
|
async videoToolStatus(sub, call = {}) {
|
|
9519
9593
|
const { adapter, ctx } = videoToolTarget(sub.model, call);
|
|
@@ -9525,8 +9599,10 @@ function createModelKit(config, adapters) {
|
|
|
9525
9599
|
const { adapter, ctx } = videoToolTarget(sub.model, rest);
|
|
9526
9600
|
if (!adapter.videoToolResult) throw noVideoTools(adapter, ctx.model);
|
|
9527
9601
|
const result = await adapter.videoToolResult(sub, ctx, webhook);
|
|
9528
|
-
|
|
9529
|
-
|
|
9602
|
+
const base = { ...result.usage, model: ctx.model.id, unit: ctx.model.usage.unit };
|
|
9603
|
+
const usage2 = sub.submittedAt === void 0 ? base : timed(base, sub.submittedAt);
|
|
9604
|
+
await emit(usage2);
|
|
9605
|
+
return { ...result, usage: usage2 };
|
|
9530
9606
|
},
|
|
9531
9607
|
async cancelVideoTool(sub, call = {}) {
|
|
9532
9608
|
const { adapter, ctx } = videoToolTarget(sub.model, call);
|
|
@@ -9548,6 +9624,7 @@ function createModelKit(config, adapters) {
|
|
|
9548
9624
|
(model) => textTarget(model, call),
|
|
9549
9625
|
options.providerOptions
|
|
9550
9626
|
);
|
|
9627
|
+
const startedAt = Date.now();
|
|
9551
9628
|
const result = await aiGenerateText2({
|
|
9552
9629
|
...options,
|
|
9553
9630
|
...textAbortOptions(options.abortSignal, call.signal),
|
|
@@ -9557,7 +9634,8 @@ function createModelKit(config, adapters) {
|
|
|
9557
9634
|
options.prepareStep ?? options.experimental_prepareStep
|
|
9558
9635
|
)
|
|
9559
9636
|
});
|
|
9560
|
-
for (const event of steps.usage(result.steps))
|
|
9637
|
+
for (const event of steps.usage(result.steps))
|
|
9638
|
+
await emit(textTimed(withRowUnit(event), result.steps.length, startedAt));
|
|
9561
9639
|
return result;
|
|
9562
9640
|
},
|
|
9563
9641
|
streamText(options, call = {}) {
|
|
@@ -9568,6 +9646,7 @@ function createModelKit(config, adapters) {
|
|
|
9568
9646
|
options.providerOptions
|
|
9569
9647
|
);
|
|
9570
9648
|
const callerOnFinish = options.onFinish;
|
|
9649
|
+
const startedAt = Date.now();
|
|
9571
9650
|
return aiStreamText2({
|
|
9572
9651
|
...options,
|
|
9573
9652
|
...textAbortOptions(options.abortSignal, call.signal),
|
|
@@ -9577,7 +9656,8 @@ function createModelKit(config, adapters) {
|
|
|
9577
9656
|
options.prepareStep ?? options.experimental_prepareStep
|
|
9578
9657
|
),
|
|
9579
9658
|
onFinish: async (event) => {
|
|
9580
|
-
for (const usage2 of steps.usage(event.steps))
|
|
9659
|
+
for (const usage2 of steps.usage(event.steps))
|
|
9660
|
+
await emit(textTimed(withRowUnit(usage2), event.steps.length, startedAt));
|
|
9581
9661
|
await callerOnFinish?.(event);
|
|
9582
9662
|
}
|
|
9583
9663
|
});
|
|
@@ -9590,15 +9670,22 @@ function createModelKit(config, adapters) {
|
|
|
9590
9670
|
model: languageModel2,
|
|
9591
9671
|
providerOptions: mergeTextProviderOptions(entry, options.providerOptions)
|
|
9592
9672
|
};
|
|
9673
|
+
const startedAt = Date.now();
|
|
9593
9674
|
const result = await aiGenerateObject2(sdkOptions);
|
|
9594
9675
|
await emit(
|
|
9595
|
-
|
|
9676
|
+
timed(
|
|
9677
|
+
withRowUnit(
|
|
9678
|
+
textUsageEvent(entry, provider, result.usage, result.providerMetadata)
|
|
9679
|
+
),
|
|
9680
|
+
startedAt
|
|
9681
|
+
)
|
|
9596
9682
|
);
|
|
9597
9683
|
return result;
|
|
9598
9684
|
},
|
|
9599
9685
|
streamObject(options, call = {}) {
|
|
9600
9686
|
const { entry, languageModel: languageModel2, provider } = textTarget(options.model, call);
|
|
9601
9687
|
const callerOnFinish = options.onFinish;
|
|
9688
|
+
const startedAt = Date.now();
|
|
9602
9689
|
const sdkOptions = {
|
|
9603
9690
|
...options,
|
|
9604
9691
|
...textAbortOptions(options.abortSignal, call.signal),
|
|
@@ -9606,8 +9693,16 @@ function createModelKit(config, adapters) {
|
|
|
9606
9693
|
providerOptions: mergeTextProviderOptions(entry, options.providerOptions),
|
|
9607
9694
|
onFinish: async (event) => {
|
|
9608
9695
|
await emit(
|
|
9609
|
-
|
|
9610
|
-
|
|
9696
|
+
timed(
|
|
9697
|
+
withRowUnit(
|
|
9698
|
+
textUsageEvent(
|
|
9699
|
+
entry,
|
|
9700
|
+
provider,
|
|
9701
|
+
event.usage,
|
|
9702
|
+
event.providerMetadata
|
|
9703
|
+
)
|
|
9704
|
+
),
|
|
9705
|
+
startedAt
|
|
9611
9706
|
)
|
|
9612
9707
|
);
|
|
9613
9708
|
await callerOnFinish?.(event);
|