devicely 2.2.13 → 2.2.14
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/bin/devicely.js +1 -1
- package/lib/advanced-logger.js +1 -1
- package/lib/androidDeviceDetection.js +1 -1
- package/lib/appMappings.js +1 -1
- package/lib/commanderService.js +1 -1
- package/lib/deviceDetection.js +1 -1
- package/lib/devices.js +1 -1
- package/lib/doctor.js +1 -1
- package/lib/encryption.js +1 -1
- package/lib/executor.js +1 -1
- package/lib/hybridAI.js +1 -1
- package/lib/intelligentLocatorService.js +1 -1
- package/lib/lightweightAI.js +1 -1
- package/lib/localBuiltInAI.js +1 -1
- package/lib/localBuiltInAI_backup.js +1 -1
- package/lib/localBuiltInAI_simple.js +1 -1
- package/lib/locatorStrategy.js +1 -1
- package/lib/logger-demo.js +1 -1
- package/lib/logger.js +1 -1
- package/lib/quick-start-logger.js +1 -1
- package/lib/scriptLoader.js +1 -1
- package/lib/server.js +1 -1
- package/lib/tensorflowAI.js +1 -1
- package/lib/tinyAI.js +1 -1
- package/lib/universalSessionManager.js +1 -1
- package/package.json +1 -1
- package/lib/.logging-backup/aiProviders.js.backup +0 -654
- package/lib/.logging-backup/appMappings.js.backup +0 -337
- package/lib/.logging-backup/commanderService.js.backup +0 -4427
- package/lib/.logging-backup/devices.js.backup +0 -54
- package/lib/.logging-backup/doctor.js.backup +0 -94
- package/lib/.logging-backup/encryption.js.backup +0 -61
- package/lib/.logging-backup/executor.js.backup +0 -104
- package/lib/.logging-backup/hybridAI.js.backup +0 -154
- package/lib/.logging-backup/intelligentLocatorService.js.backup +0 -1541
- package/lib/.logging-backup/locatorStrategy.js.backup +0 -342
- package/lib/.logging-backup/scriptLoader.js.backup +0 -13
- package/lib/.logging-backup/server.js.backup +0 -6298
- package/lib/.logging-backup/tensorflowAI.js.backup +0 -714
- package/lib/.logging-backup/universalSessionManager.js.backup +0 -370
- package/lib/.logging-enhanced-backup/server.js.enhanced-backup +0 -6298
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Device listing utility for Devicely CLI
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
// Import deviceDetection from appropriate location
|
|
6
|
-
let discoverAllDevices;
|
|
7
|
-
try {
|
|
8
|
-
({ discoverAllDevices } = require('./deviceDetection'));
|
|
9
|
-
} catch (err) {
|
|
10
|
-
({ discoverAllDevices } = require('../../deviceDetection'));
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
async function listDevices(options = {}) {
|
|
14
|
-
const devices = await discoverAllDevices();
|
|
15
|
-
|
|
16
|
-
if (!devices || devices.length === 0) {
|
|
17
|
-
console.log('\n⚠️ No devices found');
|
|
18
|
-
console.log('\n💡 Tips:');
|
|
19
|
-
console.log(' • For iOS: Connect device via USB or ensure Xcode pairing');
|
|
20
|
-
console.log(' • For Android: Enable USB debugging and connect device');
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
console.log(`\n✅ Found ${devices.length} device(s):\n`);
|
|
25
|
-
|
|
26
|
-
devices.forEach((device, index) => {
|
|
27
|
-
const status = device.status === 'online' ? '🟢' : '🔴';
|
|
28
|
-
const platform = device.platform === 'ios' ? '🍎' : '🤖';
|
|
29
|
-
|
|
30
|
-
console.log(`${index + 1}. ${status} ${platform} ${device.name}`);
|
|
31
|
-
|
|
32
|
-
if (options.verbose) {
|
|
33
|
-
console.log(` Platform: ${device.platform}`);
|
|
34
|
-
console.log(` UDID: ${device.udid}`);
|
|
35
|
-
console.log(` Type: ${device.type}`);
|
|
36
|
-
console.log(` Status: ${device.status}`);
|
|
37
|
-
if (device.osVersion) {
|
|
38
|
-
console.log(` OS Version: ${device.osVersion}`);
|
|
39
|
-
}
|
|
40
|
-
if (device.port) {
|
|
41
|
-
console.log(` Port: ${device.port}`);
|
|
42
|
-
}
|
|
43
|
-
console.log('');
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
if (!options.verbose) {
|
|
48
|
-
console.log('\n💡 Use --verbose for detailed information');
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
module.exports = {
|
|
53
|
-
listDevices
|
|
54
|
-
};
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* System requirements checker for Devicely
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const { execSync } = require('child_process');
|
|
6
|
-
const chalk = require('chalk');
|
|
7
|
-
|
|
8
|
-
function checkCommand(command, name) {
|
|
9
|
-
try {
|
|
10
|
-
execSync(`which ${command}`, { stdio: 'ignore' });
|
|
11
|
-
console.log(`${chalk.green('✓')} ${name} installed`);
|
|
12
|
-
return true;
|
|
13
|
-
} catch (error) {
|
|
14
|
-
console.log(`${chalk.red('✗')} ${name} not found`);
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function getVersion(command) {
|
|
20
|
-
try {
|
|
21
|
-
const version = execSync(command, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] });
|
|
22
|
-
return version.trim().split('\n')[0];
|
|
23
|
-
} catch (error) {
|
|
24
|
-
return 'Unknown';
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async function checkDoctor() {
|
|
29
|
-
console.log('\n📋 System Requirements Check\n');
|
|
30
|
-
|
|
31
|
-
let allGood = true;
|
|
32
|
-
|
|
33
|
-
// Node.js
|
|
34
|
-
console.log(chalk.bold('Node.js:'));
|
|
35
|
-
const nodeVersion = process.version;
|
|
36
|
-
console.log(`${chalk.green('✓')} Version: ${nodeVersion}\n`);
|
|
37
|
-
|
|
38
|
-
// iOS Tools
|
|
39
|
-
console.log(chalk.bold('iOS Automation Tools:'));
|
|
40
|
-
const hasXcode = checkCommand('xcodebuild', 'Xcode');
|
|
41
|
-
const hasIdevice = checkCommand('idevice_id', 'libimobiledevice');
|
|
42
|
-
const hasIproxy = checkCommand('iproxy', 'usbmuxd');
|
|
43
|
-
allGood = allGood && hasXcode && hasIdevice && hasIproxy;
|
|
44
|
-
console.log('');
|
|
45
|
-
|
|
46
|
-
// Android Tools
|
|
47
|
-
console.log(chalk.bold('Android Automation Tools:'));
|
|
48
|
-
const hasAdb = checkCommand('adb', 'Android Debug Bridge (adb)');
|
|
49
|
-
allGood = allGood && hasAdb;
|
|
50
|
-
|
|
51
|
-
if (hasAdb) {
|
|
52
|
-
const adbVersion = getVersion('adb --version');
|
|
53
|
-
console.log(` Version: ${adbVersion}`);
|
|
54
|
-
}
|
|
55
|
-
console.log('');
|
|
56
|
-
|
|
57
|
-
// Python (for UIAutomator2)
|
|
58
|
-
console.log(chalk.bold('Python:'));
|
|
59
|
-
const hasPython = checkCommand('python3', 'Python 3');
|
|
60
|
-
if (hasPython) {
|
|
61
|
-
const pythonVersion = getVersion('python3 --version');
|
|
62
|
-
console.log(` Version: ${pythonVersion}`);
|
|
63
|
-
}
|
|
64
|
-
console.log('');
|
|
65
|
-
|
|
66
|
-
// Summary
|
|
67
|
-
if (allGood) {
|
|
68
|
-
console.log(chalk.green.bold('✅ All requirements met!'));
|
|
69
|
-
console.log(chalk.gray('\nYou can start using Devicely with: devicely start'));
|
|
70
|
-
} else {
|
|
71
|
-
console.log(chalk.yellow.bold('⚠️ Some requirements are missing'));
|
|
72
|
-
console.log(chalk.gray('\n📖 Installation Guide:'));
|
|
73
|
-
|
|
74
|
-
if (!hasIdevice || !hasIproxy) {
|
|
75
|
-
console.log(chalk.gray('\nFor iOS support:'));
|
|
76
|
-
console.log(' brew install libimobiledevice usbmuxd');
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (!hasAdb) {
|
|
80
|
-
console.log(chalk.gray('\nFor Android support:'));
|
|
81
|
-
console.log(' brew install android-platform-tools');
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (!hasPython) {
|
|
85
|
-
console.log(chalk.gray('\nFor Python:'));
|
|
86
|
-
console.log(' brew install python3');
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
console.log('');
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
module.exports = {
|
|
93
|
-
checkDoctor
|
|
94
|
-
};
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
const crypto = require('crypto');
|
|
2
|
-
|
|
3
|
-
const ENCRYPTION_CONFIG = {
|
|
4
|
-
algorithm: 'aes-256-cbc',
|
|
5
|
-
encoding: {
|
|
6
|
-
input: 'utf8',
|
|
7
|
-
output: 'hex'
|
|
8
|
-
},
|
|
9
|
-
keyDerivation: 'sha256',
|
|
10
|
-
keySeed: 'devicely-encryption-key-v1'
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
function generateKey() {
|
|
14
|
-
let packageName = 'devicely';
|
|
15
|
-
try {
|
|
16
|
-
const pkg = require('../../npm-package/package.json');
|
|
17
|
-
packageName = pkg.name;
|
|
18
|
-
} catch (e) {
|
|
19
|
-
try {
|
|
20
|
-
const pkg = require('../../package.json');
|
|
21
|
-
packageName = pkg.name;
|
|
22
|
-
} catch (e2) {
|
|
23
|
-
packageName = 'devicely';
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
const keySource = `${packageName}-${ENCRYPTION_CONFIG.keySeed}`;
|
|
27
|
-
return crypto.createHash(ENCRYPTION_CONFIG.keyDerivation).update(keySource).digest();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function generateIV() {
|
|
31
|
-
const ivSource = `${ENCRYPTION_CONFIG.keySeed}-iv`;
|
|
32
|
-
return crypto.createHash('md5').update(ivSource).digest();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function encrypt(content) {
|
|
36
|
-
try {
|
|
37
|
-
const key = generateKey();
|
|
38
|
-
const iv = generateIV();
|
|
39
|
-
const cipher = crypto.createCipheriv(ENCRYPTION_CONFIG.algorithm, key, iv);
|
|
40
|
-
let encrypted = cipher.update(content, ENCRYPTION_CONFIG.encoding.input, ENCRYPTION_CONFIG.encoding.output);
|
|
41
|
-
encrypted += cipher.final(ENCRYPTION_CONFIG.encoding.output);
|
|
42
|
-
return encrypted;
|
|
43
|
-
} catch (error) {
|
|
44
|
-
throw new Error(`Encryption failed: ${error.message}`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function decrypt(encrypted) {
|
|
49
|
-
try {
|
|
50
|
-
const key = generateKey();
|
|
51
|
-
const iv = generateIV();
|
|
52
|
-
const decipher = crypto.createDecipheriv(ENCRYPTION_CONFIG.algorithm, key, iv);
|
|
53
|
-
let decrypted = decipher.update(encrypted, ENCRYPTION_CONFIG.encoding.output, ENCRYPTION_CONFIG.encoding.input);
|
|
54
|
-
decrypted += decipher.final(ENCRYPTION_CONFIG.encoding.input);
|
|
55
|
-
return decrypted;
|
|
56
|
-
} catch (error) {
|
|
57
|
-
throw new Error(`Decryption failed: ${error.message}`);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
module.exports = { encrypt, decrypt, ENCRYPTION_CONFIG };
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Command executor for Devicely CLI
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const { spawn } = require('child_process');
|
|
6
|
-
const path = require('path');
|
|
7
|
-
const chalk = require('chalk');
|
|
8
|
-
|
|
9
|
-
// Import deviceDetection from appropriate location
|
|
10
|
-
let discoverAllDevices;
|
|
11
|
-
try {
|
|
12
|
-
({ discoverAllDevices } = require('./deviceDetection'));
|
|
13
|
-
} catch (err) {
|
|
14
|
-
({ discoverAllDevices } = require('../../deviceDetection'));
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async function executeCommand(command, options = {}) {
|
|
18
|
-
const devices = await discoverAllDevices();
|
|
19
|
-
|
|
20
|
-
if (!devices || devices.length === 0) {
|
|
21
|
-
console.log(chalk.red('\n❌ No devices found'));
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
let targetDevices = devices.filter(d => d.status === 'online');
|
|
26
|
-
|
|
27
|
-
if (options.device) {
|
|
28
|
-
targetDevices = devices.filter(d =>
|
|
29
|
-
d.name === options.device && d.status === 'online'
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
if (targetDevices.length === 0) {
|
|
33
|
-
console.log(chalk.red(`\n❌ Device "${options.device}" not found or offline`));
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (targetDevices.length === 0) {
|
|
39
|
-
console.log(chalk.yellow('\n⚠️ No online devices found'));
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
console.log(chalk.cyan(`\nExecuting on ${targetDevices.length} device(s):`));
|
|
44
|
-
targetDevices.forEach(d => console.log(` • ${d.name}`));
|
|
45
|
-
console.log('');
|
|
46
|
-
|
|
47
|
-
const scriptDir = path.join(__dirname, '../../scripts/shell');
|
|
48
|
-
|
|
49
|
-
for (const device of targetDevices) {
|
|
50
|
-
const platform = device.platform;
|
|
51
|
-
const type = device.type;
|
|
52
|
-
|
|
53
|
-
let scriptName;
|
|
54
|
-
if (platform === 'ios' && type === 'usb') {
|
|
55
|
-
scriptName = 'connect_ios_usb_multi_final.sh';
|
|
56
|
-
} else if (platform === 'ios' && type === 'wireless') {
|
|
57
|
-
scriptName = 'connect_ios_wireless_multi_final.sh';
|
|
58
|
-
} else if (platform === 'android' && type === 'usb') {
|
|
59
|
-
scriptName = 'connect_android_usb_multi_final.sh';
|
|
60
|
-
} else if (platform === 'android' && type === 'wireless') {
|
|
61
|
-
scriptName = 'connect_android_wireless_multi_final.sh';
|
|
62
|
-
} else {
|
|
63
|
-
console.log(chalk.yellow(`⚠️ Unsupported device type: ${platform}-${type}`));
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const scriptPath = path.join(scriptDir, scriptName);
|
|
68
|
-
|
|
69
|
-
console.log(chalk.blue(`[${device.name}] Running command...`));
|
|
70
|
-
|
|
71
|
-
const child = spawn(scriptPath, ['-d', device.name, ...command.split(' ')], {
|
|
72
|
-
stdio: 'pipe'
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
child.stdout.on('data', (data) => {
|
|
76
|
-
const lines = data.toString().split('\n').filter(l => l.trim());
|
|
77
|
-
lines.forEach(line => {
|
|
78
|
-
console.log(chalk.gray(` ${line}`));
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
child.stderr.on('data', (data) => {
|
|
83
|
-
const lines = data.toString().split('\n').filter(l => l.trim());
|
|
84
|
-
lines.forEach(line => {
|
|
85
|
-
console.log(chalk.red(` ${line}`));
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
await new Promise((resolve) => {
|
|
90
|
-
child.on('close', (code) => {
|
|
91
|
-
if (code === 0) {
|
|
92
|
-
console.log(chalk.green(`[${device.name}] ✅ Success\n`));
|
|
93
|
-
} else {
|
|
94
|
-
console.log(chalk.red(`[${device.name}] ❌ Failed (exit code: ${code})\n`));
|
|
95
|
-
}
|
|
96
|
-
resolve();
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
module.exports = {
|
|
103
|
-
executeCommand
|
|
104
|
-
};
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 🤖 HYBRID AI MANAGER
|
|
3
|
-
* Intelligently chooses between Tiny AI (LLM) and Rule-based AI
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
class HybridAI {
|
|
7
|
-
constructor() {
|
|
8
|
-
this.logger = console;
|
|
9
|
-
this.tinyAI = null;
|
|
10
|
-
this.ruleBasedAI = null;
|
|
11
|
-
this.preferTinyAI = true; // User preference
|
|
12
|
-
this.stats = {
|
|
13
|
-
totalRequests: 0,
|
|
14
|
-
tinyAISuccess: 0,
|
|
15
|
-
ruleBasedFallback: 0,
|
|
16
|
-
errors: 0
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* 🧠 Main AI conversion with intelligent fallback
|
|
22
|
-
*/
|
|
23
|
-
async convertCommand(text, devices = [], options = {}) {
|
|
24
|
-
this.stats.totalRequests++;
|
|
25
|
-
const startTime = Date.now();
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
// Try Tiny AI first if available and preferred
|
|
29
|
-
if (this.preferTinyAI && await this.isTinyAIAvailable()) {
|
|
30
|
-
this.logger.info('🧠 HybridAI: Attempting Tiny AI conversion...');
|
|
31
|
-
|
|
32
|
-
const result = await this.getTinyAI().convertCommand(text, devices, options);
|
|
33
|
-
|
|
34
|
-
if (result && result.success && result.method === 'tiny-ai') {
|
|
35
|
-
this.stats.tinyAISuccess++;
|
|
36
|
-
this.logger.info(`✅ HybridAI: Tiny AI succeeded in ${Date.now() - startTime}ms`);
|
|
37
|
-
return result;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Fallback to rule-based AI
|
|
42
|
-
this.logger.info('🔄 HybridAI: Using rule-based AI...');
|
|
43
|
-
const result = await this.getRuleBasedAI().convertCommand(text, devices, options);
|
|
44
|
-
|
|
45
|
-
if (result && result.success) {
|
|
46
|
-
this.stats.ruleBasedFallback++;
|
|
47
|
-
result.method = 'rule-based';
|
|
48
|
-
this.logger.info(`✅ HybridAI: Rule-based AI succeeded in ${Date.now() - startTime}ms`);
|
|
49
|
-
return result;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Both failed
|
|
53
|
-
this.stats.errors++;
|
|
54
|
-
return {
|
|
55
|
-
success: false,
|
|
56
|
-
error: 'Both AI systems failed to parse command',
|
|
57
|
-
processingTime: Date.now() - startTime,
|
|
58
|
-
method: 'none'
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
} catch (error) {
|
|
62
|
-
this.stats.errors++;
|
|
63
|
-
this.logger.error('❌ HybridAI: Error:', error.message);
|
|
64
|
-
|
|
65
|
-
return {
|
|
66
|
-
success: false,
|
|
67
|
-
error: error.message,
|
|
68
|
-
processingTime: Date.now() - startTime,
|
|
69
|
-
method: 'error'
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* 🔍 Check if Tiny AI is available and ready
|
|
76
|
-
*/
|
|
77
|
-
async isTinyAIAvailable() {
|
|
78
|
-
try {
|
|
79
|
-
const tinyAI = this.getTinyAI();
|
|
80
|
-
return await tinyAI.initialize();
|
|
81
|
-
} catch (error) {
|
|
82
|
-
return false;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* 🧠 Get or create Tiny AI instance
|
|
88
|
-
*/
|
|
89
|
-
getTinyAI() {
|
|
90
|
-
if (!this.tinyAI) {
|
|
91
|
-
try {
|
|
92
|
-
const TinyAI = require('./tinyAI');
|
|
93
|
-
this.tinyAI = new TinyAI();
|
|
94
|
-
} catch (error) {
|
|
95
|
-
this.logger.warn('⚠️ HybridAI: TinyAI not available:', error.message);
|
|
96
|
-
throw error;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return this.tinyAI;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* 📏 Get or create rule-based AI instance
|
|
104
|
-
*/
|
|
105
|
-
getRuleBasedAI() {
|
|
106
|
-
if (!this.ruleBasedAI) {
|
|
107
|
-
const LocalBuiltInAI = require('./localBuiltInAI');
|
|
108
|
-
this.ruleBasedAI = new LocalBuiltInAI();
|
|
109
|
-
}
|
|
110
|
-
return this.ruleBasedAI;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* ⚙️ Configure AI preferences
|
|
115
|
-
*/
|
|
116
|
-
configure(options = {}) {
|
|
117
|
-
if (typeof options.preferTinyAI === 'boolean') {
|
|
118
|
-
this.preferTinyAI = options.preferTinyAI;
|
|
119
|
-
this.logger.info(`🔧 HybridAI: Tiny AI preference set to ${this.preferTinyAI}`);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* 📊 Get AI statistics and status
|
|
125
|
-
*/
|
|
126
|
-
getStatus() {
|
|
127
|
-
const tinyAIStatus = this.tinyAI ? this.tinyAI.getStatus() : null;
|
|
128
|
-
|
|
129
|
-
return {
|
|
130
|
-
preferTinyAI: this.preferTinyAI,
|
|
131
|
-
tinyAI: tinyAIStatus,
|
|
132
|
-
ruleBasedAI: { ready: true }, // Always available
|
|
133
|
-
stats: { ...this.stats },
|
|
134
|
-
successRate: this.stats.totalRequests > 0
|
|
135
|
-
? ((this.stats.tinyAISuccess + this.stats.ruleBasedFallback) / this.stats.totalRequests * 100).toFixed(1) + '%'
|
|
136
|
-
: 'N/A'
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* 🧹 Reset statistics
|
|
142
|
-
*/
|
|
143
|
-
resetStats() {
|
|
144
|
-
this.stats = {
|
|
145
|
-
totalRequests: 0,
|
|
146
|
-
tinyAISuccess: 0,
|
|
147
|
-
ruleBasedFallback: 0,
|
|
148
|
-
errors: 0
|
|
149
|
-
};
|
|
150
|
-
this.logger.info('🧹 HybridAI: Statistics reset');
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
module.exports = HybridAI;
|