@multiplayer-app/ai-agent-node 0.0.1

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.
Files changed (210) hide show
  1. package/.env.example +45 -0
  2. package/README.md +611 -0
  3. package/config.example.json +73 -0
  4. package/dist/config.d.ts +35 -0
  5. package/dist/config.d.ts.map +1 -0
  6. package/dist/config.js +44 -0
  7. package/dist/config.js.map +1 -0
  8. package/dist/helpers/AIHelper.d.ts +23 -0
  9. package/dist/helpers/AIHelper.d.ts.map +1 -0
  10. package/dist/helpers/AIHelper.js +326 -0
  11. package/dist/helpers/AIHelper.js.map +1 -0
  12. package/dist/helpers/AIHelper.test.d.ts +2 -0
  13. package/dist/helpers/AIHelper.test.d.ts.map +1 -0
  14. package/dist/helpers/AIHelper.test.js +332 -0
  15. package/dist/helpers/AIHelper.test.js.map +1 -0
  16. package/dist/helpers/ConfigHelper.d.ts +20 -0
  17. package/dist/helpers/ConfigHelper.d.ts.map +1 -0
  18. package/dist/helpers/ConfigHelper.js +118 -0
  19. package/dist/helpers/ConfigHelper.js.map +1 -0
  20. package/dist/helpers/ContextLimiter.d.ts +82 -0
  21. package/dist/helpers/ContextLimiter.d.ts.map +1 -0
  22. package/dist/helpers/ContextLimiter.js +165 -0
  23. package/dist/helpers/ContextLimiter.js.map +1 -0
  24. package/dist/helpers/FileHelper.d.ts +31 -0
  25. package/dist/helpers/FileHelper.d.ts.map +1 -0
  26. package/dist/helpers/FileHelper.js +175 -0
  27. package/dist/helpers/FileHelper.js.map +1 -0
  28. package/dist/helpers/SetupHelper.d.ts +5 -0
  29. package/dist/helpers/SetupHelper.d.ts.map +1 -0
  30. package/dist/helpers/SetupHelper.js +32 -0
  31. package/dist/helpers/SetupHelper.js.map +1 -0
  32. package/dist/helpers/index.d.ts +6 -0
  33. package/dist/helpers/index.d.ts.map +1 -0
  34. package/dist/helpers/index.js +6 -0
  35. package/dist/helpers/index.js.map +1 -0
  36. package/dist/index.d.ts +18 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +17 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/libs/index.d.ts +4 -0
  41. package/dist/libs/index.d.ts.map +1 -0
  42. package/dist/libs/index.js +4 -0
  43. package/dist/libs/index.js.map +1 -0
  44. package/dist/libs/kafka/config.d.ts +5 -0
  45. package/dist/libs/kafka/config.d.ts.map +1 -0
  46. package/dist/libs/kafka/config.js +5 -0
  47. package/dist/libs/kafka/config.js.map +1 -0
  48. package/dist/libs/kafka/consumer.d.ts +16 -0
  49. package/dist/libs/kafka/consumer.d.ts.map +1 -0
  50. package/dist/libs/kafka/consumer.js +126 -0
  51. package/dist/libs/kafka/consumer.js.map +1 -0
  52. package/dist/libs/kafka/index.d.ts +3 -0
  53. package/dist/libs/kafka/index.d.ts.map +1 -0
  54. package/dist/libs/kafka/index.js +3 -0
  55. package/dist/libs/kafka/index.js.map +1 -0
  56. package/dist/libs/kafka/kafka.d.ts +3 -0
  57. package/dist/libs/kafka/kafka.d.ts.map +1 -0
  58. package/dist/libs/kafka/kafka.js +24 -0
  59. package/dist/libs/kafka/kafka.js.map +1 -0
  60. package/dist/libs/kafka/producer.d.ts +11 -0
  61. package/dist/libs/kafka/producer.d.ts.map +1 -0
  62. package/dist/libs/kafka/producer.js +44 -0
  63. package/dist/libs/kafka/producer.js.map +1 -0
  64. package/dist/libs/logger/config.d.ts +5 -0
  65. package/dist/libs/logger/config.d.ts.map +1 -0
  66. package/dist/libs/logger/config.js +6 -0
  67. package/dist/libs/logger/config.js.map +1 -0
  68. package/dist/libs/logger/index.d.ts +10 -0
  69. package/dist/libs/logger/index.d.ts.map +1 -0
  70. package/dist/libs/logger/index.js +20 -0
  71. package/dist/libs/logger/index.js.map +1 -0
  72. package/dist/libs/logger/kafkajs-logger-creator.d.ts +12 -0
  73. package/dist/libs/logger/kafkajs-logger-creator.d.ts.map +1 -0
  74. package/dist/libs/logger/kafkajs-logger-creator.js +29 -0
  75. package/dist/libs/logger/kafkajs-logger-creator.js.map +1 -0
  76. package/dist/libs/logger/logger.d.ts +42 -0
  77. package/dist/libs/logger/logger.d.ts.map +1 -0
  78. package/dist/libs/logger/logger.js +44 -0
  79. package/dist/libs/logger/logger.js.map +1 -0
  80. package/dist/libs/s3/config.d.ts +7 -0
  81. package/dist/libs/s3/config.d.ts.map +1 -0
  82. package/dist/libs/s3/config.js +7 -0
  83. package/dist/libs/s3/config.js.map +1 -0
  84. package/dist/libs/s3/index.d.ts +4 -0
  85. package/dist/libs/s3/index.d.ts.map +1 -0
  86. package/dist/libs/s3/index.js +4 -0
  87. package/dist/libs/s3/index.js.map +1 -0
  88. package/dist/libs/s3/s3.lib.d.ts +25 -0
  89. package/dist/libs/s3/s3.lib.d.ts.map +1 -0
  90. package/dist/libs/s3/s3.lib.js +202 -0
  91. package/dist/libs/s3/s3.lib.js.map +1 -0
  92. package/dist/processors/ChatProcessor.d.ts +66 -0
  93. package/dist/processors/ChatProcessor.d.ts.map +1 -0
  94. package/dist/processors/ChatProcessor.js +610 -0
  95. package/dist/processors/ChatProcessor.js.map +1 -0
  96. package/dist/processors/ModelsProcessor.d.ts +11 -0
  97. package/dist/processors/ModelsProcessor.d.ts.map +1 -0
  98. package/dist/processors/ModelsProcessor.js +30 -0
  99. package/dist/processors/ModelsProcessor.js.map +1 -0
  100. package/dist/processors/index.d.ts +3 -0
  101. package/dist/processors/index.d.ts.map +1 -0
  102. package/dist/processors/index.js +3 -0
  103. package/dist/processors/index.js.map +1 -0
  104. package/dist/services/AIService.d.ts +48 -0
  105. package/dist/services/AIService.d.ts.map +1 -0
  106. package/dist/services/AIService.js +196 -0
  107. package/dist/services/AIService.js.map +1 -0
  108. package/dist/services/InternalEventsHandler.d.ts +21 -0
  109. package/dist/services/InternalEventsHandler.d.ts.map +1 -0
  110. package/dist/services/InternalEventsHandler.js +56 -0
  111. package/dist/services/InternalEventsHandler.js.map +1 -0
  112. package/dist/services/KafkaService.d.ts +35 -0
  113. package/dist/services/KafkaService.d.ts.map +1 -0
  114. package/dist/services/KafkaService.js +120 -0
  115. package/dist/services/KafkaService.js.map +1 -0
  116. package/dist/services/ModelFetcher.d.ts +54 -0
  117. package/dist/services/ModelFetcher.d.ts.map +1 -0
  118. package/dist/services/ModelFetcher.js +247 -0
  119. package/dist/services/ModelFetcher.js.map +1 -0
  120. package/dist/services/RedisService.d.ts +90 -0
  121. package/dist/services/RedisService.d.ts.map +1 -0
  122. package/dist/services/RedisService.js +236 -0
  123. package/dist/services/RedisService.js.map +1 -0
  124. package/dist/services/SocketService.d.ts +39 -0
  125. package/dist/services/SocketService.d.ts.map +1 -0
  126. package/dist/services/SocketService.js +128 -0
  127. package/dist/services/SocketService.js.map +1 -0
  128. package/dist/services/index.d.ts +7 -0
  129. package/dist/services/index.d.ts.map +1 -0
  130. package/dist/services/index.js +7 -0
  131. package/dist/services/index.js.map +1 -0
  132. package/dist/store/AgentStore.d.ts +48 -0
  133. package/dist/store/AgentStore.d.ts.map +1 -0
  134. package/dist/store/AgentStore.js +98 -0
  135. package/dist/store/AgentStore.js.map +1 -0
  136. package/dist/store/ArtifactStore.d.ts +13 -0
  137. package/dist/store/ArtifactStore.d.ts.map +1 -0
  138. package/dist/store/ArtifactStore.js +27 -0
  139. package/dist/store/ArtifactStore.js.map +1 -0
  140. package/dist/store/ConfigStore.d.ts +89 -0
  141. package/dist/store/ConfigStore.d.ts.map +1 -0
  142. package/dist/store/ConfigStore.js +214 -0
  143. package/dist/store/ConfigStore.js.map +1 -0
  144. package/dist/store/ConfigStore.test.d.ts +2 -0
  145. package/dist/store/ConfigStore.test.d.ts.map +1 -0
  146. package/dist/store/ConfigStore.test.js +259 -0
  147. package/dist/store/ConfigStore.test.js.map +1 -0
  148. package/dist/store/ModelStore.d.ts +44 -0
  149. package/dist/store/ModelStore.d.ts.map +1 -0
  150. package/dist/store/ModelStore.js +81 -0
  151. package/dist/store/ModelStore.js.map +1 -0
  152. package/dist/store/ModelStore.test.d.ts +2 -0
  153. package/dist/store/ModelStore.test.d.ts.map +1 -0
  154. package/dist/store/ModelStore.test.js +390 -0
  155. package/dist/store/ModelStore.test.js.map +1 -0
  156. package/dist/store/index.d.ts +5 -0
  157. package/dist/store/index.d.ts.map +1 -0
  158. package/dist/store/index.js +5 -0
  159. package/dist/store/index.js.map +1 -0
  160. package/dist/tools/generateChartTool.d.ts +24 -0
  161. package/dist/tools/generateChartTool.d.ts.map +1 -0
  162. package/dist/tools/generateChartTool.js +124 -0
  163. package/dist/tools/generateChartTool.js.map +1 -0
  164. package/dist/tools/proposeFormValuesTool.d.ts +35 -0
  165. package/dist/tools/proposeFormValuesTool.d.ts.map +1 -0
  166. package/dist/tools/proposeFormValuesTool.js +56 -0
  167. package/dist/tools/proposeFormValuesTool.js.map +1 -0
  168. package/package.json +71 -0
  169. package/src/config.ts +46 -0
  170. package/src/helpers/AIHelper.test.ts +375 -0
  171. package/src/helpers/AIHelper.ts +353 -0
  172. package/src/helpers/ConfigHelper.ts +130 -0
  173. package/src/helpers/ContextLimiter.ts +228 -0
  174. package/src/helpers/FileHelper.ts +197 -0
  175. package/src/helpers/SetupHelper.ts +35 -0
  176. package/src/helpers/index.ts +5 -0
  177. package/src/index.ts +18 -0
  178. package/src/libs/index.ts +3 -0
  179. package/src/libs/kafka/config.ts +4 -0
  180. package/src/libs/kafka/consumer.ts +161 -0
  181. package/src/libs/kafka/index.ts +2 -0
  182. package/src/libs/kafka/kafka.ts +27 -0
  183. package/src/libs/kafka/producer.ts +48 -0
  184. package/src/libs/logger/config.ts +4 -0
  185. package/src/libs/logger/index.ts +21 -0
  186. package/src/libs/logger/kafkajs-logger-creator.ts +28 -0
  187. package/src/libs/logger/logger.ts +60 -0
  188. package/src/libs/s3/config.ts +7 -0
  189. package/src/libs/s3/index.ts +3 -0
  190. package/src/libs/s3/s3.lib.ts +284 -0
  191. package/src/processors/ChatProcessor.ts +713 -0
  192. package/src/processors/ModelsProcessor.ts +34 -0
  193. package/src/processors/index.ts +2 -0
  194. package/src/services/AIService.ts +241 -0
  195. package/src/services/InternalEventsHandler.ts +61 -0
  196. package/src/services/KafkaService.ts +142 -0
  197. package/src/services/ModelFetcher.ts +286 -0
  198. package/src/services/RedisService.ts +285 -0
  199. package/src/services/SocketService.ts +153 -0
  200. package/src/services/index.ts +6 -0
  201. package/src/store/AgentStore.ts +138 -0
  202. package/src/store/ArtifactStore.ts +29 -0
  203. package/src/store/ConfigStore.test.ts +314 -0
  204. package/src/store/ConfigStore.ts +239 -0
  205. package/src/store/ModelStore.test.ts +473 -0
  206. package/src/store/ModelStore.ts +93 -0
  207. package/src/store/index.ts +4 -0
  208. package/src/tools/generateChartTool.ts +131 -0
  209. package/src/tools/proposeFormValuesTool.ts +67 -0
  210. package/tsconfig.json +24 -0
@@ -0,0 +1,214 @@
1
+ import { ConfigHelper } from '../helpers/ConfigHelper';
2
+ import { logger } from '../libs/logger';
3
+ import { config as appConfig } from '../config';
4
+ export class ConfigStore {
5
+ constructor() {
6
+ this.config = {};
7
+ this.allowedModels = [];
8
+ this.agentsMap = new Map();
9
+ this.defaultAgentConfig = {
10
+ name: '__default',
11
+ description: 'Default agent',
12
+ systemPrompt: 'You are a helpful agent that can answer questions and help with tasks.',
13
+ tools: [],
14
+ defaultModel: appConfig.ai.defaultModel,
15
+ };
16
+ }
17
+ /**
18
+ * Get the singleton instance of ConfigStore
19
+ */
20
+ static getInstance() {
21
+ if (!ConfigStore.instance) {
22
+ ConfigStore.instance = new ConfigStore();
23
+ }
24
+ return ConfigStore.instance;
25
+ }
26
+ /**
27
+ * Load the app config from a file path
28
+ * This method is idempotent - if config is already loaded, it returns the existing promise
29
+ * @param rawConfig - Raw config object (may include models array)
30
+ * @throws Error if config cannot be loaded
31
+ */
32
+ loadConfig(rawConfig) {
33
+ this.config = ConfigHelper.loadConfig(rawConfig);
34
+ this.allowedModels = Array.isArray(rawConfig.models) ? rawConfig.models : [];
35
+ for (const contextKey of Object.keys(this.config)) {
36
+ for (const agentConfig of this.config[contextKey]) {
37
+ this.agentsMap.set(agentConfig.name, agentConfig);
38
+ }
39
+ }
40
+ logger.info(`Successfully loaded config with ${this.getTotalAgentsCount()} agents across ${this.getContextKeys().length} contexts`);
41
+ }
42
+ addAllowedModelPattern(pattern) {
43
+ this.allowedModels.push(pattern);
44
+ }
45
+ addAgent(contextKeys, agentConfig) {
46
+ for (const contextKey of contextKeys) {
47
+ if (!this.config[contextKey]) {
48
+ this.config[contextKey] = [];
49
+ }
50
+ this.config[contextKey].push(agentConfig);
51
+ }
52
+ this.agentsMap.set(agentConfig.name, agentConfig);
53
+ }
54
+ /**
55
+ * Add a tool to every loaded agent (across all contexts).
56
+ * This is intended for built-in tools that should always be available.
57
+ * @param tool - The tool to add to all agents
58
+ */
59
+ addToolToAllAgents(tool) {
60
+ var _a, _b;
61
+ for (const agents of Object.values(this.config)) {
62
+ for (const agent of agents) {
63
+ const existing = (_a = agent.tools) !== null && _a !== void 0 ? _a : [];
64
+ const toolName = (_b = tool === null || tool === void 0 ? void 0 : tool.data) === null || _b === void 0 ? void 0 : _b.name;
65
+ const alreadyPresent = toolName
66
+ ? existing.some((t) => { var _a; return ((_a = t === null || t === void 0 ? void 0 : t.data) === null || _a === void 0 ? void 0 : _a.name) === toolName; })
67
+ : existing.some((t) => JSON.stringify(t) === JSON.stringify(tool));
68
+ if (!alreadyPresent) {
69
+ agent.tools = [...existing, tool];
70
+ }
71
+ }
72
+ }
73
+ }
74
+ getAgentConfigByName(agentName) {
75
+ if (!agentName) {
76
+ return this.defaultAgentConfig;
77
+ }
78
+ return this.agentsMap.get(agentName) || this.defaultAgentConfig;
79
+ }
80
+ /**
81
+ * Get all agents for a specific context key
82
+ * @param contextKey - The context key to get agents for
83
+ * @returns Array of AgentConfig for the context, or empty array if context not found
84
+ */
85
+ getAgentsForContext(contextKey) {
86
+ return this.config[contextKey] || [this.defaultAgentConfig];
87
+ }
88
+ /**
89
+ * Get a specific agent by name for a context
90
+ * @param contextKey - The context key
91
+ * @param agentName - The name of the agent
92
+ * @returns AgentConfig if found, undefined otherwise
93
+ */
94
+ getAgentForContext(contextKey, agentName) {
95
+ const agents = this.getAgentsForContext(contextKey);
96
+ return agents.find(agent => agent.name === agentName) || this.defaultAgentConfig;
97
+ }
98
+ /**
99
+ * Get all context keys
100
+ * @returns Array of context key strings
101
+ */
102
+ getContextKeys() {
103
+ if (!this.config) {
104
+ throw new Error('Config not loaded. Call loadConfig() first.');
105
+ }
106
+ return Object.keys(this.config);
107
+ }
108
+ /**
109
+ * Check if a context key exists
110
+ * @param contextKey - The context key to check
111
+ * @returns true if context exists, false otherwise
112
+ */
113
+ hasContext(contextKey) {
114
+ if (!this.config) {
115
+ return false;
116
+ }
117
+ return contextKey in this.config;
118
+ }
119
+ /**
120
+ * Get the total number of agents across all contexts
121
+ * @returns Total count of agents
122
+ */
123
+ getTotalAgentsCount() {
124
+ if (!this.config) {
125
+ return 0;
126
+ }
127
+ return Object.values(this.config).reduce((total, agents) => total + agents.length, 0);
128
+ }
129
+ /**
130
+ * Get all unique agent names across all contexts
131
+ * @returns Array of unique agent names
132
+ */
133
+ getAllAgentNames() {
134
+ if (!this.config) {
135
+ return [];
136
+ }
137
+ const agentNames = new Set();
138
+ for (const agents of Object.values(this.config)) {
139
+ for (const agent of agents) {
140
+ agentNames.add(agent.name);
141
+ }
142
+ }
143
+ return Array.from(agentNames);
144
+ }
145
+ /**
146
+ * Check if config has been loaded
147
+ * @returns true if config is loaded, false otherwise
148
+ */
149
+ isLoaded() {
150
+ return this.config !== null;
151
+ }
152
+ /**
153
+ * Check if a model is allowed based on the configured allowedModels patterns
154
+ * Patterns support wildcards (*) which match any sequence of characters
155
+ * - Patterns without a provider prefix (e.g., 'gpt-4') match the model ID across all providers
156
+ * - Patterns with a provider prefix (e.g., 'openai/gpt-4') only match that specific provider
157
+ * @param model - The model identifier to check (e.g., 'openai/gpt-4o', 'anthropic/claude-3-5-sonnet', 'gpt-4')
158
+ * @param provider - Optional provider name. If provided and model doesn't contain '/', constructs as 'provider/model'.
159
+ * For OpenRouter, the model should already contain the full path (e.g., 'openai/gpt-4')
160
+ * @returns true if model matches any allowed pattern, false otherwise
161
+ */
162
+ isModelAllowed(model, provider) {
163
+ if (this.allowedModels.length === 0) {
164
+ // If no allowedModels are configured, allow all models
165
+ return true;
166
+ }
167
+ // Construct the full model identifier if provider is provided
168
+ let modelToCheck;
169
+ if (provider && !model.includes('/')) {
170
+ // Provider provided and model doesn't have provider prefix - construct as 'provider/model'
171
+ modelToCheck = `${provider}/${model}`;
172
+ }
173
+ else {
174
+ // Use model as-is (either already has provider prefix or no provider provided)
175
+ modelToCheck = model;
176
+ }
177
+ // Check if model matches any of the allowed patterns
178
+ return this.allowedModels.some(pattern => {
179
+ const hasProvider = pattern.includes('/');
180
+ // Convert wildcard pattern to regex
181
+ // Escape special regex characters except *, then replace * with .*
182
+ const regexPattern = pattern
183
+ .replace(/[.+?^${}()|[\]\\]/g, '\\$&') // Escape special regex chars
184
+ .replace(/\*/g, '.*'); // Replace * with .*
185
+ if (hasProvider) {
186
+ // Pattern has provider prefix - match exactly
187
+ const regex = new RegExp(`^${regexPattern}$`);
188
+ return regex.test(modelToCheck);
189
+ }
190
+ else {
191
+ // Pattern has no provider prefix - match both exact and with any provider prefix
192
+ // Match: 'gpt-4' OR '*/gpt-4' OR 'provider/gpt-4'
193
+ const exactRegex = new RegExp(`^${regexPattern}$`);
194
+ const withProviderRegex = new RegExp(`^.*/${regexPattern}$`);
195
+ return exactRegex.test(modelToCheck) || withProviderRegex.test(modelToCheck);
196
+ }
197
+ });
198
+ }
199
+ /**
200
+ * Get the allowed model patterns
201
+ * @returns Array of allowed model patterns
202
+ */
203
+ getAllowedModels() {
204
+ return [...this.allowedModels];
205
+ }
206
+ /**
207
+ * Clear the loaded config (useful for testing or reloading)
208
+ */
209
+ clear() {
210
+ this.config = {};
211
+ this.allowedModels = [];
212
+ }
213
+ }
214
+ //# sourceMappingURL=ConfigStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigStore.js","sourceRoot":"","sources":["../../src/store/ConfigStore.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,WAAW,CAAC;AAEhD,MAAM,OAAO,WAAW;IActB;QAZQ,WAAM,GAAmB,EAAE,CAAC;QAC5B,kBAAa,GAAa,EAAE,CAAC;QAC7B,cAAS,GAA6B,IAAI,GAAG,EAAE,CAAC;QAGxC,uBAAkB,GAAgB;YAChD,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,eAAe;YAC5B,YAAY,EAAE,wEAAwE;YACtF,KAAK,EAAE,EAAE;YACT,YAAY,EAAE,SAAS,CAAC,EAAE,CAAC,YAAY;SACxC,CAAC;IACsB,CAAC;IAEzB;;OAEG;IACH,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;YAC1B,WAAW,CAAC,QAAQ,GAAG,IAAI,WAAW,EAAE,CAAC;QAC3C,CAAC;QACD,OAAO,WAAW,CAAC,QAAQ,CAAC;IAC9B,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,SAA8B;QACvC,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,KAAI,MAAM,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACjD,KAAI,MAAM,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;gBACjD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,mCAAmC,IAAI,CAAC,mBAAmB,EAAE,kBAAkB,IAAI,CAAC,cAAc,EAAE,CAAC,MAAM,WAAW,CAAC,CAAC;IACtI,CAAC;IACD,sBAAsB,CAAC,OAAe;QACpC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,QAAQ,CAAU,WAAqB,EAAE,WAA2B;QAClE,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC7B,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;YAC/B,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACpD,CAAC;IAED;;;;OAIG;IACH,kBAAkB,CAAC,IAAe;;QAChC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAChD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,MAAM,QAAQ,GAAG,MAAA,KAAK,CAAC,KAAK,mCAAI,EAAE,CAAC;gBACnC,MAAM,QAAQ,GAAG,MAAC,IAAY,aAAZ,IAAI,uBAAJ,IAAI,CAAU,IAAI,0CAAE,IAAI,CAAC;gBAC3C,MAAM,cAAc,GAClB,QAAQ;oBACN,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,WAAC,OAAA,CAAA,MAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,IAAI,0CAAE,IAAI,MAAK,QAAQ,CAAA,EAAA,CAAC;oBACvD,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC5E,IAAI,CAAC,cAAc,EAAE,CAAC;oBACpB,KAAK,CAAC,KAAK,GAAG,CAAC,GAAG,QAAQ,EAAE,IAAI,CAAQ,CAAC;gBAC3C,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAGD,oBAAoB,CAAC,SAA6B;QAChD,IAAG,CAAC,SAAS,EAAE,CAAC;YACd,OAAO,IAAI,CAAC,kBAAkB,CAAC;QACjC,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,kBAAkB,CAAC;IAClE,CAAC;IAED;;;;OAIG;IACH,mBAAmB,CAAC,UAAkB;QACpC,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC9D,CAAC;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,UAAkB,EAAE,SAAiB;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;QACpD,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,IAAI,CAAC,kBAAkB,CAAC;IACnF,CAAC;IAED;;;OAGG;IACH,cAAc;QACZ,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED;;;;OAIG;IACH,UAAU,CAAC,UAAkB;QAC3B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC;IACnC,CAAC;IAED;;;OAGG;IACH,mBAAmB;QACjB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,CAAC,CAAC;QACX,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACxF,CAAC;IAED;;;OAGG;IACH,gBAAgB;QACd,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QACrC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAChD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAChC,CAAC;IAED;;;OAGG;IACH,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC;IAC9B,CAAC;IAED;;;;;;;;;OASG;IACH,cAAc,CAAC,KAAa,EAAE,QAAiB;QAC7C,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,uDAAuD;YACvD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,8DAA8D;QAC9D,IAAI,YAAoB,CAAC;QACzB,IAAI,QAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACrC,2FAA2F;YAC3F,YAAY,GAAG,GAAG,QAAQ,IAAI,KAAK,EAAE,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,+EAA+E;YAC/E,YAAY,GAAG,KAAK,CAAC;QACvB,CAAC;QAED,qDAAqD;QACrD,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;YACvC,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAE1C,oCAAoC;YACpC,mEAAmE;YACnE,MAAM,YAAY,GAAG,OAAO;iBACzB,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC,6BAA6B;iBACnE,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,oBAAoB;YAE7C,IAAI,WAAW,EAAE,CAAC;gBAChB,8CAA8C;gBAC9C,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,YAAY,GAAG,CAAC,CAAC;gBAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAClC,CAAC;iBAAM,CAAC;gBACN,iFAAiF;gBACjF,kDAAkD;gBAClD,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,IAAI,YAAY,GAAG,CAAC,CAAC;gBACnD,MAAM,iBAAiB,GAAG,IAAI,MAAM,CAAC,OAAO,YAAY,GAAG,CAAC,CAAC;gBAC7D,OAAO,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC/E,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,gBAAgB;QACd,OAAO,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ConfigStore.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigStore.test.d.ts","sourceRoot":"","sources":["../../src/store/ConfigStore.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,259 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { ConfigStore } from './ConfigStore';
3
+ describe('ConfigStore', () => {
4
+ let configStore;
5
+ beforeEach(() => {
6
+ configStore = ConfigStore.getInstance();
7
+ configStore.clear();
8
+ });
9
+ describe('isModelAllowed', () => {
10
+ describe('when no allowedModels are configured', () => {
11
+ it('should allow all models', () => {
12
+ configStore.loadConfig({ agents: [] });
13
+ expect(configStore.isModelAllowed('openai/gpt-4o')).toBe(true);
14
+ expect(configStore.isModelAllowed('anthropic/claude-3-5-sonnet')).toBe(true);
15
+ expect(configStore.isModelAllowed('any-model')).toBe(true);
16
+ });
17
+ });
18
+ describe('wildcard patterns', () => {
19
+ it('should allow all models if no provider is specified', () => {
20
+ configStore.loadConfig({ agents: [], models: ['gpt-4'] });
21
+ expect(configStore.isModelAllowed('gpt-4')).toBe(true);
22
+ expect(configStore.isModelAllowed('openai/gpt-4')).toBe(true);
23
+ expect(configStore.isModelAllowed('anyprovider/gpt-4')).toBe(true);
24
+ });
25
+ it('should restrict by provider if it is specified', () => {
26
+ configStore.loadConfig({ agents: [], models: ['openai/gpt-4'] });
27
+ expect(configStore.isModelAllowed('gpt-4')).toBe(false);
28
+ expect(configStore.isModelAllowed('openai/gpt-4')).toBe(true);
29
+ expect(configStore.isModelAllowed('anyprovider/gpt-4')).toBe(false);
30
+ });
31
+ it('should use provider parameter when model id is provided separately', () => {
32
+ configStore.loadConfig({ agents: [], models: ['openai/gpt-4'] });
33
+ // When provider is provided and model doesn't have provider prefix, construct as 'provider/model'
34
+ expect(configStore.isModelAllowed('gpt-4', 'openai')).toBe(true);
35
+ expect(configStore.isModelAllowed('gpt-4', 'anthropic')).toBe(false);
36
+ // When model already has provider prefix, use it as-is (provider parameter is ignored)
37
+ expect(configStore.isModelAllowed('openai/gpt-4', 'openrouter')).toBe(true);
38
+ expect(configStore.isModelAllowed('openrouter/openai/gpt-4', 'openrouter')).toBe(false);
39
+ });
40
+ it('should handle OpenRouter provider with full model path in id', () => {
41
+ configStore.loadConfig({ agents: [], models: ['openai/gpt-4'] });
42
+ // For OpenRouter, the model id already contains the full path
43
+ expect(configStore.isModelAllowed('openai/gpt-4', 'openrouter')).toBe(true);
44
+ expect(configStore.isModelAllowed('anthropic/claude-3-5-sonnet', 'openrouter')).toBe(false);
45
+ });
46
+ it('should match patterns with wildcard at the end', () => {
47
+ configStore.loadConfig({
48
+ models: ['openai/gpt-4*'],
49
+ agents: []
50
+ });
51
+ expect(configStore.isModelAllowed('openai/gpt-4o')).toBe(true);
52
+ expect(configStore.isModelAllowed('openai/gpt-4-turbo')).toBe(true);
53
+ expect(configStore.isModelAllowed('openai/gpt-4')).toBe(true);
54
+ expect(configStore.isModelAllowed('openai/gpt-4o-mini')).toBe(true);
55
+ expect(configStore.isModelAllowed('openai/gpt-3.5-turbo')).toBe(false);
56
+ expect(configStore.isModelAllowed('anthropic/claude-3-5-sonnet')).toBe(false);
57
+ });
58
+ it('should match patterns with wildcard at the beginning', () => {
59
+ configStore.loadConfig({
60
+ models: ['*/gpt-4o'],
61
+ agents: []
62
+ });
63
+ expect(configStore.isModelAllowed('openai/gpt-4o')).toBe(true);
64
+ expect(configStore.isModelAllowed('openrouter/gpt-4o')).toBe(true);
65
+ expect(configStore.isModelAllowed('custom/gpt-4o')).toBe(true);
66
+ expect(configStore.isModelAllowed('openai/gpt-4-turbo')).toBe(false);
67
+ });
68
+ it('should match patterns with wildcard in the middle', () => {
69
+ configStore.loadConfig({
70
+ models: ['openai/gpt-*o'],
71
+ agents: []
72
+ });
73
+ expect(configStore.isModelAllowed('openai/gpt-4o')).toBe(true);
74
+ expect(configStore.isModelAllowed('openai/gpt-3.5-turbo')).toBe(true);
75
+ expect(configStore.isModelAllowed('openai/gpt-4-turbo')).toBe(true);
76
+ expect(configStore.isModelAllowed('openai/gpt-4')).toBe(false);
77
+ });
78
+ it('should match patterns with multiple wildcards', () => {
79
+ configStore.loadConfig({
80
+ models: ['openai/*-*'],
81
+ agents: []
82
+ });
83
+ expect(configStore.isModelAllowed('openai/gpt-4o')).toBe(true);
84
+ expect(configStore.isModelAllowed('openai/gpt-4-turbo')).toBe(true);
85
+ expect(configStore.isModelAllowed('openai/gpt4')).toBe(false);
86
+ });
87
+ it('should match provider wildcard patterns', () => {
88
+ configStore.loadConfig({
89
+ models: ['anthropic/*'],
90
+ agents: []
91
+ });
92
+ expect(configStore.isModelAllowed('anthropic/claude-3-5-sonnet')).toBe(true);
93
+ expect(configStore.isModelAllowed('anthropic/claude-3-opus')).toBe(true);
94
+ expect(configStore.isModelAllowed('anthropic/claude-2')).toBe(true);
95
+ expect(configStore.isModelAllowed('openai/gpt-4o')).toBe(false);
96
+ expect(configStore.isModelAllowed('openrouter/gpt-4o')).toBe(false);
97
+ });
98
+ it('should match openrouter wildcard patterns', () => {
99
+ configStore.loadConfig({
100
+ models: ['openrouter/*'],
101
+ agents: []
102
+ });
103
+ expect(configStore.isModelAllowed('openrouter/gpt-4o')).toBe(true);
104
+ expect(configStore.isModelAllowed('openrouter/claude-3-5-sonnet')).toBe(true);
105
+ expect(configStore.isModelAllowed('openrouter/any-model')).toBe(true);
106
+ expect(configStore.isModelAllowed('openai/gpt-4o')).toBe(false);
107
+ });
108
+ });
109
+ describe('exact matches', () => {
110
+ it('should match exact model identifiers', () => {
111
+ configStore.loadConfig({
112
+ models: ['openai/gpt-4o', 'anthropic/claude-3-5-sonnet'],
113
+ agents: []
114
+ });
115
+ expect(configStore.isModelAllowed('openai/gpt-4o')).toBe(true);
116
+ expect(configStore.isModelAllowed('anthropic/claude-3-5-sonnet')).toBe(true);
117
+ expect(configStore.isModelAllowed('openai/gpt-4-turbo')).toBe(false);
118
+ expect(configStore.isModelAllowed('anthropic/claude-3-opus')).toBe(false);
119
+ });
120
+ });
121
+ describe('multiple patterns', () => {
122
+ it('should allow models matching any pattern', () => {
123
+ configStore.loadConfig({
124
+ models: ['openai/gpt-4*', 'anthropic/*', 'openrouter/*'],
125
+ agents: []
126
+ });
127
+ expect(configStore.isModelAllowed('openai/gpt-4o')).toBe(true);
128
+ expect(configStore.isModelAllowed('openai/gpt-4-turbo')).toBe(true);
129
+ expect(configStore.isModelAllowed('anthropic/claude-3-5-sonnet')).toBe(true);
130
+ expect(configStore.isModelAllowed('openrouter/gpt-4o')).toBe(true);
131
+ expect(configStore.isModelAllowed('google/gemini-pro')).toBe(false);
132
+ });
133
+ it('should handle overlapping patterns correctly', () => {
134
+ configStore.loadConfig({
135
+ models: ['openai/*', 'openai/gpt-4*'],
136
+ agents: []
137
+ });
138
+ expect(configStore.isModelAllowed('openai/gpt-4o')).toBe(true);
139
+ expect(configStore.isModelAllowed('openai/gpt-3.5-turbo')).toBe(true);
140
+ expect(configStore.isModelAllowed('openai/davinci')).toBe(true);
141
+ });
142
+ });
143
+ describe('edge cases', () => {
144
+ it('should handle empty model string', () => {
145
+ configStore.loadConfig({
146
+ models: ['openai/*'],
147
+ agents: []
148
+ });
149
+ expect(configStore.isModelAllowed('')).toBe(false);
150
+ });
151
+ it('should handle patterns with special regex characters', () => {
152
+ configStore.loadConfig({
153
+ models: ['openai/gpt-4.5*', 'model.with.dots*'],
154
+ agents: []
155
+ });
156
+ expect(configStore.isModelAllowed('openai/gpt-4.5')).toBe(true);
157
+ expect(configStore.isModelAllowed('openai/gpt-4.5-turbo')).toBe(true);
158
+ expect(configStore.isModelAllowed('model.with.dots')).toBe(true);
159
+ expect(configStore.isModelAllowed('model.with.dots-v2')).toBe(true);
160
+ });
161
+ it('should escape special characters correctly', () => {
162
+ configStore.loadConfig({
163
+ models: ['model+plus*', 'model(version)*'],
164
+ agents: []
165
+ });
166
+ expect(configStore.isModelAllowed('model+plus')).toBe(true);
167
+ expect(configStore.isModelAllowed('model+plus-v2')).toBe(true);
168
+ expect(configStore.isModelAllowed('model(version)')).toBe(true);
169
+ expect(configStore.isModelAllowed('model(version)-v2')).toBe(true);
170
+ });
171
+ it('should handle patterns with question marks and other special chars', () => {
172
+ configStore.loadConfig({
173
+ models: ['model?test*'],
174
+ agents: []
175
+ });
176
+ expect(configStore.isModelAllowed('model?test')).toBe(true);
177
+ expect(configStore.isModelAllowed('model?test-v2')).toBe(true);
178
+ });
179
+ it('should handle patterns with brackets', () => {
180
+ configStore.loadConfig({
181
+ models: ['model[version]*'],
182
+ agents: []
183
+ });
184
+ expect(configStore.isModelAllowed('model[version]')).toBe(true);
185
+ expect(configStore.isModelAllowed('model[version]-v2')).toBe(true);
186
+ });
187
+ it('should handle patterns with dollar signs and caret', () => {
188
+ configStore.loadConfig({
189
+ models: ['model$test*', 'model^test*'],
190
+ agents: []
191
+ });
192
+ expect(configStore.isModelAllowed('model$test')).toBe(true);
193
+ expect(configStore.isModelAllowed('model$test-v2')).toBe(true);
194
+ expect(configStore.isModelAllowed('model^test')).toBe(true);
195
+ expect(configStore.isModelAllowed('model^test-v2')).toBe(true);
196
+ });
197
+ });
198
+ describe('real-world examples', () => {
199
+ it('should match examples from config.json', () => {
200
+ configStore.loadConfig({
201
+ models: ['openai/gpt-4*', 'anthropic/*'],
202
+ agents: []
203
+ });
204
+ // OpenAI GPT-4 variants
205
+ expect(configStore.isModelAllowed('openai/gpt-4o')).toBe(true);
206
+ expect(configStore.isModelAllowed('openai/gpt-4-turbo')).toBe(true);
207
+ expect(configStore.isModelAllowed('openai/gpt-4')).toBe(true);
208
+ expect(configStore.isModelAllowed('openai/gpt-4o-mini')).toBe(true);
209
+ // Anthropic models
210
+ expect(configStore.isModelAllowed('anthropic/claude-3-5-sonnet-20241022')).toBe(true);
211
+ expect(configStore.isModelAllowed('anthropic/claude-3-opus-20240229')).toBe(true);
212
+ expect(configStore.isModelAllowed('anthropic/claude-2.1')).toBe(true);
213
+ // Should not match
214
+ expect(configStore.isModelAllowed('openai/gpt-3.5-turbo')).toBe(false);
215
+ expect(configStore.isModelAllowed('google/gemini-pro')).toBe(false);
216
+ expect(configStore.isModelAllowed('openrouter/gpt-4o')).toBe(false);
217
+ });
218
+ it('should match openrouter pattern', () => {
219
+ configStore.loadConfig({
220
+ models: ['openrouter/*'],
221
+ agents: []
222
+ });
223
+ expect(configStore.isModelAllowed('openrouter/openai/gpt-4o')).toBe(true);
224
+ expect(configStore.isModelAllowed('openrouter/anthropic/claude-3-5-sonnet')).toBe(true);
225
+ expect(configStore.isModelAllowed('openrouter/meta-llama/llama-3-70b-instruct')).toBe(true);
226
+ });
227
+ });
228
+ describe('getAllowedModels', () => {
229
+ it('should return a copy of allowed models', () => {
230
+ const models = ['openai/gpt-4*', 'anthropic/*'];
231
+ configStore.loadConfig({
232
+ models,
233
+ agents: []
234
+ });
235
+ const allowed = configStore.getAllowedModels();
236
+ expect(allowed).toEqual(models);
237
+ expect(allowed).not.toBe(configStore.getAllowedModels()); // Should be a new array
238
+ });
239
+ it('should return empty array when no models configured', () => {
240
+ configStore.loadConfig({ agents: [] });
241
+ expect(configStore.getAllowedModels()).toEqual([]);
242
+ });
243
+ });
244
+ describe('clear method', () => {
245
+ it('should clear allowedModels when clear is called', () => {
246
+ configStore.loadConfig({
247
+ models: ['openai/gpt-4*'],
248
+ agents: []
249
+ });
250
+ expect(configStore.isModelAllowed('openai/gpt-4o')).toBe(true);
251
+ configStore.clear();
252
+ // After clear, should allow all (no patterns configured)
253
+ expect(configStore.isModelAllowed('openai/gpt-4o')).toBe(true);
254
+ expect(configStore.getAllowedModels()).toEqual([]);
255
+ });
256
+ });
257
+ });
258
+ });
259
+ //# sourceMappingURL=ConfigStore.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigStore.test.js","sourceRoot":"","sources":["../../src/store/ConfigStore.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,IAAI,WAAwB,CAAC;IAE7B,UAAU,CAAC,GAAG,EAAE;QACd,WAAW,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;QACxC,WAAW,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;YACpD,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;gBACjC,WAAW,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;gBAEvC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC7E,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7D,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;YACjC,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;gBAC7D,WAAW,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBAE1D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACvD,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC9D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrE,CAAC,CAAC,CAAC;YACH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;gBACxD,WAAW,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;gBAEjE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACxD,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC9D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtE,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;gBAC5E,WAAW,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;gBAEjE,kGAAkG;gBAClG,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAErE,uFAAuF;gBACvF,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC5E,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,yBAAyB,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1F,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;gBACtE,WAAW,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;gBAEjE,8DAA8D;gBAC9D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC5E,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,6BAA6B,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC9F,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;gBACxD,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,eAAe,CAAC;oBACzB,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACpE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC9D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACpE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACvE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChF,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;gBAC9D,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,UAAU,CAAC;oBACpB,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACnE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;gBAC3D,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,eAAe,CAAC;oBACzB,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACpE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACjE,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;gBACvD,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,YAAY,CAAC;oBACtB,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACpE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChE,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;gBACjD,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,aAAa,CAAC;oBACvB,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC7E,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,yBAAyB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACzE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACpE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAChE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtE,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;gBACnD,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,cAAc,CAAC;oBACxB,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACnE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,8BAA8B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC9E,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAClE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;YAC7B,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;gBAC9C,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,eAAe,EAAE,6BAA6B,CAAC;oBACxD,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC7E,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACrE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,yBAAyB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5E,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;YACjC,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;gBAClD,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,eAAe,EAAE,aAAa,EAAE,cAAc,CAAC;oBACxD,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACpE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC7E,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACnE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtE,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;gBACtD,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,UAAU,EAAE,eAAe,CAAC;oBACrC,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;YAC1B,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;gBAC1C,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,UAAU,CAAC;oBACpB,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;gBAC9D,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;oBAC/C,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtE,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;gBACpD,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,aAAa,EAAE,iBAAiB,CAAC;oBAC1C,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC5D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrE,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;gBAC5E,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,aAAa,CAAC;oBACvB,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC5D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjE,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;gBAC9C,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,iBAAiB,CAAC;oBAC3B,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrE,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;gBAC5D,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,aAAa,EAAE,aAAa,CAAC;oBACtC,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC5D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC5D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;YACnC,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;gBAChD,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,eAAe,EAAE,aAAa,CAAC;oBACxC,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,wBAAwB;gBACxB,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACpE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC9D,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAEpE,mBAAmB;gBACnB,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,sCAAsC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtF,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,kCAAkC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAClF,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAEtE,mBAAmB;gBACnB,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACvE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACpE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtE,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;gBACzC,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,cAAc,CAAC;oBACxB,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC1E,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,wCAAwC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACxF,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,4CAA4C,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9F,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;YAChC,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;gBAChD,MAAM,MAAM,GAAG,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;gBAChD,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM;oBACN,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,OAAO,GAAG,WAAW,CAAC,gBAAgB,EAAE,CAAC;gBAC/C,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAChC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,wBAAwB;YACpF,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;gBAC7D,WAAW,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;gBACvC,MAAM,CAAC,WAAW,CAAC,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAGH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;YAC5B,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;gBACzD,WAAW,CAAC,UAAU,CAAC;oBACrB,MAAM,EAAE,CAAC,eAAe,CAAC;oBACzB,MAAM,EAAE,EAAE;iBACX,CAAC,CAAC;gBAEH,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAE/D,WAAW,CAAC,KAAK,EAAE,CAAC;gBAEpB,yDAAyD;gBACzD,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/D,MAAM,CAAC,WAAW,CAAC,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,44 @@
1
+ import type { ModelOption } from '@multiplayer-app/ai-agent-types';
2
+ export declare class ModelStore {
3
+ private static instance;
4
+ private models;
5
+ private lastFetched;
6
+ private constructor();
7
+ /**
8
+ * Get the singleton instance of ModelStore
9
+ */
10
+ static getInstance(): ModelStore;
11
+ /**
12
+ * Set models in the store
13
+ */
14
+ setModels(models: ModelOption[]): void;
15
+ /**
16
+ * Get all models
17
+ */
18
+ getModels(): ModelOption[];
19
+ /**
20
+ * Get models by provider
21
+ */
22
+ getModelsByProvider(provider: string): ModelOption[];
23
+ /**
24
+ * Get a specific model by ID
25
+ */
26
+ getModelById(id: string): ModelOption | undefined;
27
+ /**
28
+ * Get all unique providers
29
+ */
30
+ getProviders(): string[];
31
+ /**
32
+ * Get when models were last fetched
33
+ */
34
+ getLastFetched(): Date | null;
35
+ /**
36
+ * Check if models have been loaded
37
+ */
38
+ hasModels(): boolean;
39
+ /**
40
+ * Clear all models
41
+ */
42
+ clear(): void;
43
+ }
44
+ //# sourceMappingURL=ModelStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModelStore.d.ts","sourceRoot":"","sources":["../../src/store/ModelStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAInE,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAa;IACpC,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,WAAW,CAAqB;IAExC,OAAO;IAEP;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,UAAU;IAOhC;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI;IAMtC;;OAEG;IACH,SAAS,IAAI,WAAW,EAAE;IAI1B;;OAEG;IACH,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE;IAIpD;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAWjD;;OAEG;IACH,YAAY,IAAI,MAAM,EAAE;IAUxB;;OAEG;IACH,cAAc,IAAI,IAAI,GAAG,IAAI;IAI7B;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,KAAK,IAAI,IAAI;CAId"}
@@ -0,0 +1,81 @@
1
+ import { logger } from '../libs/logger';
2
+ import { ConfigStore } from './ConfigStore';
3
+ export class ModelStore {
4
+ constructor() {
5
+ this.models = [];
6
+ this.lastFetched = null;
7
+ }
8
+ /**
9
+ * Get the singleton instance of ModelStore
10
+ */
11
+ static getInstance() {
12
+ if (!ModelStore.instance) {
13
+ ModelStore.instance = new ModelStore();
14
+ }
15
+ return ModelStore.instance;
16
+ }
17
+ /**
18
+ * Set models in the store
19
+ */
20
+ setModels(models) {
21
+ this.models = models.filter((model) => ConfigStore.getInstance().isModelAllowed(model.id, model.provider));
22
+ this.lastFetched = new Date();
23
+ logger.info(`Loaded ${models.length} models, available after filtering: ${this.models.length} from ${this.getProviders().length} providers`);
24
+ }
25
+ /**
26
+ * Get all models
27
+ */
28
+ getModels() {
29
+ return this.models;
30
+ }
31
+ /**
32
+ * Get models by provider
33
+ */
34
+ getModelsByProvider(provider) {
35
+ return this.models.filter((model) => model.provider === provider);
36
+ }
37
+ /**
38
+ * Get a specific model by ID
39
+ */
40
+ getModelById(id) {
41
+ const found = this.models.find((model) => model.id === id);
42
+ if (found) {
43
+ return found;
44
+ }
45
+ const idData = id.split('/', 2);
46
+ const modelName = idData[idData.length - 1];
47
+ return this.models.find((model) => model.id.endsWith(modelName));
48
+ }
49
+ /**
50
+ * Get all unique providers
51
+ */
52
+ getProviders() {
53
+ const providers = new Set();
54
+ for (const model of this.models) {
55
+ if (model.provider) {
56
+ providers.add(model.provider);
57
+ }
58
+ }
59
+ return Array.from(providers);
60
+ }
61
+ /**
62
+ * Get when models were last fetched
63
+ */
64
+ getLastFetched() {
65
+ return this.lastFetched;
66
+ }
67
+ /**
68
+ * Check if models have been loaded
69
+ */
70
+ hasModels() {
71
+ return this.models.length > 0;
72
+ }
73
+ /**
74
+ * Clear all models
75
+ */
76
+ clear() {
77
+ this.models = [];
78
+ this.lastFetched = null;
79
+ }
80
+ }
81
+ //# sourceMappingURL=ModelStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModelStore.js","sourceRoot":"","sources":["../../src/store/ModelStore.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,OAAO,UAAU;IAKrB;QAHQ,WAAM,GAAkB,EAAE,CAAC;QAC3B,gBAAW,GAAgB,IAAI,CAAC;IAEjB,CAAC;IAExB;;OAEG;IACH,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;YACzB,UAAU,CAAC,QAAQ,GAAG,IAAI,UAAU,EAAE,CAAC;QACzC,CAAC;QACD,OAAO,UAAU,CAAC,QAAQ,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,MAAqB;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC3G,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,UAAU,MAAM,CAAC,MAAM,uCAAuC,IAAI,CAAC,MAAM,CAAC,MAAM,SAAS,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,YAAY,CAAC,CAAC;IAC/I,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,mBAAmB,CAAC,QAAgB;QAClC,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;IACpE,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,EAAU;QACrB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAE3D,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IACnE,CAAC;IAED;;OAEG;IACH,YAAY;QACV,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;QACpC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACnB,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ModelStore.test.d.ts.map