Use json_serializable and const to improve AI data model
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
import 'ai_message.dart';
|
import 'ai_message.dart';
|
||||||
|
|
||||||
class AIAPIRequest {
|
class AIAPIRequest {
|
||||||
|
static const String _defaultModel = 'gpt-oss-120b';
|
||||||
|
|
||||||
final List<AIMessage> messages;
|
final List<AIMessage> messages;
|
||||||
|
|
||||||
const AIAPIRequest({
|
const AIAPIRequest({
|
||||||
@@ -9,7 +11,7 @@ class AIAPIRequest {
|
|||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return {
|
return {
|
||||||
'model': 'gpt-oss-120b',
|
'model': _defaultModel,
|
||||||
'messages': messages.map((m) => m.toJson()).toList(),
|
'messages': messages.map((m) => m.toJson()).toList(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,44 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'ai_api_response.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
class AIApiResponse {
|
class AIApiResponse {
|
||||||
final String content;
|
final List<Choice> choices;
|
||||||
|
|
||||||
const AIApiResponse({
|
const AIApiResponse({
|
||||||
|
required this.choices
|
||||||
|
});
|
||||||
|
|
||||||
|
factory AIApiResponse.fromJson(Map<String, dynamic> json) => _$AIApiResponseFromJson(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$AIApiResponseToJson(this);
|
||||||
|
|
||||||
|
String? get content => choices.isNotEmpty ? choices[0].message.content : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class Choice {
|
||||||
|
final Message message;
|
||||||
|
|
||||||
|
const Choice({
|
||||||
|
required this.message
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Choice.fromJson(Map<String, dynamic> json) => _$ChoiceFromJson(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$ChoiceToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class Message {
|
||||||
|
final String content;
|
||||||
|
|
||||||
|
const Message({
|
||||||
required this.content
|
required this.content
|
||||||
});
|
});
|
||||||
|
|
||||||
static AIApiResponse? parse(Map<String, dynamic> json) {
|
factory Message.fromJson(Map<String, dynamic> json) => _$MessageFromJson(json);
|
||||||
final choices = json['choices'] as List<dynamic>?;
|
|
||||||
if (choices == null || choices.isEmpty) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final firstChoice = choices[0] as Map<String, dynamic>?;
|
Map<String, dynamic> toJson() => _$MessageToJson(this);
|
||||||
if (firstChoice == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final message = firstChoice['message'] as Map<String, dynamic>?;
|
|
||||||
if (message == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final content = message['content'] as String?;
|
|
||||||
if (content == null || content.isEmpty) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return AIApiResponse(content: content);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'ai_message.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
class AIMessage {
|
class AIMessage {
|
||||||
final String role;
|
final String role;
|
||||||
final String content;
|
final String content;
|
||||||
@@ -7,10 +12,7 @@ class AIMessage {
|
|||||||
required this.content,
|
required this.content,
|
||||||
});
|
});
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
factory AIMessage.fromJson(Map<String, dynamic> json) => _$AIMessageFromJson(json);
|
||||||
return {
|
|
||||||
'role': role,
|
Map<String, dynamic> toJson() => _$AIMessageToJson(this);
|
||||||
'content': content,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,12 +28,7 @@ class AIApi {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
final parsedResponse = AIApiResponse.parse(response.data);
|
return AIApiResponse.fromJson(response.data);
|
||||||
if (parsedResponse != null) {
|
|
||||||
return parsedResponse;
|
|
||||||
} else {
|
|
||||||
throw Exception('Empty response from AI service');
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
throw Exception('AI API returned status code: ${response.statusCode}');
|
throw Exception('AI API returned status code: ${response.statusCode}');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
class AIResponse {
|
class AIResponse {
|
||||||
final String result;
|
final String? result;
|
||||||
|
|
||||||
const AIResponse({required this.result});
|
const AIResponse({required this.result});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user