2026.06.24
Electra AI Center — Release Notes (2026.06.24)
This patch release represents an exhaustive, multi-layered hardening of the Coder and Command execution loops (ai termina) and the WebKit-GTK GUI thread integrations (electra gui) .
🔴 Coder Fallback Rotations & Message Sanitization (ai terminal)
A series of execution-state and history-corruption bugs have been resolved to prevent redundant model rotations and downstream API validation rejections.
Clean Fallback Slate: Both the ChunkedEncodingError and general Exception fallback paths now cleanly reset all tracking metrics when rotating to a new model:
sarfailures = 0 — Clears search-and-replace failures, preventing the new model from immediately inheriting "Your last SAR call failed" steering.
consecutive_test_failures = 0 — Clears the consecutive test-failure counter.
stuckasked_this_episode = False — Re-enables the interactive user hint dialog for the new model's execution window.
Provider-Side Rate Limits & 5xx Failures: Added explicit pattern detection for "429 Too Many Requests (provider)" and HTTP 5xx responses (500, 502, 503, 504) to the isall_failed condition. Rather than silently pausing the agent, these external server errors now trigger an immediate model rotation to resume the task.
Double-Retry Model Bypass: Prior to clearing codertried during the second queue loop attempt queueretries_count < 2), the original failed model is explicitly added back to the tried list. This ensures the fallback logic doesn't immediately retry the first broken model on a secondary pass.
Context Token Calculations: Modified the ctxused calculation to parse and include tool_calls payloads (json.dumps(tool_calls)). Previously, context-size checks only read message content strings, drastically understating token estimates by tens of thousands of characters during heavy file-writing operations, which led to silent context overflows and server-side 400 errors instead of auto-compaction.
Double-Append Prevention & Safe History Appends:
Piped background system warnings BGCRASH_MESSAGES), plan auto-execution approvals ([PLAN AUTO-EXECUTE]), and lint/testing failures through safeappend_user() rather than bare coding_history.append(). This guarantees that mid-turn system updates do not result in consecutive same-role (user→user) blocks.
Optimized sanitizemessages Rule 3 to also drop orphaned assistant stubs that have no id properties if no matching tool results are found in the following messages, preventing validation rejections on strict backends.
🔴 Command Mode & GPS Session State Repairs (ai terminal)
Several state-loss bugs in the command-execution and terminal-helper threads have been patched.
GUI_KILL_FLAG Reset: Added GUI_KILL_FLAG.clear() at the non-continuation entry of process_command_message. Previously, the flag stayed set after a user pressed Stop, causing any subsequent command to instantly terminate on turn 0 before executing.
GPS Continuation Mapping: Bounded GPS indexing to the initial task gpssession_key. Previously, the 100-turn checkpoint continuation hashed the handoff string continuationmsg), creating a different key that cleared all plan/done/run progress and triggered redundant file-reads and shell commands.
Dynamic Fallback Filtering: Refactored getnext_command_model() to ignore models with a "reason" capability unless they also feature "tool" support. Removed pure-reasoning models (step-3.7-flash, ol-qwen3-next:80b) from COMMAND_FALLBACK_CHAIN and replaced them with specialized coding fallback options (llm7-codestral-latest).
Command Mode Idle Nudges: Implemented a command mode idle-turn tracker (cmd_idle_turns). If a model outputs text without calling tools mid-task, it injects a [SYSTEM: You MUST call a tool NOW] nudge and forces tool_choice = "required".
🖥️ WebKit DOM & GTK GUI State Syncing (electra gui)
Chat→Command Double-End Regression (Critical): Fixed a regression introduced by the earlier double endStream() fix where the GUI became permanently locked in a spinning state during Chat→Command routing. Split the dispatcher's state check into coderrouted (which bypasses the dispatcher's end() because coder manages its own lifecycle) and cmdrouted (which forces end() execution because command mode does not).
Spurious Bubble Prevention & History Deduplication: Captured CODING_MODE and COMMAND_MODE states before calling process_text_in_chunks(). If they change during execution, it suppresses the GUI dispatcher's start("Chat") bubble, preventing double-fires of stream_end(), duplicate console renderings, and duplicate history entry appends inside the sidebar panel.
WebKit2 API Compatibility: Refactored onapply_code_result to handle WebKit2 4.1/6.0 API variations safely. Replaced old WebKit2 4.0 run_javascript_finish and get_js_value().to_string() operations with compatibility try/except clauses that fall back to get_value() and str() equivalents, eliminating silent transfer failures.
LSP casting safeguards: Wrapped int() conversions on incoming line/column parameters for all four language server tools inside try/except (TypeError, ValueError) blocks with safe default fallbacks .
Model Syncing & Multi-Threaded Regenerations:
Wired GUI_INFO_CALLBACK and CURRENT_MODEL_ID syncs across all initial auto-routing and final teardown paths (8 locations) to update the bottom info bar and model picker dropdown highlighted states modelrow_btns).
Guarded handlechat_action("regenerate") with isai_working to prevent spawning concurrent backend threads writing to the same history and tool-use maps.
🔒 Batch-Write Type-Guards & Payload Checks (ai terminal)
A critical bug has been resolved where models (specifically larger reasoning models) mis-serialized their JSON payloads.
write_files Type Safeguards (Critical): If a model passed a string instead of a structured JSON array for the files key, the inner loop would iterate through characters and crash with 'str' object has no attribute 'get'. The system now enforces structural type checks on arrival:
If the files argument evaluates to a string, the tool rejects the call and returns a schema-correcting instruction to the model.
Validates that each element within the array is an instance of dict before invoking .get(), skipping malformed array items with console warnings instead of throwing unhandled exceptions.
File-Count Sanity Capping: Implemented an upper boundary of 50 files per write_files call. If a model attempts to write an excessive volume of files in a single pass (such as the 1,672 files detected in recent error logs), the tool rejects the payload, instructing the model to chunk its modifications into sequential batches.
Defensive Tool Wrapper Refactoring: Wrapped both command and novel mode execute_tool calls inside localized try/except Exception as e blocks. This matches the coder agent's existing resilience profile: any tool exception (permission errors, missing paths, invalid arguments) is converted to an informative error string and returned to the model as a tool execution output, allowing the agent to self-correct rather than breaking the history state and crashing the loop.
has_write_ops Completeness: Added write_files and search_and_replace_batch to the has_write_ops evaluation tuple within the coder idle-turn checker. This prevents false positive "No tool call detected" nudges after successful batch writes.
🚫 Reasoning Model Fallback Exclusions
Reasoning models (such as step-3.7-flash or ol-qwen3-next:80b) tend to over-plan and output massive thought blocks, making them highly unstable for structured tool-calling. This patch completely isolates them from agentic operations.
Model Re-Tagging: Re-tagged step-3.7-flash as "reason" (removed "tool") in MODEL_CAPABILITIES. Set CODER_FALLBACK_MODEL to llm7-codestral-latest (a purpose-built, stable tool-calling coder model).
Comprehensive Reason-Filtering:
Removed reasoning-only models from both CODER_FALLBACK_CHAIN and COMMAND_FALLBACK_CHAIN.
Filtered out any model containing the "reason" capability tag within all fallback candidate loops (stream-error paths, all-models-failed paths, and getnext_command_model loops) unless the model also explicitly possesses the "tool" capability tag.
🏎️ Connection & Retry State Alignment (ai terminal)
streamretries[turn] Reset on All-Failed Switch (Medium Severity): When the SSE loop hit a non-stream error (all-failed, API bad requests, or keys exhausted) and rotated models, streamretries[turn] was never reset. The new model inherited the stale retry count (e.g. 3/3), meaning any minor stream drop immediately triggered another model rotation. The state is now reset to 0 upon rotation.
BGCRASH_MESSAGES Queue Concurrency Guard: Ensured that background crash/pinned file messages injected via BGCRASH_MESSAGES are mapped to safeappend_user() to prevent consecutive user-role messages.
Core Loop Unhandled Exception Protection: Wrapped the entire Coder loop within an outer try/finally block. If an unhandled exception manages to escape the loop, it now programmatically decrements CODERCHECKPOINT_DEPTH to prevent resource leaks and schedules stream_end() to unlock the GUI spinner.
🖥️ GTK Thread Safety & Double-Output Fixes
GUI Thinking Console Double-Output (Medium Severity): When GUI_MODE=True, thinking chunks were sent to both GUI_STREAM_CALLBACK and sys.stdout. The terminal launched by the GUI was getting a raw cyan dump of all thinking text while the GUI panel was also rendering it. Gated the stdout write on not GUI_MODE.
diffconfirm Main Thread Safety: If DIFF_PREVIEW=True and GUI_CONFIRM_CALLBACK had not yet been wired (early in startup), the if GUI_MODE check fell through to terminal input(), freezing the GTK main thread. Added a safe fallback that auto-approves diffs and logs the event to prevent deadlocks.
🧩 Open VSX Extension Subsystem & Asset Extraction
We have implemented an asynchronous, non-blocking extension panel in the sidebar to download and ingest VS Code extensions directly from the open-source Open VSX Registry (open-vsx.org).
- .vsix Extraction & Lifecycle Management
VSIX Zip Ingestion: The client queries the Open VSX API, fetches requested .vsix packages (standard ZIP files), and extracts contents locally to ~/.config/electra/extensions/publisher.name/ .
Package Contribution Parsing: The setup engine parses package.json configurations to identify and register contributed static assets:
TextMate Grammars (.tmLanguage / .tmLanguage.json): Copies these definition files directly to the GtkSourceView language-specs/ system directories. This activates native syntax highlighting on subsequent application loads for new file types.
JSON Snippet Sheets: Parses and copies snippets to ~/.config/electra/snippets/.
Color Themes: Parses VS Code theme configurations, strips JSON comment blocks, normalizes 8-digit hex values (#RRGGBBAA), and registers them directly with the Electra THEMES dictionary, allowing live selection without a recompile.
Active AI Context Injection: Every coder turn now appends an [INSTALLED EXTENSIONS] block to the system prompt, detailing installed extension names, versions, snippet triggers, and detected active LSP configurations. This enables the AI to dynamically adapt its recommendations based on available tools.
✂️ Tabstop-Navigable Snippet Engine
The editor now features a full-featured snippet expansion engine that operates natively with GtkSourceView buffers.
Dynamic Expansion (Tab key): Typing a designated snippet trigger word and pressing Tab parses and expands the JSON snippet body inline.
VS Code Variable Resolution: Remaps standard TextMate variables on insertion:
${TM_FILENAME} / ${TM_FILENAME_BASE} — Resolves to the active file name or base.
${TM_DIRECTORY} — Resolves to the absolute workspace directory of the file.
${TM_SELECTED_TEXT} — Preserves active text selections.
Interactive Tabstops:
Cursor focus automatically snaps to target tabstops ($1, $2, $3), pre-selecting any placeholder text.
Pressing Tab increments the focus index to the next tabstop.
Pressing Esc terminates navigation and restores standard keyboard inputs.
Searchable Snippet Palette (Ctrl+Shift+S): Added a searchable popover listing every snippet trigger word, extension origin, and description. Selecting an entry inserts the snippet with active tabstop navigation.
🗺️ Coder Elite: Spatial Context & Live Code Maps
To prevent memory decay during long multi-file agentic runs, we have deployed the Live Code Map framework.
Live Workspace Mapping lcmupdate): Every time the agent modifies a file, the system updates a persistent Live Code Map. It records the relative filepath, the agent turn index of the change, and a concise, extracted header description.
Turn-by-Turn GPS Injection: The completed map is injected as an active metadata block into every system turn:
codeCode
[LIVE CODE MAP — auto-updated each write] src/api.py (t3) — FastAPI app, 3 endpoints src/db.py (t7) — SQLite wrapper
This prevents the model from experiencing spatial amnesia during multi-turn tasks, eliminating redundant files read passes or write attempts to obsolete paths.
🧠 Intent-Aware Tool Routing & Error Parsing
We have added dynamic routing boundaries to restrict model actions based on the immediate intent of the user's prompt.
Zero-Turn Intent Classification classifycoder_intent()): Evaluates the user's prompt prior to tool selection, confining model actions to specific tool subsets:
Debugging (DEBUG_TOOLS): Restricts access to diagnostic and read tools. The model is forced to inspect file buffers and analyze stack traces before it is granted permission to write code.
Refactoring (REFACTOR_TOOLS): Limits workspace modifications to precise hunk edits to prevent bulk file destruction.
Explanations (READONLY_TOOLS): Strips all writing and system execution tools.
Note: This restriction profile mitigates tool-selection errors on smaller, cheaper cloud models.
Structured Error Parsing: Intercepts noisy compiler and POSIX traceback messages before the AI processes them. Parses long traceback blocks into focused signal blocks, pinpointing the specific file, line number, and compiler notification (e.g., [STRUCTURED ERROR] Python TypeError at src/api.py:47) to enable fast, single-pass fixes.
⚡ Interactive Next-Step Suggestions
Completing an agentic task now triggers an automated next-step suggestion workflow.
Background Completion Task: Following a task completion event (complete_task), a lightweight background API call evaluates the modified workspace files and generates three contextually relevant next-step tasks.
Horizontal Suggestion Bar: Renders three styled, accent-bordered action buttons below the chat response.
Pre-Filled Automation: Clicking a suggestion button pre-fills the chat text area and automatically dispatches the prompt, enabling seamless multi-task chaining with zero manual typing.
🧠 New Prompt Compression / Token Efficiency Layer Explained.
Inspired by the new GLM 5.2 "index share / reusing attention indices across multiple layers" feature. We have implemented the following :
Instead of just trimming history, actively compress it. Before sending to the API, we run a local compression pass:
Tool results over 500 chars get summarized to their key findings
Repeated file content chunks get duplicated into a reference: [file.py already read — line 45-120]
Consecutive assistant text turns get merged
This is our version of "index share" — we reduce what the model needs to process, which directly improves output quality on smaller models because their limited context window gets filled with signal, not noise. This greatly improves the performance of all models, especially the smaller models.
🔴 Checkpoint Auto-Continuation Structural Fix (ai terminal)
The Python for/else Structural Trap: Resolved a logic bug in the multi-turn agent execution loop [1]. The else: block designed to act as a loop-exhaustion handler (for running checkpoint continuations on turn 80) was actually bound to the preceding if FILES_MODIFIED and not COMMAND_MODE statement [1].
The Symptom: Checkpoint continuations only fired when FILES_MODIFIED was completely empty (i.e., tasks with zero file modifications), and never executed during normal, productive coding sessions [1].
The Solution: Introduced a thread-safe sentinel boolean loopexhausted = True before the loop, programmatically set it to False across all 12 explicit break paths, and replaced the misplaced else: statement with a clean if loopexhausted: condition [1].
Continuation Double-Append Prevention: Resolved an issue where the checkpoint continuation logic recursively called process_coding_message but double-appended the continuation user message, generating duplicate conversational stubs [1].
Model Override Retention: When users deliberately change models via the GUI selector during a running task, the post-loop model restoration now detects GUIMODEL_OVERRIDE and preserves the user's manual selection instead of forcing a fallback revert [1].
🔴 Context Leakage Prevention & Session Hygiene (ai terminal)
- Conversation ID Regeneration
The Problem: Clearing the chat panel (CLEAR_CHAT) or changing active modes (MODE_CHANGE) reset local memory buffers but did not generate new UUID session hashes (coding_conversation_id or command_conversation_id) [1].
The Impact: The backend server preserved old session logs in its own memory cache using the stale UUID key [1]. This caused models in new sessions to refer to files and variables from previous projects [1].
The Fix: Integrated explicit UUID-4 regeneration calls inside both the CLEAR_CHAT and MODE_CHANGE handlers:
codePython
coding_conversation_id = str(uuid.uuid4())
Both variables have been added to the global definitions inside guibackend_handler to prevent local scope trapping [1].
- State Reset Hardening
PREFLIGHTWARNED Reset: Shifted the PREFLIGHTWARNED context-limit warning state from a sticky global flag to a per-task initialization variable, resetting it on process_coding_message entry and within CLEAR_CHAT actions to ensure subsequent long sessions are properly warned [1].
Session and File List Clears: Configured the CLEAR_CHAT callback to reset SESSION_TURN_COUNT = 0 and FILES_MODIFIED = [], preventing "15+ turn" warnings from firing on the first prompt of a cleared session [1].
🔒 GTK Main-Thread Safety & Event Locks (electra gui)
isai_working Lockout Race: During checkpoint auto-continuation, the outer process_coding_message loop returned and scheduled backenddone on the GTK thread while the inner recursive call was starting [1]. This occasionally unlocked the UI (re-enabling text fields and send buttons) while the background agent was still running [1]. Modified stream_start() to set selfisai_working = True directly, ensuring the UI remains locked [1].
New Chat Input Guard: Guarded on_clear_clicked (New Chat) with an isai_working check [1]. This prevents users from initiating a history wipe on the background thread while the model is actively writing to those same buffers [1].
Model Dropdown Highlight Synchronization: Configured update_info_bar to synchronize selection states across all model selection widgets modelrow_btns), ensuring the dropdown UI correctly reflects active fallback models [1].
⚙️ WebKit DOM & SSE Stream Adjustments
Stream Bubble ID Collision Guard: The WebKit-JS layout uses a unique #current-stream selector to stream data chunks [1]. If a new stream started before the old one was officially closed (common during recursive continuations), duplicate IDs existed in the DOM, corrupting the text rendering [1]. Updated the startStream JS routine to check for and cleanly close any existing open stream bubbles prior to initiating a new one [1].
3P Fallback Error Silencing: When a direct-provider (3p-*) model failed, the code previously appended an error chunk ("
Model Specific Routing Bugs Fixed:
🔴 Critical ai terminal Add try/finally to safeagent_call to fire GUI_STREAM_CALLBACK("end") on crash
🔴 Critical ai terminal Remove "T" from gpt-o4-mini in MODEL_DISPLAY_INFO, remove from command set
🟠 Medium ai terminal Add "Ag" to gpt-oss-120b and zai-glm-4.7 in MODEL_DISPLAY_INFO
🟠 Medium ai terminal Add "Re" to minimaxai/minimax-m3 and minimaxai/minimax-m2.7 in MODEL_DISPLAY_INFO
🟠 Medium ai terminal Remove gpt-o4-mini and deepseek-r1-0528 from ROUTEDMODEL_SETS["command"]
General Routing / Coding / Command Bigs Fixed
🔴 Critical process_coding_message + process_command_message Infinite recursion → stack overflow on long tasks, no depth guard
🔴 Critical gui backend_handler command mode Double end() on kill during checkpoint continuation
🔴 Critical process_coding_message CODING_MODEL not restored if inner checkpoint call crashes
🟠 High process_command_message continuation Inner fallback rotations leak CODING_MODEL permanently
🟠 High CLEAR_CHAT handlerStale coding_history if enable_coding_mode raises
🟠 High GUI_MODEL_OVERRIDEFlag consumed by wrong mode; model override lost
🟠 High select_context_aware_coder_modelLarge-context path uses unsorted list — always picks first-online instead of fastest
🟠 High MODE_CHANGE → CommandMay inherit fallback-rotated model with no tool-calling capability
🟡 Medium Speed cache TTL15min TTL too long for time-of-day opr- limits
🟡 Medium CANCEL handler3s auto-clear can clear kill flag before slow subprocess returns
🟡 Medium sanitize_messages Bridge stubs accumulate over checkpoints, bloating context
🟡 Medium MODEL_DISPLAY_INFO "Ag" tagging deepseek-v4-flash missing tag — unfairly deprioritized in command routing