diff options
| author | amankumarsingh77 <amankumarsingh7702@gmal.com> | 2026-05-02 16:36:50 +0530 |
|---|---|---|
| committer | amankumarsingh77 <amankumarsingh7702@gmal.com> | 2026-05-02 16:36:50 +0530 |
| commit | b7fd72a6aa065df6335d1b4710c07bb4fd67615e (patch) | |
| tree | 4786b3297e7a4feae27abf27c7734b7661db6b4f /src/domains | |
| parent | 96934b772378b57aed243919d3c1d6ad6e96df1f (diff) | |
feat(domains): migrate http_get (timeout covers body) and get_network_log (deprecation note)
Diffstat (limited to 'src/domains')
| -rw-r--r-- | src/domains/network.ts | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/domains/network.ts b/src/domains/network.ts new file mode 100644 index 0000000..312f39a --- /dev/null +++ b/src/domains/network.ts @@ -0,0 +1,80 @@ +import { Type } from "typebox"; +import { type Result, err, ok } from "../util/result"; +import { defineBrowserTool, type ToolErr, type ToolOk } from "../util/tool"; +import { applyTruncation } from "../util/truncate"; + +const HttpGetArgs = Type.Object({ + url: Type.String({ description: "URL to GET" }), + headers: Type.Optional(Type.Record(Type.String(), Type.String(), { description: "Optional HTTP headers" })), + timeout: Type.Optional( + Type.Number({ default: 20, minimum: 1, maximum: 120, description: "Total seconds (covers headers AND body)" }), + ), +}); + +export const httpGetTool = defineBrowserTool({ + name: "browser_http_get", + label: "Browser HTTP GET", + description: + "Fetch a URL outside the browser (faster than browser_navigate for APIs and static pages). Timeout covers headers AND body read.", + promptSnippet: "HTTP GET (outside browser; for APIs/static pages)", + promptGuidelines: [ + "Faster than navigate+execute_js for JSON/HTML APIs.", + "No JS rendering — for SPAs use browser_navigate.", + ], + parameters: HttpGetArgs, + ensureAlive: false, + async handler(args): Promise<Result<ToolOk, ToolErr>> { + const ac = new AbortController(); + const timer = setTimeout(() => ac.abort(), (args.timeout ?? 20) * 1000); + try { + const fetchInit: RequestInit = { signal: ac.signal }; + if (args.headers !== undefined) fetchInit.headers = args.headers; + const res = await fetch(args.url, fetchInit); + const body = await res.text(); + clearTimeout(timer); + const ct = res.headers.get("content-type") ?? ""; + const truncated = await applyTruncation(body, "http"); + return ok({ + text: `HTTP ${res.status} ${ct}\n${truncated.text}`, + details: truncated.fullOutputPath !== undefined + ? { status: res.status, contentType: ct, length: body.length, fullOutputPath: truncated.fullOutputPath, wasTruncated: truncated.wasTruncated } + : { status: res.status, contentType: ct, length: body.length, wasTruncated: truncated.wasTruncated }, + }); + } catch (e) { + clearTimeout(timer); + const msg = e instanceof Error ? e.message : String(e); + const kind: ToolErr["kind"] = msg.toLowerCase().includes("abort") ? "timeout" : "io_error"; + return err({ kind, message: msg }); + } + }, +}); + +const NetLogArgs = Type.Object({ + eventTypes: Type.Optional( + Type.Array(Type.String(), { description: "CDP event names to filter (e.g., ['Network.requestWillBeSent'])" }), + ), + limit: Type.Optional(Type.Integer({ default: 50, minimum: 1, maximum: 500 })), +}); + +export const getNetworkLogTool = defineBrowserTool({ + name: "browser_get_network_log", + label: "Browser Get Network Log", + description: + "Read buffered Network.* CDP events. NOTE: in v0.3 the event stream is consumed internally by the session manager; this tool is a placeholder. Use browser_execute_js with PerformanceObserver as a workaround.", + promptSnippet: "Get buffered network events (DEPRECATED in v0.3 — see description)", + promptGuidelines: [ + "v0.3 routes CDP events through an internal AsyncIterable; a synchronous drain API isn't exposed yet.", + "For now, use browser_execute_js with PerformanceObserver, performance.getEntries(), or fetch interceptors.", + ], + parameters: NetLogArgs, + async handler(args): Promise<Result<ToolOk, ToolErr>> { + return ok({ + text: "browser_get_network_log: in v0.3 the CDP event stream is consumed by the session; use browser_execute_js with PerformanceObserver or performance.getEntries() to inspect network activity.", + details: { + deprecated: true, + eventTypes: args.eventTypes ?? null, + limit: args.limit ?? null, + }, + }); + }, +}); |
