@loxia-labs/loxia-autopilot-one 1.0.1 → 1.0.4

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 (120) hide show
  1. package/README.md +44 -54
  2. package/bin/cli.js +1 -115
  3. package/bin/loxia-terminal-v2.js +3 -0
  4. package/bin/loxia-terminal.js +3 -0
  5. package/bin/start-with-terminal.js +3 -0
  6. package/package.json +15 -15
  7. package/scripts/install-scanners.js +1 -235
  8. package/src/analyzers/CSSAnalyzer.js +1 -297
  9. package/src/analyzers/ConfigValidator.js +1 -690
  10. package/src/analyzers/ESLintAnalyzer.js +1 -320
  11. package/src/analyzers/JavaScriptAnalyzer.js +1 -261
  12. package/src/analyzers/PrettierFormatter.js +1 -247
  13. package/src/analyzers/PythonAnalyzer.js +1 -266
  14. package/src/analyzers/SecurityAnalyzer.js +1 -729
  15. package/src/analyzers/TypeScriptAnalyzer.js +1 -247
  16. package/src/analyzers/codeCloneDetector/analyzer.js +1 -344
  17. package/src/analyzers/codeCloneDetector/detector.js +1 -203
  18. package/src/analyzers/codeCloneDetector/index.js +1 -160
  19. package/src/analyzers/codeCloneDetector/parser.js +1 -199
  20. package/src/analyzers/codeCloneDetector/reporter.js +1 -148
  21. package/src/analyzers/codeCloneDetector/scanner.js +1 -59
  22. package/src/core/agentPool.js +1 -1474
  23. package/src/core/agentScheduler.js +1 -2147
  24. package/src/core/contextManager.js +1 -709
  25. package/src/core/messageProcessor.js +1 -732
  26. package/src/core/orchestrator.js +1 -548
  27. package/src/core/stateManager.js +1 -877
  28. package/src/index.js +1 -631
  29. package/src/interfaces/cli.js +1 -549
  30. package/src/interfaces/terminal/__tests__/smoke/advancedFeatures.test.js +1 -0
  31. package/src/interfaces/terminal/__tests__/smoke/agentControl.test.js +1 -0
  32. package/src/interfaces/terminal/__tests__/smoke/agents.test.js +1 -0
  33. package/src/interfaces/terminal/__tests__/smoke/components.test.js +1 -0
  34. package/src/interfaces/terminal/__tests__/smoke/connection.test.js +1 -0
  35. package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +1 -0
  36. package/src/interfaces/terminal/__tests__/smoke/imports.test.js +1 -0
  37. package/src/interfaces/terminal/__tests__/smoke/messages.test.js +1 -0
  38. package/src/interfaces/terminal/__tests__/smoke/tools.test.js +1 -0
  39. package/src/interfaces/terminal/api/apiClient.js +1 -0
  40. package/src/interfaces/terminal/api/messageRouter.js +1 -0
  41. package/src/interfaces/terminal/api/session.js +1 -0
  42. package/src/interfaces/terminal/api/websocket.js +1 -0
  43. package/src/interfaces/terminal/components/AgentCreator.js +1 -0
  44. package/src/interfaces/terminal/components/AgentEditor.js +1 -0
  45. package/src/interfaces/terminal/components/AgentSwitcher.js +1 -0
  46. package/src/interfaces/terminal/components/ErrorBoundary.js +1 -0
  47. package/src/interfaces/terminal/components/ErrorPanel.js +1 -0
  48. package/src/interfaces/terminal/components/Header.js +1 -0
  49. package/src/interfaces/terminal/components/HelpPanel.js +1 -0
  50. package/src/interfaces/terminal/components/InputBox.js +1 -0
  51. package/src/interfaces/terminal/components/Layout.js +1 -0
  52. package/src/interfaces/terminal/components/LoadingSpinner.js +1 -0
  53. package/src/interfaces/terminal/components/MessageList.js +1 -0
  54. package/src/interfaces/terminal/components/MultilineTextInput.js +1 -0
  55. package/src/interfaces/terminal/components/SearchPanel.js +1 -0
  56. package/src/interfaces/terminal/components/SettingsPanel.js +1 -0
  57. package/src/interfaces/terminal/components/StatusBar.js +1 -0
  58. package/src/interfaces/terminal/components/TextInput.js +1 -0
  59. package/src/interfaces/terminal/config/agentEditorConstants.js +1 -0
  60. package/src/interfaces/terminal/config/constants.js +1 -0
  61. package/src/interfaces/terminal/index.js +1 -0
  62. package/src/interfaces/terminal/state/useAgentControl.js +1 -0
  63. package/src/interfaces/terminal/state/useAgents.js +1 -0
  64. package/src/interfaces/terminal/state/useConnection.js +1 -0
  65. package/src/interfaces/terminal/state/useMessages.js +1 -0
  66. package/src/interfaces/terminal/state/useTools.js +1 -0
  67. package/src/interfaces/terminal/utils/debugLogger.js +1 -0
  68. package/src/interfaces/terminal/utils/settingsStorage.js +1 -0
  69. package/src/interfaces/terminal/utils/theme.js +1 -0
  70. package/src/interfaces/webServer.js +1 -2162
  71. package/src/modules/fileExplorer/controller.js +1 -280
  72. package/src/modules/fileExplorer/index.js +1 -37
  73. package/src/modules/fileExplorer/middleware.js +1 -92
  74. package/src/modules/fileExplorer/routes.js +1 -125
  75. package/src/modules/fileExplorer/types.js +1 -44
  76. package/src/services/aiService.js +1 -1232
  77. package/src/services/apiKeyManager.js +1 -164
  78. package/src/services/benchmarkService.js +1 -366
  79. package/src/services/budgetService.js +1 -539
  80. package/src/services/contextInjectionService.js +1 -247
  81. package/src/services/conversationCompactionService.js +1 -637
  82. package/src/services/errorHandler.js +1 -810
  83. package/src/services/fileAttachmentService.js +1 -544
  84. package/src/services/modelRouterService.js +1 -366
  85. package/src/services/modelsService.js +1 -322
  86. package/src/services/qualityInspector.js +1 -796
  87. package/src/services/tokenCountingService.js +1 -536
  88. package/src/tools/agentCommunicationTool.js +1 -1344
  89. package/src/tools/agentDelayTool.js +1 -485
  90. package/src/tools/asyncToolManager.js +1 -604
  91. package/src/tools/baseTool.js +1 -800
  92. package/src/tools/browserTool.js +1 -920
  93. package/src/tools/cloneDetectionTool.js +1 -621
  94. package/src/tools/dependencyResolverTool.js +1 -1215
  95. package/src/tools/fileContentReplaceTool.js +1 -875
  96. package/src/tools/fileSystemTool.js +1 -1107
  97. package/src/tools/fileTreeTool.js +1 -853
  98. package/src/tools/imageTool.js +1 -901
  99. package/src/tools/importAnalyzerTool.js +1 -1060
  100. package/src/tools/jobDoneTool.js +1 -248
  101. package/src/tools/seekTool.js +1 -956
  102. package/src/tools/staticAnalysisTool.js +1 -1778
  103. package/src/tools/taskManagerTool.js +1 -2873
  104. package/src/tools/terminalTool.js +1 -2304
  105. package/src/tools/webTool.js +1 -1430
  106. package/src/types/agent.js +1 -519
  107. package/src/types/contextReference.js +1 -972
  108. package/src/types/conversation.js +1 -730
  109. package/src/types/toolCommand.js +1 -747
  110. package/src/utilities/attachmentValidator.js +1 -292
  111. package/src/utilities/configManager.js +1 -582
  112. package/src/utilities/constants.js +1 -722
  113. package/src/utilities/directoryAccessManager.js +1 -535
  114. package/src/utilities/fileProcessor.js +1 -307
  115. package/src/utilities/logger.js +1 -436
  116. package/src/utilities/tagParser.js +1 -1246
  117. package/src/utilities/toolConstants.js +1 -317
  118. package/web-ui/build/index.html +2 -2
  119. package/web-ui/build/static/{index-Dy2bYbOa.css → index-CClD1090.css} +1 -1
  120. package/web-ui/build/static/{index-CjkkcnFA.js → index-lCBai6dX.js} +66 -67
@@ -1,582 +1 @@
1
- /**
2
- * ConfigManager - Centralized configuration management for the Loxia AI Agents System
3
- *
4
- * Purpose:
5
- * - Load and merge configuration from multiple sources
6
- * - Environment variable support
7
- * - Configuration validation
8
- * - Runtime configuration updates
9
- * - Default configuration management
10
- */
11
-
12
- import { promises as fs } from 'fs';
13
- import path from 'path';
14
-
15
- import {
16
- SYSTEM_DEFAULTS,
17
- MODELS,
18
- MODEL_ROUTING,
19
- TOOL_NAMES,
20
- STATE_DIRECTORIES,
21
- ERROR_TYPES
22
- } from './constants.js';
23
-
24
- class ConfigManager {
25
- constructor(options = {}) {
26
- this.configPaths = options.configPaths || [];
27
- this.envPrefix = options.envPrefix || 'LOXIA';
28
- this.config = {};
29
- this.watchers = new Map();
30
- this.changeListeners = new Set();
31
-
32
- // Default configuration
33
- this.defaultConfig = this.getDefaultConfig();
34
- }
35
-
36
- /**
37
- * Load configuration from all sources
38
- * @returns {Promise<Object>} Loaded configuration
39
- */
40
- async loadConfig() {
41
- let config = { ...this.defaultConfig };
42
-
43
- // Load from config files
44
- for (const configPath of this.configPaths) {
45
- try {
46
- const fileConfig = await this.loadConfigFile(configPath);
47
- config = this.mergeConfig(config, fileConfig);
48
- } catch (error) {
49
- console.warn(`Failed to load config file ${configPath}:`, error.message);
50
- }
51
- }
52
-
53
- // Override with environment variables
54
- const envConfig = this.loadEnvironmentConfig();
55
- config = this.mergeConfig(config, envConfig);
56
-
57
- // Validate configuration
58
- const validation = this.validateConfig(config);
59
- if (!validation.valid) {
60
- throw new Error(`Configuration validation failed: ${validation.errors.join(', ')}`);
61
- }
62
-
63
- // Apply configuration transformations
64
- config = this.transformConfig(config);
65
-
66
- this.config = config;
67
-
68
- // Notify listeners of config change
69
- this.notifyConfigChange(config);
70
-
71
- return config;
72
- }
73
-
74
- /**
75
- * Get current configuration
76
- * @returns {Object} Current configuration
77
- */
78
- getConfig() {
79
- return { ...this.config };
80
- }
81
-
82
- /**
83
- * Get configuration value by path
84
- * @param {string} path - Configuration path (e.g., 'system.maxAgentsPerProject')
85
- * @param {*} defaultValue - Default value if path not found
86
- * @returns {*} Configuration value
87
- */
88
- get(path, defaultValue = undefined) {
89
- const keys = path.split('.');
90
- let value = this.config;
91
-
92
- for (const key of keys) {
93
- if (value && typeof value === 'object' && key in value) {
94
- value = value[key];
95
- } else {
96
- return defaultValue;
97
- }
98
- }
99
-
100
- return value;
101
- }
102
-
103
- /**
104
- * Set configuration value by path
105
- * @param {string} path - Configuration path
106
- * @param {*} value - Value to set
107
- */
108
- set(path, value) {
109
- const keys = path.split('.');
110
- const lastKey = keys.pop();
111
- let target = this.config;
112
-
113
- // Navigate to parent object
114
- for (const key of keys) {
115
- if (!(key in target) || typeof target[key] !== 'object') {
116
- target[key] = {};
117
- }
118
- target = target[key];
119
- }
120
-
121
- target[lastKey] = value;
122
-
123
- // Notify listeners of config change
124
- this.notifyConfigChange(this.config);
125
- }
126
-
127
- /**
128
- * Watch configuration files for changes
129
- * @param {boolean} enable - Enable or disable watching
130
- * @returns {Promise<void>}
131
- */
132
- async watchConfig(enable = true) {
133
- if (!enable) {
134
- // Stop all watchers
135
- for (const [filePath, watcher] of this.watchers) {
136
- watcher.close();
137
- this.watchers.delete(filePath);
138
- }
139
- return;
140
- }
141
-
142
- // Start watching config files
143
- for (const configPath of this.configPaths) {
144
- if (this.watchers.has(configPath)) continue;
145
-
146
- try {
147
- const { watch } = await import('fs');
148
- const watcher = watch(configPath, async (eventType) => {
149
- if (eventType === 'change') {
150
- try {
151
- await this.loadConfig();
152
- } catch (error) {
153
- console.error(`Failed to reload config after change in ${configPath}:`, error.message);
154
- }
155
- }
156
- });
157
-
158
- this.watchers.set(configPath, watcher);
159
- } catch (error) {
160
- console.warn(`Failed to watch config file ${configPath}:`, error.message);
161
- }
162
- }
163
- }
164
-
165
- /**
166
- * Add configuration change listener
167
- * @param {Function} listener - Change listener function
168
- */
169
- addChangeListener(listener) {
170
- this.changeListeners.add(listener);
171
- }
172
-
173
- /**
174
- * Remove configuration change listener
175
- * @param {Function} listener - Change listener function
176
- */
177
- removeChangeListener(listener) {
178
- this.changeListeners.delete(listener);
179
- }
180
-
181
- /**
182
- * Load configuration from file
183
- * @private
184
- */
185
- async loadConfigFile(filePath) {
186
- try {
187
- const content = await fs.readFile(filePath, 'utf8');
188
-
189
- const ext = path.extname(filePath).toLowerCase();
190
- switch (ext) {
191
- case '.json':
192
- return JSON.parse(content);
193
-
194
- case '.js':
195
- // For .js files, use dynamic import
196
- const fullPath = path.resolve(filePath);
197
- const module = await import(fullPath);
198
- return module.default || module;
199
-
200
- case '.yaml':
201
- case '.yml':
202
- // Would need yaml parser dependency
203
- throw new Error('YAML configuration files not supported in this implementation');
204
-
205
- default:
206
- throw new Error(`Unsupported configuration file format: ${ext}`);
207
- }
208
- } catch (error) {
209
- throw new Error(`Failed to load config file ${filePath}: ${error.message}`);
210
- }
211
- }
212
-
213
- /**
214
- * Load configuration from environment variables
215
- * @private
216
- */
217
- loadEnvironmentConfig() {
218
- const envConfig = {};
219
-
220
- // Map environment variables to config paths
221
- const envMappings = {
222
- [`${this.envPrefix}_API_KEY`]: 'apiKey',
223
- [`${this.envPrefix}_LOG_LEVEL`]: 'logging.level',
224
- [`${this.envPrefix}_MAX_AGENTS`]: 'system.maxAgentsPerProject',
225
- [`${this.envPrefix}_DEFAULT_MODEL`]: 'system.defaultModel',
226
- [`${this.envPrefix}_BACKEND_URL`]: 'backend.baseUrl',
227
- [`${this.envPrefix}_BACKEND_TIMEOUT`]: 'backend.timeout',
228
- [`${this.envPrefix}_STATE_DIR`]: 'system.stateDirectory',
229
- [`${this.envPrefix}_BUDGET_LIMIT`]: 'budget.limit',
230
- [`${this.envPrefix}_TOOLS_ENABLED`]: 'tools.enabled'
231
- };
232
-
233
- for (const [envVar, configPath] of Object.entries(envMappings)) {
234
- const value = process.env[envVar];
235
- if (value !== undefined) {
236
- this.setNestedValue(envConfig, configPath, this.parseEnvValue(value));
237
- }
238
- }
239
-
240
- return envConfig;
241
- }
242
-
243
- /**
244
- * Parse environment variable value
245
- * @private
246
- */
247
- parseEnvValue(value) {
248
- // Try to parse as JSON first
249
- try {
250
- return JSON.parse(value);
251
- } catch {
252
- // Return as string if not valid JSON
253
- return value;
254
- }
255
- }
256
-
257
- /**
258
- * Set nested object value by path
259
- * @private
260
- */
261
- setNestedValue(obj, path, value) {
262
- const keys = path.split('.');
263
- const lastKey = keys.pop();
264
- let target = obj;
265
-
266
- for (const key of keys) {
267
- if (!(key in target)) {
268
- target[key] = {};
269
- }
270
- target = target[key];
271
- }
272
-
273
- target[lastKey] = value;
274
- }
275
-
276
- /**
277
- * Merge configuration objects
278
- * @private
279
- */
280
- mergeConfig(base, override) {
281
- const result = { ...base };
282
-
283
- for (const [key, value] of Object.entries(override)) {
284
- if (value && typeof value === 'object' && !Array.isArray(value)) {
285
- result[key] = this.mergeConfig(result[key] || {}, value);
286
- } else {
287
- result[key] = value;
288
- }
289
- }
290
-
291
- return result;
292
- }
293
-
294
- /**
295
- * Validate configuration
296
- * @private
297
- */
298
- validateConfig(config) {
299
- const errors = [];
300
-
301
- // Validate system configuration
302
- if (config.system) {
303
- const { maxAgentsPerProject, defaultModel, stateDirectory } = config.system;
304
-
305
- if (maxAgentsPerProject && (typeof maxAgentsPerProject !== 'number' || maxAgentsPerProject < 1)) {
306
- errors.push('system.maxAgentsPerProject must be a positive number');
307
- }
308
-
309
- if (defaultModel && !Object.values(MODELS).includes(defaultModel)) {
310
- errors.push(`system.defaultModel must be one of: ${Object.values(MODELS).join(', ')}`);
311
- }
312
-
313
- if (stateDirectory && typeof stateDirectory !== 'string') {
314
- errors.push('system.stateDirectory must be a string');
315
- }
316
- }
317
-
318
- // Validate backend configuration
319
- if (config.backend) {
320
- const { baseUrl, timeout, retryAttempts } = config.backend;
321
-
322
- if (baseUrl && typeof baseUrl !== 'string') {
323
- errors.push('backend.baseUrl must be a string');
324
- }
325
-
326
- if (timeout && (typeof timeout !== 'number' || timeout < 1000)) {
327
- errors.push('backend.timeout must be a number >= 1000');
328
- }
329
-
330
- if (retryAttempts && (typeof retryAttempts !== 'number' || retryAttempts < 0)) {
331
- errors.push('backend.retryAttempts must be a non-negative number');
332
- }
333
- }
334
-
335
- // Validate tool configuration
336
- if (config.tools) {
337
- for (const [toolName, toolConfig] of Object.entries(config.tools)) {
338
- if (toolConfig && typeof toolConfig !== 'object') {
339
- errors.push(`tools.${toolName} must be an object`);
340
- }
341
-
342
- if (toolConfig?.timeout && (typeof toolConfig.timeout !== 'number' || toolConfig.timeout < 1000)) {
343
- errors.push(`tools.${toolName}.timeout must be a number >= 1000`);
344
- }
345
- }
346
- }
347
-
348
- // Validate model routing
349
- if (config.models?.routingTable) {
350
- const routingTable = config.models.routingTable;
351
-
352
- for (const [task, models] of Object.entries(routingTable)) {
353
- if (!Array.isArray(models)) {
354
- errors.push(`models.routingTable.${task} must be an array`);
355
- continue;
356
- }
357
-
358
- for (const model of models) {
359
- if (!Object.values(MODELS).includes(model)) {
360
- errors.push(`Invalid model in routing table: ${model}`);
361
- }
362
- }
363
- }
364
- }
365
-
366
- return {
367
- valid: errors.length === 0,
368
- errors
369
- };
370
- }
371
-
372
- /**
373
- * Transform configuration after loading
374
- * @private
375
- */
376
- transformConfig(config) {
377
- // Ensure required nested objects exist
378
- if (!config.system) config.system = {};
379
- if (!config.backend) config.backend = {};
380
- if (!config.tools) config.tools = {};
381
- if (!config.models) config.models = {};
382
- if (!config.context) config.context = {};
383
- if (!config.logging) config.logging = {};
384
-
385
- // Apply defaults for missing values
386
- config.system.maxAgentsPerProject = config.system.maxAgentsPerProject || SYSTEM_DEFAULTS.MAX_AGENTS_PER_PROJECT;
387
- config.system.defaultModel = config.system.defaultModel || SYSTEM_DEFAULTS.DEFAULT_MODEL;
388
- config.system.stateDirectory = config.system.stateDirectory || SYSTEM_DEFAULTS.STATE_DIRECTORY;
389
- config.system.maxPauseDuration = config.system.maxPauseDuration || SYSTEM_DEFAULTS.MAX_PAUSE_DURATION;
390
-
391
- config.context.maxSize = config.context.maxSize || SYSTEM_DEFAULTS.MAX_CONTEXT_SIZE;
392
- config.context.maxReferences = config.context.maxReferences || SYSTEM_DEFAULTS.MAX_CONTEXT_REFERENCES;
393
- config.context.autoValidation = config.context.autoValidation !== false;
394
- config.context.cacheExpiry = config.context.cacheExpiry || SYSTEM_DEFAULTS.CACHE_EXPIRY;
395
-
396
- // Ensure model routing table exists
397
- if (!config.models.routingTable) {
398
- config.models.routingTable = { ...MODEL_ROUTING };
399
- }
400
-
401
- // Ensure essential tools are configured
402
- for (const toolName of Object.values(TOOL_NAMES)) {
403
- if (!config.tools[toolName]) {
404
- config.tools[toolName] = {
405
- enabled: true,
406
- timeout: SYSTEM_DEFAULTS.MAX_TOOL_EXECUTION_TIME
407
- };
408
- }
409
- }
410
-
411
- return config;
412
- }
413
-
414
- /**
415
- * Notify configuration change listeners
416
- * @private
417
- */
418
- notifyConfigChange(config) {
419
- for (const listener of this.changeListeners) {
420
- try {
421
- listener(config);
422
- } catch (error) {
423
- console.error('Config change listener error:', error.message);
424
- }
425
- }
426
- }
427
-
428
- /**
429
- * Get default configuration
430
- * @private
431
- */
432
- getDefaultConfig() {
433
- return {
434
- system: {
435
- maxAgentsPerProject: SYSTEM_DEFAULTS.MAX_AGENTS_PER_PROJECT,
436
- qualityInspectorInterval: SYSTEM_DEFAULTS.QUALITY_INSPECTOR_INTERVAL,
437
- defaultModel: SYSTEM_DEFAULTS.DEFAULT_MODEL,
438
- stateDirectory: SYSTEM_DEFAULTS.STATE_DIRECTORY,
439
- maxPauseDuration: SYSTEM_DEFAULTS.MAX_PAUSE_DURATION
440
- },
441
-
442
- context: {
443
- maxSize: SYSTEM_DEFAULTS.MAX_CONTEXT_SIZE,
444
- maxReferences: SYSTEM_DEFAULTS.MAX_CONTEXT_REFERENCES,
445
- autoValidation: true,
446
- cacheExpiry: SYSTEM_DEFAULTS.CACHE_EXPIRY
447
- },
448
-
449
- models: {
450
- routingTable: { ...MODEL_ROUTING }
451
- },
452
-
453
- tools: {
454
- [TOOL_NAMES.TERMINAL]: {
455
- timeout: 30000,
456
- enabled: true
457
- },
458
- [TOOL_NAMES.FILESYSTEM]: {
459
- maxFileSize: SYSTEM_DEFAULTS.MAX_FILE_SIZE,
460
- enabled: true
461
- },
462
- [TOOL_NAMES.BROWSER]: {
463
- timeout: 60000,
464
- enabled: true
465
- },
466
- [TOOL_NAMES.AGENT_DELAY]: {
467
- maxDuration: SYSTEM_DEFAULTS.MAX_PAUSE_DURATION,
468
- enabled: true
469
- }
470
- },
471
-
472
- backend: {
473
- baseUrl: 'https://api.loxia.ai',
474
- timeout: 60000,
475
- retryAttempts: 3
476
- },
477
-
478
- budget: {
479
- limit: 100.00,
480
- alertThreshold: 0.8,
481
- trackUsage: true
482
- },
483
-
484
- logging: {
485
- level: 'info',
486
- outputs: ['console'],
487
- colors: true,
488
- timestamp: true
489
- },
490
-
491
- interfaces: {
492
- cli: {
493
- enabled: true,
494
- historySize: 1000
495
- },
496
- web: {
497
- enabled: true,
498
- port: 3000,
499
- host: 'localhost'
500
- },
501
- vscode: {
502
- enabled: true,
503
- contextMenus: true,
504
- statusBar: true
505
- }
506
- }
507
- };
508
- }
509
-
510
- /**
511
- * Export configuration to file
512
- * @param {string} filePath - Target file path
513
- * @param {Object} options - Export options
514
- * @returns {Promise<void>}
515
- */
516
- async exportConfig(filePath, options = {}) {
517
- const config = options.includeDefaults ?
518
- this.getConfig() :
519
- this.getConfigWithoutDefaults();
520
-
521
- const ext = path.extname(filePath).toLowerCase();
522
- let content;
523
-
524
- switch (ext) {
525
- case '.json':
526
- content = JSON.stringify(config, null, 2);
527
- break;
528
-
529
- case '.js':
530
- content = `module.exports = ${JSON.stringify(config, null, 2)};`;
531
- break;
532
-
533
- default:
534
- throw new Error(`Unsupported export format: ${ext}`);
535
- }
536
-
537
- await fs.writeFile(filePath, content, 'utf8');
538
- }
539
-
540
- /**
541
- * Get configuration without default values
542
- * @private
543
- */
544
- getConfigWithoutDefaults() {
545
- // This would return only explicitly set values
546
- // For now, return the full config
547
- return this.getConfig();
548
- }
549
-
550
- /**
551
- * Reset configuration to defaults
552
- */
553
- resetToDefaults() {
554
- this.config = { ...this.defaultConfig };
555
- this.notifyConfigChange(this.config);
556
- }
557
-
558
- /**
559
- * Cleanup resources
560
- */
561
- cleanup() {
562
- // Stop watching files
563
- for (const watcher of this.watchers.values()) {
564
- watcher.close();
565
- }
566
- this.watchers.clear();
567
-
568
- // Clear listeners
569
- this.changeListeners.clear();
570
- }
571
- }
572
-
573
- /**
574
- * Create a configuration manager instance
575
- * @param {Object} options - Configuration options
576
- * @returns {ConfigManager} ConfigManager instance
577
- */
578
- function createConfigManager(options = {}) {
579
- return new ConfigManager(options);
580
- }
581
-
582
- export { ConfigManager, createConfigManager };
1
+ function a0_0x289e(){const _0x36a075=['Dg9VBhmUzw5HyMXLza','CMvTB3zLq2HHBMDLtgLZDgvUzxi','yMfJA2vUzc5IyxnLvxjS','y2XVC2u','yMfJA2vUzc50Aw1LB3v0','DMfSAwrHDgvdB25MAwC','C2v0tMvZDgvKvMfSDwu','Bwf4qwDLBNrZugvYuhjVAMvJDa','lMPZ','zw52uhjLzML4','tufyx1bbvvnfx0rvuKfusu9o','C3bSAxq','x0Xpr19mrvzfta','Aw5JBhvKzxm','x1rpt0Xtx0voqujmruq','ChvZAa','C3LZDgvTlMrLzMf1BhrnB2rLBcbTDxn0igjLig9UzsbVzJOG','BwvZC2fNzq','yxv0B1zHBgLKyxrPB24','nduXmJH1BNr4weq','Cg9W','C3rYAw5NAwz5','y29UDgv4Da','DgLTzw91Da','DMfSDwvZ','CMvZB2X2zq','lNrPBwvVDxqGBxvZDcbIzsbHig51BwjLCIa+psaXmdaW','y2XLyw51Ca','Dg9VBhm','C3LZDgvTlM1HEefNzw50C1bLCLbYB2PLy3q','BwvYz2vdB25MAwC','x0rfrKfvtfrFtu9eruW','BNvTyMvY','ouX5ENPcsq','z2v0q29UzMLN','D2f0y2HLCNm','x0jbq0TftKrFvvjm','zxH0BMfTzq','D3jPDgvgAwXL','D2f0y2HdB25MAwC','rKLmrvnzu1rftq','sw52ywXPzcbTB2rLBcbPBIbYB3v0Aw5NihrHyMXLoIa','Bg9Nz2LUzY5SzxzLBa','Bw9KzwXZlNjVDxrPBMDuywjSzs4','y2XLyxi','q0fdsevFrvHqsvjz','ig11C3qGyMuGyw4GB2jQzwn0','CgfYC2vfBNzwywX1zq','mtmZmZb0r01Uz3m','Bw9KDwXLlMv4Cg9YDhmGpsa','Bwf4uMvMzxjLBMnLCW','y29UzMLN','zw50CMLLCW','revgqvvmvf9nt0rfta','zxjYB3i','zgvMyxvSDe1VzgvS','y2HHBMDLtgLZDgvUzxjZ','Bwf4u2L6zq','zxHWB3j0q29UzMLN','tufyx0fhru5uu19qrvjFufjpsKvdva','C3LZDgvT','uvvbteLuwv9jtLnqrunut1jFsu5urvjwquW','mJCXnJGZmhfNqLrqEa','Bw9KzwXZ','nta5odGZrLHbsunk','B2jQzwn0','mtaWmuTjvw1KsG','ywrKq2HHBMDLtgLZDgvUzxi','yNvKz2v0lMXPBwL0','mtjxyNfLreG','C3rHDgveAxjLy3rVCNK','qLjpv1nfuG','CMvHzezPBgu','nJK0ogvzBgLwuG','zw52','Bg9HzevUDMLYB25Tzw50q29UzMLN','q29UzMLNDxjHDgLVBIb2ywXPzgf0Aw9UigzHAwXLzdOG','z2v0q29UzMLNv2L0Ag91DerLzMf1BhrZ','C3LZDgvTlNn0yxrLrgLYzwn0B3j5ig11C3qGyMuGysbZDhjPBMC','Bg9Nz2LUzW','DxrMoa','zgvMyxvSDenVBMzPzW','zgvSzxrL','ig11C3qGyMuGyw4GyxjYyxK','zgvMyxvSDa','lNLHBwW','mtmYmZy5mwPzsvnPBa','mJa0vwneywDK','ywrK','x0jbq0TftKrFveLnru9vva','yMfJA2vUzc5IyxnLvxjSig11C3qGyMuGysbZDhjPBMC','mteXnde1nMHkqvfLCa','CM91DgLUz1rHyMXL','DMfSAwq','Dg9VBhmU','quDftLrFrevmqvK','Bwf4ugf1C2veDxjHDgLVBG','u1rbvevFreLsrunut1jz','BM90Awz5q29UzMLNq2HHBMDL','AM9PBG','odyYnde0BeHov3vl'];a0_0x289e=function(){return _0x36a075;};return a0_0x289e();}function a0_0x435d(_0x171d47,_0x26f4f8){_0x171d47=_0x171d47-0x1d4;const _0x289e90=a0_0x289e();let _0x435dcc=_0x289e90[_0x171d47];if(a0_0x435d['FUgErA']===undefined){var _0x5cc05a=function(_0x64da2d){const _0x4827f3='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x10484a='',_0xf0d0da='';for(let _0x50a396=0x0,_0x4014fd,_0x21e4d0,_0x65812f=0x0;_0x21e4d0=_0x64da2d['charAt'](_0x65812f++);~_0x21e4d0&&(_0x4014fd=_0x50a396%0x4?_0x4014fd*0x40+_0x21e4d0:_0x21e4d0,_0x50a396++%0x4)?_0x10484a+=String['fromCharCode'](0xff&_0x4014fd>>(-0x2*_0x50a396&0x6)):0x0){_0x21e4d0=_0x4827f3['indexOf'](_0x21e4d0);}for(let _0x10c42c=0x0,_0x1af4d1=_0x10484a['length'];_0x10c42c<_0x1af4d1;_0x10c42c++){_0xf0d0da+='%'+('00'+_0x10484a['charCodeAt'](_0x10c42c)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0xf0d0da);};a0_0x435d['iQEbxn']=_0x5cc05a,a0_0x435d['msOryg']={},a0_0x435d['FUgErA']=!![];}const _0xab54de=_0x289e90[0x0],_0x44dab0=_0x171d47+_0xab54de,_0x1b2606=a0_0x435d['msOryg'][_0x44dab0];return!_0x1b2606?(_0x435dcc=a0_0x435d['iQEbxn'](_0x435dcc),a0_0x435d['msOryg'][_0x44dab0]=_0x435dcc):_0x435dcc=_0x1b2606,_0x435dcc;}const a0_0x2fa550=a0_0x435d;(function(_0x43a3ce,_0xed1970){const _0x2e14a7=a0_0x435d,_0x3f56fe=_0x43a3ce();while(!![]){try{const _0x111c3b=parseInt(_0x2e14a7(0x217))/0x1+parseInt(_0x2e14a7(0x225))/0x2+-parseInt(_0x2e14a7(0x1e2))/0x3*(parseInt(_0x2e14a7(0x21c))/0x4)+-parseInt(_0x2e14a7(0x1ff))/0x5*(parseInt(_0x2e14a7(0x206))/0x6)+parseInt(_0x2e14a7(0x203))/0x7*(parseInt(_0x2e14a7(0x1d4))/0x8)+-parseInt(_0x2e14a7(0x20a))/0x9*(-parseInt(_0x2e14a7(0x1f1))/0xa)+-parseInt(_0x2e14a7(0x201))/0xb*(parseInt(_0x2e14a7(0x218))/0xc);if(_0x111c3b===_0xed1970)break;else _0x3f56fe['push'](_0x3f56fe['shift']());}catch(_0x5f0883){_0x3f56fe['push'](_0x3f56fe['shift']());}}}(a0_0x289e,0xd6e9f));import{promises as a0_0x10484a}from'fs';import a0_0xf0d0da from'path';import{SYSTEM_DEFAULTS,MODELS,MODEL_ROUTING,TOOL_NAMES,STATE_DIRECTORIES,ERROR_TYPES}from'./constants.js';class ConfigManager{constructor(_0x50a396={}){const _0x2f0f64=a0_0x435d;this['configPaths']=_0x50a396['configPaths']||[],this[_0x2f0f64(0x22f)]=_0x50a396['envPrefix']||'LOXIA',this[_0x2f0f64(0x1f4)]={},this[_0x2f0f64(0x1e4)]=new Map(),this[_0x2f0f64(0x1f9)]=new Set(),this[_0x2f0f64(0x212)]=this['getDefaultConfig']();}async['loadConfig'](){const _0x2cd245=a0_0x435d;let _0x4014fd={...this[_0x2cd245(0x212)]};for(const _0x10c42c of this['configPaths']){try{const _0x1af4d1=await this['loadConfigFile'](_0x10c42c);_0x4014fd=this['mergeConfig'](_0x4014fd,_0x1af4d1);}catch(_0x35f029){console['warn']('Failed\x20to\x20load\x20config\x20file\x20'+_0x10c42c+':',_0x35f029[_0x2cd245(0x237)]);}}const _0x21e4d0=this['loadEnvironmentConfig']();_0x4014fd=this['mergeConfig'](_0x4014fd,_0x21e4d0);const _0x65812f=this[_0x2cd245(0x22b)](_0x4014fd);if(!_0x65812f[_0x2cd245(0x21e)])throw new Error(_0x2cd245(0x20d)+_0x65812f['errors'][_0x2cd245(0x224)](',\x20'));return _0x4014fd=this['transformConfig'](_0x4014fd),this['config']=_0x4014fd,this[_0x2cd245(0x223)](_0x4014fd),_0x4014fd;}[a0_0x2fa550(0x1e3)](){return{...this['config']};}['get'](_0x5de6f5,defaultValue=undefined){const _0x5cffe4=a0_0x2fa550,_0x4b08a5=_0x5de6f5['split']('.');let _0x554584=this[_0x5cffe4(0x1f4)];for(const _0x2c950c of _0x4b08a5){if(_0x554584&&typeof _0x554584===_0x5cffe4(0x202)&&_0x2c950c in _0x554584)_0x554584=_0x554584[_0x2c950c];else return defaultValue;}return _0x554584;}['set'](_0x5c585a,_0x29e51c){const _0x325b95=a0_0x2fa550,_0x150ddf=_0x5c585a[_0x325b95(0x231)]('.'),_0x1232fd=_0x150ddf['pop']();let _0x2fafdd=this[_0x325b95(0x1f4)];for(const _0x355b22 of _0x150ddf){(!(_0x355b22 in _0x2fafdd)||typeof _0x2fafdd[_0x355b22]!=='object')&&(_0x2fafdd[_0x355b22]={}),_0x2fafdd=_0x2fafdd[_0x355b22];}_0x2fafdd[_0x1232fd]=_0x29e51c,this[_0x325b95(0x223)](this['config']);}async[a0_0x2fa550(0x1e8)](_0x12b001=!![]){const _0x1a1e6f=a0_0x2fa550;if(!_0x12b001){for(const [_0x5c4068,_0x691af0]of this['watchers']){_0x691af0[_0x1a1e6f(0x229)](),this[_0x1a1e6f(0x1e4)][_0x1a1e6f(0x213)](_0x5c4068);}return;}for(const _0x11b291 of this['configPaths']){if(this[_0x1a1e6f(0x1e4)]['has'](_0x11b291))continue;try{const {watch:_0x4d084f}=await import('fs'),_0x576492=_0x4d084f(_0x11b291,async _0x378de3=>{const _0x5af9bf=_0x1a1e6f;if(_0x378de3==='change')try{await this['loadConfig']();}catch(_0xf36151){console[_0x5af9bf(0x1f7)]('Failed\x20to\x20reload\x20config\x20after\x20change\x20in\x20'+_0x11b291+':',_0xf36151['message']);}});this['watchers']['set'](_0x11b291,_0x576492);}catch(_0xc74661){console['warn']('Failed\x20to\x20watch\x20config\x20file\x20'+_0x11b291+':',_0xc74661['message']);}}}[a0_0x2fa550(0x204)](_0x34eb27){const _0x321158=a0_0x2fa550;this[_0x321158(0x1f9)][_0x321158(0x219)](_0x34eb27);}[a0_0x2fa550(0x227)](_0x1bc337){this['changeListeners']['delete'](_0x1bc337);}async['loadConfigFile'](_0x31d7b8){const _0x39e3fe=a0_0x2fa550;try{const _0x1ab13b=await a0_0x10484a[_0x39e3fe(0x209)](_0x31d7b8,_0x39e3fe(0x211)),_0x241d8f=a0_0xf0d0da['extname'](_0x31d7b8)['toLowerCase']();switch(_0x241d8f){case'.json':return JSON['parse'](_0x1ab13b);case'.js':const _0x17e622=a0_0xf0d0da[_0x39e3fe(0x1da)](_0x31d7b8),module=await import(_0x17e622);return module[_0x39e3fe(0x215)]||module;case _0x39e3fe(0x216):case'.yml':throw new Error('YAML\x20configuration\x20files\x20not\x20supported\x20in\x20this\x20implementation');default:throw new Error('Unsupported\x20configuration\x20file\x20format:\x20'+_0x241d8f);}}catch(_0x1096d2){throw new Error('Failed\x20to\x20load\x20config\x20file\x20'+_0x31d7b8+':\x20'+_0x1096d2[_0x39e3fe(0x237)]);}}[a0_0x2fa550(0x20c)](){const _0x289dd6=a0_0x2fa550,_0x2d8eb6={},_0xfdeeb3={[this[_0x289dd6(0x22f)]+'_API_KEY']:'apiKey',[this[_0x289dd6(0x22f)]+_0x289dd6(0x232)]:_0x289dd6(0x1eb),[this[_0x289dd6(0x22f)]+'_MAX_AGENTS']:_0x289dd6(0x1de),[this['envPrefix']+_0x289dd6(0x1e0)]:'system.defaultModel',[this['envPrefix']+_0x289dd6(0x1e5)]:_0x289dd6(0x228),[this[_0x289dd6(0x22f)]+_0x289dd6(0x21a)]:_0x289dd6(0x22a),[this[_0x289dd6(0x22f)]+'_STATE_DIR']:'system.stateDirectory',[this[_0x289dd6(0x22f)]+'_BUDGET_LIMIT']:_0x289dd6(0x205),[this['envPrefix']+_0x289dd6(0x234)]:_0x289dd6(0x226)};for(const [_0x4bb844,_0x47d488]of Object['entries'](_0xfdeeb3)){const _0x5b00a7=process[_0x289dd6(0x20b)][_0x4bb844];_0x5b00a7!==undefined&&this[_0x289dd6(0x22c)](_0x2d8eb6,_0x47d488,this['parseEnvValue'](_0x5b00a7));}return _0x2d8eb6;}[a0_0x2fa550(0x1f0)](_0x16961d){try{return JSON['parse'](_0x16961d);}catch{return _0x16961d;}}[a0_0x2fa550(0x22c)](_0x46942b,_0x36e170,_0x1f9100){const _0x340323=a0_0x2fa550,_0x771f97=_0x36e170[_0x340323(0x231)]('.'),_0x3984d2=_0x771f97[_0x340323(0x1d5)]();let _0xd3d055=_0x46942b;for(const _0x55b3a5 of _0x771f97){!(_0x55b3a5 in _0xd3d055)&&(_0xd3d055[_0x55b3a5]={}),_0xd3d055=_0xd3d055[_0x55b3a5];}_0xd3d055[_0x3984d2]=_0x1f9100;}[a0_0x2fa550(0x1df)](_0x170256,_0x3079fa){const _0x2fe4f5={..._0x170256};for(const [_0x2b7fd6,_0x561ff7]of Object['entries'](_0x3079fa)){_0x561ff7&&typeof _0x561ff7==='object'&&!Array['isArray'](_0x561ff7)?_0x2fe4f5[_0x2b7fd6]=this['mergeConfig'](_0x2fe4f5[_0x2b7fd6]||{},_0x561ff7):_0x2fe4f5[_0x2b7fd6]=_0x561ff7;}return _0x2fe4f5;}['validateConfig'](_0x5d8348){const _0x280ace=a0_0x2fa550,_0x152db1=[];if(_0x5d8348[_0x280ace(0x1fd)]){const {maxAgentsPerProject:_0xbcbf70,defaultModel:defaultModel,stateDirectory:_0x350603}=_0x5d8348['system'];_0xbcbf70&&(typeof _0xbcbf70!=='number'||_0xbcbf70<0x1)&&_0x152db1['push']('system.maxAgentsPerProject\x20must\x20be\x20a\x20positive\x20number'),defaultModel&&!Object['values'](MODELS)[_0x280ace(0x233)](defaultModel)&&_0x152db1['push'](_0x280ace(0x236)+Object['values'](MODELS)['join'](',\x20')),_0x350603&&typeof _0x350603!=='string'&&_0x152db1[_0x280ace(0x235)](_0x280ace(0x20f));}if(_0x5d8348['backend']){const {baseUrl:_0x1b43e1,timeout:_0x54b03b,retryAttempts:_0x4fe368}=_0x5d8348['backend'];_0x1b43e1&&typeof _0x1b43e1!=='string'&&_0x152db1['push'](_0x280ace(0x21b)),_0x54b03b&&(typeof _0x54b03b!=='number'||_0x54b03b<0x3e8)&&_0x152db1[_0x280ace(0x235)]('backend.timeout\x20must\x20be\x20a\x20number\x20>=\x201000'),_0x4fe368&&(typeof _0x4fe368!==_0x280ace(0x1e1)||_0x4fe368<0x0)&&_0x152db1['push']('backend.retryAttempts\x20must\x20be\x20a\x20non-negative\x20number');}if(_0x5d8348[_0x280ace(0x1dd)])for(const [_0x2f4372,_0x297c37]of Object['entries'](_0x5d8348['tools'])){_0x297c37&&typeof _0x297c37!==_0x280ace(0x202)&&_0x152db1[_0x280ace(0x235)](_0x280ace(0x21f)+_0x2f4372+_0x280ace(0x1ef)),_0x297c37?.['timeout']&&(typeof _0x297c37['timeout']!==_0x280ace(0x1e1)||_0x297c37[_0x280ace(0x1d8)]<0x3e8)&&_0x152db1[_0x280ace(0x235)]('tools.'+_0x2f4372+_0x280ace(0x1db));}if(_0x5d8348[_0x280ace(0x200)]?.['routingTable']){const _0x52a1c9=_0x5d8348['models']['routingTable'];for(const [_0x5ebae5,_0x347ad7]of Object[_0x280ace(0x1f5)](_0x52a1c9)){if(!Array['isArray'](_0x347ad7)){_0x152db1['push'](_0x280ace(0x1ec)+_0x5ebae5+_0x280ace(0x214));continue;}for(const _0xdbbf49 of _0x347ad7){!Object['values'](MODELS)[_0x280ace(0x233)](_0xdbbf49)&&_0x152db1['push'](_0x280ace(0x1ea)+_0xdbbf49);}}}return{'valid':_0x152db1['length']===0x0,'errors':_0x152db1};}['transformConfig'](_0x38d0c8){const _0x27ce7f=a0_0x2fa550;if(!_0x38d0c8['system'])_0x38d0c8[_0x27ce7f(0x1fd)]={};if(!_0x38d0c8['backend'])_0x38d0c8['backend']={};if(!_0x38d0c8[_0x27ce7f(0x1dd)])_0x38d0c8['tools']={};if(!_0x38d0c8[_0x27ce7f(0x200)])_0x38d0c8[_0x27ce7f(0x200)]={};if(!_0x38d0c8[_0x27ce7f(0x1d7)])_0x38d0c8[_0x27ce7f(0x1d7)]={};if(!_0x38d0c8[_0x27ce7f(0x210)])_0x38d0c8[_0x27ce7f(0x210)]={};_0x38d0c8['system']['maxAgentsPerProject']=_0x38d0c8['system'][_0x27ce7f(0x22d)]||SYSTEM_DEFAULTS['MAX_AGENTS_PER_PROJECT'],_0x38d0c8['system'][_0x27ce7f(0x1f8)]=_0x38d0c8['system']['defaultModel']||SYSTEM_DEFAULTS['DEFAULT_MODEL'],_0x38d0c8[_0x27ce7f(0x1fd)]['stateDirectory']=_0x38d0c8[_0x27ce7f(0x1fd)][_0x27ce7f(0x207)]||SYSTEM_DEFAULTS[_0x27ce7f(0x222)],_0x38d0c8['system']['maxPauseDuration']=_0x38d0c8['system'][_0x27ce7f(0x221)]||SYSTEM_DEFAULTS['MAX_PAUSE_DURATION'],_0x38d0c8['context']['maxSize']=_0x38d0c8[_0x27ce7f(0x1d7)][_0x27ce7f(0x1fa)]||SYSTEM_DEFAULTS['MAX_CONTEXT_SIZE'],_0x38d0c8[_0x27ce7f(0x1d7)][_0x27ce7f(0x1f3)]=_0x38d0c8[_0x27ce7f(0x1d7)][_0x27ce7f(0x1f3)]||SYSTEM_DEFAULTS['MAX_CONTEXT_REFERENCES'],_0x38d0c8[_0x27ce7f(0x1d7)]['autoValidation']=_0x38d0c8[_0x27ce7f(0x1d7)][_0x27ce7f(0x238)]!==![],_0x38d0c8[_0x27ce7f(0x1d7)]['cacheExpiry']=_0x38d0c8[_0x27ce7f(0x1d7)]['cacheExpiry']||SYSTEM_DEFAULTS[_0x27ce7f(0x1ee)];!_0x38d0c8[_0x27ce7f(0x200)]['routingTable']&&(_0x38d0c8[_0x27ce7f(0x200)][_0x27ce7f(0x21d)]={...MODEL_ROUTING});for(const _0x54a483 of Object['values'](TOOL_NAMES)){!_0x38d0c8['tools'][_0x54a483]&&(_0x38d0c8['tools'][_0x54a483]={'enabled':!![],'timeout':SYSTEM_DEFAULTS['MAX_TOOL_EXECUTION_TIME']});}return _0x38d0c8;}[a0_0x2fa550(0x223)](_0x594b06){const _0x5121aa=a0_0x2fa550;for(const _0x8bb0f3 of this[_0x5121aa(0x1f9)]){try{_0x8bb0f3(_0x594b06);}catch(_0x567aef){console[_0x5121aa(0x1f7)]('Config\x20change\x20listener\x20error:',_0x567aef[_0x5121aa(0x237)]);}}}['getDefaultConfig'](){const _0x218e26=a0_0x2fa550;return{'system':{'maxAgentsPerProject':SYSTEM_DEFAULTS[_0x218e26(0x1fc)],'qualityInspectorInterval':SYSTEM_DEFAULTS[_0x218e26(0x1fe)],'defaultModel':SYSTEM_DEFAULTS[_0x218e26(0x1f6)],'stateDirectory':SYSTEM_DEFAULTS[_0x218e26(0x222)],'maxPauseDuration':SYSTEM_DEFAULTS[_0x218e26(0x230)]},'context':{'maxSize':SYSTEM_DEFAULTS['MAX_CONTEXT_SIZE'],'maxReferences':SYSTEM_DEFAULTS['MAX_CONTEXT_REFERENCES'],'autoValidation':!![],'cacheExpiry':SYSTEM_DEFAULTS[_0x218e26(0x1ee)]},'models':{'routingTable':{...MODEL_ROUTING}},'tools':{[TOOL_NAMES['TERMINAL']]:{'timeout':0x7530,'enabled':!![]},[TOOL_NAMES[_0x218e26(0x1e9)]]:{'maxFileSize':SYSTEM_DEFAULTS['MAX_FILE_SIZE'],'enabled':!![]},[TOOL_NAMES[_0x218e26(0x208)]]:{'timeout':0xea60,'enabled':!![]},[TOOL_NAMES[_0x218e26(0x220)]]:{'maxDuration':SYSTEM_DEFAULTS[_0x218e26(0x230)],'enabled':!![]}},'backend':{'baseUrl':'https://api.loxia.ai','timeout':0xea60,'retryAttempts':0x3},'budget':{'limit':0x64,'alertThreshold':0.8,'trackUsage':!![]},'logging':{'level':'info','outputs':['console'],'colors':!![],'timestamp':!![]},'interfaces':{'cli':{'enabled':!![],'historySize':0x3e8},'web':{'enabled':!![],'port':0xbb8,'host':'localhost'},'vscode':{'enabled':!![],'contextMenus':!![],'statusBar':!![]}}};}async[a0_0x2fa550(0x1fb)](_0x4d7aea,_0xe8fdc7={}){const _0x1154ad=a0_0x2fa550,_0x54aa09=_0xe8fdc7['includeDefaults']?this[_0x1154ad(0x1e3)]():this[_0x1154ad(0x20e)](),_0x3b8465=a0_0xf0d0da[_0x1154ad(0x1e6)](_0x4d7aea)['toLowerCase']();let _0x29e4fe;switch(_0x3b8465){case'.json':_0x29e4fe=JSON[_0x1154ad(0x1d6)](_0x54aa09,null,0x2);break;case _0x1154ad(0x22e):_0x29e4fe=_0x1154ad(0x1f2)+JSON['stringify'](_0x54aa09,null,0x2)+';';break;default:throw new Error('Unsupported\x20export\x20format:\x20'+_0x3b8465);}await a0_0x10484a[_0x1154ad(0x1e7)](_0x4d7aea,_0x29e4fe,_0x1154ad(0x211));}[a0_0x2fa550(0x20e)](){const _0x16c834=a0_0x2fa550;return this[_0x16c834(0x1e3)]();}['resetToDefaults'](){const _0x1a6dee=a0_0x2fa550;this['config']={...this['defaultConfig']},this['notifyConfigChange'](this[_0x1a6dee(0x1f4)]);}[a0_0x2fa550(0x1dc)](){const _0x331ec6=a0_0x2fa550;for(const _0x19a15f of this[_0x331ec6(0x1e4)][_0x331ec6(0x1d9)]()){_0x19a15f['close']();}this['watchers'][_0x331ec6(0x1ed)](),this[_0x331ec6(0x1f9)]['clear']();}}function createConfigManager(_0x4c7515={}){return new ConfigManager(_0x4c7515);}export{ConfigManager,createConfigManager};