from __future__ import annotations import json from pathlib import Path from types import SimpleNamespace from typing import Any import pytest from store_assistant.store import Store CATALOG = Path(__file__).resolve().parent.parent / "data" / "demo_store.json" @pytest.fixture() def store(tmp_path: Path) -> Store: s = Store(tmp_path / "test.db") s.load_catalog(CATALOG) yield s s.close() def tool_call(call_id: str, name: str, arguments: dict[str, Any] | str) -> SimpleNamespace: args = arguments if isinstance(arguments, str) else json.dumps(arguments) return SimpleNamespace(id=call_id, type="function", function=SimpleNamespace(name=name, arguments=args)) def completion(content: str | None = None, tool_calls: list[SimpleNamespace] | None = None) -> SimpleNamespace: message = SimpleNamespace(role="assistant", content=content, tool_calls=tool_calls) return SimpleNamespace(choices=[SimpleNamespace(message=message, finish_reason="stop")]) class FakeClient: """Plays back scripted responses and records every request.""" def __init__(self, responses: list[Any]) -> None: self._responses = list(responses) self.requests: list[dict[str, Any]] = [] self.chat = SimpleNamespace(completions=SimpleNamespace(create=self._create)) async def _create(self, **kwargs: Any) -> Any: # Copy the messages: the caller keeps appending to the same list. self.requests.append({**kwargs, "messages": [dict(m) for m in kwargs["messages"]]}) if not self._responses: raise AssertionError("FakeClient ran out of scripted responses") response = self._responses.pop(0) if isinstance(response, Exception): raise response return response