Why the OpenAI Agents SDK + Tabstack
Wiring web access into an agent usually means hand-rolled fetches, HTML parsing, and prompt gymnastics to coax structured data out of messy text. @tabstack/openai-agents replaces that with a hosted API exposed as native Agents SDK tools: schema-enforced output, server-side rendering of JS-heavy pages, and one key for extraction, research, generation, and automation. Tool names stay in lockstep with the @tabstack/langchain, @tabstack/ai, @tabstack/eve, and Python langchain-tabstack packages.
Quickstart
Install the adapter and set your key:
npm install @tabstack/openai-agents @openai/agents zod
export TABSTACK_API_KEY="your-key-here"@openai/agents (v0.13 or later) and zod (v4) are peer dependencies. tabstackTools is an array of ready-to-use tools, so hand it to an Agent and run it:
import { Agent, run } from "@openai/agents";
import { tabstackTools } from "@tabstack/openai-agents";
const agent = new Agent({
name: "Research assistant",
instructions:
"You are a research assistant with web intelligence tools. Use research_question for open " +
"questions that need multiple sources, extract_page_content to read a specific URL as " +
"markdown, and the extract tools to pull structured fields from a page. Always cite sources.",
tools: tabstackTools,
});
const result = await run(agent, "What are Vercel's pricing plans, with sources?");
console.log(result.finalOutput);The tools resolve TABSTACK_API_KEY lazily on first call, so importing the package never requires a key.
For a custom key, base URL, or a shared client, build the tools explicitly:
import { createTabstackOpenAIAgentsTools } from "@tabstack/openai-agents";
const tools = createTabstackOpenAIAgentsTools({ apiKey: process.env.MY_KEY });
// or pass an SDK client you already have: createTabstackOpenAIAgentsTools({ client })The tools
| Tool name | Export | What it does |
|---|---|---|
extract_structured_data | extractStructuredDataTool | Pull specific fields from a URL into a JSON shape you define. |
extract_page_content | extractPageContentTool | Fetch a page as clean markdown. |
research_question | researchQuestionTool | Synthesized answer with cited sources across multiple pages. |
generate_structured_data | generateStructuredDataTool | Fetch a page, then AI-transform it into derived or reshaped JSON. |
automate_browser_task | automateBrowserTaskTool | Run a multi-step, natural-language browser task. |
Strict mode and schemas
The Agents SDK forces strict JSON Schema mode whenever a tool's parameters is a Zod schema, and passing strict: false alongside a Zod schema throws. Strict mode cannot represent two constructs the shared core schemas rely on: .optional() fields, since strict mode requires every property to appear in required, and automate_browser_task's open data object, which needs a schema-valued additionalProperties that strict mode forbids.
So the adapter converts each core Zod schema to a JSON Schema and registers the tools with strict: false. The model still sees full field descriptions, and every call is validated against the core Zod schema inside execute before the request runs, so malformed model output fails fast with a clear error.
Good to know
automate_browser_taskruns non-interactively. It does not pause for human-in-the-loop form input, so it never blocks. It returns the final answer plus the data it extracted and the pages it visited.- Failed calls throw
TabstackToolError, a normalized message plus an HTTPstatusfor API errors. The Agents SDK surfaces tool errors to the model as a tool result, so a failing call does not abort the run by default. - Requires Zod 4. The SDK depends on it, and the adapter uses Zod 4's native
z.toJSONSchemato advertise each tool's parameters.
Common use cases
- Give a research agent cited, multi-source answers instead of a single fetch.
- Pull structured fields off a page without writing parsing code.
- Let an agent drive a multi-step browser task in natural language.
- Keep tool names consistent across your TypeScript and Python agents.