@shop-os/modelkit 0.3.7 → 0.4.0
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 +23 -0
- package/README.md +2 -2
- package/dist/catalog.cjs +3 -1
- 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 +3 -1
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +118 -35
- 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 +118 -35
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -929,7 +929,9 @@ var OTHER_MODELS = [
|
|
|
929
929
|
},
|
|
930
930
|
{
|
|
931
931
|
id: "bg-remove",
|
|
932
|
-
|
|
932
|
+
// Task ids the two emitters report on usage events (trigger-workflows,
|
|
933
|
+
// vibe-triggers); the usage price lookup resolves them to this row.
|
|
934
|
+
aliases: ["prodia-background-remover", "prodia-remove-background"],
|
|
933
935
|
label: "Background Remover",
|
|
934
936
|
type: "bg-remove",
|
|
935
937
|
adapter: "prodia",
|
|
@@ -3402,6 +3404,36 @@ function describeThrown(cause) {
|
|
|
3402
3404
|
|
|
3403
3405
|
// src/retry.ts
|
|
3404
3406
|
var textBody = import_zod6.z.string();
|
|
3407
|
+
var BILLING_CODES = /* @__PURE__ */ new Set([
|
|
3408
|
+
"insufficient_quota",
|
|
3409
|
+
"billing_hard_limit_reached",
|
|
3410
|
+
"billing_not_active",
|
|
3411
|
+
"payment_required",
|
|
3412
|
+
"insufficient_balance",
|
|
3413
|
+
"insufficient_credits",
|
|
3414
|
+
"insufficient_credit"
|
|
3415
|
+
]);
|
|
3416
|
+
var errorCodes = import_zod6.z.object({
|
|
3417
|
+
code: import_zod6.z.string().optional(),
|
|
3418
|
+
type: import_zod6.z.string().optional(),
|
|
3419
|
+
error: import_zod6.z.object({ code: import_zod6.z.string().optional(), type: import_zod6.z.string().optional() }).optional()
|
|
3420
|
+
});
|
|
3421
|
+
var BILLING_TEXT = /insufficient_quota|payment[ _]required|exhausted balance|insufficient (?:credits?|balance|funds)|billing_hard_limit/i;
|
|
3422
|
+
var BILLING_TEXT_STATUSES = /* @__PURE__ */ new Set([403, 429]);
|
|
3423
|
+
function billingCode(body) {
|
|
3424
|
+
const parsed = errorCodes.safeParse(body);
|
|
3425
|
+
if (!parsed.success) return false;
|
|
3426
|
+
const { code, type, error } = parsed.data;
|
|
3427
|
+
return [code, type, error?.code, error?.type].some(
|
|
3428
|
+
(value) => value !== void 0 && BILLING_CODES.has(value.toLowerCase())
|
|
3429
|
+
);
|
|
3430
|
+
}
|
|
3431
|
+
function isBillingFailure(status, body, text2) {
|
|
3432
|
+
if (status === 402) return true;
|
|
3433
|
+
if (status === void 0 || status < 400 || status >= 500) return false;
|
|
3434
|
+
if (billingCode(body)) return true;
|
|
3435
|
+
return BILLING_TEXT_STATUSES.has(status) && BILLING_TEXT.test(text2);
|
|
3436
|
+
}
|
|
3405
3437
|
function classifyHttpError(status, body, provider, model) {
|
|
3406
3438
|
const asText = textBody.safeParse(body);
|
|
3407
3439
|
const text2 = asText.success ? asText.data : JSON.stringify(body);
|
|
@@ -3410,6 +3442,7 @@ function classifyHttpError(status, body, provider, model) {
|
|
|
3410
3442
|
);
|
|
3411
3443
|
let code = "provider_rejected";
|
|
3412
3444
|
if (blocked) code = "content_blocked";
|
|
3445
|
+
else if (isBillingFailure(status, body, text2)) code = "provider_billing";
|
|
3413
3446
|
else if (status === 401 || status === 403) code = "auth";
|
|
3414
3447
|
else if (status === 429) code = "rate_limited";
|
|
3415
3448
|
else if (status === 408 || status === 504) code = "timeout";
|
|
@@ -3472,12 +3505,11 @@ function sleep(ms, signal) {
|
|
|
3472
3505
|
rejectAborted();
|
|
3473
3506
|
return;
|
|
3474
3507
|
}
|
|
3475
|
-
let timer;
|
|
3476
3508
|
const onAbort = () => {
|
|
3477
|
-
|
|
3509
|
+
clearTimeout(timer);
|
|
3478
3510
|
rejectAborted();
|
|
3479
3511
|
};
|
|
3480
|
-
timer = setTimeout(() => {
|
|
3512
|
+
const timer = setTimeout(() => {
|
|
3481
3513
|
signal?.removeEventListener("abort", onAbort);
|
|
3482
3514
|
resolve();
|
|
3483
3515
|
}, ms);
|
|
@@ -9258,6 +9290,13 @@ function createModelKit(config, adapters) {
|
|
|
9258
9290
|
model: model.id
|
|
9259
9291
|
});
|
|
9260
9292
|
}
|
|
9293
|
+
function timed(event, startedAt) {
|
|
9294
|
+
if (event.latencyMs !== void 0) return event;
|
|
9295
|
+
return { ...event, latencyMs: Math.max(0, Date.now() - startedAt) };
|
|
9296
|
+
}
|
|
9297
|
+
function textTimed(event, stepCount, startedAt) {
|
|
9298
|
+
return stepCount === 1 ? timed(event, startedAt) : event;
|
|
9299
|
+
}
|
|
9261
9300
|
async function emit(event) {
|
|
9262
9301
|
try {
|
|
9263
9302
|
await config.onUsage?.(event);
|
|
@@ -9341,17 +9380,21 @@ function createModelKit(config, adapters) {
|
|
|
9341
9380
|
const abortSignal = combineSignals(req.abortSignal, call.signal);
|
|
9342
9381
|
if (abortSignal) options.abortSignal = abortSignal;
|
|
9343
9382
|
if (call.maxRetries !== void 0) options.maxRetries = call.maxRetries;
|
|
9383
|
+
const startedAt = Date.now();
|
|
9344
9384
|
const result = await (0, import_ai5.generateImage)(options);
|
|
9345
9385
|
const images = result.images.map(
|
|
9346
9386
|
(file) => toGeneratedImage({ bytes: file.uint8Array, mime: file.mediaType })
|
|
9347
9387
|
);
|
|
9348
|
-
const usage2 =
|
|
9349
|
-
|
|
9350
|
-
|
|
9351
|
-
|
|
9352
|
-
|
|
9353
|
-
|
|
9354
|
-
|
|
9388
|
+
const usage2 = timed(
|
|
9389
|
+
{
|
|
9390
|
+
model: model.modelId,
|
|
9391
|
+
provider: model.provider,
|
|
9392
|
+
modality: "IMAGE",
|
|
9393
|
+
unit: "images",
|
|
9394
|
+
quantity: images.length
|
|
9395
|
+
},
|
|
9396
|
+
startedAt
|
|
9397
|
+
);
|
|
9355
9398
|
await emit(usage2);
|
|
9356
9399
|
return { image: images[0], images, usage: usage2, raw: result, warnings };
|
|
9357
9400
|
}
|
|
@@ -9424,18 +9467,22 @@ function createModelKit(config, adapters) {
|
|
|
9424
9467
|
if (providerOptions) options.providerOptions = providerOptions;
|
|
9425
9468
|
if (abortSignal) options.abortSignal = abortSignal;
|
|
9426
9469
|
logCoercions(logger, model.modelId, warnings);
|
|
9470
|
+
const startedAt = Date.now();
|
|
9427
9471
|
const pending = (0, import_ai5.experimental_generateVideo)(options);
|
|
9428
9472
|
let settled;
|
|
9429
9473
|
let failed = false;
|
|
9430
9474
|
const done = pending.then(async (result) => {
|
|
9431
|
-
const usage2 =
|
|
9432
|
-
|
|
9433
|
-
|
|
9434
|
-
|
|
9435
|
-
|
|
9436
|
-
|
|
9437
|
-
|
|
9438
|
-
|
|
9475
|
+
const usage2 = timed(
|
|
9476
|
+
{
|
|
9477
|
+
model: model.modelId,
|
|
9478
|
+
provider: model.provider,
|
|
9479
|
+
modality: "VIDEO",
|
|
9480
|
+
unit: "seconds",
|
|
9481
|
+
quantity: seconds2 ?? 0,
|
|
9482
|
+
...seconds2 !== void 0 && { durationSeconds: seconds2 }
|
|
9483
|
+
},
|
|
9484
|
+
startedAt
|
|
9485
|
+
);
|
|
9439
9486
|
settled = {
|
|
9440
9487
|
video: { bytes: result.video.uint8Array, mime: result.video.mediaType },
|
|
9441
9488
|
usage: usage2,
|
|
@@ -9492,8 +9539,12 @@ function createModelKit(config, adapters) {
|
|
|
9492
9539
|
message: `${adapter.id} cannot generate images`,
|
|
9493
9540
|
model: model.id
|
|
9494
9541
|
});
|
|
9542
|
+
const startedAt = Date.now();
|
|
9495
9543
|
const result = await adapter.generateImage(request, ctx);
|
|
9496
|
-
const usage2 =
|
|
9544
|
+
const usage2 = timed(
|
|
9545
|
+
{ ...result.usage, model: model.id, unit: model.usage.unit },
|
|
9546
|
+
startedAt
|
|
9547
|
+
);
|
|
9497
9548
|
await emit(usage2);
|
|
9498
9549
|
const images = result.images.map(toGeneratedImage);
|
|
9499
9550
|
const first = images[0];
|
|
@@ -9536,6 +9587,7 @@ function createModelKit(config, adapters) {
|
|
|
9536
9587
|
message: `${adapter.id} cannot generate video`,
|
|
9537
9588
|
model: model.id
|
|
9538
9589
|
});
|
|
9590
|
+
const startedAt = Date.now();
|
|
9539
9591
|
const job = await adapter.generateVideo(request, ctx);
|
|
9540
9592
|
const result = job.result.bind(job);
|
|
9541
9593
|
let settled;
|
|
@@ -9545,11 +9597,14 @@ function createModelKit(config, adapters) {
|
|
|
9545
9597
|
result(opts) {
|
|
9546
9598
|
if (settled) return settled;
|
|
9547
9599
|
const pending = result(opts).then(
|
|
9548
|
-
(out) =>
|
|
9549
|
-
|
|
9550
|
-
|
|
9551
|
-
|
|
9552
|
-
|
|
9600
|
+
async (out) => {
|
|
9601
|
+
const usage2 = timed(
|
|
9602
|
+
{ ...out.usage, model: model.id, unit: model.usage.unit },
|
|
9603
|
+
startedAt
|
|
9604
|
+
);
|
|
9605
|
+
await emit(usage2);
|
|
9606
|
+
return { ...out, usage: usage2 };
|
|
9607
|
+
},
|
|
9553
9608
|
(cause) => {
|
|
9554
9609
|
settled = void 0;
|
|
9555
9610
|
throw cause;
|
|
@@ -9586,9 +9641,14 @@ function createModelKit(config, adapters) {
|
|
|
9586
9641
|
model: model.id
|
|
9587
9642
|
});
|
|
9588
9643
|
}
|
|
9644
|
+
const startedAt = Date.now();
|
|
9589
9645
|
const result = await adapter.generateAudio(resolved, ctx);
|
|
9590
|
-
|
|
9591
|
-
|
|
9646
|
+
const usage2 = timed(
|
|
9647
|
+
{ ...result.usage, model: model.id, unit: model.usage.unit },
|
|
9648
|
+
startedAt
|
|
9649
|
+
);
|
|
9650
|
+
await emit(usage2);
|
|
9651
|
+
return { ...result, usage: usage2 };
|
|
9592
9652
|
},
|
|
9593
9653
|
async prepareMediaPart(modelId, ref, mediaType, call = {}) {
|
|
9594
9654
|
mediaRetryOptions(call);
|
|
@@ -9617,11 +9677,13 @@ function createModelKit(config, adapters) {
|
|
|
9617
9677
|
const { webhookUrl, ...rest } = call;
|
|
9618
9678
|
const { adapter, ctx } = videoToolTarget(req.model, rest);
|
|
9619
9679
|
if (!adapter.submitVideoTool) throw noVideoTools(adapter, ctx.model);
|
|
9620
|
-
|
|
9680
|
+
const submittedAt = Date.now();
|
|
9681
|
+
const submission = await adapter.submitVideoTool(
|
|
9621
9682
|
req,
|
|
9622
9683
|
ctx,
|
|
9623
9684
|
webhookUrl !== void 0 ? { webhookUrl } : {}
|
|
9624
9685
|
);
|
|
9686
|
+
return { ...submission, submittedAt };
|
|
9625
9687
|
},
|
|
9626
9688
|
async videoToolStatus(sub, call = {}) {
|
|
9627
9689
|
const { adapter, ctx } = videoToolTarget(sub.model, call);
|
|
@@ -9633,8 +9695,10 @@ function createModelKit(config, adapters) {
|
|
|
9633
9695
|
const { adapter, ctx } = videoToolTarget(sub.model, rest);
|
|
9634
9696
|
if (!adapter.videoToolResult) throw noVideoTools(adapter, ctx.model);
|
|
9635
9697
|
const result = await adapter.videoToolResult(sub, ctx, webhook);
|
|
9636
|
-
|
|
9637
|
-
|
|
9698
|
+
const base = { ...result.usage, model: ctx.model.id, unit: ctx.model.usage.unit };
|
|
9699
|
+
const usage2 = sub.submittedAt === void 0 ? base : timed(base, sub.submittedAt);
|
|
9700
|
+
await emit(usage2);
|
|
9701
|
+
return { ...result, usage: usage2 };
|
|
9638
9702
|
},
|
|
9639
9703
|
async cancelVideoTool(sub, call = {}) {
|
|
9640
9704
|
const { adapter, ctx } = videoToolTarget(sub.model, call);
|
|
@@ -9656,6 +9720,7 @@ function createModelKit(config, adapters) {
|
|
|
9656
9720
|
(model) => textTarget(model, call),
|
|
9657
9721
|
options.providerOptions
|
|
9658
9722
|
);
|
|
9723
|
+
const startedAt = Date.now();
|
|
9659
9724
|
const result = await (0, import_ai5.generateText)({
|
|
9660
9725
|
...options,
|
|
9661
9726
|
...textAbortOptions(options.abortSignal, call.signal),
|
|
@@ -9665,7 +9730,8 @@ function createModelKit(config, adapters) {
|
|
|
9665
9730
|
options.prepareStep ?? options.experimental_prepareStep
|
|
9666
9731
|
)
|
|
9667
9732
|
});
|
|
9668
|
-
for (const event of steps.usage(result.steps))
|
|
9733
|
+
for (const event of steps.usage(result.steps))
|
|
9734
|
+
await emit(textTimed(withRowUnit(event), result.steps.length, startedAt));
|
|
9669
9735
|
return result;
|
|
9670
9736
|
},
|
|
9671
9737
|
streamText(options, call = {}) {
|
|
@@ -9676,6 +9742,7 @@ function createModelKit(config, adapters) {
|
|
|
9676
9742
|
options.providerOptions
|
|
9677
9743
|
);
|
|
9678
9744
|
const callerOnFinish = options.onFinish;
|
|
9745
|
+
const startedAt = Date.now();
|
|
9679
9746
|
return (0, import_ai5.streamText)({
|
|
9680
9747
|
...options,
|
|
9681
9748
|
...textAbortOptions(options.abortSignal, call.signal),
|
|
@@ -9685,7 +9752,8 @@ function createModelKit(config, adapters) {
|
|
|
9685
9752
|
options.prepareStep ?? options.experimental_prepareStep
|
|
9686
9753
|
),
|
|
9687
9754
|
onFinish: async (event) => {
|
|
9688
|
-
for (const usage2 of steps.usage(event.steps))
|
|
9755
|
+
for (const usage2 of steps.usage(event.steps))
|
|
9756
|
+
await emit(textTimed(withRowUnit(usage2), event.steps.length, startedAt));
|
|
9689
9757
|
await callerOnFinish?.(event);
|
|
9690
9758
|
}
|
|
9691
9759
|
});
|
|
@@ -9698,15 +9766,22 @@ function createModelKit(config, adapters) {
|
|
|
9698
9766
|
model: languageModel2,
|
|
9699
9767
|
providerOptions: mergeTextProviderOptions(entry, options.providerOptions)
|
|
9700
9768
|
};
|
|
9769
|
+
const startedAt = Date.now();
|
|
9701
9770
|
const result = await (0, import_ai5.generateObject)(sdkOptions);
|
|
9702
9771
|
await emit(
|
|
9703
|
-
|
|
9772
|
+
timed(
|
|
9773
|
+
withRowUnit(
|
|
9774
|
+
textUsageEvent(entry, provider, result.usage, result.providerMetadata)
|
|
9775
|
+
),
|
|
9776
|
+
startedAt
|
|
9777
|
+
)
|
|
9704
9778
|
);
|
|
9705
9779
|
return result;
|
|
9706
9780
|
},
|
|
9707
9781
|
streamObject(options, call = {}) {
|
|
9708
9782
|
const { entry, languageModel: languageModel2, provider } = textTarget(options.model, call);
|
|
9709
9783
|
const callerOnFinish = options.onFinish;
|
|
9784
|
+
const startedAt = Date.now();
|
|
9710
9785
|
const sdkOptions = {
|
|
9711
9786
|
...options,
|
|
9712
9787
|
...textAbortOptions(options.abortSignal, call.signal),
|
|
@@ -9714,8 +9789,16 @@ function createModelKit(config, adapters) {
|
|
|
9714
9789
|
providerOptions: mergeTextProviderOptions(entry, options.providerOptions),
|
|
9715
9790
|
onFinish: async (event) => {
|
|
9716
9791
|
await emit(
|
|
9717
|
-
|
|
9718
|
-
|
|
9792
|
+
timed(
|
|
9793
|
+
withRowUnit(
|
|
9794
|
+
textUsageEvent(
|
|
9795
|
+
entry,
|
|
9796
|
+
provider,
|
|
9797
|
+
event.usage,
|
|
9798
|
+
event.providerMetadata
|
|
9799
|
+
)
|
|
9800
|
+
),
|
|
9801
|
+
startedAt
|
|
9719
9802
|
)
|
|
9720
9803
|
);
|
|
9721
9804
|
await callerOnFinish?.(event);
|