@loxia-labs/loxia-autopilot-one 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -54
- package/bin/cli.js +1 -115
- package/bin/loxia-terminal-v2.js +3 -0
- package/bin/loxia-terminal.js +3 -0
- package/bin/start-with-terminal.js +3 -0
- package/package.json +14 -15
- package/scripts/install-scanners.js +1 -235
- package/src/analyzers/CSSAnalyzer.js +1 -297
- package/src/analyzers/ConfigValidator.js +1 -690
- package/src/analyzers/ESLintAnalyzer.js +1 -320
- package/src/analyzers/JavaScriptAnalyzer.js +1 -261
- package/src/analyzers/PrettierFormatter.js +1 -247
- package/src/analyzers/PythonAnalyzer.js +1 -266
- package/src/analyzers/SecurityAnalyzer.js +1 -729
- package/src/analyzers/TypeScriptAnalyzer.js +1 -247
- package/src/analyzers/codeCloneDetector/analyzer.js +1 -344
- package/src/analyzers/codeCloneDetector/detector.js +1 -203
- package/src/analyzers/codeCloneDetector/index.js +1 -160
- package/src/analyzers/codeCloneDetector/parser.js +1 -199
- package/src/analyzers/codeCloneDetector/reporter.js +1 -148
- package/src/analyzers/codeCloneDetector/scanner.js +1 -59
- package/src/core/agentPool.js +1 -1474
- package/src/core/agentScheduler.js +1 -2147
- package/src/core/contextManager.js +1 -709
- package/src/core/messageProcessor.js +1 -732
- package/src/core/orchestrator.js +1 -548
- package/src/core/stateManager.js +1 -877
- package/src/index.js +1 -631
- package/src/interfaces/cli.js +1 -549
- package/src/interfaces/terminal/__tests__/smoke/advancedFeatures.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agentControl.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agents.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/components.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/connection.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/imports.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/messages.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/tools.test.js +1 -0
- package/src/interfaces/terminal/api/apiClient.js +1 -0
- package/src/interfaces/terminal/api/messageRouter.js +1 -0
- package/src/interfaces/terminal/api/session.js +1 -0
- package/src/interfaces/terminal/api/websocket.js +1 -0
- package/src/interfaces/terminal/components/AgentCreator.js +1 -0
- package/src/interfaces/terminal/components/AgentEditor.js +1 -0
- package/src/interfaces/terminal/components/AgentSwitcher.js +1 -0
- package/src/interfaces/terminal/components/ErrorBoundary.js +1 -0
- package/src/interfaces/terminal/components/ErrorPanel.js +1 -0
- package/src/interfaces/terminal/components/Header.js +1 -0
- package/src/interfaces/terminal/components/HelpPanel.js +1 -0
- package/src/interfaces/terminal/components/InputBox.js +1 -0
- package/src/interfaces/terminal/components/Layout.js +1 -0
- package/src/interfaces/terminal/components/LoadingSpinner.js +1 -0
- package/src/interfaces/terminal/components/MessageList.js +1 -0
- package/src/interfaces/terminal/components/MultilineTextInput.js +1 -0
- package/src/interfaces/terminal/components/SearchPanel.js +1 -0
- package/src/interfaces/terminal/components/SettingsPanel.js +1 -0
- package/src/interfaces/terminal/components/StatusBar.js +1 -0
- package/src/interfaces/terminal/components/TextInput.js +1 -0
- package/src/interfaces/terminal/config/agentEditorConstants.js +1 -0
- package/src/interfaces/terminal/config/constants.js +1 -0
- package/src/interfaces/terminal/index.js +1 -0
- package/src/interfaces/terminal/state/useAgentControl.js +1 -0
- package/src/interfaces/terminal/state/useAgents.js +1 -0
- package/src/interfaces/terminal/state/useConnection.js +1 -0
- package/src/interfaces/terminal/state/useMessages.js +1 -0
- package/src/interfaces/terminal/state/useTools.js +1 -0
- package/src/interfaces/terminal/utils/debugLogger.js +1 -0
- package/src/interfaces/terminal/utils/settingsStorage.js +1 -0
- package/src/interfaces/terminal/utils/theme.js +1 -0
- package/src/interfaces/webServer.js +1 -2162
- package/src/modules/fileExplorer/controller.js +1 -280
- package/src/modules/fileExplorer/index.js +1 -37
- package/src/modules/fileExplorer/middleware.js +1 -92
- package/src/modules/fileExplorer/routes.js +1 -125
- package/src/modules/fileExplorer/types.js +1 -44
- package/src/services/aiService.js +1 -1232
- package/src/services/apiKeyManager.js +1 -164
- package/src/services/benchmarkService.js +1 -366
- package/src/services/budgetService.js +1 -539
- package/src/services/contextInjectionService.js +1 -247
- package/src/services/conversationCompactionService.js +1 -637
- package/src/services/errorHandler.js +1 -810
- package/src/services/fileAttachmentService.js +1 -544
- package/src/services/modelRouterService.js +1 -366
- package/src/services/modelsService.js +1 -322
- package/src/services/qualityInspector.js +1 -796
- package/src/services/tokenCountingService.js +1 -536
- package/src/tools/agentCommunicationTool.js +1 -1344
- package/src/tools/agentDelayTool.js +1 -485
- package/src/tools/asyncToolManager.js +1 -604
- package/src/tools/baseTool.js +1 -800
- package/src/tools/browserTool.js +1 -920
- package/src/tools/cloneDetectionTool.js +1 -621
- package/src/tools/dependencyResolverTool.js +1 -1215
- package/src/tools/fileContentReplaceTool.js +1 -875
- package/src/tools/fileSystemTool.js +1 -1107
- package/src/tools/fileTreeTool.js +1 -853
- package/src/tools/imageTool.js +1 -901
- package/src/tools/importAnalyzerTool.js +1 -1060
- package/src/tools/jobDoneTool.js +1 -248
- package/src/tools/seekTool.js +1 -956
- package/src/tools/staticAnalysisTool.js +1 -1778
- package/src/tools/taskManagerTool.js +1 -2873
- package/src/tools/terminalTool.js +1 -2304
- package/src/tools/webTool.js +1 -1430
- package/src/types/agent.js +1 -519
- package/src/types/contextReference.js +1 -972
- package/src/types/conversation.js +1 -730
- package/src/types/toolCommand.js +1 -747
- package/src/utilities/attachmentValidator.js +1 -292
- package/src/utilities/configManager.js +1 -582
- package/src/utilities/constants.js +1 -722
- package/src/utilities/directoryAccessManager.js +1 -535
- package/src/utilities/fileProcessor.js +1 -307
- package/src/utilities/logger.js +1 -436
- package/src/utilities/tagParser.js +1 -1246
- package/src/utilities/toolConstants.js +1 -317
- package/web-ui/build/index.html +2 -2
- package/web-ui/build/static/{index-Dy2bYbOa.css → index-CClD1090.css} +1 -1
- package/web-ui/build/static/{index-CjkkcnFA.js → index-lCBai6dX.js} +66 -67
|
@@ -1,164 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* API Key Manager - Session-based API key storage and management
|
|
3
|
-
*
|
|
4
|
-
* Purpose:
|
|
5
|
-
* - Store API keys per session (no persistent storage)
|
|
6
|
-
* - Manage both platform (Loxia) and vendor-specific keys
|
|
7
|
-
* - Provide keys to AI services based on model requirements
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
class ApiKeyManager {
|
|
11
|
-
constructor(logger) {
|
|
12
|
-
this.logger = logger;
|
|
13
|
-
|
|
14
|
-
// Session-based storage: sessionId -> { loxiaApiKey, vendorKeys: { anthropic, openai, etc. } }
|
|
15
|
-
this.sessionKeys = new Map();
|
|
16
|
-
|
|
17
|
-
// Global fallback keys (can be set via config, but session keys take priority)
|
|
18
|
-
this.globalKeys = {
|
|
19
|
-
loxiaApiKey: null,
|
|
20
|
-
vendorKeys: {}
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Set API keys for a session
|
|
26
|
-
* @param {string} sessionId - Session identifier
|
|
27
|
-
* @param {Object} keys - API keys object
|
|
28
|
-
* @param {string} keys.loxiaApiKey - Loxia platform API key
|
|
29
|
-
* @param {Object} keys.vendorKeys - Vendor-specific keys { anthropic: 'key', openai: 'key', etc. }
|
|
30
|
-
*/
|
|
31
|
-
setSessionKeys(sessionId, keys) {
|
|
32
|
-
if (!sessionId) {
|
|
33
|
-
throw new Error('Session ID is required');
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
this.sessionKeys.set(sessionId, {
|
|
37
|
-
loxiaApiKey: keys.loxiaApiKey || null,
|
|
38
|
-
vendorKeys: keys.vendorKeys || {},
|
|
39
|
-
updatedAt: new Date().toISOString()
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
this.logger?.info('API keys updated for session', {
|
|
43
|
-
sessionId,
|
|
44
|
-
hasLoxiaKey: !!keys.loxiaApiKey,
|
|
45
|
-
vendorKeys: Object.keys(keys.vendorKeys || {}),
|
|
46
|
-
timestamp: new Date().toISOString()
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Get API keys for a session
|
|
52
|
-
* @param {string} sessionId - Session identifier
|
|
53
|
-
* @returns {Object} API keys object
|
|
54
|
-
*/
|
|
55
|
-
getSessionKeys(sessionId) {
|
|
56
|
-
if (!sessionId) {
|
|
57
|
-
return this.globalKeys;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const sessionKeys = this.sessionKeys.get(sessionId);
|
|
61
|
-
if (sessionKeys) {
|
|
62
|
-
return sessionKeys;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Fallback to global keys
|
|
66
|
-
return this.globalKeys;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Get the appropriate API key for a model/request
|
|
71
|
-
* @param {string} sessionId - Session identifier
|
|
72
|
-
* @param {Object} options - Request options
|
|
73
|
-
* @param {boolean} options.platformProvided - Whether this is a platform-provided model
|
|
74
|
-
* @param {string} options.vendor - Vendor name (anthropic, openai, etc.)
|
|
75
|
-
* @returns {Object} { loxiaApiKey, vendorApiKey }
|
|
76
|
-
*/
|
|
77
|
-
getKeysForRequest(sessionId, options = {}) {
|
|
78
|
-
const keys = this.getSessionKeys(sessionId);
|
|
79
|
-
|
|
80
|
-
const result = {
|
|
81
|
-
loxiaApiKey: keys.loxiaApiKey,
|
|
82
|
-
vendorApiKey: null
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
// For direct access models, also include vendor-specific key
|
|
86
|
-
if (!options.platformProvided && options.vendor && keys.vendorKeys) {
|
|
87
|
-
result.vendorApiKey = keys.vendorKeys[options.vendor];
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return result;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Remove API keys for a session
|
|
95
|
-
* @param {string} sessionId - Session identifier
|
|
96
|
-
*/
|
|
97
|
-
removeSessionKeys(sessionId) {
|
|
98
|
-
if (this.sessionKeys.delete(sessionId)) {
|
|
99
|
-
this.logger?.info('API keys removed for session', { sessionId });
|
|
100
|
-
return true;
|
|
101
|
-
}
|
|
102
|
-
return false;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Set global fallback API keys
|
|
107
|
-
* @param {Object} keys - Global API keys
|
|
108
|
-
*/
|
|
109
|
-
setGlobalKeys(keys) {
|
|
110
|
-
this.globalKeys = {
|
|
111
|
-
loxiaApiKey: keys.loxiaApiKey || this.globalKeys.loxiaApiKey,
|
|
112
|
-
vendorKeys: { ...this.globalKeys.vendorKeys, ...(keys.vendorKeys || {}) }
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
this.logger?.info('Global API keys updated', {
|
|
116
|
-
hasLoxiaKey: !!this.globalKeys.loxiaApiKey,
|
|
117
|
-
vendorKeys: Object.keys(this.globalKeys.vendorKeys)
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* List all active sessions with API keys
|
|
123
|
-
* @returns {Array} Array of session information
|
|
124
|
-
*/
|
|
125
|
-
getActiveSessions() {
|
|
126
|
-
return Array.from(this.sessionKeys.entries()).map(([sessionId, keys]) => ({
|
|
127
|
-
sessionId,
|
|
128
|
-
hasLoxiaKey: !!keys.loxiaApiKey,
|
|
129
|
-
vendorKeys: Object.keys(keys.vendorKeys || {}),
|
|
130
|
-
updatedAt: keys.updatedAt
|
|
131
|
-
}));
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Clean up expired sessions (optional)
|
|
136
|
-
* @param {number} maxAge - Maximum age in milliseconds
|
|
137
|
-
*/
|
|
138
|
-
cleanupExpiredSessions(maxAge = 24 * 60 * 60 * 1000) { // 24 hours default
|
|
139
|
-
const now = Date.now();
|
|
140
|
-
const expired = [];
|
|
141
|
-
|
|
142
|
-
for (const [sessionId, keys] of this.sessionKeys.entries()) {
|
|
143
|
-
const age = now - new Date(keys.updatedAt).getTime();
|
|
144
|
-
if (age > maxAge) {
|
|
145
|
-
expired.push(sessionId);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
expired.forEach(sessionId => {
|
|
150
|
-
this.sessionKeys.delete(sessionId);
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
if (expired.length > 0) {
|
|
154
|
-
this.logger?.info('Cleaned up expired API key sessions', {
|
|
155
|
-
expiredSessions: expired.length,
|
|
156
|
-
remainingSessions: this.sessionKeys.size
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
return expired.length;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export default ApiKeyManager;
|
|
1
|
+
const a0_0x318adb=a0_0x419c;function a0_0xefe6(){const _0x532f10=['A2v5CW','zw50CMLLCW','C2v0','mJK5mtaWs0XHrfzA','DMvUzg9YqxbPs2v5','qvbjigTLExmGCMvTB3zLzcbMB3iGC2vZC2LVBG','z2v0u2vZC2LVBKTLExm','mJqXntCZmKPXwfvnCW','Dg9ju09tDhjPBMC','Aw5MBW','DMvUzg9Ys2v5CW','q2XLyw5Lzcb1CcbLEhbPCMvKiefqssbRzxKGC2vZC2LVBNm','z2v0vgLTzq','mtK2mte0meLHuxbqBa','mtq3nJi0D0vNA3vo','CgXHDgzVCM1qCM92AwrLza','Bg9Nz2vY','z2XVyMfSs2v5CW','nti5oti5r0HUCfjv','n09MENvHBG','BgvUz3rO','mtm3mZm2mdbyugf6DuW','CMvTB3zLu2vZC2LVBKTLExm','Bg94AwfbCgLlzxK','DxbKyxrLzef0','mta1nde3s0LPqM9w','zgvSzxrL','z2v0qwn0AxzLu2vZC2LVBNm','C2vZC2LVBKTLExm','DMvUzg9Y'];a0_0xefe6=function(){return _0x532f10;};return a0_0xefe6();}function a0_0x419c(_0x1d3a05,_0x221d2f){_0x1d3a05=_0x1d3a05-0x144;const _0xefe64=a0_0xefe6();let _0x419c51=_0xefe64[_0x1d3a05];if(a0_0x419c['wbmZIM']===undefined){var _0x5a47c4=function(_0x517c88){const _0x52028a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x41f77b='',_0x1051e3='';for(let _0x5c62dc=0x0,_0x34fd63,_0x5429bd,_0x412c18=0x0;_0x5429bd=_0x517c88['charAt'](_0x412c18++);~_0x5429bd&&(_0x34fd63=_0x5c62dc%0x4?_0x34fd63*0x40+_0x5429bd:_0x5429bd,_0x5c62dc++%0x4)?_0x41f77b+=String['fromCharCode'](0xff&_0x34fd63>>(-0x2*_0x5c62dc&0x6)):0x0){_0x5429bd=_0x52028a['indexOf'](_0x5429bd);}for(let _0x527979=0x0,_0x21b044=_0x41f77b['length'];_0x527979<_0x21b044;_0x527979++){_0x1051e3+='%'+('00'+_0x41f77b['charCodeAt'](_0x527979)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x1051e3);};a0_0x419c['RSYmGm']=_0x5a47c4,a0_0x419c['jPxGIT']={},a0_0x419c['wbmZIM']=!![];}const _0x5e9705=_0xefe64[0x0],_0x1d3c31=_0x1d3a05+_0x5e9705,_0x3a9ac8=a0_0x419c['jPxGIT'][_0x1d3c31];return!_0x3a9ac8?(_0x419c51=a0_0x419c['RSYmGm'](_0x419c51),a0_0x419c['jPxGIT'][_0x1d3c31]=_0x419c51):_0x419c51=_0x3a9ac8,_0x419c51;}(function(_0x47e829,_0x5a504c){const _0x5f1d91=a0_0x419c,_0x451387=_0x47e829();while(!![]){try{const _0x4eb1dc=-parseInt(_0x5f1d91(0x144))/0x1+parseInt(_0x5f1d91(0x153))/0x2+-parseInt(_0x5f1d91(0x14b))/0x3+-parseInt(_0x5f1d91(0x157))/0x4+-parseInt(_0x5f1d91(0x15d))/0x5+parseInt(_0x5f1d91(0x15e))/0x6*(parseInt(_0x5f1d91(0x145))/0x7)+parseInt(_0x5f1d91(0x147))/0x8;if(_0x4eb1dc===_0x5a504c)break;else _0x451387['push'](_0x451387['shift']());}catch(_0x23850a){_0x451387['push'](_0x451387['shift']());}}}(a0_0xefe6,0x50799));class ApiKeyManager{constructor(_0x41f77b){this['logger']=_0x41f77b,this['sessionKeys']=new Map(),this['globalKeys']={'loxiaApiKey':null,'vendorKeys':{}};}['setSessionKeys'](_0x1051e3,_0x5c62dc){const _0x4c2027=a0_0x419c;if(!_0x1051e3)throw new Error('Session\x20ID\x20is\x20required');this['sessionKeys'][_0x4c2027(0x152)](_0x1051e3,{'loxiaApiKey':_0x5c62dc[_0x4c2027(0x149)]||null,'vendorKeys':_0x5c62dc[_0x4c2027(0x15a)]||{},'updatedAt':new Date()[_0x4c2027(0x158)]()}),this['logger']?.[_0x4c2027(0x159)]('API\x20keys\x20updated\x20for\x20session',{'sessionId':_0x1051e3,'hasLoxiaKey':!!_0x5c62dc[_0x4c2027(0x149)],'vendorKeys':Object['keys'](_0x5c62dc[_0x4c2027(0x15a)]||{}),'timestamp':new Date()[_0x4c2027(0x158)]()});}[a0_0x318adb(0x156)](_0x34fd63){const _0x5f1cff=a0_0x318adb;if(!_0x34fd63)return this[_0x5f1cff(0x161)];const _0x5429bd=this[_0x5f1cff(0x14e)]['get'](_0x34fd63);if(_0x5429bd)return _0x5429bd;return this['globalKeys'];}['getKeysForRequest'](_0x412c18,_0x527979={}){const _0x30c3b8=a0_0x318adb,_0x21b044=this[_0x30c3b8(0x156)](_0x412c18),_0x2c0d8f={'loxiaApiKey':_0x21b044['loxiaApiKey'],'vendorApiKey':null};return!_0x527979[_0x30c3b8(0x15f)]&&_0x527979[_0x30c3b8(0x14f)]&&_0x21b044[_0x30c3b8(0x15a)]&&(_0x2c0d8f[_0x30c3b8(0x154)]=_0x21b044[_0x30c3b8(0x15a)][_0x527979[_0x30c3b8(0x14f)]]),_0x2c0d8f;}[a0_0x318adb(0x148)](_0x52c4d7){const _0x5c4d6a=a0_0x318adb;if(this[_0x5c4d6a(0x14e)][_0x5c4d6a(0x14c)](_0x52c4d7))return this['logger']?.[_0x5c4d6a(0x159)](_0x5c4d6a(0x155),{'sessionId':_0x52c4d7}),!![];return![];}['setGlobalKeys'](_0x2113b9){const _0x34bfcb=a0_0x318adb;this[_0x34bfcb(0x161)]={'loxiaApiKey':_0x2113b9['loxiaApiKey']||this[_0x34bfcb(0x161)][_0x34bfcb(0x149)],'vendorKeys':{...this[_0x34bfcb(0x161)]['vendorKeys'],..._0x2113b9[_0x34bfcb(0x15a)]||{}}},this[_0x34bfcb(0x160)]?.[_0x34bfcb(0x159)]('Global\x20API\x20keys\x20updated',{'hasLoxiaKey':!!this['globalKeys']['loxiaApiKey'],'vendorKeys':Object[_0x34bfcb(0x150)](this['globalKeys'][_0x34bfcb(0x15a)])});}[a0_0x318adb(0x14d)](){const _0x52cb52=a0_0x318adb;return Array['from'](this['sessionKeys'][_0x52cb52(0x151)]())['map'](([_0x1d7e97,_0x287144])=>({'sessionId':_0x1d7e97,'hasLoxiaKey':!!_0x287144[_0x52cb52(0x149)],'vendorKeys':Object[_0x52cb52(0x150)](_0x287144['vendorKeys']||{}),'updatedAt':_0x287144[_0x52cb52(0x14a)]}));}['cleanupExpiredSessions'](_0x22b938=0x18*0x3c*0x3c*0x3e8){const _0x3baefd=a0_0x318adb,_0x50fd8d=Date['now'](),_0x5117f6=[];for(const [_0x185c92,_0x12b409]of this[_0x3baefd(0x14e)]['entries']()){const _0x5f1a32=_0x50fd8d-new Date(_0x12b409[_0x3baefd(0x14a)])[_0x3baefd(0x15c)]();_0x5f1a32>_0x22b938&&_0x5117f6['push'](_0x185c92);}return _0x5117f6['forEach'](_0x1ba635=>{this['sessionKeys']['delete'](_0x1ba635);}),_0x5117f6[_0x3baefd(0x146)]>0x0&&this['logger']?.['info'](_0x3baefd(0x15b),{'expiredSessions':_0x5117f6['length'],'remainingSessions':this[_0x3baefd(0x14e)]['size']}),_0x5117f6[_0x3baefd(0x146)];}}export default ApiKeyManager;
|
|
@@ -1,366 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* BenchmarkService - Manages model performance benchmarks for routing decisions
|
|
3
|
-
*
|
|
4
|
-
* Purpose:
|
|
5
|
-
* - Fetch benchmark data from Azure backend
|
|
6
|
-
* - Provide local fallback data
|
|
7
|
-
* - Refresh benchmarks periodically
|
|
8
|
-
* - Supply benchmark data to model router
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { MODEL_ROUTER_CONFIG, HTTP_STATUS } from '../utilities/constants.js';
|
|
12
|
-
|
|
13
|
-
class BenchmarkService {
|
|
14
|
-
constructor(config, logger) {
|
|
15
|
-
this.config = config;
|
|
16
|
-
this.logger = logger;
|
|
17
|
-
|
|
18
|
-
this.benchmarks = null;
|
|
19
|
-
this.lastUpdated = null;
|
|
20
|
-
this.isLoading = false;
|
|
21
|
-
|
|
22
|
-
this.azureBackendUrl = 'https://autopilot-api.azurewebsites.net';
|
|
23
|
-
this.refreshInterval = MODEL_ROUTER_CONFIG.BENCHMARK_REFRESH_INTERVAL;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Initialize benchmark service and load initial data
|
|
28
|
-
*/
|
|
29
|
-
async initialize() {
|
|
30
|
-
try {
|
|
31
|
-
await this.loadBenchmarks();
|
|
32
|
-
this._scheduleRefresh();
|
|
33
|
-
this.logger.info('Benchmark service initialized');
|
|
34
|
-
} catch (error) {
|
|
35
|
-
this.logger.error('Failed to initialize benchmark service', { error: error.message });
|
|
36
|
-
// Use fallback data on initialization failure
|
|
37
|
-
this.benchmarks = this._getFallbackBenchmarks();
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Get current benchmark data
|
|
43
|
-
*/
|
|
44
|
-
getBenchmarks() {
|
|
45
|
-
if (!this.benchmarks) {
|
|
46
|
-
this.logger.warn('No benchmark data available, using fallback');
|
|
47
|
-
return this._getFallbackBenchmarks();
|
|
48
|
-
}
|
|
49
|
-
return this.benchmarks;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Load benchmarks from Azure backend with fallback
|
|
54
|
-
*/
|
|
55
|
-
async loadBenchmarks() {
|
|
56
|
-
if (this.isLoading) {
|
|
57
|
-
this.logger.debug('Benchmark loading already in progress');
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
this.isLoading = true;
|
|
62
|
-
|
|
63
|
-
try {
|
|
64
|
-
// Try to load from Azure backend
|
|
65
|
-
const benchmarks = await this._fetchFromAzureBackend();
|
|
66
|
-
|
|
67
|
-
if (benchmarks) {
|
|
68
|
-
this.benchmarks = benchmarks;
|
|
69
|
-
this.lastUpdated = new Date();
|
|
70
|
-
this.logger.info('Benchmarks loaded from Azure backend', {
|
|
71
|
-
modelCount: benchmarks.models?.length || 0
|
|
72
|
-
});
|
|
73
|
-
} else {
|
|
74
|
-
throw new Error('No benchmark data received from backend');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
} catch (error) {
|
|
78
|
-
this.logger.warn('Failed to fetch benchmarks from Azure backend, using fallback', {
|
|
79
|
-
error: error.message
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
// Use fallback data
|
|
83
|
-
this.benchmarks = this._getFallbackBenchmarks();
|
|
84
|
-
this.lastUpdated = new Date();
|
|
85
|
-
|
|
86
|
-
} finally {
|
|
87
|
-
this.isLoading = false;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Get benchmark comparison table formatted for PHI-4 router
|
|
93
|
-
*/
|
|
94
|
-
getBenchmarkTable() {
|
|
95
|
-
const benchmarks = this.getBenchmarks();
|
|
96
|
-
|
|
97
|
-
return {
|
|
98
|
-
lastUpdated: this.lastUpdated?.toISOString() || 'unknown',
|
|
99
|
-
models: benchmarks.models || [],
|
|
100
|
-
tasks: benchmarks.tasks || {},
|
|
101
|
-
summary: this._generateBenchmarkSummary(benchmarks)
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Check if benchmarks need refresh
|
|
107
|
-
*/
|
|
108
|
-
needsRefresh() {
|
|
109
|
-
if (!this.lastUpdated) return true;
|
|
110
|
-
|
|
111
|
-
const timeSinceUpdate = Date.now() - this.lastUpdated.getTime();
|
|
112
|
-
return timeSinceUpdate > this.refreshInterval;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Fetch benchmarks from Azure backend
|
|
117
|
-
* @private
|
|
118
|
-
*/
|
|
119
|
-
async _fetchFromAzureBackend() {
|
|
120
|
-
const url = `${this.azureBackendUrl}/llm/model-benchmarks`;
|
|
121
|
-
|
|
122
|
-
// Get platform API key
|
|
123
|
-
let apiKey = null;
|
|
124
|
-
if (this.config.apiKey) {
|
|
125
|
-
apiKey = this.config.apiKey;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const fetchOptions = {
|
|
129
|
-
method: 'GET',
|
|
130
|
-
headers: {
|
|
131
|
-
'Content-Type': 'application/json',
|
|
132
|
-
...(apiKey && { 'Authorization': `Bearer ${apiKey}` })
|
|
133
|
-
},
|
|
134
|
-
timeout: 10000 // 10 second timeout
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
this.logger.debug('Fetching benchmarks from Azure backend', { url });
|
|
138
|
-
|
|
139
|
-
const response = await fetch(url, fetchOptions);
|
|
140
|
-
|
|
141
|
-
if (!response.ok) {
|
|
142
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const data = await response.json();
|
|
146
|
-
return data;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Get fallback benchmark data
|
|
151
|
-
* @private
|
|
152
|
-
*/
|
|
153
|
-
_getFallbackBenchmarks() {
|
|
154
|
-
return {
|
|
155
|
-
version: '1.0.0',
|
|
156
|
-
lastUpdated: new Date().toISOString(),
|
|
157
|
-
source: 'fallback',
|
|
158
|
-
models: [
|
|
159
|
-
{
|
|
160
|
-
name: 'anthropic-sonnet',
|
|
161
|
-
provider: 'anthropic',
|
|
162
|
-
tasks: {
|
|
163
|
-
coding: { score: 85, speed: 'medium', cost: 'medium' },
|
|
164
|
-
analysis: { score: 90, speed: 'medium', cost: 'medium' },
|
|
165
|
-
'quick-tasks': { score: 75, speed: 'fast', cost: 'low' },
|
|
166
|
-
creative: { score: 88, speed: 'medium', cost: 'medium' }
|
|
167
|
-
},
|
|
168
|
-
strengths: ['reasoning', 'code-understanding', 'analysis'],
|
|
169
|
-
contextWindow: 200000,
|
|
170
|
-
maxTokens: 4096
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
name: 'anthropic-opus',
|
|
174
|
-
provider: 'anthropic',
|
|
175
|
-
tasks: {
|
|
176
|
-
coding: { score: 92, speed: 'slow', cost: 'high' },
|
|
177
|
-
analysis: { score: 95, speed: 'slow', cost: 'high' },
|
|
178
|
-
'quick-tasks': { score: 80, speed: 'medium', cost: 'high' },
|
|
179
|
-
creative: { score: 95, speed: 'slow', cost: 'high' }
|
|
180
|
-
},
|
|
181
|
-
strengths: ['complex-reasoning', 'creative-writing', 'deep-analysis'],
|
|
182
|
-
contextWindow: 200000,
|
|
183
|
-
maxTokens: 4096
|
|
184
|
-
},
|
|
185
|
-
{
|
|
186
|
-
name: 'anthropic-haiku',
|
|
187
|
-
provider: 'anthropic',
|
|
188
|
-
tasks: {
|
|
189
|
-
coding: { score: 70, speed: 'fast', cost: 'low' },
|
|
190
|
-
analysis: { score: 75, speed: 'fast', cost: 'low' },
|
|
191
|
-
'quick-tasks': { score: 85, speed: 'very-fast', cost: 'very-low' },
|
|
192
|
-
creative: { score: 70, speed: 'fast', cost: 'low' }
|
|
193
|
-
},
|
|
194
|
-
strengths: ['speed', 'simple-tasks', 'cost-efficiency'],
|
|
195
|
-
contextWindow: 200000,
|
|
196
|
-
maxTokens: 4096
|
|
197
|
-
},
|
|
198
|
-
{
|
|
199
|
-
name: 'gpt-4',
|
|
200
|
-
provider: 'openai',
|
|
201
|
-
tasks: {
|
|
202
|
-
coding: { score: 88, speed: 'medium', cost: 'high' },
|
|
203
|
-
analysis: { score: 85, speed: 'medium', cost: 'high' },
|
|
204
|
-
'quick-tasks': { score: 80, speed: 'medium', cost: 'high' },
|
|
205
|
-
creative: { score: 90, speed: 'medium', cost: 'high' }
|
|
206
|
-
},
|
|
207
|
-
strengths: ['general-purpose', 'coding', 'problem-solving'],
|
|
208
|
-
contextWindow: 128000,
|
|
209
|
-
maxTokens: 4096
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
name: 'gpt-4-mini',
|
|
213
|
-
provider: 'openai',
|
|
214
|
-
tasks: {
|
|
215
|
-
coding: { score: 75, speed: 'fast', cost: 'low' },
|
|
216
|
-
analysis: { score: 70, speed: 'fast', cost: 'low' },
|
|
217
|
-
'quick-tasks': { score: 80, speed: 'very-fast', cost: 'very-low' },
|
|
218
|
-
creative: { score: 72, speed: 'fast', cost: 'low' }
|
|
219
|
-
},
|
|
220
|
-
strengths: ['speed', 'cost-efficiency', 'simple-coding'],
|
|
221
|
-
contextWindow: 128000,
|
|
222
|
-
maxTokens: 16384
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
name: 'azure-ai-grok3',
|
|
226
|
-
provider: 'xai',
|
|
227
|
-
tasks: {
|
|
228
|
-
coding: { score: 82, speed: 'medium', cost: 'medium' },
|
|
229
|
-
analysis: { score: 85, speed: 'medium', cost: 'medium' },
|
|
230
|
-
'quick-tasks': { score: 78, speed: 'fast', cost: 'medium' },
|
|
231
|
-
creative: { score: 88, speed: 'medium', cost: 'medium' }
|
|
232
|
-
},
|
|
233
|
-
strengths: ['reasoning', 'real-time-data', 'analysis'],
|
|
234
|
-
contextWindow: 128000,
|
|
235
|
-
maxTokens: 4096
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
name: 'deepseek-r1',
|
|
239
|
-
provider: 'deepseek',
|
|
240
|
-
tasks: {
|
|
241
|
-
coding: { score: 90, speed: 'medium', cost: 'low' },
|
|
242
|
-
analysis: { score: 80, speed: 'medium', cost: 'low' },
|
|
243
|
-
'quick-tasks': { score: 75, speed: 'fast', cost: 'very-low' },
|
|
244
|
-
creative: { score: 65, speed: 'medium', cost: 'low' }
|
|
245
|
-
},
|
|
246
|
-
strengths: ['coding', 'reasoning', 'cost-efficiency'],
|
|
247
|
-
contextWindow: 128000,
|
|
248
|
-
maxTokens: 8192
|
|
249
|
-
},
|
|
250
|
-
{
|
|
251
|
-
name: 'phi-4',
|
|
252
|
-
provider: 'microsoft',
|
|
253
|
-
tasks: {
|
|
254
|
-
coding: { score: 72, speed: 'fast', cost: 'very-low' },
|
|
255
|
-
analysis: { score: 78, speed: 'fast', cost: 'very-low' },
|
|
256
|
-
'quick-tasks': { score: 82, speed: 'very-fast', cost: 'very-low' },
|
|
257
|
-
creative: { score: 68, speed: 'fast', cost: 'very-low' }
|
|
258
|
-
},
|
|
259
|
-
strengths: ['speed', 'efficiency', 'small-tasks'],
|
|
260
|
-
contextWindow: 16384,
|
|
261
|
-
maxTokens: 2048
|
|
262
|
-
}
|
|
263
|
-
],
|
|
264
|
-
tasks: {
|
|
265
|
-
coding: {
|
|
266
|
-
description: 'Programming, debugging, code review, refactoring',
|
|
267
|
-
topModels: ['deepseek-r1', 'anthropic-opus', 'gpt-4', 'anthropic-sonnet']
|
|
268
|
-
},
|
|
269
|
-
analysis: {
|
|
270
|
-
description: 'Data analysis, research, document review, reasoning',
|
|
271
|
-
topModels: ['anthropic-opus', 'anthropic-sonnet', 'azure-ai-grok3', 'gpt-4']
|
|
272
|
-
},
|
|
273
|
-
'quick-tasks': {
|
|
274
|
-
description: 'Simple questions, formatting, quick edits, summaries',
|
|
275
|
-
topModels: ['anthropic-haiku', 'phi-4', 'gpt-4-mini', 'azure-ai-grok3']
|
|
276
|
-
},
|
|
277
|
-
creative: {
|
|
278
|
-
description: 'Writing, brainstorming, content creation, storytelling',
|
|
279
|
-
topModels: ['anthropic-opus', 'gpt-4', 'azure-ai-grok3', 'anthropic-sonnet']
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* Generate benchmark summary for router
|
|
287
|
-
* @private
|
|
288
|
-
*/
|
|
289
|
-
_generateBenchmarkSummary(benchmarks) {
|
|
290
|
-
const models = benchmarks.models || [];
|
|
291
|
-
|
|
292
|
-
return {
|
|
293
|
-
totalModels: models.length,
|
|
294
|
-
taskCategories: Object.keys(benchmarks.tasks || {}),
|
|
295
|
-
bestForCoding: this._getBestModelForTask(models, 'coding'),
|
|
296
|
-
bestForAnalysis: this._getBestModelForTask(models, 'analysis'),
|
|
297
|
-
bestForQuickTasks: this._getBestModelForTask(models, 'quick-tasks'),
|
|
298
|
-
bestForCreative: this._getBestModelForTask(models, 'creative'),
|
|
299
|
-
fastestModel: this._getFastestModel(models),
|
|
300
|
-
mostCostEfficient: this._getMostCostEfficient(models)
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
_getBestModelForTask(models, task) {
|
|
305
|
-
return models
|
|
306
|
-
.filter(m => m.tasks && m.tasks[task])
|
|
307
|
-
.sort((a, b) => (b.tasks[task].score || 0) - (a.tasks[task].score || 0))[0]?.name || 'unknown';
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
_getFastestModel(models) {
|
|
311
|
-
const speedOrder = { 'very-fast': 4, 'fast': 3, 'medium': 2, 'slow': 1 };
|
|
312
|
-
return models
|
|
313
|
-
.sort((a, b) => {
|
|
314
|
-
const aSpeed = Math.max(...Object.values(a.tasks || {}).map(t => speedOrder[t.speed] || 0));
|
|
315
|
-
const bSpeed = Math.max(...Object.values(b.tasks || {}).map(t => speedOrder[t.speed] || 0));
|
|
316
|
-
return bSpeed - aSpeed;
|
|
317
|
-
})[0]?.name || 'unknown';
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
_getMostCostEfficient(models) {
|
|
321
|
-
const costOrder = { 'very-low': 4, 'low': 3, 'medium': 2, 'high': 1 };
|
|
322
|
-
return models
|
|
323
|
-
.sort((a, b) => {
|
|
324
|
-
const aCost = Math.max(...Object.values(a.tasks || {}).map(t => costOrder[t.cost] || 0));
|
|
325
|
-
const bCost = Math.max(...Object.values(b.tasks || {}).map(t => costOrder[t.cost] || 0));
|
|
326
|
-
return bCost - aCost;
|
|
327
|
-
})[0]?.name || 'unknown';
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
/**
|
|
331
|
-
* Schedule periodic refresh
|
|
332
|
-
* @private
|
|
333
|
-
*/
|
|
334
|
-
_scheduleRefresh() {
|
|
335
|
-
setInterval(async () => {
|
|
336
|
-
if (this.needsRefresh()) {
|
|
337
|
-
this.logger.debug('Refreshing benchmark data');
|
|
338
|
-
await this.loadBenchmarks();
|
|
339
|
-
}
|
|
340
|
-
}, this.refreshInterval);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
/**
|
|
344
|
-
* Force refresh benchmarks
|
|
345
|
-
*/
|
|
346
|
-
async forceRefresh() {
|
|
347
|
-
this.logger.info('Force refreshing benchmark data');
|
|
348
|
-
await this.loadBenchmarks();
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* Get service status
|
|
353
|
-
*/
|
|
354
|
-
getStatus() {
|
|
355
|
-
return {
|
|
356
|
-
initialized: !!this.benchmarks,
|
|
357
|
-
lastUpdated: this.lastUpdated?.toISOString() || null,
|
|
358
|
-
source: this.benchmarks?.source || 'unknown',
|
|
359
|
-
modelCount: this.benchmarks?.models?.length || 0,
|
|
360
|
-
isLoading: this.isLoading,
|
|
361
|
-
needsRefresh: this.needsRefresh()
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
export default BenchmarkService;
|
|
1
|
+
function a0_0xb4ed(){const _0x1611b0=['x2DLDejLC3rnB2rLBezVCLrHC2S','yxbPs2v5','mJC0odqWmeLpB1rbsW','mtqWmdm0oxrHs2vIrW','rMfPBgvKihrVigLUAxrPywXPEMuGyMvUy2HTyxjRihnLCNzPy2uGlsbotYbgquXmqKfdsW','Bg9Nz2vY','x2DLBMvYyxrLqMvUy2HTyxjRu3vTBwfYEq','sfruuca','z2v0vgLTzq','DgfZA3m','yMvUy2HTyxjRCW','yw5HBhLZAxm','Dw5RBM93BG','z2v0qMvUy2HTyxjRCW','mtG4mdiWmKLLswf5sq','BwfW','BMvLzhnszwzYzxnO','z2v0u3rHDhvZ','CMvMCMvZAeLUDgvYDMfS','A2v5CW','qMvUy2HTyxjRigXVywrPBMCGywXYzwfKEsbPBIbWCM9NCMvZCW','z2v0qMvUy2HTyxjRvgfIBgu','Bg9HzejLBMnOBwfYA3m','y29ZDa','mtm4nZq3qMr5EeLt','nevXruX1BG','DMfSDwvZ','qMvUy2HTyxjRihnLCNzPy2uGAw5PDgLHBgL6zwq','x2DLDezHC3rLC3rnB2rLBa','ANnVBG','qMvHCMvYia','Aw5MBW','C3bLzwq','x2DLDe1VC3rdB3n0rwzMAwnPzw50','C3rHDhvZvgv4Da','mZe0nJq5ovPWAeTOzW','qKvoq0Hnqvjlx1jfrLjfu0HFsu5urvjwquW','C3rHDhvZ','BgvUz3rO','zgvIDwC','zxjYB3i','C2nVCMu','BgfZDfvWzgf0zwq','Bw9KzwXZ','ode3mZy1nwjwEuHvtG','ndi0q0fcCKTL','Bwf4','odG4mZqXs21rwvLI'];a0_0xb4ed=function(){return _0x1611b0;};return a0_0xb4ed();}const a0_0x1da0d4=a0_0x4498;(function(_0x7a72b7,_0x490e78){const _0x515f2d=a0_0x4498,_0x25d4b3=_0x7a72b7();while(!![]){try{const _0x1cc297=-parseInt(_0x515f2d(0xb1))/0x1+-parseInt(_0x515f2d(0xb4))/0x2+parseInt(_0x515f2d(0xb5))/0x3*(parseInt(_0x515f2d(0x9b))/0x4)+parseInt(_0x515f2d(0xae))/0x5+parseInt(_0x515f2d(0x90))/0x6+parseInt(_0x515f2d(0x9a))/0x7*(parseInt(_0x515f2d(0xaf))/0x8)+-parseInt(_0x515f2d(0xa5))/0x9;if(_0x1cc297===_0x490e78)break;else _0x25d4b3['push'](_0x25d4b3['shift']());}catch(_0x4114b6){_0x25d4b3['push'](_0x25d4b3['shift']());}}}(a0_0xb4ed,0xd04fa));import{MODEL_ROUTER_CONFIG,HTTP_STATUS}from'../utilities/constants.js';class BenchmarkService{constructor(_0x5c7edb,_0x208189){const _0x2087ff=a0_0x4498;this['config']=_0x5c7edb,this['logger']=_0x208189,this[_0x2087ff(0xbc)]=null,this[_0x2087ff(0xac)]=null,this['isLoading']=![],this['azureBackendUrl']='https://autopilot-api.azurewebsites.net',this['refreshInterval']=MODEL_ROUTER_CONFIG[_0x2087ff(0xa6)];}async['initialize'](){const _0xe95e9f=a0_0x4498;try{await this['loadBenchmarks'](),this['_scheduleRefresh'](),this[_0xe95e9f(0xb7)][_0xe95e9f(0xa1)](_0xe95e9f(0x9d));}catch(_0x43e9f9){this[_0xe95e9f(0xb7)]['error'](_0xe95e9f(0xb6),{'error':_0x43e9f9['message']}),this['benchmarks']=null;}}[a0_0x1da0d4(0xbf)](){if(!this['benchmarks'])return this['logger']['error']('No\x20benchmark\x20data\x20available\x20-\x20API\x20fetch\x20failed',{'message':'Benchmarks must be fetched from Azure backend','retryRecommended':!![]}),null;return this['benchmarks'];}async[a0_0x1da0d4(0x98)](){const _0x56c4e8=a0_0x1da0d4;if(this['isLoading']){this['logger']['debug'](_0x56c4e8(0x96));return;}this['isLoading']=!![];try{const _0x4a7220=await this['_fetchFromAzureBackend']();if(_0x4a7220)this[_0x56c4e8(0xbc)]=_0x4a7220,this['lastUpdated']=new Date(),this[_0x56c4e8(0xb7)][_0x56c4e8(0xa1)]('Benchmarks loaded from Azure backend',{'modelCount':_0x4a7220[_0x56c4e8(0xad)]?.[_0x56c4e8(0xa8)]||0x0});else throw new Error('No benchmark data received from backend');}catch(_0x3d3912){this[_0x56c4e8(0xb7)][_0x56c4e8(0xaa)]('Failed to fetch benchmarks from Azure backend - NO FALLBACK',{'error':_0x3d3912['message'],'endpoint':url}),!this['benchmarks']&&(this[_0x56c4e8(0xbc)]=null);}finally{this['isLoading']=![];}}[a0_0x1da0d4(0x97)](){const _0x35e4aa=a0_0x1da0d4,_0x10a088=this[_0x35e4aa(0xbf)]();return{'lastUpdated':this[_0x35e4aa(0xac)]?.['toISOString']()||_0x35e4aa(0xbe),'models':_0x10a088['models']||[],'tasks':_0x10a088[_0x35e4aa(0xbb)]||{},'summary':this[_0x35e4aa(0xb8)](_0x10a088)};}[a0_0x1da0d4(0x92)](){const _0x5bd2bf=a0_0x1da0d4;if(!this['lastUpdated'])return!![];const _0x205cc1=Date['now']()-this[_0x5bd2bf(0xac)][_0x5bd2bf(0xba)]();return _0x205cc1>this[_0x5bd2bf(0x94)];}async['_fetchFromAzureBackend'](){const _0x3cba4b=a0_0x1da0d4,_0x656b53=this['azureBackendUrl']+'/llm/model-benchmarks';let _0x364916=null;this['config'][_0x3cba4b(0xb3)]&&(_0x364916=this['config']['apiKey']);const _0x36868a={'method':'GET','headers':{'Content-Type':'application/json',..._0x364916&&{'Authorization':_0x3cba4b(0xa0)+_0x364916}},'timeout':0x2710};this['logger'][_0x3cba4b(0xa9)]('Fetching benchmarks from Azure backend',{'url':_0x656b53});const _0x1f7168=await fetch(_0x656b53,_0x36868a);if(!_0x1f7168['ok'])throw new Error(_0x3cba4b(0xb9)+_0x1f7168[_0x3cba4b(0xa7)]+':\x20'+_0x1f7168[_0x3cba4b(0xa4)]);const _0x23a216=await _0x1f7168[_0x3cba4b(0x9f)]();return _0x23a216;}['_generateBenchmarkSummary'](_0x254d85){const _0x5484bb=a0_0x1da0d4,_0x422e75=_0x254d85['models']||[];return{'totalModels':_0x422e75['length'],'taskCategories':Object[_0x5484bb(0x95)](_0x254d85[_0x5484bb(0xbb)]||{}),'bestForCoding':this[_0x5484bb(0xb2)](_0x422e75,'coding'),'bestForAnalysis':this['_getBestModelForTask'](_0x422e75,_0x5484bb(0xbd)),'bestForQuickTasks':this[_0x5484bb(0xb2)](_0x422e75,'quick-tasks'),'bestForCreative':this['_getBestModelForTask'](_0x422e75,'creative'),'fastestModel':this[_0x5484bb(0x9e)](_0x422e75),'mostCostEfficient':this[_0x5484bb(0xa3)](_0x422e75)};}['_getBestModelForTask'](_0x1d9e8a,_0x82cd78){const _0x28af87=a0_0x1da0d4;return _0x1d9e8a['filter'](_0x2acf5e=>_0x2acf5e[_0x28af87(0xbb)]&&_0x2acf5e[_0x28af87(0xbb)][_0x82cd78])['sort']((_0x2b5342,_0x599307)=>(_0x599307[_0x28af87(0xbb)][_0x82cd78]['score']||0x0)-(_0x2b5342[_0x28af87(0xbb)][_0x82cd78][_0x28af87(0xab)]||0x0))[0x0]?.['name']||'unknown';}[a0_0x1da0d4(0x9e)](_0x483887){const _0x247a03={'very-fast':0x4,'fast':0x3,'medium':0x2,'slow':0x1};return _0x483887['sort']((_0x57e0bf,_0x2db19c)=>{const _0x64f8c7=a0_0x4498,_0x4d21c0=Math['max'](...Object[_0x64f8c7(0x9c)](_0x57e0bf[_0x64f8c7(0xbb)]||{})['map'](_0x44ca8d=>_0x247a03[_0x44ca8d[_0x64f8c7(0xa2)]]||0x0)),_0x150370=Math[_0x64f8c7(0xb0)](...Object['values'](_0x2db19c['tasks']||{})[_0x64f8c7(0x91)](_0x1298be=>_0x247a03[_0x1298be[_0x64f8c7(0xa2)]]||0x0));return _0x150370-_0x4d21c0;})[0x0]?.['name']||'unknown';}[a0_0x1da0d4(0xa3)](_0x2ff3f3){const _0x1298e7=a0_0x1da0d4,_0x314592={'very-low':0x4,'low':0x3,'medium':0x2,'high':0x1};return _0x2ff3f3['sort']((_0xde4823,_0x521d89)=>{const _0xfae019=a0_0x4498,_0x25428e=Math['max'](...Object['values'](_0xde4823[_0xfae019(0xbb)]||{})[_0xfae019(0x91)](_0x6b49a2=>_0x314592[_0x6b49a2[_0xfae019(0x99)]]||0x0)),_0x28a208=Math[_0xfae019(0xb0)](...Object[_0xfae019(0x9c)](_0x521d89[_0xfae019(0xbb)]||{})['map'](_0x151527=>_0x314592[_0x151527[_0xfae019(0x99)]]||0x0));return _0x28a208-_0x25428e;})[0x0]?.['name']||_0x1298e7(0xbe);}['_scheduleRefresh'](){const _0x56591a=a0_0x1da0d4;setInterval(async()=>{const _0x3286de=a0_0x4498;this[_0x3286de(0x92)]()&&(this['logger'][_0x3286de(0xa9)]('Refreshing\x20benchmark\x20data'),await this['loadBenchmarks']());},this[_0x56591a(0x94)]);}async['forceRefresh'](){const _0x299576=a0_0x1da0d4;this['logger'][_0x299576(0xa1)]('Force\x20refreshing\x20benchmark\x20data'),await this['loadBenchmarks']();}[a0_0x1da0d4(0x93)](){const _0x317f9=a0_0x1da0d4;return{'initialized':!!this['benchmarks'],'lastUpdated':this['lastUpdated']?.['toISOString']()||null,'source':this[_0x317f9(0xbc)]?.['source']||'unknown','modelCount':this[_0x317f9(0xbc)]?.[_0x317f9(0xad)]?.[_0x317f9(0xa8)]||0x0,'isLoading':this['isLoading'],'needsRefresh':this['needsRefresh']()};}}function a0_0x4498(_0x3f4d6b,_0x922b86){_0x3f4d6b=_0x3f4d6b-0x90;const _0xb4ed2e=a0_0xb4ed();let _0x449852=_0xb4ed2e[_0x3f4d6b];if(a0_0x4498['elFYsY']===undefined){var _0x3b950b=function(_0x3ff57e){const _0x4ab107='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x5c7edb='',_0x208189='';for(let _0x43e9f9=0x0,_0x4a7220,_0x3d3912,_0x10a088=0x0;_0x3d3912=_0x3ff57e['charAt'](_0x10a088++);~_0x3d3912&&(_0x4a7220=_0x43e9f9%0x4?_0x4a7220*0x40+_0x3d3912:_0x3d3912,_0x43e9f9++%0x4)?_0x5c7edb+=String['fromCharCode'](0xff&_0x4a7220>>(-0x2*_0x43e9f9&0x6)):0x0){_0x3d3912=_0x4ab107['indexOf'](_0x3d3912);}for(let _0x205cc1=0x0,_0x656b53=_0x5c7edb['length'];_0x205cc1<_0x656b53;_0x205cc1++){_0x208189+='%'+('00'+_0x5c7edb['charCodeAt'](_0x205cc1)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x208189);};a0_0x4498['mrpKJu']=_0x3b950b,a0_0x4498['cPzojX']={},a0_0x4498['elFYsY']=!![];}const _0x321aab=_0xb4ed2e[0x0],_0x253b34=_0x3f4d6b+_0x321aab,_0x2376d2=a0_0x4498['cPzojX'][_0x253b34];return!_0x2376d2?(_0x449852=a0_0x4498['mrpKJu'](_0x449852),a0_0x4498['cPzojX'][_0x253b34]=_0x449852):_0x449852=_0x2376d2,_0x449852;}export default BenchmarkService;
|