 kevinandClaude Fable 5
|
57cca6bb7a
|
签到工具新增检查功能:修复状态误判问题
问题:
- 用户询问'我今天签到了吗'时,AI基于对话历史判断而非查询数据库
- 导致明明没签到,AI却说已经签到了(误判)
解决方案:
- 新增 action=check 操作,专门用于检查当前节点今天是否已签到
- 直接调用 HasSignedOnDay 查询数据库,返回准确的签到状态
- AI 现在会强制调用工具查询,而不是根据记忆猜测
改动内容:
- 工具定义中添加 check 操作类型
- 实现 executeCheck 方法,查询数据库并返回明确状态
- 添加完整的单元测试(未签到/已签到两种场景)
- 更新文档说明 check 操作的使用
使用示例:
- 用户:'我今天签到了吗?'
- AI 调用:{"action": "check"}
- 返回:'XXX 今天还没有签到。' 或 'XXX 今天已经签到过了。'
测试:
- ✅ 未签到场景测试通过
- ✅ 已签到场景测试通过
- ✅ 所有签到工具测试通过
- ✅ 项目编译成功
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-06-23 21:37:44 +08:00 |
|
kevin
|
bd25b79724
|
up
|
2026-06-23 21:27:52 +08:00 |
|
 kevinandClaude Fable 5
|
cd5dcb29f5
|
新增活跃度查询工具
功能:
- 查询指定时间范围内的活跃节点数和活跃人数
- 活跃节点:统计 nodeinfo 表 updated_at 字段
- 活跃人数:统计 text_message 表按 from_id 去重的用户数
使用场景:
- 用户问'现在有多少人活跃'时 AI 调用此工具
- 用户问'当前有多少节点在线'时 AI 调用此工具
- 支持附带时间条件,默认1小时,最大24小时
参数:
- hours: 查询最近N小时,默认1小时,最大24小时
- query_type: both/nodes/users,默认 both
实现:
- internal/agents/active/active.go - 工具主逻辑
- internal/store/active_store.go - 数据库查询方法
- 完整的单元测试,所有测试通过
- 在 ai/service.go 中注册工具
测试:
- ✅ 默认查询(1小时,both)
- ✅ 指定时间查询(6小时、24小时)
- ✅ 仅查询节点/人数
- ✅ 时间限制验证
- ✅ 项目编译成功
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-06-23 21:26:14 +08:00 |
|
 kevinandClaude Fable 5
|
2f83308dce
|
修复 LLM Provider 配置热更新问题
问题:在 /admin/llm/api 页面修改 AI 提供商配置后,配置没有立即生效,AI 依然使用旧的提供商工作
根本原因:
- LLM Provider 配置在程序启动时加载到内存 (llm.State)
- 管理后台修改配置时,只更新了数据库,内存配置未更新
- AI 继续使用内存中的旧配置
解决方案:
1. 为 llm.State 添加动态更新方法 (UpdateProvider/AddProvider/RemoveProvider)
2. 在 AI Service 中暴露配置更新接口,支持运行时重新加载
3. 在配置保存后自动触发内存配置重新加载
4. 创建新的 LLM Client 使新配置立即生效
关键特性:
- 线程安全:使用 sync.RWMutex 保护并发访问
- 容错处理:重新加载失败不影响数据库更新
- 无需重启:配置修改后立即生效
- 完整测试:添加单元测试验证功能
修改文件:
- internal/llm/state.go: 添加配置更新方法
- internal/ai/service.go: 添加配置重新加载接口
- internal/llmadmin/admin_llm_routes.go: 配置更新时触发重新加载
- internal/web/web.go: 传递 AI Service 到路由
- main.go: 连接组件
- internal/llm/state_test.go: 新增单元测试
- internal/web/map_tile_proxy_routes_test.go: 修复测试
测试:
- ✅ 所有现有测试通过
- ✅ 新增测试覆盖核心功能
- ✅ 项目成功编译
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-06-23 21:13:31 +08:00 |
|
kevin
|
c50c7a57d7
|
签到
|
2026-06-23 21:04:31 +08:00 |
|
 kevinandClaude Fable 5
|
ec24e70275
|
修复 MQTT QoS0 消息重发问题
问题:
- 设备发送 QoS0 消息后服务器未及时响应 TCP ACK
- 导致设备重发 3 次
- 有时能一次成功,有时需要多次重发
根本原因:
- TCP Nagle 算法延迟小数据包(包括 TCP ACK)40-200ms
- QoS0 不需要 MQTT 应用层 PUBACK,但依赖 TCP 层 ACK
- TCP ACK 延迟触发客户端 TCP 重传机制
解决方案:
- 在 OnConnect hook 中设置 TCP_NODELAY
- 禁用 Nagle 算法,确保 TCP ACK 立即发送
- TCP ACK 延迟从 40-200ms 降低到 ~0.05ms
测试:
- 添加 tcp_nodelay_test.go 验证修复
- 平均往返延迟:54µs
- 符合 MQTT broker 行业最佳实践(Mosquitto、EMQX、HiveMQ 均默认启用)
文档:
- doc/TCP_ACK_FIX_CN.md - 中文详细说明
- doc/TCP_ACK_FIX.md - 英文详细说明
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-06-23 21:04:00 +08:00 |
|
 kevinandClaude
|
d57dff58f3
|
重构:把剩余 12 个顶层包全部迁到 internal/
继续之前的重构:把根目录残留的非数据/资源类子目录(agents、agenttool、ai、
autoreply、completion、conversation、llm、message、mqtpp、stream、
toolmanager、toolrouter)一并搬到 internal/ 下,并把全工程引用它们的
import 路径从 "meshtastic_mqtt_server/<x>" 重写为
"meshtastic_mqtt_server/internal/<x>"。
变更
- git mv 12 个顶层目录进 internal/,无函数体改动。
- 全工程 sed 把 import path 加上 internal/ 前缀,包括 main.go、
internal/bot/bot_service.go、internal/store/bot_store.go 中对 mqtpp
的引用,以及 ai 子系统内部 agents/agenttool/autoreply/conversation/
llm/toolmanager/toolrouter 之间的相互引用。
验证
- go build ./... 通过;go test ./... 全部包通过。
- AI 自动回复链路(main → ai.NewService → autoreply.Service → botSender)
保持不变,仅 import 路径调整。
- 根目录最终只剩 main.go / main_test.go / internal/ 加 go.mod / go.sum
与数据资源目录(dist、doc、firmware、py、win、meshmap_frontend)。
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-18 18:43:42 +08:00 |
|
 kevinandClaude
|
02b445884d
|
合并 refactor/internal-packages:把根目录 46 个 .go 文件按功能拆到 internal/ 下
把工程根目录全部 package main 文件按业务边界搬到 internal/ 子包下。
根目录从 46 个文件 12.6k 行降到 2 个文件 480 行;新增 13 个 internal 子包:
auth、blocking、bot、config、help、llmadmin、mapsource、mqttforward、
runtimesettings、sign、store、store/testutil、web、webutil。
共 4 个 commit 渐进迁移,每个 commit 单独 build/test 通过:
- eff4972 拆出 internal/config 与 internal/store
- c527a9f 拆出 auth / blocking / runtimesettings / help / mqttforward
- 9394aa0 拆出 bot / sign / mapsource / llmadmin / web
- 46916d9 main.go 直接 import 子包并删除全部 bridge
go build ./... 与 go test ./... 全部通过,测试数量与重构前一致。
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-18 18:34:14 +08:00 |
|
 kevinandClaude
|
46916d9a93
|
重构:main.go 直接 import 各 internal/ 子包,删除全部 bridge
最后一步:把 main.go 里所有指向桥接小写名的引用(store / config /
blocking / bot / runtimesettings / mqttforward / web 等)改写成直接调用
internal/* 子包的导出 API,从而拆掉所有 *_bridge.go。
变更点
- main.go 顶部 import 区改为引用 11 个 internal/ 子包:auth、blocking、
bot、config、mqttforward、runtimesettings、store、web 等。
- meshtasticFilterHook 字段类型改为 *storepkg.WriteQueue / *blockingpkg.Cache
/ *rspkg.Cache / *mqttforwardpkg.Stats;不再依赖 main 包内别名。
- mqttClientInfoFromClient 返回 storepkg.MQTTClientInfo(之前为 main 包别名)。
- run() 里 newSessionManager → auth.NewManager;newRouter → webpkg.NewRouter;
serveHTTPUnixSocket → webpkg.ServeUnixSocket;mqttRuntimeStatus →
webpkg.MQTTRuntimeStatus;botSendTextRequest → botpkg.SendTextRequest;
newBlockingCache / newRuntimeSettingsCache / newMQTTForwardManager 都改为
对应包的 New / NewManager。
- main_test.go 里的 BlockingViolationForRecord 测试改用 testutil.OpenStore
+ blockingpkg.New,全部通过 store.Store 的公开 API 构造数据,不再需要
根目录 test_helpers_test.go。
删除根目录文件
- config.go、auth.go(已删)、blocking_bridge.go、bot_bridge.go、
help_bridge.go、llmadmin_bridge.go、mapsource_bridge.go、
mqttforward_bridge.go、runtime_settings_bridge.go、sign_bridge.go、
store_bridge.go、web_bridge.go、test_helpers_test.go。
最终结果
- 根目录只剩 main.go (~370 行) 和 main_test.go (~110 行)。
- internal/ 下 13 个独立子包:auth / blocking / bot / config / help /
llmadmin / mapsource / mqttforward / runtimesettings / sign / store /
store/testutil / web / webutil。
- go build ./... / go test ./... 全部通过;测试数量与重构前一致;
go build . 可以产出可执行二进制(约 50 MB)。
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-18 18:30:00 +08:00 |
|
 kevinandClaude
|
9394aa0f4a
|
重构:拆出 bot / sign / mapsource / llmadmin / web 包
第三批(最终批):把 root 中剩下所有领域文件按功能搬到 internal/ 下。
完成后根目录从 46 个 .go 文件降到 14 个,其中 11 个是 bridge(type alias
+ thin wrapper),仅供尚未改造的 main.go 引用。
新增包
- internal/bot/ Service / TextSender / NewPKIKeyResolver /
RegisterRoutes,含 PKI 直连发送、节点信息广播、
outbound DM 持久化等业务逻辑。
- internal/sign/ SignDTO / SignDayCountDTO / RegisterAdminRoutes,
把原来分散在 admin_sign_routes.go 与 web.go 中的
sign DTO/路由收拢到一处。
- internal/mapsource/ AdminDTO / PublicDTO / RegisterAdminRoutes /
RegisterPublicRoutes。
- internal/llmadmin/ LLM 消息队列、Provider、ToolRouter、PrimaryConfig 的
admin 路由。
- internal/web/ 路由总入口(NewRouter/NewHTTPServer/ServeUnixSocket)、
各资源的 GET API、admin 用户/登录/MQTT 状态、所有
DTO 函数。把 auth.go 的 sessionClaims 升级为
auth.SessionClaims;mqtt_status.go 重写成
MQTTRuntimeStatus / AdminMQTTStatus 结构体并把
client info 解析在 web 包内自带,不再依赖 main 包。
map_tile_proxy_routes 与测试一起搬入。
修改
- web.go 中 parseListOptions / writeListResponse / ptrString 等本地 helper
改为对 internal/webutil 的 thin wrapper,避免重复实现。
- internal/auth 在 step 4 已创建,本批中 web 包正式开始引用其 Manager /
RequireAdmin / SessionClaims。
根目录新增 bridge:bot_bridge.go / sign_bridge.go / mapsource_bridge.go /
llmadmin_bridge.go / web_bridge.go。后者把 mqttRuntimeStatus 包成
webpkg.MQTTStatusProvider 适配器,使 main.go 中旧字段名保持可用。
go build ./... / go test ./... 全部通过;测试数量未变。
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-18 18:24:14 +08:00 |
|
 kevinandClaude
|
c527a9fd9a
|
重构:拆出 auth / blocking / runtimesettings / help / mqttforward 包
第二批:把根目录中纯逻辑领域文件(cache、service、admin route)按业务边界
迁到 internal/ 下的子包。各子包暴露 RegisterRoutes 给 web 包调用,根目录
只留下一行 bridge 文件保留旧名字别名。
新增包
- internal/auth/ SessionClaims / Manager / RequireAdmin / HashPassword /
VerifyPassword / AdminUserResponse 等。原 auth.go 中
被两个 admin route 依赖的 sessionClaims 现在以 auth.
SessionClaims 形式被它们 import;不再被锁在 main 包。
- internal/blocking/ Cache + RegisterRoutes,以前散在 blocking_cache.go
和 admin_blocking_routes.go 里。
- internal/runtimesettings/ Cache + RegisterRoutes。
- internal/help/ RenderMarkdown / RegisterPublicRoutes /
RegisterAdminRoutes(拆分原来的 registerHelpRoutes
和 registerAdminHelpRoutes 两条入口)。
- internal/mqttforward/ Manager / Reloader / Stats / RegisterRoutes。
forwarder runner、循环抑制 cache 等运行时逻辑随之迁入。
- internal/webutil/ ParseListOptions / WriteListResponse[WithTotal] /
ParseMapReportListOptions / ParseMapReportViewportOptions
以及 PtrString/PtrInt64/... 等指针解引用 helper。
以前散在 web.go 中,现在被各 admin route 子包共享,
避免 internal/blocking → internal/web → internal/blocking
的循环依赖。
- internal/store/testutil/ OpenStore(t) helper,让其它包测试零样板拿到 store。
根目录新增 bridge 文件
- blocking_bridge.go / runtime_settings_bridge.go / help_bridge.go /
mqttforward_bridge.go:用 type alias + thin wrapper 把上述子包的导出
名映射到旧的小写名(blockingCache、registerAdminBlockingRoutes 等),
让 main.go / web.go 等仍未迁出的文件无须改动。
修改
- auth.go 改为对 internal/auth 的 bridge;web.go 中 sessions.newCookie /
clearCookie 改为 NewCookie / ClearCookie。
- main_test.go 中 BlockingViolationForRecord* 测试不再直接构造未导出字段,
改成走 store.CreateNodeBlocking → newBlockingCache 的真实路径。
- internal/mqttforward 把以前 *_store.go 中没有方法依赖的运行时类型
(forwarder runner、loop cache)和 admin route 一并归位;mqtt_status.go
暂时仍留在根目录(依赖 main 中的 mqttClientInfoFromClient)。
go build ./... / go test ./... 全部通过;测试数量未变。
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-18 14:23:56 +08:00 |
|
 kevinandClaude
|
eff4972668
|
重构:拆出 internal/config 与 internal/store 子包
把工程根目录中和"配置加载"、"数据存储"两个领域相关的全部 Go 文件迁到
internal/ 下的子包,按功能分组的第一阶段成果。
internal/config/
- 从 config.go 抽出 Config / MQTTConfig / WebConfig / DatabaseConfig 等
类型并大写导出,函数改名 Default/Load/Write/Validate/BuildTLS 等。
- 测试随被测代码迁移成 package config 的内部测试。
- 根目录留 config.go 作桥接:用 type alias 让旧的小写名(config /
mqttConfig / databaseConfig 等)继续可用,避免修改 30+ 处调用方。
internal/store/
- 把 db.go、store_query.go、db_write_queue.go 与 13 个 *_store.go 一并
迁入;26 个 *Record 类型与 store 同包以避免循环依赖。
- store -> Store;50+ 标识符从小写未导出改为大写导出(包括 record、
ListOptions、错误变量、bot/llm/runtime 常量、helpers 等)。
- 新增 DB() / Driver() 访问器供 ai 子系统使用,避免直接访问私有字段。
- bot_pki_store.go 独立出来,把 PKI 解密所需的 store 方法集中归类。
- helpers.go 提供 hashPassword / uint32FromRecord / printJSON 等以前在
其他根目录文件中的辅助;test_helpers_test.go 提供 verifyPassword
与 publicMapTileSourceDTO 让测试可以本地运行而不依赖 main 包。
根目录新增:
- store_bridge.go:完整 type-alias / 函数包装层,把 internal/store 的
导出名映射回旧的小写名,让 admin_*_routes.go、web.go、bot_service.go
等仍未迁出的文件继续编译。后续步骤把它们迁到各自领域包后可逐步删除。
- test_helpers_test.go:根目录测试沿用 openTestStore 的入口。
go build ./... 与 go test ./... 全部通过;测试数量与重构前一致。
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-18 13:56:36 +08:00 |
|
kevin
|
6f6b06e37d
|
up
|
2026-06-18 12:24:18 +08:00 |
|
kevin
|
f3ee4035bb
|
up
|
2026-06-17 20:58:01 +08:00 |
|
kevin
|
b0a9f52096
|
实现每机器人独立 LLM 消息队列
主要变更:
- 后端:为 botNodeRecord 添加 llm_queue_enabled 和 llm_include_channel_messages 字段
- 后端:移除全局 LLM 队列开关,完全基于每个机器人的设置
- 后端:重写 enqueueChannelMessageToLLM,为每个启用了「包含频道消息」的机器人创建独立队列记录
- 后端:频道消息不再使用 bot_id=0,每条消息都有明确的机器人归属
- 前端:AdminLLM.vue 完全重写,添加机器人 LLM 设置面板
- 前端:消息列表表格新增「机器人」列,显示机器人名称和节点 ID
- 前端:消息类型判断逻辑改为使用 channel_id 区分频道/私聊
- 前后端类型同步更新
|
2026-06-17 20:51:22 +08:00 |
|
kevin
|
e2bf6aa173
|
up
|
2026-06-17 20:18:37 +08:00 |
|
 kevinandClaude
|
2840aca69b
|
修复签到日历人数显示
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-16 20:56:50 +08:00 |
|
 kevinandClaude
|
8690265fa0
|
新增签到日历筛选
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-16 20:49:21 +08:00 |
|
 kevinandClaude
|
d36455ce71
|
修复签到页顶部导航显示
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-16 20:26:13 +08:00 |
|
 kevinandClaude
|
6084897bdb
|
新增签到管理功能
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-16 20:16:28 +08:00 |
|
 kevinandClaude
|
eeefdaa180
|
调整轨迹浮窗宽度
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-16 19:56:42 +08:00 |
|
 kevinandClaude
|
5b873ea059
|
修复轨迹浮窗文字布局
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-16 19:54:01 +08:00 |
|
kevin
|
3a94cf2c3e
|
Merge branch 'feature/web-listener-toggles'
|
2026-06-16 19:50:28 +08:00 |
|
 kevinandClaude
|
e6a8826a8f
|
显示轨迹全部坐标节点
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-16 19:45:27 +08:00 |
|
 kevinandClaude
|
0f04047517
|
支持 Web 端口和 Sock 同时启用
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-06-16 19:36:47 +08:00 |
|
kevin
|
f00f030ef3
|
节点移出地图不消失
|
2026-06-16 18:56:19 +08:00 |
|