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.mjs
CHANGED
|
@@ -556,14 +556,26 @@ function getModelPricing(modelName) {
|
|
|
556
556
|
|
|
557
557
|
// src/pricing/calculator.ts
|
|
558
558
|
function calculateCost(params) {
|
|
559
|
-
|
|
559
|
+
let rates;
|
|
560
|
+
if (params.customRate) {
|
|
561
|
+
const outRate = params.customRate.out ?? params.customRate.output ?? 0;
|
|
562
|
+
rates = {
|
|
563
|
+
inputPer1M: params.customRate.in,
|
|
564
|
+
outputPer1M: outRate,
|
|
565
|
+
reasoningPer1M: params.customRate.reasoning ?? outRate,
|
|
566
|
+
cachedInputPer1M: params.customRate.cached ?? params.customRate.in * 0.15,
|
|
567
|
+
currency: "USD"
|
|
568
|
+
};
|
|
569
|
+
} else {
|
|
570
|
+
rates = getModelPricing(params.model);
|
|
571
|
+
}
|
|
560
572
|
const inputTokens = params.inputTokens ?? 0;
|
|
561
573
|
const outputTokens = params.outputTokens ?? 0;
|
|
562
574
|
const reasoningTokens = params.reasoningTokens ?? 0;
|
|
563
575
|
const cachedTokens = params.cachedTokens ?? 0;
|
|
564
576
|
const regularInputTokens = Math.max(0, inputTokens - cachedTokens);
|
|
565
577
|
const regularInputCost = regularInputTokens / 1e6 * rates.inputPer1M;
|
|
566
|
-
const cachedRate = rates.cachedInputPer1M ?? rates.inputPer1M * 0.
|
|
578
|
+
const cachedRate = rates.cachedInputPer1M ?? rates.inputPer1M * 0.15;
|
|
567
579
|
const cachedInputCost = cachedTokens / 1e6 * cachedRate;
|
|
568
580
|
const inputCostUSD = regularInputCost + cachedInputCost;
|
|
569
581
|
const outputCostUSD = outputTokens / 1e6 * rates.outputPer1M;
|
|
@@ -571,20 +583,27 @@ function calculateCost(params) {
|
|
|
571
583
|
const reasoningCostUSD = reasoningTokens / 1e6 * reasoningRate;
|
|
572
584
|
const standardCacheCost = cachedTokens / 1e6 * rates.inputPer1M;
|
|
573
585
|
const cachedDiscountUSD = Math.max(0, standardCacheCost - cachedInputCost);
|
|
574
|
-
|
|
586
|
+
let totalUSD = inputCostUSD + outputCostUSD;
|
|
575
587
|
const markup = params.markupMultiplier ?? 1;
|
|
576
|
-
|
|
588
|
+
let retailUSD = void 0;
|
|
589
|
+
if (markup !== 1 || params.minimumChargeUSD !== void 0) {
|
|
590
|
+
retailUSD = totalUSD * markup;
|
|
591
|
+
if (params.minimumChargeUSD !== void 0 && retailUSD < params.minimumChargeUSD) {
|
|
592
|
+
retailUSD = params.minimumChargeUSD;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
577
595
|
return {
|
|
578
596
|
inputCostUSD: Number(inputCostUSD.toFixed(8)),
|
|
579
597
|
outputCostUSD: Number(outputCostUSD.toFixed(8)),
|
|
580
598
|
reasoningCostUSD: reasoningTokens > 0 ? Number(reasoningCostUSD.toFixed(8)) : void 0,
|
|
581
599
|
cachedDiscountUSD: cachedTokens > 0 ? Number(cachedDiscountUSD.toFixed(8)) : void 0,
|
|
582
600
|
totalUSD: Number(totalUSD.toFixed(8)),
|
|
583
|
-
retailUSD: retailUSD ? Number(retailUSD.toFixed(8)) : void 0,
|
|
601
|
+
retailUSD: retailUSD !== void 0 ? Number(retailUSD.toFixed(8)) : void 0,
|
|
584
602
|
currency: rates.currency || "USD"
|
|
585
603
|
};
|
|
586
604
|
}
|
|
587
|
-
function calculateUsageCost(model, usage,
|
|
605
|
+
function calculateUsageCost(model, usage, optionsOrMarkup) {
|
|
606
|
+
const options = typeof optionsOrMarkup === "number" ? { markupMultiplier: optionsOrMarkup } : optionsOrMarkup || {};
|
|
588
607
|
return calculateCost({
|
|
589
608
|
model,
|
|
590
609
|
inputTokens: usage.inputTokens,
|
|
@@ -592,7 +611,9 @@ function calculateUsageCost(model, usage, markupMultiplier) {
|
|
|
592
611
|
reasoningTokens: usage.reasoningTokens,
|
|
593
612
|
cachedTokens: usage.cachedTokens,
|
|
594
613
|
cacheWriteTokens: usage.cacheWriteTokens,
|
|
595
|
-
markupMultiplier
|
|
614
|
+
markupMultiplier: options.markupMultiplier,
|
|
615
|
+
minimumChargeUSD: options.minimumChargeUSD,
|
|
616
|
+
customRate: options.customRate
|
|
596
617
|
});
|
|
597
618
|
}
|
|
598
619
|
|
|
@@ -843,7 +864,22 @@ function withBilling(model, options = {}) {
|
|
|
843
864
|
const customerId = typeof options.customer === "string" ? options.customer : options.customer?.id || options.customerId;
|
|
844
865
|
const modelId = model.modelId || "unknown-model";
|
|
845
866
|
const provider = model.provider?.replace(/^@ai-sdk\//, "") || "ai-sdk";
|
|
846
|
-
const
|
|
867
|
+
const maxCostPerCall = options.maxCostPerCallUSD !== void 0 ? options.maxCostPerCallUSD : 0.5;
|
|
868
|
+
const captureOnAbort = options.captureOnAbort !== false;
|
|
869
|
+
const scheduleFlush = () => {
|
|
870
|
+
try {
|
|
871
|
+
const flushPromise = meter.flush();
|
|
872
|
+
if (typeof globalThis !== "undefined") {
|
|
873
|
+
const g = globalThis;
|
|
874
|
+
if (typeof g.after === "function") {
|
|
875
|
+
g.after(() => flushPromise);
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
} catch {
|
|
880
|
+
}
|
|
881
|
+
};
|
|
882
|
+
const handleUsage = (rawUsage, extraMeta) => {
|
|
847
883
|
if (!rawUsage) return;
|
|
848
884
|
const inputTokens = rawUsage.promptTokens ?? rawUsage.inputTokens ?? 0;
|
|
849
885
|
const outputTokens = rawUsage.completionTokens ?? rawUsage.outputTokens ?? 0;
|
|
@@ -857,15 +893,19 @@ function withBilling(model, options = {}) {
|
|
|
857
893
|
visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),
|
|
858
894
|
cachedTokens: cachedTokens > 0 ? cachedTokens : void 0
|
|
859
895
|
};
|
|
860
|
-
const cost = calculateUsageCost(modelId, usage
|
|
861
|
-
|
|
896
|
+
const cost = calculateUsageCost(modelId, usage, {
|
|
897
|
+
markupMultiplier: options.pricing?.margin,
|
|
898
|
+
minimumChargeUSD: options.pricing?.minimumChargeUSD,
|
|
899
|
+
customRate: options.rate
|
|
900
|
+
});
|
|
901
|
+
if (maxCostPerCall > 0 && maxCostPerCall !== Infinity && cost.totalUSD > maxCostPerCall) {
|
|
862
902
|
const budgetEvent = {
|
|
863
903
|
reason: "cost_per_call_exceeded",
|
|
864
|
-
limit:
|
|
904
|
+
limit: maxCostPerCall,
|
|
865
905
|
current: cost.totalUSD,
|
|
866
906
|
model: modelId,
|
|
867
907
|
customerId,
|
|
868
|
-
message: `[vibezcheck] Circuit Breaker tripped: Call cost ($${cost.totalUSD.toFixed(4)}) exceeded
|
|
908
|
+
message: `[vibezcheck] Circuit Breaker tripped: Call cost ($${cost.totalUSD.toFixed(4)}) exceeded budget ceiling ($${maxCostPerCall.toFixed(4)}).`
|
|
869
909
|
};
|
|
870
910
|
if (options.onBudgetExceeded) {
|
|
871
911
|
options.onBudgetExceeded(budgetEvent);
|
|
@@ -897,7 +937,11 @@ function withBilling(model, options = {}) {
|
|
|
897
937
|
usage,
|
|
898
938
|
cost,
|
|
899
939
|
customerId,
|
|
900
|
-
metadata:
|
|
940
|
+
metadata: {
|
|
941
|
+
...options.metadata,
|
|
942
|
+
...extraMeta,
|
|
943
|
+
billingMode: options.billing?.mode || "postpaid"
|
|
944
|
+
}
|
|
901
945
|
};
|
|
902
946
|
meter.recordUsage({
|
|
903
947
|
model: modelId,
|
|
@@ -907,11 +951,12 @@ function withBilling(model, options = {}) {
|
|
|
907
951
|
reasoningTokens: usage.reasoningTokens,
|
|
908
952
|
cachedTokens: usage.cachedTokens,
|
|
909
953
|
customerId,
|
|
910
|
-
metadata:
|
|
954
|
+
metadata: event.metadata
|
|
911
955
|
});
|
|
912
956
|
if (options.onUsage) {
|
|
913
957
|
options.onUsage(event);
|
|
914
958
|
}
|
|
959
|
+
scheduleFlush();
|
|
915
960
|
};
|
|
916
961
|
const handler = {
|
|
917
962
|
get(target, prop, receiver) {
|
|
@@ -923,12 +968,59 @@ function withBilling(model, options = {}) {
|
|
|
923
968
|
return result;
|
|
924
969
|
}
|
|
925
970
|
const originalStream = result.stream;
|
|
971
|
+
let streamCompleted = false;
|
|
972
|
+
let accumulatedChars = 0;
|
|
973
|
+
let estimatedInputTokens = 0;
|
|
974
|
+
try {
|
|
975
|
+
if (args[0]?.prompt) {
|
|
976
|
+
const str = typeof args[0].prompt === "string" ? args[0].prompt : JSON.stringify(args[0].prompt);
|
|
977
|
+
estimatedInputTokens = Math.ceil(str.length / 4);
|
|
978
|
+
}
|
|
979
|
+
} catch {
|
|
980
|
+
}
|
|
981
|
+
const abortSignal = args[0]?.abortSignal;
|
|
982
|
+
if (abortSignal && captureOnAbort) {
|
|
983
|
+
abortSignal.addEventListener(
|
|
984
|
+
"abort",
|
|
985
|
+
() => {
|
|
986
|
+
if (!streamCompleted && accumulatedChars > 0) {
|
|
987
|
+
streamCompleted = true;
|
|
988
|
+
const estimatedOutputTokens = Math.ceil(accumulatedChars / 3.8);
|
|
989
|
+
handleUsage(
|
|
990
|
+
{
|
|
991
|
+
inputTokens: estimatedInputTokens,
|
|
992
|
+
outputTokens: estimatedOutputTokens
|
|
993
|
+
},
|
|
994
|
+
{ aborted: true, partial: true }
|
|
995
|
+
);
|
|
996
|
+
}
|
|
997
|
+
},
|
|
998
|
+
{ once: true }
|
|
999
|
+
);
|
|
1000
|
+
}
|
|
926
1001
|
const transformStream = new TransformStream({
|
|
927
1002
|
transform(chunk, controller) {
|
|
928
1003
|
controller.enqueue(chunk);
|
|
1004
|
+
if (chunk.type === "text-delta" && chunk.textDelta) {
|
|
1005
|
+
accumulatedChars += chunk.textDelta.length;
|
|
1006
|
+
}
|
|
929
1007
|
if (chunk.type === "finish" && chunk.usage) {
|
|
1008
|
+
streamCompleted = true;
|
|
930
1009
|
handleUsage(chunk.usage);
|
|
931
1010
|
}
|
|
1011
|
+
},
|
|
1012
|
+
flush() {
|
|
1013
|
+
if (!streamCompleted && captureOnAbort && accumulatedChars > 0) {
|
|
1014
|
+
streamCompleted = true;
|
|
1015
|
+
const estimatedOutputTokens = Math.ceil(accumulatedChars / 3.8);
|
|
1016
|
+
handleUsage(
|
|
1017
|
+
{
|
|
1018
|
+
inputTokens: estimatedInputTokens,
|
|
1019
|
+
outputTokens: estimatedOutputTokens
|
|
1020
|
+
},
|
|
1021
|
+
{ aborted: true, partial: true }
|
|
1022
|
+
);
|
|
1023
|
+
}
|
|
932
1024
|
}
|
|
933
1025
|
});
|
|
934
1026
|
return {
|
|
@@ -1002,9 +1094,69 @@ function createVibezModel(modelOrId, options = {}) {
|
|
|
1002
1094
|
}
|
|
1003
1095
|
return modelOrId;
|
|
1004
1096
|
}
|
|
1097
|
+
function createVibezSession(sessionOptions = {}) {
|
|
1098
|
+
const meter = createMeter({
|
|
1099
|
+
apiKey: sessionOptions.stripeApiKey
|
|
1100
|
+
});
|
|
1101
|
+
const customerId = typeof sessionOptions.customer === "string" ? sessionOptions.customer : sessionOptions.customer?.id;
|
|
1102
|
+
return {
|
|
1103
|
+
meter,
|
|
1104
|
+
model: (modelOrId, callOptions = {}) => {
|
|
1105
|
+
return createVibezModel(modelOrId, {
|
|
1106
|
+
customer: sessionOptions.customer,
|
|
1107
|
+
pricing: sessionOptions.pricing,
|
|
1108
|
+
billing: sessionOptions.billing,
|
|
1109
|
+
meter,
|
|
1110
|
+
metadata: {
|
|
1111
|
+
...sessionOptions.metadata,
|
|
1112
|
+
...callOptions.metadata
|
|
1113
|
+
},
|
|
1114
|
+
...callOptions
|
|
1115
|
+
});
|
|
1116
|
+
},
|
|
1117
|
+
trackTool: async (name, { costUSD, metadata }) => {
|
|
1118
|
+
const event = {
|
|
1119
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1120
|
+
model: `tool:${name}`,
|
|
1121
|
+
provider: "tool",
|
|
1122
|
+
usage: {
|
|
1123
|
+
inputTokens: 0,
|
|
1124
|
+
outputTokens: 0,
|
|
1125
|
+
totalTokens: 0
|
|
1126
|
+
},
|
|
1127
|
+
cost: {
|
|
1128
|
+
inputCostUSD: 0,
|
|
1129
|
+
outputCostUSD: costUSD,
|
|
1130
|
+
totalUSD: costUSD,
|
|
1131
|
+
currency: "USD"
|
|
1132
|
+
},
|
|
1133
|
+
customerId,
|
|
1134
|
+
metadata: {
|
|
1135
|
+
...sessionOptions.metadata,
|
|
1136
|
+
...metadata,
|
|
1137
|
+
tool: name
|
|
1138
|
+
}
|
|
1139
|
+
};
|
|
1140
|
+
meter.recordUsage({
|
|
1141
|
+
model: `tool:${name}`,
|
|
1142
|
+
provider: "tool",
|
|
1143
|
+
inputTokens: 0,
|
|
1144
|
+
outputTokens: 0,
|
|
1145
|
+
customerId,
|
|
1146
|
+
metadata: event.metadata
|
|
1147
|
+
});
|
|
1148
|
+
await meter.flush();
|
|
1149
|
+
}
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1152
|
+
var vibezcheck = Object.assign(createVibezModel, {
|
|
1153
|
+
session: createVibezSession
|
|
1154
|
+
});
|
|
1005
1155
|
export {
|
|
1006
1156
|
createVibezModel,
|
|
1157
|
+
createVibezSession,
|
|
1007
1158
|
meteredModel,
|
|
1159
|
+
vibezcheck,
|
|
1008
1160
|
withBilling
|
|
1009
1161
|
};
|
|
1010
1162
|
//# sourceMappingURL=index.mjs.map
|