query-embed-on-cpu, follow-up daemon-embedder-gpu-pool: huginn-daemon takes repeated --ollama-url (GPU hosts) and --reserve-ollama-url (CPU hosts) and builds the same EmbedderPool as huginn-sources, through one ollama::pool constructor. A lone --ollama-url is a pool of one. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
99 lines
5.8 KiB
Markdown
99 lines
5.8 KiB
Markdown
# Huginn
|
|
|
|
Huginn is the GameCult memory organ. It owns each agent instance's mind as
|
|
typed state: what an instance remembers, which of that memory is admitted to
|
|
steer its next action, and the provenance of every admitted claim.
|
|
|
|
Upstream: `https://github.com/GameCult/Huginn.git`
|
|
|
|
**Status.** Live: `huginn-mind` (admission with receipts, typed queries, derived status), `huginn-daemon` (CultNet RUDP with a Qdrant semantic index), and the `huginn` CLI from `crates/eureka-state` (whoami, view, query, admit, schema). The `eureka` instance runs on Yggdrasil. Entry points: `cargo check --workspace`, `crates/huginn-mind/src/admission.rs`, `crates/huginn-daemon/src/serve.rs`, `schemas/cultnet/`. Planned: what each crate does next is owned by the `eureka-body` cut specs in the mind and `docs/eureka-body-map.md`; the legacy `.voidbot/` Persona migration belongs to the portable-Persona work.
|
|
|
|
## Authority
|
|
|
|
- An instance owns its mind; Huginn owns the state. Huginn is the single
|
|
writer of an instance's memory documents. No other service, script, or agent
|
|
writes them.
|
|
- Memory documents are CultCache state. `huginn-mind` persists them through
|
|
CultLib's Rust CultCache into a redb store at
|
|
`<state_root>/minds/<instance>/mind.redb`. `huginn-daemon` serves one such
|
|
mind over CultNet RUDP: admission and the read side ride
|
|
`cultnet.operation_request.v0` and `cultnet.operation_response.v0`, and the
|
|
two wire schemas answer a schema catalog request.
|
|
- Retrieval depends on Qdrant directly, with no second store and no second
|
|
writer. `huginn-daemon` keeps one collection per mind, `huginn_mind_<instance>`,
|
|
as a projection of the mind: one worker thread embeds each indexable
|
|
document through Ollama and writes its point, off the serving path, and a
|
|
restart compares the mind with the collection and writes what is missing. An
|
|
unreachable Qdrant or Ollama shows in `whoami` as the index's status and is
|
|
retried; admission never waits on it. The daemon requires `--qdrant-url`,
|
|
`--ollama-url` and `--embedding-model`; `--ollama-url` repeats for each GPU
|
|
host and `--reserve-ollama-url` for each CPU host, and the GPU hosts embed
|
|
together while the CPU hosts serve only when none can. A `query` carrying `semantic` is
|
|
answered through the same selection as any other: the index supplies
|
|
candidate ids and scores, and the mind keeps only the documents it holds and
|
|
the selection admits (ask for `in_force` to exclude resolved ones), ordered by
|
|
score. It takes no cursor, and it is refused `Unavailable` while the index is
|
|
failing or refused.
|
|
- Mind state is not version-controlled. It lives in Huginn's store, not in
|
|
any repository.
|
|
|
|
Generic `.cc` inspection is not Huginn's job. CultCache Studio inspects and
|
|
edits `.cc` state. Huginn reads and writes minds.
|
|
|
|
## Layout
|
|
|
|
A Cargo workspace of five crates (`crates/eureka-pipeline` holds the document shapes and keys, `crates/mind-body` the control store, launch primitive and `mind-heartbeat` timeline; the three below are the mind, the daemon and the client):
|
|
|
|
- `crates/huginn-mind`: storage, identity, admission, and queries and derived
|
|
status over memory documents.
|
|
- `crates/huginn-daemon`: the CultNet surface. The socket, the sessions and
|
|
the process, and no rule. The operation envelope both sides speak is
|
|
`huginn-mind`'s.
|
|
- `crates/eureka-state`: the client core, `HuginnClient::call`: one request to a
|
|
daemon over CultNet RUDP, a deferred answer resolved, and no state. Its
|
|
`huginn` binary is the agents' CLI: whoami, view, query and named recipes,
|
|
admit with read-back, schema.
|
|
|
|
`huginn-mind` is live: it opens one instance's store (an owned redb CultCache
|
|
at `<state_root>/minds/<instance>/mind.redb`, locked for the mind's lifetime),
|
|
and refuses a store whose `instance` document names another instance, whose
|
|
epoch record is foreign, or whose types are not a mind's. It admits batches
|
|
of pipeline documents through one commit path: the leaf's bounds, formats and
|
|
keys, then the organ's cross-document rules (references, in-force status,
|
|
the resolution matrix, derived resolutions and stewardships), then one
|
|
compare-and-swap that lands the batch whole with a receipt naming the exact
|
|
bytes it read and wrote. An exact replay answers with the stored receipt.
|
|
It reads them back the same way: a document with the facts of its admission
|
|
joined from that receipt and its status derived at read time, and typed
|
|
queries over one mind. Status is never stored, and the views derive it
|
|
through the same rules admission does. Document shape and keys come from
|
|
`eureka-pipeline` (`crates/eureka-pipeline`); the store is CultLib's Rust CultCache.
|
|
|
|
`huginn-daemon` opens one mind, binds one UDP socket in that order, and
|
|
answers every frame on the session it arrived on: one operation per `Mind`
|
|
method plus `whoami`, whose payload is the mind's own types as named
|
|
MessagePack. A refusal is an answer with a `rejected` status, never a
|
|
transport error; an envelope that does not decode is answered with a typed
|
|
failure and reaches no mind. The two schemas it publishes live in
|
|
`schemas/cultnet/`, listed in its `index.json`, and are pinned to their
|
|
derivation by a test.
|
|
|
|
The campaign's cut specs in the mind (`eureka-body`) and
|
|
`docs/eureka-body-map.md` own what each crate does next.
|
|
|
|
```powershell
|
|
cargo check --workspace
|
|
cargo run -p huginn-daemon -- --state-root <abs> --instance <slug> --bind 127.0.0.1:17872 `
|
|
--qdrant-url http://127.0.0.1:6333 --ollama-url http://10.77.0.4:11434 --embedding-model qwen3-embedding:0.6b
|
|
```
|
|
|
|
The deployed daemon (instance `eureka` on Yggdrasil) is installed and run by
|
|
`gamecult-ops/runbooks/huginn-yggdrasil.md`.
|
|
|
|
## Persona
|
|
|
|
Huginn's legacy repo Persona lives under `.voidbot/`. Its `state/huginn.cc`
|
|
holds legacy `void.*` documents and its `voice/identity.json` names the
|
|
Persona. The two disagree about jurisdiction; that migration belongs to the
|
|
portable-Persona work, not to this workspace, and nothing here reads or writes
|
|
`.voidbot/`.
|