refactored the dir structure
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
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
|
||||
AuthToken string `toml:"auth_token"` // for HTTP Bearer authentication
|
||||
Headers map[string]string `toml:"headers"` // for custom headers
|
||||
}
|
||||
|
||||
// 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
|
||||
EnableShellExec bool `toml:"enable_shell_exec"`
|
||||
Streaming bool `toml:"streaming"`
|
||||
LogIntermediate bool `toml:"log_intermediate"`
|
||||
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
|
||||
}
|
||||
|
||||
func (s *MCPServerConfig) Resolve() {
|
||||
s.Command = resolveEnv(s.Command)
|
||||
for i, arg := range s.Args {
|
||||
s.Args[i] = resolveEnv(arg)
|
||||
}
|
||||
for i, e := range s.Env {
|
||||
parts := strings.SplitN(e, "=", 2)
|
||||
if len(parts) == 2 {
|
||||
s.Env[i] = parts[0] + "=" + resolveEnv(parts[1])
|
||||
} else {
|
||||
s.Env[i] = resolveEnv(e)
|
||||
}
|
||||
}
|
||||
s.URL = resolveEnv(s.URL)
|
||||
s.AuthToken = resolveEnv(s.AuthToken)
|
||||
for k, v := range s.Headers {
|
||||
s.Headers[k] = resolveEnv(v)
|
||||
}
|
||||
}
|
||||
|
||||
// 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, s := range cfg.MCPServers {
|
||||
s.Resolve()
|
||||
cfg.MCPServers[k] = s
|
||||
}
|
||||
for k, a := range cfg.Agents {
|
||||
a.ID = k
|
||||
a.ToolResponseThreshold = cfg.ToolResponseThreshold
|
||||
cfg.Agents[k] = a
|
||||
}
|
||||
return &cfg, nil
|
||||
}
|
||||
Reference in New Issue
Block a user