fbf04d90db
Port the Oracle off the Python g4f container onto on-device providers: Chromium HTTP via Cronet, a shared cookie session, IterList retry, hosted OpenAI-compat aggregators, and same-origin WebView fallbacks instead of CORS fetch.
119 lines
3.4 KiB
Dart
119 lines
3.4 KiB
Dart
import 'dart:convert';
|
|
import 'dart:math';
|
|
import 'package:http/http.dart' as http;
|
|
import '../http_client.dart';
|
|
import 'package:crypto/crypto.dart';
|
|
import 'package:uuid/uuid.dart';
|
|
import '../models.dart';
|
|
import 'base_provider.dart';
|
|
|
|
class DeepAi extends BaseProvider {
|
|
@override
|
|
String get name => 'DeepAI';
|
|
|
|
@override
|
|
String get label => 'DeepAI';
|
|
|
|
@override
|
|
String get url => 'https://deepai.org/chat';
|
|
|
|
@override
|
|
bool get working => true;
|
|
|
|
@override
|
|
bool get supportsStream => true;
|
|
|
|
@override
|
|
String get defaultModel => 'standard';
|
|
|
|
@override
|
|
Map<String, String> get modelAliases => const {
|
|
G4FModels.gpt4: 'standard',
|
|
G4FModels.gpt4o: 'standard',
|
|
G4FModels.gpt4oMini: 'standard',
|
|
};
|
|
|
|
@override
|
|
List<String> get models => [
|
|
'standard',
|
|
'online',
|
|
'gemma-4',
|
|
'gemini-2.5-flash-lite',
|
|
'deepseek-v3.2',
|
|
];
|
|
|
|
String _reverseString(String input) {
|
|
return input.split('').reversed.join('');
|
|
}
|
|
|
|
String _myHashFunction(String inputStr) {
|
|
var bytes = utf8.encode(inputStr);
|
|
var digest = md5.convert(bytes);
|
|
return _reverseString(digest.toString());
|
|
}
|
|
|
|
String _generateApiKey(String userAgent) {
|
|
final random = Random();
|
|
final myRandomStr = (random.nextDouble() * 100000000000).round().toString();
|
|
|
|
final hash1 = _myHashFunction(
|
|
userAgent + myRandomStr + "hackers_become_a_little_stinkier_every_time_they_hack");
|
|
final hash2 = _myHashFunction(userAgent + hash1);
|
|
final hash3 = _myHashFunction(userAgent + hash2);
|
|
|
|
return "tryit-$myRandomStr-$hash3";
|
|
}
|
|
|
|
@override
|
|
Stream<String> createAsyncGenerator(
|
|
String model,
|
|
List<Message> messages, {
|
|
bool stream = true,
|
|
}) async* {
|
|
final userAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36';
|
|
final apiKey = _generateApiKey(userAgent);
|
|
|
|
final headers = {
|
|
'api-key': apiKey,
|
|
'user-agent': userAgent,
|
|
'origin': 'https://deepai.org',
|
|
'referer': 'https://deepai.org/chat',
|
|
};
|
|
|
|
final cleanedMessages = messages.map((m) => {'role': m.role.name, 'content': m.content}).toList();
|
|
|
|
var request = http.MultipartRequest('POST', Uri.parse('https://api.deepai.org/hacking_is_a_serious_crime'));
|
|
request.headers.addAll(headers);
|
|
|
|
request.fields['chat_style'] = 'chat';
|
|
request.fields['chatHistory'] = jsonEncode(cleanedMessages);
|
|
request.fields['model'] = model;
|
|
request.fields['session_uuid'] = const Uuid().v4();
|
|
request.fields['sensitivity_request_id'] = const Uuid().v4();
|
|
request.fields['hacker_is_stinky'] = 'very_stinky';
|
|
request.fields['enabled_tools'] = jsonEncode(["image_generator", "image_editor"]);
|
|
|
|
final response = await g4fHttp.send(request).timeout(requestTimeout);
|
|
|
|
if (response.statusCode != 200) {
|
|
final errorText = await response.stream.bytesToString();
|
|
throw Exception('DeepAI API returned status: ${response.statusCode} $errorText');
|
|
}
|
|
|
|
const fs = '\x1c';
|
|
var buffer = '';
|
|
await for (final chunk in response.stream.transform(utf8.decoder)) {
|
|
if (chunk.isEmpty) continue;
|
|
if (chunk.contains(fs) || buffer.contains(fs)) {
|
|
buffer += chunk;
|
|
final parts = buffer.split(fs);
|
|
if (parts[0].trim().isNotEmpty) {
|
|
yield parts[0];
|
|
}
|
|
break;
|
|
}
|
|
yield chunk;
|
|
}
|
|
}
|
|
}
|