feat: add Hermes-powered T3 Work - #4604
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:
✨ Finishing Touches🧪 Generate unit tests (beta)
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.
Effect service review: one error-modeling convention violation found in the new Hermes service code. Details inline.
Posted via Macroscope — Effect Service Conventions
ApprovabilityVerdict: Needs human review 1 blocking correctness issue found. Diff is too large for automated approval analysis. A human reviewer should evaluate this PR. You can customize Macroscope's approvability policy. Learn more. |
There was a problem hiding this comment.
Effect service review found error-modeling convention violations in the new Hermes services. Two new findings are noted inline below. A previously reported issue in HermesProactiveEventRepository.ts (the detail/message derived from cause) is still present at this commit but is not re-flagged here to avoid duplicating the earlier comment.
Posted via Macroscope — Effect Service Conventions
| to: "completed", | ||
| now: DateTime.formatIso(yield* DateTime.now), | ||
| }); | ||
| yield* hydrateThread(threadId); |
There was a problem hiding this comment.
Import hydrate failures stay empty
High Severity
Import now marks the ledger completed and then calls hydrateThread, whose failures are only logged. A transient hydrate error leaves a completed import with no projected transcript. Combined with the new 4007 read-only resume path, a later vanished upstream session can never recover that history.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit ab7d3f0. Configure here.
| projectId: backingProject.id, | ||
| title: session.title || session.preview || "Hermes session", | ||
| isMain: false, | ||
| ...(startedAt === undefined ? {} : { createdAt: startedAt }), |
There was a problem hiding this comment.
Settle wipes historical updatedAt
Medium Severity
Imported settled sessions get a historical createdAt from started_at, then immediately receive thread.settle, which sets updatedAt to wall-clock now. Until a successful hydrate rewrites activity from message times—or forever when history is empty or hydrate fails—those threads sort and appear as freshly active at import time.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit ab7d3f0. Configure here.
| } | ||
| if (navigation.kind === "new-chat") { | ||
| if (nextWorkspace === "work" && openWorkComposer()) return; | ||
| void router.navigate({ to: "/" }); |
There was a problem hiding this comment.
Work switch opens Code landing
Medium Severity
When switching to Work and openWorkComposer fails, navigation falls through to / after setWorkspace("work"). The index route starts a Code draft for the most recent project, so the sidebar is Work while the main pane opens a Code composer—especially during Hermes setup when Work is not ready yet.
Reviewed by Cursor Bugbot for commit ab7d3f0. Configure here.
4e8f49c to
9fd6b62
Compare
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- retry import hydration and log at error level so a transient gateway failure cannot silently leave a completed import without a transcript - leave the inherited boundary unrecorded while history reads empty so a later full history still receives import normalization and rehydration - resolve MEDIA output protocol inside rehydrated tool activities into durable attachment markers instead of leaving raw MEDIA: text - historical settles stamp updatedAt from settledAt so imported threads keep sorting by when the work actually ended Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- close() rejects sent in-flight mutations with HermesGatewayMutationIndeterminateError instead of a connection error - reconcileMutation only touches the local fence when the queried mutation id belongs to the fenced operation - HermesCron reuses one shared gateway client per provider connection so operationId fences survive across cron calls; duplicate operation ids map to invalid_input and blocked writes map to indeterminate - projectProvider projects success:false cron list responses as a provider error instead of a ready empty inventory - HermesProviderDirectory applies assessHermesConnectionSecurity, so remote wss endpoints no longer receive the broad local gateway token, and an empty endpoint resolves to the default loopback endpoint Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- EffectWorker: verify lease ownership before projecting permanent failures and keep effects retryable when the terminal projection fails - HermesHistoryNormalization: stop unquoted MEDIA paths from swallowing a second MEDIA directive on the same line - HermesServeAdapterV2: bound oversized tool property names and redact standard Authorization schemes plus OAuth parameters - HermesSessionCatalog: route discovery through the serve runtime's ensureReady so managed local Hermes instances are started first - HermesServeRuntime: relaunch an owned unhealthy process instead of reporting endpoint_in_use for T3's own listener - ThreadLaunchService: still generate thread titles when workspace preparation is skipped - HermesDriver: resolve default-model capabilities from the active provider on duplicate model slugs Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- SidebarV2: stay put instead of landing on the Code composer when the Work composer cannot open after a workspace switch - SidebarV2: only blur the pin toggle on pointer activation so keyboard focus survives Enter/Space - mobile: exclude Hermes threads from the Code workspace, matching web sidebar classification Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…tion in skills settings
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ture Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- EffectWorker: never re-execute permanently failed effects; persist a pending-terminalization marker so reclaims retry only the terminal projection - HermesCron: close and evict stale gateway clients when a provider's connection identity (endpoint/token) changes - HermesCron: only report duplicate-operation-id for actual duplicates via HermesGatewayDuplicateOperationIdError; map other configuration errors to a gateway diagnostic - HermesDriver: omit the session catalog for disabled instances - HermesServeRuntime: stop any lingering owned process before launching a replacement, even when the endpoint is unreachable - sanitizeHermesToolValue: short-circuit object/array iteration when the size budget is exhausted Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… message snapshots, and route drafts on workspace switch Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…keep the index draft off the T3 Work backing project Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ort hydrate ledger, probe warnings, draft classification) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…classify Hermes Code threads Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…response placeholder with attachments Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… dedup by id and time proximity Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
There are 4 total unresolved issues (including 3 from previous reviews).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 8b4f455. Configure here.
…amps are synthetic) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…nto committed entries Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
I'm watching this and #4678 with attention and expectation. |


Stack
This is a cross-fork draft stacked directly on #4400 (
codex/v1-v2-state-migration). Its parent is the current #4400 head,80082809973557d1cec7f7107932a4db1d37f0e7.Summary
MEDIA:output handling, reply normalization, and safe durable asset access.session_mcp.Reliability and security
profile.import+session.lifecyclecapability inventory; legacy gateways are not granted synthetic optional/mutating capabilities.MEDIA:ingestion is confined to canonical Hermes-owned cache roots by default. Additional roots require explicit operator configuration; traversal and symlink escapes are rejected.Verification
67changed test files passed,746tests total.@t3tools/contracts,@t3tools/shared,@t3tools/client-runtime,t3,@t3tools/web,@t3tools/mobile, and@t3tools/scripts.git diff --check, and the staged commit hook passed.Browser/dev-server/simulator testing was intentionally not run for this handoff. CodeRabbit CLI was installed but signed out, so its external review was unavailable; the branch received independent Sol-medium backend, client, security, and integration reviews instead.
Current protocol constraints
session_mcplease support; the pinned legacy gateway remains correctly reported as blocked rather than receiving unsafe fallback behavior.UI Changes — Screenshots & demos
All media below is from live end-to-end runs against a real Hermes gateway (Codex OAuth, GPT‑5.5), through both T3 Work and T3 Code.
Demo videos
Full e2e pass — Hermes code work, attachments (image/PDF/file/video), MEDIA output, delegation:
Reload dedupe + attachment-only rendering verification (fresh and older Hermes Code threads render each message exactly once after hard reload):
Hermes in T3 Work
Image upload in a Work thread — Hermes describes the attached gradient:
Hermes generates an image via its terminal tool; the
MEDIA:output renders as an image bubble:Subagent delegation — spawn acknowledged once, then the result reported back:
Hermes tool inventory surfaced natively (delegate_task, cronjob, skill_manage, project tools, …):
Hermes model picker (provider models incl. Codex OAuth) with the "Delegated tasks" panel:
Session import
Hermes in T3 Code
Hermes as a coding provider on a normal Code project — native
Updated greet.pyfile-change activity, thread classified into the Code sidebar:Note
Add Hermes-powered T3 Work workspace with session import, cron, skills, and ACP driver support
hermesprovider driver (HermesDriver.ts),hermesAcpACP driver (HermesAcpDriver.ts), andopenclawACP driver (OpenClawDriver.ts) to the built-in driver registry.HermesServeAdapterV2andHermesAcpAdapterV2orchestration adapter with full session/thread/turn lifecycle, MCP lease handling, and media persistence against a Hermes gateway (HermesServeAdapterV2.ts).HermesConnectionSecurityfor endpoint classification andHermesServeRuntimeto attach to or launch a local Hermes gateway process (HermesConnectionSecurity.ts, HermesServeRuntime.ts).enableHermesrollout flag and creates a T3 Work backing project automatically on first use.Macroscope summarized f024045.
Note
Medium Risk
Work launches depend on correct Hermes/t3-work routing and
prepareWorkspace: falsepropagating through mobile outbox and turn bootstrap; server asset and Hermes remote/cron paths add security-sensitive surface area but include explicit fail-closed checks and tests.Overview
Mobile gains a persisted T3 Work / T3 Code workspace switch in the home header, sidebar, and split layouts. Lists and pending outbox items are filtered by provider driver (Hermes vs coding providers) via new
mobileWorkspacehelpers; Work mode forces thread-list v2, shows an Inbox header, and hides project filters.Starting a task in Work resolves a Hermes backing project and model through
resolveHermesConversationTarget, opens a New conversation draft with preselected Hermes model, uses work-scoped composer drafts, and sendsprepareWorkspace: falsethrough the outbox andthread.turn.startbootstrap so routing-only projects do not run workspace prep. Code keeps the existing new-task flow. Hermes and OpenClaw provider icons are added to the thread list.Server changes in this diff extend signed asset URLs to workspace videos and browser artifacts (safe filenames,
O_NOFOLLOWstreaming), broaden attachment filename extensions, and addt3WorkDir/browserArtifactsDirderived paths. Hermes connection security assesses loopback vs remote endpoints (pairing token, TLS fingerprint, kill switches) and blocks unsupported remote verification. Hermes cron projects gateway capability inventory into list/mutate APIs with shared clients, operation-id deduplication, and execution provenance/deduping.Reviewed by Cursor Bugbot for commit f024045. Bugbot is set up for automated code reviews on this repo. Configure here.