Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
605 commits
Select commit Hold shift + click to select a range
f8ba265
fix(aux): trigger fallback on 429 rate-limit errors in auxiliary client
zeejaytan Apr 21, 2026
dbe9b15
chore: AUTHOR_MAP entry for zeejaytan
teknium1 May 5, 2026
e8e9147
fix(acp): preserve assistant reasoning metadata in session persistence
Aslaaen Apr 21, 2026
cc2c820
chore: AUTHOR_MAP entry for Aslaaen
teknium1 May 5, 2026
60235db
feat(cli): add list_picker_providers for credential-filtered picker
Tkander17 Apr 21, 2026
87b113c
chore: AUTHOR_MAP entry for Tkander1715
teknium1 May 5, 2026
0397be5
feat(tui): remove /provider alias for /model (#20358)
teknium1 May 5, 2026
3b75071
fix: resolve lazy session creation regressions (#18370 fallout) (#20363)
alt-glitch May 5, 2026
a628992
docs(web_tools): correct web_extract summarizer timeout comment
beardthelion May 5, 2026
ce9888b
docs(config): fix fallback provider config paths
LeonSGP43 May 5, 2026
27a8ba4
docs(prompt): clarify supported customization surfaces
Beandon13 May 5, 2026
c85a25f
chore: AUTHOR_MAP entry for Beandon13
teknium1 May 5, 2026
2d5f206
docs: remove dead reference links in flash-attention skill
WadydX Apr 23, 2026
58f93fb
docs: remove dead papers.md link from saelens references
WadydX Apr 23, 2026
0664bf9
docs: fix broken nix-setup anchor for container-aware CLI
WadydX Apr 23, 2026
41545f7
fix(telegram): keep DM topic typing scoped
helix4u May 5, 2026
d5357f8
refactor(telegram): make typing thread-id resolver symmetric with send
teknium1 May 5, 2026
c28c2a2
docs(tts): document per-provider max_text_length caps
r266-tech Apr 22, 2026
0dc677f
docs(skill/hermes-agent): sync slash commands + add durable-systems s…
teknium1 May 5, 2026
ee502e5
docs(cli): add --deliver-only flag to hermes webhook subscribe
r266-tech Apr 19, 2026
00d2559
perf(ui-tui): narrow overlay subscriptions to focused selectors
OutThisLife May 5, 2026
ec7f2f2
docs(cli): add skills reset subcommand to CLI reference
r266-tech Apr 17, 2026
f67063b
feat(kanban): generic diagnostics engine for task distress signals (#…
teknium1 May 5, 2026
72c33df
docs(agent): remove stale BuiltinMemoryProvider references from memor…
Bartok9 Apr 23, 2026
91f339b
docs(plugins): document ctx.dispatch_tool() in plugin capabilities table
r266-tech Apr 16, 2026
b6e4e40
docs(guide): add Dispatch tools from slash commands section
r266-tech Apr 16, 2026
e4723f6
docs(cron): add context_from chaining section
May 5, 2026
2b500ed
chore: AUTHOR_MAP entry for asimons81
teknium1 May 5, 2026
20a4f79
feat: provider modules — ProviderProfile ABC, 33 providers, fetch_mod…
kshitijk4poor May 5, 2026
9022804
feat(providers): make all 33 providers pluggable under plugins/model-…
teknium1 May 5, 2026
84ec276
docs(cli): expand hermes import reference — add description, warning,…
Sertug17 Apr 23, 2026
7b05ccd
docs(bedrock): fix IAM permissions, add quickstart entry, add fallbac…
JiaDe-Wu Apr 16, 2026
af312cc
docs: fix Camofox Docker setup instructions
wysie Apr 29, 2026
acca3ec
docs(providers): Together/Groq/Perplexity cookbook via custom_providers
perlowja Apr 25, 2026
794f487
fix(tui): close slash parity gaps with CLI (#20339)
OutThisLife May 5, 2026
b1476c7
docs(gemini): add Google Gemini guide
jethac Apr 28, 2026
8fa5a03
chore: AUTHOR_MAP entry for jethac
teknium1 May 5, 2026
0df80f4
docs: align terminal-backend count and naming across docs and code
deep-name May 3, 2026
7cc0008
chore: AUTHOR_MAP entry for deep-name
teknium1 May 5, 2026
3beef57
docs: refresh stale platform/LOC/test counts; clarify gateway vs plug…
deep-name May 3, 2026
80c579a
docs(skills): explain restoring bundled skills
LeonSGP43 May 3, 2026
398efdb
docs(docker): add section on connecting to local inference servers (v…
Magicray1217 Apr 19, 2026
de0ac21
docs(docker): document API_SERVER_* env vars for exposing the OpenAI-…
May 5, 2026
1b10371
chore: AUTHOR_MAP entry for CES4751
teknium1 May 5, 2026
5f8e59b
docs(discord): fix Server Members Intent + SSRC-mapping drift; add /v…
malaiwah May 5, 2026
15be493
docs(skills): modernize Obsidian file workflows
counterposition May 3, 2026
79902a0
chore: AUTHOR_MAP entry for counterposition
teknium1 May 5, 2026
5bd75c7
docs(kanban): document handoff evidence metadata
Fearvox May 4, 2026
bb2b129
chore: AUTHOR_MAP entry for Fearvox
teknium1 May 5, 2026
f13b349
docs: clarify Telegram group chat troubleshooting
LeonSGP43 May 2, 2026
ca8e688
docs(codex): clarify OAuth auth prerequisite
LeonSGP43 May 2, 2026
39560c9
docs(voice): add Doubao speech integration examples (TTS + STT)
Hypnus-Yuan Apr 30, 2026
391e3ff
chore: AUTHOR_MAP entry for Hypnus-Yuan
teknium1 May 5, 2026
144ba71
docs(faq): use messaging extra for gateway deps
xsfX20 Apr 30, 2026
587ef55
chore: AUTHOR_MAP entry for xsfX20
teknium1 May 5, 2026
1fc8733
fix(kanban): unify failure counter across spawn/timeout/crash outcome…
teknium1 May 5, 2026
9a0a4c5
docs(guides): add guide for running Hermes locally with Ollama
binhnt92 Apr 7, 2026
92a08c6
chore: AUTHOR_MAP entry for binhnt92
teknium1 May 5, 2026
1c42d8f
docs: add Open WebUI bootstrap script
Apr 14, 2026
a860a10
chore: AUTHOR_MAP entry for acesjohnny
teknium1 May 5, 2026
a11234d
docs(browser): document WSL-to-Windows Chrome MCP bridge
liu-collab Apr 12, 2026
a321874
chore: AUTHOR_MAP entry for liu-collab
teknium1 May 5, 2026
74e4f5f
docs(i18n): add zh-Hans Tool Gateway, image gen, and Windows WSL guide
haidao1919 Apr 17, 2026
05cdcac
docs: add Chinese (zh-CN) README translation
zhanggttry Apr 21, 2026
f97d022
chore: AUTHOR_MAP entry for zhanggttry
teknium1 May 5, 2026
0d945d1
docs: update VS Code setup instructions for ACP Client integration
formulahendry Apr 19, 2026
50ab0a8
chore: AUTHOR_MAP entry for formulahendry
teknium1 May 5, 2026
0b9cbc8
test(kanban): cover metadata handoff round-trip
Fearvox May 4, 2026
f0d2784
feat(gateway): respect kanban.max_spawn config to limit concurrent tasks
momowind May 4, 2026
56b4795
guard kanban worker lifecycle by run id
misery-hl May 4, 2026
1efed67
chore(release): AUTHOR_MAP entries for momowind and misery-hl
teknium1 May 5, 2026
3082fa0
feat(hindsight): probe API for update_mode='append' support, dedupe a…
nicoloboschi May 5, 2026
3188e63
fix(api_server): SSE token batching + error handling for Open WebUI p…
bogerman1 May 5, 2026
ee8edd4
chore: AUTHOR_MAP entry for bogerman1
teknium1 May 5, 2026
0d41e94
feat(i18n): add French (fr) locale support
May 5, 2026
c4b287b
feat(i18n): add Ukrainian locale
olisikh May 5, 2026
735349c
chore: AUTHOR_MAP entry for olisikh
teknium1 May 6, 2026
2d4eaed
arcee temperature + compression
rob-maron May 5, 2026
f0b95cc
test(arcee): cover Trinity Large Thinking temperature + compression o…
teknium1 May 6, 2026
eda326d
fix(doctor): report Kanban worker tools as runtime-gated
suncokret12 May 1, 2026
6d302b3
fix(kanban): accept created_cards linked as child of completing task
LeonSGP43 May 5, 2026
b28ab4f
fix(kanban): measure max runtime from current run
mioimotoai-lgtm May 4, 2026
8a1a42d
test(kanban): backdate task_runs.started_at alongside tasks.started_at
teknium1 May 5, 2026
d2c6ece
fix(kanban): prevent child task dispatch when parent is not done
SimbaKingjoe May 4, 2026
3f97297
feat(kanban): surface task_runs.summary on dashboard cards + ``kanban…
Brecht-H May 5, 2026
a49670c
fix(kanban): wire dependency selects
LeonSGP43 May 5, 2026
fab3ad9
chore(release): AUTHOR_MAP entries for suncokret12 and mioimotoai-lgtm
teknium1 May 5, 2026
9851338
feat(i18n): add Turkish (tr) locale
etherman-os May 5, 2026
39f451f
fix: add Turkish locale references in config, tests, and docs
etherman-os May 5, 2026
e598e18
docs: document custom model aliases for /model command (#20475)
teknium1 May 6, 2026
477e4a2
feat(models): add deepseek/deepseek-v4-pro to OpenRouter + Nous Porta…
teknium1 May 6, 2026
f27fcb6
feat(models): add x-ai/grok-4.3 to OpenRouter + Nous Portal curated l…
teknium1 May 6, 2026
aa88dcc
fix: salvage batch — compaction guidance, memory authority, cache evi…
kshitijk4poor May 6, 2026
395dbcc
feat(browser): add Lightpanda engine support with automatic Chrome fa…
kshitijk4poor May 4, 2026
3ebdd26
fix(browser): surface Lightpanda Chrome fallback warnings
kshitijk4poor May 6, 2026
d78c349
feat(tui): collapsible sections in startup banner (skills, system pro…
kshitijk4poor May 6, 2026
68162eb
fix(tui): collapse long system messages in transcript with expand toggle
kshitijk4poor May 6, 2026
629d8b8
fix(browser): tighten Lightpanda fallback edge cases
kshitijk4poor May 6, 2026
466f3a1
fix(gateway): preserve model picker current context
helix4u May 6, 2026
a6f5f9c
fix(update): drop pip --quiet so slow installs don't look hung (#20679)
teknium1 May 6, 2026
e70e490
fix(cli): guard logger.debug in signal handler (#13710 regression) (#…
teknium1 May 6, 2026
043a118
fix: harden install.sh against inherited Python env leakage
adybag14-cyber May 5, 2026
a869a52
chore: AUTHOR_MAP entry for adybag14-cyber
teknium1 May 6, 2026
e45df2e
fix(ui): reduce status-line jitter while scrolling
adybag14-cyber May 5, 2026
ca5febf
fix(tui): stabilize FaceTicker elapsed width to prevent composer drift
adybag14-cyber May 6, 2026
a0556b8
fix(tui): restore gap before duration when verb segment is hidden
teknium1 May 6, 2026
b1e0ef8
chore(release): map liuguangyong@hellobike -> liuguangyong93
teknium1 May 6, 2026
1768791
fix(kanban): reset code element background inside board
May 6, 2026
76074d9
fix(cli): recover classic CLI output after resize
helix4u May 5, 2026
b045e7a
feat(skills): add shop-app personal shopping assistant (optional) (#2…
teknium1 May 6, 2026
a0fedfb
feat(checkpoints): v2 single-store rewrite with real pruning + disk g…
teknium1 May 6, 2026
906881c
fix(cli): catch OSError in _resolve_attachment_path to prevent ENAMET…
curiouscleo May 5, 2026
3ce1233
chore(release): map cleo@edaphic.xyz → curiouscleo
teknium1 May 6, 2026
90a7adc
docs(wsl2): expand Windows (WSL2) guide — filesystem, networking, ser…
teknium1 May 6, 2026
b62a82e
docs: pluggable surfaces coverage — model-provider guide, full plugin…
teknium1 May 6, 2026
63c51d8
change: enable ruff/ty
ethernet8023 May 4, 2026
9627ee7
feat(ci): add typecheck (warnings only in CI)
ethernet8023 May 4, 2026
ad7aad2
feat(skills/linear): add Documents support + Python helper script (#2…
teknium1 May 6, 2026
773cf48
docs(plugins): close the gaps \u2014 image-gen-provider-plugin guide …
teknium1 May 6, 2026
a24789d
fix(opencode-go): keep users on opencode-go instead of hijacking to n…
teknium1 May 6, 2026
6388aaf
feat(dashboard): add 'default-large' built-in theme with 18px base si…
teknium1 May 6, 2026
cd2cbc7
refactor(web): per-capability backend selection for search/extract split
kshitijk4poor May 6, 2026
5c906d7
feat(web): add SearXNG as a native search-only backend
kshitijk4poor May 6, 2026
94016dd
docs+skill: add searxng-search optional skill and documentation
kshitijk4poor May 6, 2026
48c2418
docs: add Web Search + Extract feature page with SearXNG setup guide
kshitijk4poor May 6, 2026
441ef75
fix(feishu): keep topic replies in threads
yuqianma May 4, 2026
28299af
chore: follow-up cleanup for Feishu topic thread fix
kshitijk4poor May 6, 2026
b1d420e
fix(kanban): avoid fragile failure-column renames
helix4u May 6, 2026
a2ff193
chore: follow-up cleanup for Kanban migration fix
kshitijk4poor May 6, 2026
a345f7b
Merge pull request #19908 from NousResearch/typecheck
ethernet8023 May 6, 2026
946ef0e
fix(tui): bound virtual history offset searches
asheriif May 5, 2026
f4031df
ci(docker): don't cancel overlapping builds, guard :latest
ethernet8023 May 6, 2026
d514dd4
docs(tool-gateway): rewrite as pitch-first marketing page (#20827)
teknium1 May 6, 2026
33bf5f6
fix(auth): fall back to global-root auth.json for providers missing i…
teknium1 May 6, 2026
b71f80e
feat(gateway): per-platform gateway_restart_notification flag
guillaumemeyer May 6, 2026
7df6115
feat(gateway): also gate pre-restart "Gateway restarting" notification
guillaumemeyer May 6, 2026
d8b85bf
chore: add guillaumemeyer to AUTHOR_MAP
teknium1 May 6, 2026
5044e1c
fix(cli): submit LF enter in thin PTYs (#20896)
OutThisLife May 6, 2026
da60198
fix(tui): refresh virtual offsets after row resize (#20898)
OutThisLife May 6, 2026
f1a8e99
fix(tui): honor skin highlight colors (#20895)
OutThisLife May 6, 2026
53a0249
Merge pull request #20890 from NousResearch/fix/docker-push
ethernet8023 May 6, 2026
5ccab51
fix(tui): steady transcript scrollbar (#20917)
OutThisLife May 6, 2026
04cf478
fix(tui): restore voice push-to-talk parity (#20897)
OutThisLife May 6, 2026
3cdbf33
fix(gateway): don't dead-end setup wizard when only system-scope unit…
teknium1 May 6, 2026
d797755
fix(gateway): wait for systemd restart readiness
helix4u May 6, 2026
5a3cadf
fix(discord): narrow rate-limit catch and move sync state under gateway/
teknium1 May 7, 2026
45cbf93
docs(kanban): fix orchestrator skill setup instructions (#20958)
helix4u May 7, 2026
49c3c2e
docs(kanban): fix worker skill setup instructions too (#20960)
teknium1 May 7, 2026
51f9953
feat(profiles): --no-skills flag for empty profile creation (#20986)
teknium1 May 7, 2026
bd0c54d
fix: route Telegram image documents through photo handling
mrcoferland May 2, 2026
e7eb07c
chore: AUTHOR_MAP entry for mrcoferland
teknium1 May 7, 2026
033e533
test(docker): align Dockerfile contract tests with simplified TUI flow
Sanjays2402 May 2, 2026
595bcc8
test(update): patch isatty on real streams to fix xdist-flaky --yes t…
Sanjays2402 May 2, 2026
a5c9c83
fix(web): force light color-scheme on docs iframe
counterposition May 4, 2026
7d36e83
fix(security): close TOCTOU window when saving MCP OAuth credentials
Gutslabs May 7, 2026
aa56903
chore(release): add Gutslabs to AUTHOR_MAP for PR #21148 salvage
teknium1 May 7, 2026
1f27ca6
test(update): teach restart-mocks about the post-update survivor sweep
Sanjays2402 May 2, 2026
11b9b14
fix(image-routing): expose attached image paths in native multimodal …
briandevans May 3, 2026
fce58cb
feat(optional-skills): port Anthropic financial-services skills as op…
teknium1 May 7, 2026
d4de7d4
test(skills): cover additional rescan paths in skill_commands cache (…
Tranquil-Flow May 3, 2026
7c0766e
fix(gateway): translate inbound document host paths to container path…
ambition0802 May 2, 2026
bf843ad
feat(gateway): opt-in cleanup of temporary progress bubbles (#21186)
teknium1 May 7, 2026
40b51c9
fix(kanban): heartbeat tool extends claim TTL, not just last_heartbea…
stephen0110 May 7, 2026
63bd690
chore(release): map stephen0110 noreply email
teknium1 May 7, 2026
06f2435
fix(kanban): stop reclaimed workers before retry
LeonSGP43 May 7, 2026
b49a3f8
fix(kanban): reap completed worker children in dispatch_once
sonic-netizen May 7, 2026
595e906
chore(release): map sonic-netizen noreply email
teknium1 May 7, 2026
411cfa2
fix: auto-block repeated kanban retries
mwnickerson May 6, 2026
233bfd3
chore(release): map mwnickerson noreply email
teknium1 May 7, 2026
fad684b
feat(gateway): auto-resume interrupted sessions after restart
kyan12 May 6, 2026
961a353
fix(gateway): preserve resume marker on interrupted restart
kyan12 May 6, 2026
38b1c7d
refactor(gateway): simplify auto-resume + extend to crash recovery
teknium1 May 7, 2026
a84e56d
fix(auth): sync shared Nous refresh tokens
quocanh261997 May 5, 2026
429e785
refactor(auth): dedupe file-lock helper; document Nous lock order
teknium1 May 7, 2026
8a96fa4
fix(gateway): avoid duplicated responses history
thelumiereguy May 2, 2026
73d6371
chore: add AUTHOR_MAP entries for thelumiereguy and counterposition
teknium1 May 7, 2026
6e8f1e0
fix(gateway): use monotonic deadlines in QR onboarding flows
Zyproth May 5, 2026
2e00bca
fix(oauth,gateway): monotonic deadlines for polling/timeout loops
teknium1 May 7, 2026
3a0d52d
fix(weixin): replace all aiohttp ClientTimeout with asyncio.wait_for()
May 3, 2026
ecaafe5
test(weixin): update timeout assertion for asyncio.wait_for migration
teknium1 May 7, 2026
d856f45
chore: AUTHOR_MAP entry for chenlinfeng@ruije / @noOne-list
teknium1 May 7, 2026
fb1ce79
feat(security): enable secret redaction by default (#17691, #20785) (…
teknium1 May 7, 2026
8b32a9d
feat: add Discord message deletion action
May 3, 2026
991df4e
chore: AUTHOR_MAP entry for @likejudy
teknium1 May 7, 2026
042eb93
fix(security): close TOCTOU window in hermes_cli/auth.py credential w…
teknium1 May 7, 2026
6969203
fix(delegate): correct ACP docs — Claude Code CLI has no --acp flag
liuhao1024 May 3, 2026
5bf12eb
fix: exclude hidden and archive dirs from _find_skill rglob
Kailigithub May 3, 2026
176b935
fix(gateway): preserve thread routing from cached live session sources
Zyproth May 5, 2026
333598c
fix(gateway): cap cached session sources with LRU eviction
teknium1 May 7, 2026
4f364c4
fix(mcp): give 'mcp add --command' a distinct argparse dest
discodirector May 4, 2026
f0dd5b9
chore: add discodirector email to AUTHOR_MAP
teknium1 May 7, 2026
8d363f8
fix(bedrock): preserve reasoningContent across converse normalization
molvikar May 5, 2026
d34f03c
feat(gateway): support [[as_document]] directive for skill media routing
leon7609 May 3, 2026
e82f3b0
test: update send_message_tool mocks for force_document kwarg
teknium1 May 7, 2026
4e27e4e
chore: AUTHOR_MAP entry for @leon7609
teknium1 May 7, 2026
abe5a3c
fix(model_switch): live model discovery for custom_providers in /mode…
0oAstro May 3, 2026
7137ccc
fix(memory): support OpenViking local resource uploads
ggnnggez Apr 15, 2026
187951e
test(memory): harden OpenViking local upload coverage
ehz0ah May 4, 2026
2b6345c
fix(memory): harden OpenViking local path uploads
ehz0ah May 4, 2026
aa9a209
chore(release): add AUTHOR_MAP entries for ggnnggez and ehz0ah
teknium1 May 7, 2026
699c770
docs(readme): drop misleading RL install-extras claim, defer to CONTR…
deep-name May 3, 2026
fdb9e0f
fix(kanban): auto-block workers that exit without completing (#20894)…
teknium1 May 7, 2026
a0758cd
fix(dashboard): stabilize embedded chat resume and scrollback
nouseman666 May 3, 2026
8aceef5
fix(dashboard): let embedded chat use a single scroll system
nouseman666 May 3, 2026
7cbef2b
fix(dashboard): route browser wheel into inner TUI scrolling
nouseman666 May 3, 2026
eef2335
chore: AUTHOR_MAP entry for @nouseman666
teknium1 May 7, 2026
6d9b306
fix(cli): honor positive tool preview length
GinWU05 May 3, 2026
3c8154e
chore: AUTHOR_MAP entry for @GinWU05
teknium1 May 7, 2026
e38ea38
fix(credential_pool): resolve key mix-up when custom providers share …
May 3, 2026
103e119
feat(cli): show context compression count in status bar
TruaShamu May 1, 2026
f5a232a
refactor: replace 'cmp' text with 🗜️ emoji in status bar
TruaShamu May 2, 2026
3a82172
feat(tui): surface compression count in Ink status bar
teknium1 May 7, 2026
bda7b24
chore(release): map altriatree@gmail.com -> @TruaShamu
teknium1 May 7, 2026
6b9f714
fix(curator): make manual runs synchronous
LeonSGP43 May 6, 2026
6b3a9b4
docs(curator): update CLI docs for synchronous-by-default manual run
teknium1 May 7, 2026
d8d57fb
fix(install): remove uv exclude-newer cutoff
LeonSGP43 May 4, 2026
43a6645
docs: clarify API server tool execution locality
pingchesu May 3, 2026
36ad973
fix(kanban): treat dashboard event-stream cancellation as normal shut…
SandroHub013 May 6, 2026
a5f116f
chore(release): map SandroHub013 email
teknium1 May 7, 2026
fe4748e
test(kanban): regression for CancelledError swallow in stream_events
teknium1 May 7, 2026
61d9e33
fix(model_tools): log plugin hook exceptions instead of silently swal…
sprmn24 May 4, 2026
3c439ec
feat(gateway): add `hermes gateway list` to show all profiles' gatewa…
cixuuz May 3, 2026
c4a7992
fix(mcp-oauth): persist OAuth server metadata across process restarts…
teknium1 May 7, 2026
12289c2
feat: add SSE transport support for MCP client
andrewhosf May 3, 2026
0214858
fix(browser): enforce cloud-metadata SSRF floor in hybrid routing (#1…
teknium1 May 7, 2026
0d3593e
fix: WhatsApp bridge process leak and disable config asymmetry
liuhao1024 May 3, 2026
647f95b
docs(contributing): align tool discovery and test runner with AGENTS.md
xxxigm May 6, 2026
b9f1ac8
fix(kanban): make dashboard board pin authoritative over server curre…
teknium1 May 7, 2026
e9685a5
fix: avoid unsupported anthropic context beta by default
abhinav11082001-stack May 3, 2026
b12a5a7
Follow latest child session on dashboard resume
CCClelo May 3, 2026
6e250a5
fix(openviking): add Bearer auth header and omit empty/legacy tenant …
teknium1 May 7, 2026
c3be6ec
feat: add transform_llm_output plugin hook
JezzaHehn May 6, 2026
47bf5d7
test+docs: cover transform_llm_output hook + release author map
teknium1 May 7, 2026
ae1f058
feat(curator): add `hermes curator list-archived` command (#21236)
teknium1 May 7, 2026
5b24c0f
fix: require memory schema fields by action
altmazza0-star May 3, 2026
2c14d3b
fix(tui): refresh scroll height at cached bottom
counterposition May 6, 2026
8308d18
fix(gateway): preserve max turns after env reload
altmazza0-star May 3, 2026
ef1e565
fix(discord): scope DISCORD_ALLOWED_ROLES to originating guild (CVSS …
0xyg3n Apr 18, 2026
5c045b8
fix(discord): extend role-scope fix to slash surface + fixture update
teknium1 May 7, 2026
80717a1
fix(discord): route DM role-auth opt-in through config.yaml (not env …
teknium1 May 7, 2026
e735089
fix(agent): avoid persisting empty-response recovery scaffolding
wxst May 3, 2026
2021c18
fix(agent): drop terminal empty-response sentinels
wxst May 3, 2026
8dcdc3c
fix(auth): keep Spotify logout from resetting model config
LeonSGP43 May 3, 2026
6e46f99
fix(tui): surface backend error as visible text when final_response i…
teknium1 May 7, 2026
14f3882
fix(models): prefer image modalities for vision routing
LeonSGP43 May 3, 2026
5ead126
fix(doctor): retry DashScope China endpoint
LeonSGP43 May 3, 2026
5cf7032
fix(image-routing): sniff magic bytes for image MIME, ignore misleadi…
shashwatgokhe May 3, 2026
afbcca0
chore: AUTHOR_MAP entry for @shashwatgokhe
teknium1 May 7, 2026
84287b0
fix(docker): refuse root gateway runs in official image
LeonSGP43 May 3, 2026
e5f3976
chore: sync with upstream main (2026-05-07)
May 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 142 additions & 3 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,32 @@ on:
permissions:
contents: read

# Top-level concurrency: do NOT cancel in-flight builds when a new push lands.
# Every commit deserves its own SHA-tagged image in the registry, and we guard
# the :latest tag in a separate job below (with its own concurrency group) so
# a slow run can't clobber :latest with older bits.
concurrency:
group: docker-${{ github.ref }}
cancel-in-progress: true
cancel-in-progress: false

jobs:
build-and-push:
# Only run on the upstream repository, not on forks
if: github.repository == 'NousResearch/hermes-agent'
runs-on: ubuntu-latest
timeout-minutes: 60
outputs:
pushed_sha_tag: ${{ steps.mark_pushed.outputs.pushed }}
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
submodules: recursive
# Fetch enough history to run `git merge-base --is-ancestor` in the
# move-latest job. That job reuses this checkout via its own
# actions/checkout call, but commits reachable from main up to ~1000
# back are plenty for any realistic race window.
fetch-depth: 1000

- name: Set up QEMU
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3
Expand Down Expand Up @@ -74,18 +85,30 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Push multi-arch image (main branch)
# Always push a per-commit SHA tag on main. This is race-free because
# every commit has a unique SHA — concurrent runs can't clobber each
# other here. We also embed the git SHA as an OCI label so the
# move-latest job (below) can read it back off the registry's `:latest`.
- name: Push multi-arch image with SHA tag (main branch)
id: push_sha
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with:
context: .
file: Dockerfile
push: true
platforms: linux/amd64,linux/arm64
tags: nousresearch/hermes-agent:latest
tags: nousresearch/hermes-agent:sha-${{ github.sha }}
labels: |
org.opencontainers.image.revision=${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Mark SHA tag pushed
id: mark_pushed
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: echo "pushed=true" >> "$GITHUB_OUTPUT"

- name: Push multi-arch image (release)
if: github.event_name == 'release'
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
Expand All @@ -97,3 +120,119 @@ jobs:
tags: nousresearch/hermes-agent:${{ github.event.release.tag_name }}
cache-from: type=gha
cache-to: type=gha,mode=max

# Second job: moves `:latest` to point at the SHA tag the first job pushed.
#
# Has its own concurrency group with `cancel-in-progress: true`, which
# gives us the serialization we need: if a newer push arrives while an
# older run is mid-way through this job, the older run is cancelled
# before it can clobber `:latest`. Combined with the ancestor check
# below, this means `:latest` only ever moves forward in git history.
move-latest:
if: |
github.repository == 'NousResearch/hermes-agent'
&& github.event_name == 'push'
&& github.ref == 'refs/heads/main'
&& needs.build-and-push.outputs.pushed_sha_tag == 'true'
needs: build-and-push
runs-on: ubuntu-latest
timeout-minutes: 10
concurrency:
group: docker-move-latest-${{ github.ref }}
cancel-in-progress: true
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 1000

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3

- name: Log in to Docker Hub
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

# Read the git revision label off the current `:latest` manifest, then
# use `git merge-base --is-ancestor` to check whether our commit is a
# descendant of it. If `:latest` doesn't exist yet, or its label is
# missing, we treat that as "safe to publish". If another run already
# advanced `:latest` past us (or diverged), we skip and leave it alone.
- name: Decide whether to move :latest
id: latest_check
run: |
set -euo pipefail
image=nousresearch/hermes-agent

# Pull the JSON for the linux/amd64 sub-manifest's config and extract
# the OCI revision label with jq — Go template field access can't
# handle dots in map keys, so using json+jq is the robust route.
image_json=$(
docker buildx imagetools inspect "${image}:latest" \
--format '{{ json (index .Image "linux/amd64") }}' \
2>/dev/null || true
)

if [ -z "${image_json}" ]; then
echo "No existing :latest (or inspect failed) — safe to publish."
echo "push_latest=true" >> "$GITHUB_OUTPUT"
exit 0
fi

current_sha=$(
printf '%s' "${image_json}" \
| jq -r '.config.Labels."org.opencontainers.image.revision" // ""'
)

if [ -z "${current_sha}" ]; then
echo "Registry :latest has no revision label — safe to publish."
echo "push_latest=true" >> "$GITHUB_OUTPUT"
exit 0
fi

echo "Registry :latest is at ${current_sha}"
echo "This run is at ${GITHUB_SHA}"

if [ "${current_sha}" = "${GITHUB_SHA}" ]; then
echo ":latest already points at our SHA — nothing to do."
echo "push_latest=false" >> "$GITHUB_OUTPUT"
exit 0
fi

# Make sure we have the :latest commit locally for merge-base.
if ! git cat-file -e "${current_sha}^{commit}" 2>/dev/null; then
git fetch --no-tags --prune origin \
"+refs/heads/main:refs/remotes/origin/main" \
|| true
fi

if ! git cat-file -e "${current_sha}^{commit}" 2>/dev/null; then
echo "Registry :latest points at an unknown commit (${current_sha}); refusing to overwrite."
echo "push_latest=false" >> "$GITHUB_OUTPUT"
exit 0
fi

# Our SHA must be a descendant of the current :latest to be safe.
if git merge-base --is-ancestor "${current_sha}" "${GITHUB_SHA}"; then
echo "Our commit is a descendant of :latest — safe to advance."
echo "push_latest=true" >> "$GITHUB_OUTPUT"
else
echo "Another run advanced :latest past us (or diverged) — leaving it alone."
echo "push_latest=false" >> "$GITHUB_OUTPUT"
fi

# Retag the already-pushed SHA manifest as :latest. This is a registry-
# side operation — no rebuild, no layer re-push — so it's quick and
# atomic per-tag. The ancestor check above plus the cancel-in-progress
# concurrency on this job together guarantee we only ever move :latest
# forward in git history.
- name: Move :latest to this SHA
if: steps.latest_check.outputs.push_latest == 'true'
run: |
set -euo pipefail
image=nousresearch/hermes-agent
docker buildx imagetools create \
--tag "${image}:latest" \
"${image}:sha-${GITHUB_SHA}"
151 changes: 151 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
name: Lint (ruff + ty)

# Surface ruff and ty diagnostics as a diff vs the target branch.
# This check is advisory only ATM it always exits zero and never blocks merge.
# It posts a Markdown summary to the workflow run and, for pull requests,
# comments the same summary on the PR.

on:
push:
branches: [main]
paths-ignore:
- "**/*.md"
- "docs/**"
- "website/**"
pull_request:
branches: [main]
paths-ignore:
- "**/*.md"
- "docs/**"
- "website/**"

permissions:
contents: read
pull-requests: write # needed to post/update PR comments

concurrency:
group: lint-${{ github.ref }}
cancel-in-progress: true

jobs:
lint-diff:
name: ruff + ty diff
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0 # need full history for merge-base + worktree

- name: Install uv
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5

- name: Install ruff + ty
run: |
uv tool install ruff
uv tool install ty

- name: Determine base ref
id: base
run: |
# For PRs, diff against the merge base with the target branch.
# For pushes to main, diff against the previous commit on main.
if [ "${{ github.event_name }}" = "pull_request" ]; then
BASE_SHA=$(git merge-base "origin/${{ github.base_ref }}" HEAD)
BASE_REF="origin/${{ github.base_ref }}"
else
BASE_SHA=$(git rev-parse HEAD~1 2>/dev/null || git rev-parse HEAD)
BASE_REF="HEAD~1"
fi
echo "sha=${BASE_SHA}" >> "$GITHUB_OUTPUT"
echo "ref=${BASE_REF}" >> "$GITHUB_OUTPUT"
echo "Base SHA: ${BASE_SHA}"
echo "Base ref: ${BASE_REF}"

- name: Run ruff + ty on HEAD
run: |
mkdir -p .lint-reports/head
ruff check --output-format json --exit-zero \
> .lint-reports/head/ruff.json || true
ty check --output-format gitlab --exit-zero \
> .lint-reports/head/ty.json || true
echo "HEAD ruff: $(wc -c < .lint-reports/head/ruff.json) bytes"
echo "HEAD ty: $(wc -c < .lint-reports/head/ty.json) bytes"

- name: Run ruff + ty on base (via git worktree)
run: |
mkdir -p .lint-reports/base
# Use a worktree so we don't clobber the main checkout. If the basex
# SHA is identical to HEAD (e.g. first commit), skip and leave the
# base reports empty — the diff script handles missing files.
HEAD_SHA=$(git rev-parse HEAD)
BASE_SHA="${{ steps.base.outputs.sha }}"
if [ "$BASE_SHA" = "$HEAD_SHA" ]; then
echo "Base SHA == HEAD SHA, skipping base scan."
echo '[]' > .lint-reports/base/ruff.json
echo '[]' > .lint-reports/base/ty.json
else
git worktree add --detach /tmp/lint-base "$BASE_SHA"
(
cd /tmp/lint-base
ruff check --output-format json --exit-zero \
> "$GITHUB_WORKSPACE/.lint-reports/base/ruff.json" || true
ty check --output-format gitlab --exit-zero \
> "$GITHUB_WORKSPACE/.lint-reports/base/ty.json" || true
)
git worktree remove --force /tmp/lint-base
fi
echo "base ruff: $(wc -c < .lint-reports/base/ruff.json) bytes"
echo "base ty: $(wc -c < .lint-reports/base/ty.json) bytes"

- name: Generate diff summary
run: |
python scripts/lint_diff.py \
--base-ruff .lint-reports/base/ruff.json \
--head-ruff .lint-reports/head/ruff.json \
--base-ty .lint-reports/base/ty.json \
--head-ty .lint-reports/head/ty.json \
--base-ref "${{ steps.base.outputs.ref }}" \
--head-ref "${{ github.event_name == 'pull_request' && github.head_ref || github.ref_name }}" \
--output .lint-reports/summary.md
cat .lint-reports/summary.md >> "$GITHUB_STEP_SUMMARY"

- name: Upload reports as artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: lint-reports
path: .lint-reports/
retention-days: 14

- name: Post / update PR comment
if: github.event_name == 'pull_request'
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
with:
script: |
const fs = require('fs');
const body = fs.readFileSync('.lint-reports/summary.md', 'utf8');
const marker = '<!-- lint-diff-summary -->';
const fullBody = marker + '\n' + body;

const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const existing = comments.find(c => c.body && c.body.includes(marker));
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body: fullBody,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: fullBody,
});
}
26 changes: 26 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ hermes-agent/
├── plugins/ # Plugin system (see "Plugins" section below)
│ ├── memory/ # Memory-provider plugins (honcho, mem0, supermemory, ...)
│ ├── context_engine/ # Context-engine plugins
│ ├── model-providers/ # Inference backend plugins (openrouter, anthropic, gmi, ...)
│ ├── kanban/ # Multi-agent board dispatcher + worker plugin
│ ├── hermes-achievements/ # Gamified achievement tracking
│ ├── observability/ # Metrics / traces / logs plugin
Expand Down Expand Up @@ -512,6 +513,31 @@ generic plugin surface (new hook, new ctx method) — never hardcode
plugin-specific logic into core. PR #5295 removed 95 lines of hardcoded
honcho argparse from `main.py` for exactly this reason.

### Model-provider plugins (`plugins/model-providers/<name>/`)

Every inference backend (openrouter, anthropic, gmi, deepseek, nvidia, …)
ships as a plugin here. Each plugin's `__init__.py` calls
`providers.register_provider(ProviderProfile(...))` at module load.
`providers/__init__.py._discover_providers()` is a **lazy, separate
discovery system** — scanned on first `get_provider_profile()` or
`list_providers()` call, NOT by the general PluginManager.

Scan order:
1. Bundled: `<repo>/plugins/model-providers/<name>/`
2. User: `$HERMES_HOME/plugins/model-providers/<name>/`
3. Legacy: `<repo>/providers/<name>.py` (back-compat)

User plugins of the same name override bundled ones — `register_provider()`
is last-writer-wins. This lets third parties swap out any built-in
profile without a repo patch.

The general PluginManager records `kind: model-provider` manifests but does
NOT import them (would double-instantiate `ProviderProfile`). Plugins
without an explicit `kind:` get auto-coerced via a source-text heuristic
(`register_provider` + `ProviderProfile` in `__init__.py`).

Full authoring guide: `website/docs/developer-guide/model-provider-plugin.md`.

### Dashboard / context-engine / image-gen plugin directories

`plugins/context_engine/`, `plugins/image_gen/`, `plugins/example-dashboard/`,
Expand Down
Loading
Loading