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
@@ -16,6 +16,8 @@ class _VersionTestApi extends ApiRepository {
SavedConversation? lastSaved;
String? indexedWorkspace;
List<String> indexedFiles = const [];
final indexedRequests = <List<String>>[];
final availableFiles = <String>['README.md'];
List<String> deletedFiles = const [];
String? registeredProject;
String? unregisteredProject;
@@ -60,9 +62,8 @@ class _VersionTestApi extends ApiRepository {
Future<List<SavedConversation>> listConversations() async => [];
@override
Future<List<String>> listWorkspaceFiles(String workspacePath) async => [
'README.md',
];
Future<List<String>> listWorkspaceFiles(String workspacePath) async =>
List.of(availableFiles);
@override
Future<List<String>> registerWorkspaceProject(String workspacePath) async {
@@ -82,6 +83,8 @@ class _VersionTestApi extends ApiRepository {
) async {
indexedWorkspace = workspacePath;
indexedFiles = files;
indexedRequests.add(List.of(files));
await Future<void>.delayed(const Duration(milliseconds: 1));
return {
'indexed': [
for (final file in files) {'path': file, 'chunks': 2},
@@ -175,21 +178,39 @@ void main() {
test('selected workspace files can be indexed as local knowledge', () async {
final api = _VersionTestApi();
api.availableFiles.add('lib/main.dart');
final cubit = ChatCubit(api, settingsStore: LocalSettingsStore.inMemory());
await Future<void>.delayed(Duration.zero);
await cubit.selectWorkspace(r'C:\Projects\sample');
cubit.selectWorkspaceFiles(['README.md']);
final progressUpdates = <String?>[];
final subscription = cubit.stream.listen(
(state) => progressUpdates.add(state.agentProgress),
);
cubit.selectWorkspaceFiles(['README.md', 'lib/main.dart']);
final message = await cubit.indexSelectedWorkspaceKnowledge();
expect(api.indexedWorkspace, r'C:\Projects\sample');
expect(api.indexedFiles, ['README.md']);
expect(message, contains('2 مقطعًا'));
expect(api.indexedRequests, [
['README.md'],
['lib/main.dart'],
]);
expect(message, contains('فُهرست 2 ملفًا'));
expect(message, contains('4 مقطعًا'));
expect(
progressUpdates,
contains('يفهرس الملف 1/2: README.md…'),
);
expect(
progressUpdates,
contains('يفهرس الملف 2/2: main.dart…'),
);
expect(cubit.state.agentProgress, isNull);
await subscription.cancel();
final removal = await cubit.removeSelectedWorkspaceKnowledge();
expect(api.deletedFiles, ['README.md']);
expect(removal, contains('أُزيل 1 ملف'));
expect(api.deletedFiles, ['README.md', 'lib/main.dart']);
expect(removal, contains('أُزيل 2 ملف'));
await cubit.close();
});