Vendored
+57
@@ -12,6 +12,8 @@ const paths = require('./paths.js');
|
||||
const completeWatch = require('./complete-watch.js');
|
||||
const toolParse = require('./tool-parse.js');
|
||||
const repeatLoop = require('./repeat-loop.js');
|
||||
const groq = require('./groq.js');
|
||||
const webProcess = require('./web-process.js');
|
||||
|
||||
let sdk = null;
|
||||
let initError = null;
|
||||
@@ -19,6 +21,35 @@ let initPromise = null;
|
||||
let holdCount = 0;
|
||||
let loaded = emptyLoaded();
|
||||
const activeRequests = new Map();
|
||||
let remote = { provider: 'local', apiKey: '', model: 'openai/gpt-oss-20b' };
|
||||
|
||||
function configureRemote(opts) {
|
||||
opts = opts || {};
|
||||
remote.provider = opts.provider === 'groq' ? 'groq' : 'local';
|
||||
if (opts.apiKey != null) remote.apiKey = String(opts.apiKey).trim();
|
||||
if (opts.model) remote.model = String(opts.model).trim();
|
||||
}
|
||||
|
||||
function remoteActive() {
|
||||
return remote.provider === 'groq';
|
||||
}
|
||||
|
||||
function groqLoaded() {
|
||||
return {
|
||||
modelId: 'groq:' + remote.model,
|
||||
friendlyId: remote.model,
|
||||
constant: remote.model,
|
||||
tools: true,
|
||||
vision: groq.visionModel(remote.model),
|
||||
device: 'groq',
|
||||
backend: 'groq',
|
||||
backendId: null,
|
||||
deviceName: 'Groq',
|
||||
vram: null,
|
||||
ctxSize: 131072,
|
||||
requestId: null,
|
||||
};
|
||||
}
|
||||
|
||||
function emptyLoaded() {
|
||||
return {
|
||||
@@ -401,7 +432,28 @@ async function unload() {
|
||||
}
|
||||
}
|
||||
|
||||
function localLoaded() {
|
||||
return Object.assign({}, loaded);
|
||||
}
|
||||
|
||||
async function complete(opts, onEvent) {
|
||||
// Groq thinks only about a local Chrome crawl. Every other turn stays here.
|
||||
if (remoteActive() && opts && opts.webProcess) {
|
||||
if (!remote.apiKey) {
|
||||
throw new Error('Groq agent inference needs a Groq API key. Set it in Settings or GROQ_API_KEY.');
|
||||
}
|
||||
const rawHistory = (opts && opts.history) || (opts && opts.messages) || [];
|
||||
const history = prepareVisionHistory(rawHistory).concat([{ role: 'system', content: webProcess.GROQ_WEB_HINT }]);
|
||||
return groq.complete({
|
||||
history,
|
||||
tools: webProcess.browserToolsOnly(opts && opts.tools),
|
||||
timeoutMs: opts && opts.timeoutMs,
|
||||
idleMs: opts && opts.idleMs,
|
||||
stream: opts && opts.stream,
|
||||
model: remote.model,
|
||||
apiKey: remote.apiKey,
|
||||
}, onEvent);
|
||||
}
|
||||
const s = await ensureInit();
|
||||
if (!loaded.modelId && !(opts && opts.modelId)) throw new Error('no model loaded');
|
||||
const rawHistory = (opts && opts.history) || (opts && opts.messages) || [];
|
||||
@@ -568,6 +620,7 @@ async function complete(opts, onEvent) {
|
||||
}
|
||||
|
||||
async function cancel() {
|
||||
groq.cancel();
|
||||
const id = loaded.requestId;
|
||||
const run = id && activeRequests.get(id);
|
||||
try {
|
||||
@@ -577,6 +630,7 @@ async function cancel() {
|
||||
}
|
||||
|
||||
function getLoaded() {
|
||||
if (remoteActive()) return groqLoaded();
|
||||
return Object.assign({}, loaded);
|
||||
}
|
||||
|
||||
@@ -606,7 +660,10 @@ module.exports = {
|
||||
complete,
|
||||
cancel,
|
||||
getLoaded,
|
||||
localLoaded,
|
||||
resources,
|
||||
configureRemote,
|
||||
remoteActive,
|
||||
VISION_FOLLOWUP_QUESTION,
|
||||
prepareVisionHistory,
|
||||
hold,
|
||||
|
||||
Reference in New Issue
Block a user