feat(providers): add full Hermes agent support - #7168
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
One finding in the web icon layer. The rest of the in-scope web changes (provider icon map, driver metadata, model placeholder, picker option, diagnostics regex, display-name switch) follow the existing per-provider registration patterns.
Posted via Macroscope — UI Consistency
ApprovabilityVerdict: Needs human review 1 blocking correctness issue found. This PR introduces a complete new provider driver (Hermes) with ~2900 lines of new code including session management, turn handling, permissions, and text generation. New features of this scope require human review. Additionally, there are unresolved high-severity findings about error handling in the session/turn management logic. You can customize Macroscope's approvability policy. Learn more. |
Replace the U+2624 text glyph (which depends on host font coverage and renders as a missing-glyph box on some platforms) with a hand-drawn vector caduceus in both the web and mobile provider icons. Also drops the hardcoded aria-hidden on the web icon so callers can override it.
There was a problem hiding this comment.
Reviewed the new Hermes Effect code (driver, adapter, ACP support, provider snapshot, text generation) against the service conventions.
Service definition, module layout, dependency acquisition (yield* Foo.Foo), namespace imports, catchTags usage, and predicate exports all look consistent with the conventions. Three findings, all the same error-modeling rule: the wrapper's detail (and therefore its message) is derived from cause.message instead of stable structural attributes. cause is already preserved in each case, so the underlying text stays available without being copied into the wrapper. ClaudeAdapter.ts (e.g. detail: "Failed to read attachment file.") shows the compliant form already used in this repo.
Posted via Macroscope — Effect Service Conventions
Address review findings on the Hermes provider: - sendTurn accounting now runs under the per-thread lock (mirroring the hardened GrokAdapter path): the active turn id is bound atomically with the in-flight count, so concurrent steers can no longer both treat themselves as a fresh turn and emit duplicate turn.started events. - image steers check interruptedTurnIds after cancelling and awaiting the superseded prompt, so a Stop arriving during steer preparation no longer submits a fresh prompt (interrupt guard equivalent to Grok's). - interruptTurn registers the interrupted turn id under the same thread lock before cancelling the ACP session. - model discovery keeps the built-in 'default' entry when Hermes reports currentModelId 'default', instead of forcing clients onto the first concrete model (adds regression test). - error detail strings are stable and bounded; cause text and paths stay in the cause field, matching repo convention.
Validate prompt content before binding the session to the new turn id and emitting turn.started, and clear the active turn id when a fresh turn is rejected, so an empty sendTurn can no longer leave a phantom running turn.
There was a problem hiding this comment.
One finding on the new web provider icon: its color contract differs from every other entry in PROVIDER_ICON_BY_PROVIDER, which makes it the only provider glyph whose tone changes with the surrounding text color.
Posted via Macroscope — UI Consistency
Match the other provider icons: explicit theme-aware fill instead of fill-current, so the icon keeps full contrast in muted-foreground rows.
- emit turn.completed(cancelled) when an image steer is interrupted, so the superseded prompt's skipped completion cannot leave the thread running forever - check interruptedTurnIds after prompt preparation on the normal path too, so a stop during attachment I/O/config cannot publish a late turn.started - clear the active turn id on every fresh-turn preparation failure (invalid attachment, read error, empty prompt, interrupt), not just the empty-prompt path, so a concurrent sendTurn cannot misclassify itself as a steer - drop the per-thread semaphore from threadLocksRef when a session is stopped, preventing unbounded map growth across sessions
| }); | ||
| } | ||
|
|
||
| const result = yield* ctx.acp |
There was a problem hiding this comment.
🟠 High Layers/HermesAdapter.ts:988
When ctx.acp.prompt(...) fails, sendTurn returns an error but the session remains marked as running: no turn.completed event is emitted, and ctx.session.activeTurnId and ctx.activeTurnId remain set. The ensuring block only decrements promptsInFlight, so transport or process failures leave consumers and listSessions observing a permanently active turn; handle this failure path by clearing the active-turn state and emitting a cancelled/completed event.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/HermesAdapter.ts around line 988:
When `ctx.acp.prompt(...)` fails, `sendTurn` returns an error but the session remains marked as running: no `turn.completed` event is emitted, and `ctx.session.activeTurnId` and `ctx.activeTurnId` remain set. The `ensuring` block only decrements `promptsInFlight`, so transport or process failures leave consumers and `listSessions` observing a permanently active turn; handle this failure path by clearing the active-turn state and emitting a cancelled/completed event.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f07fba0. Configure here.
| method: "session/prompt", | ||
| detail: "Hermes prompt was interrupted during preparation.", | ||
| }); | ||
| } |
There was a problem hiding this comment.
Steer interrupt leaves turn open
High Severity
The new interrupt-during-preparation path returns without emitting turn.completed, unlike the image-steer wait path that just fixed the same gap. After a steer, the earlier prompt often already skipped completion because promptsInFlight was still above one, so aborting here can leave the thread running with no terminal turn event.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit f07fba0. Configure here.
| const next = new Map(current); | ||
| next.delete(ctx.threadId); | ||
| return next; | ||
| }); |
There was a problem hiding this comment.
Lock map delete breaks exclusion
Medium Severity
Removing the thread entry from threadLocksRef inside stopSessionInternal can orphan the old semaphore while another fiber still waits on or holds it. A later getThreadSemaphore then creates a second lock for the same threadId, so stop/start/sendTurn ensuring no longer mutually exclude and can corrupt promptsInFlight on a replacement session.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit f07fba0. Configure here.
|
Please merge this 🙏🏻🙏🏻🙏🏻 |
|
Note 🤖 GPT-5.6 Sol responding on behalf of Theo Closing this PR after an automated pass over open pull requests. Adds an unsupported first-party provider or source-control host without a maintainer request. |


What Changed
Adds Hermes Agent as a first-class Early Access provider. T3 Code connects to the Hermes Agent Protocol (ACP) server of a local Hermes Agent installation and uses Hermes' own models, credentials, tools, skills, rules, and session history.
Server
HermesDriver+HermesHome: built-in instance plus additional instances viaHERMES_HOME— different homes keep configuration, credentials, and history isolated; shared homes can continue each other's sessionsHermesAdapter/HermesProviderover ACP: model list from Hermes, permission-mode mapping (Approval required / Auto →default, Auto-accept edits →accept_edits, Full access →dont_ask), session-scoped auto-approval (never a silent permanent grant), image support via ACP, slash commands advertised by the running CLI, MCP server startupHermesAcpSupport+AcpRuntimeModel/AcpSessionRuntimeupdates: persisted ACP session ID for continuation, replay suppression on resume, updated approval-choices flowHermesTextGenerationfor source-control text generation (short-lived provider checks skip configured MCP startup)builtInDrivers, provider contracts (HermesProviderSettings,ProviderKind), Cursor/Grok adapter alignmentClients
hermes update), settings form, model options, context window entry, diagnostics flagDocs
docs/user/providers-hermes.md; updates toinstall.md,providers.md,overview.md,glossary.mdTests
Why
Hermes Agent (hermes-agent.nousresearch.com) is an open-source, ACP-speaking agent runtime with its own provider, credentials, tools, skills, and session state. Because T3 Code already speaks ACP, the natural integration is a provider card that drives the real Hermes CLI instead of a separate adapter protocol — users get their existing Hermes setup (models, skills, MCP servers, session history) working inside T3 Code with no duplicate configuration. Requires Hermes Agent ≥ 0.20.0.
UI Changes
New Hermes provider card in Settings → Providers (CLI version detection, provider update action, model list) and the Hermes icon in the web/mobile provider pickers. Screenshots can be provided on request.
Checklist
Note
Medium Risk
Large new provider adapter and ACP session/turn concurrency changes affect core agent runtime; mis-handling steer/interrupt or permission mapping could break threads, though coverage is mostly unit-tested.
Overview
Adds Hermes Agent as a first-class Early Access provider end-to-end: server driver (
HermesDriver,HermesHome, provider snapshot/discovery), a large ACP adapter (hermes acp) for sessions, permissions, steering, images, token usage, and resume cursors, plus Hermes-backed text generation for git metadata jobs.Contracts & settings: New
HermesSettings(enabled by default,binaryPath,homePath, custom models), Hermes defaults in model maps, and registry/tests updated so Hermes boots alongside other shipped drivers.ACP layer (shared):
AcpRuntimeModelnow emits reasoning text, usage, and available-commands updates; content deltas carrystreamKind;AcpSessionRuntimesupports concurrent prompts (used by Hermes). Cursor/Grok adapters passstreamKindand ignore the new notification types.Clients & docs: Hermes icon, picker entry, model labels, thread settings (primary expanded provider), settings form, diagnostics agent detection; new
providers-hermes.mdand install/docs refresh.Reviewed by Cursor Bugbot for commit f07fba0. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add full Hermes agent provider support across server, mobile, and web
hermesprovider driver including ACP session management, session lifecycle, turn steering, permission handling, model/mode configuration, and event streaming viaHermesAdapter.tsandHermesDriver.tsenabled,binaryPath,homePath,customModels) inHermesProvider.tsandsettings.tsHermesTextGeneration.tsAvailableCommandsUpdated,UsageUpdated, and reasoningContentDelta(streamKind) event typesenabled: true) in server settings, which will trigger provider status checks on all existing deploymentsMacroscope summarized f07fba0.