TanStack / TanStack/ai

OpenAI ProviderTools that require user-execution (e.g. apply_patch, shell) are silently dropped / do not work.

Open
#495 0 comments 0 reactions 1 assignee View on GitHub

@tombeckenham is already working on this.

Since Sep 17, 2026.

waiting-on: maintainer
Dominant language
TypeScript
Stars
3.1k
Forks
331
Avg merge
1d 22h
Merged PRs (30d)
160

Description

TanStack AI version

0.13.0

Framework/Library version

n/a

Describe the bug and the steps to reproduce it

The OpenAI tools shell and apply_patch and are only semi provider tools: OpenAI providers the tool definition, they train the model to use these tools properly - but they're only sometimes run on their servers.

For example, shell supports a local shell mode: { "type": "shell", "environment": { "type": "local" } }]

apply_patch is even more local - it always is supposed to be processed by the API user, not the LLM provider. Calling it a provider-tool is perhaps even a stretch.

Either way, these tool calls are expected to be handled by the user. From OpenAI's docs:

  1. Call the Responses API with the apply_patch tool
    • Provide the model with context about available files (or a summary) in your input, or give the model tools for exploring your file system.
    • Enable the tool with tools=[{"type": "apply_patch"}].
  2. Let the model return one or more patch operations
    • The Response output includes one or more apply_patch_call objects.
    • Each call describes a single file operation: create, update, or delete.
  3. Apply patches in your environment
    • Run a patch harness or script that:
    • Interprets the operation diff for each apply_patch_call.
    • Applies the patch to your working directory or repo.
    • Records whether each patch succeeded and any logs or error messages.
  4. Report patch results back to the model
    • Call the Responses API again, either with previous_response_id or by passing back your conversation items into input.
    • Include an apply_patch_call_output event for each call_id, with a status and optional output string.
    • Keep tools=[{"type": "apply_patch"}] so the model can continue editing if needed.

This workflow is currently straight-up impossible with tanstack/ai. Because y'all drop the chunks here: https://github.com/TanStack/ai/blob/main/packages/typescript/ai-openai/src/adapters/text.ts#L307

The chunks (e.g. response.shell_call_command.delta) are just simply never handled.

In general, this function is a bit dangerous in my opinion - it silently drops all unkown chunks, which, you know, can contain important information.

The relevant parts I observed are:

chunk type response.output_item.added
chunk type response.shell_call_command.added
chunk type response.shell_call_command.delta
chunk type response.shell_call_command.delta
chunk type response.shell_call_command.delta
chunk type response.shell_call_command.delta
chunk type response.shell_call_command.delta
chunk type response.shell_call_command.delta
chunk type response.shell_call_command.delta
chunk type response.shell_call_command.delta
chunk type response.shell_call_command.delta
chunk type response.shell_call_command.done
chunk type response.output_item.done

There's no good way at all to recover the chunks (as far as I can tell), and no mechanism to reply with a good output.

In addition, the shell tool clearly should take parameters, but doesn't.

I'm not sure how to best solve this issue myself, because it does touch a couple parts (how'd it be saved in the message history? Would this just be a special tool call? Lots of architecture decisions I'm not comfortable making as a first-time contributor).

But yeah, in the end, e.g. for apply_diff the chunk needs to be surfaced to the user. And there needs to be a way to reply.

Otherwise, ai-sdk is super interesting, and tanstack start is quite nice! But this makes it unfortunately impossible to use for my usecase.

Your Minimal, Reproducible Example - (Sandbox Highly Recommended)

sowwy for not putting it on StackBlitz or sth, but i'm on a train and internet is dire. bun run file.ts should be enough to repro. debug: true surfaces some of the chunks, I think, but I surfaced them by editing node_modules/@tanstack/ai-openai/dist/esm/adapters/text.js - as one does.

import { shellTool } from "@tanstack/ai-openai/tools";
import { chat } from "@tanstack/ai";
import { openaiText } from "@tanstack/ai-openai";

const stream = chat({
  adapter: openaiText("gpt-5.1-codex"),
  tools: [shellTool()],
  messages: [
    {
      role: "user",
      content: "Can you print a simple hello world?",
    },
  ],
  systemPrompts: ["Do what the user tells you to."],
  modelOptions: {
    tool_choice: "required",
    include: ["reasoning.encrypted_content"],
    reasoning: {
      effort: "medium",
      summary: "detailed",
    },
  },
  stream: false,
});

// Observe - nothing is happening.
console.log(await stream);
Do you intend to try to help solve this bug with your own PR?

None

Terms & Code of Conduct
  • I agree to follow this project's Code of Conduct
  • I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.