ServableAgent contract can be registered and served — the first-party Agent class is just one implementation.
The ServableAgent contract
defineExternalAgent()
Wrap external logic behind an explicit host function. It normalizes your return value into a fullRunOutput, provides a default stream() fallback, wires up an EventBus (so observability works out of the box), and auto-registers in the global registry.
defineExternalAgent alone does not start a server.
Returning rich output
Return a partialRunOutput to include usage, tool calls, or structured data — missing fields are filled with defaults:
Native streaming
By default,stream() runs to completion and yields the text as a single chunk. Provide your own generator for true streaming:
Configuration
Observe the run lifecycle
defineExternalAgent emits the standard run lifecycle events (run.start, run.complete, run.error) on its event bus, so Tracer, MetricsExporter, and StructuredLogger work unchanged:
Registry names are labels (v2.3.2+)
Registering an agent with an existing name replaces the previous entry (last-write-wins) — names are labels, not unique keys. Gateways resolve a name to the most recently registered instance. Useregister: false for request-owned instances so they cannot replace a shared hosted service.
register: false (on AgentConfig or ExternalAgentConfig) for ephemeral agents that should skip the registry entirely.
Cross-references
- Express Transport — the routes every served agent gets
- Socket.IO Gateway — realtime serving
- Observability — event-bus-driven tracing and metrics