Repository navigation
fix(openai-base): pass the streamed apply_patch diff to the app - #1948
peter-daptic wants to merge 1 commit into
Conversation
🦋 Changeset detectedLatest commit: fbfbec7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
User-run call lifecycle and unit coverage packages/openai-base/src/adapters/responses-text.ts, packages/openai-base/tests/responses-text.test.ts, .changeset/openai-streamed-apply-patch-diff.md |
userToolChunks emits TOOL_CALL_START once and waits until the item is no longer in progress to emit TOOL_CALL_END with its input. A streaming test checks that the end event contains the completed diff. The changeset records a patch release. |
End-to-end streamed diff validation testing/e2e/src/routes/api.openai-apply-patch-wire.ts, testing/e2e/src/routeTree.gen.ts, testing/e2e/tests/openai-apply-patch-wire.spec.ts |
A test route streams an apply_patch_call with diff events, runs the tool executor, and returns recorded inputs. The route tree registers the endpoint, and a Playwright test checks the resulting file-update operation. |
Priority:
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Bug fix · Severity of issue fixed: Medium
Suggested reviewers: alemtuzlak, tombeckenham
Merge Risk: 
Minimal · up to fbfbe
-
No actionable issue was established with the streamed diff change; it is ready for normal merge checks.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passed-
Full details: Title check
-
Explanation
The title "fix(openai-base): pass the streamed apply_patch diff to the app" describes the main change. The changeset updates userToolChunks in packages/openai-base so that user-run apply_patch_call items emit TOOL_CALL_START when added and TOOL_CALL_END with the complete diff once the item is no longer in_progress. The title is specific, uses the conventional commit form, and matches the core fix. It is 63 characters, within a reasonable length.
Full details: Description check
-
Explanation
The description follows the template well. It has a Changes section that names the modified function, the test files, the E2E route and spec, and the changeset. The checklist is filled in. The Release Impact section is marked. It also adds a root cause analysis, alternatives considered, detailed test commands and results, a manual test procedure, linked issue
#1947, and a risk and rollback note. The author explains why no docs change was needed. Minor gap: the template's checklist asks the author to state whether docs were updated, and the author checked the box while also stating no docs change was made, which is slightly inconsistent but still clear.
Full details: Linked Issues check
-
Explanation
Issue
#1947requires streamed Responses API user-run calls to reach the app with complete input. The adapter now emitsTOOL_CALL_STARTonce and delaysTOOL_CALL_ENDwhile the item status isin_progress. It sends the completed input when the item status changes. The unit test replays the streamedapply_patch_callsequence and verifies the full diff. The implementation applies to the user-run call types listed in the issue.
Full details: Out of Scope Changes check
-
Explanation
The changes stay within issue
#1947. The adapter change implements the required call lifecycle. The unit test, E2E route, E2E spec, generated route registration, and changeset test or release this fix. No unrelated change is demonstrated.
-
Full details: Docstring Coverage
-
Explanation
Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 1 functions across 5 files.
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
-
Finishing Touches
-
🧪 Generate unit tests (beta)
-
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
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 @coderabbitai help to get the list of available commands.
2dcc38d to
c6d5ed5
Compare
The Responses API adds an apply_patch_call with status "in_progress" and an empty diff, and streams the diff in before the item is done. User-run calls were started and ended at output_item.added, so the complete item at output_item.done was skipped and execute always got diff "". Start a user-run call when its item is added, and end it with its input once the item is no longer in progress, as function calls already do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
e60a714 to
fbfbec7
Compare
|
Thanks for the PR, @peter-daptic! 🙌 @tombeckenham will take a look. Automated pre-review checks
Automated triage — a human review follows. |
A streamed
apply_patchcall reached the app withdiff: "", soexecutenever got the patch. This PR starts a user-run call when its item is added, and ends it with its input when the item is no longerin_progress. Function calls already work this way.🎯 Changes
userToolChunksinpackages/openai-base/src/adapters/responses-text.tsemitsTOOL_CALL_STARTonce, when it first sees the call. It emitsTOOL_CALL_ENDwith the input only when the itemstatusis notin_progress.packages/openai-base/tests/responses-text.test.tsstreams the real event sequence:output_item.addedwith an empty diff, the diff deltas, thenoutput_item.donewith the full diff.openai-apply-patch-wire) send the same sequence throughchat()and check the input thatexecutegets.@tanstack/openai-base.No docs change: the fix restores the documented behavior.
✅ Checklist
pnpm run test:pr, or these tests do not apply to this pull request.docs/for this change, or this change is not user-facing.pnpm changeset), or this PR does not change a published package.🚀 Release Impact
Root cause
Issue. An app that runs
applyPatchTool()withchat()on the Responses API getsoperation.diff === ""for every streamed patch. An agent loop then sends empty patches until it hits its iteration limit.Cause. The API adds an
apply_patch_callwithstatus: "in_progress"and an empty diff, then streams the diff.processStreamChunkscallsuserToolChunksatresponse.output_item.added.userToolChunksemitsTOOL_CALL_STARTandTOOL_CALL_ENDwith the empty diff and marks the callended. Atoutput_item.doneand in theresponse.completedfallback, theendedcheck skips the complete item.Fix.
userToolChunksnow reads the itemstatus. While the item isin_progress, it emits onlyTOOL_CALL_START. When the item is done, it emitsTOOL_CALL_ENDwith the complete input and marks the callended.Possible alternatives
userToolChunkscall atoutput_item.added. It is a one-line fix, becauseoutput_item.doneandresponse.completedalready emit the full call. This PR did not take it because thestatuscheck states the rule directly and matches how function calls work.apply_patch_callwith an empty diff. It fixes this tool only. The shell tools are safe today only because their command list is empty when the item is added. Astatuscheck does not depend on that.Testing
Commands run
vitest run tests/responses-text.test.ts -t "apply_patch"inpackages/openai-base. The new test fails onmainand passes on this branch.vitest runinpackages/openai-base: 33 files, 404 tests pass.playwright test tests/openai-apply-patch-wire.spec.tsagainst the e2e dev server. It fails onmainand passes on this branch.playwright testforopenai-computer-use-wire,openai-shell-skills-wire,computer-useandanthropic-computer-use-wire. All 12 pass on this branch.oxfmt --checkon the changed files,oxlinton the changed files, andtscforopenai-baseandtesting/e2e. All pass.pnpm test:pron Node 24.8.0 and pnpm 11.9.0. It passes: all targets for 30 affected projects, andtest:dts.@tanstack/openai-basehas 404 tests and@tanstack/ai-openaihas 431 tests, and all pass.Not run: the full E2E matrix.
Unit test on
main:Unit test on this branch:
E2E on
main:E2E on this branch:
Manual test
main, runpnpm --filter @tanstack/ai-e2e test:e2e -- tests/openai-apply-patch-wire.spec.ts. It fails: the tool getsdiff: "".How this PR makes testing easy
The unit test and the E2E spec replay the real stream, so a reviewer needs no API key.
Linked issues
Fixes #1947
Risk / rollback
Low risk. For a user-run call,
TOOL_CALL_ENDnow comes atoutput_item.done, not atoutput_item.added. An item with nostatus, or with any status other thanin_progress, ends at once, as before. To undo, revert this PR.🤖 Generated with Claude Code
Summary by CodeRabbit