Default Factory Registry

The built-in `FactoryRegistry` populated with every adapter, store, and adapter the runtime ships with.

default_factory_registry()

The built-in set of FactoryInvokers, ready to use.

default_factory_registry() returns a FactoryRegistry pre-loaded with every Component implementation that ships in the box. It is the entry point for AgentConfig::into_extensions: the config loads, the registry is consulted for each [[components]] entry, and the corresponding Component is constructed.

The full file is src/runtime/components.rs; the convenience entry point is default_factory_registry.

What it registers

kindComponentRequired feature
provider.openai.chatOpenAiChatComponentopenai
provider.openai.embeddingOpenAiEmbeddingComponentopenai
provider.anthropic.chatAnthropicChatComponentanthropic
store.session.memoryMemorySessionStoreComponent(default)
store.execution.memoryMemoryExecutionStoreComponent(default)
store.run.memoryMemoryRunStoreComponent(default)
store.embedding.memoryMemoryEmbeddingStoreComponent(default)
store.artifact.memoryMemoryArtifactStoreComponent(default)
context.pipelineContextPipelineComponent(default)

Additional factories are added by feature flag:

kindComponentFeature
provider.anthropic.chatAnthropicChatComponentanthropic
store.session.redisRedisSessionStoreComponentredis
store.session.postgresPostgresSessionStoreComponentsqlx-postgres
store.session.mongodbMongoSessionStoreComponentmongodb
store.session.surrealdbSurrealSessionStoreComponentsurrealdb
store.embedding.qdrantQdrantEmbeddingStoreComponentqdrant
event_store.redisRedisRuntimeEventStoreComponentredis
stream_adapter.redisRedisRuntimeStreamAdapterComponentredis
stream_adapter.nats_jetstreamNatsJetStreamStreamAdapterComponentnats
event_publisher.natsNatsEventPublisherComponentnats + queue
event_publisher.redis_streamsRedisStreamsPublisherComponentredis + queue

The exact set of registered kinds is determined at compile time. Calling kinds() on the registry returns the active set.

How to extend

The default registry is built via:

pub fn default_factory_registry() -> FactoryRegistry {
    let reg = FactoryRegistry::new();
    let reg = register_providers(reg);
    let reg = register_memory_stores(reg);
    register_context_pipeline(reg)
}

Each register_* function takes a FactoryRegistry and returns the augmented one:

pub fn register_providers(reg: FactoryRegistry) -> FactoryRegistry;
pub fn register_memory_stores(reg: FactoryRegistry) -> FactoryRegistry;
pub fn register_context_pipeline(reg: FactoryRegistry) -> FactoryRegistry;

To add a custom factory, call register on the result:

let mut reg = default_factory_registry();
reg = reg.register("mycompany.internal-chat", my_invoke);

For feature-gated backends, register_* functions are added at compile time, so the augmentation depends on the feature set.

Worked example

use behest::runtime::factory_registry::FactoryRegistry;
use behest::runtime::default_factory_registry;
use serde_json::json;

let reg: FactoryRegistry = default_factory_registry();
for kind in reg.kinds() {
    println!("{kind}");
}
// default features, no `openai` or `anthropic`:
//   store.session.memory
//   store.execution.memory
//   store.run.memory
//   store.embedding.memory
//   store.artifact.memory
//   context.pipeline

Edge cases

  • Feature off — a kind registered by a feature is simply absent; invoke returns FactoryError::UnknownKind. The factory is not "disabled" — it is not compiled in.
  • Custom registration replaces default — if you call reg.register("store.session.memory", my_invoke), your my_invoke shadows the default. There is no "extend" semantics; if you want both, register yours under a different kind and pick the one you want in the config.
  • Order does not matterregister returns self; the resulting registry is identical regardless of the order in which kinds were registered.

Relationship to other components

See also

Related components

Edit this page on GitHub →