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/react/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { T as TokenUsage, I as InferenceCost } from '../types-
|
|
2
|
-
import React$1 from 'react';
|
|
1
|
+
import { T as TokenUsage, I as InferenceCost } from '../types-DCuzLVyc.mjs';
|
|
2
|
+
import * as React$1 from 'react';
|
|
3
|
+
import React__default from 'react';
|
|
3
4
|
import 'stripe';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -122,33 +123,84 @@ interface VibezSessionBadgeProps {
|
|
|
122
123
|
style?: React.CSSProperties;
|
|
123
124
|
}
|
|
124
125
|
|
|
125
|
-
declare const VibezSessionContext:
|
|
126
|
-
declare const VibezSessionProvider:
|
|
126
|
+
declare const VibezSessionContext: React__default.Context<VibezSessionContextValue | null>;
|
|
127
|
+
declare const VibezSessionProvider: React__default.FC<VibezSessionProviderProps>;
|
|
127
128
|
|
|
128
129
|
/**
|
|
129
130
|
* Hook to access live session usage, cost totals, and turn recorder
|
|
131
|
+
*/
|
|
132
|
+
declare function useVibezSession(): VibezSessionContextValue;
|
|
133
|
+
declare const useVibez: typeof useVibezSession;
|
|
134
|
+
interface VibezChatMessage {
|
|
135
|
+
id: string;
|
|
136
|
+
role: 'user' | 'assistant' | 'system';
|
|
137
|
+
content: string;
|
|
138
|
+
annotations?: Array<{
|
|
139
|
+
type: string;
|
|
140
|
+
reasoning?: string;
|
|
141
|
+
[key: string]: any;
|
|
142
|
+
}>;
|
|
143
|
+
createdAt?: Date;
|
|
144
|
+
}
|
|
145
|
+
interface UseVibezChatOptions {
|
|
146
|
+
api?: string;
|
|
147
|
+
model?: string;
|
|
148
|
+
customer?: string;
|
|
149
|
+
body?: Record<string, any>;
|
|
150
|
+
initialMessages?: VibezChatMessage[];
|
|
151
|
+
onFinish?: (message: VibezChatMessage, usage: any) => void;
|
|
152
|
+
onError?: (error: Error) => void;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Declarative, 1-line Chat Streaming Hook with automatic VibezCheck session tracking.
|
|
130
156
|
*
|
|
131
157
|
* @example
|
|
132
158
|
* ```tsx
|
|
133
|
-
* const {
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* recordTurn({ model: 'gpt-5.6-sol', usage });
|
|
138
|
-
* }
|
|
159
|
+
* const { messages, input, handleInputChange, handleSubmit, isLoading } = useVibezChat({
|
|
160
|
+
* model: 'gpt-4o-mini',
|
|
161
|
+
* customer: 'alex@example.com',
|
|
162
|
+
* });
|
|
139
163
|
* ```
|
|
140
164
|
*/
|
|
141
|
-
declare function
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
165
|
+
declare function useVibezChat(options?: UseVibezChatOptions): {
|
|
166
|
+
messages: VibezChatMessage[];
|
|
167
|
+
setMessages: React$1.Dispatch<React$1.SetStateAction<VibezChatMessage[]>>;
|
|
168
|
+
input: string;
|
|
169
|
+
setInput: React$1.Dispatch<React$1.SetStateAction<string>>;
|
|
170
|
+
handleInputChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
171
|
+
handleSubmit: (e?: React.FormEvent) => void;
|
|
172
|
+
isLoading: boolean;
|
|
173
|
+
stop: () => void;
|
|
174
|
+
append: (userMessage: VibezChatMessage) => Promise<void>;
|
|
175
|
+
};
|
|
146
176
|
|
|
147
|
-
declare const VibezSessionWidget:
|
|
177
|
+
declare const VibezSessionWidget: React__default.FC<VibezSessionWidgetProps>;
|
|
148
178
|
|
|
149
179
|
/**
|
|
150
180
|
* Compact inline badge for chat input bars, headers, or navbars
|
|
151
181
|
*/
|
|
152
|
-
declare const VibezSessionBadge:
|
|
182
|
+
declare const VibezSessionBadge: React__default.FC<VibezSessionBadgeProps>;
|
|
183
|
+
|
|
184
|
+
interface VibezBillingNotice {
|
|
185
|
+
status?: 'requires_payment' | 'limit_reached' | 'upgrade_required';
|
|
186
|
+
customerId?: string;
|
|
187
|
+
customerEmail?: string;
|
|
188
|
+
checkoutUrl?: string;
|
|
189
|
+
tokensUsed?: number;
|
|
190
|
+
costUSD?: number;
|
|
191
|
+
message?: string;
|
|
192
|
+
}
|
|
193
|
+
interface VibezBillingModalProps {
|
|
194
|
+
notice?: VibezBillingNotice | null;
|
|
195
|
+
isOpen?: boolean;
|
|
196
|
+
onClose?: () => void;
|
|
197
|
+
onSuccess?: () => void;
|
|
198
|
+
theme?: 'light' | 'dark';
|
|
199
|
+
testMode?: boolean;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Intuitive React Modal for Stripe Top-Up, Card Registration & Paywall
|
|
203
|
+
*/
|
|
204
|
+
declare const VibezBillingModal: React__default.FC<VibezBillingModalProps>;
|
|
153
205
|
|
|
154
|
-
export { type CustomStorageAdapter, type SessionPersistenceMode, type SessionState, type SessionTurnRecord, VibezSessionBadge, type VibezSessionBadgeProps, VibezSessionContext, type VibezSessionContextValue, VibezSessionProvider, type VibezSessionProviderProps, VibezSessionWidget, type VibezSessionWidgetProps, useVibez, useVibezSession };
|
|
206
|
+
export { type CustomStorageAdapter, type SessionPersistenceMode, type SessionState, type SessionTurnRecord, type UseVibezChatOptions, VibezBillingModal, type VibezBillingModalProps, type VibezBillingNotice, type VibezChatMessage, VibezSessionBadge, type VibezSessionBadgeProps, VibezSessionContext, type VibezSessionContextValue, VibezSessionProvider, type VibezSessionProviderProps, VibezSessionWidget, type VibezSessionWidgetProps, useVibez, useVibezChat, useVibezSession };
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { T as TokenUsage, I as InferenceCost } from '../types-
|
|
2
|
-
import React$1 from 'react';
|
|
1
|
+
import { T as TokenUsage, I as InferenceCost } from '../types-DCuzLVyc.js';
|
|
2
|
+
import * as React$1 from 'react';
|
|
3
|
+
import React__default from 'react';
|
|
3
4
|
import 'stripe';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -122,33 +123,84 @@ interface VibezSessionBadgeProps {
|
|
|
122
123
|
style?: React.CSSProperties;
|
|
123
124
|
}
|
|
124
125
|
|
|
125
|
-
declare const VibezSessionContext:
|
|
126
|
-
declare const VibezSessionProvider:
|
|
126
|
+
declare const VibezSessionContext: React__default.Context<VibezSessionContextValue | null>;
|
|
127
|
+
declare const VibezSessionProvider: React__default.FC<VibezSessionProviderProps>;
|
|
127
128
|
|
|
128
129
|
/**
|
|
129
130
|
* Hook to access live session usage, cost totals, and turn recorder
|
|
131
|
+
*/
|
|
132
|
+
declare function useVibezSession(): VibezSessionContextValue;
|
|
133
|
+
declare const useVibez: typeof useVibezSession;
|
|
134
|
+
interface VibezChatMessage {
|
|
135
|
+
id: string;
|
|
136
|
+
role: 'user' | 'assistant' | 'system';
|
|
137
|
+
content: string;
|
|
138
|
+
annotations?: Array<{
|
|
139
|
+
type: string;
|
|
140
|
+
reasoning?: string;
|
|
141
|
+
[key: string]: any;
|
|
142
|
+
}>;
|
|
143
|
+
createdAt?: Date;
|
|
144
|
+
}
|
|
145
|
+
interface UseVibezChatOptions {
|
|
146
|
+
api?: string;
|
|
147
|
+
model?: string;
|
|
148
|
+
customer?: string;
|
|
149
|
+
body?: Record<string, any>;
|
|
150
|
+
initialMessages?: VibezChatMessage[];
|
|
151
|
+
onFinish?: (message: VibezChatMessage, usage: any) => void;
|
|
152
|
+
onError?: (error: Error) => void;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Declarative, 1-line Chat Streaming Hook with automatic VibezCheck session tracking.
|
|
130
156
|
*
|
|
131
157
|
* @example
|
|
132
158
|
* ```tsx
|
|
133
|
-
* const {
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* recordTurn({ model: 'gpt-5.6-sol', usage });
|
|
138
|
-
* }
|
|
159
|
+
* const { messages, input, handleInputChange, handleSubmit, isLoading } = useVibezChat({
|
|
160
|
+
* model: 'gpt-4o-mini',
|
|
161
|
+
* customer: 'alex@example.com',
|
|
162
|
+
* });
|
|
139
163
|
* ```
|
|
140
164
|
*/
|
|
141
|
-
declare function
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
165
|
+
declare function useVibezChat(options?: UseVibezChatOptions): {
|
|
166
|
+
messages: VibezChatMessage[];
|
|
167
|
+
setMessages: React$1.Dispatch<React$1.SetStateAction<VibezChatMessage[]>>;
|
|
168
|
+
input: string;
|
|
169
|
+
setInput: React$1.Dispatch<React$1.SetStateAction<string>>;
|
|
170
|
+
handleInputChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
171
|
+
handleSubmit: (e?: React.FormEvent) => void;
|
|
172
|
+
isLoading: boolean;
|
|
173
|
+
stop: () => void;
|
|
174
|
+
append: (userMessage: VibezChatMessage) => Promise<void>;
|
|
175
|
+
};
|
|
146
176
|
|
|
147
|
-
declare const VibezSessionWidget:
|
|
177
|
+
declare const VibezSessionWidget: React__default.FC<VibezSessionWidgetProps>;
|
|
148
178
|
|
|
149
179
|
/**
|
|
150
180
|
* Compact inline badge for chat input bars, headers, or navbars
|
|
151
181
|
*/
|
|
152
|
-
declare const VibezSessionBadge:
|
|
182
|
+
declare const VibezSessionBadge: React__default.FC<VibezSessionBadgeProps>;
|
|
183
|
+
|
|
184
|
+
interface VibezBillingNotice {
|
|
185
|
+
status?: 'requires_payment' | 'limit_reached' | 'upgrade_required';
|
|
186
|
+
customerId?: string;
|
|
187
|
+
customerEmail?: string;
|
|
188
|
+
checkoutUrl?: string;
|
|
189
|
+
tokensUsed?: number;
|
|
190
|
+
costUSD?: number;
|
|
191
|
+
message?: string;
|
|
192
|
+
}
|
|
193
|
+
interface VibezBillingModalProps {
|
|
194
|
+
notice?: VibezBillingNotice | null;
|
|
195
|
+
isOpen?: boolean;
|
|
196
|
+
onClose?: () => void;
|
|
197
|
+
onSuccess?: () => void;
|
|
198
|
+
theme?: 'light' | 'dark';
|
|
199
|
+
testMode?: boolean;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Intuitive React Modal for Stripe Top-Up, Card Registration & Paywall
|
|
203
|
+
*/
|
|
204
|
+
declare const VibezBillingModal: React__default.FC<VibezBillingModalProps>;
|
|
153
205
|
|
|
154
|
-
export { type CustomStorageAdapter, type SessionPersistenceMode, type SessionState, type SessionTurnRecord, VibezSessionBadge, type VibezSessionBadgeProps, VibezSessionContext, type VibezSessionContextValue, VibezSessionProvider, type VibezSessionProviderProps, VibezSessionWidget, type VibezSessionWidgetProps, useVibez, useVibezSession };
|
|
206
|
+
export { type CustomStorageAdapter, type SessionPersistenceMode, type SessionState, type SessionTurnRecord, type UseVibezChatOptions, VibezBillingModal, type VibezBillingModalProps, type VibezBillingNotice, type VibezChatMessage, VibezSessionBadge, type VibezSessionBadgeProps, VibezSessionContext, type VibezSessionContextValue, VibezSessionProvider, type VibezSessionProviderProps, VibezSessionWidget, type VibezSessionWidgetProps, useVibez, useVibezChat, useVibezSession };
|
package/dist/react/index.js
CHANGED
|
@@ -20,11 +20,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/react/index.ts
|
|
21
21
|
var react_exports = {};
|
|
22
22
|
__export(react_exports, {
|
|
23
|
+
VibezBillingModal: () => VibezBillingModal,
|
|
23
24
|
VibezSessionBadge: () => VibezSessionBadge,
|
|
24
25
|
VibezSessionContext: () => VibezSessionContext,
|
|
25
26
|
VibezSessionProvider: () => VibezSessionProvider,
|
|
26
27
|
VibezSessionWidget: () => VibezSessionWidget,
|
|
27
28
|
useVibez: () => useVibez,
|
|
29
|
+
useVibezChat: () => useVibezChat,
|
|
28
30
|
useVibezSession: () => useVibezSession
|
|
29
31
|
});
|
|
30
32
|
module.exports = __toCommonJS(react_exports);
|
|
@@ -425,6 +427,193 @@ function useVibezSession() {
|
|
|
425
427
|
return context;
|
|
426
428
|
}
|
|
427
429
|
var useVibez = useVibezSession;
|
|
430
|
+
function useVibezChat(options = {}) {
|
|
431
|
+
const {
|
|
432
|
+
api = "/api/chat",
|
|
433
|
+
model = "gpt-4o-mini",
|
|
434
|
+
customer = "anonymous",
|
|
435
|
+
body = {},
|
|
436
|
+
initialMessages = [],
|
|
437
|
+
onFinish,
|
|
438
|
+
onError
|
|
439
|
+
} = options;
|
|
440
|
+
const session = (0, import_react2.useContext)(VibezSessionContext);
|
|
441
|
+
const [messages, setMessages] = (0, import_react2.useState)(initialMessages);
|
|
442
|
+
const [input, setInput] = (0, import_react2.useState)("");
|
|
443
|
+
const [isLoading, setIsLoading] = (0, import_react2.useState)(false);
|
|
444
|
+
const abortControllerRef = (0, import_react2.useRef)(null);
|
|
445
|
+
const handleInputChange = (0, import_react2.useCallback)(
|
|
446
|
+
(e) => {
|
|
447
|
+
setInput(e.target.value);
|
|
448
|
+
},
|
|
449
|
+
[]
|
|
450
|
+
);
|
|
451
|
+
const append = (0, import_react2.useCallback)(
|
|
452
|
+
async (userMessage) => {
|
|
453
|
+
const updatedMessages = [...messages, userMessage];
|
|
454
|
+
setMessages(updatedMessages);
|
|
455
|
+
setIsLoading(true);
|
|
456
|
+
const assistantId = "msg_" + Math.random().toString(36).substring(2, 9);
|
|
457
|
+
let assistantContent = "";
|
|
458
|
+
let detectedReasoning = "";
|
|
459
|
+
let detectedUsage = {
|
|
460
|
+
promptTokens: 0,
|
|
461
|
+
completionTokens: 0,
|
|
462
|
+
totalTokens: 0,
|
|
463
|
+
reasoningTokens: 0
|
|
464
|
+
};
|
|
465
|
+
setMessages((prev) => [
|
|
466
|
+
...prev,
|
|
467
|
+
{
|
|
468
|
+
id: assistantId,
|
|
469
|
+
role: "assistant",
|
|
470
|
+
content: "",
|
|
471
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
472
|
+
}
|
|
473
|
+
]);
|
|
474
|
+
try {
|
|
475
|
+
abortControllerRef.current = new AbortController();
|
|
476
|
+
const res = await fetch(api, {
|
|
477
|
+
method: "POST",
|
|
478
|
+
headers: { "Content-Type": "application/json" },
|
|
479
|
+
body: JSON.stringify({
|
|
480
|
+
messages: updatedMessages.map((m) => ({
|
|
481
|
+
role: m.role,
|
|
482
|
+
content: m.content
|
|
483
|
+
})),
|
|
484
|
+
model,
|
|
485
|
+
customer,
|
|
486
|
+
...body
|
|
487
|
+
}),
|
|
488
|
+
signal: abortControllerRef.current.signal
|
|
489
|
+
});
|
|
490
|
+
if (!res.ok) {
|
|
491
|
+
const errData = await res.json().catch(() => ({}));
|
|
492
|
+
throw new Error(errData.error || `HTTP error! status: ${res.status}`);
|
|
493
|
+
}
|
|
494
|
+
const reader = res.body?.getReader();
|
|
495
|
+
if (!reader) throw new Error("No stream body available");
|
|
496
|
+
const decoder = new TextDecoder();
|
|
497
|
+
let buffer = "";
|
|
498
|
+
while (true) {
|
|
499
|
+
const { done, value } = await reader.read();
|
|
500
|
+
if (done) break;
|
|
501
|
+
buffer += decoder.decode(value, { stream: true });
|
|
502
|
+
const lines = buffer.split("\n");
|
|
503
|
+
buffer = lines.pop() || "";
|
|
504
|
+
for (const line of lines) {
|
|
505
|
+
if (!line.trim()) continue;
|
|
506
|
+
if (line.startsWith("0:")) {
|
|
507
|
+
try {
|
|
508
|
+
assistantContent += JSON.parse(line.substring(2));
|
|
509
|
+
} catch {
|
|
510
|
+
assistantContent += line.substring(2).replace(/^"|"$/g, "");
|
|
511
|
+
}
|
|
512
|
+
} else if (line.startsWith("d:")) {
|
|
513
|
+
try {
|
|
514
|
+
const data = JSON.parse(line.substring(2));
|
|
515
|
+
if (data.usage) {
|
|
516
|
+
detectedUsage = {
|
|
517
|
+
promptTokens: data.usage.promptTokens ?? 0,
|
|
518
|
+
completionTokens: data.usage.completionTokens ?? 0,
|
|
519
|
+
totalTokens: (data.usage.promptTokens ?? 0) + (data.usage.completionTokens ?? 0),
|
|
520
|
+
reasoningTokens: data.usage.reasoningTokens ?? 0
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
} catch {
|
|
524
|
+
}
|
|
525
|
+
} else if (line.startsWith("e:") || line.startsWith("g:")) {
|
|
526
|
+
try {
|
|
527
|
+
detectedReasoning += JSON.parse(line.substring(2));
|
|
528
|
+
} catch {
|
|
529
|
+
detectedReasoning += line.substring(2);
|
|
530
|
+
}
|
|
531
|
+
} else if (!line.startsWith("f:") && !line.startsWith("2:")) {
|
|
532
|
+
assistantContent += line;
|
|
533
|
+
}
|
|
534
|
+
setMessages(
|
|
535
|
+
(prev) => prev.map(
|
|
536
|
+
(msg) => msg.id === assistantId ? {
|
|
537
|
+
...msg,
|
|
538
|
+
content: assistantContent,
|
|
539
|
+
annotations: detectedReasoning ? [{ type: "reasoning", reasoning: detectedReasoning }] : void 0
|
|
540
|
+
} : msg
|
|
541
|
+
)
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
if (detectedUsage.promptTokens === 0 && detectedUsage.completionTokens === 0) {
|
|
546
|
+
const promptWords = updatedMessages.reduce(
|
|
547
|
+
(acc, m) => acc + m.content.split(/\s+/).length,
|
|
548
|
+
0
|
|
549
|
+
);
|
|
550
|
+
const outputWords = assistantContent.split(/\s+/).length;
|
|
551
|
+
detectedUsage = {
|
|
552
|
+
promptTokens: Math.ceil(promptWords * 1.3),
|
|
553
|
+
completionTokens: Math.ceil(outputWords * 1.3),
|
|
554
|
+
totalTokens: Math.ceil((promptWords + outputWords) * 1.3),
|
|
555
|
+
reasoningTokens: detectedReasoning ? Math.ceil(detectedReasoning.split(/\s+/).length * 1.3) : 0
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
if (session) {
|
|
559
|
+
session.recordTurn({
|
|
560
|
+
model,
|
|
561
|
+
usage: detectedUsage
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
const finalMsg = {
|
|
565
|
+
id: assistantId,
|
|
566
|
+
role: "assistant",
|
|
567
|
+
content: assistantContent,
|
|
568
|
+
annotations: detectedReasoning ? [{ type: "reasoning", reasoning: detectedReasoning }] : void 0,
|
|
569
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
570
|
+
};
|
|
571
|
+
if (onFinish) {
|
|
572
|
+
onFinish(finalMsg, detectedUsage);
|
|
573
|
+
}
|
|
574
|
+
} catch (err) {
|
|
575
|
+
if (err.name === "AbortError") return;
|
|
576
|
+
console.error("[useVibezChat Error]", err);
|
|
577
|
+
if (onError) onError(err);
|
|
578
|
+
} finally {
|
|
579
|
+
setIsLoading(false);
|
|
580
|
+
}
|
|
581
|
+
},
|
|
582
|
+
[api, model, customer, body, messages, session, onFinish, onError]
|
|
583
|
+
);
|
|
584
|
+
const handleSubmit = (0, import_react2.useCallback)(
|
|
585
|
+
(e) => {
|
|
586
|
+
if (e) e.preventDefault();
|
|
587
|
+
if (!input.trim() || isLoading) return;
|
|
588
|
+
const userMsg = {
|
|
589
|
+
id: "msg_" + Math.random().toString(36).substring(2, 9),
|
|
590
|
+
role: "user",
|
|
591
|
+
content: input.trim(),
|
|
592
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
593
|
+
};
|
|
594
|
+
setInput("");
|
|
595
|
+
append(userMsg);
|
|
596
|
+
},
|
|
597
|
+
[input, isLoading, append]
|
|
598
|
+
);
|
|
599
|
+
const stop = (0, import_react2.useCallback)(() => {
|
|
600
|
+
if (abortControllerRef.current) {
|
|
601
|
+
abortControllerRef.current.abort();
|
|
602
|
+
setIsLoading(false);
|
|
603
|
+
}
|
|
604
|
+
}, []);
|
|
605
|
+
return {
|
|
606
|
+
messages,
|
|
607
|
+
setMessages,
|
|
608
|
+
input,
|
|
609
|
+
setInput,
|
|
610
|
+
handleInputChange,
|
|
611
|
+
handleSubmit,
|
|
612
|
+
isLoading,
|
|
613
|
+
stop,
|
|
614
|
+
append
|
|
615
|
+
};
|
|
616
|
+
}
|
|
428
617
|
|
|
429
618
|
// src/react/widget.tsx
|
|
430
619
|
var import_react3 = require("react");
|
|
@@ -662,13 +851,169 @@ var VibezSessionBadge = ({
|
|
|
662
851
|
}
|
|
663
852
|
);
|
|
664
853
|
};
|
|
854
|
+
|
|
855
|
+
// src/react/billing-modal.tsx
|
|
856
|
+
var import_react4 = require("react");
|
|
857
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
858
|
+
var CreditCardIcon = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: [
|
|
859
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { x: "2", y: "5", width: "20", height: "14", rx: "2", strokeWidth: "2" }),
|
|
860
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "2", y1: "10", x2: "22", y2: "10", strokeWidth: "2" })
|
|
861
|
+
] });
|
|
862
|
+
var ShieldCheckIcon = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "h-3.5 w-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" }) });
|
|
863
|
+
var ZapIcon = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "h-3.5 w-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("polygon", { points: "13 2 3 14 12 14 11 22 21 10 12 10 13 2", strokeWidth: "2", strokeLinejoin: "round" }) });
|
|
864
|
+
var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: [
|
|
865
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18", strokeWidth: "2", strokeLinecap: "round" }),
|
|
866
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18", strokeWidth: "2", strokeLinecap: "round" })
|
|
867
|
+
] });
|
|
868
|
+
var CheckIcon = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("polyline", { points: "20 6 9 17 4 12", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
869
|
+
var ArrowRightIcon = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: [
|
|
870
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "5", y1: "12", x2: "19", y2: "12", strokeWidth: "2", strokeLinecap: "round" }),
|
|
871
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("polyline", { points: "12 5 19 12 12 19", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
872
|
+
] });
|
|
873
|
+
var VibezBillingModal = ({
|
|
874
|
+
notice,
|
|
875
|
+
isOpen: explicitIsOpen,
|
|
876
|
+
onClose,
|
|
877
|
+
onSuccess,
|
|
878
|
+
theme = "light",
|
|
879
|
+
testMode = true
|
|
880
|
+
}) => {
|
|
881
|
+
const [loading, setLoading] = (0, import_react4.useState)(false);
|
|
882
|
+
const [successState, setSuccessState] = (0, import_react4.useState)(false);
|
|
883
|
+
const [selectedPlan, setSelectedPlan] = (0, import_react4.useState)("starter");
|
|
884
|
+
const isVisible = explicitIsOpen !== void 0 ? explicitIsOpen : Boolean(notice);
|
|
885
|
+
if (!isVisible) return null;
|
|
886
|
+
const handleSimulatePayment = async () => {
|
|
887
|
+
setLoading(true);
|
|
888
|
+
if (notice?.checkoutUrl) {
|
|
889
|
+
window.location.href = notice.checkoutUrl;
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
await new Promise((r) => setTimeout(r, 1200));
|
|
893
|
+
setLoading(false);
|
|
894
|
+
setSuccessState(true);
|
|
895
|
+
setTimeout(() => {
|
|
896
|
+
setSuccessState(false);
|
|
897
|
+
if (onSuccess) onSuccess();
|
|
898
|
+
if (onClose) onClose();
|
|
899
|
+
}, 1500);
|
|
900
|
+
};
|
|
901
|
+
const isLight = theme === "light";
|
|
902
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-900/60 backdrop-blur-sm animate-in fade-in duration-200", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
903
|
+
"div",
|
|
904
|
+
{
|
|
905
|
+
className: `relative w-full max-w-md rounded-2xl shadow-2xl border transition-all overflow-hidden ${isLight ? "bg-white border-slate-200 text-slate-900" : "bg-slate-900 border-slate-800 text-white"}`,
|
|
906
|
+
children: [
|
|
907
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "h-1.5 w-full bg-gradient-to-r from-indigo-500 via-purple-500 to-emerald-500" }),
|
|
908
|
+
onClose && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
909
|
+
"button",
|
|
910
|
+
{
|
|
911
|
+
onClick: onClose,
|
|
912
|
+
className: "absolute top-3.5 right-3.5 p-1 rounded-lg text-slate-400 hover:text-slate-700 hover:bg-slate-100 transition",
|
|
913
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseIcon, {})
|
|
914
|
+
}
|
|
915
|
+
),
|
|
916
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "p-6 space-y-5", children: [
|
|
917
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
918
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "h-10 w-10 rounded-xl bg-indigo-600 flex items-center justify-center text-white shadow-md shadow-indigo-500/20 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CreditCardIcon, {}) }),
|
|
919
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
|
|
920
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
921
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "font-bold text-base tracking-tight", children: notice?.status === "limit_reached" ? "Token Limit Reached" : "Add Billing Credits" }),
|
|
922
|
+
testMode && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-[10px] uppercase font-bold px-2 py-0.5 rounded-full bg-amber-50 text-amber-700 border border-amber-200", children: "Stripe Sandbox" })
|
|
923
|
+
] }),
|
|
924
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "text-xs text-slate-500 mt-0.5", children: notice?.message || "Top up your account to continue streaming AI tokens." })
|
|
925
|
+
] })
|
|
926
|
+
] }),
|
|
927
|
+
(notice?.tokensUsed || notice?.costUSD) && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
928
|
+
"div",
|
|
929
|
+
{
|
|
930
|
+
className: `p-3 rounded-xl border flex items-center justify-between text-xs ${isLight ? "bg-slate-50 border-slate-200" : "bg-slate-800 border-slate-700"}`,
|
|
931
|
+
children: [
|
|
932
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
|
|
933
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-slate-400", children: "Tokens Metered:" }),
|
|
934
|
+
" ",
|
|
935
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { className: "text-slate-800 font-semibold", children: notice.tokensUsed?.toLocaleString() || 0 })
|
|
936
|
+
] }),
|
|
937
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
|
|
938
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-slate-400", children: "Cost:" }),
|
|
939
|
+
" ",
|
|
940
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("strong", { className: "text-indigo-600 font-semibold", children: [
|
|
941
|
+
"$",
|
|
942
|
+
notice.costUSD?.toFixed(4) || "0.0000",
|
|
943
|
+
" USD"
|
|
944
|
+
] })
|
|
945
|
+
] })
|
|
946
|
+
]
|
|
947
|
+
}
|
|
948
|
+
),
|
|
949
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "space-y-2", children: [
|
|
950
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { className: "text-xs font-semibold text-slate-500 uppercase tracking-wider", children: "Select Top-Up Option" }),
|
|
951
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "grid grid-cols-2 gap-2.5", children: [
|
|
952
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
953
|
+
"button",
|
|
954
|
+
{
|
|
955
|
+
type: "button",
|
|
956
|
+
onClick: () => setSelectedPlan("starter"),
|
|
957
|
+
className: `p-3 rounded-xl border text-left transition relative ${selectedPlan === "starter" ? "border-indigo-600 bg-indigo-50/60 ring-2 ring-indigo-500/20" : isLight ? "border-slate-200 bg-white hover:border-slate-300" : "border-slate-800 bg-slate-800/50"}`,
|
|
958
|
+
children: [
|
|
959
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "text-xs font-bold text-slate-900", children: "$5.00 Top-Up" }),
|
|
960
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "text-[11px] text-slate-500 mt-0.5", children: "500k AI Tokens" })
|
|
961
|
+
]
|
|
962
|
+
}
|
|
963
|
+
),
|
|
964
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
965
|
+
"button",
|
|
966
|
+
{
|
|
967
|
+
type: "button",
|
|
968
|
+
onClick: () => setSelectedPlan("pro"),
|
|
969
|
+
className: `p-3 rounded-xl border text-left transition relative ${selectedPlan === "pro" ? "border-indigo-600 bg-indigo-50/60 ring-2 ring-indigo-500/20" : isLight ? "border-slate-200 bg-white hover:border-slate-300" : "border-slate-800 bg-slate-800/50"}`,
|
|
970
|
+
children: [
|
|
971
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "text-xs font-bold text-slate-900", children: "$20.00 Pro" }),
|
|
972
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "text-[11px] text-slate-500 mt-0.5", children: "2.5M AI Tokens" })
|
|
973
|
+
]
|
|
974
|
+
}
|
|
975
|
+
)
|
|
976
|
+
] })
|
|
977
|
+
] }),
|
|
978
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
979
|
+
"button",
|
|
980
|
+
{
|
|
981
|
+
onClick: handleSimulatePayment,
|
|
982
|
+
disabled: loading || successState,
|
|
983
|
+
className: "w-full py-2.5 px-4 rounded-xl bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 text-white text-sm font-semibold flex items-center justify-center gap-2 shadow-md shadow-indigo-500/20 transition",
|
|
984
|
+
children: loading ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Processing Stripe Sandbox Checkout..." }) : successState ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "flex items-center gap-1.5 text-emerald-300 font-semibold", children: [
|
|
985
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CheckIcon, {}),
|
|
986
|
+
" Credits Added Successfully!"
|
|
987
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "flex items-center gap-1.5", children: [
|
|
988
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Checkout with Stripe" }),
|
|
989
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ArrowRightIcon, {})
|
|
990
|
+
] })
|
|
991
|
+
}
|
|
992
|
+
),
|
|
993
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center justify-center gap-4 text-[11px] text-slate-400 pt-1 border-t border-slate-100", children: [
|
|
994
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
995
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ShieldCheckIcon, {}),
|
|
996
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Stripe v2 Meter Events" })
|
|
997
|
+
] }),
|
|
998
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
999
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ZapIcon, {}),
|
|
1000
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Zero Latency Telemetry" })
|
|
1001
|
+
] })
|
|
1002
|
+
] })
|
|
1003
|
+
] })
|
|
1004
|
+
]
|
|
1005
|
+
}
|
|
1006
|
+
) });
|
|
1007
|
+
};
|
|
665
1008
|
// Annotate the CommonJS export names for ESM import in node:
|
|
666
1009
|
0 && (module.exports = {
|
|
1010
|
+
VibezBillingModal,
|
|
667
1011
|
VibezSessionBadge,
|
|
668
1012
|
VibezSessionContext,
|
|
669
1013
|
VibezSessionProvider,
|
|
670
1014
|
VibezSessionWidget,
|
|
671
1015
|
useVibez,
|
|
1016
|
+
useVibezChat,
|
|
672
1017
|
useVibezSession
|
|
673
1018
|
});
|
|
674
1019
|
//# sourceMappingURL=index.js.map
|