Forge Extension
Run Nexus as a forge.Extension with auto-discovery and DI.
Setup
import (
"github.com/xraph/forge"
nexusext "github.com/xraph/nexus/extension"
)
app := forge.New(
forge.WithExtension(nexusext.New(
nexusext.WithProvider(openai.New(key)),
)),
)
app.Start(ctx)Auto-Discovery
When running in a Forge application, the Nexus extension automatically discovers other Forge extensions via vessel DI:
- Chronicle — Wires
audit_hookwith Chronicle recorder - Shield — Wires Shield as a guardrail adapter
- Relay — Wires
relay_hookwith Relay sender - Authsome — Wires Authsome as auth provider
- Metrics — Wires observability with
gu.MetricFactory
YAML configuration
When running inside Forge, Nexus automatically loads configuration from the application's YAML config file. The extension looks for settings under two keys (in order):
extensions.nexus(namespaced, recommended)nexus(legacy shorthand)
extensions:
nexus:
base_path: "/ai"
default_timeout: "30s"
default_max_retries: 2
global_rate_limit: 1000
log_level: "info"
enable_usage: true
enable_cache: false
grove_database: ""
disable_routes: false
disable_migrate: falseConfiguration reference
| Field | YAML key | Type | Default | Description |
|---|---|---|---|---|
BasePath | base_path | string | "/ai" | URL prefix for gateway routes |
DefaultTimeout | default_timeout | duration | 30s | Default timeout for provider requests |
DefaultMaxRetries | default_max_retries | int | 2 | Default retries per request |
GlobalRateLimit | global_rate_limit | int | 0 | Global rate limit in RPM (0 = unlimited) |
LogLevel | log_level | string | "info" | Gateway log level |
EnableUsage | enable_usage | bool | true | Enable usage tracking |
EnableCache | enable_cache | bool | false | Enable response caching |
GroveDatabase | grove_database | string | "" | Name of grove.DB to resolve from DI |
DisableRoutes | disable_routes | bool | false | Disable automatic route registration |
DisableMigrate | disable_migrate | bool | false | Disable automatic store migration |
Merge behavior
File-based and programmatic configuration are merged with these rules:
| Category | Precedence |
|---|---|
Boolean flags (disable_routes, disable_migrate, enable_cache) | Programmatic true wins |
String fields (base_path, log_level, grove_database) | YAML takes precedence; programmatic fills gaps |
Duration/int fields (default_timeout, default_max_retries, global_rate_limit) | YAML takes precedence; programmatic fills gaps |
Pointer fields (enable_usage) | YAML takes precedence; programmatic fills gaps |
Any remaining zero-valued fields are filled from DefaultConfig().
Requiring file config
If your deployment relies on the config file being present, use WithRequireConfig:
app := forge.New(
forge.WithExtension(nexusext.New(
nexusext.WithRequireConfig(true),
)),
)When RequireConfig is true and no config is found under either key, Register returns an error.
Extension options
| Option | Purpose |
|---|---|
WithProvider(p) | Register an LLM provider |
WithDatabase(s) | Set the persistence store directly |
WithGatewayOption(opt) | Pass a raw nexus.Option to the gateway |
WithBasePath(path) | Set the HTTP base path (default: /ai) |
WithConfig(cfg) | Set extension configuration directly |
WithDisableRoutes() | Disable automatic route registration |
WithDisableMigrate() | Disable automatic store migration |
WithRequireConfig(bool) | Require config to be present in YAML files |
WithGroveDatabase(name) | Resolve a grove.DB from DI by name |
Grove database integration
When your Forge app uses the Grove extension to manage database connections, Nexus can automatically resolve a grove.DB from the DI container and construct the correct store backend based on the driver type.
Using the default grove database
If the Grove extension registers a single database (or a default in multi-DB mode), use WithGroveDatabase with an empty name:
ext := nexusext.New(
nexusext.WithGroveDatabase(""),
nexusext.WithProvider(openai.New(key)),
)Using a named grove database
In multi-database setups, reference a specific database by name:
ext := nexusext.New(
nexusext.WithGroveDatabase("nexus"),
nexusext.WithProvider(openai.New(key)),
)This resolves the grove.DB named "nexus" from the DI container and auto-constructs the matching store. The driver type is detected automatically -- you do not need to import individual store packages.
Via YAML
Grove database can also be configured via the YAML config file:
extensions:
nexus:
grove_database: "nexus"When grove_database is set in YAML, the extension enables grove resolution automatically.
Store resolution order
The extension resolves its store in this order:
- Explicit store -- if
WithDatabase(s)was called, it is used directly and grove is ignored. - Grove database -- if
WithGroveDatabase(name)was called, the named or defaultgrove.DBis resolved from DI. - In-memory fallback -- if neither is configured, an in-memory store is used.
DI Registration
The extension registers the Gateway in the vessel container:
// Other extensions can resolve it
gw, err := vessel.Resolve[*nexus.Gateway](container)