fix: keep agent streams alive during long tasks

This commit is contained in:
Hamza Ayed
2026-10-04 13:41:22 +03:00
parent ad221e24aa
commit d1010b79d7
11 changed files with 334 additions and 37 deletions
@@ -508,7 +508,7 @@ class ApiRepository {
headers: await _userHeaders(),
body: jsonEncode({'workspace_path': workspacePath, 'files': files}),
)
.timeout(const Duration(minutes: 2));
.timeout(const Duration(minutes: 5));
_checkStatus(response);
return jsonDecode(response.body) as Map<String, dynamic>;
}
@@ -337,25 +337,46 @@ class ChatCubit extends Cubit<ChatState> {
if (path == null || files.isEmpty) {
throw StateError('اختر مساحة عمل وحدد ملفًا واحدًا على الأقل للفهرسة.');
}
emit(state.copyWith(agentProgress: 'يفهرس الملفات المحددة محليًا…'));
emit(
state.copyWith(agentProgress: 'يجهز فهرسة ${files.length} ملفًا محليًا…'),
);
var indexedCount = 0;
var chunks = 0;
String? currentFile;
try {
final result = await _api.indexWorkspaceKnowledge(path, files);
final indexed = result['indexed'] as List<dynamic>? ?? const [];
final chunks = indexed.fold<int>(
0,
(total, item) =>
total + ((item as Map<String, dynamic>)['chunks'] as int? ?? 0),
);
for (var index = 0; index < files.length; index++) {
currentFile = files[index];
final fileName = currentFile.split(RegExp(r'[/\\]')).last;
emit(
state.copyWith(
agentProgress:
'يفهرس الملف ${index + 1}/${files.length}: $fileName…',
clearError: true,
),
);
final result = await _api.indexWorkspaceKnowledge(path, [currentFile]);
final indexed = result['indexed'] as List<dynamic>? ?? const [];
if (indexed.length != 1) {
throw StateError('لم يؤكد الخادم فهرسة الملف $fileName.');
}
indexedCount++;
chunks +=
(indexed.single as Map<String, dynamic>)['chunks'] as int? ?? 0;
}
if (!isClosed) {
emit(state.copyWith(clearAgentProgress: true, clearError: true));
}
return 'فُهرست ${indexed.length} ملفًا محليًا في SQLite ($chunks مقطعًا).';
return 'فُهرست $indexedCount ملفًا محليًا في SQLite ($chunks مقطعًا).';
} catch (error) {
final message = _readableError(error);
final detail =
indexedCount == 0
? 'تعذرت فهرسة ${currentFile ?? 'الملف المحدد'}: $message'
: 'فُهرست $indexedCount من ${files.length} ملفات. تعذرت فهرسة ${currentFile ?? 'الملف التالي'}: $message';
if (!isClosed) {
emit(state.copyWith(clearAgentProgress: true, error: message));
emit(state.copyWith(clearAgentProgress: true, error: detail));
}
throw Exception(message);
throw Exception(detail);
}
}