vibezcheck 0.1.0 → 0.2.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.
@@ -0,0 +1,674 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/react/index.ts
21
+ var react_exports = {};
22
+ __export(react_exports, {
23
+ VibezSessionBadge: () => VibezSessionBadge,
24
+ VibezSessionContext: () => VibezSessionContext,
25
+ VibezSessionProvider: () => VibezSessionProvider,
26
+ VibezSessionWidget: () => VibezSessionWidget,
27
+ useVibez: () => useVibez,
28
+ useVibezSession: () => useVibezSession
29
+ });
30
+ module.exports = __toCommonJS(react_exports);
31
+
32
+ // src/react/context.tsx
33
+ var import_react = require("react");
34
+
35
+ // src/pricing/table.ts
36
+ var MODEL_PRICING_TABLE = {
37
+ // --- OpenAI ---
38
+ "gpt-5.6-sol": { inputPer1M: 4, outputPer1M: 20, cachedInputPer1M: 0.4 },
39
+ "gpt-5.6-terra": { inputPer1M: 2, outputPer1M: 12, cachedInputPer1M: 0.2 },
40
+ "gpt-5.6-luna": { inputPer1M: 0.2, outputPer1M: 1.2, cachedInputPer1M: 0.02 },
41
+ "gpt-5": { inputPer1M: 4, outputPer1M: 20, cachedInputPer1M: 0.4 },
42
+ "gpt-5-mini": { inputPer1M: 0.2, outputPer1M: 1.2, cachedInputPer1M: 0.02 },
43
+ "o1": { inputPer1M: 15, outputPer1M: 60, cachedInputPer1M: 7.5 },
44
+ "o1-mini": { inputPer1M: 1.1, outputPer1M: 4.4, cachedInputPer1M: 0.55 },
45
+ "o3": { inputPer1M: 15, outputPer1M: 60, cachedInputPer1M: 7.5 },
46
+ "o3-mini": { inputPer1M: 1.1, outputPer1M: 4.4, cachedInputPer1M: 0.55 },
47
+ "gpt-4o": { inputPer1M: 2.5, outputPer1M: 10, cachedInputPer1M: 1.25 },
48
+ "gpt-4o-mini": { inputPer1M: 0.15, outputPer1M: 0.6, cachedInputPer1M: 0.075 },
49
+ "gpt-4.1": { inputPer1M: 2, outputPer1M: 8, cachedInputPer1M: 1 },
50
+ "gpt-4.1-nano": { inputPer1M: 0.1, outputPer1M: 0.4, cachedInputPer1M: 0.05 },
51
+ "text-embedding-3-small": { inputPer1M: 0.02, outputPer1M: 0 },
52
+ "text-embedding-3-large": { inputPer1M: 0.13, outputPer1M: 0 },
53
+ // --- Anthropic ---
54
+ "claude-3-7-sonnet": { inputPer1M: 0.59, outputPer1M: 2.93, cachedInputPer1M: 0.3 },
55
+ "claude-sonnet-5": { inputPer1M: 2, outputPer1M: 10, cachedInputPer1M: 0.3 },
56
+ "claude-3-5-sonnet": { inputPer1M: 3, outputPer1M: 15, cachedInputPer1M: 0.3 },
57
+ "claude-3-5-haiku": { inputPer1M: 0.8, outputPer1M: 4, cachedInputPer1M: 0.08 },
58
+ "haiku-4.5": { inputPer1M: 1, outputPer1M: 5, cachedInputPer1M: 0.1 },
59
+ "claude-opus-5": { inputPer1M: 5, outputPer1M: 25, cachedInputPer1M: 1.5 },
60
+ "claude-3-opus": { inputPer1M: 15, outputPer1M: 75, cachedInputPer1M: 1.5 },
61
+ // --- Google Gemini ---
62
+ "gemini-3.7-flash": { inputPer1M: 0.75, outputPer1M: 3.75, cachedInputPer1M: 0.18 },
63
+ "gemini-3.1-pro": { inputPer1M: 2, outputPer1M: 12, cachedInputPer1M: 0.5 },
64
+ "gemini-3.5-flash": { inputPer1M: 1.5, outputPer1M: 9, cachedInputPer1M: 0.38 },
65
+ "gemini-3.1-flash-lite": { inputPer1M: 0.25, outputPer1M: 1.5, cachedInputPer1M: 0.06 },
66
+ "gemini-2.0-flash": { inputPer1M: 0.1, outputPer1M: 0.4, cachedInputPer1M: 0.025 },
67
+ "gemini-1.5-pro": { inputPer1M: 1.25, outputPer1M: 5, cachedInputPer1M: 0.3125 },
68
+ "gemini-1.5-flash": { inputPer1M: 0.075, outputPer1M: 0.3, cachedInputPer1M: 0.01875 },
69
+ // --- xAI Grok ---
70
+ "grok-4.6": { inputPer1M: 3, outputPer1M: 15 },
71
+ "grok-2": { inputPer1M: 2, outputPer1M: 10 },
72
+ "grok-2-vision": { inputPer1M: 2, outputPer1M: 10 },
73
+ "grok-beta": { inputPer1M: 5, outputPer1M: 15 },
74
+ // --- Mistral ---
75
+ "mistral-large-3": { inputPer1M: 2, outputPer1M: 6 },
76
+ "mistral-large-latest": { inputPer1M: 2, outputPer1M: 6 },
77
+ "codestral-latest": { inputPer1M: 0.3, outputPer1M: 0.9 },
78
+ "mistral-small-latest": { inputPer1M: 0.2, outputPer1M: 0.6 },
79
+ "ministral-8b-latest": { inputPer1M: 0.1, outputPer1M: 0.1 },
80
+ // --- Groq LPUs ---
81
+ "llama-3.3-70b-versatile": { inputPer1M: 0.59, outputPer1M: 0.79 },
82
+ "llama-3.1-8b-instant": { inputPer1M: 0.05, outputPer1M: 0.08 },
83
+ "deepseek-r1-distill-llama-70b": { inputPer1M: 0.75, outputPer1M: 0.99 },
84
+ "qwen-2.5-32b": { inputPer1M: 0.29, outputPer1M: 0.39 },
85
+ // --- DeepSeek ---
86
+ "deepseek-v4-pro": { inputPer1M: 0.66, outputPer1M: 1.98, cachedInputPer1M: 0.15 },
87
+ "deepseek-v4-flash": { inputPer1M: 0.22, outputPer1M: 0.66, cachedInputPer1M: 0.05 },
88
+ "deepseek-chat": { inputPer1M: 0.22, outputPer1M: 0.66, cachedInputPer1M: 0.05 },
89
+ "deepseek-reasoner": { inputPer1M: 0.66, outputPer1M: 1.98, cachedInputPer1M: 0.15 },
90
+ // --- Cohere ---
91
+ "command-r-plus": { inputPer1M: 2.5, outputPer1M: 10 },
92
+ "command-r": { inputPer1M: 0.15, outputPer1M: 0.6 }
93
+ };
94
+ var customPricingRegistry = {};
95
+ function normalizeModelKey(rawModel) {
96
+ if (!rawModel) return "unknown";
97
+ let model = rawModel.toLowerCase().trim();
98
+ if (model.includes("/")) {
99
+ model = model.split("/")[1] || model;
100
+ }
101
+ model = model.replace(/-\d{8}$/, "");
102
+ model = model.replace(/-\d{4}-\d{2}-\d{2}$/, "");
103
+ return model;
104
+ }
105
+ function getModelPricing(modelName) {
106
+ const normalized = normalizeModelKey(modelName);
107
+ if (customPricingRegistry[normalized]) {
108
+ return customPricingRegistry[normalized];
109
+ }
110
+ if (customPricingRegistry[modelName]) {
111
+ return customPricingRegistry[modelName];
112
+ }
113
+ if (MODEL_PRICING_TABLE[normalized]) {
114
+ return MODEL_PRICING_TABLE[normalized];
115
+ }
116
+ if (MODEL_PRICING_TABLE[modelName]) {
117
+ return MODEL_PRICING_TABLE[modelName];
118
+ }
119
+ return {
120
+ inputPer1M: 1,
121
+ outputPer1M: 3,
122
+ cachedInputPer1M: 0.5
123
+ };
124
+ }
125
+
126
+ // src/pricing/calculator.ts
127
+ function calculateCost(params) {
128
+ const rates = getModelPricing(params.model);
129
+ const inputTokens = params.inputTokens ?? 0;
130
+ const outputTokens = params.outputTokens ?? 0;
131
+ const reasoningTokens = params.reasoningTokens ?? 0;
132
+ const cachedTokens = params.cachedTokens ?? 0;
133
+ const regularInputTokens = Math.max(0, inputTokens - cachedTokens);
134
+ const regularInputCost = regularInputTokens / 1e6 * rates.inputPer1M;
135
+ const cachedRate = rates.cachedInputPer1M ?? rates.inputPer1M * 0.5;
136
+ const cachedInputCost = cachedTokens / 1e6 * cachedRate;
137
+ const inputCostUSD = regularInputCost + cachedInputCost;
138
+ const outputCostUSD = outputTokens / 1e6 * rates.outputPer1M;
139
+ const reasoningRate = rates.reasoningPer1M ?? rates.outputPer1M;
140
+ const reasoningCostUSD = reasoningTokens / 1e6 * reasoningRate;
141
+ const standardCacheCost = cachedTokens / 1e6 * rates.inputPer1M;
142
+ const cachedDiscountUSD = Math.max(0, standardCacheCost - cachedInputCost);
143
+ const totalUSD = inputCostUSD + outputCostUSD;
144
+ const markup = params.markupMultiplier ?? 1;
145
+ const retailUSD = markup !== 1 ? totalUSD * markup : void 0;
146
+ return {
147
+ inputCostUSD: Number(inputCostUSD.toFixed(8)),
148
+ outputCostUSD: Number(outputCostUSD.toFixed(8)),
149
+ reasoningCostUSD: reasoningTokens > 0 ? Number(reasoningCostUSD.toFixed(8)) : void 0,
150
+ cachedDiscountUSD: cachedTokens > 0 ? Number(cachedDiscountUSD.toFixed(8)) : void 0,
151
+ totalUSD: Number(totalUSD.toFixed(8)),
152
+ retailUSD: retailUSD ? Number(retailUSD.toFixed(8)) : void 0,
153
+ currency: rates.currency || "USD"
154
+ };
155
+ }
156
+ function calculateUsageCost(model, usage, markupMultiplier) {
157
+ return calculateCost({
158
+ model,
159
+ inputTokens: usage.inputTokens,
160
+ outputTokens: usage.outputTokens,
161
+ reasoningTokens: usage.reasoningTokens,
162
+ cachedTokens: usage.cachedTokens,
163
+ cacheWriteTokens: usage.cacheWriteTokens,
164
+ markupMultiplier
165
+ });
166
+ }
167
+
168
+ // src/react/context.tsx
169
+ var import_jsx_runtime = require("react/jsx-runtime");
170
+ var INITIAL_USAGE = {
171
+ inputTokens: 0,
172
+ outputTokens: 0,
173
+ totalTokens: 0,
174
+ reasoningTokens: 0,
175
+ visibleOutputTokens: 0,
176
+ cachedTokens: 0
177
+ };
178
+ var INITIAL_COST = {
179
+ inputCostUSD: 0,
180
+ outputCostUSD: 0,
181
+ reasoningCostUSD: 0,
182
+ cachedDiscountUSD: 0,
183
+ totalUSD: 0,
184
+ currency: "USD"
185
+ };
186
+ var VibezSessionContext = (0, import_react.createContext)(null);
187
+ function generateId() {
188
+ return "sess_" + Math.random().toString(36).substring(2, 11) + "_" + Date.now().toString(36);
189
+ }
190
+ var VibezSessionProvider = ({
191
+ children,
192
+ sessionId: customSessionId,
193
+ persist = "memory",
194
+ storage,
195
+ storageKey = "vibez_session_",
196
+ markupMultiplier,
197
+ onTurnRecorded
198
+ }) => {
199
+ const [sessionId, setSessionId] = (0, import_react.useState)(() => customSessionId || generateId());
200
+ const [turnCount, setTurnCount] = (0, import_react.useState)(0);
201
+ const [sessionUsage, setSessionUsage] = (0, import_react.useState)(INITIAL_USAGE);
202
+ const [sessionCost, setSessionCost] = (0, import_react.useState)(INITIAL_COST);
203
+ const [byModel, setByModel] = (0, import_react.useState)({});
204
+ const [history, setHistory] = (0, import_react.useState)([]);
205
+ const fullStorageKey = (0, import_react.useMemo)(() => `${storageKey}${sessionId}`, [storageKey, sessionId]);
206
+ (0, import_react.useEffect)(() => {
207
+ if (persist === "memory") return;
208
+ try {
209
+ if (persist === "sessionStorage" && typeof window !== "undefined" && window.sessionStorage) {
210
+ const data = window.sessionStorage.getItem(fullStorageKey);
211
+ if (data) {
212
+ const parsed = JSON.parse(data);
213
+ setTurnCount(parsed.turnCount);
214
+ setSessionUsage(parsed.sessionUsage);
215
+ setSessionCost(parsed.sessionCost);
216
+ setByModel(parsed.byModel);
217
+ setHistory(parsed.history);
218
+ }
219
+ } else if (persist === "localStorage" && typeof window !== "undefined" && window.localStorage) {
220
+ const data = window.localStorage.getItem(fullStorageKey);
221
+ if (data) {
222
+ const parsed = JSON.parse(data);
223
+ setTurnCount(parsed.turnCount);
224
+ setSessionUsage(parsed.sessionUsage);
225
+ setSessionCost(parsed.sessionCost);
226
+ setByModel(parsed.byModel);
227
+ setHistory(parsed.history);
228
+ }
229
+ } else if (persist === "custom" && storage) {
230
+ const res = storage.getItem(fullStorageKey);
231
+ if (res instanceof Promise) {
232
+ res.then((data) => {
233
+ if (data) {
234
+ const parsed = JSON.parse(data);
235
+ setTurnCount(parsed.turnCount);
236
+ setSessionUsage(parsed.sessionUsage);
237
+ setSessionCost(parsed.sessionCost);
238
+ setByModel(parsed.byModel);
239
+ setHistory(parsed.history);
240
+ }
241
+ });
242
+ } else if (res) {
243
+ const parsed = JSON.parse(res);
244
+ setTurnCount(parsed.turnCount);
245
+ setSessionUsage(parsed.sessionUsage);
246
+ setSessionCost(parsed.sessionCost);
247
+ setByModel(parsed.byModel);
248
+ setHistory(parsed.history);
249
+ }
250
+ }
251
+ } catch {
252
+ }
253
+ }, [persist, fullStorageKey, storage]);
254
+ const saveState = (0, import_react.useCallback)(
255
+ (newState) => {
256
+ if (persist === "memory") return;
257
+ try {
258
+ const json = JSON.stringify(newState);
259
+ if (persist === "sessionStorage" && typeof window !== "undefined" && window.sessionStorage) {
260
+ window.sessionStorage.setItem(fullStorageKey, json);
261
+ } else if (persist === "localStorage" && typeof window !== "undefined" && window.localStorage) {
262
+ window.localStorage.setItem(fullStorageKey, json);
263
+ } else if (persist === "custom" && storage) {
264
+ storage.setItem(fullStorageKey, json);
265
+ }
266
+ } catch {
267
+ }
268
+ },
269
+ [persist, fullStorageKey, storage]
270
+ );
271
+ const recordTurn = (0, import_react.useCallback)(
272
+ ({ model, usage: rawUsage, metadata }) => {
273
+ const inputTokens = rawUsage.promptTokens ?? rawUsage.inputTokens ?? 0;
274
+ const outputTokens = rawUsage.completionTokens ?? rawUsage.outputTokens ?? 0;
275
+ const reasoningTokens = rawUsage.reasoningTokens ?? rawUsage.completionTokensDetails?.reasoning_tokens ?? 0;
276
+ const cachedTokens = rawUsage.cachedTokens ?? rawUsage.promptTokensDetails?.cached_tokens ?? 0;
277
+ const cacheWriteTokens = rawUsage.cacheWriteTokens ?? 0;
278
+ const turnUsage = {
279
+ inputTokens,
280
+ outputTokens,
281
+ totalTokens: rawUsage.totalTokens ?? inputTokens + outputTokens,
282
+ reasoningTokens: reasoningTokens > 0 ? reasoningTokens : void 0,
283
+ visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),
284
+ cachedTokens: cachedTokens > 0 ? cachedTokens : void 0,
285
+ cacheWriteTokens: cacheWriteTokens > 0 ? cacheWriteTokens : void 0
286
+ };
287
+ const turnCost = calculateUsageCost(model, turnUsage, markupMultiplier);
288
+ const record = {
289
+ id: "turn_" + Math.random().toString(36).substring(2, 9) + "_" + Date.now().toString(36),
290
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
291
+ model,
292
+ usage: turnUsage,
293
+ cost: turnCost,
294
+ metadata
295
+ };
296
+ const newTurnCount = turnCount + 1;
297
+ setTurnCount(newTurnCount);
298
+ const newUsage = {
299
+ inputTokens: sessionUsage.inputTokens + inputTokens,
300
+ outputTokens: sessionUsage.outputTokens + outputTokens,
301
+ totalTokens: sessionUsage.totalTokens + turnUsage.totalTokens,
302
+ reasoningTokens: (sessionUsage.reasoningTokens ?? 0) + (turnUsage.reasoningTokens ?? 0),
303
+ visibleOutputTokens: (sessionUsage.visibleOutputTokens ?? 0) + (turnUsage.visibleOutputTokens ?? outputTokens),
304
+ cachedTokens: (sessionUsage.cachedTokens ?? 0) + (turnUsage.cachedTokens ?? 0),
305
+ cacheWriteTokens: (sessionUsage.cacheWriteTokens ?? 0) + (turnUsage.cacheWriteTokens ?? 0)
306
+ };
307
+ setSessionUsage(newUsage);
308
+ const newCost = {
309
+ inputCostUSD: Number((sessionCost.inputCostUSD + turnCost.inputCostUSD).toFixed(6)),
310
+ outputCostUSD: Number((sessionCost.outputCostUSD + turnCost.outputCostUSD).toFixed(6)),
311
+ reasoningCostUSD: turnCost.reasoningCostUSD !== void 0 || sessionCost.reasoningCostUSD !== void 0 ? Number(
312
+ ((sessionCost.reasoningCostUSD ?? 0) + (turnCost.reasoningCostUSD ?? 0)).toFixed(6)
313
+ ) : void 0,
314
+ cachedDiscountUSD: turnCost.cachedDiscountUSD !== void 0 || sessionCost.cachedDiscountUSD !== void 0 ? Number(
315
+ ((sessionCost.cachedDiscountUSD ?? 0) + (turnCost.cachedDiscountUSD ?? 0)).toFixed(6)
316
+ ) : void 0,
317
+ totalUSD: Number((sessionCost.totalUSD + turnCost.totalUSD).toFixed(6)),
318
+ retailUSD: turnCost.retailUSD !== void 0 || sessionCost.retailUSD !== void 0 ? Number(((sessionCost.retailUSD ?? 0) + (turnCost.retailUSD ?? 0)).toFixed(6)) : void 0,
319
+ currency: turnCost.currency || "USD"
320
+ };
321
+ setSessionCost(newCost);
322
+ const prevModelStats = byModel[model] || {
323
+ turns: 0,
324
+ usage: { ...INITIAL_USAGE },
325
+ cost: { ...INITIAL_COST }
326
+ };
327
+ const newModelStats = {
328
+ turns: prevModelStats.turns + 1,
329
+ usage: {
330
+ inputTokens: prevModelStats.usage.inputTokens + inputTokens,
331
+ outputTokens: prevModelStats.usage.outputTokens + outputTokens,
332
+ totalTokens: prevModelStats.usage.totalTokens + turnUsage.totalTokens,
333
+ reasoningTokens: (prevModelStats.usage.reasoningTokens ?? 0) + (turnUsage.reasoningTokens ?? 0),
334
+ visibleOutputTokens: (prevModelStats.usage.visibleOutputTokens ?? 0) + (turnUsage.visibleOutputTokens ?? outputTokens),
335
+ cachedTokens: (prevModelStats.usage.cachedTokens ?? 0) + (turnUsage.cachedTokens ?? 0)
336
+ },
337
+ cost: {
338
+ inputCostUSD: Number(
339
+ (prevModelStats.cost.inputCostUSD + turnCost.inputCostUSD).toFixed(6)
340
+ ),
341
+ outputCostUSD: Number(
342
+ (prevModelStats.cost.outputCostUSD + turnCost.outputCostUSD).toFixed(6)
343
+ ),
344
+ totalUSD: Number((prevModelStats.cost.totalUSD + turnCost.totalUSD).toFixed(6)),
345
+ currency: turnCost.currency || "USD"
346
+ }
347
+ };
348
+ const newByModel = {
349
+ ...byModel,
350
+ [model]: newModelStats
351
+ };
352
+ setByModel(newByModel);
353
+ const newHistory = [...history, record];
354
+ setHistory(newHistory);
355
+ const updatedState = {
356
+ sessionId,
357
+ turnCount: newTurnCount,
358
+ sessionUsage: newUsage,
359
+ sessionCost: newCost,
360
+ byModel: newByModel,
361
+ history: newHistory
362
+ };
363
+ saveState(updatedState);
364
+ if (onTurnRecorded) {
365
+ onTurnRecorded(record, updatedState);
366
+ }
367
+ return record;
368
+ },
369
+ [
370
+ turnCount,
371
+ sessionUsage,
372
+ sessionCost,
373
+ byModel,
374
+ history,
375
+ sessionId,
376
+ markupMultiplier,
377
+ onTurnRecorded,
378
+ saveState
379
+ ]
380
+ );
381
+ const resetSession = (0, import_react.useCallback)(
382
+ (newSessionId) => {
383
+ const nextId = newSessionId || generateId();
384
+ setSessionId(nextId);
385
+ setTurnCount(0);
386
+ setSessionUsage(INITIAL_USAGE);
387
+ setSessionCost(INITIAL_COST);
388
+ setByModel({});
389
+ setHistory([]);
390
+ if (persist === "sessionStorage" && typeof window !== "undefined" && window.sessionStorage) {
391
+ window.sessionStorage.removeItem(fullStorageKey);
392
+ } else if (persist === "localStorage" && typeof window !== "undefined" && window.localStorage) {
393
+ window.localStorage.removeItem(fullStorageKey);
394
+ } else if (persist === "custom" && storage) {
395
+ storage.removeItem(fullStorageKey);
396
+ }
397
+ },
398
+ [persist, fullStorageKey, storage]
399
+ );
400
+ const value = (0, import_react.useMemo)(
401
+ () => ({
402
+ sessionId,
403
+ turnCount,
404
+ sessionUsage,
405
+ sessionCost,
406
+ byModel,
407
+ history,
408
+ recordTurn,
409
+ resetSession
410
+ }),
411
+ [sessionId, turnCount, sessionUsage, sessionCost, byModel, history, recordTurn, resetSession]
412
+ );
413
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VibezSessionContext.Provider, { value, children });
414
+ };
415
+
416
+ // src/react/hooks.ts
417
+ var import_react2 = require("react");
418
+ function useVibezSession() {
419
+ const context = (0, import_react2.useContext)(VibezSessionContext);
420
+ if (!context) {
421
+ throw new Error(
422
+ "[vibezcheck/react] useVibezSession must be used within a <VibezSessionProvider>."
423
+ );
424
+ }
425
+ return context;
426
+ }
427
+ var useVibez = useVibezSession;
428
+
429
+ // src/react/widget.tsx
430
+ var import_react3 = require("react");
431
+ var import_jsx_runtime2 = require("react/jsx-runtime");
432
+ var VibezSessionWidget = ({
433
+ position = "bottom-right",
434
+ showCost = true,
435
+ showTokens = true,
436
+ showReasoning = true,
437
+ theme = "auto",
438
+ className,
439
+ style
440
+ }) => {
441
+ const { sessionUsage, sessionCost, turnCount, byModel } = useVibezSession();
442
+ const [expanded, setExpanded] = (0, import_react3.useState)(false);
443
+ const hasUsage = sessionUsage.totalTokens > 0;
444
+ const isDark = theme === "dark" || theme === "auto" && typeof window !== "undefined" && window.matchMedia?.("(prefers-color-scheme: dark)").matches;
445
+ const colors = {
446
+ bg: isDark ? "#171717" : "#ffffff",
447
+ text: isDark ? "#f5f5f5" : "#171717",
448
+ subtext: isDark ? "#a3a3a3" : "#737373",
449
+ border: isDark ? "#262626" : "#e5e5e5",
450
+ accent: "#8b5cf6",
451
+ reasoningBg: isDark ? "#2e1065" : "#f3e8ff",
452
+ reasoningText: isDark ? "#c084fc" : "#7c3aed"
453
+ };
454
+ const getPositionStyles = () => {
455
+ if (position === "inline") return {};
456
+ const base = { position: "fixed", zIndex: 9999 };
457
+ switch (position) {
458
+ case "bottom-right":
459
+ return { ...base, bottom: "20px", right: "20px" };
460
+ case "bottom-left":
461
+ return { ...base, bottom: "20px", left: "20px" };
462
+ case "top-right":
463
+ return { ...base, top: "20px", right: "20px" };
464
+ case "top-left":
465
+ return { ...base, top: "20px", left: "20px" };
466
+ default:
467
+ return base;
468
+ }
469
+ };
470
+ const formatTokens = (num) => {
471
+ if (num >= 1e6) return (num / 1e6).toFixed(1) + "M";
472
+ if (num >= 1e3) return (num / 1e3).toFixed(1) + "k";
473
+ return num.toString();
474
+ };
475
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
476
+ "div",
477
+ {
478
+ className,
479
+ style: {
480
+ ...getPositionStyles(),
481
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
482
+ fontSize: "13px",
483
+ ...style
484
+ },
485
+ children: [
486
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
487
+ "div",
488
+ {
489
+ onClick: () => setExpanded(!expanded),
490
+ style: {
491
+ display: "flex",
492
+ alignItems: "center",
493
+ gap: "8px",
494
+ padding: "8px 14px",
495
+ backgroundColor: colors.bg,
496
+ color: colors.text,
497
+ border: `1px solid ${colors.border}`,
498
+ borderRadius: "9999px",
499
+ boxShadow: "0 4px 12px rgba(0,0,0,0.08)",
500
+ cursor: "pointer",
501
+ userSelect: "none",
502
+ transition: "all 0.15s ease"
503
+ },
504
+ children: [
505
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: colors.accent, fontWeight: "bold" }, children: "\u26A1" }),
506
+ showTokens && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { fontWeight: 600 }, children: [
507
+ formatTokens(sessionUsage.totalTokens),
508
+ " tokens"
509
+ ] }),
510
+ showCost && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { color: colors.subtext }, children: [
511
+ "($",
512
+ sessionCost.totalUSD.toFixed(4),
513
+ ")"
514
+ ] }),
515
+ showReasoning && sessionUsage.reasoningTokens > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
516
+ "span",
517
+ {
518
+ style: {
519
+ fontSize: "11px",
520
+ padding: "2px 6px",
521
+ borderRadius: "6px",
522
+ backgroundColor: colors.reasoningBg,
523
+ color: colors.reasoningText,
524
+ fontWeight: 500
525
+ },
526
+ children: [
527
+ "\u{1F9E0} ",
528
+ formatTokens(sessionUsage.reasoningTokens)
529
+ ]
530
+ }
531
+ ),
532
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: colors.subtext, fontSize: "10px" }, children: expanded ? "\u25B2" : "\u25BC" })
533
+ ]
534
+ }
535
+ ),
536
+ expanded && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
537
+ "div",
538
+ {
539
+ style: {
540
+ marginTop: "8px",
541
+ padding: "14px",
542
+ backgroundColor: colors.bg,
543
+ color: colors.text,
544
+ border: `1px solid ${colors.border}`,
545
+ borderRadius: "12px",
546
+ boxShadow: "0 10px 25px rgba(0,0,0,0.15)",
547
+ width: "260px"
548
+ },
549
+ children: [
550
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
551
+ "div",
552
+ {
553
+ style: {
554
+ display: "flex",
555
+ justifyContent: "space-between",
556
+ fontWeight: 600,
557
+ marginBottom: "8px",
558
+ paddingBottom: "6px",
559
+ borderBottom: `1px solid ${colors.border}`
560
+ },
561
+ children: [
562
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Live Session Usage" }),
563
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { color: colors.subtext }, children: [
564
+ turnCount,
565
+ " turns"
566
+ ] })
567
+ ]
568
+ }
569
+ ),
570
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "6px", fontSize: "12px" }, children: [
571
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
572
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: colors.subtext }, children: "Prompt Input:" }),
573
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: sessionUsage.inputTokens.toLocaleString() })
574
+ ] }),
575
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
576
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: colors.subtext }, children: "Output Tokens:" }),
577
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: sessionUsage.outputTokens.toLocaleString() })
578
+ ] }),
579
+ sessionUsage.reasoningTokens > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", color: colors.reasoningText }, children: [
580
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u{1F9E0} Thinking Tokens:" }),
581
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: sessionUsage.reasoningTokens.toLocaleString() })
582
+ ] }),
583
+ sessionUsage.cachedTokens > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", color: "#10b981" }, children: [
584
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u26A1 Cached Tokens:" }),
585
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: sessionUsage.cachedTokens.toLocaleString() })
586
+ ] }),
587
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
588
+ "div",
589
+ {
590
+ style: {
591
+ display: "flex",
592
+ justifyContent: "space-between",
593
+ fontWeight: 600,
594
+ marginTop: "6px",
595
+ paddingTop: "6px",
596
+ borderTop: `1px solid ${colors.border}`
597
+ },
598
+ children: [
599
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Session Cost:" }),
600
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
601
+ "$",
602
+ sessionCost.totalUSD.toFixed(5),
603
+ " ",
604
+ sessionCost.currency
605
+ ] })
606
+ ]
607
+ }
608
+ )
609
+ ] })
610
+ ]
611
+ }
612
+ )
613
+ ]
614
+ }
615
+ );
616
+ };
617
+
618
+ // src/react/badge.tsx
619
+ var import_jsx_runtime3 = require("react/jsx-runtime");
620
+ var VibezSessionBadge = ({
621
+ showCost = true,
622
+ showTokens = true,
623
+ className,
624
+ style
625
+ }) => {
626
+ const { sessionUsage, sessionCost } = useVibezSession();
627
+ const formatTokens = (num) => {
628
+ if (num >= 1e6) return (num / 1e6).toFixed(1) + "M";
629
+ if (num >= 1e3) return (num / 1e3).toFixed(1) + "k";
630
+ return num.toString();
631
+ };
632
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
633
+ "span",
634
+ {
635
+ className,
636
+ style: {
637
+ display: "inline-flex",
638
+ alignItems: "center",
639
+ gap: "5px",
640
+ padding: "3px 8px",
641
+ fontSize: "11px",
642
+ fontWeight: 500,
643
+ borderRadius: "9999px",
644
+ backgroundColor: "rgba(139, 92, 246, 0.1)",
645
+ color: "#8b5cf6",
646
+ border: "1px solid rgba(139, 92, 246, 0.2)",
647
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
648
+ ...style
649
+ },
650
+ children: [
651
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u26A1" }),
652
+ showTokens && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
653
+ formatTokens(sessionUsage.totalTokens),
654
+ " tok"
655
+ ] }),
656
+ showCost && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
657
+ "($",
658
+ sessionCost.totalUSD.toFixed(4),
659
+ ")"
660
+ ] })
661
+ ]
662
+ }
663
+ );
664
+ };
665
+ // Annotate the CommonJS export names for ESM import in node:
666
+ 0 && (module.exports = {
667
+ VibezSessionBadge,
668
+ VibezSessionContext,
669
+ VibezSessionProvider,
670
+ VibezSessionWidget,
671
+ useVibez,
672
+ useVibezSession
673
+ });
674
+ //# sourceMappingURL=index.js.map