nonebot-plugin-codex 0.1.1__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. nonebot_plugin_codex-0.1.2/PKG-INFO +246 -0
  2. nonebot_plugin_codex-0.1.2/README.md +233 -0
  3. {nonebot_plugin_codex-0.1.1 → nonebot_plugin_codex-0.1.2}/pyproject.toml +2 -1
  4. {nonebot_plugin_codex-0.1.1 → nonebot_plugin_codex-0.1.2}/src/nonebot_plugin_codex/__init__.py +29 -16
  5. nonebot_plugin_codex-0.1.2/src/nonebot_plugin_codex/config.py +15 -0
  6. nonebot_plugin_codex-0.1.2/src/nonebot_plugin_codex/runtime.py +21 -0
  7. {nonebot_plugin_codex-0.1.1 → nonebot_plugin_codex-0.1.2}/src/nonebot_plugin_codex/service.py +525 -52
  8. {nonebot_plugin_codex-0.1.1 → nonebot_plugin_codex-0.1.2}/src/nonebot_plugin_codex/telegram.py +176 -54
  9. nonebot_plugin_codex-0.1.2/src/nonebot_plugin_codex/telegram_rendering.py +114 -0
  10. {nonebot_plugin_codex-0.1.1 → nonebot_plugin_codex-0.1.2}/tests/conftest.py +28 -0
  11. nonebot_plugin_codex-0.1.2/tests/test_config.py +53 -0
  12. nonebot_plugin_codex-0.1.2/tests/test_plugin_meta.py +32 -0
  13. nonebot_plugin_codex-0.1.2/tests/test_release_notes.py +52 -0
  14. nonebot_plugin_codex-0.1.2/tests/test_runtime.py +25 -0
  15. nonebot_plugin_codex-0.1.2/tests/test_service.py +491 -0
  16. nonebot_plugin_codex-0.1.2/tests/test_telegram_handlers.py +596 -0
  17. nonebot_plugin_codex-0.1.2/tests/test_telegram_rendering.py +56 -0
  18. nonebot_plugin_codex-0.1.1/PKG-INFO +0 -196
  19. nonebot_plugin_codex-0.1.1/README.md +0 -184
  20. nonebot_plugin_codex-0.1.1/src/nonebot_plugin_codex/config.py +0 -84
  21. nonebot_plugin_codex-0.1.1/tests/test_config.py +0 -33
  22. nonebot_plugin_codex-0.1.1/tests/test_plugin_meta.py +0 -8
  23. nonebot_plugin_codex-0.1.1/tests/test_service.py +0 -164
  24. nonebot_plugin_codex-0.1.1/tests/test_telegram_handlers.py +0 -246
  25. {nonebot_plugin_codex-0.1.1 → nonebot_plugin_codex-0.1.2}/LICENSE +0 -0
  26. {nonebot_plugin_codex-0.1.1 → nonebot_plugin_codex-0.1.2}/src/nonebot_plugin_codex/native_client.py +0 -0
  27. {nonebot_plugin_codex-0.1.1 → nonebot_plugin_codex-0.1.2}/tests/__init__.py +0 -0
  28. {nonebot_plugin_codex-0.1.1 → nonebot_plugin_codex-0.1.2}/tests/test_native_client.py +0 -0
@@ -0,0 +1,246 @@
1
+ Metadata-Version: 2.1
2
+ Name: nonebot-plugin-codex
3
+ Version: 0.1.2
4
+ Summary: Telegram bridge plugin for driving Codex from NoneBot
5
+ Author-Email: ttiee <469784630@qq.com>
6
+ License: GPL-3.0-or-later
7
+ Requires-Python: >=3.10
8
+ Requires-Dist: nonebot2>=2.4.4
9
+ Requires-Dist: nonebot-adapter-telegram>=0.1.0b20
10
+ Requires-Dist: nonebot-plugin-localstore>=0.7.4
11
+ Requires-Dist: tomli>=2.0.1; python_version < "3.11"
12
+ Description-Content-Type: text/markdown
13
+
14
+ <!-- markdownlint-disable MD033 MD041 -->
15
+ <p align="center">
16
+ <a href="https://nonebot.dev/"><img src="https://nonebot.dev/logo.png" width="200" height="200" alt="nonebot"></a>
17
+ </p>
18
+
19
+ <div align="center">
20
+
21
+ # nonebot-plugin-codex
22
+
23
+ _✨ 在 Telegram 里驱动 Codex CLI 的 NoneBot 插件 ✨_
24
+ <!-- **把本机 Codex CLI 接入 Telegram 的 NoneBot 插件** -->
25
+
26
+ 让你直接在 Telegram 里发起 Codex 会话、续聊上下文、切换工作目录、浏览历史会话,把本地开发工作流搬进聊天窗口。
27
+
28
+ <p>
29
+ <a href="https://github.com/ttiee/nonebot-plugin-codex/blob/main/LICENSE">
30
+ <img src="https://img.shields.io/github/license/ttiee/nonebot-plugin-codex.svg" alt="license">
31
+ </a>
32
+ <a href="https://pypi.org/project/nonebot-plugin-codex/">
33
+ <img src="https://img.shields.io/pypi/v/nonebot-plugin-codex.svg" alt="pypi">
34
+ </a>
35
+ <img src="https://img.shields.io/badge/python-3.10+-3776AB.svg" alt="python">
36
+ <img src="https://img.shields.io/badge/NoneBot-2.4.4+-00A7E1.svg" alt="nonebot">
37
+ <img src="https://img.shields.io/badge/adapter-Telegram-26A5E4.svg" alt="telegram">
38
+ <img src="https://img.shields.io/github/actions/workflow/status/ttiee/nonebot-plugin-codex/test.yml?branch=main&label=test" alt="test">
39
+ </p>
40
+
41
+ </div>
42
+
43
+ ## 项目介绍
44
+
45
+ `nonebot-plugin-codex` 是一个面向 Telegram 场景的 NoneBot 插件,用来把本机 `codex` CLI 暴露为可对话、可续聊、可管理工作目录的聊天式开发助手。
46
+
47
+ 它不是简单地把命令行输出转发到聊天窗口,而是围绕实际使用场景补齐了会话管理与状态管理能力:
48
+
49
+ - 同一聊天内持续续聊,保留上下文
50
+ - 支持 `resume` 与 `exec` 两种运行模式
51
+ - 每个聊天独立维护模型、推理强度、权限模式和工作目录
52
+ - 可视化浏览目录与历史会话
53
+ - 插件自身状态使用 localstore 管理,本地 Codex 历史读取 `~/.codex/*`
54
+
55
+ 如果你已经习惯在本机使用 Codex,又希望通过 Telegram 远程发起编码、排查、审阅或文档整理任务,这个插件就是为这个场景设计的。
56
+
57
+ ## 核心特性
58
+
59
+ - **聊天即入口**:`/codex` 连接后,普通文本消息可直接续聊当前会话。
60
+ - **双模式工作流**:持续对话用 `resume`,一次性任务用 `exec`。
61
+ - **细粒度会话隔离**:不同聊天各自持有模型、权限、工作目录与历史绑定。
62
+ - **目录浏览能力**:支持在 Telegram 内切换目录、设定 Home、查看隐藏目录。
63
+ - **历史会话恢复**:可浏览 native 与 exec 历史,并尽量恢复原始工作目录。
64
+ - **兼容迁移**:可以沿用旧配置文件与 Codex 历史目录,减少迁移成本。
65
+
66
+ ## 快速开始
67
+
68
+ ### 1. 准备运行环境
69
+
70
+ 确保满足以下条件:
71
+
72
+ - Python `3.10+`
73
+ - NoneBot `2.4.4+`
74
+ - 已安装 `nonebot-adapter-telegram`
75
+ - 目标主机上已安装并可直接调用 `codex`
76
+
77
+ ### 2. 安装插件
78
+
79
+ 在 NoneBot 项目根目录中执行其一:
80
+
81
+ ```bash
82
+ nb plugin install nonebot-plugin-codex
83
+ ```
84
+
85
+ 或:
86
+
87
+ ```bash
88
+ pip install nonebot-plugin-codex
89
+ ```
90
+
91
+ 或:
92
+
93
+ ```bash
94
+ pdm add nonebot-plugin-codex
95
+ ```
96
+
97
+ ### 3. 启用插件
98
+
99
+ 在 `pyproject.toml` 中启用:
100
+
101
+ ```toml
102
+ [tool.nonebot]
103
+ plugins = ["nonebot_plugin_codex"]
104
+ ```
105
+
106
+ ### 4. 写入最小可用配置
107
+
108
+ ```toml
109
+ [tool.nonebot]
110
+ plugins = ["nonebot_plugin_codex"]
111
+
112
+ [tool.nonebot.plugin_config]
113
+ codex_binary = "codex"
114
+ codex_workdir = "/home/yourname"
115
+ ```
116
+
117
+ 如果你的 `codex` 不在 `PATH` 中,把 `codex_binary` 改成绝对路径即可。
118
+
119
+ ## 使用方式
120
+
121
+ 一个典型工作流通常是这样的:
122
+
123
+ ```text
124
+ /codex 帮我检查当前仓库为什么测试失败
125
+ /cd /home/yourname/projects/demo
126
+ /permission danger
127
+ /mode resume
128
+ 然后继续直接发送普通文本消息续聊
129
+ ```
130
+
131
+ 你也可以把一次性任务交给 `exec` 模式:
132
+
133
+ ```text
134
+ /exec 用三点总结这个仓库 README 还缺什么
135
+ ```
136
+
137
+ ## 配置说明
138
+
139
+ 完整配置如下,配置名与当前实现保持一致:
140
+
141
+ ```toml
142
+ [tool.nonebot]
143
+ plugins = ["nonebot_plugin_codex"]
144
+
145
+ [tool.nonebot.plugin_config]
146
+ # Codex 可执行文件名或绝对路径,默认直接调用 PATH 中的 `codex`
147
+ codex_binary = "codex"
148
+
149
+ # 默认工作目录;新会话、目录浏览器 Home 入口、相对路径解析都基于它
150
+ codex_workdir = "/home/yourname"
151
+
152
+ # `/stop` 或重置会话时,等待 Codex 子进程退出的超时时间,单位秒
153
+ codex_kill_timeout = 5.0
154
+
155
+ # 运行中在 Telegram 中保留的进度消息条数
156
+ codex_progress_history = 6
157
+
158
+ # 运行失败时最多保留多少条诊断输出
159
+ codex_diagnostic_history = 20
160
+
161
+ # 单条 Telegram 消息的分片长度,过长回复会自动拆分
162
+ codex_chunk_size = 3500
163
+
164
+ # 读取 Codex stdout / stderr 的缓冲区大小
165
+ codex_stream_read_limit = 1048576
166
+
167
+ ```
168
+
169
+ 几个最关键的配置项:
170
+
171
+ - `codex_binary`:如果宿主机不是直接执行 `codex`,改成实际绝对路径。
172
+ - `codex_workdir`:默认工作目录,也是 `/cd` 相对路径解析与目录浏览器 Home 的基准。
173
+ - 其余项分别控制停止超时、进度保留条数、诊断输出条数、Telegram 分片长度和流读取上限。
174
+ - 插件自己的配置数据由 `nonebot-plugin-localstore` 自动管理。
175
+ - 模型缓存、Codex CLI 配置和历史会话目录默认读取 `~/.codex/*`,属于插件内部实现路径。
176
+
177
+ ## 命令一览
178
+
179
+ | 命令 | 说明 |
180
+ | --- | --- |
181
+ | `/codex [prompt]` | 连接 Codex,会附带发送首条 prompt |
182
+ | `/mode [resume\|exec]` | 查看或切换默认模式 |
183
+ | `/exec <prompt>` | 以一次性 `exec` 模式执行任务 |
184
+ | `/new` | 清空当前聊天绑定的会话 |
185
+ | `/stop` | 断开当前聊天的 Codex 会话 |
186
+ | `/models` | 查看可用模型 |
187
+ | `/model [slug]` | 查看或切换模型 |
188
+ | `/effort [high\|xhigh]` | 查看或切换推理强度 |
189
+ | `/permission [safe\|danger]` | 查看或切换权限模式 |
190
+ | `/pwd` | 查看当前工作目录与当前设置 |
191
+ | `/cd [path]` | 直接切换目录;不带参数时打开目录浏览器 |
192
+ | `/home` | 将工作目录重置到 Home |
193
+ | `/sessions` | 打开历史会话浏览器 |
194
+
195
+ ## 模式说明
196
+
197
+ ### `resume`
198
+
199
+ 适合需要持续上下文的对话式场景:
200
+
201
+ - 优先使用 `codex app-server`
202
+ - 为同一聊天维持 native thread
203
+ - 更适合连续编码、持续追问和多轮调试
204
+
205
+ ### `exec`
206
+
207
+ 适合一次性任务或脚本式调用:
208
+
209
+ - 使用 `codex exec --json`
210
+ - 支持恢复已有 exec thread
211
+ - 恢复失败时会自动新开会话并提示
212
+
213
+ ## 目录与历史会话
214
+
215
+ - `/cd` 可打开目录浏览器,逐级进入目录、切换 Home、显示隐藏目录,并把当前浏览目录设置为工作目录。
216
+ - `/sessions` 会列出 native 与 exec 历史会话,便于恢复此前任务。
217
+ - 历史会话恢复时会尝试切回原始工作目录;如果原目录不存在,会保留当前目录并给出提示。
218
+
219
+ ## 发布说明
220
+
221
+ 仓库已包含基础发布流程:
222
+
223
+ - `test.yml`:安装依赖并运行测试
224
+ - `release.yml`:在推送 `v*` 标签时执行 `pdm publish`、生成两个版本间的结构化发布说明,并上传构建产物
225
+
226
+ Release 说明会按 tag 区间内的 Conventional Commits 自动分组,例如 `feat`、`fix`、`docs`、`chore` 等,并附上 compare 链接,避免每次手工整理改动列表。
227
+
228
+ 如果你要启用 PyPI Trusted Publishing,请在 PyPI 项目设置中添加以下信息:
229
+
230
+ - Project name: `nonebot-plugin-codex`
231
+ - Owner: `ttiee`
232
+ - Repository name: `nonebot-plugin-codex`
233
+ - Workflow name: `release.yml`
234
+
235
+ ## 本地开发
236
+
237
+ ```bash
238
+ pdm sync -G:all
239
+ pdm run pytest
240
+ pdm run ruff check .
241
+ pdm build
242
+ ```
243
+
244
+ ## License
245
+
246
+ 本项目使用 [GPL-3.0-or-later](https://github.com/ttiee/nonebot-plugin-codex/blob/main/LICENSE) 许可证。
@@ -0,0 +1,233 @@
1
+ <!-- markdownlint-disable MD033 MD041 -->
2
+ <p align="center">
3
+ <a href="https://nonebot.dev/"><img src="https://nonebot.dev/logo.png" width="200" height="200" alt="nonebot"></a>
4
+ </p>
5
+
6
+ <div align="center">
7
+
8
+ # nonebot-plugin-codex
9
+
10
+ _✨ 在 Telegram 里驱动 Codex CLI 的 NoneBot 插件 ✨_
11
+ <!-- **把本机 Codex CLI 接入 Telegram 的 NoneBot 插件** -->
12
+
13
+ 让你直接在 Telegram 里发起 Codex 会话、续聊上下文、切换工作目录、浏览历史会话,把本地开发工作流搬进聊天窗口。
14
+
15
+ <p>
16
+ <a href="https://github.com/ttiee/nonebot-plugin-codex/blob/main/LICENSE">
17
+ <img src="https://img.shields.io/github/license/ttiee/nonebot-plugin-codex.svg" alt="license">
18
+ </a>
19
+ <a href="https://pypi.org/project/nonebot-plugin-codex/">
20
+ <img src="https://img.shields.io/pypi/v/nonebot-plugin-codex.svg" alt="pypi">
21
+ </a>
22
+ <img src="https://img.shields.io/badge/python-3.10+-3776AB.svg" alt="python">
23
+ <img src="https://img.shields.io/badge/NoneBot-2.4.4+-00A7E1.svg" alt="nonebot">
24
+ <img src="https://img.shields.io/badge/adapter-Telegram-26A5E4.svg" alt="telegram">
25
+ <img src="https://img.shields.io/github/actions/workflow/status/ttiee/nonebot-plugin-codex/test.yml?branch=main&label=test" alt="test">
26
+ </p>
27
+
28
+ </div>
29
+
30
+ ## 项目介绍
31
+
32
+ `nonebot-plugin-codex` 是一个面向 Telegram 场景的 NoneBot 插件,用来把本机 `codex` CLI 暴露为可对话、可续聊、可管理工作目录的聊天式开发助手。
33
+
34
+ 它不是简单地把命令行输出转发到聊天窗口,而是围绕实际使用场景补齐了会话管理与状态管理能力:
35
+
36
+ - 同一聊天内持续续聊,保留上下文
37
+ - 支持 `resume` 与 `exec` 两种运行模式
38
+ - 每个聊天独立维护模型、推理强度、权限模式和工作目录
39
+ - 可视化浏览目录与历史会话
40
+ - 插件自身状态使用 localstore 管理,本地 Codex 历史读取 `~/.codex/*`
41
+
42
+ 如果你已经习惯在本机使用 Codex,又希望通过 Telegram 远程发起编码、排查、审阅或文档整理任务,这个插件就是为这个场景设计的。
43
+
44
+ ## 核心特性
45
+
46
+ - **聊天即入口**:`/codex` 连接后,普通文本消息可直接续聊当前会话。
47
+ - **双模式工作流**:持续对话用 `resume`,一次性任务用 `exec`。
48
+ - **细粒度会话隔离**:不同聊天各自持有模型、权限、工作目录与历史绑定。
49
+ - **目录浏览能力**:支持在 Telegram 内切换目录、设定 Home、查看隐藏目录。
50
+ - **历史会话恢复**:可浏览 native 与 exec 历史,并尽量恢复原始工作目录。
51
+ - **兼容迁移**:可以沿用旧配置文件与 Codex 历史目录,减少迁移成本。
52
+
53
+ ## 快速开始
54
+
55
+ ### 1. 准备运行环境
56
+
57
+ 确保满足以下条件:
58
+
59
+ - Python `3.10+`
60
+ - NoneBot `2.4.4+`
61
+ - 已安装 `nonebot-adapter-telegram`
62
+ - 目标主机上已安装并可直接调用 `codex`
63
+
64
+ ### 2. 安装插件
65
+
66
+ 在 NoneBot 项目根目录中执行其一:
67
+
68
+ ```bash
69
+ nb plugin install nonebot-plugin-codex
70
+ ```
71
+
72
+ 或:
73
+
74
+ ```bash
75
+ pip install nonebot-plugin-codex
76
+ ```
77
+
78
+ 或:
79
+
80
+ ```bash
81
+ pdm add nonebot-plugin-codex
82
+ ```
83
+
84
+ ### 3. 启用插件
85
+
86
+ 在 `pyproject.toml` 中启用:
87
+
88
+ ```toml
89
+ [tool.nonebot]
90
+ plugins = ["nonebot_plugin_codex"]
91
+ ```
92
+
93
+ ### 4. 写入最小可用配置
94
+
95
+ ```toml
96
+ [tool.nonebot]
97
+ plugins = ["nonebot_plugin_codex"]
98
+
99
+ [tool.nonebot.plugin_config]
100
+ codex_binary = "codex"
101
+ codex_workdir = "/home/yourname"
102
+ ```
103
+
104
+ 如果你的 `codex` 不在 `PATH` 中,把 `codex_binary` 改成绝对路径即可。
105
+
106
+ ## 使用方式
107
+
108
+ 一个典型工作流通常是这样的:
109
+
110
+ ```text
111
+ /codex 帮我检查当前仓库为什么测试失败
112
+ /cd /home/yourname/projects/demo
113
+ /permission danger
114
+ /mode resume
115
+ 然后继续直接发送普通文本消息续聊
116
+ ```
117
+
118
+ 你也可以把一次性任务交给 `exec` 模式:
119
+
120
+ ```text
121
+ /exec 用三点总结这个仓库 README 还缺什么
122
+ ```
123
+
124
+ ## 配置说明
125
+
126
+ 完整配置如下,配置名与当前实现保持一致:
127
+
128
+ ```toml
129
+ [tool.nonebot]
130
+ plugins = ["nonebot_plugin_codex"]
131
+
132
+ [tool.nonebot.plugin_config]
133
+ # Codex 可执行文件名或绝对路径,默认直接调用 PATH 中的 `codex`
134
+ codex_binary = "codex"
135
+
136
+ # 默认工作目录;新会话、目录浏览器 Home 入口、相对路径解析都基于它
137
+ codex_workdir = "/home/yourname"
138
+
139
+ # `/stop` 或重置会话时,等待 Codex 子进程退出的超时时间,单位秒
140
+ codex_kill_timeout = 5.0
141
+
142
+ # 运行中在 Telegram 中保留的进度消息条数
143
+ codex_progress_history = 6
144
+
145
+ # 运行失败时最多保留多少条诊断输出
146
+ codex_diagnostic_history = 20
147
+
148
+ # 单条 Telegram 消息的分片长度,过长回复会自动拆分
149
+ codex_chunk_size = 3500
150
+
151
+ # 读取 Codex stdout / stderr 的缓冲区大小
152
+ codex_stream_read_limit = 1048576
153
+
154
+ ```
155
+
156
+ 几个最关键的配置项:
157
+
158
+ - `codex_binary`:如果宿主机不是直接执行 `codex`,改成实际绝对路径。
159
+ - `codex_workdir`:默认工作目录,也是 `/cd` 相对路径解析与目录浏览器 Home 的基准。
160
+ - 其余项分别控制停止超时、进度保留条数、诊断输出条数、Telegram 分片长度和流读取上限。
161
+ - 插件自己的配置数据由 `nonebot-plugin-localstore` 自动管理。
162
+ - 模型缓存、Codex CLI 配置和历史会话目录默认读取 `~/.codex/*`,属于插件内部实现路径。
163
+
164
+ ## 命令一览
165
+
166
+ | 命令 | 说明 |
167
+ | --- | --- |
168
+ | `/codex [prompt]` | 连接 Codex,会附带发送首条 prompt |
169
+ | `/mode [resume\|exec]` | 查看或切换默认模式 |
170
+ | `/exec <prompt>` | 以一次性 `exec` 模式执行任务 |
171
+ | `/new` | 清空当前聊天绑定的会话 |
172
+ | `/stop` | 断开当前聊天的 Codex 会话 |
173
+ | `/models` | 查看可用模型 |
174
+ | `/model [slug]` | 查看或切换模型 |
175
+ | `/effort [high\|xhigh]` | 查看或切换推理强度 |
176
+ | `/permission [safe\|danger]` | 查看或切换权限模式 |
177
+ | `/pwd` | 查看当前工作目录与当前设置 |
178
+ | `/cd [path]` | 直接切换目录;不带参数时打开目录浏览器 |
179
+ | `/home` | 将工作目录重置到 Home |
180
+ | `/sessions` | 打开历史会话浏览器 |
181
+
182
+ ## 模式说明
183
+
184
+ ### `resume`
185
+
186
+ 适合需要持续上下文的对话式场景:
187
+
188
+ - 优先使用 `codex app-server`
189
+ - 为同一聊天维持 native thread
190
+ - 更适合连续编码、持续追问和多轮调试
191
+
192
+ ### `exec`
193
+
194
+ 适合一次性任务或脚本式调用:
195
+
196
+ - 使用 `codex exec --json`
197
+ - 支持恢复已有 exec thread
198
+ - 恢复失败时会自动新开会话并提示
199
+
200
+ ## 目录与历史会话
201
+
202
+ - `/cd` 可打开目录浏览器,逐级进入目录、切换 Home、显示隐藏目录,并把当前浏览目录设置为工作目录。
203
+ - `/sessions` 会列出 native 与 exec 历史会话,便于恢复此前任务。
204
+ - 历史会话恢复时会尝试切回原始工作目录;如果原目录不存在,会保留当前目录并给出提示。
205
+
206
+ ## 发布说明
207
+
208
+ 仓库已包含基础发布流程:
209
+
210
+ - `test.yml`:安装依赖并运行测试
211
+ - `release.yml`:在推送 `v*` 标签时执行 `pdm publish`、生成两个版本间的结构化发布说明,并上传构建产物
212
+
213
+ Release 说明会按 tag 区间内的 Conventional Commits 自动分组,例如 `feat`、`fix`、`docs`、`chore` 等,并附上 compare 链接,避免每次手工整理改动列表。
214
+
215
+ 如果你要启用 PyPI Trusted Publishing,请在 PyPI 项目设置中添加以下信息:
216
+
217
+ - Project name: `nonebot-plugin-codex`
218
+ - Owner: `ttiee`
219
+ - Repository name: `nonebot-plugin-codex`
220
+ - Workflow name: `release.yml`
221
+
222
+ ## 本地开发
223
+
224
+ ```bash
225
+ pdm sync -G:all
226
+ pdm run pytest
227
+ pdm run ruff check .
228
+ pdm build
229
+ ```
230
+
231
+ ## License
232
+
233
+ 本项目使用 [GPL-3.0-or-later](https://github.com/ttiee/nonebot-plugin-codex/blob/main/LICENSE) 许可证。
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nonebot-plugin-codex"
3
- version = "0.1.1"
3
+ version = "0.1.2"
4
4
  description = "Telegram bridge plugin for driving Codex from NoneBot"
5
5
  authors = [
6
6
  { name = "ttiee", email = "469784630@qq.com" },
@@ -8,6 +8,7 @@ authors = [
8
8
  dependencies = [
9
9
  "nonebot2>=2.4.4",
10
10
  "nonebot-adapter-telegram>=0.1.0b20",
11
+ "nonebot-plugin-localstore>=0.7.4",
11
12
  "tomli>=2.0.1; python_version < '3.11'",
12
13
  ]
13
14
  requires-python = ">=3.10"
@@ -1,6 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
- from nonebot import get_plugin_config, on_command, on_message, on_type
3
+ from pathlib import Path
4
+
5
+ from nonebot import get_plugin_config, on_command, on_message, on_type, require
4
6
  from nonebot.plugin import PluginMetadata
5
7
  from nonebot.params import CommandArg
6
8
  from nonebot.adapters.telegram import Bot
@@ -10,7 +12,8 @@ from nonebot.adapters.telegram.event import MessageEvent, CallbackQueryEvent
10
12
  from .config import Config
11
13
  from .telegram import TelegramHandlers
12
14
  from .native_client import NativeCodexClient
13
- from .service import CodexBridgeService, CodexBridgeSettings
15
+ from .runtime import build_service_settings
16
+ from .service import CodexBridgeService
14
17
 
15
18
  __plugin_meta__ = PluginMetadata(
16
19
  name="Codex",
@@ -32,21 +35,21 @@ except ValueError:
32
35
  plugin_config = Config()
33
36
  _runtime_ready = False
34
37
 
38
+
39
+ def _get_plugin_data_dir() -> Path:
40
+ try:
41
+ require("nonebot_plugin_localstore")
42
+ import nonebot_plugin_localstore as store
43
+
44
+ return store.get_plugin_data_dir()
45
+ except Exception:
46
+ return Path("data") / "nonebot_plugin_codex"
47
+
48
+
35
49
  service = CodexBridgeService(
36
- CodexBridgeSettings(
37
- binary=plugin_config.codex_binary,
38
- workdir=str(plugin_config.codex_workdir),
39
- kill_timeout=plugin_config.codex_kill_timeout,
40
- progress_history=plugin_config.codex_progress_history,
41
- diagnostic_history=plugin_config.codex_diagnostic_history,
42
- chunk_size=plugin_config.codex_chunk_size,
43
- stream_read_limit=plugin_config.codex_stream_read_limit,
44
- models_cache_path=plugin_config.codex_models_cache_path,
45
- codex_config_path=plugin_config.codex_codex_config_path,
46
- preferences_path=plugin_config.codex_preferences_path,
47
- session_index_path=plugin_config.codex_session_index_path,
48
- sessions_dir=plugin_config.codex_sessions_dir,
49
- archived_sessions_dir=plugin_config.codex_archived_sessions_dir,
50
+ build_service_settings(
51
+ plugin_config,
52
+ plugin_data_dir=_get_plugin_data_dir(),
50
53
  ),
51
54
  native_client=NativeCodexClient(
52
55
  binary=plugin_config.codex_binary,
@@ -82,6 +85,12 @@ if _runtime_ready:
82
85
  block=True,
83
86
  rule=handlers.is_history_callback,
84
87
  )
88
+ setting_callback = on_type(
89
+ CallbackQueryEvent,
90
+ priority=10,
91
+ block=True,
92
+ rule=handlers.is_setting_callback,
93
+ )
85
94
 
86
95
  @codex_cmd.handle()
87
96
  async def _handle_codex(
@@ -159,6 +168,10 @@ if _runtime_ready:
159
168
  async def _handle_history_callback(bot: Bot, event: CallbackQueryEvent) -> None:
160
169
  await handlers.handle_history_callback(bot, event)
161
170
 
171
+ @setting_callback.handle()
172
+ async def _handle_setting_callback(bot: Bot, event: CallbackQueryEvent) -> None:
173
+ await handlers.handle_setting_callback(bot, event)
174
+
162
175
  @follow_up.handle()
163
176
  async def _handle_follow_up(bot: Bot, event: MessageEvent) -> None:
164
177
  await handlers.handle_follow_up(bot, event)
@@ -0,0 +1,15 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ from pydantic import BaseModel, Field
6
+
7
+
8
+ class Config(BaseModel):
9
+ codex_binary: str = "codex"
10
+ codex_workdir: Path = Field(default_factory=Path.home)
11
+ codex_kill_timeout: float = 5.0
12
+ codex_progress_history: int = 6
13
+ codex_diagnostic_history: int = 20
14
+ codex_chunk_size: int = 3500
15
+ codex_stream_read_limit: int = 1024 * 1024
@@ -0,0 +1,21 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ from .config import Config
6
+ from .service import CodexBridgeSettings
7
+
8
+
9
+ def build_service_settings(
10
+ plugin_config: Config, *, plugin_data_dir: Path
11
+ ) -> CodexBridgeSettings:
12
+ return CodexBridgeSettings(
13
+ binary=plugin_config.codex_binary,
14
+ workdir=str(plugin_config.codex_workdir),
15
+ kill_timeout=plugin_config.codex_kill_timeout,
16
+ progress_history=plugin_config.codex_progress_history,
17
+ diagnostic_history=plugin_config.codex_diagnostic_history,
18
+ chunk_size=plugin_config.codex_chunk_size,
19
+ stream_read_limit=plugin_config.codex_stream_read_limit,
20
+ preferences_path=plugin_data_dir / "preferences.json",
21
+ )