first commit
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
APIKey string
|
||||
BaseURL string
|
||||
Model string
|
||||
Port string
|
||||
Workspace string
|
||||
DataDir string
|
||||
// AuthCode 是 Web/API/WS 访问授权码。为空(默认)表示不启用授权;
|
||||
// 非空(Docker 部署时通过环境变量 AGENT_AUTH_CODE 注入)表示启用:
|
||||
// 访问者必须输入正确授权码才能使用本实例。
|
||||
AuthCode string
|
||||
MaxContextTokens int
|
||||
KeepRecentMessages int
|
||||
MaxToolResultChars int
|
||||
MaxIterations int
|
||||
ToolTimeout time.Duration
|
||||
RequestTimeout time.Duration
|
||||
StreamOutputTokens int
|
||||
CompactionTokens int
|
||||
Temperature float64
|
||||
}
|
||||
|
||||
func LoadConfig() Config {
|
||||
loadDotEnv(".env")
|
||||
|
||||
workspace := getenv("AGENT_WORKSPACE", "")
|
||||
if workspace == "" {
|
||||
workspace, _ = os.Getwd()
|
||||
}
|
||||
absWorkspace, err := filepath.Abs(workspace)
|
||||
if err != nil {
|
||||
absWorkspace = workspace
|
||||
}
|
||||
dataDir := getenv("AGENT_DATA_DIR", filepath.Join(absWorkspace, "data"))
|
||||
if !filepath.IsAbs(dataDir) {
|
||||
dataDir = filepath.Join(absWorkspace, dataDir)
|
||||
}
|
||||
|
||||
cfg := Config{
|
||||
APIKey: os.Getenv("SILICONFLOW_API_KEY"),
|
||||
BaseURL: getenv("SILICONFLOW_BASE_URL", "https://api.siliconflow.cn/v1/chat/completions"),
|
||||
Model: getenv("AGENT_MODEL", "Qwen/Qwen3-32B"),
|
||||
Port: getenv("AGENT_PORT", "8080"),
|
||||
Workspace: absWorkspace,
|
||||
DataDir: dataDir,
|
||||
// 全面放开限制以适配 DeepSeek(128K 上下文、大输出)跑复杂任务:
|
||||
// - MaxContextTokens 给到 1M,确保 compactionInputBudget 公式(window - Compaction - Stream - window/8)仍有充足余量
|
||||
// - StreamOutputTokens 提升到 65536:直接作为 max_tokens 传给 LLM(见 llm.go),是放开主 Agent 输出能力的关键
|
||||
// - CompactionTokens 提升到 16384:压缩摘要允许足够长度,避免历史信息丢失
|
||||
// - MaxToolResultChars 提升到 100000:复杂任务的脚本/日志能完整传回 LLM,不被截断
|
||||
// - KeepRecentMessages 提升到 50:压缩后保留更多历史,复杂多步任务上下文不丢
|
||||
// - ToolTimeout/RequestTimeout 提升到 600s:编译/长命令/深度推理有充足时间
|
||||
MaxContextTokens: getenvInt("AGENT_MAX_CONTEXT_TOKENS", 1000000),
|
||||
KeepRecentMessages: getenvInt("AGENT_KEEP_RECENT_MESSAGES", 50),
|
||||
MaxToolResultChars: getenvInt("AGENT_MAX_TOOL_RESULT_CHARS", 100000),
|
||||
MaxIterations: getenvInt("AGENT_MAX_ITERATIONS", 50),
|
||||
ToolTimeout: time.Duration(getenvInt("AGENT_TOOL_TIMEOUT_SECONDS", 600)) * time.Second,
|
||||
RequestTimeout: time.Duration(getenvInt("AGENT_REQUEST_TIMEOUT_SECONDS", 600)) * time.Second,
|
||||
StreamOutputTokens: getenvInt("AGENT_STREAM_OUTPUT_TOKENS", 65536),
|
||||
CompactionTokens: getenvInt("AGENT_COMPACTION_TOKENS", 16384),
|
||||
Temperature: getenvFloat("AGENT_TEMPERATURE", 0.3),
|
||||
// 授权码默认关闭:仅当 Docker 部署时显式注入 AGENT_AUTH_CODE 才启用访问授权。
|
||||
AuthCode: getenv("AGENT_AUTH_CODE", ""),
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
func loadDotEnv(path string) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
key, value, ok := strings.Cut(line, "=")
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
key = strings.TrimSpace(key)
|
||||
value = strings.TrimSpace(value)
|
||||
value = strings.Trim(value, `"'`)
|
||||
if key == "" {
|
||||
continue
|
||||
}
|
||||
if _, exists := os.LookupEnv(key); !exists {
|
||||
_ = os.Setenv(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getenv(key, fallback string) string {
|
||||
if value := os.Getenv(key); value != "" {
|
||||
return value
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func getenvInt(key string, fallback int) int {
|
||||
value := os.Getenv(key)
|
||||
if value == "" {
|
||||
return fallback
|
||||
}
|
||||
parsed, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return fallback
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
|
||||
func getenvFloat(key string, fallback float64) float64 {
|
||||
value := os.Getenv(key)
|
||||
if value == "" {
|
||||
return fallback
|
||||
}
|
||||
parsed, err := strconv.ParseFloat(value, 64)
|
||||
if err != nil {
|
||||
return fallback
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
Reference in New Issue
Block a user