Files
opensquilla--opensquilla/tests/test_provider_ollama_trace.py
2026-07-13 13:12:33 +08:00

66 lines
2.1 KiB
Python

from __future__ import annotations
import asyncio
import json
from typing import Any
import httpx
from opensquilla.provider.ollama import OllamaProvider
from opensquilla.provider.types import ChatConfig, DoneEvent, Message
def test_ollama_provider_writes_llm_trace(monkeypatch: Any, tmp_path: Any) -> None:
trace_path = tmp_path / "ollama-llm-calls.jsonl"
monkeypatch.setenv("OPENSQUILLA_LLM_TRACE_RECORDER", "full")
monkeypatch.setenv("OPENSQUILLA_LLM_TRACE_PATH", str(trace_path))
body = b"".join(
[
json.dumps({"message": {"content": "ok"}, "done": False}).encode() + b"\n",
json.dumps(
{"message": {}, "done": True, "prompt_eval_count": 5, "eval_count": 2}
).encode()
+ b"\n",
]
)
def handler(request: httpx.Request) -> httpx.Response:
return httpx.Response(
200,
headers={"content-type": "application/x-ndjson"},
content=body,
)
transport = httpx.MockTransport(handler)
real_async_client = httpx.AsyncClient
def patched_async_client(*args: Any, **kwargs: Any) -> httpx.AsyncClient:
kwargs["transport"] = transport
return real_async_client(*args, **kwargs)
monkeypatch.setattr("opensquilla.provider.ollama.httpx.AsyncClient", patched_async_client)
provider = OllamaProvider(model="llama3")
async def _run() -> list[Any]:
return [
event
async for event in provider.chat(
[Message(role="user", content="hi")],
config=ChatConfig(max_tokens=12),
)
]
events = asyncio.run(_run())
assert any(isinstance(event, DoneEvent) for event in events)
rows = [json.loads(line) for line in trace_path.read_text(encoding="utf-8").splitlines()]
assert [row["event"] for row in rows] == [
"llm.request",
"llm.response_chunk",
"llm.response_chunk",
"llm.response",
]
assert rows[0]["provider"] == "ollama"
assert rows[-1]["assistant_text"] == "ok"
assert rows[-1]["usage"]["input_tokens"] == 5