feat(config): add context_window, summary_max_tokens, summary_temperature
This commit is contained in:
parent
96fda2e090
commit
f6df9991e5
10 changed files with 104 additions and 37 deletions
|
|
@ -4,8 +4,11 @@
|
|||
"workspace": "~/.picoclaw/workspace",
|
||||
"restrict_to_workspace": true,
|
||||
"model": "gpt4",
|
||||
"context_window": 8192,
|
||||
"max_tokens": 8192,
|
||||
"temperature": 0.7,
|
||||
"summary_max_tokens": 1024,
|
||||
"summary_temperature": 0.3,
|
||||
"max_tool_iterations": 20
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -15,22 +15,24 @@ import (
|
|||
// AgentInstance represents a fully configured agent with its own workspace,
|
||||
// session manager, context builder, and tool registry.
|
||||
type AgentInstance struct {
|
||||
ID string
|
||||
Name string
|
||||
Model string
|
||||
Fallbacks []string
|
||||
Workspace string
|
||||
MaxIterations int
|
||||
MaxTokens int
|
||||
Temperature float64
|
||||
ContextWindow int
|
||||
Provider providers.LLMProvider
|
||||
Sessions *session.SessionManager
|
||||
ContextBuilder *ContextBuilder
|
||||
Tools *tools.ToolRegistry
|
||||
Subagents *config.SubagentsConfig
|
||||
SkillsFilter []string
|
||||
Candidates []providers.FallbackCandidate
|
||||
ID string
|
||||
Name string
|
||||
Model string
|
||||
Fallbacks []string
|
||||
Workspace string
|
||||
MaxIterations int
|
||||
ContextWindow int // Token limit used for summarization threshold and message-size guard (not the LLM response limit).
|
||||
MaxTokens int // Max tokens allowed in a single LLM response (passed to provider Chat).
|
||||
Temperature float64
|
||||
SummaryMaxTokens int
|
||||
SummaryTemperature float64
|
||||
Provider providers.LLMProvider
|
||||
Sessions *session.SessionManager
|
||||
ContextBuilder *ContextBuilder
|
||||
Tools *tools.ToolRegistry
|
||||
Subagents *config.SubagentsConfig
|
||||
SkillsFilter []string
|
||||
Candidates []providers.FallbackCandidate
|
||||
}
|
||||
|
||||
// NewAgentInstance creates an agent instance from config.
|
||||
|
|
@ -78,11 +80,26 @@ func NewAgentInstance(
|
|||
maxIter = 20
|
||||
}
|
||||
|
||||
contextWindow := defaults.ContextWindow
|
||||
if contextWindow <= 0 {
|
||||
contextWindow = 8192
|
||||
}
|
||||
|
||||
maxTokens := defaults.MaxTokens
|
||||
if maxTokens == 0 {
|
||||
if maxTokens <= 0 {
|
||||
maxTokens = 8192
|
||||
}
|
||||
|
||||
sumMaxTok := defaults.SummaryMaxTokens
|
||||
if sumMaxTok <= 0 {
|
||||
sumMaxTok = 1024
|
||||
}
|
||||
|
||||
sumTemp := defaults.SummaryTemperature
|
||||
if sumTemp <= 0 {
|
||||
sumTemp = 0.3
|
||||
}
|
||||
|
||||
temperature := 0.7
|
||||
if defaults.Temperature != nil {
|
||||
temperature = *defaults.Temperature
|
||||
|
|
@ -96,22 +113,24 @@ func NewAgentInstance(
|
|||
candidates := providers.ResolveCandidates(modelCfg, defaults.Provider)
|
||||
|
||||
return &AgentInstance{
|
||||
ID: agentID,
|
||||
Name: agentName,
|
||||
Model: model,
|
||||
Fallbacks: fallbacks,
|
||||
Workspace: workspace,
|
||||
MaxIterations: maxIter,
|
||||
MaxTokens: maxTokens,
|
||||
Temperature: temperature,
|
||||
ContextWindow: maxTokens,
|
||||
Provider: provider,
|
||||
Sessions: sessionsManager,
|
||||
ContextBuilder: contextBuilder,
|
||||
Tools: toolsRegistry,
|
||||
Subagents: subagents,
|
||||
SkillsFilter: skillsFilter,
|
||||
Candidates: candidates,
|
||||
ID: agentID,
|
||||
Name: agentName,
|
||||
Model: model,
|
||||
Fallbacks: fallbacks,
|
||||
Workspace: workspace,
|
||||
MaxIterations: maxIter,
|
||||
ContextWindow: contextWindow,
|
||||
MaxTokens: maxTokens,
|
||||
Temperature: temperature,
|
||||
SummaryMaxTokens: sumMaxTok,
|
||||
SummaryTemperature: sumTemp,
|
||||
Provider: provider,
|
||||
Sessions: sessionsManager,
|
||||
ContextBuilder: contextBuilder,
|
||||
Tools: toolsRegistry,
|
||||
Subagents: subagents,
|
||||
SkillsFilter: skillsFilter,
|
||||
Candidates: candidates,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -977,8 +977,8 @@ func (al *AgentLoop) summarizeSession(agent *AgentInstance, sessionKey string) {
|
|||
nil,
|
||||
agent.Model,
|
||||
map[string]any{
|
||||
"max_tokens": 1024,
|
||||
"temperature": 0.3,
|
||||
"max_tokens": agent.SummaryMaxTokens,
|
||||
"temperature": agent.SummaryTemperature,
|
||||
},
|
||||
)
|
||||
if err == nil {
|
||||
|
|
@ -1027,8 +1027,8 @@ func (al *AgentLoop) summarizeBatch(
|
|||
nil,
|
||||
agent.Model,
|
||||
map[string]any{
|
||||
"max_tokens": 1024,
|
||||
"temperature": 0.3,
|
||||
"max_tokens": agent.SummaryMaxTokens,
|
||||
"temperature": agent.SummaryTemperature,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ func TestRecordLastChannel(t *testing.T) {
|
|||
Defaults: config.AgentDefaults{
|
||||
Workspace: tmpDir,
|
||||
Model: "test-model",
|
||||
ContextWindow: 4096,
|
||||
MaxTokens: 4096,
|
||||
MaxToolIterations: 10,
|
||||
},
|
||||
|
|
@ -73,6 +74,7 @@ func TestRecordLastChatID(t *testing.T) {
|
|||
Defaults: config.AgentDefaults{
|
||||
Workspace: tmpDir,
|
||||
Model: "test-model",
|
||||
ContextWindow: 4096,
|
||||
MaxTokens: 4096,
|
||||
MaxToolIterations: 10,
|
||||
},
|
||||
|
|
@ -118,6 +120,7 @@ func TestNewAgentLoop_StateInitialized(t *testing.T) {
|
|||
Defaults: config.AgentDefaults{
|
||||
Workspace: tmpDir,
|
||||
Model: "test-model",
|
||||
ContextWindow: 4096,
|
||||
MaxTokens: 4096,
|
||||
MaxToolIterations: 10,
|
||||
},
|
||||
|
|
@ -154,6 +157,7 @@ func TestToolRegistry_ToolRegistration(t *testing.T) {
|
|||
Defaults: config.AgentDefaults{
|
||||
Workspace: tmpDir,
|
||||
Model: "test-model",
|
||||
ContextWindow: 4096,
|
||||
MaxTokens: 4096,
|
||||
MaxToolIterations: 10,
|
||||
},
|
||||
|
|
@ -200,6 +204,7 @@ func TestToolContext_Updates(t *testing.T) {
|
|||
Defaults: config.AgentDefaults{
|
||||
Workspace: tmpDir,
|
||||
Model: "test-model",
|
||||
ContextWindow: 4096,
|
||||
MaxTokens: 4096,
|
||||
MaxToolIterations: 10,
|
||||
},
|
||||
|
|
@ -231,6 +236,7 @@ func TestToolRegistry_GetDefinitions(t *testing.T) {
|
|||
Defaults: config.AgentDefaults{
|
||||
Workspace: tmpDir,
|
||||
Model: "test-model",
|
||||
ContextWindow: 4096,
|
||||
MaxTokens: 4096,
|
||||
MaxToolIterations: 10,
|
||||
},
|
||||
|
|
@ -275,6 +281,7 @@ func TestAgentLoop_GetStartupInfo(t *testing.T) {
|
|||
Defaults: config.AgentDefaults{
|
||||
Workspace: tmpDir,
|
||||
Model: "test-model",
|
||||
ContextWindow: 4096,
|
||||
MaxTokens: 4096,
|
||||
MaxToolIterations: 10,
|
||||
},
|
||||
|
|
@ -322,6 +329,7 @@ func TestAgentLoop_Stop(t *testing.T) {
|
|||
Defaults: config.AgentDefaults{
|
||||
Workspace: tmpDir,
|
||||
Model: "test-model",
|
||||
ContextWindow: 4096,
|
||||
MaxTokens: 4096,
|
||||
MaxToolIterations: 10,
|
||||
},
|
||||
|
|
@ -450,6 +458,7 @@ func TestToolResult_SilentToolDoesNotSendUserMessage(t *testing.T) {
|
|||
Defaults: config.AgentDefaults{
|
||||
Workspace: tmpDir,
|
||||
Model: "test-model",
|
||||
ContextWindow: 4096,
|
||||
MaxTokens: 4096,
|
||||
MaxToolIterations: 10,
|
||||
},
|
||||
|
|
@ -492,6 +501,7 @@ func TestToolResult_UserFacingToolDoesSendMessage(t *testing.T) {
|
|||
Defaults: config.AgentDefaults{
|
||||
Workspace: tmpDir,
|
||||
Model: "test-model",
|
||||
ContextWindow: 4096,
|
||||
MaxTokens: 4096,
|
||||
MaxToolIterations: 10,
|
||||
},
|
||||
|
|
@ -563,6 +573,7 @@ func TestAgentLoop_ContextExhaustionRetry(t *testing.T) {
|
|||
Defaults: config.AgentDefaults{
|
||||
Workspace: tmpDir,
|
||||
Model: "test-model",
|
||||
ContextWindow: 4096,
|
||||
MaxTokens: 4096,
|
||||
MaxToolIterations: 10,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ func testCfg(agents []config.AgentConfig) *config.Config {
|
|||
Defaults: config.AgentDefaults{
|
||||
Workspace: "/tmp/picoclaw-test-registry",
|
||||
Model: "gpt-4",
|
||||
ContextWindow: 8192,
|
||||
MaxTokens: 8192,
|
||||
MaxToolIterations: 10,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -178,8 +178,11 @@ type AgentDefaults struct {
|
|||
ModelFallbacks []string `json:"model_fallbacks,omitempty"`
|
||||
ImageModel string `json:"image_model,omitempty" env:"PICOCLAW_AGENTS_DEFAULTS_IMAGE_MODEL"`
|
||||
ImageModelFallbacks []string `json:"image_model_fallbacks,omitempty"`
|
||||
ContextWindow int `json:"context_window" env:"PICOCLAW_AGENTS_DEFAULTS_CONTEXT_WINDOW"`
|
||||
MaxTokens int `json:"max_tokens" env:"PICOCLAW_AGENTS_DEFAULTS_MAX_TOKENS"`
|
||||
Temperature *float64 `json:"temperature,omitempty" env:"PICOCLAW_AGENTS_DEFAULTS_TEMPERATURE"`
|
||||
SummaryMaxTokens int `json:"summary_max_tokens" env:"PICOCLAW_AGENTS_DEFAULTS_SUMMARY_MAX_TOKENS"`
|
||||
SummaryTemperature float64 `json:"summary_temperature" env:"PICOCLAW_AGENTS_DEFAULTS_SUMMARY_TEMPERATURE"`
|
||||
MaxToolIterations int `json:"max_tool_iterations" env:"PICOCLAW_AGENTS_DEFAULTS_MAX_TOOL_ITERATIONS"`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -215,6 +215,15 @@ func TestDefaultConfig_Model(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestDefaultConfig_ContextWindow verifies context_window has default value
|
||||
func TestDefaultConfig_ContextWindow(t *testing.T) {
|
||||
cfg := DefaultConfig()
|
||||
|
||||
if cfg.Agents.Defaults.ContextWindow == 0 {
|
||||
t.Error("ContextWindow should not be zero")
|
||||
}
|
||||
}
|
||||
|
||||
// TestDefaultConfig_MaxTokens verifies max tokens has default value
|
||||
func TestDefaultConfig_MaxTokens(t *testing.T) {
|
||||
cfg := DefaultConfig()
|
||||
|
|
@ -337,6 +346,9 @@ func TestConfig_Complete(t *testing.T) {
|
|||
if cfg.Agents.Defaults.Temperature != nil {
|
||||
t.Error("Temperature should be nil when not provided")
|
||||
}
|
||||
if cfg.Agents.Defaults.ContextWindow == 0 {
|
||||
t.Error("ContextWindow should not be zero")
|
||||
}
|
||||
if cfg.Agents.Defaults.MaxTokens == 0 {
|
||||
t.Error("MaxTokens should not be zero")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,10 @@ func DefaultConfig() *Config {
|
|||
RestrictToWorkspace: true,
|
||||
Provider: "",
|
||||
Model: "glm-4.7",
|
||||
ContextWindow: 8192,
|
||||
MaxTokens: 8192,
|
||||
SummaryMaxTokens: 1024,
|
||||
SummaryTemperature: 0.3,
|
||||
Temperature: nil, // nil means use provider default
|
||||
MaxToolIterations: 20,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -75,12 +75,24 @@ func ConvertConfig(data map[string]any) (*config.Config, []string, error) {
|
|||
if v, ok := getString(defaults, "model"); ok {
|
||||
cfg.Agents.Defaults.Model = v
|
||||
}
|
||||
if v, ok := getFloat(defaults, "context_window"); ok {
|
||||
cfg.Agents.Defaults.ContextWindow = int(v)
|
||||
} else if v, ok := getFloat(defaults, "max_tokens"); ok {
|
||||
// Backward compat: old configs used max_tokens for both; set context_window from it.
|
||||
cfg.Agents.Defaults.ContextWindow = int(v)
|
||||
}
|
||||
if v, ok := getFloat(defaults, "max_tokens"); ok {
|
||||
cfg.Agents.Defaults.MaxTokens = int(v)
|
||||
}
|
||||
if v, ok := getFloat(defaults, "temperature"); ok {
|
||||
cfg.Agents.Defaults.Temperature = &v
|
||||
}
|
||||
if v, ok := getFloat(defaults, "summary_max_tokens"); ok {
|
||||
cfg.Agents.Defaults.SummaryMaxTokens = int(v)
|
||||
}
|
||||
if v, ok := getFloat(defaults, "summary_temperature"); ok {
|
||||
cfg.Agents.Defaults.SummaryTemperature = v
|
||||
}
|
||||
if v, ok := getFloat(defaults, "max_tool_iterations"); ok {
|
||||
cfg.Agents.Defaults.MaxToolIterations = int(v)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -272,6 +272,9 @@ func TestConvertConfig(t *testing.T) {
|
|||
if cfg.Agents.Defaults.Model != "claude-3-opus" {
|
||||
t.Errorf("Model = %q, want %q", cfg.Agents.Defaults.Model, "claude-3-opus")
|
||||
}
|
||||
if cfg.Agents.Defaults.ContextWindow != 4096 {
|
||||
t.Errorf("ContextWindow = %d, want 4096 (backward compat from max_tokens)", cfg.Agents.Defaults.ContextWindow)
|
||||
}
|
||||
if cfg.Agents.Defaults.MaxTokens != 4096 {
|
||||
t.Errorf("MaxTokens = %d, want %d", cfg.Agents.Defaults.MaxTokens, 4096)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue