dify/dify-agent-runtime/internal/server/config.go
Yunlu Wen 302d7b1e1b
feat(agent): shellctl rewritten in go (#38841)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 01:58:36 +00:00

129 lines
4.6 KiB
Go

package server
import (
"os"
"path/filepath"
"runtime"
"time"
)
const (
DefaultListen = "127.0.0.1:8765"
DefaultTimeoutSeconds = 30.0
DefaultMaxWaitTimeoutSeconds = 600.0
DefaultIdleFlushSeconds = 0.5
DefaultTerminalCols = 200
DefaultTerminalRows = 50
DefaultOutputLimitBytes = 16 * 1024
MaxOutputLimitBytes = 512 * 1024
DefaultListLimit = 50
MaxListLimit = 200
DefaultTerminateGraceSeconds = 10.0
DefaultGCIntervalSeconds = 60.0
DefaultGCFinishedJobRetentionSeconds = 300.0
DefaultPollInterval = 50 * time.Millisecond
DefaultPipeMonitorInterval = 1 * time.Second
DefaultPipeReadyTimeout = 10 * time.Second
DefaultSQLiteBusyTimeoutMs = 5000
DefaultAuthTokenEnv = "SHELLCTL_AUTH_TOKEN"
HealthStatus = "ok"
)
// Config holds runtime configuration for the shellctl server.
type Config struct {
Listen string
AuthToken string
StateDir string
RuntimeDir string
GCInterval time.Duration
GCFinishedJobRetention time.Duration
DefaultTimeout time.Duration
MaxWaitTimeout time.Duration
IdleFlushDuration time.Duration
DefaultCwd string
DefaultTerminalCols int
DefaultTerminalRows int
DefaultListLimit int
MaxListLimit int
DefaultOutputLimitBytes int
MaxOutputLimitBytes int
DefaultTerminateGraceSeconds float64
PollInterval time.Duration
PipeMonitorInterval time.Duration
PipeReadyTimeout time.Duration
SQLiteBusyTimeoutMs int
SanitizePtyCommand []string
RunnerExitCommand []string
}
// DefaultConfig returns a Config with sensible defaults.
func DefaultConfig() *Config {
homeDir, _ := os.UserHomeDir()
stateDir := defaultStateDir()
runtimeDir := filepath.Join(stateDir, "runtime")
cfg := &Config{
Listen: DefaultListen,
StateDir: stateDir,
RuntimeDir: runtimeDir,
GCInterval: time.Duration(DefaultGCIntervalSeconds * float64(time.Second)),
GCFinishedJobRetention: time.Duration(DefaultGCFinishedJobRetentionSeconds * float64(time.Second)),
DefaultTimeout: time.Duration(DefaultTimeoutSeconds * float64(time.Second)),
MaxWaitTimeout: time.Duration(DefaultMaxWaitTimeoutSeconds * float64(time.Second)),
IdleFlushDuration: time.Duration(DefaultIdleFlushSeconds * float64(time.Second)),
DefaultCwd: homeDir,
DefaultTerminalCols: DefaultTerminalCols,
DefaultTerminalRows: DefaultTerminalRows,
DefaultListLimit: DefaultListLimit,
MaxListLimit: MaxListLimit,
DefaultOutputLimitBytes: DefaultOutputLimitBytes,
MaxOutputLimitBytes: MaxOutputLimitBytes,
DefaultTerminateGraceSeconds: DefaultTerminateGraceSeconds,
PollInterval: DefaultPollInterval,
PipeMonitorInterval: DefaultPipeMonitorInterval,
PipeReadyTimeout: DefaultPipeReadyTimeout,
SQLiteBusyTimeoutMs: DefaultSQLiteBusyTimeoutMs,
SanitizePtyCommand: []string{"shellctl-sanitize-pty"},
RunnerExitCommand: []string{"shellctl-runner-exit"},
}
// Auth token from environment if not set explicitly
if cfg.AuthToken == "" {
cfg.AuthToken = os.Getenv(DefaultAuthTokenEnv)
}
return cfg
}
// JobsDir returns the path to the jobs artifact directory.
func (c *Config) JobsDir() string {
return filepath.Join(c.StateDir, "jobs")
}
// DBPath returns the path to the SQLite database.
func (c *Config) DBPath() string {
return filepath.Join(c.StateDir, "shellctl.db")
}
// TmuxSocket returns the path to the dedicated tmux socket.
func (c *Config) TmuxSocket() string {
return filepath.Join(c.RuntimeDir, "tmux.sock")
}
// RunnerPath returns the path to the installed runner script.
func (c *Config) RunnerPath() string {
return filepath.Join(c.RuntimeDir, "bin", "shellctl-runner")
}
func defaultStateDir() string {
if runtime.GOOS == "darwin" {
home, _ := os.UserHomeDir()
return filepath.Join(home, ".local", "share", "shellctl")
}
if xdg := os.Getenv("XDG_DATA_HOME"); xdg != "" {
return filepath.Join(xdg, "shellctl")
}
home, _ := os.UserHomeDir()
return filepath.Join(home, ".local", "share", "shellctl")
}