codex: Unicode property escapeを含むtool schemaのpatternを除去して502を修正 - #2
Conversation
Claude Code の Artifact ツールは field パラメータの JSON Schema に
`^(?!__.*__$)[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}"\\./[\]]{1,200}$` を持つ。
Responses API のスキーマ検証は `\p{...}` / `\P{...}` を受け付けず、
`Invalid schema for function 'Artifact': ... is not a 'regex'` で
リクエスト全体を弾くため、プロキシは 502 を返してターンが失敗していた。
read_tools は input_schema を無加工で parameters に転送していたので、
ツールスキーマを再帰的に走査してサポート外の pattern だけを落とす。
pattern はモデルが生成する引数への制約でしかなく、削除してもツールは
そのまま使える。lookahead は Responses API に受理されるため温存し、
リテラルのバックスラッシュに続く `p` は property escape と誤認しない。
未修正の 0.1.17-codex.5 と本ビルドに同一リクエストを投げて、前者が
502、後者が正常応答になることを実機で確認済み。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Roy4wexpCM7KiEnkiMDMmv
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4a2699ae75
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
PR #2 のレビュー指摘 (P2) の対応。strip_unsupported_patterns が JSON 値を 無差別に再帰していたため、enum / const / default / examples に置かれた インスタンスデータまでスキーマとして扱っていた。`"enum": [{"pattern": "\p{L}"}]` のように pattern キーを持つオブジェクトが許容値である場合、それを {} へ 書き換えるとツールの許容引数そのものが変わってしまう。 サブスキーマを持つキーワード (properties / patternProperties / items / prefixItems / anyOf / oneOf / allOf / $defs / definitions / dependentSchemas / additionalProperties / propertyNames / contains / if / then / else / not 等) だけを辿り、インスタンスデータには立ち入らない。items は 2020-12 の単一 スキーマと draft-07 のタプルの両方を扱う。additionalProperties: false の ような非スキーマ値は object でないため素通りする。 実機確認: Artifact の実スキーマは本ビルドでも従来どおり通る。enum に オブジェクトを含むスキーマは修正前の codex.5 でも同じく Responses API に 拒否されるため、本変更による差異ではない (codex.5 は enum 内の pattern を 消していたが、それでも拒否されており改変は副作用でしかなかった)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Roy4wexpCM7KiEnkiMDMmv
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f661341fb2
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
PR #2 のレビュー指摘 (P2) の対応。`"dependencies": {"foo": {"properties": {"bar": {"pattern": "\p{L}"}}}}` のような draft-07 の schema dependency を 走査していなかったため、そこに置かれたサポート外の pattern がそのまま 上流へ渡り、同じ 502 を引き起こしうる状態だった。tuple 形式の items を 明示的に扱っている以上、同じ draft-07 の dependencies も揃えるべき。 SUBSCHEMA_MAP_KEYS に dependencies を追加する。property dependency は 名前の配列であってオブジェクトではないため、strip_unsupported_patterns が そのまま素通りする(特別扱い不要)。 テストに schema dependency と property dependency の両方を追加した。 dependencies を外すと当該テストが落ちることを確認済み。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Roy4wexpCM7KiEnkiMDMmv
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e070699275
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
PR #2 のレビュー指摘 (P2 2件) の対応。 contentSchema: 2019-09/2020-12 のキーワードで、JSON を含む文字列の中身を 記述するサブスキーマを持つ。unevaluatedProperties や prefixItems を既に 扱っている以上ここも揃える必要があり、走査対象に追加する。 patternProperties: マップのキー自体が正規表現であり、キーに \p{...} が 入っていると値をいくらサニタイズしても同じ is not a 'regex' で弾かれる。 サポート外のキーを持つエントリはキーごと削除する。上流に渡せない制約で ある以上、残してもリクエスト全体を失うだけのため。サポート済みのキーは 残し、その値は従来どおり再帰する。 テストを追加し、それぞれの対応を外すと当該テストが落ちることを確認済み。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Roy4wexpCM7KiEnkiMDMmv
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 526b531017
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
PR #2 のレビュー指摘 (P2) の対応。前段の実装はサポート外のキーを持つ エントリを丸ごと削除していたが、additionalProperties: false と併用されて いる場合、そのエントリは当該の動的プロパティを許可し記述する唯一の サブスキーマである。削除するとかつてマッチしていたキーがすべて拒否され、 そのキーが必須なら充足不能なスキーマになり、502 は避けられてもツール コールを生成できなくなる。 キーごと削除するのをやめ、Responses API が受理する ^.*$ へ値スキーマを 移す。置換後のキーは元より広くマッチするが、それは上流が元から強制でき なかった制約を緩めるだけである。^.*$ が既に存在する場合はそれが全キーを 覆うため、既存のサブスキーマをそのまま残す。 テストを再キー方式に更新し、既存 ^.*$ との衝突ケースも追加した。退避を 外すと当該テストが落ちることを確認済み。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Roy4wexpCM7KiEnkiMDMmv
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a22b9fa1fa
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
PR #2 のレビュー指摘 (P2) の対応。キーを ^.*$ へ退避する前段の実装は、 兄弟エントリと重なったときに壊れる。^\p{L}+$ が string を、^[0-9]+$ が number を要求している状況で前者を ^.*$ にすると、数値キーが両方に マッチして充足不能になる。未サポートのエントリが複数ある場合に最初の 値スキーマしか残らない実装上の欠陥もあった。 削除・再キーのどちらもスキーマの意味を保てないため、キーには手を加えず そのまま転送する方針に戻す。未サポートなキーを持つスキーマは上流で 拒否されるが、リクエストが正しく失敗するのは黙って歪んだスキーマを 送るより健全である。値のサブスキーマは従来どおりサニタイズする。 判断の経緯を strip_unsupported_patterns の doc コメントに残し、キーが 素通りすることを固定するテストに差し替えた。contentSchema・dependencies・ instance data の保護は影響を受けない。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Roy4wexpCM7KiEnkiMDMmv
|
@codex review |
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
* codex: Unicode property escapeを含むtool schemaのpatternを除去して502を修正 fork の d655f4c (#2) を upstream v0.1.37 へ移植。 Claude Code の Artifact ツールは field パラメータの JSON Schema に `^(?!__.*__$)[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}"\\./[\]]{1,200}$` を持つ。 Responses API のスキーマ検証は `\p{...}` / `\P{...}` を受け付けず、 `Invalid schema for function 'Artifact': ... is not a 'regex'` で リクエスト全体を弾くため、プロキシは 502 を返してターンが失敗する (upstream issue raine#141 と同じ事象)。 read_tools は input_schema を無加工で parameters に転送していたので、 ツールスキーマのサブスキーマ位置だけを再帰的に走査してサポート外の pattern を落とす。enum / const / default / examples はインスタンス データを持ち、そこでの pattern キーは制約ではなく許容値そのものなので 立ち入らない。patternProperties のキーは正規表現だが、削除も再キーも スキーマの意味を保てないためそのまま転送する。 バージョンを 0.1.37-codex.1 とする。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Roy4wexpCM7KiEnkiMDMmv * codex: auth をプロセス内キャッシュし上流の並行数を制限する fork の c2eefec を upstream v0.1.37 へ移植。 get_auth() は上流リクエストのたびに /usr/bin/security を起動して macOS Keychain を読んでいたため、並行リクエストが集中すると1リクエストにつき 1子プロセスが生まれ、プロセスのファイルディスクリプタ上限を使い切って (EMFILE) 偽の 401 で認証が失敗し、リスナーごと落ちることがあった。短い TTL のメモリキャッシュを置き、並行バーストを 1 回の keychain 読み取りに 畳み込む。自前のトークン更新時は write-through するため、更新直後の値は TTL に関係なく即座に見える。 あわせて CCP_CODEX_MAX_CONCURRENT (既定 8) を追加し、開始中の上流 リクエスト数を制限する。ChatGPT はサブスクリプションの過剰な並行接続を WebSocket ハンドシェイクの 401 で拒否するため、多数の並列エージェントが 共有プロキシに集中すると踏む。 upstream 側への適応: - refresh_lock はプロセス全体で共有する CODEX_REFRESH_LOCK を使う upstream の実装をそのまま残し、キャッシュ用フィールドのみ追加した。 - 並行数の permit は handle_messages から handle_messages_inner へ移した。 upstream が会話 identity 対応で本体をこちらへ集約したため。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Roy4wexpCM7KiEnkiMDMmv * chore: fork 向けに release ワークフローを調整する fork の 639123f のうち CI 部分を upstream v0.1.37 へ移植。 release ジョブを既定の GITHUB_TOKEN (top-level の contents: write) に 向ける。upstream の RELEASE_TOKEN シークレットは fork には無い。 homebrew-tap 更新ジョブを削除する。raine の tap を更新するもので、この fork には関係しない。 バージョンの引き上げは移植済みのため、この移植では CI 部分のみ扱う。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Roy4wexpCM7KiEnkiMDMmv * codex: permitをストリームタスクへ渡しauth読み取りを直列化する PR #3 のレビュー指摘 (P1/P2) の対応。どちらも fork が v0.1.17 の時点から 抱えていた既存の欠陥で、移植で新たに作ったものではない。 P1: 並行数の permit をストリームタスクが保持する ストリーミングでは live_stream_response が最初の意味のある出力で復帰し、 remaining_live_stream_response がまだ生きている上流接続を spawn した タスクへ移す。permit をハンドラのスコープに置いていたため最初のチャンク で解放され、CCP_CODEX_MAX_CONCURRENT を超える長時間ストリームが接続を 維持できてしまい、この limiter が防ぐはずの並行由来 401 を後続の ハンドシェイクが踏みうる状態だった。 permit を live_stream_response → live_stream_response_once → remaining_live_stream_response へ渡し、spawn したタスクへ move する。 リトライは permit を使い回すため、実際にストリームが始まったときだけ 消費する。 P2: キャッシュミス時の読み取りを直列化する cold または期限切れのキャッシュでは、並行リクエストが揃って cache_get() の None を観測してから誰も cache_store() に到達しておらず、各呼び出しが 独立に永続ストアを読んで macOS では /usr/bin/security を起動していた。 十分な規模のバーストでは、このキャッシュが防ぐはずの FD 枯渇を再現する。 ミス経路を single-flight ロックで保護し、ロック取得後にキャッシュを再確認 する。ロックはブロッキングなストア読み取りの周りだけで保持し、await を 跨がない。 いずれもテストを追加し、修正を外すと落ちることを確認済み。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Roy4wexpCM7KiEnkiMDMmv * codex: compaction より前に並行数の permit を取得する PR #3 のレビュー指摘 (P2) の対応。 CCP_CODEX_SERVER_COMPACTION=true で compact-boundary リクエストが来ると、 request_compaction が permit 取得より前に post_codex_for_owner を呼んで いた。全 permit が埋まっている状況でも compaction リクエストが上限の外で 開始でき、CCP_CODEX_MAX_CONCURRENT + 1 本の接続が成立して、この limiter が防ぐはずの並行由来の失敗を再現しうる状態だった。 permit の取得を compaction 分岐より前へ移し、以降の生成まで保持する。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Roy4wexpCM7KiEnkiMDMmv --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
問題
claude-codex 経由のセッションが
502で落ちる。エラー実体は~/.local/state/claude-code-proxy/errors/に記録されていた:これは Claude Code の
Artifactツールのfieldパラメータ(write_dbのstr_replace用)のpatternそのもの。ツール定義に載っているだけでリクエスト全体が弾かれるため、そのターンは必ず失敗する。原因
read_toolsが Anthropic のinput_schemaを無加工で Responses API のparametersに転送していた(Readツールの description 補強を除く)。Responses API はツールスキーマのpatternを検証し、Unicode property escape (\p{...}/\P{...}) を含むものをis not a 'regex'で拒否する。稼働中の proxy に最小ツール定義を投げて切り分けた結果:
^[a-z]{1,10}$^(?!__).{1,10}$(lookahead のみ)^[^\p{Cc}]{1,10}$^\P{Cc}{1,10}$itemsにネストした\p{}patternキー自体を削除犯人は lookahead ではなく
\p{...}/\P{...}のみ。ネストしていても弾かれる。変更
ツールスキーマを再帰的に走査し、Unicode property escape を含む
patternだけを落とす。patternはモデルが生成する引数への制約でしかないので、削除してもツールはそのまま使える。ターンごと失う方が損失が大きい。pattern(lookahead を含む)は温存する。p(\\p{L})は property escape と誤認しない。検証
cargo test --lib providers::codex::translate::request— 33 passeditems内の pattern が除去され、^[0-9a-f]{32}$と lookahead 付き pattern は保持されること/リテラルバックスラッシュの判定end_turnで正常応答cargo fmt --check/cargo clippy— 本 PR で触ったrequest.rsに指摘なし(kimi/translate/accumulate.rsの fmt とcursor/sse.rs等の clippy 指摘はベースブランチ由来で本 PR の対象外)マージ後に必要な作業
v0.1.17-codex.6タグを打ってリリースinstall.sh:12とbin/claude-codex-doctor:202のv0.1.17-codex.5)補足(本 PR の対象外)
read_output_formatのjson_schema経路(text.format.schema)も同じ無加工転送で、strict: trueで送られる。同種の欠陥を持つ可能性はあるが、今回は再現・検証できていないためスコープ外とした。🤖 Generated with Claude Code
https://claude.ai/code/session_01Roy4wexpCM7KiEnkiMDMmv