fix: wire agent identity + persistent memory into hermes_self runtime#3
Merged
Conversation
The agent had no system prompt and no conversation history — every turn
started cold. Three missing wire-ups fixed:
1. vault_memory.py — add parse_history() to convert the markdown log
back to OpenAI-style messages list so runtimes can pass it to LLMs.
2. hermes_self/invoke.py — load supersan.yaml system_prompt (cached),
load per-user vault history, pass both to every LLM call, then
write the turn back to vault so the next session can recall it.
3. bot.py — pass metadata={"user_id": str(chat_id)} on the Job so
invoke.py knows which conversation file to open/append.
Also: fix pyproject.toml missing pythonpath=["src"] so uv run pytest
works without PYTHONPATH override; clean 4 pre-existing ruff warnings
in bot.py (unused import, unsorted imports, asyncio.TimeoutError).
All 19 tests pass (11 unit + 8 smoke).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each deployed agent now sets AGENT_IDENTITY=<name> and gets its own system prompt loaded from orchestrator/config/identities/<name>.yaml. Supported names: supersan, coo, gtm, head_of_ops (one YAML per agent). Per-job override also works: job.metadata["identity"] = "coo" lets the orchestrator pin an identity at dispatch time without relying on env var. Prompts are cached per identity name so the YAML is only read once. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Send /identity to list available personas and the current one. Send /identity <name> to switch (e.g. /identity coo, /identity video_agent). The selected persona is stored per chat_id and passed as job.metadata["identity"] on every subsequent message, which causes hermes_self to load that agent's system_prompt from its YAML file. Adding a new agent persona is now: create the YAML, send /identity <name>. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… SETUP QUICKSTART gets a new Step 5 covering /identity in plain English: what it does, how to switch, how to create a new persona from a YAML file, and how to set AGENT_IDENTITY as the deployment default. SETUP gets a dedicated "Agent personas" section up front explaining how the system works, the four built-in personas, how to switch via Telegram, how to set a default per service, and a full walkthrough for creating a new persona from scratch. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
jbellsolutions
added a commit
that referenced
this pull request
May 15, 2026
#1) * feat(openswarm): runtime adapter + fleet manager + agent-builder + ops Phase A: vendor OpenSwarm submodule, runtime conforming to RuntimeResult contract, fleet manager with file-locked registry + port allocator + HTTP client for agency-swarm FastAPI, routing entries. Phase B: pluggable Customizer (noop/manual/claude_code) + Validator (noop/health/smoke), builder.build() with atomic rollback at every step, builder.upgrade() with recorded-customization replay + atomic folder swap, auto-generated SKILL.md per swarm, decision record. Phase C: upgrader stream #3 (openswarm) with real smoke harness that re-replays each swarm's customization against fresh vendor; cost_rollup per swarm; idle hibernation; vault/graph/openswarm.json snapshot; BudgetExceeded pre-flight gate; Next.js dashboard fleet tile. Phase D: cross-swarm pipeline ({prev} threading); parallel fan_out via ThreadPoolExecutor; Slack /build-swarm and /list-swarms slash commands. 128 unit tests passing, ruff clean, agent-os route + invoke smoke-verified. * docs(readme): add OpenSwarm runtime + agent-builder section - New row in "What you're getting" table linking to OpenSwarm + builder - OpenSwarm fleet section with the 15 invoke ops, customizer/validator matrix, and the Slack slash command surface - Repo map updated: runtimes/openswarm/ + vendor/openswarm/ - Upgrader entry now reads "11 streams" with OpenSwarm in the list - Status block: 23 → 128 tests, 7 → 8 submodules - Reading order: added vault/decisions/openswarm-runtime-adoption.md No source changes — pure docs follow-through on the runtime that landed in the prior commit on this branch. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(ci): drop pnpm version override — let packageManager drive it GitHub Action `pnpm/action-setup@v4` errors with ERR_PNPM_BAD_PM_VERSION when `with.version` and package.json's `packageManager` field both pin a version. The latter is more authoritative (the lockfile depends on it), so drop the action-level override. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: jbellsolutions <jbellsolutions@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
hermes_self/invoke.py— loadssupersan.yamlsystem prompt at startup; pulls last 10 conversation turns from vault before every LLM call; writes both turns back to vault after the response. Agent now has identity and memory across sessions.vault_memory.py— addsparse_history()to convert the markdown conversation log back to OpenAI-style[{role, content}]messages so any runtime can pass them directly to LLM APIs.bot.py— passesmetadata={"user_id": str(chat_id)}on the Job so the runtime knows which vault file to read and write. Also cleans 3 pre-existing ruff warnings (unused import, unsorted imports,asyncio.TimeoutError).pyproject.toml— addspythonpath = ["src"]to pytest config souv run pytestworks without aPYTHONPATHenv override.Test plan
uv run pytest tests/unit/test_telegram_bot.py— 11 passeduv run pytest tests/smoke/— 8 passeduv run ruff check src/agent_os/runtimes/hermes_self/invoke.py src/agent_os/channels/telegram/bot.py src/agent_os/orchestrator/adapters/vault_memory.py— all checks passedgit pull origin main && restart bot— agent should open with Super Agent identity and recall prior turns🤖 Generated with Claude Code