mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix(acp): populate usage from top-level result fields
This commit is contained in:
parent
eaa21a8275
commit
f92298fe95
2 changed files with 39 additions and 0 deletions
|
|
@ -460,6 +460,14 @@ class HermesACPAgent(acp.Agent):
|
||||||
thought_tokens=usage_data.get("reasoning_tokens"),
|
thought_tokens=usage_data.get("reasoning_tokens"),
|
||||||
cached_read_tokens=usage_data.get("cached_tokens"),
|
cached_read_tokens=usage_data.get("cached_tokens"),
|
||||||
)
|
)
|
||||||
|
elif any(result.get(key) is not None for key in ("prompt_tokens", "completion_tokens", "total_tokens")):
|
||||||
|
usage = Usage(
|
||||||
|
input_tokens=result.get("prompt_tokens", 0),
|
||||||
|
output_tokens=result.get("completion_tokens", 0),
|
||||||
|
total_tokens=result.get("total_tokens", 0),
|
||||||
|
thought_tokens=result.get("reasoning_tokens"),
|
||||||
|
cached_read_tokens=result.get("cache_read_tokens"),
|
||||||
|
)
|
||||||
|
|
||||||
stop_reason = "cancelled" if state.cancel_event and state.cancel_event.is_set() else "end_turn"
|
stop_reason = "cancelled" if state.cancel_event and state.cancel_event.is_set() else "end_turn"
|
||||||
return PromptResponse(stop_reason=stop_reason, usage=usage)
|
return PromptResponse(stop_reason=stop_reason, usage=usage)
|
||||||
|
|
|
||||||
|
|
@ -410,6 +410,37 @@ class TestPrompt:
|
||||||
update = last_call[1].get("update") or last_call[0][1]
|
update = last_call[1].get("update") or last_call[0][1]
|
||||||
assert update.session_update == "agent_message_chunk"
|
assert update.session_update == "agent_message_chunk"
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_prompt_populates_usage_from_top_level_run_conversation_fields(self, agent):
|
||||||
|
"""ACP should map top-level token fields into PromptResponse.usage."""
|
||||||
|
new_resp = await agent.new_session(cwd=".")
|
||||||
|
state = agent.session_manager.get_session(new_resp.session_id)
|
||||||
|
|
||||||
|
state.agent.run_conversation = MagicMock(return_value={
|
||||||
|
"final_response": "usage attached",
|
||||||
|
"messages": [],
|
||||||
|
"prompt_tokens": 123,
|
||||||
|
"completion_tokens": 45,
|
||||||
|
"total_tokens": 168,
|
||||||
|
"reasoning_tokens": 7,
|
||||||
|
"cache_read_tokens": 11,
|
||||||
|
})
|
||||||
|
|
||||||
|
mock_conn = MagicMock(spec=acp.Client)
|
||||||
|
mock_conn.session_update = AsyncMock()
|
||||||
|
agent._conn = mock_conn
|
||||||
|
|
||||||
|
prompt = [TextContentBlock(type="text", text="show usage")]
|
||||||
|
resp = await agent.prompt(prompt=prompt, session_id=new_resp.session_id)
|
||||||
|
|
||||||
|
assert isinstance(resp, PromptResponse)
|
||||||
|
assert resp.usage is not None
|
||||||
|
assert resp.usage.input_tokens == 123
|
||||||
|
assert resp.usage.output_tokens == 45
|
||||||
|
assert resp.usage.total_tokens == 168
|
||||||
|
assert resp.usage.thought_tokens == 7
|
||||||
|
assert resp.usage.cached_read_tokens == 11
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_prompt_cancelled_returns_cancelled_stop_reason(self, agent):
|
async def test_prompt_cancelled_returns_cancelled_stop_reason(self, agent):
|
||||||
"""If cancel is called during prompt, stop_reason should be 'cancelled'."""
|
"""If cancel is called during prompt, stop_reason should be 'cancelled'."""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue