Pydantic AI Compatibility
Goal: keep Pydantic AI as the runtime owner while exposing its agent through
the LLLM Tactic boundary.
Prerequisites
python -m pip install -e ".[dev]"
Files Used
examples/pydantic_ai_tactic/
fake_agent.py
structured_agent.py
surrounding_features.py
tests/
test_pydantic_ai_adapter.py
test_examples.py
Executable offline examples live in
examples/pydantic_ai_tactic/structured_agent.py and
examples/pydantic_ai_tactic/surrounding_features.py.
Wrap
from pydantic import BaseModel
from lllm.runtimes import PydanticAITactic
class BriefInput(BaseModel):
topic: str
class BriefOutput(BaseModel):
title: str
tactic = PydanticAITactic(
agent,
input_type=BriefInput,
output_type=BriefOutput,
)
When a Pydantic model reaches the adapter, the default input_mode="auto"
sends JSON to the agent. Use input_mode="dict" or input_mode="python" when
your agent expects those shapes instead.
Metadata
Context metadata is forwarded when the agent method accepts metadata:
from lllm import CallContext
result = tactic.run(
{"topic": "refs"},
context=CallContext(trace_id="trace-1", metadata={"caller": "demo"}),
)
Runtime-owned features stay runtime-owned. Configure model/provider settings, instrumentation, eval hooks, durable execution IDs, graph/workflow state, tool approval, and dependencies on the agent or pass them as normal run kwargs:
The offline surrounding-features example models Logfire/OpenTelemetry-style instrumentation as agent-owned state and asserts the LLLM wrapper leaves that state intact.
Runtime Features
tactic = PydanticAITactic(
agent,
input_type=BriefInput,
output_type=BriefOutput,
run_kwargs={
"model_settings": {"temperature": 0},
"eval_hook": "offline-score",
},
)
result = tactic.run(
{"topic": "refs"},
durable_run_id="run-1",
graph_node="planner.step",
)
If you pass metadata= yourself, LLLM does not overwrite it with context
metadata.
Any LLLM tactic can also become a runtime-owned tool:
Tool Wrapper
from lllm.runtimes import tactic_as_tool
tool = tactic_as_tool(tactic, parameter_mode="kwargs")
output = tool(topic="refs")
See examples/pydantic_ai_tactic/structured_agent.py and
examples/pydantic_ai_tactic/surrounding_features.py for fully offline fake
agents that demonstrate structured input/output, streaming, metadata, tool
wrapping, and runtime-owned surrounding features.
Verify
python -m pytest tests/test_pydantic_ai_adapter.py tests/test_examples.py -q
Expected output:
... passed
Next, serve the wrapped agent with create_tactic_app() or export tactic
metadata for a PsiHub package.