from __future__ import annotations from genesis.inference.types import TokenUsage class FakeLLMClient: """可编程的假 LLM 客户端:记录调用,按脚本返回(离线)。""" def __init__(self, script=None): # script: list[(status, content)];status: "ok" | "raise_timeout" | "raise_network" | "parse_fail" self.script = script or [("ok", "hello")] self.calls: list[dict] = [] async def chat(self, *, model, messages, temperature, max_tokens): # 与真实 HttpLLMClient 的 payload 结构一致:{role, content}(T4 防护断言 role) self.calls.append({ "model": model, "messages": [{"role": m.role, "content": m.content} for m in messages], }) status, content = self.script.pop(0) if status == "raise_timeout": from genesis.inference.exceptions import LLMTimeoutError raise LLMTimeoutError("timeout") if status == "raise_network": from genesis.inference.exceptions import LLMNetworkError raise LLMNetworkError("network") if status == "parse_fail": content = "NOT JSON" return content, TokenUsage(input_tokens=10, output_tokens=2)