Skip to content

Commit 1da37a5

Browse files
author
Brendan Gray
committed
Bump version to 1.8.51
1 parent 4841ed3 commit 1da37a5

6 files changed

Lines changed: 105 additions & 168 deletions

File tree

electron-main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ function createWindow() {
287287
titleBarOverlay: {
288288
color: '#1e1e1e',
289289
symbolColor: '#cccccc',
290-
height: 32,
290+
height: 34,
291291
},
292292
backgroundColor: '#1e1e1e',
293293
show: false,

main/pipeline/agenticLoop.js

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,19 +89,17 @@ async function handleLocalChat(ctx, message, context, helpers) {
8989

9090
// Calculate budget splits
9191
const maxResponseTokens = Math.min(Math.floor(totalCtx * 0.25), 4096);
92+
const toolCount = typeof mcpToolServer.getToolDefinitions === 'function' ? mcpToolServer.getToolDefinitions().length : 20;
93+
const sysPromptReserve = Math.max(500, toolCount * 55);
94+
let maxPromptTokens = Math.max(totalCtx - sysPromptReserve - maxResponseTokens, 256);
95+
96+
console.log(`[AgenticLoop] Context budget: total=${totalCtx}, sysReserve=${sysPromptReserve}, maxPrompt=${maxPromptTokens}, maxResponse=${maxResponseTokens}`);
9297

93-
// Get compact tool hint FIRST so we can measure its actual size for budget
98+
// Get compact tool hint
9499
const toolHint = typeof mcpToolServer.getCompactToolHint === 'function'
95100
? mcpToolServer.getCompactToolHint('general')
96101
: '';
97102

98-
// Compute sysPromptReserve from ACTUAL measured sizes (not per-tool estimate)
99-
const toolHintTokens = estimateTokens(toolHint);
100-
const sysPromptReserve = Math.max(500, toolHintTokens + 600); // +600 for preamble + project context + buffer
101-
let maxPromptTokens = Math.max(totalCtx - sysPromptReserve - maxResponseTokens, 256);
102-
103-
console.log(`[AgenticLoop] Context budget: total=${totalCtx}, sysReserve=${sysPromptReserve} (toolHint=${toolHintTokens}tok), maxPrompt=${maxPromptTokens}, maxResponse=${maxResponseTokens}`);
104-
105103
// Select preamble based on model size/context
106104
const contextIsConstrained = totalCtx < 8192;
107105
const useCompact = isSmallModel || contextIsConstrained;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "guide-ide",
3-
"version": "1.8.50",
3+
"version": "1.8.51",
44
"description": "guIDE - AI-Powered Offline IDE with local LLM, RAG, MCP tools, browser automation, and integrated terminal",
55
"author": {
66
"name": "Brendan Gray",

src/components/Chat/ChatPanel.tsx

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2452,18 +2452,16 @@ ${e.message}`,
24522452
/>
24532453
) : (
24542454
<>
2455-
{/* Header — spacer pushes buttons to right edge */}
2455+
{/* Header — justify-between puts title left, buttons right */}
24562456
<div
2457-
className={`h-[32px] flex items-center px-2 ${navigator.userAgent.includes('Electron') ? 'pr-[140px]' : 'pr-2'} flex-shrink-0`}
2457+
className={`h-[32px] flex items-center justify-between px-2 ${navigator.userAgent.includes('Electron') ? 'pr-[140px]' : 'pr-2'} flex-shrink-0`}
24582458
style={{ backgroundColor: 'var(--theme-bg-secondary)', borderBottom: '1px solid var(--theme-border)' }}
24592459
>
24602460
<div className="flex items-center flex-shrink-0">
24612461
<Sparkles size={14} className="mr-2 flex-shrink-0" style={{ color: 'var(--theme-accent)' }} />
24622462
<span className="text-[12px] font-semibold whitespace-nowrap brand-font" style={{ color: 'var(--theme-foreground)' }}>gu<span style={{ color: 'var(--theme-accent)' }}>IDE</span></span>
24632463
</div>
2464-
{/* Spacer — pushes action buttons to the right */}
2465-
<div className="flex-1 min-w-0" />
2466-
{/* Action buttons — pinned right by spacer */}
2464+
{/* Action buttons — justify-between places these at right edge */}
24672465
<div className="flex items-center gap-[1px] flex-shrink-0 chat-header-buttons">
24682466

24692467
<button
@@ -2837,6 +2835,98 @@ ${e.message}`,
28372835
{licenseMessage}
28382836
</p>
28392837
)}
2838+
2839+
{/* Tool Toggles */}
2840+
<div className="border-t border-[#3c3c3c] my-2" />
2841+
<p className="text-[10px] text-[#858585] mb-1 uppercase tracking-wider flex items-center gap-1.5">
2842+
<Settings size={10} /> Tools
2843+
<span className="ml-auto text-[9px] text-[#585858] normal-case tracking-normal">
2844+
{66 - disabledTools.length}/{66} enabled
2845+
</span>
2846+
</p>
2847+
<p className="text-[10px] text-[#585858] mb-2">Toggle tools the AI can use. Disabled tools are hidden from the model and rejected at execution.</p>
2848+
{(() => {
2849+
const toolCategories: Record<string, string[]> = {
2850+
'File Operations': ['read_file', 'write_file', 'edit_file', 'append_to_file', 'delete_file', 'rename_file', 'copy_file', 'list_directory', 'find_files', 'create_directory', 'get_project_structure', 'get_file_info', 'open_file_in_editor', 'diff_files'],
2851+
'Search': ['grep_search', 'search_in_file', 'search_codebase', 'replace_in_files'],
2852+
'Terminal': ['run_command', 'check_port', 'install_packages'],
2853+
'Web': ['web_search', 'fetch_webpage', 'http_request'],
2854+
'Browser': ['browser_navigate', 'browser_snapshot', 'browser_click', 'browser_type', 'browser_fill_form', 'browser_select_option', 'browser_evaluate', 'browser_scroll', 'browser_back', 'browser_press_key', 'browser_hover', 'browser_drag', 'browser_screenshot', 'browser_get_content', 'browser_get_url', 'browser_get_links', 'browser_tabs', 'browser_handle_dialog', 'browser_console_messages', 'browser_file_upload', 'browser_resize', 'browser_wait', 'browser_wait_for', 'browser_close'],
2855+
'Git': ['git_status', 'git_commit', 'git_diff', 'git_log', 'git_branch', 'git_stash', 'git_reset'],
2856+
'Code Analysis': ['analyze_error'],
2857+
'Undo': ['undo_edit', 'list_undoable'],
2858+
'Memory': ['save_memory', 'get_memory', 'list_memories'],
2859+
'Planning': ['write_todos', 'update_todo'],
2860+
'Scratchpad': ['write_scratchpad', 'read_scratchpad'],
2861+
'Image Generation': ['generate_image'],
2862+
};
2863+
const allToolNames = Object.values(toolCategories).flat();
2864+
return (
2865+
<div className="space-y-0.5 max-h-[200px] overflow-auto">
2866+
{Object.entries(toolCategories).map(([category, tools]) => {
2867+
const enabledInCat = tools.filter(t => !disabledTools.includes(t)).length;
2868+
const allEnabled = enabledInCat === tools.length;
2869+
const noneEnabled = enabledInCat === 0;
2870+
return (
2871+
<details key={category} className="group">
2872+
<summary className="flex items-center gap-1.5 py-0.5 cursor-pointer select-none text-[10px] text-[#cccccc] hover:text-white list-none">
2873+
<ChevronDown size={10} className="transition-transform group-open:rotate-0 -rotate-90 text-[#585858]" />
2874+
<span className="flex-1">{category} <span className="text-[#585858]">({enabledInCat}/{tools.length})</span></span>
2875+
<button
2876+
onClick={(e) => {
2877+
e.preventDefault();
2878+
e.stopPropagation();
2879+
if (allEnabled) {
2880+
setDisabledTools(prev => [...new Set([...prev, ...tools])]);
2881+
} else {
2882+
setDisabledTools(prev => prev.filter(t => !tools.includes(t)));
2883+
}
2884+
}}
2885+
className="text-[9px] px-1.5 py-0 rounded transition-colors"
2886+
style={{
2887+
color: allEnabled ? '#585858' : '#3794ff',
2888+
backgroundColor: 'transparent',
2889+
}}
2890+
onMouseEnter={e => { e.currentTarget.style.backgroundColor = '#ffffff10'; }}
2891+
onMouseLeave={e => { e.currentTarget.style.backgroundColor = 'transparent'; }}
2892+
>
2893+
{allEnabled ? 'Disable all' : 'Enable all'}
2894+
</button>
2895+
</summary>
2896+
<div className="pl-4 pb-1 space-y-0">
2897+
{tools.map(toolName => {
2898+
const isEnabled = !disabledTools.includes(toolName);
2899+
return (
2900+
<label key={toolName} className="flex items-center gap-1.5 py-[1px] cursor-pointer text-[10px] hover:bg-[#ffffff06] rounded px-1 -mx-1">
2901+
<div
2902+
onClick={() => toggleTool(toolName)}
2903+
className="w-[26px] h-[13px] rounded-full relative transition-colors flex-shrink-0 cursor-pointer"
2904+
style={{ backgroundColor: isEnabled ? '#007acc' : '#3c3c3c' }}
2905+
>
2906+
<div
2907+
className="w-[9px] h-[9px] rounded-full bg-white absolute top-[2px] transition-all"
2908+
style={{ left: isEnabled ? '15px' : '2px' }}
2909+
/>
2910+
</div>
2911+
<span style={{ color: isEnabled ? '#cccccc' : '#585858' }}>{toolName}</span>
2912+
</label>
2913+
);
2914+
})}
2915+
</div>
2916+
</details>
2917+
);
2918+
})}
2919+
{disabledTools.length > 0 && (
2920+
<button
2921+
onClick={() => setDisabledTools([])}
2922+
className="text-[9px] text-[#3794ff] hover:text-[#4da6ff] hover:underline mt-1 cursor-pointer"
2923+
>
2924+
Enable all tools
2925+
</button>
2926+
)}
2927+
</div>
2928+
);
2929+
})()}
28402930
</div>
28412931
)}
28422932

src/components/Chat/hooks/useChatSettings.ts

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -67,27 +67,7 @@ export function useChatSettings(): ChatSettings & ChatSettingsActions {
6767
const [ttsEnabled, setTtsEnabled] = useState(false);
6868
const [autoMode, setAutoMode] = useState(false);
6969
const [planMode, setPlanMode] = useState(false);
70-
const [disabledTools, setDisabledTools] = useState<string[]>([
71-
// Non-essential tools disabled by default — users can enable in Settings > Tools
72-
'delete_file', 'rename_file', 'copy_file', 'create_directory', 'get_file_info',
73-
'open_file_in_editor', 'diff_files',
74-
'search_in_file', 'replace_in_files',
75-
'check_port', 'install_packages',
76-
'http_request',
77-
'browser_fill_form', 'browser_select_option', 'browser_evaluate',
78-
'browser_scroll', 'browser_back', 'browser_press_key', 'browser_hover',
79-
'browser_drag', 'browser_screenshot', 'browser_get_content',
80-
'browser_get_url', 'browser_get_links', 'browser_tabs',
81-
'browser_handle_dialog', 'browser_console_messages', 'browser_file_upload',
82-
'browser_resize', 'browser_wait', 'browser_wait_for', 'browser_close',
83-
'git_status', 'git_commit', 'git_diff', 'git_log', 'git_branch',
84-
'git_stash', 'git_reset',
85-
'analyze_error',
86-
'undo_edit', 'list_undoable',
87-
'list_memories',
88-
'write_scratchpad', 'read_scratchpad',
89-
'generate_image',
90-
]);
70+
const [disabledTools, setDisabledTools] = useState<string[]>([]);
9171
const [cloudProvider, setCloudProvider] = useState<string | null>(() => {
9272
try { return localStorage.getItem('guide-cloud-provider') || null; } catch { return null; }
9373
});
@@ -214,26 +194,7 @@ export function useChatSettings(): ChatSettings & ChatSettingsActions {
214194
setReasoningEffort('medium');
215195
setThinkingBudget(0);
216196
setMaxIterations(100);
217-
setDisabledTools([
218-
'delete_file', 'rename_file', 'copy_file', 'create_directory', 'get_file_info',
219-
'open_file_in_editor', 'diff_files',
220-
'search_in_file', 'replace_in_files',
221-
'check_port', 'install_packages',
222-
'http_request',
223-
'browser_fill_form', 'browser_select_option', 'browser_evaluate',
224-
'browser_scroll', 'browser_back', 'browser_press_key', 'browser_hover',
225-
'browser_drag', 'browser_screenshot', 'browser_get_content',
226-
'browser_get_url', 'browser_get_links', 'browser_tabs',
227-
'browser_handle_dialog', 'browser_console_messages', 'browser_file_upload',
228-
'browser_resize', 'browser_wait', 'browser_wait_for', 'browser_close',
229-
'git_status', 'git_commit', 'git_diff', 'git_log', 'git_branch',
230-
'git_stash', 'git_reset',
231-
'analyze_error',
232-
'undo_edit', 'list_undoable',
233-
'list_memories',
234-
'write_scratchpad', 'read_scratchpad',
235-
'generate_image',
236-
]);
197+
setDisabledTools([]);
237198
(window as any).electronAPI?.llmSetContextSize?.(0);
238199
(window as any).electronAPI?.llmSetReasoningEffort?.('medium');
239200
}, []);

src/components/Settings/AdvancedSettingsPanel.tsx

Lines changed: 0 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ interface SettingsState {
3838
cloudProvider: string;
3939
cloudApiKey: string;
4040
cloudModel: string;
41-
// Tools
42-
disabledTools: string[];
4341
}
4442

4543
const DEFAULTS: SettingsState = {
@@ -74,26 +72,6 @@ const DEFAULTS: SettingsState = {
7472
cloudProvider: 'none',
7573
cloudApiKey: '',
7674
cloudModel: '',
77-
disabledTools: [
78-
'delete_file', 'rename_file', 'copy_file', 'create_directory', 'get_file_info',
79-
'open_file_in_editor', 'diff_files',
80-
'search_in_file', 'replace_in_files',
81-
'check_port', 'install_packages',
82-
'http_request',
83-
'browser_fill_form', 'browser_select_option', 'browser_evaluate',
84-
'browser_scroll', 'browser_back', 'browser_press_key', 'browser_hover',
85-
'browser_drag', 'browser_screenshot', 'browser_get_content',
86-
'browser_get_url', 'browser_get_links', 'browser_tabs',
87-
'browser_handle_dialog', 'browser_console_messages', 'browser_file_upload',
88-
'browser_resize', 'browser_wait', 'browser_wait_for', 'browser_close',
89-
'git_status', 'git_commit', 'git_diff', 'git_log', 'git_branch',
90-
'git_stash', 'git_reset',
91-
'analyze_error',
92-
'undo_edit', 'list_undoable',
93-
'list_memories',
94-
'write_scratchpad', 'read_scratchpad',
95-
'generate_image',
96-
],
9775
};
9876

9977
const CLOUD_PROVIDERS = [
@@ -626,96 +604,6 @@ export const AdvancedSettingsPanel: React.FC = () => {
626604
<ToggleField label="Format on Type" value={settings.formatOnType} onChange={v => update('formatOnType', v)} />
627605
</Section>
628606

629-
{/* ── Tools ───────────────────────────── */}
630-
<Section title="Tools" defaultOpen={false}>
631-
<p className="text-[10px] mb-2" style={{ color: 'var(--theme-foreground-muted)' }}>
632-
Toggle which tools the AI can use. Disabled tools are hidden from the model. {66 - settings.disabledTools.length}/66 enabled.
633-
</p>
634-
{(() => {
635-
const toolCategories: Record<string, string[]> = {
636-
'File Operations': ['read_file', 'write_file', 'edit_file', 'append_to_file', 'delete_file', 'rename_file', 'copy_file', 'list_directory', 'find_files', 'create_directory', 'get_project_structure', 'get_file_info', 'open_file_in_editor', 'diff_files'],
637-
'Search': ['grep_search', 'search_in_file', 'search_codebase', 'replace_in_files'],
638-
'Terminal': ['run_command', 'check_port', 'install_packages'],
639-
'Web': ['web_search', 'fetch_webpage', 'http_request'],
640-
'Browser': ['browser_navigate', 'browser_snapshot', 'browser_click', 'browser_type', 'browser_fill_form', 'browser_select_option', 'browser_evaluate', 'browser_scroll', 'browser_back', 'browser_press_key', 'browser_hover', 'browser_drag', 'browser_screenshot', 'browser_get_content', 'browser_get_url', 'browser_get_links', 'browser_tabs', 'browser_handle_dialog', 'browser_console_messages', 'browser_file_upload', 'browser_resize', 'browser_wait', 'browser_wait_for', 'browser_close'],
641-
'Git': ['git_status', 'git_commit', 'git_diff', 'git_log', 'git_branch', 'git_stash', 'git_reset'],
642-
'Code Analysis': ['analyze_error'],
643-
'Undo': ['undo_edit', 'list_undoable'],
644-
'Memory': ['save_memory', 'get_memory', 'list_memories'],
645-
'Planning': ['write_todos', 'update_todo'],
646-
'Scratchpad': ['write_scratchpad', 'read_scratchpad'],
647-
'Image Generation': ['generate_image'],
648-
};
649-
return (
650-
<div className="space-y-0.5 max-h-[300px] overflow-auto">
651-
{Object.entries(toolCategories).map(([category, tools]) => {
652-
const enabledInCat = tools.filter(t => !settings.disabledTools.includes(t)).length;
653-
const allEnabled = enabledInCat === tools.length;
654-
return (
655-
<details key={category} className="group">
656-
<summary className="flex items-center gap-1.5 py-0.5 cursor-pointer select-none text-[10px] list-none" style={{ color: 'var(--theme-foreground)' }}>
657-
<span style={{ transition: 'transform 0.15s', display: 'inline-block', transform: 'rotate(-90deg)' }} className="group-open:!rotate-0">
658-
<ChevronDown size={10} />
659-
</span>
660-
<span className="flex-1">{category} <span style={{ color: 'var(--theme-foreground-muted)' }}>({enabledInCat}/{tools.length})</span></span>
661-
<button
662-
onClick={(e) => {
663-
e.preventDefault();
664-
e.stopPropagation();
665-
if (allEnabled) {
666-
update('disabledTools', [...new Set([...settings.disabledTools, ...tools])]);
667-
} else {
668-
update('disabledTools', settings.disabledTools.filter(t => !tools.includes(t)));
669-
}
670-
}}
671-
className="text-[9px] px-1.5 py-0 rounded transition-colors"
672-
style={{ color: allEnabled ? 'var(--theme-foreground-muted)' : 'var(--theme-accent)', backgroundColor: 'transparent' }}
673-
>
674-
{allEnabled ? 'Disable all' : 'Enable all'}
675-
</button>
676-
</summary>
677-
<div className="pl-4 pb-1 space-y-0">
678-
{tools.map(toolName => {
679-
const isEnabled = !settings.disabledTools.includes(toolName);
680-
return (
681-
<label key={toolName} className="flex items-center gap-1.5 py-[1px] cursor-pointer text-[10px] rounded px-1 -mx-1" style={{ color: isEnabled ? 'var(--theme-foreground)' : 'var(--theme-foreground-muted)' }}>
682-
<div
683-
onClick={() => {
684-
const newDisabled = isEnabled
685-
? [...settings.disabledTools, toolName]
686-
: settings.disabledTools.filter(t => t !== toolName);
687-
update('disabledTools', newDisabled);
688-
}}
689-
className="w-[26px] h-[13px] rounded-full relative transition-colors flex-shrink-0 cursor-pointer"
690-
style={{ backgroundColor: isEnabled ? 'var(--theme-accent)' : 'var(--theme-bg-tertiary, #3c3c3c)' }}
691-
>
692-
<div
693-
className="w-[9px] h-[9px] rounded-full bg-white absolute top-[2px] transition-all"
694-
style={{ left: isEnabled ? '15px' : '2px' }}
695-
/>
696-
</div>
697-
<span>{toolName}</span>
698-
</label>
699-
);
700-
})}
701-
</div>
702-
</details>
703-
);
704-
})}
705-
{settings.disabledTools.length > 0 && (
706-
<button
707-
onClick={() => update('disabledTools', [])}
708-
className="text-[9px] hover:underline mt-1 cursor-pointer"
709-
style={{ color: 'var(--theme-accent)' }}
710-
>
711-
Enable all tools
712-
</button>
713-
)}
714-
</div>
715-
);
716-
})()}
717-
</Section>
718-
719607
{/* Footer spacer */}
720608
<div className="h-4" />
721609
</div>

0 commit comments

Comments
 (0)