feat: add configurable summary and compression trigger thresholds
- Add CompressionTriggerRatio, SummaryTriggerMessages, SummaryTriggerRatio to config - Pass maxTokens and temperature to subagent for consistent LLM settings - Update ToolLoop to support configurable MaxTokens and Temperature - Update default config values and documentation - Fix hardcoded values (8192, 0.7) to use configurable parameters
This commit is contained in:
parent
13e4028d42
commit
6464ca4880
8 changed files with 159 additions and 68 deletions
29
README.md
29
README.md
|
|
@ -198,7 +198,10 @@ picoclaw onboard
|
|||
"model": "glm-4.7",
|
||||
"max_tokens": 8192,
|
||||
"temperature": 0.7,
|
||||
"max_tool_iterations": 20
|
||||
"max_tool_iterations": 20,
|
||||
"compression_trigger_ratio": 0.75,
|
||||
"summary_trigger_messages": 20,
|
||||
"summary_trigger_ratio": 0.75
|
||||
}
|
||||
},
|
||||
"providers": {
|
||||
|
|
@ -650,6 +653,30 @@ The subagent has access to tools (message, web_search, etc.) and can communicate
|
|||
* `PICOCLAW_HEARTBEAT_ENABLED=false` to disable
|
||||
* `PICOCLAW_HEARTBEAT_INTERVAL=60` to change interval
|
||||
|
||||
### Threshold Configuration
|
||||
|
||||
PicoClaw supports customizable conversation summary and compression trigger thresholds to prevent premature context truncation.
|
||||
|
||||
| Configuration | Default | Description |
|
||||
|--------------|---------|-------------|
|
||||
| `max_tokens` | `8192` | Context window size and LLM output token limit |
|
||||
| `compression_trigger_ratio` | `0.75` | Trigger force compression when context exceeds `max_tokens × compression_trigger_ratio` |
|
||||
| `summary_trigger_messages` | `20` | Trigger automatic summary when history message count exceeds this value (set to 0 to disable message count-based triggering) |
|
||||
| `summary_trigger_ratio` | `0.75` | Trigger automatic summary when history token estimate exceeds `max_tokens × summary_trigger_ratio` |
|
||||
|
||||
**Environment variables:**
|
||||
|
||||
* `PICOCLAW_AGENTS_DEFAULTS_MAX_TOKENS=16384` Increase context window
|
||||
* `PICOCLAW_AGENTS_DEFAULTS_COMPRESSION_TRIGGER_RATIO=0.9` Raise compression trigger threshold (e.g., from 75% to 90%)
|
||||
* `PICOCLAW_AGENTS_DEFAULTS_SUMMARY_TRIGGER_MESSAGES=50` Delay message count-based triggering (e.g., from 20 to 50 messages)
|
||||
* `PICOCLAW_AGENTS_DEFAULTS_SUMMARY_TRIGGER_RATIO=0.85` Raise summary trigger threshold (e.g., from 75% to 85%)
|
||||
|
||||
**Usage recommendations:**
|
||||
|
||||
- **Longer conversations**: Increase all thresholds for longer conversations
|
||||
- **Faster response**: Decrease thresholds for quicker summarization and compression
|
||||
- **Token-only control**: Set `summary_trigger_messages=0` to only use `summary_trigger_ratio` for summary triggering
|
||||
|
||||
### Providers
|
||||
|
||||
> [!NOTE]
|
||||
|
|
|
|||
29
README.zh.md
29
README.zh.md
|
|
@ -204,7 +204,10 @@ picoclaw onboard
|
|||
"model": "glm-4.7",
|
||||
"max_tokens": 8192,
|
||||
"temperature": 0.7,
|
||||
"max_tool_iterations": 20
|
||||
"max_tool_iterations": 20,
|
||||
"compression_trigger_ratio": 0.75,
|
||||
"summary_trigger_messages": 20,
|
||||
"summary_trigger_ratio": 0.75
|
||||
}
|
||||
},
|
||||
"providers": {
|
||||
|
|
@ -521,6 +524,30 @@ Agent 读取 HEARTBEAT.md
|
|||
* `PICOCLAW_HEARTBEAT_ENABLED=false` 禁用
|
||||
* `PICOCLAW_HEARTBEAT_INTERVAL=60` 更改间隔
|
||||
|
||||
### 对话阈值配置 (Threshold Configuration)
|
||||
|
||||
PicoClaw 支持自定义对话总结和压缩触发阈值,避免过早截断上下文。
|
||||
|
||||
| 配置项 | 默认值 | 描述 |
|
||||
| --- | --- | --- |
|
||||
| `max_tokens` | `8192` | 上下文窗口大小和 LLM 输出 token 上限 |
|
||||
| `compression_trigger_ratio` | `0.75` | 当上下文超过 `max_tokens × compression_trigger_ratio` 时触发强制压缩(forceCompression) |
|
||||
| `summary_trigger_messages` | `20` | 当历史消息数超过此值时触发自动总结(设为 0 可禁用按条数触发) |
|
||||
| `summary_trigger_ratio` | `0.75` | 当历史消息 token 估算超过 `max_tokens × summary_trigger_ratio` 时触发自动总结 |
|
||||
|
||||
**环境变量:**
|
||||
|
||||
* `PICOCLAW_AGENTS_DEFAULTS_MAX_TOKENS=16384` 提升上下文窗口
|
||||
* `PICOCLAW_AGENTS_DEFAULTS_COMPRESSION_TRIGGER_RATIO=0.9` 提高压缩触发阈值(例如从 75% 提升到 90%)
|
||||
* `PICOCLAW_AGENTS_DEFAULTS_SUMMARY_TRIGGER_MESSAGES=50` 延迟按条数触发(例如从 20 条提升到 50 条)
|
||||
* `PICOCLAW_AGENTS_DEFAULTS_SUMMARY_TRIGGER_RATIO=0.85` 提高总结触发阈值(例如从 75% 提升到 85%)
|
||||
|
||||
**使用建议:**
|
||||
|
||||
- **延长对话**: 提高所有阈值,让对话保持更长时间
|
||||
- **快速响应**: 降低阈值,更快触发总结和压缩
|
||||
- **仅按 token 控制**: 设置 `summary_trigger_messages=0`,仅使用 `summary_trigger_ratio` 控制总结触发
|
||||
|
||||
### 提供商 (Providers)
|
||||
|
||||
> [!NOTE]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@
|
|||
"model": "glm-4.7",
|
||||
"max_tokens": 8192,
|
||||
"temperature": 0.7,
|
||||
"max_tool_iterations": 20
|
||||
"max_tool_iterations": 20,
|
||||
"compression_trigger_ratio": 0.75,
|
||||
"summary_trigger_messages": 20,
|
||||
"summary_trigger_ratio": 0.75
|
||||
}
|
||||
},
|
||||
"channels": {
|
||||
|
|
|
|||
|
|
@ -31,19 +31,23 @@ import (
|
|||
)
|
||||
|
||||
type AgentLoop struct {
|
||||
bus *bus.MessageBus
|
||||
provider providers.LLMProvider
|
||||
workspace string
|
||||
model string
|
||||
contextWindow int // Maximum context window size in tokens
|
||||
maxIterations int
|
||||
sessions *session.SessionManager
|
||||
state *state.Manager
|
||||
contextBuilder *ContextBuilder
|
||||
tools *tools.ToolRegistry
|
||||
running atomic.Bool
|
||||
summarizing sync.Map // Tracks which sessions are currently being summarized
|
||||
channelManager *channels.Manager
|
||||
bus *bus.MessageBus
|
||||
provider providers.LLMProvider
|
||||
workspace string
|
||||
model string
|
||||
contextWindow int // Maximum context window size in tokens
|
||||
maxIterations int
|
||||
sessions *session.SessionManager
|
||||
state *state.Manager
|
||||
contextBuilder *ContextBuilder
|
||||
tools *tools.ToolRegistry
|
||||
running atomic.Bool
|
||||
summarizing sync.Map // Tracks which sessions are currently being summarized
|
||||
channelManager *channels.Manager
|
||||
compressionTriggerRatio float64
|
||||
summaryTriggerMessages int
|
||||
summaryTriggerRatio float64
|
||||
temperature float64
|
||||
}
|
||||
|
||||
// processOptions configures how a message is processed
|
||||
|
|
@ -114,7 +118,14 @@ func NewAgentLoop(cfg *config.Config, msgBus *bus.MessageBus, provider providers
|
|||
toolsRegistry := createToolRegistry(workspace, restrict, cfg, msgBus)
|
||||
|
||||
// Create subagent manager with its own tool registry
|
||||
subagentManager := tools.NewSubagentManager(provider, cfg.Agents.Defaults.Model, workspace, msgBus)
|
||||
subagentManager := tools.NewSubagentManager(
|
||||
provider,
|
||||
cfg.Agents.Defaults.Model,
|
||||
cfg.Agents.Defaults.MaxTokens,
|
||||
cfg.Agents.Defaults.Temperature,
|
||||
workspace,
|
||||
msgBus,
|
||||
)
|
||||
subagentTools := createToolRegistry(workspace, restrict, cfg, msgBus)
|
||||
// Subagent doesn't need spawn/subagent tools to avoid recursion
|
||||
subagentManager.SetTools(subagentTools)
|
||||
|
|
@ -137,17 +148,21 @@ func NewAgentLoop(cfg *config.Config, msgBus *bus.MessageBus, provider providers
|
|||
contextBuilder.SetToolsRegistry(toolsRegistry)
|
||||
|
||||
return &AgentLoop{
|
||||
bus: msgBus,
|
||||
provider: provider,
|
||||
workspace: workspace,
|
||||
model: cfg.Agents.Defaults.Model,
|
||||
contextWindow: cfg.Agents.Defaults.MaxTokens, // Restore context window for summarization
|
||||
maxIterations: cfg.Agents.Defaults.MaxToolIterations,
|
||||
sessions: sessionsManager,
|
||||
state: stateManager,
|
||||
contextBuilder: contextBuilder,
|
||||
tools: toolsRegistry,
|
||||
summarizing: sync.Map{},
|
||||
bus: msgBus,
|
||||
provider: provider,
|
||||
workspace: workspace,
|
||||
model: cfg.Agents.Defaults.Model,
|
||||
contextWindow: cfg.Agents.Defaults.MaxTokens,
|
||||
maxIterations: cfg.Agents.Defaults.MaxToolIterations,
|
||||
sessions: sessionsManager,
|
||||
state: stateManager,
|
||||
contextBuilder: contextBuilder,
|
||||
tools: toolsRegistry,
|
||||
summarizing: sync.Map{},
|
||||
compressionTriggerRatio: cfg.Agents.Defaults.CompressionTriggerRatio,
|
||||
summaryTriggerMessages: cfg.Agents.Defaults.SummaryTriggerMessages,
|
||||
summaryTriggerRatio: cfg.Agents.Defaults.SummaryTriggerRatio,
|
||||
temperature: cfg.Agents.Defaults.Temperature,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -443,8 +458,8 @@ func (al *AgentLoop) runLLMIteration(ctx context.Context, messages []providers.M
|
|||
"model": al.model,
|
||||
"messages_count": len(messages),
|
||||
"tools_count": len(providerToolDefs),
|
||||
"max_tokens": 8192,
|
||||
"temperature": 0.7,
|
||||
"max_tokens": al.contextWindow,
|
||||
"temperature": al.temperature,
|
||||
"system_prompt_len": len(messages[0].Content),
|
||||
})
|
||||
|
||||
|
|
@ -463,8 +478,8 @@ func (al *AgentLoop) runLLMIteration(ctx context.Context, messages []providers.M
|
|||
maxRetries := 2
|
||||
for retry := 0; retry <= maxRetries; retry++ {
|
||||
response, err = al.provider.Chat(ctx, messages, providerToolDefs, al.model, map[string]interface{}{
|
||||
"max_tokens": 8192,
|
||||
"temperature": 0.7,
|
||||
"max_tokens": al.contextWindow,
|
||||
"temperature": al.temperature,
|
||||
})
|
||||
|
||||
if err == nil {
|
||||
|
|
@ -723,9 +738,9 @@ func (al *AgentLoop) updateToolContexts(channel, chatID string) {
|
|||
func (al *AgentLoop) maybeSummarize(sessionKey, channel, chatID string) {
|
||||
newHistory := al.sessions.GetHistory(sessionKey)
|
||||
tokenEstimate := al.estimateTokens(newHistory)
|
||||
threshold := al.contextWindow * 75 / 100
|
||||
threshold := int(float64(al.contextWindow) * al.summaryTriggerRatio)
|
||||
|
||||
if len(newHistory) > 20 || tokenEstimate > threshold {
|
||||
if len(newHistory) > al.summaryTriggerMessages || tokenEstimate > threshold {
|
||||
if _, loading := al.summarizing.LoadOrStore(sessionKey, true); !loading {
|
||||
go func() {
|
||||
defer al.summarizing.Delete(sessionKey)
|
||||
|
|
@ -887,8 +902,8 @@ func (al *AgentLoop) summarizeSession(sessionKey string) {
|
|||
toSummarize := history[:len(history)-4]
|
||||
|
||||
// Oversized Message Guard
|
||||
// Skip messages larger than 50% of context window to prevent summarizer overflow
|
||||
maxMessageTokens := al.contextWindow / 2
|
||||
// Skip messages larger than compression_trigger_ratio of context window to prevent summarizer overflow
|
||||
maxMessageTokens := int(float64(al.contextWindow) * al.compressionTriggerRatio)
|
||||
validMessages := make([]providers.Message, 0)
|
||||
omitted := false
|
||||
|
||||
|
|
|
|||
|
|
@ -59,13 +59,16 @@ type AgentsConfig struct {
|
|||
}
|
||||
|
||||
type AgentDefaults struct {
|
||||
Workspace string `json:"workspace" env:"PICOCLAW_AGENTS_DEFAULTS_WORKSPACE"`
|
||||
RestrictToWorkspace bool `json:"restrict_to_workspace" env:"PICOCLAW_AGENTS_DEFAULTS_RESTRICT_TO_WORKSPACE"`
|
||||
Provider string `json:"provider" env:"PICOCLAW_AGENTS_DEFAULTS_PROVIDER"`
|
||||
Model string `json:"model" env:"PICOCLAW_AGENTS_DEFAULTS_MODEL"`
|
||||
MaxTokens int `json:"max_tokens" env:"PICOCLAW_AGENTS_DEFAULTS_MAX_TOKENS"`
|
||||
Temperature float64 `json:"temperature" env:"PICOCLAW_AGENTS_DEFAULTS_TEMPERATURE"`
|
||||
MaxToolIterations int `json:"max_tool_iterations" env:"PICOCLAW_AGENTS_DEFAULTS_MAX_TOOL_ITERATIONS"`
|
||||
Workspace string `json:"workspace" env:"PICOCLAW_AGENTS_DEFAULTS_WORKSPACE"`
|
||||
RestrictToWorkspace bool `json:"restrict_to_workspace" env:"PICOCLAW_AGENTS_DEFAULTS_RESTRICT_TO_WORKSPACE"`
|
||||
Provider string `json:"provider" env:"PICOCLAW_AGENTS_DEFAULTS_PROVIDER"`
|
||||
Model string `json:"model" env:"PICOCLAW_AGENTS_DEFAULTS_MODEL"`
|
||||
MaxTokens int `json:"max_tokens" env:"PICOCLAW_AGENTS_DEFAULTS_MAX_TOKENS"`
|
||||
Temperature float64 `json:"temperature" env:"PICOCLAW_AGENTS_DEFAULTS_TEMPERATURE"`
|
||||
MaxToolIterations int `json:"max_tool_iterations" env:"PICOCLAW_AGENTS_DEFAULTS_MAX_TOOL_ITERATIONS"`
|
||||
CompressionTriggerRatio float64 `json:"compression_trigger_ratio" env:"PICOCLAW_AGENTS_DEFAULTS_COMPRESSION_TRIGGER_RATIO"`
|
||||
SummaryTriggerMessages int `json:"summary_trigger_messages" env:"PICOCLAW_AGENTS_DEFAULTS_SUMMARY_TRIGGER_MESSAGES"`
|
||||
SummaryTriggerRatio float64 `json:"summary_trigger_ratio" env:"PICOCLAW_AGENTS_DEFAULTS_SUMMARY_TRIGGER_RATIO"`
|
||||
}
|
||||
|
||||
type ChannelsConfig struct {
|
||||
|
|
@ -219,13 +222,16 @@ func DefaultConfig() *Config {
|
|||
return &Config{
|
||||
Agents: AgentsConfig{
|
||||
Defaults: AgentDefaults{
|
||||
Workspace: "~/.picoclaw/workspace",
|
||||
RestrictToWorkspace: true,
|
||||
Provider: "",
|
||||
Model: "glm-4.7",
|
||||
MaxTokens: 8192,
|
||||
Temperature: 0.7,
|
||||
MaxToolIterations: 20,
|
||||
Workspace: "~/.picoclaw/workspace",
|
||||
RestrictToWorkspace: true,
|
||||
Provider: "",
|
||||
Model: "glm-4.7",
|
||||
MaxTokens: 8192,
|
||||
Temperature: 0.7,
|
||||
MaxToolIterations: 20,
|
||||
CompressionTriggerRatio: 0.75,
|
||||
SummaryTriggerMessages: 20,
|
||||
SummaryTriggerRatio: 0.75,
|
||||
},
|
||||
},
|
||||
Channels: ChannelsConfig{
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ type SubagentManager struct {
|
|||
mu sync.RWMutex
|
||||
provider providers.LLMProvider
|
||||
defaultModel string
|
||||
maxTokens int
|
||||
temperature float64
|
||||
bus *bus.MessageBus
|
||||
workspace string
|
||||
tools *ToolRegistry
|
||||
|
|
@ -33,11 +35,13 @@ type SubagentManager struct {
|
|||
nextID int
|
||||
}
|
||||
|
||||
func NewSubagentManager(provider providers.LLMProvider, defaultModel, workspace string, bus *bus.MessageBus) *SubagentManager {
|
||||
func NewSubagentManager(provider providers.LLMProvider, defaultModel string, maxTokens int, temperature float64, workspace string, bus *bus.MessageBus) *SubagentManager {
|
||||
return &SubagentManager{
|
||||
tasks: make(map[string]*SubagentTask),
|
||||
provider: provider,
|
||||
defaultModel: defaultModel,
|
||||
maxTokens: maxTokens,
|
||||
temperature: temperature,
|
||||
bus: bus,
|
||||
workspace: workspace,
|
||||
tools: NewToolRegistry(),
|
||||
|
|
@ -123,17 +127,17 @@ After completing the task, provide a clear summary of what was done.`
|
|||
sm.mu.RLock()
|
||||
tools := sm.tools
|
||||
maxIter := sm.maxIterations
|
||||
maxTokens := sm.maxTokens
|
||||
temperature := sm.temperature
|
||||
sm.mu.RUnlock()
|
||||
|
||||
loopResult, err := RunToolLoop(ctx, ToolLoopConfig{
|
||||
Provider: sm.provider,
|
||||
Model: sm.defaultModel,
|
||||
MaxTokens: maxTokens,
|
||||
Temperature: temperature,
|
||||
Tools: tools,
|
||||
MaxIterations: maxIter,
|
||||
LLMOptions: map[string]any{
|
||||
"max_tokens": 4096,
|
||||
"temperature": 0.7,
|
||||
},
|
||||
}, messages, task.OriginChannel, task.OriginChatID)
|
||||
|
||||
sm.mu.Lock()
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func (m *MockLLMProvider) GetContextWindow() int {
|
|||
// TestSubagentTool_Name verifies tool name
|
||||
func TestSubagentTool_Name(t *testing.T) {
|
||||
provider := &MockLLMProvider{}
|
||||
manager := NewSubagentManager(provider, "test-model", "/tmp/test", nil)
|
||||
manager := NewSubagentManager(provider, "test-model", 4096, 0.7, "/tmp/test", nil)
|
||||
tool := NewSubagentTool(manager)
|
||||
|
||||
if tool.Name() != "subagent" {
|
||||
|
|
@ -50,7 +50,7 @@ func TestSubagentTool_Name(t *testing.T) {
|
|||
// TestSubagentTool_Description verifies tool description
|
||||
func TestSubagentTool_Description(t *testing.T) {
|
||||
provider := &MockLLMProvider{}
|
||||
manager := NewSubagentManager(provider, "test-model", "/tmp/test", nil)
|
||||
manager := NewSubagentManager(provider, "test-model", 4096, 0.7, "/tmp/test", nil)
|
||||
tool := NewSubagentTool(manager)
|
||||
|
||||
desc := tool.Description()
|
||||
|
|
@ -65,7 +65,7 @@ func TestSubagentTool_Description(t *testing.T) {
|
|||
// TestSubagentTool_Parameters verifies tool parameters schema
|
||||
func TestSubagentTool_Parameters(t *testing.T) {
|
||||
provider := &MockLLMProvider{}
|
||||
manager := NewSubagentManager(provider, "test-model", "/tmp/test", nil)
|
||||
manager := NewSubagentManager(provider, "test-model", 4096, 0.7, "/tmp/test", nil)
|
||||
tool := NewSubagentTool(manager)
|
||||
|
||||
params := tool.Parameters()
|
||||
|
|
@ -115,7 +115,7 @@ func TestSubagentTool_Parameters(t *testing.T) {
|
|||
// TestSubagentTool_SetContext verifies context setting
|
||||
func TestSubagentTool_SetContext(t *testing.T) {
|
||||
provider := &MockLLMProvider{}
|
||||
manager := NewSubagentManager(provider, "test-model", "/tmp/test", nil)
|
||||
manager := NewSubagentManager(provider, "test-model", 4096, 0.7, "/tmp/test", nil)
|
||||
tool := NewSubagentTool(manager)
|
||||
|
||||
tool.SetContext("test-channel", "test-chat")
|
||||
|
|
@ -129,7 +129,7 @@ func TestSubagentTool_SetContext(t *testing.T) {
|
|||
func TestSubagentTool_Execute_Success(t *testing.T) {
|
||||
provider := &MockLLMProvider{}
|
||||
msgBus := bus.NewMessageBus()
|
||||
manager := NewSubagentManager(provider, "test-model", "/tmp/test", msgBus)
|
||||
manager := NewSubagentManager(provider, "test-model", 4096, 0.7, "/tmp/test", msgBus)
|
||||
tool := NewSubagentTool(manager)
|
||||
tool.SetContext("telegram", "chat-123")
|
||||
|
||||
|
|
@ -185,7 +185,7 @@ func TestSubagentTool_Execute_Success(t *testing.T) {
|
|||
func TestSubagentTool_Execute_NoLabel(t *testing.T) {
|
||||
provider := &MockLLMProvider{}
|
||||
msgBus := bus.NewMessageBus()
|
||||
manager := NewSubagentManager(provider, "test-model", "/tmp/test", msgBus)
|
||||
manager := NewSubagentManager(provider, "test-model", 4096, 0.7, "/tmp/test", msgBus)
|
||||
tool := NewSubagentTool(manager)
|
||||
|
||||
ctx := context.Background()
|
||||
|
|
@ -208,7 +208,7 @@ func TestSubagentTool_Execute_NoLabel(t *testing.T) {
|
|||
// TestSubagentTool_Execute_MissingTask tests error handling for missing task
|
||||
func TestSubagentTool_Execute_MissingTask(t *testing.T) {
|
||||
provider := &MockLLMProvider{}
|
||||
manager := NewSubagentManager(provider, "test-model", "/tmp/test", nil)
|
||||
manager := NewSubagentManager(provider, "test-model", 4096, 0.7, "/tmp/test", nil)
|
||||
tool := NewSubagentTool(manager)
|
||||
|
||||
ctx := context.Background()
|
||||
|
|
@ -259,7 +259,7 @@ func TestSubagentTool_Execute_NilManager(t *testing.T) {
|
|||
func TestSubagentTool_Execute_ContextPassing(t *testing.T) {
|
||||
provider := &MockLLMProvider{}
|
||||
msgBus := bus.NewMessageBus()
|
||||
manager := NewSubagentManager(provider, "test-model", "/tmp/test", msgBus)
|
||||
manager := NewSubagentManager(provider, "test-model", 4096, 0.7, "/tmp/test", msgBus)
|
||||
tool := NewSubagentTool(manager)
|
||||
|
||||
// Set context
|
||||
|
|
@ -288,7 +288,7 @@ func TestSubagentTool_ForUserTruncation(t *testing.T) {
|
|||
// Create a mock provider that returns very long content
|
||||
provider := &MockLLMProvider{}
|
||||
msgBus := bus.NewMessageBus()
|
||||
manager := NewSubagentManager(provider, "test-model", "/tmp/test", msgBus)
|
||||
manager := NewSubagentManager(provider, "test-model", 4096, 0.7, "/tmp/test", msgBus)
|
||||
tool := NewSubagentTool(manager)
|
||||
|
||||
ctx := context.Background()
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import (
|
|||
type ToolLoopConfig struct {
|
||||
Provider providers.LLMProvider
|
||||
Model string
|
||||
MaxTokens int
|
||||
Temperature float64
|
||||
Tools *ToolRegistry
|
||||
MaxIterations int
|
||||
LLMOptions map[string]any
|
||||
|
|
@ -55,10 +57,17 @@ func RunToolLoop(ctx context.Context, config ToolLoopConfig, messages []provider
|
|||
// 2. Set default LLM options
|
||||
llmOpts := config.LLMOptions
|
||||
if llmOpts == nil {
|
||||
llmOpts = map[string]any{
|
||||
"max_tokens": 4096,
|
||||
"temperature": 0.7,
|
||||
}
|
||||
llmOpts = map[string]any{}
|
||||
}
|
||||
|
||||
// Set max_tokens if not specified in LLMOptions
|
||||
if _, ok := llmOpts["max_tokens"]; !ok && config.MaxTokens > 0 {
|
||||
llmOpts["max_tokens"] = config.MaxTokens
|
||||
}
|
||||
|
||||
// Set temperature if not specified in LLMOptions
|
||||
if _, ok := llmOpts["temperature"]; !ok && config.Temperature > 0 {
|
||||
llmOpts["temperature"] = config.Temperature
|
||||
}
|
||||
|
||||
// 3. Call LLM
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue