refactor(providers): define typed usage contract

This commit is contained in:
chengyongru
2026-08-25 01:04:25 +08:00
committed by chengyongru
parent 89c94d8744
commit 9895c23cb5
84 changed files with 1643 additions and 726 deletions
+10 -9
View File
@@ -15,6 +15,7 @@ from nanobot.agent.tools.self import MyTool
from nanobot.agent.tools.shell import ExecToolConfig
from nanobot.agent.tools.web import WebSearchConfig, WebToolsConfig
from nanobot.config.schema import ModelPresetConfig
from nanobot.providers.base import LLMUsage
# ---------------------------------------------------------------------------
# Helpers
@@ -31,7 +32,7 @@ def _make_mock_loop(**overrides):
loop._start_time = 1000.0
loop.exec_config = ExecToolConfig()
loop.channels_config = MagicMock()
loop._last_usage = {"prompt_tokens": 100, "completion_tokens": 50}
loop._last_usage = LLMUsage.reported(input_tokens=100, output_tokens=50)
loop.last_usage = loop._last_usage
loop._current_iteration = 0
loop.current_iteration = loop._current_iteration
@@ -163,9 +164,9 @@ class TestInspectPathNavigation:
@pytest.mark.asyncio
async def test_inspect_dict_key_via_dotpath(self):
loop = _make_mock_loop()
loop._last_usage = {"prompt_tokens": 100, "completion_tokens": 50}
loop._last_usage = LLMUsage.reported(input_tokens=100, output_tokens=50)
tool = _make_tool(loop=loop)
result = await tool.execute(action="check", key="_last_usage.prompt_tokens")
result = await tool.execute(action="check", key="_last_usage.input_tokens")
assert "100" in result
@pytest.mark.asyncio
@@ -624,7 +625,7 @@ class TestSubagentStatusFormatting:
{"name": "grep", "status": "ok", "detail": "searched ERROR"},
{"name": "exec", "status": "error", "detail": "timeout"},
],
usage={"prompt_tokens": 4500, "completion_tokens": 1200},
usage=LLMUsage.reported(input_tokens=4500, output_tokens=1200),
)
result = MyTool._format_value(status)
assert "abc12345" in result
@@ -698,14 +699,14 @@ class TestSubagentHookStatus:
iteration=5,
messages=[],
tool_events=[{"name": "read_file", "status": "ok", "detail": "ok"}],
usage={"prompt_tokens": 100, "completion_tokens": 50},
usage=LLMUsage.reported(input_tokens=100, output_tokens=50),
)
await hook.after_iteration(context)
assert status.iteration == 5
assert len(status.tool_events) == 1
assert status.tool_events[0]["name"] == "read_file"
assert status.usage == {"prompt_tokens": 100, "completion_tokens": 50}
assert status.usage == LLMUsage.reported(input_tokens=100, output_tokens=50)
@pytest.mark.asyncio
async def test_after_iteration_with_error(self):
@@ -821,7 +822,7 @@ class TestInspectTaskStatuses:
phase="awaiting_tools",
iteration=2,
tool_events=[{"name": "read_file", "status": "ok", "detail": "ok"}],
usage={"prompt_tokens": 500, "completion_tokens": 100},
usage=LLMUsage.reported(input_tokens=500, output_tokens=100),
),
}
tool = _make_tool(loop=loop)
@@ -1127,12 +1128,12 @@ class TestLastUsageInSummary:
tool = _make_tool()
result = await tool.execute(action="check")
assert "_last_usage" in result
assert "prompt_tokens" in result
assert "input_tokens" in result
@pytest.mark.asyncio
async def test_last_usage_not_shown_when_empty(self):
loop = _make_mock_loop()
loop._last_usage = {}
loop._last_usage = None
loop.last_usage = loop._last_usage
tool = _make_tool(loop=loop)
result = await tool.execute(action="check")
+4 -4
View File
@@ -456,7 +456,7 @@ async def test_agent_loop_syncs_updated_max_iterations_before_run(tmp_path):
error=None,
tool_events=[],
messages=[],
usage={},
usage=None,
had_injections=False,
tools_used=[],
)
@@ -501,7 +501,7 @@ async def test_drain_pending_blocks_while_subagents_running(tmp_path):
error=None,
tool_events=[],
messages=[],
usage={},
usage=None,
had_injections=False,
tools_used=[],
provider_state=None,
@@ -587,7 +587,7 @@ async def test_drain_pending_no_block_when_no_subagents(tmp_path):
error=None,
tool_events=[],
messages=[],
usage={},
usage=None,
had_injections=False,
tools_used=[],
provider_state=None,
@@ -637,7 +637,7 @@ async def test_drain_pending_timeout(tmp_path):
error=None,
tool_events=[],
messages=[],
usage={},
usage=None,
had_injections=False,
tools_used=[],
provider_state=None,