398 lines
11 KiB
Dart
398 lines
11 KiB
Dart
import 'setting_node.dart';
|
|
import 'package:ainoval/utils/date_time_parser.dart';
|
|
|
|
/// 设定生成事件基类
|
|
abstract class SettingGenerationEvent {
|
|
final String sessionId;
|
|
final DateTime timestamp;
|
|
final String eventType;
|
|
|
|
const SettingGenerationEvent({
|
|
required this.sessionId,
|
|
required this.timestamp,
|
|
required this.eventType,
|
|
});
|
|
|
|
factory SettingGenerationEvent.fromJson(Map<String, dynamic> json) {
|
|
final eventType = json['eventType'] as String;
|
|
|
|
switch (eventType) {
|
|
case 'SESSION_STARTED':
|
|
return SessionStartedEvent.fromJson(json);
|
|
case 'NODE_CREATED':
|
|
return NodeCreatedEvent.fromJson(json);
|
|
case 'NODE_UPDATED':
|
|
return NodeUpdatedEvent.fromJson(json);
|
|
case 'NODE_DELETED':
|
|
return NodeDeletedEvent.fromJson(json);
|
|
case 'GENERATION_PROGRESS':
|
|
return GenerationProgressEvent.fromJson(json);
|
|
case 'GENERATION_COMPLETED':
|
|
return GenerationCompletedEvent.fromJson(json);
|
|
case 'GENERATION_ERROR':
|
|
return GenerationErrorEvent.fromJson(json);
|
|
case 'COST_ESTIMATION':
|
|
return CostEstimationEvent.fromJson(json);
|
|
default:
|
|
throw ArgumentError('Unknown event type: $eventType');
|
|
}
|
|
}
|
|
|
|
Map<String, dynamic> toJson();
|
|
}
|
|
|
|
/// 预计积分事件
|
|
class CostEstimationEvent extends SettingGenerationEvent {
|
|
final int? estimatedCost;
|
|
final int? estimatedInputTokens;
|
|
final int? estimatedOutputTokens;
|
|
final String? modelProvider;
|
|
final String? modelId;
|
|
final double? creditMultiplier;
|
|
final bool? publicModel;
|
|
|
|
const CostEstimationEvent({
|
|
required String sessionId,
|
|
required DateTime timestamp,
|
|
this.estimatedCost,
|
|
this.estimatedInputTokens,
|
|
this.estimatedOutputTokens,
|
|
this.modelProvider,
|
|
this.modelId,
|
|
this.creditMultiplier,
|
|
this.publicModel,
|
|
}) : super(
|
|
sessionId: sessionId,
|
|
timestamp: timestamp,
|
|
eventType: 'COST_ESTIMATION',
|
|
);
|
|
|
|
factory CostEstimationEvent.fromJson(Map<String, dynamic> json) {
|
|
return CostEstimationEvent(
|
|
sessionId: json['sessionId'] as String,
|
|
timestamp: parseBackendDateTime(json['timestamp']),
|
|
estimatedCost: (json['estimatedCost'] as num?)?.toInt(),
|
|
estimatedInputTokens: (json['estimatedInputTokens'] as num?)?.toInt(),
|
|
estimatedOutputTokens: (json['estimatedOutputTokens'] as num?)?.toInt(),
|
|
modelProvider: json['modelProvider'] as String?,
|
|
modelId: json['modelId'] as String?,
|
|
creditMultiplier: (json['creditMultiplier'] as num?)?.toDouble(),
|
|
publicModel: json['publicModel'] as bool?,
|
|
);
|
|
}
|
|
|
|
@override
|
|
Map<String, dynamic> toJson() => {
|
|
'sessionId': sessionId,
|
|
'timestamp': timestamp.toIso8601String(),
|
|
'eventType': eventType,
|
|
'estimatedCost': estimatedCost,
|
|
'estimatedInputTokens': estimatedInputTokens,
|
|
'estimatedOutputTokens': estimatedOutputTokens,
|
|
'modelProvider': modelProvider,
|
|
'modelId': modelId,
|
|
'creditMultiplier': creditMultiplier,
|
|
'publicModel': publicModel,
|
|
};
|
|
}
|
|
|
|
/// 会话开始事件
|
|
class SessionStartedEvent extends SettingGenerationEvent {
|
|
final String initialPrompt;
|
|
final String strategy;
|
|
|
|
const SessionStartedEvent({
|
|
required String sessionId,
|
|
required DateTime timestamp,
|
|
required this.initialPrompt,
|
|
required this.strategy,
|
|
}) : super(
|
|
sessionId: sessionId,
|
|
timestamp: timestamp,
|
|
eventType: 'SESSION_STARTED',
|
|
);
|
|
|
|
factory SessionStartedEvent.fromJson(Map<String, dynamic> json) {
|
|
return SessionStartedEvent(
|
|
sessionId: json['sessionId'] as String,
|
|
timestamp: parseBackendDateTime(json['timestamp']),
|
|
initialPrompt: json['initialPrompt'] as String,
|
|
strategy: json['strategy'] as String,
|
|
);
|
|
}
|
|
|
|
@override
|
|
Map<String, dynamic> toJson() => {
|
|
'sessionId': sessionId,
|
|
'timestamp': timestamp.toIso8601String(),
|
|
'eventType': eventType,
|
|
'initialPrompt': initialPrompt,
|
|
'strategy': strategy,
|
|
};
|
|
}
|
|
|
|
/// 节点创建事件
|
|
class NodeCreatedEvent extends SettingGenerationEvent {
|
|
final SettingNode node;
|
|
final String? parentPath; // 从根节点到父节点的路径
|
|
|
|
const NodeCreatedEvent({
|
|
required String sessionId,
|
|
required DateTime timestamp,
|
|
required this.node,
|
|
this.parentPath,
|
|
}) : super(
|
|
sessionId: sessionId,
|
|
timestamp: timestamp,
|
|
eventType: 'NODE_CREATED',
|
|
);
|
|
|
|
factory NodeCreatedEvent.fromJson(Map<String, dynamic> json) {
|
|
return NodeCreatedEvent(
|
|
sessionId: json['sessionId'] as String,
|
|
timestamp: parseBackendDateTime(json['timestamp']),
|
|
node: SettingNode.fromJson(json['node'] as Map<String, dynamic>),
|
|
parentPath: json['parentPath'] as String?,
|
|
);
|
|
}
|
|
|
|
@override
|
|
Map<String, dynamic> toJson() => {
|
|
'sessionId': sessionId,
|
|
'timestamp': timestamp.toIso8601String(),
|
|
'eventType': eventType,
|
|
'node': node.toJson(),
|
|
'parentPath': parentPath,
|
|
};
|
|
}
|
|
|
|
/// 节点更新事件
|
|
class NodeUpdatedEvent extends SettingGenerationEvent {
|
|
final SettingNode node;
|
|
final List<String> changedFields;
|
|
|
|
const NodeUpdatedEvent({
|
|
required String sessionId,
|
|
required DateTime timestamp,
|
|
required this.node,
|
|
required this.changedFields,
|
|
}) : super(
|
|
sessionId: sessionId,
|
|
timestamp: timestamp,
|
|
eventType: 'NODE_UPDATED',
|
|
);
|
|
|
|
factory NodeUpdatedEvent.fromJson(Map<String, dynamic> json) {
|
|
return NodeUpdatedEvent(
|
|
sessionId: json['sessionId'] as String,
|
|
timestamp: parseBackendDateTime(json['timestamp']),
|
|
node: SettingNode.fromJson(json['node'] as Map<String, dynamic>),
|
|
changedFields: List<String>.from(json['changedFields'] ?? []),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Map<String, dynamic> toJson() => {
|
|
'sessionId': sessionId,
|
|
'timestamp': timestamp.toIso8601String(),
|
|
'eventType': eventType,
|
|
'node': node.toJson(),
|
|
'changedFields': changedFields,
|
|
};
|
|
}
|
|
|
|
/// 节点删除事件
|
|
class NodeDeletedEvent extends SettingGenerationEvent {
|
|
final List<String> deletedNodeIds;
|
|
final String? reason;
|
|
|
|
const NodeDeletedEvent({
|
|
required String sessionId,
|
|
required DateTime timestamp,
|
|
required this.deletedNodeIds,
|
|
this.reason,
|
|
}) : super(
|
|
sessionId: sessionId,
|
|
timestamp: timestamp,
|
|
eventType: 'NODE_DELETED',
|
|
);
|
|
|
|
factory NodeDeletedEvent.fromJson(Map<String, dynamic> json) {
|
|
// 兼容旧的 'nodeId' 字段和新的 'deletedNodeIds' 字段
|
|
List<String> ids = [];
|
|
if (json.containsKey('deletedNodeIds')) {
|
|
ids = List<String>.from(json['deletedNodeIds']);
|
|
} else if (json.containsKey('nodeId')) {
|
|
ids = [json['nodeId'] as String];
|
|
}
|
|
|
|
return NodeDeletedEvent(
|
|
sessionId: json['sessionId'] as String,
|
|
timestamp: parseBackendDateTime(json['timestamp']),
|
|
deletedNodeIds: ids,
|
|
reason: json['reason'] as String?,
|
|
);
|
|
}
|
|
|
|
@override
|
|
Map<String, dynamic> toJson() => {
|
|
'sessionId': sessionId,
|
|
'timestamp': timestamp.toIso8601String(),
|
|
'eventType': eventType,
|
|
'deletedNodeIds': deletedNodeIds,
|
|
'reason': reason,
|
|
};
|
|
}
|
|
|
|
/// 生成进度事件
|
|
class GenerationProgressEvent extends SettingGenerationEvent {
|
|
final String stage;
|
|
final String message;
|
|
final int? currentStep;
|
|
final int? totalSteps;
|
|
final String? nodeId;
|
|
|
|
const GenerationProgressEvent({
|
|
required String sessionId,
|
|
required DateTime timestamp,
|
|
required this.stage,
|
|
required this.message,
|
|
this.currentStep,
|
|
this.totalSteps,
|
|
this.nodeId,
|
|
}) : super(
|
|
sessionId: sessionId,
|
|
timestamp: timestamp,
|
|
eventType: 'GENERATION_PROGRESS',
|
|
);
|
|
|
|
factory GenerationProgressEvent.fromJson(Map<String, dynamic> json) {
|
|
return GenerationProgressEvent(
|
|
sessionId: json['sessionId'] as String,
|
|
timestamp: parseBackendDateTime(json['timestamp']),
|
|
stage: json['stage'] as String,
|
|
message: json['message'] as String,
|
|
currentStep: json['currentStep'] as int?,
|
|
totalSteps: json['totalSteps'] as int?,
|
|
nodeId: json['nodeId'] as String?,
|
|
);
|
|
}
|
|
|
|
@override
|
|
Map<String, dynamic> toJson() => {
|
|
'sessionId': sessionId,
|
|
'timestamp': timestamp.toIso8601String(),
|
|
'eventType': eventType,
|
|
'stage': stage,
|
|
'message': message,
|
|
'currentStep': currentStep,
|
|
'totalSteps': totalSteps,
|
|
'nodeId': nodeId,
|
|
};
|
|
}
|
|
|
|
/// 生成完成事件
|
|
class GenerationCompletedEvent extends SettingGenerationEvent {
|
|
final String stage;
|
|
final String message;
|
|
final String? resultSummary;
|
|
final List<String>? affectedNodeIds;
|
|
|
|
const GenerationCompletedEvent({
|
|
required String sessionId,
|
|
required DateTime timestamp,
|
|
required this.stage,
|
|
required this.message,
|
|
this.resultSummary,
|
|
this.affectedNodeIds,
|
|
}) : super(
|
|
sessionId: sessionId,
|
|
timestamp: timestamp,
|
|
eventType: 'GENERATION_COMPLETED',
|
|
);
|
|
|
|
factory GenerationCompletedEvent.fromJson(Map<String, dynamic> json) {
|
|
return GenerationCompletedEvent(
|
|
sessionId: json['sessionId'] as String,
|
|
timestamp: parseBackendDateTime(json['timestamp']),
|
|
stage: json['stage'] as String? ?? 'completed',
|
|
message: json['message'] as String? ?? '生成完成',
|
|
resultSummary: json['resultSummary'] as String?,
|
|
affectedNodeIds: json['affectedNodeIds'] != null
|
|
? List<String>.from(json['affectedNodeIds'])
|
|
: null,
|
|
);
|
|
}
|
|
|
|
@override
|
|
Map<String, dynamic> toJson() => {
|
|
'sessionId': sessionId,
|
|
'timestamp': timestamp.toIso8601String(),
|
|
'eventType': eventType,
|
|
'stage': stage,
|
|
'message': message,
|
|
'resultSummary': resultSummary,
|
|
'affectedNodeIds': affectedNodeIds,
|
|
};
|
|
}
|
|
|
|
/// 生成错误事件
|
|
class GenerationErrorEvent extends SettingGenerationEvent {
|
|
final String errorCode;
|
|
final String errorMessage;
|
|
final String? stage;
|
|
final String? nodeId;
|
|
final bool? recoverable;
|
|
final String? suggestionForUser;
|
|
|
|
const GenerationErrorEvent({
|
|
required String sessionId,
|
|
required DateTime timestamp,
|
|
required this.errorCode,
|
|
required this.errorMessage,
|
|
this.stage,
|
|
this.nodeId,
|
|
this.recoverable,
|
|
this.suggestionForUser,
|
|
}) : super(
|
|
sessionId: sessionId,
|
|
timestamp: timestamp,
|
|
eventType: 'GENERATION_ERROR',
|
|
);
|
|
|
|
factory GenerationErrorEvent.fromJson(Map<String, dynamic> json) {
|
|
// 兼容后端在 onErrorResume 分支可能未填充的字段
|
|
final rawSessionId = json['sessionId'];
|
|
final sessionId = (rawSessionId is String && rawSessionId.isNotEmpty)
|
|
? rawSessionId
|
|
: 'unknown-session';
|
|
final rawTimestamp = json['timestamp'];
|
|
final timestamp = rawTimestamp != null
|
|
? parseBackendDateTime(rawTimestamp)
|
|
: DateTime.now();
|
|
return GenerationErrorEvent(
|
|
sessionId: sessionId,
|
|
timestamp: timestamp,
|
|
errorCode: (json['errorCode'] as String?) ?? 'UNKNOWN_ERROR',
|
|
errorMessage: (json['errorMessage'] as String?) ?? '发生错误',
|
|
stage: json['stage'] as String?,
|
|
nodeId: json['nodeId'] as String?,
|
|
recoverable: json['recoverable'] as bool?,
|
|
suggestionForUser: json['suggestionForUser'] as String?,
|
|
);
|
|
}
|
|
|
|
@override
|
|
Map<String, dynamic> toJson() => {
|
|
'sessionId': sessionId,
|
|
'timestamp': timestamp.toIso8601String(),
|
|
'eventType': eventType,
|
|
'errorCode': errorCode,
|
|
'errorMessage': errorMessage,
|
|
'stage': stage,
|
|
'nodeId': nodeId,
|
|
'recoverable': recoverable,
|
|
'suggestionForUser': suggestionForUser,
|
|
};
|
|
}
|