fix: format code with golines to pass linter checks
Fixed formatting issues in three files to comply with golines requirements: - pkg/agent/loop.go: Split long function calls and logger statements - pkg/config/config.go: Align struct field tags - pkg/tools/toolloop.go: Split long function calls Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
aca03f5df7
commit
2cb05975bf
3 changed files with 153 additions and 41 deletions
|
|
@ -163,7 +163,10 @@ func registerSharedTools(
|
|||
|
||||
if cfg.Tools.IsToolEnabled("web") {
|
||||
searchTool, err := tools.NewWebSearchTool(tools.WebSearchToolOptions{
|
||||
BraveAPIKeys: config.MergeAPIKeys(cfg.Tools.Web.Brave.APIKey(), cfg.Tools.Web.Brave.APIKeys()),
|
||||
BraveAPIKeys: config.MergeAPIKeys(
|
||||
cfg.Tools.Web.Brave.APIKey(),
|
||||
cfg.Tools.Web.Brave.APIKeys(),
|
||||
),
|
||||
BraveMaxResults: cfg.Tools.Web.Brave.MaxResults,
|
||||
BraveEnabled: cfg.Tools.Web.Brave.Enabled,
|
||||
TavilyAPIKeys: config.MergeAPIKeys(
|
||||
|
|
@ -196,7 +199,11 @@ func registerSharedTools(
|
|||
Proxy: cfg.Tools.Web.Proxy,
|
||||
})
|
||||
if err != nil {
|
||||
logger.ErrorCF("agent", "Failed to create web search tool", map[string]any{"error": err.Error()})
|
||||
logger.ErrorCF(
|
||||
"agent",
|
||||
"Failed to create web search tool",
|
||||
map[string]any{"error": err.Error()},
|
||||
)
|
||||
} else if searchTool != nil {
|
||||
agent.Tools.Register(searchTool)
|
||||
}
|
||||
|
|
@ -209,7 +216,11 @@ func registerSharedTools(
|
|||
cfg.Tools.Web.FetchLimitBytes,
|
||||
cfg.Tools.Web.PrivateHostWhitelist)
|
||||
if err != nil {
|
||||
logger.ErrorCF("agent", "Failed to create web fetch tool", map[string]any{"error": err.Error()})
|
||||
logger.ErrorCF(
|
||||
"agent",
|
||||
"Failed to create web fetch tool",
|
||||
map[string]any{"error": err.Error()},
|
||||
)
|
||||
} else {
|
||||
agent.Tools.Register(fetchTool)
|
||||
}
|
||||
|
|
@ -285,7 +296,14 @@ func registerSharedTools(
|
|||
}
|
||||
|
||||
// Team tool
|
||||
teamSubagentManager := tools.NewSubagentManager(provider, agent.Model, agent.Candidates, agent.Workspace, cfg.Tools.Team, msgBus)
|
||||
teamSubagentManager := tools.NewSubagentManager(
|
||||
provider,
|
||||
agent.Model,
|
||||
agent.Candidates,
|
||||
agent.Workspace,
|
||||
cfg.Tools.Team,
|
||||
msgBus,
|
||||
)
|
||||
teamSubagentManager.SetLLMOptions(agent.MaxTokens, agent.Temperature)
|
||||
|
||||
teamTool := tools.NewTeamTool(teamSubagentManager, cfg)
|
||||
|
|
@ -492,7 +510,12 @@ func (al *AgentLoop) Run(ctx context.Context) error {
|
|||
"queue_depth": al.pendingSteeringCountForScope(target.SessionKey),
|
||||
})
|
||||
|
||||
continued, continueErr := al.Continue(ctx, target.SessionKey, target.Channel, target.ChatID)
|
||||
continued, continueErr := al.Continue(
|
||||
ctx,
|
||||
target.SessionKey,
|
||||
target.Channel,
|
||||
target.ChatID,
|
||||
)
|
||||
if continueErr != nil {
|
||||
logger.WarnCF("agent", "Failed to continue queued steering",
|
||||
map[string]any{
|
||||
|
|
@ -520,14 +543,22 @@ func (al *AgentLoop) Run(ctx context.Context) error {
|
|||
"queue_depth": al.pendingSteeringCountForScope(target.SessionKey),
|
||||
})
|
||||
|
||||
continued, continueErr := al.Continue(ctx, target.SessionKey, target.Channel, target.ChatID)
|
||||
continued, continueErr := al.Continue(
|
||||
ctx,
|
||||
target.SessionKey,
|
||||
target.Channel,
|
||||
target.ChatID,
|
||||
)
|
||||
if continueErr != nil {
|
||||
logger.WarnCF("agent", "Failed to continue queued steering after shutdown drain",
|
||||
logger.WarnCF(
|
||||
"agent",
|
||||
"Failed to continue queued steering after shutdown drain",
|
||||
map[string]any{
|
||||
"channel": target.Channel,
|
||||
"chat_id": target.ChatID,
|
||||
"error": continueErr.Error(),
|
||||
})
|
||||
},
|
||||
)
|
||||
return
|
||||
}
|
||||
if continued == "" {
|
||||
|
|
@ -586,11 +617,15 @@ func (al *AgentLoop) drainBusToSteering(ctx context.Context, activeScope, active
|
|||
msgScope, _, scopeOK := al.resolveSteeringTarget(msg)
|
||||
if !scopeOK || msgScope != activeScope {
|
||||
if err := al.requeueInboundMessage(msg); err != nil {
|
||||
logger.WarnCF("agent", "Failed to requeue non-steering inbound message", map[string]any{
|
||||
"error": err.Error(),
|
||||
"channel": msg.Channel,
|
||||
"sender_id": msg.SenderID,
|
||||
})
|
||||
logger.WarnCF(
|
||||
"agent",
|
||||
"Failed to requeue non-steering inbound message",
|
||||
map[string]any{
|
||||
"error": err.Error(),
|
||||
"channel": msg.Channel,
|
||||
"sender_id": msg.SenderID,
|
||||
},
|
||||
)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
|
@ -624,7 +659,10 @@ func (al *AgentLoop) Stop() {
|
|||
al.running.Store(false)
|
||||
}
|
||||
|
||||
func (al *AgentLoop) publishResponseIfNeeded(ctx context.Context, channel, chatID, response string) {
|
||||
func (al *AgentLoop) publishResponseIfNeeded(
|
||||
ctx context.Context,
|
||||
channel, chatID, response string,
|
||||
) {
|
||||
if response == "" {
|
||||
return
|
||||
}
|
||||
|
|
@ -1074,7 +1112,10 @@ var audioAnnotationRe = regexp.MustCompile(`\[(voice|audio)(?::[^\]]*)?\]`)
|
|||
// transcribeAudioInMessage resolves audio media refs, transcribes them, and
|
||||
// replaces audio annotations in msg.Content with the transcribed text.
|
||||
// Returns the (possibly modified) message and true if audio was transcribed.
|
||||
func (al *AgentLoop) transcribeAudioInMessage(ctx context.Context, msg bus.InboundMessage) (bus.InboundMessage, bool) {
|
||||
func (al *AgentLoop) transcribeAudioInMessage(
|
||||
ctx context.Context,
|
||||
msg bus.InboundMessage,
|
||||
) (bus.InboundMessage, bool) {
|
||||
if al.transcriber == nil || al.mediaStore == nil || len(msg.Media) == 0 {
|
||||
return msg, false
|
||||
}
|
||||
|
|
@ -1084,7 +1125,11 @@ func (al *AgentLoop) transcribeAudioInMessage(ctx context.Context, msg bus.Inbou
|
|||
for _, ref := range msg.Media {
|
||||
path, meta, err := al.mediaStore.ResolveWithMeta(ref)
|
||||
if err != nil {
|
||||
logger.WarnCF("voice", "Failed to resolve media ref", map[string]any{"ref": ref, "error": err})
|
||||
logger.WarnCF(
|
||||
"voice",
|
||||
"Failed to resolve media ref",
|
||||
map[string]any{"ref": ref, "error": err},
|
||||
)
|
||||
continue
|
||||
}
|
||||
if !utils.IsAudioFile(meta.Filename, meta.ContentType) {
|
||||
|
|
@ -1162,7 +1207,11 @@ func (al *AgentLoop) sendTranscriptionFeedback(
|
|||
ReplyToMessageID: messageID,
|
||||
})
|
||||
if err != nil {
|
||||
logger.WarnCF("voice", "Failed to send transcription feedback", map[string]any{"error": err.Error()})
|
||||
logger.WarnCF(
|
||||
"voice",
|
||||
"Failed to send transcription feedback",
|
||||
map[string]any{"error": err.Error()},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1362,7 +1411,9 @@ func (al *AgentLoop) processMessage(ctx context.Context, msg bus.InboundMessage)
|
|||
return al.runAgentLoop(ctx, agent, opts)
|
||||
}
|
||||
|
||||
func (al *AgentLoop) resolveMessageRoute(msg bus.InboundMessage) (routing.ResolvedRoute, *AgentInstance, error) {
|
||||
func (al *AgentLoop) resolveMessageRoute(
|
||||
msg bus.InboundMessage,
|
||||
) (routing.ResolvedRoute, *AgentInstance, error) {
|
||||
registry := al.GetRegistry()
|
||||
route := registry.ResolveRoute(routing.RouteInput{
|
||||
Channel: msg.Channel,
|
||||
|
|
@ -1378,7 +1429,10 @@ func (al *AgentLoop) resolveMessageRoute(msg bus.InboundMessage) (routing.Resolv
|
|||
agent = registry.GetDefaultAgent()
|
||||
}
|
||||
if agent == nil {
|
||||
return routing.ResolvedRoute{}, nil, fmt.Errorf("no agent available for route (agent_id=%s)", route.AgentID)
|
||||
return routing.ResolvedRoute{}, nil, fmt.Errorf(
|
||||
"no agent available for route (agent_id=%s)",
|
||||
route.AgentID,
|
||||
)
|
||||
}
|
||||
|
||||
return route, agent, nil
|
||||
|
|
@ -2579,12 +2633,15 @@ turnLoop:
|
|||
}
|
||||
|
||||
if steerMsgs := al.dequeueSteeringMessagesForScope(ts.sessionKey); len(steerMsgs) > 0 {
|
||||
logger.InfoCF("agent", "Steering arrived after turn completion; continuing turn before finalizing",
|
||||
logger.InfoCF(
|
||||
"agent",
|
||||
"Steering arrived after turn completion; continuing turn before finalizing",
|
||||
map[string]any{
|
||||
"agent_id": ts.agent.ID,
|
||||
"steering_count": len(steerMsgs),
|
||||
"session_key": ts.sessionKey,
|
||||
})
|
||||
},
|
||||
)
|
||||
pendingMessages = append(pendingMessages, steerMsgs...)
|
||||
finalContent = ""
|
||||
goto turnLoop
|
||||
|
|
@ -2701,11 +2758,18 @@ func (al *AgentLoop) selectCandidates(
|
|||
"score": score,
|
||||
"threshold": agent.Router.Threshold(),
|
||||
})
|
||||
return agent.LightCandidates, resolvedCandidateModel(agent.LightCandidates, agent.Router.LightModel())
|
||||
return agent.LightCandidates, resolvedCandidateModel(
|
||||
agent.LightCandidates,
|
||||
agent.Router.LightModel(),
|
||||
)
|
||||
}
|
||||
|
||||
// maybeSummarize triggers summarization if the session history exceeds thresholds.
|
||||
func (al *AgentLoop) maybeSummarize(agent *AgentInstance, sessionKey string, turnScope turnEventScope) {
|
||||
func (al *AgentLoop) maybeSummarize(
|
||||
agent *AgentInstance,
|
||||
sessionKey string,
|
||||
turnScope turnEventScope,
|
||||
) {
|
||||
newHistory := agent.Sessions.GetHistory(sessionKey)
|
||||
tokenEstimate := al.estimateTokens(newHistory)
|
||||
threshold := agent.ContextWindow * agent.SummarizeTokenPercent / 100
|
||||
|
|
@ -2739,7 +2803,10 @@ type compressionResult struct {
|
|||
// prompt is built dynamically by BuildMessages and is NOT stored here.
|
||||
// The compression note is recorded in the session summary so that
|
||||
// BuildMessages can include it in the next system prompt.
|
||||
func (al *AgentLoop) forceCompression(agent *AgentInstance, sessionKey string) (compressionResult, bool) {
|
||||
func (al *AgentLoop) forceCompression(
|
||||
agent *AgentInstance,
|
||||
sessionKey string,
|
||||
) (compressionResult, bool) {
|
||||
history := agent.Sessions.GetHistory(sessionKey)
|
||||
if len(history) <= 2 {
|
||||
return compressionResult{}, false
|
||||
|
|
@ -2892,7 +2959,11 @@ func formatToolsForLog(toolDefs []providers.ToolDefinition) string {
|
|||
}
|
||||
|
||||
// summarizeSession summarizes the conversation history for a session.
|
||||
func (al *AgentLoop) summarizeSession(agent *AgentInstance, sessionKey string, turnScope turnEventScope) {
|
||||
func (al *AgentLoop) summarizeSession(
|
||||
agent *AgentInstance,
|
||||
sessionKey string,
|
||||
turnScope turnEventScope,
|
||||
) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
|
||||
defer cancel()
|
||||
|
||||
|
|
@ -3180,7 +3251,10 @@ func (al *AgentLoop) handleCommand(
|
|||
}
|
||||
}
|
||||
|
||||
func (al *AgentLoop) buildCommandsRuntime(agent *AgentInstance, opts *processOptions) *commands.Runtime {
|
||||
func (al *AgentLoop) buildCommandsRuntime(
|
||||
agent *AgentInstance,
|
||||
opts *processOptions,
|
||||
) *commands.Runtime {
|
||||
registry := al.GetRegistry()
|
||||
cfg := al.GetConfig()
|
||||
rt := &commands.Runtime{
|
||||
|
|
@ -3221,7 +3295,10 @@ func (al *AgentLoop) buildCommandsRuntime(agent *AgentInstance, opts *processOpt
|
|||
}
|
||||
if agent != nil {
|
||||
rt.GetModelInfo = func() (string, string) {
|
||||
return agent.Model, resolvedCandidateProvider(agent.Candidates, cfg.Agents.Defaults.Provider)
|
||||
return agent.Model, resolvedCandidateProvider(
|
||||
agent.Candidates,
|
||||
cfg.Agents.Defaults.Provider,
|
||||
)
|
||||
}
|
||||
rt.SwitchModel = func(value string) (string, error) {
|
||||
value = strings.TrimSpace(value)
|
||||
|
|
@ -3235,7 +3312,12 @@ func (al *AgentLoop) buildCommandsRuntime(agent *AgentInstance, opts *processOpt
|
|||
return "", fmt.Errorf("failed to initialize model %q: %w", value, err)
|
||||
}
|
||||
|
||||
nextCandidates := resolveModelCandidates(cfg, cfg.Agents.Defaults.Provider, modelCfg.Model, agent.Fallbacks)
|
||||
nextCandidates := resolveModelCandidates(
|
||||
cfg,
|
||||
cfg.Agents.Defaults.Provider,
|
||||
modelCfg.Model,
|
||||
agent.Fallbacks,
|
||||
)
|
||||
if len(nextCandidates) == 0 {
|
||||
return "", fmt.Errorf("model %q did not resolve to any provider candidates", value)
|
||||
}
|
||||
|
|
@ -3324,7 +3406,10 @@ func (al *AgentLoop) applyExplicitSkillCommand(
|
|||
|
||||
canonicalSkill, ok := agent.ContextBuilder.ResolveSkillName(fields[1])
|
||||
if !ok {
|
||||
return true, true, fmt.Sprintf("Unknown skill: %s\nUse /list skills to see installed skills.", fields[1])
|
||||
return true, true, fmt.Sprintf(
|
||||
"Unknown skill: %s\nUse /list skills to see installed skills.",
|
||||
fields[1],
|
||||
)
|
||||
}
|
||||
|
||||
if len(fields) == 2 {
|
||||
|
|
|
|||
|
|
@ -1015,9 +1015,9 @@ func (c *ModelConfig) SetAPIKey(value string) {
|
|||
}
|
||||
|
||||
type GatewayConfig struct {
|
||||
Host string `json:"host" env:"PICOCLAW_GATEWAY_HOST"`
|
||||
Port int `json:"port" env:"PICOCLAW_GATEWAY_PORT"`
|
||||
HotReload bool `json:"hot_reload" env:"PICOCLAW_GATEWAY_HOT_RELOAD"`
|
||||
Host string `json:"host" env:"PICOCLAW_GATEWAY_HOST"`
|
||||
Port int `json:"port" env:"PICOCLAW_GATEWAY_PORT"`
|
||||
HotReload bool `json:"hot_reload" env:"PICOCLAW_GATEWAY_HOT_RELOAD"`
|
||||
// LogLevel controls the logging verbosity for the gateway server.
|
||||
// Valid values: "debug", "info", "warn", "error", "fatal" (default: "fatal")
|
||||
LogLevel string `json:"log_level,omitempty" env:"PICOCLAW_LOG_LEVEL"`
|
||||
|
|
@ -1395,7 +1395,10 @@ func LoadConfig(path string) (*Config, error) {
|
|||
var cfg *Config
|
||||
switch versionInfo.Version {
|
||||
case 0:
|
||||
logger.InfoF("config migrate start", map[string]any{"from": versionInfo.Version, "to": CurrentVersion})
|
||||
logger.InfoF(
|
||||
"config migrate start",
|
||||
map[string]any{"from": versionInfo.Version, "to": CurrentVersion},
|
||||
)
|
||||
// Legacy config (no version field)
|
||||
v, e := loadConfigV0(data)
|
||||
if e != nil {
|
||||
|
|
@ -1403,10 +1406,16 @@ func LoadConfig(path string) (*Config, error) {
|
|||
}
|
||||
cfg, e = v.Migrate()
|
||||
if e != nil {
|
||||
logger.DebugF("config migrate fail", map[string]any{"from": versionInfo.Version, "to": CurrentVersion})
|
||||
logger.DebugF(
|
||||
"config migrate fail",
|
||||
map[string]any{"from": versionInfo.Version, "to": CurrentVersion},
|
||||
)
|
||||
return nil, e
|
||||
}
|
||||
logger.DebugF("config migrate success", map[string]any{"from": versionInfo.Version, "to": CurrentVersion})
|
||||
logger.DebugF(
|
||||
"config migrate success",
|
||||
map[string]any{"from": versionInfo.Version, "to": CurrentVersion},
|
||||
)
|
||||
defer func() {
|
||||
_ = SaveConfig(path, cfg)
|
||||
}()
|
||||
|
|
@ -1437,9 +1446,11 @@ func LoadConfig(path string) (*Config, error) {
|
|||
for _, m := range cfg.ModelList {
|
||||
for _, k := range m.apiKeys {
|
||||
if k != "" && !strings.HasPrefix(k, "enc://") && !strings.HasPrefix(k, "file://") {
|
||||
fmt.Fprintf(os.Stderr,
|
||||
fmt.Fprintf(
|
||||
os.Stderr,
|
||||
"picoclaw: warning: model %q has a plaintext api_key; call SaveConfig to encrypt it\n",
|
||||
m.ModelName)
|
||||
m.ModelName,
|
||||
)
|
||||
break // Only warn once per model
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,13 @@ func RunToolLoop(
|
|||
llmOpts = map[string]any{}
|
||||
}
|
||||
// 3. Call LLM
|
||||
response, err := config.Provider.Chat(ctx, messages, providerToolDefs, config.Model, llmOpts)
|
||||
response, err := config.Provider.Chat(
|
||||
ctx,
|
||||
messages,
|
||||
providerToolDefs,
|
||||
config.Model,
|
||||
llmOpts,
|
||||
)
|
||||
if err != nil {
|
||||
logger.ErrorCF("toolloop", "LLM call failed",
|
||||
map[string]any{
|
||||
|
|
@ -119,8 +125,11 @@ func RunToolLoop(
|
|||
// 3.6 Truncation Recovery: LLM response was cut off (max_tokens hit or malformed JSON).
|
||||
// Inject a recovery message so the LLM knows to retry with a shorter, complete response.
|
||||
if response.FinishReason == "truncated" {
|
||||
logger.WarnCF("toolloop", "LLM response was truncated (max_tokens hit), injecting recovery message",
|
||||
map[string]any{"iteration": iteration})
|
||||
logger.WarnCF(
|
||||
"toolloop",
|
||||
"LLM response was truncated (max_tokens hit), injecting recovery message",
|
||||
map[string]any{"iteration": iteration},
|
||||
)
|
||||
messages = append(messages, providers.Message{
|
||||
Role: "assistant",
|
||||
Content: response.Content,
|
||||
|
|
@ -233,7 +242,14 @@ func RunToolLoop(
|
|||
|
||||
var toolResult *ToolResult
|
||||
if config.Tools != nil {
|
||||
toolResult = config.Tools.ExecuteWithContext(ctx, tc.Name, tc.Arguments, channel, chatID, nil)
|
||||
toolResult = config.Tools.ExecuteWithContext(
|
||||
ctx,
|
||||
tc.Name,
|
||||
tc.Arguments,
|
||||
channel,
|
||||
chatID,
|
||||
nil,
|
||||
)
|
||||
} else {
|
||||
toolResult = ErrorResult("No tools available")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue