Handle /cost command - show session cost. Args: args: Command arguments context: Command context Returns: LocalCommandResult
(args: str, context: CommandContext)
| 275 | |
| 276 | |
| 277 | def cost_command_call(args: str, context: CommandContext) -> LocalCommandResult: |
| 278 | """ |
| 279 | Handle /cost command - show session cost. |
| 280 | |
| 281 | Args: |
| 282 | args: Command arguments |
| 283 | context: Command context |
| 284 | |
| 285 | Returns: |
| 286 | LocalCommandResult |
| 287 | """ |
| 288 | from src.bootstrap.state import get_model_usage, get_total_cost_usd |
| 289 | from src.services.pricing import format_cost_usd |
| 290 | |
| 291 | lines: list[str] = ["Session Cost:", ""] |
| 292 | lines.append(f" Total: {format_cost_usd(get_total_cost_usd())}") |
| 293 | |
| 294 | # Per-model token usage + prompt-cache hit-rate. ``cache_read_input_tokens`` |
| 295 | # is the cached portion of the prompt (DeepSeek hits, Anthropic cache |
| 296 | # reads); ``input_tokens`` + ``cache_creation_input_tokens`` is the |
| 297 | # uncached portion. Surfacing the hit-rate is what makes the DeepSeek |
| 298 | # prefix-cache savings visible. |
| 299 | model_usage = get_model_usage() |
| 300 | for model, u in sorted(model_usage.items()): |
| 301 | cached = int(getattr(u, "cache_read_input_tokens", 0) or 0) |
| 302 | uncached = int( |
| 303 | (getattr(u, "input_tokens", 0) or 0) |
| 304 | + (getattr(u, "cache_creation_input_tokens", 0) or 0) |
| 305 | ) |
| 306 | prompt_total = cached + uncached |
| 307 | hit_pct = (100.0 * cached / prompt_total) if prompt_total else 0.0 |
| 308 | lines.append("") |
| 309 | lines.append(f" {model} {format_cost_usd(u.cost_usd)}") |
| 310 | lines.append( |
| 311 | f" prompt {prompt_total:,} tok " |
| 312 | f"({cached:,} cached, {hit_pct:.0f}% hit) · " |
| 313 | f"output {int(getattr(u, 'output_tokens', 0) or 0):,} tok" |
| 314 | ) |
| 315 | |
| 316 | # Legacy free-form units/events (costHook ``/cost`` event log). |
| 317 | tracker = context.cost_tracker |
| 318 | if tracker is not None and (tracker.total_units or tracker.events): |
| 319 | lines.append("") |
| 320 | lines.append(f" Recorded units: {tracker.total_units}") |
| 321 | for event in tracker.events[-10:]: |
| 322 | lines.append(f" - {event}") |
| 323 | |
| 324 | return LocalCommandResult( |
| 325 | type="text", |
| 326 | value="\n".join(lines), |
| 327 | ) |
| 328 | |
| 329 | |
| 330 | def context_command_call(args: str, context: CommandContext) -> LocalCommandResult: |