diff --git a/cmd/ollie-remote/sandbox/default.yaml b/cmd/ollie-remote/sandbox/default.yaml deleted file mode 100644 index 99ca5ad..0000000 --- a/cmd/ollie-remote/sandbox/default.yaml +++ /dev/null @@ -1 +0,0 @@ -# Placeholder — real config copied during build (just ollie-remote) diff --git a/cmd/olliesrv/main.go b/cmd/olliesrv/main.go index f41f54d..da4d3f7 100644 --- a/cmd/olliesrv/main.go +++ b/cmd/olliesrv/main.go @@ -17,12 +17,13 @@ import ( "9fans.net/go/plan9/client" "ollie/agent" "ollie/backend" - oldbus "ollie/dbus" "ollie/elevate" "ollie/env" "ollie/fs/session" olog "ollie/log" "ollie/mount" + + "github.com/godbus/dbus/v5" "ollie/paths" "ollie/skills" "ollie/toolsrv" @@ -33,8 +34,7 @@ const serviceName = "ollie" var tcpAddr = flag.String("tcp", "", "also listen on TCP address (e.g. :564)") var strict = flag.Bool("strict", false, "only allow tool steps; reject inline code") var yolo = flag.Bool("yolo", false, "skip landrun sandbox for shell") -var nodbus = flag.Bool("nodbus", false, "disable D-Bus adapter (for headless/container use)") -var no9p = flag.Bool("no9p", false, "disable 9P listener (D-Bus only mode)") +var no9p = flag.Bool("no9p", false, "disable 9P listener") // ModelCache caches the list of models from all backends. type ModelCache struct { @@ -141,12 +141,6 @@ func cmdMount() { func runServer(sockPath string) { env.EnsureDefaults() - // -no9p requires D-Bus (otherwise there's no interface at all) - if *no9p && *nodbus { - fmt.Fprintln(os.Stderr, "error: -no9p and -nodbus are mutually exclusive") - os.Exit(1) - } - // Remove stale socket if !*no9p { if _, err := os.Stat(sockPath); err == nil { @@ -168,9 +162,6 @@ func runServer(sockPath string) { // Create the skills registry skillsRegistry := skills.NewRegistry() - // D-Bus adapter (initialized after manager so callbacks can reference it). - var dbusAdapter *oldbus.DBusAdapter - // Elevate broker (initialized after manager; closures capture the pointer). var elevateBroker *elevate.Broker @@ -189,42 +180,12 @@ func runServer(sockPath string) { Yolo: *yolo, NoMount: *no9p || *tcpAddr != "", Enable9P: !*no9p, - EnableDBus: !*nodbus && (*no9p || *tcpAddr == ""), InvalidateModels: modelCache.Invalidate, - OnSessionCreated: func(id string, sess *fs.Session) { - if dbusAdapter != nil { - dbusAdapter.OnSessionCreated(id, sess) - } - }, - OnSessionKilled: func(id string) { - if dbusAdapter != nil { - dbusAdapter.OnSessionKilled(id) - } - }, - OnSessionRenamed: func(oldID, newID string) { - if dbusAdapter != nil { - dbusAdapter.OnSessionRenamed(oldID, newID) - } - }, }) var srv *Server // Server creation deferred until after elevate broker is ready (see below) - // Start D-Bus adapter. - // -tcp implies -nodbus (remote/headless deployments have no session bus). - // -no9p forces D-Bus on (it's the only interface). - if !*nodbus && (*no9p || *tcpAddr == "") { - dbusAdapter = oldbus.StartDBus(sessionTree) - if dbusAdapter != nil { - dbusAdapter.WatchExisting() - } - if *no9p && dbusAdapter == nil { - fmt.Fprintln(os.Stderr, "error: -no9p mode requires D-Bus but session bus is unavailable") - os.Exit(1) - } - } - // Start elevation broker elevateSocket := os.Getenv("OLLIE_ELEVATE_SOCKET") if elevateSocket == "" { @@ -272,8 +233,9 @@ func runServer(sockPath string) { fmt.Fprintf(os.Stderr, "warning: %v\n", err) } else { defer elevateBroker.Close() - if dbusAdapter != nil { - initElevateNotifier(dbusAdapter.Conn(), elevateBroker) + // Desktop notifications for elevation prompts (uses D-Bus notifications API directly) + if conn, err := dbus.SessionBus(); err == nil { + initElevateNotifier(conn, elevateBroker) } } } @@ -335,19 +297,12 @@ func runServer(sockPath string) { fmt.Printf("olliesrv listening on tcp %s\n", *tcpAddr) } - if *no9p { - fmt.Println("olliesrv running in D-Bus only mode") - } - sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) <-sigChan fmt.Println("shutting down") daemonCancel() // signal all sessions via context propagation - if dbusAdapter != nil { - dbusAdapter.Close() - } if srv != nil { srv.Shutdown() } diff --git a/dbus/dbus.go b/dbus/dbus.go deleted file mode 100644 index df7c2b2..0000000 --- a/dbus/dbus.go +++ /dev/null @@ -1,697 +0,0 @@ -package dbus - -import ( - "context" - "encoding/json" - "fmt" - "os" - "sort" - "strings" - "sync" - "time" - - "github.com/godbus/dbus/v5" - "github.com/godbus/dbus/v5/introspect" - - "ollie/agent" - "ollie/backend" - "ollie/fs/session" -) - -const ( - busName = "org.ollie.SessionManager" - busPath = "/org/ollie/SessionManager" - busIface = "org.ollie.SessionManager" -) - -// DBusAdapter exposes sessions over D-Bus. -type DBusAdapter struct { - conn *dbus.Conn - tree *fs.Tree - - mu sync.RWMutex - watchers map[string]context.CancelFunc // sessionID -> cancel for state watcher -} - -// StartDBus connects to the session bus, claims the well-known name, and -// exports the adapter. Returns nil (no-op) if the bus is unavailable. -func StartDBus(tree *fs.Tree) *DBusAdapter { - conn, err := dbus.ConnectSessionBus() - if err != nil { - fmt.Fprintf(os.Stderr, "dbus: session bus unavailable: %v\n", err) - return nil - } - - reply, err := conn.RequestName(busName, dbus.NameFlagDoNotQueue) - if err != nil || reply != dbus.RequestNameReplyPrimaryOwner { - fmt.Fprintf(os.Stderr, "dbus: cannot claim %s (ollied already running?)\n", busName) - conn.Close() - return nil - } - - a := &DBusAdapter{ - conn: conn, - tree: tree, - watchers: make(map[string]context.CancelFunc), - } - - conn.Export(a, busPath, busIface) - conn.Export(introspect.Introspectable(introspectXML), busPath, "org.freedesktop.DBus.Introspectable") - - fmt.Printf("dbus: exported %s\n", busName) - return a -} - -// WatchExisting starts watchers for all sessions that already exist. -// Called after the adapter is initialized to cover sessions restored at startup. -func (a *DBusAdapter) WatchExisting() { - if a == nil { - return - } - for _, sess := range fs.All(a.tree) { - id := sess.RunnableID() - a.startWatcher(id, sess) - // Emit SessionCreated so GUI clients that connected before restore - // (via serviceRegistered) learn about pre-existing sessions. - a.conn.Emit(busPath, busIface+".SessionCreated", id) - } -} - -func (a *DBusAdapter) Close() { - if a == nil || a.conn == nil { - return - } - a.mu.Lock() - for _, cancel := range a.watchers { - cancel() - } - a.mu.Unlock() - a.conn.Close() -} - -// Conn returns the underlying D-Bus connection, or nil if the adapter is nil. -func (a *DBusAdapter) Conn() *dbus.Conn { - if a == nil { - return nil - } - return a.conn -} - -// --- Lifecycle callbacks --- - -func (a *DBusAdapter) OnSessionCreated(id string, sess *fs.Session) { - if a == nil { - return - } - a.startWatcher(id, sess) - go a.conn.Emit(busPath, busIface+".SessionCreated", id) -} - -func (a *DBusAdapter) OnSessionKilled(id string) { - if a == nil { - return - } - a.stopWatcher(id) - go a.conn.Emit(busPath, busIface+".SessionKilled", id) -} - -func (a *DBusAdapter) OnSessionRenamed(oldID, newID string) { - if a == nil { - return - } - a.stopWatcher(oldID) - // The session object is the same, just re-lookup - sess := fs.Lookup(a.tree, newID) - if sess != nil { - a.startWatcher(newID, sess) - } - go a.conn.Emit(busPath, busIface+".SessionRenamed", oldID, newID) -} - -// startWatcher launches goroutines for StateChanged and ChatUpdated signals. -func (a *DBusAdapter) startWatcher(id string, sess *fs.Session) { - ctx, cancel := context.WithCancel(context.Background()) - a.mu.Lock() - a.watchers[id] = cancel - a.mu.Unlock() - - // State watcher - go func() { - current := sess.Core.Agent().State() - for { - next, ok := sess.Core.WaitChange(ctx, agent.WatchState, current) - if !ok { - return - } - current = next - a.conn.Emit(busPath, busIface+".StateChanged", id, current) - if current == "idle" { - a.sendNotification("Ollie", "Session "+id+" finished") - } - } - }() - - // Agent watcher — emits ConfigChanged when the agent name changes - go func() { - current := sess.Core.Agent().Name() - for { - next, ok := sess.Core.WaitChange(ctx, "agent", current) - if !ok { - return - } - current = next - a.conn.Emit(busPath, busIface+".ConfigChanged", id, "agent", current) - } - }() - - // Chat watcher (polls log version) - go func() { - var lastLen int - var lastVers uint32 - for { - select { - case <-ctx.Done(): - return - case <-time.After(150 * time.Millisecond): - } - l, v := sess.LogInfo() - if v == lastVers { - continue - } - if l > lastLen { - // Read the new chunk - sess.Mu().RLock() - chunk := string(sess.Log()[lastLen:]) - sess.Mu().RUnlock() - a.conn.Emit(busPath, busIface+".ChatUpdated", id, int64(lastLen), chunk) - } - lastLen = l - lastVers = v - } - }() - - // Detached process exit watcher - go func() { - exitedPIDs := make(map[int]bool) // already-reported PIDs - for { - select { - case <-ctx.Done(): - return - case <-time.After(1 * time.Second): - } - infos := sess.Core.Agent().ListDetached() - // Clean up stale entries from exitedPIDs - activePIDs := make(map[int]bool, len(infos)) - for _, info := range infos { - activePIDs[info.PID] = true - } - for pid := range exitedPIDs { - if !activePIDs[pid] { - delete(exitedPIDs, pid) - } - } - for _, info := range infos { - if info.Exited && !exitedPIDs[info.PID] { - exitedPIDs[info.PID] = true - a.conn.Emit(busPath, busIface+".ProcessExited", id, int32(info.PID), int32(info.ExitCode)) - } - } - } - }() -} - -func (a *DBusAdapter) stopWatcher(id string) { - a.mu.Lock() - if cancel, ok := a.watchers[id]; ok { - cancel() - delete(a.watchers, id) - } - a.mu.Unlock() -} - -// --- D-Bus exported methods --- - -func (a *DBusAdapter) CreateSession(cwd, backendName, modelName, agentName, systemPrompt, remote string) (string, *dbus.Error) { - var args []string - if cwd != "" { - args = append(args, "cwd="+cwd) - } - if backendName != "" { - args = append(args, "backend="+backendName) - } - if modelName != "" { - args = append(args, "model="+modelName) - } - if agentName != "" { - args = append(args, "agent="+agentName) - } - if systemPrompt != "" { - args = append(args, "system_prompt="+systemPrompt) - } - if remote != "" { - args = append(args, "remote="+remote) - } - if cwd == "" { - dir, _ := os.Getwd() - args = append(args, "cwd="+dir) - } - id, err := fs.CreateFromRoot(a.tree, args) - if err != nil { - return "", dbus.MakeFailedError(err) - } - return id, nil -} - -func (a *DBusAdapter) ListSessions() ([]string, *dbus.Error) { - var result []string - for _, sess := range fs.All(a.tree) { - id := sess.RunnableID() - result = append(result, fmt.Sprintf("%s\t%s\t%s\t%s", - id, sess.Core.Agent().State(), sess.Core.Agent().ModelName(), sess.Core.Agent().Name())) - } - return result, nil -} - -func (a *DBusAdapter) KillSession(sessionID string) (bool, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return false, nil - } - fs.KillFromRoot(a.tree, sessionID) - return true, nil -} - -func (a *DBusAdapter) RenameSession(sessionID, newName string) (bool, *dbus.Error) { - if err := fs.RenameFromRoot(a.tree, sessionID, newName); err != nil { - return false, dbus.MakeFailedError(err) - } - return true, nil -} - -func (a *DBusAdapter) Submit(sessionID, prompt string) (bool, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return false, nil - } - go sess.Core.Agent().Submit(sess.SessionCtx, prompt) - return true, nil -} - -func (a *DBusAdapter) Interrupt(sessionID string) (bool, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return false, nil - } - sess.Core.Agent().Interrupt(agent.ErrInterrupted) - return true, nil -} - -func (a *DBusAdapter) GetState(sessionID string) (string, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return "", nil - } - return sess.Core.Agent().State(), nil -} - -func (a *DBusAdapter) GetChat(sessionID string, offset int64) (string, int64, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return "", offset, nil - } - sess.Mu().RLock() - log := sess.Log() - if offset < 0 { - offset = 0 - } - if offset > int64(len(log)) { - offset = int64(len(log)) - } - text := string(log[offset:]) - newOffset := int64(len(log)) - sess.Mu().RUnlock() - return text, newOffset, nil -} - -func (a *DBusAdapter) GetUsage(sessionID string) (string, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return "", nil - } - return sess.Core.Agent().UsageStr(), nil -} - -func (a *DBusAdapter) GetCost(sessionID string) (string, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return "", nil - } - return sess.Core.Agent().CostStr(), nil -} - -func (a *DBusAdapter) GetConfig(sessionID string) (string, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return "", nil - } - var sb strings.Builder - fmt.Fprintf(&sb, "model=%s\n", sess.Core.Agent().ModelName()) - fmt.Fprintf(&sb, "backend=%s\n", sess.Core.Agent().BackendName()) - fmt.Fprintf(&sb, "agent=%s\n", sess.Core.Agent().Name()) - fmt.Fprintf(&sb, "cwd=%s\n", sess.Core.CWD()) - fmt.Fprintf(&sb, "state=%s\n", sess.Core.Agent().State()) - return sb.String(), nil -} - -func (a *DBusAdapter) SetConfig(sessionID, key, value string) (bool, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return false, nil - } - switch key { - case "model": - sess.Core.Agent().Submit(sess.SessionCtx, "/model "+value) - case "cwd": - if err := sess.Core.SetCWD(value); err != nil { - return false, nil - } - default: - return false, nil - } - return true, nil -} - -func (a *DBusAdapter) GetContext(sessionID string) (string, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return "", nil - } - msgs := sess.Core.Agent().Context() - var sb strings.Builder - enc := json.NewEncoder(&sb) - enc.SetEscapeHTML(false) - for _, msg := range msgs { - enc.Encode(msg) - } - return sb.String(), nil -} - -func (a *DBusAdapter) ListBackends() ([]string, *dbus.Error) { - return backend.Backends(), nil -} - -func (a *DBusAdapter) ListModelsByBackend(backendName string) ([]string, *dbus.Error) { - be, err := backend.NewWithName(backendName) - if err != nil { - return nil, dbus.MakeFailedError(err) - } - models := be.Models(context.Background()) - sort.Strings(models) - return models, nil -} - -func (a *DBusAdapter) ListModels(sessionID string) ([]string, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return nil, nil - } - raw := sess.CachedListModels() - models := strings.Split(strings.TrimSpace(raw), "\n") - if len(models) == 1 && models[0] == "" { - return nil, nil - } - sort.Strings(models) - return models, nil -} - -func (a *DBusAdapter) ListAgents() ([]string, *dbus.Error) { - var result []string - for _, dir := range agent.AgentsDirs() { - entries, err := os.ReadDir(dir) - if err != nil { - continue - } - for _, e := range entries { - name := e.Name() - if strings.HasSuffix(name, ".json") { - result = append(result, strings.TrimSuffix(name, ".json")) - } - } - } - return result, nil -} - - -// --- Detached processes --- - -func (a *DBusAdapter) DetachProcess(sessionID string) (bool, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return false, dbus.MakeFailedError(fmt.Errorf("session not found: %s", sessionID)) - } - if !sess.Core.Agent().Detach() { - return false, dbus.MakeFailedError(fmt.Errorf("no running process to detach")) - } - a.conn.Emit(busPath, busIface+".ProcessDetached", sessionID) - return true, nil -} - -func (a *DBusAdapter) ListDetached(sessionID string) ([]string, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return nil, dbus.MakeFailedError(fmt.Errorf("session not found: %s", sessionID)) - } - infos := sess.Core.Agent().ListDetached() - out := make([]string, len(infos)) - for i, info := range infos { - status := "running" - if info.Exited { - status = fmt.Sprintf("exited(%d)", info.ExitCode) - } - out[i] = fmt.Sprintf("%d\t%s\t%d\t%s", info.PID, info.Command, info.Started, status) - } - return out, nil -} - -func (a *DBusAdapter) SignalDetached(sessionID string, pid int32, signal string) (bool, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return false, dbus.MakeFailedError(fmt.Errorf("session not found: %s", sessionID)) - } - var sig int - switch strings.ToUpper(signal) { - case "TERM", "SIGTERM", "15": - sig = 15 - case "KILL", "SIGKILL", "9": - sig = 9 - default: - return false, dbus.MakeFailedError(fmt.Errorf("unsupported signal: %s", signal)) - } - if err := sess.Core.Agent().SignalDetached(int(pid), sig); err != nil { - return false, dbus.MakeFailedError(err) - } - return true, nil -} - -func (a *DBusAdapter) GetDetachedOutput(sessionID string, pid int32) (string, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return "", dbus.MakeFailedError(fmt.Errorf("session not found: %s", sessionID)) - } - output, err := sess.Core.Agent().GetDetachedOutput(int(pid)) - if err != nil { - return "", dbus.MakeFailedError(err) - } - return output, nil -} - -func (a *DBusAdapter) DismissDetached(sessionID string, pid int32) (bool, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return false, dbus.MakeFailedError(fmt.Errorf("session not found: %s", sessionID)) - } - return sess.Core.Agent().DismissDetached(int(pid)), nil -} - -// --- Generate / Route --- - -func (a *DBusAdapter) Generate(prompt, system, backendName, model string) (string, *dbus.Error) { - result, err := backend.Generate(context.Background(), backend.GenerateRequest{ - Prompt: prompt, - System: system, - Backend: backendName, - Model: model, - }) - if err != nil { - return "", dbus.MakeFailedError(err) - } - return result, nil -} - -func (a *DBusAdapter) Route(task, backendName string) (string, *dbus.Error) { - result, err := backend.Route(context.Background(), backend.RouteRequest{ - Task: task, - Backend: backendName, - }) - if err != nil { - return "", dbus.MakeFailedError(err) - } - return fmt.Sprintf("backend=%s model=%s", result.Backend, result.Model), nil -} - -func (a *DBusAdapter) Complete(cwd, filePath, prefix, suffix, extraContext string) (string, *dbus.Error) { - result, err := agent.Complete(cwd, filePath, prefix, suffix, extraContext) - if err != nil { - return "", dbus.MakeFailedError(err) - } - return result, nil -} - -func (a *DBusAdapter) GetEnv(sessionID string) (string, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return "", nil - } - var sb strings.Builder - fmt.Fprintf(&sb, "OLLIE_SESSION_ID=%s\n", sess.RunnableID()) - for _, e := range os.Environ() { - if strings.HasPrefix(e, "OLLIE_") && !strings.HasPrefix(e, "OLLIE_SESSION_ID=") { - sb.WriteString(e) - sb.WriteByte('\n') - } - } - return sb.String(), nil -} - -func (a *DBusAdapter) GetPlan(sessionID string) (string, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return "", nil - } - sess.Mu().RLock() - plan := string(sess.Plan()) - sess.Mu().RUnlock() - return plan, nil -} - -func (a *DBusAdapter) SetPlan(sessionID, plan string) (bool, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return false, nil - } - sess.Mu().Lock() - sess.SetPlan([]byte(plan)) - sess.Mu().Unlock() - return true, nil -} - -func (a *DBusAdapter) GetSystemPrompt(sessionID string) (string, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return "", nil - } - return sess.Core.Agent().SystemPrompt(), nil -} - -func (a *DBusAdapter) GetContextSize(sessionID string) (string, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return "", nil - } - return sess.Core.Agent().CtxSz(), nil -} - -func (a *DBusAdapter) GetPreviousPrompt(sessionID string) (string, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return "", nil - } - sess.Mu().RLock() - p := string(sess.PrevPrompt()) - sess.Mu().RUnlock() - return p, nil -} - -func (a *DBusAdapter) Compact(sessionID string) (bool, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return false, nil - } - sess.Core.Agent().Submit(sess.SessionCtx, "/compact") - return true, nil -} - -func (a *DBusAdapter) ClearContext(sessionID string) (bool, *dbus.Error) { - sess := fs.Lookup(a.tree, sessionID) - if sess == nil { - return false, nil - } - sess.Core.Agent().Submit(sess.SessionCtx, "/clear") - return true, nil -} - -// --- Notifications --- - -func (a *DBusAdapter) sendNotification(title, body string) { - go func() { - obj := a.conn.Object("org.freedesktop.Notifications", "/org/freedesktop/Notifications") - obj.Call("org.freedesktop.Notifications.Notify", 0, - "olliesrv", uint32(0), "system-run", title, body, - []string{}, map[string]dbus.Variant{}, int32(5000)) - }() -} - -// Introspection XML. -var introspectXML = ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -` diff --git a/fs/session/create.go b/fs/session/create.go index 8d1e56d..e460c05 100644 --- a/fs/session/create.go +++ b/fs/session/create.go @@ -194,7 +194,7 @@ func Create(rs *rootState, args []string) (string, error) { envMap[k] = v } } - opModel := prompts.OperationalModel(rs.cfg.Enable9P, rs.cfg.EnableDBus, envMap) + opModel := prompts.OperationalModel(rs.cfg.Enable9P, false, envMap) platform := "linux" isGitRepo := false @@ -256,9 +256,6 @@ func Create(rs *rootState, args []string) (string, error) { rs.cfg.Log.Info("new session %s (backend=%s model=%s agent=%s)", sessID, core.Agent().BackendName(), core.Agent().ModelName(), core.Agent().Name()) - if rs.cfg.OnSessionCreated != nil { - rs.cfg.OnSessionCreated(sessID, sess) - } return sessID, nil } diff --git a/fs/session/persist.go b/fs/session/persist.go index f7575b2..ca8ff3b 100644 --- a/fs/session/persist.go +++ b/fs/session/persist.go @@ -30,9 +30,6 @@ func Kill(rs *rootState, id string) { } removePersistedAgent(rs, id) rs.cfg.Log.Info("killed session %s", id) - if rs.cfg.OnSessionKilled != nil { - rs.cfg.OnSessionKilled(id) - } } } @@ -70,9 +67,6 @@ func Rename(rs *rootState, old, new string) error { sess.AppendLog([]byte(fmt.Sprintf(":: session renamed: %s -> %s\n", old, new))) rs.cfg.Log.Info("renamed session %s -> %s", old, new) - if rs.cfg.OnSessionRenamed != nil { - rs.cfg.OnSessionRenamed(old, new) - } return nil } @@ -296,7 +290,7 @@ func restoreSession(rs *rootState, ps *agent.PersistedAgent) error { envMap[k] = v } } - opModel := prompts.OperationalModel(rs.cfg.Enable9P, rs.cfg.EnableDBus, envMap) + opModel := prompts.OperationalModel(rs.cfg.Enable9P, false, envMap) platform := "linux" isGitRepo := false for _, e := range promptEnv { @@ -358,8 +352,5 @@ func restoreSession(rs *rootState, ps *agent.PersistedAgent) error { rs.mu.Unlock() rs.cfg.Log.Info("restored session %s (backend=%s model=%s agent=%s)", sessID, backendName, modelName, agentName) - if rs.cfg.OnSessionCreated != nil { - rs.cfg.OnSessionCreated(sessID, sess) - } return nil } diff --git a/fs/session/root.go b/fs/session/root.go index 218aa55..2d9553c 100644 --- a/fs/session/root.go +++ b/fs/session/root.go @@ -47,20 +47,12 @@ type Config struct { NoMount bool // Enable9P indicates the 9P listener is active (for operational model injection). Enable9P bool - // EnableDBus indicates the D-Bus adapter is active (for operational model injection). - EnableDBus bool // InvalidateModels clears the model cache, forcing a refresh. InvalidateModels func() // ToolRegistry is the shared tool registry for lazy tool promotion. ToolRegistry *toolsrv.Registry // SkillsRegistry is the shared skills registry for skill loading. SkillsRegistry *skills.Registry - // OnSessionCreated is called after a new session is added. - OnSessionCreated func(id string, sess *Session) - // OnSessionKilled is called after a session is removed. - OnSessionKilled func(id string) - // OnSessionRenamed is called after a session is renamed. - OnSessionRenamed func(oldID, newID string) } // rootState is the package-level state stored in root.Data.