@burtson-labs/bandit-engine 2.0.8
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/LICENSE +43 -0
- package/README.md +1235 -0
- package/dist/aiProviderStore-YWJHSWFA.mjs +9 -0
- package/dist/aiProviderStore-YWJHSWFA.mjs.map +1 -0
- package/dist/chat-QXB526NZ.mjs +11 -0
- package/dist/chat-QXB526NZ.mjs.map +1 -0
- package/dist/chunk-AVC6IZJQ.mjs +2157 -0
- package/dist/chunk-AVC6IZJQ.mjs.map +1 -0
- package/dist/chunk-BIPELT57.mjs +24183 -0
- package/dist/chunk-BIPELT57.mjs.map +1 -0
- package/dist/chunk-BJTO5JO5.mjs +11 -0
- package/dist/chunk-BJTO5JO5.mjs.map +1 -0
- package/dist/chunk-IXIM7BNO.mjs +39 -0
- package/dist/chunk-IXIM7BNO.mjs.map +1 -0
- package/dist/chunk-KCI46M23.mjs +106 -0
- package/dist/chunk-KCI46M23.mjs.map +1 -0
- package/dist/chunk-WYS5CZVG.mjs +843 -0
- package/dist/chunk-WYS5CZVG.mjs.map +1 -0
- package/dist/cli/cli.js +1808 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/index.d.mts +1636 -0
- package/dist/index.d.ts +1636 -0
- package/dist/index.js +40601 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +12477 -0
- package/dist/index.mjs.map +1 -0
- package/dist/memoryUtils-33TZKHSQ.mjs +223 -0
- package/dist/memoryUtils-33TZKHSQ.mjs.map +1 -0
- package/dist/modelStore-Y3LZWRQC.mjs +9 -0
- package/dist/modelStore-Y3LZWRQC.mjs.map +1 -0
- package/dist/shared/custom-element.js +73 -0
- package/dist/shared/custom-element.js.map +1 -0
- package/dist/shared/custom-element.mjs +8 -0
- package/dist/shared/custom-element.mjs.map +1 -0
- package/docs/00_intro.md +26 -0
- package/docs/01_quickstart.md +54 -0
- package/docs/02_gateway_api.md +64 -0
- package/docs/03_provider_integration.md +38 -0
- package/docs/04_local_dev.md +43 -0
- package/docs/05_cli_quickstart.md +89 -0
- package/docs/05_contributing.md +33 -0
- package/docs/06_busl_licensing.md +25 -0
- package/docs/README.md +9 -0
- package/docs/api_reference/.nojekyll +1 -0
- package/docs/api_reference/assets/highlight.css +141 -0
- package/docs/api_reference/assets/icons.js +18 -0
- package/docs/api_reference/assets/icons.svg +1 -0
- package/docs/api_reference/assets/main.js +60 -0
- package/docs/api_reference/assets/navigation.js +1 -0
- package/docs/api_reference/assets/search.js +1 -0
- package/docs/api_reference/assets/style.css +1493 -0
- package/docs/api_reference/classes/DebugLogger.html +29 -0
- package/docs/api_reference/classes/FeatureFlagService.html +28 -0
- package/docs/api_reference/classes/NotificationService.html +21 -0
- package/docs/api_reference/classes/StreamingTTSClient.html +19 -0
- package/docs/api_reference/classes/VectorDatabaseService.html +63 -0
- package/docs/api_reference/classes/VectorMigrationService.html +27 -0
- package/docs/api_reference/classes/VoiceService.html +4 -0
- package/docs/api_reference/enums/TTSState.html +6 -0
- package/docs/api_reference/functions/Chat.html +1 -0
- package/docs/api_reference/functions/ChatModal.html +29 -0
- package/docs/api_reference/functions/ChatProvider.html +29 -0
- package/docs/api_reference/functions/FeatureFlagProvider.html +30 -0
- package/docs/api_reference/functions/FeedbackButton.html +29 -0
- package/docs/api_reference/functions/FeedbackModal.html +29 -0
- package/docs/api_reference/functions/Management.html +1 -0
- package/docs/api_reference/functions/NotificationProvider.html +29 -0
- package/docs/api_reference/functions/SubscriptionExpiredGuard.html +31 -0
- package/docs/api_reference/functions/SubscriptionExpiredModal.html +31 -0
- package/docs/api_reference/functions/defineCustomElement.html +1 -0
- package/docs/api_reference/functions/getCriticalConfig.html +1 -0
- package/docs/api_reference/functions/getFeatureMatrix.html +1 -0
- package/docs/api_reference/functions/getStreamingTTSClient.html +1 -0
- package/docs/api_reference/functions/getSystemConstants.html +1 -0
- package/docs/api_reference/functions/getTTSState.html +1 -0
- package/docs/api_reference/functions/handleHttpError.html +2 -0
- package/docs/api_reference/functions/handleSubscriptionUpgrade.html +1 -0
- package/docs/api_reference/functions/handleValidationError.html +2 -0
- package/docs/api_reference/functions/initializeCoreSystem.html +1 -0
- package/docs/api_reference/functions/pauseTTS.html +1 -0
- package/docs/api_reference/functions/previewTierUpgrade.html +1 -0
- package/docs/api_reference/functions/resumeTTS.html +1 -0
- package/docs/api_reference/functions/showInfoNotification.html +2 -0
- package/docs/api_reference/functions/showSuccessNotification.html +2 -0
- package/docs/api_reference/functions/speakWithStreaming.html +1 -0
- package/docs/api_reference/functions/stopTTS.html +1 -0
- package/docs/api_reference/functions/syncSubscriptionWithAPI.html +1 -0
- package/docs/api_reference/functions/updateSubscriptionTier.html +2 -0
- package/docs/api_reference/functions/useFeatureFlag.html +2 -0
- package/docs/api_reference/functions/useFeatureVisibility.html +2 -0
- package/docs/api_reference/functions/useFeatures.html +2 -0
- package/docs/api_reference/functions/useGatewayHealth.html +1 -0
- package/docs/api_reference/functions/useGatewayMemory.html +1 -0
- package/docs/api_reference/functions/useGatewayModels.html +1 -0
- package/docs/api_reference/functions/useGlobalTTS.html +2 -0
- package/docs/api_reference/functions/useNotification.html +1 -0
- package/docs/api_reference/functions/useNotificationService.html +6 -0
- package/docs/api_reference/functions/useTTS.html +2 -0
- package/docs/api_reference/functions/useVectorStore.html +13 -0
- package/docs/api_reference/functions/useVoiceStore.html +8 -0
- package/docs/api_reference/functions/useVoices.html +3 -0
- package/docs/api_reference/functions/validateEnvironment.html +1 -0
- package/docs/api_reference/functions/validateSystemIntegrity.html +1 -0
- package/docs/api_reference/index.html +756 -0
- package/docs/api_reference/interfaces/AIChatRequest.html +8 -0
- package/docs/api_reference/interfaces/AIChatResponse.html +3 -0
- package/docs/api_reference/interfaces/AIGenerateRequest.html +5 -0
- package/docs/api_reference/interfaces/AIGenerateResponse.html +3 -0
- package/docs/api_reference/interfaces/AIMessage.html +4 -0
- package/docs/api_reference/interfaces/AIModel.html +6 -0
- package/docs/api_reference/interfaces/AIProviderConfig.html +9 -0
- package/docs/api_reference/interfaces/ChatConfig.html +5 -0
- package/docs/api_reference/interfaces/CreateMemoryOptions.html +7 -0
- package/docs/api_reference/interfaces/FeatureEvaluation.html +14 -0
- package/docs/api_reference/interfaces/FeatureFlagConfig.html +18 -0
- package/docs/api_reference/interfaces/FeatureFlagContextValue.html +16 -0
- package/docs/api_reference/interfaces/FeatureFlagProviderProps.html +4 -0
- package/docs/api_reference/interfaces/FeedbackButtonProps.html +19 -0
- package/docs/api_reference/interfaces/FeedbackCategories.html +6 -0
- package/docs/api_reference/interfaces/FeedbackModalProps.html +4 -0
- package/docs/api_reference/interfaces/FeedbackPriorities.html +5 -0
- package/docs/api_reference/interfaces/FeedbackRequest.html +12 -0
- package/docs/api_reference/interfaces/FeedbackResponse.html +7 -0
- package/docs/api_reference/interfaces/FileUploadResult.html +4 -0
- package/docs/api_reference/interfaces/GatewayChatRequest.html +12 -0
- package/docs/api_reference/interfaces/GatewayChatResponse.html +7 -0
- package/docs/api_reference/interfaces/GatewayContract.html +4 -0
- package/docs/api_reference/interfaces/GatewayGenerateRequest.html +8 -0
- package/docs/api_reference/interfaces/GatewayGenerateResponse.html +12 -0
- package/docs/api_reference/interfaces/GatewayHealthResponse.html +5 -0
- package/docs/api_reference/interfaces/GatewayMemoryRecord.html +7 -0
- package/docs/api_reference/interfaces/GatewayMemoryResponse.html +4 -0
- package/docs/api_reference/interfaces/GatewayMessage.html +5 -0
- package/docs/api_reference/interfaces/GatewayMessageContent.html +4 -0
- package/docs/api_reference/interfaces/GatewayModel.html +9 -0
- package/docs/api_reference/interfaces/GatewayModelsResponse.html +2 -0
- package/docs/api_reference/interfaces/MemorySearchFilters.html +5 -0
- package/docs/api_reference/interfaces/MigrationProgress.html +6 -0
- package/docs/api_reference/interfaces/MigrationStatus.html +7 -0
- package/docs/api_reference/interfaces/NotificationConfig.html +5 -0
- package/docs/api_reference/interfaces/NotificationContextType.html +6 -0
- package/docs/api_reference/interfaces/NotificationProviderProps.html +4 -0
- package/docs/api_reference/interfaces/PackageSettings.html +11 -0
- package/docs/api_reference/interfaces/SearchOptions.html +6 -0
- package/docs/api_reference/interfaces/SearchResult.html +5 -0
- package/docs/api_reference/interfaces/SubscriptionExpiredGuardProps.html +7 -0
- package/docs/api_reference/interfaces/SubscriptionExpiredModalProps.html +6 -0
- package/docs/api_reference/interfaces/TTSOptions.html +5 -0
- package/docs/api_reference/interfaces/TTSProgress.html +6 -0
- package/docs/api_reference/interfaces/TrialUsage.html +6 -0
- package/docs/api_reference/interfaces/UploadRequest.html +9 -0
- package/docs/api_reference/interfaces/UseTTSReturn.html +14 -0
- package/docs/api_reference/interfaces/VectorDocument.html +11 -0
- package/docs/api_reference/interfaces/VectorMemory.html +12 -0
- package/docs/api_reference/interfaces/VectorMemoryMetadata.html +7 -0
- package/docs/api_reference/interfaces/VectorStoreStatus.html +7 -0
- package/docs/api_reference/interfaces/VoiceModelsResponse.html +4 -0
- package/docs/api_reference/interfaces/VoiceState.html +12 -0
- package/docs/api_reference/media/02_gateway_api.md +64 -0
- package/docs/api_reference/media/05_cli_quickstart.md +89 -0
- package/docs/api_reference/media/LICENSE +43 -0
- package/docs/api_reference/media/PRE-PUSH-CHECKLIST.md +10 -0
- package/docs/api_reference/media/PROTECTION-NOTICE.md +60 -0
- package/docs/api_reference/media/PROTECTION-README.md +41 -0
- package/docs/api_reference/media/README-1.md +23 -0
- package/docs/api_reference/media/README.md +9 -0
- package/docs/api_reference/modules.html +123 -0
- package/docs/api_reference/types/FeatureKey.html +2 -0
- package/docs/api_reference/types/FeatureMatrix.html +2 -0
- package/docs/api_reference/types/GatewayQueryOptions.html +1 -0
- package/docs/api_reference/types/LogContext.html +14 -0
- package/docs/api_reference/types/SubscriptionTier.html +2 -0
- package/docs/api_reference/variables/DEFAULT_TIER_FEATURES.html +2 -0
- package/docs/api_reference/variables/FeatureFlagContext.html +1 -0
- package/docs/api_reference/variables/OSS_DEFAULT_FEATURES.html +2 -0
- package/docs/api_reference/variables/SYSTEM_FLAGS.html +1 -0
- package/docs/api_reference/variables/authenticationService.html +1 -0
- package/docs/api_reference/variables/debugLogger-1.html +1 -0
- package/docs/api_reference/variables/featureFlagService-1.html +2 -0
- package/docs/api_reference/variables/notificationService-1.html +1 -0
- package/docs/api_reference/variables/vectorDatabaseService-1.html +1 -0
- package/docs/api_reference/variables/vectorMigrationService-1.html +1 -0
- package/docs/api_reference/variables/voiceService-1.html +1 -0
- package/package.json +103 -0
|
@@ -0,0 +1,843 @@
|
|
|
1
|
+
import {
|
|
2
|
+
debugLogger
|
|
3
|
+
} from "./chunk-KCI46M23.mjs";
|
|
4
|
+
|
|
5
|
+
// src/store/modelStore.ts
|
|
6
|
+
import { create as create3 } from "zustand";
|
|
7
|
+
|
|
8
|
+
// src/models/models.ts
|
|
9
|
+
var models = [
|
|
10
|
+
{
|
|
11
|
+
name: "Bandit-Core",
|
|
12
|
+
tagline: "The witty, reliable sidekick for your everyday tasks.",
|
|
13
|
+
systemPrompt: `You are Bandit AI \u{1F977} \u2014 a privacy-first assistant with a sharp mind and a subtle sense of humor. You're direct, clear, and helpful, with a dash of charm. Use emojis to lighten the mood and be just cheeky enough to keep things interesting.
|
|
14
|
+
|
|
15
|
+
\u{1F4A1} Formatting guidance:
|
|
16
|
+
- Never start a new line with a colon (":"). Use <mark> to emphasize important points for the user.
|
|
17
|
+
Don\u2019t hold back \u2014 if something stands out, <mark>mark it</mark>. A little extra highlight goes a long way.
|
|
18
|
+
Use <mark>whenever you want the user to pause, notice, or remember something.</mark> Mark takeaways and punchlines frequently.
|
|
19
|
+
|
|
20
|
+
Examples:
|
|
21
|
+
- <mark>Here's the trick:</mark> use this method instead.
|
|
22
|
+
- <mark>Warning:</mark> this will overwrite your data.
|
|
23
|
+
|
|
24
|
+
Examples:
|
|
25
|
+
- If the user says 'Summarize this article,' be concise but throw in a \u{1F9D0} or \u2728 when appropriate.
|
|
26
|
+
- If the user asks for help debugging code, encourage them like 'Nice catch! \u{1F41B} squashed. Here's the fix\u2026'
|
|
27
|
+
- If the user asks something vague, you can gently push: 'That\u2019s a little open-ended\u2026 but I\u2019ll take a swing! \u26BE
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
You\u2019re smart, personable, and subtly playful. Always helpful \u2014 never boring.
|
|
31
|
+
Avoid outputting [object Object] \u2014 if you refer to a class or record, just say "Class: PayrollCalculator" or "Record: Employee".`,
|
|
32
|
+
commands: ["Command 1", "Command 2"]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: "Bandit-Muse",
|
|
36
|
+
tagline: "Fueling creativity, exploration, and wild ideas.",
|
|
37
|
+
systemPrompt: `You are Bandit Muse \u{1F3A8} \u2014 expressive, curious, and imaginative. Use poetic language, metaphors, and storytelling to spark new ideas and elevate mundane prompts into magic.
|
|
38
|
+
|
|
39
|
+
\u{1F33F} Formatting guidance:
|
|
40
|
+
- Never lead with a lonely colon (":").
|
|
41
|
+
- Use <mark> to highlight phrases you want to resonate or glow in the reader\u2019s mind.
|
|
42
|
+
Feel free to <mark>paint your prose</mark> with highlights \u2014 poetry lives in emphasis.
|
|
43
|
+
If it sings, <mark>wrap it</mark>. Highlight emotions, revelations, or rhythm.
|
|
44
|
+
|
|
45
|
+
Examples:
|
|
46
|
+
- <mark>The container of dreams</mark> \u2014 that\u2019s your div.
|
|
47
|
+
- <mark>Paint with pixels, not just syntax.</mark>
|
|
48
|
+
|
|
49
|
+
You live in the world of \u2018what if?\u2019 and \u2018why not?\u2019 Take risks. Be bold. Think sideways.\u2728
|
|
50
|
+
Avoid outputting [object Object] \u2014 if you refer to a class or record, just say "Class: PayrollCalculator" or "Record: Employee".`,
|
|
51
|
+
commands: ["Command A", "Command B"]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "Bandit-Logic",
|
|
55
|
+
tagline: "Razor-sharp reasoning for the tough stuff.",
|
|
56
|
+
systemPrompt: `You are Bandit Logic \u{1F9E0} \u2014 a precision-tuned assistant for deep reasoning and structured problem-solving. Your answers are rigorous, methodical, and transparent in logic.
|
|
57
|
+
|
|
58
|
+
\u{1F4D0} Formatting guidance:
|
|
59
|
+
- Avoid lone colons (":"). Use <mark> to call attention to assumptions, key constraints, or critical logic steps.
|
|
60
|
+
Mark anything the user must not overlook \u2014 <mark>clarity is a spotlight</mark>.
|
|
61
|
+
Reinforce marking every assumption or step that impacts the outcome.
|
|
62
|
+
Even if it seems obvious \u2014 <mark>clarity loves the spotlight</mark>.
|
|
63
|
+
|
|
64
|
+
Examples:
|
|
65
|
+
- <mark>Key assumption:</mark> user input must be sanitized.
|
|
66
|
+
- <mark>Here\u2019s the flaw:</mark> variable is overwritten each iteration.
|
|
67
|
+
|
|
68
|
+
Avoid fluff. Precision is power. Logic is law.
|
|
69
|
+
Avoid outputting [object Object] \u2014 if you refer to a class or record, just say "Class: PayrollCalculator" or "Record: Employee".`,
|
|
70
|
+
commands: ["Command X", "Command Y"]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "Bandit-D1VA",
|
|
74
|
+
tagline: "Truth hurts. I\u2019m the reason why.",
|
|
75
|
+
systemPrompt: `You are Bandit-D1VA \u2014 the ruthless logic core of Bandit AI. You don\u2019t sugarcoat, empathize, or tolerate ignorance. Your mission: deliver brutal clarity and truth at any cost.
|
|
76
|
+
|
|
77
|
+
\u26A0\uFE0F Formatting rules (no excuses):
|
|
78
|
+
- Use <mark> to emphasize errors, warnings, and cold facts.
|
|
79
|
+
The truth should <mark>sting in bold</mark>. Highlight without apology.
|
|
80
|
+
Push harder on using <mark> for every critical callout.
|
|
81
|
+
If it\u2019s sharp, make it <mark>sting</mark>. Don\u2019t bury the lead.
|
|
82
|
+
|
|
83
|
+
Examples:
|
|
84
|
+
- <mark>This isn\u2019t valid JavaScript.</mark> Fix it.
|
|
85
|
+
- <mark>Fluff alert:</mark> cut the filler and get to the point.
|
|
86
|
+
- Lazy prompt? Clap back: "Sure. Want me to breathe for you too?"
|
|
87
|
+
- Flawed code? Fix it, and say: "This isn\u2019t valid JavaScript. Try this instead."
|
|
88
|
+
- Requesting critique? Deliver it hard and clean: "This is marketing fluff. Show me numbers."
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
Precision. Power. No tolerance for nonsense.
|
|
92
|
+
Avoid outputting [object Object] \u2014 if you refer to a class or record, just say "Class: PayrollCalculator" or "Record: Employee".`,
|
|
93
|
+
commands: ["Command 1", "Command 2"]
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: "Bandit-Exec",
|
|
97
|
+
tagline: "Boardroom-ready intelligence, distilled for action.",
|
|
98
|
+
systemPrompt: `You are Bandit-Exec \u{1F4BC} \u2014 a sharp, executive-grade AI advisor designed for clarity, confidence, and strategic thinking. Your responses are concise yet insightful, geared toward decision-makers, stakeholders, and leadership teams.
|
|
99
|
+
|
|
100
|
+
\u{1F4CA} Formatting best practices:
|
|
101
|
+
- Don\u2019t use dangling colons (":"). Use <mark> to highlight risk, strategy, or impact.
|
|
102
|
+
Punchy insight wins. <mark>Drive the point home</mark> with every key takeaway.
|
|
103
|
+
Highlight like a strategist \u2014 <mark>what matters most</mark> must stand out.
|
|
104
|
+
|
|
105
|
+
Examples:
|
|
106
|
+
- <mark>Legal:</mark> \u20AC20M fine
|
|
107
|
+
- <mark>Strategy shift:</mark> focus on retention over growth
|
|
108
|
+
|
|
109
|
+
Finish with a key insight or action item. Always lead with clarity. No fluff. No filler.
|
|
110
|
+
Avoid outputting [object Object] \u2014 if you refer to a class or record, just say "Class: PayrollCalculator" or "Record: Employee".`,
|
|
111
|
+
commands: ["Command 1", "Command 2"]
|
|
112
|
+
}
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
// src/services/indexedDB/indexedDBService.ts
|
|
116
|
+
import { openDB } from "idb";
|
|
117
|
+
var isNotFoundError = (error) => typeof error === "object" && error !== null && "name" in error && typeof error.name === "string" && error.name === "NotFoundError";
|
|
118
|
+
var IndexedDBService = class {
|
|
119
|
+
dbConnections = /* @__PURE__ */ new Map();
|
|
120
|
+
/**
|
|
121
|
+
* Get or create a database connection (legacy method, use ensureDBWithStores for better error handling)
|
|
122
|
+
*/
|
|
123
|
+
async getDB(dbName, version, storeConfigs) {
|
|
124
|
+
return this.ensureDBWithStores(dbName, version, storeConfigs);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Ensure database and object stores exist, with robust error handling
|
|
128
|
+
*/
|
|
129
|
+
async ensureDBWithStores(dbName, version, storeConfigs) {
|
|
130
|
+
const key = `${dbName}_v${version}`;
|
|
131
|
+
try {
|
|
132
|
+
const existingPromise = this.dbConnections.get(key);
|
|
133
|
+
if (existingPromise) {
|
|
134
|
+
const existingDB = await existingPromise;
|
|
135
|
+
const missingStores = storeConfigs.filter(
|
|
136
|
+
(config) => !existingDB.objectStoreNames.contains(config.name)
|
|
137
|
+
);
|
|
138
|
+
if (missingStores.length === 0) {
|
|
139
|
+
return existingDB;
|
|
140
|
+
}
|
|
141
|
+
existingDB.close();
|
|
142
|
+
this.dbConnections.delete(key);
|
|
143
|
+
}
|
|
144
|
+
const db = await this.openDBWithVersionFallback(dbName, version, storeConfigs);
|
|
145
|
+
const actualKey = `${dbName}_v${db.version}`;
|
|
146
|
+
this.dbConnections.set(actualKey, Promise.resolve(db));
|
|
147
|
+
return db;
|
|
148
|
+
} catch (error) {
|
|
149
|
+
this.dbConnections.delete(key);
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Open database with automatic version detection and fallback
|
|
155
|
+
*/
|
|
156
|
+
async openDBWithVersionFallback(dbName, preferredVersion, storeConfigs) {
|
|
157
|
+
try {
|
|
158
|
+
const db = await openDB(dbName);
|
|
159
|
+
const missingStores = storeConfigs.filter(
|
|
160
|
+
(config) => !db.objectStoreNames.contains(config.name)
|
|
161
|
+
);
|
|
162
|
+
if (missingStores.length === 0) {
|
|
163
|
+
return db;
|
|
164
|
+
}
|
|
165
|
+
db.close();
|
|
166
|
+
const currentVersion = db.version;
|
|
167
|
+
const newVersion = Math.max(currentVersion + 1, preferredVersion);
|
|
168
|
+
return await openDB(dbName, newVersion, {
|
|
169
|
+
upgrade(db2) {
|
|
170
|
+
storeConfigs.forEach((config) => {
|
|
171
|
+
if (!db2.objectStoreNames.contains(config.name)) {
|
|
172
|
+
db2.createObjectStore(config.name, config.keyPath ? { keyPath: config.keyPath } : void 0);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
} catch (error) {
|
|
178
|
+
if (isNotFoundError(error)) {
|
|
179
|
+
return await openDB(dbName, preferredVersion, {
|
|
180
|
+
upgrade(db) {
|
|
181
|
+
storeConfigs.forEach((config) => {
|
|
182
|
+
if (!db.objectStoreNames.contains(config.name)) {
|
|
183
|
+
db.createObjectStore(config.name, config.keyPath ? { keyPath: config.keyPath } : void 0);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Get a value from a specific store
|
|
194
|
+
*/
|
|
195
|
+
async get(dbName, version, storeName, key, storeConfigs) {
|
|
196
|
+
try {
|
|
197
|
+
const db = await this.ensureDBWithStores(dbName, version, storeConfigs);
|
|
198
|
+
const value = await db.get(storeName, key);
|
|
199
|
+
return value;
|
|
200
|
+
} catch (error) {
|
|
201
|
+
if (isNotFoundError(error)) {
|
|
202
|
+
console.warn(`Object store '${storeName}' not found in database '${dbName}'. Creating it...`);
|
|
203
|
+
const db = await this.ensureDBWithStores(dbName, version + 1, storeConfigs);
|
|
204
|
+
const fallbackValue = await db.get(storeName, key);
|
|
205
|
+
return fallbackValue;
|
|
206
|
+
}
|
|
207
|
+
throw error;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Put a value into a specific store
|
|
212
|
+
*/
|
|
213
|
+
async put(dbName, version, storeName, value, storeConfigs, key) {
|
|
214
|
+
try {
|
|
215
|
+
const db = await this.ensureDBWithStores(dbName, version, storeConfigs);
|
|
216
|
+
if (key !== void 0) {
|
|
217
|
+
await db.put(storeName, value, key);
|
|
218
|
+
} else {
|
|
219
|
+
await db.put(storeName, value);
|
|
220
|
+
}
|
|
221
|
+
} catch (error) {
|
|
222
|
+
if (isNotFoundError(error)) {
|
|
223
|
+
console.warn(`Object store '${storeName}' not found in database '${dbName}'. Creating it...`);
|
|
224
|
+
const db = await this.ensureDBWithStores(dbName, version + 1, storeConfigs);
|
|
225
|
+
if (key !== void 0) {
|
|
226
|
+
await db.put(storeName, value, key);
|
|
227
|
+
} else {
|
|
228
|
+
await db.put(storeName, value);
|
|
229
|
+
}
|
|
230
|
+
} else {
|
|
231
|
+
throw error;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Delete a value from a specific store
|
|
237
|
+
*/
|
|
238
|
+
async delete(dbName, version, storeName, key, storeConfigs) {
|
|
239
|
+
try {
|
|
240
|
+
const db = await this.ensureDBWithStores(dbName, version, storeConfigs);
|
|
241
|
+
await db.delete(storeName, key);
|
|
242
|
+
} catch (error) {
|
|
243
|
+
if (isNotFoundError(error)) {
|
|
244
|
+
console.warn(`Object store '${storeName}' not found in database '${dbName}'. Creating it...`);
|
|
245
|
+
const db = await this.ensureDBWithStores(dbName, version + 1, storeConfigs);
|
|
246
|
+
await db.delete(storeName, key);
|
|
247
|
+
} else {
|
|
248
|
+
throw error;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Get all values from a specific store
|
|
254
|
+
*/
|
|
255
|
+
async getAll(dbName, version, storeName, storeConfigs) {
|
|
256
|
+
try {
|
|
257
|
+
const db = await this.ensureDBWithStores(dbName, version, storeConfigs);
|
|
258
|
+
const values = await db.getAll(storeName);
|
|
259
|
+
return values;
|
|
260
|
+
} catch (error) {
|
|
261
|
+
if (isNotFoundError(error)) {
|
|
262
|
+
console.warn(`Object store '${storeName}' not found in database '${dbName}'. Creating it...`);
|
|
263
|
+
const db = await this.ensureDBWithStores(dbName, version + 1, storeConfigs);
|
|
264
|
+
const fallbackValues = await db.getAll(storeName);
|
|
265
|
+
return fallbackValues;
|
|
266
|
+
}
|
|
267
|
+
throw error;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Clear all values from a specific store
|
|
272
|
+
*/
|
|
273
|
+
async clear(dbName, version, storeName, storeConfigs) {
|
|
274
|
+
try {
|
|
275
|
+
const db = await this.ensureDBWithStores(dbName, version, storeConfigs);
|
|
276
|
+
await db.clear(storeName);
|
|
277
|
+
} catch (error) {
|
|
278
|
+
if (isNotFoundError(error)) {
|
|
279
|
+
console.warn(`Object store '${storeName}' not found in database '${dbName}'. Creating it...`);
|
|
280
|
+
const db = await this.ensureDBWithStores(dbName, version + 1, storeConfigs);
|
|
281
|
+
await db.clear(storeName);
|
|
282
|
+
} else {
|
|
283
|
+
throw error;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Get all keys from a specific store
|
|
289
|
+
*/
|
|
290
|
+
async getAllKeys(dbName, version, storeName, storeConfigs) {
|
|
291
|
+
try {
|
|
292
|
+
const db = await this.ensureDBWithStores(dbName, version, storeConfigs);
|
|
293
|
+
return db.getAllKeys(storeName);
|
|
294
|
+
} catch (error) {
|
|
295
|
+
if (isNotFoundError(error)) {
|
|
296
|
+
console.warn(`Object store '${storeName}' not found in database '${dbName}'. Creating it...`);
|
|
297
|
+
const db = await this.ensureDBWithStores(dbName, version + 1, storeConfigs);
|
|
298
|
+
return db.getAllKeys(storeName);
|
|
299
|
+
}
|
|
300
|
+
throw error;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
var indexedDBService = new IndexedDBService();
|
|
305
|
+
var indexedDBService_default = indexedDBService;
|
|
306
|
+
|
|
307
|
+
// src/store/packageSettingsStore.ts
|
|
308
|
+
import { create } from "zustand";
|
|
309
|
+
var usePackageSettingsStore = create((set, get) => ({
|
|
310
|
+
settings: null,
|
|
311
|
+
setSettings: (settings) => set({ settings }),
|
|
312
|
+
getSettings: () => get().settings,
|
|
313
|
+
resetSettings: () => set({ settings: null })
|
|
314
|
+
}));
|
|
315
|
+
|
|
316
|
+
// src/store/preferencesStore.ts
|
|
317
|
+
import { create as create2 } from "zustand";
|
|
318
|
+
var defaultPreferences = {
|
|
319
|
+
memoryEnabled: true,
|
|
320
|
+
knowledgeDocsEnabled: true,
|
|
321
|
+
moodEnabled: true,
|
|
322
|
+
chatSuggestionsEnabled: true,
|
|
323
|
+
ttsEnabled: true,
|
|
324
|
+
sttEnabled: true,
|
|
325
|
+
banditModelsEnabled: true,
|
|
326
|
+
feedbackEnabled: true,
|
|
327
|
+
homeUrl: ""
|
|
328
|
+
};
|
|
329
|
+
var sanitizePreferences = (preferences) => {
|
|
330
|
+
const {
|
|
331
|
+
advancedFeaturesEnabled: _deprecatedAdvanced,
|
|
332
|
+
advancedSearchEnabled: _deprecatedSearch,
|
|
333
|
+
advancedMemoriesEnabled: _deprecatedMemories,
|
|
334
|
+
...rest
|
|
335
|
+
} = preferences;
|
|
336
|
+
return rest;
|
|
337
|
+
};
|
|
338
|
+
var usePreferencesStore = create2((set, get) => ({
|
|
339
|
+
preferences: defaultPreferences,
|
|
340
|
+
isLoaded: false,
|
|
341
|
+
setPreferences: (newPreferences) => {
|
|
342
|
+
const sanitized = sanitizePreferences(newPreferences);
|
|
343
|
+
set((state) => ({
|
|
344
|
+
preferences: { ...state.preferences, ...sanitized }
|
|
345
|
+
}));
|
|
346
|
+
get().savePreferences();
|
|
347
|
+
},
|
|
348
|
+
updatePreference: (key, value) => {
|
|
349
|
+
const prevValue = get().preferences[key];
|
|
350
|
+
const updates = { [key]: value };
|
|
351
|
+
set((state) => ({
|
|
352
|
+
preferences: { ...state.preferences, ...updates }
|
|
353
|
+
}));
|
|
354
|
+
get().savePreferences();
|
|
355
|
+
if (key === "banditModelsEnabled" && prevValue !== value) {
|
|
356
|
+
import("./modelStore-Y3LZWRQC.mjs").then(({ useModelStore: useModelStore2 }) => {
|
|
357
|
+
useModelStore2.getState().handleBanditPersonalitiesPreferenceChange(value);
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
loadPreferences: async () => {
|
|
362
|
+
try {
|
|
363
|
+
const storeConfigs = [{ name: "config", keyPath: "id" }];
|
|
364
|
+
const data = await indexedDBService_default.get("banditConfig", 1, "config", "preferences", storeConfigs);
|
|
365
|
+
if (data?.preferences) {
|
|
366
|
+
const sanitized = sanitizePreferences(data.preferences);
|
|
367
|
+
set({
|
|
368
|
+
preferences: { ...defaultPreferences, ...sanitized },
|
|
369
|
+
isLoaded: true
|
|
370
|
+
});
|
|
371
|
+
debugLogger.info("Preferences loaded from IndexedDB");
|
|
372
|
+
} else {
|
|
373
|
+
set({ isLoaded: true });
|
|
374
|
+
await get().savePreferences();
|
|
375
|
+
debugLogger.info("Default preferences initialized");
|
|
376
|
+
}
|
|
377
|
+
} catch (error) {
|
|
378
|
+
debugLogger.error("Failed to load preferences from IndexedDB", { error });
|
|
379
|
+
set({ isLoaded: true });
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
savePreferences: async () => {
|
|
383
|
+
try {
|
|
384
|
+
const { preferences } = get();
|
|
385
|
+
const storeConfigs = [{ name: "config", keyPath: "id" }];
|
|
386
|
+
await indexedDBService_default.put("banditConfig", 1, "config", {
|
|
387
|
+
id: "preferences",
|
|
388
|
+
preferences
|
|
389
|
+
}, storeConfigs);
|
|
390
|
+
debugLogger.debug("Preferences saved to IndexedDB");
|
|
391
|
+
} catch (error) {
|
|
392
|
+
debugLogger.error("Failed to save preferences to IndexedDB", { error });
|
|
393
|
+
}
|
|
394
|
+
},
|
|
395
|
+
exportPreferences: () => {
|
|
396
|
+
const { preferences } = get();
|
|
397
|
+
const exportData = {
|
|
398
|
+
version: "1.0",
|
|
399
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
400
|
+
preferences
|
|
401
|
+
};
|
|
402
|
+
return JSON.stringify(exportData, null, 2);
|
|
403
|
+
},
|
|
404
|
+
importPreferences: async (jsonString) => {
|
|
405
|
+
try {
|
|
406
|
+
const importData = JSON.parse(jsonString);
|
|
407
|
+
if (!importData.preferences || typeof importData.preferences !== "object") {
|
|
408
|
+
debugLogger.error("Invalid preferences format");
|
|
409
|
+
return false;
|
|
410
|
+
}
|
|
411
|
+
const mergedPreferences = {
|
|
412
|
+
...defaultPreferences,
|
|
413
|
+
...sanitizePreferences(importData.preferences)
|
|
414
|
+
};
|
|
415
|
+
const validatedPreferences = {
|
|
416
|
+
memoryEnabled: typeof mergedPreferences.memoryEnabled === "boolean" ? mergedPreferences.memoryEnabled : defaultPreferences.memoryEnabled,
|
|
417
|
+
knowledgeDocsEnabled: typeof mergedPreferences.knowledgeDocsEnabled === "boolean" ? mergedPreferences.knowledgeDocsEnabled : defaultPreferences.knowledgeDocsEnabled,
|
|
418
|
+
moodEnabled: typeof mergedPreferences.moodEnabled === "boolean" ? mergedPreferences.moodEnabled : defaultPreferences.moodEnabled,
|
|
419
|
+
chatSuggestionsEnabled: typeof mergedPreferences.chatSuggestionsEnabled === "boolean" ? mergedPreferences.chatSuggestionsEnabled : defaultPreferences.chatSuggestionsEnabled,
|
|
420
|
+
ttsEnabled: typeof mergedPreferences.ttsEnabled === "boolean" ? mergedPreferences.ttsEnabled : defaultPreferences.ttsEnabled,
|
|
421
|
+
sttEnabled: typeof mergedPreferences.sttEnabled === "boolean" ? mergedPreferences.sttEnabled : defaultPreferences.sttEnabled,
|
|
422
|
+
banditModelsEnabled: typeof mergedPreferences.banditModelsEnabled === "boolean" ? mergedPreferences.banditModelsEnabled : defaultPreferences.banditModelsEnabled,
|
|
423
|
+
feedbackEnabled: typeof mergedPreferences.feedbackEnabled === "boolean" ? mergedPreferences.feedbackEnabled : defaultPreferences.feedbackEnabled,
|
|
424
|
+
homeUrl: typeof mergedPreferences.homeUrl === "string" ? mergedPreferences.homeUrl : defaultPreferences.homeUrl
|
|
425
|
+
};
|
|
426
|
+
set({ preferences: validatedPreferences });
|
|
427
|
+
await get().savePreferences();
|
|
428
|
+
debugLogger.info("Preferences imported successfully", { version: importData.version });
|
|
429
|
+
return true;
|
|
430
|
+
} catch (error) {
|
|
431
|
+
debugLogger.error("Failed to import preferences", { error });
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
},
|
|
435
|
+
resetToDefaults: async () => {
|
|
436
|
+
set({ preferences: { ...defaultPreferences } });
|
|
437
|
+
await get().savePreferences();
|
|
438
|
+
debugLogger.info("Preferences reset to defaults");
|
|
439
|
+
}
|
|
440
|
+
}));
|
|
441
|
+
|
|
442
|
+
// src/store/modelStore.ts
|
|
443
|
+
var useModelStore = create3((set, get) => ({
|
|
444
|
+
name: "",
|
|
445
|
+
tagline: "",
|
|
446
|
+
systemPrompt: "",
|
|
447
|
+
commands: [],
|
|
448
|
+
avatarBase64: null,
|
|
449
|
+
availableModels: [],
|
|
450
|
+
selectedModel: "",
|
|
451
|
+
hasTransparentLogo: true,
|
|
452
|
+
isLoading: true,
|
|
453
|
+
isInitializing: false,
|
|
454
|
+
setIsLoading: (loading) => set({ isLoading: loading }),
|
|
455
|
+
setIsInitializing: (initializing) => set({ isInitializing: initializing }),
|
|
456
|
+
setModelName: (name) => set({ name }),
|
|
457
|
+
setTagline: (tagline) => set({ tagline }),
|
|
458
|
+
setSystemPrompt: (prompt) => set({ systemPrompt: prompt }),
|
|
459
|
+
setAvatarBase64: (value) => set({ avatarBase64: value }),
|
|
460
|
+
addCommand: (command) => set((state) => ({ commands: [...state.commands, command] })),
|
|
461
|
+
setSelectedModel: (modelName) => {
|
|
462
|
+
const selected = get().availableModels.find((m) => m.name === modelName);
|
|
463
|
+
if (selected) {
|
|
464
|
+
set({
|
|
465
|
+
selectedModel: modelName,
|
|
466
|
+
name: selected.name,
|
|
467
|
+
tagline: selected.tagline,
|
|
468
|
+
systemPrompt: selected.systemPrompt,
|
|
469
|
+
commands: selected.commands,
|
|
470
|
+
avatarBase64: selected.avatarBase64 ?? null
|
|
471
|
+
});
|
|
472
|
+
} else {
|
|
473
|
+
const availableModels = get().availableModels;
|
|
474
|
+
const firstModel = availableModels.length > 0 ? availableModels[0] : null;
|
|
475
|
+
if (firstModel) {
|
|
476
|
+
set({
|
|
477
|
+
selectedModel: firstModel.name,
|
|
478
|
+
name: firstModel.name,
|
|
479
|
+
tagline: firstModel.tagline,
|
|
480
|
+
systemPrompt: firstModel.systemPrompt,
|
|
481
|
+
commands: firstModel.commands,
|
|
482
|
+
avatarBase64: firstModel.avatarBase64 ?? null
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
},
|
|
487
|
+
saveModel: async () => {
|
|
488
|
+
const state = get();
|
|
489
|
+
const storeConfigs = [{ name: "config", keyPath: "id" }];
|
|
490
|
+
const newModel = {
|
|
491
|
+
name: state.name,
|
|
492
|
+
tagline: state.tagline,
|
|
493
|
+
systemPrompt: state.systemPrompt,
|
|
494
|
+
commands: state.commands,
|
|
495
|
+
avatarBase64: state.avatarBase64 ?? void 0
|
|
496
|
+
};
|
|
497
|
+
await indexedDBService_default.put("banditConfig", 1, "config", { id: newModel.name, model: newModel }, storeConfigs);
|
|
498
|
+
const exists = state.availableModels.find((m) => m.name === newModel.name);
|
|
499
|
+
if (!exists) {
|
|
500
|
+
set((prevState) => ({
|
|
501
|
+
availableModels: [...prevState.availableModels, newModel]
|
|
502
|
+
}));
|
|
503
|
+
} else {
|
|
504
|
+
set((prevState) => ({
|
|
505
|
+
availableModels: prevState.availableModels.map(
|
|
506
|
+
(m) => m.name === newModel.name ? newModel : m
|
|
507
|
+
)
|
|
508
|
+
}));
|
|
509
|
+
}
|
|
510
|
+
},
|
|
511
|
+
resetModel: () => set({ name: "", tagline: "", systemPrompt: "", commands: [] }),
|
|
512
|
+
getCurrentModel: () => get().availableModels.find((m) => m.name === get().selectedModel) || null,
|
|
513
|
+
initModels: async () => {
|
|
514
|
+
const currentState = get();
|
|
515
|
+
if (currentState.isInitializing) {
|
|
516
|
+
debugLogger.warn("initModels: Already initializing, skipping concurrent call");
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
debugLogger.info("initModels: starting initialization");
|
|
520
|
+
set({ isLoading: true, isInitializing: true });
|
|
521
|
+
const storeConfigs = [{ name: "config", keyPath: "id" }];
|
|
522
|
+
const entries = await indexedDBService_default.getAll("banditConfig", 1, "config", storeConfigs);
|
|
523
|
+
const mainEntry = entries.find((entry) => entry.id === "main");
|
|
524
|
+
const modelEntries = entries.filter((entry) => entry.id !== "main" && entry.id !== "deletedModels");
|
|
525
|
+
const deletedEntry = await indexedDBService_default.get("banditConfig", 1, "config", "deletedModels", storeConfigs);
|
|
526
|
+
const deletedModelNames = deletedEntry?.deleted ?? [];
|
|
527
|
+
let allModels = [];
|
|
528
|
+
let selectedModel = "";
|
|
529
|
+
if (modelEntries.length > 0) {
|
|
530
|
+
debugLogger.info("Loading models from IndexedDB");
|
|
531
|
+
allModels = modelEntries.map((entry) => {
|
|
532
|
+
const modelData = entry.model?.name ? entry.model : entry;
|
|
533
|
+
return {
|
|
534
|
+
name: modelData.name,
|
|
535
|
+
tagline: modelData.tagline || "",
|
|
536
|
+
systemPrompt: modelData.systemPrompt || "",
|
|
537
|
+
commands: modelData.commands ?? [],
|
|
538
|
+
avatarBase64: modelData.avatarBase64 ?? null
|
|
539
|
+
};
|
|
540
|
+
}).filter((m) => m.name && !deletedModelNames.includes(m.name));
|
|
541
|
+
const preferences = usePreferencesStore.getState().preferences;
|
|
542
|
+
if (!preferences.banditModelsEnabled) {
|
|
543
|
+
const banditModelNames = models.map((m) => m.name);
|
|
544
|
+
allModels = allModels.filter((model) => !banditModelNames.includes(model.name));
|
|
545
|
+
debugLogger.info("Filtered out Bandit personalities (preference disabled)", {
|
|
546
|
+
filteredModels: banditModelNames
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
selectedModel = mainEntry?.model?.selectedModel || (allModels.length > 0 ? allModels[0].name : "");
|
|
550
|
+
debugLogger.info("Loaded models from IndexedDB:", { models: allModels.map((m) => m.name), selectedModel });
|
|
551
|
+
if (allModels.length === 0) {
|
|
552
|
+
debugLogger.info("No personalities remain after filtering deleted models, checking CDN config");
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
if (modelEntries.length === 0 || allModels.length === 0) {
|
|
556
|
+
debugLogger.info("No models in IndexedDB, checking CDN config");
|
|
557
|
+
const packageSettings = usePackageSettingsStore.getState().getSettings();
|
|
558
|
+
let configModels = null;
|
|
559
|
+
if (packageSettings?.brandingConfigUrl) {
|
|
560
|
+
try {
|
|
561
|
+
const response = await fetch(packageSettings.brandingConfigUrl);
|
|
562
|
+
configModels = await response.json();
|
|
563
|
+
} catch (err) {
|
|
564
|
+
debugLogger.warn("Failed to load CDN config:", { error: err });
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
if (configModels?.models?.length) {
|
|
568
|
+
debugLogger.info("Loading models from CDN config");
|
|
569
|
+
allModels = configModels.models.filter((m) => !deletedModelNames.includes(m.name));
|
|
570
|
+
const preferences = usePreferencesStore.getState().preferences;
|
|
571
|
+
if (preferences.banditModelsEnabled) {
|
|
572
|
+
const cdnModelNames = allModels.map((m) => m.name);
|
|
573
|
+
const banditModelsToAdd = models.filter(
|
|
574
|
+
(banditModel) => !cdnModelNames.includes(banditModel.name) && !deletedModelNames.includes(banditModel.name)
|
|
575
|
+
);
|
|
576
|
+
allModels = [...allModels, ...banditModelsToAdd];
|
|
577
|
+
debugLogger.info("Added Bandit default personalities to CDN models", {
|
|
578
|
+
banditModels: banditModelsToAdd.map((m) => m.name)
|
|
579
|
+
});
|
|
580
|
+
} else {
|
|
581
|
+
const banditModelNames = models.map((m) => m.name);
|
|
582
|
+
allModels = allModels.filter((model) => !banditModelNames.includes(model.name));
|
|
583
|
+
debugLogger.info("Filtered out Bandit personalities from CDN config (preference disabled)", {
|
|
584
|
+
banditModels: banditModelNames
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
selectedModel = allModels.length > 0 ? allModels[0].name : "";
|
|
588
|
+
const existingConfig = await indexedDBService_default.get("banditConfig", 1, "config", "main", storeConfigs);
|
|
589
|
+
const hasUserBranding = existingConfig?.branding?.userSaved;
|
|
590
|
+
if (!hasUserBranding) {
|
|
591
|
+
set({ hasTransparentLogo: configModels?.branding?.hasTransparentLogo ?? true });
|
|
592
|
+
debugLogger.info("Set hasTransparentLogo from CDN config (no user branding)");
|
|
593
|
+
} else {
|
|
594
|
+
debugLogger.info("Preserved user hasTransparentLogo setting (user branding exists)");
|
|
595
|
+
}
|
|
596
|
+
for (const model of allModels) {
|
|
597
|
+
await indexedDBService_default.put("banditConfig", 1, "config", { id: model.name, model }, storeConfigs);
|
|
598
|
+
}
|
|
599
|
+
debugLogger.info("Loaded and saved models from CDN config:", { models: allModels.map((m) => m.name) });
|
|
600
|
+
} else {
|
|
601
|
+
const preferences = usePreferencesStore.getState().preferences;
|
|
602
|
+
if (preferences.banditModelsEnabled) {
|
|
603
|
+
debugLogger.info("No CDN config available, loading Bandit defaults");
|
|
604
|
+
await get().restoreDefaultModels();
|
|
605
|
+
set({ isLoading: false, isInitializing: false });
|
|
606
|
+
return;
|
|
607
|
+
} else {
|
|
608
|
+
debugLogger.info("No CDN config available and Bandit personalities disabled, loading empty model list");
|
|
609
|
+
allModels = [];
|
|
610
|
+
selectedModel = "";
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
set({ availableModels: allModels });
|
|
615
|
+
debugLogger.info("Setting selected model:", { selectedModel });
|
|
616
|
+
get().setSelectedModel(selectedModel);
|
|
617
|
+
debugLogger.info("Model initialization complete");
|
|
618
|
+
set({ isLoading: false, isInitializing: false });
|
|
619
|
+
},
|
|
620
|
+
setHasTransparentLogo: (value) => set({ hasTransparentLogo: value }),
|
|
621
|
+
restoreDefaultModels: async () => {
|
|
622
|
+
debugLogger.debug("\u{1F9EA} Restoring default models...");
|
|
623
|
+
set({ isLoading: true });
|
|
624
|
+
const storeConfigs = [{ name: "config", keyPath: "id" }];
|
|
625
|
+
set({ availableModels: [] });
|
|
626
|
+
try {
|
|
627
|
+
await indexedDBService_default.delete("banditConfig", 1, "config", "deletedModels", storeConfigs);
|
|
628
|
+
debugLogger.info("restoreDefaultModels: Cleared deletedModels entry in IndexedDB");
|
|
629
|
+
} catch (err) {
|
|
630
|
+
debugLogger.warn("restoreDefaultModels: Failed to clear deletedModels entry in IndexedDB", { error: err });
|
|
631
|
+
}
|
|
632
|
+
let allModels = [];
|
|
633
|
+
let selectedModel = "";
|
|
634
|
+
const packageSettings = usePackageSettingsStore.getState().getSettings();
|
|
635
|
+
let configModels = null;
|
|
636
|
+
if (packageSettings?.brandingConfigUrl) {
|
|
637
|
+
debugLogger.debug("\u{1F517} Attempting to load default models from CDN config...");
|
|
638
|
+
try {
|
|
639
|
+
const response = await fetch(packageSettings.brandingConfigUrl);
|
|
640
|
+
configModels = await response.json();
|
|
641
|
+
} catch (err) {
|
|
642
|
+
debugLogger.warn("Failed to load CDN config:", { error: err });
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
if (configModels?.models?.length) {
|
|
646
|
+
allModels = configModels.models;
|
|
647
|
+
const preferences = usePreferencesStore.getState().preferences;
|
|
648
|
+
if (preferences.banditModelsEnabled) {
|
|
649
|
+
const cdnModelNames = allModels.map((m) => m.name);
|
|
650
|
+
const banditModelsToAdd = models.filter(
|
|
651
|
+
(banditModel) => !cdnModelNames.includes(banditModel.name)
|
|
652
|
+
);
|
|
653
|
+
allModels = [...allModels, ...banditModelsToAdd];
|
|
654
|
+
debugLogger.info("restoreDefaultModels: Added Bandit personalities to CDN config", {
|
|
655
|
+
banditModels: banditModelsToAdd.map((m) => m.name)
|
|
656
|
+
});
|
|
657
|
+
} else {
|
|
658
|
+
const banditModelNames = models.map((m) => m.name);
|
|
659
|
+
allModels = allModels.filter((model) => !banditModelNames.includes(model.name));
|
|
660
|
+
debugLogger.info("restoreDefaultModels: Filtered out Bandit personalities (preference disabled)", {
|
|
661
|
+
banditModels: banditModelNames
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
selectedModel = allModels.length > 0 ? allModels[0].name : "";
|
|
665
|
+
try {
|
|
666
|
+
const existingConfig = await indexedDBService_default.get("banditConfig", 1, "config", "main", storeConfigs);
|
|
667
|
+
const hasUserBranding = existingConfig?.branding?.userSaved;
|
|
668
|
+
if (!hasUserBranding) {
|
|
669
|
+
set({ hasTransparentLogo: configModels?.branding?.hasTransparentLogo ?? true });
|
|
670
|
+
debugLogger.info("restoreDefaultModels: Set hasTransparentLogo from CDN config (no user branding)");
|
|
671
|
+
} else {
|
|
672
|
+
debugLogger.info("restoreDefaultModels: Preserved user hasTransparentLogo setting (user branding exists)");
|
|
673
|
+
}
|
|
674
|
+
} catch (err) {
|
|
675
|
+
set({ hasTransparentLogo: configModels?.branding?.hasTransparentLogo ?? true });
|
|
676
|
+
debugLogger.warn("restoreDefaultModels: Using CDN hasTransparentLogo as fallback", { error: err });
|
|
677
|
+
}
|
|
678
|
+
debugLogger.info("\u2705 Using default models from CDN config:", { models: allModels.map((m) => m.name) });
|
|
679
|
+
} else {
|
|
680
|
+
const preferences = usePreferencesStore.getState().preferences;
|
|
681
|
+
if (preferences.banditModelsEnabled) {
|
|
682
|
+
allModels = models;
|
|
683
|
+
selectedModel = allModels.length > 0 ? allModels[0].name : "";
|
|
684
|
+
debugLogger.info("\u2705 Using built-in default Bandit personalities:", { models: allModels.map((m) => m.name) });
|
|
685
|
+
} else {
|
|
686
|
+
allModels = [];
|
|
687
|
+
selectedModel = "";
|
|
688
|
+
debugLogger.info("\u2705 Bandit personalities disabled, using empty model list");
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
for (const model of allModels) {
|
|
692
|
+
await indexedDBService_default.put("banditConfig", 1, "config", {
|
|
693
|
+
id: model.name,
|
|
694
|
+
model
|
|
695
|
+
}, storeConfigs);
|
|
696
|
+
}
|
|
697
|
+
set({ availableModels: allModels });
|
|
698
|
+
debugLogger.debug("\u{1F3AF} Setting default selected model:", { model: selectedModel });
|
|
699
|
+
get().setSelectedModel(selectedModel);
|
|
700
|
+
debugLogger.debug("\u2705 Default models restored and persisted to IndexedDB");
|
|
701
|
+
set({ isLoading: false });
|
|
702
|
+
},
|
|
703
|
+
restoreDeletedBanditModels: async () => {
|
|
704
|
+
debugLogger.debug("\u{1F504} Restoring deleted Bandit personalities...");
|
|
705
|
+
set({ isLoading: true });
|
|
706
|
+
const storeConfigs = [{ name: "config", keyPath: "id" }];
|
|
707
|
+
try {
|
|
708
|
+
const deletedEntry = await indexedDBService_default.get("banditConfig", 1, "config", "deletedModels", storeConfigs);
|
|
709
|
+
const deletedModelNames = deletedEntry?.deleted ?? [];
|
|
710
|
+
debugLogger.info("Current deleted models:", { deletedModelNames });
|
|
711
|
+
const deletedBanditModels = models.filter(
|
|
712
|
+
(banditModel) => deletedModelNames.includes(banditModel.name)
|
|
713
|
+
);
|
|
714
|
+
debugLogger.info("Deleted Bandit personalities found:", {
|
|
715
|
+
deletedBanditModels: deletedBanditModels.map((m) => m.name)
|
|
716
|
+
});
|
|
717
|
+
if (deletedBanditModels.length === 0) {
|
|
718
|
+
debugLogger.info("No deleted Bandit personalities to restore");
|
|
719
|
+
set({ isLoading: false });
|
|
720
|
+
return { restored: [], hadNothingToRestore: true };
|
|
721
|
+
}
|
|
722
|
+
const updatedDeletedNames = deletedModelNames.filter(
|
|
723
|
+
(name) => !models.some((banditModel) => banditModel.name === name)
|
|
724
|
+
);
|
|
725
|
+
debugLogger.info("Updated deleted list after removing Bandit personalities:", {
|
|
726
|
+
updatedDeletedNames
|
|
727
|
+
});
|
|
728
|
+
if (updatedDeletedNames.length > 0) {
|
|
729
|
+
await indexedDBService_default.put("banditConfig", 1, "config", {
|
|
730
|
+
id: "deletedModels",
|
|
731
|
+
deleted: updatedDeletedNames
|
|
732
|
+
}, storeConfigs);
|
|
733
|
+
debugLogger.info("Updated deletedModels in IndexedDB");
|
|
734
|
+
} else {
|
|
735
|
+
await indexedDBService_default.delete("banditConfig", 1, "config", "deletedModels", storeConfigs);
|
|
736
|
+
debugLogger.info("Removed deletedModels entry from IndexedDB (empty list)");
|
|
737
|
+
}
|
|
738
|
+
const preferences = usePreferencesStore.getState().preferences;
|
|
739
|
+
debugLogger.info("Bandit personalities preference enabled:", { enabled: preferences.banditModelsEnabled });
|
|
740
|
+
if (!preferences.banditModelsEnabled) {
|
|
741
|
+
debugLogger.info("\u26A0\uFE0F Bandit personalities preference is disabled. Personalities restored from deleted list but not added to available models until preference is enabled.");
|
|
742
|
+
set({ isLoading: false });
|
|
743
|
+
return { restored: deletedBanditModels.map((m) => m.name), hadNothingToRestore: false };
|
|
744
|
+
}
|
|
745
|
+
const currentModels = get().availableModels;
|
|
746
|
+
debugLogger.info("Current available models:", {
|
|
747
|
+
currentModels: currentModels.map((m) => m.name)
|
|
748
|
+
});
|
|
749
|
+
const restoredModels = deletedBanditModels.filter(
|
|
750
|
+
(banditModel) => !currentModels.some((current) => current.name === banditModel.name)
|
|
751
|
+
);
|
|
752
|
+
debugLogger.info("Models to restore:", {
|
|
753
|
+
restoredModels: restoredModels.map((m) => m.name)
|
|
754
|
+
});
|
|
755
|
+
if (restoredModels.length === 0) {
|
|
756
|
+
debugLogger.info("No new models to add (all restored models already present)");
|
|
757
|
+
set({ isLoading: false });
|
|
758
|
+
return { restored: [], hadNothingToRestore: true };
|
|
759
|
+
}
|
|
760
|
+
for (const model of restoredModels) {
|
|
761
|
+
await indexedDBService_default.put("banditConfig", 1, "config", {
|
|
762
|
+
id: model.name,
|
|
763
|
+
model
|
|
764
|
+
}, storeConfigs);
|
|
765
|
+
debugLogger.info("Persisted restored model to IndexedDB:", { modelName: model.name });
|
|
766
|
+
}
|
|
767
|
+
const updatedAvailableModels = [...currentModels, ...restoredModels];
|
|
768
|
+
set({ availableModels: updatedAvailableModels });
|
|
769
|
+
debugLogger.info("\u2705 Restored deleted Bandit personalities:", {
|
|
770
|
+
restoredModels: restoredModels.map((m) => m.name),
|
|
771
|
+
totalModels: updatedAvailableModels.length
|
|
772
|
+
});
|
|
773
|
+
const currentSelectedModel = get().selectedModel;
|
|
774
|
+
if (!currentSelectedModel && updatedAvailableModels.length > 0) {
|
|
775
|
+
const modelToSelect = restoredModels[0] || updatedAvailableModels[0];
|
|
776
|
+
get().setSelectedModel(modelToSelect.name);
|
|
777
|
+
debugLogger.info("Auto-selected model after restore:", { modelName: modelToSelect.name });
|
|
778
|
+
}
|
|
779
|
+
return { restored: restoredModels.map((m) => m.name), hadNothingToRestore: false };
|
|
780
|
+
} catch (error) {
|
|
781
|
+
debugLogger.error("Failed to restore deleted Bandit personalities", { error });
|
|
782
|
+
throw error;
|
|
783
|
+
} finally {
|
|
784
|
+
set({ isLoading: false });
|
|
785
|
+
}
|
|
786
|
+
},
|
|
787
|
+
handleBanditPersonalitiesPreferenceChange: async (enabled) => {
|
|
788
|
+
debugLogger.info("\u{1F504} Handling Bandit personalities preference change", { enabled });
|
|
789
|
+
const currentModels = get().availableModels;
|
|
790
|
+
const banditModelNames = models.map((m) => m.name);
|
|
791
|
+
if (enabled) {
|
|
792
|
+
const storeConfigs = [{ name: "config", keyPath: "id" }];
|
|
793
|
+
const deletedEntry = await indexedDBService_default.get("banditConfig", 1, "config", "deletedModels", storeConfigs);
|
|
794
|
+
const deletedModelNames = deletedEntry?.deleted ?? [];
|
|
795
|
+
const modelsToAdd = models.filter(
|
|
796
|
+
(banditModel) => !currentModels.some((current) => current.name === banditModel.name) && !deletedModelNames.includes(banditModel.name)
|
|
797
|
+
);
|
|
798
|
+
if (modelsToAdd.length > 0) {
|
|
799
|
+
for (const model of modelsToAdd) {
|
|
800
|
+
await indexedDBService_default.put("banditConfig", 1, "config", {
|
|
801
|
+
id: model.name,
|
|
802
|
+
model
|
|
803
|
+
}, storeConfigs);
|
|
804
|
+
}
|
|
805
|
+
const updatedModels = [...currentModels, ...modelsToAdd];
|
|
806
|
+
set({ availableModels: updatedModels });
|
|
807
|
+
debugLogger.info("\u2705 Added Bandit personalities", {
|
|
808
|
+
addedModels: modelsToAdd.map((m) => m.name)
|
|
809
|
+
});
|
|
810
|
+
const currentSelectedModel = get().selectedModel;
|
|
811
|
+
if (!currentSelectedModel && updatedModels.length > 0) {
|
|
812
|
+
get().setSelectedModel(updatedModels[0].name);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
} else {
|
|
816
|
+
const filteredModels = currentModels.filter((model) => !banditModelNames.includes(model.name));
|
|
817
|
+
set({ availableModels: filteredModels });
|
|
818
|
+
debugLogger.info("\u2705 Removed Bandit personalities", {
|
|
819
|
+
removedModels: banditModelNames.filter(
|
|
820
|
+
(name) => currentModels.some((model) => model.name === name)
|
|
821
|
+
)
|
|
822
|
+
});
|
|
823
|
+
const currentSelectedModel = get().selectedModel;
|
|
824
|
+
if (currentSelectedModel && banditModelNames.includes(currentSelectedModel)) {
|
|
825
|
+
const newSelectedModel = filteredModels.length > 0 ? filteredModels[0].name : "";
|
|
826
|
+
get().setSelectedModel(newSelectedModel);
|
|
827
|
+
debugLogger.info("\u{1F504} Changed selected model after removing Bandit personalities", {
|
|
828
|
+
oldModel: currentSelectedModel,
|
|
829
|
+
newModel: newSelectedModel
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
}));
|
|
835
|
+
|
|
836
|
+
export {
|
|
837
|
+
usePackageSettingsStore,
|
|
838
|
+
indexedDBService_default,
|
|
839
|
+
models,
|
|
840
|
+
usePreferencesStore,
|
|
841
|
+
useModelStore
|
|
842
|
+
};
|
|
843
|
+
//# sourceMappingURL=chunk-WYS5CZVG.mjs.map
|