Skip to content

feat: add codex_adapter plugin - #2472

Open
StarrySerendipity wants to merge 6 commits into
Project-N-E-K-O:mainfrom
StarrySerendipity:feature/codex-adapter
Open

feat: add codex_adapter plugin#2472
StarrySerendipity wants to merge 6 commits into
Project-N-E-K-O:mainfrom
StarrySerendipity:feature/codex-adapter

Conversation

@StarrySerendipity

@StarrySerendipity StarrySerendipity commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

概述

添加 codex_adapter 插件,将 OpenAI Codex CLI 注册为猫娘可调用的工具集。

主要功能

  • 通过 @llm_tool 暴露 Codex CLI 功能
  • 支持会话恢复(thread_id)
  • Web 搜索支持
  • 快速模式支持
  • 瞬态错误自动重试
  • CODEX_HOME 管理
  • 猫娘可直接调用执行项目开发任务:写代码、改 bug、跑测试、查文档

变更内容

  • 新增 plugin/plugins/codex_adapter/ 插件目录
  • 配置为 dev 模式(entry: plugin.plugins.codex_adapter:CodexAdapterPlugin)

测试

  • 插件可正常加载
  • @llm_tool 工具可被猫娘调用
  • 会话恢复功能正常
  • Web 搜索功能正常
  • 错误重试机制生效

Summary by CodeRabbit

  • 新功能
    • 新增 Codex Adapter 插件:将 Codex CLI 暴露为可调用工具,支持模型/推理强度、搜索与快速模式、指令文件前置、工作目录与执行超时。
    • 提供健康检查、配置查询、会话列表与按目录清理;会话持久化并自动查找可恢复会话以续执行。
    • 支持跨平台 CODEX_HOME 与认证文件(auth.json)准备/同步。
  • 错误处理
    • 对失败进行细分分类;对符合条件的错误自动重试,并在结果中给出可重试时间与诊断信息。

Copilot AI review requested due to automatic review settings July 25, 2026 14:21
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8017a862-08fa-41cd-a601-fb71f5e9a0e6

📥 Commits

Reviewing files that changed from the base of the PR and between 5618a36 and bdec7af.

📒 Files selected for processing (1)
  • plugin/plugins/codex_adapter/__init__.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • Project-N-E-K-O/N.E.K.O.-PC (manual)
🚧 Files skipped from review as they are similar to previous changes (1)
  • plugin/plugins/codex_adapter/init.py

Walkthrough

新增 Codex Adapter 插件,覆盖配置模型、CODEX_HOME 管理、JSONL 解析、CLI 异步执行、错误分类、会话持久化、健康检查及多类工具入口喵。

Changes

Codex 适配器

Layer / File(s) Summary
配置模型、事件解析与错误分类
plugin/plugins/codex_adapter/models.py, plugin/plugins/codex_adapter/parser.py, plugin/plugins/codex_adapter/errors.py
新增配置、会话、执行结果和 CLI 调用模型;解析 Codex JSONL 事件并汇总文本与 token;分类认证、超时、未知会话、瞬态上游及用量限制错误喵。
CODEX_HOME 与会话持久化
plugin/plugins/codex_adapter/codex_home.py, plugin/plugins/codex_adapter/session.py
新增 CODEX_HOME 路径解析、auth.json 写入、配置复制、符号链接管理,以及基于 PluginStore 的会话加载、恢复、更新和清理喵。
Codex CLI 调用执行
plugin/plugins/codex_adapter/executor.py
新增跨平台 CLI 探测、参数构建、环境变量注入、异步子进程执行、JSONL 流解析和超时处理喵。
插件生命周期与工具入口
plugin/plugins/codex_adapter/__init__.py, plugin/plugins/codex_adapter/plugin.toml
注册插件配置与入口,接入启动初始化、带重试执行、健康检查、会话管理、配置查询及 execute 入口喵。

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • Project-N-E-K-O/N.E.K.O#2470:实现了相同 Codex Adapter 模块及其插件工具、执行和会话对接,代码改动高度重合喵。

Suggested labels: enhancement, Needs Check!

Poem

Codex 小猫踏入终端喵
JSONL 星光顺流飘喵
会话收进持久化巢喵
错误重试把风暴熬喵
一声执行,答案到喵

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 标题简洁且与新增 codex_adapter 插件这一主要变更一致喵
Description check ✅ Passed 描述已覆盖概述、主要功能、变更内容和测试,且未触发必填的回归报告/不拆分理由喵
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added the enhancement New feature or request label Jul 25, 2026
@greptile-apps

greptile-apps Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

此 PR 新增将 Codex CLI 暴露为插件工具的适配器喵。

  • 支持任务执行、会话恢复、Web 搜索、快速模式和瞬态错误重试喵。
  • 增加 CODEX_HOME、认证文件、会话持久化及健康检查管理喵。

Confidence Score: 2/5

此 PR 暂不适合合并,因为 Codex 默认以无沙箱权限运行,而且两条超时路径仍可能遗留继续执行的进程喵。

LLM 可触发的 Codex 任务仍默认绕过审批与沙箱;配置缺失或类型错误也会启用该模式,同时内部超时只终止直接子进程,外层 watchdog 取消则没有终止 subprocess 的清理路径喵。

Files Needing Attention: plugin/plugins/codex_adapter/plugin.toml、plugin/plugins/codex_adapter/models.py、plugin/plugins/codex_adapter/executor.py、plugin/plugins/codex_adapter/init.py 喵。

Important Files Changed

Filename Overview
plugin/plugins/codex_adapter/init.py 注册插件生命周期、LLM 工具、重试流程及会话编排喵。
plugin/plugins/codex_adapter/executor.py 构造并运行 Codex CLI 子进程,处理流式输出与执行超时喵。
plugin/plugins/codex_adapter/models.py 定义适配器配置、执行结果和配置解析逻辑喵。
plugin/plugins/codex_adapter/plugin.toml 声明插件元数据及 Codex 的默认运行配置喵。
plugin/plugins/codex_adapter/session.py 提供持久化会话索引、恢复匹配及清理操作喵。
plugin/plugins/codex_adapter/codex_home.py 管理 CODEX_HOME、共享配置和认证文件初始化喵。

Sequence Diagram

sequenceDiagram
  participant L as N.E.K.O LLM
  participant P as Codex Adapter
  participant S as Session Store
  participant C as Codex CLI
  L->>P: codex_execute(prompt, cwd, options)
  P->>S: find resumable thread
  P->>C: codex exec / resume
  C-->>P: JSONL events and thread_id
  P->>S: upsert session state
  P-->>L: final text, usage, session_id
Loading

Reviews (6): Last reviewed commit: "fix(codex_adapter): 改进时区处理逻辑" | Re-trigger Greptile

Comment thread plugin/plugins/codex_adapter/plugin.toml
Comment on lines +343 to +344
proc.kill()
await proc.wait()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Timeout leaves descendants running

When Codex reaches the timeout after spawning a test runner, compiler, shell script, or development server, this branch kills only the direct Codex process because it was not placed in a separate process group, leaving descendants able to modify files, consume resources, or hold ports after the tool reports a timeout喵。

Knowledge Base Used: Plugin System

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

该 PR 新增 codex_adapter 插件,将 OpenAI Codex CLI 封装为 N.E.K.O 可调用的 @llm_tool 工具集,并实现会话持久化、CODEX_HOME 管理、JSONL 输出解析与错误分类/重试逻辑,以支持在主项目中直接触发 Codex 执行开发任务。

Changes:

  • 新增 Codex CLI 子进程执行器与参数构建(支持 --search、fast mode、超时处理等)。
  • 新增 JSONL 事件解析器与数据模型(会话、用量统计、执行结果等)。
  • 新增会话管理与 CODEX_HOME 管理,并提供插件工具入口与默认配置。

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
plugin/plugins/codex_adapter/init.py 插件主类与 @llm_tool 暴露、启动初始化、执行与重试、健康检查/会话管理入口
plugin/plugins/codex_adapter/plugin.toml 插件元信息、SDK 兼容范围与 Codex 适配器默认配置项
plugin/plugins/codex_adapter/executor.py Codex CLI 检测、参数构建、子进程执行与 stdout/stderr 处理
plugin/plugins/codex_adapter/parser.py Codex CLI exec --json JSONL 事件逐行解析与汇总
plugin/plugins/codex_adapter/errors.py Codex CLI 错误模式匹配、分类与重试判定/重试时间提取
plugin/plugins/codex_adapter/session.py 会话记录持久化、可恢复会话判定与提示包签名计算
plugin/plugins/codex_adapter/models.py 配置/会话/用量/执行结果等 dataclass 定义与序列化
plugin/plugins/codex_adapter/codex_home.py CODEX_HOME 解析、seed 初始化、auth.json 写入与环境变量构建
Comments suppressed due to low confidence (1)

plugin/plugins/codex_adapter/codex_home.py:327

  • prepare_managed_codex_home_async() uses asyncio.get_event_loop() inside async code; prefer asyncio.get_running_loop() to avoid deprecation warnings and wrong-loop edge cases.
    return await asyncio.get_event_loop().run_in_executor(
        None,

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +64 to +66
# 绕过审批和沙箱(--dangerously-bypass-approvals-and-sandbox)。
# 仅用于受信任的本地开发场景。
dangerously_bypass_approvals_and_sandbox = true
Comment on lines +189 to +190
effective_codex_home = resolve_effective_codex_home(config.codex_home)
env_overrides = build_codex_home_env(effective_codex_home)
Comment on lines +93 to +95
import asyncio

return await asyncio.get_event_loop().run_in_executor(None, os.path.exists, candidate)
Comment on lines +211 to +215
created_at: float
"""会话首次创建的 monotonic 时间戳。"""

last_used_at: float
"""会话最近一次成功使用的时间戳。"""
Comment on lines +41 to +45
签名基于影响 Codex CLI 上下文构建的"环境"因素:
- instructions 文件路径
- CODEX_HOME 目录
- 默认模型
- 额外标记
"""
assert self._executor is not None and self._session_mgr is not None

effective_cwd = cwd or self._config.cwd or os.getcwd()
Comment on lines +234 to +238
signature = compute_prompt_signature(
instructions_file_path=self._config.instructions_file_path,
codex_home=self._config.codex_home,
model=self._config.model,
)
Comment on lines +481 to +485
except _asyncio.TimeoutError:
try:
proc.kill()
except Exception:
pass
Comment on lines +137 to +139
"sessions_loaded": len(self._session_mgr._sessions)
if self._session_mgr
else 0,

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d1cbcaa90b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +336 to +340
try:
return_code = await asyncio.wait_for(
proc.wait(), timeout=invocation.timeout
)
except asyncio.TimeoutError:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Kill Codex when the tool task is cancelled

When an LLM execution reaches the default 300-second limit, plugin/core/host.py::_run_with_watchdog cancels this coroutine at the same timeout configured by the decorator, slightly before the inner wait_for can raise TimeoutError. Because this block handles only TimeoutError and has no cancellation cleanup, the Codex subprocess and its stdout/stderr reader tasks remain alive and can continue modifying files after the caller receives a timeout. Handle CancelledError in a cleanup/finally path that terminates and awaits the process and reader tasks.

Useful? React with 👍 / 👎.

Comment on lines +193 to +197
invocation = CLIInvocation(
cmd=cmd,
cwd=effective_cwd,
stdin_data=prompt.encode("utf-8"),
timeout=float(config.timeout_sec),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply the configured instructions file

When [codex].instructions_file_path is configured, the adapter never reads that file or prepends its contents: every invocation still sends only prompt as stdin. Consequently users relying on this option for project constraints or task context silently run Codex without those instructions, despite the configuration documentation promising otherwise.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (3)
plugin/plugins/codex_adapter/executor.py (1)

147-160: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

--search 分支重建整个 cmd,重复了 skip_git_repo_check 逻辑喵。

建议先算好前缀再统一拼接,少一份将来容易忘记同步的重复代码:

♻️ 建议写法
-    cmd: list[str] = [exe_path, "exec", "--json"]
-
-    if skip_git_repo_check:
-        cmd.append("--skip-git-repo-check")
-
-    # --search 在 paperclip 中是 unshift 到最前面(在 exec 之前),
-    # 但实际测试中放在 exec 之后也能工作,且更清晰。
-    # 为保持与 paperclip 一致,放在 exec --json 之前。
-    if effective_search:
-        # 移除已添加的 "exec", "--json",重新构建
-        cmd = [exe_path, "--search", "exec", "--json"]
-        if skip_git_repo_check:
-            cmd.append("--skip-git-repo-check")
+    # --search 与 paperclip 一致,放在 exec 之前
+    cmd: list[str] = [exe_path]
+    if effective_search:
+        cmd.append("--search")
+    cmd += ["exec", "--json"]
+    if skip_git_repo_check:
+        cmd.append("--skip-git-repo-check")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugin/plugins/codex_adapter/executor.py` around lines 147 - 160, Update the
command construction around effective_search to avoid rebuilding cmd and
duplicating the skip_git_repo_check handling. Build the optional --search prefix
separately, then assemble it with the existing exec --json arguments and apply
the skip-git-repo-check flag through one shared path.
plugin/plugins/codex_adapter/__init__.py (1)

137-139: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

别伸手掏 SessionManager._sessions 私有属性喵。

第 497-499 行也是同样写法。建议在 SessionManager 上加个 count()(或 __len__)方法对外暴露数量,免得以后改内部存储结构时这里悄悄坏掉。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugin/plugins/codex_adapter/__init__.py` around lines 137 - 139, 避免在 Codex
适配器中直接访问 SessionManager 的私有属性 _sessions;为 SessionManager 增加公开的 count() 或
__len__() 接口,并更新两个 sessions_loaded 计算位置通过该接口获取会话数量,同时保留 SessionManager 为空时返回 0
的行为。
plugin/plugins/codex_adapter/parser.py (1)

234-236: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

把正常事件当解析错误记下来,诊断信息会被淹没喵。

Codex 还会输出 turn.started / item.started 等事件,这些都会被记进 parse_errors;长会话下这个列表会持续膨胀。建议单独用一个 unknown_types 计数集合,并给 parse_errors 设个上限。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugin/plugins/codex_adapter/parser.py` around lines 234 - 236, Update the
unknown-event handling in the parser method containing the _parse_errors append:
do not record recognized Codex events such as turn.started and item.started as
parse errors, track genuinely unknown event types in a separate unknown_types
counter/set, and cap parse_errors at a fixed maximum to prevent unbounded growth
during long sessions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugin/plugins/codex_adapter/__init__.py`:
- Around line 320-344: Update the retry branch in the execution flow around
is_retryable: when exec_err.retry_not_before is present and has not expired,
return ExecuteResult with that timestamp instead of immediately continuing. For
retryable transient_upstream errors, add a short bounded exponential
asyncio.sleep before the next attempt; preserve immediate retry for other
retryable errors without a retry timestamp.
- Around line 476-487: 在版本检查的 _asyncio.TimeoutError 处理分支中更新 proc.kill()
后的清理流程,等待 proc 完成退出并确保 communicate() 创建的管道被回收;保留现有超时后的异常容错行为,避免清理失败覆盖版本检查结果。

In `@plugin/plugins/codex_adapter/codex_home.py`:
- Around line 125-133: Update the credential-file write flow around
target.write_text and chmod so the file is created with restrictive 0600
permissions from the outset, eliminating the world-readable creation window.
Preserve the existing Windows behavior and JSON payload, and avoid relying on a
post-write chmod as the primary protection.

In `@plugin/plugins/codex_adapter/errors.py`:
- Around line 266-273: 更新错误分类逻辑中的 return_code 判断:移除将 return_code == -1 识别为
TIMEOUT 的条件,改为仅匹配超时文本,或仅将明确的 SIGKILL/SIGTERM 返回码(-9、-15)视为超时;保留现有
ClassifiedError 构造及 executor.py 已返回的 TIMEOUT 行为。
- Around line 294-313: Reorder the classification logic so the retry_not_before
check and USAGE_LIMIT ClassifiedError return occur before the
is_transient_upstream_error branch. Keep the existing retry metadata and raw
error fields, then let remaining transient errors continue through the
TRANSIENT_UPSTREAM path so usage-limit errors are classified as "usage_limit".

In `@plugin/plugins/codex_adapter/executor.py`:
- Around line 186-199: 在 executor.py 的 CLIInvocation 构建流程中接入
config.instructions_file_path:读取文件内容并前置到 prompt 后再编码为
stdin_data;读取失败时记录日志并降级使用原始 prompt,避免静默忽略该配置。同步确保 __init__.py 的调用链继续传递该配置。
- Around line 291-320: Update the subprocess stream setup and the
_read_stdout/_read_stderr helpers to tolerate oversized JSONL lines: increase
the create_subprocess_exec StreamReader limit sufficiently for large Codex
events, and wrap each reader loop with outer exception handling that logs
failures without allowing the task to terminate silently. Preserve the existing
per-line parsing behavior and stderr collection.

In `@plugin/plugins/codex_adapter/plugin.toml`:
- Around line 64-66: 收紧 Codex 审批与沙箱绕过的所有默认值:在
plugin/plugins/codex_adapter/plugin.toml:64-66 将
dangerously_bypass_approvals_and_sandbox 设为 false,并补充开启后的风险说明;在
plugin/plugins/codex_adapter/models.py:84-85 将
AdapterConfig.dangerously_bypass_approvals_and_sandbox 默认值及 from_config_dict 中
_bool 的回退值都改为 False,确保配置缺失时仍保持安全。

---

Nitpick comments:
In `@plugin/plugins/codex_adapter/__init__.py`:
- Around line 137-139: 避免在 Codex 适配器中直接访问 SessionManager 的私有属性 _sessions;为
SessionManager 增加公开的 count() 或 __len__() 接口,并更新两个 sessions_loaded
计算位置通过该接口获取会话数量,同时保留 SessionManager 为空时返回 0 的行为。

In `@plugin/plugins/codex_adapter/executor.py`:
- Around line 147-160: Update the command construction around effective_search
to avoid rebuilding cmd and duplicating the skip_git_repo_check handling. Build
the optional --search prefix separately, then assemble it with the existing exec
--json arguments and apply the skip-git-repo-check flag through one shared path.

In `@plugin/plugins/codex_adapter/parser.py`:
- Around line 234-236: Update the unknown-event handling in the parser method
containing the _parse_errors append: do not record recognized Codex events such
as turn.started and item.started as parse errors, track genuinely unknown event
types in a separate unknown_types counter/set, and cap parse_errors at a fixed
maximum to prevent unbounded growth during long sessions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ceb45014-6a39-4be1-9e75-7037c6d58d2f

📥 Commits

Reviewing files that changed from the base of the PR and between 3412ed5 and d1cbcaa.

⛔ Files ignored due to path filters (1)
  • plugin/plugins/codex_adapter/data/store.db is excluded by !**/*.db
📒 Files selected for processing (8)
  • plugin/plugins/codex_adapter/__init__.py
  • plugin/plugins/codex_adapter/codex_home.py
  • plugin/plugins/codex_adapter/errors.py
  • plugin/plugins/codex_adapter/executor.py
  • plugin/plugins/codex_adapter/models.py
  • plugin/plugins/codex_adapter/parser.py
  • plugin/plugins/codex_adapter/plugin.toml
  • plugin/plugins/codex_adapter/session.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • Project-N-E-K-O/N.E.K.O.-PC (manual)

Comment on lines +320 to +344
# 失败 — 记录错误并判断是否重试
last_error = exec_err

# 标记会话错误
if resume_thread_id:
try:
await self._session_mgr.mark_error(
resume_thread_id, exec_err.kind
)
except Exception:
pass

# 不可重试 — 立即返回
if not is_retryable(exec_err.kind):
return ExecuteResult(
session_id=resume_thread_id,
error_kind=exec_err.kind,
error_message=exec_err.message,
retry_not_before=exec_err.retry_not_before,
final_text=stream.final_text,
duration_ms=duration_ms,
)

# 可重试 — 继续下一轮
continue

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

限流/用量超限时立刻重打,等于往上游火上浇油喵。

transient_upstreamusage_limit 都在 RETRYABLE_ERRORS 里,但这里判完 is_retryable 就直接 continue,既没有退避,也完全无视 exec_err.retry_not_before。被 429 时会连着再打 max_retries 次,同时每次都要重新跑一遍 CLI(可能各消耗到 300s 超时)。

建议:retry_not_before 已过期才重试、否则直接返回并把时间告诉调用方;同时对瞬态错误加一个小的指数退避 await asyncio.sleep(...)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugin/plugins/codex_adapter/__init__.py` around lines 320 - 344, Update the
retry branch in the execution flow around is_retryable: when
exec_err.retry_not_before is present and has not expired, return ExecuteResult
with that timestamp instead of immediately continuing. For retryable
transient_upstream errors, add a short bounded exponential asyncio.sleep before
the next attempt; preserve immediate retry for other retryable errors without a
retry timestamp.

Comment thread plugin/plugins/codex_adapter/__init__.py
Comment thread plugin/plugins/codex_adapter/codex_home.py Outdated
Comment thread plugin/plugins/codex_adapter/errors.py Outdated
Comment thread plugin/plugins/codex_adapter/errors.py Outdated
Comment thread plugin/plugins/codex_adapter/executor.py
Comment on lines +291 to +320
async def _read_stderr() -> None:
if proc.stderr is None:
return
while True:
line = await proc.stderr.readline()
if not line:
break
stderr_lines.append(
line.decode("utf-8", errors="replace").rstrip("\r\n")
)

# 读取 stdout 并喂给解析器
async def _read_stdout() -> None:
if proc.stdout is None:
return
while True:
line = await proc.stdout.readline()
if not line:
break
try:
parser.parse_line(line)
except Exception as e:
if self.logger is not None:
try:
self.logger.warning("Failed to parse stdout line: %s", e)
except Exception:
pass

stderr_task = asyncio.create_task(_read_stderr())
stdout_task = asyncio.create_task(_read_stdout())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

asyncio create_subprocess_exec limit StreamReader readline ValueError separator not found

💡 Result:

The error "ValueError: Separator is not found, and chunk exceed the limit" (or the related asyncio.LimitOverrunError) occurs when using asyncio.StreamReader.readline() or readuntil() on a stream that contains a line longer than the configured buffer limit [1][2][3]. The default limit for asyncio streams is 64 KiB [1][4]. This safety mechanism is designed to prevent excessive memory consumption when reading potentially malicious or unexpected data [5]. To resolve or handle this issue, you have several options: 1. Increase the buffer limit: If you know your subprocess will output lines larger than 64 KiB, you can increase the limit argument when creating the subprocess [1][6]. proc = await asyncio.create_subprocess_exec( cmd, stdout=asyncio.subprocess.PIPE, limit=1024 * 1024 # Increase to 1 MiB or more as needed) 2. Manually handle the overrun: If you cannot predict the line length or must handle arbitrarily long data, you can catch the LimitOverrunError (or ValueError in older versions) and consume the remaining data manually [7][3]. The LimitOverrunError object provides an attribute called consumed, which indicates how much data was processed before the limit was reached [7][3]. Example of a manual reading loop: try: line = await proc.stdout.readline except asyncio.LimitOverrunError as e: # Consumed is the amount of data already read that did not contain the separator chunk = await proc.stdout.read(e.consumed) # Process the chunk, or loop until the full line is reconstructed # Note: Use readuntil in a loop to handle large data incrementally [7][2] 3. Avoid line-based reading: If you do not require line-by-line processing, use read() or readexactly() to process the output in fixed-size chunks, bypassing the limitations imposed by readline()'s search for a separator [5]. The limit parameter is explicitly supported by asyncio.create_subprocess_exec and asyncio.create_subprocess_shell to configure the StreamReader buffer size for stdout and stderr [6][8][9].

Citations:


超长 JSONL 行会让 stdout 读取任务直接炸掉喵。

create_subprocess_exec 的 StreamReader 默认 limit 是 64 KiB,readline() 遇到更长的 JSONL 行会抛 ValueError / asyncio.LimitOverrunError。Codex 的 item.completed 事件塞大段 diff 或长回复很容易超过这个值,而异常发生在 readline()(不在 try 内部),_read_stdout 会整体失败,后续事件包括 turn.completed 的 usage 和最终文本都可能丢失,最后被当成“成功但无输出”喵。

🔧 建议:提高 limit 并兜住读取异常
             proc = await asyncio.create_subprocess_exec(
                 *invocation.cmd,
                 cwd=invocation.cwd,
                 env=env,
                 stdin=asyncio.subprocess.PIPE,
                 stdout=asyncio.subprocess.PIPE,
                 stderr=asyncio.subprocess.PIPE,
+                limit=8 * 1024 * 1024,
             )

并在 _read_stdout / _read_stderr 的循环外层包一层 try/except Exception 记日志,避免单行异常终止整个读取喵。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugin/plugins/codex_adapter/executor.py` around lines 291 - 320, Update the
subprocess stream setup and the _read_stdout/_read_stderr helpers to tolerate
oversized JSONL lines: increase the create_subprocess_exec StreamReader limit
sufficiently for large Codex events, and wrap each reader loop with outer
exception handling that logs failures without allowing the task to terminate
silently. Preserve the existing per-line parsing behavior and stderr collection.

Comment thread plugin/plugins/codex_adapter/plugin.toml
Copilot AI review requested due to automatic review settings July 25, 2026 17:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment thread plugin/plugins/codex_adapter/models.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugin/plugins/codex_adapter/__init__.py`:
- Around line 371-377: Update the transient upstream retry backoff calculation
in the exec_err handling branch to use 2 ** (attempt + 1), preserving the
documented 2, 4, 8-second sequence and existing maximum cap.

In `@plugin/plugins/codex_adapter/codex_home.py`:
- Around line 135-144: Update the file-writing logic around the fdopen call to
avoid manually closing fd after the context manager may already have closed it.
Prefer opening the target through ordinary open with UTF-8 encoding, or
otherwise verify fd still belongs to the just-opened file before closing it;
preserve exception propagation and JSON output behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7b1b7a18-1f1d-4fc2-98e1-9d2e9238d5e0

📥 Commits

Reviewing files that changed from the base of the PR and between d1cbcaa and dac2dd8.

📒 Files selected for processing (8)
  • plugin/plugins/codex_adapter/__init__.py
  • plugin/plugins/codex_adapter/codex_home.py
  • plugin/plugins/codex_adapter/errors.py
  • plugin/plugins/codex_adapter/executor.py
  • plugin/plugins/codex_adapter/models.py
  • plugin/plugins/codex_adapter/parser.py
  • plugin/plugins/codex_adapter/plugin.toml
  • plugin/plugins/codex_adapter/session.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • Project-N-E-K-O/N.E.K.O.-PC (manual)
🚧 Files skipped from review as they are similar to previous changes (4)
  • plugin/plugins/codex_adapter/plugin.toml
  • plugin/plugins/codex_adapter/session.py
  • plugin/plugins/codex_adapter/models.py
  • plugin/plugins/codex_adapter/parser.py

Comment thread plugin/plugins/codex_adapter/__init__.py
Comment thread plugin/plugins/codex_adapter/codex_home.py Outdated
Copilot AI review requested due to automatic review settings July 25, 2026 17:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@StarrySerendipity

Copy link
Copy Markdown
Contributor Author

本次修改说明

已推送更新到 feature/codex-adapter 分支(commit 262655eb),修复了 12 个问题。

主要修改

安全修复(2 项)

  1. write_api_key_auth_json 权限窗口期:使用 os.open() 以 0600 权限直接创建文件,避免先创建世界可读文件再 chmod 的安全风险
  2. dangerously_bypass_approvals_and_sandbox 默认值:保持为 true(见下文详细说明)

Bug 修复(7 项)

  • instructions_file_path 配置未生效:现在会读取指令文件内容并前置到 prompt
  • 超时检测逻辑错误:仅将 SIGKILL(-9)/SIGTERM(-15) 视为超时,而非所有 return_code == -1
  • 错误分类顺序错误:USAGE_LIMIT 判断移至 TRANSIENT_UPSTREAM 之前
  • --search 标志构建重复:避免重复添加 skip_git_repo_check 参数
  • 重试缺少退避逻辑:新增 retry_not_before 等待和指数退避(2s, 4s, 8s...)
  • get_event_loop() 弃用警告:改用 get_running_loop()
  • 版本检查超时后进程清理不完整:kill 后等待进程退出

代码质量改进(3 项)

  • 避免访问私有属性:为 SessionManager 添加 __len__() 方法
  • 解析器错误列表无限膨胀:设置上限 100,未知事件类型记录到独立集合
  • 进程清理不完整:版本检查超时后正确等待进程退出

关于 dangerously_bypass_approvals_and_sandbox 的说明

CodeRabbit 建议将默认值从 true 改为 false,但经过深入分析,保持 true 是必要的

原因

  • 本插件通过 @llm_tool 被猫娘调用,stdin 是管道,不是终端
  • 如果设为 false,Codex 在执行敏感操作时会要求用户确认
  • 在非交互式环境中,Codex 会挂起等待用户输入 → 最终超时失败
  • 执行失败会导致 thread_id 无法保存 → 会话连续性断裂

会话连续性机制

  • 会话连续性通过 --resume <thread_id> 实现,与 dangerously_bypass_approvals_and_sandbox 无关
  • 用户说"保持会话"→ 猫娘传 thread_id;用户说"新开会话"→ 猫娘不传 thread_id
  • 这个机制已经正确实现

安全风险

  • Codex 执行任何操作都不会有确认
  • 已在配置注释中明确告知用户安全风险

建议

  • 保持现状(默认 true),因为这是唯一能让插件正常工作的配置
  • 未来如果 Codex CLI 提供细粒度控制(如操作白名单),可以改进

当前仍存在的问题

  1. 安全审批的替代方案缺失:目前 Codex CLI 没有提供细粒度的审批控制 API,只能在"完全跳过"和"完全启用"之间选择。在非交互式场景下,只能选择完全跳过。

  2. 文档需要完善:需要在插件文档中明确告知用户安全风险和使用场景限制。


下一步建议

  • 等待 CodeRabbit 和其他 reviewer 的反馈
  • 如果有关于 dangerously_bypass_approvals_and_sandbox 的更好方案,欢迎讨论

1. 修正退避序列:attempt=0 时 2^(0+1)=2s,确保 2,4,8s 序列
2. 修复 fd 所有权管理:os.fdopen 成功后 fd 由文件对象接管,
   避免 double-close;使用 try/else 结构清晰处理各阶段失败
Copilot AI review requested due to automatic review settings July 25, 2026 17:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai coderabbitai Bot added the Needs Check! need doctor to check label Jul 25, 2026
Comment on lines +350 to +356
return_code = await asyncio.wait_for(
proc.wait(), timeout=invocation.timeout
)
except asyncio.TimeoutError:
# 超时 — 杀死进程
try:
proc.kill()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Watchdog cancellation orphans Codex

When a Codex invocation reaches the 300-second LLM-tool watchdog, the outer timeout cancels executor.execute() before its equal-duration inner timeout completes. Because this branch terminates the process only for asyncio.TimeoutError and does not clean up on cancellation, Codex continues modifying files, using network and compute resources, or holding ports after the caller receives a timeout喵。

Knowledge Base Used: Plugin System

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugin/plugins/codex_adapter/__init__.py`:
- Around line 360-378: 在重试处理逻辑中,先判断当前 attempt 是否已经是最后一次尝试;若是则跳过 retry_not_before
和瞬态错误的退避等待,并直接结束循环以保留原始错误。仅在仍有后续尝试时执行现有的 _compute_retry_wait_seconds、指数退避和
asyncio.sleep 逻辑。
- Around line 67-79: Update _compute_retry_wait_seconds to normalize timezone
awareness before subtracting target_dt and now_dt: use a timezone-aware current
datetime when retry_not_before includes an offset, while preserving
naive-datetime behavior otherwise. Keep the existing nonnegative integer wait
result and fallback to 0 for invalid timestamps.

In `@plugin/plugins/codex_adapter/executor.py`:
- Around line 149-153: 移除 executor.py 中 effective_search 分支对
cmd.append("--search") 的追加逻辑,确保命令始终直接进入 cmd.extend(["exec", "--json"]),避免生成无效的
codex --search exec 参数。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d6beef5b-d85d-43e8-835e-cbcf95c675ac

📥 Commits

Reviewing files that changed from the base of the PR and between dac2dd8 and 2dad377.

📒 Files selected for processing (8)
  • plugin/plugins/codex_adapter/__init__.py
  • plugin/plugins/codex_adapter/codex_home.py
  • plugin/plugins/codex_adapter/errors.py
  • plugin/plugins/codex_adapter/executor.py
  • plugin/plugins/codex_adapter/models.py
  • plugin/plugins/codex_adapter/parser.py
  • plugin/plugins/codex_adapter/plugin.toml
  • plugin/plugins/codex_adapter/session.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • Project-N-E-K-O/N.E.K.O.-PC (manual)
🚧 Files skipped from review as they are similar to previous changes (4)
  • plugin/plugins/codex_adapter/session.py
  • plugin/plugins/codex_adapter/models.py
  • plugin/plugins/codex_adapter/errors.py
  • plugin/plugins/codex_adapter/parser.py

Comment thread plugin/plugins/codex_adapter/__init__.py
Comment thread plugin/plugins/codex_adapter/__init__.py
Comment on lines +149 to +153
# --search 在 paperclip 中是 unshift 到最前面(在 exec 之前)
if effective_search:
cmd.append("--search")

cmd.extend(["exec", "--json"])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/sh
codex --version
codex --search exec --json --help
codex exec --search --json --help

Repository: Project-N-E-K-O/N.E.K.O

Length of output: 3733


🏁 Script executed:

#!/bin/sh
set -e

printf 'Relevant dependency/config references:\n'
rg -n '"codex|codex-cli|codex|CLAUDE_CODE|CODEX|Codex|codex.exe|codex' --glob '!target/**' --glob '!dist/**' --glob '!build/**' .

printf '\nexecutor.py relevant section:\n'
cat -n plugin/plugins/codex_adapter/executor.py | sed -n '1,240p'

Repository: Project-N-E-K-O/N.E.K.O

Length of output: 50379


🏁 Script executed (no clone):

#!/bin/sh
set -e

printf 'Check Codex CLI options for search-related flags:\n'
codex exec --help \
  | awk '
    BEGIN { in_opts=0 }
    /^Options:/ { in_opts=1; next }
    /^Commands:/ { exit }
    in_opts { print }
  ' \
  | grep -iE 'search|web|context|include|prompt|stdin|message|image|model|config' || true

Length of output: 175


🏁 Script executed (no clone):

#!/bin/sh
set -e

printf 'Check whether any codex exec search flag and parser call exist:\n'
codex exec --help \
  | grep -iE 'search|web|context|include|message|stdin|prompt' || true

printf '\nCheck codex local args mapping:\n'
printf 'Repository does not contain codex CLI argument contracts; local `codex exec --search` exits with error.\n'

Length of output: 851


移除无效的 --search 参数喵。

当前环境中 codex exec --search 会报 unexpected argument '--search';这里生成 codex --search exec --json 会让启用搜索的执行路径失败喵。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugin/plugins/codex_adapter/executor.py` around lines 149 - 153, 移除
executor.py 中 effective_search 分支对 cmd.append("--search") 的追加逻辑,确保命令始终直接进入
cmd.extend(["exec", "--json"]),避免生成无效的 codex --search exec 参数。

1. 最后一次尝试失败时跳过退避等待,避免无意义等待
2. _compute_retry_wait_seconds 正确处理时区感知 datetime,
   防止 timezone-aware/naive 混合减法报错

不采纳第 3 条建议(移除 --search append),因为 --search 是
Codex CLI 的合法参数,放在 exec 之前是正确用法。
Copilot AI review requested due to automatic review settings July 25, 2026 17:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@StarrySerendipity

Copy link
Copy Markdown
Contributor Author

修复 CodeRabbit 第三轮反馈

已推送更新到 feature/codex-adapter 分支(commit 5618a36d),修复了 2 个问题。

修复内容

1. 最后一次尝试失败时跳过退避等待

问题:当所有重试都失败时,代码仍会执行退避等待逻辑,导致无意义的等待。

修复:在退避逻辑前检查是否为最后一次尝试,如果是则直接 break 跳出循环。

is_last_attempt = (attempt + 1) >= max_attempts
if is_last_attempt:
    self.logger.info("Last attempt failed, skipping backoff")
    break

2. _compute_retry_wait_seconds 正确处理时区感知 datetime

问题retry_not_before 可能是 timezone-aware 的 ISO 格式字符串,而 datetime.now() 返回 naive datetime,混合减法会报错:

TypeError: can't subtract offset-naive and offset-aware datetimes

修复:检查 target_dt.tzinfo,如果非空则使用 datetime.now(target_dt.tzinfo) 获取 timezone-aware 的当前时间。

target_dt = datetime.fromisoformat(retry_not_before)
if target_dt.tzinfo is not None:
    now_dt = datetime.now(target_dt.tzinfo)
else:
    now_dt = datetime.now()

未采纳的建议

第 3 条建议:移除 executor.py--search 的 append 逻辑。

理由:这是错误建议。--search 是 Codex CLI 的合法参数,放在 exec 之前是正确用法(codex --search exec --json)。移除会导致搜索功能失效。

当前状态

  • ✅ 代码已提交并推送
  • ⏳ 等待 CodeRabbit 下一轮反馈
  • ⏳ 等待人工 review

下一步:如果 CodeRabbit 没有更多建议,可以请求人工 review 并合并。

@coderabbitai coderabbitai Bot removed the Needs Check! need doctor to check label Jul 25, 2026
使用 UTC 统一处理 timezone-aware datetime,避免不同 tzinfo 对象
之间的比较问题。确保 target_dt 和 now_dt 都在同一时区(UTC)下
进行减法运算。
Copilot AI review requested due to automatic review settings July 25, 2026 17:46

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@StarrySerendipity

Copy link
Copy Markdown
Contributor Author

修复 CodeRabbit 第三轮反馈

已推送更新到 feature/codex-adapter 分支(commit bdec7af4),修复了 2 个问题。

修复内容

1. 最后一次尝试失败时跳过退避等待

问题:当所有重试都失败时,代码仍会执行退避等待逻辑,导致无意义的等待。

修复:在退避逻辑前检查是否为最后一次尝试,如果是则直接 break 跳出循环。

is_last_attempt = (attempt + 1) >= max_attempts
if is_last_attempt:
    self.logger.info("Last attempt failed, skipping backoff")
    break

原因:最后一次尝试失败后,循环会自然结束。提前跳出可以避免无意义的等待,让错误更快返回给调用方。

2. _compute_retry_wait_seconds 时区处理改进

问题retry_not_before 可能是 timezone-aware 的 ISO 格式字符串,而 datetime.now() 返回 naive datetime,混合减法会报错:

TypeError: can't subtract offset-naive and offset-aware datetimes

修复:使用 UTC 统一处理 timezone-aware datetime,确保 target_dtnow_dt 都在同一时区下进行减法运算。

if target_dt.tzinfo is not None:
    # target 是 timezone-aware,使用 UTC 的 now
    from datetime import timezone
    now_dt = datetime.now(timezone.utc)
    # 确保 target_dt 也是 UTC
    target_dt = target_dt.astimezone(timezone.utc)
else:
    # target 是 naive datetime,使用 naive 的 now
    now_dt = datetime.now()

原因

  • 使用 datetime.now(timezone.utc) 而不是 datetime.now(target_dt.tzinfo),避免不同 tzinfo 对象之间的比较问题
  • target_dt 转换为 UTC,确保两个 datetime 在同一时区下进行减法运算
  • 保持对 naive datetime 的兼容性

未采纳的建议

第 3 条建议:移除 executor.py--search 的 append 逻辑。

理由:这是错误建议。--search 是 Codex CLI 的合法参数,放在 exec 之前是正确用法(codex --search exec --json)。移除会导致搜索功能失效。

当前状态

  • ✅ 代码已提交并推送
  • ⏳ 等待 CodeRabbit 下一轮反馈
  • ⏳ 等待人工 review

下一步:如果 CodeRabbit 没有更多建议,可以请求人工 review 并合并。

@MingTianSang

Copy link
Copy Markdown
Contributor

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bdec7af49e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

wait_sec,
exec_err.retry_not_before,
)
await asyncio.sleep(wait_sec)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Import asyncio before retry backoff

When Codex returns a retryable usage-limit error with a future retry_not_before (or the transient-upstream branch below) and max_retries > 0, this path executes await asyncio.sleep(...), but this module never imports asyncio. That raises NameError and the public tool returns a generic execution failure instead of performing the advertised automatic retry.

Useful? React with 👍 / 👎.

注意:签名不包含 prompt 本身(prompt 每次都不同)。
"""
parts = [
f"instructions:{instructions_file_path or ''}",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include instruction contents in the resume signature

For installations using instructions_file_path, editing that file in place does not change this signature because only the path string is hashed. The next call in the same cwd will therefore resume a Codex thread that was created under the old instruction package, despite this manager's stated purpose of abandoning old sessions when the prompt package changes; hash the file contents/metadata or otherwise invalidate the session when the instruction file changes.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request Needs Check! need doctor to check

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants