From 33aef48f84a2404d87401964469a2589ac1adfdb Mon Sep 17 00:00:00 2001 From: "guangfei.zhao" Date: Wed, 17 Sep 2025 15:09:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5=20oneApp=20=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CODE_ANALYSIS.md | 425 ++++++++++++++++++ android/build.gradle | 14 +- .../reports/problems/problems-report.html | 4 +- android/settings.gradle | 2 +- assets/images/ai1.png | Bin 0 -> 8621 bytes assets/images/ai2.png | Bin 0 -> 7275 bytes devtools_options.yaml | 3 + example/android/app/build.gradle.kts | 4 +- example/pubspec.lock | 100 ++--- example/pubspec.yaml | 4 +- lib/main.dart | 18 - lib/screens/part_screen.dart | 19 +- lib/services/chat_sse_service.dart | 13 +- lib/services/message_service.dart | 14 +- lib/utils/tts_util.dart | 2 +- lib/widgets/chat_bubble.dart | 37 +- lib/widgets/chat_header.dart | 2 +- packages/basic_intl/pubspec.lock | 82 ++-- packages/basic_intl/pubspec.yaml | 2 +- pubspec.lock | 36 +- pubspec.yaml | 2 +- 21 files changed, 597 insertions(+), 186 deletions(-) create mode 100644 CODE_ANALYSIS.md create mode 100644 assets/images/ai1.png create mode 100644 assets/images/ai2.png create mode 100644 devtools_options.yaml delete mode 100644 lib/main.dart diff --git a/CODE_ANALYSIS.md b/CODE_ANALYSIS.md new file mode 100644 index 0000000..213931c --- /dev/null +++ b/CODE_ANALYSIS.md @@ -0,0 +1,425 @@ +# AI Chat Assistant Flutter Plugin - 详细代码逻辑文档 + +## 📋 项目概述 + +这是一个专为车载系统设计的AI聊天助手Flutter插件,采用插件化架构设计,支持语音识别、AI对话、车控命令执行等功能。项目从原有的App结构重构为Plugin结构,便于集成到其他Flutter应用中。 + +## 🏗️ 核心架构分析 + +### 1. 架构模式 + +- **插件化架构**: 采用Flutter Plugin架构,便于第三方应用集成 +- **单例模式**: 核心服务类(MessageService)采用单例模式确保全局状态一致 +- **观察者模式**: 基于Provider的状态管理,实现响应式UI更新 +- **回调机制**: 通过CommandCallback实现车控命令的解耦处理 + +### 2. 目录结构与职责 + +``` +lib/ +├── app.dart # 插件主入口,提供初始化接口 +├── enums/ # 枚举定义层 +├── models/ # 数据模型层 +├── services/ # 业务逻辑服务层 +├── screens/ # UI界面层 +├── widgets/ # UI组件层 +├── utils/ # 工具类层 +└── themes/ # 主题样式层 +``` + +## 🔧 核心枚举定义 (Enums) + +### MessageServiceState +```dart +enum MessageServiceState { + idle, // 空闲状态 + recording, // 录音中 + recognizing, // 识别中 + replying, // 回复中 +} +``` + +### MessageStatus +```dart +enum MessageStatus { + normal, // 普通消息 + listening, // 聆听中 + recognizing, // 识别中 + thinking, // 思考中 + completed, // 完成回答 + executing, // 执行中 + success, // 执行成功 + failure, // 执行失败 + aborted, // 已中止 +} +``` + +### VehicleCommandType +支持22种车控命令类型: +- 车门控制:lock, unlock +- 车窗控制:openWindow, closeWindow +- 空调控制:openAC, closeAC, changeACTemp, coolSharply +- 特殊功能:prepareCar, meltSnow, honk, locateCar +- 加热功能:座椅加热、方向盘加热等 + +## 📊 数据模型层 (Models) + +### ChatMessage +```dart +class ChatMessage { + final String id; // 消息唯一标识 + final String text; // 消息内容 + final bool isUser; // 是否为用户消息 + final DateTime timestamp; // 时间戳 + MessageStatus status; // 消息状态 +} +``` + +### VehicleCommand +```dart +class VehicleCommand { + final VehicleCommandType type; // 命令类型 + final Map? params; // 命令参数 + final String error; // 错误信息 +} +``` + +## 🔄 核心服务层 (Services) + +### 1. MessageService - 核心消息管理服务 + +**设计模式**: 单例模式 + 观察者模式 + +**主要职责**: +- 统一管理聊天消息 +- 协调语音识别、AI对话、车控命令执行流程 +- 维护应用状态机 + +**核心方法分析**: + +#### 语音输入流程 +```dart +// 开始语音输入 +Future startVoiceInput() async { + // 1. 权限检查 + // 2. 状态验证 + // 3. 初始化录音 + // 4. 调用原生ASR服务 +} + +// 停止并处理语音输入 +Future stopAndProcessVoiceInput() async { + // 1. 停止录音 + // 2. 等待ASR结果 + // 3. 调用reply()处理识别结果 +} +``` + +#### 智能回复流程 +```dart +Future reply(String text) async { + // 1. 文本分类(TextClassificationService) + // 2. 根据分类结果路由到不同处理逻辑: + // - 车控命令 (category=2) -> handleVehicleControl() + // - 普通问答 (default) -> answerQuestion() + // - 错误问题 (category=4) -> answerWrongQuestion() + // - 系统错误 (category=-1) -> occurError() +} +``` + +#### 车控命令处理 +```dart +Future handleVehicleControl(String text, bool isChinese) async { + // 1. 调用VehicleCommandService解析命令 + // 2. 执行TTS播报 + // 3. 逐个执行车控命令 + // 4. 处理命令执行结果 + // 5. 生成执行反馈 +} +``` + +**状态管理机制**: +- 使用`ChangeNotifier`实现响应式状态更新 +- 通过`_state`维护服务状态机 +- 使用`_isReplyAborted`实现流程中断控制 + +### 2. CommandService - 车控命令处理服务 + +**设计模式**: 静态方法 + 回调机制 + +**职责**: +- 提供车控命令执行接口 +- 维护主应用注册的回调函数 +- 实现命令执行的解耦 + +```dart +// 命令回调函数定义 +typedef CommandCallback = Future<(bool, Map? params)> Function( + VehicleCommandType type, Map? params); + +// 执行车控命令 +static Future<(bool, Map? params)> executeCommand( + VehicleCommandType type, {Map? params}) async { + // 调用注册的回调函数执行实际车控逻辑 +} +``` + +### 3. TextClassificationService - 文本分类服务 + +**职责**: 对用户输入文本进行意图分类 + +```dart +Future classifyText(String text) async { + // HTTP POST请求到分类服务 + // 返回分类结果: + // -1: 错误 + // 2: 车控命令 + // 4: 错误问题 + // 其他: 普通问答 +} +``` + +### 4. VehicleCommandService - 车控命令解析服务 + +**职责**: +- 解析自然语言为车控命令 +- 生成命令执行反馈 + +```dart +Future getCommandFromText(String text) async { + // 1. 发送文本到车控解析服务 + // 2. 解析返回的命令列表 + // 3. 返回VehicleCommandResponse对象 +} + +Future getControlResponse(List successCommandList) async { + // 根据成功执行的命令列表生成友好的反馈文本 +} +``` + +## 🎨 UI层架构分析 + +### 1. 主界面 (MainScreen) + +**设计**: 采用Stack布局,背景图片 + 浮动图标 + +```dart +Widget build(BuildContext context) { + return Scaffold( + body: Stack( + children: [ + // 背景图片 + Container(decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/bg.jpg', package: 'ai_chat_assistant'), + ), + )), + // 浮动AI助手图标 + FloatingIcon(), + ], + ), + ); +} +``` + +### 2. 浮动图标 (FloatingIcon) + +**功能特性**: +- 可拖拽定位 +- 状态指示(通过不同图标) +- 点击展开聊天界面 +- 动画效果支持 + +**交互流程**: +1. 长按拖拽调整位置 +2. 点击展开部分屏幕聊天界面 +3. 根据MessageService状态切换图标 + +### 3. 聊天界面架构 + +**部分屏模式** (PartScreen): +- 简化的聊天界面 +- 支持语音输入和文本显示 +- 可展开到全屏模式 + +**全屏模式** (FullScreen): +- 完整的聊天功能 +- 历史消息展示 +- 更多操作按钮 + +## 🔌 原生平台集成 + +### Android ASR集成 + +**Method Channel通信**: +```dart +static const MethodChannel _asrChannel = + MethodChannel('com.example.ai_chat_assistant/ali_sdk'); +``` + +**ASR事件处理**: +```dart +_asrChannel.setMethodCallHandler((call) async { + switch (call.method) { + case "onAsrResult": + // 实时更新识别结果 + replaceMessage(id: _latestUserMessageId!, text: call.arguments); + break; + case "onAsrStop": + // 识别结束,触发后续处理 + if (_asrCompleter != null && !_asrCompleter!.isCompleted) { + _asrCompleter!.complete(messages.last.text); + } + break; + } +}); +``` + +## 🛠️ 工具类分析 + +### CommonUtil +**主要功能**: +- 中文检测: `containChinese(String text)` +- Markdown清理: `cleanText(String text, bool forTts)` +- 公共颜色常量定义 + +**Markdown清理逻辑**: +```dart +static String cleanText(String text, bool forTts) { + // 1. 清理粗体/斜体标记 + // 2. 处理代码块 + // 3. 清理表格格式 + // 4. 处理链接和图片 + // 5. 清理列表和引用 + // 6. 规范化空白字符 +} +``` + +## 🔄 数据流分析 + +### 完整对话流程 + +```mermaid +graph TD + A[用户点击语音按钮] --> B[startVoiceInput] + B --> C[检查麦克风权限] + C --> D[开始录音/ASR] + D --> E[实时显示识别结果] + E --> F[用户松开按钮] + F --> G[stopAndProcessVoiceInput] + G --> H[调用reply处理文本] + H --> I[文本分类] + I --> J{分类结果} + J -->|车控命令| K[handleVehicleControl] + J -->|普通问答| L[answerQuestion] + J -->|错误问题| M[answerWrongQuestion] + K --> N[解析车控命令] + N --> O[执行TTS播报] + O --> P[执行车控命令] + P --> Q[生成执行反馈] + Q --> R[更新UI显示] +``` + +### 状态管理流程 + +**MessageService状态变化**: +``` +idle -> recording -> recognizing -> replying -> idle +``` + +**消息状态变化**: +``` +listening -> normal -> thinking -> executing -> success/failure +``` + +## 🔧 配置与扩展 + +### 1. 插件初始化 + +```dart +// 在主应用中初始化插件 +ChatAssistantApp.initialize( + commandCallback: (VehicleCommandType type, Map? params) async { + // 实现具体的车控逻辑 + return (true, {'message': '命令执行成功'}); + }, +); +``` + +### 2. 服务端接口配置 + +**当前硬编码的服务端地址**: +- 文本分类: `http://143.64.185.20:18606/classify` +- 车控解析: `http://143.64.185.20:18606/control` +- 控制反馈: `http://143.64.185.20:18606/control_resp` + +**建议改进**: 将服务端地址配置化,支持动态配置 + +### 3. 资源文件引用 + +**图片资源**: +- 使用`package: 'ai_chat_assistant'`前缀 +- 路径: `assets/images/` + +**字体资源**: +- VWHead_Bold.otf +- VWHead_Regular.otf + +## 🐛 已知问题与注意事项 + +### 1. 资源路径问题 +当前资源文件引用可能存在路径问题,需要确保在example项目中正确配置package前缀。 + +### 2. 硬编码服务地址 +服务端API地址硬编码,不利于部署和环境切换。 + +### 3. 错误处理 +部分网络请求缺少完善的错误处理和重试机制。 + +### 4. 内存管理 +长时间运行可能存在内存泄漏风险,需要关注Completer和监听器的清理。 + +## 🚀 扩展建议 + +### 1. 配置化改进 +- 服务端地址配置化 +- 支持多语言配置 +- 主题自定义配置 + +### 2. 功能增强 +- 添加离线语音识别支持 +- 实现消息历史持久化 +- 添加更多车控命令类型 + +### 3. 性能优化 +- 实现网络请求缓存 +- 优化UI渲染性能 +- 添加资源预加载 + +### 4. 测试完善 +- 添加单元测试 +- 集成测试覆盖 +- 性能测试工具 + +## 📝 开发流程建议 + +### 1. 添加新功能 +1. 在相应的枚举中定义新类型 +2. 在models中添加数据模型 +3. 在services中实现业务逻辑 +4. 在widgets中创建UI组件 +5. 更新主流程集成新功能 + +### 2. 调试技巧 +- 使用`debugPrint`添加关键节点日志 +- 通过Provider DevTools监控状态变化 +- 使用Flutter Inspector检查UI结构 + +### 3. 集成测试 +- 在example项目中测试完整流程 +- 验证车控命令回调机制 +- 测试不同场景下的错误处理 + +--- + +这份文档涵盖了项目的核心架构、关键代码逻辑、数据流分析和扩展建议,可以帮助您快速理解项目结构并进行后续开发。如有具体问题,可以针对特定模块进行深入分析。 diff --git a/android/build.gradle b/android/build.gradle index 8f52ca7..dd5e36a 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -5,7 +5,6 @@ buildscript { ext.kotlin_version = '2.1.20' repositories { maven { url file("mavenLocal") } - google() mavenCentral() } @@ -19,7 +18,6 @@ buildscript { allprojects { repositories { maven { url file("mavenLocal") } - google() mavenCentral() } @@ -50,7 +48,7 @@ android { } defaultConfig { - minSdkVersion 23 + minSdkVersion 21 ndk { abiFilters "armeabi-v7a", "arm64-v8a" } @@ -77,9 +75,9 @@ android { } repositories { -// flatDir { -// dirs("libs") -// } + flatDir { + dirs("libs") + } } dependencies { @@ -87,8 +85,6 @@ android { implementation 'com.alibaba:fastjson:1.2.83' // compileOnly files("$flutterRoot/bin/cache/artifacts/engine/android-arm/flutter.jar") // implementation(files("libs/fastjson-1.1.46.android.jar")) -// implementation(files("libs/nui-release-1.0.0.aar")) + // implementation(files("libs/nui-release-1.0.0.aar")) } } - - diff --git a/android/build/reports/problems/problems-report.html b/android/build/reports/problems/problems-report.html index d3f963a..30af9b7 100644 --- a/android/build/reports/problems/problems-report.html +++ b/android/build/reports/problems/problems-report.html @@ -650,12 +650,12 @@ code + .copy-button { diff --git a/android/settings.gradle b/android/settings.gradle index 9ca8501..99b20e8 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1 +1 @@ - rootProject.name = 'ai_assistant_plugin' \ No newline at end of file +rootProject.name = 'ai_assistant_plugin' \ No newline at end of file diff --git a/assets/images/ai1.png b/assets/images/ai1.png new file mode 100644 index 0000000000000000000000000000000000000000..142e85c86711d35091d024863a921a5c1ae14dab GIT binary patch literal 8621 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 literal 0 HcmV?d00001 diff --git a/assets/images/ai2.png b/assets/images/ai2.png new file mode 100644 index 0000000000000000000000000000000000000000..5ef2db4e4eb74ab624177f7d01ed18fd7f97ceb3 GIT binary patch literal 7275 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 FV1l3<+S334 literal 0 HcmV?d00001 diff --git a/devtools_options.yaml b/devtools_options.yaml new file mode 100644 index 0000000..fa0b357 --- /dev/null +++ b/devtools_options.yaml @@ -0,0 +1,3 @@ +description: This file stores settings for Dart & Flutter DevTools. +documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states +extensions: diff --git a/example/android/app/build.gradle.kts b/example/android/app/build.gradle.kts index cc7d3a4..498f87f 100644 --- a/example/android/app/build.gradle.kts +++ b/example/android/app/build.gradle.kts @@ -24,7 +24,7 @@ android { applicationId = "com.example.example" // You can update the following values to match your application needs. // For more information, see: https://flutter.dev/to/review-gradle-config. - minSdk = flutter.minSdkVersion + minSdk = 23 targetSdk = flutter.targetSdkVersion versionCode = flutter.versionCode versionName = flutter.versionName @@ -44,7 +44,7 @@ android { includeInApk = includeInApk includeInBundle = includeInBundle } - ndkVersion = ndkVersion + ndkVersion = "27.0.12077973" } flutter { diff --git a/example/pubspec.lock b/example/pubspec.lock index 3e86f95..6f3836a 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -20,10 +20,10 @@ packages: dependency: transitive description: name: async - sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.flutter-io.cn" source: hosted - version: "2.13.0" + version: "2.11.0" audioplayers: dependency: transitive description: @@ -91,34 +91,34 @@ packages: dependency: transitive description: name: boolean_selector - sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.2" + version: "2.1.1" characters: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.flutter-io.cn" source: hosted - version: "1.4.0" + version: "1.3.0" clock: dependency: transitive description: name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.2" + version: "1.1.1" collection: dependency: transitive description: name: collection - sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.flutter-io.cn" source: hosted - version: "1.19.1" + version: "1.19.0" crypto: dependency: transitive description: @@ -139,18 +139,18 @@ packages: dependency: transitive description: name: fake_async - sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" url: "https://pub.flutter-io.cn" source: hosted - version: "1.3.3" + version: "1.3.1" ffi: dependency: transitive description: name: ffi - sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.4" + version: "2.1.3" file: dependency: transitive description: @@ -234,26 +234,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.flutter-io.cn" source: hosted - version: "11.0.1" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.10" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.2" + version: "3.0.1" lints: dependency: transitive description: @@ -274,10 +274,10 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.flutter-io.cn" source: hosted - version: "0.12.17" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: @@ -290,10 +290,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.flutter-io.cn" source: hosted - version: "1.16.0" + version: "1.15.0" nested: dependency: transitive description: @@ -306,10 +306,10 @@ packages: dependency: transitive description: name: path - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.flutter-io.cn" source: hosted - version: "1.9.1" + version: "1.9.0" path_provider: dependency: transitive description: @@ -322,18 +322,18 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db" + sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9 url: "https://pub.flutter-io.cn" source: hosted - version: "2.2.18" + version: "2.2.17" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd" + sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" url: "https://pub.flutter-io.cn" source: hosted - version: "2.4.2" + version: "2.4.1" path_provider_linux: dependency: transitive description: @@ -503,58 +503,58 @@ packages: dependency: transitive description: name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.flutter-io.cn" source: hosted - version: "1.10.1" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.flutter-io.cn" source: hosted - version: "1.12.1" + version: "1.12.0" stream_channel: dependency: transitive description: name: stream_channel - sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.4" + version: "2.1.2" string_scanner: dependency: transitive description: name: string_scanner - sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.flutter-io.cn" source: hosted - version: "1.4.1" + version: "1.3.0" synchronized: dependency: transitive description: name: synchronized - sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0 + sha256: "69fe30f3a8b04a0be0c15ae6490fc859a78ef4c43ae2dd5e8a623d45bfcf9225" url: "https://pub.flutter-io.cn" source: hosted - version: "3.4.0" + version: "3.3.0+3" term_glyph: dependency: transitive description: name: term_glyph - sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 url: "https://pub.flutter-io.cn" source: hosted - version: "1.2.2" + version: "1.2.1" test_api: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.flutter-io.cn" source: hosted - version: "0.7.6" + version: "0.7.3" typed_data: dependency: transitive description: @@ -575,18 +575,18 @@ packages: dependency: transitive description: name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" url: "https://pub.flutter-io.cn" source: hosted - version: "2.2.0" + version: "2.1.4" vm_service: dependency: transitive description: name: vm_service - sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.flutter-io.cn" source: hosted - version: "15.0.2" + version: "14.3.0" web: dependency: transitive description: @@ -604,5 +604,5 @@ packages: source: hosted version: "1.1.0" sdks: - dart: ">=3.9.0 <4.0.0" - flutter: ">=3.29.0" + dart: ">=3.6.0 <4.0.0" + flutter: ">=3.27.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index ff8a43b..e659557 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,4 +1,4 @@ -name: example +name: ai_chat_example description: "AI Chat Assistant Example App" # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. @@ -19,7 +19,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ^3.9.0 + sdk: ^3.5.0 # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions diff --git a/lib/main.dart b/lib/main.dart deleted file mode 100644 index 10b0e39..0000000 --- a/lib/main.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:permission_handler/permission_handler.dart'; -import 'app.dart'; -import 'package:provider/provider.dart'; -import 'services/message_service.dart'; - -void main() async { - WidgetsFlutterBinding.ensureInitialized(); - if (!await Permission.microphone.isGranted) { - await Permission.microphone.request(); - } - runApp( - ChangeNotifierProvider( - create: (_) => MessageService(), - child: const ChatAssistantApp(), - ), - ); -} diff --git a/lib/screens/part_screen.dart b/lib/screens/part_screen.dart index de4051b..cb44627 100644 --- a/lib/screens/part_screen.dart +++ b/lib/screens/part_screen.dart @@ -1,4 +1,3 @@ -import 'package:ai_chat_assistant/utils/assets_util.dart'; import 'package:flutter/material.dart'; import 'dart:ui'; import '../widgets/chat_box.dart'; @@ -127,18 +126,14 @@ class _PartScreenState extends State { children: [ Padding( padding: const EdgeInsets.only( - top: 50, - left: 6, - right: 6, - bottom: 30), + top: 50, left: 6, right: 6, bottom: 30), child: LayoutBuilder( - builder: (context, boxConstraints) { - return ChatBox( - scrollController: _scrollController, - messages: messageService.messages, - ); - } - ), + builder: (context, boxConstraints) { + return ChatBox( + scrollController: _scrollController, + messages: messageService.messages, + ); + }), ), Positioned( top: 6, diff --git a/lib/services/chat_sse_service.dart b/lib/services/chat_sse_service.dart index 493779f..c95680b 100644 --- a/lib/services/chat_sse_service.dart +++ b/lib/services/chat_sse_service.dart @@ -59,7 +59,8 @@ class ChatSseService { txt = txt.substring(0, imgStart) + txt.substring(imgEnd + 1); imgStart = txt.indexOf('!['); } - + // 彻底移除 markdown 有序/无序列表序号(如 1.、2.、-、*、+) + txt = txt.replaceAll(RegExp(r'(^|\n)[ \t]*[0-9]+\.[ \t]*'), '\n'); txt = txt.replaceAll(RegExp(r'(^|\n)[ \t]*[-\*\+][ \t]+'), '\n'); // 分句符 RegExp enders = isChinese ? zhEnders : enEnders; @@ -76,14 +77,8 @@ class ChatSseService { } // 只在达到完整句子时调用 TtsUtil.send for (final s in sentences) { - String ttsStr=CommonUtil.cleanText(s, true)+"\n"; - - ttsStr = ttsStr.replaceAllMapped( - RegExp(r'(? ' ${m.group(1)} ', - ); - - print("发送数据到TTS: $ttsStr"); + String ttsStr=CommonUtil.cleanText(s, true); + // print("发送数据到TTS: $ttsStr"); TtsUtil.send(ttsStr); } // 缓存剩余不完整部分 diff --git a/lib/services/message_service.dart b/lib/services/message_service.dart index a31058f..da89c53 100644 --- a/lib/services/message_service.dart +++ b/lib/services/message_service.dart @@ -21,7 +21,7 @@ import 'command_service.dart'; import 'package:fluttertoast/fluttertoast.dart'; class MessageService extends ChangeNotifier { - static const MethodChannel _asrChannel = MethodChannel('com.example.ai_chat_assistant/asr'); + static const MethodChannel _asrChannel = MethodChannel('com.example.ai_chat_assistant/ali_sdk'); static final MessageService _instance = MessageService._internal(); @@ -61,7 +61,7 @@ class MessageService extends ChangeNotifier { // final AudioRecorderService _audioService = AudioRecorderService(); // final VoiceRecognitionService _recognitionService = VoiceRecognitionService(); final TextClassificationService _classificationService = - TextClassificationService(); + TextClassificationService(); final VehicleCommandService _vehicleCommandService = VehicleCommandService(); final List _messages = []; @@ -106,7 +106,6 @@ class MessageService extends ChangeNotifier { abortReply(); _latestUserMessageId = null; _latestAssistantMessageId = null; - _isReplyAborted = false; changeState(MessageServiceState.recording); _latestUserMessageId = addMessage("", true, MessageStatus.listening); _asrChannel.invokeMethod("startAsr"); @@ -138,6 +137,7 @@ class MessageService extends ChangeNotifier { return; } try { + _isReplyAborted = false; changeState(MessageServiceState.recognizing); _asrChannel.invokeMethod("stopAsr"); _asrCompleter = Completer(); @@ -227,7 +227,7 @@ class MessageService extends ChangeNotifier { return; } final vehicleCommandResponse = - await _vehicleCommandService.getCommandFromText(text); + await _vehicleCommandService.getCommandFromText(text); if (vehicleCommandResponse == null) { if (_isReplyAborted) { return; @@ -269,12 +269,12 @@ class MessageService extends ChangeNotifier { bool isSuccess; if (containOpenAC && command.type == VehicleCommandType.changeACTemp) { isSuccess = await Future.delayed(const Duration(milliseconds: 2000), - () => processCommand(command, isChinese)); + () => processCommand(command, isChinese)); } else { isSuccess = await processCommand(command, isChinese); } if (isSuccess) { - successCommandList.add(command.type.name); + successCommandList.add(isChinese ? command.type.chinese : command.type.english); } } replaceMessage( @@ -286,7 +286,7 @@ class MessageService extends ChangeNotifier { return; } String controlResponse = - await _vehicleCommandService.getControlResponse(successCommandList); + await _vehicleCommandService.getControlResponse(successCommandList); if (_isReplyAborted || controlResponse.isEmpty) { return; } diff --git a/lib/utils/tts_util.dart b/lib/utils/tts_util.dart index 165577a..86c6f62 100644 --- a/lib/utils/tts_util.dart +++ b/lib/utils/tts_util.dart @@ -2,7 +2,7 @@ import 'package:flutter/services.dart'; class TtsUtil { static const MethodChannel _channel = - MethodChannel('com.example.ai_chat_assistant/tts'); + MethodChannel('com.example.ai_chat_assistant/ali_sdk'); static Future execute(String method, [Map? arguments]) { diff --git a/lib/widgets/chat_bubble.dart b/lib/widgets/chat_bubble.dart index 95addd9..f7e027f 100644 --- a/lib/widgets/chat_bubble.dart +++ b/lib/widgets/chat_bubble.dart @@ -123,7 +123,12 @@ class _ChatBubbleState extends State { break; case MessageStatus.completed: case MessageStatus.success: - icon = Image.asset('assets/images/checked.png', width: 20, height: 20, package: 'ai_chat_assistant',); + icon = Image.asset( + 'assets/images/checked.png', + width: 20, + height: 20, + package: 'ai_chat_assistant', + ); color = Colors.white; break; case MessageStatus.failure: @@ -301,8 +306,10 @@ class _ChatBubbleState extends State { }, child: Padding( padding: const EdgeInsets.only(left: 12), - child: Image.asset('assets/images/copy.png',package: 'ai_chat_assistant', - width: 22, height: 22), + child: Image.asset('assets/images/copy.png', + package: 'ai_chat_assistant', + width: 22, + height: 22), ), ), InkWell( @@ -315,10 +322,14 @@ class _ChatBubbleState extends State { child: Padding( padding: const EdgeInsets.only(left: 12), child: _liked - ? Image.asset('assets/images/liked2.png',package: 'ai_chat_assistant', - width: 22, height: 22) - : Image.asset('assets/images/liked1.png',package: 'ai_chat_assistant', - width: 22, height: 22), + ? Image.asset('assets/images/liked2.png', + package: 'ai_chat_assistant', + width: 22, + height: 22) + : Image.asset('assets/images/liked1.png', + package: 'ai_chat_assistant', + width: 22, + height: 22), ), ), InkWell( @@ -331,10 +342,14 @@ class _ChatBubbleState extends State { child: Padding( padding: const EdgeInsets.only(left: 12), child: _disliked - ? Image.asset('assets/images/disliked2.png',package: 'ai_chat_assistant', - width: 22, height: 22) - : Image.asset('assets/images/disliked1.png',package: 'ai_chat_assistant', - width: 22, height: 22)), + ? Image.asset('assets/images/disliked2.png', + package: 'ai_chat_assistant', + width: 22, + height: 22) + : Image.asset('assets/images/disliked1.png', + package: 'ai_chat_assistant', + width: 22, + height: 22)), ), ], ), diff --git a/lib/widgets/chat_header.dart b/lib/widgets/chat_header.dart index a354244..d9ad52f 100644 --- a/lib/widgets/chat_header.dart +++ b/lib/widgets/chat_header.dart @@ -44,7 +44,7 @@ class ChatHeader extends StatelessWidget { ? '您的专属看、选、买、用车助手' : 'Your exclusive assistant', style: TextStyle( - fontSize: 12, + fontSize: 11, color: Colors.white70, ), ), diff --git a/packages/basic_intl/pubspec.lock b/packages/basic_intl/pubspec.lock index 6b97eb2..312a984 100644 --- a/packages/basic_intl/pubspec.lock +++ b/packages/basic_intl/pubspec.lock @@ -5,50 +5,50 @@ packages: dependency: transitive description: name: async - sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.flutter-io.cn" source: hosted - version: "2.13.0" + version: "2.11.0" boolean_selector: dependency: transitive description: name: boolean_selector - sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.2" + version: "2.1.1" characters: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.flutter-io.cn" source: hosted - version: "1.4.0" + version: "1.3.0" clock: dependency: transitive description: name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.2" + version: "1.1.1" collection: dependency: transitive description: name: collection - sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.flutter-io.cn" source: hosted - version: "1.19.1" + version: "1.19.0" fake_async: dependency: transitive description: name: fake_async - sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" url: "https://pub.flutter-io.cn" source: hosted - version: "1.3.3" + version: "1.3.1" flutter: dependency: "direct main" description: flutter @@ -63,34 +63,34 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.flutter-io.cn" source: hosted - version: "11.0.1" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.10" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.2" + version: "3.0.1" matcher: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.flutter-io.cn" source: hosted - version: "0.12.17" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: @@ -103,18 +103,18 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.flutter-io.cn" source: hosted - version: "1.16.0" + version: "1.15.0" path: dependency: transitive description: name: path - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.flutter-io.cn" source: hosted - version: "1.9.1" + version: "1.9.0" sky_engine: dependency: transitive description: flutter @@ -124,66 +124,66 @@ packages: dependency: transitive description: name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.flutter-io.cn" source: hosted - version: "1.10.1" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.flutter-io.cn" source: hosted - version: "1.12.1" + version: "1.12.0" stream_channel: dependency: transitive description: name: stream_channel - sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.4" + version: "2.1.2" string_scanner: dependency: transitive description: name: string_scanner - sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.flutter-io.cn" source: hosted - version: "1.4.1" + version: "1.3.0" term_glyph: dependency: transitive description: name: term_glyph - sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 url: "https://pub.flutter-io.cn" source: hosted - version: "1.2.2" + version: "1.2.1" test_api: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.flutter-io.cn" source: hosted - version: "0.7.6" + version: "0.7.3" vector_math: dependency: transitive description: name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" url: "https://pub.flutter-io.cn" source: hosted - version: "2.2.0" + version: "2.1.4" vm_service: dependency: transitive description: name: vm_service - sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.flutter-io.cn" source: hosted - version: "15.0.2" + version: "14.3.0" sdks: - dart: ">=3.8.0-0 <4.0.0" + dart: ">=3.5.0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/packages/basic_intl/pubspec.yaml b/packages/basic_intl/pubspec.yaml index 520a608..8c9d942 100644 --- a/packages/basic_intl/pubspec.yaml +++ b/packages/basic_intl/pubspec.yaml @@ -3,7 +3,7 @@ description: Basic internationalization utilities for ai_chat_assistant version: 0.2.0 environment: - sdk: ^3.6.2 + sdk: ^3.5.0 dependencies: flutter: diff --git a/pubspec.lock b/pubspec.lock index 3de2e65..e5009f2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -84,18 +84,18 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.flutter-io.cn" source: hosted - version: "1.4.0" + version: "1.3.0" collection: dependency: transitive description: name: collection - sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.flutter-io.cn" source: hosted - version: "1.19.1" + version: "1.19.0" crypto: dependency: transitive description: @@ -108,10 +108,10 @@ packages: dependency: transitive description: name: ffi - sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.4" + version: "2.1.3" file: dependency: transitive description: @@ -214,10 +214,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.flutter-io.cn" source: hosted - version: "1.16.0" + version: "1.15.0" nested: dependency: transitive description: @@ -246,18 +246,18 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db" + sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9 url: "https://pub.flutter-io.cn" source: hosted - version: "2.2.18" + version: "2.2.17" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd" + sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" url: "https://pub.flutter-io.cn" source: hosted - version: "2.4.2" + version: "2.4.1" path_provider_linux: dependency: transitive description: @@ -443,10 +443,10 @@ packages: dependency: transitive description: name: synchronized - sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0 + sha256: "69fe30f3a8b04a0be0c15ae6490fc859a78ef4c43ae2dd5e8a623d45bfcf9225" url: "https://pub.flutter-io.cn" source: hosted - version: "3.4.0" + version: "3.3.0+3" term_glyph: dependency: transitive description: @@ -475,10 +475,10 @@ packages: dependency: transitive description: name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" url: "https://pub.flutter-io.cn" source: hosted - version: "2.2.0" + version: "2.1.4" web: dependency: transitive description: @@ -496,5 +496,5 @@ packages: source: hosted version: "1.1.0" sdks: - dart: ">=3.8.0 <4.0.0" - flutter: ">=3.29.0" + dart: ">=3.6.2 <4.0.0" + flutter: ">=3.27.0" diff --git a/pubspec.yaml b/pubspec.yaml index ca1a9a4..602e418 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: "ai_chat_assistant" publish_to: 'none' version: 1.0.0+1 environment: - sdk: ^3.6.2 + sdk: ^3.5.0 dependencies: flutter: sdk: flutter