diff --git a/cmd/olliesrv/internal/agent/agent.go b/cmd/olliesrv/internal/agent/agent.go index dbe6ca5..fa250d0 100644 --- a/cmd/olliesrv/internal/agent/agent.go +++ b/cmd/olliesrv/internal/agent/agent.go @@ -62,7 +62,6 @@ type Agent struct { output EventHandler log *olog.Logger sessionID string // the owning session's ID - startupMessages []string memoryWakePending atomic.Bool save func() // trigger debounced persistence flush func() // immediately flush persistence @@ -846,7 +845,6 @@ type AgentParams struct { NewToolServer func() *toolclient.ToolsrvConn NewBackend func(string) (backend.Backend, error) Log *olog.Logger - StartupMsgs []string Save func() Flush func() } @@ -864,16 +862,15 @@ func NewAgent(cfg AgentParams) *Agent { id: cfg.ID, parentID: cfg.ParentID, getCwd: cfg.GetCwd, - systemPrompt: cfg.SystemPrompt, - envBlock: cfg.EnvBlock, - newToolServer: cfg.NewToolServer, - newBackend: cfg.NewBackend, - log: cfg.Log, - sessionID: cfg.SessionID, - startupMessages: cfg.StartupMsgs, - save: cfg.Save, - flush: cfg.Flush, - state: "idle", + systemPrompt: cfg.SystemPrompt, + envBlock: cfg.EnvBlock, + newToolServer: cfg.NewToolServer, + newBackend: cfg.NewBackend, + log: cfg.Log, + sessionID: cfg.SessionID, + save: cfg.Save, + flush: cfg.Flush, + state: "idle", } ag.signalCh = make(chan struct{}) ag.chatSignalCh = make(chan struct{}) diff --git a/cmd/olliesrv/internal/agent/agent_config.go b/cmd/olliesrv/internal/agent/agent_config.go index 1db0dd6..804ee21 100644 --- a/cmd/olliesrv/internal/agent/agent_config.go +++ b/cmd/olliesrv/internal/agent/agent_config.go @@ -27,10 +27,9 @@ type AgentConfig struct { UserPrompts Prompt `json:"userPrompts,omitempty"` Backend string `json:"backend,omitempty"` Model string `json:"model,omitempty"` - Tools *bool `json:"tools,omitempty"` - AutoLoad []string `json:"autoLoad,omitempty"` - CompactionModel string `json:"compactionModel,omitempty"` + AutoLoad []string `json:"autoLoad,omitempty"` + CompactionModel string `json:"compactionModel,omitempty"` // SystemPrompt overrides the embedded system prompt with a file path. SystemPrompt string `json:"systemPrompt,omitempty"` @@ -45,9 +44,3 @@ func Load(r io.Reader) (*AgentConfig, error) { } return &cfg, nil } - -// ToolsEnabled reports whether tool use is enabled. Defaults to true when -// the field is omitted from the config. -func (c *AgentConfig) ToolsEnabled() bool { - return c.Tools == nil || *c.Tools -} diff --git a/cmd/olliesrv/internal/agent/loop.go b/cmd/olliesrv/internal/agent/loop.go index a7e12a0..e0d381b 100644 --- a/cmd/olliesrv/internal/agent/loop.go +++ b/cmd/olliesrv/internal/agent/loop.go @@ -774,19 +774,6 @@ func (ag *Agent) trackErrors(ctx context.Context, results []toolResult, es *erro // ── helpers ───────────────────────────────────────────────────────────────── -// contextBudget returns the token threshold (50% of context length) above which -// cold material should be proactively stripped. Returns 0 if unknown. -func contextBudget(ctx context.Context, b backend.Backend) int { - if b == nil { - return 0 - } - ctxLen := b.ContextLength(ctx) - if ctxLen <= 0 { - return 0 - } - return ctxLen / 2 -} - // defaultToolResultMaxBytes caps tool result content sent back to the model. // This is the single semantic limit for what enters the LLM context window. // diff --git a/cmd/olliesrv/internal/agent/runtime.go b/cmd/olliesrv/internal/agent/runtime.go index 02744ed..b2701dc 100644 --- a/cmd/olliesrv/internal/agent/runtime.go +++ b/cmd/olliesrv/internal/agent/runtime.go @@ -148,7 +148,6 @@ type Runtime struct { GenParams backend.GenerationParams CompactionModel string UserPrompt string // resolved user prompts, prepended to each turn's input - Messages []string } // PreambleString returns the fully rendered system prompt. @@ -162,17 +161,11 @@ func (rt *Runtime) PreambleString() string { // BuildRuntime constructs a Runtime from a pre-configured tool server and // optional agent config. func BuildRuntime(cfg *AgentConfig, srv *toolclient.ToolsrvConn, cwd string, env []string, systemPrompt, envBlock string) *Runtime { - var messages []string - var allToolInfos []protocol.ToolInfo var allTools []backend.Tool - if srv != nil && (cfg == nil || cfg.ToolsEnabled()) { - var listErr error - allToolInfos, listErr = srv.ListTools() - if listErr != nil { - messages = append(messages, fmt.Sprintf("list tools: %v", listErr)) - } + if srv != nil { + allToolInfos, _ = srv.ListTools() allTools = toolInfosToBackend(allToolInfos) } var toolRevision uint64 @@ -240,7 +233,6 @@ func BuildRuntime(cfg *AgentConfig, srv *toolclient.ToolsrvConn, cwd string, env GenParams: genParams, CompactionModel: compactionModel, UserPrompt: userPrompt, - Messages: messages, } } diff --git a/cmd/olliesrv/internal/agent/turn.go b/cmd/olliesrv/internal/agent/turn.go index 9b5eeca..2f18bf2 100644 --- a/cmd/olliesrv/internal/agent/turn.go +++ b/cmd/olliesrv/internal/agent/turn.go @@ -155,11 +155,6 @@ func (ag *Agent) executeTurn(ctx context.Context, input string) string { } if ag.history == nil { - for _, msg := range ag.startupMessages { - ag.log.Debug("startup: %s", msg) - ag.emit(infoEvent(msg)) - } - ag.startupMessages = nil ag.history = newHistory(input) if sc := ag.spawnContext(ctx); sc != "" { ag.history.appendUserMessage(sc) diff --git a/cmd/olliesrv/internal/backend/new.go b/cmd/olliesrv/internal/backend/new.go index d9d0fea..e018907 100644 --- a/cmd/olliesrv/internal/backend/new.go +++ b/cmd/olliesrv/internal/backend/new.go @@ -17,10 +17,6 @@ func NewWithName(name string) (Backend, error) { return newBackendFromConfig(name, cfg) } -func newBackend(which string) (Backend, error) { - return newBackendFromConfig(which, loadConfig()) -} - func newBackendFromConfig(which string, cfg configFile) (Backend, error) { bc := cfg.Backends[which] diff --git a/cmd/olliesrv/internal/fs/spec.go b/cmd/olliesrv/internal/fs/spec.go index e23052b..7c3764d 100644 --- a/cmd/olliesrv/internal/fs/spec.go +++ b/cmd/olliesrv/internal/fs/spec.go @@ -31,13 +31,6 @@ type ( SyntheticFileInfo = virtfs.SyntheticFileInfo ) -// Structural permissions. -const ( - PermChildDir = virtfs.PermChildDir - PermIdx = virtfs.PermIdx - PermMkdir = virtfs.PermMkdir - PermMkdirPrivate = virtfs.PermMkdirPrivate -) var treeSpecUID, treeSpecGID string diff --git a/cmd/olliesrv/internal/fs/support.go b/cmd/olliesrv/internal/fs/support.go index 5e7a1cf..3156f9d 100644 --- a/cmd/olliesrv/internal/fs/support.go +++ b/cmd/olliesrv/internal/fs/support.go @@ -5,7 +5,6 @@ package fs import ( "bytes" "fmt" - "os" "strings" "sync" @@ -189,15 +188,3 @@ func messagesUpToTurn(msgs []backend.Message, n int) []backend.Message { } return msgs } - -// agentCwd returns a reasonable CWD for a new agent in a session. -// Uses the first agent's CWD, or falls back to os.Getwd(). -func agentCwd(s *session.Session) string { - for _, ag := range s.Agents() { - if c := ag.Cwd(); c != "" { - return c - } - } - wd, _ := os.Getwd() - return wd -} diff --git a/cmd/olliesrv/internal/session/registry.go b/cmd/olliesrv/internal/session/registry.go index cf4eef9..da369c3 100644 --- a/cmd/olliesrv/internal/session/registry.go +++ b/cmd/olliesrv/internal/session/registry.go @@ -458,34 +458,6 @@ func buildAgent(sess *Session, p AgentParams) (*agent.Agent, error) { return ag, nil } -// CreateAgent creates a new agent within an existing session. -// Args: [profile] [key=value...] where keys include name, backend, model, remote. -func CreateAgent(sessName string, args []string) (*agent.Agent, error) { - // Parse args into AgentParams. - p := AgentParams{Profile: "default"} - for _, arg := range args { - if k, v, ok := strings.Cut(arg, "="); ok { - switch k { - case "name": - p.Name = v - case "backend": - p.Backend = v - case "model": - p.Model = v - case "remote": - p.Remote = v - } - } else if p.Profile == "default" { - p.Profile = arg - } - } - sess := Lookup(sessName) - if sess == nil { - return nil, fmt.Errorf("session not found: %s", sessName) - } - return CreateAgentWithParams(sessName, p) -} - // CreateAgentWithParams creates a new agent within an existing session using // a pre-built AgentParams struct. func CreateAgentWithParams(sessName string, p AgentParams) (*agent.Agent, error) { diff --git a/cmd/olliesrv/internal/session/session.go b/cmd/olliesrv/internal/session/session.go index b6ce164..7b6abc2 100644 --- a/cmd/olliesrv/internal/session/session.go +++ b/cmd/olliesrv/internal/session/session.go @@ -64,20 +64,10 @@ type Session struct { modelsCacheAt time.Time } -var sweepTmpOnce sync.Once - func ollieTmpDir() string { return filepath.Join(util.DataDir(), "tmp") } -func sweepStaleTmpDirs() { - sweepTmpOnce.Do(func() { - base := ollieTmpDir() - os.RemoveAll(base) //nolint:errcheck - os.MkdirAll(base, 0700) //nolint:errcheck - }) -} - // --- Mutable field accessors (only for fields that race) --- // Name returns the mutable friendly name. @@ -438,66 +428,37 @@ func (s *Session) Resume() error { s.Cancel = cancel s.log.Debug("Resume: context created") - // Ensure we always have a Keeper. If the session was restored from disk - // without infra, spawn a new tool server now. - if s.Keeper == nil { - s.log.Info("Resume: no keeper, starting toolsrv") - cwd := s.cwd - if cwd == "" { - cwd, _ = os.Getwd() - } - if s.Remote != "" { - s.log.Info("Resume: spawning remote toolsrv target=%s cwd=%s", s.Remote, cwd) - } else { - s.log.Info("Resume: spawning local toolsrv cwd=%s", cwd) - } - infra, err := SetupToolServer(ToolServerConfig{ - Ctx: ctx, - CWD: cwd, - RemoteTarget: s.Remote, - SessionID: s.ID, - Yolo: s.Yolo, - }) - if err != nil { - s.log.Error("Resume: toolsrv startup failed: %v", err) - cancel() - s.mu.Unlock() - return fmt.Errorf("resume: %w", err) - } - s.log.Info("Resume: toolsrv started") - s.Proc = infra.Proc - s.Keeper = infra.Keeper - s.toolsConn = infra.ToolsConn - for _, ag := range s.agents { - ag.SetToolServer(infra.NewToolServer, infra.NewToolServer()) - ag.SetSessionEnv(s.ID) - } + // Start fresh toolsrv infrastructure. + s.log.Info("Resume: starting toolsrv") + cwd := s.cwd + if cwd == "" { + cwd, _ = os.Getwd() + } + if s.Remote != "" { + s.log.Info("Resume: spawning remote toolsrv target=%s cwd=%s", s.Remote, cwd) } else { - // A paused keeper was closed with the paused process. Start fresh infra. - s.log.Info("Resume: starting fresh toolsrv") - cwd := s.cwd - if cwd == "" { - cwd, _ = os.Getwd() - } - infra, err := SetupToolServer(ToolServerConfig{ - Ctx: ctx, - CWD: cwd, - RemoteTarget: s.Remote, - SessionID: s.ID, - Yolo: s.Yolo, - }) - if err != nil { - cancel() - s.mu.Unlock() - return fmt.Errorf("resume: %w", err) - } - s.Proc = infra.Proc - s.Keeper = infra.Keeper - s.toolsConn = infra.ToolsConn - for _, ag := range s.agents { - ag.SetToolServer(infra.NewToolServer, infra.NewToolServer()) - ag.SetSessionEnv(s.ID) - } + s.log.Info("Resume: spawning local toolsrv cwd=%s", cwd) + } + infra, err := SetupToolServer(ToolServerConfig{ + Ctx: ctx, + CWD: cwd, + RemoteTarget: s.Remote, + SessionID: s.ID, + Yolo: s.Yolo, + }) + if err != nil { + s.log.Error("Resume: toolsrv startup failed: %v", err) + cancel() + s.mu.Unlock() + return fmt.Errorf("resume: %w", err) + } + s.log.Info("Resume: toolsrv started") + s.Proc = infra.Proc + s.Keeper = infra.Keeper + s.toolsConn = infra.ToolsConn + for _, ag := range s.agents { + ag.SetToolServer(infra.NewToolServer, infra.NewToolServer()) + ag.SetSessionEnv(s.ID) } s.paused = false @@ -549,22 +510,6 @@ func rebuildAgentRuntime(ag *agent.Agent, sessID string) error { // --- Tool loading --- -// LoadTool loads a tool into the tool server. -func (s *Session) LoadTool(name string, ag *agent.Agent) error { - name = strings.TrimSpace(name) - if name == "" { - return nil - } - conn := s.ToolsConn() - if conn == nil { - return nil - } - // Ensure session ID is set on toolsrv before loading - the server uses this - // to scope the tool registry. Required because conn may have been reconnected. - conn.SetEnv("OLLIE_SESSION_ID", s.ID) - return LoadToolOnConn(conn, name) -} - // LoadToolOnConn loads a tool on the given connection. func LoadToolOnConn(conn *toolclient.ToolsrvConn, name string) error { if conn == nil { diff --git a/cmd/toolsrv/internal/bypass/bypass.go b/cmd/toolsrv/internal/bypass/bypass.go index 8519949..dadaeeb 100644 --- a/cmd/toolsrv/internal/bypass/bypass.go +++ b/cmd/toolsrv/internal/bypass/bypass.go @@ -115,13 +115,6 @@ func Resolve(id string, approved bool, errMsg string) bool { return true } -// PendingCount returns the number of pending requests (for diagnostics). -func PendingCount() int { - mu.Lock() - defer mu.Unlock() - return len(requests) -} - func nextID() string { b := make([]byte, 8) rand.Read(b) diff --git a/cmd/toolsrv/internal/sandbox/config.go b/cmd/toolsrv/internal/sandbox/config.go index fc23f9c..0de257f 100644 --- a/cmd/toolsrv/internal/sandbox/config.go +++ b/cmd/toolsrv/internal/sandbox/config.go @@ -115,53 +115,6 @@ func expandPath(pattern, cwd string, getenv EnvFunc) string { return s } -// checkPath checks if the given absolute path is allowed by the sandbox config. -// If write is true, the path must fall under an RW or RWX entry. -// If write is false, any entry (RO, ROX, RW, RWX) grants access. -func checkPath(cfg *Config, path string, write bool, cwd string, getenv EnvFunc) error { - cleaned := filepath.Clean(path) - if resolved, err := filepath.EvalSymlinks(cleaned); err == nil { - cleaned = resolved - } else { - // File may not exist yet (new file creation). Resolve parent. - if rp, err2 := filepath.EvalSymlinks(filepath.Dir(cleaned)); err2 == nil { - cleaned = filepath.Join(rp, filepath.Base(cleaned)) - } - } - - var allowed []string - expandAndSplit := func(entries []string) { - for _, p := range entries { - for _, ep := range strings.Split(expandPath(p, cwd, getenv), ":") { - if ep != "" { - allowed = append(allowed, ep) - } - } - } - } - expandAndSplit(cfg.Filesystem.RW) - expandAndSplit(cfg.Filesystem.RWX) - if !write { - expandAndSplit(cfg.Filesystem.RO) - expandAndSplit(cfg.Filesystem.ROX) - } - - for _, root := range allowed { - if pathUnder(cleaned, root) { - return nil - } - } - - if write { - return fmt.Errorf("path outside sandbox (no write access): %s", path) - } - return fmt.Errorf("path outside sandbox (no read access): %s", path) -} - -func pathUnder(path, root string) bool { - return path == root || strings.HasPrefix(path, root+string(filepath.Separator)) -} - // LoadSandbox parses a sandbox config from r. func LoadSandbox(r io.Reader) (*Config, error) { data, err := io.ReadAll(r) diff --git a/cmd/toolsrv/internal/server/proc.go b/cmd/toolsrv/internal/server/proc.go index 9e6ad1b..f7ffaec 100644 --- a/cmd/toolsrv/internal/server/proc.go +++ b/cmd/toolsrv/internal/server/proc.go @@ -12,7 +12,6 @@ import ( "strconv" "strings" "sync" - "sync/atomic" "syscall" "time" @@ -485,12 +484,6 @@ func (st *State) ListProcs() []int { return pids } -// ListProcsWithState returns a formatted list of all processes with their state. -// Format: "pid\tstate\ttool\n" where state is "running" or "exited (code)". -func (st *State) ListProcsWithState() string { - return st.ListProcsForAgent("") -} - // ListProcsForAgent returns a formatted list of processes for the given agent. // If agentID is empty, returns all processes. // Format: "pid\tstate\ttool\tcmd\n" @@ -834,11 +827,3 @@ func escapeJSON(s string) string { s = strings.ReplaceAll(s, "\t", "\\t") return s } - -// --- Atomic counters for unique IDs --- - -var globalProcCounter atomic.Int64 - -func init() { - globalProcCounter.Store(time.Now().UnixNano() % 10000) -} diff --git a/cmd/toolsrv/internal/server/server.go b/cmd/toolsrv/internal/server/server.go index 4125421..477fa93 100644 --- a/cmd/toolsrv/internal/server/server.go +++ b/cmd/toolsrv/internal/server/server.go @@ -7,7 +7,6 @@ import ( "encoding/hex" "encoding/json" "fmt" - "os" "runtime" "strconv" "strings" @@ -261,10 +260,3 @@ func Spec(srv *Server) virtfs.FsNodeDecl { ), ) } - -// Mode constants for convenience. -const ( - ModeReadOnly os.FileMode = 0444 - ModeWriteOnly os.FileMode = 0222 - ModeReadWrite os.FileMode = 0666 -)