3 files changed
+50
-14
lib/features/chat/data/chat_service.dart
+34
-12
@@ -430,12 +430,23 @@ class OpenAICompatibleChatService implements ChatService {
430
}
431
try {
432
final json = jsonDecode(data) as Map<String, dynamic>;
433
- final content = json['choices']?[0]?['delta']?['content'];
434
- if (content != null && content is String) {
435
- yield ChatResponse(
436
- type: ChatResponseType.message,
437
- content: content,
438
- );
433
+ final delta = json['choices']?[0]?['delta'] as Map<String, dynamic>?;
434
+ if (delta != null) {
435
+ final content = delta['content'] as String?;
436
+ final reasoning = (delta['reasoning'] ?? delta['reasoning_content']) as String?;
437
+
438
+ if (content != null && content.isNotEmpty) {
439
+ yield ChatResponse(
440
+ type: ChatResponseType.message,
441
+ content: content,
442
+ );
443
+ }
444
+ if (reasoning != null && reasoning.isNotEmpty) {
445
+ yield ChatResponse(
446
+ type: ChatResponseType.reasoning,
447
+ reasoningContent: reasoning,
448
+ );
449
+ }
450
}
451
} catch (e) {
452
// ignore: empty_catches
@@ -585,12 +596,23 @@ class OpenRouterChatService implements ChatService {
596
}
597
try {
598
final json = jsonDecode(data) as Map<String, dynamic>;
588
- final content = json['choices']?[0]?['delta']?['content'];
589
- if (content != null && content is String) {
590
- yield ChatResponse(
591
- type: ChatResponseType.message,
592
- content: content,
593
- );
599
+ final delta = json['choices']?[0]?['delta'] as Map<String, dynamic>?;
600
+ if (delta != null) {
601
+ final content = delta['content'] as String?;
602
+ final reasoning = (delta['reasoning'] ?? delta['reasoning_content']) as String?;
603
+
604
+ if (content != null && content.isNotEmpty) {
605
+ yield ChatResponse(
606
+ type: ChatResponseType.message,
607
+ content: content,
608
+ );
609
+ }
610
+ if (reasoning != null && reasoning.isNotEmpty) {
611
+ yield ChatResponse(
612
+ type: ChatResponseType.reasoning,
613
+ reasoningContent: reasoning,
614
+ );
615
+ }
616
}
617
} catch (e) {
618
// ignore: empty_catches
lib/features/chat/views/components/reasoning_widget.dart
+15
-1
@@ -15,7 +15,21 @@ class ReasoningWidget extends StatefulWidget {
15
}
16
17
class _ReasoningWidgetState extends State<ReasoningWidget> {
18
- bool _isExpanded = false;
18
+ late bool _isExpanded;
19
+
20
+ @override
21
+ void initState() {
22
+ super.initState();
23
+ _isExpanded = widget.isStreaming;
24
+ }
25
+
26
+ @override
27
+ void didUpdateWidget(ReasoningWidget oldWidget) {
28
+ super.didUpdateWidget(oldWidget);
29
+ if (widget.isStreaming && !oldWidget.isStreaming) {
30
+ _isExpanded = true;
31
+ }
32
+ }
33
34
String _getLastLines(String content, int maxLines) {
35
final lines = content
pubspec.yaml
+1
-1
@@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
16
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
17
# In Windows, build-name is used as the major, minor, and patch parts
18
# of the product and file versions while build-number is used as the build suffix.
19
-version: 1.0.0+2
19
+version: 1.0.0+3
20
21
environment:
22
sdk: ^3.11.0