From 7fe4deff0d90de4591e0b4ec15f96bc4b020c85d Mon Sep 17 00:00:00 2001 From: A Magno Date: Mon, 2 Mar 2026 14:16:13 +0100 Subject: [PATCH] perf: align with readme-magno optimizations (timestamp, cache logging) - Change system prompt timestamp to daily-only format (was HH:MM, invalidating dynamic block every minute unnecessarily) - Add CacheCreatedTokens and CacheReadTokens to UsageInfo - Extract Anthropic cache_creation/cache_read tokens in parseResponse - Log cache hit/miss stats per session for cost monitoring Made-with: Cursor --- pkg/agent/context.go | 2 +- pkg/agent/loop.go | 16 ++++++++++------ pkg/providers/anthropic/provider.go | 8 +++++--- pkg/providers/protocoltypes/types.go | 8 +++++--- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/pkg/agent/context.go b/pkg/agent/context.go index ab9c36d05..583377272 100644 --- a/pkg/agent/context.go +++ b/pkg/agent/context.go @@ -367,7 +367,7 @@ func (cb *ContextBuilder) LoadBootstrapFiles() string { // See: https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching // See: https://platform.openai.com/docs/guides/prompt-caching func (cb *ContextBuilder) buildDynamicContext(channel, chatID string) string { - now := time.Now().Format("2006-01-02 15:04 (Monday)") + now := time.Now().Format("2006-01-02 (Monday)") rt := fmt.Sprintf("%s %s, Go %s", runtime.GOOS, runtime.GOARCH, runtime.Version()) var sb strings.Builder diff --git a/pkg/agent/loop.go b/pkg/agent/loop.go index 973a1a45a..0b405586c 100644 --- a/pkg/agent/loop.go +++ b/pkg/agent/loop.go @@ -661,7 +661,7 @@ func (al *AgentLoop) runLLMIteration( ) (string, int, error) { iteration := 0 var finalContent string - var totalInputTokens, totalOutputTokens int + var totalInputTokens, totalOutputTokens, totalCacheCreated, totalCacheRead int for iteration < agent.MaxIterations { iteration++ @@ -809,6 +809,8 @@ func (al *AgentLoop) runLLMIteration( if response.Usage != nil { totalInputTokens += response.Usage.PromptTokens totalOutputTokens += response.Usage.CompletionTokens + totalCacheCreated += response.Usage.CacheCreatedTokens + totalCacheRead += response.Usage.CacheReadTokens } logger.DebugCF("agent", "LLM response", @@ -988,11 +990,13 @@ func (al *AgentLoop) runLLMIteration( if totalInputTokens > 0 || totalOutputTokens > 0 { logger.InfoCF("agent", "Session token usage", map[string]any{ - "agent_id": agent.ID, - "iterations": iteration, - "input_tokens": totalInputTokens, - "output_tokens": totalOutputTokens, - "total_tokens": totalInputTokens + totalOutputTokens, + "agent_id": agent.ID, + "iterations": iteration, + "input_tokens": totalInputTokens, + "output_tokens": totalOutputTokens, + "total_tokens": totalInputTokens + totalOutputTokens, + "cache_created": totalCacheCreated, + "cache_read": totalCacheRead, }) } diff --git a/pkg/providers/anthropic/provider.go b/pkg/providers/anthropic/provider.go index 1f77f16b8..1c8dfc563 100644 --- a/pkg/providers/anthropic/provider.go +++ b/pkg/providers/anthropic/provider.go @@ -303,9 +303,11 @@ func parseResponse(resp *anthropic.Message) *LLMResponse { ToolCalls: toolCalls, FinishReason: finishReason, Usage: &UsageInfo{ - PromptTokens: int(resp.Usage.InputTokens), - CompletionTokens: int(resp.Usage.OutputTokens), - TotalTokens: int(resp.Usage.InputTokens + resp.Usage.OutputTokens), + PromptTokens: int(resp.Usage.InputTokens), + CompletionTokens: int(resp.Usage.OutputTokens), + TotalTokens: int(resp.Usage.InputTokens + resp.Usage.OutputTokens), + CacheCreatedTokens: int(resp.Usage.CacheCreationInputTokens), + CacheReadTokens: int(resp.Usage.CacheReadInputTokens), }, } } diff --git a/pkg/providers/protocoltypes/types.go b/pkg/providers/protocoltypes/types.go index 99f13334e..e3ce5edd5 100644 --- a/pkg/providers/protocoltypes/types.go +++ b/pkg/providers/protocoltypes/types.go @@ -42,9 +42,11 @@ type ReasoningDetail struct { } type UsageInfo struct { - PromptTokens int `json:"prompt_tokens"` - CompletionTokens int `json:"completion_tokens"` - TotalTokens int `json:"total_tokens"` + PromptTokens int `json:"prompt_tokens"` + CompletionTokens int `json:"completion_tokens"` + TotalTokens int `json:"total_tokens"` + CacheCreatedTokens int `json:"cache_created_tokens,omitempty"` + CacheReadTokens int `json:"cache_read_tokens,omitempty"` } // CacheControl marks a content block for LLM-side prefix caching.