Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/amplifier_agent_http/_wire.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ def stop_chunk(
completion_tokens: int = 0,
cached_tokens: int = 0,
cost_usd: str | None = None,
total_nano_aiu: int | None = None,
include_usage: bool = True,
) -> dict[str, Any]:
"""Final chunk -- empty delta, finish_reason: stop, optional usage block.
Expand All @@ -206,6 +207,8 @@ def stop_chunk(
cached_tokens=cached_tokens,
cost_usd=cost_usd,
)
if total_nano_aiu is not None:
chunk["copilot_usage"] = {"total_nano_aiu": total_nano_aiu}
return chunk


Expand Down Expand Up @@ -262,6 +265,7 @@ def tool_calls_stop_chunk(
completion_tokens: int = 0,
cached_tokens: int = 0,
cost_usd: str | None = None,
total_nano_aiu: int | None = None,
include_usage: bool = True,
) -> dict[str, Any]:
"""Terminal chunk for a turn that ends with host-delegated tool calls.
Expand All @@ -287,6 +291,8 @@ def tool_calls_stop_chunk(
cached_tokens=cached_tokens,
cost_usd=cost_usd,
)
if total_nano_aiu is not None:
chunk["copilot_usage"] = {"total_nano_aiu": total_nano_aiu}
return chunk


Expand Down
12 changes: 11 additions & 1 deletion src/amplifier_agent_http/routes/chat_completions.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import logging
import time
from collections.abc import AsyncGenerator
from decimal import Decimal, InvalidOperation
from decimal import ROUND_HALF_UP, Decimal, InvalidOperation
from typing import Any

from fastapi import APIRouter, Depends, HTTPException, Request, status
Expand Down Expand Up @@ -427,6 +427,14 @@ async def _stream_chat_completion(
# runs the tool host-side, then re-POSTs.
# - "stop" for the normal end-of-turn path (with or without text).
cost_str_final: str | None = str(usage_cost) if usage_cost is not None else None
# opencode reads a top-level copilot_usage.total_nano_aiu and overrides its
# own token x rate cost estimate with total_nano_aiu / 1e11, so emitting
# round(cost_usd * 1e11) makes its displayed cost exactly cost_usd.
total_nano_aiu: int | None = (
int((usage_cost * Decimal(10**11)).to_integral_value(rounding=ROUND_HALF_UP))
if usage_cost is not None
else None
)
if finish_reason_tool_calls:
yield sse_data(
tool_calls_stop_chunk(
Expand All @@ -436,6 +444,7 @@ async def _stream_chat_completion(
completion_tokens=usage_completion,
cached_tokens=usage_cached,
cost_usd=cost_str_final,
total_nano_aiu=total_nano_aiu,
include_usage=True,
)
)
Expand All @@ -448,6 +457,7 @@ async def _stream_chat_completion(
completion_tokens=usage_completion,
cached_tokens=usage_cached,
cost_usd=cost_str_final,
total_nano_aiu=total_nano_aiu,
include_usage=True,
)
)
Expand Down
Loading