From b96d91378517d29b849868b14f347dacdc058510 Mon Sep 17 00:00:00 2001 From: pdfinn Date: Mon, 2 Mar 2026 11:40:39 +0700 Subject: [PATCH] fix(llm): seed session model from backend and persist sessions across connections Two bugs found during gpt-oss/Ollama operational test: 1. DefaultSessionDefaults() hardcoded the Claude model ID, causing llm9p to send "claude-sonnet-4-5-20250929" to Ollama which has no such model. NewSessionManager now seeds defaults.Model from apiClient.Model() so the session inherits the backend's configured model (e.g. "gpt-oss:20b"). 2. Sessions started with refs=0 and were auto-deleted the moment the first 9P fid using them was clunked. The plan9port 9p CLI tool opens a new connection per command, so a session created by "9p read new" was gone before the next "9p write N/ask" could use it. Sessions now start with refs=1 (the session holds a reference to itself) and persist until explicitly closed via "ctl close". Co-Authored-By: Claude Sonnet 4.6 --- internal/llm/session.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/internal/llm/session.go b/internal/llm/session.go index a9d2be79ef9a28e601f71310198d742063458337..2aece6ac3619e4b5343167462fdbf69288b24c3c 100644 --- a/internal/llm/session.go +++ b/internal/llm/session.go @@ -327,11 +327,13 @@ type SessionManager struct { // NewSessionManager creates a new session manager. func NewSessionManager(apiClient Backend) *SessionManager { + defaults := DefaultSessionDefaults() + defaults.Model = apiClient.Model() return &SessionManager{ sessions: make(map[int]*Session), nextID: 0, apiClient: apiClient, - defaults: DefaultSessionDefaults(), + defaults: defaults, } } @@ -343,6 +345,9 @@ func (sm *SessionManager) SetDefaults(defaults SessionDefaults) { } // Create creates a new session and returns its ID. +// Sessions start with refs=1 so they persist across independent +// 9P connections (e.g. CLI tool invocations). Use sm.Close or +// write "close" to the session's ctl file to explicitly remove it. func (sm *SessionManager) Create() int { sm.mu.Lock() defer sm.mu.Unlock() @@ -350,7 +355,9 @@ func (sm *SessionManager) Create() int { id := sm.nextID sm.nextID++ - sm.sessions[id] = NewSession(id, sm.defaults) + s := NewSession(id, sm.defaults) + s.refs = 1 // session holds a reference to itself until explicitly closed + sm.sessions[id] = s return id }