@@ -30,18 +30,79 @@ class SessionChatInputCard extends ConsumerStatefulWidget {
3030}
3131
3232class _SessionChatInputCardState extends ConsumerState <SessionChatInputCard > {
33+ Set <String > _extractMentionedTables (String encoded) {
34+ final segments = MentionSegmentSerializer .decode (encoded);
35+ final tableNames = < String > {};
36+
37+ // 只取“真正的 mention token”
38+ for (final s in segments) {
39+ if (s is MentionSegment ) {
40+ tableNames.add (s.label);
41+ }
42+ }
43+
44+ return tableNames;
45+ }
46+
47+ MetaDataNode ? _findSchemaNode (SessionAIChatModel chatModel) {
48+ if (chatModel.metadata == null || chatModel.currentSchema == null ) return null ;
49+ final root = MetaDataNode (MetaType .instance, "" , items: chatModel.metadata! .metadata);
50+ MetaDataNode ? schemaNode;
51+ root.visitor ((node, _) {
52+ if (schemaNode != null ) return false ;
53+ if (node.type == MetaType .schema && node.value == chatModel.currentSchema) {
54+ schemaNode = node;
55+ return false ;
56+ }
57+ return true ;
58+ });
59+ return schemaNode;
60+ }
61+
62+ String _buildTableRef (SessionAIChatModel chatModel, Iterable <String > mentionedTables) {
63+ final schemaNode = _findSchemaNode (chatModel);
64+ if (schemaNode == null ) return '' ;
65+
66+ final tables = mentionedTables.toSet ().toList ()..sort ();
67+ if (tables.isEmpty) return '' ;
68+
69+ final b = StringBuffer ();
70+ for (final tableName in tables) {
71+ MetaDataNode ? tableNode;
72+ for (final n in (schemaNode.items ?? const < MetaDataNode > [])) {
73+ if (n.type == MetaType .table && n.value == tableName) {
74+ tableNode = n;
75+ break ;
76+ }
77+ }
78+
79+ // 直接复用 MetaDataNode.toString() 的 JSON 序列化(见 db_driver_metadata.dart)
80+ if (tableNode != null ) {
81+ b.writeln (tableNode.toString ());
82+ }
83+ }
84+
85+ return b.toString ().trimRight ();
86+ }
87+
3388 Future <void > _sendMessage (AIChatId chatId, SessionAIChatModel chatModel) async {
3489 final chatInputController = SessionController .sessionController (chatModel.sessionId).chatInputController;
3590 final encoded = chatInputController.text.trim ();
36- final text = MentionSegmentSerializer .decode (encoded).map ((s) => s.toDisplayText ()).join ().trim ();
91+ final segments = MentionSegmentSerializer .decode (encoded);
92+ final text = segments.map ((s) => s.toDisplayText ()).join ().trim ();
3793 chatInputController.clear ();
3894
95+ // 如果用户通过 @ 提及了表,则把表结构信息放到 ref 里
96+ final mentionedTables = _extractMentionedTables (encoded);
97+ final refText = _buildTableRef (chatModel, mentionedTables);
98+
3999 // 调用AIChatService的chat方法
40100 await ref.read (aIChatServiceProvider.notifier).chat (
41101 chatId,
42102 chatModel.llmAgents.lastUsedLLMAgent! .id,
43103 genChatSystemPrompt (chatModel),
44104 message: text,
105+ refText: refText.isEmpty ? null : refText,
45106 );
46107
47108 final scrollController = SessionController .sessionController (chatModel.sessionId).aiChatScrollController;
@@ -80,9 +141,8 @@ class _SessionChatInputCardState extends ConsumerState<SessionChatInputCard> {
80141 // 输入框
81142 ChatInputFieldWidget (
82143 model: widget.model,
83- onSubmitted: widget.model.canSendMessage ()
84- ? () => _sendMessage (widget.model.chatModel.id, widget.model)
85- : null ,
144+ onSubmitted:
145+ widget.model.canSendMessage () ? () => _sendMessage (widget.model.chatModel.id, widget.model) : null ,
86146 ),
87147
88148 const SizedBox (height: kSpacingSmall),
@@ -375,12 +435,9 @@ class _ChatInputFieldWidgetState extends ConsumerState<ChatInputFieldWidget> {
375435 if (widget.model.metadata == null || widget.model.currentSchema == null ) {
376436 return [];
377437 }
378- final schema = MetaDataNode (MetaType .instance, "" , items: widget.model.metadata! );
438+ final schema = MetaDataNode (MetaType .instance, "" , items: widget.model.metadata! .metadata );
379439 final schemaNodes = schema.getChildren (MetaType .schema, widget.model.currentSchema! );
380- return schemaNodes
381- .where ((e) => e.type == MetaType .table)
382- .map ((e) => e.value)
383- .toList ();
440+ return schemaNodes.where ((e) => e.type == MetaType .table).map ((e) => e.value).toList ();
384441 }
385442
386443 List <String > _filterAndSortTables (List <String > allTables, String query) {
0 commit comments