Skip to content
Get started

Technical Landscape Researcher

Turn a single question into a cited, multi-source report with /research. Shows streaming progress, fast vs balanced mode, and how to read the cited sources off the complete event.

Ask a question, get back a synthesized report with citations. This example wraps /research into a small function that streams progress while the agent works, then prints the finished report and the list of sources it cited. It’s a focused demonstration of the endpoint itself: one question in, multi-source cited synthesis out, with no orchestration code of your own. For a larger agent that combines research with structured extraction, see the Competitor Briefing Agent.

import Tabstack from "@tabstack/sdk";
const client = new Tabstack();
type Source = { title: string; url: string };
async function researchTopic(query: string) {
const stream = await client.agent.research({
query,
mode: "fast", // "balanced" runs a deeper, multi-source pass (requires a paid plan)
});
let report: string | null = null;
const sources: Source[] = [];
for await (const event of stream) {
switch (event.event) {
case "iteration:start":
// Show progress as the agent runs its search loop.
process.stdout.write(
`\r[researching: iteration ${event.data.iteration}/${event.data.maxIterations}]`,
);
break;
case "complete":
report = event.data.report;
for (const page of event.data.metadata.citedPages ?? []) {
sources.push({ title: page.title ?? "(untitled)", url: page.url });
}
break;
case "error":
// Task-level failures arrive inside the stream, not as an HTTP error.
throw new Error(event.data.error?.message ?? "research failed");
}
}
console.log("\n\n" + (report ?? "(no report returned)"));
console.log(`\nCited ${sources.length} sources:`);
for (const source of sources) {
console.log(`- ${source.title}: ${source.url}`);
}
return { report, sources };
}
researchTopic(
"What are the main approaches to cloud browser automation for AI agents, and how do they differ?",
);
  • One call, full pipeline. client.agent.research(...) handles source selection, fetching, reading, and synthesis. You pass a question and consume a stream; there is no search, ranking, or citation code to write.
  • Stream progress as it runs. A research run can take from seconds to minutes. Switching on iteration:start gives you a live “iteration N of M” indicator. The full set of progress events (planning:*, searching:*, writing:*, and more on balanced mode) is documented in Autonomous Research.
  • The report and citations arrive on complete. event.data.report is the synthesized report as a markdown string, and event.data.metadata.citedPages (cited_pages in Python) lists every source the report drew on. Treat a missing value as an empty list.
  • Always handle error. A failed run delivers an error event inside the stream, not an HTTP error. If you only listen for complete, a failure produces no output.

fast is the default and is right for most questions. balanced consults more sources and runs a deeper pass, at the cost of time, and it requires a paid plan. Switch by changing the mode argument. For the full tradeoff and the extra progress events balanced emits, see Autonomous Research.

If you are researching something that changes often (pricing, release notes, live stats), pass nocache: true to skip any cached result and force a fresh run.

Terminal window
npm install @tabstack/sdk

Set your API key before running:

Terminal window
export TABSTACK_API_KEY=your_api_key