symfonic.core.testing¶
testing ¶
symfonic.core.testing โ Test doubles for symfonic.core.
Provides MockModelProvider and MockChatModel for testing without live API
keys, plus :class:~symfonic.core.testing.deterministic.DeterministicProvider
โ a contract-conformant adapter for each supported wire family, for tests
that need per-family behaviour (cache dialect, the extended-thinking forced
tool-choice constraint, sampling knobs) rather than a scripted reply.
Install via: pip install symfonic-core[testing]
MockChatModel ¶
Bases: BaseChatModel
Minimal chat model that returns scripted responses. For testing only.
bind_tools ¶
v7.12.0: testing pass-through.
Pre-v7.12.0 the framework never registered tools unless the
adopter did, so MockModel-based tests rarely exercised
bind_tools. v7.12.0 auto-registers recall_tool_result
whenever tool_result_compaction_enabled=True (the new
default), which means the react node now binds at least one
tool even on bare SymfonicAgent(model_provider=MockModelProvider())
instances. Without this override BaseChatModel.bind_tools
raises NotImplementedError and the entire suite of
FastAPI / engine / scope-injection / tenant-auth tests
regress.
Behaviour: returns self so the bound runnable is still
the mock. tool_choice and other kwargs are accepted and
ignored -- the mock does not honour forcing semantics.
Source code in symfonic/core/testing/__init__.py
with_structured_output ¶
Return a runnable that yields a validated schema instance.
Mirrors BaseChatModel.with_structured_output so structured-output
tests run without a live tool-calling model. The instance is built
from structured_response (validated against schema); if that
is unset, a best-effort default instance is constructed so the happy
path still returns a typed object.
Source code in symfonic/core/testing/__init__.py
MockModelProvider ¶
MockModelProvider(response: str = 'Mock response', tool_calls: list[dict[str, Any]] | None = None, structured_response: dict[str, Any] | None = None)
Test double for ModelProvider. Returns configurable responses without a live API key.
Install via: pip install symfonic-core[testing]
For a double that speaks a specific wire family (Anthropic cache
dialect, the extended-thinking forced-tool-choice constraint, per-family
sampling knobs) use :class:DeterministicProvider instead; this class is
deliberately wire-neutral.