vibezcheck 0.2.0 → 0.3.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 -191
- package/bin/vibezcheck.js +4 -0
- package/dist/ai-sdk/index.d.mts +43 -7
- package/dist/ai-sdk/index.d.ts +43 -7
- package/dist/ai-sdk/index.js +115 -55
- package/dist/ai-sdk/index.js.map +1 -1
- package/dist/ai-sdk/index.mjs +121 -55
- package/dist/ai-sdk/index.mjs.map +1 -1
- package/dist/cli/index.d.mts +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +232 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/index.mjs +209 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/{client-MJ3tl7bz.d.mts → client-C67DW_tR.d.mts} +1 -1
- package/dist/{client-txrE0D_D.d.ts → client-S3qmTXTR.d.ts} +1 -1
- package/dist/index.d.mts +49 -26
- package/dist/index.d.ts +49 -26
- package/dist/index.js +136 -94
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +141 -94
- 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/pricing/index.d.mts +1 -1
- package/dist/pricing/index.d.ts +1 -1
- package/dist/react/index.d.mts +70 -18
- package/dist/react/index.d.ts +70 -18
- package/dist/react/index.js +345 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +346 -3
- package/dist/react/index.mjs.map +1 -1
- package/dist/{types-CSrSmsd1.d.mts → types-DCuzLVyc.d.mts} +48 -3
- package/dist/{types-CSrSmsd1.d.ts → types-DCuzLVyc.d.ts} +48 -3
- package/package.json +5 -1
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
1
8
|
// src/index.ts
|
|
2
9
|
import Stripe5 from "stripe";
|
|
3
10
|
|
|
@@ -822,6 +829,16 @@ function createMeter(options = {}) {
|
|
|
822
829
|
return new VibezMeter(options);
|
|
823
830
|
}
|
|
824
831
|
|
|
832
|
+
// src/types.ts
|
|
833
|
+
var VibezCircuitBreakerError = class extends Error {
|
|
834
|
+
event;
|
|
835
|
+
constructor(event) {
|
|
836
|
+
super(event.message);
|
|
837
|
+
this.name = "VibezCircuitBreakerError";
|
|
838
|
+
this.event = event;
|
|
839
|
+
}
|
|
840
|
+
};
|
|
841
|
+
|
|
825
842
|
// src/ai-sdk/with-billing.ts
|
|
826
843
|
function withBilling(model, options = {}) {
|
|
827
844
|
if (!model || typeof model !== "object") {
|
|
@@ -849,6 +866,38 @@ function withBilling(model, options = {}) {
|
|
|
849
866
|
cachedTokens: cachedTokens > 0 ? cachedTokens : void 0
|
|
850
867
|
};
|
|
851
868
|
const cost = calculateUsageCost(modelId, usage);
|
|
869
|
+
if (options.maxCostPerCallUSD && cost.totalUSD > options.maxCostPerCallUSD) {
|
|
870
|
+
const budgetEvent = {
|
|
871
|
+
reason: "cost_per_call_exceeded",
|
|
872
|
+
limit: options.maxCostPerCallUSD,
|
|
873
|
+
current: cost.totalUSD,
|
|
874
|
+
model: modelId,
|
|
875
|
+
customerId,
|
|
876
|
+
message: `[vibezcheck] Circuit Breaker tripped: Call cost ($${cost.totalUSD.toFixed(4)}) exceeded maxCostPerCallUSD threshold ($${options.maxCostPerCallUSD.toFixed(4)}).`
|
|
877
|
+
};
|
|
878
|
+
if (options.onBudgetExceeded) {
|
|
879
|
+
options.onBudgetExceeded(budgetEvent);
|
|
880
|
+
}
|
|
881
|
+
if (options.throwOnBudgetExceeded) {
|
|
882
|
+
throw new VibezCircuitBreakerError(budgetEvent);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
if (options.maxTokensPerCall && usage.totalTokens > options.maxTokensPerCall) {
|
|
886
|
+
const budgetEvent = {
|
|
887
|
+
reason: "max_tokens_exceeded",
|
|
888
|
+
limit: options.maxTokensPerCall,
|
|
889
|
+
current: usage.totalTokens,
|
|
890
|
+
model: modelId,
|
|
891
|
+
customerId,
|
|
892
|
+
message: `[vibezcheck] Circuit Breaker tripped: Token count (${usage.totalTokens}) exceeded maxTokensPerCall limit (${options.maxTokensPerCall}).`
|
|
893
|
+
};
|
|
894
|
+
if (options.onBudgetExceeded) {
|
|
895
|
+
options.onBudgetExceeded(budgetEvent);
|
|
896
|
+
}
|
|
897
|
+
if (options.throwOnBudgetExceeded) {
|
|
898
|
+
throw new VibezCircuitBreakerError(budgetEvent);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
852
901
|
const event = {
|
|
853
902
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
854
903
|
model: modelId,
|
|
@@ -872,18 +921,9 @@ function withBilling(model, options = {}) {
|
|
|
872
921
|
options.onUsage(event);
|
|
873
922
|
}
|
|
874
923
|
};
|
|
875
|
-
|
|
924
|
+
const handler = {
|
|
876
925
|
get(target, prop, receiver) {
|
|
877
926
|
const originalValue = Reflect.get(target, prop, receiver);
|
|
878
|
-
if (prop === "doGenerate" && typeof originalValue === "function") {
|
|
879
|
-
return async function(...args) {
|
|
880
|
-
const result = await originalValue.apply(target, args);
|
|
881
|
-
if (result && result.usage) {
|
|
882
|
-
handleUsage(result.usage);
|
|
883
|
-
}
|
|
884
|
-
return result;
|
|
885
|
-
};
|
|
886
|
-
}
|
|
887
927
|
if (prop === "doStream" && typeof originalValue === "function") {
|
|
888
928
|
return async function(...args) {
|
|
889
929
|
const result = await originalValue.apply(target, args);
|
|
@@ -891,61 +931,86 @@ function withBilling(model, options = {}) {
|
|
|
891
931
|
return result;
|
|
892
932
|
}
|
|
893
933
|
const originalStream = result.stream;
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
while (true) {
|
|
900
|
-
const { done, value } = await reader.read();
|
|
901
|
-
if (done) {
|
|
902
|
-
controller.close();
|
|
903
|
-
break;
|
|
904
|
-
}
|
|
905
|
-
if (value && typeof value === "object") {
|
|
906
|
-
if (value.type === "finish" && value.usage) {
|
|
907
|
-
handleUsage(value.usage);
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
controller.enqueue(value);
|
|
911
|
-
}
|
|
912
|
-
} catch (err) {
|
|
913
|
-
controller.error(err);
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
});
|
|
917
|
-
return {
|
|
918
|
-
...result,
|
|
919
|
-
stream: transformedStream
|
|
920
|
-
};
|
|
921
|
-
}
|
|
922
|
-
if (Symbol.asyncIterator in originalStream) {
|
|
923
|
-
const wrappedAsyncIterable = {
|
|
924
|
-
async *[Symbol.asyncIterator]() {
|
|
925
|
-
for await (const chunk of originalStream) {
|
|
926
|
-
if (chunk && typeof chunk === "object") {
|
|
927
|
-
if (chunk.type === "finish" && chunk.usage) {
|
|
928
|
-
handleUsage(chunk.usage);
|
|
929
|
-
}
|
|
930
|
-
}
|
|
931
|
-
yield chunk;
|
|
932
|
-
}
|
|
934
|
+
const transformStream = new TransformStream({
|
|
935
|
+
transform(chunk, controller) {
|
|
936
|
+
controller.enqueue(chunk);
|
|
937
|
+
if (chunk.type === "finish" && chunk.usage) {
|
|
938
|
+
handleUsage(chunk.usage);
|
|
933
939
|
}
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
940
|
+
}
|
|
941
|
+
});
|
|
942
|
+
return {
|
|
943
|
+
...result,
|
|
944
|
+
stream: originalStream.pipeThrough(transformStream)
|
|
945
|
+
};
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
if (prop === "doGenerate" && typeof originalValue === "function") {
|
|
949
|
+
return async function(...args) {
|
|
950
|
+
const result = await originalValue.apply(target, args);
|
|
951
|
+
if (result && result.usage) {
|
|
952
|
+
handleUsage(result.usage);
|
|
939
953
|
}
|
|
940
954
|
return result;
|
|
941
955
|
};
|
|
942
956
|
}
|
|
943
957
|
return originalValue;
|
|
944
958
|
}
|
|
945
|
-
}
|
|
959
|
+
};
|
|
960
|
+
return new Proxy(model, handler);
|
|
946
961
|
}
|
|
947
962
|
var meteredModel = withBilling;
|
|
948
963
|
|
|
964
|
+
// src/ai-sdk/declarative.ts
|
|
965
|
+
function createVibezModel(modelOrId, options = {}) {
|
|
966
|
+
if (typeof modelOrId === "object" && modelOrId !== null) {
|
|
967
|
+
return withBilling(modelOrId, options);
|
|
968
|
+
}
|
|
969
|
+
if (typeof modelOrId === "string") {
|
|
970
|
+
const rawId = modelOrId;
|
|
971
|
+
let providerName = "openai";
|
|
972
|
+
let cleanModelId = rawId;
|
|
973
|
+
if (rawId.includes("/")) {
|
|
974
|
+
const parts = rawId.split("/");
|
|
975
|
+
providerName = parts[0].toLowerCase();
|
|
976
|
+
cleanModelId = parts.slice(1).join("/");
|
|
977
|
+
}
|
|
978
|
+
const apiKey = options.apiKey || process.env.AI_GATEWAY_API_KEY || process.env.OPENAI_API_KEY || process.env.ANTHROPIC_API_KEY || process.env.GOOGLE_GENERATIVE_AI_API_KEY;
|
|
979
|
+
const baseURL = options.baseURL || process.env.AI_GATEWAY_BASE_URL || (providerName === "openai" ? "https://api.openai.com/v1" : void 0);
|
|
980
|
+
let baseModelInstance = null;
|
|
981
|
+
try {
|
|
982
|
+
if (providerName === "openai" || providerName === "gateway" || !providerName) {
|
|
983
|
+
const { createOpenAI } = __require("@ai-sdk/openai");
|
|
984
|
+
const openaiProvider = createOpenAI({ apiKey, baseURL });
|
|
985
|
+
baseModelInstance = openaiProvider(cleanModelId);
|
|
986
|
+
} else if (providerName === "anthropic") {
|
|
987
|
+
const { createAnthropic } = __require("@ai-sdk/anthropic");
|
|
988
|
+
const anthropicProvider = createAnthropic({ apiKey, baseURL });
|
|
989
|
+
baseModelInstance = anthropicProvider(cleanModelId);
|
|
990
|
+
} else if (providerName === "google") {
|
|
991
|
+
const { createGoogleGenerativeAI } = __require("@ai-sdk/google");
|
|
992
|
+
const googleProvider = createGoogleGenerativeAI({ apiKey, baseURL });
|
|
993
|
+
baseModelInstance = googleProvider(cleanModelId);
|
|
994
|
+
}
|
|
995
|
+
} catch {
|
|
996
|
+
baseModelInstance = {
|
|
997
|
+
specificationVersion: "v2",
|
|
998
|
+
provider: providerName,
|
|
999
|
+
modelId: cleanModelId
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
if (!baseModelInstance) {
|
|
1003
|
+
baseModelInstance = {
|
|
1004
|
+
specificationVersion: "v2",
|
|
1005
|
+
provider: providerName,
|
|
1006
|
+
modelId: cleanModelId
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
return withBilling(baseModelInstance, options);
|
|
1010
|
+
}
|
|
1011
|
+
return modelOrId;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
949
1014
|
// src/customers/manager.ts
|
|
950
1015
|
import Stripe2 from "stripe";
|
|
951
1016
|
|
|
@@ -1284,43 +1349,12 @@ var VibezCheckClient = class {
|
|
|
1284
1349
|
});
|
|
1285
1350
|
}
|
|
1286
1351
|
/**
|
|
1287
|
-
*
|
|
1352
|
+
* Declarative model resolver for Vercel AI SDK
|
|
1288
1353
|
*/
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
model: params.model,
|
|
1294
|
-
messages: params.messages,
|
|
1295
|
-
stream: true,
|
|
1296
|
-
stream_options: { include_usage: true },
|
|
1297
|
-
temperature: params.temperature
|
|
1298
|
-
});
|
|
1299
|
-
const meteredStream = this.wrapStream(responseStream, {
|
|
1300
|
-
customer: params.customer,
|
|
1301
|
-
model: params.model
|
|
1302
|
-
});
|
|
1303
|
-
const encoder = new TextEncoder();
|
|
1304
|
-
const readable = new ReadableStream({
|
|
1305
|
-
async start(controller) {
|
|
1306
|
-
try {
|
|
1307
|
-
for await (const chunk of meteredStream) {
|
|
1308
|
-
const text = chunk.choices?.[0]?.delta?.content || "";
|
|
1309
|
-
if (text) {
|
|
1310
|
-
controller.enqueue(encoder.encode(text));
|
|
1311
|
-
}
|
|
1312
|
-
}
|
|
1313
|
-
controller.close();
|
|
1314
|
-
} catch (err) {
|
|
1315
|
-
controller.error(err);
|
|
1316
|
-
}
|
|
1317
|
-
}
|
|
1318
|
-
});
|
|
1319
|
-
return new Response(readable, {
|
|
1320
|
-
headers: {
|
|
1321
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
1322
|
-
"Transfer-Encoding": "chunked"
|
|
1323
|
-
}
|
|
1354
|
+
model(modelOrId, options) {
|
|
1355
|
+
return createVibezModel(modelOrId, {
|
|
1356
|
+
...options,
|
|
1357
|
+
meter: this.meter
|
|
1324
1358
|
});
|
|
1325
1359
|
}
|
|
1326
1360
|
/**
|
|
@@ -1339,9 +1373,20 @@ var VibezCheckClient = class {
|
|
|
1339
1373
|
function createVibezCheck(config = {}) {
|
|
1340
1374
|
return new VibezCheckClient(config);
|
|
1341
1375
|
}
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1376
|
+
function vibezcheck(firstArg, secondArg) {
|
|
1377
|
+
if (typeof firstArg === "string" || firstArg && (firstArg.specificationVersion || firstArg.doGenerate || firstArg.doStream)) {
|
|
1378
|
+
return createVibezModel(firstArg, secondArg);
|
|
1379
|
+
}
|
|
1380
|
+
return new VibezCheckClient(firstArg || {});
|
|
1381
|
+
}
|
|
1382
|
+
vibezcheck.calculateCost = calculateCost;
|
|
1383
|
+
vibezcheck.getModelPricing = getModelPricing;
|
|
1384
|
+
vibezcheck.registerModelPricing = registerModelPricing;
|
|
1385
|
+
vibezcheck.create = createVibezCheck;
|
|
1386
|
+
vibezcheck.withBilling = withBilling;
|
|
1387
|
+
vibezcheck.createMeter = createMeter;
|
|
1388
|
+
var vibez = new VibezCheckClient();
|
|
1389
|
+
var vibescheck = vibezcheck;
|
|
1345
1390
|
var vibes = vibez;
|
|
1346
1391
|
export {
|
|
1347
1392
|
AnthropicStreamAccumulator,
|
|
@@ -1352,6 +1397,7 @@ export {
|
|
|
1352
1397
|
MODEL_PRICING_TABLE,
|
|
1353
1398
|
MeterBatcher,
|
|
1354
1399
|
VibezCheckClient,
|
|
1400
|
+
VibezCircuitBreakerError,
|
|
1355
1401
|
VibezMeter,
|
|
1356
1402
|
calculateCost,
|
|
1357
1403
|
calculateUsageCost,
|
|
@@ -1360,6 +1406,7 @@ export {
|
|
|
1360
1406
|
createCustomerManager,
|
|
1361
1407
|
createMeter,
|
|
1362
1408
|
createVibezCheck,
|
|
1409
|
+
createVibezModel,
|
|
1363
1410
|
detectAndExtractUsage,
|
|
1364
1411
|
extractAnthropicResponseUsage,
|
|
1365
1412
|
extractAuthToken,
|