9p: update imports for agent/ package extraction

Types moved from ollie/session to ollie/agent:
AgentConfig, AgentConfigPath, AgentsDirs, BuildRuntime, Load, Event,
PersistedAgent, LoadPersistedAgent, RestoreHistory, PromptEnv,
History, Runtime, ErrInterrupted, WatchState.

ollie/session is no longer imported directly in top-level 9p/ files
or mgr/format.go and mgr/sessionfile.go (they only need agent types).

WatchAgent const inlined as string literal.
This commit is contained in:
Levi Neely 2026-07-29 21:46:00 +02:00
parent a6a7fae7ca
commit e630714403
9 changed files with 38 additions and 33 deletions

10
dbus.go
View File

@ -13,7 +13,7 @@ import (
"github.com/godbus/dbus/v5" "github.com/godbus/dbus/v5"
"github.com/godbus/dbus/v5/introspect" "github.com/godbus/dbus/v5/introspect"
"ollie/session" "ollie/agent"
"ollie/backend" "ollie/backend"
"olliesrv/mgr" "olliesrv/mgr"
) )
@ -139,7 +139,7 @@ func (a *DBusAdapter) startWatcher(id string, sess *mgr.Session) {
go func() { go func() {
current := sess.Core.State() current := sess.Core.State()
for { for {
next, ok := sess.Core.WaitChange(ctx, session.WatchState, current) next, ok := sess.Core.WaitChange(ctx, agent.WatchState, current)
if !ok { if !ok {
return return
} }
@ -155,7 +155,7 @@ func (a *DBusAdapter) startWatcher(id string, sess *mgr.Session) {
go func() { go func() {
current := sess.Core.AgentName() current := sess.Core.AgentName()
for { for {
next, ok := sess.Core.WaitChange(ctx, session.WatchAgent, current) next, ok := sess.Core.WaitChange(ctx, "agent", current)
if !ok { if !ok {
return return
} }
@ -325,7 +325,7 @@ func (a *DBusAdapter) Interrupt(sessionID string) (bool, *dbus.Error) {
if sess == nil { if sess == nil {
return false, nil return false, nil
} }
sess.Core.Interrupt(session.ErrInterrupted) sess.Core.Interrupt(agent.ErrInterrupted)
return true, nil return true, nil
} }
@ -461,7 +461,7 @@ func (a *DBusAdapter) ListModels(sessionID string) ([]string, *dbus.Error) {
func (a *DBusAdapter) ListAgents() ([]string, *dbus.Error) { func (a *DBusAdapter) ListAgents() ([]string, *dbus.Error) {
var result []string var result []string
for _, dir := range session.AgentsDirs() { for _, dir := range agent.AgentsDirs() {
entries, err := os.ReadDir(dir) entries, err := os.ReadDir(dir)
if err != nil { if err != nil {
continue continue

View File

@ -14,7 +14,7 @@ import (
"syscall" "syscall"
"9fans.net/go/plan9/client" "9fans.net/go/plan9/client"
"ollie/session" "ollie/agent"
"ollie/backend" "ollie/backend"
"ollie/elevate" "ollie/elevate"
"ollie/env" "ollie/env"
@ -157,7 +157,7 @@ func runServer(sockPath string) {
sink := olog.NewSink(os.Stdout, os.Stderr, olog.ParseLevel(os.Getenv("OLLIE_LOG"), olog.LevelWarn)) sink := olog.NewSink(os.Stdout, os.Stderr, olog.ParseLevel(os.Getenv("OLLIE_LOG"), olog.LevelWarn))
agentsDirs := session.AgentsDirs() agentsDirs := agent.AgentsDirs()
sessionsDir := paths.DataDir() + "/sessions" sessionsDir := paths.DataDir() + "/sessions"
// Create the tool registry // Create the tool registry
@ -366,7 +366,7 @@ func NewRootStore(reg *tools.Registry) *fs.Tree {
}, },
"agents": func() ([]byte, error) { "agents": func() ([]byte, error) {
var sb strings.Builder var sb strings.Builder
for _, dir := range session.AgentsDirs() { for _, dir := range agent.AgentsDirs() {
entries, err := os.ReadDir(dir) entries, err := os.ReadDir(dir)
if err != nil { if err != nil {
continue continue

View File

@ -12,6 +12,7 @@ import (
"time" "time"
"ollie/session" "ollie/session"
"ollie/agent"
"ollie/backend" "ollie/backend"
olog "ollie/log" olog "ollie/log"
"olliesrv/fs" "olliesrv/fs"
@ -942,14 +943,14 @@ func TestLoadAgentConfig(t *testing.T) {
func TestFormatEvent(t *testing.T) { func TestFormatEvent(t *testing.T) {
tests := []struct { tests := []struct {
ev session.Event ev agent.Event
want string want string
}{ }{
{session.Event{Role: "user", Content: "hello"}, "[user]\nhello\n"}, {agent.Event{Role: "user", Content: "hello"}, "[user]\nhello\n"},
{session.Event{Role: "assistant", Content: "hi"}, "hi"}, {agent.Event{Role: "assistant", Content: "hi"}, "hi"},
{session.Event{Role: "call", Name: "fn", Content: "args"}, "[call:fn]\nargs\n"}, {agent.Event{Role: "call", Name: "fn", Content: "args"}, "[call:fn]\nargs\n"},
{session.Event{Role: "tool", Name: "fn", Content: "result"}, "[tool:fn]\nresult\n"}, {agent.Event{Role: "tool", Name: "fn", Content: "result"}, "[tool:fn]\nresult\n"},
{session.Event{Role: "info", Content: "msg\n"}, "[info]\nmsg\n"}, {agent.Event{Role: "info", Content: "msg\n"}, "[info]\nmsg\n"},
} }
for _, tc := range tests { for _, tc := range tests {
got := string(mgr.FormatEvent(tc.ev)) got := string(mgr.FormatEvent(tc.ev))

View File

@ -2,6 +2,7 @@ package mgr
import ( import (
"ollie/session" "ollie/session"
"ollie/agent"
"context" "context"
"fmt" "fmt"
"ollie/backend" "ollie/backend"
@ -161,7 +162,7 @@ func (s *Manager) CreateSession(args []string) (string, error) {
if len(remoteEnv) > 0 { if len(remoteEnv) > 0 {
promptEnv = remoteEnv promptEnv = remoteEnv
} else { } else {
promptEnv = session.PromptEnv(cwd) promptEnv = agent.PromptEnv(cwd)
} }
env := []string{"OLLIE_SESSION_ID=" + sessID, "OLLIE_UNAME=" + uname} env := []string{"OLLIE_SESSION_ID=" + sessID, "OLLIE_UNAME=" + uname}
env = append(env, promptEnv...) env = append(env, promptEnv...)
@ -197,7 +198,7 @@ func (s *Manager) CreateSession(args []string) (string, error) {
envBlock := prompts.Environment(cwd, platform, isGitRepo, "") envBlock := prompts.Environment(cwd, platform, isGitRepo, "")
disp := newDisp() disp := newDisp()
rt := session.BuildRuntime(cfg, disp, cwd, env, sysPrompt, opModel, envBlock) rt := agent.BuildRuntime(cfg, disp, cwd, env, sysPrompt, opModel, envBlock)
// sessPtr is set after NewSession; the ReadPlanStep closure captures it. // sessPtr is set after NewSession; the ReadPlanStep closure captures it.
core = session.New(session.Config{ core = session.New(session.Config{

View File

@ -1,30 +1,30 @@
package mgr package mgr
import ( import (
"ollie/session" "ollie/agent"
"ollie/backend" "ollie/backend"
"os" "os"
"strings" "strings"
) )
func LoadAgentConfig(agentsDir, name string, open func(string) (*os.File, error)) *session.AgentConfig { func LoadAgentConfig(agentsDir, name string, open func(string) (*os.File, error)) *agent.AgentConfig {
if open == nil { if open == nil {
open = os.Open open = os.Open
} }
path := session.AgentConfigPath(agentsDir, name) path := agent.AgentConfigPath(agentsDir, name)
f, err := open(path) f, err := open(path)
if err != nil { if err != nil {
return nil return nil
} }
defer f.Close() defer f.Close()
cfg, _ := session.Load(f) cfg, _ := agent.Load(f)
return cfg return cfg
} }
// FormatEvent converts an agent Event to bytes for appending to a chat log. // FormatEvent converts an agent Event to bytes for appending to a chat log.
// Streaming roles (assistant, reasoning) return only the content chunk; // Streaming roles (assistant, reasoning) return only the content chunk;
// the caller (startEventLog) is responsible for writing the [role] header. // the caller (startEventLog) is responsible for writing the [role] header.
func FormatEvent(ev session.Event) []byte { func FormatEvent(ev agent.Event) []byte {
switch ev.Role { switch ev.Role {
case "user": case "user":
return []byte("[user]\n" + ev.Content + "\n") return []byte("[user]\n" + ev.Content + "\n")

View File

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"ollie/paths" "ollie/paths"
"ollie/session" "ollie/session"
"ollie/agent"
"ollie/skills" "ollie/skills"
"ollie/tools" "ollie/tools"
"olliesrv/fs" "olliesrv/fs"
@ -588,7 +589,7 @@ func (s *Manager) InterruptAll() {
s.mu.RLock() s.mu.RLock()
defer s.mu.RUnlock() defer s.mu.RUnlock()
for _, sess := range s.sessions { for _, sess := range s.sessions {
sess.Core.Interrupt(session.ErrInterrupted) sess.Core.Interrupt(agent.ErrInterrupted)
} }
} }

View File

@ -2,6 +2,7 @@ package mgr
import ( import (
"ollie/session" "ollie/session"
"ollie/agent"
"context" "context"
"fmt" "fmt"
"ollie/backend" "ollie/backend"
@ -63,7 +64,7 @@ func (s *Manager) restoreAllSessions() {
// Load all persisted session JSONs (fast, sequential disk reads) // Load all persisted session JSONs (fast, sequential disk reads)
type loadedSession struct { type loadedSession struct {
ps *session.PersistedAgent ps *agent.PersistedAgent
name string name string
} }
var loaded []loadedSession var loaded []loadedSession
@ -72,7 +73,7 @@ func (s *Manager) restoreAllSessions() {
continue continue
} }
path := filepath.Join(dir, e.Name()) path := filepath.Join(dir, e.Name())
ps, err := session.LoadPersistedAgent(path) ps, err := agent.LoadPersistedAgent(path)
if err != nil { if err != nil {
s.cfg.Log.Error("restore session %s: %v", e.Name(), err) s.cfg.Log.Error("restore session %s: %v", e.Name(), err)
continue continue
@ -98,7 +99,7 @@ func (s *Manager) restoreAllSessions() {
wg.Wait() wg.Wait()
} }
func (s *Manager) restoreSession(ps *session.PersistedAgent) error { func (s *Manager) restoreSession(ps *agent.PersistedAgent) error {
cwd := ps.CWD cwd := ps.CWD
if cwd == "" { if cwd == "" {
cwd, _ = os.Getwd() cwd, _ = os.Getwd()
@ -170,7 +171,7 @@ func (s *Manager) restoreSession(ps *session.PersistedAgent) error {
newDisp = tools.NewDispatcherFunc(map[string]func() tools.Server{ newDisp = tools.NewDispatcherFunc(map[string]func() tools.Server{
"execute": execute.Decl(cwd, execOpts...), "execute": execute.Decl(cwd, execOpts...),
}) })
promptEnv = session.PromptEnv(cwd) promptEnv = agent.PromptEnv(cwd)
} }
env := []string{"OLLIE_SESSION_ID=" + sessID, "OLLIE_UNAME=" + uname} env := []string{"OLLIE_SESSION_ID=" + sessID, "OLLIE_UNAME=" + uname}
@ -204,9 +205,9 @@ func (s *Manager) restoreSession(ps *session.PersistedAgent) error {
envBlock := prompts.Environment(cwd, platform, isGitRepo, "") envBlock := prompts.Environment(cwd, platform, isGitRepo, "")
disp := newDisp() disp := newDisp()
rt := session.BuildRuntime(cfg, disp, cwd, env, sysPrompt, opModel, envBlock) rt := agent.BuildRuntime(cfg, disp, cwd, env, sysPrompt, opModel, envBlock)
restoredSession := session.RestoreHistory(ps) restoredSession := agent.RestoreHistory(ps)
var sessPtr *Session var sessPtr *Session
core := session.New(session.Config{ core := session.New(session.Config{

View File

@ -6,6 +6,7 @@ import (
"time" "time"
"ollie/session" "ollie/session"
"ollie/agent"
) )
// Session holds all state for one agent session. // Session holds all state for one agent session.
@ -83,7 +84,7 @@ func (sess *Session) Cancel() {
} }
func (sess *Session) Interrupt() { func (sess *Session) Interrupt() {
sess.Core.Interrupt(session.ErrInterrupted) sess.Core.Interrupt(agent.ErrInterrupted)
} }
// AppendLog appends data to the session's log and bumps the version. // AppendLog appends data to the session's log and bumps the version.
@ -113,7 +114,7 @@ func (sess *Session) startEventLog() {
streamingRole := "" // tracks current streaming role ("assistant", "reasoning", or "tool") streamingRole := "" // tracks current streaming role ("assistant", "reasoning", or "tool")
streamingResponseID := "" streamingResponseID := ""
sess.Core.Bus().Subscribe("event", func(ev session.Event) { sess.Core.Bus().Subscribe("event", func(ev agent.Event) {
switch ev.Role { switch ev.Role {
case "assistant", "reasoning": case "assistant", "reasoning":
if streamingRole != ev.Role || (ev.Role == "assistant" && ev.ResponseID != streamingResponseID) { if streamingRole != ev.Role || (ev.Role == "assistant" && ev.ResponseID != streamingResponseID) {

View File

@ -8,7 +8,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"ollie/session" "ollie/agent"
"ollie/backend" "ollie/backend"
"ollie/tools" "ollie/tools"
olog "ollie/log" olog "ollie/log"
@ -277,7 +277,7 @@ func (h *sessionHelper) fileSpec(name string, mode os.FileMode) fs.FileSpec {
if base == "" { if base == "" {
base = h.sess.Core.State() base = h.sess.Core.State()
} }
v, ok := h.sess.Core.WaitChange(ctx, session.WatchState, base) v, ok := h.sess.Core.WaitChange(ctx, agent.WatchState, base)
if !ok { if !ok {
s := h.sess.Core.State() s := h.sess.Core.State()
return []byte(s + "\n"), s, nil return []byte(s + "\n"), s, nil
@ -637,7 +637,7 @@ func (h *sessionHelper) handleCtl(input string) error {
} }
switch cmd[0] { switch cmd[0] {
case "stop": case "stop":
h.sess.Core.Interrupt(session.ErrInterrupted) h.sess.Core.Interrupt(agent.ErrInterrupted)
case "kill": case "kill":
h.kill() h.kill()
case "rn": case "rn":