refactor: remove dead code across packages (-220 lines)
Dead code removal based on code review: fs/spec.go: - Remove unused Perm* constant aliases fs/support.go: - Remove unused agentCwd() function session/registry.go: - Remove unused CreateAgent() (callers use CreateAgentWithParams directly) session/session.go: - Remove unused sweepStaleTmpDirs() and sweepTmpOnce - Remove unused Session.LoadTool() (callers use LoadToolOnConn directly) - Simplify Resume() by removing dead else branch (Pause() always nils Keeper) toolsrv/server/proc.go: - Remove unused globalProcCounter - Remove unused ListProcsWithState() toolsrv/server/server.go: - Remove unused Mode* constants toolsrv/bypass/bypass.go: - Remove unused PendingCount() toolsrv/sandbox/config.go: - Remove unused checkPath() and pathUnder() backend/new.go: - Remove unused newBackend() (callers use NewWithName) agent/loop.go: - Remove unused contextBudget() agent/agent.go + turn.go + runtime.go: - Remove unused startupMessages, StartupMsgs, Runtime.Messages agent/agent_config.go: - Remove unused Tools *bool field and ToolsEnabled() (tools always enabled)
This commit is contained in:
parent
600fedf1e5
commit
2b59409845
|
|
@ -62,7 +62,6 @@ type Agent struct {
|
||||||
output EventHandler
|
output EventHandler
|
||||||
log *olog.Logger
|
log *olog.Logger
|
||||||
sessionID string // the owning session's ID
|
sessionID string // the owning session's ID
|
||||||
startupMessages []string
|
|
||||||
memoryWakePending atomic.Bool
|
memoryWakePending atomic.Bool
|
||||||
save func() // trigger debounced persistence
|
save func() // trigger debounced persistence
|
||||||
flush func() // immediately flush persistence
|
flush func() // immediately flush persistence
|
||||||
|
|
@ -846,7 +845,6 @@ type AgentParams struct {
|
||||||
NewToolServer func() *toolclient.ToolsrvConn
|
NewToolServer func() *toolclient.ToolsrvConn
|
||||||
NewBackend func(string) (backend.Backend, error)
|
NewBackend func(string) (backend.Backend, error)
|
||||||
Log *olog.Logger
|
Log *olog.Logger
|
||||||
StartupMsgs []string
|
|
||||||
Save func()
|
Save func()
|
||||||
Flush func()
|
Flush func()
|
||||||
}
|
}
|
||||||
|
|
@ -864,16 +862,15 @@ func NewAgent(cfg AgentParams) *Agent {
|
||||||
id: cfg.ID,
|
id: cfg.ID,
|
||||||
parentID: cfg.ParentID,
|
parentID: cfg.ParentID,
|
||||||
getCwd: cfg.GetCwd,
|
getCwd: cfg.GetCwd,
|
||||||
systemPrompt: cfg.SystemPrompt,
|
systemPrompt: cfg.SystemPrompt,
|
||||||
envBlock: cfg.EnvBlock,
|
envBlock: cfg.EnvBlock,
|
||||||
newToolServer: cfg.NewToolServer,
|
newToolServer: cfg.NewToolServer,
|
||||||
newBackend: cfg.NewBackend,
|
newBackend: cfg.NewBackend,
|
||||||
log: cfg.Log,
|
log: cfg.Log,
|
||||||
sessionID: cfg.SessionID,
|
sessionID: cfg.SessionID,
|
||||||
startupMessages: cfg.StartupMsgs,
|
save: cfg.Save,
|
||||||
save: cfg.Save,
|
flush: cfg.Flush,
|
||||||
flush: cfg.Flush,
|
state: "idle",
|
||||||
state: "idle",
|
|
||||||
}
|
}
|
||||||
ag.signalCh = make(chan struct{})
|
ag.signalCh = make(chan struct{})
|
||||||
ag.chatSignalCh = make(chan struct{})
|
ag.chatSignalCh = make(chan struct{})
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,9 @@ type AgentConfig struct {
|
||||||
UserPrompts Prompt `json:"userPrompts,omitempty"`
|
UserPrompts Prompt `json:"userPrompts,omitempty"`
|
||||||
Backend string `json:"backend,omitempty"`
|
Backend string `json:"backend,omitempty"`
|
||||||
Model string `json:"model,omitempty"`
|
Model string `json:"model,omitempty"`
|
||||||
Tools *bool `json:"tools,omitempty"`
|
|
||||||
|
|
||||||
AutoLoad []string `json:"autoLoad,omitempty"`
|
AutoLoad []string `json:"autoLoad,omitempty"`
|
||||||
CompactionModel string `json:"compactionModel,omitempty"`
|
CompactionModel string `json:"compactionModel,omitempty"`
|
||||||
// SystemPrompt overrides the embedded system prompt with a file path.
|
// SystemPrompt overrides the embedded system prompt with a file path.
|
||||||
SystemPrompt string `json:"systemPrompt,omitempty"`
|
SystemPrompt string `json:"systemPrompt,omitempty"`
|
||||||
|
|
||||||
|
|
@ -45,9 +44,3 @@ func Load(r io.Reader) (*AgentConfig, error) {
|
||||||
}
|
}
|
||||||
return &cfg, nil
|
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
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -774,19 +774,6 @@ func (ag *Agent) trackErrors(ctx context.Context, results []toolResult, es *erro
|
||||||
|
|
||||||
// ── helpers ─────────────────────────────────────────────────────────────────
|
// ── 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.
|
// defaultToolResultMaxBytes caps tool result content sent back to the model.
|
||||||
// This is the single semantic limit for what enters the LLM context window.
|
// This is the single semantic limit for what enters the LLM context window.
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,6 @@ type Runtime struct {
|
||||||
GenParams backend.GenerationParams
|
GenParams backend.GenerationParams
|
||||||
CompactionModel string
|
CompactionModel string
|
||||||
UserPrompt string // resolved user prompts, prepended to each turn's input
|
UserPrompt string // resolved user prompts, prepended to each turn's input
|
||||||
Messages []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PreambleString returns the fully rendered system prompt.
|
// 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
|
// BuildRuntime constructs a Runtime from a pre-configured tool server and
|
||||||
// optional agent config.
|
// optional agent config.
|
||||||
func BuildRuntime(cfg *AgentConfig, srv *toolclient.ToolsrvConn, cwd string, env []string, systemPrompt, envBlock string) *Runtime {
|
func BuildRuntime(cfg *AgentConfig, srv *toolclient.ToolsrvConn, cwd string, env []string, systemPrompt, envBlock string) *Runtime {
|
||||||
var messages []string
|
|
||||||
|
|
||||||
var allToolInfos []protocol.ToolInfo
|
var allToolInfos []protocol.ToolInfo
|
||||||
var allTools []backend.Tool
|
var allTools []backend.Tool
|
||||||
|
|
||||||
if srv != nil && (cfg == nil || cfg.ToolsEnabled()) {
|
if srv != nil {
|
||||||
var listErr error
|
allToolInfos, _ = srv.ListTools()
|
||||||
allToolInfos, listErr = srv.ListTools()
|
|
||||||
if listErr != nil {
|
|
||||||
messages = append(messages, fmt.Sprintf("list tools: %v", listErr))
|
|
||||||
}
|
|
||||||
allTools = toolInfosToBackend(allToolInfos)
|
allTools = toolInfosToBackend(allToolInfos)
|
||||||
}
|
}
|
||||||
var toolRevision uint64
|
var toolRevision uint64
|
||||||
|
|
@ -240,7 +233,6 @@ func BuildRuntime(cfg *AgentConfig, srv *toolclient.ToolsrvConn, cwd string, env
|
||||||
GenParams: genParams,
|
GenParams: genParams,
|
||||||
CompactionModel: compactionModel,
|
CompactionModel: compactionModel,
|
||||||
UserPrompt: userPrompt,
|
UserPrompt: userPrompt,
|
||||||
Messages: messages,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -155,11 +155,6 @@ func (ag *Agent) executeTurn(ctx context.Context, input string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ag.history == nil {
|
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)
|
ag.history = newHistory(input)
|
||||||
if sc := ag.spawnContext(ctx); sc != "" {
|
if sc := ag.spawnContext(ctx); sc != "" {
|
||||||
ag.history.appendUserMessage(sc)
|
ag.history.appendUserMessage(sc)
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,6 @@ func NewWithName(name string) (Backend, error) {
|
||||||
return newBackendFromConfig(name, cfg)
|
return newBackendFromConfig(name, cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBackend(which string) (Backend, error) {
|
|
||||||
return newBackendFromConfig(which, loadConfig())
|
|
||||||
}
|
|
||||||
|
|
||||||
func newBackendFromConfig(which string, cfg configFile) (Backend, error) {
|
func newBackendFromConfig(which string, cfg configFile) (Backend, error) {
|
||||||
bc := cfg.Backends[which]
|
bc := cfg.Backends[which]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,13 +31,6 @@ type (
|
||||||
SyntheticFileInfo = virtfs.SyntheticFileInfo
|
SyntheticFileInfo = virtfs.SyntheticFileInfo
|
||||||
)
|
)
|
||||||
|
|
||||||
// Structural permissions.
|
|
||||||
const (
|
|
||||||
PermChildDir = virtfs.PermChildDir
|
|
||||||
PermIdx = virtfs.PermIdx
|
|
||||||
PermMkdir = virtfs.PermMkdir
|
|
||||||
PermMkdirPrivate = virtfs.PermMkdirPrivate
|
|
||||||
)
|
|
||||||
|
|
||||||
var treeSpecUID, treeSpecGID string
|
var treeSpecUID, treeSpecGID string
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ package fs
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
|
@ -189,15 +188,3 @@ func messagesUpToTurn(msgs []backend.Message, n int) []backend.Message {
|
||||||
}
|
}
|
||||||
return msgs
|
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
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -458,34 +458,6 @@ func buildAgent(sess *Session, p AgentParams) (*agent.Agent, error) {
|
||||||
return ag, nil
|
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
|
// CreateAgentWithParams creates a new agent within an existing session using
|
||||||
// a pre-built AgentParams struct.
|
// a pre-built AgentParams struct.
|
||||||
func CreateAgentWithParams(sessName string, p AgentParams) (*agent.Agent, error) {
|
func CreateAgentWithParams(sessName string, p AgentParams) (*agent.Agent, error) {
|
||||||
|
|
|
||||||
|
|
@ -64,20 +64,10 @@ type Session struct {
|
||||||
modelsCacheAt time.Time
|
modelsCacheAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
var sweepTmpOnce sync.Once
|
|
||||||
|
|
||||||
func ollieTmpDir() string {
|
func ollieTmpDir() string {
|
||||||
return filepath.Join(util.DataDir(), "tmp")
|
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) ---
|
// --- Mutable field accessors (only for fields that race) ---
|
||||||
|
|
||||||
// Name returns the mutable friendly name.
|
// Name returns the mutable friendly name.
|
||||||
|
|
@ -438,66 +428,37 @@ func (s *Session) Resume() error {
|
||||||
s.Cancel = cancel
|
s.Cancel = cancel
|
||||||
s.log.Debug("Resume: context created")
|
s.log.Debug("Resume: context created")
|
||||||
|
|
||||||
// Ensure we always have a Keeper. If the session was restored from disk
|
// Start fresh toolsrv infrastructure.
|
||||||
// without infra, spawn a new tool server now.
|
s.log.Info("Resume: starting toolsrv")
|
||||||
if s.Keeper == nil {
|
cwd := s.cwd
|
||||||
s.log.Info("Resume: no keeper, starting toolsrv")
|
if cwd == "" {
|
||||||
cwd := s.cwd
|
cwd, _ = os.Getwd()
|
||||||
if cwd == "" {
|
}
|
||||||
cwd, _ = os.Getwd()
|
if s.Remote != "" {
|
||||||
}
|
s.log.Info("Resume: spawning remote toolsrv target=%s cwd=%s", s.Remote, cwd)
|
||||||
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)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// A paused keeper was closed with the paused process. Start fresh infra.
|
s.log.Info("Resume: spawning local toolsrv cwd=%s", cwd)
|
||||||
s.log.Info("Resume: starting fresh toolsrv")
|
}
|
||||||
cwd := s.cwd
|
infra, err := SetupToolServer(ToolServerConfig{
|
||||||
if cwd == "" {
|
Ctx: ctx,
|
||||||
cwd, _ = os.Getwd()
|
CWD: cwd,
|
||||||
}
|
RemoteTarget: s.Remote,
|
||||||
infra, err := SetupToolServer(ToolServerConfig{
|
SessionID: s.ID,
|
||||||
Ctx: ctx,
|
Yolo: s.Yolo,
|
||||||
CWD: cwd,
|
})
|
||||||
RemoteTarget: s.Remote,
|
if err != nil {
|
||||||
SessionID: s.ID,
|
s.log.Error("Resume: toolsrv startup failed: %v", err)
|
||||||
Yolo: s.Yolo,
|
cancel()
|
||||||
})
|
s.mu.Unlock()
|
||||||
if err != nil {
|
return fmt.Errorf("resume: %w", err)
|
||||||
cancel()
|
}
|
||||||
s.mu.Unlock()
|
s.log.Info("Resume: toolsrv started")
|
||||||
return fmt.Errorf("resume: %w", err)
|
s.Proc = infra.Proc
|
||||||
}
|
s.Keeper = infra.Keeper
|
||||||
s.Proc = infra.Proc
|
s.toolsConn = infra.ToolsConn
|
||||||
s.Keeper = infra.Keeper
|
for _, ag := range s.agents {
|
||||||
s.toolsConn = infra.ToolsConn
|
ag.SetToolServer(infra.NewToolServer, infra.NewToolServer())
|
||||||
for _, ag := range s.agents {
|
ag.SetSessionEnv(s.ID)
|
||||||
ag.SetToolServer(infra.NewToolServer, infra.NewToolServer())
|
|
||||||
ag.SetSessionEnv(s.ID)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s.paused = false
|
s.paused = false
|
||||||
|
|
@ -549,22 +510,6 @@ func rebuildAgentRuntime(ag *agent.Agent, sessID string) error {
|
||||||
|
|
||||||
// --- Tool loading ---
|
// --- 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.
|
// LoadToolOnConn loads a tool on the given connection.
|
||||||
func LoadToolOnConn(conn *toolclient.ToolsrvConn, name string) error {
|
func LoadToolOnConn(conn *toolclient.ToolsrvConn, name string) error {
|
||||||
if conn == nil {
|
if conn == nil {
|
||||||
|
|
|
||||||
|
|
@ -115,13 +115,6 @@ func Resolve(id string, approved bool, errMsg string) bool {
|
||||||
return true
|
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 {
|
func nextID() string {
|
||||||
b := make([]byte, 8)
|
b := make([]byte, 8)
|
||||||
rand.Read(b)
|
rand.Read(b)
|
||||||
|
|
|
||||||
|
|
@ -115,53 +115,6 @@ func expandPath(pattern, cwd string, getenv EnvFunc) string {
|
||||||
return s
|
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.
|
// LoadSandbox parses a sandbox config from r.
|
||||||
func LoadSandbox(r io.Reader) (*Config, error) {
|
func LoadSandbox(r io.Reader) (*Config, error) {
|
||||||
data, err := io.ReadAll(r)
|
data, err := io.ReadAll(r)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -485,12 +484,6 @@ func (st *State) ListProcs() []int {
|
||||||
return pids
|
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.
|
// ListProcsForAgent returns a formatted list of processes for the given agent.
|
||||||
// If agentID is empty, returns all processes.
|
// If agentID is empty, returns all processes.
|
||||||
// Format: "pid\tstate\ttool\tcmd\n"
|
// Format: "pid\tstate\ttool\tcmd\n"
|
||||||
|
|
@ -834,11 +827,3 @@ func escapeJSON(s string) string {
|
||||||
s = strings.ReplaceAll(s, "\t", "\\t")
|
s = strings.ReplaceAll(s, "\t", "\\t")
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Atomic counters for unique IDs ---
|
|
||||||
|
|
||||||
var globalProcCounter atomic.Int64
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
globalProcCounter.Store(time.Now().UnixNano() % 10000)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"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
|
|
||||||
)
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue