🐛 Bug fixes

This commit is contained in:
2025-11-16 00:34:10 +08:00
parent 429b966c4b
commit e516f0a862
2 changed files with 63 additions and 53 deletions

View File

@@ -68,7 +68,6 @@ class ThoughtScreen extends HookConsumerWidget {
); );
}, },
), ),
// TODO: Need to access chat state for actions
const Gap(8), const Gap(8),
], ],
), ),

View File

@@ -10,6 +10,7 @@ import 'package:island/models/thought.dart';
import 'package:island/pods/network.dart'; import 'package:island/pods/network.dart';
import 'package:island/pods/userinfo.dart'; import 'package:island/pods/userinfo.dart';
import 'package:island/screens/posts/compose.dart'; import 'package:island/screens/posts/compose.dart';
import 'package:island/talker.dart';
import 'package:island/widgets/alert.dart'; import 'package:island/widgets/alert.dart';
import 'package:island/widgets/post/compose_sheet.dart'; import 'package:island/widgets/post/compose_sheet.dart';
import 'package:island/widgets/thought/function_calls_section.dart'; import 'package:island/widgets/thought/function_calls_section.dart';
@@ -19,6 +20,7 @@ import 'package:island/widgets/thought/thought_content.dart';
import 'package:island/widgets/thought/thought_header.dart'; import 'package:island/widgets/thought/thought_header.dart';
import 'package:island/widgets/thought/token_info.dart'; import 'package:island/widgets/thought/token_info.dart';
import 'package:material_symbols_icons/material_symbols_icons.dart'; import 'package:material_symbols_icons/material_symbols_icons.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:super_sliver_list/super_sliver_list.dart'; import 'package:super_sliver_list/super_sliver_list.dart';
class StreamItem { class StreamItem {
@@ -185,12 +187,17 @@ ThoughtChatState useThoughtChat(
final event = jsonDecode(jsonStr); final event = jsonDecode(jsonStr);
final type = event['type']; final type = event['type'];
final eventData = event['data']; final eventData = event['data'];
if (type == 'text') { if (type != 'text') {
talker.info('[Thought] Received event: $type');
}
switch (type) {
case 'text':
streamingItems.value = [ streamingItems.value = [
...streamingItems.value, ...streamingItems.value,
StreamItem('text', eventData), StreamItem('text', eventData),
]; ];
} else if (type == 'function_call') { break;
case 'function_call':
streamingItems.value = [ streamingItems.value = [
...streamingItems.value, ...streamingItems.value,
StreamItem( StreamItem(
@@ -198,7 +205,8 @@ ThoughtChatState useThoughtChat(
SnFunctionCall.fromJson(eventData), SnFunctionCall.fromJson(eventData),
), ),
]; ];
} else if (type == 'function_result') { break;
case 'function_result':
streamingItems.value = [ streamingItems.value = [
...streamingItems.value, ...streamingItems.value,
StreamItem( StreamItem(
@@ -206,11 +214,16 @@ ThoughtChatState useThoughtChat(
SnFunctionResult.fromJson(eventData), SnFunctionResult.fromJson(eventData),
), ),
]; ];
} else if (type == 'reasoning') { break;
case 'reasoning':
streamingItems.value = [ streamingItems.value = [
...streamingItems.value, ...streamingItems.value,
StreamItem('reasoning', eventData), StreamItem('reasoning', eventData),
]; ];
break;
default:
// ignore unknown types
break;
} }
} else if (line.startsWith('topic: ')) { } else if (line.startsWith('topic: ')) {
final jsonStr = line.substring(7); final jsonStr = line.substring(7);
@@ -729,17 +742,13 @@ class ThoughtItem extends StatelessWidget {
hasOpenText = true; hasOpenText = true;
} else if (item.type == 'function_call') { } else if (item.type == 'function_call') {
if (hasOpenText) { if (hasOpenText) {
bool isLastTextBlock = widgets.add(buildTextRow(currentText));
!items.sublist(i).any((it) => it.type == 'text');
widgets.add(buildTextRow(currentText, isLastTextBlock));
currentText = ''; currentText = '';
hasOpenText = false; hasOpenText = false;
} }
// check next for result // check next for result
StreamItem? result; StreamItem? result;
if (i + 1 < items.length && if (i + 1 < items.length && items[i + 1].type == 'function_result') {
items[i + 1].type == 'function_result' &&
items[i + 1].data.callId == item.data.id) {
result = items[i + 1]; result = items[i + 1];
i++; // skip it i++; // skip it
} }
@@ -756,9 +765,7 @@ class ThoughtItem extends StatelessWidget {
); );
} else if (item.type == 'function_result') { } else if (item.type == 'function_result') {
if (hasOpenText) { if (hasOpenText) {
bool isLastTextBlock = widgets.add(buildTextRow(currentText));
!items.sublist(i).any((it) => it.type == 'text');
widgets.add(buildTextRow(currentText, isLastTextBlock));
currentText = ''; currentText = '';
hasOpenText = false; hasOpenText = false;
} }
@@ -775,21 +782,34 @@ class ThoughtItem extends StatelessWidget {
); );
} else if (item.type == 'reasoning') { } else if (item.type == 'reasoning') {
if (hasOpenText) { if (hasOpenText) {
bool isLastTextBlock = widgets.add(buildTextRow(currentText));
!items.sublist(i).any((it) => it.type == 'text');
widgets.add(buildTextRow(currentText, isLastTextBlock));
currentText = ''; currentText = '';
hasOpenText = false; hasOpenText = false;
} }
widgets.add(buildItemWidget(item)); widgets.add(buildItemWidget(item));
} else { } else {
// ignore or throw // ignore
print('unknown item type ${item.type}');
} }
i++; i++;
} }
if (hasOpenText) { if (hasOpenText) {
widgets.add(buildTextRow(currentText, true)); widgets.add(buildTextRow(currentText));
}
// Add spinner at the end if streaming
if (isStreaming) {
widgets.add(
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
const SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(strokeWidth: 2.5),
).padding(left: 8),
],
),
);
} }
// The proposals and token info at the end // The proposals and token info at the end
@@ -810,27 +830,18 @@ class ThoughtItem extends StatelessWidget {
return widgets; return widgets;
} }
Row buildTextRow(String text, bool hasSpinner) { Widget buildTextRow(String text) {
return Row( return Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
Flexible( Flexible(
child: ThoughtContent( child: ThoughtContent(
isStreaming: isStreaming && hasSpinner, isStreaming: isStreaming,
streamingText: text, streamingText: text,
thought: thought, thought: thought,
), ),
), ),
if (isStreaming && hasSpinner)
const SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(
strokeWidth: 2.5,
padding: EdgeInsets.all(4),
),
),
], ],
); );
} }