Vendored
+29
-5
@@ -11,6 +11,7 @@ const events = require('./events.js');
|
||||
const paths = require('./paths.js');
|
||||
const completeWatch = require('./complete-watch.js');
|
||||
const toolParse = require('./tool-parse.js');
|
||||
const repeatLoop = require('./repeat-loop.js');
|
||||
|
||||
let sdk = null;
|
||||
let initError = null;
|
||||
@@ -273,6 +274,7 @@ async function load(opts, onProgress) {
|
||||
const wantVision =
|
||||
opts.vision !== false && (entry ? entry.vision === true : catalog.isVisionModel(opts.model || opts.modelSrc));
|
||||
const mmprojSrc = wantVision ? await resolveMmproj(s, entry) : null;
|
||||
const loadParams = catalog.generationParamsForModel((entry && entry.id) || opts.model);
|
||||
const modelConfig = Object.assign(
|
||||
{
|
||||
device: dev.device,
|
||||
@@ -281,6 +283,7 @@ async function load(opts, onProgress) {
|
||||
tools: !!toolsOn,
|
||||
'mmproj-use-gpu': !!mmprojGpu,
|
||||
},
|
||||
loadParams.reasoning_budget != null ? { reasoning_budget: loadParams.reasoning_budget } : {},
|
||||
mmprojSrc ? { projectionModelSrc: mmprojSrc } : {}
|
||||
);
|
||||
const loadOpts = {
|
||||
@@ -317,7 +320,7 @@ async function load(opts, onProgress) {
|
||||
} catch (err) {
|
||||
const msg = flattenError(err);
|
||||
log('load failed: ' + msg);
|
||||
if (dev.device === 'gpu' && String(opts.device || 'auto').toLowerCase() !== 'cpu') {
|
||||
if (dev.device === 'gpu' && String(opts.device || 'auto').toLowerCase() === 'auto' && process.env.JARVIS_GPU_REQUIRED !== '1') {
|
||||
log('retrying load on cpu');
|
||||
modelConfig.device = 'cpu';
|
||||
modelConfig.gpu_layers = 0;
|
||||
@@ -340,8 +343,8 @@ async function load(opts, onProgress) {
|
||||
tools: !!toolsOn,
|
||||
vision: !!mmprojSrc,
|
||||
device: dev.device,
|
||||
backend: bl.backend,
|
||||
backendId: bl.backendId,
|
||||
backend: dev.device === 'gpu' ? bl.backend : 'cpu',
|
||||
backendId: dev.device === 'gpu' ? bl.backendId : 0,
|
||||
deviceName: bl.deviceName,
|
||||
vram: res && (res.vram || res.vramBytes),
|
||||
ctxSize: modelConfig.ctx_size,
|
||||
@@ -371,9 +374,13 @@ async function complete(opts, onEvent) {
|
||||
const history = prepareVisionHistory(rawHistory);
|
||||
const tools = toTools(opts && opts.tools);
|
||||
const dialect = (opts && opts.toolDialect) || catalog.toolDialectFor(loaded.friendlyId || loaded.constant);
|
||||
const generationParams = catalog.generationParamsForModel(
|
||||
loaded.friendlyId || loaded.constant,
|
||||
opts && opts.generationParams
|
||||
);
|
||||
const params = {
|
||||
modelId: (opts && opts.modelId) || loaded.modelId,
|
||||
history,
|
||||
history: toolParse.prepareToolHistory(history, dialect),
|
||||
stream: opts && opts.stream === false ? false : true,
|
||||
captureThinking: true,
|
||||
};
|
||||
@@ -381,7 +388,7 @@ async function complete(opts, onEvent) {
|
||||
params.tools = tools;
|
||||
params.toolDialect = dialect;
|
||||
}
|
||||
if (opts && opts.generationParams) params.generationParams = opts.generationParams;
|
||||
if (Object.keys(generationParams).length) params.generationParams = generationParams;
|
||||
const run = s.completion(params);
|
||||
const requestId = run.requestId || (opts && opts.requestId) || null;
|
||||
loaded.requestId = requestId;
|
||||
@@ -416,9 +423,19 @@ async function complete(opts, onEvent) {
|
||||
if (n.type === 'contentDelta') {
|
||||
text += n.delta;
|
||||
if (onEvent) onEvent(n);
|
||||
if (repeatLoop.isRepeating(text)) {
|
||||
abortRun();
|
||||
settleTimeout();
|
||||
return;
|
||||
}
|
||||
} else if (n.type === 'thinkingDelta') {
|
||||
thinking += n.delta;
|
||||
if (onEvent) onEvent(n);
|
||||
if (repeatLoop.isRepeating(thinking)) {
|
||||
abortRun();
|
||||
settleTimeout();
|
||||
return;
|
||||
}
|
||||
} else if (n.type === 'toolCall') {
|
||||
toolCalls.push(n.call);
|
||||
if (onEvent) onEvent(n);
|
||||
@@ -432,6 +449,11 @@ async function complete(opts, onEvent) {
|
||||
watch.bump();
|
||||
text += token;
|
||||
if (onEvent) onEvent({ type: 'contentDelta', delta: token });
|
||||
if (repeatLoop.isRepeating(text)) {
|
||||
abortRun();
|
||||
settleTimeout();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (run.toolCallStream) {
|
||||
for await (const evt of run.toolCallStream) {
|
||||
@@ -476,6 +498,8 @@ async function complete(opts, onEvent) {
|
||||
} else {
|
||||
text = toolParse.stripToolMarkup(text);
|
||||
}
|
||||
text = repeatLoop.collapseRepeats(text);
|
||||
thinking = repeatLoop.collapseRepeats(thinking);
|
||||
return {
|
||||
text,
|
||||
thinking,
|
||||
|
||||
Reference in New Issue
Block a user