<div align="center">
中文 · English
hermeslike-MoA
Hermes-style Mixture-of-Agents (MoA) request aggregator — runs every routed LLM call through a router → parallel reference advisors → aggregator streaming pipeline, with dual-provider failover and a V4P triple-gate cost guard.
</div>
---
hermeslike-moa is a DSH plugin (dsh.bundle). It registers a dsh-llm LlmAdapter (provider route deepseek-moa, plus go-moa when an OpenCode Go key is configured); every model request routed to those providers runs the MoA pipeline:
user request
→ V4F router (one call, JSON verdict: does the task warrant V4P?)
→ reference advisors ×N in parallel (V4F; Hermes-style advisor system prompt;
tool calls/results folded into plain text; tool results head+tail preview;
reference outputs redacted; synthetic user judgement instruction appended)
→ aggregator (model: explicit user choice first → router → V4P triple gate)
→ streaming passthrough (standard dsh-llm StreamChunk)The three model entries
The model picker offers three models:
| Model | Meaning |
|---|---|
deepseek-v4-mix (MoA Mix) | Full MoA pipeline: router → reference advisors ×N (flash, parallel) → aggregator (pro or flash) → stream. Costs N+2 calls (1 router + N refs + 1 aggregator); aggregator pro is V4P-gated |
deepseek-v4-pro | Direct single V4 Pro (no MoA overhead); still V4P-gated (anti-footgun: demotes to flash on empty budget or errors per settings) |
deepseek-v4-flash | Direct single V4 Flash (no MoA, cheapest/fastest; not gated) |
> Any unknown model id (outside the three above) is treated as flash direct — it never silently triggers the expensive MoA path.
Highlights
mixmodel category: the model picker now listsMoA Mix · 模型混合(deepseek-v4-mix) — selecting it pins the full MoA pipeline (a "simulate selection" entry); the aggregator model still follows settings/router;flash/proremain explicit aggregator choices.- Hermes-faithful advisory view (
lib/reference.js, modeled on Hermesmoa_loop.py): drops the acting agent's system prompt, renderstool_callsas[called tool: name(args)], folds each tool result (head+tail preview, 4000-char budget) into the preceding assistant turn, emits zero tool-role messages (strict-provider safe), appends a synthetic user judgement instruction so the view ends on user. - Redaction: centralized secret shapes (sk-/Bearer/JWT/private keys/DB URLs) + safe email/phone regexes (delimited, never mangling SHAs/IDs/dates).
- Context trim: rough token estimate, drop oldest frames, keep user-first invariant, keep trailing synthetic instruction.
- Dual channel: official (DeepSeek pay-as-you-go) + go (OpenCode Go subscription); go-preferred whole pipeline, auto-switch to official after 3 consecutive failures.
- V4P triple gate: budget multiple (look-ahead pool = F spend×ratio − P spend) + per-window cap + min interval.
- New-contract accounting: dsh-llm disjoint
TokenUsage(inputTokens= uncached input; cache read/write separate), rolling-window cost.
Install
# bundle: enters the profile layer stack (restart web)
dsh plugin --profile web add github:beimianism/Hermeslike-Mixagent-MoA
# or local dev path (use your own)
dsh plugin --profile web add /path/to/hermeslike-moa> Public @deepseek-ai/* and cordis deps are intentionally undeclared (injected by the profile pnpm closure).
System settings (recommended)
The plugin ships its own web settings page (Settings → Hermeslike MoA, rendered by its client half — the official Models page disables third-party provider editors). Every field has a ⓘ hover tooltip, and each API-key field shows a live health diagnostic (keyHealth):
- Enable / disable the MoA aggregator.
- API keys (type them right here, robustness-first): the form has two
write-only password fields — DeepSeek API key and OpenCode Go API key. Type a key directly in the settings UI and it takes effect (stored locally in settings.yaml, never echoed back, stripped on the wire); leave blank to fall back to the env refs (apiKeyEnv/goApiKeyEnv, resolved via credentials/environment). If both are empty: missing official key → requests fail 401; missing Go key → Go channel just disabled. Health shows "✓ valid / ✗ malformed reason" live.
- Model mix:
- reference advisor count (1–8, default 3) - reference temperatures (in order) - aggregator model: auto (router decides) / flash / pro (V4P-gated) — the Hermes aggregator-slot equivalent - prefer Go channel: OpenCode Go subscription first; auto-switch to official after 3 consecutive failures
- V4P triple gate: budget multiple / per-window cap / min interval /
degrade-to-flash on gate block
- Privacy: advisor-output redaction level
- API keys are configured in the credentials seam (referencing env var names
like DEEPSEEK_API_KEY, never literal secrets)
The settings document holds the hermeslike-moa: section; the plugin row config: in cordis.patch.yml acts as the composition base (user overrides win).
Configuration (composition base)
These fields default from the plugin row config: in cordis.patch.yml; user settings override them:
| Key | Default | Meaning |
|---|---|---|
apiKeyEnv / DEEPSEEK_API_KEY | DEEPSEEK_API_KEY | DeepSeek official key env ref |
goApiKeyEnv / OPENCODE_API_KEY | OPENCODE_API_KEY | OpenCode Go key env ref (empty disables Go) |
endpoint | https://api.deepseek.com/chat/completions | official endpoint |
goEndpoint | https://opencode.ai/api/v1/chat/completions | Go endpoint |
enabled | true | master switch |
ratio | 0.5 | V4P look-ahead pool ratio (F×ratio−P) |
windowMs | 3600000 | ledger rolling window |
refCount | 3 | reference advisor count |
refTemps | [0.5,0.8,1.1] | per-reference temperature |
aggregatorModel | auto | aggregator model (auto/flash/pro) |
preferGo | true | prefer Go channel |
fallbackToFlash | true | degrade V4F when gate blocks V4P |
minBudgetMultiple | 3 | gate: budget multiple |
maxProPerWindow | 3 | gate: V4P per-window cap |
minProIntervalMs | 900000 | gate: min interval |
Example:
- insert:
- id: hermeslike-moa
name: 'hermeslike-moa'
config:
apiKeyEnv: DEEPSEEK_API_KEY
goApiKeyEnv: OPENCODE_API_KEY
ratio: 0.5
refCount: 3Layout
hermeslike-moa/
├── package.json
├── cordis.patch.yml
├── index.js # apply(): config parse + registerAdapter
├── lib/
│ ├── adapter.js # MoaAdapter extends LlmAdapter (dual + failover)
│ ├── pipeline.js # MoaPipeline: route → refs×N → aggregate → stream
│ ├── router.js # V4F router + keyword fallback
│ ├── reference.js # Hermes advisory view: render/truncate/redact/trim
│ ├── wire.js # HTTP one-shot/stream + TokenUsage normalization
│ ├── ledger.js # spend ledger + V4P triple gate
│ ├── prices.js # price table
│ ├── prompts.js # three system prompts
│ └── settings.js # settings schema (web settings form) + resolution
└── README / README.enLicense
[MIT](./LICENSE)