olliesrv: add -strict and -yolo flags
-strict: only tool steps allowed, inline code rejected. -yolo: skip landrun sandbox for execute_code.
This commit is contained in:
parent
9bfccebff6
commit
88ea073135
15
README.md
15
README.md
|
|
@ -123,6 +123,21 @@ The server listens on a Unix socket in the Plan 9 namespace (`$NAMESPACE/ollie`)
|
|||
|
||||
`olliesrv mount` is for remote instances: it calls `9pfuse <addr> <mnt>` and defaults the mountpoint to `$HOME/mnt/<addr>`.
|
||||
|
||||
### Flags
|
||||
|
||||
| Flag | Effect |
|
||||
|------|--------|
|
||||
| `-strict` | Only `{tool}` steps are allowed in `execute_code`; inline `{code}` steps are rejected. |
|
||||
| `-yolo` | Skip the landrun sandbox for all `execute_code` execution. |
|
||||
| `-tcp <addr>` | Also listen on a TCP address (e.g. `:564`). |
|
||||
| `-mount <path>` | Override the FUSE mount path. |
|
||||
|
||||
```sh
|
||||
olliesrv start -strict # tools only, sandboxed
|
||||
olliesrv start -yolo # arbitrary code, no sandbox
|
||||
olliesrv start -strict -yolo # tools only, no sandbox
|
||||
```
|
||||
|
||||
## Sessions
|
||||
|
||||
### Create
|
||||
|
|
|
|||
17
main.go
17
main.go
|
|
@ -20,6 +20,8 @@ const serviceName = "ollie"
|
|||
|
||||
var mountPath = flag.String("mount", "", "FUSE mount path (default: $HOME/mnt/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 execute_code")
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
|
|
@ -115,6 +117,12 @@ func daemonize(pidPath string) {
|
|||
if *tcpAddr != "" {
|
||||
args = append(args, "-tcp", *tcpAddr)
|
||||
}
|
||||
if *strict {
|
||||
args = append(args, "-strict")
|
||||
}
|
||||
if *yolo {
|
||||
args = append(args, "-yolo")
|
||||
}
|
||||
cmd := exec.Command(exe, args...)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true}
|
||||
if err := cmd.Start(); err != nil {
|
||||
|
|
@ -152,7 +160,14 @@ func runServer(sockPath, pidPath string) {
|
|||
os.WriteFile(pidPath, []byte(fmt.Sprintf("%d", os.Getpid())), 0644) //nolint:errcheck
|
||||
|
||||
sink := olog.NewSink(os.Stdout, os.Stderr, olog.ParseLevel(os.Getenv("OLLIE_LOG"), olog.LevelWarn))
|
||||
srv := New(sink)
|
||||
var srvOpts []ServerOption
|
||||
if *strict {
|
||||
srvOpts = append(srvOpts, WithStrict())
|
||||
}
|
||||
if *yolo {
|
||||
srvOpts = append(srvOpts, WithYolo())
|
||||
}
|
||||
srv := New(sink, srvOpts...)
|
||||
|
||||
listener, err := net.Listen("unix", sockPath)
|
||||
if err != nil {
|
||||
|
|
|
|||
15
server.go
15
server.go
|
|
@ -226,10 +226,18 @@ type Server struct {
|
|||
sessionStore *SessionStore
|
||||
transcriptStore Store
|
||||
tmpStore Store
|
||||
strict bool
|
||||
yolo bool
|
||||
}
|
||||
|
||||
// ServerOption configures the 9P server.
|
||||
type ServerOption func(*Server)
|
||||
|
||||
func WithStrict() ServerOption { return func(s *Server) { s.strict = true } }
|
||||
func WithYolo() ServerOption { return func(s *Server) { s.yolo = true } }
|
||||
|
||||
// New creates a new Server.
|
||||
func New(sink *olog.Sink) *Server {
|
||||
func New(sink *olog.Sink, opts ...ServerOption) *Server {
|
||||
memDir := defaultMemDir()
|
||||
os.MkdirAll(memDir, 0755) //nolint:errcheck
|
||||
transcriptDir := defaultTranscriptDir()
|
||||
|
|
@ -252,11 +260,16 @@ func New(sink *olog.Sink) *Server {
|
|||
transcriptStore: NewFlatDirStore(transcriptDir, 0444),
|
||||
tmpStore: NewFlatDirStore(tmpDir, 0600),
|
||||
}
|
||||
for _, o := range opts {
|
||||
o(s)
|
||||
}
|
||||
s.sessionStore = store.NewSessionStore(store.SessionStoreConfig{
|
||||
AgentsDir: agentsDir,
|
||||
SessionsDir: sessionsDir,
|
||||
Log: s.log,
|
||||
Sink: s.sink,
|
||||
Strict: s.strict,
|
||||
Yolo: s.yolo,
|
||||
SaveTranscript: func(data []byte) error {
|
||||
name := time.Now().Format("20060102T150405") + "-chat.md"
|
||||
return storeWrite(s.transcriptStore, name, data)
|
||||
|
|
|
|||
|
|
@ -110,6 +110,10 @@ type SessionStoreConfig struct {
|
|||
// NewCore, if non-nil, replaces the default backend.New + agent.NewAgentCore
|
||||
// path. It receives the session ID, agent name, and cwd, and returns a Core.
|
||||
NewCore func(sessionID, agentName, cwd string) (agent.Core, error)
|
||||
// Strict rejects inline code steps; only tool steps are allowed.
|
||||
Strict bool
|
||||
// Yolo skips the landrun sandbox.
|
||||
Yolo bool
|
||||
}
|
||||
|
||||
// SessionStore implements Store for session management.
|
||||
|
|
@ -371,8 +375,15 @@ func (s *SessionStore) createSession(args []string) error {
|
|||
|
||||
cfg := LoadAgentConfig(s.cfg.AgentsDir, agentName, nil)
|
||||
|
||||
var execOpts []execute.Option
|
||||
if s.cfg.Strict {
|
||||
execOpts = append(execOpts, execute.WithStrict())
|
||||
}
|
||||
if s.cfg.Yolo {
|
||||
execOpts = append(execOpts, execute.WithYolo())
|
||||
}
|
||||
newDisp := tools.NewDispatcherFunc(map[string]func() tools.Server{
|
||||
"execute": execute.Decl(cwd),
|
||||
"execute": execute.Decl(cwd, execOpts...),
|
||||
})
|
||||
|
||||
env := agent.BuildAgentEnv(cfg, newDisp(), cwd)
|
||||
|
|
|
|||
Reference in New Issue