2026.06.18
Electra AI Center — Release Notes (2026.06.18)
This release implements a new Electra AT-SPI / Electra D-bus system, a total hardening of the agentic execution core inside ai terminal and electra gui. Over 40 distinct stability bugs—discovered during a 11-round audit of the coder and command mode loops—have been resolved to prevent stream-dropout freezes, execution memory loss, payload structural violations, and main-thread graphical stuttering [1].
⚡ New Electra AT-SPI - What is AT-SPI?
AT-SPI stands for Assistive Technology Service Provider Interface. It is the standard Linux accessibility layer — the same infrastructure used by screen readers for visually impaired users. Every GTK, Qt, and Electron application on your desktop exposes its UI structure through AT-SPI automatically: the text content, button labels, window titles, input field values, menu items, and document content are all readable by any process that connects to the AT-SPI bus.
Electra now connects to this bus through a lightweight background daemon (electra_atspi_daemon.py) and reads whatever application you currently have focused.
What does it actually give the AI?
Every 2.5 seconds, the daemon captures:
The name of the focused application (e.g. Firefox, Gedit, LibreOffice Writer, Nemo, Terminal)
The window title (e.g. "GitHub — Mozilla Firefox", "main.py — Gedit")
The current URL if a browser is focused (extracted from the address bar)
The focused widget — which input field, button, or text area the cursor is in
The visible text content of the active window — document text, terminal output, web page content, file listings, error messages — up to 3,000 characters, trimmed intelligently from start and end
This is written to /tmp/electra_atspi_context.json and injected into the AI's system prompt on every message.
What this means in practice:
You see an error in Firefox → ask Electra "what does this mean?" → Electra has already read the page, no copy-paste needed
You're looking at a terminal with a failed build → ask "why did this fail?" → Electra read the output
LibreOffice document is open → ask "summarise this for me" → Electra read the document
You're browsing a GitHub issue → ask "what's the fix?" → Electra has the issue text
File manager open on a folder → ask "which of these files is the largest?" → Electra sees the listing
What it does NOT do:
It does not take screenshots — purely text via accessibility API
It does not record anything — context is read live, not stored
It does not read password fields — AT-SPI masks password role widgets
It ignores the Electra app itself to avoid circular context
⚡ New Electra D-Bus - What is D-Bus?
D-Bus (Desktop Bus) is the standard inter-process communication system on Linux. It is the backbone of the entire Linux desktop: every notification you see, every volume change, every network status update, every media player control — all of it travels over D-Bus. By registering a name on the D-Bus session bus, an application becomes reachable by any other application running in the same desktop session.
Electra now registers org.makululinux.Electra on the D-Bus session bus through a background daemon (electra_dbus.py), which means any application, script, keyboard shortcut, or file manager plugin on your desktop can send queries to Electra and receive responses without going through the GUI.
What is exposed?
The daemon exposes the following interface at /org/makululinux/Electra:
MethodWhat it doesPing()Health check — returns "pong". Use to verify the daemon is alive.ExecuteIntent(query)Send any natural-language query to Electra's AI. Returns a request ID immediately, fires a ResponseReady signal with the answer when done.GetContext()Returns a JSON blob with the current Electra context: active workspace path, current AT-SPI screen content, and model information.Notify(title, body)Send a desktop notification through Electra. Uses notify-send under the hood.TileWindows(layout)Command the compositor to arrange windows. Supports Hyprland (hyprctl) and generic X11 (wmctrl).
What this makes possible (building blocks for future features):
Nemo right-click integration: "Ask Electra about this file" → one dbus-send call → response in a dialog
Global keyboard shortcut: bind any hotkey to send selected text or clipboard content to Electra instantly
Custom application integration: any app built by you or third parties can query Electra's AI without embedding API keys
Automation scripts: shell scripts and cron jobs can use Electra's AI as a reasoning engine
Voice assistant integration: bind a push-to-talk key → transcribe → ExecuteIntent → speak response
Other desktop apps: any GTK, Qt, or terminal application can become "Electra-aware" with three lines of code
The ResponseReady signal:
Because AI responses take time, ExecuteIntent is non-blocking. It returns immediately with a request_id and fires a D-Bus signal ResponseReady(request_id, response) when the answer is ready. Any application that wants to receive Electra's response just listens for this signal on the session bus.
🔴 Stream Dropout Resiliency & Fallback Model Rotations (ai terminal)
A major focus of this release was addressing failures in the stream interruption and fallback recovery paths [1].
Elimination of Stale Connection Counters: Removed a persistent, function-attribute counter (process_coding_messageconnretries) [1]. Previously, this counter tracked cumulative network hiccups across separate tasks [1]. Once it reached 3, it permanently locked, causing all subsequent stream interruptions to immediately abort without attempting model switches [1].
Per-Turn Retry Budget: Replaced the global counter with streamretries (a per-call dictionary keyed on the active turn index, reset dynamically) [1].
Dynamic Model Switching: If a stream fails (e.g., ChunkedEncodingError, connection timeouts, server drops) and exhausts its 3-retry budget, the loop now rotates to the next model in CODER_FALLBACK_CHAIN rather than stopping [1].
Context-Preserving Handoff Messages: Upon switching models mid-task, a structured [HANDOFF] user message is injected into the conversation history [1]. This message informs the replacement model:
Which model it is replacing and the error that triggered the handoff [1].
Which files have already been modified during the session [1].
Which tool calls were completed (e.g., write_file×3, read_file×1) [1].
An explicit instruction directive: "Continue the task — do NOT restart from scratch" [1].
🔴 Thread-Safe Message Sanitization sanitize messages
To prevent upstream API validators from rejecting payloads due to structural history violations (which return HTTP 400 Bad Request and crash the loop), we designed a module-level message sanitization engine sanitizemessages) [1]. This engine validates and repairs the active message list before every API dispatch in both Coder and Command modes [1]:
Consecutive Role Deduplication: Prevents back-to-back same-role messages [1]. If consecutive user/user messages occur (e.g., a handoff note injected right after a user's prompt, or a manual file pin), the system wraps the call with a new safeappend_user helper to insert a minimal assistant confirmation bridge [1].
Empty and Null-Content Pruning:
Replaced content: null definitions (which occur when reasoning/thinking models output tool calls but no text) with content: "" to satisfy strict schema validators [1].
Prunes empty assistant stubs (content=None, tool_calls=None) [1].
Orphaned Tool Result Cleaning: Automatically strips tool result messages if their matching tool_calls definitions were dropped during a stream interrupt, and ensures payloads always end on a user role to comply with strict 3rd-party APIs [1].
🔴 Coder and Command Agentic Loop Hardening (ai terminal)
History Snapshot Bug Fix: Resolved a command mode bug where historysnapshot_len was captured before user_input was appended to command_history [1]. On model switches, the rollback deleted everything from index 1 onward, wiping out the user's initial prompt and causing fallback models to start with zero context [1]. The user message is now appended first [1].
Automatic Checkpoint Continues (Turn 80): In GUI mode, when hitting max_turns = 80, instead of silently stopping and abandoning the task, the agent now automatically appends a checkpoint summary and continues [1].
Safe Tool Parameter Casting: Wrapped int casts inside read_file (max_lines) and all four LSP tools (lsp_goto_definition, etc.) in try/except statements [1]. If models pass None or a non-numeric string (common with smaller models), the system falls back to default values instead of throwing unhandled exceptions [1].
Auto-Compactor Data Sanitization: Fixed a critical bug in autocompact_session where raw message lists containing "tool" or "tool_calls" roles were forwarded to /v1 compactors without schemas [1]. This triggered silent HTTP 400 errors, causing the session memory to compact into a blank handoff [1].
🟡 Cairo context & GTK Keystroke Repair (electra gui)
Gdk backslash Keypress Crash: Fixed the editor keyboard event listener to map the correct GTK property Gdk.KEY_backslash (lowercase) instead of the broken Gdk.KEY_BackSlash (capital S) [1]. Because this listener evaluates every keystroke globally, the typo was throwing AttributeError exceptions on every single key pressed in the editor [1].
Cairo Context Type-Bridge Failures: On Debian/Ubuntu installations lacking proper Python-to-GI Cairo bindings, GTK's native draw events (used for minimaps, theme swatches, and intro tours) threw constant TypeError: Couldn't find foreign struct converter for 'cairo.Context' warnings [1]. Added a CAIROOK startup check to gracefully disable drawing bindings if the foreign structure converter is missing, eliminating console noise [1].
Synchronous Workspace Shifts: Converted remaining synchronous folder and workspace-change calls to use background threads, eliminating multi-second UI freezes during filesystem indexing [1].
⚙️ Diff Panel & Autocomplete Optimizations (electra gui)
Diff Tab Accumulation Capping: To prevent the editor bar from being cluttered with permanent Δ filename tabs, we integrated sdiffdone_tabs [1]. The layout now limits auto-mode diff tabs to a maximum of 3, automatically removing the oldest tab from the notebook when a new one is appended [1].
Ghost Text Concurrency Block: Added a check to the ghost-text auto-completer ghosttrigger) to immediately return False if selfisai_working is True [1]. This prevents autocomplete completions from firing while the agent is writing files, saving API token budgets [1].
Electra AI Center — Notes (2026.06.17)
This release implements a variety of critical fixes resolving synchronous main-thread GUI blocking, 3rd-party/offline streaming pipeline failures, AST/compiler exception recoveries, and an import-time permission deadlock inside the ISO Agent module [1].
Additionally, the project release notes have undergone an 80% truncation pass, leaving only the three most recent detailed changelogs intact and summarizing earlier legacy achievements into a single high-density background block [1].
🔴 Synchronous Main-Thread GUI Block Fixes (electra gui)
Background Thread Offloading: Click events on Mode Tabs onmode_btn), Folder Pickers (on_open_folder_clicked), the Workspace Switcher onws_switch), and the Clear Chat dialog (on_clear_clicked) were invoking backend_handler(...) synchronously on the GTK main thread [1].
The Performance Issue: The backend enable_coding_mode() procedure performs heavy filesystem indexing countproject_files, indexproject_cached, and build_project_context), which freezes the entire GUI window for up to several seconds during every mode or workspace switch [1].
The Resolution: All three action types (MODE_CHANGE, WORKSPACE_CHANGE, and CLEAR_CHAT) now dispatch asynchronously to a dedicated daemonized worker thread, preventing main-thread GUI blocking [1]. Added a named backendmode_change_worker thread to catch and log any internal state errors cleanly [1].
🔴 3P & Offline Stream Routing Corrections (ai terminal)
- 3rd-Party GUI Streaming Pipeline
The Problem: When 3rd-party API providers (OpenAI direct, Groq, xAI, Perplexity, etc.) were active in Coder/Writer modes, 3pstream_chat only wrote chunks to standard output (sys.stdout.write) and bypassed the WebKit chat view [1]. Furthermore, the routing loop fired a terminal "end" callback without a preceding "start" event, resulting in a completely silent response inside the GUI [1].
The Fix:
Moved the GUI_STREAM_CALLBACK("start", phase=...) event to fire before initiating 3P stream routing [1].
Added a gui_callback parameter pass to 3pstream_chat() [1]. Both the Anthropic and OpenAI-compatible SSE chunk loops now dynamically pipe incoming data packets to gui_callback("chunk", chunk, False) [1].
- Ollama / Offline Mode GUI Unlocking
The Problem: The local model execution path bypassed standard WebKit stream bindings [1]. In GUI mode, this left the interface permanently locked at completion with no printed output and an unreleased focus state [1].
The Fix: Wrapped the local/Ollama response generation inside a standard start-chunk-end stream callback lifecycle, ensuring proper UI unlocking on exit [1].
🔒 Compactor Token Validation & Thread-Safe Guards (ai terminal)
- Session Compaction Schema Failures (Critical)
The Problem: During auto-compaction routines autocompact_session and autocompact_command_session), raw message lists containing "tool" or "tool_calls" roles were forwarded directly to chat completion endpoints without their matching tools schemas [1]. This triggered silent HTTP 400 Bad Request exceptions on upstream servers [1]. Because raise_for_status() was absent, the handler returned a blank string, wiping out all AI session context [1].
The Fix:
Filtered history payloads to system/user/assistant roles [1].
Flattened complex list-type message contents, enforced a max_tokens: 1024 cap, and added an explicit raise_for_status() validator to capture future network failures [1].
- Dry-Run Thread Deadlocks (Critical)
The Problem: Running shell operations through run_command while in DRY_RUN_MODE invoked a bare terminal-only input() prompt [1]. In GUI mode, this permanently deadlocked the background worker thread [1].
The Solution: Intercepted the prompt and routed the query through GUI_CONFIRM_CALLBACK when running in GUI_MODE, reserving CLI input() only for terminal sessions [1].
💿 ISO Agent Import-Time Permission Fix (iso agent v2)
The Problem: A 4-line testing script was left at module scope inside iso_agent.py:
codePython
with open('/tmp/iso_part1.py', 'a') as f: import inspect pass print("part1 appended OK")
Because this executed at import time, any permission restriction on the /tmp/iso_part1.py file path (such as files created by a previous root execution) raised [Errno 13] Permission denied [1]. This caused the entire module import to fail when a user confirmed a build, crashing the terminal session before any function was invoked [1].
The Fix: Removed the module-level test lines, resolving the permission crash [1].
⚡ Additional Subsystem & Tool Refactorings
- Dynamic Host OS Diagnostics
The system prompt previously instructed the AI "OS: Unknown, you need to detect the OS", forcing models to waste their first agentic turn running discovery commands like uname [1].
The system now queries host parameters once on startup (via /etc/os-release, uname -r, uname -m) and injects them directly into the system prompt (e.g., "OS: MakuluLinux 2025 kernel 6.8.0-51-generic x86_64") [1].
- LSP Numeric Line Exception Handling
The four language server tools (lsp_goto_definition, lsp_find_references, lsp_rename_symbol, lsp_hover) cast line parameters using int(args.get("line", 1)) [1]. If models passed a non-numeric string or None, this raised unhandled casting exceptions that crashed the loop [1].
Wrapped all four casts in try/except (TypeError, ValueError) with fallbacks [1].
- Comprehensive Diff Preview Finalization
Added streaming_diff_done triggers to search_and_replace, edit_file_lines, and search_and_replace_batch [1]. This allows diff panels to resolve out of "pending" states immediately upon tool completion [1].
Integrated full workspace tree updates, file-open actions, and activity log tracking for patch_file operations [1].
- Double-Refreshes & Handoff Tracking
Idempotency Guard: Added a selfisai_working state check to backenddone inside electra_gui.py to prevent duplicate file tree refreshes and focus grabs on recovery paths [1].
Handoff Age Calculation: Cleaned up a double syscall in hfage_days checks, replacing the logical and statement with a clean variable assignment [1].
🧩 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 deduplicated 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.