diff --git a/.env.example b/.env.example index d9d3ac74..e9e0d6f4 100644 --- a/.env.example +++ b/.env.example @@ -176,5 +176,15 @@ COS_ENABLE_OLD_DOMAIN=true # 影响:单文件上传、gRPC消息大小、Nginx请求体大小 # MAX_FILE_SIZE_MB=50 +# ========== Agent Skills Sandbox 配置 ========== +# Sandbox 模式: docker(推荐), local, disabled(默认) +# WEKNORA_SANDBOX_MODE=disabled + +# 脚本执行超时时间(秒),默认60 +# WEKNORA_SANDBOX_TIMEOUT=60 + +# 自定义 Sandbox Docker 镜像 +# WEKNORA_SANDBOX_DOCKER_IMAGE=wechatopenai/weknora-sandbox:latest + # APK 镜像源设置(可选) APK_MIRROR_ARG=mirrors.tencent.com diff --git a/docs/agent-skills.md b/docs/agent-skills.md index 7bf55517..4f799708 100644 --- a/docs/agent-skills.md +++ b/docs/agent-skills.md @@ -101,13 +101,11 @@ with pdfplumber.open("document.pdf") as pdf: ```go type AgentConfig struct { // ... 其他配置 ... - + // Skills 相关配置 SkillsEnabled bool `json:"skills_enabled"` // 是否启用 Skills SkillDirs []string `json:"skill_dirs"` // Skill 目录列表 AllowedSkills []string `json:"allowed_skills"` // 白名单(空=全部允许) - SandboxMode string `json:"sandbox_mode"` // sandbox 模式 - SandboxTimeout int `json:"sandbox_timeout"` // 脚本执行超时(秒) } ``` @@ -120,12 +118,20 @@ type AgentConfig struct { "/path/to/project/skills", "/home/user/.agent-skills" ], - "allowed_skills": ["pdf-processing", "code-review"], - "sandbox_mode": "docker", - "sandbox_timeout": 30 + "allowed_skills": ["pdf-processing", "code-review"] } ``` +### Sandbox 配置(环境变量) + +Sandbox 相关配置通过环境变量设置: + +| 环境变量 | 说明 | 默认值 | +|---------|------|--------| +| `WEKNORA_SANDBOX_MODE` | sandbox 模式: `docker`, `local`, `disabled` | `disabled` | +| `WEKNORA_SANDBOX_TIMEOUT` | 脚本执行超时(秒) | `60` | +| `WEKNORA_SANDBOX_DOCKER_IMAGE` | 自定义 Docker 镜像 | `wechatopenai/weknora-sandbox:latest` | + ### Sandbox 模式 | 模式 | 说明 | diff --git a/internal/application/service/agent_service.go b/internal/application/service/agent_service.go index 426c131a..93592319 100644 --- a/internal/application/service/agent_service.go +++ b/internal/application/service/agent_service.go @@ -4,6 +4,8 @@ import ( "context" "database/sql" "fmt" + "os" + "strconv" "github.com/Tencent/WeKnora/internal/agent" "github.com/Tencent/WeKnora/internal/agent/skills" @@ -219,18 +221,32 @@ func (s *agentService) initializeSkillsManager( config *types.AgentConfig, toolRegistry *tools.ToolRegistry, ) (*skills.Manager, error) { - // Initialize sandbox manager based on configuration + // Initialize sandbox manager based on environment variables + // WEKNORA_SANDBOX_MODE: "docker", "local", "disabled" (default: "disabled") + // WEKNORA_SANDBOX_TIMEOUT: timeout in seconds (default: 60) + // WEKNORA_SANDBOX_DOCKER_IMAGE: custom Docker image (default: wechatopenai/weknora-sandbox:latest) var sandboxMgr sandbox.Manager var err error - sandboxMode := config.SandboxMode + sandboxMode := os.Getenv("WEKNORA_SANDBOX_MODE") if sandboxMode == "" { sandboxMode = "disabled" } + dockerImage := os.Getenv("WEKNORA_SANDBOX_DOCKER_IMAGE") + if dockerImage == "" { + dockerImage = sandbox.DefaultDockerImage + } + sandboxTimeoutStr := os.Getenv("WEKNORA_SANDBOX_TIMEOUT") + sandboxTimeout := 60 + if sandboxTimeoutStr != "" { + if v, err := strconv.Atoi(sandboxTimeoutStr); err == nil && v > 0 { + sandboxTimeout = v + } + } switch sandboxMode { case "docker": - sandboxMgr, err = sandbox.NewManagerFromType("docker", true, config.DockerImage) // Enable fallback to local + sandboxMgr, err = sandbox.NewManagerFromType("docker", true, dockerImage) // Enable fallback to local if err != nil { logger.Warnf(ctx, "Failed to initialize Docker sandbox, falling back to disabled: %v", err) sandboxMgr = sandbox.NewDisabledManager() @@ -244,6 +260,7 @@ func (s *agentService) initializeSkillsManager( default: sandboxMgr = sandbox.NewDisabledManager() } + logger.Infof(ctx, "Sandbox configured: mode=%s, timeout=%ds, image=%s", sandboxMode, sandboxTimeout, dockerImage) // Create skills manager skillsConfig := &skills.ManagerConfig{ diff --git a/internal/application/service/session.go b/internal/application/service/session.go index 78f5937e..64143a27 100644 --- a/internal/application/service/session.go +++ b/internal/application/service/session.go @@ -886,23 +886,6 @@ func (s *sessionService) configureSkillsFromAgent( logger.Warnf(ctx, "Unknown SkillsSelectionMode=%s: skills disabled", customAgent.Config.SkillsSelectionMode) } - // Configure sandbox mode for skill script execution - if agentConfig.SkillsEnabled { - // Set sandbox mode (default to "docker" when skills are enabled) - agentConfig.SandboxMode = customAgent.Config.SandboxMode - if agentConfig.SandboxMode == "" { - agentConfig.SandboxMode = "docker" // Default to docker for security - } - // Set sandbox timeout (default to 60 seconds) - agentConfig.SandboxTimeout = customAgent.Config.SandboxTimeout - if agentConfig.SandboxTimeout == 0 { - agentConfig.SandboxTimeout = 60 - } - // Set custom Docker image (empty means use default) - agentConfig.DockerImage = customAgent.Config.DockerImage - logger.Infof(ctx, "Sandbox configured: mode=%s, timeout=%ds, image=%s", - agentConfig.SandboxMode, agentConfig.SandboxTimeout, agentConfig.DockerImage) - } } // buildSearchTargets computes the unified search targets from knowledgeBaseIDs and knowledgeIDs diff --git a/internal/types/agent.go b/internal/types/agent.go index c50dc752..4390f731 100644 --- a/internal/types/agent.go +++ b/internal/types/agent.go @@ -38,9 +38,6 @@ type AgentConfig struct { SkillsEnabled bool `json:"skills_enabled"` // Whether skills are enabled (default: false) SkillDirs []string `json:"skill_dirs"` // Directories to search for skills AllowedSkills []string `json:"allowed_skills"` // Skill names whitelist (empty = allow all) - SandboxMode string `json:"sandbox_mode"` // Sandbox mode: "docker", "local", "disabled" (default: "disabled") - SandboxTimeout int `json:"sandbox_timeout"` // Script execution timeout in seconds (default: 60) - DockerImage string `json:"docker_image"` // Custom sandbox Docker image (default: wechatopenai/weknora-sandbox:latest) } // SessionAgentConfig represents session-level agent configuration diff --git a/internal/types/custom_agent.go b/internal/types/custom_agent.go index 1b58dfa1..2d170d59 100644 --- a/internal/types/custom_agent.go +++ b/internal/types/custom_agent.go @@ -99,13 +99,6 @@ type CustomAgentConfig struct { SkillsSelectionMode string `yaml:"skills_selection_mode" json:"skills_selection_mode"` // Selected skill names (only used when SkillsSelectionMode is "selected") SelectedSkills []string `yaml:"selected_skills" json:"selected_skills"` - // Sandbox mode for skill script execution: "docker", "local", "disabled" (default: "docker" when skills enabled) - SandboxMode string `yaml:"sandbox_mode" json:"sandbox_mode"` - // Script execution timeout in seconds (default: 60) - SandboxTimeout int `yaml:"sandbox_timeout" json:"sandbox_timeout"` - // Custom sandbox Docker image (default: wechatopenai/weknora-sandbox:latest) - DockerImage string `yaml:"docker_image" json:"docker_image"` - // ===== Knowledge Base Settings ===== // Knowledge base selection mode: "all" = all KBs, "selected" = specific KBs, "none" = no KB KBSelectionMode string `yaml:"kb_selection_mode" json:"kb_selection_mode"`