Skip to content

fix(responses): execute code-mode view_image through unified exec - #4475

Merged
lidge-jun merged 3 commits into
devfrom
codex/260913-carry-4455
Sep 13, 2026
Merged

fix(responses): execute code-mode view_image through unified exec#4475
lidge-jun merged 3 commits into
devfrom
codex/260913-carry-4455

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • A routed provider that echoes the nested code-mode helper name emitted view_image instead of the declared exec, and the undeclared-tool guard failed the whole turn with a 502. view_image now joins the helper names the guard admits behind a bare exec declaration.
  • The compat compiler turns that call into await tools.view_image(...) and surfaces the returned image_url through image(), falling back to text() when the host returns no image. It executes the helper rather than acknowledging the call with a text-only stub.
  • The synthetic default.view_image spelling some providers invent is stripped to the bare helper first, matching the existing default. handling for the other helpers.
  • Argument aliases normalize onto Codex's path: an explicit path wins, then file_path, file and image_path in that order. Anything else is passed through as data so nested validation can reject it.
  • Carries fix(responses): execute code-mode view_image through unified exec #4455 by @jeongjin0 together with the overlapping four-file subset in fix(responses): gracefully handle code-mode view_image calls via unified exec #4171 by @rrmlima. Both answer [bug] code-mode exec catalog rejects routed default.view_image as undeclared #4412 and both authors are credited with Co-authored-by trailers on the branch commit.

Closes #4412

Review findings folded in

#4171 carries a CHANGES_REQUESTED review. Its findings are addressed here rather than carried forward:

  • The path executes tools.view_image and returns the image, instead of accepting an undeclared call and emitting only text().
  • Nothing asserts that view_image is universally unavailable in code mode, and no host capability is invented.
  • The composition cases the review named are covered end to end through the real streaming and non-streaming restore paths, not only at the compiler and name guard in isolation: emitted exec payload and tool-call identity, a directly declared view_image, a namespaced view_image, a flat-bridge catalog that declares exec beside a bare exec_command, and malformed arguments.
  • The carry sits on current dev (d0cbfffdd), not the stale merge base the review flagged.

Verification

  • bun test tests/adapters/bridge-legacy-shell-normalization.test.ts tests/responses/legacy-shell-compat.test.ts tests/responses/responses-undeclared-tool-guard.test.ts — 123 pass, 0 fail.
  • bun run typecheck — clean.
  • bun run structure:check — passed. structure/transports/responses.md sits exactly at its 600-line budget on dev, so the paragraph documenting this seam was rewrapped in place to stay net-neutral rather than pushing the doc over.
  • bun run privacy:scan — passed.
  • Full suite runs in hosted CI on the lane tip. This branch is a non-tip link in the lane R carry stack, so its head commit carries [skip ci].

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

The guard question is the security-relevant one here, and it is unchanged in shape: view_image is admitted only when the request catalog declares a bare exec. A namespaced exec declaration still authorizes nothing, and a catalog that declares view_image or a legacy shell bridge name itself is never rewritten.

Summary by CodeRabbit

  • New Features

    • Added support for the view_image tool in code-mode execution.
    • Image results are surfaced directly when available, with text fallback support.
    • Improved compatibility with namespaced tool names and common file-path aliases.
  • Bug Fixes

    • Corrected handling of prefixed helper tools so supported commands route consistently through the declared execution tool.
    • Preserved explicitly provided paths when multiple aliases are present.
  • Documentation

    • Updated code-mode execution guidance for image-tool handling and result formatting.
  • Tests

    • Added coverage for image results, aliases, namespaced tools, invalid input, and streaming and non-streaming execution.

…ip ci]

A routed provider that echoes the nested helper name emitted `view_image`
instead of the declared code-mode `exec`, and the undeclared-tool guard failed
the turn. `view_image` now joins the helper names the guard admits behind a bare
`exec` declaration, and the compiler turns the call into
`await tools.view_image(...)`, surfacing the returned `image_url` through
`image()` and falling back to `text()` when the host returns no image. The
`default.view_image` spelling some providers invent is stripped to the bare
helper first. Explicit `path` wins over the `file_path`, `file` and
`image_path` aliases, in that order.

Carries #4455 by jeongjin0 and the overlapping four-file subset in #4171 by
rrmlima, both answering #4412.

Folds in the review findings recorded on #4171: the compat path executes the
helper rather than emitting a text-only stub, it asserts nothing about
`view_image` being unavailable in code mode, and the composition cases the
review named are covered end to end — a namespaced `view_image` keeps its full
wire name, a flat-bridge catalog that declares `exec` beside a bare
`exec_command` is never rewritten, and malformed arguments still reach nested
validation as data.

Co-authored-by: Jeongjin Shin <80797980+jeongjin0@users.noreply.github.com>
Co-authored-by: rrmlima <137737127+rrmlima@users.noreply.github.com>
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner September 13, 2026 06:56
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 13, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-13T07:00:32.708147Z 9d8e46c PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Sep 13, 2026
@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: adcca950-41bc-42b4-9d67-05ee7465cb15

📥 Commits

Reviewing files that changed from the base of the PR and between af8de10 and 6391609.

📒 Files selected for processing (1)
  • structure/transports/responses.md

Included review availability: Your plan provides up to 10 included reviews per hour; 5 remain after this review.


📝 Walkthrough

Walkthrough

The change adds view_image to code-mode helper normalization. Bare and default.view_image calls compile through declared exec, map path aliases, and return images through image(). Guard tests preserve fail-closed behavior.

Changes

Code-mode view_image compatibility

Layer / File(s) Summary
Helper name normalization and compilation
src/types/tools.ts, src/responses/code-mode-helper-compat.ts
view_image joins the code-mode helper list. default. prefixes are normalized when bare exec is declared. The compiler maps path aliases and emits tools.view_image(...) with image or text output.
Bridge execution and helper behavior tests
tests/responses/legacy-shell-compat.test.ts, tests/adapters/bridge-legacy-shell-normalization.test.ts
Tests cover bare and prefixed calls, alias precedence, explicit path, image and text output, malformed input, and declared top-level view_image.
Undeclared-tool guard and documentation
src/server/responses-undeclared-tool-guard.ts, src/server/responses/core.ts, tests/responses/responses-undeclared-tool-guard.test.ts, structure/transports/responses.md
The guard accepts view_image only through bare code-mode exec, rejects namespaced-only declarations, and covers streaming and non-streaming responses. Comments and documentation describe the updated behavior.

Priority: ⬆️ High

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant RoutedProvider
  participant ResponsesGuard
  participant normalizeDeclaredToolName
  participant compileCodeModeHelperInput
  participant CodeModeExec
  RoutedProvider->>ResponsesGuard: Emit default.view_image
  ResponsesGuard->>normalizeDeclaredToolName: Check declared tool catalog
  normalizeDeclaredToolName-->>ResponsesGuard: Resolve to exec when code mode is declared
  ResponsesGuard->>compileCodeModeHelperInput: Compile view_image arguments
  compileCodeModeHelperInput->>CodeModeExec: Run tools.view_image(...)
  CodeModeExec-->>compileCodeModeHelperInput: Return image_url
  compileCodeModeHelperInput-->>RoutedProvider: Emit image(image_url)
Loading

Possibly related PRs

  • lidge-jun/opencodex#2663: Introduced the helper compilation, bridge routing, and exec normalization paths extended by this change.

Merge Risk: ⚪ Minimal · up to 63916

The routed view_image compatibility paths and guard behavior are covered without a concrete unresolved merge risk.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Most changes support #4412. However, structure/transports/responses.md also changes unrelated documentation for exec-result wording and states that wording is centralized in `src/adapters/exec-tool-… Revert the unrelated exec-result wording documentation change in structure/transports/responses.md. Retain the documentation that describes the #4412 view_image compatibility behavior.
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 7 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: executing code-mode view_image calls through the unified exec tool.
Linked Issues check ✅ Passed Issue #4412 is satisfied. src/types/tools.ts adds view_image to CODE_MODE_HELPER_TOOL_NAMES and maps invented default.view_image to exec only when bare code-mode exec is declared. `src/res…
Full details: Out of Scope Changes check

Explanation

Most changes support #4412. However, structure/transports/responses.md also changes unrelated documentation for exec-result wording and states that wording is centralized in src/adapters/exec-tool-result-normalize.ts. That change does not document or implement routed view_image, default.view_image, helper compilation, alias mapping, image output, or the undeclared-tool guard.

Full details: Docstring Coverage

Explanation

Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 7 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/260913-carry-4455

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.

@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: 9d8e46c257

ℹ️ 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".

Comment thread src/types/tools.ts
Comment on lines +107 to +108
&& declared.has(CODE_MODE_EXEC_TOOL_NAME)
&& (CODE_MODE_HELPER_TOOL_NAMES as readonly string[]).includes(bare)

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 Reject default helpers in flat-bridge catalogs

When the catalog declares exec alongside exec_command or shell_command (the flat-bridge shape), this new branch strips default.apply_patch because apply_patch is in the helper list. The subsequent unconditional candidate === "apply_patch" check then rewrites it to exec before the flat-bridge guard runs, so an undeclared provider call is authorized and converted into JavaScript for an ordinary exec tool. Gate this prefix branch with declaresCodeModeExec, or perform the flat-bridge refusal before the apply_patch rewrite.

Useful? React with 👍 / 👎.

if (helperName === "write_stdin") {
return `const result = await tools.write_stdin(${JSON.stringify(args)});\ntext(result);`;
}
if (helperName === "view_image") {

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 Add the missing co-author trailers

The commit message explicitly says this carries #4455 by @jeongjin0 and part of #4171 by @rrmlima, but the commit contains no Co-authored-by trailers despite claiming that both authors were credited that way. The prose attribution does not register either contributor; add proper trailers to the PR description or a follow-up branch commit so they survive the squash.

AGENTS.md reference: AGENTS.md:L288-L292

Useful? React with 👍 / 👎.

@lidge-jun

Copy link
Copy Markdown
Owner Author

리뷰 · 우선순위 72 / 80

설명
이 PR은 #4455를 tip으로 캐리한다. code-mode에서 선언은 exec인데, routed provider가 중첩 헬퍼 이름 view_image를 그대로 부르면 undeclared-tool guard가 턴을 502로 죽였다. view_imageexec_command/apply_patch와 같은 helper 목록에 넣어, 카탈로그에 bare exec가 있을 때만 exec로 정규화하고 실행한다.

src/types/tools.tsview_imageCODE_MODE_HELPER_TOOL_NAMES에 추가하고, default.view_image처럼 접두가 붙은 헬퍼도 bare로 벗겨 helper 목록이 exec로 쓰게 한다. src/responses/code-mode-helper-compat.tsview_imageawait tools.view_image(...)로 컴파일하고 image_urlimage()로 올린다. file_path/file/image_path 별칭은 path로 모은다. guard·core 주석도 helper 목록에 view_image를 명시한다. 테스트는 bridge legacy-shell, undeclared-tool-guard, legacy-shell-compat에 컴파일·가드·거부 경로를 보강한다.

우선순위 72는 실제 502 사용자 경로를 막고, helper 허용 규칙을 기존 exec 계약 안에 넣으며, tip과 겹침이 적기 때문이다. types/config 분할 캠페인과는 무관하다.

src/types/tools.ts CODE_MODE_HELPER_TOOL_NAMES + normalizeDeclaredToolName - view_image 및 default. 접두 헬퍼를 exec로.

src/responses/code-mode-helper-compat.ts compileCodeModeHelperInput - view_image 컴파일·별칭·image_url surface. helperName은 default. 접두 제거 후 비교.

src/server/responses-undeclared-tool-guard.ts / src/server/responses/core.ts - 주석상 helper 집합에 view_image 포함. bare exec 선언 없이 열리면 안 된다는 기존 안전장치 유지.

심볼 원본 #4455 / #4412(default. 접두) - 캐리가 원본+접두 수정까지 묶었는지 머지 전 한 번 확인.

메인테이너의 판단이 필요한 지점

  • #4455를 이 PR 머지 후 즉시 Landed로 닫을지.
  • MCP가 진짜 view_image를 선언한 경우 helper 정규화가 끼어들지 않는다는 테스트가 충분한지.

너의 추천
가드·컴파일 테스트 초록이면 머지하세요. 이어서 #4455를 닫으세요.

이 댓글은 grok-bot이 작성했습니다

@lidge-jun
lidge-jun merged commit 98dc77e into dev Sep 13, 2026
9 checks passed
lidge-jun added a commit that referenced this pull request Sep 13, 2026
Lane R of the contributor carry train, the serialized responses/core lane: code-mode view_image through unified exec (#4455 by jeongjin0, also carrying the duplicate #4171 by rrmlima), routed effort ladders from models.dev with a refused-rung replay (#4409 by yxr1995-maker), and web-search continuations bound to the serving API key (#4387 by luvs01).

Cross-platform CI run 34746891233 concluded success on 2c28886, the exact head merged here, and it covers every link because the lane is cumulative. #4475 and #4488 carry no ci check of their own; their head commits carry [skip ci] by design, under the owner-authorized tip-only CI economy for this batch.

The fourth planned link, #4086 by Eleven-is-cool, is not here because it is already on dev as d6723f7 with its own Co-authored-by trailer. The lane attempted the carry first and found a modify/delete conflict on structure/04_transports-and-sidecars.md, which the #4276 SSOT restructure had removed; the landed version is a superset of the branch.

All four source authors are credited by Co-authored-by trailers in the landed commits.
@lidge-jun
lidge-jun deleted the codex/260913-carry-4455 branch September 13, 2026 08:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant