Source code for factor_agent.llm.scripted

"""A scripted backend: replies read from a file, in order. For tests and offline smoke runs."""

import json
import threading
from pathlib import Path

from factor_agent.llm.base import Reply, Request


[docs] class ScriptedBackend: """Answer each request with the next reply of a fixed list. ``requests`` keeps every request received, in order; calls from several threads take the replies one at a time, in the order they arrive. Raises ------ RuntimeError From ``complete`` when every reply has been used. """ def __init__(self, replies: list[str]): self._replies = list(replies) self.requests: list[Request] = [] self._taking = threading.Lock() #: The options a role's config may give besides ``backend`` and ``model``; ``replies`` is needed. OPTIONS = ("replies",)
[docs] @classmethod def from_config(cls, spec: dict) -> "ScriptedBackend": """Build from ``{"replies": <path to a JSON list of reply texts>}``.""" return cls(json.loads(Path(spec["replies"]).read_text()))
[docs] def complete(self, request: Request) -> Reply: """Return the next scripted reply and keep ``request``.""" with self._taking: if len(self.requests) >= len(self._replies): raise RuntimeError(f"ScriptedBackend: no reply left for request {len(self.requests) + 1}") text = self._replies[len(self.requests)] self.requests.append(request) return Reply(text=text, usage={}, model_id="scripted")