removed http-fetch

This commit is contained in:
Arjun 2026-05-04 17:06:41 +05:30
parent 684a45b9b6
commit b9a62f6662
2 changed files with 2 additions and 81 deletions

View file

@ -107,15 +107,12 @@ Security: ` + "`eval`" + ` runs in the active tab's origin with the user's cooki
## Companion Tools
### http-fetch
Use for **unauthenticated** API calls (e.g., ` + "`api.github.com`" + `, public REST endpoints) where you don't need the browser's logged-in session. Often faster and cleaner than DOM scraping many sites expose a public API that returns the same data. For authenticated requests that require the user's browser cookies, use ` + "`browser-control`" + ` with ` + "`action: \"eval\"`" + ` and call ` + "`fetch()`" + ` inside the page context instead.
### load-browser-skill
Rowboat caches a library of browser skills (from ` + "`browser-use/browser-harness`" + `) indexed by both **domain** (github, linkedin, amazon, booking, ) and **interaction type** within a domain (e.g. ` + "`github/repo-actions`" + `, ` + "`github/scraping`" + `, ` + "`arxiv-bulk/*`" + `). Whenever ` + "`browser-control`" + ` returns a ` + "`suggestedSkills`" + ` array which it does on ` + "`navigate`" + `, ` + "`new-tab`" + `, and ` + "`read-page`" + ` treat it as a required reading step, not optional. Pick the entry that matches the current task (domain match first, then the interaction-specific variant if one exists) and call ` + "`load-browser-skill({ id: \"<id>\" })`" + ` before attempting the action.
You can also proactively call ` + "`load-browser-skill({ action: \"list\", site: \"<site>\" })`" + ` when you know you're about to work on a site, to see what skills exist even if ` + "`suggestedSkills`" + ` is empty (e.g. before navigating).
These skills are written against a Python harness, so treat them as **reference knowledge** adapt the recipes into the actions above (especially ` + "`eval`" + ` + ` + "`http-fetch`" + ` for the ` + "`js(...)`" + ` and ` + "`http_get(...)`" + ` calls they use). The selectors, DOM gotchas, and sequencing are the durable part; the exact function names are not.
These skills are written against a Python harness, so treat them as **reference knowledge** adapt the recipes into the actions above, especially structured browser actions plus ` + "`eval`" + ` for the ` + "`js(...)`" + ` and ` + "`http_get(...)`" + ` style calls they use. **Do not look for or call ` + "`http-fetch`" + ` it is not available.** If a harness recipe suggests hitting a public API directly, either use ` + "`eval`" + ` with ` + "`fetch()`" + ` inside the page context when that is truly necessary, or fall back to reading and interacting with the page itself. The selectors, DOM gotchas, and sequencing are the durable part; the exact function names are not.
## Important Rules
@ -125,7 +122,7 @@ These skills are written against a Python harness, so treat them as **reference
- After navigation, clicking, typing, pressing, or scrolling, use the returned page snapshot instead of assuming the page state.
- **Always check ` + "`suggestedSkills`" + ` after ` + "`navigate`" + `, ` + "`new-tab`" + `, or ` + "`read-page`" + `, and load the matching domain or interaction skill before acting.** Skipping this step is the single most common way to waste a dozen failed clicks on a site whose quirks are already documented. If the array is empty, proceed normally but don't skip the check.
- Prefer structured actions (click/type/press) over ` + "`eval`" + ` when both work. Reach for ` + "`eval`" + ` when the site fights synthetic events, when you need to submit a form directly, or when you need to read DOM state the structured actions don't surface.
- For read-only data, check if ` + "`http-fetch`" + ` against the site's public API works before scraping the DOM.
- Do not try to use ` + "`http-fetch`" + `. If a browser-harness recipe mentions ` + "`http_get(...)`" + ` or a public API shortcut, adapt it to ` + "`eval`" + ` or DOM-based browsing instead.
- Use Rowboat's browser for live interaction. Use web search tools for research where a live session is unnecessary.
- Do not wrap browser URLs or browser pages in ` + "```filepath" + ` blocks. Filepath cards are only for real files on disk, not web pages or browser tabs.
- If you mention a page the browser opened, use plain text for the URL/title instead of trying to create a clickable file card.

View file

@ -995,82 +995,6 @@ export const BuiltinTools: z.infer<typeof BuiltinToolsSchema> = {
},
},
// ============================================================================
// HTTP Fetch
// ============================================================================
'http-fetch': {
description: 'Make a plain HTTP request (GET/POST/etc.) and return the response. Use this for API calls that do not require a logged-in browser session. For authenticated requests that need the user\'s active browser cookies, use browser-control with action "eval" and call fetch() inside the page context instead.',
inputSchema: z.object({
url: z.string().url().describe('Absolute URL to fetch.'),
method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD']).optional().describe('HTTP method. Defaults to GET.'),
headers: z.record(z.string(), z.string()).optional().describe('Request headers.'),
body: z.string().optional().describe('Request body as a string. For JSON, stringify first and set Content-Type: application/json.'),
responseType: z.enum(['text', 'json']).optional().describe('How to parse the response body. Defaults to text.'),
timeoutMs: z.number().int().positive().max(60000).optional().describe('Request timeout in milliseconds. Defaults to 15000.'),
}),
execute: async (input: {
url: string;
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD';
headers?: Record<string, string>;
body?: string;
responseType?: 'text' | 'json';
timeoutMs?: number;
}) => {
const MAX_BODY_BYTES = 500_000;
const timeout = input.timeoutMs ?? 15000;
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(input.url, {
method: input.method ?? 'GET',
headers: input.headers,
body: input.body,
signal: controller.signal,
redirect: 'follow',
});
const responseHeaders: Record<string, string> = {};
response.headers.forEach((value, key) => { responseHeaders[key] = value; });
const rawText = await response.text();
const truncated = rawText.length > MAX_BODY_BYTES;
const text = truncated ? rawText.slice(0, MAX_BODY_BYTES) : rawText;
let parsed: unknown = undefined;
if (input.responseType === 'json') {
try {
parsed = JSON.parse(rawText);
} catch (err) {
return {
success: false,
status: response.status,
statusText: response.statusText,
url: response.url,
headers: responseHeaders,
error: `Response was not valid JSON: ${err instanceof Error ? err.message : 'parse error'}`,
bodyPreview: text.slice(0, 2000),
};
}
}
return {
success: response.ok,
status: response.status,
statusText: response.statusText,
url: response.url,
headers: responseHeaders,
body: input.responseType === 'json' ? parsed : text,
truncated,
};
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'HTTP fetch failed.',
aborted: controller.signal.aborted,
};
} finally {
clearTimeout(timer);
}
},
},
// ============================================================================
// Browser Skills (browser-use/browser-harness domain-skills cache)
// ============================================================================