Releases: VforVitorio/lmcode
v0.7.0
What's new
Model switching mid-session
New /model command lets you switch models without restarting lmcode:
/model list— show all downloaded models with size and load status/model load <id>— load a different model and reset the conversation/model unload— unload the current model from memory
Auto-start LM Studio at startup
When you run lmcode with LM Studio closed, it now automatically tries to bring it up:
- Tries
lms server start(if LM Studio GUI is already open but server is off) - Falls back to
lms daemon up(fully headless, no GUI needed)
Animated dots keep you informed while it starts — no more frozen terminal.
Interactive model picker
When no model is loaded, an arrow-key menu lets you pick from your downloaded models directly from lmcode. Animated dots while the model loads.
ASCII art logo in startup menus
The lmcode banner now appears above every startup menu.
Fixes
- Fast startup: socket pre-check (0.5 s) before SDK probe eliminates the multi-second freeze when the server is not running
lms loadnow uses correct--gpu autoarg format (was--gpu=auto)- Model identifier resolved from
modelKeyfield inlms ls --json
v0.6.1
What's changed
Refactored
agent/core.pysplit into focused submodules — the 1 259-line monolith is now four files:_noise.py— SDK WebSocket noise suppression (installed at import time)_display.py— all print/render helpers, diff rendering,SLASH_COMMANDS_prompt.py— prompt-toolkitPromptSessionfactory, Tab key bindings, autocompletecore.py— slimmed to ~820 lines, ownsAgent,run_chat, system prompt
Fixed
write_filemixed newline unescape — the previous guard"\n" not in contentsilently skipped unescaping when a model (e.g. Qwen 7B) emitted a mix of real and literal\nsequences, producing syntactically invalid Python files. Guard removed; unescape now always runs when a literal\nis present.
Tests
tests/test_agent/test_display.py— full coverage for_ctx_usage_line,_build_stats_line,_format_tool_signature,_render_diff_sidebyside,_print_history,SLASH_COMMANDS.tests/test_agent/test_noise.py— coverage for_FilterSDKNoisestderr wrapper and_FilteredLastResortlogging interceptor.
Full changelog: https://github.com/VforVitorio/lmcode/blob/main/CHANGELOG.md
v0.6.0
What's new in v0.6.0
Fixed
- LM Studio disconnect — closing LM Studio mid-session now shows a clean message instead of a raw traceback:
LM Studio disconnected → restart LM Studio and run lmcode again - SDK WebSocket JSON noise — the
{"event": "Websocket failed, terminating session."}lines that appeared on disconnect are now fully suppressed. Root cause: Python'slogging.lastResortbypasses root-logger filters; the fix wrapslastResort.handle()directly.
Closes #70.
v0.5.0
What's new in v0.5.0
Added
- Ctrl+C interrupt mid-generation — pressing Ctrl+C returns to the input prompt instead of exiting lmcode. Shows
^C+ italicinterruptedwith a Rule separator. Chat history is rolled back cleanly so the next turn has no dangling context. - Syntax-highlighted diff blocks for
write_file— when a file is overwritten the agent displays a side-by-side diff with+/-counts and Catppuccin colours. New files get a dedicated "new file" panel. - Playground folder —
playground/sandbox for end-to-end manual testing of all UI features. /history [n]slash command to review past turns as Rich panels.- Ctrl+R reverse history search in the input prompt.
- Tab mode cycling — Tab cycles through
ask → auto → strict → askpermission modes. - Ghost-text autocomplete for slash commands (accepted with Tab or →).
Changed
run_shelloutput is now wrapped in an IN/OUT panel with a separator Rule and uppercase labels.read_fileresults render in a one-dark themed panel with violet rounded border and line numbers.- System prompt rewritten with tool-first framing, hard constraints, and environment block — tuned for reliable tool-calling on 7B models.
- Tool docstrings rewritten with explicit use-case guidance for better tool-selection on small models.
Fixed
- Verbose panels always shown — the SDK calls tools with positional args, leaving
kwargs={}. Fixed withinspect.signaturepositional-arg merge in_wrap_tool_verbose. write_fileescape sequences — models that emit literal\n/\t/\"(no real newlines) now have those sequences unescaped before writing.- SDK "already closed channel" noise — the warning emitted after Ctrl+C is suppressed via a root-logger
logging.Filterand asys.stderrwrapper. - Completion menu colours, CI lint/typecheck failures.
Tests
79 tests passing. New coverage for write_file escape sequences, _wrap_tool_verbose positional args, keyboard interrupt propagation, and chat rollback after Ctrl+C.
v0.4.0 — animated spinner, ghost-text autocomplete, file preview & /history
What's new in v0.4.0
Spinner & status labels
The thinking spinner now shows animated dots and changes label based on what the agent is doing:
thinking…— waiting for the model's first tokenworking…— a tool call is in progress (shows tool name + path)finishing…— model is generating the final response
Ghost-text slash autocomplete
Type / and the first matching command appears as dim ghost text. Press Tab to accept it inline — no popup menu, no noise.
/h→ ghost textelp→ Tab →/help
Tab mode cycling
Tab without a / prefix cycles the permission mode: ask → auto → strict.
Persistent history (Ctrl+R)
Prompts are saved to ~/.lmcode/history. Use Ctrl+R or the Up-arrow to recall previous inputs across sessions.
read_file syntax panel
When the agent reads a file, the result is shown as a monokai syntax-highlighted panel (up to 20 lines with line numbers) instead of a plain one-liner.
/history [N]
New slash command — prints the last N conversation turns as bordered panels (default 5).
/history # last 5 turns
/history 10 # last 10 turns
Banner fix
The compact banner fallback now triggers at 70 columns (was 90), so the full ASCII logo shows in more terminal widths.
Issues closed
v0.3.0 — /compact, context indicator & cycling tips
What's new in v0.3.0
/compact — summarise history to free context space
Run /compact when the conversation is getting long. lmcode asks the model to summarise everything discussed so far, resets the chat, and injects the summary as context. A bouncingBar spinner shows while compacting, then a panel displays the summary preview and how many messages were collapsed.
Context window indicator (#41)
/statusand/tokensnow show a live arc indicator:◔ 38% (12.4k / 32k tok)- Arcs cycle through
○ ◔ ◑ ◕ ●as usage grows - One-time warning printed after a response when the context exceeds 80%:
⚠ context at 83% — run /compact to summarise the conversation - Percentage is calculated from the last turn's prompt tokens (the actual history size sent to the model), not a cumulative sum
Cycling tips (#38)
Tips below the spinner now rotate every 8 seconds through a shuffled list instead of staying static for the whole turn.
/tokens (#29)
New slash command showing session-wide token totals:
session tokens
prompt (↑) 14.2k
generated (↓) 1.8k
total 16.0k
context ◔ 38% (14.2k / 32k tok)
/hide-model (#36)
Toggles the model name in the live prompt:
- On:
● lmcode (qwen2.5-1.5b-instruct) [ask] › - Off:
● lmcode [ask] ›
Spinner keepalive
The spinner label now refreshes every 100 ms via an asyncio.create_task keepalive, keeping the animation smooth during the model prefill phase.
Requirements
- Python 3.12+
- LM Studio with local server enabled and a model loaded
Usage
pip install lmcode
lmcodev0.2.0 — UI polish, slash commands & error handling
What's new in v0.2.0
UI & interaction
- Spinner:
dotsstyle with violet (brand) colour instead of the old arc - History entries: submitted prompt line rewrites in-place to a dim
› messagestyle — no more cluttered scrollback - Exchange separator: plain
Ruleline after each response cleanly separates turns - Rotating tips: a random tip appears below the spinner while the model is thinking
- Responsive banner: full ASCII art panel on wide terminals, compact 2-line fallback on narrow ones
- Mode badge removed from the startup banner (mode is always visible in the live prompt)
Slash commands
| Command | What it does |
|---|---|
/tools |
List all registered tools with their signatures |
/status |
Show model, mode, verbose, tips, stats, and turn count |
/tips |
Toggle rotating tips during thinking |
/stats |
Toggle the token stats line after each response |
/verbose |
Toggle tool call and result display |
Error handling
- No server: exits cleanly with a clear message when LM Studio's local server is not reachable
- No model loaded: exits with instructions before showing the banner
- Model ejected mid-session: catches
LMStudioModelNotFoundErrorand exits gracefully instead of throwing a traceback - XML in responses: response text is now printed via
Text + highlight=False— Rich no longer mis-highlights XML tags that small models sometimes emit
System prompt
- Model is explicitly instructed to only call tools when the request requires file/shell access
- Model is instructed never to output raw XML, HTML, or JSON schemas
Settings
UISettingsadded tolmcode.toml:spinner,show_tips,show_stats- Token-aware file read limit:
max_file_bytesis now computed from the model's actual context length viamodel.get_context_length()
Developer
mypyclean: addedIterator[Path]return types to generator helpers infilesystem.pyandsearch.py
Requirements
- Python 3.12+
- LM Studio with the local server enabled (default:
localhost:1234) and a model loaded
Usage
pip install lmcode
# or: uv add lmcode
lmcodev0.1.0 — Basic chat with LM Studio
What's in this release
- CLI with ASCII art banner and color palette
- Interactive chat loop connecting to LM Studio via \model.act()
- Auto-detects loaded model (no need to specify --model)
- read_file\ tool with binary detection and truncation
- Per-repo context via \LMCODE.md\ files
- Plugin system scaffolding (pluggy)
- Session event models (JSONL format, recorder coming in v0.2.0)
Requirements
- Python 3.12+
- LM Studio running locally with a model loaded and the local server enabled (default: \localhost:1234)
Usage
pip install lmcode
# or: uv add lmcode
lmcode chat