Files
gnome-jarvis/vendor/agent-harness/lib/web-process.js
T
snxraven ac5f18f79d
Rolling release / release (push) Failing after 2m11s
Updates
2026-09-14 10:19:13 -04:00

111 lines
3.9 KiB
JavaScript

/**
* Web browsing stays on the local Chrome window. Groq only thinks about
* browser results. Other tools stay on the local model.
*/
const RETIRED_WEB = new Set([
'web_search',
'google_search',
'fetch_page',
'web_fetch',
'wiki_search',
'hn_search',
'code_search',
]);
const CANON = {
search: 'web_search',
websearch: 'web_search',
google: 'google_search',
googlesearch: 'google_search',
fetch: 'web_fetch',
webfetch: 'web_fetch',
fetchpage: 'fetch_page',
open_url: 'fetch_page',
openurl: 'fetch_page',
};
function fold(name) {
return String(name || '').trim().toLowerCase().replace(/[\s-]+/g, '_');
}
function canonicalWeb(name) {
const folded = fold(name);
return CANON[folded] || folded;
}
function isRetiredWeb(name) {
return RETIRED_WEB.has(canonicalWeb(name));
}
function searchUrl(query, engine) {
const q = encodeURIComponent(String(query || '').trim());
const id = fold(engine) || 'duckduckgo';
if (id === 'google') return 'https://www.google.com/search?q=' + q;
if (id === 'bing') return 'https://www.bing.com/search?q=' + q;
if (id === 'wikipedia' || id === 'wiki') return 'https://en.wikipedia.org/w/index.php?search=' + q;
if (id === 'hn' || id === 'hackernews') return 'https://hn.algolia.com/?q=' + q;
if (id === 'github') return 'https://github.com/search?q=' + q + '&type=repositories';
if (id === 'npm') return 'https://www.npmjs.com/search?q=' + q;
if (id === 'mdn') return 'https://developer.mozilla.org/en-US/search?q=' + q;
if (id === 'stackoverflow') return 'https://stackoverflow.com/search?q=' + q;
if (id === 'arxiv') return 'https://arxiv.org/search/?query=' + q + '&searchtype=all';
return 'https://duckduckgo.com/?q=' + q;
}
function asBrowserCall(name, args) {
const canonical = canonicalWeb(name);
const input = args && typeof args === 'object' && !Array.isArray(args) ? args : {};
if (!RETIRED_WEB.has(canonical)) return { name, arguments: input };
if (canonical === 'web_fetch' || canonical === 'fetch_page') {
return { name: 'browser', arguments: { action: 'navigate', url: String(input.url || input.href || '') } };
}
const engine = canonical === 'google_search' ? 'google'
: canonical === 'wiki_search' ? 'wikipedia'
: canonical === 'hn_search' ? 'hn'
: canonical === 'code_search' ? (input.engine || 'github')
: (input.engine || 'duckduckgo');
return { name: 'browser', arguments: { action: 'navigate', url: searchUrl(input.query || input.q, engine) } };
}
function callName(call) {
if (!call) return '';
return call.name || (call.function && call.function.name) || '';
}
function needsGroqWebProcess(history) {
const list = Array.isArray(history) ? history : [];
for (let i = list.length - 1; i >= 0; i--) {
const msg = list[i];
if (!msg || !msg.role) continue;
if (msg.role === 'user') return false;
if (msg.role === 'tool' || msg.role === 'function') return callName(msg) === 'browser' || msg.name === 'browser';
if (msg.role === 'assistant' && Array.isArray(msg.tool_calls) && msg.tool_calls.length) {
const names = msg.tool_calls.map(callName).filter(Boolean);
return names.length > 0 && names.every((n) => n === 'browser');
}
if (msg.role === 'assistant') return false;
}
return false;
}
function browserToolsOnly(tools) {
return (Array.isArray(tools) ? tools : []).filter((tool) => {
if (!tool) return false;
return tool.name === 'browser' || (tool.function && tool.function.name === 'browser');
});
}
const GROQ_WEB_HINT = 'This turn is web-page processing only. Chrome already crawled on this computer. Think about the latest browser result, then speak the answer or call browser again to click, type, or open the next page. Do not call file, shell, desktop, or camera tools. Those stay on the local model.';
module.exports = {
RETIRED_WEB,
canonicalWeb,
isRetiredWeb,
asBrowserCall,
needsGroqWebProcess,
browserToolsOnly,
GROQ_WEB_HINT,
searchUrl,
};