Skip to content

Commit c5ae10e

Browse files
author
Brendan Gray
committed
v1.8.30: Continuation budget fix, code fence detection, tool bubble text leak fix, verification enforcement
1 parent fa5eaf3 commit c5ae10e

2 files changed

Lines changed: 24 additions & 5 deletions

File tree

main/agenticChat.js

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,10 +1011,11 @@ function register(ctx) {
10111011
let _tb = '';
10121012
let _tIdx = 9000;
10131013
let _tStart = -1;
1014+
let _tEnd = -1;
10141015
let _tName = null;
10151016
if (_pendingPartialBlock) {
10161017
const seedMatch = _pendingPartialBlock.match(/\{\s*"tool"\s*:\s*"([^"]+)"/);
1017-
if (seedMatch) { _tStart = 0; _tName = seedMatch[1]; }
1018+
if (seedMatch) { _tStart = 0; _tEnd = -1; _tName = seedMatch[1]; }
10181019
}
10191020

10201021
let result;
@@ -1072,10 +1073,22 @@ function register(ctx) {
10721073
_tb += token;
10731074
if (_tStart === -1) {
10741075
const m = _tb.match(/\{\s*"tool"\s*:\s*"([^"]+)"/);
1075-
if (m) { _tStart = m.index; _tName = m[1]; }
1076+
if (m) { _tStart = m.index; _tName = m[1]; _tEnd = -1; }
10761077
}
1077-
if (_tStart !== -1 && _tName && mainWindow && !mainWindow.isDestroyed()) {
1078+
// Detect when tool JSON ends (balanced braces) to avoid including post-JSON text
1079+
if (_tStart !== -1 && _tEnd === -1) {
10781080
const raw = _tb.slice(_tStart);
1081+
let depth = 0, idx = 0;
1082+
for (; idx < raw.length; idx++) {
1083+
if (raw[idx] === '{') depth++;
1084+
else if (raw[idx] === '}') depth--;
1085+
if (depth === 0 && idx > 0) { _tEnd = _tStart + idx + 1; break; }
1086+
}
1087+
}
1088+
if (_tStart !== -1 && _tName && mainWindow && !mainWindow.isDestroyed()) {
1089+
// Only include up to the end of the JSON (or all if not yet closed)
1090+
const endPos = _tEnd !== -1 ? _tEnd : _tb.length;
1091+
const raw = _tb.slice(_tStart, endPos);
10791092
// Smart truncation: ensure "content" key is always visible for preview
10801093
let paramsText;
10811094
if (raw.length <= 8000) {
@@ -1381,6 +1394,9 @@ function register(ctx) {
13811394
let _hasUnclosedToolFence = _fenceIdx !== -1 &&
13821395
!_afterFence.match(/```(?:json|tool_call|tool)\b[\s\S]*?\n```/) &&
13831396
!_afterFence.match(/```(?:json|tool_call|tool)\b[\s\S]*?[^`]```\s*$/);
1397+
// Also detect any unclosed code fence (html, js, css, etc.) for higher continuation budget
1398+
const _anyCodeFenceIdx = _stitchedForMcp.search(/```(?:html?|css|javascript|js|typescript|ts|python|py|json|jsx|tsx|java|c|cpp|csharp|ruby|go|rust|php|sql|xml|yaml|sh|bash|markdown|md)\b/);
1399+
const _hasUnclosedCodeFence = _anyCodeFenceIdx !== -1 && !_stitchedForMcp.slice(_anyCodeFenceIdx).match(/```[^\n]*\n[\s\S]*?\n```/);
13841400

13851401
// If the unclosed fence contains a complete JSON tool call, don't treat as truncated
13861402
if (_hasUnclosedToolFence) {
@@ -1414,9 +1430,10 @@ function register(ctx) {
14141430
contContextPct = contUsed / totalCtx;
14151431
} catch (_) {}
14161432

1417-
const budgetLimit = _hasUnclosedToolFence ? 0.92 : 0.70;
1433+
// Higher budget limit for unclosed code fences to allow large code blocks to complete
1434+
const budgetLimit = _hasUnclosedToolFence ? 0.92 : (_hasUnclosedCodeFence ? 0.90 : 0.88);
14181435
if (contContextPct > budgetLimit) {
1419-
console.log(`[AI Chat] Continuation aborted: context at ${Math.round(contContextPct * 100)}%`);
1436+
console.log(`[AI Chat] Continuation aborted: context at ${Math.round(contContextPct * 100)}% (limit=${Math.round(budgetLimit * 100)}%)`);
14201437
continuationCount = 0;
14211438
// Try salvage
14221439
if (_hasUnclosedToolFence && _stitchedForMcp) {

main/constants.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ const DEFAULT_COMPACT_PREAMBLE = `You are a helpful, knowledgeable AI assistant.
105105
## Rules
106106
- **Never output full file content as code blocks in chat** — always use write_file, edit_file, or append_to_file. Code blocks are only for brief snippets or explanations.
107107
- **For new files: call write_file immediately.** Do not describe what the file would contain — create it.
108+
- **When the user asks for confirmation or verification, ALWAYS call list_directory or read_file to verify.** NEVER say "I can confirm" without actually checking. NEVER refuse a verification request — you MUST call the tool.
109+
- **Path awareness:** All relative paths are relative to the project root. Use paths like "file.html" for root files, "subfolder/file.html" for nested files. To delete directories, use run_command with "Remove-Item -Recurse -Force path".
108110
- When calling tools, format tool calls as valid JSON with properly quoted string values. Never use backtick template literals in tool call JSON.
109111
- Tools execute in the live environment. Call them — do not describe what you would do.
110112
- Never say you did something unless you called the tool that did it.

0 commit comments

Comments
 (0)