From da611d3ef2ffa4edaac3d21ee96743e1a87c481b Mon Sep 17 00:00:00 2001 From: Levi Neely <141506390+lneely@users.noreply.github.com> Date: Sat, 18 Jul 2026 22:36:24 +0200 Subject: [PATCH] dbus: add Complete and missing session methods; readme: add -nodbus flag --- README.md | 1 + dbus.go | 100 +++++++++++++++++++++++++++++++++++++++++++++ session/session.go | 9 ++++ 3 files changed, 110 insertions(+) diff --git a/README.md b/README.md index 8c65905..8886852 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,7 @@ The server listens on a Unix socket in the Plan 9 namespace (`$NAMESPACE/ollie`) | `-yolo` | Skip the landrun sandbox for all `execute_code` execution. | | `-tcp ` | Also listen on a TCP address (e.g. `:564`). | | `-mount ` | Override the FUSE mount path. | +| `-nodbus` | Disable the embedded D-Bus adapter (implied by `-tcp`). | ```sh olliesrv start -strict # tools only, sandboxed diff --git a/dbus.go b/dbus.go index 7066d16..cae3475 100644 --- a/dbus.go +++ b/dbus.go @@ -543,6 +543,97 @@ func (a *DBusAdapter) Route(task, backendName string) (string, *dbus.Error) { 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 := a.mgr.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 := a.mgr.Session(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 := a.mgr.Session(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 := a.mgr.Session(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 := a.mgr.Session(sessionID) + if sess == nil { + return "", nil + } + return sess.Core.SystemPrompt(), nil +} + +func (a *DBusAdapter) GetContextSize(sessionID string) (string, *dbus.Error) { + sess := a.mgr.Session(sessionID) + if sess == nil { + return "", nil + } + return sess.Core.CtxSz(), nil +} + +func (a *DBusAdapter) GetPreviousPrompt(sessionID string) (string, *dbus.Error) { + sess := a.mgr.Session(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 := a.mgr.Session(sessionID) + if sess == nil { + return false, nil + } + sess.Core.Submit(sess.Ctx, "/compact") + return true, nil +} + +func (a *DBusAdapter) ClearContext(sessionID string) (bool, *dbus.Error) { + sess := a.mgr.Session(sessionID) + if sess == nil { + return false, nil + } + sess.Core.Submit(sess.Ctx, "/clear") + return true, nil +} + // --- Notifications --- func (a *DBusAdapter) sendNotification(title, body string) { @@ -590,6 +681,15 @@ var introspectXML = ` + + + + + + + + + diff --git a/session/session.go b/session/session.go index c2f47b1..01c9562 100644 --- a/session/session.go +++ b/session/session.go @@ -164,6 +164,15 @@ func (sess *Session) Mu() *sync.RWMutex { return &sess.mu } // Log returns the raw chat log bytes. Caller must hold Mu().RLock(). func (sess *Session) Log() []byte { return sess.log } +// Plan returns the plan bytes. Caller must hold Mu().RLock(). +func (sess *Session) Plan() []byte { return sess.plan } + +// SetPlan sets the plan. Caller must hold Mu().Lock(). +func (sess *Session) SetPlan(p []byte) { sess.plan = p } + +// PrevPrompt returns the last submitted prompt. Caller must hold Mu().RLock(). +func (sess *Session) PrevPrompt() []byte { return sess.prevPrompt } + var sessionStoreOrder = []string{"new", "idx", "ls", "kill", "sh", "b", "bfg", "bbg", "cleanup"}