Files
social-app/apps/lib/features/chat/data/tools/route_navigation_tool.dart
T
zl-q 120df903d2 feat: AG-UI 协议对齐与路由导航功能
- 前端: 添加 SSE 流式支持、stateSnapshot 事件、路由导航工具
- 前端: 实现工具调用审批流程,支持 pending 状态展示
- 后端: Agent 状态管理与会话持久化相关重构
- 文档: 新增 agent-agui-full-alignance 设计文档
- 测试: 补充相关单元测试和集成测试
2026-03-07 17:30:20 +08:00

79 lines
1.7 KiB
Dart

typedef RouteNavigator = void Function(String target, {bool replace});
const Set<String> _allowedRoutes = {
'/settings',
'/todo',
'/calendar/dayweek',
'/messages/invites',
};
const List<String> _allowedRoutePrefixes = [
'/calendar/events/',
];
class RouteNavigationTool {
RouteNavigationTool._();
static final RouteNavigationTool instance = RouteNavigationTool._();
RouteNavigator? _navigator;
void bindNavigator(RouteNavigator navigator) {
_navigator = navigator;
}
void clearNavigator() {
_navigator = null;
}
Map<String, dynamic> execute(Map<String, dynamic> args) {
final target = args['target'];
if (target is! String || target.isEmpty) {
return {
'ok': false,
'error': 'target is required',
};
}
if (!_isAllowedTarget(target)) {
return {
'ok': false,
'target': target,
'error': 'target is not allowed',
};
}
final replace = args['replace'] == true;
final navigator = _navigator;
if (navigator == null) {
return {
'ok': false,
'target': target,
'replace': replace,
'error': 'navigator not bound',
};
}
navigator(target, replace: replace);
return {
'ok': true,
'target': target,
'replace': replace,
'applied': true,
};
}
bool _isAllowedTarget(String target) {
if (!target.startsWith('/')) {
return false;
}
final normalized = target.split('?').first;
if (_allowedRoutes.contains(normalized)) {
return true;
}
for (final prefix in _allowedRoutePrefixes) {
if (normalized.startsWith(prefix)) {
return true;
}
}
return false;
}
}