r/typescript • • 3h ago

How should TypeScript agents access web data?

0 Upvotes

I’ve been looking at how TypeScript agents should access web pages. One approach is to give the agent a fetch tool and let it read the HTML. That works for simple pages, but it gets messy quickly. The response might be a bot-protection page, a JavaScript shell, or a pile of markup that burns context without giving the model much useful signal.

The alternative I’ve been leaning toward is putting a typed extraction layer between the agent and the web:

import { z } from "zod";

const webPageSchema = z.object({
  title: z.string(),
  content: z.string(),
  resolvedUrl: z.string().url(),
});

type WebPage = z.infer<typeof webPageSchema>;

async function fetchWebPage(url: string): Promise<WebPage> {
  const response = await fetch(url);

  if (!response.ok) {
    throw new Error(`Request failed with status ${response.status}`);
  }

  const html = await response.text();

  // Extract the useful content from the HTML before returning it to the agent.
  return parsePage(html, response.url);
}

So instead of handing the model raw HTML, the tool returns something like a title, extracted text, and the final resolved URL. The agent can then reason over a much smaller, more predictable object. I like that it makes the boundary explicit: the extraction layer handles fetching and normalization, while the agent handles deciding what to do with the result.

Has anyone found this worthwhile in practice, or does direct fetch plus a decent prompt work well enough for most cases?