summaryrefslogtreecommitdiffstats
path: root/CHANGELOG.md
blob: 8d3542e9ff792c8d3c6622c878f45bcee711803b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# Changelog

All notable changes to this project are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.2.1] - 2026-07-31

### Fixed

- Reasoning could be spliced into the reply. A delta carrying both
  `reasoning_content` and an empty `content` was classified by truthiness,
  so the thinking fell through to the content branch and the tail of the
  model's reasoning was stored and shown as the answer. Deltas are now
  classified on the presence of the field, and an empty reasoning delta
  renders nothing instead of falling through.
- An unbalanced backtick reflowed the rest of a reply as code. Leaked
  thinking is dense with backticks, and an odd count left a run open to the
  end of the message. An unterminated fence is now closed before parsing,
  with a closer matching the opener's length, and a lone dangling inline
  backtick is dropped. This also covers streaming, where a fence is
  unclosed on nearly every frame.

### Added

- Context meter in the top bar showing how much of the active model's
  context window the next request will use. It estimates while typing and
  switches to the server's exact token counts after each reply, turning
  amber at 75% and red at 90%. The limit comes from `ctx-size` in
  `presets.ini`, since the router does not report it.
- System prompts stored as markdown files in `~/.config/llamachat/prompts/`.
  A global `default.md` applies to new conversations, named presets replace
  it, and any conversation can take a one-off custom prompt or none at all.
  A dialog behind the picker adds, edits and deletes them; the files stay
  editable outside the app.
- `default_prompt` in `config.toml` chooses what new conversations start
  with.
- Streaming requests now ask for usage statistics, which is what makes the
  meter exact without an extra round trip.
- A toggle for the history panel, on the `☰` button and `Ctrl+\`. The
  panel's width and hidden state are remembered between runs in
  `~/.config/llamachat/state.ini`.
- `Ctrl+N` starts a fresh conversation, `Ctrl+F` jumps to the search field.

### Fixed

- Escape while filtering history dismissed the whole window. It now backs
  out of the search field first: clear the text, then return to the input,
  and only then hide.

### Changed

- Sessions record the system prompt they were built with, so reopening a
  conversation restores it rather than applying whatever is selected now.

## [0.1.0] - 2026-07-31

First working version.

### Added

- Persistent background process with a Unix-socket control channel, so a
  window toggle costs a socket round trip instead of a process start. The
  control commands (`--toggle`, `--show`, `--hide`, `--ping`, `--quit`) do
  not import Qt and answer in well under a tenth of a second.
- Two chat modes. One-shot asks a single question with no context carried
  over; Chat keeps a resumable multi-turn conversation.
- Model picker populated at runtime from the router's `/v1/models`, with
  vision-capable models marked.
- Streaming replies rendered token by token.
- Markdown rendering for replies: headings, emphasis, lists, tables, inline
  code and tinted fenced code blocks, via `QTextDocument` with no markdown
  dependency. User input is shown literally so attached file contents are
  never reflowed.
- Collapsed reasoning. Models with a reasoning budget return their thinking
  in a separate field; it shows as a one-line summary that expands on click,
  tracked per reply.
- File attachment by drag-and-drop or file dialog. Text and code files are
  inlined into the prompt and truncated to fit the model's context with a
  warning. Images require a vision model, and dropping one on a text model
  offers to switch.
- SQLite history with FTS5 full-text search. Chat sessions reopen and
  continue with context intact; one-shot entries reopen read-only.
- Attachment provenance: original path, size, SHA-256, and a thumbnail for
  images, so a reopened conversation still shows what was sent even if the
  file has since moved.
- System tray icon for show/hide/quit.
- Configuration in `~/.config/llamachat/config.toml`, written with defaults
  on first run.
- `presets.ini` parsing for the two things the API does not report: which
  models have an mmproj file, and each model's context size.
- Hyprland Lua snippets for autostart, keybind and floating window rules.

### Fixed

- `presets.ini` opens with a bare `version = 1` before any section, which
  made `configparser` reject the whole file.
- Sessions sharing a one-second timestamp sorted unpredictably in the
  history list and in search results.
- A venv PySide6 bundles almost no Qt plugins, so `QT_QPA_PLATFORMTHEME`
  found nothing and every window fell back to Fusion, ignoring qt6ct and
  Kvantum. The system plugin directory is now used when its Qt version
  matches the bundled one exactly.
- A reply containing a markdown link to the internal reasoning scheme
  produced a working toggle, letting model output drive the interface.
  The scheme is namespaced, forged anchors are rewritten before display,
  and only `http`, `https` and `mailto` links reach the desktop opener.
- Venv discovery compared resolved interpreter paths, so a venv created
  with `--system-site-packages`, whose `bin/python3` symlinks to the system
  interpreter, was discarded as "already running".

### Security

- Markdown is parsed with the `MarkdownNoHTML` flag, so markup in a reply is
  displayed rather than interpreted.
- The control socket is created mode 0600.
- Search input is tokenised and quoted before reaching FTS5, so punctuation
  cannot be read as query syntax.