Commit Graph

354 Commits

Author SHA1 Message Date
Levi Neely 34d4a97b3d gui: complete KF5 build with full feature parity
- Add chatblockmodel.cpp and thememanager.cpp to KF5 GUI target
- Link KF5::ConfigCore and KF5::SyntaxHighlighting to GUI
- Strip Qt6-only grouped palette syntax from QML at configure time
  (ThemeManager::applyPalette handles palette via QGuiApplication)
- Fix QStringList brace-init ambiguity in Qt5
- Fix QList::remove(pos,count) not available in Qt5 (use erase)
2026-08-03 09:03:12 +02:00
Levi Neely 7cb809fad2 revert all system-user-interruption changes 2026-08-03 00:41:49 +02:00
Levi Neely 64883cf9b8 Revert "render system-user-interruption as styled yellow box in prose"
This reverts commit 4e455e2dd3.
2026-08-03 00:39:34 +02:00
Levi Neely 4e455e2dd3 render system-user-interruption as styled yellow box in prose 2026-08-03 00:38:01 +02:00
Levi Neely e08b69c152 fix build: replace-with-lambda requires Qt 6.5+, use manual global-match loop 2026-08-03 00:32:26 +02:00
Levi Neely 1fdae741c3 render system-user-interruption as a styled yellow box with warning icon 2026-08-03 00:31:08 +02:00
Levi Neely cf4313165b fix fence close regex: only match backtick on its own line 2026-08-03 00:27:25 +02:00
Levi Neely b841f556d4 gui: preserve newlines in plaintext blocks 2026-08-03 00:24:52 +02:00
Levi Neely 4dabab1f71 fix connection dot indicators 2026-08-02 23:59:28 +02:00
Levi Neely 41f95e84c2 session ended as disconnect signal 2026-08-02 23:51:40 +02:00
Levi Neely b50a2e01b2 fix source block rendering 2026-08-02 23:48:00 +02:00
Levi Neely 6e7245dd99 connection statuses 2026-08-02 23:35:14 +02:00
Levi Neely c983e2bb6a simplify rendering 2026-08-02 22:43:11 +02:00
Levi Neely 220adf9b05 Fix session and agent rename handling 2026-08-02 22:34:39 +02:00
Levi Neely bd78b2b703 duplicate param 2026-08-02 22:10:31 +02:00
Levi Neely 753467db5b fix: preserve pre-fence text and post-fence content in rendered blocks
When a fence () closes inside a block, prepend any content
that came before the fence to renderedHtml so both text and the
highlighted fence show up. When content is appended after the fence,
keep renderedHtml in sync by appending the escaped text. This prevents
the fence from 'eating' surrounding content.
2026-08-02 11:13:22 +02:00
Levi Neely 67b33f95d2 refactor: StreamFsm lifecycle + chatblock model FSM fix
- Introduce StreamFsm class wrapping QProcess lifecycle with
  Oneshot/Looping/Guarded restart policies
- Replace raw QProcess management in Ollie9pClient with StreamFsm
- Fix chatblockmodel FSM to properly handle [[[end]]] and fence
  transitions with a combined State enum (Outside/InBlock/InFence)
- Add Q_INVOKABLE to setActiveSessionId for direct QML access
- Add streamfsm.cpp to CMakeLists.txt for both KF5 and KF6 builds
2026-08-02 11:11:05 +02:00
Levi Neely bfac41b2ae gui: update eventwait to use new global /eventwait with structured events
- Changed path from session/eventwait to /eventwait (global, not per-session)
- Use ollie-9p instead of plan9port 9p for the read
- Changed from parsing full session index to just calling refreshSessions()
  on any event (the event format is now structured deltas, but the GUI
  is kept simple with a full index refresh)
2026-08-02 10:25:10 +02:00
Levi Neely cd7bb9e272 gui: stop validating statewait via agent directory listing
startStateStream now trusts the explicit session/agent selection and
opens session/<sid>/agent/<aid>/statewait directly. It no longer calls
getAgents(), which was repeatedly listing session/<sid>/agent on every
statewait reopen.
2026-08-01 21:53:01 +02:00
Levi Neely 3bb75b6c20 gui: stop rebuilding session tree on selection changes
The dominant 9P spam came from buildSessionTree() re-listing
session/<sid>/agent on every activeSessionIdChanged and
activeAgentIdChanged signal. Tree rebuilds are now limited to
sessionsChanged and startup refresh; selection changes only
refresh the right pane transcript.
2026-08-01 21:48:04 +02:00
Levi Neely 50bca0a770 gui: add debug logs for session/agent selection and statewait startup 2026-08-01 21:24:38 +02:00
Levi Neely b8fc64fb18 gui: clicking a session clears explicit agent selection
- Session row click now calls setActiveSessionId(id)
- setActiveSessionId no longer returns early for same-session clicks;
  it always clears m_agentId and stops per-agent streams
- This enforces a clean 'session selected, no agent selected' state
2026-08-01 21:22:33 +02:00
Levi Neely 38cd1313ec gui: make switchAgent the only stream-start path
- setActiveSessionId remains session-only and never starts streams
- setActiveAgentId now clears any existing per-agent streams and only
  updates selection/state
- switchAgent is explicitly the only place that starts chat/statewait
- onStateFinished only reopens for the current explicit selection
2026-08-01 21:20:52 +02:00
Levi Neely 22e58b348f gui: require explicit agent selection for statewait/chat
- setActiveSessionId now selects only the session; it clears m_agentId
  and never auto-selects a lone agent.
- startStateStream no longer re-resolves or falls back to another agent;
  it only runs when the explicit active agent still exists.
- QML now handles activeAgentId changes explicitly and keeps the right
  pane blank/disabled when no session or no agent is selected.
2026-08-01 21:18:09 +02:00
Levi Neely 56b08d8f8f Revert "gui: never auto-restart statewait/chat streams on finish"
This reverts commit 608127e4ac.
2026-08-01 20:59:08 +02:00
Levi Neely 9f51a2181b Revert "gui: verify agent directory before starting statewait/chat streams"
This reverts commit dbbcc07934.
2026-08-01 20:59:08 +02:00
Levi Neely dbbcc07934 gui: verify agent directory before starting statewait/chat streams
Add a run9p stat check before opening blocking reads on
statewait and chat. If the agent directory doesn't exist,
skip starting (prevents tight restart loops when a session
is killed while streams are active). Only one statewait
reader runs at a time.
2026-08-01 20:56:40 +02:00
Levi Neely 608127e4ac gui: never auto-restart statewait/chat streams on finish
onStateFinished and onChatFinished no longer restart their
streams. Streams are only started when the user explicitly
selects an agent (setActiveSessionId for single-agent,
switchAgent for multi-agent). This prevents tight restart
loops when pointing to a nonexistent directory.
2026-08-01 20:55:41 +02:00
Levi Neely ef03cdc7f3 gui: deduplicate sessions from multi-agent index, fix field mapping
- Deduplicate session entries in refreshSessions and onEventReadyRead
  using QSet to skip duplicate session IDs from multi-agent index.
- Fix field mapping: index format is name\tstate\tcwd\tbackend\tmodel\tagent
- Added QSet include
2026-08-01 20:53:07 +02:00
Levi Neely 5fc4ebe64e gui: track agents by name, not by index
- setActiveSessionId: only auto-select agent when exactly ONE exists.
  With multiple agents, clear m_agentId and let user click on
  an agent node in the tree to activate it.
- startStateStream: verify current agent directory still exists
  instead of always re-discovering to the first agent. Only
  fall back to first agent if current agent is gone.
- Emit activeAgentIdChanged so QML reacts to agent changes.
2026-08-01 20:49:39 +02:00
Levi Neely e3fc0c49dd fix(gui): stop trimming lines before splitting by tab
The previous fix stopped trimming the whole output but still called
.trimmed() on each individual line, which stripped trailing tabs from
empty-session lines like "testsession2\t\t\t\t\t". Now we split
by tab directly without any trimming — empty fields stay as empty
strings and the parts count stays at 6.
2026-08-01 20:20:01 +02:00
Levi Neely f0a2185e2f fix(gui): trailing tabs stripped by trimmed() dropping empty sessions
refreshSessions() and onEventReadyRead() called .trimmed() on the full
session/idx output, which stripped trailing tab characters from the
last line. An empty session line ("testsession2\t\t\t\t\t")
became just "testsession2" — a single field that failed the size>=2
check and was silently dropped from the session list.
2026-08-01 20:18:26 +02:00
Levi Neely c8fb652785 debug: add qDebug output to session refresh and event handler 2026-08-01 20:16:47 +02:00
Levi Neely c85252b09a fix(gui): prevent session list from stealing keyboard focus
- ListView and its placeholder label now have activeFocusOnTab: false
  and focus: false so clicking the empty sidebar doesn't steal focus
  from the prompt text area
2026-08-01 20:14:40 +02:00
Levi Neely b68b72b31f fix(gui): use eventwait data directly, remove focus-stealing timer
- onEventReadyRead() now parses the eventwait data directly instead of
  discarding it and re-reading session/idx
- Removed the 2-second refresh timer that was stealing focus from the
  prompt text area on every tick
2026-08-01 20:13:53 +02:00
Levi Neely 87850f7f10 fix(gui): ensure sessions load on startup and via periodic refresh
- Call ollie.refreshSessions() from Component.onCompleted before
  buildSessionTree() for reliable initial load
- Add a 2-second periodic refresh timer as fallback for missed events
2026-08-01 20:10:17 +02:00
Levi Neely adb2760c91 fix(gui): load sessions on startup, show '(no sessions)' placeholder
- ensureRootDataLoaded() now calls refreshSessions() so the initial
  session list is populated immediately, not only on events
- Added '(no sessions)' placeholder label in the session tree ListView
  when no sessions exist
2026-08-01 20:05:31 +02:00
Levi Neely 6fcef9f60c feat(gui): handle empty sessions in ollie-gui
- getAgents(): filter out 'new' (agent creation file), return empty list
- setActiveSessionId(): skip agent init when no agents exist
- submit/interrupt/kill/streams: guard against empty m_agentId
- prompt input: disable when no agent, show 'No agent' placeholder
2026-08-01 19:51:07 +02:00
Levi Neely c4d6f2a1b9 gui: use rdwr (not write) for session/new and agent/new 2026-08-01 18:50:19 +02:00
Levi Neely 153b40cbc7 gui: write name= to session/new, then agent params to session/{name}/agent/new 2026-08-01 18:41:16 +02:00
Levi Neely 68a84a2404 gui: session group has Name only; all else under Agent 2026-08-01 18:35:32 +02:00
Levi Neely 1b67305ef7 gui: group session/agent params in new session dialog; add agent alias field 2026-08-01 18:33:05 +02:00
Levi Neely 374349622e gui: stop state stream when session is killed; don't restart if session gone 2026-08-01 18:27:55 +02:00
Levi Neely 363b2e95ed gui: add double-click to rename agent nodes in tree view 2026-08-01 18:17:13 +02:00
Levi Neely 74d346418d gui: re-discover agent ID on state stream start to pick up renames 2026-08-01 18:14:29 +02:00
Levi Neely 79d031ff04 remove 'Agent ' prefix from agent display name 2026-08-01 18:04:28 +02:00
Levi Neely cec358bdb9 omit response ID from assistant header 2026-08-01 17:18:27 +02:00
Levi Neely e8a3c6e1d8 ▶️ for call, 🖥️ for tool headers 2026-08-01 17:17:36 +02:00
Levi Neely 25492c889e ❌ for error headers 2026-08-01 17:16:19 +02:00
Levi Neely 37d4b995f4 emoji labels: 🧑 Human, 🤖 Ollie, ℹ️ Info 2026-08-01 17:15:45 +02:00