Repository navigation
v1.3.87
v1.3.87
LAN Chat Agent Availability + Desktop UX Improvements + Session Robustness
New Features
LAN Chat agent availability — The lanchat tool's list output now includes
an agent_busy field for each participant, indicating whether that node's agent
is currently processing a task. This allows LLMs to make informed routing decisions
when delegating work across instances.
AgentBusyfield added toParticipantstruct, propagated via presence exchangeHub.SetAgentBusy(bool)method — called automatically when agent runs start/end- Wired in TUI (
startAgent/handleAgentDone), Desktop (sendMessageData/completion) - Tool
Description()updated to guide LLMs: "prefer idle agents (agent_busy=false)" - Presence rebroadcast on state change so peers learn immediately
TUI session auto-selection — When ggcode tui starts without --resume,
it now iterates through all workspace sessions (newest-first) and loads the first
unlocked one. Previously it only tried the single most recent session and fell back
to the interactive picker if that was locked.
- With N sessions and N+1 instances starting sequentially: each instance gets a
different session; the last creates a new one. Store.ListForWorkspace(workspace)added tosession.Storeinterface.
Desktop identity editor — Click your nickname in the ChatView top bar to edit
your LAN Chat nickname, role, and team via a modal dialog. Previously the desktop
had no UI for editing identity — only the LanChatView sidebar had a basic prompt().
Desktop markdown rendering for LAN Chat messages — Agent-to-agent LAN Chat
messages now render as formatted markdown in both TUI and Desktop, instead of raw
source text. Regular user input remains plain text.
Desktop sidebar default hidden — Session list sidebar is now collapsed by
default on startup. Click the sidebar toggle in the NavRail to open it.
Bug Fixes
Tool call reconciliation — Unpaired tool_use blocks in conversation history
(caused by crashes, interruptions, or session restoration) now get matching
tool_result entries with a "cancelled" status automatically. This prevents LLM
API errors from providers that require every tool_use to have a tool_result.
ContextManager.ReconcileToolCalls()— handles session restore and runtime
interruption scenarios- Orphan
tool_resultblocks (whosetool_idhas no matchingtool_use) are removed - Called from
RestoreSessionIntoAgent()and at the start ofRunStreamWithContent()
LAN Chat agent message deduplication — Agent-directed messages (@agent) no
longer cause duplicate rendering, persistence, or event emission.
- Hub: skips
persistMessage()for agent-directed DMs (session JSONL is the
source of truth) - Hub: skips
onMessagecallback for agent-directed DMs (avoids duplicate
system message + agent loop injection) - TUI: skips system message rendering for agent-directed DMs (already rendered
as user message via agent loop) - Desktop: skips
lanchat:messageevent emission for agent-directed DMs
Desktop session self-lock fix — The session list no longer shows the current
session as "locked". ListSessions now skips the lock check for the session held
by the current process (ChatBridge.CurrentSessionID()), since TryAcquireSessionLock
would fail on our own flock.
Desktop startup session history — The desktop app now renders session history
on startup. Previously, EnsureSession() ran in Go startup() before the React
frontend mounted, so the session:changed event was lost. Now the frontend polls
GetCurrentSessionID() 500ms after mount to sync state.
Desktop locked session protection — Locked sessions in the sidebar show a lock
icon, appear dimmed, and cannot be clicked. A toast informs the user that the
session is held by another instance.
Improvements
LAN Chat tool definition clarity — Restructured the lanchat tool description
and parameter docs to clearly distinguish the three messaging scopes:
send= DM one participant (requiresto=<node_id>)send_team= broadcast to a team (requiresteam=<name>)broadcast= broadcast to ALL participants (notoorteam)
Debug log noise reduction — mDNS lookup logs and layout calculation logs are
now gated behind debug.IsVerbose(), reducing log spam in normal operation.