Menu

Tree [11721d] master /
 History

HTTPS access


File Date Author Commit
 spyder_ai_chat 2026-07-12 mp_amd\mpieck mp_amd\mpieck [11721d] v 1.0.7 chat history list deletion fix
 .gitignore 2026-04-11 mp_amd\mpieck mp_amd\mpieck [14c889] version 0.8.1 fixes
 LICENSE 2026-03-01 mp_amd\mpieck mp_amd\mpieck [c38e99] version 0.1.2
 README.md 2026-07-12 mp_amd\mpieck mp_amd\mpieck [11721d] v 1.0.7 chat history list deletion fix
 README_PYPI.md 2026-07-12 mp_amd\mpieck mp_amd\mpieck [11721d] v 1.0.7 chat history list deletion fix
 pyproject.toml 2026-07-09 mp_amd\mpieck mp_amd\mpieck [b8b7e8] v 1.0.7 introducing xml tool call template
 spyder_ai_chat_plugin_bg.png 2026-04-30 mp_amd\mpieck mp_amd\mpieck [66e316] v. 0.8.8 collapsable agentic actions, git check...

Read Me

Spyder AI Chat Plugin

An OpenAI-compatible chat pane for Spyder 6.1+.
Supports 12 providers out of the box — OpenAI, Groq, Mistral, DeepSeek, Together AI, Fireworks AI, OpenRouter, Azure OpenAI, Ollama, LM Studio, vLLM, and any custom OpenAI-compatible endpoint — all from inside your IDE without switching windows.

© 2026 Maciej Piecko — MIT License


Features

Feature Details
🗨️ Chat UI Scrollable conversation with colour-coded user / assistant messages
⚡ Streaming Token-by-token streaming with incremental markdown rendering — completed blocks are formatted live as they arrive
🔁 Model selector Dropdown populated live from the API — switch models instantly
🔧 12 providers OpenAI, Groq, Mistral, DeepSeek, Together, Fireworks, OpenRouter, Azure, Ollama, LM Studio, vLLM, Custom
⚙ Inference parameters Per-chat temperature, max tokens, top-p, top-k, min-p, penalties, seed, num_ctx — provider-aware (only relevant params shown)
🔑 Optional API key Leave blank for local models that require no authentication
🧠 System prompt Custom system prompt field, or select from a saved prompts library
💬 Saved system prompts Define reusable system prompts; manage via Settings → System Prompts tab
⏹ Stop Cancel a streaming reply at any time
▶ Send controls Composer action row with + Image, inference params, context estimate, > Send, and [] Stop controls grouped below the prompt field; Send shows a small animated spinner while the LLM is generating
🗑 New Chat Start a fresh conversation; the current one is saved automatically
📋 Chat history Browse, load, and delete saved chats; live search by title or content; active chat highlighted in green
📄 Chat history paging Chats longer than 120 messages are split into pages; centered << / < / numbered / > / >> navigation bar below the chat area; current page highlighted; page bar hidden for shorter chats
🗂 Chat collections Organise chats into named collections; create, rename, and delete collections via the ⚙ manager; move chats between collections with right-click; search within a collection or across all collections
📎 File context Attach whole files or selected text from the editor, or IPython console output, as context — colour-coded tags in the input bar; Ctrl+Shift+A (add file) and Ctrl+Shift+Q (add selection) keyboard shortcuts available in the editor
🖼 Image attachments Attach images (JPEG, PNG, WebP, GIF) to any message via the + Image composer button or by pasting a screenshot from the clipboard (Ctrl+V); violet chips with thumbnail hover preview; images scaled and base64-encoded before sending; vision-capable providers only (OpenAI, Groq, Mistral, Ollama, LM Studio, vLLM, and others — DeepSeek excluded); max dimension and JPEG quality configurable in Settings → Context → Image attachments
📁 Project context Attach the entire Spyder project to the chat with the 📁 Proj. Context toggle — folder selection, delta updates, live buffer for unsaved edits, file change detection
🖊️ Markdown rendering Headings, bold, italic, tables, code blocks (with horizontal scroll), blockquotes, links, strikethrough
🗂 Nested lists Arbitrarily deep bullet & numbered lists, mixed types, blank-line-separated items
🧠 Thinking blocks <think> tags rendered as a collapsible scrollable thinking box (DeepSeek-R1, QwQ, Qwen-thinking …)
📋 Copy to editor Insert any code block or full response at the cursor in the active file
🗑 Delete exchange Remove any exchange with a 3-second undo window; or clear all exchanges before a point
🔄 Regenerate Re-run the last assistant response with one click; button greys out immediately after click while the retry is prepared
⚙ Settings Tabbed dialog: provider connection, dialog font sizes, history options, system prompts library, slash commands, AI auto-complete
/ Commands Define slash-command aliases (e.g. /tests, /explain) — type / in input to get a picker dropdown; commands expand to full prompts before sending
⚡ Built-in commands Plugin-defined commands shown with ⚡ prefix in a separate dropdown section — not user-editable; /compact (manual LLM summary compaction) and /clear (wipe conversation, keep all settings)
📊 Context size estimate Always-visible ~X.Xk / Yk (Z%) token counter in the composer action row — colour-coded by usage level; hover for a per-category breakdown popup (history, system prompt, context files, compaction buffer)
✍️ AI auto-complete FIM (fill-in-middle) ghost-text completions in the editor — supports Ollama, LM Studio, vLLM, DeepSeek, Codestral/Mistral, OpenRouter, and custom endpoints
🤖 Agentic mode LLM can use configured tools for file operations, project inspection, Python console runs, git, lint, HTTP, and waits — actions execute through the Semi/Full response-processing flow
🤖 Autonomous modes Semi — batch dialog + auto-send after each response; Full — silent or confirm-modifying execution, results always auto-sent; ℹ behaviour-matrix popup in settings
🔎 Lint tool lint: runs pylint on a file, directory, or glob pattern; returns compact inline summary (all errors, first 5 warnings, counts for conventions/refactors) with source lines injected; full per-file JSON reports written to .ai_chat/lint/; optional pylint args in the tool body; triggers Spyder's Code Analysis panel for single-file and multi-file runs

Installation

Install from PyPI

pip install spyder-ai-chat

Install from source

# Unzip the release archive, then:
cd spyder_ai_chat
pip install -e .

Important: install into the same Python environment that Spyder uses.
If you launched Spyder from a conda environment, activate that environment first.

After installation, restart Spyder.
The plugin appears automatically; if the pane is not visible go to
Window → Panes → AI Chat to show it.


Configuration

Click the ⚙ Settings button in the plugin pane toolbar to open the tabbed settings dialog.

Tab 1 — Connection

Select your provider from the dropdown. The form updates automatically to show only the fields relevant to that provider.

Provider Default URL API key
OpenAI https://api.openai.com/v1 Required
Groq https://api.groq.com/openai/v1 Required
Mistral AI https://api.mistral.ai/v1 Required
DeepSeek https://api.deepseek.com Required
Together AI https://api.together.xyz/v1 Required
Fireworks AI https://api.fireworks.ai/inference/v1 Required
OpenRouter https://openrouter.ai/api/v1 Required
Azure OpenAI https://<resource>.openai.azure.com/… Required + deployment name + API version
Ollama (local) http://localhost:11434/v1 Not required
LM Studio (local) http://localhost:1234/v1 Optional
vLLM http://localhost:8000/v1 Optional
Custom (any URL) Optional

A Test Connection button sends a GET /models probe to the configured endpoint and reports how many models are available, helping verify credentials and reachability before saving.

Tab 2 — Dialogs

Configure font sizes (6–24 pt) for each rendered element independently:

Setting Default Affects
Base text 10 pt Paragraphs, blockquotes
Code blocks 10 pt Fenced code block content
Headings (H1 base) 14 pt H1 = base, H2 = base−2, H3 = base−4
Lists 10 pt Bullet and numbered lists
Tables 10 pt Table header and data cells
Thinking box 9 pt <think> block content

Changes apply to new messages rendered after saving.

Tab 3 — History

  • Automatically save chats to history — when on, every completed exchange is written to disk silently.
  • Save unsent chat when starting New Chat — only relevant when auto-save is off; gives a one-time save at the moment you click New Chat.

Tab 4 — Context

Configure limits and exclusion rules for the 📁 Proj. Context feature.

  • Max file size — files larger than this limit are skipped when collecting project context.
  • Max file count — cap on the total number of files included per send.
  • Extra exclusion patterns — additional glob patterns (on top of built-in exclusions and .gitignore rules) used to filter out files from project context.

Tab 5 — System Prompts

Manage reusable system prompts. Selecting a prompt from the dropdown immediately opens it for editing. The 💾 Save prompt button activates only when the title or content has been modified. Use + New to create a prompt and Delete to remove the currently selected one.

Tab 6 — Commands

Define slash-command aliases for the chat input field. Type / in the input box to open the command picker dropdown and select a command — it is inserted as a short token (e.g. /tests) that expands to its full prompt text before being sent to the LLM. Built-in plugin commands appear at the bottom of the picker with an ⚡ prefix and blue-purple colour.

Built-in commands (read-only) — shown in a group box at the top of the tab. These are provided by the plugin and cannot be edited or deleted:

Command Visible when
/compact Compaction enabled + LLM Summary strategy + Full autonomous mode + Project Context off
/clear Always

User-defined commands — selecting a command from the list immediately opens it for editing. The Save command button activates only when the name or prompt has been changed.

  • + New — create a new command (name ≥ 2 characters, no leading /; built-in names are reserved)
  • Delete — remove the currently selected command
  • Restore built-in defaults — resets the 5 default commands (/tests, /simplify, /fix, /explain, /doc) to their default prompts without affecting user-defined commands

Commands are stored in ~/.spyder_ai_chat/commands.json.

Tab 7 — Auto-complete

Configure AI-powered fill-in-middle (FIM) ghost-text completions in the Spyder code editor. Auto-complete is disabled by default and requires explicit setup.

Setup steps:

  1. Check Enable AI auto-completion in the editor.
  2. Select a Provider and enter the API URL (pre-filled for known providers).
  3. Click Load Models — the plugin fetches the model list and probes which FIM backends the endpoint supports.
  4. Choose a Model and Backend type from the populated dropdowns.

Backend types (probed automatically, working ones shown first):

Backend Endpoint Notes
Ollama /api/generate /api/generate Native FIM — best choice for Ollama
OpenAI-compat /v1/completions /v1/completions Legacy completions — LM Studio, vLLM
Codestral /v1/fim/completions /v1/fim/completions Mistral / Codestral native FIM
Chat completions /v1/chat/completions Prompt-injection fallback — any provider

Model Parameters: max tokens, temperature, context window before/after cursor.

Trigger modes:

  • Auto — completion fires after a configurable debounce delay (default 600 ms)
  • After new line only — fires only when a newline is typed
  • Manual only — press Alt+\ to request a completion

Ghost text appears in grey after the cursor. Press Tab to accept, Escape to dismiss.

Tab 8 — Agentic

Enable Agentic mode to let the LLM take direct actions using configured tools. Each action is shown as an action block in the chat — the LLM never executes anything without your confirmation.

Master switch — enable or disable agentic mode globally.

Autonomous Mode — two mutually-exclusive radio buttons control how actions are confirmed. Results from executed tools are forwarded to the LLM automatically. Click the button next to the label to view the behaviour-matrix popup.

Mode Confirmation Results forwarded to LLM
Semi Batch dialog for all actions ✓ Always auto-sent
Full (confirm modifying) Reads: silent · Modifying: confirm dialog ✓ Always auto-sent
Full (silent all) No confirmation for any action ✓ Always auto-sent

Cancelled tool calls stay visible in the chat as non-executable cancelled blocks.
If the whole confirmation dialog is cancelled, no immediate LLM follow-up is
sent; the next user request includes a client notice that the previous tool calls
were cancelled. If only some actions are approved, the executed results and a
short cancellation notice are sent together.

Sub-option for Full mode: "Confirm only modifying actions" (default ON) — when checked, read/ls/grep/lint tools run silently while all other enabled tools go through the confirm dialog.

Allow action types — enable or disable each action type independently:

Action Tool syntax Default
Create / overwrite file ```file:path/to/file.py On
Apply unified diff patch ```patch:path/to/file.py On
Read file ```read:path/to/file.py On
Read file with line numbers ```read:path/to/file.py:lines On
Read line range ```read:path/to/file.py:100-150 On
Read line range with line numbers ```read:path/to/file.py:100-150:lines On
List directory ```ls:path/to/dir/ On
Search files with Python regex ```grep:path/to/file_or_dir + regex in body On
Copy file / directory ```copy:source/path + destination in body On
Delete file ```delete:path/to/file.py On
Delete directory recursively ```delete_dir:path/to/dir/ Off
Rename / move file ```rename:old/path.py + new path in body On
Rename / move directory ```rename_dir:old/dir/ + new path in body Off
Run in IPython console ```run:python On
Install package ```install:pip Off
Run git command ```run:git On
Run pylint ```lint:path/to/file_or_dir On
HTTP request ```http:GET https://example.com On
Sleep / wait ```sleep:1000 On

Disabled action types fall back to plain code block rendering so their content is still visible.

For grep:, put the Python regular expression in the block body so : can be used safely inside the pattern:

```grep:app/main.py
@app.*"/admin:airports
```

Default base path — the root directory used to resolve relative file paths in file: and patch: tool calls. Defaults to the active Spyder project root, then the user home directory.

In Semi mode the typical git commit workflow collapses to two clicks: the git bar Commit button and Run selected in the batch dialog. The LLM then receives the commit output and confirms the result.

Prompt template — customise the agentic system prompt injected when agentic mode is enabled. Pre-filled with the built-in default. Use Reset to default to restore the original text.

Action block colours:

  • 🔵 Blue — create new file
  • 🟡 Amber — overwrite existing file
  • 🟢 Green — run in console / apply patch
  • 🩵 Teal — install package
  • 🟠 Orange — run git command

After execution the action button is replaced by a ✓ Done badge. Hover the badge to reveal ↺ Re-run. Execution state is persisted in the chat history and restored on reload.

Agentic output messages — user messages generated automatically by the plugin (git bar prompts, auto-sent execution results) are displayed as a collapsed ⚙ Agentic output block in the chat. Click the header to expand.


Usage

Sending messages

  1. Type your message in the input box at the bottom.
  2. Press Ctrl+Enter or click Send.
  3. The assistant's reply streams in above in real time.
  4. Click Stop to cancel a reply mid-stream.

Inference parameters

Click -> Inference params in the bottom composer action row to open the per-chat parameters popup. Only the parameters supported by the selected provider are shown. Parameters set here override the provider's defaults for this chat session. When active, the button turns amber and shows a compact, elided summary of the values set. Starting a new chat resets parameters to defaults.

Model selection

Click the model name button at the top of the pane to open the model dropdown.
Click to refresh the model list from the API.

System prompt

Type a system prompt in the field above the input box, or select a saved prompt from the System prompts: dropdown. Click ↓📋 Copy and edit to copy a saved prompt into the editable field for customisation.

Adding file context

Right-click in any editor tab to access the AI Chat submenu, or use the keyboard shortcuts:

  • Add file to context — attaches the current file's full content. Shortcut: Ctrl+Shift+A
  • Add selection to context — attaches the currently highlighted text. Shortcut: Ctrl+Shift+Q

Right-click in the IPython console to access the same AI Chat submenu:

  • Add console content to context — attaches the full console output text.
  • Add selection to context — attaches the currently selected console text.

Context tags appear above the input box and can be dismissed individually before sending. Editor attachments are shown with a blue tag; console attachments are shown with a teal-green tag.

Chat history

Click the checklist icon (🗒) in the toolbar to open the chat history popup.

  • Collection selector — choose a named collection or Default to browse chats from that collection only; choose ⊕ All Collections to search and list chats from every collection.
  • ⚙ (gear) button — opens the Collection Manager dialog to create, rename, and delete collections, and to move chats between them.
  • Search field — type any text to instantly filter chats; searches both the title preview and the full message content of every saved chat.
  • Click an entry to load that chat.
  • — delete a chat (3-second countdown with Cancel).
  • Right-click an entryMove to → submenu lets you move that chat to any other collection.
  • 🗑 Delete all — hover for 1 second to unlock, then a 3-second countdown before deletion; deletes all chats in the currently selected collection only.
  • The active chat is highlighted green.

Chats are saved to ~/.spyder_ai_chat/chats/. Named collections are subdirectories (e.g. chats/Work/).

Project context

Click the 📁 Proj. Context ○ toggle button in the chat bar to enable project-wide context.

  • A folder-selection dialog opens showing all top-level project folders with file counts and an estimated token count. Check the folders to include and click Enable project context.
  • The badge changes to 📁 Proj. Context ● (amber) and appears in the attachment bar for every message.
  • First message — all selected files are sent in full. Open files with unsaved edits use the live editor buffer. New unsaved files (not yet on disk) are always included automatically.
  • Subsequent messages — only files that changed since the last send are appended as a delta block. Unchanged files are already in the LLM's conversation history and are not re-sent.
  • File change detection — a file watcher monitors the project directory. The badge shows a changed-file count (e.g. · 3 changed ⚠) before you send.
  • Disabling — click the toggle again; a confirmation dialog warns that context will be detached from the chat.
  • Whole-file attachments are blocked while project context is ON to avoid duplication. Editor selections and IPython console attachments remain available.
  • Configure max file size, max file count, and extra exclusion patterns in Settings → 📁 Context.

AI auto-complete (FIM ghost text)

Once configured in Settings → Auto-complete, ghost-text suggestions appear automatically while typing in the editor.

  • Tab — accept the full suggestion
  • Escape — dismiss the suggestion
  • Alt+\ — manually request a completion (when trigger mode is Manual only)

The completion uses the code before and after the cursor as context (configurable character limits).

Markdown rendering

  • Headings H1–H3 with scaled sizes
  • Bold, italic, bold+italic, ~~strikethrough~~, inline code
  • Bullet and numbered lists with arbitrary nesting — cycling symbols (, , , )
  • Blockquotes with blue left border
  • Fenced code blocks with language label, Copy to editor button, and horizontal scrollbar for long lines
  • Tables with header row and alternating row shading
  • Clickable hyperlinks
  • <think>...</think> blocks rendered as a collapsible Thinking box with scrollbar — works with DeepSeek-R1, QwQ, Qwen-thinking variants

Ollama quick-start

ollama serve          # starts the server on port 11434
ollama pull llama3    # download a model

In Settings → Connection select Ollama (local). URL is pre-filled; leave the API key blank.


Data storage

All plugin data is stored under ~/.spyder_ai_chat/:

Path Contents
state.json Provider type, API URL, selected model, model list cache, editor font sizes, history settings, FIM configuration, active collection, and API-key storage metadata
chats/ One JSON file per saved chat session (Default collection)
chats/<CollectionName>/ Chats belonging to a named collection
system_prompts.json Saved system prompts library
commands.json Slash-command aliases

Chat and FIM API keys are stored per provider, so switching providers in
Settings restores the key saved for that provider. Keys are stored in the
operating system keyring when Python keyring is available and the OS backend
accepts the write. If keyring is unavailable or fails, the plugin falls back
to provider-scoped plaintext storage in state.json and shows a warning when
settings are saved.


Project structure

spyder_ai_chat/
├── pyproject.toml               # Build config, version, author, license
├── README.md                    # This file
├── README_PYPI.md               # PyPI landing page description
├── LICENSE                      # MIT
└── spyder_ai_chat/
    ├── __init__.py              # Package init
    ├── plugin.py                # SpyderDockablePlugin subclass —
                                #   Spyder integration, editor + IPython
                                #   console context menu injection,
                                #   FIM ghost-text wiring
    ├── confpage.py              # Preferences page (reserved for future use)
    ├── fim/
       ├── __init__.py
       ├── client.py            # HTTP FIM client:
                               #   multi-backend request/response handling
                               #   (Ollama, OpenAI-compat, Codestral, chat fallback)
       ├── config.py            # FIM configuration dataclass:
                               #   provider, URL, API key, model, backend type,
                               #   max tokens, temperature, context window,
                               #   trigger mode, debounce delay
       ├── ghost_text.py        # Ghost-text rendering:
                               #   inline grey suggestion overlay in the editor,
                               #   Tab to accept, Escape to dismiss,
                               #   cursor-offset fix for \r\n line endings
       ├── provider.py          # FIM completion provider:
                               #   AiFimProvider (Spyder completions API),
                               #   debounce timer, trigger-mode dispatcher,
                               #   Escape ShortcutOverride intercept
       └── widgets/
           ├── __init__.py
           └── status.py        # FIM status-bar widget:
                                #   shows active model / provider in the editor status bar
    └── widgets/
        ├── __init__.py
        ├── chat_widget.py          # Main chat panel UI:
                                   #   streaming API worker, model popup,
                                   #   chat history popup, inference params popup,
                                   #   file context bar, system prompt selector,
                                   #   bottom panel layout, state persistence
        ├── chat_history_manager.py # File-per-chat JSON storage:
                                   #   save / load / delete / list chats,
                                   #   collection directory helpers
        ├── collection_manager.py   # ChatCollectionManagerDialog:
                                   #   create / rename / delete collections,
                                   #   move chats between collections
        ├── markdown_renderer.py    # Markdown → Qt widgets renderer:
                                   #   headings, paragraphs, recursive nested lists,
                                   #   tables, code blocks (QPlainTextEdit + h-scroll),
                                   #   blockquotes, think blocks (scrollable),
                                   #   inline formatting, configurable font sizes
        ├── settings_dialog.py      # Tabbed settings dialog:
                                   #   provider registry (12 providers + param defs),
                                   #   Connection tab (dynamic form + Test Connection),
                                   #   Dialogs font sizes, History options,
                                   #   System Prompts & Commands (auto-edit on select,
                                   #   dirty-save tracking), Auto-complete FIM tab
        ├── system_prompts.py       # Saved system prompts CRUD:
                                   #   load / save / new / update / delete,
                                   #   persisted to ~/.spyder_ai_chat/system_prompts.json
        ├── commands.py             # Slash-command definitions:
                                   #   load / save / defaults,
                                   #   persisted to ~/.spyder_ai_chat/commands.json
        └── agentic_actions.py      # Agentic action execution:
                                    #   execute_create_file, execute_patch_file,
                                    #   _apply_unified_diff, run_git_command,
                                    #   show_confirm_dialog, show_batch_confirm_dialog,
                                    #   AGENTIC_SYSTEM_PROMPT constant

Requirements

  • Python ≥ 3.9
  • Spyder ≥ 6.1
  • No extra Python packages — uses only urllib from the standard library for HTTP and Qt (already bundled with Spyder) for the UI.

Changelog

1.0.7

  • Switchable tool-call signatures - Agentic settings now support Compatibility, XML-only, and legacy Markdown-only tool syntax modes. Compatibility mode is the default and teaches the new XML-style tool format while still accepting existing Markdown tool fences.
  • Markdown minimal tool prompt - The tool-call syntax selector now uses shorter labels (Compatible, XML, XML minimal, Markdown, Markdown minimal) and adds a compact Markdown prompt for micro/small models that handle Markdown fences better than XML.
  • XML tool parser and prompt support - All agentic tools now have XML tag metadata, XML examples in the injected tool-use prompt, and parser normalization into the existing execution pipeline, including streaming placeholders and malformed unclosed-body guards.
  • XML minimal tool prompt - A new XML minimal syntax mode keeps the injected tool-use prompt short and example-focused for weaker local models while still using the XML tool parser.
  • Tool-syntax-aware rendering - Live rendering, collapsed agentic summaries, and action detection now respect the selected tool-call syntax so XML-only mode does not treat legacy Markdown fences as executable tools.
  • Safer Markdown tool fences - Legacy Markdown tool mode now supports four-backtick file: and patch: fences so generated Markdown code blocks inside file content do not close the tool call early; live rendering also avoids transient empty code blocks while long tool openers stream in.
  • Per-chat confirmation suppression - Same-tool confirmation dialogs now offer an Always run ... action that runs the selected actions and suppresses future confirmation dialogs for that tool type in the current chat session; mixed-tool batches remain guarded and suppressions reset after Spyder restarts.
  • Clearer standard XML and Compatible prompts - detailed XML prompts now organize enabled tools under Markdown-formatted inspection and modifying/application groups, keep sequencing guidance beside the relevant group, and remove repeated batching, syntax, and supported-tool rules.
  • Tool-syntax-aware patch recovery - failed patches now return recovery instructions matching the selected XML or Markdown prompt; standard modes can request numbered reads, minimal modes use only their advertised base read form, and disabled read/file tools are omitted from the advice.
  • Corrected minimal tool definitions - XML/Markdown minimal prompts now distinguish body-based calls, Markdown copy:, rename:, and rename_dir: examples place the destination in the tool body, disabled-action warnings list the unavailable functions, and file creation notes that parent directories are created automatically.
  • Opaque Run Python streaming - unfinished run:python and <tool:run> bodies now use the compact generating spinner and live character counter instead of exposing long scripts line by line; the completed tool renders normally after its closing marker arrives.
  • Independent chat-history deletion countdowns - arming deletion on multiple chat rows now keeps every countdown active; each chat is deleted and removed independently when its own timer expires instead of the first deletion cancelling the remaining rows.

1.0.6

  • Paged-chat Regenerate placement fix — Regenerate is now shown only on the latest assistant/error message in the full chat history, not merely the latest assistant visible on the current page.
  • Faster long-stream rendering — hidden in-progress file:/patch: tool bodies now drain from the provider queue in adaptive batches, helping the UI keep up with very fast local models while preserving normal character-level Markdown rendering.
  • Settings startup blink fix — the Context tab token-limit table no longer creates transient unparented Qt widgets while opening Settings, removing the brief top-level window flash.
  • Compaction-aware regenerate safety — regeneration continues to use the same compacted active context as normal sends, avoiding full-history payloads after compaction.

1.0.5

  • First-run context-limit refresh fix — model-specific token limits added immediately after first provider configuration now update the chat token estimator without requiring a Spyder restart.
  • Per-model inference parameter templates — the inference-parameters popup can now save, update, delete, and manually load settings per provider/model; new chats automatically start with the saved template while existing chats keep their own saved params unless the user loads the template.
  • Inference parameter default display fix — unset float parameters with negative ranges, such as presence and frequency penalties, now show default instead of misleading 0,00; explicit zero values are still supported when the user sets them.
  • Settings provider/model handoff fix — the Connection tab's Test & Load Models button now loads fetched model names into the open Settings session, so the Context tab can add per-model token limits for a newly configured provider before closing and reopening Settings; the success message now clarifies that OK is still required to save.
  • FIM model-load error reporting — the Auto-complete settings panel no longer reports stale saved FIM models as freshly loaded when the provider server is unavailable; failed loads keep the visible error state.
  • Stop-button lifecycle fix — clicking Stop just after a provider stream has already ended no longer crashes when Qt has deleted the worker thread before the panel cleared its reference.
  • Malformed long tool-call safety guard — Stop now force-closes the active streaming response, late chunks are ignored, unclosed file:/patch: tool bodies are capped by a configurable Agentic setting (default 50k chars), and an error-only render failure can no longer overwrite an existing real chat history file.
  • Unclosed file/patch stream limit enforcement — the live generating counter for open file: and patch: tool calls now enforces the configured max unclosed stream size directly, so malformed never-ending file bodies are stopped and recorded as assistant errors instead of continuing to drain buffered text silently.
  • Stopped tool-call context notice — stopped partial assistant responses persist with agentic_discarded: true, reload as disabled tool blocks, and now add a user-side client notice to the next LLM request that the partial tool calls were discarded and not executed.
  • OpenRouter preset support — OpenRouter connection settings now include a Preset identifier field, saved in plugin state and sent as the root preset value in chat-completion requests when configured.
  • Agentic tool prompt clarity — the injected tool-use prompt now starts with clearer “real-world actions” wording, explicitly separates enabled inspection tools from modifying/application tools, integrates patch line-number inspection guidance into the file/patch rules, and keeps final formatting guardrails for non-inline tool calls.
  • Grouped inspection readability — grouped inspect actions now show the specific tool icon and label for each entry (Read, List, Search, or Lint) so mixed inspection batches are easier to scan.
  • Grouped inspection output collapse fix — agentic output rows linked to grouped inspection actions now also respect the top-level agentic summary collapse state, so collapsing the parent group hides the output consistently like modifying-tool groups.
  • Contiguous inspection grouping — inspection actions are now grouped only when they are adjacent in the assistant message; explanatory text or modifying/application actions split the group so the rendered order matches the actual tool execution order.
  • Git diff popup newborn-repo fix — the local diff popup now works after git init before the first commit exists, avoiding HEAD-based diff failures, previewing untracked files as additions, and disabling branch-comparison scopes until an initial commit is available.
  • Regenerate after compaction guard — Regenerate buttons are hidden for assistant responses that sit before the latest compaction request or summary boundary, preventing regenerated content from being inserted into already-compacted history segments.

1.0.4

  • Live tool generation stability — open streamed tool calls now show a compact text-only generating label in the existing assistant stream instead of creating a transient Qt widget, preventing small top-level window flashes during file/read/list generation.
  • Generating label polish — the live tool-call progress text is smaller and aligned with rendered action titles, uses a normalized timer-driven spinner, shows only the tool name/target and character count, and no longer leaks the current raw streamed line.
  • Generating-state contrast — the live tool-call spinner and generating text now use a theme-aware light-orange colour so they remain distinct from the action title and target.
  • Lazy agentic-output previews — agentic output hover popups are created only when hovered, reducing unnecessary widget creation in long agentic chats.
  • Agentic output visual alignment — auto-sent tool-result messages now use the same blue left accent as user-side content, with tighter indentation so the “Agentic output” label aligns with nearby lightweight tool-action titles.
  • Batched agentic-output visibility fix — agentic output rows linked to batched tool calls now inspect the collapse state of every action in the batch, including mixed batches separated by explanatory text, so expanding any participating action reveals the shared output and collapsing all of them hides it.
  • On-demand file and patch previews — collapsed file: and patch: action blocks now defer editor creation, syntax/diff formatting, and content population until their first expansion, reducing live-rendering overhead and accelerating long chat-history loads.
  • Safer action status parsing — successful actions whose paths contain words like error, failed, cannot, or running no longer appear as failed/running in the action header; status detection now relies on explicit status prefixes and stored action state.
  • Strict patch validation — malformed patch calls without unified-diff hunks and patches that produce no actual file changes are now rejected and reported to the LLM with patch-recovery guidance instead of being marked as successfully applied.
  • Read/list error persistence — failed read: and ls: actions no longer fall through to the success recorder; they remain Error in both live and history rendering, with the failure reason shown consistently in the expanded detail line and agentic output.
  • Stable nested-list rendering — Markdown lists now use explicit Qt marker/content rows instead of native ordered-list markers, preventing malformed numbering and wrapped nested entries from overlapping following items at different chat-pane widths while preserving readable row spacing and compact indentation.
  • Semi-mode compaction fallback fix — selecting LLM Summary while Agentic mode is Semi now consistently uses the effective Cut-off strategy in request building, context estimates, automatic triggering, and HTTP output budgeting. Cut-off removes complete old exchanges at real user-request boundaries while preserving the newest exchange, and internal compaction request/summary records are excluded from the active conversation window.
  • Prompt-aware compaction budget — Cut-off and first-summary history trimming now reserve threshold space for the active system prompt, generated agentic tool prompt, project-root note, and existing compaction summary instead of granting message history the entire threshold budget and adding fixed prompt content afterward.

1.0.3

  • Local graphical git diff popup — clicking the git bar branch/stat text opens a local-only diff viewer for uncommitted changes on the current branch, without sending anything to the LLM.
  • Git diff scope selector — the popup can switch between Working tree vs HEAD, committed Branch vs main/master, and committed Branch vs upstream views, with branch scopes loaded asynchronously and uncommitted changes reported separately.
  • Patch-style git diff rendering — changed, staged, unstaged, deleted, and untracked text files are shown in per-file cards using the existing coloured patch diff view, with binary/large-file safeguards.
  • Git diff summary polish — the popup now keeps only the compact overall summary at the top and moves per-file insertion/deletion stats into the corresponding file diff cards.
  • Git diff popup responsiveness and polish — the diff window now opens immediately with a loading state, uses a single button-like git status pill in the git bar, and removes extra borders from file diff previews.
  • Chat user-message polish — normal user messages now appear as right-aligned themed blocks with improved spacing, while agentic output and error blocks keep their existing rendering.
  • Stop-before-first-token handling — stopping an LLM request before any visible response now creates a visible assistant-side stopped/error record, preserving valid chat history and enabling Regenerate.
  • Agentic inspect grouping stability — grouped read/list/grep/lint action widgets now receive the proper chat parent before insertion to avoid transient top-level widget flashes during auto execution.
  • Agentic settings tabs — the Agentic settings page is split into Agentic settings, Action's properties, and Tools system prompt tabs for easier navigation.
  • Tool prompt preview polish — the tool system prompt tab now uses the full page, removes the old collapse control, and includes a short note explaining the plugin's Markdown DSL tool-calling scheme.

1.0.2

  • Agentic web search tool — added web_search:<query> for structured public web-search results through Jina AI or Tavily, with Jina shown first in settings.
  • Secure web-search tokens — Jina AI and Tavily access tokens are configured separately in Agentic → Action properties and stored with the existing OS keyring fallback flow.
  • Web-search confirmation flow — web search is treated as a confirmation-required modifying tool, runs asynchronously, persists Done/Cancelled/Error state, and auto-sends structured title/URL/description/date results to the LLM.
  • Web-search onboarding notice — enabling the tool without a selected provider token shows an inline Agentic settings notice with links to the provider token pages.

1.0.1

  • Streaming renderer stability — live streamed responses from chunked providers now drain through a small character queue, making Markdown lists and code blocks render consistently while keeping the final saved history unchanged.
  • Live code-block duplication guard — completed code blocks are no longer duplicated or mixed while streaming providers send larger text chunks.
  • Lightweight tool block polish — collapsed tool blocks now keep action titles readable, align expand markers after the title, collapse successful status/output details with the action content, and use tighter spacing for grouped actions.
  • Live agentic action placeholders — incomplete streamed tool calls now show only a generating action title, spinner, and character count until the closing fence arrives, so raw file or patch bodies no longer scroll through the chat.
  • Model selector layout fix — the model filter field and empty-results row now stay aligned to the top of the popup, so “No matching models” no longer appears in the middle of the dropdown.
  • System prompt popup — system prompt controls moved into an SP popup in the prompt toolbar, with panel-clamped positioning, hover-highlighted toolbar styling, dark/light theme styling, and an agentic prompt injection note.

1.0.0

  • Manual agentic mode removed — Agentic mode now supports only Semi and Full. Existing saved Manual/off configurations migrate to Semi, preserving confirmation review while simplifying the execution model.
  • Inline action execution removed — chat-rendered tool blocks no longer expose execute or re-run buttons; actions execute only through the normal Semi/Full response-processing flow and historical blocks are passive status records.
  • Cancelled action state — cancelling a confirmation dialog marks requested tools as Cancelled by user in chat/history. Full-dialog cancel stops the chain without an immediate LLM call; the next real user request includes a client notice. Partial approval auto-sends executed results plus a concise cancelled-action notice.
  • Lightweight tool block rendering — chat-rendered tool blocks now use plain clickable text headers, collapsed content by default, subtle content backgrounds, plain text status rows, and an always-on 10-line expanded-content cap with scrollbars; the old file/patch height-limit setting was removed.
  • Prompt and Settings cleanup — the injected tool-use prompt, Agentic settings controls, and behaviour matrix now describe only Semi and Full workflows.

0.9.6

  • Default agentic startup mode — fresh installs now start in Full autonomous mode with Confirm only modifying actions enabled, giving the smoother default workflow while still requiring review before modifying operations run.
  • Silent full-autonomous warning refinement — the amber Full-mode warning now appears only when modifying-action confirmation is disabled, and explicitly advises keeping confirmation enabled unless the user trusts the LLM not to damage the application or system.
  • No-project safety guard — when no Spyder project is open or pinned, the chat pane now shows an amber warning explaining that full agentic functionality requires a project; modifying tools are blocked for safety.
  • Project-required tool restrictionsfile:, patch:, copy:, delete:, delete_dir:, rename:, rename_dir:, run:python, install:pip, run:git, and lint: now require a trusted project root, preventing console, git, install, or lint report generation from bypassing project-root safety.
  • Blocked async tool output forwarding fix — security-blocked async-capable tools such as run:python now forward their restriction error into the collected agentic output, so the LLM receives the same feedback as it does for blocked file: actions.
  • LLM connection-error context — provider failures that happen before any assistant text is streamed are saved as assistant_error chat entries and converted into user-side client notices in the next API payload, preserving failed prompts and error details without sending invalid message roles.
  • User-boundary delete cleanup — chat delete controls now appear only on real user messages; deleting a user request removes the full user-started exchange, including any following agentic outputs and assistant continuations up to the next real user request.
  • Manual mode result forwarding fixes — manually clicking a modifying action block after cancelling the batch dialog now forwards successful results to the LLM, matching the batch-confirmation path; Manual batches also collect run:python and sleep: output into the same agentic-output message.
  • Manual mode inspection guard polish — Manual mode now rejects mixed modifying/inspection responses and inspection-only batches with more than one inspection tool using model-facing “Tool-use rule violation” messages; skipped tool names are included, buttons stay disabled after reload, and the forwarded output no longer mentions internal Manual-mode jargon.
  • Agentic collapse readability polish — collapsed agentic groups now keep the assistant text that appears before the first tool call visible above the collapse summary, so the model's plan or intro is not hidden; the summary typography was tuned for both title-row and inline placements.
  • Thinking block auto-collapse setting — Settings → Dialogs now includes a default-on option to auto-collapse <think> blocks, applying to live streamed thinking sections and chats loaded from history.
  • Model selector filtering — the top model dropdown now includes a live filter field, making large provider lists such as OpenRouter easier to search by partial or multi-term model names.
  • Chat collection move fix — moving the currently open chat from Manage Chat Collections now updates the active save target immediately, preventing autosave from recreating the chat in its old collection.
  • Agentic prompt cleanup — the injected tool-use prompt no longer tells the model about “manual mode”; inspection rules are merged into one concise section and the listed inspection tools are generated from the tools actually enabled in Settings.
  • Compaction prompt improvement — subsequent LLM-summary compactions now explicitly ask for one updated replacement summary that preserves the previous compacted summary while merging in newer messages and tool/action results, reducing repeated summaries.
  • Compaction no-tool guard — LLM-summary compaction requests now explicitly forbid tool calls and list only the currently enabled tool-call markers as forbidden examples, so disabled tools are not advertised while the model writes the replacement summary directly as Markdown.
  • Agentic tool registry refactor — tool metadata such as settings keys, parser prefixes, supported-tool formats, labels, project-root requirements, and compaction no-tool markers now comes from one shared registry to prevent drift between the prompt, renderer, settings, and chat UI.
  • Git output decoding fix — Git bar actions and run:git now decode subprocess output as UTF-8 with replacement, avoiding Spyder errors on Windows when diffs contain bytes that cannot be decoded by the system code page.
  • Context estimate popup layout polish — the token tooltip now groups statistics as Current context, Full history, Current context message count, and LLM speed, with aligned full-width section dividers and clearer spacing around the usage bar.
  • Inference parameters popup cleanup — provider connection notes, such as the LM Studio optional API-key warning, no longer appear in the per-chat inference parameters popup where they could overflow the compact window.
  • Reliable install:pip execution and reporting — package installs no longer use Spyder's unreliable %pip console magic or scrape console text; the tool now runs sys.executable -m pip install ... in a background subprocess, captures pip output and exit code directly, and participates in the semi/full auto batch collector so normal semi-auto installs are returned as Agentic output.
  • Semi/full batch output fix — normal semi/full autonomous tool execution now routes install:pip through the same batch collector as other tools, while direct action-block clicks keep the manual-style forwarded-output behavior.
  • HTTP tool User-Agent fallback — public http: requests now receive a random browser-like User-Agent when the LLM did not provide one, improving compatibility with sites that reject bare urllib clients while leaving local/private traffic and explicit headers unchanged.
  • HTTP text-mode response sizing — the default HTTP returned-content limit increased from 20k to 100k characters, and http:...:text now applies that cap after HTML is stripped so public pages produce useful cleaned text instead of only the first raw HTML fragment.
  • HTTP context safety gatehttp: result size is now capped before the request worker starts using a protected recent-chain budget, so large web pages cannot push the triggering user request or assistant tool call out of the active model context.
  • Git bar startup recovery — the git status bar now re-checks Spyder's live project root on every refresh and resets retry state when the detected working directory changes, so it can recover when startup project signals arrive before the plugin cache is ready.
  • Settings text polish — Agentic Manual mode now clarifies that only inspection-tool results are not auto-sent, and the LLM Project Context section matches the 📁 Proj. Context ○ / ● toggle label with the token-usage warning moved directly under the explanation.
  • Lint report hint claritylint: results now explicitly call .ai_chat/lint/ a directory and include a compact list of created report-file paths, nudging models to read specific JSON reports instead of treating the directory as a file.
  • Indented list rendering fix — Markdown lists that start indented after headings or paragraphs now render correctly, and malformed block-looking lines are consumed as plain text so list/blockquote edge cases cannot stall chat or compaction rendering.

0.9.5

  • Agentic tools terminology — the injected agentic prompt and Settings → Agentic text now use the more familiar "tool use" language instead of "agentic fences", making the instructions closer to the terminology used in small-model tool-use training data.
  • Agentic prompt format cleanup — the prompt now has a clearer Available tools section, a generic triple-backtick tool-call format, and an explicit final list of supported tools so models are told that no other tool names are available.
  • File and patch guidance improvementsfile: and patch: are grouped together in the prompt, file paths are described as relative to the project root or absolute, example paths are called out as placeholders, multiple file creations in one response are allowed, and patch guidance now recommends checking with read: after applying a patch when that tool is enabled.
  • Numbered read output for patch repairread: now supports :lines (read:app/main.py:lines and read:app/main.py:100-150:lines) to return file content with line numbers at the beginning of every line, helping small models produce corrected patches after context mismatches.
  • Shorter patch recovery guidance — failed patch blocks now return a compact recovery hint that points the LLM to read:<file>:lines, asks for one corrected patch: call, and only suggests full-file file: recreation if patching still fails.
  • Body-based grep toolgrep: now uses the opening marker as an optional file/directory scope and the block body as the Python regex, so colons inside patterns are safe; old inline grep:pattern[:scope] parsing was removed to avoid ambiguity.
  • Manual mode guardrail — Manual mode is now marked deprecated in Settings and the prompt tells the LLM not to mix inspection tools with modifying/application tools; if such a mixed response is generated, inspection tools are skipped, their buttons stay disabled after reload, and the LLM receives an auto-sent warning with the executed modifying results. Manual also permits only one inspection tool per response: later inspection tools are skipped, disabled in chat/history, and the first inspection result panel includes a warning before the user can forward it.
  • Batch tool-use guidance — autonomous and semi-autonomous modes now tell the LLM to call independent tools together in one response when possible, while still waiting when inspection results or prior action results are needed before deciding the next step.
  • Console bypass guard — when run:python is enabled, the prompt explicitly tells the LLM not to use it to bypass disabled higher-risk tools such as package installation, delete/rename operations, or HTTP calls.
  • Markdown code-block rendering fix — indented regular Markdown code blocks inside lists, such as SQL or bash examples in numbered instructions, now render as code blocks without requiring them to be agentic tools.
  • Compaction summary formatting fix — LLM summary compaction blocks now preserve basic Markdown formatting such as headings, lists, tables, and code blocks while keeping the summary visually distinct; accidental tool-looking blocks inside summaries render inertly and cannot be executed. Full-summary outer markdown/md code fences are unwrapped before rendering so nested SQL/code blocks stay inside their own blocks instead of spilling into the summary body.
  • File action create/overwrite history fixfile: action blocks now remember whether the target existed before execution, so newly created files stay labeled Create File after full-autonomous batch execution and after chat-history reload instead of being reclassified as Overwrite File just because the file now exists.
  • Duplicate write-target confirmation fix — the batch confirmation dialog now treats duplicate write targets as conflicts only when the same tool type targets the same path, so a valid file: then patch: repair sequence stays checked while repeated file: writes to the same file are still warned about and earlier duplicates are unchecked.
  • Response speed and TTFT stats — the estimated context-token popup now shows estimated tokens-per-second and TTFT (time to first token) for the last completed LLM response, plus volatile last-5-response averages for the currently opened chat; speed uses the existing approximate token estimate because streamed chunks are provider-dependent and not guaranteed to equal tokens.
  • LLM-summary compaction chain fix — automatic LLM summary compaction now triggers correctly after long full-autonomous agentic tool chains even when the chain jumps past the hard context limit; the trigger uses the untrimmed active conversation size, while the summary request still trims older history for provider safety and preserves the newest exchange so the model is never asked to summarize an empty conversation.
  • Light-theme rendering polish — compaction summary blocks, grouped read/ls/grep/lint tool summaries, warmup delete buttons, and context-size button styling were adjusted for Spyder light themes, including fixes for low-contrast text, dark read-batch backgrounds, black delete buttons, list background seams, and Qt stylesheet parse warnings.
  • Agentic confirmation stylesheet cleanup — action confirmation rows no longer use Qt-incompatible alpha hex colors in QFrame styles, removing stylesheet parse warnings seen when create/patch rows were shown.
  • Chat collection cleanup — the Manage Chat Collections dialog now has a Delete selected button for the right-side chat list, allowing multi-selected chats to be removed from the current collection with confirmation.
  • Tool wording cleanup — remaining user-visible warnings and generated helper prompts now refer to agentic tools and tool calls instead of "fences" where the wording is shown to the user or sent to the LLM.

0.9.4

  • First-run provider onboarding — fresh installs no longer show stale default model names; the chat pane now starts with a clear "No provider configured" state, disables sending until a provider is saved, and shows an Open Settings callout so new users know how to begin.
  • Default prompt restoration fixes+ New Chat, deleting the currently open chat, deleting all chats, and restarting Spyder with no last chat now all restore the configured default system prompt consistently.
  • Agentic prompt compaction — the injected agentic system prompt was shortened substantially while keeping the key safety rules: available fences only, closing backticks on their own line, example paths are placeholders, and run:python must not be used to bypass disabled fences.
  • Small-model fence robustness — bodyless one-line action fences such as ls:.``` are normalized safely, and indented regular Markdown code blocks such as ``sql inside numbered instructions render as code blocks instead of being swallowed as paragraph text.
  • Duplicate action target warning — the batch confirmation dialog now detects repeated write targets, warns when later actions may overwrite earlier ones, and unchecks earlier duplicate file: creates by default while leaving all actions visible.
  • Stopped-response agentic safety — pressing Stop while an LLM response is still streaming now suppresses any pending agentic confirmation dialog, marks the partial assistant message with agentic_discarded, disables all action buttons in those partial fences, and adds a warning note explaining that the response was stopped and the action contents may be incomplete; the disabled state is preserved when chat history is reloaded.
  • Batch run:python output forwarding fixrun:python fences now participate in the same chained batch collector as file, git, HTTP, lint, and sleep actions, so console output is included in the single agentic-output message sent back to the LLM instead of being added separately as a pending prompt attachment.
  • Regenerate keeps agentic collapse controls — regenerating the last assistant response now rebuilds agentic pair collapse headers for earlier assistant/action-output pairs, so the collapse arrow near earlier Assistant messages does not disappear.
  • Agentic system prompt clarity for small models — the dynamically injected prompt now states that action fences must start on a new line, aligns manual/full-autonomous wording with the actual confirmation and result-forwarding behavior, removes conflicting "always explain before the fence" guidance for inspection fences, and adds a conditional patch-recovery rule that allows recreating a full file with file: only after corrected patch: attempts fail.
  • Patch retry guidance tightened — the agentic prompt and patch failure message now tell the LLM to send only one patch: action per file in a single response, wait for the result, and retry with a corrected patch in the next response instead of stacking repeat patches.
  • Agentic chat rendering setting — Settings → Agentic → Action properties now includes a Chat rendering settings section with a default-on option to collapse completed agentic assistant/output pairs; disabling it keeps newly rendered agentic responses expanded.
  • Patch fuzzy-apply improvement — when a unified-diff hunk fails because the LLM supplied stale surrounding context, the patch engine now safely falls back to replacing the contiguous removed-line block if that block appears exactly once in the file; one-line removals still require a nearby context match, avoiding ambiguous edits while improving small-model patch recovery.
  • Patch preview gutter sizing fix — unified-diff previews no longer let long @@ hunk headers stretch the old/new line-number columns in chat action blocks or the batch confirmation dialog.
  • Agentic collapse summary cleanup — collapsed agentic headers now show only the first two action types plus a +N more suffix for narrow panes, expose the full action list in a tooltip, and summarize action fences from the assistant response itself so failed patch/action attempts are included without being marked as successfully done.
  • Action-fence parser crash fix — nested triple-backtick handling is now limited to file: fences, so one-line action fences such as lint:, read:, ls:, and grep: close correctly when normal text follows them during streaming instead of being misparsed as still-open nested blocks.
  • Streaming render safety guard — parser/render errors during LLM streaming now stop the worker and show an in-pane assistant error instead of continuing to update Qt widgets; oversized unclosed bodies in small one-line action fences (lint:, read:, ls:, grep:, sleep:, delete:) are also aborted, while large file: and patch: responses are left unrestricted.
  • Model context estimate refresh fix — changing the current model from the top model selector, including after reloading the model list, now immediately refreshes the estimated context usage button so the configured per-model token limit is reflected without needing to send a message, reload history, or reopen Settings.
  • Provider-specific secure key storage refinements — chat and FIM API keys are stored per provider, migrate from legacy single-key fields on Settings save, and display a themed key indicator showing keyring, plaintext fallback, or unsaved state; the key icon now uses a colorable symbol so keyring/plaintext/unsaved states are visually distinct.
  • FIM provider key switching fix — changing the FIM provider in Settings now restores that provider's saved key or clears the field when no key is saved, matching the main Connection tab behavior.
  • Settings and composer UI polish — inference-parameter and token-estimate popups are centered above their buttons, the inference popup border is clearer in both themes, inference spinbox arrows align in a single column, and delete controls were compacted to icon-only buttons.
  • Agentic run:python manual capture fix — manual mode console execution now captures and shows output when available instead of waiting for the timeout unnecessarily after the process has already finished.

0.9.3

  • Image attachments in user messages — attach images to any message sent to the LLM via the + Image composer button or by pasting a screenshot from the clipboard (Ctrl+V); supported formats: JPEG, PNG, WebP (re-encoded to JPEG), GIF (converted to JPEG):
  • + Image button — opens a file browser filtered to image formats (*.jpg *.jpeg *.png *.gif *.webp); appears in the composer action row; greyed out with a descriptive tooltip for providers that do not support vision input
  • Clipboard paste — pasting a screenshot or browser-copied image into the input field intercepts the Qt insertFromMimeData event, emits an image_pasted signal, and adds the image as a chip without inserting anything into the text field; text paste (Ctrl+V for code etc.) is unaffected; paste is silently blocked for non-vision providers with a status bar notice
  • Context bar chips — each attached image appears as a violet chip (🖼 filename.jpg) with a × remove button; hovering the chip shows a 200 × 200 px thumbnail popup (same popup for badges in chat history)
  • Vision-capable providers — OpenAI, Groq, Mistral, Together AI, Fireworks AI, OpenRouter, Azure OpenAI, Ollama, LM Studio, vLLM, and Custom endpoints; DeepSeek is excluded (text-only models as of 0.9.3)
  • API payload — when images are present and the provider supports vision, the LLM content field becomes an OpenAI-compatible array of {"type": "text"} and {"type": "image_url", "image_url": {"url": "data:mime;base64,…"}} blocks; for text-only providers content is still sent as a plain string (images silently excluded but preserved in history JSON)
  • Scaling pipeline — images larger than the configured maximum dimension are scaled down (longest side, Qt.SmoothTransformation) before base64 encoding; GIF and WebP are re-encoded to JPEG at the configured quality level; PNG files are always lossless; clipboard screenshots are always saved as JPEG; a 5 MB base64 cap rejects oversized images with a status bar error pointing to Settings → Context → Image attachments
  • Settings → Context — Image attachments group — two new spinners:
    • Max image dimension (256–4096 px, step 128, default 1 280 px) — longest-side cap before encoding; 1 280 px is the sweet spot for current small vision models (Qwen2-VL, Llama 3.2 Vision, MiniCPM-V); applied live at attachment time so changing the setting takes effect on the next attached image without restarting
    • JPEG/WebP quality (1–95, step 5, default 85) — re-encode quality for lossy formats; PNG is unaffected; 85 is the recommended balance between file size and fidelity
  • Chat history — image attachments are stored as base64 in the chat JSON (image_data + image_mime keys); on reload, violet image badges appear in the message header with the same thumbnail hover preview; switching to a non-vision provider after saving does not lose the image data — it is simply excluded from the API payload and re-included if the provider is switched back
  • Token estimate — each pending image attachment adds ~1 500 tokens to the context-size counter (conservative flat estimate visible in the ~X.Xk / Yk (Z%) bar and the breakdown popup)
  • LM Studio / local-model "No user query found" fix — two targeted guards in the API payload builder prevent Jinja2 chat-template errors that occur with strict user/assistant-alternation models (Qwen3, Llama 3):
  • Consecutive same-role merge — when Stop is pressed before any tokens arrive no assistant message is recorded, causing the next send to produce two back-to-back user messages in the payload; the payload builder now merges adjacent same-role plain-text messages (plain strings only; vision content arrays are left untouched) in both _send() and _on_regenerate() before the request is dispatched
  • Leading-assistant guard — the 2-at-a-time history-trimming loop assumes [user, assistant] pairs, but consecutive user messages in _messages (e.g. two manually typed messages sent in quick succession) form a [user, user] pseudo-pair that the loop removes together, exposing the following assistant message as the first non-system entry in the payload; a post-trim pass now drops any assistant messages that appear immediately after the system message, ensuring the payload always starts system → user → …
  • Composer action-row refresh — the user prompt area is now one bordered composer containing the prompt field plus a bottom action row; the old right-side vertical button stack is replaced by a horizontal row with + Image, compact inference params, compact context estimate, > Send, and [] Stop controls, improving narrow-pane layout and matching Spyder light/dark themes
  • Send / Stop feedback polish — Send and Stop now include simple text icons (> Send, [] Stop); while a request or regeneration is running, Send switches to a small Braille spinner animation until the response completes, errors, or the user presses Stop
  • Inference params and context estimate controls — moved from their own bar into the composer action row; both controls are bordered, theme-aware, centered, and width-limited so long active parameter summaries are elided instead of increasing the panel height or pushing Send/Stop out of place
  • Regenerate click feedback — clicking the last-response Regenerate button now immediately greys out the button and changes its text to ⠋ Regenerate before the chat rebuild starts, giving visible feedback during the short retry-preparation pause
  • LLM summary compaction warning fix — the Settings → Context warning for LLM summary compaction now reads the live autonomous-mode radio buttons inside the open Settings dialog; switching from Full autonomous to Manual/Semi and then visiting the Context tab shows the warning immediately, even before settings are saved
  • Provider-specific API keys — each chat provider and FIM provider now keeps its own API key; switching providers in Settings restores that provider's saved key instead of reusing one global key
  • API-key storage indicator — Connection and FIM API-key fields now show a key icon with the plugin's themed hover popup explaining whether the current key is stored in secure system storage, plaintext fallback, or not saved yet
  • Secure API-key storage — chat-provider and FIM-provider API keys are now stored in the OS keyring via Python keyring when available; state.json keeps only storage metadata and blank secret fields after a successful keyring save; if keyring is unavailable or rejects the write, the plugin falls back to provider-scoped plaintext and shows a warning

0.9.2

  • Top bar moved into Spyder's pane toolbar row — the model selector, ⟳ reload, + New Chat, ⚙ Settings, and chat history buttons are no longer a separate row inside the panel; they are placed in Spyder's standard _main_toolbar band (the same horizontal strip that holds the ≡ options button on the right), saving one full row of vertical space in the chat area; implemented by wrapping the top bar in a QWidget (_top_bar_w) exposed from AIChatPanel and registered via add_item_to_toolbar() in AIChatWidget.setup()
  • Project-root security filter for all file-operation fences — path validation previously limited to delete, delete_dir, rename, rename_dir, and copy is now extended to file, patch, read, ls, and grep fences; two separate policies apply: write operations (file, patch, copy, delete, delete_dir, rename, rename_dir) are always restricted to the project root and blocked entirely when no project is open; read operations (read, ls, grep) are restricted by a user-configurable toggle (on by default) that only enforces the boundary when a project is open, passing through silently otherwise; the unified _proj_security_check() function gains an env_key parameter to distinguish the two policies; a new Filesystem operations permissions sub-group in Settings → 🤖 Agentic → Action properties exposes the read toggle and a permanently-checked (greyed-out) write toggle, with an ℹ popup showing the full behaviour matrix

0.9.1

  • sleep: agentic fence — new fence that pauses execution for a specified number of milliseconds without blocking the Spyder UI; value is given in the fence tag (sleep:5000 waits 5 seconds); maximum is 60 000 ms (60 s); runs in a background _SleepWorker(QThread) so the window stays fully responsive and the button shows ⏳ Waiting… during the wait; LLM receives Slept N ms as confirmation; chains correctly in batch execution the same way http: and git: do; enabled by default in Settings → 🤖 Agentic → Application calls (Sleep / wait (sleep:ms) checkbox)
  • http: fence — configurable request properties — a new collapsible Action properties panel in Settings → 🤖 Agentic (between the Allow actions group boxes and the Default base path section) exposes five per-request settings that were previously hard-coded:
  • Follow redirects (default: on) — uncheck to block all HTTP redirects; implemented via a custom _NoRedirect(HTTPRedirectHandler) urllib opener
  • Max redirects spinner 0–20 (default: 2) — caps the number of redirects followed when follow redirects is on; the spinner is automatically disabled when follow redirects is unchecked; implemented via a custom _LimitedRedirect(HTTPRedirectHandler) opener that overrides max_repeats and max_redirections
  • Timeout (s) spinner 1–300 (default: 5 s, was hard-coded at 30 s) — per-request network timeout passed to opener.open()
  • Max response body (chars) spinner 1 000–200 000 step 1 000 (default: 20 000, was hard-coded at 10 000) — cap on the response body returned to the LLM; a truncation note is appended when the body is cut
  • Include link URLs in text mode (default: off) — when the :text modifier is active, href attributes from <a> tags are appended as (url) next to the anchor text so the LLM sees actual hyperlink targets
  • All five settings are persisted in state.json under the agentic key and read from _agentic_cfg() each time an http: fence executes
  • http: fence — :text mode href extraction_strip_html() now accepts an include_hrefs parameter; when true, the HTMLParser subclass tracks href from <a> start tags and appends (url) in the matching </a> end-tag handler; only absolute http:///https:// URLs are included; controlled by the new "Include link URLs in text mode" checkbox in Action properties
  • LLM summary compaction threshold fix — the 80 % compaction threshold now fires correctly instead of only near 100 % of the context window; root cause: _maybe_trigger_compaction() computed only message-history tokens and compared them directly against the model limit, ignoring system-prompt and agentic-prompt overhead which can account for 10–20 % of the total; fix: the trigger now delegates to _compute_context_stats() — the same calculation the always-visible context-size indicator uses — so the threshold fires at exactly the percentage shown in the UI
  • LLM summary compaction — first-compaction window fix — for chats that accumulated history in cutoff mode and then switched to LLM summary strategy (no prior compaction summary), the compaction request was built from the full message history which could exceed the provider's context limit and cause an API error; fixed by applying the same cutoff trim to 80 % of the token limit when last_compact_idx is None, matching what _send() actually sends to the API and leaving headroom for system-prompt and compaction-prompt overhead
  • chat_widget.py split into focused modules (Phase 1 refactor) — the 7 217-line monolith is reorganised into single-responsibility files with zero behaviour change:
  • widgets/chat_panel.py (~3 775 lines) — AIChatPanel (the main QWidget panel), extracted verbatim from chat_widget.py
  • widgets/_panel/ sub-package (new internal package) — 10 helper modules:
    • utils.py_is_dark_theme, _agentic_action_labels, DEFAULT_MODELS, _encode_chat_ref, _decode_chat_ref, style-factory helpers
    • small_widgets.py_FlowLayout, _WarmupButton, _ClickableLabel, _ClickEventFilter, _AgenticTooltipPopup, _AgenticHoverFilter, _PageBar
    • context_size.py_CtxSizeButton, _CtxTooltipPopup, _TipHoverFilter, _install_themed_tip, _group_read_frames_in_layout, _build_read_group_widget
    • command_input.py_CommandInput, _CommandDropdown
    • chat_history.py_ChatHistory (full message rendering engine), _build_llm_content
    • workers.py_ChatWorker, _GitStatusWorker, _GitActionWorker, _parse_porcelain_stat
    • git_status_bar.py_GitStatusBar
    • infer_popups.py_InferParamsPopup, _ModelPopup
    • history_popup.py_ChatHistoryPopup
    • project_dialog.py_ProjectContextDialog
  • widgets/chat_widget.py reduced to ~90 lines — only AIChatWidget (Spyder PluginMainWidget wrapper) plus two targeted re-exports; all existing plugin.py import paths unchanged
  • file: fence — bare no-lang nested code block fixfile: fences containing nested code blocks with no language tag (bare ``` without a lang identifier, e.g. an env-vars section or a project structure tree inside a README) were incorrectly truncated at the first such fence; the parser treated the bare opening ``` as the outer action fence's closing delimiter; fixed with a one-line lookahead: a bare ``` at nesting depth 0 is classified as a nested opener when the immediately following line contains non-fence content, and as the outer fence close otherwise; resolves a recurring issue where large README.md writes were silently cut in half
  • Batch confirmation dialog — LLM context label — when the LLM sends explanatory text immediately before an action fence (e.g. "I'll check if the server is running:" before an http: fence) that text is now displayed as an italic grey 💬 … label above the action preview header in the batch confirmation dialog; shown only for rows whose LLM response included a preceding paragraph (hidden for rows without one); text is truncated at 200 chars with "…"; this closes a UX gap where the agentic group being collapsed in chat caused the LLM's reasoning to become invisible precisely when the batch confirmation dialog was the only thing visible
  • Agentic system prompt — wait-for-acknowledgment guidance — the closing paragraph of the injected agentic system prompt now explicitly tells the LLM: when a manual user step is required before an action can proceed (restart an application, provide credentials, configure something externally), send that instruction as a plain message with no action fence and wait for the user's acknowledgment before sending the fence in a subsequent response
  • http: fence block — orange colour scheme — the http: action block header previously used dark red (#b03030), making it visually indistinguishable from an error state; changed to warm orange (#e09030 header text, #1e1200 dark-mode background, #fff8ee light-mode background); the row colour in the batch confirmation dialog is updated to match; the http: entry was also added to the dialog's icon, colour, and verb tables so its row renders correctly
  • Stop button active during agentic execution — clicking Stop while agentic fences are running now correctly cancels the in-progress batch; previously _on_done() unconditionally disabled the Stop button before starting agentic execution, making it impossible to abort mid-batch; fix: Stop is kept enabled when pending fences exist, and _stop() now sets an _agentic_cancelled flag that is checked at the start of each _batch_execute._next() iteration; cancellation resets the batch badge, suppresses LLM auto-send, and re-enables the Send button
  • Autonomous mode — behaviour matrix popup updated — the popup in Settings → 🤖 Agentic now lists all 16 fence types; previously missing: lint: (in the Inspection row alongside read/ls/grep), http: (new dedicated row: Manual = inspection panel, Semi = auto-sent, Full = auto-sent), sleep: (new dedicated row: all modes run silently with no LLM output), and copy:/delete_dir:/rename_dir: added to the Modifying row; legend updated with project-root security check footnote for delete/rename/copy; dialog minimum width increased from 620 → 700 px
  • lint: fence — manual mode inspection panel fix — in Manual autonomous mode lint results were silently discarded with no way for the user to send them to the LLM; root cause: action_type == "lint" was missing from the elif action_type in ("read", "ls", "grep", "http"): condition that activates the inspection output panel with Send/Dismiss buttons; one-line fix; Semi and Full modes were unaffected
  • patch: fence — silent failure detectionexecute_patch_file previously always reported "✓ Patched" even when no hunks could be matched (e.g. stale context lines from an LLM retry), causing the LLM to receive false confirmation and retry indefinitely; fix:
  • _apply_unified_diff now tracks n_applied, n_total, and failed_headers (the @@ … @@ lines of every hunk that could not be located) and returns all four values as a tuple
  • execute_patch_file raises ValueError when all hunks fail (complete mismatch) — the error message names the specific failing @@ … @@ headers and instructs the LLM to re-read the file and resend with correct context lines
  • Partial failures (some hunks applied, some not) write the partial result then raise ValueError with an "⚠ Partial patch: N/M hunks applied" message
  • Trailing-newline preservation fix: "\n".join(result) previously stripped the original file's final newline; the file's trailing \n is now restored after joining
  • Agentic action errors always forwarded to LLM — in Manual autonomous mode, exceptions raised during fence execution (e.g. patch mismatch, security check failure) were shown in the status label but never sent to the LLM, leaving it without feedback; fix: _run_action's exception handler now returns "[Error: …]" instead of None, and _on_execute detects error results and calls auto_send_fn immediately regardless of mode so the LLM can self-correct
  • Project context warning bar — visual and logic fixes — the amber warning bar (shown when the Spyder project differs from the chat's pinned project root) received several fixes:
  • Border styling — single external border with bottom line visible; the inner QLabel no longer inherits a spurious border from Qt stylesheet propagation (border: none added to both init and dynamic stylesheets)
  • Startup false positive — bar no longer appears at load time when the chat's pinned root matches the live Spyder project; root cause was _live_spyder_root being None at load so any non-None _proj_root triggered the warning
  • _proj_root corruption on project switchon_project_closed() previously set _proj_root = None, causing on_project_loaded(B) to adopt project B as the chat's pinned root; fix: _proj_root is only cleared when project context is disabled; when enabled it is always the user's original pinned root
  • Warning bar not hiding on project switch backon_project_loaded() had no else branch to hide the bar when the new project matches the chat's root; added explicit hide + _proj_warn_shown = False in the matching branch
  • Project context badge — hover info popup — hovering the 📁 Project badge in the context bar now shows a themed popup with: the full project root path, file count in context (or "pending first send"), count of files changed since last send, and up to 5 included folder names (with overflow count)
  • Git bar buttons — hover tooltips — the ⎇ PR desc and ? Changes buttons in the git status bar now show descriptive hover popups explaining what data each button collects and sends to the LLM; the ⎇ Commit button tooltip already existed and is updated dynamically based on whether git commit is enabled
  • Context estimation popup — message counts section — the "Estimated context tokens usage" hover popup now includes a Messages count section below the token breakdown, showing user message count, agentic output count, and LLM response count for the current context window, plus a Total messages summary row; all rows share the same table as the token stats so columns are perfectly aligned
  • Context estimation popup — Full history section — when LLM summary compaction is active the popup also shows a Full history section (rendered in a blue accent colour to distinguish it from the green context-window stats) with the total token count across all messages (including compacted history, shown as a percentage of the context limit) and the total message count; when compaction is off this section is hidden since context window = full history
  • Context estimation popup — title renamed — heading changed from "Used context estimation in tokens" to "Estimated context tokens usage"; spacing between the heading, the token summary line, and the bar graph also improved

0.9.0

  • copy: agentic fence — new fence that copies a file or directory to a destination path; the destination is written in the fence body (one path per line); files are copied with metadata preserved (shutil.copy2); directories are copied recursively (shutil.copytree; destination must not already exist); relative paths are resolved from the project root; both source and destination are validated against the project root security guard so out-of-project copies are blocked even after the user confirms; enabled by default in Settings → 🤖 Agentic → File operations; included in the injected system prompt only when enabled
  • http: agentic fence — new fence that makes an HTTP request (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS) using stdlib urllib (no extra dependencies) and returns the response to the LLM:
  • Syntax`http:GET https://api.example.com/data` for a plain request; request headers (before the blank line) and a request body (after the blank line) can be placed in the fence body; JSON bodies receive Content-Type: application/json automatically when not specified
  • :text modifier`http:GET:text https://example.com/page` strips HTML tags, <script>, <style>, <svg>, and other non-text elements from the response body using stdlib html.parser, leaving readable plain text; block-level tags (<p>, <div>, <h2>, etc.) are converted to newlines; inline whitespace is collapsed; useful for scraping page content without token-heavy markup
  • Response format — status line, up to 15 response headers, then the body (capped at 10 000 chars with a truncation note when exceeded); HTTP-level 4xx/5xx errors are treated as valid responses (rc=0) so the LLM sees the actual error body; network/timeout errors return rc=1
  • Non-blocking UI — the HTTP request runs in a background _HttpWorker(QThread) so Spyder's UI remains responsive during the 30-second timeout; the button shows ⏳ Fetching… while in flight
  • Agentic output block — in full/semi autonomous mode the result flows through the same batch-chain mechanism as git (run_direct_chained + on_http_done_extra) so it appears as a proper "⚙ Agentic output" block, not a separate standalone user message
  • SettingsHTTP requests checkbox in Settings → 🤖 Agentic → Application calls; off by default (network access); when unchecked, fence is blocked and its section excluded from the injected system prompt
  • lint: agentic fence — new inspection fence that runs pylint on one or more Python files and returns the analysis to the LLM:
  • Syntax`lint:path/to/file.py` (single file), `lint:src/` (directory, recursive, up to 50 files), `lint:src/**/*.py` (glob pattern); optional pylint arguments in the fence body (e.g. --disable=C0301 --max-line-length=120)
  • Progress indicator — button shows ⏳ Running… while the subprocess runs; no confirmation required in "confirm only modifying actions" mode (treated as a read-only inspection fence alongside read:, ls:, grep:)
  • Source line injection — each pylint message in the returned JSON includes a "source" field with the exact line of code at the reported location (single line, indentation preserved); files are opened once per path and cached; absent if the file cannot be read
  • Compact inline summary — all errors (up to 20) and the first 5 warnings shown with file path, line number, symbol, and source line; convention and refactor issue counts shown as totals only; a score header (Score: X.XX/10 — N issues in M file(s) | E:N W:N C:N R:N) is prepended
  • Per-file JSON reports — full pylint JSON written to .ai_chat/lint/<rel_path>.json mirroring the project structure; persist across re-runs; navigable with read: / ls: fences
  • Spyder Code Analysis panel — delegates to Spyder's own start_code_analysis() so the score and results always populate correctly (pylint --output-format=json does not output the score line; Spyder's text-format runner does); single-file runs trigger immediately; multi-file/directory runs are queued with 3-second gaps between each file; silently skipped when the Pylint plugin is absent
  • SettingsRun linter checkbox in the new Application calls group in Settings → 🤖 Agentic (enabled by default); when unchecked, the fence is blocked and its section is excluded from the injected system prompt
  • Lint fence block — empty body fix — a lint fence with no extra args no longer shows two blank lines below the header; the code body widget is suppressed when the fence body is empty (extra args are shown when present); the "✓ Done" badge moves to the header row, consistent with other inspection fences
  • Settings → 🤖 Agentic — Allow actions reorganised into two groups — the flat checkbox grid is replaced by two labelled group boxes: File operations (create/overwrite files, apply patches, read files, list directories, search files, delete files, delete directories, rename/move files and directories) and Application calls (run code in console, install packages, run git commands, run linter); no functionality changed
  • Compaction command — plugin-style display — the LLM summary compaction request message is now rendered as a collapsed purple "📦 Compaction request · click to expand/collapse" frame instead of a plain user message bubble, making it visually distinct from real user input; the plugin_command field is persisted in the message dict so the style is preserved on history reload

0.8.8

  • Collapsible agentic action pairs — completed assistant+agentic-output message pairs are now automatically collapsed into the assistant title row after rendering; the label shows "Agentic: Read file, Git command ▶" (dark-yellow, with action names de-duplicated); clicking it expands both inner blocks and changes the arrow to ; clicking again collapses; delete buttons are hidden while collapsed and restored on expand; consecutive runs of 2+ agentic pairs are grouped under a single label with repeat counts (e.g. "Agentic: Git command ×2 ▶"); applies to both history loads and live streaming responses; _blocks is never modified so the block_idx → msg_idx mapping used by delete remains correct
  • Agentic collapse — live grouping shake fixed — when a second consecutive agentic pair arrived during live streaming, the chat briefly "shook" (content flashed visible then re-collapsed) as the old undo+redo approach removed and re-inserted the summary label; replaced with a surgical extension strategy: on each _wrap_agentic_pairs() call the existing collapse group is grown in-place by appending new widgets to the same mutable list already captured by the toggle closure, and the summary label text is updated via setText() instead of being removed and re-created; the toggle closure automatically covers the new widgets because it holds a reference to the shared list; zero visual artifact, no expand/contract cycle, no floating label
  • Fence parser — infinite loop on spaces in fence tag fixed — any action fence whose tag contained a space (e.g. ```grep:SHOW TABLES, ```file:path/with spaces.py) caused parse_blocks() to enter an infinite loop, making Spyder completely unresponsive; root cause: the fence-opening regex \S* stopped at the first space so the line failed to match the fence branch; the paragraph collector then immediately broke on its own ^``` guard without advancing i, sending the outer loop back to the same line forever; fixed by changing the regex capture group from \S* to (\S[^\n]*?|) so the full tag (including embedded spaces) is captured as long as it starts with a non-whitespace character; a second defensive elif i += 1 guard was added after the paragraph collector so that any ```-starting line that still fails the fence regex (e.g. ``` lang with a leading space between the backticks and the lang) advances i rather than looping
  • Blockquote rendering fix — the > markdown blockquote no longer shows a doubled vertical line on the left; root cause was Qt's built-in frame border engine adding a second line when border-left was set on a QFrame; fixed by switching to a plain QWidget with a separate 3 px wide coloured child widget as the accent bar; nested fenced code blocks inside blockquotes now render correctly as full syntax-highlighted code block widgets instead of plain text
  • Plugin logo in Settings dialog — the plugin logo is now displayed at the bottom of the tab-bar column in the Settings dialog; it is embedded in the package under spyder_ai_chat/resources/ (declared as package data in pyproject.toml) so it is available after pip install without any extra files; position is recomputed on every resize via resizeEvent
  • Git bar disabled by default — the git status bar is now off by default for new installs; users enable it explicitly once they have confirmed git is available on their system
  • Git availability check on enable — when the "Show Git status bar" checkbox is ticked in Settings → ⎇ Git bar, the plugin immediately checks git availability via shutil.which("git") (a pure PATH lookup — no subprocess, no blocking, no console flash); a green "✓ git found in PATH" label appears next to the checkbox if git is found; if git is absent a red "⚠ git not found in PATH — bar will not work" warning is shown and the checkbox is automatically unchecked; the check also runs at dialog open time if the setting was already enabled

0.8.7

  • Settings — light theme support — resolved multiple elements that were invisible or showed a black box when Spyder's light UI theme was active: Context tab warning boxes (LLM Project Context and LLM Summary compaction), Agentic tab full-autonomy warning, Commands tab built-in commands group box, Connection tab title label, autonomous mode behaviour matrix popup (all colours now theme-conditional), and agentic system prompt preview textarea; all theme-adaptive styling uses a _is_dialog_dark() helper that reads Spyder's appearance/ui_theme setting with a QPalette luminance fallback
  • Table rendering — height fix — LLM table responses no longer stretch to fill the full chat window height when no vertical scrollbar is visible; root cause: QTextBrowser.showEvent fired before the viewport had a valid width, causing setTextWidth(0) which produced an enormous document height; fixed by guarding against w ≤ 0 before calling setTextWidth and changing the vertical size policy from Expanding to Preferred
  • Manual mode — inspection output panel — executing a read:/ls:/grep: fence in Manual autonomous mode via the batch confirmation dialog now correctly shows the per-block output panel with "📤 Send to LLM" and "✕ Dismiss" buttons; previously the result was silently discarded because the _on_execute() path was never reached in the batch execution route
  • Manual mode — git output panel — confirming a run:git fence in Manual mode now shows the git output panel with "📤 Send to LLM" and "✕ Dismiss" buttons; previously git output was auto-sent to the LLM without user control regardless of mode
  • Manual mode — modifying action results auto-sent — results from file:, patch:, delete:, rename:, and install: fences confirmed in Manual mode are now automatically forwarded to the LLM as brief confirmations so it knows what completed; only read:/ls:/grep: and run:git results remain under user control via the output panel
  • "📤 Send to LLM" on git panel — sends immediately — clicking the button on a git output panel previously only added an attachment tag to the context bar without triggering a message send; it now calls auto_send_fn which adds the tag and immediately fires _send(), consistent with the inspection panel behaviour
  • Autonomous mode behaviour matrix — git row added — git now has its own row in the matrix popup (Manual: "panel → user decides"; Semi/Full: "auto-sent ✓"); previously git was incorrectly grouped under the Modifying row showing "auto-sent ✓" for Manual mode; legend updated accordingly
  • Git output panel — text always visible — the text area no longer collapses to show only a scrollbar when the command output contains a long line (e.g. the LF→CRLF warning from git add); changed from NoWrap to WidgetWidth wrap mode so long lines fold instead of triggering a horizontal scrollbar that consumed the full widget height; added a minimum height floor of 52 px to guard against near-zero font metrics on hidden widgets
  • Dead code removed — four legacy inject_*_output_fn closures and their env-dict keys have been removed; they were superseded by auto_send_fn across all output panel send paths
  • Editor keyboard shortcuts — two keyboard shortcuts are now available in the Spyder code editor: Ctrl+Shift+A adds the current file to the AI Chat context; Ctrl+Shift+Q adds the current text selection to the context; both shortcuts are scoped to the editor widget so they do not interfere with the rest of Spyder; the key bindings are also shown as hints in the right-click AI Chat submenu

0.8.6

  • Dynamic agentic system prompt — the agentic system prompt injected into each chat is now assembled at send time from only the fence types that are enabled in Settings → 🤖 Agentic; a user who enables only patch: and read: sees a prompt that describes only those two fences — the LLM is never told about fences it cannot use; previously the full 12-fence prompt was always sent regardless of which fences were enabled
  • Mode-aware agentic prompt wording — the injected system prompt now adapts its phrasing to the selected autonomous mode; the preamble correctly describes whether the user must confirm actions via a dialog, whether results are auto-forwarded, or whether execution is fully silent; git output, delete/rename confirmation text, and the inspection-fence discipline paragraph also vary by mode
  • Missing delete / rename fences in system prompt — fixeddelete:, delete_dir:, rename:, and rename_dir: fences were fully implemented but never mentioned in the agentic system prompt, so the LLM did not know they were available; they are now included as conditional sections (shown only when the respective fence is enabled in Settings)
  • Settings: read-only agentic prompt preview — the editable prompt textarea in Settings → 🤖 Agentic is replaced by a collapsible read-only preview that shows the exact system prompt that will be injected for the current combination of enabled fences and selected autonomous mode; the preview updates live as any checkbox or mode radio button is toggled; the prompt_template field is removed from saved state
  • Agentic action widget — no blank body for delete / rename fencesdelete:, delete_dir:, rename:, and rename_dir: action blocks in the chat no longer show an empty text area below the header; the target path (and destination for rename) is fully described in the header row, so rendering an empty content body was redundant; the fix aligns these fences with git, read, ls, and grep which already suppressed the body area
  • Chat history paging — chats longer than 120 messages are now split into pages; a centered navigation bar (<< / < / five numbered page buttons / > / >>) appears below the chat area when paging is active; the current page button is highlighted in blue; opening a saved long chat displays the last (newest) page with the scroll position anchored to the bottom; navigating to any earlier page scrolls to the top; page navigation reuses the batched-load pipeline with a "Page N loading… N%" progress overlay so the UI stays responsive; page navigation buttons are disabled during active streaming and re-enabled when the response finishes; chats with 120 or fewer messages are completely unaffected — the page bar stays hidden
  • Incremental chat history loading — history loading is now split into batches of 12 messages with an event-loop yield between each batch, so the application remains interactive (scrollable, closable, resizable) while a large chat loads; a "Loading chat… N%" progress overlay tracks progress and disappears when the last batch is rendered; before this change the UI froze completely for the entire load duration
  • Chat scroll height — long-chat sizeHint fix — loading a saved chat with more than 120 messages no longer produces large blank space below the last message; root cause was Qt's internal sizeHint cache becoming stale after rendering many word-wrapped labels in a single layout pass; paging caps the rendered widget count to 120 per page (20 full batches of 6), which stays within the range where the cache remains reliable
  • Patch diff line numberspatch: action blocks in the chat window, the single-action confirmation dialog, and the batch confirmation dialog all now show line numbers on the left border of the diff view; two gutter columns display old-file line number (left) and new-file line number (right), both parsed from @@ hunk headers so they reflect real file positions rather than diff-relative offsets; removed lines show only the old-file number, added lines show only the new-file number, context lines show both; gutter width auto-sizes to the widest line number in the diff; @@ hunk separator rows now display the full header text (@@ -N,M +P,Q @@) instead of the former ────────────── placeholder
  • Patch application — context verification_apply_unified_diff now verifies that the file content at the line-number-computed position matches the expected hunk context before applying; previously each hunk was written blindly, meaning stale LLM-generated line numbers could silently corrupt lines far from the intended edit
  • Patch application — fuzzy fallback with offset recalibration — when context verification fails (stale line numbers), the engine falls back to a content-based fuzzy search; when a fuzzy match is found at a different position, the running offset is recalibrated so all subsequent hunks in the same diff are also placed correctly; hunks that cannot be located by either strategy are skipped rather than misapplied
  • Patch application — Python indentation / whitespace preservation — when the fuzzy path is taken, context lines (unchanged lines that bracket the actual edit) are now sourced from the FILE's original content verbatim instead of from the diff; this prevents the LLM's slightly-wrong context lines (e.g. 3 spaces instead of 4, or missing trailing whitespace) from overwriting correct indentation — especially important for Python code where indentation is semantically significant; added lines continue to use the diff content as the LLM set their indentation intentionally
  • Chat scroll height — bug fix — fixed ~950 px of empty space appearing at the bottom of the chat pane after a streaming response finished; root cause: QScrollArea processes updateGeometry() asynchronously via QEvent::LayoutRequest, so the content widget retained its old inflated height for one event-loop pass after the streaming label was removed; fix: synchronously resize _ChatHistory to the correct height immediately after layout invalidation; also improved the _scroll_to_bottom retry condition to distinguish genuinely-unreachable scroll targets from layout-not-yet-propagated cases

0.8.5

  • Context History Compaction — new configurable feature in Settings → 📁 Context that limits how much history is forwarded to the LLM on each turn without ever deleting messages from the local chat log:
  • Cut-off strategy: oldest user+assistant pairs are silently dropped from the LLM payload when estimated token usage exceeds the configured threshold (%)
  • LLM summary strategy: in Full autonomous mode, a summary request is automatically sent when the threshold is reached; the LLM's response is stored as a collapsible 📦 compaction block in the chat; all subsequent sends include only messages after that block, with the summary injected as a system context note
  • Per-provider/model token limit table with provider dropdown and editable model combo (pre-populated with the live model list when provider matches the active one); configurable default fallback limit and trigger threshold
  • Compaction is automatically disabled while Project Context is active
  • Built-in commands — new plugin-defined command category (not user-editable, not stored in commands.json); shown with ⚡ prefix and blue-purple colour in a dedicated "── Built-in ──" section of the slash-command picker dropdown; displayed read-only in a group box at the top of the Commands settings tab; built-in names are protected from user collision in the save validator
  • /compact built-in command — manually triggers LLM summary compaction of the chat history; visible in the dropdown only when ALL four conditions are met simultaneously: Context History Compaction enabled, strategy = LLM Summary, autonomous mode = Full, and Project Context not active for the current chat; ignores the token threshold but re-validates all other guards before firing; selecting it removes the / from the input field and fires the compaction silently (no user message is added to the chat)
  • Context size estimate in params bar — always-visible ~X.Xk / Yk (Z%) button on the right side of the inference params bar; colour-coded: gray (normal), amber (near compaction threshold), red (over limit); hovering shows a dark floating popup with a progress bar and per-category token breakdown (history messages, system prompt, context files, compaction buffer, total, free space) plus the active compaction strategy and threshold; refreshes on every send, LLM response completion, and chat switch
  • Inspection fence output panel — executing a read:/ls:/grep: fence in manual mode (auto-send OFF) now shows a scrollable output panel with "📤 Send to LLM" and "✕ Dismiss" buttons; previously the result was silently discarded when the user clicked Execute
  • Confirm dialog for inspection fences — the confirmation dialog for read:/ls:/grep: fences now shows the correct icon, a human-readable label ("Read File" / "List Directory" / "Search in Files"), and a styled detail block (file path with optional line range, directory path, or pattern + scope); previously showed "? read" with an empty preview body
  • Project root in system prompt — when a Spyder project is open the absolute project root path is automatically appended to the system prompt so the LLM uses it as the base directory for all file operations even when Project Context is disabled; prevents the LLM from defaulting to the filesystem root
  • Agentic output visual — the collapsed "⚙ Agentic output" user-message frame now has a straight blue left border (#569cd6, border-radius: 0) matching the style of regular user message bubbles
  • Attachment content tooltip — hovering over any locked attachment badge in a sent user message shows the first 25 lines of the attachment content as a tooltip; a "… (N more lines)" footer appears when the content is longer
  • Regenerate after service error — bug fix — fixed two root causes of the LLM not receiving agentic action output when regenerating after a failed response: (1) _on_regenerate now correctly marks already-executed fence indices so they are excluded from _exec_registry during the history rebuild; (2) read:/ls:/grep: results now use source="result" (was "file") so they are never silently dropped by add_file_context_content when Project Context is enabled
  • Context size estimate refresh on chat switch — bug fix — the context size estimate in the params bar now correctly recalculates after loading a saved chat; previously _update_ctx_size_label() was called before messages were restored, so the counter always showed the empty-history value until the next LLM call
  • "Send to LLM" button — the "📎 Add to chat" label on the inspection output panel and git output panel renamed to "📤 Send to LLM"
  • Settings: ⎇ Git bar tab — git status bar settings moved from the Context tab to a dedicated "⎇ Git bar" tab placed between History and Context
  • Settings window height — minimum height raised from 520 px to 770 px
  • Context tab: Project Context warning — amber warning banner added inside the "📁 LLM Project Context" settings group and in the folder-selection dialog, advising users to prefer agentic read/ls/grep actions for token efficiency
  • Agentic warning colour — the "Full autonomous mode" warning box in Settings → 🤖 Agentic now uses amber styling (matching the Project Context warning) instead of red
  • "− Remove row" button fix — the button in the Compaction token limits table was clipping the last letter; width corrected
  • /clear built-in command — clears all messages in the current conversation while keeping every setting (model, system prompt, inference parameters, project context, collection); the conversation is unconditionally saved to history before wiping regardless of the autosave setting; always visible in the slash-command picker for all chats; does not add a user message to the chat; replaces the former toolbar 🗑 button
  • Read fence batch grouping — two or more consecutive read:/ls:/grep: action blocks from the same LLM response are automatically collapsed into a single collapsible summary block: ▶/▼ toggle in the header, scrollable path list, ✓ Done badge in the header row; individual button rows are hidden; applies to both live streaming responses and history reloads
  • Read fence auto-batching in off mode — when autonomous mode is Off, all read:/ls:/grep: fences in a response are collected into a single batch execution (matching the behaviour of Semi/Full modes); previously each fence required a separate manual Execute click
  • Agentic output hover popup — the "⚙ Agentic output" label now triggers a custom scrollable floating popup on hover instead of the system QToolTip; dark blue (#0d1a2e) background, 420 px max height with vertical scroll, 200 ms hide grace timer; tooltip fires only from the label text, not the full header row
  • Context size refresh on delete — the ~X.Xk / Yk (Z%) token counter now updates immediately after deleting any exchange; previously it stayed stale until the next LLM send
  • /clear history save fix — the clear action now saves to history unconditionally before wiping; previously the save was gated on the save_on_new setting, meaning an autosaved file could remain on disk with old messages and reload them when navigated to from the history popup
  • "Off" autonomous mode renamed to "Manual" — the former Off mode now shows a batch confirmation dialog for ALL action types (read/ls/grep and modifying alike), identical to Semi mode, but results are never auto-sent to the LLM; the key distinction between Manual and Semi is purely the auto-send step; the internal stored value "off" is unchanged for backward compatibility
  • Autonomous mode behaviour matrix popup — a small button next to the "Autonomous Mode:" label in Settings → 🤖 Agentic opens a dialog with a colour-coded table showing confirmation style and auto-send behaviour for every action type across all four mode variants (Manual, Semi, Full-confirm, Full-silent)
  • Removed "Auto-send individual Execute results" checkbox — the standalone checkbox that was only enabled in Manual mode has been removed; it was redundant (Manual+auto-send is functionally identical to Semi) and misleading given the new batch-dialog behaviour
  • Agentic mode enabled by default — new installs start with agentic mode on; context history compaction is also on by default with the Cut-off strategy
  • Stop-before-first-token Regenerate fix — clicking Regenerate after stopping a response before any tokens arrived now correctly re-sends the last user message; previously _on_regenerate bailed out immediately because the last stored message was the user's auto-send (not an assistant reply), and the Regenerate button itself was not repositioned after the empty streaming block was removed
  • Console output shown as Agentic output block — auto-sent console execution results are now rendered as the collapsed blue ⚙ Agentic output frame (matching other agentic auto-sends) instead of a plain "You:" user bubble; root cause was a missing _pending_agentic_response = True flag in the async console output callback
  • Batch confirm dialog patch preview fix — opening the batch confirmation dialog when it contained a patch: action caused a TypeError: _diff_to_html() got an unexpected keyword argument 'context_lines'; fixed by passing font_size=9 as a positional argument, matching the function signature
  • Settings version label fix — the plugin version label in the bottom-left of the settings dialog was clipped to "Ch" because tabBar().sizeHint() was called while WA_DontShowOnScreen was active (zero layout size); replaced setFixedWidth(sizeHint) with a natural-width label + addStretch() between label and buttons

0.8.4

  • Full autonomous mode — new third execution mode in Settings → 🤖 Agentic; the LLM's requested actions are executed immediately without any confirmation dialog; sub-option "Confirm only modifying actions" (default ON) still shows the batch dialog for file/patch/run/install/git actions while silently auto-executing read-only inspection fences (read/ls/grep)
  • Autonomous mode redesign — the former "Semi-autonomous mode" label + two checkboxes are replaced by a proper Autonomous Mode section with three mutually-exclusive radio buttons: Off, Auto-show batch confirmation (semi — default), and Full autonomous; "Auto-send execution results" is a standalone option below the radios, free to toggle in Off mode, forced ON in Semi/Full
  • On-demand file inspection tools — three tool types let the LLM inspect project files without requiring full project context: read:path/to/file.py (full, line-range, or :lines numbered read), ls:some/dir/ (directory listing with line counts for ≤50 entries), and grep:path/or/dir with the Python regex in the block body (file:line output, capped at 200 results)
  • Read line-range syntaxread:path/to/file.py:100-150 reads only lines 100–150; read:path/to/file.py:100-150:lines includes line numbers at the beginning of every returned line; header always shows total line count so the LLM knows the file size
  • Inspection error forwarding — when a read:/ls:/grep: fence fails (file not found, invalid regex, etc.) the error is now forwarded to the LLM so it can react correctly instead of hallucinating based on missing output
  • Inspection fence discipline in system prompt — the agentic system prompt now explicitly instructs the LLM to end its response immediately after outputting a read:/ls:/grep: fence and not speculate about the contents before receiving real results, preventing duplicate responses
  • Git bar refresh timer configurable — new "Refresh interval" spinbox in Settings → 📁 Context → Git Status Bar (default 10 s, range 5–300 s); the timer catches working-tree edits that don't touch .git/HEAD or .git/index
  • Git bar counts untracked files — switched from git diff --shortstat HEAD (tracked only) to git status --porcelain; new/untracked files now appear in the diff stats immediately without staging
  • All git outputs forwarded in batch — fixed a bug where only the first run:git command's output was sent to the LLM when multiple git commands were batched; root cause was (1) target always empty for git blocks (command lives in content), (2) duplicate tag names silently dropped by add_file_context_content
  • Settings tabs vertical with horizontal labels — the settings dialog tab bar is now on the left side with compact horizontal text labels; tab height is font-height + 24 px padding; version label moved to bottom-left corner centred under the tab column
  • Context tab grouped — the Context settings tab is split into two QGroupBox sections: "📁 LLM Project Context" and "⎇ Git Status Bar"
  • Agentic output tooltip — hovering over an ⚙ Agentic output block shows the full message text and each attachment's content in a tooltip; clicking no longer expands the block (content is attachment data not meant for inline display)
  • Re-run disabled for inspection fences — the ✓ Done badge on read:/ls:/grep: blocks is a static indicator with no hover animation and no re-run on click, since re-running an inspection doesn't make sense mid-conversation
  • "Copy to editor" button removed — the per-response "📋 Copy to editor" button that appeared after plain-text LLM responses has been removed

0.8.3

  • Batch confirmation dialog — all agentic action blocks produced by a single LLM response are grouped into one scrollable dialog; each row shows a user-friendly verb + target with a per-action include/exclude checkbox; "Run selected" executes only the checked items in block order; "Cancel" leaves all Execute buttons available as before
  • Auto-show confirmation (Settings → 🤖 Agentic → Semi-autonomous mode) — when enabled the batch dialog appears automatically after each LLM response that contains action blocks, without requiring the user to click individual Execute buttons; requires at least one uncompleted action block in the response
  • Auto-send execution results — after actions complete, each result is injected as a context tag and a follow-up is automatically sent to the LLM so it can confirm success or react to errors; always enabled when Auto-show confirmation is on; available independently for manual Execute clicks when Auto-show confirmation is off
  • Collapsible agentic output messages — user messages generated by the plugin (auto-sent results, git action prompts from the git bar) are wrapped in a collapsed ⚙ Agentic output frame in the chat view; click to expand; stored in JSON as "agentic_response": true
  • Sequential git execution in batch mode — when a batch contains multiple run:git commands (e.g. git add -A then git commit), each command waits for the previous to finish before starting, preventing race conditions
  • Auto-dismiss git output panel — when auto-send is enabled, the inline output panel that would normally appear after a git command is suppressed; the ✓ Done badge is shown instead and the output travels to the LLM automatically; the panel still appears in manual mode
  • Settings constraint: auto-confirm implies auto-send — enabling "Auto-show batch confirmation" forces "Auto-send execution results" on and grays it out; the two options can be toggled independently only when auto-confirm is off
  • No console popup windows on Windows — git subprocess calls now use CREATE_NO_WINDOW so no terminal flickers on screen during git operations

0.8.2

  • Git Status Bar — a compact bar below the context tag bar shows the current branch name (⎇ branch), uncommitted diff stats (+N −N in N files), and three action buttons that send a pre-filled prompt to the LLM: Commit (asks the LLM to suggest a commit message + run:git commit fence), PR desc (generates a PR description from the current diff), and Changes (summarises uncommitted changes); the bar is hidden when no Spyder project is open or the root is not a git repository
  • Git bar auto-refresh — the bar updates automatically when .git/HEAD (branch switch) or .git/index (staged changes) is modified, using a non-blocking QThread worker; the worker guard prevents overlapping queries
  • Branch-change context injection — when the active branch changes while a chat has project context enabled, the next delta context update includes the new Branch: header so the LLM always knows the current branch
  • Git info in project context — when the git bar is enabled, Branch: <name> and Uncommitted: <diff_stat> are injected into the project context header sent with each message (configurable via "Show git status bar" in Settings → 📁 Context)
  • show_git_bar setting — new checkbox in Settings → 📁 Context controls both bar visibility and git metadata injection into project context; defaults to enabled

0.8.1

  • run:git agentic fence — the LLM can run git commands via ```run:git fences; each command shows as an orange action block; execution is non-blocking (QThread); output appears inline with 📎 Add to chat / ✕ Dismiss buttons; adding output injects an orange attachment tag into the next message; git availability is checked before execution with a friendly error if git is not on PATH
  • Diff syntax highlightingpatch: action blocks render with coloured unified-diff highlighting (+ lines green, lines red, @@ dividers) in both the chat block and the confirmation dialog; the internal patch text is always preserved unchanged for correct application
  • Robust patch application_apply_unified_diff now falls back to fuzzy line-search when the LLM omits line numbers from the @@ hunk header (bare @@), preventing silent no-op patches
  • Agentic system prompt upgrade notice — removed the hash-based auto-upgrade mechanism; instead shows an amber warning label in Settings → 🤖 Agentic: "If agentic mode doesn't work properly after a plugin upgrade, reset the agentic system prompt!"; Reset to default button moved to the always-visible header row above the collapsible textarea
  • Agentic patch: vs file: rule — the built-in system prompt now includes an explicit rule: use patch: to edit existing files, file: only for brand-new files; editing/modifying prompts always produce a patch: fence
  • Full absolute paths in file attachments — manually attached files, editor selections, and project context blocks all store and display the full absolute path so the LLM can use them directly in fences
  • Wrapping context bar — the context tag bar now uses a flow layout that wraps to the next row instead of expanding the plugin window horizontally; project context toggle stays in a fixed right column
  • Always-off project context on new chat — starting a new chat always disables project context (configurable via the new "Always disable project context when starting a new chat" checkbox in Settings → 📁 Context)
  • Clear manual attachments on project context enable — toggling the project context toggle ON now removes any manually attached files from the context bar (project context replaces them)
  • Live project root for agentic actions — base directory for file/patch/git actions is now resolved lazily at click time using the live Spyder project root, regardless of whether project context is enabled for the chat; home directory is the last-resort fallback only
  • .git metadata files in project contextHEAD, config, COMMIT_EDITMSG and other readable .git files are now correctly collected when project context is active (walk into .git/ root only; subdirectories like objects/ and refs/ are still excluded)
  • Version shown in Settings — plugin version is now displayed at the bottom of the Settings → Connection tab

0.8.0

  • Named chat collections — organise saved chats into user-defined collections (folders inside ~/.spyder_ai_chat/chats/); the Default collection at the root is fully backward-compatible with existing chat files
  • Collection selector in history popup — a "Collection:" dropdown above the search field lets you browse one collection at a time or switch to ⊕ All Collections to search and list chats across every collection simultaneously
  • Collection Manager dialog — click the ⚙ gear button next to the selector to open a side-by-side manager: left panel lists collections, right panel shows chats in the selected collection; buttons: + New, Rename, Delete (with choice to delete chats or move them to another collection), and Move selected to [combo] for bulk chat moves
  • Right-click "Move to →" — context menu on any chat row in the history popup offers a submenu listing all other collections; moving the currently open chat updates the panel's active collection reference live
  • Delete all scoped to current collection — the "🗑 Delete all" button removes only the chats visible in the selected collection; the button is hidden when "All Collections" mode is active
  • Collection badge in All-Collections view — chat rows show a [CollectionName] badge in the timestamp area when browsing all collections, so the source is always visible
  • Persistent collection state — the active collection is saved to state.json (current_collection key) and restored on restart; last_chat_file encodes the collection as "CollectionName/filename.json" for non-default collections (bare filename = Default, fully backward-compatible)
  • Auto-complete settings fix — "Context before cursor" QSpinBox range lowered from minimum 100 to 1, fixing a Qt intermediate-validation bug that caused the value to be silently reset to 100 when clicking OK
  • Button icon fixes — "⚙ Settings" button now uses the Unicode text-variation selector (U+FE0E) to force monochrome rendering on Windows, preventing the coloured emoji appearance at startup

0.7.1

  • Project Explorer context menu — right-click any file (or multi-select files) in the Project Explorer pane to access the AI Chat submenu: Add file to context for a single file, Add N files to context for a multi-selection; directories are silently skipped; the action is automatically disabled when project context is ON (same rule as the editor context menu)
  • Editor context menu fix (Spyder 6.1.4) — the AI Chat submenu in the editor right-click menu disappeared after upgrading to Spyder 6.1.4; fixed by switching from the deprecated codeeditor.menu attribute to the new codeeditor.get_menu('context_menu') / get_menu('read_only_menu') API; both writable and read-only editor tabs are supported; Spyder ≤ 6.1.3 fallback retained
  • Agentic: overwrite header updates live — after clicking ✓ Create file the action block header, border, and button immediately switch to the amber ⚠ Overwrite file state without requiring a chat reload
  • Agentic: patch reloads open file — after ✎ Apply patch succeeds, if the patched file is currently open in the editor its buffer is reloaded from disk automatically; files not open are left untouched
  • Agentic: startup chat action blocks fixedRun in console blocks in the default startup chat now execute correctly on first click; previously they showed ⚠ No console available until the user switched chats and returned (project context and base path were being resolved after the message loop instead of before)
  • Agentic: overwrite detection on startup fixedCreate file blocks in a startup chat now correctly show ⚠ Overwrite file (amber) when the target already exists; previously the block showed the blue ✓ Create file state until the chat was reloaded
  • Action block colourApply patch block changed from purple to lime green (#80c040) on dark green background for better readability
  • Settings: Agentic tab layoutEnable agentic mode and Batch file confirmations now share one row; the four Allow checkboxes are arranged in a 2 × 2 grid; a note explains disabled-action fallback behaviour; the prompt template textarea is collapsible (▶ / ▼ toggle) so the tab fits without scrolling

0.7.0

  • Agentic mode — the LLM can take direct actions using special code fences; each action appears as a styled action block in the chat and requires a one-click confirmation before executing:
  • ```file:path/to/file.py — create or overwrite a file (path relative to project root or absolute); new file is automatically opened in the Spyder editor
  • ```run:python — send Python code to the active IPython console
  • ```install:pip — install one or more packages via the console
  • ```patch:path/to/file.py — apply a unified diff patch to an existing file
  • Agentic settings tab (Settings → 🤖 Agentic): master enable switch, batch-confirm toggle, per-action allow flags (create file, run console, install, patch — install is off by default), default base path field with Browse button, and a customisable prompt template textarea pre-filled with the built-in default; Reset to default restores the built-in prompt
  • Overwrite detectionfile: action blocks show a blue "✓ Create file" button for new paths and an amber "⚠ Overwrite file" button when the target already exists
  • Action block colours — create file = blue, overwrite = amber, run in console = green, install = teal, apply patch = purple; disabled action types fall back to plain code block rendering
  • Done badge — after successful execution the action button is replaced by a ✓ Done badge; hovering the badge reveals ↺ Re-run; clicking re-runs the action
  • Execution persistence — executed actions are stored in the chat JSON; on chat reload Done badges are shown immediately for previously executed blocks
  • Regenerate fix — the 🔄 Regenerate button now correctly injects the agentic system prompt, so regenerated responses include agentic action fences as expected
  • Streaming flash fix — eliminated the brief floating widget that appeared when an action block started rendering during streaming (parentless Qt widget visibility race)

0.6.0

  • Project-wide context — enable the 📁 Proj. Context toggle in the chat bar to attach your entire Spyder project to the conversation:
  • Folder-selection dialog with live token estimate; choose which top-level folders to include
  • First message sends all selected files in full; subsequent messages send only changed files as a delta
  • Open files with unsaved edits use the live editor buffer — the LLM always sees current state
  • New unsaved files (not yet saved to disk) are auto-included from the editor buffer
  • File watcher monitors the project directory; badge shows changed-file count before each send
  • Re-opening a saved chat restores project context; files re-expanded if hashes match, stale badge otherwise
  • Whole-file attachments blocked while project context is ON; editor selections and console attachments remain available
  • New 📁 Context tab in Settings: max file size, max file count, extra exclusion glob patterns

0.5.1

  • Chat history search — live search field in the history popup filters chats by title preview and full message content simultaneously as you type
  • Table <br> tag fix — line breaks inside table cells now render correctly instead of appearing as literal <br> text
  • Table scroll fix — mouse wheel over a rendered table now scrolls the chat window instead of scrolling the table widget independently

0.5.0

  • IPython console context menu — right-click anywhere in the IPython console to access the AI Chat submenu: Add console content to context attaches the full console output; Add selection to context attaches the selected text; both support ANSI-escape stripping
  • Console attachment colour distinction — console context tags in the input bar are rendered with a teal-green background (#1e3a2a / #3a7a5a) to visually distinguish them from blue editor/file tags
  • Think block show/hide scroll fix — clicking the show/hide toggle on a thinking block no longer causes the chat window to jump to the bottom; scroll position is preserved
  • Live code block rendering — code block widget appears as soon as the opening ``` line arrives during streaming and grows line by line; the widget is finalised (scrollbar, exact height) when the closing ``` is received
  • Code block height fixes — height calculated from fontMetrics().lineSpacing() (instead of pointSize()+8); horizontal scrollbar height reserved; single-line blocks no longer clipped

0.4.1

  • Default system prompt for new chat — Settings → System Prompts tab now has a "Default for new chat:" dropdown; the selected prompt is automatically applied to the system prompt field whenever a new chat is started
  • Think block streaming fix<think> blocks are now rendered as a collapsible Thinking widget immediately after </think> arrives during streaming, instead of remaining as raw text until the full response finishes
  • Nested list streaming fix — nested list items now render with correct line breaks during progressive streaming
  • Code-only message fix — messages consisting of a single code block no longer show an empty code widget; the block stays as raw text during streaming and renders correctly when the closing ``` arrives
  • build_code_block crash fix — fixed UnboundLocalError that caused saved chats containing code blocks to fail loading after restart

0.4.0

  • Processing spinner — a braille spinner (⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏) is shown in the chat panel while waiting for the first LLM token; it disappears and the streaming response appears as soon as the first character arrives
  • Incremental markdown rendering — the response is formatted in real time as it streams: completed blocks (headings, paragraphs, code fences, tables, blockquotes, think boxes) are promoted to rendered Qt widgets immediately; only the trailing incomplete block remains as live plain text
  • HTTP error display — API errors (e.g. HTTP 403/500) now appear in a visually distinct dark-red box with an "⚠ Response error" header instead of unstyled text; no spurious empty "Assistant:" block is created on error
  • Delete on error blocks — the delete button on an error response block now works correctly (previously a message-index mismatch caused it to silently fail)
  • Regenerate on error — the Regenerate button now appears on error response blocks, allowing an immediate retry without clearing the conversation

0.3.2

  • Plugin entry-point renamed from ai_chat to ai_chat_plugin (spyder.plugins entry point in pyproject.toml); FIM provider entry-point renamed from ai_fim to ai_fim_provider (spyder.completions entry point)
  • NAME and CONF_SECTION in AIChatPlugin updated to "ai_chat_plugin" to stay consistent with the entry-point key
  • COMPLETION_PROVIDER_NAME and CONF_SECTION in AiFimProvider updated to "ai_fim_provider" and "ai_chat_plugin" respectively

0.3.1

  • Settings → ⚡ Auto-complete tab completely redesigned as a step-by-step wizard: enable checkbox → set provider/URL/key → Load Models → pick model + backend; previous tab was a flat form with no guidance
  • Load Models button with braille spinner animation fetches the model list and automatically probes which FIM backends the endpoint supports; backend probe validates the response body (not just HTTP status 200) to avoid false positives from providers that return {"error":…} on unsupported endpoints
  • Model list and backend list persistence: full dropdown contents saved to config on OK; restored on next open without needing to re-run Load Models
  • Test Connection button added to the Connection tab — sends a GET /models probe and reports the number of available models; uses an OpenAI-SDK-style User-Agent header to avoid Cloudflare 403 (error 1010) blocks
  • Settings window width increased by ~10%; tab bar stretches edge-to-edge with uniform padding
  • "🖊 Dialogs" tab (renamed from "🖊 Editor") with descriptive info label at the top
  • System Prompts tab: Edit button removed; selecting a prompt from the dropdown immediately enables editing; 💾 Save prompt activates only when title or content has been modified
  • Commands tab: Edit button removed; selecting a command immediately enables editing; Save command activates only when name or prompt has been modified
  • FIM cursor-offset fix: cursor position now derived from (blockNumber, columnNumber) and converted with a line-ending-aware helper, eliminating stale completions when files use \r\n endings
  • Editor context menu (Add file / Add selection) fixed: items re-injected on every aboutToShow event to survive Spyder's menu rebuild cycle
  • FIM default values: temperature default changed to 0.5, context before/after cursor default changed to 100 characters

0.3.0

  • AI auto-complete (FIM) — fill-in-middle ghost-text completions in the Spyder code editor (fim/provider.py); registered as a spyder.completions entry point
  • Ghost-text rendering: grey inline suggestion after the cursor; Tab to accept, Escape to dismiss
  • Multi-backend support: Ollama /api/generate, OpenAI-compat /v1/completions, Codestral /v1/fim/completions, chat-completions fallback
  • Trigger modes: auto (debounce), after-newline, manual (Alt+\)
  • Settings → FIM tab: provider, URL, API key, model, backend type, max tokens, temperature, context window, trigger mode, debounce delay
  • Escape key fix: intercepts ShortcutOverride event to prevent Spyder's global Escape shortcut from stealing the dismiss keystroke before the FIM provider can handle it
  • Fixed: editor context-menu items "Add whole file to context" and "Add selection to context" now reliably appear and call the correct attachment handler

0.2.1

  • Slash-command aliases (commands.py): define short aliases (e.g. /tests, /explain) that expand to full prompt text before being sent to the LLM; type / in the input to open a keyboard-navigable picker dropdown
  • 5 built-in commands: /tests, /simplify, /fix, /explain, /doc — auto-seeded on first run to ~/.spyder_ai_chat/commands.json
  • Settings → / Commands tab: create, edit, delete, and restore built-in commands; restoring built-ins does not affect user-defined commands
  • Command highlighting: active command tokens shown with a green highlight in the input field and in sent chat bubbles
  • Chat history: command spans stored in JSON (command_spans); original expanded prompt preserved in content_llm so history replay is correct even if a command is later edited or deleted
  • Chat history preview: command-only messages now show /command — filename.py (attachment), /command — user text, or /command — at yyyy-mm-dd hh:mm (timestamp fallback) instead of the bare command name
  • LM Studio API key: now optional (previously hidden) — shown in Connection tab for setups with authentication enabled
  • Connection tab UI: added "Only one provider can be active at a time." info label, horizontal separator, and "Configure active provider:" label above the provider form
  • Settings → Connection tab: rebuilt to use permanent form rows with show/hide instead of takeRow/addRow on provider switch (layout stability improvement)

0.2.0

  • 12-provider support with a provider registry in settings_dialog.py: OpenAI, Groq, Mistral AI, DeepSeek, Together AI, Fireworks AI, OpenRouter, Azure OpenAI, Ollama, LM Studio, vLLM, Custom — each with its own default URL, API key requirement, and supported inference parameters
  • Provider dropdown with grouping: Local (Ollama, LM Studio, vLLM) / Cloud API / Custom sections with non-selectable separator headers
  • Per-chat inference hyperparameters popup: temperature, max_tokens, top_p, top_k, min_p, presence_penalty, frequency_penalty, repetition_penalty, seed, num_ctx — only parameters supported by the selected provider are displayed; popup anchors above the params bar
  • Inference params bar always visible above the system prompts row: idle state shows muted hint text; amber summary text when params are active; clicking opens the popup; resets on New Chat
  • Bottom panel redesign: inference params bar → system prompts row (label + combo + ⚙ settings shortcut + Copy and edit) → system prompt field → input row (text field + stacked Send/Stop buttons)
  • ⚙ shortcut in system prompts row opens Settings directly on the System Prompts tab
  • Send/Stop stacked layout: Send button takes ~66% of height, Stop ~34%, separated by 4 px gap
  • Azure OpenAI extra fields (deployment name, API version) now correctly hide when switching away from the Azure provider
  • Thinking block now uses a scrollable QPlainTextEdit (max-height 200 px) — eliminates all previous word-wrap and height-calculation issues
  • Code blocks now use QPlainTextEdit with NoWrap mode and a horizontal scrollbar — long lines no longer clip
  • Delete-all warmup reduced from 2 s hover to 1 s hover

0.1.9

  • Delete exchange buttons on every user and assistant message: 🗑 This removes the user+assistant pair, ⏫ All before removes all preceding exchanges; both have a 3-second countdown with ↩ Cancel
  • 🔄 Regenerate button on the last assistant message; moves automatically after deletion or regeneration
  • Fixed: scroll position anchors to the bottom after markdown re-render completes
  • Fixed: clear_all method restored; chat history loading no longer raises AttributeError

0.1.8

  • New Saved System Prompts library (system_prompts.py)
  • Settings → 💬 System Prompts tab: create, edit, delete saved prompts
  • Prompt selector bar with dropdown and 📋 Copy to field button
  • Chat history stores prompt_id; restored on load

0.1.7

  • Fully recursive list parser; mixed bullet/numbered types at any depth; blank-line-separated items
  • Bullet symbols cycle by depth:
  • Numbered lists preserve source numbers
  • Fixed: auto-scroll to bottom on send and during streaming
  • Fixed: short responses no longer float in the middle of the chat area

0.1.6

  • Menu path corrected: Window → Panes → AI Chat

0.1.5

  • PyPI README_PYPI.md added; [project.urls] Homepage field in pyproject.toml

0.1.4

  • Tabbed settings dialog: Connection, Editor, History tabs
  • Configurable font sizes for all rendered markdown elements
  • History saving options with correct enable/disable logic
  • Horizontal scrollbar in chat area for wide code blocks
  • File/text context attachments restructured; locked badges in user message bubbles

0.1.3

  • User-Agent header added to fix 403 errors with Groq and some providers
  • Improved HTTP error reporting

0.1.2

  • Full markdown rendering (markdown_renderer.py): headings, bold/italic, lists, tables, blockquotes, links, strikethrough
  • <think> block support with collapsible thinking box
  • Chat history: save, load, delete, browse
  • Auto-save after every completed exchange
  • Editor context menu: Add whole file / Add selection to context

0.1.0

  • Initial release: streaming chat, model selector, system prompt, stop button, code block rendering with Copy to editor

License

MIT — see LICENSE file.