import 'package:get/get.dart'; import '../../../data/services/bailian_multimodal_service.dart'; import '../../emai/controllers/emai_controller.dart'; /// EaiCar 车载助手的依赖装配。 /// /// 复用 EMAI 那套对话 UI 与控制器,只把「连哪个百炼应用」换掉: /// 这里 put 一个带 EaiCar 专属 app_id 的 [BailianMultimodalService], /// 再用它构造一个同 tag 的 [EmaiController]。 /// /// ⚠️ **两者都必须带 tag**:不带 tag 会覆盖掉全局那个 EMAI 用的实例, /// 表现为退出车载助手后 EMAI 也连到了车载的应用上。 /// `EmaiView(controllerTag: kEaiCarTag)` 靠同一个 tag 取到这里的控制器。 /// /// ⚠️ **service 必须是独立实例**,不能 `Get.find` 全局那个: /// `BailianMultimodalService.start()` 第一件事就是 `stop()`,共用会让两个 agent /// 互相把对方的会话掐掉,下行音频还会串到对方的播放器上。 class EaiCarChatBinding extends Bindings { @override void dependencies() { if (!Get.isRegistered(tag: kEaiCarTag)) { Get.put( BailianMultimodalService(appId: kEaiCarBailianAppId), tag: kEaiCarTag, permanent: true, ); } Get.lazyPut( () => EmaiController( service: Get.find(tag: kEaiCarTag), // 手机麦也和设备一样半双工:AI 说话时关麦,说完才开 halfDuplexMic: true, ), tag: kEaiCarTag, ); } } /// GetX 实例 tag:service 与 controller 共用这一个 const String kEaiCarTag = 'eaicar'; /// EaiCar 车载助手在百炼里的多模态应用 ID(workspace 与 EMAI 同一个, /// 所以不覆盖 workspaceId,让它走全局配置)。 /// /// ⚠️ 写死在客户端是**有意选的**(落地文档 6.3 方案 A):换 app_id 要发版。 /// 等运营提出「要后台随时改」时,再改成从 `DBAgent.serviceData` 下发—— /// 那时要给客户端手写镜像补 `source` / `serviceData` 两个字段,且**必须 nullable**, /// 否则老后端不下发就整个 `fromJson` 抛 TypeError、应用配置全空白。 const String kEaiCarBailianAppId = 'mm_127ddb82ba1244a99d2feaef0c1f';