mcpField
I
integrate-genui-firebase

integrate-genui-firebase

github.com/flutter开发1.8k82 次安装2 周前更新
代码仓库

关于 integrate-genui-firebase

这项技能指导开发者在现有 Flutter 应用中加入 genui,并连接 Firebase AI Logic 对话 Agent。它涵盖依赖配置、控制器与事件接线及界面渲染,并要求先确认状态组件和输入控件选择。

主要功能

  1. 01检查 Firebase 初始化与依赖
  2. 02添加 genui 并配置日志
  3. 03连接对话与界面控制器
  4. 04通过 Firebase AI Logic 传递消息
  5. 05处理对话事件并渲染界面
  6. 06先确认状态组件和输入界面

适用场景

  1. 01在 Flutter 聊天界面集成 GenUI
  2. 02将聊天会话连接到 Firebase AI Logic
  3. 03在应用中呈现 Agent 提供的界面

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/flutter/genui --skill integrate-genui-firebase

安装后在 Claude Code 中输入/integrate-genui-firebase确认已加载。

详细介绍

将 GenUI 与 Firebase AI Logic 集成

目标

将 genui 包成功集成到 Flutter 应用中,并使用 Firebase AI Logic 设置基本的对话 Agent。本指南假设项目中已设置并正常运行 Firebase AI Logic。

说明

接到集成 genui 并开始简单对话的任务时,请按以下步骤操作:

  1. 验证 Firebase 设置: 确保 pubspec.yaml 中包含 firebase_core 和 firebase_ai。 确认在 main() 函数中调用了 Firebase.initializeApp:

    WidgetsFlutterBinding.ensureInitialized();
    await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
    
  2. 添加 GenUI 包: 将 genui 添加到 pubspec.yaml 的依赖项中。

  3. 导入所需库: 导入 genui 并隐藏 TextPart,以免与其他包冲突,然后再次导入并为其指定别名:

    import 'package:genui/genui.dart' hide TextPart;
    import 'package:genui/genui.dart' as genui;
    
  4. 配置基本日志记录: 在 main() 函数开头配置 GenUI 日志记录:

    configureLogging(
      logCallback: (level, msg) => debugPrint('GenUI $level: $msg'),
    );
    
  5. 创建模型和聊天会话: 初始化生成式模型并启动聊天会话。

    final model = FirebaseAI.googleAI().generativeModel(
      model: 'gemini-3-flash-preview',
    );
    final _chatSession = model.startChat();
    
  6. 确定目标 StatefulWidget: 如果不确定,请暂停并询问用户: 此集成需要一个 StatefulWidget 来保存 GenUI 控制器(SurfaceController、A2uiTransportAdapter 和 Conversation)的引用。确定应用中要使用哪个 StatefulWidget。如果不确定哪个 Widget 应保存此状态,请在继续之前询问用户。

  7. 在 State 中连接 GenUI 控制器: 在已确定的 State 类中,实例化 SurfaceController、A2uiTransportAdapter 和 Conversation:

    final catalog = BasicCatalogItems.asCatalog(); // Optionally inject custom CatalogItems
    final _controller = SurfaceController(catalogs: [catalog]);
    final _transport = A2uiTransportAdapter(onSend: _sendAndReceive);
    final _conversation = Conversation(
      controller: _controller,
      transport: _transport,
    );
    
  8. 实现 _sendAndReceive 方法: 创建一个方法,从传输适配器获取消息,将其发送到 Firebase,并将 AI 的响应传回传输适配器。

    Future<void> _sendAndReceive(ChatMessage msg) async {
      final buffer = StringBuffer();
    
      for (final part in msg.parts) {
        if (part.isUiInteractionPart) {
          buffer.write(part.asUiInteractionPart!.interaction);
        } else if (part is genui.TextPart) {
          buffer.write(part.text);
        }
      }
    
      if (buffer.isEmpty) return;
    
      final text = buffer.toString();
      final response = await _chatSession.sendMessage(Content.text(text));
    
      if (response.text?.isNotEmpty ?? false) {
        _transport.addChunk(response.text!);
      }
    }
    
  9. 监听 Conversation 事件: 在 State 类中为每种事件类型创建空方法,并添加 DartDoc 注释说明这些方法需要执行的行为。根据界面设计,Agent 发来的新界面和文本会采用不同的处理方式。例如,对话界面可以将所有内容添加到列表中,并显示在 ListView 中;而在标题、页脚等特定位置展示 UI 组件的界面,可能会依赖系统指令中提供给 Agent 的特定表面 ID,以确定在哪些位置显示哪些表面。

    /// Updates state to include the new [surfaceId] so a new `Surface` widget can be built.
    void _onSurfaceAdded(String surfaceId) {
      // TODO: Implement state update to add surfaceId
    }
    
    /// Updates state to remove the [surfaceId] so its `Surface` widget is no longer built.
    void _onSurfaceRemoved(String surfaceId) {
      // TODO: Implement state update to remove surfaceId
    }
    
    /// Handles displaying raw text content received from the AI to the user.
    void _onContentReceived(String text) {
      // TODO: Implement displaying the received text
    }
    
    /// Handles errors that occur during the conversation appropriately.
    void _onError(Object error) {
      // TODO: Implement error handling
    }
    

    订阅 _conversation.events,以跟踪 UI 表面或聊天消息的到达情况,并将其分派到相应的空方法:

    _conversation.events.listen((event) {
      switch (event) {
        case ConversationSurfaceAdded added:
          _onSurfaceAdded(added.surfaceId);
        case ConversationSurfaceRemoved removed:
          _onSurfaceRemoved(removed.surfaceId);
        case ConversationContentReceived content:
          _onContentReceived(content.text);
        case ConversationError error:
          _onError(error.error);
        default:
      }
    });
    
  10. 初始化系统提示词: 使用 PromptBuilder 为 AI 提供基本指令,然后将其作为系统消息发送。

    final promptBuilder = PromptBuilder.chat(
      catalog: catalog,
      instructions: 'You are a helpful assistant. Respond to messages in a chatty way.',
    );
    _conversation.sendRequest(ChatMessage.system(promptBuilder.systemPrompt));
    
  11. 显示表面: 在 Flutter 的 build() 方法中,使用在第 9 步收集的 surfaceIds,在需要渲染 GenUI Widget 的位置放置 Surface Widget。

    Surface(surfaceContext: _controller.contextFor(surfaceId));
    
  12. 询问用户的输入偏好: 暂停并询问用户: 请用户说明希望使用哪些 UI 元素来接收输入。说明 TextField 和 ElevatedButton 是不错的默认选项,但除非用户明确选择,否则不要假定他们就想使用这些 Widget。

约束

  • 不要擅自假设用户输入 UI 元素;请参阅第 12 步。
  • 确保在 Widget 的 dispose() 方法中正确清理 GenUI 控制器(_transport.dispose()、_controller.dispose())。

评论

支持 Markdown