Merge pull request #46 from hobbyistlabs-coder/feat/error-categorization-logging-10686897873219792435

feat: Implement error categorization for agent loop observability
This commit is contained in:
hobbyistlabs-coder 2026-03-17 17:11:06 -04:00 committed by GitHub
commit 7733e5c61d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 21 additions and 4 deletions

View file

@ -33,7 +33,7 @@ This document outlines a series of tasks to improve the main loop of the agentic
## Phase 5: Observability & Logging Dashboard ## Phase 5: Observability & Logging Dashboard
* [ ] **Session Replay:** Capture the full "Chain of Thought" (CoT), including tool-call inputs/outputs, and state transitions to facilitate deep-dive session reviews. * [ ] **Session Replay:** Capture the full "Chain of Thought" (CoT), including tool-call inputs/outputs, and state transitions to facilitate deep-dive session reviews.
* [ ] **Error Categorization:** Distinguish between Model Failures (hallucinations/refusals), Infrastructure Failures (API timeouts), and Logic Failures (code execution errors). * [x] **Error Categorization:** Distinguish between Model Failures (hallucinations/refusals), Infrastructure Failures (API timeouts), and Logic Failures (code execution errors).
* [ ] **Real-time Visuals:** Implement a lightweight UI/Dashboard using a Go-compatible framework like a custom Bubble Tea TUI to monitor the agent's health. * [ ] **Real-time Visuals:** Implement a lightweight UI/Dashboard using a Go-compatible framework like a custom Bubble Tea TUI to monitor the agent's health.
--- ---

View file

@ -142,11 +142,19 @@ func (al *AgentLoop) executeLLMWithRetry(
} }
if err != nil { if err != nil {
errorCategory := "infrastructure_failure"
if failErr := providers.ClassifyError(err, agent.ID, activeModel); failErr != nil {
if failErr.Reason == providers.FailoverFormat || failErr.Reason == providers.FailoverContextLength {
errorCategory = "model_failure"
}
}
logger.ErrorCF("agent", "LLM call failed", logger.ErrorCF("agent", "LLM call failed",
map[string]any{ map[string]any{
"agent_id": agent.ID, "agent_id": agent.ID,
"iteration": iteration, "iteration": iteration,
"error": err.Error(), "error": err.Error(),
"error_category": errorCategory,
}) })
return nil, fmt.Errorf("LLM call failed after retries: %w", err) return nil, fmt.Errorf("LLM call failed after retries: %w", err)
} }

View file

@ -361,6 +361,15 @@ func (al *AgentLoop) runLLMIteration(
contentForLLM = r.result.Err.Error() contentForLLM = r.result.Err.Error()
} }
if r.result.IsError {
logger.ErrorCF("agent", "Tool execution failed",
map[string]any{
"tool": r.tc.Name,
"error": contentForLLM,
"error_category": "logic_failure",
})
}
toolResultMsg := providers.Message{ toolResultMsg := providers.Message{
Role: "tool", Role: "tool",
Content: contentForLLM, Content: contentForLLM,