mirror of
https://github.com/we-promise/sure.git
synced 2026-04-07 22:34:47 +00:00
Backend fixes: - Fix duplicate AssistantResponseJob triggering causing duplicate AI responses - UserMessage model already handles job triggering via after_create_commit callback - Remove redundant job enqueue in chats_controller and messages_controller Mobile app features: - Implement complete AI chat interface and conversation management - Add Chat, Message, and ToolCall data models - Add ChatProvider for state management with polling mechanism - Add ChatService to handle all chat-related API requests - Add chat list screen (ChatListScreen) - Add conversation detail screen (ChatConversationScreen) - Refactor navigation structure with bottom navigation bar (MainNavigationScreen) - Add settings screen (SettingsScreen) - Optimize TransactionsProvider to support account filtering Technical details: - Implement message polling mechanism for real-time AI responses - Support chat creation, deletion, retry and other operations - Integrate Material Design 3 design language - Improve user experience and error handling Co-authored-by: dwvwdv <dwvwdv@protonmail.com>
54 lines
1.4 KiB
Dart
54 lines
1.4 KiB
Dart
import 'dart:convert';
|
|
|
|
class ToolCall {
|
|
final String id;
|
|
final String functionName;
|
|
final Map<String, dynamic> functionArguments;
|
|
final Map<String, dynamic>? functionResult;
|
|
final DateTime createdAt;
|
|
|
|
ToolCall({
|
|
required this.id,
|
|
required this.functionName,
|
|
required this.functionArguments,
|
|
this.functionResult,
|
|
required this.createdAt,
|
|
});
|
|
|
|
factory ToolCall.fromJson(Map<String, dynamic> json) {
|
|
return ToolCall(
|
|
id: json['id'].toString(),
|
|
functionName: json['function_name'] as String,
|
|
functionArguments: _parseJsonField(json['function_arguments']),
|
|
functionResult: json['function_result'] != null
|
|
? _parseJsonField(json['function_result'])
|
|
: null,
|
|
createdAt: DateTime.parse(json['created_at'] as String),
|
|
);
|
|
}
|
|
|
|
static Map<String, dynamic> _parseJsonField(dynamic field) {
|
|
if (field == null) return {};
|
|
if (field is Map<String, dynamic>) return field;
|
|
if (field is String) {
|
|
try {
|
|
final parsed = jsonDecode(field);
|
|
return parsed is Map<String, dynamic> ? parsed : {};
|
|
} catch (e) {
|
|
return {};
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'id': id,
|
|
'function_name': functionName,
|
|
'function_arguments': functionArguments,
|
|
'function_result': functionResult,
|
|
'created_at': createdAt.toIso8601String(),
|
|
};
|
|
}
|
|
}
|