@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.
- 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 +15 -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
|
+
function a0_0xc30d(_0x3064c0,_0x5860a0){_0x3064c0=_0x3064c0-0x11d;const _0x48d27c=a0_0x48d2();let _0xc30da=_0x48d27c[_0x3064c0];if(a0_0xc30d['mCwxzB']===undefined){var _0x533422=function(_0x4f3802){const _0x3af920='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x40d8fd='',_0x25ca01='';for(let _0x2bcf34=0x0,_0x310495,_0x237e07,_0x2cc361=0x0;_0x237e07=_0x4f3802['charAt'](_0x2cc361++);~_0x237e07&&(_0x310495=_0x2bcf34%0x4?_0x310495*0x40+_0x237e07:_0x237e07,_0x2bcf34++%0x4)?_0x40d8fd+=String['fromCharCode'](0xff&_0x310495>>(-0x2*_0x2bcf34&0x6)):0x0){_0x237e07=_0x3af920['indexOf'](_0x237e07);}for(let _0x56b7d5=0x0,_0x127e78=_0x40d8fd['length'];_0x56b7d5<_0x127e78;_0x56b7d5++){_0x25ca01+='%'+('00'+_0x40d8fd['charCodeAt'](_0x56b7d5)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x25ca01);};a0_0xc30d['PbePRf']=_0x533422,a0_0xc30d['bQuZLo']={},a0_0xc30d['mCwxzB']=!![];}const _0x418927=_0x48d27c[0x0],_0x33da7a=_0x3064c0+_0x418927,_0x3a4dc5=a0_0xc30d['bQuZLo'][_0x33da7a];return!_0x3a4dc5?(_0xc30da=a0_0xc30d['PbePRf'](_0xc30da),a0_0xc30d['bQuZLo'][_0x33da7a]=_0xc30da):_0xc30da=_0x3a4dc5,_0xc30da;}const a0_0x5c8590=a0_0xc30d;(function(_0x252a51,_0x17caee){const _0x2c47e0=a0_0xc30d,_0xabd73f=_0x252a51();while(!![]){try{const _0x20b9b4=parseInt(_0x2c47e0(0x120))/0x1+parseInt(_0x2c47e0(0x11d))/0x2*(parseInt(_0x2c47e0(0x12e))/0x3)+-parseInt(_0x2c47e0(0x131))/0x4+-parseInt(_0x2c47e0(0x129))/0x5+parseInt(_0x2c47e0(0x123))/0x6*(parseInt(_0x2c47e0(0x127))/0x7)+-parseInt(_0x2c47e0(0x122))/0x8+parseInt(_0x2c47e0(0x12d))/0x9*(parseInt(_0x2c47e0(0x133))/0xa);if(_0x20b9b4===_0x17caee)break;else _0xabd73f['push'](_0xabd73f['shift']());}catch(_0x17bf23){_0xabd73f['push'](_0xabd73f['shift']());}}}(a0_0x48d2,0x4ad03));class ApiKeyManager{constructor(_0x40d8fd){const _0x11f10c=a0_0xc30d;this[_0x11f10c(0x136)]=_0x40d8fd,this['sessionKeys']=new Map(),this['globalKeys']={'loxiaApiKey':null,'vendorKeys':{}};}['setSessionKeys'](_0x25ca01,_0x2bcf34){const _0x40fbe7=a0_0xc30d;if(!_0x25ca01)throw new Error('Session\x20ID\x20is\x20required');this['sessionKeys'][_0x40fbe7(0x12b)](_0x25ca01,{'loxiaApiKey':_0x2bcf34['loxiaApiKey']||null,'vendorKeys':_0x2bcf34['vendorKeys']||{},'updatedAt':new Date()['toISOString']()}),this['logger']?.['info'](_0x40fbe7(0x126),{'sessionId':_0x25ca01,'hasLoxiaKey':!!_0x2bcf34[_0x40fbe7(0x12f)],'vendorKeys':Object[_0x40fbe7(0x121)](_0x2bcf34[_0x40fbe7(0x13a)]||{}),'timestamp':new Date()['toISOString']()});}[a0_0x5c8590(0x125)](_0x310495){const _0x230e5d=a0_0x5c8590;if(!_0x310495)return this[_0x230e5d(0x128)];const _0x237e07=this['sessionKeys'][_0x230e5d(0x137)](_0x310495);if(_0x237e07)return _0x237e07;return this[_0x230e5d(0x128)];}['getKeysForRequest'](_0x2cc361,_0x56b7d5={}){const _0xf13782=a0_0x5c8590,_0x127e78=this[_0xf13782(0x125)](_0x2cc361),_0xaf6d55={'loxiaApiKey':_0x127e78['loxiaApiKey'],'vendorApiKey':null};return!_0x56b7d5[_0xf13782(0x132)]&&_0x56b7d5[_0xf13782(0x11e)]&&_0x127e78['vendorKeys']&&(_0xaf6d55[_0xf13782(0x11f)]=_0x127e78[_0xf13782(0x13a)][_0x56b7d5[_0xf13782(0x11e)]]),_0xaf6d55;}['removeSessionKeys'](_0x8449f1){const _0x294bd0=a0_0x5c8590;if(this[_0x294bd0(0x12a)][_0x294bd0(0x139)](_0x8449f1))return this[_0x294bd0(0x136)]?.[_0x294bd0(0x130)]('API\x20keys\x20removed\x20for\x20session',{'sessionId':_0x8449f1}),!![];return![];}['setGlobalKeys'](_0x234081){const _0x5b3d9c=a0_0x5c8590;this['globalKeys']={'loxiaApiKey':_0x234081[_0x5b3d9c(0x12f)]||this['globalKeys']['loxiaApiKey'],'vendorKeys':{...this['globalKeys'][_0x5b3d9c(0x13a)],..._0x234081[_0x5b3d9c(0x13a)]||{}}},this[_0x5b3d9c(0x136)]?.['info']('Global\x20API\x20keys\x20updated',{'hasLoxiaKey':!!this[_0x5b3d9c(0x128)][_0x5b3d9c(0x12f)],'vendorKeys':Object[_0x5b3d9c(0x121)](this[_0x5b3d9c(0x128)]['vendorKeys'])});}[a0_0x5c8590(0x134)](){const _0x512641=a0_0x5c8590;return Array['from'](this['sessionKeys'][_0x512641(0x135)]())['map'](([_0x40914b,_0x19c252])=>({'sessionId':_0x40914b,'hasLoxiaKey':!!_0x19c252['loxiaApiKey'],'vendorKeys':Object['keys'](_0x19c252[_0x512641(0x13a)]||{}),'updatedAt':_0x19c252['updatedAt']}));}[a0_0x5c8590(0x138)](_0x2325f1=0x18*0x3c*0x3c*0x3e8){const _0x874c0e=a0_0x5c8590,_0x1f4c10=Date['now'](),_0x2024a3=[];for(const [_0x11cdaf,_0x47a319]of this['sessionKeys']['entries']()){const _0x2b325a=_0x1f4c10-new Date(_0x47a319['updatedAt'])['getTime']();_0x2b325a>_0x2325f1&&_0x2024a3['push'](_0x11cdaf);}return _0x2024a3[_0x874c0e(0x124)](_0x4d3db0=>{const _0x439deb=_0x874c0e;this[_0x439deb(0x12a)][_0x439deb(0x139)](_0x4d3db0);}),_0x2024a3['length']>0x0&&this['logger']?.[_0x874c0e(0x130)]('Cleaned\x20up\x20expired\x20API\x20key\x20sessions',{'expiredSessions':_0x2024a3[_0x874c0e(0x12c)],'remainingSessions':this['sessionKeys']['size']}),_0x2024a3['length'];}}export default ApiKeyManager;function a0_0x48d2(){const _0xf05bf6=['zw50CMLLCW','Bg9Nz2vY','z2v0','y2XLyw51Cev4CgLYzwrtzxnZAw9UCW','zgvSzxrL','DMvUzg9Ys2v5CW','ng9Ks2L2sG','DMvUzg9Y','DMvUzg9YqxbPs2v5','mJG5ntm0Agv0ANbA','A2v5CW','nJKZnZiWDKPxsvzK','nteWntrise5rBhG','zM9YrwfJAa','z2v0u2vZC2LVBKTLExm','qvbjigTLExmGDxbKyxrLzcbMB3iGC2vZC2LVBG','mtG5ufzxCvLU','z2XVyMfSs2v5CW','mJi5ndy1nuves3DKBG','C2vZC2LVBKTLExm','C2v0','BgvUz3rO','mtuXmK9fBwDABq','nZuXnJm4wNfYswr0','Bg94AwfbCgLlzxK','Aw5MBW','mtyZmda4mhLnDvzerq','CgXHDgzVCM1qCM92AwrLza','mtqYndbyExrerfa','z2v0qwn0AxzLu2vZC2LVBNm'];a0_0x48d2=function(){return _0xf05bf6;};return a0_0x48d2();}
|
|
@@ -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
|
+
const a0_0x1015cd=a0_0x471c;(function(_0x519a00,_0x269bae){const _0x560bdf=a0_0x471c,_0x2a94fa=_0x519a00();while(!![]){try{const _0x2995b1=parseInt(_0x560bdf(0x1ad))/0x1*(-parseInt(_0x560bdf(0x19e))/0x2)+parseInt(_0x560bdf(0x198))/0x3*(parseInt(_0x560bdf(0x1ae))/0x4)+-parseInt(_0x560bdf(0x184))/0x5*(-parseInt(_0x560bdf(0x191))/0x6)+-parseInt(_0x560bdf(0x1af))/0x7*(parseInt(_0x560bdf(0x1ac))/0x8)+parseInt(_0x560bdf(0x1a7))/0x9*(parseInt(_0x560bdf(0x194))/0xa)+-parseInt(_0x560bdf(0x1b0))/0xb+-parseInt(_0x560bdf(0x19c))/0xc;if(_0x2995b1===_0x269bae)break;else _0x2a94fa['push'](_0x2a94fa['shift']());}catch(_0xcb5616){_0x2a94fa['push'](_0x2a94fa['shift']());}}}(a0_0x16ef,0x6cab4));function a0_0x471c(_0x19843c,_0x5bd363){_0x19843c=_0x19843c-0x17d;const _0x16ef40=a0_0x16ef();let _0x471c6f=_0x16ef40[_0x19843c];if(a0_0x471c['wHbQuk']===undefined){var _0x5e9719=function(_0x2b611d){const _0x3c6694='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0xcdf71c='',_0x4c18b2='';for(let _0x540f79=0x0,_0x970edf,_0x214a99,_0x190987=0x0;_0x214a99=_0x2b611d['charAt'](_0x190987++);~_0x214a99&&(_0x970edf=_0x540f79%0x4?_0x970edf*0x40+_0x214a99:_0x214a99,_0x540f79++%0x4)?_0xcdf71c+=String['fromCharCode'](0xff&_0x970edf>>(-0x2*_0x540f79&0x6)):0x0){_0x214a99=_0x3c6694['indexOf'](_0x214a99);}for(let _0x5efe09=0x0,_0x519d2f=_0xcdf71c['length'];_0x5efe09<_0x519d2f;_0x5efe09++){_0x4c18b2+='%'+('00'+_0xcdf71c['charCodeAt'](_0x5efe09)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x4c18b2);};a0_0x471c['GnIGaX']=_0x5e9719,a0_0x471c['CJAmwa']={},a0_0x471c['wHbQuk']=!![];}const _0x3ffb79=_0x16ef40[0x0],_0x50844c=_0x19843c+_0x3ffb79,_0x20dfbc=a0_0x471c['CJAmwa'][_0x50844c];return!_0x20dfbc?(_0x471c6f=a0_0x471c['GnIGaX'](_0x471c6f),a0_0x471c['CJAmwa'][_0x50844c]=_0x471c6f):_0x471c6f=_0x20dfbc,_0x471c6f;}import{MODEL_ROUTER_CONFIG,HTTP_STATUS}from'../utilities/constants.js';class BenchmarkService{constructor(_0xcdf71c,_0x4c18b2){const _0x5edaf5=a0_0x471c;this['config']=_0xcdf71c,this['logger']=_0x4c18b2,this['benchmarks']=null,this['lastUpdated']=null,this[_0x5edaf5(0x19b)]=![],this[_0x5edaf5(0x180)]='https://autopilot-api.azurewebsites.net',this['refreshInterval']=MODEL_ROUTER_CONFIG[_0x5edaf5(0x181)];}async['initialize'](){const _0xc7b8e2=a0_0x471c;try{await this[_0xc7b8e2(0x1b3)](),this[_0xc7b8e2(0x1a8)](),this['logger']['info'](_0xc7b8e2(0x1aa));}catch(_0x540f79){this['logger']['error']('Failed\x20to\x20initialize\x20benchmark\x20service\x20-\x20NO\x20FALLBACK',{'error':_0x540f79['message']}),this['benchmarks']=null;}}[a0_0x1015cd(0x1a3)](){const _0x48924a=a0_0x1015cd;if(!this[_0x48924a(0x17e)])return this[_0x48924a(0x19d)][_0x48924a(0x18d)](_0x48924a(0x193),{'message':'Benchmarks must be fetched from Azure backend','retryRecommended':!![]}),null;return this[_0x48924a(0x17e)];}async[a0_0x1015cd(0x1b3)](){const _0x28d662=a0_0x1015cd;if(this['isLoading']){this['logger']['debug'](_0x28d662(0x1a6));return;}this[_0x28d662(0x19b)]=!![];try{const _0x970edf=await this[_0x28d662(0x1ab)]();if(_0x970edf)this['benchmarks']=_0x970edf,this[_0x28d662(0x18e)]=new Date(),this['logger'][_0x28d662(0x189)]('Benchmarks loaded from Azure backend',{'modelCount':_0x970edf['models']?.[_0x28d662(0x1a5)]||0x0});else throw new Error('No benchmark data received from backend');}catch(_0x214a99){this[_0x28d662(0x19d)]['error']('Failed to fetch benchmarks from Azure backend - NO FALLBACK',{'error':_0x214a99[_0x28d662(0x1a2)],'endpoint':url}),!this['benchmarks']&&(this['benchmarks']=null);}finally{this['isLoading']=![];}}['getBenchmarkTable'](){const _0x229b0d=a0_0x1015cd,_0x190987=this['getBenchmarks']();return{'lastUpdated':this[_0x229b0d(0x18e)]?.[_0x229b0d(0x195)]()||_0x229b0d(0x183),'models':_0x190987[_0x229b0d(0x1a1)]||[],'tasks':_0x190987[_0x229b0d(0x19f)]||{},'summary':this[_0x229b0d(0x19a)](_0x190987)};}[a0_0x1015cd(0x1b4)](){const _0x26fdb5=a0_0x1015cd;if(!this['lastUpdated'])return!![];const _0x5efe09=Date[_0x26fdb5(0x187)]()-this[_0x26fdb5(0x18e)][_0x26fdb5(0x186)]();return _0x5efe09>this['refreshInterval'];}async['_fetchFromAzureBackend'](){const _0xb54ae6=a0_0x1015cd,_0x519d2f=this[_0xb54ae6(0x180)]+'/llm/model-benchmarks';let _0x2576fb=null;this['config'][_0xb54ae6(0x18f)]&&(_0x2576fb=this[_0xb54ae6(0x185)]['apiKey']);const _0x1d092b={'method':'GET','headers':{'Content-Type':'application/json',..._0x2576fb&&{'Authorization':'Bearer\x20'+_0x2576fb}},'timeout':0x2710};this['logger']['debug']('Fetching benchmarks from Azure backend',{'url':_0x519d2f});const _0x25acfa=await fetch(_0x519d2f,_0x1d092b);if(!_0x25acfa['ok'])throw new Error('HTTP\x20'+_0x25acfa['status']+':\x20'+_0x25acfa['statusText']);const _0x4e11a7=await _0x25acfa['json']();return _0x4e11a7;}['_generateBenchmarkSummary'](_0x45e1d6){const _0x399acf=a0_0x1015cd,_0x521200=_0x45e1d6['models']||[];return{'totalModels':_0x521200[_0x399acf(0x1a5)],'taskCategories':Object['keys'](_0x45e1d6['tasks']||{}),'bestForCoding':this['_getBestModelForTask'](_0x521200,_0x399acf(0x1b1)),'bestForAnalysis':this[_0x399acf(0x1a0)](_0x521200,'analysis'),'bestForQuickTasks':this['_getBestModelForTask'](_0x521200,'quick-tasks'),'bestForCreative':this['_getBestModelForTask'](_0x521200,_0x399acf(0x1a9)),'fastestModel':this[_0x399acf(0x1a4)](_0x521200),'mostCostEfficient':this['_getMostCostEfficient'](_0x521200)};}['_getBestModelForTask'](_0x16d476,_0xef6174){const _0x4b1475=a0_0x1015cd;return _0x16d476[_0x4b1475(0x196)](_0x596a7d=>_0x596a7d['tasks']&&_0x596a7d['tasks'][_0xef6174])[_0x4b1475(0x18c)]((_0x218f14,_0x233162)=>(_0x233162['tasks'][_0xef6174]['score']||0x0)-(_0x218f14['tasks'][_0xef6174]['score']||0x0))[0x0]?.[_0x4b1475(0x197)]||_0x4b1475(0x183);}['_getFastestModel'](_0x20ba8c){const _0xd510a2=a0_0x1015cd,_0x4ccf29={'very-fast':0x4,'fast':0x3,'medium':0x2,'slow':0x1};return _0x20ba8c['sort']((_0x24fa3f,_0xbdfeea)=>{const _0x7b0612=a0_0x471c,_0x116683=Math['max'](...Object[_0x7b0612(0x188)](_0x24fa3f[_0x7b0612(0x19f)]||{})['map'](_0x56fc20=>_0x4ccf29[_0x56fc20[_0x7b0612(0x1b2)]]||0x0)),_0x259b8c=Math['max'](...Object['values'](_0xbdfeea['tasks']||{})['map'](_0xf1031c=>_0x4ccf29[_0xf1031c[_0x7b0612(0x1b2)]]||0x0));return _0x259b8c-_0x116683;})[0x0]?.[_0xd510a2(0x197)]||_0xd510a2(0x183);}[a0_0x1015cd(0x192)](_0x5cbf53){const _0x3c85b7=a0_0x1015cd,_0x235131={'very-low':0x4,'low':0x3,'medium':0x2,'high':0x1};return _0x5cbf53['sort']((_0x219589,_0x343f73)=>{const _0x4a4e0a=a0_0x471c,_0x5a84ab=Math[_0x4a4e0a(0x18a)](...Object['values'](_0x219589['tasks']||{})[_0x4a4e0a(0x190)](_0x15f7c4=>_0x235131[_0x15f7c4['cost']]||0x0)),_0xcfe481=Math['max'](...Object['values'](_0x343f73[_0x4a4e0a(0x19f)]||{})['map'](_0x449170=>_0x235131[_0x449170['cost']]||0x0));return _0xcfe481-_0x5a84ab;})[0x0]?.[_0x3c85b7(0x197)]||_0x3c85b7(0x183);}['_scheduleRefresh'](){const _0x7155a1=a0_0x1015cd;setInterval(async()=>{const _0x5290b7=a0_0x471c;this[_0x5290b7(0x1b4)]()&&(this[_0x5290b7(0x19d)][_0x5290b7(0x17d)]('Refreshing\x20benchmark\x20data'),await this['loadBenchmarks']());},this[_0x7155a1(0x18b)]);}async[a0_0x1015cd(0x199)](){const _0x363a0a=a0_0x1015cd;this[_0x363a0a(0x19d)][_0x363a0a(0x189)](_0x363a0a(0x182)),await this['loadBenchmarks']();}['getStatus'](){const _0x503a7b=a0_0x1015cd;return{'initialized':!!this['benchmarks'],'lastUpdated':this['lastUpdated']?.[_0x503a7b(0x195)]()||null,'source':this['benchmarks']?.[_0x503a7b(0x17f)]||'unknown','modelCount':this['benchmarks']?.[_0x503a7b(0x1a1)]?.['length']||0x0,'isLoading':this['isLoading'],'needsRefresh':this[_0x503a7b(0x1b4)]()};}}function a0_0x16ef(){const _0x578dfd=['nJzqAfLjwgi','DgfZA3m','x2DLDejLC3rnB2rLBezVCLrHC2S','Bw9KzwXZ','BwvZC2fNzq','z2v0qMvUy2HTyxjRCW','x2DLDezHC3rLC3rnB2rLBa','BgvUz3rO','qMvUy2HTyxjRigXVywrPBMCGywXYzwfKEsbPBIbWCM9NCMvZCW','mJDnAMn6vKG','x3nJAgvKDwXLuMvMCMvZAa','y3jLyxrPDMu','qMvUy2HTyxjRihnLCNzPy2uGAw5PDgLHBgL6zwq','x2zLDgnOrNjVBuf6DxjLqMfJA2vUza','mteYDMHMyKHO','otq2n0DTvLbUwq','mZi5mMTbyKz6zG','odi4mZfMB2vPzKi','mtmZntCXoxfMsev2za','y29KAw5N','C3bLzwq','Bg9HzejLBMnOBwfYA3m','BMvLzhnszwzYzxnO','zgvIDwC','yMvUy2HTyxjRCW','C291CMnL','yxP1CMvcywnRzw5KvxjS','qKvoq0Hnqvjlx1jfrLjfu0HFsu5urvjwquW','rM9Yy2uGCMvMCMvZAgLUzYbIzw5JAg1HCMSGzgf0yq','Dw5RBM93BG','nwv0uhjICG','y29UzMLN','z2v0vgLTzq','BM93','DMfSDwvZ','Aw5MBW','Bwf4','CMvMCMvZAeLUDgvYDMfS','C29YDa','zxjYB3i','BgfZDfvWzgf0zwq','yxbPs2v5','BwfW','ndi0mtK0nMvPy2vSqG','x2DLDe1VC3rdB3n0rwzMAwnPzw50','tM8GyMvUy2HTyxjRigrHDgeGyxzHAwXHyMXLic0GqvbjigzLDgnOigzHAwXLza','mtK1nJm5mg5bC2rTDW','Dg9ju09tDhjPBMC','zMLSDgvY','BMfTzq','mJa3vuvbs3v3','zM9Yy2vszwzYzxnO','x2DLBMvYyxrLqMvUy2HTyxjRu3vTBwfYEq','AxnmB2fKAw5N','mZy3mZaYmgDJt1DcBa','Bg9Nz2vY'];a0_0x16ef=function(){return _0x578dfd;};return a0_0x16ef();}export default BenchmarkService;
|