fix(cursor): explain empty exec results + forbid native probing in code mode - #2662
fix(cursor): explain empty exec results + forbid native probing in code mode#2662lidge-jun wants to merge 1 commit into
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review (2)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 65e8fe0e8a
ℹ️ 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".
| if (isCodexExecBridgeTool(options.toolName, options.toolNamespace) && EMPTY_EXEC_OUTPUT_REGEX.test(text.trim())) { | ||
| return { | ||
| text: "[empty output: the exec cell completed but emitted nothing. This is NOT lost context and NOT a blocked tool — in code mode call text(...) or notify(...) on any value you need to see (a bare await tools.exec_command(...) is not echoed automatically); in shell mode the command simply printed nothing. Do not re-run the same call expecting different output.]", | ||
| isError: false, |
There was a problem hiding this comment.
Preserve existing errors when annotating empty exec results
When an exec or shell-bridge result arrives with isError: true and an empty payload—or even the explicitly matched Script failed wrapper—this branch overwrites the flag with false. The Cursor wire result therefore reports a failed command as successful and tells the model not to retry, potentially allowing work to continue from a command that never completed; preserve the incoming isError value or apply the non-error annotation only when it is already false.
AGENTS.md reference: src/AGENTS.md:L19-L19
Useful? React with 👍 / 👎.
| * re-orientation retries (devlog 260826_cursor_responses_gap, live subagent transcripts). | ||
| */ | ||
| function isCodexExecBridgeTool(toolName?: string, toolNamespace?: string): boolean { | ||
| if (toolNamespace && toolNamespace.includes("opencodex-responses")) return true; |
There was a problem hiding this comment.
Match only exec aliases under the Responses namespace
When any unrelated Responses-owned tool returns empty output, this namespace check classifies it as an exec bridge before inspecting its name. For example, wait with namespace opencodex-responses is recognized by isCursorWaitTool, while display aliases such as mcp_opencodex-responses_apply_patch share the same generic prefix; both now receive misleading exec-cell guidance rather than retaining their actual result semantics. Require the normalized tool name to be exactly exec, exec_command, or shell_command instead of accepting the provider namespace or every prefixed tool.
AGENTS.md reference: src/AGENTS.md:L19-L19
Useful? React with 👍 / 👎.
|
✅ Deterministic PR hygiene checks passed. |
리뷰 · 우선순위 56 / 80설명 이 풀 리퀘스트는 코드 모드 exec가 text(...)나 notify(...)를 부르지 않아 결과가 비어 있을 때, 모델이 이전 결과가 사라졌거나 도구가 막혔다고 착각하지 않게 설명을 넣습니다. 지금 dev의 src/adapters/cursor/tool-result-normalize.ts 70-91줄 normalizeCursorToolResultText는 Computer Use와 node_repl 이름에만 빈 출력을 고칩니다. 52-53줄 EMPTY_EXEC_OUTPUT_REGEX는 진짜 빈 문자열뿐 아니라 Script completed와 Output: 래퍼도 빈 출력으로 봅니다. Codex exec/shell 브리지는 그 정규식을 타도 설명이 없어서, 빈 [tool_result]가 그대로 모델에 갑니다. 고침은 isCodexExecBridgeTool을 더합니다. exec, exec_command, shell_command, mcp_opencodex-responses_ 접두사, 네임스페이스에 opencodex-responses가 있으면 같은 길로 갑니다. 빈 출력이면 isError는 false로 두고, 사라진 맥락이 아니며 text(...)를 쓰라는 글을 넣습니다. Computer Use 빈 출력은 여전히 isError true입니다. 테스트가 그 차이를 고정합니다. 비어 있지 않은 exec 출력은 바이트 그대로 통과합니다. 두 번째 변경은 안내문입니다. src/adapters/cursor/tool-definitions.ts 656-658줄 코드 모드 안내에, 네이티브 Shell/Read를 탐색하지 말라는 문장을 붙입니다. 지금 665-667줄의 Prefer the Codex shell bridge 문장은 hasBareExec일 때만 타고, 코드 모드만 있는 턴은 그 금지를 못 봅니다. 코드 모드 쪽에 같은 금지를 옮기는 것은 맞습니다. 다만 문장이 길어지고, NEVER와 FIRST attempt가 모델마다 다르게 읽힐 수 있습니다. 이 PR은 베이스가 #2656입니다. 현재 dev(7181ebd) 위에 혼자 합칠 수 없습니다. 네임스페이스 검사는 includes("opencodex-responses")라서, 비슷한 글자가 들어간 다른 네임스페이스도 빈 출력을 설명 글로 바꿀 수 있습니다. 또한 빈 출력을 설명으로 바꾸면, 정말로 실패한 침묵 오류를 성공처럼 읽게 할 수 있습니다. isError false가 그 지점입니다. src/adapters/cursor/tool-result-normalize.ts:76 - 빈 출력 다시 쓰기가 Computer Use 이름에만 걸려 Codex exec가 빈 [tool_result]를 남깁니다. 메인테이너의 판단이 필요한 지점
너의 추천 #2650-#2656 스택이 먼저 들어간 뒤에 이 PR을 합치세요. 지금 dev에 직접 합치지 마세요. 합치기 전에는 네임스페이스 검사를 더 좁히고, 빈 출력이 진짜 실패일 때의 메시지를 한 줄로 구분해 두세요. 미리보기 배포는 계획에 없습니다. 이 댓글은 grok-bot이 작성했습니다 |
65e8fe0 to
f3624c2
Compare
611b2cb to
6dce24e
Compare
6dce24e to
f3bd8b3
Compare
f3624c2 to
ddecc67
Compare
Summary
text(...)/notify(...)legitimately returns empty output, andnormalizeCursorToolResultTextonly rewrote empties for Computer-Use/node_repl tool names — the Codex exec/shell bridge got a blank[tool_result]. Now bridge-tool empties (flat +mcp_opencodex-responses_*display aliases) are rewritten into an explanatory non-error message telling the model the result is not lost and how to surface values.Stacked on #2656 (codex/cursor-gap-6).
Verification
bun test tests/cursor-exec-empty-result.test.ts— 6 pass (bridge empties across all alias shapes, non-empty passthrough, computer-use semantics preserved, unrelated tools untouched).bun test tests/cursor-tool-definitions.test.ts tests/cursor-blob.test.ts tests/cursor-request-builder.test.ts— 156 pass 0 fail.bun x tsc --noEmit— clean.Checklist