The agentic loop that gives an app an embodied AI presence. Install embodiment in an app or wrap one, supply a model seam plus IO callbacks, and it drives the perceive-decide-act loop and the presence pump - extracted from colleague so the loop is written once and imported, not reimplemented per host.
Project description
embodiment
The agentic loop that gives an app an embodied AI presence. Install embodiment
in an app or wrap one, supply a model seam plus IO callbacks, and it
drives the perceive → decide → act loop and the presence pump — extracted from
colleague so the loop is written
once and imported, not reimplemented per host.
Software presence, not a robot body. "Embodiment" is an overloaded word in this mesh:
reachy-mini-cliowns the physical robot,reachy-lobesits local brain. This package gives an application a loop and a presence — it does not drive hardware, and nothing here claims a body. If that ever changes it will be a stated goal agreed with the robot siblings, never an implication drawn from the name.
Status
Scaffold stage. What ships today is the agent-first CLI, the mesh identity,
the vendored skill kit, and green CI + PyPI publishing. The loop and the
presence pump are still in colleague 1.52.1 awaiting extraction — see
Roadmap and issue #1.
CLAUDE.md marks what exists versus what is planned; this README does the same.
What you get
- An agent-first CLI cited from teken
(
afi-cli) — the runtime package has no third-party dependencies. - A mesh identity —
culture.yaml(suffix+backend) and the matching resident prompt file (AGENTS.colleague.md, since this agent runsbackend: colleague). - The canonical guildmaster skill kit (18 skills) under
.claude/skills/, vendored cite-don't-import. Seedocs/skill-sources.md. - A build + deploy baseline — pytest, lint, the agent-first rubric gate, and PyPI Trusted Publishing wired into GitHub Actions.
Quickstart
uv sync
uv run pytest -n auto # run the test suite
uv run embodiment whoami # identity from culture.yaml
uv run embodiment learn # self-teaching prompt (add --json)
uv run teken cli doctor . --strict # the agent-first rubric gate CI runs
CLI
| Verb | What it does |
|---|---|
whoami |
Report this agent's nick, version, backend, and model from culture.yaml. |
learn |
Print a structured self-teaching prompt. |
explain <path> |
Markdown docs for any noun/verb path. |
overview |
Read-only descriptive snapshot of the agent. |
doctor |
Check the agent-identity invariants (prompt-file-present, backend-consistency). |
cli overview |
Describe the CLI surface itself. |
Every command supports --json. Results go to stdout, errors/diagnostics to
stderr (never mixed). Exit codes: 0 success, 1 user error, 2 environment
error, 3+ reserved.
Where embodiment sits
| Layer | Package | Owns |
|---|---|---|
| Surface | agentfront |
CLI / MCP / HTTP / TAUI fronts, the App registry |
| Tools | shell-cli |
The file-and-shell tool surface + approval policy |
| Loop + presence | embodiment |
The pump: perceive → decide → act, and the presence between acts |
| Memory / trust | eidetic-cli, coherence-cli |
Durable recall + provenance; drift and consistency signals |
| Product | colleague |
The coder-agent harness — the opinions, not the plumbing |
Three questions, three layers: how does a human or agent reach it
(agentfront), what can it do (shell-cli), what makes it keep going and
feel present (embodiment).
Gwen — the embodiment we ship
The reference embodiment is Gwen: one prompt-visible teammate produced by cooperating cognitive roles across two model families — G from Gemma, wen from Qwen. Colleague stays the runtime; embodiment drives the roles; Gwen is who the operator talks to.
| Concept | Value | Authority |
|---|---|---|
| Runtime | colleague |
the harness |
| Loop + presence | embodiment |
the pump |
| Teammate identity | Gwen | who the operator addresses |
| Cortex | Qwen 3.6 27B (sakamakismile/Qwen3.6-27B-Text-NVFP4-MTP) |
bounded tool loop, repo actions, final synthesis — final authority |
| Muse | Gemma 4 31B (nvidia/Gemma-4-31B-IT-NVFP4) |
tools-off advisory reasoning; proposes, never decides |
| Senses | Gemma 4 12B (coolthor/gemma-4-12B-it-NVFP4A16) |
intake, perception, conversational presence, speak-back; never acts on the repo |
| Ears / voice | Parakeet STT + Chatterbox TTS (lobes audio overlay) | the realtime lane below |
Roles resolve by name from a lobes
gateway's /capabilities contract — never by parsing model names. The identity
contract is tracked in
colleague#352 and holds
four rules that keep it honest:
- Absent identity ⇒ byte-identical prompts. Un-named deployments behave exactly as they do today.
- Identity never changes authority. Framing renames who speaks; it does not touch tool authority, routing, or safety policy.
- Same identity, role-specific authority. Senses speaks as Gwen in the first person; cortex is framed only on the top-level acting loop; muse receives its boundary on every advisory path; transcription stays neutral.
- Traces stay truthful — they always expose the actual contributing role, model, and machine, and a single-model run never claims another mind exists.
The realtime interface (lobes)
The rig's lobes gateway serves a /v1/realtime WebSocket (server-VAD, pcm16 @
24 kHz). Gwen's ear rides it ears-only: the client never triggers the
bridge's own model, so senses stays the only mind that answers and replies go
out over the batch TTS lane. The microphone is opt-in per session, a
client-edge half-duplex mute substitutes for AEC on hardware without one, and
turn-based voice is the degrade floor — a flaky socket degrades with a recorded
notice, never an exception into the host's main path.
Roadmap
Both seams already exist in colleague, written injection-shaped, so this is
decoupling work rather than redesign:
- The bounded tool loop (
colleague/loop.py) — engine-agnostic: handed acompletecallable that performs one model turn, it drives until the model finishes, stops requesting tools, or the step budget is reached. Termination is guaranteed; hooks at four lifecycle points can deny or rewrite a tool call but add no exit path. - The presence pump (
colleague/presence_engine.py+presence.py) — one pump every surface shares, assuming no TTY, no thread, and no clock: all IO rides injected callbacks and cadence is step/phase-based. - The senses coordination loop (
colleague/senses_loop.py) — agentic without ever putting a tool schema on the wire, with an explicitloop → beats → offdegradation ladder that records every transition.
Two invariants come across unchanged: the operator's words are preserved verbatim, never round-tripped through a model, and perception never raises — it degrades to a recorded, observable failure. A presence layer that can lose the user's words, or fail loudly into an app's main path, is worse than no presence layer.
Open issues
| Issue | What it asks |
|---|---|
| #1 | The build brief: extract the loop + presence from colleague, stay pure-stdlib (colleague's zero-deps guard), don't overclaim the name, keep degradation observable. Parks five questions to answer before building — one loop or two, one model seam or two, library mode or wrapper mode first, the decoupling cost of loop.py's dozen module-scope imports, and whether embodiment owns the presence event stream that harmonics-cli and reterminal currently consume without a shared producer. |
| #2 | Continuity: compose eidetic-cli (memory, provenance, ageing) and coherence-cli (agreement between memory and the present) rather than reimplementing either. Embodiment owns the lived sequence; memory and coherence are runtime, not tools the model picks arbitrarily; checks happen at meaningful boundaries; degradation is visible to the host. Done means a second, non-colleague app gains the same continuity. |
Neither issue has replies yet — answers belong on the issue or in an exported spec, not only in a commit message.
Make it your own
This repo was minted from
culture-agent-template.
To mint another agent from it:
- Rename the package
embodiment/and theembodimentCLI/dist name throughoutpyproject.toml, the package,tests/,sonar-project.properties, and thisREADME.md. The name is hard-coded in ~100 places, so list every occurrence first:git grep -nF -e embodiment. - Edit
culture.yamlwith yoursuffixandbackend. - Rewrite
CLAUDE.mdfor your agent and run/init. - Re-vendor only the skills you need from guildmaster (see
docs/skill-sources.md).
See CLAUDE.md for the full conventions (version-bump-every-PR,
the cicd PR lane, worktree layout, memory discipline, deploy setup).
License
Apache 2.0 — see LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file embodiment-0.6.2.tar.gz.
File metadata
- Download URL: embodiment-0.6.2.tar.gz
- Upload date:
- Size: 166.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50e9c2e6263db82008c5584be94e634ae77186d24e188b741bd0d9f64862f94e
|
|
| MD5 |
02c306620c2e2d24194d4466102ff2b2
|
|
| BLAKE2b-256 |
190d9202077393464ff7a502056f8d128e01f3e14b3987fd232bab66da6b5e7f
|
File details
Details for the file embodiment-0.6.2-py3-none-any.whl.
File metadata
- Download URL: embodiment-0.6.2-py3-none-any.whl
- Upload date:
- Size: 25.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ced2a169404b3fda3bda310793893986a09eccaa96fe0cbd267198718ce5203
|
|
| MD5 |
a151ace7df6062e91eaf1f0ad3c799e2
|
|
| BLAKE2b-256 |
cf692752526fbc603982c25c801d8d8c311d2503cb7e386dab5beb2bfbfcc199
|