symfonic.platform.agent_host¶
agent_host ¶
The host and registry, implemented (task-1-2-2).
Contracts in :mod:symfonic.platform.host; this is the one implementation the
generated scaffold builds. Nothing here takes a turn or inspects one.
AgentHost ¶
AgentHost(*, composer: Any, resources: Any, open_resources: Any = None, continuation_factory: Any = None)
Owns the process's shared resources and the registry over them.
Built once by a composition root and closed once. open_resources is a
separate callable rather than a method on the resources object because
opening is not part of :class:~symfonic.platform.host.SharedResources:
an adopter may hand over something already open, and requiring an aopen
would make that a lie.
Source code in src/symfonic/platform/agent_host.py
aclose
async
¶
Close the registry, then the resources, exactly once.
In that order: an agent holding a closed pool is a worse failure than a pool held a moment longer, because the first surfaces mid-turn and the second surfaces nowhere.
Resources are closed only if they were opened. A host whose
construction failed before start is still closed by the handler,
and closing what was never opened is how a shutdown path raises during
a shutdown that was already going badly.
Source code in src/symfonic/platform/agent_host.py
resume
async
¶
Continue a durable human pause through this host's scoped agents.
A host with no configured continuation fails early instead of accepting
a token it cannot safely bind to a scope. Compose
human_continuation(...) with a verified claim-to-scope resolver.
Source code in src/symfonic/platform/agent_host.py
start
async
¶
Open shared resources once, however many times this is called.
Source code in src/symfonic/platform/agent_host.py
ScopedAgentRegistry ¶
One agent per scope, composed on first use.
Concurrency is handled with a per-scope lock rather than one global lock, so a slow composition for one tenant does not serialise every other tenant's first request. The double check inside the lock is what makes the composer run exactly once: the first waiter composes, the rest find the entry already there.
Source code in src/symfonic/platform/agent_host.py
aclose
async
¶
Drop every agent. Idempotent, and does not touch shared resources.
Ownership runs one way: the registry borrows what the host opened, so closing it here would close a pool other registries may still hold -- and would do it from whichever one happened to close first.