DevLog:2025年12月12日

1、昨天给使用Flutter重构的ChatWith增加了多模型管理和切换、联网搜索、回收站、深度思考等等,添加OpenRouter的Claude 3.7 Sonnet和硅基流动的DeepSeek-R1试试看,首轮测试问题如下:

1.在添加/编辑模型页,目前“模型名称”和“模型”两个字段都是必填,如果作用一样的话,可以去掉“模型”字段

2.模型管理页,不需要显示太多内容,可以去掉这里的Base URL,只保留“模型名称”和“备注”字段

3.模型管理页,每个模型前边都有星号,但点击星号无法设置为默认模型,而是进入了模型编辑页,我需要在点击星号时将其设为默认模型,再次点击取消默认

4.点击对话界面上方的按钮,可以切换模型,想再次切换时就会显示“加载中”,看不到我添加的其它模型

5.对话时,AI返回的内容是乱码

6.创建新对话后,仍然使用了我在上次对话时切换的模型,想切换其他模型就会显示“加载中”,看不到我添加的其它模型

2、全部反馈给Cursor进行修改,去掉了“模型”字段,包括“模型名称”会作为model字段的值保留,模型管理页简化显示,点击星号设置默认模型,并且可切换实心空心,修复模型选择器加载问题,使用watch正确监听模型列表变化,使用utf8.decode()正确解码响应流,新对话使用默认模型,再次测试,上面提到的问题1、2、3、5均已修复,但在对话中切换模型时依然会显示“加载中”,看不到我添加的其它模型

3、决定简化对话页的逻辑,并做更多修改如下:

1.创建新对话时即使用默认模型,仅在对话窗口上方显示当前的默认模型,不需要在这里切换模型

2.去掉对话列表和收藏列表右上方的“设置”按钮,将“设置”改成应用底部的第三个Tab

3.设置页顶部的“设置”二字居左显示,和对话列表页顶部的“全部对话”保持一致

4.收藏页顶部的“收藏夹”三个字居左显示,和对话列表页顶部的“全部对话”样式一致

5.与支持深度思考的模型(如DeepSeek R1)对话时,看不到思考过程,是否需要增加一个判断模型是否支持深度思考的功能?如果支持就展示思考过程

6.AI对话内容的字号调小一点,现在有点大

4、Cursor陆续实现上述需求,创建了ModelDisplay组件,在对话窗口只显示当前的默认模型名称,移除了模型切换功能,在AIModel中添加了supportsThinkinggetter,通过模型名称判断是否支持深度思考,目前的判定逻辑是包含r1、o1、deepseek、thinking等关键词,但我觉得可能不是很合适,后面还得再优化,然后把Markdown样式中段落字号从16调整为14,再次测试,果然在与DeepSeek R1对话时仍未显示思考过程,且对话页、收藏页、设置页三个页面的标题目前均为居中,继续反馈问题并增加更多需求:

1.在与DeepSeek R1对话时仍然未能显示思考过程,可能通过模型名称来判断是否支持深度思考并不是很合适,有没有其它更好的判定方法?或者在添加/编辑模型页增加一个是否支持深度思考的选项?如果选择了支持,就在对话时展示思考过程,如果选择了不支持,就不展示思考内容,这两种方式你更推荐哪一种?(先回答我这个问题,不要直接修改,后面问题2到问题6请直接修改)

2.对话页、收藏页、设置页三个页面的标题(全部对话、收藏夹、设置)目前均为居中,我需要统一成居左显示

3.对话列表里的标题显示用户提出的最后一个问题,下面的小字显示AI最后一次回答的内容,都只显示一行

4.对话详情页,用户和AI都需要有一个头像,并且在消息下方显示消息时间

5.调整一下设置页的“数据管理”,点击“数据统计”,打开新页面,可在新页面里查看AI对话、收藏内容的数量,并且也在“数据统计”前增加一个图标,和“回收站”入口的样式一致

6.在设置页,把外观设置挪到最下方,设置页共三个模块:模型管理、数据管理、外观

5、关于上面的第一个问题,Cursor更推荐在添加/编辑模型页增加“是否支持深度思考”选项,这种方式不依赖模型名称的命名规则,用户可手动控制,模型名称变化不影响判断,用户明确知道哪些模型支持,决定采纳建议,并进一步明确如下:

在添加/编辑模型页增加“是否支持深度思考”选项,默认选中“不支持”,用户可自行选择,同时在模型管理页,每个模型的信息中增加一行,根据用户的选择情况显示“支持深度思考”或“不支持深度思考”

6、让Cursor实现上述需求,修改过程中重写了chat_message_item.dart文件,可能是多次修改导致结构出现了问题?完成之后再次测试,对话详情页已支持对话双方的头像,设置页已基本符合需求,回答内容的流式输出正常,Markdown渲染正常

7、但是,对话页、收藏页、设置页三个页面的标题仍然是居中显示(第二次修改仍然无效),对话列表里每个对话只能看到最后一个问题,看不到最后一次回答,即使我给硅基流动的DeepSeek R1打开了支持深度思考,好像仍然不显示思考过程,需要再用其它问题试一下

8、另外还需要补充的功能包括触发联网搜索、显示联网搜索的参考链接、测试模型是否可用、对话的置顶/修改/删除功能(已有按钮,需测试是否可用)

9、使用Flutter创建的应用,在界面上整体明显更偏向原生安卓的风格,毕竟谷歌出品

DevLog:2025年12月11日

1、需要给应用增加多模型管理和切换、联网搜索(通过Tavily,在模型界面增加Tavily Key字段)、回收站(可删除和恢复AI对话、收藏内容)、深度思考(在使用支持深度思考的模型时,可在对话过程中看到思考过程,并且样式和回答内容要有区别)、流式输出(可能现在已经有了?)、Markdown渲染(可能现在已经有了?)等功能

2、决定先增加联网搜索、回收站、深度思考功能,Cursor规划了7步:实现联网搜索功能(Tavily):添加Tavily Key字段到设置页面和存储、创建Tavily服务,实现联网搜索API调用、在聊天中集成联网搜索功能、实现回收站功能:修改数据库添加is_deleted字段、修改删除逻辑为软删除,创建回收站页面、实现深度思考功能:修改OpenAI服务解析思考内容、修改消息显示组件,区分显示思考过程和回答内容

3、Cursor只用了几分钟就完成了如下修改:

1. 联网搜索功能(Tavily):在设置页面的API配置部分添加了Tavily Key输入字段;创建了TavilyService处理联网搜索API调用;在聊天中集成:配置Tavily Key后,发送消息时会自动进行联网搜索,并将搜索结果作为上下文发送给 AI

2. 回收站功能:数据库更新:为conversations和messages表添加了is_deleted和deleted_at字段;软删除:删除操作改为软删除,数据不会真正删除;回收站页面:在设置页面的“数据管理”部分可进入回收站;可查看已删除的AI对话和收藏内容;可恢复已删除的内容;永久删除(不可恢复)

3. 深度思考功能:OpenAI服务更新:支持解析深度思考模型的thinking字段;消息显示更新:区分显示思考过程和回答内容;思考过程:灰色背景、斜体、带边框,顶部有“思考过程”标签;回答内容:正常样式显示

4、按照目前已有的功能,应该已经可以实现从添加模型到对话到删除的完整流程了,测试一下,先让Cursor解决两个问题,以及一个新需求:

1.在模拟器中打开应用时,对话页面出现了错误提示:LocaleDataException: Locale data has not been initialized, call initializedDataFormatting(<locale>).

2.在填写API Key、Base URL、模型名、Tavily Key后,填写的信息无法保存,退出设置界面后再回来看填写的信息就消失了

3.我需要把数据统计和回收站都放到设置-数据管理里

5、第一个问题,可能是因为中文日期的问题?第二个问题,为所有输入框添加了onEditComplete回调,在失去焦点时自动保存,第三个问题,将数据统计和回收站合并到了“数据管理”卡片中,继续测试,1和3已经解决,二仍然未能保存,决定直接动个大手术,添加多模型管理和切换功能,并在其中增加模型信息保存机制,需求包括:

1.在设置界面增加“模型管理”卡片,将现有的API配置整合到“模型管理”卡片中

2.可以在“模型管理”界面查看我添加的所有模型,可以在这里新建、修改、删除模型,并且可以将我添加的任何一个模型设置为默认模型,在开启新对话时,直接使用默认模型

3.添加和修改模型的界面,需要有取消和确认按钮,点确认按钮确认添加/修改,点取消按钮可取消添加/修改,点击确认或取消后可以返回“模型管理”界面

4.在添加和修改模型的界面,增加“备注”字段,可自行填写,并在对话窗口右上角的模型切换按钮上显示备注名和模型名

5.开启新对话时,直接使用默认模型

6.在对话中允许用户切换模型,模型切换按钮放在对话窗口右上角

6、修改过程中,Cursor将操作分为如下步骤:更新AIModel模型,添加备注字段和默认模型标记;创建模型数据库表和DAO;创建模型管理的Respository和Provider、创建模型管理界面、创建添加/编辑模型界面、修改设置界面,整合API配置到模型管理、修改对话页面,添加模型切换功能、修改聊天provider使用当前模型,大概耗时5分钟

7、在测试之前先记录一个关于Flutter开发的知识点:关于这几天在修改过程中频繁出现的DAO、Repository和Provider。

1.DAO(Data Access Object,数据访问对象)专注于数据存储层的读写,是直接与底层数据源交互的抽象层,封装所有数据访问细节,对外提供统一的GRUD(增删改查)接口,简单说就是DAO只负责“怎么从数据库/网络/本地文件拿数据/存数据”,不关心业务逻辑

2.Repository(业务数据仓库)是“业务层与数据层的中间层”,聚合多个DAO/数据源,封装业务逻辑,为上层(UI/Provider)提供统一的业务数据接口,简单说就是Repository负责“什么时候/从哪里/拿什么数据”,是数据的“调度中心”

3.Provider(状态管理工具)是“UI层与业务层的桥梁”,管理应用的状态(如用户信息、页面数据、加载状态),并将状态分发给UI组件,实现“状态变化——UI自动刷新”,简单说就是Provider负责“管理UI需要的状态,让UI能拿到最新数据”。

4.这几个概念之间的关系是:UI依赖Provider,Provider依赖Repository,Repository依赖DAO,分层设计本质是为了降低耦合,提升代码的可维护性

8、后续再测试今天新增的功能:多模型管理和切换、联网搜索、回收站、深度思考,测试正常后,还需要补充的细节包括流式输出、回答和收藏内容的Markdown渲染、模型测试、消息时间显示等等

DevLog:2025年12月9日

1、昨天在使用Flutter重写ChatWith时,一直无法成功构建,即使用Cursor提供的终端命令也无法打开应用,同时在修改过程中,Cursor给我创建了大量的.md说明文档和.sh安装脚本文件,只是在告诉我应该怎么做,而不是像之前那样直接进行修改

2、打开一个新对话,再让Cursor继续修复Xcode报的问题,并且看看这些.md和.sh文件是否有必要保留,于是询问Cursor:我之前用Flutter重写了这个应用,但一直构建失败,提示:Command PhaseScriptExecution failed with a nonzero exit code,并且在重写过程中,文件夹里多了很多.md和.sh文件,这些文件是否可以删除?

3、Cursor修复了构建失败的问题,认为构建失败不是因为PhaseScriptExecution脚本问题,而是代码编译错误,包括Message类问题、CardTheme类型错误、类型声明错误、缺少导入等,然后清理了.md和.sh文件共23个,然后在Xcode中尝试构建,竟然真的构建成功了

4、但是出现了很多的错误提示,基本都是Stale file ‘/Users/jinlei.wu/Documents/GitHub/ChatWith/chatwith_flutter/build/ios/Debug-iphonesimulator’ is located outside of the allowed root paths.,看这个提示信息,像是这个文件的路径错误?Clean Build Folder后解决,并且可以成功构建

5、决定让Cursor删掉/Users/jinlei.wu/Documents/GitHub/ChatWith/目录下使用Swift原生构建的应用,只保留使用Flutter构建的应用

6、继续构建并测试功能,首先就是点击右上角的设置按钮,设置界面里是空白的,提示“错误:Exception: SharedPreferences not initialized”,所以也没有办法添加模型,测试对话等一系列功能,Cursor认为问题原因在于preferencesStorageProvider是同步provider,但依赖异步的sharedPreferencesProvider,当SharedPreferences尚未初始化时,preferencesStorageProvider会抛出“SharedPreferences not initialized”异常,修复之后重新生成了代码,现在可以看到设置界面了,以后再添加模型试试能否正常使用

7、这几次构建测试,总觉得应用启动速度好慢,后面还需要给应用增加多模型管理和切换、联网搜索、回收站、深度思考、流式输出、Markdown渲染等功能,又是一个不断增加功能、测试功能的过程

DevLog:2025年12月8日

1、继续上周对移动端ChatWith的修改(或者说重写),用跨端开发框架Flutter替换Swift,“我需要你按照你的建议,帮我完全迁移,并且使用你推荐的技术栈”,Cursor列举了如下步骤:

1.创建Flutter项目结构和配置文件

2.实现核心数据模型(Message、Conversation、AIModel)

3.实现数据库层(SQLite+DAO)

4.实现API服务层(OpenAI流式输出)

5.实现Riverpod状态管理

6.实现UI层(启动页、主框架、对话列表、聊天界面、收藏、设置)

7.实现Markdown渲染和主题系统

8.配置全屏显示和平台特定设置

2、Cursor只用了十来分钟就写完了数十个文件,但接下来还需要我安装Flutter SDK、进入项目并安装依赖、生成代码,然后才能运行应用

3、目前涉及的技术栈包括:状态管理: Riverpod 2.5.1、网络请求: Dio 5.4.0、本地存储: SQLite + SharedPreferences、Markdown: flutter_markdown 0.6.18

4、手动下载并解压Flutter SDK之后,我不知道下一步该怎么配置,直接跟Cursor说“我已经下载了Flutter SDK,下一步怎么操作”,它就在电脑里搜索到了Flutter SDK的位置是/Users/jinlei.wu/Documents/Dev/flutter,然后开始配置环境变量,并验证安装、安装项目依赖、生成代码,之后还创建了一个总结文档

5、但不清楚目前怎样在iOS端运行应用,于是询问“怎样在浏览器里打开当前应用?怎样在Xcode中通过模拟器打开当前应用?”,Cursor直接给我提供了两个运行说明文档QUICK_RUN.md和RUN_GUIDE.md

6、按照提示在Xcode中打开RUNNER.xcworkspace,但提示错误Command PhaseScriptExecution failed with a nonzero exit code,Cursor检查后表示是因为未安装CocoaPods(iOS开发必须的依赖管理工具,Flutter的iOS插件需要通过它来管理),虽然它给出了解决方案,我还是希望Cursor能帮我安装,但未能实现,可能是卡在权限或者无法连接GitHub的资源上了?

7、可能还是需要通过终端命令的形式来安装,Cursor给出的步骤如下,中途切换了一下网络,第一步就无法直接下载

1.安装 Homebrew(如果还没有)

/bin/bash -c “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)”

这一步中途切换了下网络,不然无法下载,但依然卡在了“Downloading Command Line Tools for Xcode 26.1”,搜索发现这还不是个例,网上有不少教程都建议这里手动去苹果开发者网站下载安装,然后重新运行这个命令

2.安装 Ruby 和 CocoaPods

brew install ruby cocoapods

第一步完成之后需要关掉终端,重新打开之后再输入这一命令,不然会提示zsh: command not found: brew

3.安装 iOS 依赖

cd /Users/jinlei.wu/Documents/GitHub/ChatWith/chatwith_flutter

cd ios

pod install

cd ..

4.在 Xcode 中打开

open ios/Runner.xcworkspace

8、在上面第三步就卡住了,多次调整后依然无法在Xcode中正常构建,明明CocoaPods已经安装并且可以查到版本号了,但仍然频繁出现构建失败的情况,Cursor建议优先使用Flutter命令运行应用,但也无法运行,提示找不到设备:

cd /Users/jinlei.wu/Documents/GitHub/ChatWith/chatwith_flutter

export PATH=”$PATH:/Users/jinlei.wu/Documents/Dev/flutter/bin”

flutter run -d “iPhone 16”

9、很奇怪的一点是,不知道为啥,Cursor给我创建了大量的.md说明文档和.sh安装脚本文件,而不是像之前那样直接进行修改操作,明天打开一个新对话,再让Cursor继续修复问题,并且看看这些.md和.sh文件是否有必要保留

DevLog:2026年12月5日

1、昨天引入RichTextKit,替换了目前的备忘录模块,但依然未能正常进行构建测试,在Xcode中构建时发现存在两处错误,再次反馈给Cursor并修改后构建成功

2、测试发现目前的确已经可以实现富文本编辑器的部分功能,比如设置加粗、下划线、删除线、文字颜色、字体、对齐方式,但工具栏中的斜体、字号大小,还有一个不知道是啥按钮,点亮和取消都没有看到什么变化,而且需要先选中文字,再从菜单里选“Format——More”才能在窗口底部弹出格式工具栏,感觉不够直观,需要缩减菜单层级

3、反馈后Cursor把工具栏改成了常驻在标题和编辑器之间,但在Xcode中多次构建都存在错误,猜测可能是Composer 1模型的问题?于是把Cursor中的模型切换回了Auto再试,但在修改过程中又把格式工具栏给我改回了自定义的NSAttributedString,测试发现其中的按钮基本都没有用,于是要求Cursor用RichTextKit内置工具栏RichTextFormat.Toolbar替换自定义实现

4、这下RichTextFormat.Toolbar常驻在备忘录详情页的标题和编辑器之间了,但格式工具栏高度有些夸张了,我希望能把第一行(包含加粗、斜体、下划线、删除线、字号)常驻,其他按钮先折叠起来,在第一行按钮后方增加一个向下的箭头,点击可以展开完整的工具栏

5、Cursor在使用RichTextContent的API、RichTextStyle枚举、RichTextAction,并保持与RichTextKit的兼容性的同时,实现了我的需求,工具栏默认折叠,只显示第一行常用按钮,点击箭头可以展开更多选项,效果还可以

6、接下来添加一个支持深度思考的模型,测试思考内容的流式输出和展示是否正常

7、插播另一个话题,在使用Cherry Studio询问“有哪些比较好用的跨端开发框架”时,发现使用Cherry Studio调用百度千帆平台的DeepSeek API时,响应速度和回答速度都非常慢,回答一个问题可能需要四五分钟的时间,但直接调用DeepSeek官方的API就没有问题,看了下我在百度千帆上的费用还有47块多,消耗的速度好慢

8、说到跨端开发框架,DeepSeek推荐用Flutter,支持iOS、Android、Web、桌面(Windows/macOS/Linux),高性能、重热载、组件库丰富、生态强大,缺点在于需要学习Dart语言(有Cursor,这个不算缺点)、包体积较大、Web端体验较差(无所谓,我也没打算上Web端),看起来的确是最符合我需求的跨端开发框架

9、之前移动端的ChatWith一直无法全屏显示,多次修改也无果,决定就用它开刀了,看能否在Cursor里使用Flutter框架,把它改成跨端应用,先搞好iOS端,再搞Mac端

10、询问Cursor如果我想把ChatWith改成用Flutter框架的话,可行性如何,Cursor认为目前应用的功能在Flutter中均可实现,核心功能在Flutter中均有对应的方案,我比较关注本地存储和Markdown渲染,本次存储上,Cursor建议对话数据用sqflite数据库,配置用shared_preferences,Markdown渲染用flutter_markdown或markdown_widget,且Flutter的Markdown包更成熟,但是,需要完全重写,无法复用Swift代码

11、Cursor还推荐了如下技术栈:

核心框架:Flutter SDK(最新稳定版)

状态管理:Provider或Riverpod(推荐 Riverpod)

网络请求:dio(支持流式响应)

本地存储:shared_preferences (配置)、sqflite (对话数据)

Markdown渲染:flutter_markdown

UI组件:cupertino_icons (iOS风格图标) 、flutter_slidable (滑动操作)

并且推荐完全迁移,优点在于跨平台、长期维护成本低,缺点在于需要重写所有代码

12、继续询问,如果按照Cursor的建议完全迁移,并使用Cursor推荐的技术栈的话,让它分析了一下详细的迁移计划和项目结构建议,它直接写了三个文档:FLUTTER_MIGRATION_PLAN.md(迁移计划)、FLUTTER_CODE_EXAMPLES.md(代码示例)、FLUTTER_QUICK_START.md(快速开始),可能Cursor认为我自己会参考这三个文档来开发吧,先这样,接下来让Cursor来进行迁移