Engine Selection – Backend-Selectable Agent Execution¶
The same agent definition can run on different execution backends: ADK (default), asyncio (zero-dependency), or Temporal (durable). Use .engine() per-agent or configure() globally. The agent logic stays identical – only the execution engine changes.
This is the core concept of the five-layer architecture: Definition → Compile → Runtime → Backend → Compute
Tip
What you’ll learn How to configure agents for production runtime.
Source: 68_engine_selection.py
from adk_fluent import Agent, Pipeline, FanOut, configure, reset_config
from adk_fluent import EngineCapabilities, CompilationResult
from adk_fluent import compile as compile_ir
from adk_fluent.backends import available_backends, get_backend
# 1. Check what backends are registered
backends = available_backends()
# 2. Per-agent engine selection with .engine()
# .engine() stores the backend choice; .ask_async() routes accordingly.
agent_adk = Agent("helper").instruct("You help users.").engine("adk")
agent_asyncio = Agent("helper").instruct("You help users.").engine("asyncio")
agent_temporal = Agent("helper").instruct("You help users.").engine("temporal", task_queue="research")
# 3. Global configuration with configure()
# Sets the default engine for ALL agents that don't specify .engine().
configure(engine="asyncio")
agent_uses_global = Agent("test").instruct("Hello")
# Reset to defaults
reset_config()
# 4. Pipeline with engine selection
# The engine is set on the outermost builder -- all steps inherit it.
pipeline = (
Agent("researcher").instruct("Research the topic.")
>> Agent("writer").instruct("Write the report.")
>> Agent("reviewer").instruct("Review the report.")
).engine("asyncio")
# 5. Compile IR to different backends explicitly
ir = pipeline.to_ir()
adk_compiled = compile_ir(ir, backend="adk")
asyncio_compiled = compile_ir(ir, backend="asyncio")
temporal_compiled = compile_ir(ir, backend="temporal")
# 6. Inspect capabilities
adk_caps = adk_compiled.capabilities
asyncio_caps = asyncio_compiled.capabilities
temporal_caps = temporal_compiled.capabilities
graph TD
n1[["researcher_then_writer_then_reviewer (sequence)"]]
n2["researcher"]
n3["writer"]
n4["reviewer"]
n2 --> n3
n3 --> n4
Equivalence¶
# All three backends are registered
assert "adk" in backends
assert "asyncio" in backends
assert "temporal" in backends
# .engine() stores the backend name
assert agent_adk._config["_engine"] == "adk"
assert agent_asyncio._config["_engine"] == "asyncio"
assert agent_temporal._config["_engine"] == "temporal"
assert agent_temporal._config["_engine_kwargs"]["task_queue"] == "research"
# Pipeline inherits engine
assert pipeline._config["_engine"] == "asyncio"
# compile_ir returns CompilationResult with backend metadata
assert isinstance(adk_compiled, CompilationResult)
assert adk_compiled.backend_name == "adk"
assert asyncio_compiled.backend_name == "asyncio"
assert temporal_compiled.backend_name == "temporal"
# Each backend declares its capabilities
assert adk_caps.streaming is True
assert adk_caps.durable is False
assert asyncio_caps.streaming is True
assert asyncio_caps.parallel is True
assert asyncio_caps.durable is False
assert temporal_caps.durable is True
assert temporal_caps.replay is True
assert temporal_caps.checkpointing is True
assert temporal_caps.signals is True
assert temporal_caps.distributed is True
assert temporal_caps.streaming is False # Temporal doesn't stream natively