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.