refactor(chat): 重构聊天模块并集成历史消息加载功能

- 删除冗余的 chat_history_repository 和 home_mock_data
- 简化 ag_ui_event fromJson 使用工厂映射表
- 提取 ChatBloc 事件处理方法,添加 loadHistory/loadMoreHistory
- HomeScreen 集成 ChatBloc 实现历史消息加载和下拉刷新
- 更新 AGENTS.md 文档约束
This commit is contained in:
qzl
2026-03-02 15:05:10 +08:00
parent 6b32990986
commit e161ca22c4
16 changed files with 915 additions and 752 deletions
@@ -34,6 +34,7 @@ enum AgUiEventType {
unknown,
}
// wire 类型到枚举的映射
const _wireToTypeMap = {
AgUiEventTypeWire.runStarted: AgUiEventType.runStarted,
AgUiEventTypeWire.runFinished: AgUiEventType.runFinished,
@@ -49,6 +50,7 @@ const _wireToTypeMap = {
AgUiEventTypeWire.messagesSnapshot: AgUiEventType.messagesSnapshot,
};
// 枚举到 wire 类型的映射
const _typeToWireMap = {
AgUiEventType.runStarted: AgUiEventTypeWire.runStarted,
AgUiEventType.runFinished: AgUiEventTypeWire.runFinished,
@@ -70,6 +72,23 @@ AgUiEventType agUiEventTypeFromWire(String wire) =>
String agUiEventTypeToWire(AgUiEventType type) => _typeToWireMap[type] ?? '';
// 类型到工厂函数的映射,用于简化 fromJson
final _typeToFactory = {
AgUiEventType.runStarted: RunStartedEvent.fromJson,
AgUiEventType.runFinished: RunFinishedEvent.fromJson,
AgUiEventType.runError: RunErrorEvent.fromJson,
AgUiEventType.textMessageStart: TextMessageStartEvent.fromJson,
AgUiEventType.textMessageContent: TextMessageContentEvent.fromJson,
AgUiEventType.textMessageEnd: TextMessageEndEvent.fromJson,
AgUiEventType.toolCallStart: ToolCallStartEvent.fromJson,
AgUiEventType.toolCallArgs: ToolCallArgsEvent.fromJson,
AgUiEventType.toolCallEnd: ToolCallEndEvent.fromJson,
AgUiEventType.toolCallResult: ToolCallResultEvent.fromJson,
AgUiEventType.toolCallError: ToolCallErrorEvent.fromJson,
AgUiEventType.messagesSnapshot: MessagesSnapshotEvent.fromJson,
AgUiEventType.unknown: UnknownAgUiEvent.fromJson,
};
@JsonSerializable()
class AgUiEvent {
final AgUiEventType type;
@@ -79,35 +98,7 @@ class AgUiEvent {
factory AgUiEvent.fromJson(Map<String, dynamic> json) {
final typeStr = json['type'] as String? ?? '';
final type = agUiEventTypeFromWire(typeStr);
switch (type) {
case AgUiEventType.runStarted:
return RunStartedEvent.fromJson(json);
case AgUiEventType.runFinished:
return RunFinishedEvent.fromJson(json);
case AgUiEventType.runError:
return RunErrorEvent.fromJson(json);
case AgUiEventType.textMessageStart:
return TextMessageStartEvent.fromJson(json);
case AgUiEventType.textMessageContent:
return TextMessageContentEvent.fromJson(json);
case AgUiEventType.textMessageEnd:
return TextMessageEndEvent.fromJson(json);
case AgUiEventType.toolCallStart:
return ToolCallStartEvent.fromJson(json);
case AgUiEventType.toolCallArgs:
return ToolCallArgsEvent.fromJson(json);
case AgUiEventType.toolCallEnd:
return ToolCallEndEvent.fromJson(json);
case AgUiEventType.toolCallResult:
return ToolCallResultEvent.fromJson(json);
case AgUiEventType.toolCallError:
return ToolCallErrorEvent.fromJson(json);
case AgUiEventType.messagesSnapshot:
return MessagesSnapshotEvent.fromJson(json);
case AgUiEventType.unknown:
return UnknownAgUiEvent.fromJson(json);
}
return _typeToFactory[type]?.call(json) ?? UnknownAgUiEvent.fromJson(json);
}
Map<String, dynamic> toJson() => _$AgUiEventToJson(this);
@@ -322,6 +313,7 @@ class SnapshotMessage {
final String? content;
final String? toolCallId;
final UiCard? ui;
final DateTime? timestamp;
SnapshotMessage({
required this.id,
@@ -329,6 +321,7 @@ class SnapshotMessage {
this.content,
this.toolCallId,
this.ui,
this.timestamp,
});
factory SnapshotMessage.fromJson(Map<String, dynamic> json) =>