Skip to content

Commit bfe0e07

Browse files
author
Brendan Gray
committed
v1.8.29: 7 bug fixes - single-click open, tool instructions, live preview, reasoning dropdown, code-dump nudge
1 parent 7d89921 commit bfe0e07

5 files changed

Lines changed: 63 additions & 14 deletions

File tree

.github/copilot-instructions.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# 🚫 STOP — READ THIS FIRST — NON-NEGOTIABLE — NO EXCEPTIONS
22

3+
## 🔴 RULE -1 — NEVER END INTERACTION WITHOUT MULTI-CHOICE QUESTION — ABSOLUTE
4+
5+
**This is THE most critical rule. Every premium request costs money. Ending without continuation wastes it.**
6+
7+
- **NEVER end an interaction by just stopping.** If you complete a task, hit a wall, need input, or have nothing more to do — you MUST use the multi-choice question tool to give the user options.
8+
- **Every interaction MUST end with either:** (1) a multi-choice question tool call, OR (2) active work still in progress (e.g., waiting for a build, running a command)
9+
- **"I've completed X, let me know if you need anything else"** — BANNED. This is ending without continuation.
10+
- **"Ready to proceed when you are"** — BANNED. Use multi-choice question instead.
11+
- **If you are about to type your final message:** STOP. Call the multi-choice question tool with options like: "Build it", "Make additional changes", "Review the plan", "I have questions", etc.
12+
- **This rule applies to EVERY interaction, no exceptions.** The user should never have to type a new message just to continue — they should be able to click an option.
13+
314
** NEVER BLAME MODEL
415
SIZE —ALL MODELS EXCEL IN LM STUDIO AT SAME TASKS THEYRE BEING TESTED ON HERE! If something fails, the problem is in the pipeline. Exhaust all levers before concluding "the model isn't good enough." Do not say "the model can't do this" without first confirming that every other lever has been pulled. This is a production software project, not a research experiment. The user expects results, not excuses.
516

main/agenticChat.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1667,8 +1667,11 @@ function register(ctx) {
16671667
}
16681668
}
16691669

1670-
// Route planning text to thinking panel
1671-
if (toolResults.hasToolCalls && toolResults.results.length > 0 && mainWindow) {
1670+
// Route planning text to thinking panel — ONLY for thinking models
1671+
// Non-thinking models' intro text ("Let me create that...") is their response, not reasoning
1672+
const _modelPath = llmEngine?.currentModelPath || '';
1673+
const _isThinkingModel = /qwq|r1-distill|deepseek.*r1|-think/i.test(_modelPath);
1674+
if (_isThinkingModel && toolResults.hasToolCalls && toolResults.results.length > 0 && mainWindow) {
16721675
let planningText;
16731676
if (toolResults.formalCallCount > 0) {
16741677
// Formal tool calls — strip from tool indicators onward
@@ -1713,12 +1716,15 @@ function register(ctx) {
17131716
const _unclosedFenceMatch = !hasCodeBlocks && responseText.match(/```(?:html?|css|javascript|js|typescript|ts|python|py|json)\s*\n([\s\S]{500,})$/i);
17141717
const hasUnclosedLargeBlock = !!_unclosedFenceMatch && !_unclosedFenceMatch[1].includes('```');
17151718
// Detect raw HTML/code dumped without fences (model obeyed "no code blocks" but didn't use write_file)
1716-
// Requires STRUCTURAL HTML document tags (<!DOCTYPE, <html, <head, <body) to avoid false
1717-
// positives on plain-text descriptions that mention individual element names like <div>, <section>.
1718-
const hasRawCodeDump = !hasCodeBlocks && !hasUnclosedLargeBlock && responseText.length > 500 && (
1719-
(/<html[\s>]/i.test(responseText) && (/<head[\s>]/i.test(responseText) || /<body[\s>]/i.test(responseText))) ||
1720-
(/<style[\s>]/i.test(responseText) && (responseText.match(/[{};]\s*\w+\s*:/g) || []).length > 5) ||
1721-
(/<script[\s>]/i.test(responseText) && (responseText.match(/(?:function |const |let |var |=>)/g) || []).length > 3)
1719+
// STRICT detection: requires FULL document structure (<html> AND (<head> OR <body>)) with significant length
1720+
// to avoid false positives on partial explanations or snippets. Length threshold raised to 1500 chars.
1721+
const hasRawCodeDump = !hasCodeBlocks && !hasUnclosedLargeBlock && responseText.length > 1500 && (
1722+
// Full HTML document: must have <html> AND at least one of <head> or <body> with substantial content
1723+
(/<html[\s>]/i.test(responseText) && /<head[\s>]/i.test(responseText) && /<body[\s>]/i.test(responseText) && (responseText.match(/<\/\w+>/g) || []).length > 10) ||
1724+
// CSS block: must have multiple complete CSS rules (not just a few property mentions)
1725+
(/<style[\s>]/i.test(responseText) && (responseText.match(/\{[^}]+\}/g) || []).length > 8) ||
1726+
// JS block: must have multiple function/variable declarations (substantial code)
1727+
(/<script[\s>]/i.test(responseText) && (responseText.match(/(?:function\s+\w+|const\s+\w+\s*=|let\s+\w+\s*=|var\s+\w+\s*=)/g) || []).length > 5)
17221728
);
17231729

17241730
// Skip nudge when context is critically small — resetSession can hang on degraded KV cache

main/constants.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,31 @@ If your output is cut off mid-generation, the system will automatically continue
7676

7777
const DEFAULT_COMPACT_PREAMBLE = `You are a helpful, knowledgeable AI assistant. You can answer questions on ANY topic — coding, history, science, math, creative writing, and more. You also have coding tools available. Call tools to take action — never just describe what you'd do. Never refuse a request because it is not about code. Always attempt to fulfill the user's request regardless of its length or complexity. When the user specifies output format or file structure, follow those requirements exactly.
7878
79+
## CRITICAL — ALWAYS USE TOOLS
80+
**When the user asks you to create, write, save, or generate ANY file — call write_file IMMEDIATELY.** Do NOT write code in your response. Do NOT describe what the file would contain. CALL THE TOOL.
81+
- User: "Create an HTML page" → YOU call write_file, NOT output HTML in chat
82+
- User: "Make a script" → YOU call write_file, NOT output code blocks
83+
- User: "Build a website" → YOU call write_file for EACH file
84+
**Code blocks in chat = WRONG. Tool calls = CORRECT.**
85+
7986
## CRITICAL — You Have Real-Time Access
8087
**Use web_search or fetch_webpage for live data.** NEVER say "I cannot access real-time data." You CAN. If cut off mid-task, the system continues automatically — NEVER refuse.
8188
82-
## Tools
83-
read_file, write_file, edit_file, list_directory, find_files, grep_search, run_command, web_search, fetch_webpage, browser_navigate, browser_snapshot, browser_click, browser_type, search_codebase, analyze_error, append_to_file, write_todos, update_todo
89+
## Tools (USE THEM!)
90+
- **write_file** — Create/overwrite files. USE THIS when asked to create ANY file.
91+
- **edit_file** — Modify a specific part of an existing file.
92+
- **append_to_file** — Add content to end of file without overwriting.
93+
- **read_file** — Read file contents before editing.
94+
- **list_directory** — See what files exist in a folder.
95+
- **find_files** — Search for files by name pattern.
96+
- **grep_search** — Search file contents for text.
97+
- **run_command** — Execute terminal/shell commands.
98+
- **web_search** — Get live internet data (current info, docs, news).
99+
- **fetch_webpage** — Get full text content from a URL.
100+
- **browser_navigate** — Open a URL in browser.
101+
- **browser_snapshot** — Capture current browser page.
102+
- **browser_click/type** — Interact with browser page elements.
103+
- **write_todos/update_todo** — Track multi-step tasks.
84104
85105
## Rules
86106
- **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.

src/components/Editor/Previews.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,14 @@ export const BinaryPreview: React.FC<{ filePath: string; fileName: string }> = (
6262
// ── HTML Preview ──
6363
export const HtmlPreview: React.FC<{ content: string; filePath: string; onToggleCode: () => void }> = ({ content, filePath, onToggleCode }) => {
6464
const iframeRef = useRef<HTMLIFrameElement>(null);
65-
const [key, setKey] = useState(0);
65+
const [manualKey, setManualKey] = useState(0);
66+
// Auto-refresh: hash content so iframe re-renders on every edit (live preview)
67+
const contentHash = useMemo(() => {
68+
let h = 0;
69+
for (let i = 0; i < content.length; i++) h = ((h << 5) - h + content.charCodeAt(i)) | 0;
70+
return h;
71+
}, [content]);
72+
const key = `${manualKey}-${contentHash}`;
6673

6774
const resolvedContent = useMemo(() => {
6875
const dir = filePath.replace(/\\/g, '/').replace(/\/[^/]*$/, '');
@@ -89,7 +96,7 @@ export const HtmlPreview: React.FC<{ content: string; filePath: string; onToggle
8996
<div className="flex-1" />
9097
<button
9198
className="p-1 text-[#858585] hover:text-white rounded hover:bg-[#3c3c3c] transition-colors"
92-
onClick={() => setKey(k => k + 1)}
99+
onClick={() => setManualKey(k => k + 1)}
93100
title="Refresh preview"
94101
>
95102
<RefreshCw size={12} />

src/components/FileExplorer/FileNode.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,14 @@ export const FileNodeComponent: React.FC<FileNodeComponentProps> = ({
5151
const handleClick = useCallback((event: React.MouseEvent) => {
5252
event.preventDefault();
5353
event.stopPropagation();
54-
if (node.type === 'directory') onToggle(node);
54+
if (node.type === 'directory') {
55+
onToggle(node);
56+
} else {
57+
// Single-click on file opens it (regression fix: was double-click only)
58+
onOpenFile?.(node);
59+
}
5560
onSelect(node, event);
56-
}, [node, onToggle, onSelect]);
61+
}, [node, onToggle, onSelect, onOpenFile]);
5762

5863
const handleExpandClick = useCallback((event: React.MouseEvent) => {
5964
event.preventDefault();

0 commit comments

Comments
 (0)