Ctrl K
ComunidadGuías…

tests/test_eval_usage.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""The eval's per-trial usage counts the replies the kernel dropped and the
empty-reply nudges, from a real task log."""

from __future__ import annotations

from pathlib import Path
from types import SimpleNamespace
from typing import Any

from evals.engine import subtask_events, trial_usage
from noeta.backends.stores.sqlite import SqliteStore
from noeta.core.agent import Agent
from noeta.core.client import Client
from noeta.core.runner import Runtime
from noeta.core.types import Message, ModelResponse, Thinking, Usage
from noeta.plugins.empty_reply import EmptyReply
from noeta.testing import ScriptedProvider, reply


async def _no_sleep(_: float) -> None:
    return None


async def test_trial_usage_counts_dropped_replies_and_nudges(tmp_path: Path) -> None:
    cut = ModelResponse(message=Message(role="assistant", content=[Thinking(text="hmm")]),
                        stop_reason="max_tokens", usage=Usage(uncached=10, output=7))
    provider = ScriptedProvider([cut, reply(""), reply("hi"), reply(""), reply("")])
    store = SqliteStore(str(tmp_path / "t.db"))
    agent = Agent(name="a", model="m", extensions=[EmptyReply()])
    rt = Runtime(store=store, agents={"a": agent}, provider_for=lambda _m: provider,
                 env_for=lambda _s: None,  # type: ignore[arg-type,return-value]
                 sleep=_no_sleep)
    client = Client(store)
    tid = await client.create("a", "go")
    await rt.run_until_idle()
    await client.send(tid, "again")
    await rt.run_until_idle()
    usage = trial_usage([r.event for r in await client.events(tid)])
    await store.close()
    # cut + empty + "hi", then empty + empty: five calls, two nudges.
    assert usage["requests"] == 5
    assert usage["empty_nudges"] == 2
    assert usage["output_tokens"] == 7 + 4 * 5
    assert usage["input_tokens"] == 50


async def test_subtask_events_walks_every_level_below_the_root() -> None:
    children = {"root": ["a", "b"], "a": ["a1"], "b": [], "a1": []}

    class FakeClient:
        async def tasks(self, *, parent_id: str, limit: int) -> list[Any]:
            return [SimpleNamespace(task_id=c) for c in children[parent_id]]

        async def events(self, task_id: str) -> list[Any]:
            return [SimpleNamespace(event=f"{task_id}-1"), SimpleNamespace(event=f"{task_id}-2")]

    got = await subtask_events(FakeClient(), "root")  # type: ignore[arg-type]
    assert sorted(got) == ["a-1", "a-2", "a1-1", "a1-2", "b-1", "b-2"]