Updates
Rolling release / release (push) Successful in 6m40s

This commit is contained in:
2026-09-12 07:22:47 -04:00
parent e4546f8e95
commit e9040d110a
30 changed files with 1688 additions and 444 deletions
+85 -32
View File
@@ -15,6 +15,7 @@ const toolSet = require('./tool-set.js');
const planMode = require('./plan-mode.js');
const todos = require('./todos.js');
const stationarity = require('./stationarity.js');
const toolBudget = require('./tool-budget.js');
const goalMod = require('./goal.js');
const truncate = require('./truncate.js');
const sr = require('./search-replace.js');
@@ -160,7 +161,18 @@ function resolvePermission(jobId, toolCallId, decision) {
if (fn) {
pendingPerms.delete(key);
fn(decision);
return true;
}
const keys = Array.from(pendingPerms.keys());
for (const k of keys) {
if (k === toolCallId || k.endsWith(':' + toolCallId)) {
const resolve = pendingPerms.get(k);
pendingPerms.delete(k);
if (resolve) resolve(decision);
return true;
}
}
return false;
}
function waitCustomResult(jobId, toolCallId) {
@@ -260,11 +272,15 @@ function applyPlanWrite(session, name, args) {
return { ok: true, path: file, bytes: text.length };
}
function sidecarMessages(session, tracker) {
function sidecarMessages(session, tracker, budget) {
const extra = [];
if (budget && budget.answerOnly) {
extra.push({ role: 'user', content: toolBudget.answerNowMessage() });
}
if (tracker && tracker.pendingCompactReminder) {
extra.push({ role: 'user', content: compaction.compactReminder() });
const cont = compaction.autoContinue(session.history);
const voice = !!(budget && budget.voice);
extra.push({ role: 'user', content: compaction.compactReminder({ voice }) });
const cont = compaction.autoContinue(session.history, { voice });
if (cont) extra.push(cont);
tracker.pendingCompactReminder = false;
}
@@ -368,6 +384,7 @@ async function runTurn(ctx) {
await ensureModel(session.model);
const voice = (payload && payload.voice === true) || origin === 'jarvis-qvac';
let extraSys = payload && payload.system;
if (session.goal && goalMod.isActive(session.goal)) {
extraSys = [extraSys, goalMod.plannerAddendum(session.goal)].filter(Boolean).join('\n\n');
@@ -376,20 +393,24 @@ async function runTurn(ctx) {
cwd: hostWorkspace ? cwd : session.workspace || cwd,
hostWorkspace,
extra: extraSys,
fsRead: hostWorkspace
? (c, r) => {
try {
return fsRead(c, r);
} catch (_) {
return '';
personality: voice ? 'voice' : undefined,
fsRead:
hostWorkspace && !voice
? (c, r) => {
try {
return fsRead(c, r);
} catch (_) {
return '';
}
}
}
: null,
: null,
});
const sidecars = [];
if (hostWorkspace) {
const gitText = await gitSidecar.gitStatusSb(cwd, { hostWorkspace: true, run: tools.runShell });
if (gitText) sidecars.push(gitText);
if (!voice) {
const gitText = await gitSidecar.gitStatusSb(cwd, { hostWorkspace: true, run: tools.runShell });
if (gitText) sidecars.push(gitText);
}
const memText = memory.injectBlock(origin, userText || '');
if (memText) sidecars.push(memText);
}
@@ -416,6 +437,7 @@ async function runTurn(ctx) {
const cancelled = () => live.get(session.id) && live.get(session.id).cancelled;
const stuck = stationarity.create();
const budget = toolBudget.fromPayload(payload, origin);
let lastText = '';
let goalNudges = 0;
@@ -557,29 +579,39 @@ async function runTurn(ctx) {
}
try {
for (let turn = 0; turn < MAX_TURNS; turn++) {
for (let turn = 0; turn < budget.maxTurns; turn++) {
if (cancelled()) return endTurn(emit, session, jobId, tracker, { reason: 'cancelled', turns: turn });
const toolDefs = buildToolDefs(session, payload, tracker);
if (turn === budget.maxTurns - 1) toolBudget.forceAnswer(budget);
const toolDefs = budget.answerOnly ? [] : buildToolDefs(session, payload, tracker);
ctx.planMode = planMode.isActive(tracker);
const ctxSize = loadedCtxSize();
const beforeLen = session.history.length;
const beforeUsage = compaction.usage(session.history, toolDefs, ctxSize);
emitLive(emit, session.id, jobId, Object.assign({ type: 'context' }, beforeUsage));
if (compaction.shouldCompact(session.history, toolDefs, ctxSize)) {
const useLlm = !budget.voice || compaction.nonSystemCount(session.history) >= 8;
emitUpdate(emit, session.id, jobId, {
type: 'compaction',
status: 'start',
method: 'llm',
method: useLlm ? 'llm' : 'heuristic',
used: beforeUsage.used,
limit: beforeUsage.limit,
pct: beforeUsage.pct,
threshold: beforeUsage.threshold,
});
session.history = await compaction.compactWithLlm(session.history, {
const compactOpts = {
budgetTokens: compaction.historyBudget(ctxSize, toolDefs, 0),
tools: toolDefs,
complete: (opts) => engine.complete(Object.assign({}, opts, { desktopVision: false })),
});
voice: !!budget.voice,
};
session.history = useLlm
? await compaction.compactWithLlm(
session.history,
Object.assign({}, compactOpts, {
complete: (opts) => engine.complete(Object.assign({}, opts, { desktopVision: false })),
})
)
: compaction.compact(session.history, compactOpts);
sessions.replaceHistory(session.id, session.history);
tracker.pendingCompactReminder = true;
if (hostWorkspace) {
@@ -593,7 +625,7 @@ async function runTurn(ctx) {
emitUpdate(emit, session.id, jobId, {
type: 'compaction',
status: 'done',
method: 'llm',
method: useLlm ? 'llm' : 'heuristic',
used: afterUsage.used,
limit: afterUsage.limit,
pct: afterUsage.pct,
@@ -605,6 +637,7 @@ async function runTurn(ctx) {
session.history = compaction.compact(session.history, {
budgetTokens: compaction.historyBudget(ctxSize, toolDefs, 0),
tools: toolDefs,
voice: !!budget.voice,
});
if (session.history.length !== beforeLen) {
sessions.replaceHistory(session.id, session.history);
@@ -624,7 +657,7 @@ async function runTurn(ctx) {
}
emitUpdate(emit, session.id, jobId, { type: 'turn', turn });
let streamBase = compaction.usage(session.history.concat(sidecarMessages(session, tracker)), toolDefs, ctxSize);
let streamBase = compaction.usage(session.history.concat(sidecarMessages(session, tracker, budget)), toolDefs, ctxSize);
emitLive(emit, session.id, jobId, Object.assign({ type: 'context' }, streamBase));
let streamChars = 0;
function liveUsed() {
@@ -636,7 +669,7 @@ async function runTurn(ctx) {
}
let result;
for (let overflowTry = 0; overflowTry < 4; overflowTry++) {
const history = session.history.concat(sidecarMessages(session, tracker));
const history = session.history.concat(sidecarMessages(session, tracker, budget));
streamBase = compaction.usage(history, toolDefs, ctxSize);
streamChars = 0;
try {
@@ -681,6 +714,7 @@ async function runTurn(ctx) {
budgetTokens: compaction.historyBudget(ctxSize, toolDefs, overflowTry + 1),
tools: toolDefs,
aggressive: true,
voice: !!budget.voice,
});
sessions.replaceHistory(session.id, session.history);
tracker.pendingCompactReminder = true;
@@ -694,15 +728,17 @@ async function runTurn(ctx) {
Object.assign({ type: 'context' }, usageFromStats(result && result.stats, liveUsed(), ctxSize))
);
if (result.text) {
lastText = result.text;
pushHistory(session, { role: 'assistant', content: result.text });
let calls = (result && result.toolCalls) || [];
if (budget.answerOnly) calls = [];
if ((result && result.text) || calls.length) {
if (result.text) lastText = result.text;
const assistant = { role: 'assistant', content: result.text || '' };
if (calls.length) assistant.tool_calls = calls;
pushHistory(session, assistant);
}
const calls = result.toolCalls || [];
if (!calls.length) {
const goalActive = goalMod.isActive(session.goal);
if (goalActive && goalNudges < MAX_GOAL_NUDGES) {
if (goalActive && goalNudges < MAX_GOAL_NUDGES && !budget.answerOnly) {
goalNudges += 1;
pushHistory(session, { role: 'user', content: goalMod.continuation(session.goal) });
continue;
@@ -710,7 +746,7 @@ async function runTurn(ctx) {
return endTurn(emit, session, jobId, tracker, {
type: 'end',
reason: 'stop',
text: result.text || lastText || '',
text: (result && result.text) || lastText || toolBudget.lastToolText(session.history) || '',
turns: turn + 1,
});
}
@@ -738,6 +774,13 @@ async function runTurn(ctx) {
continue;
}
if (name === 'run_terminal_cmd' && toolBudget.shouldSkipShell(budget)) {
const skipped = toolBudget.skipShellMessage();
pushHistory(session, { role: 'tool', name, content: skipped, tool_call_id: toolCallId });
emitUpdate(emit, session.id, jobId, { type: 'tool_result', toolCallId, name, result: skipped });
continue;
}
if (sandbox.needsPermission(name, mode) && !planMode.isPlanFilePath(args.path, tracker.planPath)) {
let remembered = null;
try {
@@ -760,7 +803,7 @@ async function runTurn(ctx) {
let decision = await waitPermission(jobId, { toolCallId });
if (decision === 'always') {
try {
permStore.remember(name, args, 'allow');
permStore.rememberAlways(name);
} catch (_) {}
decision = 'allow';
}
@@ -774,6 +817,7 @@ async function runTurn(ctx) {
}
prepared.push({ name, args, toolCallId });
if (name === 'run_terminal_cmd') toolBudget.markShell(budget);
}
let stopEarly = null;
@@ -795,19 +839,28 @@ async function runTurn(ctx) {
}
if (stopEarly) break;
}
if (prepared.length) toolBudget.markToolRound(budget);
if (stopEarly) {
return endTurn(emit, session, jobId, tracker, stopEarly);
}
if (stuckNow) {
return endTurn(emit, session, jobId, tracker, { reason: 'stuck', text: lastText, turns: turn + 1 });
return endTurn(emit, session, jobId, tracker, {
reason: 'stuck',
text: lastText || toolBudget.lastToolText(session.history),
turns: turn + 1,
});
}
if (stationarity.shouldNudge(stuck)) {
stationarity.markNudged(stuck);
pushHistory(session, { role: 'user', content: stationarity.nudgeText() });
}
}
return endTurn(emit, session, jobId, tracker, { reason: 'max_turns', text: lastText, turns: MAX_TURNS });
return endTurn(emit, session, jobId, tracker, {
reason: 'max_turns',
text: lastText || toolBudget.lastToolText(session.history),
turns: budget.maxTurns,
});
} catch (err) {
if (err && err.message === 'cancelled') {
return endTurn(emit, session, jobId, tracker, { reason: 'cancelled', text: lastText });