TypeScript SDK
本页说明如何安装、配置并使用官方 @web-agent/sdk Node / 浏览器包:起 session、跑 task、订阅事件。
npm install @web-agent/sdk
# 或 pnpm add @web-agent/sdk / yarn add @web-agent/sdk / bun add @web-agent/sdk支持 Node 20+ 与现代浏览器。
不要把 server 端
wa_key 塞进浏览器——key 是 project 级权限,仅限 server-side 或可信运行时。
一个入口:Client
用户面 API 都挂在同一个 Client 上:
import { Client } from "@web-agent/sdk";| 资源 | 对应产品 | 用法 |
|---|---|---|
client.sessions / messages / events | DoAnything(开放型) | 自由输入,agent 自己定路径 |
client.deepResearch | DeepResearch(定型 — 研究→报告) | Standalone API |
client.webSearch | WebSearch(定型 — 查询→结果) | 默认 wait=true 同步糖 |
client.track | Track(监控 → snapshot) | 长寿命 monitor + webhook 通道 |
DoAnything —— 开放型任务
import { Client } from "@web-agent/sdk";
const client = new Client({
apiKey: process.env.WEBAGENT_API_KEY!,
projectId: process.env.WEBAGENT_PROJECT_ID!,
});
const session = await client.sessions.create({
instructions: "找出 Hacker News 现在 Top 5 的故事。",
});
const task = session.tasks[0]; // session 创建会隐式排好首个 task
for await (const event of client.events.stream(session.id, task.id)) {
console.log(event.type, event.data);
if (event.type === "task.completed") break;
}wire 字段一律 snake_case 与 API 对齐;方法名 camelCase。
续传 + 心跳
for await (const event of client.events.stream(session.id, task.id, {
lastEventId: "142",
includeHeartbeats: false,
})) {
if (event.type === "task.completed") break;
}底层用 fetch + 手写 SSE parser——Node 20+ / Bun / Cloudflare Workers / 浏览器都跑得起来。
「起新 task」 vs 「往运行中 task 塞消息」
// 1. 塞消息进当前 task 的对话队列
await client.messages.send(session.id, task.id, {
content: "顺便把每条的评论数也带上。",
});
// 2. 在同一个 session 里起新 task
const followup = await client.sessions.createTask(session.id, {
instructions: "点进第一条,总结评论区。",
});回应 input request
await client.messages.intervene(session.id, task.id, {
kind: "answer_input_request",
input_request_id: "ir_01HXX",
response: { solved: true },
});kind 是 discriminator,同一个端点也处理 take_control / release_control——见 Take Control。
取消 / 停止 / 列表
await client.sessions.cancelTask(session.id, task.id, { reason: "user_cancelled" });
await client.sessions.stop(session.id, { force: false });
const list = await client.sessions.list({ status: "running", limit: 20 });
list.items.forEach((s) => console.log(s.id, s.status));DeepResearch —— 研究 → 报告
DR 是 Standalone API(pidless:/v1/deep_research),项目租户从 Bearer token 解析。
const task = await client.deepResearch.run({
topic: "2026 年开源向量数据库格局",
depth: "deep", // light / standard / deep
requireOutlineApproval: true, // 默认开 outline HITL gate
});
// 订阅事件流(DR 走 DoAnything 的 SSE 通道)+ 响应 outline gate
for await (const event of client.events.stream(
task.session_id as string, task.task_id as string,
)) {
if (event.type === "task.input_request") {
await client.deepResearch.intervene(task.task_id as string, {
requestId: (event.data as { request_id: string }).request_id,
response: "approve", // 或 { action: "approve_with_edits", edits: [...] }
});
}
if (event.type === "task.completed") break;
}
// 拉取产物三件套(final.md / citations.json / confidence.json)
const artifacts = await client.deepResearch.listArtifacts(task.task_id as string);
const final = await client.deepResearch.getArtifact(
task.task_id as string, artifacts[0]!.id as string,
);WebSearch —— 查询 → 结果
WS 是 project-scoped API。run() 默认 wait: true,服务器阻塞 ≤30s 后返回 done envelope;超时退化 202,调 get(taskId) 轮询。
// 同步形态(默认)
const result = await client.webSearch.run({
queries: ["best TypeScript ORM 2026"],
engines: ["tavily"],
summarize: true,
});
// 异步形态
const pending = await client.webSearch.runAsync({
queries: ["best TypeScript ORM 2026"],
});
const detail = await client.webSearch.get(pending.task_id as string);
// Refine(同 task 内重搜)
await client.webSearch.refine(pending.task_id as string, {
text: "再加 site:reddit.com 限制重搜",
});Track —— 长寿命监控
Track 是 project-scoped API。一个 monitor 是长寿命后台 job:cron / interval / event 调度 + 抽取目标 + 通知通道(webhook)。每次 tick 产生一行 snapshot;trigger DSL 判定 diff 值得通知时,通道发送 payload。
const mon = await client.track.create({
intent: "apple.com 上 iPhone 17 Pro 跌破 $999 时通知我",
schedule: { kind: "interval", every_seconds: 3600 },
notifyChannel: { kind: "callback_url", url: "https://hooks.example.com/track" },
});
// 生命周期 —— 通过 patch 暂停 / 恢复 / refine:
await client.track.pause(mon.id as string, { reason: "人工核对" });
await client.track.resume(mon.id as string);
await client.track.refine(mon.id as string, {
triggerDsl: { op: "lt", field: "price", value: 999 },
});
// 手动触发一次 tick(绕开 schedule):
const outcome = await client.track.runNow(mon.id as string);
// snapshot 历史(最新优先):
const snaps = await client.track.listSnapshots(mon.id as string);
const snap = await client.track.getSnapshot(
mon.id as string,
snaps.items[0]!.id as string,
);
// webhook outbox + 重投:
const deliveries = await client.track.listDeliveries(mon.id as string, {
includePayload: true,
});
await client.track.retryDelivery(
mon.id as string,
deliveries.items[0]!.id as number,
);
// 取消 monitor(终态):
await client.track.cancel(mon.id as string); // 等价:client.track.delete(...)Alignment HITL(可选)
Supervisor 需要让你澄清意图时,monitor 进入 pending_clarification,发出 alignment.input_request 事件。用 intervene() 回答:
await client.track.intervene(mon.id as string, {
requestId: "req_align_1",
response: "SKU A",
});也可以随时往 alignment 队列推自由文本:client.track.message(monId, { content: "…" })。
错误
import {
ApiError,
InsufficientCreditsError,
RateLimitedError,
UnauthorizedError,
} from "@web-agent/sdk";
try {
await client.sessions.create({ instructions: "…" });
} catch (err) {
if (err instanceof InsufficientCreditsError) {
console.log("top up:", err.detail, err.extra);
} else if (err instanceof ApiError) {
console.log(err.code, err.statusCode, err.detail);
} else {
throw err;
}
}每个错误类都继承 ApiError,暴露 code / statusCode / detail / extra,对应 API 错误信封。
类型
DoAnything 的 request / response 类型都是顶层 export:
import type {
Session, Task, Event, EventType,
CreateSessionRequest, CreateTaskRequest, InterveneRequest,
TaskStatus, SessionStatus, TerminalReason,
} from "@web-agent/sdk";DR / DS / WS 的响应是 Record<string, unknown>(按 OpenAPI 信封原样回传),用键名访问(task.task_id / task.status)。各资源也导出自己的 option 类型(DRRunOptions / DSRunOptions / WSRunOptions)。
接下来
- Python SDK —— Python 同样的接口
- 错误码与重试 —— 推荐重试策略 + 幂等键
- Sessions 与 Tasks —— 生命周期 / profile / workspace