Skip to content

Commit 062d9c3

Browse files
mattgodboltclaude
andcommitted
Add cached field to response and improve metrics
- Add 'cached' boolean field to ExplainResponse to indicate cache hits - Fix get_cached_response to properly mark responses as cached - Add metrics to distinguish cached vs fresh responses: - ClaudeExplainCachedResponse for cache hits - ClaudeExplainFreshResponse for API calls - 'cached' property on all requests for filtering - Update documentation to show cached field in response This allows monitoring cache effectiveness and helps users understand when responses are served from cache. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 9cbbc6e commit 062d9c3

File tree

6 files changed

+16
-2
lines changed

6 files changed

+16
-2
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ uv run ruff format
142142
"input_cost": 0.000123,
143143
"output_cost": 0.000456,
144144
"total_cost": 0.000579
145-
}
145+
},
146+
"cached": false
146147
}
147148
```
148149

app/cache.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,10 @@ async def get_cached_response(
185185

186186
try:
187187
# Convert cached dict back to ExplainResponse
188-
return ExplainResponse(**cached_data)
188+
response = ExplainResponse(**cached_data)
189+
# Mark this response as cached
190+
response.cached = True
191+
return response
189192
except Exception as e:
190193
LOGGER.warning(f"Error deserializing cached response: {e}")
191194
return None

app/explain.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ async def process_request(
5050
metrics_provider.set_property("language", body.language)
5151
metrics_provider.set_property("compiler", body.compiler)
5252
metrics_provider.set_property("instructionSet", body.instructionSet or "unknown")
53+
metrics_provider.set_property("cached", "true")
5354
metrics_provider.put_metric("ClaudeExplainRequest", 1)
55+
metrics_provider.put_metric("ClaudeExplainCachedResponse", 1)
5456

5557
return cached_response
5658

@@ -107,7 +109,9 @@ async def _call_anthropic_api(
107109
metrics_provider.set_property("language", body.language)
108110
metrics_provider.set_property("compiler", body.compiler)
109111
metrics_provider.set_property("instructionSet", body.instructionSet or "unknown")
112+
metrics_provider.set_property("cached", "false")
110113
metrics_provider.put_metric("ClaudeExplainRequest", 1)
114+
metrics_provider.put_metric("ClaudeExplainFreshResponse", 1)
111115

112116
# Track token usage
113117
metrics_provider.put_metric("ClaudeExplainInputTokens", input_tokens)
@@ -129,4 +133,5 @@ async def _call_anthropic_api(
129133
output_cost=round(output_cost, 6),
130134
total_cost=round(total_cost, 6),
131135
),
136+
cached=False, # This is a fresh response from the API
132137
)

app/explain_api.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ class ExplainResponse(BaseModel):
8484
model: str | None = Field(None, description="The Claude model used")
8585
usage: TokenUsage | None = Field(None, description="Token usage information")
8686
cost: CostBreakdown | None = Field(None, description="Cost breakdown")
87+
cached: bool = Field(default=False, description="Whether this response was served from cache")
8788

8889

8990
class ExplainErrorResponse(BaseModel):

app/test_cache.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ async def test_get_cached_response_cache_hit(self, sample_request, test_prompt,
292292
assert result is not None
293293
assert result.status == "success"
294294
assert result.explanation == "This function implements a square operation..."
295+
assert result.cached is True
295296
mock_cache.get.assert_called_once()
296297

297298
@pytest.mark.asyncio

app/test_explain.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ async def test_process_request_success(self, sample_request, mock_anthropic_clie
102102
assert isinstance(response.cost.output_cost, float)
103103
assert isinstance(response.cost.total_cost, float)
104104

105+
# Check cached flag
106+
assert response.cached is False # Should not be cached on first request
107+
105108
# Verify the mock was called correctly
106109
mock_anthropic_client.messages.create.assert_called_once()
107110
args, kwargs = mock_anthropic_client.messages.create.call_args

0 commit comments

Comments
 (0)