Covers routing, failover, the circuit breaker, structured-output retries, the cache-prefix validator, cost computation including cached-token pricing, the daily budget breaker, the quota protocol, the task state machine and log redaction. HTTP is mocked -- no unit test spends money. The integration test runs the real slice against PostgreSQL and Redis with a faked provider.
59 lines
2.0 KiB
Python
Executable File
59 lines
2.0 KiB
Python
Executable File
"""Prompt versioning (架构文档 §8.1 Prompt 版本)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from packages.llm.errors import PromptNotFoundError
|
|
from packages.llm.prompts import PromptRegistry, parse_prompt_file
|
|
|
|
|
|
def test_loads_by_id_and_version(prompts_dir: Path) -> None:
|
|
registry = PromptRegistry(prompts_dir)
|
|
v1 = registry.get("agent_chat", "v1")
|
|
v2 = registry.get("agent_chat", "v2")
|
|
|
|
assert v1.prompt_id == "agent_chat"
|
|
assert v1.version == "v1"
|
|
assert v1.ref == "agent_chat@v1"
|
|
assert v1.system_prefix != v2.system_prefix
|
|
|
|
|
|
def test_templates_are_cached_after_first_load(prompts_dir: Path) -> None:
|
|
registry = PromptRegistry(prompts_dir)
|
|
assert registry.get("agent_chat", "v1") is registry.get("agent_chat", "v1")
|
|
|
|
|
|
def test_missing_prompt_raises(prompts_dir: Path) -> None:
|
|
registry = PromptRegistry(prompts_dir)
|
|
with pytest.raises(PromptNotFoundError):
|
|
registry.get("agent_chat", "v99")
|
|
|
|
|
|
def test_available_versions(prompts_dir: Path) -> None:
|
|
registry = PromptRegistry(prompts_dir)
|
|
assert registry.available_versions("agent_chat") == ["v1", "v2"]
|
|
assert registry.available_versions("nope") == []
|
|
|
|
|
|
def test_user_template_rendering() -> None:
|
|
template = parse_prompt_file(
|
|
"[system]\n固定前缀\n\n[user]\n用户说:{user_input}\n", prompt_id="x", version="v1"
|
|
)
|
|
assert template.render_user({"user_input": "面试穿什么"}) == "用户说:面试穿什么"
|
|
|
|
|
|
def test_missing_variable_is_reported_with_the_prompt_ref() -> None:
|
|
template = parse_prompt_file(
|
|
"[system]\n固定前缀\n\n[user]\n{user_input}\n", prompt_id="x", version="v1"
|
|
)
|
|
with pytest.raises(PromptNotFoundError, match="user_input"):
|
|
template.render_user({})
|
|
|
|
|
|
def test_prompt_without_user_section_renders_empty() -> None:
|
|
template = parse_prompt_file("[system]\n只有系统前缀\n", prompt_id="x", version="v1")
|
|
assert template.render_user({"anything": "1"}) == ""
|