mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-18 12:14:24 +00:00
feat(thinking): add per-agent extended thinking with Anthropic, OpenAI, and DashScope support
Implement full thinking mode system: per-agent thinking_level config (off/low/medium/high) stored in other_config JSONB, per-provider param injection (Anthropic budget_tokens, OpenAI reasoning_effort, DashScope enable_thinking+thinking_budget), Anthropic extended thinking with streaming parse and tool use block preservation via RawAssistantContent, thinking token tracking in trace spans, and Web UI with agent config selector, chat thinking block rendering, and trace thinking token display. No DB migration needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
d913f29c69
commit
552ddc059e
18 files changed
+455
-33
No files matched your search
+17
-5
@@ -100,6 +100,9 @@ type Loop struct {
|
||||
|
||||
// Global builtin tool settings (from builtin_tools table, managed mode)
|
||||
builtinToolSettings tools.BuiltinToolSettings
|
||||
|
||||
// Thinking level for extended thinking support
|
||||
thinkingLevel string
|
||||
}
|
||||
|
||||
// AgentEvent is emitted during agent execution for WS broadcasting.
|
||||
@@ -162,6 +165,9 @@ type LoopConfig struct {
|
||||
|
||||
// Global builtin tool settings (from builtin_tools table, managed mode)
|
||||
BuiltinToolSettings tools.BuiltinToolSettings
|
||||
|
||||
// Thinking level: "off", "low", "medium", "high" (from agent other_config)
|
||||
ThinkingLevel string
|
||||
}
|
||||
|
||||
func NewLoop(cfg LoopConfig) *Loop {
|
||||
@@ -220,6 +226,7 @@ func NewLoop(cfg LoopConfig) *Loop {
|
||||
injectionAction: action,
|
||||
maxMessageChars: cfg.MaxMessageChars,
|
||||
builtinToolSettings: cfg.BuiltinToolSettings,
|
||||
thinkingLevel: cfg.ThinkingLevel,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,10 +547,13 @@ func (l *Loop) runLoop(ctx context.Context, req RunRequest) (*RunResult, error)
|
||||
Tools: toolDefs,
|
||||
Model: l.model,
|
||||
Options: map[string]interface{}{
|
||||
"max_tokens": 8192,
|
||||
"temperature": 0.7,
|
||||
providers.OptMaxTokens: 8192,
|
||||
providers.OptTemperature: 0.7,
|
||||
},
|
||||
}
|
||||
if l.thinkingLevel != "" && l.thinkingLevel != "off" {
|
||||
chatReq.Options[providers.OptThinkingLevel] = l.thinkingLevel
|
||||
}
|
||||
|
||||
// Call LLM (streaming or non-streaming)
|
||||
var resp *providers.ChatResponse
|
||||
@@ -585,6 +595,7 @@ func (l *Loop) runLoop(ctx context.Context, req RunRequest) (*RunResult, error)
|
||||
totalUsage.PromptTokens += resp.Usage.PromptTokens
|
||||
totalUsage.CompletionTokens += resp.Usage.CompletionTokens
|
||||
totalUsage.TotalTokens += resp.Usage.TotalTokens
|
||||
totalUsage.ThinkingTokens += resp.Usage.ThinkingTokens
|
||||
}
|
||||
|
||||
// No tool calls → done
|
||||
@@ -595,9 +606,10 @@ func (l *Loop) runLoop(ctx context.Context, req RunRequest) (*RunResult, error)
|
||||
|
||||
// Build assistant message with tool calls
|
||||
assistantMsg := providers.Message{
|
||||
Role: "assistant",
|
||||
Content: resp.Content,
|
||||
ToolCalls: resp.ToolCalls,
|
||||
Role: "assistant",
|
||||
Content: resp.Content,
|
||||
ToolCalls: resp.ToolCalls,
|
||||
RawAssistantContent: resp.RawAssistantContent, // preserve thinking blocks for Anthropic passback
|
||||
}
|
||||
messages = append(messages, assistantMsg)
|
||||
pendingMsgs = append(pendingMsgs, assistantMsg)
|
||||
|
||||
Reference in new issue
Block a user