@doderasoftware/restify-ai 0.2.0-beta.1 → 0.2.0-beta.2
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 +192 -17
- package/dist/components/input/InputActions.vue.d.ts.map +1 -1
- package/dist/restify-ai.js +3 -3
- package/dist/restify-ai.umd.cjs +3 -3
- package/dist/types/api.d.ts.map +1 -1
- package/package.json +10 -8
- package/tailwind.config.cjs +1 -30
package/README.md
CHANGED
|
@@ -251,10 +251,13 @@ export function setupRestifyAi(app: App) {
|
|
|
251
251
|
},
|
|
252
252
|
|
|
253
253
|
// ═══════════════════════════════════════════════════════════════
|
|
254
|
-
// LIMITS
|
|
254
|
+
// LIMITS & AI MODEL
|
|
255
255
|
// ═══════════════════════════════════════════════════════════════
|
|
256
256
|
|
|
257
257
|
chatHistoryLimit: 20, // Maximum user messages per conversation
|
|
258
|
+
model: 'gpt-4', // AI model to use (passed to backend)
|
|
259
|
+
temperature: 0.7, // AI temperature (0-1)
|
|
260
|
+
maxTokens: 2048, // Maximum tokens per response
|
|
258
261
|
maxAttachments: 5,
|
|
259
262
|
maxFileSize: 10 * 1024 * 1024, // 10MB
|
|
260
263
|
acceptedFileTypes: 'image/*,.pdf,.txt,.doc,.docx,.xls,.xlsx,.csv',
|
|
@@ -272,6 +275,7 @@ export function setupRestifyAi(app: App) {
|
|
|
272
275
|
|
|
273
276
|
keyboardShortcut: 'mod+g', // 'mod' = Cmd on Mac, Ctrl on Windows
|
|
274
277
|
enableSupportMode: true,
|
|
278
|
+
useQuota: true, // Enable quota management
|
|
275
279
|
canToggle: () => true,
|
|
276
280
|
|
|
277
281
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -291,6 +295,7 @@ export function setupRestifyAi(app: App) {
|
|
|
291
295
|
onResponseReceived: (message) => console.log('Response:', message),
|
|
292
296
|
onDrawerToggle: (isOpen) => console.log('Drawer:', isOpen),
|
|
293
297
|
onNewChat: () => console.log('New chat started'),
|
|
298
|
+
onSetupComplete: () => console.log('Setup completed'),
|
|
294
299
|
|
|
295
300
|
// Stream lifecycle hooks
|
|
296
301
|
onStreamStart: () => console.log('Stream started'),
|
|
@@ -318,7 +323,7 @@ export function setupRestifyAi(app: App) {
|
|
|
318
323
|
| `topOffset` | `string` | `"0"` | Top offset for fixed headers |
|
|
319
324
|
| `position` | `"left" \| "right"` | `"right"` | Drawer position |
|
|
320
325
|
| `showBackdrop` | `boolean` | `false` | Show backdrop overlay |
|
|
321
|
-
| `closeOnBackdropClick` | `boolean` | `
|
|
326
|
+
| `closeOnBackdropClick` | `boolean` | `true` | Close when clicking backdrop |
|
|
322
327
|
| `closeOnEscape` | `boolean` | `true` | Close on Escape key |
|
|
323
328
|
| `showQuota` | `boolean` | `true` | Show quota display (API usage remaining) |
|
|
324
329
|
| `showMessageCount` | `boolean` | `true` | Show message count badge (X/20 format) |
|
|
@@ -385,7 +390,7 @@ function handleContactSupport() {
|
|
|
385
390
|
| `header` | `HeaderSlotProps` | Custom header content |
|
|
386
391
|
| `quota` | `{ quota: ChatQuota }` | Custom quota display |
|
|
387
392
|
| `setup` | - | Custom setup guide |
|
|
388
|
-
| `empty-state` | `
|
|
393
|
+
| `empty-state` | `EmptyStateSlotProps` | Custom empty state |
|
|
389
394
|
| `message` | `MessageSlotProps` | Custom message bubble |
|
|
390
395
|
| `input` | `InputSlotProps` | Custom input area |
|
|
391
396
|
| `context-link` | - | Custom context link below input |
|
|
@@ -403,6 +408,11 @@ interface HeaderSlotProps {
|
|
|
403
408
|
onToggleFullscreen: () => void
|
|
404
409
|
}
|
|
405
410
|
|
|
411
|
+
interface EmptyStateSlotProps {
|
|
412
|
+
suggestions: AISuggestion[]
|
|
413
|
+
onSuggestionClick: (suggestion: AISuggestion) => void
|
|
414
|
+
}
|
|
415
|
+
|
|
406
416
|
interface MessageSlotProps {
|
|
407
417
|
message: ChatMessage
|
|
408
418
|
isUser: boolean
|
|
@@ -430,15 +440,18 @@ const store = useRestifyAiStore()
|
|
|
430
440
|
// STATE
|
|
431
441
|
// ═══════════════════════════════════════════════════════════════
|
|
432
442
|
|
|
443
|
+
store.chatHistoryLimit // number - Maximum messages allowed
|
|
433
444
|
store.chatHistory // ChatMessage[] - All messages
|
|
445
|
+
store.uploadedFiles // Record<string, ChatAttachment> - Uploaded files by ID
|
|
434
446
|
store.showChat // boolean - Drawer visibility
|
|
435
447
|
store.sending // boolean - Message being sent
|
|
436
448
|
store.loading // boolean - Loading state
|
|
437
449
|
store.isFullscreen // boolean - Fullscreen mode
|
|
438
450
|
store.quota // { limit, used, remaining }
|
|
439
|
-
store.error // { message, failedQuestion, failedAttachments, timestamp }
|
|
451
|
+
store.error // { message, failedQuestion, failedAttachments, timestamp, quotaExceeded }
|
|
440
452
|
store.supportRequestMode // boolean - Support mode active
|
|
441
453
|
store.pageContext // PageContext | null - Current page context
|
|
454
|
+
store.setupState // SetupState - Setup wizard state
|
|
442
455
|
|
|
443
456
|
// ═══════════════════════════════════════════════════════════════
|
|
444
457
|
// GETTERS
|
|
@@ -464,7 +477,14 @@ store.toggleSupportMode() // Toggle support mode
|
|
|
464
477
|
store.fetchQuota() // Fetch quota from server
|
|
465
478
|
store.uploadFile(file) // Upload file
|
|
466
479
|
store.setPageContext(context) // Set page context
|
|
467
|
-
store.scrollToBottom()
|
|
480
|
+
store.scrollToBottom(delay?) // Scroll chat to bottom
|
|
481
|
+
|
|
482
|
+
// Setup Mode Actions
|
|
483
|
+
store.startSetupMode() // Start setup wizard
|
|
484
|
+
store.setSetupStep(step) // Set current setup step
|
|
485
|
+
store.testConnection() // Test backend connection
|
|
486
|
+
store.completeSetup() // Complete setup
|
|
487
|
+
store.skipSetup() // Skip setup wizard
|
|
468
488
|
```
|
|
469
489
|
|
|
470
490
|
## 🪝 Composables
|
|
@@ -521,7 +541,44 @@ Get suggestions for current context:
|
|
|
521
541
|
```typescript
|
|
522
542
|
import { useAiSuggestions } from '@doderasoftware/restify-ai'
|
|
523
543
|
|
|
524
|
-
const { suggestions, resolvePrompt } = useAiSuggestions()
|
|
544
|
+
const { suggestions, hasContextualSuggestions, resolvePrompt } = useAiSuggestions()
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
### useLoadingText
|
|
548
|
+
|
|
549
|
+
Manage dynamic loading text messages:
|
|
550
|
+
|
|
551
|
+
```typescript
|
|
552
|
+
import { useLoadingText } from '@doderasoftware/restify-ai'
|
|
553
|
+
|
|
554
|
+
const {
|
|
555
|
+
loadingMessage,
|
|
556
|
+
startLoadingText,
|
|
557
|
+
resetLoadingText
|
|
558
|
+
} = useLoadingText(
|
|
559
|
+
() => isSending.value,
|
|
560
|
+
() => ({
|
|
561
|
+
messages: ['Thinking...', 'Analyzing...', 'Crafting response...'],
|
|
562
|
+
intervals: [0, 2000, 5000]
|
|
563
|
+
})
|
|
564
|
+
)
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
### useHistoryLimit
|
|
568
|
+
|
|
569
|
+
Handle chat history limits with warnings:
|
|
570
|
+
|
|
571
|
+
```typescript
|
|
572
|
+
import { useHistoryLimit } from '@doderasoftware/restify-ai'
|
|
573
|
+
|
|
574
|
+
const historyLimit = useHistoryLimit({
|
|
575
|
+
getHistoryLength: () => chatHistory.length,
|
|
576
|
+
getStoreLimit: () => store.chatHistoryLimit,
|
|
577
|
+
getConfig: () => historyLimitConfig,
|
|
578
|
+
getTexts: () => texts,
|
|
579
|
+
onStartNewChat: () => store.clearChatHistory(),
|
|
580
|
+
onNewChatEmit: () => emit('new-chat'),
|
|
581
|
+
})
|
|
525
582
|
```
|
|
526
583
|
|
|
527
584
|
## 🏷️ Mention Providers
|
|
@@ -847,6 +904,66 @@ interface ChatMessageUI {
|
|
|
847
904
|
}
|
|
848
905
|
```
|
|
849
906
|
|
|
907
|
+
### AiEmptyStateUI
|
|
908
|
+
|
|
909
|
+
```typescript
|
|
910
|
+
interface AiEmptyStateUI {
|
|
911
|
+
root?: string // Root container
|
|
912
|
+
content?: string // Content container
|
|
913
|
+
header?: string // Header container
|
|
914
|
+
badge?: string // AI badge
|
|
915
|
+
title?: string // Title
|
|
916
|
+
description?: string // Description
|
|
917
|
+
grid?: string // Suggestions grid
|
|
918
|
+
suggestionCard?: string // Suggestion card
|
|
919
|
+
suggestionIconContainer?: string // Icon container
|
|
920
|
+
suggestionIcon?: string // Icon
|
|
921
|
+
suggestionTitle?: string // Suggestion title
|
|
922
|
+
suggestionDescription?: string // Suggestion description
|
|
923
|
+
}
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
### MentionListUI
|
|
927
|
+
|
|
928
|
+
```typescript
|
|
929
|
+
interface MentionListUI {
|
|
930
|
+
root?: string // Root container
|
|
931
|
+
container?: string // List container
|
|
932
|
+
groupHeader?: string // Group header
|
|
933
|
+
item?: string // Item
|
|
934
|
+
itemSelected?: string // Selected item
|
|
935
|
+
itemIcon?: string // Item icon
|
|
936
|
+
itemContent?: string // Item content
|
|
937
|
+
itemName?: string // Item name
|
|
938
|
+
itemSubtitle?: string // Item subtitle
|
|
939
|
+
}
|
|
940
|
+
```
|
|
941
|
+
|
|
942
|
+
### AiAvatarUI / UserAvatarUI
|
|
943
|
+
|
|
944
|
+
```typescript
|
|
945
|
+
interface AiAvatarUI {
|
|
946
|
+
container?: string // Container
|
|
947
|
+
icon?: string // Icon
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
interface UserAvatarUI {
|
|
951
|
+
container?: string // Container
|
|
952
|
+
icon?: string // Icon
|
|
953
|
+
}
|
|
954
|
+
```
|
|
955
|
+
|
|
956
|
+
### ChatMessageActionsUI
|
|
957
|
+
|
|
958
|
+
```typescript
|
|
959
|
+
interface ChatMessageActionsUI {
|
|
960
|
+
container?: string // Container
|
|
961
|
+
button?: string // Action button
|
|
962
|
+
copyButton?: string // Copy button
|
|
963
|
+
successState?: string // Success state
|
|
964
|
+
}
|
|
965
|
+
```
|
|
966
|
+
|
|
850
967
|
## 📝 TypeScript Types
|
|
851
968
|
|
|
852
969
|
All types are exported:
|
|
@@ -866,6 +983,7 @@ import type {
|
|
|
866
983
|
ChatAttachment,
|
|
867
984
|
ChatRole,
|
|
868
985
|
SubmitPayload,
|
|
986
|
+
Mention,
|
|
869
987
|
|
|
870
988
|
// Context
|
|
871
989
|
PageContext,
|
|
@@ -873,7 +991,8 @@ import type {
|
|
|
873
991
|
// Providers
|
|
874
992
|
MentionProvider,
|
|
875
993
|
MentionItem,
|
|
876
|
-
|
|
994
|
+
MentionContext,
|
|
995
|
+
MentionParseResult,
|
|
877
996
|
SuggestionProvider,
|
|
878
997
|
AISuggestion,
|
|
879
998
|
|
|
@@ -881,17 +1000,30 @@ import type {
|
|
|
881
1000
|
HistoryLimitConfig,
|
|
882
1001
|
LoadingTextConfig,
|
|
883
1002
|
|
|
1003
|
+
// Setup
|
|
1004
|
+
SetupStep,
|
|
1005
|
+
SetupState,
|
|
1006
|
+
|
|
1007
|
+
// Store
|
|
1008
|
+
AiStoreState,
|
|
1009
|
+
|
|
884
1010
|
// UI Customization
|
|
885
1011
|
AiChatDrawerUI,
|
|
886
1012
|
ChatInputUI,
|
|
887
1013
|
ChatMessageUI,
|
|
888
1014
|
AiEmptyStateUI,
|
|
889
1015
|
MentionListUI,
|
|
1016
|
+
AiAvatarUI,
|
|
1017
|
+
UserAvatarUI,
|
|
1018
|
+
ChatMessageActionsUI,
|
|
890
1019
|
|
|
891
1020
|
// Text Customization
|
|
892
1021
|
AiChatDrawerTexts,
|
|
893
1022
|
ChatInputTexts,
|
|
894
1023
|
ChatMessageTexts,
|
|
1024
|
+
AiEmptyStateTexts,
|
|
1025
|
+
MentionListTexts,
|
|
1026
|
+
ChatMessageActionsTexts,
|
|
895
1027
|
|
|
896
1028
|
// Slot Props
|
|
897
1029
|
HeaderSlotProps,
|
|
@@ -899,15 +1031,26 @@ import type {
|
|
|
899
1031
|
InputSlotProps,
|
|
900
1032
|
EmptyStateSlotProps,
|
|
901
1033
|
|
|
902
|
-
// Hooks
|
|
1034
|
+
// API Hooks
|
|
1035
|
+
AiRequestPayload,
|
|
1036
|
+
AiStreamChunk,
|
|
903
1037
|
BeforeSendHook,
|
|
904
1038
|
AfterResponseHook,
|
|
905
1039
|
OnStreamStartHook,
|
|
906
1040
|
OnStreamEndHook,
|
|
907
1041
|
OnStreamChunkHook,
|
|
908
1042
|
StreamParserFunction,
|
|
1043
|
+
RequestInterceptor,
|
|
1044
|
+
ResponseInterceptor,
|
|
909
1045
|
RetryConfig,
|
|
1046
|
+
|
|
1047
|
+
// Functions
|
|
1048
|
+
TranslateFunction,
|
|
1049
|
+
PermissionCheckFunction,
|
|
910
1050
|
} from '@doderasoftware/restify-ai'
|
|
1051
|
+
|
|
1052
|
+
// Constants
|
|
1053
|
+
import { ChatRoles } from '@doderasoftware/restify-ai'
|
|
911
1054
|
```
|
|
912
1055
|
|
|
913
1056
|
## 🔌 Backend Integration
|
|
@@ -1002,7 +1145,17 @@ Chat history persists in `sessionStorage` by default:
|
|
|
1002
1145
|
|
|
1003
1146
|
```typescript
|
|
1004
1147
|
// Components
|
|
1005
|
-
export {
|
|
1148
|
+
export {
|
|
1149
|
+
AiChatDrawer,
|
|
1150
|
+
AiEmptyState,
|
|
1151
|
+
ChatInput,
|
|
1152
|
+
ChatMessage,
|
|
1153
|
+
ChatMessageActions,
|
|
1154
|
+
MentionList,
|
|
1155
|
+
AiAvatar,
|
|
1156
|
+
UserAvatar,
|
|
1157
|
+
ErrorBoundary,
|
|
1158
|
+
} from './components'
|
|
1006
1159
|
|
|
1007
1160
|
// Store
|
|
1008
1161
|
export { useRestifyAiStore } from './store'
|
|
@@ -1010,20 +1163,42 @@ export { useRestifyAiStore } from './store'
|
|
|
1010
1163
|
// Composables
|
|
1011
1164
|
export {
|
|
1012
1165
|
useAiDrawerShortcut,
|
|
1166
|
+
useKeyboardShortcut,
|
|
1013
1167
|
usePageAiContext,
|
|
1014
1168
|
useAiContext,
|
|
1015
|
-
useAiSuggestions
|
|
1169
|
+
useAiSuggestions,
|
|
1170
|
+
useMentionParsing,
|
|
1171
|
+
useChatMarkdown,
|
|
1172
|
+
useChatScroll,
|
|
1173
|
+
useChatErrorHandling,
|
|
1174
|
+
useLoadingText,
|
|
1175
|
+
useHistoryLimit,
|
|
1176
|
+
useSuggestionFilter,
|
|
1177
|
+
useAutoScroll,
|
|
1178
|
+
formatMentionsForApi,
|
|
1179
|
+
groupMentionsByType,
|
|
1016
1180
|
} from './composables'
|
|
1017
1181
|
|
|
1018
1182
|
// Config
|
|
1019
1183
|
export {
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1184
|
+
RestifyAiPlugin,
|
|
1185
|
+
getRestifyAiConfig,
|
|
1186
|
+
setRestifyAiConfig,
|
|
1187
|
+
getLabel,
|
|
1188
|
+
getConfigValue,
|
|
1189
|
+
isConfigured,
|
|
1190
|
+
defaultLabels,
|
|
1025
1191
|
} from './config'
|
|
1026
1192
|
|
|
1193
|
+
// Suggestions
|
|
1194
|
+
export {
|
|
1195
|
+
registerSuggestionProvider,
|
|
1196
|
+
getSuggestionsForPath,
|
|
1197
|
+
} from './suggestions'
|
|
1198
|
+
|
|
1199
|
+
// Utilities
|
|
1200
|
+
export { isImageFile, formatFileSize } from './utils'
|
|
1201
|
+
|
|
1027
1202
|
// Types
|
|
1028
1203
|
export * from './types'
|
|
1029
1204
|
```
|
|
@@ -1039,7 +1214,7 @@ export * from './types'
|
|
|
1039
1214
|
- [📖 Laravel Restify Documentation](https://laravel-restify.com)
|
|
1040
1215
|
- [📦 npm Package](https://www.npmjs.com/package/@doderasoftware/restify-ai)
|
|
1041
1216
|
- [🏢 BinarCode](https://binarcode.com)
|
|
1042
|
-
- [💻 GitHub](https://github.com/BinarCode/
|
|
1217
|
+
- [💻 GitHub](https://github.com/BinarCode/restify-chatbot)
|
|
1043
1218
|
|
|
1044
1219
|
## 📄 License
|
|
1045
1220
|
|
|
@@ -1047,4 +1222,4 @@ MIT © [BinarCode](https://binarcode.com)
|
|
|
1047
1222
|
|
|
1048
1223
|
---
|
|
1049
1224
|
|
|
1050
|
-
Built with ❤️ by the [BinarCode](https://binarcode.com) team
|
|
1225
|
+
Built with ❤️ by the [BinarCode](https://binarcode.com) team.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputActions.vue.d.ts","sourceRoot":"","sources":["../../../src/components/input/InputActions.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"InputActions.vue.d.ts","sourceRoot":"","sources":["../../../src/components/input/InputActions.vue"],"names":[],"mappings":"AAqDA;AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAI9D,UAAU,KAAK;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,kBAAkB,EAAE,OAAO,CAAA;IAC3B,qBAAqB,EAAE,OAAO,CAAA;IAC9B,EAAE,EAAE,WAAW,CAAA;IACf,KAAK,CAAC,EAAE,cAAc,CAAA;CACvB;;;;;;;;AA4MD,wBAOG;AACH,KAAK,sBAAsB,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;AACjE,KAAK,6BAA6B,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE;CAAE,CAAC"}
|
package/dist/restify-ai.js
CHANGED
|
@@ -68,7 +68,7 @@ function re() {
|
|
|
68
68
|
function fl() {
|
|
69
69
|
if (!Ge)
|
|
70
70
|
throw new Error(
|
|
71
|
-
"[
|
|
71
|
+
"[restify-ai] Plugin not initialized. Make sure to call app.use(RestifyAiPlugin, config) before using the components."
|
|
72
72
|
);
|
|
73
73
|
return Ge;
|
|
74
74
|
}
|
|
@@ -5127,7 +5127,7 @@ app.<span class="text-yellow-300">use</span>(RestifyAiPlugin, {
|
|
|
5127
5127
|
n[3] || (n[3] = p("p", { class: "text-xs text-gray-400 dark:text-gray-500 mt-4 text-center" }, [
|
|
5128
5128
|
Ft(" Need help? Check the "),
|
|
5129
5129
|
p("a", {
|
|
5130
|
-
href: "https://github.com/
|
|
5130
|
+
href: "https://github.com/BinarCode/restify-chatbot",
|
|
5131
5131
|
target: "_blank",
|
|
5132
5132
|
class: "text-primary hover:underline"
|
|
5133
5133
|
}, "documentation")
|
|
@@ -5602,7 +5602,7 @@ app.use(RestifyAiPlugin, {
|
|
|
5602
5602
|
}), Tl = {
|
|
5603
5603
|
install(t, e) {
|
|
5604
5604
|
if (!e.endpoints || !e.getAuthToken) {
|
|
5605
|
-
console.warn("[
|
|
5605
|
+
console.warn("[restify-ai] Plugin requires endpoints and getAuthToken options.");
|
|
5606
5606
|
return;
|
|
5607
5607
|
}
|
|
5608
5608
|
const n = {
|
package/dist/restify-ai.umd.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(R,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("pinia")):typeof define=="function"&&define.amd?define(["exports","vue","pinia"],e):(R=typeof globalThis<"u"?globalThis:R||self,e(R.RestifyAi={},R.Vue,R.Pinia))})(this,function(R,e,De){"use strict";var Oi=Object.defineProperty;var Pi=(R,e,De)=>e in R?Oi(R,e,{enumerable:!0,configurable:!0,writable:!0,value:De}):R[e]=De;var q=(R,e,De)=>Pi(R,typeof e!="symbol"?e+"":e,De);let Ne=null;const Mr=e.ref(null),Bt={title:"AI Assistant",aiName:"AI Assistant",you:"You",newChat:"New chat",placeholder:"Ask me anything...",inputPlaceholder:"Ask me anything...",supportPlaceholder:"Describe your support request...",loadingText:"Thinking...",analyzingText:"Analyzing...",craftingText:"Crafting response...",quotaRemaining:"{count} questions remaining",noQuota:"No AI credit available",rateLimitExceeded:"Rate limit exceeded. Please try again in a moment.",contactSupport:"Contact Support",close:"Close",minimize:"Minimize",fullscreen:"Fullscreen",exitFullscreen:"Exit fullscreen",copyToClipboard:"Copy to clipboard",copied:"Copied!",showMore:"Show more",showLess:"Show less",retry:"Retry",attachFiles:"Attach files",emptyStateTitle:"How can I help you today?",emptyStateDescription:"Ask me anything or choose a suggestion below",keyboardShortcutHint:"Press ⌘G to toggle",sendMessage:"Send message",attachFile:"Attach file",closeConfirmTitle:"Close conversation?",closeConfirmMessage:"This will clear your chat history. Are you sure you want to close?",confirmClose:"Close & Clear",cancel:"Cancel",toggleSupportMode:"Toggle support mode",exitSupportMode:"Exit support mode",historyLimitWarningTitle:"Approaching Chat Limit",historyLimitWarningMessage:"You are approaching the maximum number of messages in this conversation.",historyLimitReachedTitle:"Chat Limit Reached",historyLimitReachedMessage:"You have reached the maximum number of messages. Start a new chat to continue.",startNewChat:"Start New Chat",continueChat:"Continue",setupWelcomeTitle:"Welcome to AI Assistant",setupWelcomeDescription:"Let's get you set up to start using AI features.",setupApiKeyTitle:"API Key Configuration",setupApiKeyDescription:"Enter your API key to test the connection",setupTestingTitle:"Testing Connection...",setupBackendTitle:"Backend Configuration",setupBackendDescription:"Configure your backend endpoint",setupCompleteTitle:"Setup Complete!"};function ln(r){Ne=r,Mr.value=r}function K(){return Ne}function Br(){if(!Ne)throw new Error("[
|
|
1
|
+
(function(R,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("pinia")):typeof define=="function"&&define.amd?define(["exports","vue","pinia"],e):(R=typeof globalThis<"u"?globalThis:R||self,e(R.RestifyAi={},R.Vue,R.Pinia))})(this,function(R,e,De){"use strict";var Oi=Object.defineProperty;var Pi=(R,e,De)=>e in R?Oi(R,e,{enumerable:!0,configurable:!0,writable:!0,value:De}):R[e]=De;var q=(R,e,De)=>Pi(R,typeof e!="symbol"?e+"":e,De);let Ne=null;const Mr=e.ref(null),Bt={title:"AI Assistant",aiName:"AI Assistant",you:"You",newChat:"New chat",placeholder:"Ask me anything...",inputPlaceholder:"Ask me anything...",supportPlaceholder:"Describe your support request...",loadingText:"Thinking...",analyzingText:"Analyzing...",craftingText:"Crafting response...",quotaRemaining:"{count} questions remaining",noQuota:"No AI credit available",rateLimitExceeded:"Rate limit exceeded. Please try again in a moment.",contactSupport:"Contact Support",close:"Close",minimize:"Minimize",fullscreen:"Fullscreen",exitFullscreen:"Exit fullscreen",copyToClipboard:"Copy to clipboard",copied:"Copied!",showMore:"Show more",showLess:"Show less",retry:"Retry",attachFiles:"Attach files",emptyStateTitle:"How can I help you today?",emptyStateDescription:"Ask me anything or choose a suggestion below",keyboardShortcutHint:"Press ⌘G to toggle",sendMessage:"Send message",attachFile:"Attach file",closeConfirmTitle:"Close conversation?",closeConfirmMessage:"This will clear your chat history. Are you sure you want to close?",confirmClose:"Close & Clear",cancel:"Cancel",toggleSupportMode:"Toggle support mode",exitSupportMode:"Exit support mode",historyLimitWarningTitle:"Approaching Chat Limit",historyLimitWarningMessage:"You are approaching the maximum number of messages in this conversation.",historyLimitReachedTitle:"Chat Limit Reached",historyLimitReachedMessage:"You have reached the maximum number of messages. Start a new chat to continue.",startNewChat:"Start New Chat",continueChat:"Continue",setupWelcomeTitle:"Welcome to AI Assistant",setupWelcomeDescription:"Let's get you set up to start using AI features.",setupApiKeyTitle:"API Key Configuration",setupApiKeyDescription:"Enter your API key to test the connection",setupTestingTitle:"Testing Connection...",setupBackendTitle:"Backend Configuration",setupBackendDescription:"Configure your backend endpoint",setupCompleteTitle:"Setup Complete!"};function ln(r){Ne=r,Mr.value=r}function K(){return Ne}function Br(){if(!Ne)throw new Error("[restify-ai] Plugin not initialized. Make sure to call app.use(RestifyAiPlugin, config) before using the components.");return Ne}function Nt(){return Ne!==null}function te(r,t){const n=Ne,o=(n==null?void 0:n.labels)||{},s=n==null?void 0:n.translate;if(s){const i=s(r,t);if(i!==r)return i}let a=o[r]||Bt[r];return t&&Object.entries(t).forEach(([i,l])=>{a=a.replace(`{${i}}`,String(l))}),a}function cn(r){return{chatHistoryLimit:15,maxAttachments:5,maxFileSize:10485760,acceptedFileTypes:"image/*,.pdf,.txt,.doc,.docx,.xls,.xlsx,.csv",chatHistoryKey:"restify_ai_chat_history",drawerStateKey:"restify_ai_drawer_open",keyboardShortcut:"cmd+g",enableSupportMode:!1}[r]}function ke(r){const t=Ne;return t?t[r]??cn(r):cn(r)}function it(r){return(r.type||"").startsWith("image/")?!0:/(png|jpe?g|gif|webp)$/i.test(r.name||"")}function lt(r){if(r==null)return"";const t=typeof r=="string"?parseInt(r,10):r;return Number.isNaN(t)?"":t>=1024*1024?`${(t/(1024*1024)).toFixed(1)} MB`:t>=1024?`${Math.round(t/1024)} KB`:`${t} B`}const Re={Assistant:"assistant",User:"user",System:"system"};async function Nr(r,t){const n=r.getReader();let o;for(;!(o=await n.read()).done;)t(o.value)}function Rr(r){let t,n,o,s=!1;return function(i){t===void 0?(t=i,n=0,o=-1):t=Lr(t,i);const l=t.length;let u=0;for(;n<l;){s&&(t[n]===10&&(u=++n),s=!1);let d=-1;for(;n<l&&d===-1;++n)switch(t[n]){case 58:o===-1&&(o=n-u);break;case 13:s=!0;case 10:d=n;break}if(d===-1)break;r(t.subarray(u,d),o),u=n,o=-1}u===l?t=void 0:u!==0&&(t=t.subarray(u),n-=u)}}function _r(r,t,n){let o=un();const s=new TextDecoder;return function(i,l){if(i.length===0)n==null||n(o),o=un();else if(l>0){const u=s.decode(i.subarray(0,l)),d=l+(i[l+1]===32?2:1),m=s.decode(i.subarray(d));switch(u){case"data":o.data=o.data?o.data+`
|
|
2
2
|
`+m:m;break;case"event":o.event=m;break;case"id":r(o.id=m);break;case"retry":const h=parseInt(m,10);isNaN(h)||t(o.retry=h);break}}}}function Lr(r,t){const n=new Uint8Array(r.length+t.length);return n.set(r),n.set(t,r.length),n}function un(){return{data:"",event:"",id:"",retry:void 0}}var Ir=function(r,t){var n={};for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&t.indexOf(o)<0&&(n[o]=r[o]);if(r!=null&&typeof Object.getOwnPropertySymbols=="function")for(var s=0,o=Object.getOwnPropertySymbols(r);s<o.length;s++)t.indexOf(o[s])<0&&Object.prototype.propertyIsEnumerable.call(r,o[s])&&(n[o[s]]=r[o[s]]);return n};const Rt="text/event-stream",$r=1e3,dn="last-event-id";function Dr(r,t){var{signal:n,headers:o,onopen:s,onmessage:a,onclose:i,onerror:l,openWhenHidden:u,fetch:d}=t,m=Ir(t,["signal","headers","onopen","onmessage","onclose","onerror","openWhenHidden","fetch"]);return new Promise((h,g)=>{const y=Object.assign({},o);y.accept||(y.accept=Rt);let f;function S(){f.abort(),document.hidden||I()}u||document.addEventListener("visibilitychange",S);let p=$r,w=0;function M(){document.removeEventListener("visibilitychange",S),window.clearTimeout(w),f.abort()}n==null||n.addEventListener("abort",()=>{M(),h()});const x=d??window.fetch,C=s??zr;async function I(){var b;f=new AbortController;try{const N=await x(r,Object.assign(Object.assign({},m),{headers:y,signal:f.signal}));await C(N),await Nr(N.body,Rr(_r(L=>{L?y[dn]=L:delete y[dn]},L=>{p=L},a))),i==null||i(),M(),h()}catch(N){if(!f.signal.aborted)try{const L=(b=l==null?void 0:l(N))!==null&&b!==void 0?b:p;window.clearTimeout(w),w=window.setTimeout(I,L)}catch(L){M(),g(L)}}}I()})}function zr(r){const t=r.headers.get("content-type");if(!(t!=null&&t.startsWith(Rt)))throw new Error(`Expected content-type to be ${Rt}, Actual: ${t}`)}function ct(r){if(!r)throw console.error("[RestifyAi] Endpoint is undefined. Check your endpoints configuration."),new Error("AI service endpoint is not configured. Please contact support.");const t=K(),n=(t==null?void 0:t.baseUrl)||"";if(!n||r.startsWith("http://")||r.startsWith("https://"))return r;const o=n.endsWith("/")?n.slice(0,-1):n,s=r.startsWith("/")?r:`/${r}`;return`${o}${s}`}function Or(r){const n=(r instanceof Error?r.message:String(r)).toLowerCase();return n.includes("failed to fetch")||n.includes("network")||n.includes("fetch")?"Unable to connect to the AI service. Please check your internet connection and try again.":n.includes("500")||n.includes("internal server error")?"The AI service is temporarily unavailable. Please try again in a few moments.":n.includes("timeout")||n.includes("timed out")?"The request took too long. Please try again.":n.includes("401")||n.includes("unauthorized")||n.includes("authentication")?"Your session has expired. Please refresh the page and try again.":n.includes("429")||n.includes("rate limit")||n.includes("too many requests")?"Too many requests. Please wait a moment before trying again.":n.includes("cors")||n.includes("cross-origin")?"Unable to connect to the AI service. Please contact support.":n.includes("endpoint is not configured")?"AI service endpoint is not configured. Please contact support.":"Something went wrong. Please try again later."}function Pr(r,t){var n,o,s;try{if(t==="done"||r==="[DONE]")return"[DONE]";const a=JSON.parse(r);return(a==null?void 0:a.content)!==void 0?a.content:((s=(o=(n=a==null?void 0:a.choices)==null?void 0:n[0])==null?void 0:o.delta)==null?void 0:s.content)||null}catch{return null}}function Vr(r){return new Promise(t=>setTimeout(t,r))}function Fr(r){const t={};return r.forEach(n=>{var o;(o=n.attachments)==null||o.forEach(s=>{s!=null&&s.id&&(t[s.id]=s)})}),t}function Te(r){const t=K();return r==="chatHistory"?(t==null?void 0:t.chatHistoryKey)||"restify_ai_chat_history":r==="setupComplete"?"restify_ai_setup_complete":(t==null?void 0:t.drawerStateKey)||"restify_ai_drawer_open"}function qe(r){try{sessionStorage.setItem(Te("chatHistory"),JSON.stringify(r))}catch(t){console.warn("[RestifyAi] Failed to save chat history:",t)}}function Hr(){try{const r=sessionStorage.getItem(Te("chatHistory"));if(r){const t=JSON.parse(r),n=t.filter(a=>{var i;return!(a.role===Re.Assistant&&a.loading||a.role===Re.Assistant&&!((i=a.message)!=null&&i.trim()))}).map(a=>({...a,streaming:!1,loading:!1}));n.length!==t.length&&sessionStorage.setItem(Te("chatHistory"),JSON.stringify(n));const o=n[n.length-1],s=(o==null?void 0:o.role)===Re.User;return{history:n,hasOrphanedUserMessage:s,orphanedMessage:s?{question:o.message,attachments:o.attachments||[]}:void 0}}}catch(r){console.warn("[RestifyAi] Failed to load chat history:",r)}return{history:[],hasOrphanedUserMessage:!1}}function Ur(){try{sessionStorage.removeItem(Te("chatHistory"))}catch(r){console.warn("[RestifyAi] Failed to clear chat history:",r)}}function qr(r){try{r.message||r.failedQuestion?sessionStorage.setItem("restify_ai_error_state",JSON.stringify(r)):sessionStorage.removeItem("restify_ai_error_state")}catch(t){console.warn("[RestifyAi] Failed to save error state:",t)}}function jr(){try{const r=sessionStorage.getItem("restify_ai_error_state");if(r)return JSON.parse(r)}catch(r){console.warn("[RestifyAi] Failed to load error state:",r)}return null}function Wr(){try{sessionStorage.removeItem("restify_ai_error_state")}catch(r){console.warn("[RestifyAi] Failed to clear error state:",r)}}function _t(r){try{localStorage.setItem(Te("drawerState"),JSON.stringify(r))}catch(t){console.warn("[RestifyAi] Failed to save drawer state:",t)}}function Kr(){try{const r=localStorage.getItem(Te("drawerState"));if(r!==null)return JSON.parse(r)}catch(r){console.warn("[RestifyAi] Failed to load drawer state:",r)}return!1}function Gr(){try{return localStorage.getItem(Te("setupComplete"))==="true"}catch{return!1}}function mn(){try{localStorage.setItem(Te("setupComplete"),"true")}catch(r){console.warn("[RestifyAi] Failed to mark setup complete:",r)}}function fn(){return{isActive:!1,currentStep:"welcome",testApiKey:null,connectionStatus:"idle",backendConfigured:!1,lastError:null}}let je=new AbortController;function Qr(r,t){return r!=null&&r.message?{message:r.message,failedQuestion:r.failedQuestion,failedAttachments:r.failedAttachments,timestamp:Date.now(),quotaExceeded:!1}:t.hasOrphanedUserMessage&&t.orphanedMessage?{message:"Previous request failed. Click retry to try again.",failedQuestion:t.orphanedMessage.question,failedAttachments:t.orphanedMessage.attachments,timestamp:Date.now(),quotaExceeded:!1}:{message:null,failedQuestion:null,failedAttachments:null,timestamp:null,quotaExceeded:!1}}function Zr(r){const t=ke("chatHistoryLimit")||10;return{limit:t,used:r,remaining:Math.max(0,t-r)}}function Yr(){return!Nt()&&!Gr()?{...fn(),isActive:!0}:fn()}const Ae=De.defineStore("restifyAiStore",{state:()=>{const r=Hr(),t=jr(),n=r.history.filter(o=>o.role==="user").length;return{chatHistoryLimit:ke("chatHistoryLimit")||20,chatHistory:r.history,uploadedFiles:Fr(r.history),loading:!1,showChat:Kr(),isFullscreen:!1,sending:!1,pageContext:null,quota:Zr(n),error:Qr(t,r),supportRequestMode:!1,setupState:Yr()}},getters:{hasMessages:r=>r.chatHistory.length>0,isInSetupMode:r=>r.setupState.isActive,canChat:r=>!r.setupState.isActive||r.setupState.connectionStatus==="connected"},actions:{async scrollToBottom(r=0){await e.nextTick(),r>0&&await new Promise(n=>setTimeout(n,r));const t=document.getElementById("rai-chat-bottom");t&&t.scrollIntoView({behavior:"smooth"})},parseStreamContent(r,t){const n=K(),o=n==null?void 0:n.parseStreamContent;return o?o(t,r):Pr(t,r)},async askQuestion(r,t=[],n=[],o=!1){var y;const s=K();if(!s)return console.warn("[RestifyAi] Cannot ask question - plugin not configured"),!1;let a="",i=!1;const l=s.retry||{},u=l.maxRetries??0,d=l.retryDelay??1e3;let m=0;const h=t.map(f=>({id:f.id,name:f.name,url:f.url,type:f.type,size:f.size,extractedText:f.extractedText}));this.chatHistory.push({id:crypto.randomUUID(),role:Re.User,message:r,loading:!1,attachments:h,mentions:n,timestamp:Date.now()}),h.forEach(f=>this.registerUploadedFile(f)),qe(this.chatHistory),this.sending=!0,this.quota.remaining>0&&!o&&(this.quota.remaining--,this.quota.used++),this.scrollToBottom(),this.chatHistory.length>=this.chatHistoryLimit&&((y=s.onError)==null||y.call(s,new Error("Chat history limit reached")));const g=async()=>{var f,S,p;try{const w=this.chatHistory.map(_=>({role:_.role,content:_.message})),M={},x=_=>{_!=null&&_.id&&(M[_.id]={extracted_text:_.extractedText||"",file_name:_.name,mime_type:_.type||"",..._.size?{file_size:_.size}:{},..._.url?{file_url:_.url}:{}})};Object.values(this.uploadedFiles).forEach(x),this.chatHistory.forEach(_=>{var O;return(O=_.attachments)==null?void 0:O.forEach(x)}),h.forEach(x);const C=Object.values(M),I=this.chatHistory.length;this.chatHistory.push({id:crypto.randomUUID(),role:Re.Assistant,message:"",loading:!0,timestamp:Date.now()}),qe(this.chatHistory),je=new AbortController,this.scrollToBottom();const b=await s.getAuthToken(),L={"Content-Type":"application/json",Accept:"application/vnd.api+json",...s.getCustomHeaders?await s.getCustomHeaders():{}};this.setupState.isActive&&this.setupState.testApiKey?L["X-Test-Api-Key"]=this.setupState.testApiKey:b&&(L.Authorization=`Bearer ${b}`);const A={};if(typeof window<"u"){A.route=window.location.pathname;const _=new URLSearchParams(window.location.search),O={};_.forEach((z,ne)=>{O[ne]=z}),Object.keys(O).length>0&&(A.query=O),document.title&&(A.pageTitle=document.title)}n.length>0&&(A.mentionedEntities=n.map(_=>({type:_.type,id:_.id,displayName:_.name,metadata:_.metadata})));let B={message:r,history:w,stream:!0,...C.length>0&&{files:C},...Object.keys(A).length>0&&{context:A},...this.supportRequestMode&&{contact_support:!0},...s.model&&{model:s.model},...s.temperature&&{temperature:s.temperature},...s.maxTokens&&{max_tokens:s.maxTokens}};s.beforeSend&&(B=await s.beforeSend(B)),s.buildRequest&&(B=await s.buildRequest(B)),(f=s.onMessageSent)==null||f.call(s,this.chatHistory[I-1]);const V=ct(s.endpoints.ask);let G={method:"POST",body:JSON.stringify(B),headers:L};return s.requestInterceptor&&(G=await s.requestInterceptor(V,G)),(S=s.onStreamStart)==null||S.call(s),await Dr(V,{method:"POST",body:JSON.stringify(B),signal:je.signal,headers:G.headers,openWhenHidden:!0,async onopen(_){if(!_.ok){if(_.status===429){const O=Ae();throw O.error={message:te("rateLimitExceeded"),failedQuestion:r,failedAttachments:h,timestamp:Date.now(),quotaExceeded:!0,rateLimited:!0},s.useQuota!==!1&&await O.fetchQuota(),new Error("Rate limit exceeded")}throw new Error(`Failed to connect: ${_.status}`)}},onmessage:async _=>{var ne,be,U;const O=this.parseStreamContent(_.event,_.data);if(!O)return;this.chatHistory[I].loading=!1;const z={content:O,done:O==="[DONE]",raw:_.data};(ne=s.onStreamChunk)==null||ne.call(s,z),a?O==="[DONE]"?(this.chatHistory[I].streaming=!1,qe(this.chatHistory),(be=s.onStreamEnd)==null||be.call(s,a),this.quota.remaining===0&&s.enableSupportMode!==!1&&(this.supportRequestMode=!0),this.supportRequestMode&&this.quota.remaining>0&&(this.supportRequestMode=!1),s.afterResponse&&await s.afterResponse(this.chatHistory[I]),(U=s.onResponseReceived)==null||U.call(s,this.chatHistory[I])):(a+=O,this.chatHistory[I].message=a):(a=O,this.chatHistory[I].message=a,this.chatHistory[I].streaming=!0),await this.scrollToBottom()},onclose:()=>{var _,O;a&&!i&&(this.chatHistory[I].streaming=!1,this.chatHistory[I].loading=!1,qe(this.chatHistory),(_=s.onStreamEnd)==null||_.call(s,a),s.afterResponse&&s.afterResponse(this.chatHistory[I]),(O=s.onResponseReceived)==null||O.call(s,this.chatHistory[I]))},onerror:_=>{if(!a)throw i=!0,_}}),!0}catch(w){i=!0;const M=this.chatHistory.length-1;return this.chatHistory.splice(M,1),w.name==="AbortError"?!0:m<u&&(l.shouldRetry?l.shouldRetry(w,m):!0)?(m++,await Vr(d*m),g()):(this.error={message:Or(w),failedQuestion:r,failedAttachments:h,timestamp:Date.now()},qr({message:this.error.message,failedQuestion:this.error.failedQuestion,failedAttachments:this.error.failedAttachments||null}),(p=s.onError)==null||p.call(s,w),!1)}finally{this.sending=!1}};return g()},cancelRequest(){je==null||je.abort(),this.chatHistory=this.chatHistory.map(r=>({...r,streaming:!1,loading:!1})),this.sending=!1},clearChatHistory(){var n;const r=K();this.chatHistory=[],this.sending=!1,this.uploadedFiles={},this.clearError(),this.quota.remaining>0&&(this.supportRequestMode=!1);const t=ke("chatHistoryLimit")||10;this.quota={limit:t,used:0,remaining:t},Ur(),(n=r==null?void 0:r.onNewChat)==null||n.call(r)},async retry(){if(!this.error.failedQuestion)return!1;const r=this.error.failedQuestion,t=this.error.failedAttachments||[],n=this.chatHistory[this.chatHistory.length-1];return(n==null?void 0:n.role)===Re.User&&n.message===r&&(this.chatHistory.pop(),qe(this.chatHistory)),this.clearError(),await this.askQuestion(r,t)},clearError(){this.error={message:null,failedQuestion:null,failedAttachments:null,timestamp:null,quotaExceeded:!1},Wr()},toggleSupportMode(){this.supportRequestMode=!this.supportRequestMode},async fetchQuota(){var t,n;const r=K();if((r==null?void 0:r.useQuota)!==!1&&(t=r==null?void 0:r.endpoints)!=null&&t.quota)try{const o=await r.getAuthToken(),s=r.getCustomHeaders?await r.getCustomHeaders():{},a=ct(r.endpoints.quota),i=await fetch(a,{headers:{Accept:"application/json",...o?{Authorization:`Bearer ${o}`}:{},...s}});if(i.ok){const l=await i.json(),u=l.data??l;this.quota={limit:u.limit??this.quota.limit,used:u.used??this.quota.used,remaining:u.remaining??this.quota.remaining},this.quota.remaining===0&&r.enableSupportMode!==!1&&(this.supportRequestMode=!0),(n=r.onQuotaFetched)==null||n.call(r,this.quota)}}catch(o){console.error("[RestifyAi] Failed to fetch quota:",o)}},async uploadFile(r){var s,a,i,l,u;const t=K();if(!((s=t==null?void 0:t.endpoints)!=null&&s.uploadFile))return console.warn("[RestifyAi] No uploadFile endpoint configured"),null;const o={id:crypto.randomUUID(),name:r.name,type:r.type,size:r.size,uploading:!0,progress:0};(a=t.onFileUploadStart)==null||a.call(t,o);try{const d=await t.getAuthToken(),m=t.getCustomHeaders?await t.getCustomHeaders():{},h=ct(t.endpoints.uploadFile),g=new FormData;g.append("file",r);const y=await new Promise((f,S)=>{const p=new XMLHttpRequest;p.upload.addEventListener("progress",w=>{var M;if(w.lengthComputable){const x=Math.round(w.loaded/w.total*100);o.progress=x,(M=t.onFileUploadProgress)==null||M.call(t,o,x)}}),p.addEventListener("load",()=>{var w,M;if(p.status>=200&&p.status<300)try{const x=JSON.parse(p.responseText),C={...o,url:x.url||((w=x.data)==null?void 0:w.url),extractedText:x.extracted_text||((M=x.data)==null?void 0:M.extracted_text),uploading:!1,progress:100};f(C)}catch{S(new Error("Failed to parse upload response"))}else S(new Error(`Upload failed: ${p.status}`))}),p.addEventListener("error",()=>S(new Error("Upload failed"))),p.open("POST",h),d&&p.setRequestHeader("Authorization",`Bearer ${d}`),Object.entries(m).forEach(([w,M])=>p.setRequestHeader(w,M)),p.send(g)});return(i=t.onFileUploadComplete)==null||i.call(t,y),y}catch(d){const m={...o,uploading:!1};return(l=t.onFileUploadError)==null||l.call(t,m,d),(u=t.onError)==null||u.call(t,d),null}},setPageContext(r){this.pageContext=r},toggleDrawer(){var r,t;this.showChat=!this.showChat,_t(this.showChat),(t=(r=K())==null?void 0:r.onDrawerToggle)==null||t.call(r,this.showChat),this.showChat&&this.scrollToBottom(100)},openDrawer(){var r,t;this.showChat=!0,_t(!0),(t=(r=K())==null?void 0:r.onDrawerToggle)==null||t.call(r,!0),this.scrollToBottom(100)},closeDrawer(){var r,t;this.showChat=!1,_t(!1),(t=(r=K())==null?void 0:r.onDrawerToggle)==null||t.call(r,!1)},startSupportRequest(){this.supportRequestMode=!0},cancelSupportRequest(){this.quota.remaining>0&&(this.supportRequestMode=!1)},registerUploadedFile(r){r!=null&&r.id&&(this.uploadedFiles[r.id]={...r})},startSetupMode(){this.setupState={isActive:!0,currentStep:"welcome",testApiKey:null,connectionStatus:"idle",backendConfigured:!1,lastError:null}},setSetupStep(r){this.setupState.currentStep=r},setTestApiKey(r){this.setupState.testApiKey=r},async testConnection(){this.setupState.connectionStatus="testing",this.setupState.lastError=null;const r=K();if(!r)return this.setupState.connectionStatus="failed",this.setupState.lastError="Plugin not configured",!1;try{const t={"Content-Type":"application/json",Accept:"application/json"};this.setupState.testApiKey&&(t["X-Test-Api-Key"]=this.setupState.testApiKey);const n=r.endpoints.quota||r.endpoints.ask,o=ct(n),s=await fetch(o,{method:r.endpoints.quota?"GET":"POST",headers:t,...r.endpoints.quota?{}:{body:JSON.stringify({question:"test",stream:!1})}});return s.ok?(this.setupState.connectionStatus="connected",this.setupState.backendConfigured=!0,!0):(this.setupState.connectionStatus="failed",this.setupState.lastError=`Connection failed: ${s.status} ${s.statusText}`,!1)}catch(t){return this.setupState.connectionStatus="failed",this.setupState.lastError=t.message||"Connection failed",!1}},completeSetup(){var r,t;this.setupState.isActive=!1,this.setupState.currentStep="complete",mn(),(t=(r=K())==null?void 0:r.onSetupComplete)==null||t.call(r)},skipSetup(){this.setupState.isActive=!1,mn()}}});function pn(r){const t=/@\[([^\]]+)\]\(([^)]+)\)/g,n=[];let o=r,s;for(;(s=t.exec(r))!==null;){const[a,i,l]=s,[u,d]=l.includes(":")?l.split(":"):["default",l];n.push({id:d,name:i,type:u}),o=o.replace(a,i)}return{cleanText:o,mentions:n}}function Xr(r){const{cleanText:t}=pn(r);return t}function hn(r){return r.replace(/@([A-Z][a-z]+(?:\s+[A-Z][a-z]+)*)/g,'<span class="rai-mention">@$1</span>')}function gn(r,t){const o=r.substring(0,t).match(/@(\w*)$/);return o?{inMention:!0,query:o[1],startPos:t-o[0].length}:{inMention:!1,query:"",startPos:-1}}function Lt(r,t){var n,o;return t!=null&&t.getDisplayName?t.getDisplayName(r):r.name||r.title||((n=r.attributes)==null?void 0:n.name)||((o=r.attributes)==null?void 0:o.title)||"Unknown"}function yn(r,t){var n,o;return t!=null&&t.getSubtitle?t.getSubtitle(r):((n=r.attributes)==null?void 0:n.email)||((o=r.attributes)==null?void 0:o.description)||null}function Jr(r,t){return t!=null&&t.buildMentionText?t.buildMentionText(r):`@[${Lt(r,t)}](${r.type}:${r.id})`}function kn(r){var n;const t=K();return(n=t==null?void 0:t.mentionProviders)==null?void 0:n.find(o=>o.type===r)}function xn(r){const t=K(),n=(t==null?void 0:t.mentionProviders)||[];return r?n.filter(o=>o.routes?o.routes.some(s=>s.endsWith("*")?r.startsWith(s.slice(0,-1)):r===s||r.startsWith(s+"/")):!0):n}function bn(r){return r.map(t=>({type:t.type,id:t.id,name:t.name}))}function wn(r){return r.reduce((t,n)=>{const o=n.type||"default";return t[o]||(t[o]=[]),t[o].push(n),t},{})}function vr(){return{extractMentions:pn,parseAndCleanMessage:Xr,renderMentionsInHtml:hn,detectMentionContext:gn,getMentionDisplayName:Lt,getMentionSubtitle:yn,buildMentionText:Jr,getMentionProvider:kn,getActiveMentionProviders:xn,formatMentionsForApi:bn,groupMentionsByType:wn}}function It(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}let _e=It();function Cn(r){_e=r}const En=/[&<>"']/,eo=new RegExp(En.source,"g"),Sn=/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,to=new RegExp(Sn.source,"g"),no={"&":"&","<":"<",">":">",'"':""","'":"'"},Tn=r=>no[r];function de(r,t){if(t){if(En.test(r))return r.replace(eo,Tn)}else if(Sn.test(r))return r.replace(to,Tn);return r}const ro=/(^|[^\[])\^/g;function H(r,t){let n=typeof r=="string"?r:r.source;t=t||"";const o={replace:(s,a)=>{let i=typeof a=="string"?a:a.source;return i=i.replace(ro,"$1"),n=n.replace(s,i),o},getRegex:()=>new RegExp(n,t)};return o}function An(r){try{r=encodeURI(r).replace(/%25/g,"%")}catch{return null}return r}const We={exec:()=>null};function Mn(r,t){const n=r.replace(/\|/g,(a,i,l)=>{let u=!1,d=i;for(;--d>=0&&l[d]==="\\";)u=!u;return u?"|":" |"}),o=n.split(/ \|/);let s=0;if(o[0].trim()||o.shift(),o.length>0&&!o[o.length-1].trim()&&o.pop(),t)if(o.length>t)o.splice(t);else for(;o.length<t;)o.push("");for(;s<o.length;s++)o[s]=o[s].trim().replace(/\\\|/g,"|");return o}function Ke(r,t,n){const o=r.length;if(o===0)return"";let s=0;for(;s<o&&r.charAt(o-s-1)===t;)s++;return r.slice(0,o-s)}function oo(r,t){if(r.indexOf(t[1])===-1)return-1;let n=0;for(let o=0;o<r.length;o++)if(r[o]==="\\")o++;else if(r[o]===t[0])n++;else if(r[o]===t[1]&&(n--,n<0))return o;return-1}function Bn(r,t,n,o){const s=t.href,a=t.title?de(t.title):null,i=r[1].replace(/\\([\[\]])/g,"$1");if(r[0].charAt(0)!=="!"){o.state.inLink=!0;const l={type:"link",raw:n,href:s,title:a,text:i,tokens:o.inlineTokens(i)};return o.state.inLink=!1,l}return{type:"image",raw:n,href:s,title:a,text:de(i)}}function so(r,t){const n=r.match(/^(\s+)(?:```)/);if(n===null)return t;const o=n[1];return t.split(`
|
|
3
3
|
`).map(s=>{const a=s.match(/^\s+/);if(a===null)return s;const[i]=a;return i.length>=o.length?s.slice(o.length):s}).join(`
|
|
4
4
|
`)}class ut{constructor(t){q(this,"options");q(this,"rules");q(this,"lexer");this.options=t||_e}space(t){const n=this.rules.block.newline.exec(t);if(n&&n[0].length>0)return{type:"space",raw:n[0]}}code(t){const n=this.rules.block.code.exec(t);if(n){const o=n[0].replace(/^(?: {1,4}| {0,3}\t)/gm,"");return{type:"code",raw:n[0],codeBlockStyle:"indented",text:this.options.pedantic?o:Ke(o,`
|
|
@@ -65,7 +65,7 @@ app.<span class="text-yellow-300">use</span>(RestifyAiPlugin, {
|
|
|
65
65
|
<span class="text-blue-300">quota</span>: <span class="text-green-400">'/api/ai/quota'</span>, <span class="text-gray-500">// optional</span>
|
|
66
66
|
},
|
|
67
67
|
<span class="text-blue-300">getAuthToken</span>: () => <span class="text-yellow-300">getToken</span>(),
|
|
68
|
-
})</code></pre>`,1))]),n[3]||(n[3]=e.createElementVNode("p",{class:"text-xs text-gray-400 dark:text-gray-500 mt-4 text-center"},[e.createTextVNode(" Need help? Check the "),e.createElementVNode("a",{href:"https://github.com/
|
|
68
|
+
})</code></pre>`,1))]),n[3]||(n[3]=e.createElementVNode("p",{class:"text-xs text-gray-400 dark:text-gray-500 mt-4 text-center"},[e.createTextVNode(" Need help? Check the "),e.createElementVNode("a",{href:"https://github.com/BinarCode/restify-chatbot",target:"_blank",class:"text-primary hover:underline"},"documentation")],-1))])],64))}}),xi={key:0,class:"flex items-center gap-3 mb-4"},bi={class:"flex-shrink-0 w-10 h-10 rounded-full bg-amber-100 dark:bg-amber-900/30 flex items-center justify-center"},wi={class:"text-lg font-semibold text-gray-900 dark:text-white"},Ci={key:1,class:"text-lg font-semibold text-gray-900 dark:text-white mb-2"},Ei={class:"text-sm text-gray-600 dark:text-gray-400 mb-6"},Si={class:"flex justify-end gap-3"},lr=e.defineComponent({__name:"ConfirmDialog",props:{show:{type:Boolean},title:{},message:{},confirmText:{},cancelText:{},ui:{},icon:{default:null},confirmVariant:{default:"danger"}},emits:["confirm","cancel"],setup(r){const t=r,n=e.computed(()=>{var s,a;return t.icon==="warning"?(s=t.ui)==null?void 0:s.historyLimitModal:(a=t.ui)==null?void 0:a.closeConfirmModal}),o=e.computed(()=>{var i,l;const s=t.confirmVariant==="danger"?"bg-red-600 hover:bg-red-700":"bg-primary-500 hover:bg-primary-600",a=t.confirmVariant==="danger"?(i=t.ui)==null?void 0:i.closeConfirmButton:(l=t.ui)==null?void 0:l.historyLimitButton;return[s,a]});return(s,a)=>(e.openBlock(),e.createBlock(e.Transition,{"enter-active-class":"transition ease-out duration-200","enter-from-class":"opacity-0","enter-to-class":"opacity-100","leave-active-class":"transition ease-in duration-150","leave-from-class":"opacity-100","leave-to-class":"opacity-0"},{default:e.withCtx(()=>{var i;return[r.show?(e.openBlock(),e.createElementBlock("div",{key:0,class:"absolute inset-0 bg-black/50 flex items-center justify-center z-10",onClick:a[2]||(a[2]=e.withModifiers(l=>s.$emit("cancel"),["self"]))},[e.createElementVNode("div",{class:e.normalizeClass(["bg-white dark:bg-gray-800 rounded-xl p-6 m-4 max-w-sm w-full shadow-xl",n.value])},[r.icon==="warning"?(e.openBlock(),e.createElementBlock("div",xi,[e.createElementVNode("div",bi,[e.createVNode(e.unref(kt),{class:"w-5 h-5 text-amber-600 dark:text-amber-400"})]),e.createElementVNode("h3",wi,e.toDisplayString(r.title),1)])):(e.openBlock(),e.createElementBlock("h3",Ci,e.toDisplayString(r.title),1)),e.createElementVNode("p",Ei,e.toDisplayString(r.message),1),e.createElementVNode("div",Si,[e.createElementVNode("button",{type:"button",class:e.normalizeClass(["px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors",(i=r.ui)==null?void 0:i.cancelButton]),onClick:a[0]||(a[0]=l=>s.$emit("cancel"))},e.toDisplayString(r.cancelText),3),e.createElementVNode("button",{type:"button",class:e.normalizeClass(["px-4 py-2 text-sm font-medium text-white rounded-lg transition-colors",o.value]),onClick:a[1]||(a[1]=l=>s.$emit("confirm"))},e.toDisplayString(r.confirmText),3)])],2)])):e.createCommentVNode("",!0)]}),_:1}))}}),Ti={key:0,class:"flex-1 flex flex-col items-center justify-center p-6 overflow-y-auto"},Ai={key:0,class:"flex-1 flex flex-col overflow-y-auto"},Mi=or(e.defineComponent({__name:"AiChatDrawer",props:{modelValue:{type:Boolean},ui:{},texts:{},width:{default:"600px"},fullscreenWidth:{default:"90vw"},topOffset:{default:"0"},position:{default:"right"},showBackdrop:{type:Boolean,default:!1},closeOnBackdropClick:{type:Boolean,default:!0},closeOnEscape:{type:Boolean,default:!0},showQuota:{type:Boolean,default:!0},showMessageCount:{type:Boolean,default:!0},showFullscreenToggle:{type:Boolean,default:!0},showMinimizeButton:{type:Boolean,default:!0},showCloseButton:{type:Boolean,default:!0},showNewChatButton:{type:Boolean,default:!0},confirmClose:{type:Boolean,default:!0},historyLimit:{},loadingText:{},autoFetchQuota:{type:Boolean,default:!0}},emits:["update:modelValue","close","contact-support","new-chat"],setup(r,{emit:t}){const n=r,o=t,s=e.computed({get:()=>n.modelValue,set:$=>o("update:modelValue",$)});function a($,P){var le;const X=(le=n.texts)==null?void 0:le[$];if(X){let J=X;if(P)for(const[v,ce]of Object.entries(P))J=J.replace(`{${v}}`,String(ce));return J}return te($,P)}const i=Ae(),l=e.ref(""),u=e.ref(null),d=e.ref(null),m=e.ref(!1),h=e.ref(!1),g=e.ref(!1),{loadingMessage:y,startLoadingText:f,resetLoadingText:S}=ds(()=>i.sending,()=>n.loadingText),{showHistoryLimitWarning:p,historyLimitReached:w,historyLimitDialogTitle:M,historyLimitDialogMessage:x,dismissHistoryLimitWarning:C,handleHistoryLimitAction:I,checkHistoryLimit:b,setPendingMessage:N}=ms({getHistoryLength:()=>i.quota.limit-i.quota.remaining,getStoreLimit:()=>i.quota.limit,getConfig:()=>n.historyLimit,getTexts:()=>n.texts,onStartNewChat:()=>i.clearChatHistory(),onNewChatEmit:()=>o("new-chat")}),L=e.computed(()=>!Nt()),A=e.computed(()=>ke("enableSupportMode")??!1),{suggestions:B,resolvePrompt:V}=Xt(),{scrollToBottom:G,watchForScroll:_}=xs(u),O=e.computed(()=>L.value?[]:B.value||[]),{filteredSuggestions:z}=ks(O,l),ne=e.computed(()=>({quota:i.quota,isFullscreen:m.value,hasHistory:i.chatHistory.length>0,onNewChat:Me,onClose:Q,onMinimize:Ie,onToggleFullscreen:nt})),be=e.computed(()=>({modelValue:l.value,sending:i.sending,disabled:!1,onSubmit:ot,onCancel:()=>i.cancelRequest()}));function U($){const P=(B.value||[]).find(X=>X.id===$.id);P&&(l.value=V(P))}function nt(){m.value=!m.value}function Ie(){s.value=!1}function Q(){n.confirmClose&&!L.value&&i.chatHistory.length>0?g.value=!0:(s.value=!1,o("close"))}function xt(){g.value=!1,i.clearChatHistory(),s.value=!1,o("close")}function Y(){o("contact-support")}function bt(){i.toggleSupportMode()}function j($){l.value=$.prompt,i.clearError()}function Me(){i.clearChatHistory(),o("new-chat")}function rt($){}function Be(){navigator.clipboard.writeText(`import { RestifyAiPlugin } from '@doderasoftware/restify-ai'
|
|
69
69
|
|
|
70
70
|
app.use(RestifyAiPlugin, {
|
|
71
71
|
endpoints: {
|
|
@@ -73,4 +73,4 @@ app.use(RestifyAiPlugin, {
|
|
|
73
73
|
quota: '/api/ai/quota', // optional
|
|
74
74
|
},
|
|
75
75
|
getAuthToken: () => getToken(),
|
|
76
|
-
})`),h.value=!0,setTimeout(()=>{h.value=!1},2e3)}async function wt(){const $=await I();$&&(await e.nextTick(),await Oe($.message,$.attachments,$.mentions,$.isSupportRequest))}async function Oe($,P,X,le){i.clearError(),f(),await e.nextTick(),G();const J=await i.askQuestion($,P,X,le);S(),J&&G()}async function ot($){const{message:P,attachments:X,mentions:le,isSupportRequest:J}=$;if(i.sending)return;const v=le.map(ce=>({id:ce.id,name:ce.name,type:ce.type||"unknown",metadata:ce.metadata}));if(!b()){N({message:P,attachments:X,mentions:v,isSupportRequest:J});return}await Oe(P,X,v,J)}async function Ct(){f();const $=await i.retry();S(),$&&G()}function we($){n.closeOnEscape&&$.key==="Escape"&&s.value&&(g.value?g.value=!1:Ie())}return _(()=>i.chatHistory.length,()=>i.chatHistory.map($=>$.message).join("")),e.watch(()=>n.modelValue,async $=>{var P;$&&(await G(),(P=d.value)==null||P.focus()),$&&n.autoFetchQuota&&i.fetchQuota()},{immediate:!0}),e.onMounted(()=>{window.addEventListener("keydown",we)}),e.onUnmounted(()=>{window.removeEventListener("keydown",we)}),($,P)=>(e.openBlock(),e.createBlock(e.Teleport,{to:"body"},[e.createVNode(e.Transition,{name:"rai-fade"},{default:e.withCtx(()=>{var X;return[s.value&&r.showBackdrop?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["fixed inset-0 bg-black/30 z-40",(X=r.ui)==null?void 0:X.backdrop]),onClick:P[0]||(P[0]=le=>r.closeOnBackdropClick&&Ie())},null,2)):e.createCommentVNode("",!0)]}),_:1}),e.createVNode(e.Transition,{name:r.position==="left"?"rai-slide-right":"rai-slide-left"},{default:e.withCtx(()=>{var X,le,J;return[s.value?(e.openBlock(),e.createElementBlock("aside",{key:0,class:e.normalizeClass(["fixed bottom-0 z-50 flex-shrink-0 border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 shadow-2xl will-change-transform",[r.position==="left"?"left-0 border-r":"right-0 border-l",(X=r.ui)==null?void 0:X.drawer]]),style:e.normalizeStyle({width:m.value?r.fullscreenWidth:r.width,top:r.topOffset,height:`calc(100vh - ${r.topOffset})`})},[e.createElementVNode("div",{class:e.normalizeClass(["h-full flex flex-col relative bg-white dark:bg-gray-900",(le=r.ui)==null?void 0:le.panel])},[e.renderSlot($.$slots,"header",e.normalizeProps(e.guardReactiveProps(ne.value)),()=>[e.createVNode(oi,{ui:r.ui,"is-setup-mode":L.value,"show-new-chat-button":r.showNewChatButton,"has-history":e.unref(i).chatHistory.length>0,"show-quota":r.showQuota,quota:e.unref(i).quota,"show-close-button":r.showCloseButton,"show-minimize-button":r.showMinimizeButton,"show-fullscreen-toggle":r.showFullscreenToggle,"is-fullscreen":m.value,"show-message-count":r.showMessageCount,"message-count":e.unref(i).quota.used,"message-limit":e.unref(i).quota.limit,t:a,onNewChat:Me,onClose:Q,onMinimize:Ie,onToggleFullscreen:nt},{quota:e.withCtx(()=>[e.renderSlot($.$slots,"quota",{quota:e.unref(i).quota},void 0,!0)]),_:3},8,["ui","is-setup-mode","show-new-chat-button","has-history","show-quota","quota","show-close-button","show-minimize-button","show-fullscreen-toggle","is-fullscreen","show-message-count","message-count","message-limit"])],!0),e.createElementVNode("div",{class:e.normalizeClass(["h-full flex flex-col mx-auto w-full overflow-hidden",[{"max-w-5xl":m.value},(J=r.ui)==null?void 0:J.body]])},[L.value?(e.openBlock(),e.createElementBlock("div",Ti,[e.renderSlot($.$slots,"setup",{},()=>[e.createVNode(ki,{copied:h.value,onCopy:Be},null,8,["copied"])],!0)])):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.unref(i).chatHistory.length===0?(e.openBlock(),e.createElementBlock("div",Ai,[e.renderSlot($.$slots,"empty-state",{suggestions:e.unref(z),onClick:j},()=>[e.createVNode(ir,{onItemClick:j})],!0)])):(e.openBlock(),e.createElementBlock("div",{key:1,ref_key:"chatContainer",ref:u,class:"flex-1 overflow-y-auto py-6 pb-24"},[e.createVNode(fi,{messages:e.unref(i).chatHistory,"loading-message":e.unref(y),quota:e.unref(i).quota,error:e.unref(i).error,ui:r.ui,t:a,onCopy:rt,onContactSupport:Y,onRetry:Ct},{message:e.withCtx(v=>[e.renderSlot($.$slots,"message",{message:v.message,isUser:v.isUser,isLoading:v.isLoading,isStreaming:v.isStreaming},void 0,!0)]),_:3},8,["messages","loading-message","quota","error","ui"])],512)),P[3]||(P[3]=e.createElementVNode("div",{id:"rai-chat-bottom",class:"h-8"},null,-1)),e.renderSlot($.$slots,"input",e.normalizeProps(e.guardReactiveProps(be.value)),()=>{var v,ce;return[e.createVNode(ar,{ref_key:"chatInputRef",ref:d,modelValue:l.value,"onUpdate:modelValue":P[1]||(P[1]=Et=>l.value=Et),sending:e.unref(i).sending,placeholder:((v=n.texts)==null?void 0:v.placeholder)||e.unref(te)("inputPlaceholder"),"support-placeholder":((ce=n.texts)==null?void 0:ce.supportPlaceholder)||e.unref(te)("supportPlaceholder"),suggestions:e.unref(z),"has-history":e.unref(i).chatHistory.length>0,"support-request-mode":e.unref(i).supportRequestMode,"show-support-mode-toggle":A.value,onSubmit:ot,onCancel:e.unref(i).cancelRequest,onSuggestionSelect:U,onToggleSupportMode:bt},{"context-link":e.withCtx(()=>[e.renderSlot($.$slots,"context-link",{},void 0,!0)]),_:3},8,["modelValue","sending","placeholder","support-placeholder","suggestions","has-history","support-request-mode","show-support-mode-toggle","onCancel"])]},!0)],64))],2)],2),e.createVNode(lr,{show:g.value,title:a("closeConfirmTitle"),message:a("closeConfirmMessage"),"confirm-text":a("confirmClose"),"cancel-text":a("cancel"),ui:r.ui,"confirm-variant":"danger",onConfirm:xt,onCancel:P[2]||(P[2]=v=>g.value=!1)},null,8,["show","title","message","confirm-text","cancel-text","ui"]),e.createVNode(lr,{show:e.unref(p),title:e.unref(M),message:e.unref(x),"confirm-text":a("startNewChat"),"cancel-text":e.unref(w)?a("continueChat"):a("cancel"),ui:r.ui,icon:"warning","confirm-variant":"primary",onConfirm:wt,onCancel:e.unref(C)},null,8,["show","title","message","confirm-text","cancel-text","ui","onCancel"])],6)):e.createCommentVNode("",!0)]}),_:3},8,["name"])]))}}),[["__scopeId","data-v-25c9b34d"]]),Bi=e.defineComponent({__name:"ErrorBoundary",props:{title:{default:"Something went wrong"},message:{default:"An unexpected error occurred. Please try again."},retryText:{default:"Try Again"},showRetry:{type:Boolean,default:!0},ui:{},onError:{}},emits:["error","reset"],setup(r,{expose:t,emit:n}){const o=r,s=n,a=e.ref(!1),i=e.ref(null);e.onErrorCaptured((u,d,m)=>{var h;return a.value=!0,i.value=u,(h=o.onError)==null||h.call(o,u,m),s("error",u,m),!1});function l(){a.value=!1,i.value=null,s("reset")}return t({hasError:a,error:i,reset:l}),(u,d)=>a.value?e.renderSlot(u.$slots,"error",{key:1,error:i.value,reset:l},()=>{var m,h,g,y,f;return[e.createElementVNode("div",{class:e.normalizeClass(["flex flex-col items-center justify-center p-6 text-center",(m=r.ui)==null?void 0:m.container])},[e.createElementVNode("div",{class:e.normalizeClass(["w-12 h-12 mb-4 rounded-full bg-red-100 dark:bg-red-900/30 flex items-center justify-center",(h=r.ui)==null?void 0:h.iconContainer])},[e.createVNode(e.unref(kt),{class:"w-6 h-6 text-red-600 dark:text-red-400"})],2),e.createElementVNode("h3",{class:e.normalizeClass(["text-lg font-semibold text-gray-900 dark:text-white mb-2",(g=r.ui)==null?void 0:g.title])},e.toDisplayString(r.title),3),e.createElementVNode("p",{class:e.normalizeClass(["text-sm text-gray-600 dark:text-gray-400 mb-4",(y=r.ui)==null?void 0:y.message])},e.toDisplayString(r.message),3),r.showRetry?(e.openBlock(),e.createElementBlock("button",{key:0,class:e.normalizeClass(["px-4 py-2 text-sm font-medium text-white bg-primary rounded-lg hover:bg-primary/90 transition-colors",(f=r.ui)==null?void 0:f.retryButton]),onClick:l},e.toDisplayString(r.retryText),3)):e.createCommentVNode("",!0)],2)]}):e.renderSlot(u.$slots,"default",{key:0})}}),cr={install(r,t){if(!t.endpoints||!t.getAuthToken){console.warn("[@doderasoftware/restify-ai] Plugin requires endpoints and getAuthToken options.");return}const n={endpoints:t.endpoints,baseUrl:t.baseUrl,getAuthToken:t.getAuthToken,getCustomHeaders:t.getCustomHeaders,buildRequest:t.buildRequest,parseStreamContent:t.parseStreamContent,requestInterceptor:t.requestInterceptor,responseInterceptor:t.responseInterceptor,retry:t.retry,translate:t.translate,can:t.can,labels:{...Bt,...t.labels},mentionProviders:t.mentionProviders,suggestionProviders:t.suggestionProviders,defaultSuggestions:t.defaultSuggestions,theme:t.theme,chatHistoryLimit:t.chatHistoryLimit,maxAttachments:t.maxAttachments,maxFileSize:t.maxFileSize,acceptedFileTypes:t.acceptedFileTypes,chatHistoryKey:t.chatHistoryKey,drawerStateKey:t.drawerStateKey,keyboardShortcut:t.keyboardShortcut,enableSupportMode:t.enableSupportMode,useQuota:t.useQuota,canToggle:t.canToggle,assistantAvatar:t.assistantAvatar,userAvatar:t.userAvatar,onQuotaFetched:t.onQuotaFetched,onError:t.onError,onMessageSent:t.onMessageSent,onResponseReceived:t.onResponseReceived,onDrawerToggle:t.onDrawerToggle,onNewChat:t.onNewChat,onStreamStart:t.onStreamStart,onStreamEnd:t.onStreamEnd,onStreamChunk:t.onStreamChunk,beforeSend:t.beforeSend,afterResponse:t.afterResponse,onFileUploadStart:t.onFileUploadStart,onFileUploadProgress:t.onFileUploadProgress,onFileUploadComplete:t.onFileUploadComplete,onFileUploadError:t.onFileUploadError};ln(n),r.provide("restify-ai-config",n)}};R.AiAvatar=tr,R.AiChatDrawer=Mi,R.AiEmptyState=ir,R.ChatInput=ar,R.ChatMessage=sr,R.ChatMessageActions=rr,R.ChatRoles=Re,R.ErrorBoundary=Bi,R.MentionList=nr,R.RestifyAiPlugin=cr,R.UserAvatar=Ys,R.default=cr,R.defaultLabels=Bt,R.formatFileSize=lt,R.formatMentionsForApi=bn,R.getConfigValue=ke,R.getLabel=te,R.getRestifyAiConfig=K,R.getRestifyAiConfigOrThrow=Br,R.getSuggestionsForPath=Xn,R.groupMentionsByType=wn,R.isConfigured=Nt,R.isImageFile=it,R.registerSuggestionProvider=as,R.setRestifyAiConfig=ln,R.useAiContext=Yt,R.useAiDrawerShortcut=us,R.useAiSuggestions=Xt,R.useChatErrorHandling=ns,R.useChatMarkdown=Zn,R.useChatScroll=ts,R.useKeyboardShortcut=Jn,R.useMentionParsing=vr,R.usePageAiContext=is,R.useRestifyAiStore=Ae,Object.defineProperties(R,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
|
76
|
+
})`),h.value=!0,setTimeout(()=>{h.value=!1},2e3)}async function wt(){const $=await I();$&&(await e.nextTick(),await Oe($.message,$.attachments,$.mentions,$.isSupportRequest))}async function Oe($,P,X,le){i.clearError(),f(),await e.nextTick(),G();const J=await i.askQuestion($,P,X,le);S(),J&&G()}async function ot($){const{message:P,attachments:X,mentions:le,isSupportRequest:J}=$;if(i.sending)return;const v=le.map(ce=>({id:ce.id,name:ce.name,type:ce.type||"unknown",metadata:ce.metadata}));if(!b()){N({message:P,attachments:X,mentions:v,isSupportRequest:J});return}await Oe(P,X,v,J)}async function Ct(){f();const $=await i.retry();S(),$&&G()}function we($){n.closeOnEscape&&$.key==="Escape"&&s.value&&(g.value?g.value=!1:Ie())}return _(()=>i.chatHistory.length,()=>i.chatHistory.map($=>$.message).join("")),e.watch(()=>n.modelValue,async $=>{var P;$&&(await G(),(P=d.value)==null||P.focus()),$&&n.autoFetchQuota&&i.fetchQuota()},{immediate:!0}),e.onMounted(()=>{window.addEventListener("keydown",we)}),e.onUnmounted(()=>{window.removeEventListener("keydown",we)}),($,P)=>(e.openBlock(),e.createBlock(e.Teleport,{to:"body"},[e.createVNode(e.Transition,{name:"rai-fade"},{default:e.withCtx(()=>{var X;return[s.value&&r.showBackdrop?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["fixed inset-0 bg-black/30 z-40",(X=r.ui)==null?void 0:X.backdrop]),onClick:P[0]||(P[0]=le=>r.closeOnBackdropClick&&Ie())},null,2)):e.createCommentVNode("",!0)]}),_:1}),e.createVNode(e.Transition,{name:r.position==="left"?"rai-slide-right":"rai-slide-left"},{default:e.withCtx(()=>{var X,le,J;return[s.value?(e.openBlock(),e.createElementBlock("aside",{key:0,class:e.normalizeClass(["fixed bottom-0 z-50 flex-shrink-0 border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 shadow-2xl will-change-transform",[r.position==="left"?"left-0 border-r":"right-0 border-l",(X=r.ui)==null?void 0:X.drawer]]),style:e.normalizeStyle({width:m.value?r.fullscreenWidth:r.width,top:r.topOffset,height:`calc(100vh - ${r.topOffset})`})},[e.createElementVNode("div",{class:e.normalizeClass(["h-full flex flex-col relative bg-white dark:bg-gray-900",(le=r.ui)==null?void 0:le.panel])},[e.renderSlot($.$slots,"header",e.normalizeProps(e.guardReactiveProps(ne.value)),()=>[e.createVNode(oi,{ui:r.ui,"is-setup-mode":L.value,"show-new-chat-button":r.showNewChatButton,"has-history":e.unref(i).chatHistory.length>0,"show-quota":r.showQuota,quota:e.unref(i).quota,"show-close-button":r.showCloseButton,"show-minimize-button":r.showMinimizeButton,"show-fullscreen-toggle":r.showFullscreenToggle,"is-fullscreen":m.value,"show-message-count":r.showMessageCount,"message-count":e.unref(i).quota.used,"message-limit":e.unref(i).quota.limit,t:a,onNewChat:Me,onClose:Q,onMinimize:Ie,onToggleFullscreen:nt},{quota:e.withCtx(()=>[e.renderSlot($.$slots,"quota",{quota:e.unref(i).quota},void 0,!0)]),_:3},8,["ui","is-setup-mode","show-new-chat-button","has-history","show-quota","quota","show-close-button","show-minimize-button","show-fullscreen-toggle","is-fullscreen","show-message-count","message-count","message-limit"])],!0),e.createElementVNode("div",{class:e.normalizeClass(["h-full flex flex-col mx-auto w-full overflow-hidden",[{"max-w-5xl":m.value},(J=r.ui)==null?void 0:J.body]])},[L.value?(e.openBlock(),e.createElementBlock("div",Ti,[e.renderSlot($.$slots,"setup",{},()=>[e.createVNode(ki,{copied:h.value,onCopy:Be},null,8,["copied"])],!0)])):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.unref(i).chatHistory.length===0?(e.openBlock(),e.createElementBlock("div",Ai,[e.renderSlot($.$slots,"empty-state",{suggestions:e.unref(z),onClick:j},()=>[e.createVNode(ir,{onItemClick:j})],!0)])):(e.openBlock(),e.createElementBlock("div",{key:1,ref_key:"chatContainer",ref:u,class:"flex-1 overflow-y-auto py-6 pb-24"},[e.createVNode(fi,{messages:e.unref(i).chatHistory,"loading-message":e.unref(y),quota:e.unref(i).quota,error:e.unref(i).error,ui:r.ui,t:a,onCopy:rt,onContactSupport:Y,onRetry:Ct},{message:e.withCtx(v=>[e.renderSlot($.$slots,"message",{message:v.message,isUser:v.isUser,isLoading:v.isLoading,isStreaming:v.isStreaming},void 0,!0)]),_:3},8,["messages","loading-message","quota","error","ui"])],512)),P[3]||(P[3]=e.createElementVNode("div",{id:"rai-chat-bottom",class:"h-8"},null,-1)),e.renderSlot($.$slots,"input",e.normalizeProps(e.guardReactiveProps(be.value)),()=>{var v,ce;return[e.createVNode(ar,{ref_key:"chatInputRef",ref:d,modelValue:l.value,"onUpdate:modelValue":P[1]||(P[1]=Et=>l.value=Et),sending:e.unref(i).sending,placeholder:((v=n.texts)==null?void 0:v.placeholder)||e.unref(te)("inputPlaceholder"),"support-placeholder":((ce=n.texts)==null?void 0:ce.supportPlaceholder)||e.unref(te)("supportPlaceholder"),suggestions:e.unref(z),"has-history":e.unref(i).chatHistory.length>0,"support-request-mode":e.unref(i).supportRequestMode,"show-support-mode-toggle":A.value,onSubmit:ot,onCancel:e.unref(i).cancelRequest,onSuggestionSelect:U,onToggleSupportMode:bt},{"context-link":e.withCtx(()=>[e.renderSlot($.$slots,"context-link",{},void 0,!0)]),_:3},8,["modelValue","sending","placeholder","support-placeholder","suggestions","has-history","support-request-mode","show-support-mode-toggle","onCancel"])]},!0)],64))],2)],2),e.createVNode(lr,{show:g.value,title:a("closeConfirmTitle"),message:a("closeConfirmMessage"),"confirm-text":a("confirmClose"),"cancel-text":a("cancel"),ui:r.ui,"confirm-variant":"danger",onConfirm:xt,onCancel:P[2]||(P[2]=v=>g.value=!1)},null,8,["show","title","message","confirm-text","cancel-text","ui"]),e.createVNode(lr,{show:e.unref(p),title:e.unref(M),message:e.unref(x),"confirm-text":a("startNewChat"),"cancel-text":e.unref(w)?a("continueChat"):a("cancel"),ui:r.ui,icon:"warning","confirm-variant":"primary",onConfirm:wt,onCancel:e.unref(C)},null,8,["show","title","message","confirm-text","cancel-text","ui","onCancel"])],6)):e.createCommentVNode("",!0)]}),_:3},8,["name"])]))}}),[["__scopeId","data-v-25c9b34d"]]),Bi=e.defineComponent({__name:"ErrorBoundary",props:{title:{default:"Something went wrong"},message:{default:"An unexpected error occurred. Please try again."},retryText:{default:"Try Again"},showRetry:{type:Boolean,default:!0},ui:{},onError:{}},emits:["error","reset"],setup(r,{expose:t,emit:n}){const o=r,s=n,a=e.ref(!1),i=e.ref(null);e.onErrorCaptured((u,d,m)=>{var h;return a.value=!0,i.value=u,(h=o.onError)==null||h.call(o,u,m),s("error",u,m),!1});function l(){a.value=!1,i.value=null,s("reset")}return t({hasError:a,error:i,reset:l}),(u,d)=>a.value?e.renderSlot(u.$slots,"error",{key:1,error:i.value,reset:l},()=>{var m,h,g,y,f;return[e.createElementVNode("div",{class:e.normalizeClass(["flex flex-col items-center justify-center p-6 text-center",(m=r.ui)==null?void 0:m.container])},[e.createElementVNode("div",{class:e.normalizeClass(["w-12 h-12 mb-4 rounded-full bg-red-100 dark:bg-red-900/30 flex items-center justify-center",(h=r.ui)==null?void 0:h.iconContainer])},[e.createVNode(e.unref(kt),{class:"w-6 h-6 text-red-600 dark:text-red-400"})],2),e.createElementVNode("h3",{class:e.normalizeClass(["text-lg font-semibold text-gray-900 dark:text-white mb-2",(g=r.ui)==null?void 0:g.title])},e.toDisplayString(r.title),3),e.createElementVNode("p",{class:e.normalizeClass(["text-sm text-gray-600 dark:text-gray-400 mb-4",(y=r.ui)==null?void 0:y.message])},e.toDisplayString(r.message),3),r.showRetry?(e.openBlock(),e.createElementBlock("button",{key:0,class:e.normalizeClass(["px-4 py-2 text-sm font-medium text-white bg-primary rounded-lg hover:bg-primary/90 transition-colors",(f=r.ui)==null?void 0:f.retryButton]),onClick:l},e.toDisplayString(r.retryText),3)):e.createCommentVNode("",!0)],2)]}):e.renderSlot(u.$slots,"default",{key:0})}}),cr={install(r,t){if(!t.endpoints||!t.getAuthToken){console.warn("[restify-ai] Plugin requires endpoints and getAuthToken options.");return}const n={endpoints:t.endpoints,baseUrl:t.baseUrl,getAuthToken:t.getAuthToken,getCustomHeaders:t.getCustomHeaders,buildRequest:t.buildRequest,parseStreamContent:t.parseStreamContent,requestInterceptor:t.requestInterceptor,responseInterceptor:t.responseInterceptor,retry:t.retry,translate:t.translate,can:t.can,labels:{...Bt,...t.labels},mentionProviders:t.mentionProviders,suggestionProviders:t.suggestionProviders,defaultSuggestions:t.defaultSuggestions,theme:t.theme,chatHistoryLimit:t.chatHistoryLimit,maxAttachments:t.maxAttachments,maxFileSize:t.maxFileSize,acceptedFileTypes:t.acceptedFileTypes,chatHistoryKey:t.chatHistoryKey,drawerStateKey:t.drawerStateKey,keyboardShortcut:t.keyboardShortcut,enableSupportMode:t.enableSupportMode,useQuota:t.useQuota,canToggle:t.canToggle,assistantAvatar:t.assistantAvatar,userAvatar:t.userAvatar,onQuotaFetched:t.onQuotaFetched,onError:t.onError,onMessageSent:t.onMessageSent,onResponseReceived:t.onResponseReceived,onDrawerToggle:t.onDrawerToggle,onNewChat:t.onNewChat,onStreamStart:t.onStreamStart,onStreamEnd:t.onStreamEnd,onStreamChunk:t.onStreamChunk,beforeSend:t.beforeSend,afterResponse:t.afterResponse,onFileUploadStart:t.onFileUploadStart,onFileUploadProgress:t.onFileUploadProgress,onFileUploadComplete:t.onFileUploadComplete,onFileUploadError:t.onFileUploadError};ln(n),r.provide("restify-ai-config",n)}};R.AiAvatar=tr,R.AiChatDrawer=Mi,R.AiEmptyState=ir,R.ChatInput=ar,R.ChatMessage=sr,R.ChatMessageActions=rr,R.ChatRoles=Re,R.ErrorBoundary=Bi,R.MentionList=nr,R.RestifyAiPlugin=cr,R.UserAvatar=Ys,R.default=cr,R.defaultLabels=Bt,R.formatFileSize=lt,R.formatMentionsForApi=bn,R.getConfigValue=ke,R.getLabel=te,R.getRestifyAiConfig=K,R.getRestifyAiConfigOrThrow=Br,R.getSuggestionsForPath=Xn,R.groupMentionsByType=wn,R.isConfigured=Nt,R.isImageFile=it,R.registerSuggestionProvider=as,R.setRestifyAiConfig=ln,R.useAiContext=Yt,R.useAiDrawerShortcut=us,R.useAiSuggestions=Xt,R.useChatErrorHandling=ns,R.useChatMarkdown=Zn,R.useChatScroll=ts,R.useKeyboardShortcut=Jn,R.useMentionParsing=vr,R.usePageAiContext=is,R.useRestifyAiStore=Ae,Object.defineProperties(R,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
package/dist/types/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/types/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/types/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAEzC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;KAEhB,CAAC,CAAA;IACF,MAAM,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,OAAO,CAAA;IACb,GAAG,EAAE,OAAO,CAAA;CACb;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,gBAAgB,KAAK,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;AACxG,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AAC9E,MAAM,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAA;AAC1C,MAAM,MAAM,eAAe,GAAG,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAA;AAC3D,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;AAC9D,MAAM,MAAM,oBAAoB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAA;AAC3F,MAAM,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;AAC1G,MAAM,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,QAAQ,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;AAEtF;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAA;CACzD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doderasoftware/restify-ai",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.2",
|
|
4
4
|
"description": "Professional AI Chatbot Vue 3 component for Laravel Restify backends. SSE streaming, file uploads, @mentions, context-aware suggestions, and full TypeScript support.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/restify-ai.umd.cjs",
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"preview": "vite preview",
|
|
34
34
|
"test": "vitest",
|
|
35
35
|
"test:coverage": "vitest run --coverage",
|
|
36
|
-
"lint": "eslint
|
|
36
|
+
"lint": "eslint src --fix",
|
|
37
|
+
"lint:check": "eslint src",
|
|
37
38
|
"type-check": "vue-tsc --noEmit",
|
|
38
39
|
"prepublishOnly": "npm run build",
|
|
39
40
|
"version:patch": "npm version patch",
|
|
@@ -61,6 +62,7 @@
|
|
|
61
62
|
"marked": "^14.1.4"
|
|
62
63
|
},
|
|
63
64
|
"devDependencies": {
|
|
65
|
+
"@eslint/js": "^9.39.2",
|
|
64
66
|
"@tailwindcss/forms": "^0.5.6",
|
|
65
67
|
"@tailwindcss/typography": "^0.5.10",
|
|
66
68
|
"@types/dompurify": "^3.0.5",
|
|
@@ -71,13 +73,13 @@
|
|
|
71
73
|
"@vue/tsconfig": "^0.5.1",
|
|
72
74
|
"autoprefixer": "^10.4.16",
|
|
73
75
|
"eslint": "^9.39.2",
|
|
74
|
-
"eslint-plugin-vue": "^10.
|
|
76
|
+
"eslint-plugin-vue": "^10.7.0",
|
|
75
77
|
"globals": "^16.5.0",
|
|
76
78
|
"pinia": "^2.1.7",
|
|
77
79
|
"postcss": "^8.4.31",
|
|
78
80
|
"tailwindcss": "^3.3.5",
|
|
79
81
|
"typescript": "~5.6.0",
|
|
80
|
-
"typescript-eslint": "^8.
|
|
82
|
+
"typescript-eslint": "^8.53.1",
|
|
81
83
|
"vite": "^5.4.11",
|
|
82
84
|
"vite-plugin-dts": "^3.6.4",
|
|
83
85
|
"vitest": "^1.6.1",
|
|
@@ -119,12 +121,12 @@
|
|
|
119
121
|
"license": "MIT",
|
|
120
122
|
"repository": {
|
|
121
123
|
"type": "git",
|
|
122
|
-
"url": "git+https://github.com/BinarCode/restify-
|
|
124
|
+
"url": "git+https://github.com/BinarCode/restify-chatbot.git"
|
|
123
125
|
},
|
|
124
126
|
"bugs": {
|
|
125
|
-
"url": "https://github.com/BinarCode/restify-
|
|
127
|
+
"url": "https://github.com/BinarCode/restify-chatbot/issues"
|
|
126
128
|
},
|
|
127
|
-
"homepage": "https://
|
|
129
|
+
"homepage": "https://github.com/BinarCode/restify-chatbot#readme",
|
|
128
130
|
"publishConfig": {
|
|
129
131
|
"access": "public",
|
|
130
132
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -136,4 +138,4 @@
|
|
|
136
138
|
"type": "github",
|
|
137
139
|
"url": "https://github.com/sponsors/binarcode"
|
|
138
140
|
}
|
|
139
|
-
}
|
|
141
|
+
}
|
package/tailwind.config.cjs
CHANGED
|
@@ -1,34 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Restify AI Tailwind CSS Configuration
|
|
3
|
-
*
|
|
4
|
-
* This package uses Tailwind CSS and expects your project to have:
|
|
5
|
-
* 1. A `primary` color defined in your Tailwind theme
|
|
6
|
-
* 2. Dark mode support via the `dark` class
|
|
7
|
-
*
|
|
8
|
-
* Example in your tailwind.config.js:
|
|
9
|
-
*
|
|
10
|
-
* module.exports = {
|
|
11
|
-
* darkMode: 'class',
|
|
12
|
-
* theme: {
|
|
13
|
-
* extend: {
|
|
14
|
-
* colors: {
|
|
15
|
-
* primary: {
|
|
16
|
-
* DEFAULT: '#3b82f6', // or your brand color
|
|
17
|
-
* 50: '#eff6ff',
|
|
18
|
-
* 100: '#dbeafe',
|
|
19
|
-
* // ... etc
|
|
20
|
-
* }
|
|
21
|
-
* }
|
|
22
|
-
* }
|
|
23
|
-
* },
|
|
24
|
-
* // Add this package's components to content
|
|
25
|
-
* content: [
|
|
26
|
-
* './src/**\/*.{vue,js,ts}',
|
|
27
|
-
* './node_modules/@doderasoftware/restify-ai/**\/*.{vue,js,ts}'
|
|
28
|
-
* ]
|
|
29
|
-
* }
|
|
30
|
-
*
|
|
31
|
-
* If you use DaisyUI, the primary color is already defined.
|
|
2
|
+
* Restify AI Tailwind CSS Configuration Preset
|
|
32
3
|
*/
|
|
33
4
|
|
|
34
5
|
// This is a preset that consumers can optionally extend
|