Files
HxClaw/changelog.md
titor 5494a296d9 docs: 更新文档记录 v0.2.7 升级和 /context 命令
- agents.md: 添加上下文监控功能说明和输出示例
- changelog.md: 新增 v0.3.1 版本记录
- 更新目前进度列表
2026-05-03 02:45:22 +08:00

12 KiB
Raw Permalink Blame History

hxclaw 更新日志

版本记录

v0.3.1 (2026-05-03)

  • 升级 picoclaw 至 v0.2.7

    • 配置版本从 v2 升级至 v3
    • 适配配置结构变更Bindings → Dispatch, channels → channel_list
    • 同步更新相关间接依赖
  • 新增 /context 命令

    • 显示当前会话上下文窗口使用情况
    • 包含消息数、token 使用量、压缩阈值和剩余空间
    • 在 interactiveMode 和 simpleInteractiveMode 中均支持

v0.3.0 (2026-04-27)

  • Session 创建逻辑优化

    • Session 只在用户输入聊天消息时创建
    • /new 命令只重置 currentSession不立即创建
    • 退出后重新进入算作新会话
    • 配置项auto_session默认 true
  • LLM 生成摘要

    • Chat 摘要:调用 LLM 生成极简文言文概述
    • Session 摘要:每次对话后用 LLM 精简整合
    • 配置项summary_timeout默认 30 秒)
    • 容错处理:超时失败回退到简单截断
  • 双记忆系统合并

    • 读取 picoclaw 的 MEMORY.md 作为长期记忆
    • 合并到 hxclaw 的会话摘要上下文
    • AI 同时看到长期记忆和会话摘要
  • 独立上下文系统

    • 创建 GetContextPrompt() 返回会话摘要
    • 注入到 ProcessDirect() 调用前
    • 不再依赖 picoclaw session 管理
    • 修复 recall 结果污染 session summary 问题
  • 数据库层完善

    • 集成 libSQL (TursoDB)
    • 创建 sessions 和 chats 表
    • 实现 CRUD 操作
    • 数据库保存在 ~/.config/hxclaw/hxclaw.db
    • 向量存储使用 binary 编码float32
  • 向量检索功能

    • 硅基流动 BGE-M3 API 集成
    • 向量生成和存储
    • Cosine Similarity 计算
    • SearchSimilar() 函数实现
    • 4 个查询场景RecallHistory, RecallTopic, RecallSession, RecallWithinSession
  • 三重检测机制

    • 关键词匹配(之前、聊过、记得等)
    • 向量相似度自动检测auto_recall + 阈值)
    • /recall 命令强制触发
    • 配置项keywords, auto_recall, similarity_threshold, max_results
  • MongoDB 风格导出

    • 固定路径:~/.config/hxclaw/export-data.json
    • chats 嵌套在 sessions 下
    • 增量导出,同 session 累加
    • 版本控制version 字段)
  • UI 优化

    • 合并状态显示到单行(耗时 · 状态 · 消息数)
    • 颜色设计:金色图标 + 灰色文字
    • 暗绿色"会话已保存" / 暗红色"会话保存异常"
  • 配置项更新

    • memory.recall 配置
    • memory.vector.max_search_results
    • memory.auto_export替换 export_on_exit
    • 默认 max_search_results = 10

v0.2.1

  • 修复 TTS JSON 请求格式,兼容 Windows daemon
  • 发送格式改为 {"text": "内容"}

v0.2.0

  • 新增 TTS 语音朗读功能
    • 集成 mimo-tts client 功能,通过 TCP 连接本地 daemon
    • 支持配置文件开关tts.enabled
    • 支持命令行切换(/tts on/off/status
    • 支持临时 TTS 前缀(T 消息 临时开启)
    • 动态提示符显示 TTS 状态(👀 🔊
    • 静默失败处理(网络异常时警告日志)

v0.1.0

  • 创建 hxclaw 项目
  • 实现流式输出功能
  • Markdown 渲染glamour自动代码高亮
  • 项目配置化project.config.yml

待实现功能

v0.2.0 (当前)

  • TTS 语音朗读功能
    • 集成 mimo-tts client (TCP 连接)
    • 配置文件开关 (tts.enabled)
    • 命令行切换 (/tts on/off/status)
    • 临时 TTS 前缀 (T 消息)
    • 动态提示符显示状态
    • 静默失败处理

v0.3.0 (当前)

  • 双记忆系统合并picoclaw MEMORY.md + hxclaw 会话摘要)
  • 数据库层集成libSQL
  • 独立上下文系统(不再依赖 picoclaw session
  • 会话摘要注入
  • UI 优化(合并显示、颜色设计)
  • 向量检索(硅基流动 API
  • 4 个查询场景RecallHistory, RecallTopic...
  • 三重检测机制
  • MongoDB 风格导出
  • Session 创建逻辑优化(输入消息时自动创建)
  • /new 命令(只重置 currentSession
  • LLM 生成摘要(文言文风格)
  • summary_timeout 配置

待实现功能

v0.4.0 (计划)

  • 命令行参数支持(--theme, --tts 等)
  • 多语言支持
  • 命令提示/补全功能(输入 / 显示内置命令列表)

目前进度

  • 创建项目目录结构
  • 编写讨论记录taolun.md
  • 编写更新日志changelog.md
  • 编写 AI 行为指南agents.md
  • 创建 go.mod
  • 实现 main.go 入口
  • 实现流式输出核心逻辑
  • 编译成功,生成 hxclaw 二进制
  • 添加 spinner 加载动画组件
  • 实现 Markdown 渲染glamour
  • 实现项目配置化project.config.yml
  • 实现 TTS 语音朗读功能
  • 集成 libSQL 数据库
  • 实现独立上下文系统
  • UI 状态合并显示
  • LLM 生成摘要(文言文风格)
  • Session 自动创建逻辑
  • 升级 picoclaw 至 v0.2.7
  • 实现 /context 命令

认知纠正(踩坑记录)

Go replace 机制不需要发布到 registry

问题:最初担心需要像 npm 那样发布到 registry 才能被其他项目引用

纠正Go 的 replace 机制可以直接指向:

  • 本地路径(如 ../picoclaw
  • GitHub 仓库 + taggithub.com/sipeed/picoclaw v0.2.4

知识点Go 模块不需要发布到任何 registryGitHub 就是事实上的 registry


hxclaw 不需要实现全部 picoclaw 功能

问题:最初担心需要自己实现 onboard、tools、mcp 等全部功能

纠正hxclaw 是 CLI 增强层只替换交互逻辑。picoclaw 的核心功能agent loop、tools、mcp、skills通过导入其 pkg 即可复用

知识点:采用组合优于继承的设计,需要什么功能就导入对应的包


流式输出需要判断 Provider 是否支持

问题:不是所有 Provider 都支持流式输出

纠正:需要使用类型断言判断 Provider 是否实现 providers.StreamingProvider 接口:

if sp, ok := provider.(providers.StreamingProvider); ok {
    // 使用 ChatStream
} else {
    // 使用普通 Chat
}

知识点picoclaw 的 Provider 设计使用了接口分离原则,流式是可选能力


终端渲染使用 charmbracelet 库

问题:如何实现 Markdown 终端渲染

纠正:使用 charmbracelet 家族:

  • lipgloss样式定义
  • glow代码高亮

知识点charmbracelet 是 Go 终端UI 的事实标准API 设计优雅


独立二进制部署方式

问题hxclaw 和 picoclaw 的关系

纠正hxclaw 作为独立二进制,用户可以同时保留两个命令:

  • picoclaw agent 使用原版
  • hxclaw 使用增强版

知识点:通过 go.mod replace 实现依赖绑定,用户无需安装 picoclaw 源码


AgentRegistry 没有 BuildMessages 方法

问题:最初尝试调用 agentLoop.GetRegistry().BuildMessages() 构建消息

纠正BuildMessages 属于 ContextBuilder不是 AgentRegistry

// 正确方式
agentInstance.ContextBuilder.BuildMessages(history, summary, input, media, channel, chatID, senderID, senderDisplayName)

知识点picoclaw 代码结构中ContextBuilder 负责消息构建AgentRegistry 负责 agent 管理


ToolDefinitions 获取方式

问题:如何获取可用的工具定义列表

纠正:通过 ToolRegistry 的 ToProviderDefs 方法:

toolDefs := agentInstance.Tools.ToProviderDefs()

知识点ToolRegistry 维护工具注册ToProviderDefs 转换为 provider 可用的格式


流式输出实时刷新

问题:流式输出时字符不是实时显示,要等很久才一次性出现

纠正:在 onChunk 回调中添加 os.Stdout.Sync() 强制刷新 stdout

func(token string) {
    fmt.Print(token)
    os.Stdout.Sync()  // 强制刷新
}

知识点Go 的 fmt.Print 使用缓冲输出,需要手动刷新才能实时显示


Session 历史消息获取

问题:如何获取会话历史用于流式调用

纠正:通过 SessionStore 接口:

history := agentInstance.Sessions.GetHistory(sessionKey)
summary := agentInstance.Sessions.GetSummary(sessionKey)

知识点AgentInstance.Sessions 实现了 SessionStore 接口,支持 GetHistoryGetSummary 方法


流式调用后的消息保存

问题:流式调用绕过了 agent loop消息没有保存到 session

纠正:流式调用后手动保存消息:

agentInstance.Sessions.AddMessage(sessionKey, "user", input)
agentInstance.Sessions.AddMessage(sessionKey, "assistant", result)

知识点SessionStore 接口提供 AddMessage 方法,支持 "user" 和 "assistant" 角色


onChunk 回调接收累积文本导致重复输出

问题picoclaw 的 StreamingProvider 接口定义:

onChunk func(accumulated string)

注释说明:"onChunk receives the accumulated text so far (not individual deltas)"。每次回调时参数是累积的完整文本(如 "你好" → "你好!再次" → "你好!再次见到"),而不是增量。

纠正:使用 printedLen 跟踪已打印位置,只打印新增部分:

var printedLen int
func(accumulated string) {
    if len(accumulated) > printedLen {
        fmt.Print(accumulated[printedLen:])
        printedLen = len(accumulated)
    }
}

知识点picoclaw 故意设计为累积文本,这样可以在任意时刻获取完整内容用于调试


尝试 uilive 库但只显示最后一行

问题:为了实现同行流动效果,尝试使用 github.com/gosuri/uilive

现象:该库会覆盖每一行,只显示最后一行内容

纠正:移除 uilive直接使用 fmt.Print + os.Stdout.Sync(),让终端自然处理换行

知识点uilive 适用于进度条等场景,不适合长文本流式输出


流式输出期望同行流动但实际换行显示

问题:用户期望像 ollama 那样在同行逐字符流动

最终方案

fmt.Print(accumulated[printedLen:])
os.Stdout.Sync()

效果:

  • 字符串自然累积增长
  • 终端自动处理换行(满一行自动 wrap
  • 保留所有历史输出
  • 每次刷新缓冲区确保立即显示

知识点:最简单的方案就是最有效的方案,不需要额外库


spinner 组件的 model 更新必须使用返回值

问题spinner 动画不动

现象:调用 spinner.Update(msg) 后动画不更新

纠正spinner model 是值类型,需要使用返回值更新:

// 错误写法
func (s *Spinner) tick() {
    msg := s.spinner.Tick()
    if msg, ok := msg.(spinner.TickMsg); ok {
        s.spinner.Update(msg)  // 动画不会动!
    }
}

// 正确写法
func (s *Spinner) tick() {
    msg := s.spinner.Tick()
    if msg, ok := msg.(spinner.TickMsg); ok {
        s.spinner, _ = s.spinner.Update(msg)  // 必须使用返回值更新
    }
}

知识点bubbletea v2 的组件遵循 TEA 架构模式Update 方法返回更新后的 model需要显式使用返回值。


spinner 和流式输出在同一行的冲突问题

问题spinner 使用 \r 回到行首刷新,流式输出也在同一行打印,导致内容混在一起

现象

⠋ 回答中...  好
⠋ 回答中...  注于

纠正:在第一个 token 时停止 spinner让 spinner 输出 "思考完成." 并换行,然后再开始流式打印:

if firstToken && len(accumulated) > 0 {
    spinner.Stop()  // 停止 spinner会打印 "思考完成."
    firstToken = false
}

知识点spinner 和流式输出需要分时工作,不能同时占用同一行。


spinner 动画位置和换行策略

问题:用户期望动画在前,文字在后,且需要正确的换行

效果

思考中... ⠋  -> 用户期望 ⠋ 思考中...
思考完成.   -> 用户期望 ⠋ 思考完成.

纠正

  • 动画在前,文字在后:fmt.Printf("\r%s %s", s.spinner.View(), s.text)
  • 换行:"思考完成.\n" + 流式输出后 "fmt.Println()\n"

知识点:终端输出需要精确控制位置和换行,否则会导致格式错乱。