Skip to content
Go To Dashboard

Search the Web

Web Search lets a deployed agent find current information and the pages that support it. Agent steps call the typed ctx.sapiom.search.webSearch capability; Sapiom supplies the authenticated cloud connection when the deployed agent runs.

What the agent needsRecommended input
A synthesized answer with supporting resultsintent: "answer" or omit intent
Candidate pages to rank, scrape, or process itselfintent: "links"
A quick lookupdepth: "standard" or omit depth
A broader search for a harder research questiondepth: "deep"
The contents of one known pagesearch.scrape

Use webSearch to discover information. Once the agent has selected a source, scrape that URL when it needs the full page rather than relying on the search snippet.

const response = await ctx.sapiom.search.webSearch({
query: "What changed in the latest PostgreSQL major release?",
intent: "answer",
depth: "deep",
});
if (!response.answer) {
return {
answer: null,
sources: response.results,
};
}
return {
answer: response.answer,
sources: response.results.map(({ title, url, snippet }) => ({
title,
url,
snippet,
})),
};

The response always contains the echoed query and a results array. Each result has a title, url, and short snippet. answer is optional even when the agent asks for one, so handle an answer-less response instead of asserting that it exists.

Use link intent when the agent owns the ranking or will read the selected pages itself:

const { results } = await ctx.sapiom.search.webSearch({
query: `official documentation for ${input.library} migration`,
intent: "links",
});
const expectedHost = input.officialDomain.toLowerCase();
const official = results.filter((result) => {
try {
const url = new URL(result.url);
const host = url.hostname.toLowerCase();
return (
url.protocol === "https:" &&
(host === expectedHost || host.endsWith(`.${expectedHost}`))
);
} catch {
return false;
}
});
return { candidates: official.slice(0, 5) };

intent: "links" does not promise an answer. Validate URLs before handing them to another capability, and do not treat a snippet as a substitute for the linked source.

Local Run replaces ctx.sapiom.search.webSearch with a deterministic stub. The built-in response returns one fixture result and, unless intent is "links", a fixture answer. It does not search the web.

Override the exact capability path when a step branches on search results:

{
"version": 1,
"steps": {
"research": {
"search.webSearch": {
"query": "PostgreSQL release changes",
"answer": "The fixture answer used by this test.",
"results": [
{
"title": "PostgreSQL documentation",
"url": "https://www.postgresql.org/docs/",
"snippet": "Fixture source text"
}
]
}
}
}
}

Each override is returned verbatim. Match the query and response fields the step actually consumes, assert the terminal output, and require both unusedStubs and stubWarnings to be empty after the run. A passing Local Run proves the branch against fixture data, not source freshness or production ranking.

Phrase the query narrowly enough that a result can answer it. Keep source URLs with any derived claim, prefer primary sources for consequential decisions, and record the retrieval time when freshness matters. For high-impact research, compare more than one independent source before acting.

Search depth and intent can have different latency and usage characteristics. Use the lightest query that supports the decision, cap downstream scraping, and use the signed-in capability catalog for current availability, limits, and pricing.