Skip to content
Files SDK
Esc
↑↓navigate↵open⌘Jpreview
On this page

OpenAI

Factories for the OpenAI Responses API and the OpenAI Agents SDK - same eight operations, Zod-validated, approval-gated by default.

The files-sdk/openai subpath ships two factories targeting OpenAI directly - one for the native Responses API and one for the OpenAI Agents SDK (@openai/agents). Both wrap the same eight file operations as the Vercel subpath, with the same approval-gating defaults.

openai and @openai/agents are optional peer dependencies - install only the one(s) you use. The subpath requires Zod 4: @openai/agents peer-requires it, and Zod 4’s built-in toJSONSchema powers the Responses tool definitions.

Responses API

createResponsesFileTools returns { definitions, execute, needsApproval }. Pass definitions straight to openai.responses.create({ tools }), then call execute(call) on each function_call item in the response output to get a function_call_output ready to push into the next turn’s input.

npm install openai zod
pnpm add openai zod
yarn add openai zod
bun add openai zod
nub add openai zod
aube add openai zod
import OpenAI from "openai";
import { Files } from "files-sdk";
import { s3 } from "files-sdk/s3";
import { createResponsesFileTools } from "files-sdk/openai";

const client = new OpenAI();
const files = new Files({ adapter: s3({ bucket: "uploads" }) });
const ft = createResponsesFileTools({ files });

const input: any[] = [{ role: "user", content: "List my files." }];
while (true) {
  const res = await client.responses.create({
    model: "gpt-4.1",
    input,
    tools: ft.definitions,
  });

  const calls = res.output.filter((o) => o.type === "function_call");
  if (calls.length === 0) {
    console.log(res.output_text);
    break;
  }

  for (const call of calls) {
    let approved = false;
    if (ft.needsApproval(call.name)) {
      // surface approval UX for this exact call
      approved = true;
    }
    input.push(call, await ft.execute(call, { approved }));
  }
}

execute returns JSON parse failures, Zod validation errors, and unapproved write attempts as the tool’s output, so the model can self-correct on the next turn. For write tools whose needsApproval(name) is true, call execute(call, { approved: true }) only after your approval UX approves that exact function call. FilesError from the underlying SDK is rethrown - you decide how to surface it.

Agents SDK

createAgentsFileTools returns a record of tool() outputs keyed by tool name - spread Object.values() into new Agent({ tools }). Write tools default to needsApproval: true; the Agents SDK runner surfaces an interruption that your program resolves by approving or rejecting the call.

npm install @openai/agents zod
pnpm add @openai/agents zod
yarn add @openai/agents zod
bun add @openai/agents zod
nub add @openai/agents zod
aube add @openai/agents zod
import { Agent, run } from "@openai/agents";
import { Files } from "files-sdk";
import { s3 } from "files-sdk/s3";
import { createAgentsFileTools } from "files-sdk/openai";

const files = new Files({ adapter: s3({ bucket: "uploads" }) });
const tools = createAgentsFileTools({ files });

const agent = new Agent({
  instructions: "Help the user manage their files.",
  name: "Files agent",
  tools: Object.values(tools),
});

const result = await run(agent, "List my files.");

The Agents SDK runs Zod-typed tools in OpenAI strict mode, so each tool’s parameter schema is strict-valid: optional arguments are sent as null and read as absent, and uploadFile takes no metadata argument (strict mode can’t express a free-form map). Attach metadata from your own code, or use the Responses factory without strict, if the model needs to set it.

Errors thrown from execute() are wrapped by the Agents SDK’s default errorFunction into a model-visible string - the model sees the message and can self-correct on the next turn. This is the standard Agents-SDK pattern, and differs from the Responses flow where FilesError rethrows.

Approval, read-only, overrides

Both factories accept the same options shape as the Vercel createFileTools: requireApproval (boolean or per-tool record), readOnly (strips writes entirely), and overrides (description, plus strict for Responses or needsApproval for Agents).

Setting strict: true on a Responses tool reshapes its parameters to what OpenAI strict mode accepts: every property is listed in required, optional ones become nullable (execute treats null as “absent”), and free-form maps are dropped, so uploadFile has no metadata field under strict mode.

// Same shape across both factories.

createResponsesFileTools({ files }); // all writes gated (default)
createResponsesFileTools({ files, requireApproval: false }); // disabled
createResponsesFileTools({
  files,
  requireApproval: { deleteFile: true, uploadFile: false },
});

createAgentsFileTools({ files, readOnly: true });
// → only listFiles, getFileMetadata, downloadFile, getFileUrl

Was this page helpful?