web.agent() creates a model-backed browser agent. The agent owns one browser tool, execute_playwright_code, and receives Webcompute’s bounded post-step observation after each execution.
import { Web } from "@webcompute/sdk";
const web = new Web({ apiKey: process.env.WEBCOMPUTE_API_KEY! });
const agent = web.agent({
model: {
route: "openai",
model: "gpt-5.4-mini",
apiKeyEnv: "OPENAI_API_KEY",
},
browser: {
policy: { allowedDomains: ["sec.gov"] },
},
approval: "ask",
});
const result = await agent.run({
startUrl: "https://www.sec.gov/edgar/search/",
goal: "Find Apple's latest 10-Q filings and return filing metadata.",
});
Signature
web.agent<TOutput = unknown>(
config: WebAgentConfig<TOutput>
): WebAgent
interface WebAgent {
run<TOutput = unknown>(
input: string | WebAgentRunInput<TOutput>
): Promise<WebAgentResult<TOutput>>;
stream<TOutput = unknown>(
input: string | WebAgentRunInput<TOutput>
): AsyncIterable<WebAgentStreamEvent>;
session(input?: { startUrl?: string; browserId?: string }): Promise<WebAgentSession>;
}
WebAgentConfig
| Field | Type | Description |
|---|
model | WebAgentModelConfig | Required model provider config. |
browser | WebAgentBrowserConfig | Browser policy and browser creation defaults. |
systemPrompt | string | Additional system guidance for the model. |
approval | WebAgentApprovalMode | Default approval mode for confirmation-sensitive actions. Values: ask, delegated, never. Defaults to delegated when not set. |
onConfirm | WebAgentConfirmationHandler | Host callback for confirmation requests. |
captcha | WebAgentCaptchaResolutionOptions | CAPTCHA resolution options after approval. |
variables | WebAgentVariables | Host-provided variables available to approved Playwright code. |
maxTurns | number | Maximum model turns. |
maxToolCalls | number | Maximum browser tool calls. |
timeoutMs | number | Whole-run timeout in milliseconds. |
toolTimeoutMs | number | Per Playwright execution timeout in milliseconds. |
maxOutputTokens | number | Provider output-token budget. |
outputSchema | WebAgentSchema<TOutput> | Optional final structured-output schema. |
codePolicy | WebAgentCodePolicy | Model guidance for generated Playwright code. This is not a JavaScript sandbox. |
artifacts | WebAgentArtifactOptions | Optional returned artifact controls such as transcript retention. |
capture | WebAgentCaptureOptions | Observation and tool-result capture budgets. |
Model config
type WebAgentRoute =
| "openai"
| "openrouter"
| "openai-compatible"
| "anthropic"
| "google";
| Route | Required fields | Optional fields |
|---|
openai | route, model | apiKey, apiKeyEnv |
openrouter | route, model | apiKey, apiKeyEnv, baseUrl, defaultHeaders, modelApi |
openai-compatible | route, model | apiKey, apiKeyEnv, baseUrl, defaultHeaders, modelApi |
anthropic | route, model | apiKey, apiKeyEnv |
google | route, model | apiKey, apiKeyEnv |
modelApi accepts chat-completions or responses.
SDK web.agent() requires explicit model config. Running web model setup in the CLI configures the CLI profile store, not SDK application code.
The SDK exports model-profile helpers for applications that already have profile-shaped config:
parseWebAgentModelRoute
normalizeWebAgentModelProfile
resolveWebAgentModelAccess
webAgentModelConfigForAccess
inferWebAgentModelRoute
These helpers operate on config supplied by your application. They do not load local CLI config by themselves.
Browser config
interface WebAgentBrowserConfig {
policy?: BrowserNavigationPolicy;
create?: Omit<BrowserCreateOptions, "policy"> & {
policy?: BrowserNavigationPolicy;
};
}
Use browser.policy for the default navigation policy. Use browser.create when the agent should create its browser with browser-creation options such as proxy, maxDuration, recording, or a creation-time policy.
const agent = web.agent({
model,
browser: {
create: {
proxy: process.env.RESIDENTIAL_PROXY_URL,
recording: true,
policy: { allowedDomains: ["vendor.example"] },
},
},
});
interface WebAgentRunInput<TOutput = unknown> {
goal: string;
startUrl?: string;
browserId?: string;
approval?: WebAgentApprovalMode;
onConfirm?: WebAgentConfirmationHandler;
captcha?: WebAgentCaptchaResolutionOptions;
variables?: WebAgentVariables;
outputSchema?: WebAgentSchema<TOutput>;
metadata?: Record<string, unknown>;
signal?: AbortSignal;
}
You can pass a string shorthand when only the goal is needed:
await agent.run("Open the pricing page and summarize enterprise plan differences.");
Use browserId to run against an existing browser. Use startUrl to create or navigate the run to a starting page.
Result
interface WebAgentResult<TOutput = unknown> {
status: "completed" | "blocked" | "needs_confirmation" | "failed" | "cancelled";
text: string;
output?: TOutput;
error?: WebAgentError;
needsConfirmation?: WebAgentConfirmationRequest;
browserId: string;
debugUrl?: string;
steps: WebAgentStep[];
usage?: WebAgentUsage;
artifacts: WebAgentArtifact[];
transcript?: WebAgentTranscriptItem[];
schema?: WebAgentSchemaMetadata;
timings: {
startedAt: string;
finishedAt: string;
elapsedMs: number;
};
}
| Status | Meaning |
|---|
completed | The agent returned a final answer. |
blocked | The agent could not safely or successfully continue. |
needs_confirmation | The run stopped on a pending confirmation request. |
failed | The run failed. Inspect error. |
cancelled | The run was cancelled, usually by an abort signal. |
transcript is included only when artifacts.retainTranscript is enabled.
Streaming
for await (const event of agent.stream({ goal, startUrl })) {
if (event.type === "tool.completed") {
console.log(event.step, event.success, event.summary);
}
if (event.type === "run.completed") {
console.log(event.result.status, event.result.text);
}
}
WebAgentStreamEvent types:
| Event type | Description |
|---|
run.started | A run has started. |
browser.created | A browser was created for the run. May include a signed debug URL. |
model.started | A model turn started. |
model.delta | Incremental model text. |
model.completed | A model turn completed. May include usage. |
tool.started | Playwright execution started. Includes the generated code. |
tool.completed | Playwright execution completed. Includes page, success, elapsed time, and optional summary. |
confirmation.requested | The model requested host confirmation. |
confirmation.resolved | A confirmation request was approved or denied. |
observation | Bounded post-step page observation. |
status | Compact runtime status for a step. |
artifact | An artifact was produced. |
final.delta | Incremental final-answer text. |
structured_output.started | Structured-output finalization started. |
structured_output.validation | Structured-output validation result. |
run.completed | The run ended with a WebAgentResult. Check result.status. |
run.failed | Typed failure event. Handle it defensively, but do not assume it is the only failure path; many failures arrive through run.completed.result.status. |
Sessions
Use sessions to run multiple goals against the same browser.
const session = await agent.session({
startUrl: "https://vendor.example/dashboard",
});
await session.run("Collect invoice totals from the current account.");
await session.run("Download the most recent invoice PDF.");
await session.close();
interface WebAgentSession {
readonly browserId: string;
run<TOutput = unknown>(
input: string | WebAgentRunInput<TOutput>
): Promise<WebAgentResult<TOutput>>;
stream<TOutput = unknown>(
input: string | WebAgentRunInput<TOutput>
): AsyncIterable<WebAgentStreamEvent>;
close(): Promise<void>;
}
Approvals and confirmations
Approval mode controls how the harness handles sensitive actions:
| Mode | Behavior |
|---|
ask | Request host confirmation for sensitive actions. |
delegated | Let the harness proceed within configured policy and model guidance unless a confirmation request is required. This is the default. |
never | Do not request or grant confirmations. Sensitive actions should block. |
Approval risk values are exported as WEB_AGENT_APPROVAL_RISK_VALUES:
auth, account_creation, sensitive_data, external_submit, payment, purchase, legal_acceptance, destructive, permission_change, captcha, file_upload, out_of_scope, ambiguous, unknown.
const agent = web.agent({
model,
approval: "ask",
onConfirm: async (request) => {
if (request.risk === "payment") {
return { approved: false, reason: "Payments require a human operator." };
}
return { approved: true };
},
});
Variables and secrets
const agent = web.agent({
model,
variables: {
email: {
value: process.env.VENDOR_EMAIL!,
sensitive: true,
allowedDomains: ["vendor.example"],
description: "Vendor portal email",
},
},
});
Variables may be raw strings or WebAgentVariable descriptors:
| Field | Type | Description |
|---|
value | string | Variable value. |
description | string | Human-readable purpose. |
sensitive | boolean | Marks the variable as sensitive for logs and prompt handling. |
allowedDomains | string[] | Domains where the value may be used. |
Structured output
outputSchema accepts:
| Shape | Type |
|---|
| Raw JSON schema object | WebAgentJsonSchemaObject |
| JSON schema with validator | WebAgentRawJsonSchema<T> |
| Zod-like schema | WebAgentZodLikeSchema<T> |
| Standard Schema | WebAgentStandardSchema<T> |
Use normalizeOutputSchema when you need the SDK’s schema normalization and validation behavior outside an agent run.
Code policy
WebAgentCodePolicy guides model-generated Playwright:
| Field | Description |
|---|
allowSnapshotCalls | Allows model guidance that uses snapshot-style helpers. |
allowDirectNetwork | Allows model guidance that uses direct network calls. |
extraDeniedPatterns | Additional regular expressions discouraged in generated code. |
codePolicy is guidance for model-generated code. It is not a security sandbox for untrusted JavaScript. Use browser policy, approval handling, and server-side isolation as the control boundaries.