Files
999/lib/g4f/providers/you_chat.dart
T
Alma Alexyz fbf04d90db feat: embed a Flutter G4F client with Cronet, cookie jar, and origin WebView
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.
2026-09-01 22:05:38 +05:00

75 lines
2.1 KiB
Dart

import 'dart:convert';
import '../http_client.dart';
import '../http_util.dart';
import '../models.dart';
import '../sse.dart';
import 'base_provider.dart';
/// Port of g4f.Provider.You (default youchat mode, no login).
class YouChat extends BaseProvider {
@override
String get name => 'You';
@override
bool get working => true;
@override
List<String> get models => ['gpt-3.5-turbo', 'gpt-4o'];
@override
String get defaultModel => 'gpt-3.5-turbo';
@override
Stream<String> createAsyncGenerator(
String model,
List<Message> messages, {
bool stream = false,
}) async* {
final res = await g4fHttp
.post(
Uri.parse('https://you.com/api/streamingSearch'),
headers: browserHeaders(
origin: 'https://you.com',
referer: 'https://you.com/search?fromSearchBar=true&tbm=youchat',
accept: 'text/event-stream',
),
body: {
'q': formatPrompt(messages),
'domain': 'youchat',
'selectedChatMode': 'default',
'chat': '[]',
},
)
.timeout(requestTimeout);
if (res.statusCode != 200) {
throw Exception('You ${res.statusCode}');
}
final raw = res.body;
final buf = StringBuffer();
String? event;
for (final line in raw.split(RegExp(r'\r?\n'))) {
if (line.startsWith('event:')) {
event = line.substring(6).trim();
} else if (line.startsWith('data:')) {
final dataStr = line.substring(5).trim();
try {
final data = jsonDecode(dataStr);
if (data is Map) {
if (event == 'youChatToken' && data['youChatToken'] is String) {
buf.write(data['youChatToken']);
} else if (event == 'youChatUpdate' && data['t'] is String) {
buf.write(data['t']);
}
}
} catch (_) {}
}
}
var text = buf.toString().trim();
if (!looksLikeModelOutput(text)) {
text = extractAllSseContent(raw).join().trim();
}
if (!looksLikeModelOutput(text)) throw Exception('You empty');
yield text;
}
}