How to configure ports (dna.config.yaml)¶
The kernel is a mediator over a handful of ports — where documents live
(source), how they are searched, how text is embedded. You can wire those
imperatively, or declare them once in a dna.config.yaml and let
Kernel.from_config do the wiring. The file is language-agnostic: the same
dna.config.yaml drives the Python and the TypeScript SDK.
The file¶
# dna.config.yaml
source: postgresql://dna:dna@localhost:5432/dna # required
search: pgvector # pgvector | sqlite-vec | off (default: off)
embedding: onnx # onnx | fake | off (default: off / fake floor)
Only source is required. dna.config.yaml is parsed and validated —
an unknown key, a missing source, or an out-of-enum search/embedding
value fails loud with a didactic message rather than silently doing the wrong
thing.
source — where documents live¶
| URL | Adapter |
|---|---|
file://<path> (or a plain path) |
filesystem (read + write on disk) |
pkg://<package>[/<subpath>] |
filesystem read-only over a scope embedded as package data — travels with your app (wheel / Docker). See shipping a scope with your app. |
sqlite:///<path> |
SqlAlchemySource (aiosqlite) — Python only |
postgresql://<user>:<pass>@<host>/<db> |
SqlAlchemySource (asyncpg) |
The URL→source resolution is a public surface in its own right —
dna.adapters.source_from_url (Python) / sourceFromUrl (TypeScript) — so a
host can use it without a config file. The dna CLI consumes the same factory,
which is why DNA_SOURCE_URL=sqlite://… and postgresql://… now work from the
CLI, not just file://.
Booting from it¶
from dna import Kernel
kernel = Kernel.from_config() # discovers ./dna.config.yaml
kernel = Kernel.from_config("deploy/dna.config.yaml") # explicit path
mi = kernel.instance("helpdesk")
prompt = mi.build_prompt(agent="triage")
With no dna.config.yaml present (and no path given), from_config
behaves exactly like the bare default — a filesystem .dna source — so it is
always safe to call.
from_config returns a wired Kernel; use .instance(scope) for the manifest.
For the Runtime vocabulary, Runtime.from_config(...).manifest(scope) returns a
Runtime (the class is threaded through, like auto / quick).
from_config is a boot-time factory: SQL sources run their schema
migrations while it builds, on a short-lived event loop. Call it during
startup, not from inside a running loop.
import { fromConfig } from "@ruinosus/dna";
const kernel = await fromConfig(); // discovers ./dna.config.yaml
const mi = await kernel.instance("helpdesk");
const prompt = await mi.buildPrompt({ agent: "triage" });
The TypeScript runtime ships the filesystem and postgres source
adapters. A sqlite:// source — or a pgvector search — is Python-only
and fails loud in TypeScript with that explanation, so a shared
dna.config.yaml never silently misbehaves across languages.
search and embedding¶
These select opt-in providers and are wired only when you ask for them (so the default install never pulls ONNX or sqlite-vec):
embedding: onnxregisters the real all-MiniLM embedding provider;fake/offleave the deterministic zero-dependency floor.search: sqlite-vecregisters the offline sqlite-vec record-search provider;pgvectorregisters the Postgres one (Python), reusing the config's DSN;offleaves the lexical fallback.