fix(chat): fix ChatBloc event callback and test reliability
- Fix onEvent callback initialization in ChatBloc constructor - Add MockAgUiService to isolate test from mock API behavior - Remove unnecessary non-null assertions in tests
This commit is contained in:
@@ -2,17 +2,23 @@ import 'dart:convert';
|
||||
|
||||
enum Intent { createEvent, searchEvent, unknown }
|
||||
|
||||
class AiDecisionEngine {
|
||||
/// 意图匹配规则(顺序敏感:searchEvent 优先级高于 createEvent)
|
||||
static final List<(RegExp, Intent)> _orderedPatterns = [
|
||||
(RegExp(r'^查看|^有什么|^今天.*日程|^明天.*安排|^查询'), Intent.searchEvent),
|
||||
(RegExp(r'提醒|开会|预约|安排.*时间|创建.*日程'), Intent.createEvent),
|
||||
(
|
||||
RegExp(r'明天.*\d|今天.*\d|后天.*\d|\d{1,2}点|\d{1,2}:\d{2}'),
|
||||
Intent.createEvent,
|
||||
),
|
||||
];
|
||||
/// 意图匹配规则(顺序敏感:searchEvent 优先级高于 createEvent)
|
||||
final _orderedPatterns = <(RegExp, Intent)>[
|
||||
(RegExp(r'^查看|^有什么|^今天.*日程|^明天.*安排|^查询'), Intent.searchEvent),
|
||||
(RegExp(r'提醒|开会|预约|安排.*时间|创建.*日程'), Intent.createEvent),
|
||||
(RegExp(r'明天.*\d|今天.*\d|后天.*\d|\d{1,2}点|\d{1,2}:\d{2}'), Intent.createEvent),
|
||||
];
|
||||
|
||||
/// 时区常量
|
||||
const _defaultTimezone = 'Asia/Shanghai';
|
||||
const _dayToday = '今天';
|
||||
const _dayTomorrow = '明天';
|
||||
const _dayAfterTomorrow = '后天';
|
||||
const _tomorrowOffset = 1;
|
||||
const _dayAfterTomorrowOffset = 2;
|
||||
const _defaultMinute = 0;
|
||||
|
||||
class AiDecisionEngine {
|
||||
Intent matchIntent(String text) {
|
||||
for (final (pattern, intent) in _orderedPatterns) {
|
||||
if (pattern.hasMatch(text)) return intent;
|
||||
@@ -34,31 +40,33 @@ class AiDecisionEngine {
|
||||
.trim();
|
||||
}
|
||||
|
||||
if (args['title'] == null || (args['title'] as String).isEmpty) return null;
|
||||
final title = args['title'];
|
||||
if (title == null || (title as String).isEmpty) return null;
|
||||
|
||||
final timeMatch = RegExp(
|
||||
r'(明天|今天|后天)?\s*(\d{1,2})[:点](\d{2})?',
|
||||
).firstMatch(text);
|
||||
if (timeMatch != null) {
|
||||
final dayStr = timeMatch.group(1) ?? '今天';
|
||||
final dayStr = timeMatch.group(1) ?? _dayToday;
|
||||
final hour = int.parse(timeMatch.group(2)!);
|
||||
final minute = int.parse(timeMatch.group(3) ?? '0');
|
||||
final minute = int.parse(timeMatch.group(3) ?? '$_defaultMinute');
|
||||
|
||||
final now = DateTime.now();
|
||||
DateTime startAt;
|
||||
switch (dayStr) {
|
||||
case '明天':
|
||||
startAt = DateTime(now.year, now.month, now.day + 1, hour, minute);
|
||||
break;
|
||||
case '后天':
|
||||
startAt = DateTime(now.year, now.month, now.day + 2, hour, minute);
|
||||
break;
|
||||
default:
|
||||
startAt = DateTime(now.year, now.month, now.day, hour, minute);
|
||||
}
|
||||
final dayOffset = switch (dayStr) {
|
||||
_dayTomorrow => _tomorrowOffset,
|
||||
_dayAfterTomorrow => _dayAfterTomorrowOffset,
|
||||
_ => 0,
|
||||
};
|
||||
final startAt = DateTime(
|
||||
now.year,
|
||||
now.month,
|
||||
now.day + dayOffset,
|
||||
hour,
|
||||
minute,
|
||||
);
|
||||
|
||||
args['startAt'] = startAt.toIso8601String();
|
||||
args['timezone'] = 'Asia/Shanghai';
|
||||
args['timezone'] = _defaultTimezone;
|
||||
}
|
||||
|
||||
if (!args.containsKey('startAt')) return null;
|
||||
|
||||
Reference in New Issue
Block a user