protean-model-sync

Hermes Agent plugin · in the official plugin catalog

Model control for a Hermes fleet.

protean-model-sync gives one profile a fleet-wide voice. Set per-member model and reasoning in Bot Mode group chats, push one profile's model to every session of an agent, and apply named provider/model presets across profiles.

Three surfaces, one package: a CLI, one right-side desktop pane, and a read-only status command. Every write is diffed, backed up, and read back.

v1.1.0 · ahrazzle/hermes-group-model-sync catalog SHA 50d3d09 stdlib + PyYAML only · no pip no network of its own · no telemetry install does not activate either half

01Install

Install per profile. Writes are profile-native, so the habit is one install per profile. Pinning --ref is deliberate: an upgrade becomes an explicit choice of a new commit.

hermes -p <profile> plugins install ahrazzle/hermes-group-model-sync --ref <40-char-commit-sha>
hermes -p <profile> plugins enable hermes-group-model-sync

install is not activation. The CLI half turns on through plugins enable. The desktop half turns on in Settings → Plugins, and it hot-reloads on save once enabled. Both halves are opt-in and off by default.

Needs: Hermes with plugin support (agent half: CLI plus dashboard routes; desktop half: Hermes Desktop). The Groups and Agents tabs also need Bot Mode group chats (the bundled hermes-bots plugin) and backend support for profiles.configure. Nothing else: the agent half runs on the stock Hermes Python.

Upgrade: hermes -p <profile> plugins update hermes-group-model-sync — refused while pinned, which is intended. The desktop half needs no second command: the runtime loader watches its folder and reloads it in place. Uninstall: hermes -p <profile> plugins remove hermes-group-model-sync, and turn the desktop half off in Settings → Plugins. Removing the install folder does not touch any profile's config.yaml or any backup. presets/presets.json lives inside the install folder, so an upgrade replaces it: keep your own preset values in your own copy of this repository.

02How it works

Hermes Desktop switches a model per session, and the Dashboard switches one profile's default. Nothing shows what each agent in a group chat is running, nothing pushes one configuration to every session of an agent, and nothing applies a named provider/model preset across profiles. This plugin fills those three gaps.

hermes group-model-sync

CLI

Six verbs: preset, plan, apply, verify, rollback, doctor. Writes a named profile's config.yaml with a backup and a read-back, or writes nothing at all.

Model Sync pane

Desktop

One right-side pane, three tabs. Groups shows every member agent's model and reasoning in a Bot Mode room, changeable per member. Agents pushes one profile's model and reasoning to every existing session of that agent. Presets applies a named preset to explicitly chosen profiles, with a diff preview first.

/gms status

Read-only status

An in-session command for the CLI and the gateway. Reports the current state and writes nothing, by design.

Deliberately no agent tool

There is no model-facing tool. A tool that can rewrite config.yaml is a mis-invocation risk with no upside. Presets are applied by a human act: the CLI, or the pane.

One source of preset truth

Both halves read one file: presets/presets.json inside the installed package. That file is the only catalog v1 reads. The manifest declares no tools, no hooks, no middleware, and no settings (config_schema: {}).

03Try the CLI

Every verb is safe to explore: plan prints the diff and writes nothing. Add --json to any verb for a machine-readable receipt.

hermes group-model-sync preset list                           # ids + one-line descriptions
hermes group-model-sync preset show fleet-default             # every key that preset names
hermes group-model-sync plan  fleet-default --profiles a,b     # read-only diff; writes nothing
hermes group-model-sync apply fleet-default --profiles a,b --yes --verify
hermes group-model-sync verify --profiles a,b                  # read-back only (config + state.db)
hermes group-model-sync rollback --profile a                   # restore the newest backup
hermes group-model-sync doctor                                 # env, profiles, schema, version drift

Two modes without --yes: plain apply prints the plan and exits non-zero. --dry-run prints the plan and exits 0.

04Safe by design

The key scope is locked at six. A preset can touch these and nothing else:

KeyWhat it sets
model.providerprovider route for the profile
model.defaultdefault model
model.base_urlendpoint override
model.api_modeAPI mode
agent.reasoning_effortreasoning effort
fallback_providersfallback chain

Verification reads reality: apply --verify reads the target's state.db for usage rows of the declared model. "No usage rows yet" is reported as UNVERIFIED, never as success. --require-verified makes that fatal.

05Shipped presets

Three presets ship with the package. Two are samples. One is a real fleet array.

PresetWhat it is
fleet-defaultLabelled EXAMPLE ONLY. Illustrative machine-specific values (an opencode-go route) so plan has something real to diff against on a first run. Not a fleet default and not a recommendation.
minimalLabelled EXAMPLE ONLY. Illustrative values (a direct-deepseek route). Same rule: replace every value with your own before applying.
config-3A real guarded per-profile array: seven fleet profiles on three distinct routes, read 2026-09-17. It names no reasoning effort and no fallback chain, and it refuses every profile outside its seven.

The two example presets may be stale or invalid on another install. Replace every value with your own before applying. config-3 is guarded because one route names a model the gateway may treat as expensive, so applying it needs --confirm-expensive. Replace it with your own array before relying on it.

A preset with per-profile assignments (a named fleet array: one route per profile) applies only to the profiles it names. A target it does not name is refused with the assigned names listed. Presets never guess a route.

06Privacy disclosure

Capability boundary: the manifest declares no tools, no hooks, no middleware, and no settings (config_schema: {}). It does not hook the session loop and writes nothing outside the target profile's own config.yaml and backups.

07Source

MIT licensed. One unified package: agent half at the root, desktop half in desktop/plugin.js. In the official Hermes plugin catalog.

hermes-group-model-sync/
├── plugin.yaml              # manifest: no tools, no hooks, no settings
├── __init__.py              # register(ctx): CLI command + /gms command + bundled skill
├── plugin.py                # shared core: load, validate, diff, apply, verify, rollback
├── presets/
│   ├── presets.json         # the one source of preset truth (both halves read this)
│   └── README.md            # format, key scope, the absent-key rule
├── dashboard/
│   ├── manifest.json        # publishes the backend router to dashboard/desktop
│   ├── plugin_api.py        # FastAPI router: presets, plan, apply, profiles, status
│   └── config_core.py       # the single host-config write path (atomic, profile-scoped)
├── skills/group-model-sync/ # agent-facing how-to for the verbs
├── desktop/plugin.js        # desktop half: Groups, Agents, Presets tabs
├── test/                    # pytest + node suites
└── README.md
← Back to ASKA

Built by Aska Digital