102 lines
3.3 KiB
Go
102 lines
3.3 KiB
Go
package sidekick
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/BurntSushi/toml"
|
|
)
|
|
|
|
// ProjectConfig represents the root of the TOML configuration
|
|
type ProjectConfig struct {
|
|
ToolResponseThreshold int `toml:"tool_response_threshold"`
|
|
MCPListener MCPListenerConfig `toml:"mcp_listener"`
|
|
Models map[string]ModelConfig `toml:"models"`
|
|
MCPServers map[string]MCPServerConfig `toml:"mcp_servers"`
|
|
Agents map[string]AgentConfig `toml:"agents"`
|
|
}
|
|
|
|
// MCPListenerConfig configures the MCP server exposed by Sidekick
|
|
type MCPListenerConfig struct {
|
|
Transport string `toml:"transport"` // "stdio" or "http"
|
|
Port int `toml:"port"` // used if transport is "http"
|
|
}
|
|
|
|
// ModelConfig holds configuration for the LLM
|
|
type ModelConfig struct {
|
|
ModelID string `toml:"model_id"`
|
|
Endpoint string `toml:"endpoint"`
|
|
APIKey string `toml:"api_key"`
|
|
Temperature float32 `toml:"temperature"`
|
|
MaxTokens int `toml:"max_tokens"`
|
|
TimeoutSecs int `toml:"timeout_secs"`
|
|
Timeout time.Duration `toml:"-"`
|
|
}
|
|
|
|
// MCPServerConfig configures a single MCP server connection
|
|
type MCPServerConfig struct {
|
|
Transport string `toml:"transport"` // "stdio", "sse", "http", "websocket"
|
|
Command string `toml:"command"` // for stdio
|
|
Args []string `toml:"args"` // for stdio
|
|
Env []string `toml:"env"` // for stdio, format "KEY=VALUE"
|
|
URL string `toml:"url"` // for HTTP/SSE/WebSocket
|
|
}
|
|
|
|
// AgentConfig holds configuration for a specific agent instance
|
|
type AgentConfig struct {
|
|
ID string `toml:"-"`
|
|
Role Role `toml:"role"`
|
|
ModelID string `toml:"model_id"`
|
|
Goals []string `toml:"goals"`
|
|
SystemPrompt string `toml:"system_prompt"`
|
|
Description string `toml:"description"`
|
|
MaxIterations int `toml:"max_iterations"`
|
|
Toolsets []string `toml:"toolsets"` // Allowed tool namespaces (MCP servers)
|
|
Subagents []string `toml:"subagents"` // Allowed subagent IDs
|
|
ToolResponseThreshold int `toml:"-"`
|
|
}
|
|
|
|
// resolveEnv checks if a string starts with "env:" and resolves it
|
|
func resolveEnv(val string) string {
|
|
if strings.HasPrefix(val, "env:") {
|
|
envVar := strings.TrimPrefix(val, "env:")
|
|
return os.Getenv(envVar)
|
|
}
|
|
return val
|
|
}
|
|
|
|
// Resolve applies environment variable resolution to relevant fields
|
|
func (m *ModelConfig) Resolve() {
|
|
m.ModelID = resolveEnv(m.ModelID)
|
|
m.Endpoint = resolveEnv(m.Endpoint)
|
|
m.APIKey = resolveEnv(m.APIKey)
|
|
if m.TimeoutSecs > 0 {
|
|
m.Timeout = time.Duration(m.TimeoutSecs) * time.Second
|
|
}
|
|
if m.Timeout == 0 {
|
|
m.Timeout = 120 * time.Second
|
|
}
|
|
}
|
|
|
|
// LoadConfig parses a TOML configuration file into ProjectConfig
|
|
func LoadConfig(path string) (*ProjectConfig, error) {
|
|
var cfg ProjectConfig
|
|
if _, err := toml.DecodeFile(path, &cfg); err != nil {
|
|
return nil, err
|
|
}
|
|
if cfg.ToolResponseThreshold <= 0 {
|
|
cfg.ToolResponseThreshold = 10000
|
|
}
|
|
for k, m := range cfg.Models {
|
|
m.Resolve()
|
|
cfg.Models[k] = m
|
|
}
|
|
for k, a := range cfg.Agents {
|
|
a.ID = k
|
|
a.ToolResponseThreshold = cfg.ToolResponseThreshold
|
|
cfg.Agents[k] = a
|
|
}
|
|
return &cfg, nil
|
|
}
|