ccusage 的 OpenCode 数据源适配器:SQLite 主源、JSON 回退与 Token 成本映射全解析
ccusage 的 OpenCode 数据源适配器SQLite 主源、JSON 回退与 Token 成本映射全解析【免费下载链接】ccusagenpx ccusage项目地址: https://gitcode.com/gh_mirrors/cc/ccusage本文深入解析 ccusage 项目中 OpenCode 适配器ccusage-adapter-opencode的数据读取原理它如何定位OPENCODE_DATA_DIR或 XDG 默认目录下的 OpenCode 数据如何以 SQLite 数据库为主、legacy JSON 消息为回退完成去重加载以及inputTokens、cacheReadInputTokens等字段如何映射为 ccusage 的统一用量条目并据此计算成本。读完本文你将掌握 OpenCode 数据在 ccusage 中的完整读取链路、可用的环境变量与报告视图以及排查成本显示为 $0.00等问题的依据。一、适配器定位从 OpenCode 数据到统一用量报告ccusage 支持读取多种终端 AI 编程助手的本地会话日志OpenCodeterminal-based AI coding assistant是其中之一。承载该能力的 crate 是rust/adapters/opencode/包名ccusage-adapter-opencode其职责在 rust/adapters/opencode/README.md 中描述得很清楚把 OpenCode 的 SQLite 数据库与历史 JSON 消息文件转换成报告渲染所需的统一 usage entries。模块划分如下文件职责loader.rs读取数据源、去重、日期窗口过滤parser.rs原始记录解析、Token 映射、模型名归一化paths.rs环境变量、默认目录与文件发现report.rs报告 JSON 与表格形状lib.rs对外入口load_entries、run、has_data本适配器是仓库中少数直接依赖sqlitecrate 的适配器见 Cargo.toml因为它的主要数据源是 OpenCode 的 SQLite 数据库。二、数据位置OPENCODE_DATA_DIR与 XDG 默认路径2.1 路径解析规则适配器的数据来源遵循以下优先级实现见 paths.rs设置了OPENCODE_DATA_DIR时从该环境变量读取目录列表。它支持一个目录或逗号分隔的多个目录每个条目会做 trim、过滤空值并只在目录真实存在时才加入候选列表path.is_dir()检查重复路径只读一次。未设置OPENCODE_DATA_DIR时回退到${XDG_DATA_HOME:-$HOME/.local/share}/opencode若XDG_DATA_HOME已设置且为绝对路径则使用$XDG_DATA_HOME/opencode否则使用$HOME/.local/share/opencode。原文档给出的完整候选路径如下${OPENCODE_DATA_DIR}/opencode.db ${OPENCODE_DATA_DIR}/opencode-*.db ${XDG_DATA_HOME:-$HOME/.local/share}/opencode/opencode.db ${XDG_DATA_HOME:-$HOME/.local/share}/opencode/opencode-*.db这里的opencode-*.db指渠道channel数据库例如opencode-beta.db。paths.rs 的测试paths.rs 测试模块覆盖了多种边界情况XDG_DATA_HOME优先于$HOME回退、XDG_DATA_HOME为相对路径或空值时回退到 home、设置了OPENCODE_DATA_DIR后不再回退默认路径、逗号分隔列表中的重复路径被去重、不存在的目录被跳过等。2.2 命令行实践在终端中组合使用示例来自 docs/guide/opencode/index.md# 指定单个目录或逗号分隔的多个归档目录 OPENCODE_DATA_DIR$HOME/.local/share/opencode,/backup/opencode ccusage opencode daily # 未设置时读取默认的 XDG 数据目录 ccusage opencode daily注意多目录场景下目录内数据会被合并加载且跨目录仍按消息 ID 去重——loader 的测试suppresses_aggregate_when_message_usage_is_in_another_configured_directory验证了一个目录里有聚合记录、另一个目录里有更细的消息记录时后者胜出见 loader.rs。三、数据源类型与加载优先级3.1 SQLite 数据库是主源适配器对每个候选目录执行以下探测loader.rs 的db_path优先寻找opencode.db若不存在则扫描目录下符合opencode-channel.db命名规则的渠道数据库名称中间部分仅允许 ASCII 字母数字、_、-见is_channel_db_name排序后取第一个。数据库以只读模式打开sqlite::OpenFlags::new().with_read_only()打开失败时不会报错中断而是记录 debug 日志后跳过该数据库。从 SQLite 读取时适配器同时支持两种表结构message表legacy schema每行包含id、session_id、data消息 JSON 文本可能有time_created列。session_message表v2 schema每行包含id、session_id、type、data可能含time_created列。适配器只处理type assistant的行——只有 assistant 消息才携带用量信息测试loads_nested_v2_assistant_usage_and_ignores_session_aggregate验证了 user 行被跳过。3.2 legacy JSON 消息作为回退SQLite 之外的补充来源是storage/message/目录下的 JSON 消息文件OpenCode 的布局为${XDG_DATA_HOME:-$HOME/.local/share}/opencode/ └── storage/ ├── message/{sessionID}/msg_{messageID}.json └── session/{projectHash}/{sessionID}.json加载逻辑loader.rsload_entries_from_directory_parts遵循数据库优先、JSON 兜底、按消息 ID 去重的原则先读 SQLite 数据库得到一批 entry 及其消息 ID 集合再收集storage/message/下所有.json文件。由于文件路径形如storage/message/sessionID/messageID.json文件 stem 即消息 ID——凡是被数据库已覆盖的 ID其文件在读取前就被剔除避免无谓的磁盘读取幸存文件通过read_files_parallel并行读取之后仍按原始文件顺序做串行 ID 去重保证并行不会改变哪个重复项存活的结果测试dedup_is_stable_across_thread_counts专门验证了单线程与多线程读取产出完全一致。最终所有 entry 按时间戳排序entries.sort_by_key(|entry| entry.timestamp)。3.3 数据源检测与聚合回退has_sourceloader.rs用于判断某目录是否有可读数据存在数据库文件或至少一个消息 JSON 文件即为真。它刻意忽略--since/--until因为窗口是在读取过程中应用的避免有数据但查了个空窗口被误判为无数据。会话聚合回退当数据库存在session_v2或同时存在session_message时的session表且当前报告为Session 报告、没有任何时间过滤--since/--until/--last均未设置时适配器会读取表内的会话级累计用量作为兜底loader.rsload_session_aggregate_entries。核心约束是累积型会话聚合无法安全切片因此带时间边界的报告绝不使用该回退测试excludes_cumulative_session_aggregate_from_bounded_window与keeps_message_rows_but_excludes_aggregate_for_partial_since_bound分别验证了完整边界与部分边界下的行为。同时凡是消息级记录已覆盖的会话其聚合条目都会被抑制message_sessions.contains(...)检查。3.4 日期窗口下推性能优化ccusage 的--since/--until会构造一个半开毫秒时间窗DateWindowloader.rs并在三个层面应用SQL 下推查询message表时若列的time_created采样值看起来是毫秒刻度Unix 毫秒阈值MIN_MILLIS_SCALE 100_000_000_000见time_created_looks_like_millis则把窗口下推到 SQL。为规避列值与 payload 轻微漂移下推窗口会各放宽一天widened_for_pushdown最终每行仍以 payload 时间为准做精确判断。查询采用子查询只取id的形态prepare_message_query因为 OpenCode 的索引是(session_id, time_created, id)裸的time_created范围无法走索引而子查询只由索引回答避免读取海量datablob。payload 级过滤从原始 JSON 文本中快速提取time: {created: 数字}的毫秒值extract_message_timestamp不在窗口内则跳过完整解析提取失败则回退到完整解析绝不错杀。旧 schema 回退若表没有time_created列pre-SQLite-era 布局过滤查询无法 prepare自动退化为全表扫描由 payload 检查兜底。四、Token 映射与成本计算4.1 字段映射表原文档明确给出了 OpenCode 消息字段到 ccusage 用量字段的映射这是适配器解析的核心实现见 parser.rs 的message_value_to_entry_innerccusage 用量字段OpenCode 消息字段inputTokenstokens.inputoutputTokenstokens.outputcacheReadInputTokenstokens.cache.readcacheCreationInputTokenstokens.cache.write此外parser.rs 的OpenCodeTokens结构还声明了tokens.reasoning计入 extra total tokens与tokens.total。当input/output/cache等分项缺失时会通过apply_total_token_fallback用tokens.total兜底测试falls_back_to_total_tokens_when_opencode_token_parts_are_missing验证了只有total: 123时output_tokens记为 123。若所有 token 字段均为 0 且无正成本则该记录被丢弃。解析所需的其他消息字段包括modelID、providerID模型与提供商、time.created时间戳仅当 0时采用、id/sessionID用于会话归属与去重、cost可选的预计算美元成本。v2 的session_message行中模型信息可能嵌套在model对象里model.id/model.modelID与model.providerID由OpenCodeV2Message::into_legacy_message归一化parser.rs。4.2 cost 字段的优先级与模型候选消息可能带有预计算的cost字段单位为 USD。成本判定逻辑calculate_open_code_cost若cost存在且 0直接采用测试keeps_positive_opencode_cost验证cost: 0.02被原样保留否则按模型候选列表依次调用 ccusage 的定价表PricingMap来自ccusage-core的 pricing.rs按 token 用量计算命中即返回全部未命中则成本为 0并记录missing_pricing_model供后续提示。模型候选的构造open_code_model_candidates包含三步别名解析resolve_open_code_model_name例如gemini-3-pro-high→gemini-3-pro-preview、k2p6→kimi-k2.6名称归一化normalize_open_code_model_name例如claude-sonnet-4.5→claude-sonnet-4-5claude-haiku-/claude-opus-/claude-sonnet-前缀家族适用提供商前缀组合当 provider 不是unknown时额外生成{provider}/{model}形式的候选provider 中的-转_例如github_copilot/claude-sonnet-4.5。测试snapshots_message_to_entry_variants_and_model_candidates以快照形式固化了这些候选组合便于核对。4.3 会话聚合条目的成本当使用会话聚合回退时session_v2/session表的cost、tokens_input、tokens_output、tokens_cache_read、tokens_cache_write、tokens_reasoning会被映射为一条会话级消息条目其消息 ID 形如session:{session_id}session_value_to_entry。该路径允许仅有正 cost 而无 token的纯成本条目allow_cost_only: true。会话聚合中的model字段可能是 JSON 字符串{id: ..., providerID: ...}或纯文本由parse_session_model兼容解析。五、报告视图与运行入口5.1 支持的聚焦视图report.rs 的summarize_entries实现了四种视图视图聚合粒度JSON 键ccusage opencode daily按日期YYYY-MM-DDdailyccusage opencode weekly按 ISO 周YYYY-Www周一起weeklyccusage opencode monthly按月份YYYY-MMmonthlyccusage opencode session按会话含父子层级sessionsJSON 输出统一形如{ rows_key: [...], totals: {...} }。这些视图均支持--json结构化输出与--compact窄终端模式详见 docs/guide/opencode/index.md 中链接的每日/每周/每月/会话报告文档。5.2 会话层级展示OpenCode 支持子代理subagent会话。会话报告中带子代理的父会话标题加粗子代理会话以缩进行↳呈现并给出父子的小计行。5.3 运行方式推荐通过包管理器直接运行无需本地安装bunx ccusage opencode --help # bunx推荐 npx ccusagelatest opencode --help # npx pnpm dlx ccusage opencode --help # pnpm BUN_BE_BUN1 opencode x ccusagelatest opencode --help # 原生版 OpenCode 的 x 插件方式opencode x方式要求 OpenCode 为原生版本若通过 npm 安装 OpenCode请改用bunx/npx。运行入口在 lib.rs加载条目 → 按日期过滤 → 需要 JSON 则输出report_json支持--jq后处理与--no-cost否则输出 OpenCode Token Usage Report 表格。六、环境变量速查变量说明默认值OPENCODE_DATA_DIR覆盖 OpenCode 数据根目录支持逗号分隔多目录未设置时回退到默认路径XDG_DATA_HOME未设置OPENCODE_DATA_DIR时的基准目录~/.local/shareLOG_LEVEL日志详细度0 静默 … 5 trace3Info更完整的说明见 docs/guide/environment-variables.md其中还包含CCUSAGE_OFFLINE、NO_COLOR等全局变量。优先级为命令行参数 环境变量 配置文件 内置默认值。七、常见问题排查7.1 No OpenCode usage data found确认默认数据目录存在${XDG_DATA_HOME:-$HOME/.local/share}/opencode/storage/message/。若数据在其他位置设置OPENCODE_DATA_DIR指向该目录或逗号分隔的归档根目录。注意has_data的探测与--since/--until无关因此空窗口查询不应被误判为无数据。7.2 成本显示为 $0.00ccusage 优先采用 OpenCode 消息中预计算的cost字段若其为 0 或缺失则依赖内置定价表按 token 计算。当某个模型不在定价库中且无别名时成本即为 $0.00此时可核对模型候选含 provider 前缀与归一化形式是否正确解析例如gemini-3-pro-high是否被映射到gemini-3-pro-preview。7.3 数据重复或漏读适配器以消息 ID 为唯一键做三层去重数据库内消息、数据库 vs JSON 文件数据库胜出、JSON 文件之间。跨多个OPENCODE_DATA_DIR目录同样适用。若怀疑并行读取导致结果不稳定可参考测试dedup_is_stable_across_thread_counts的结论单线程与多线程读取的最终条目序列完全一致。八、小结OpenCode 适配器是 ccusage 多数据源架构中典型的一例以paths.rs解析环境变量与默认目录以loader.rs完成SQLite 主源 JSON 回退 跨源 ID 去重 日期窗口下推的加载管线以parser.rs完成 token 字段映射、模型别名归一化与成本计算最终由report.rs输出统一的日/周/月/会话报告。理解这条链路既有助于在自定义数据位置时正确配置环境变量也为排查成本异常、数据缺失提供了源码级的依据。【免费下载链接】ccusagenpx ccusage项目地址: https://gitcode.com/gh_mirrors/cc/ccusage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

用 MXNet Gluon 双向 LSTM 训练一个整数序列排序器:从数据编码到训练泛化

用 MXNet Gluon 双向 LSTM 训练一个整数序列排序器:从数据编码到训练泛化

人工智能深度学习机器学习 【免费下载链接】mxnet Lightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more 项目地址: https://gitcode.c…

2026/9/21 16:10:14 阅读更多 →
SAP ERP业务咨询问卷:系统配置的第一道关键决策点

SAP ERP业务咨询问卷:系统配置的第一道关键决策点

简介:这是一份面向SAP ERP项目实施前期的调研问卷,适用于咨询顾问、项目经理及企业内部关键用户开展业务现状梳理与需求收集。问卷按业务模块组织,涵盖企业基本状况、库存管理、BOM与工艺路线、生产计划、采购、车间生产、产品成本、产品配置…

2026/9/21 16:09:13 阅读更多 →
深入解析 Meshery 的 Edge-Network 关系:Service 到 Deployment 的设计与配置

深入解析 Meshery 的 Edge-Network 关系:Service 到 Deployment 的设计与配置

深入解析 Meshery 的 Edge-Network 关系:Service 到 Deployment 的设计与配置 【免费下载链接】meshery Meshery, the cloud native manager 项目地址: https://gitcode.com/GitHub_Trending/me/meshery Meshery 使用 Relationships(关系&#xf…

2026/9/21 16:09:13 阅读更多 →

最新新闻

Django框架核心优势与开发实践指南

Django框架核心优势与开发实践指南

1. Django框架概述与核心优势Django作为Python生态中最成熟的Web框架之一,已经服务了从个人博客到Instagram等大型应用的开发。我第一次接触Django是在2013年一个电商项目里,当时就被它"开箱即用"的特性所震撼。这个框架最吸引我的地方在于它完…

2026/9/21 16:34:32 阅读更多 →
Pandas进行pivot_table数据透视

Pandas进行pivot_table数据透视

在数据分析领域中,处理和理解复杂的数据是十分重要的一环。Pandas库中的pivot_table函数提供了一个强大且灵活的工具,能够将数据重新组织并根据需要进行汇总。通过数据透视,能快速提取数据的关键信息,帮助分析师在海量数据中发现趋势和模式。本文将深入讲解如何利用Pandas的…

2026/9/21 16:34:32 阅读更多 →
OpenIM Server 源码级解析:开源即时通讯服务的架构、模块与部署实践

OpenIM Server 源码级解析:开源即时通讯服务的架构、模块与部署实践

OpenIM Server 源码级解析:开源即时通讯服务的架构、模块与部署实践 【免费下载链接】open-im-server IM Chat OpenClaw 项目地址: https://gitcode.com/gh_mirrors/op/open-im-server OpenIM 是一套专为开发者设计的开源即时通讯解决方案,由 Ope…

2026/9/21 16:33:32 阅读更多 →
GeeORM 第五天:为 ORM 框架实现 Hook 钩子机制(BeforeInsert / AfterQuery / BeforeUpdate / AfterDelete 等 8 个扩展点)

GeeORM 第五天:为 ORM 框架实现 Hook 钩子机制(BeforeInsert / AfterQuery / BeforeUpdate / AfterDelete 等 8 个扩展点)

GeeORM 第五天:为 ORM 框架实现 Hook 钩子机制(BeforeInsert / AfterQuery / BeforeUpdate / AfterDelete 等 8 个扩展点) 【免费下载链接】7days-golang 7 days golang programs from scratch (web framework Gee, distributed cache GeeCac…

2026/9/21 16:33:32 阅读更多 →
【热力学】基于FEM的二维热传导与对流边界附Matlab代码和报告

【热力学】基于FEM的二维热传导与对流边界附Matlab代码和报告

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、算法改进、程序设计科研仿真。🍎 往期回顾关注个人主页:完整代码获取 定制创新 论文复现私信🍊个人信条:做科研&#xff0c…

2026/9/21 16:33:32 阅读更多 →
如何 3 条命令快速上手 Auto-claude-code-research-in-sleep(ARIS):从安装到跑通第一个科研工作流

如何 3 条命令快速上手 Auto-claude-code-research-in-sleep(ARIS):从安装到跑通第一个科研工作流

如何 3 条命令快速上手 Auto-claude-code-research-in-sleep(ARIS):从安装到跑通第一个科研工作流 【免费下载链接】Auto-claude-code-research-in-sleep ARIS ⚔️ (Auto-Research-In-Sleep) — Lightweight Markdown-only skills for auton…

2026/9/21 16:33:31 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →