vibezcheck 0.3.0 → 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/README.md +135 -145
- package/dist/ai-sdk/index.d.mts +47 -14
- package/dist/ai-sdk/index.d.ts +47 -14
- package/dist/ai-sdk/index.js +168 -14
- package/dist/ai-sdk/index.js.map +1 -1
- package/dist/ai-sdk/index.mjs +166 -14
- package/dist/ai-sdk/index.mjs.map +1 -1
- package/dist/{client-C67DW_tR.d.mts → client--iq93FQg.d.mts} +1 -1
- package/dist/{client-S3qmTXTR.d.ts → client-kJN_Znan.d.ts} +1 -1
- package/dist/index.d.mts +7 -6
- package/dist/index.d.ts +7 -6
- package/dist/index.js +176 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +175 -23
- package/dist/index.mjs.map +1 -1
- package/dist/meter/index.d.mts +2 -2
- package/dist/meter/index.d.ts +2 -2
- package/dist/meter/index.js +28 -7
- package/dist/meter/index.js.map +1 -1
- package/dist/meter/index.mjs +28 -7
- package/dist/meter/index.mjs.map +1 -1
- package/dist/pricing/index.d.mts +8 -2
- package/dist/pricing/index.d.ts +8 -2
- package/dist/pricing/index.js +28 -7
- package/dist/pricing/index.js.map +1 -1
- package/dist/pricing/index.mjs +28 -7
- package/dist/pricing/index.mjs.map +1 -1
- package/dist/react/index.d.mts +28 -2
- package/dist/react/index.d.ts +28 -2
- package/dist/react/index.js +177 -61
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +176 -61
- package/dist/react/index.mjs.map +1 -1
- package/dist/{types-DCuzLVyc.d.mts → types-Zbzxg-Ka.d.mts} +59 -2
- package/dist/{types-DCuzLVyc.d.ts → types-Zbzxg-Ka.d.ts} +59 -2
- package/package.json +2 -2
package/dist/ai-sdk/index.js
CHANGED
|
@@ -31,7 +31,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var ai_sdk_exports = {};
|
|
32
32
|
__export(ai_sdk_exports, {
|
|
33
33
|
createVibezModel: () => createVibezModel,
|
|
34
|
+
createVibezSession: () => createVibezSession,
|
|
34
35
|
meteredModel: () => meteredModel,
|
|
36
|
+
vibezcheck: () => vibezcheck,
|
|
35
37
|
withBilling: () => withBilling
|
|
36
38
|
});
|
|
37
39
|
module.exports = __toCommonJS(ai_sdk_exports);
|
|
@@ -587,14 +589,26 @@ function getModelPricing(modelName) {
|
|
|
587
589
|
|
|
588
590
|
// src/pricing/calculator.ts
|
|
589
591
|
function calculateCost(params) {
|
|
590
|
-
|
|
592
|
+
let rates;
|
|
593
|
+
if (params.customRate) {
|
|
594
|
+
const outRate = params.customRate.out ?? params.customRate.output ?? 0;
|
|
595
|
+
rates = {
|
|
596
|
+
inputPer1M: params.customRate.in,
|
|
597
|
+
outputPer1M: outRate,
|
|
598
|
+
reasoningPer1M: params.customRate.reasoning ?? outRate,
|
|
599
|
+
cachedInputPer1M: params.customRate.cached ?? params.customRate.in * 0.15,
|
|
600
|
+
currency: "USD"
|
|
601
|
+
};
|
|
602
|
+
} else {
|
|
603
|
+
rates = getModelPricing(params.model);
|
|
604
|
+
}
|
|
591
605
|
const inputTokens = params.inputTokens ?? 0;
|
|
592
606
|
const outputTokens = params.outputTokens ?? 0;
|
|
593
607
|
const reasoningTokens = params.reasoningTokens ?? 0;
|
|
594
608
|
const cachedTokens = params.cachedTokens ?? 0;
|
|
595
609
|
const regularInputTokens = Math.max(0, inputTokens - cachedTokens);
|
|
596
610
|
const regularInputCost = regularInputTokens / 1e6 * rates.inputPer1M;
|
|
597
|
-
const cachedRate = rates.cachedInputPer1M ?? rates.inputPer1M * 0.
|
|
611
|
+
const cachedRate = rates.cachedInputPer1M ?? rates.inputPer1M * 0.15;
|
|
598
612
|
const cachedInputCost = cachedTokens / 1e6 * cachedRate;
|
|
599
613
|
const inputCostUSD = regularInputCost + cachedInputCost;
|
|
600
614
|
const outputCostUSD = outputTokens / 1e6 * rates.outputPer1M;
|
|
@@ -602,20 +616,27 @@ function calculateCost(params) {
|
|
|
602
616
|
const reasoningCostUSD = reasoningTokens / 1e6 * reasoningRate;
|
|
603
617
|
const standardCacheCost = cachedTokens / 1e6 * rates.inputPer1M;
|
|
604
618
|
const cachedDiscountUSD = Math.max(0, standardCacheCost - cachedInputCost);
|
|
605
|
-
|
|
619
|
+
let totalUSD = inputCostUSD + outputCostUSD;
|
|
606
620
|
const markup = params.markupMultiplier ?? 1;
|
|
607
|
-
|
|
621
|
+
let retailUSD = void 0;
|
|
622
|
+
if (markup !== 1 || params.minimumChargeUSD !== void 0) {
|
|
623
|
+
retailUSD = totalUSD * markup;
|
|
624
|
+
if (params.minimumChargeUSD !== void 0 && retailUSD < params.minimumChargeUSD) {
|
|
625
|
+
retailUSD = params.minimumChargeUSD;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
608
628
|
return {
|
|
609
629
|
inputCostUSD: Number(inputCostUSD.toFixed(8)),
|
|
610
630
|
outputCostUSD: Number(outputCostUSD.toFixed(8)),
|
|
611
631
|
reasoningCostUSD: reasoningTokens > 0 ? Number(reasoningCostUSD.toFixed(8)) : void 0,
|
|
612
632
|
cachedDiscountUSD: cachedTokens > 0 ? Number(cachedDiscountUSD.toFixed(8)) : void 0,
|
|
613
633
|
totalUSD: Number(totalUSD.toFixed(8)),
|
|
614
|
-
retailUSD: retailUSD ? Number(retailUSD.toFixed(8)) : void 0,
|
|
634
|
+
retailUSD: retailUSD !== void 0 ? Number(retailUSD.toFixed(8)) : void 0,
|
|
615
635
|
currency: rates.currency || "USD"
|
|
616
636
|
};
|
|
617
637
|
}
|
|
618
|
-
function calculateUsageCost(model, usage,
|
|
638
|
+
function calculateUsageCost(model, usage, optionsOrMarkup) {
|
|
639
|
+
const options = typeof optionsOrMarkup === "number" ? { markupMultiplier: optionsOrMarkup } : optionsOrMarkup || {};
|
|
619
640
|
return calculateCost({
|
|
620
641
|
model,
|
|
621
642
|
inputTokens: usage.inputTokens,
|
|
@@ -623,7 +644,9 @@ function calculateUsageCost(model, usage, markupMultiplier) {
|
|
|
623
644
|
reasoningTokens: usage.reasoningTokens,
|
|
624
645
|
cachedTokens: usage.cachedTokens,
|
|
625
646
|
cacheWriteTokens: usage.cacheWriteTokens,
|
|
626
|
-
markupMultiplier
|
|
647
|
+
markupMultiplier: options.markupMultiplier,
|
|
648
|
+
minimumChargeUSD: options.minimumChargeUSD,
|
|
649
|
+
customRate: options.customRate
|
|
627
650
|
});
|
|
628
651
|
}
|
|
629
652
|
|
|
@@ -874,7 +897,22 @@ function withBilling(model, options = {}) {
|
|
|
874
897
|
const customerId = typeof options.customer === "string" ? options.customer : options.customer?.id || options.customerId;
|
|
875
898
|
const modelId = model.modelId || "unknown-model";
|
|
876
899
|
const provider = model.provider?.replace(/^@ai-sdk\//, "") || "ai-sdk";
|
|
877
|
-
const
|
|
900
|
+
const maxCostPerCall = options.maxCostPerCallUSD !== void 0 ? options.maxCostPerCallUSD : 0.5;
|
|
901
|
+
const captureOnAbort = options.captureOnAbort !== false;
|
|
902
|
+
const scheduleFlush = () => {
|
|
903
|
+
try {
|
|
904
|
+
const flushPromise = meter.flush();
|
|
905
|
+
if (typeof globalThis !== "undefined") {
|
|
906
|
+
const g = globalThis;
|
|
907
|
+
if (typeof g.after === "function") {
|
|
908
|
+
g.after(() => flushPromise);
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
} catch {
|
|
913
|
+
}
|
|
914
|
+
};
|
|
915
|
+
const handleUsage = (rawUsage, extraMeta) => {
|
|
878
916
|
if (!rawUsage) return;
|
|
879
917
|
const inputTokens = rawUsage.promptTokens ?? rawUsage.inputTokens ?? 0;
|
|
880
918
|
const outputTokens = rawUsage.completionTokens ?? rawUsage.outputTokens ?? 0;
|
|
@@ -888,15 +926,19 @@ function withBilling(model, options = {}) {
|
|
|
888
926
|
visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),
|
|
889
927
|
cachedTokens: cachedTokens > 0 ? cachedTokens : void 0
|
|
890
928
|
};
|
|
891
|
-
const cost = calculateUsageCost(modelId, usage
|
|
892
|
-
|
|
929
|
+
const cost = calculateUsageCost(modelId, usage, {
|
|
930
|
+
markupMultiplier: options.pricing?.margin,
|
|
931
|
+
minimumChargeUSD: options.pricing?.minimumChargeUSD,
|
|
932
|
+
customRate: options.rate
|
|
933
|
+
});
|
|
934
|
+
if (maxCostPerCall > 0 && maxCostPerCall !== Infinity && cost.totalUSD > maxCostPerCall) {
|
|
893
935
|
const budgetEvent = {
|
|
894
936
|
reason: "cost_per_call_exceeded",
|
|
895
|
-
limit:
|
|
937
|
+
limit: maxCostPerCall,
|
|
896
938
|
current: cost.totalUSD,
|
|
897
939
|
model: modelId,
|
|
898
940
|
customerId,
|
|
899
|
-
message: `[vibezcheck] Circuit Breaker tripped: Call cost ($${cost.totalUSD.toFixed(4)}) exceeded
|
|
941
|
+
message: `[vibezcheck] Circuit Breaker tripped: Call cost ($${cost.totalUSD.toFixed(4)}) exceeded budget ceiling ($${maxCostPerCall.toFixed(4)}).`
|
|
900
942
|
};
|
|
901
943
|
if (options.onBudgetExceeded) {
|
|
902
944
|
options.onBudgetExceeded(budgetEvent);
|
|
@@ -928,7 +970,11 @@ function withBilling(model, options = {}) {
|
|
|
928
970
|
usage,
|
|
929
971
|
cost,
|
|
930
972
|
customerId,
|
|
931
|
-
metadata:
|
|
973
|
+
metadata: {
|
|
974
|
+
...options.metadata,
|
|
975
|
+
...extraMeta,
|
|
976
|
+
billingMode: options.billing?.mode || "postpaid"
|
|
977
|
+
}
|
|
932
978
|
};
|
|
933
979
|
meter.recordUsage({
|
|
934
980
|
model: modelId,
|
|
@@ -938,11 +984,12 @@ function withBilling(model, options = {}) {
|
|
|
938
984
|
reasoningTokens: usage.reasoningTokens,
|
|
939
985
|
cachedTokens: usage.cachedTokens,
|
|
940
986
|
customerId,
|
|
941
|
-
metadata:
|
|
987
|
+
metadata: event.metadata
|
|
942
988
|
});
|
|
943
989
|
if (options.onUsage) {
|
|
944
990
|
options.onUsage(event);
|
|
945
991
|
}
|
|
992
|
+
scheduleFlush();
|
|
946
993
|
};
|
|
947
994
|
const handler = {
|
|
948
995
|
get(target, prop, receiver) {
|
|
@@ -954,12 +1001,59 @@ function withBilling(model, options = {}) {
|
|
|
954
1001
|
return result;
|
|
955
1002
|
}
|
|
956
1003
|
const originalStream = result.stream;
|
|
1004
|
+
let streamCompleted = false;
|
|
1005
|
+
let accumulatedChars = 0;
|
|
1006
|
+
let estimatedInputTokens = 0;
|
|
1007
|
+
try {
|
|
1008
|
+
if (args[0]?.prompt) {
|
|
1009
|
+
const str = typeof args[0].prompt === "string" ? args[0].prompt : JSON.stringify(args[0].prompt);
|
|
1010
|
+
estimatedInputTokens = Math.ceil(str.length / 4);
|
|
1011
|
+
}
|
|
1012
|
+
} catch {
|
|
1013
|
+
}
|
|
1014
|
+
const abortSignal = args[0]?.abortSignal;
|
|
1015
|
+
if (abortSignal && captureOnAbort) {
|
|
1016
|
+
abortSignal.addEventListener(
|
|
1017
|
+
"abort",
|
|
1018
|
+
() => {
|
|
1019
|
+
if (!streamCompleted && accumulatedChars > 0) {
|
|
1020
|
+
streamCompleted = true;
|
|
1021
|
+
const estimatedOutputTokens = Math.ceil(accumulatedChars / 3.8);
|
|
1022
|
+
handleUsage(
|
|
1023
|
+
{
|
|
1024
|
+
inputTokens: estimatedInputTokens,
|
|
1025
|
+
outputTokens: estimatedOutputTokens
|
|
1026
|
+
},
|
|
1027
|
+
{ aborted: true, partial: true }
|
|
1028
|
+
);
|
|
1029
|
+
}
|
|
1030
|
+
},
|
|
1031
|
+
{ once: true }
|
|
1032
|
+
);
|
|
1033
|
+
}
|
|
957
1034
|
const transformStream = new TransformStream({
|
|
958
1035
|
transform(chunk, controller) {
|
|
959
1036
|
controller.enqueue(chunk);
|
|
1037
|
+
if (chunk.type === "text-delta" && chunk.textDelta) {
|
|
1038
|
+
accumulatedChars += chunk.textDelta.length;
|
|
1039
|
+
}
|
|
960
1040
|
if (chunk.type === "finish" && chunk.usage) {
|
|
1041
|
+
streamCompleted = true;
|
|
961
1042
|
handleUsage(chunk.usage);
|
|
962
1043
|
}
|
|
1044
|
+
},
|
|
1045
|
+
flush() {
|
|
1046
|
+
if (!streamCompleted && captureOnAbort && accumulatedChars > 0) {
|
|
1047
|
+
streamCompleted = true;
|
|
1048
|
+
const estimatedOutputTokens = Math.ceil(accumulatedChars / 3.8);
|
|
1049
|
+
handleUsage(
|
|
1050
|
+
{
|
|
1051
|
+
inputTokens: estimatedInputTokens,
|
|
1052
|
+
outputTokens: estimatedOutputTokens
|
|
1053
|
+
},
|
|
1054
|
+
{ aborted: true, partial: true }
|
|
1055
|
+
);
|
|
1056
|
+
}
|
|
963
1057
|
}
|
|
964
1058
|
});
|
|
965
1059
|
return {
|
|
@@ -1033,10 +1127,70 @@ function createVibezModel(modelOrId, options = {}) {
|
|
|
1033
1127
|
}
|
|
1034
1128
|
return modelOrId;
|
|
1035
1129
|
}
|
|
1130
|
+
function createVibezSession(sessionOptions = {}) {
|
|
1131
|
+
const meter = createMeter({
|
|
1132
|
+
apiKey: sessionOptions.stripeApiKey
|
|
1133
|
+
});
|
|
1134
|
+
const customerId = typeof sessionOptions.customer === "string" ? sessionOptions.customer : sessionOptions.customer?.id;
|
|
1135
|
+
return {
|
|
1136
|
+
meter,
|
|
1137
|
+
model: (modelOrId, callOptions = {}) => {
|
|
1138
|
+
return createVibezModel(modelOrId, {
|
|
1139
|
+
customer: sessionOptions.customer,
|
|
1140
|
+
pricing: sessionOptions.pricing,
|
|
1141
|
+
billing: sessionOptions.billing,
|
|
1142
|
+
meter,
|
|
1143
|
+
metadata: {
|
|
1144
|
+
...sessionOptions.metadata,
|
|
1145
|
+
...callOptions.metadata
|
|
1146
|
+
},
|
|
1147
|
+
...callOptions
|
|
1148
|
+
});
|
|
1149
|
+
},
|
|
1150
|
+
trackTool: async (name, { costUSD, metadata }) => {
|
|
1151
|
+
const event = {
|
|
1152
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1153
|
+
model: `tool:${name}`,
|
|
1154
|
+
provider: "tool",
|
|
1155
|
+
usage: {
|
|
1156
|
+
inputTokens: 0,
|
|
1157
|
+
outputTokens: 0,
|
|
1158
|
+
totalTokens: 0
|
|
1159
|
+
},
|
|
1160
|
+
cost: {
|
|
1161
|
+
inputCostUSD: 0,
|
|
1162
|
+
outputCostUSD: costUSD,
|
|
1163
|
+
totalUSD: costUSD,
|
|
1164
|
+
currency: "USD"
|
|
1165
|
+
},
|
|
1166
|
+
customerId,
|
|
1167
|
+
metadata: {
|
|
1168
|
+
...sessionOptions.metadata,
|
|
1169
|
+
...metadata,
|
|
1170
|
+
tool: name
|
|
1171
|
+
}
|
|
1172
|
+
};
|
|
1173
|
+
meter.recordUsage({
|
|
1174
|
+
model: `tool:${name}`,
|
|
1175
|
+
provider: "tool",
|
|
1176
|
+
inputTokens: 0,
|
|
1177
|
+
outputTokens: 0,
|
|
1178
|
+
customerId,
|
|
1179
|
+
metadata: event.metadata
|
|
1180
|
+
});
|
|
1181
|
+
await meter.flush();
|
|
1182
|
+
}
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
var vibezcheck = Object.assign(createVibezModel, {
|
|
1186
|
+
session: createVibezSession
|
|
1187
|
+
});
|
|
1036
1188
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1037
1189
|
0 && (module.exports = {
|
|
1038
1190
|
createVibezModel,
|
|
1191
|
+
createVibezSession,
|
|
1039
1192
|
meteredModel,
|
|
1193
|
+
vibezcheck,
|
|
1040
1194
|
withBilling
|
|
1041
1195
|
});
|
|
1042
1196
|
//# sourceMappingURL=index.js.map
|