mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-09-20 00:22:21 +02:00
feat: manage task process lifetimes and preserve turn history
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
// Package processguard provides OS containment and out-of-process crash cleanup.
|
||||
// It is intentionally independent of the Agent/MCP packages so it can be
|
||||
// cross-compiled and exercised without starting the application.
|
||||
package processguard
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
Mode string `yaml:"mode" json:"mode"` // auto, required, process_group
|
||||
CgroupRoot string `yaml:"cgroup_root" json:"cgroup_root"`
|
||||
MaxProcesses int `yaml:"max_processes" json:"max_processes"`
|
||||
MemoryMaxBytes int64 `yaml:"memory_max_bytes" json:"memory_max_bytes"`
|
||||
CPUQuotaMicros int64 `yaml:"cpu_quota_micros" json:"cpu_quota_micros"` // per 100000 us
|
||||
}
|
||||
|
||||
// Prepared commands must call Commit after Start and always call Dispose.
|
||||
// Commit releases the Unix fallback launch gate only after watchdog ownership
|
||||
// is acknowledged. Strong backends assign containment atomically at creation.
|
||||
type Launch struct {
|
||||
Commit func() error
|
||||
Dispose func()
|
||||
}
|
||||
|
||||
type Group interface {
|
||||
Name() string
|
||||
Prepare(*exec.Cmd) (*Launch, error)
|
||||
Release(int) error
|
||||
Close(context.Context) error
|
||||
}
|
||||
|
||||
var configured = struct {
|
||||
sync.RWMutex
|
||||
opts Options
|
||||
}{opts: Options{Mode: "auto", MaxProcesses: 256, MemoryMaxBytes: 2 << 30}}
|
||||
|
||||
func normalize(o Options) (Options, error) {
|
||||
if o.Mode == "" {
|
||||
o.Mode = "auto"
|
||||
}
|
||||
if o.Mode != "auto" && o.Mode != "required" && o.Mode != "process_group" {
|
||||
return o, fmt.Errorf("invalid process isolation mode %q", o.Mode)
|
||||
}
|
||||
if o.MaxProcesses == 0 {
|
||||
o.MaxProcesses = 256
|
||||
}
|
||||
if o.MemoryMaxBytes == 0 {
|
||||
o.MemoryMaxBytes = 2 << 30
|
||||
}
|
||||
if o.MaxProcesses < 1 || o.MaxProcesses > 65535 || o.MemoryMaxBytes < 0 || o.CPUQuotaMicros < 0 {
|
||||
return o, fmt.Errorf("invalid process isolation resource limits")
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// Configure validates deployment before accepting any tasks. An explicit root
|
||||
// or required mode fails closed; it never silently falls back after an error.
|
||||
func Configure(o Options) error {
|
||||
var err error
|
||||
o, err = normalize(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = configurePlatform(&o); err != nil {
|
||||
return err
|
||||
}
|
||||
configured.Lock()
|
||||
configured.opts = o
|
||||
configured.Unlock()
|
||||
return nil
|
||||
}
|
||||
func New(id string) (Group, error) {
|
||||
configured.RLock()
|
||||
o := configured.opts
|
||||
configured.RUnlock()
|
||||
return NewWithOptions(id, o)
|
||||
}
|
||||
func NewWithOptions(id string, o Options) (Group, error) {
|
||||
var err error
|
||||
o, err = normalize(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newPlatformGroup(id, o)
|
||||
}
|
||||
Reference in New Issue
Block a user