devicely 2.2.12 → 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/README.md +182 -81
- package/bin/devicely.js +1 -1
- package/config/devices.conf +2 -2
- package/lib/advanced-logger.js +1 -0
- package/lib/aiProviders.js +154 -15
- package/lib/aiProviders.js.strategic-backup +657 -0
- package/lib/aiProvidersConfig.js +61 -151
- package/lib/aiProvidersConfig.js.backup +218 -0
- package/lib/androidDeviceDetection.js +1 -1
- package/lib/appMappings.js +1 -1
- package/lib/commanderService.js +1 -1
- package/lib/commanderService.js.backup +5552 -0
- package/lib/deviceDetection.js +1 -1
- package/lib/devices.js +1 -1
- package/lib/devices.js.strategic-backup +57 -0
- package/lib/doctor.js +1 -1
- package/lib/encryption.js +1 -1
- package/lib/encryption.js.strategic-backup +61 -0
- package/lib/executor.js +1 -1
- package/lib/executor.js.strategic-backup +107 -0
- package/lib/frontend/asset-manifest.json +5 -3
- package/lib/frontend/index.html +1 -1
- package/lib/hybridAI.js +1 -0
- package/lib/intelligentLocatorService.js +1 -0
- package/lib/lightweightAI.js +1 -0
- package/lib/localBuiltInAI.js +1 -0
- package/lib/localBuiltInAI_backup.js +1 -0
- package/lib/localBuiltInAI_simple.js +1 -0
- package/lib/locatorStrategy.js +1 -1
- package/lib/logger-demo.js +2 -0
- package/lib/logger-integration-examples.js +102 -0
- package/lib/logger.js +1 -1
- package/lib/package.json +5 -0
- package/lib/public/asset-manifest.json +3 -3
- package/lib/public/index.html +1 -1
- package/lib/quick-start-logger.js +2 -0
- package/lib/scriptLoader.js +1 -1
- package/lib/server.js +1 -1
- package/lib/server.js.strategic-backup +6298 -0
- package/lib/tensorflowAI.js +1 -0
- package/lib/tensorflowAI.js.strategic-backup +717 -0
- package/lib/tinyAI.js +1 -0
- package/lib/universalSessionManager.js +1 -0
- package/package.json +1 -1
- package/scripts/shell/android_device_control.enc +1 -1
- package/scripts/shell/connect_ios_usb_multi_final.enc +1 -1
- package/scripts/shell/connect_ios_wireless_multi_final.enc +1 -1
- package/lib/public/index.html.bak +0 -1
package/lib/aiProviders.js
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
// AI Provider Abstraction Layer - Enhanced Multi-Provider Support
|
|
2
|
-
// Supports: OpenAI, Google Gemini, Anthropic Claude, GitHub Copilot, Groq, Cohere, Mistral AI
|
|
2
|
+
// Supports: OpenAI, Google Gemini, Anthropic Claude, GitHub Copilot, Groq, Cohere, Mistral AI, Local Built-In AI
|
|
3
3
|
|
|
4
4
|
const { OpenAI } = require('openai');
|
|
5
5
|
const { GoogleGenerativeAI } = require('@google/generative-ai');
|
|
6
6
|
const { Anthropic } = require('@anthropic-ai/sdk');
|
|
7
7
|
const { getPackageId, APP_MAPPINGS } = require('./appMappings');
|
|
8
8
|
|
|
9
|
+
const Logger = require('./logger');
|
|
10
|
+
const logger = new Logger('AiProviders');
|
|
11
|
+
const LocalBuiltInAI = require('./localBuiltInAI'); // NEW: Import local AI
|
|
12
|
+
|
|
9
13
|
class AIProviderManager {
|
|
10
14
|
constructor() {
|
|
11
|
-
this.provider = process.env.AI_PROVIDER || '
|
|
15
|
+
this.provider = process.env.AI_PROVIDER || 'local'; // Default to Local Built-In AI (faster, no dependencies)
|
|
12
16
|
this.model = process.env.AI_MODEL || null; // Auto-select default if null
|
|
17
|
+
|
|
18
|
+
// Initialize Local Built-In AI first
|
|
19
|
+
this.localAI = new LocalBuiltInAI();
|
|
20
|
+
|
|
13
21
|
this.initializeProviders();
|
|
14
22
|
}
|
|
15
23
|
|
|
@@ -99,7 +107,9 @@ ${availableApps.slice(0, 20).map(app => `- ${app} -> launch ${APP_MAPPINGS[app][
|
|
|
99
107
|
`;
|
|
100
108
|
}
|
|
101
109
|
|
|
102
|
-
return `You are a mobile
|
|
110
|
+
return `You are a COMPLETE mobile automation AI. Convert ENTIRE natural language requests to executable commands.
|
|
111
|
+
|
|
112
|
+
🚨 CRITICAL: PROCESS THE COMPLETE INPUT - DON'T STOP EARLY! 🚨
|
|
103
113
|
|
|
104
114
|
Available commands (work on both iOS & Android):
|
|
105
115
|
- launch <app_name>: Launch an app using generic name (e.g., "launch settings", "launch chrome")
|
|
@@ -130,7 +140,50 @@ Android-specific commands:
|
|
|
130
140
|
- quicksettings: Open quick settings
|
|
131
141
|
${appListSection}
|
|
132
142
|
|
|
133
|
-
|
|
143
|
+
// 🎯 ENHANCED PHRASE MAPPINGS FOR COMPLEX SENTENCES:
|
|
144
|
+
- "launch X and do Y" -> launch X, WAIT, then Y commands
|
|
145
|
+
- "open X then scroll up" -> launch X, WAIT, swipe up
|
|
146
|
+
- "go to X and search Y" -> url X, WAIT, click search, WAIT, type Y
|
|
147
|
+
- "take photo" -> launch camera, WAIT, tap "capture button"
|
|
148
|
+
- "go back and open Y" -> back, WAIT, launch Y
|
|
149
|
+
- "scroll up and tap X" -> swipe up, WAIT, click X
|
|
150
|
+
|
|
151
|
+
// 🎯 COMPLEX SENTENCE EXAMPLES:
|
|
152
|
+
"launch camera and take photo" ->
|
|
153
|
+
launch camera
|
|
154
|
+
WAIT 3000
|
|
155
|
+
screenshot
|
|
156
|
+
|
|
157
|
+
"open settings then scroll up and go back" ->
|
|
158
|
+
launch settings
|
|
159
|
+
WAIT 2000
|
|
160
|
+
swipe up
|
|
161
|
+
WAIT 1000
|
|
162
|
+
back
|
|
163
|
+
|
|
164
|
+
"go to youtube.com search for cats and take screenshot" ->
|
|
165
|
+
url https://www.youtube.com
|
|
166
|
+
WAIT 3000
|
|
167
|
+
click "search"
|
|
168
|
+
WAIT 1000
|
|
169
|
+
type "cats"
|
|
170
|
+
WAIT 1000
|
|
171
|
+
screenshot
|
|
172
|
+
|
|
173
|
+
"launch chrome go to google.com type hello press home" ->
|
|
174
|
+
launch chrome
|
|
175
|
+
WAIT 3000
|
|
176
|
+
url https://www.google.com
|
|
177
|
+
WAIT 2000
|
|
178
|
+
click "search"
|
|
179
|
+
WAIT 1000
|
|
180
|
+
type "hello"
|
|
181
|
+
WAIT 1000
|
|
182
|
+
home
|
|
183
|
+
|
|
184
|
+
Convert this COMPLETE request to commands:
|
|
185
|
+
|
|
186
|
+
// 🔍 🔍 COMMON PHRASE MAPPINGS:
|
|
134
187
|
- "scroll up" OR "scroll down" -> swipe up OR swipe down
|
|
135
188
|
- "go to <url>" OR "open <url>" OR "visit <url>" -> url https://<url>
|
|
136
189
|
- "press home" OR "go home" OR "home button" -> home
|
|
@@ -201,6 +254,10 @@ DO NOT include any other text. Start your response with the first command.`;
|
|
|
201
254
|
|
|
202
255
|
try {
|
|
203
256
|
switch (provider) {
|
|
257
|
+
case 'local':
|
|
258
|
+
case 'built-in':
|
|
259
|
+
case 'builtin':
|
|
260
|
+
return await this.convertWithLocalAI(text, platform);
|
|
204
261
|
case 'openai':
|
|
205
262
|
return await this.convertWithOpenAI(text, platform);
|
|
206
263
|
case 'gemini':
|
|
@@ -219,7 +276,18 @@ DO NOT include any other text. Start your response with the first command.`;
|
|
|
219
276
|
throw new Error(`Unknown AI provider: ${provider}`);
|
|
220
277
|
}
|
|
221
278
|
} catch (error) {
|
|
222
|
-
|
|
279
|
+
logger.error(`Error with ${provider}:`, error.message);;
|
|
280
|
+
|
|
281
|
+
// 🎯 GENIUS: Fallback to Local AI if external provider fails
|
|
282
|
+
if (provider !== 'local' && this.localAI) {
|
|
283
|
+
logger.info(`🔄 Falling back to Local Built-In AI...`);;
|
|
284
|
+
try {
|
|
285
|
+
return await this.convertWithLocalAI(text, platform);
|
|
286
|
+
} catch (fallbackError) {
|
|
287
|
+
logger.error('Local AI fallback also failed:', fallbackError.message);;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
223
291
|
throw new Error(`AI conversion failed (${provider}): ${error.message}`);
|
|
224
292
|
}
|
|
225
293
|
}
|
|
@@ -261,9 +329,16 @@ DO NOT include any other text. Start your response with the first command.`;
|
|
|
261
329
|
});
|
|
262
330
|
|
|
263
331
|
let convertedText = response.choices[0].message.content.trim();
|
|
264
|
-
|
|
332
|
+
const cleanedResponse = this.cleanAIResponse(convertedText);
|
|
265
333
|
|
|
266
|
-
return
|
|
334
|
+
return {
|
|
335
|
+
success: true,
|
|
336
|
+
converted: cleanedResponse,
|
|
337
|
+
provider: 'OpenAI',
|
|
338
|
+
model: model,
|
|
339
|
+
confidence: 0.95,
|
|
340
|
+
processingTime: 'N/A'
|
|
341
|
+
};
|
|
267
342
|
}
|
|
268
343
|
|
|
269
344
|
async convertWithGemini(text, platform = null) {
|
|
@@ -289,18 +364,36 @@ DO NOT include any other text. Start your response with the first command.`;
|
|
|
289
364
|
const result = await model.generateContent(sanitizedPrompt);
|
|
290
365
|
const response = await result.response;
|
|
291
366
|
let convertedText = response.text().trim();
|
|
292
|
-
|
|
293
|
-
|
|
367
|
+
|
|
368
|
+
const cleanedResponse = this.cleanAIResponse(convertedText);
|
|
369
|
+
|
|
370
|
+
return {
|
|
371
|
+
success: true,
|
|
372
|
+
converted: cleanedResponse,
|
|
373
|
+
provider: 'Google Gemini',
|
|
374
|
+
model: modelName,
|
|
375
|
+
confidence: 0.9,
|
|
376
|
+
processingTime: 'N/A'
|
|
377
|
+
};
|
|
294
378
|
} catch (error) {
|
|
295
379
|
// If the model fails, try with a faster fallback
|
|
296
380
|
if (modelName !== 'gemini-2.5-flash') {
|
|
297
|
-
|
|
381
|
+
logger.warn(`Gemini model ${modelName} failed, falling back to gemini-2.5-flash`);;
|
|
298
382
|
const fallbackModel = this.gemini.getGenerativeModel({ model: 'gemini-2.5-flash' });
|
|
299
383
|
const prompt = this.getSystemPrompt(platform).replace('{INPUT}', text);
|
|
300
384
|
const sanitizedPrompt = prompt.replace(/[^\x00-\x7F]/g, " ").replace(/\s+/g, ' ').trim();
|
|
301
385
|
const result = await fallbackModel.generateContent(sanitizedPrompt);
|
|
302
386
|
const response = await result.response;
|
|
303
|
-
|
|
387
|
+
const cleanedResponse = this.cleanAIResponse(response.text().trim());
|
|
388
|
+
|
|
389
|
+
return {
|
|
390
|
+
success: true,
|
|
391
|
+
converted: cleanedResponse,
|
|
392
|
+
provider: 'Google Gemini',
|
|
393
|
+
model: 'gemini-2.5-flash',
|
|
394
|
+
confidence: 0.85,
|
|
395
|
+
processingTime: 'N/A'
|
|
396
|
+
};
|
|
304
397
|
}
|
|
305
398
|
throw error;
|
|
306
399
|
}
|
|
@@ -348,9 +441,16 @@ DO NOT include any other text. Start your response with the first command.`;
|
|
|
348
441
|
});
|
|
349
442
|
|
|
350
443
|
let convertedText = response.content[0].text.trim();
|
|
351
|
-
|
|
444
|
+
const cleanedResponse = this.cleanAIResponse(convertedText);
|
|
352
445
|
|
|
353
|
-
return
|
|
446
|
+
return {
|
|
447
|
+
success: true,
|
|
448
|
+
converted: cleanedResponse,
|
|
449
|
+
provider: 'Anthropic Claude',
|
|
450
|
+
model: model,
|
|
451
|
+
confidence: 0.93,
|
|
452
|
+
processingTime: 'N/A'
|
|
453
|
+
};
|
|
354
454
|
}
|
|
355
455
|
|
|
356
456
|
async convertWithGroq(text, platform = null) {
|
|
@@ -371,9 +471,16 @@ DO NOT include any other text. Start your response with the first command.`;
|
|
|
371
471
|
});
|
|
372
472
|
|
|
373
473
|
let convertedText = response.choices[0].message.content.trim();
|
|
374
|
-
|
|
474
|
+
const cleanedResponse = this.cleanAIResponse(convertedText);
|
|
375
475
|
|
|
376
|
-
return
|
|
476
|
+
return {
|
|
477
|
+
success: true,
|
|
478
|
+
converted: cleanedResponse,
|
|
479
|
+
provider: 'Groq',
|
|
480
|
+
model: model,
|
|
481
|
+
confidence: 0.92,
|
|
482
|
+
processingTime: 'N/A'
|
|
483
|
+
};
|
|
377
484
|
}
|
|
378
485
|
|
|
379
486
|
async convertWithCohere(text, platform = null) {
|
|
@@ -503,6 +610,9 @@ DO NOT include any other text. Start your response with the first command.`;
|
|
|
503
610
|
|
|
504
611
|
getProviderName(providerId) {
|
|
505
612
|
const names = {
|
|
613
|
+
local: 'Local Built-In AI',
|
|
614
|
+
'built-in': 'Local Built-In AI',
|
|
615
|
+
builtin: 'Local Built-In AI',
|
|
506
616
|
openai: 'OpenAI',
|
|
507
617
|
gemini: 'Google Gemini',
|
|
508
618
|
claude: 'Anthropic Claude',
|
|
@@ -513,6 +623,35 @@ DO NOT include any other text. Start your response with the first command.`;
|
|
|
513
623
|
};
|
|
514
624
|
return names[providerId] || 'Unknown';
|
|
515
625
|
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* 🤖 LOCAL BUILT-IN AI CONVERSION METHOD
|
|
629
|
+
* Zero-cost, offline, lightning-fast natural language processing
|
|
630
|
+
*/
|
|
631
|
+
async convertWithLocalAI(text, platform = null) {
|
|
632
|
+
logger.info(`🤖 Converting with Local Built-In AI: "${text}"`);;
|
|
633
|
+
|
|
634
|
+
try {
|
|
635
|
+
const devices = platform ? [{ platform }] : [];
|
|
636
|
+
const result = await this.localAI.convertCommand(text, devices);
|
|
637
|
+
|
|
638
|
+
if (result.success) {
|
|
639
|
+
return {
|
|
640
|
+
converted: result.converted,
|
|
641
|
+
provider: 'Local Built-In AI',
|
|
642
|
+
confidence: result.confidence,
|
|
643
|
+
processingTime: result.processingTime,
|
|
644
|
+
model: 'built-in-patterns',
|
|
645
|
+
cost: 0 // Always free!
|
|
646
|
+
};
|
|
647
|
+
} else {
|
|
648
|
+
throw new Error(result.error || 'Local AI conversion failed');
|
|
649
|
+
}
|
|
650
|
+
} catch (error) {
|
|
651
|
+
logger.error('Local AI conversion error:', error.message);;
|
|
652
|
+
throw error;
|
|
653
|
+
}
|
|
654
|
+
}
|
|
516
655
|
}
|
|
517
656
|
|
|
518
657
|
module.exports = AIProviderManager;
|