diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-16 15:28:48 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-16 15:28:48 +0200 |
| commit | cb16fa6c17298a6f2f4aa390c01ff8eacd53a996 (patch) | |
| tree | 61841e10189d8ca4576455adc959c49bdf6d8161 /desktop/assistant/Assistant.qml | |
| parent | 1f596b4e2c59c1fa069d2b549c1d8ae6d5a876cf (diff) | |
| download | quickshell-cb16fa6c17298a6f2f4aa390c01ff8eacd53a996.tar.gz quickshell-cb16fa6c17298a6f2f4aa390c01ff8eacd53a996.zip | |
fix(assistant): keep state across reloads, refusals and long replies
From review. A shell reload reconnected with lastActive at 0, so the next
SUPER+Home started a new conversation thirty seconds into one; hello with
turns now counts as activity. show() could send new under a reply still
running, which stops it unsaved; it waits while busy. ask() cleared the
chips before the daemon accepted them, so a refused file (unreadable, too
big, a model without vision) dropped them and collapsed the card to the
entry line; the user event clears them now, and chatting holds the layout
while a PDF is read.
In the picker, folders ignore name filters and sorted first, so filter
then Enter opened a folder; folders hide while filtering. Folder URLs are
encoded, so a '#' in a name no longer cuts the path, and glob characters
typed in the filter are taken literally. The card says the assistant is
not running in every state, panels sit under the chat header instead of
over it, and History and the picker no longer open together. Dropped
file://localhost/ URLs are accepted, other hosts refused, and the island
receptor keeps the sliver's width at rest so it takes no clicks beside it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'desktop/assistant/Assistant.qml')
| -rw-r--r-- | desktop/assistant/Assistant.qml | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/desktop/assistant/Assistant.qml b/desktop/assistant/Assistant.qml index b038dd6..977b4dd 100644 --- a/desktop/assistant/Assistant.qml +++ b/desktop/assistant/Assistant.qml @@ -78,7 +78,9 @@ Scope { // A conversation idle for 10 minutes is over: opening starts a new one, // the old one staying in History. ponytail: a constant, not a setting. function show() { - if (turns.count && Date.now() - root.lastActive > 10 * 60 * 1000) root.fresh(); + // Never while a reply runs: new would stop it, and a stopped turn is + // not saved. + if (turns.count && !root.busy && Date.now() - root.lastActive > 10 * 60 * 1000) root.fresh(); root.open = true; } @@ -120,15 +122,20 @@ Scope { link.item.flush(); } + // The chips stay until the daemon's user event takes them: a refused + // file (unreadable, too big, a model without vision) comes back as an + // error, and the chips must still be there to fix it. chatting keeps the + // chat layout meanwhile, so the card does not shrink while a PDF is read. function ask(text) { if (!root.connected || root.blocked || (text.trim() === "" && !root.staged.length)) return false; root.notice = ""; + root.chatting = true; root.send({ type: "ask", text: text, files: root.staged.map(f => f.path) }); - root.staged = []; return true; } function showHistory() { + root.pickerOpen = false; root.historyOpen = true; root.send({ type: "list" }); } @@ -172,15 +179,21 @@ Scope { root.ctxUsed = e.ctx_used; root.ctxMax = e.ctx_max; root.load(e.id, e.turns, e.pending); - if (e.pending) root.lastActive = Date.now(); + // A restart or reload counts as active: the conversation it + // reconnects to is not stale just because this process is new. + if (e.pending || e.turns.length) root.lastActive = Date.now(); break; case "conversation": root.load(e.id, e.turns, null); // Opened from History on purpose: it counts as active now. if (e.turns.length) root.lastActive = Date.now(); + // Emptied (New, or the current one deleted) with nothing staged: + // back to the entry line. + else if (!root.staged.length) root.chatting = false; break; case "user": turns.append(root.row({ user: e.text, files: e.files }, true)); + root.staged = []; root.lastActive = Date.now(); break; case "think": root.bufThink += e.delta; break; |
