β¨ feat(platform-agent): openclaw/hermes agent creation UI, device guard, and remote dispatch backend#15065
Conversation
β¦n-hetero dispatcher (LOBE-8927/8928) Introduce a shared invocation contract and unified dispatcher for the non-hetero, non-group agent call paths (callAgent speak mode and @agent direct mentions). Removes the implicit client-only fallback that existed in both entry points. Changes: - agentDispatcher.ts: add AgentInvocationIntent interface as the unified intent type for callSubAgent / callAgent / @agent invocations - nonHeteroSubAgentDispatcher.ts (new): dispatchNonHeteroSubAgent() resolves child runtime via selectRuntimeType and routes to executeClientAgent (client) or executeGatewayAgent (gateway); throws for hetero (out of scope per LOBE-8926) - conversationLifecycle.ts #executeDirectMentionRoute: replace hardcoded executeClientAgent + TODO fallback with dispatchNonHeteroSubAgent call - builtin-tool-agent-management executor.ts callAgent speak mode: replace hardcoded executeClientAgent + TODO fallback with dispatchNonHeteroSubAgent call Fixes LOBE-8927 Fixes LOBE-8928 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
β¦rd, and remote dispatch backend - Add CreatePlatformAgent 3-step creation modal (type select β config β bind device) - Add RemoteAgentConfigCard to agent profile editor for openclaw/hermes config - Add device guard banner in HeterogeneousChatInput for offline/unavailable devices - Add useRemoteAgentDeviceGuard hook for real-time device status polling - Fix backend dispatch: openclaw/hermes now use executeToolCall(runHeteroTask) instead of dispatchAgentRun (lh connect only handles tool_call_request) - Add agentNotify router for lh notify β DB write + gateway stream event - Add device.checkCapability endpoint for platform availability probe - Add notify_update event type to gateway stream and event handler - Add sendDoneSignal in heteroTask.ts for clean openclaw exit signaling - Unify non-hetero sub-agent dispatch via dispatchNonHeteroSubAgent (LOBE-8927) - Route openclaw/hermes to gateway runtime; keep claude-code/codex on hetero/client paths - Add i18n keys for platform agent UI and device guard banners Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Sorry @ONLY-yours, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
Codecov Reportβ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## canary #15065 +/- ##
===========================================
- Coverage 75.98% 70.72% -5.27%
===========================================
Files 120 3115 +2995
Lines 3869 310123 +306254
Branches 602 27077 +26475
===========================================
+ Hits 2940 219320 +216380
- Misses 916 90636 +89720
- Partials 13 167 +154
Flags with carried forward coverage won't be shown. Click here to find out more.
π New features to boost your workflow:
|
There was a problem hiding this comment.
π‘ Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: addef91b47
βΉοΈ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with π.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
β¦otify call Instead of creating a second empty bubble, the first assistant notify without a messageId now updates the placeholder assistantMessageId that execAgent already seeded in runningOperation.assistantMessageId. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Store deviceId + heteroType in topic.metadata.runningOperation at dispatch time - interruptTask now dispatches cancelHeteroTask tool call to the bound device when topicId reveals a remote hetero operation, sending SIGINT to the process - Pass topicId from gateway cancel callback to interruptTask - Add topicId to InterruptTaskSchema and InterruptTaskParams Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
β¦on into heterogeneous-agents package - Add RemoteHeterogeneousAgentConfig, REMOTE_HETEROGENEOUS_AGENT_CONFIGS, isRemoteHeterogeneousType, and derived type aliases (HeterogeneousAgentType, LocalHeterogeneousAgentType, RemoteHeterogeneousAgentType) to packages/heterogeneous-agents/src/config.ts - Extend HETEROGENEOUS_TYPE_LABELS to cover remote platform types (openclaw, hermes) via REMOTE_HETEROGENEOUS_AGENT_CONFIGS - Replace all inline `=== 'openclaw' || === 'hermes'` checks and local Sets/type aliases across aiAgent service, ProfileEditor, HeterogeneousChatInput, useRemoteAgentDeviceGuard, CreatePlatformAgent, RemoteAgentConfigCard, and deviceProxy with the shared utility - Show OpenClaw/Hermes display name in assistant message model tag (Usage component) by setting provider=heteroType on placeholder message and using HETEROGENEOUS_TYPE_LABELS for rendering - Fix ReferenceError: move remoteDeviceId declaration before updateMetadata call Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Route openclaw/hermes to gateway on desktop (P1): add isRemoteHeterogeneousType check in selectRuntimeType before desktop hetero branch β remote agents never use local desktop IPC, no special-casing needed - Fix race in heteroTask: sendAutoNotify β sendDoneSignal now sequential via .finally() so error message is written before agent_runtime_end is published - Security: validate messageId belongs to topicId in agentNotify before MessageModel.update to prevent cross-conversation data corruption - Clear capability/device/profile state on platform change in creation modal (P2) - Derive PLATFORM_DEFS from REMOTE_HETEROGENEOUS_AGENT_CONFIGS β new platforms automatically appear in the modal without code changes - Use HETEROGENEOUS_TYPE_LABELS for platform names in HeterogeneousChatInput and RemoteAgentConfigCard (remove hardcoded PLATFORM_NAMES map) - i18n: platform card descs, 'online'/'offline' tags, 'Select a device' placeholder, checkFailed error β all now use i18n keys Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
β¦+ fix test - device.ts: replace hardcoded z.enum(['hermes','openclaw']) with a zod enum derived from REMOTE_HETEROGENEOUS_AGENT_CONFIGS so new platforms are automatically covered without touching this file - heteroTask.ts / getAgentProfile.ts: use RemoteHeterogeneousAgentType instead of literal 'hermes' | 'openclaw' union for the same reason - gateway.test.ts: update cancel-handler assertion to include topicId which was added to the interruptTask call in the previous commit Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
β¦ dispatcher tests - Add enablePlatformAgent lab preference (default false) β the "Add Platform Agent" menu item is hidden until the user opts in via Settings β Advanced β Labs - Wire toggle in settings/advanced with labs i18n key (en/zh) - createPlatformAgentMenuItem returns null when flag is off - agentDispatcher.test: add remote hetero cases (openclaw/hermes β gateway on both web and desktop) to cover the routing fix added earlier Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
β¦roSubAgentDispatcher Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
β¦ng soon) Hermes is not yet ready for production. Mark it as coming-soon in the platform selection step: grayed-out card, not clickable, "Coming Soon" tag next to the name. To enable Hermes when ready: remove 'hermes' from COMING_SOON_PLATFORMS in CreatePlatformAgent/index.tsx. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The modal always mounts (open=false) and calls lambdaQuery.useQuery which requires a tRPC context not present in the test environment. Mock it out the same way as ChatGroupWizard and EditingPopover. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
β¦tems.test Adding useUserStore to useCreateMenuItems triggered user store initialization in tests, which pulled in @lobechat/const and failed because the existing mock only exports isDesktop. Mock the store and selectors directly instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
β¦bled The divider before 'Add Platform Agent' was unconditional β it showed even when the labs flag was off. Conditionally include both the divider and the menu item together so no orphaned separator appears. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
# π LobeHub Release (20260528) **Release Date:** May 28, 2026 **Since v2.2.0:** 220 merged PRs Β· 15 contributors > This cycle brings heterogeneous "platform agents" you can dispatch to local or remote devices, a rebuilt onboarding flow, document-centric chat, and a unified model-runtime error model β with new DeepSeek V4 and Gemini 3.5 Flash support along the way. --- ## β¨ Highlights - **More Hetero Agents (OpenClaw / Hermes)** β Create heterogeneous agents and dispatch them to local or remote devices through the device gateway, with an execution-target switcher in the composer and persistent CLI sessions. (#15065, #15179, #15022) - **iMessage on Desktop** β New iMessage setup and bridge on desktop, plus bot attachments across every platform. (#15228, #15227, #15029) - **Skills in the Composer** β Drag skill chips into chat, trigger installed skills from the slash menu mid-line, and surface project-level skills in the homogeneous agent runtime. (#15095, #15061, #15110) - **New Models** β DeepSeek V4 Flash/Pro and Gemini 3.5 Flash across providers, with thinking params for structured output and chat cost estimates. (#15031, #15001, #15051, #14876) - **Agent Runtime Observability** β OpenTelemetry GenAI semantic conventions plus per-call generation tracing. (#15123, #15124) --- ## π€ Agents & Heterogeneous Runtime - **Platform agent creation** β OpenClaw/Hermes creation UI, device guard, and remote dispatch backend. (#15065) - **Execution-target switcher** β Pick local vs remote execution directly in the composer; device-selection UX with actionable guidance. (#15179, #15111) - **CLI hetero dispatch** β OpenClaw/Hermes dispatch with persistent sessions and a notify protocol. (#15022) - **Gateway snapshot as source of truth** β Consume the gateway `uiMessages` snapshot at step boundaries to keep chat state consistent. (#15153, #15152) - **Client sub-agent as a normal tool call** β Simplifies the sub-agent execution path. (#15281) - **Hermes agent chain** β Implements the Hermes agent chain logic. (#15189) - **Device registry** β TRPC endpoints to register, list, update, and remove devices. (#15299) - **Desktop device routing** β Route gateway agent runs through `lh hetero exec`; restore `userId` in gateway dispatch and gate local-system by execution target. (#15132, #15232) - **Agent signals** β Anchor agent-signal receipts to messages and isolate memory-agent messages into a child thread. (#14969, #14921) --- ## π Onboarding - **Simplified first screen** β Defer topic creation to first send. (#15090) - **Market Agent Picker** β Added as a classic onboarding step, with template prefetch. (#14980, #15041) - **Welcome guidance** β Show agent welcome guidance on first run. (#15098) - **Mobile** β Adapt agent onboarding UI and restore Classic-step padding on mobile. (#15019, #15032) - **Discovery** β Streamline discovery to a single profession question. (#14987) - **Analytics** β Track onboarding step events and create-agent modal source. (#15133, #15028) --- ## π Documents, Pages & Knowledge - **Thread chat in preview** β Embed thread chat in the document preview portal. (#15216) - **Non-markdown rendering** β Render non-markdown docs as a read-only highlight. (#15272) - **Multi-select** β Multi-select delete in the document tree. (#15125) - **Page-agent streaming** β Preview `initPage` streaming arguments. (#15039) - **Per-agent topics** β Per-agent topic management page. (#15207) - **Server-side category** β Derive document category server-side and drop frontend predicates. (#15076) --- ## π§© Skills & Tools - **Drag skill chips** β Drag skills into chat input and register agent-document skills. (#15095) - **Slash menu** β Installed skills appear in the slash menu with a mid-line trigger. (#15061) - **Project skills** β Recognize project-level skills in the homogeneous agent runtime and surface them regardless of active device. (#15110, #15177) - **VFS archiving** β Archive oversized tool results to VFS instead of truncating. (#15074) - **@localfile mentions** β Drag folders into chat input as `@localFile` mentions on desktop. (#15071) --- ## π§ Model Runtime & Providers - **Error spec registry** β Unify error codes into a spec + pattern registry, split `ProviderBizError` into finer codes, classify Cloud-only codes via a tier digit, and add `DatabasePersistError`. (#15262, #15286, #15278, #15279) - **New models** β DeepSeek V4 Flash/Pro (opencode-go) and Gemini 3.5 Flash; DeepSeek V4 Pro on SiliconCloud. (#15031, #15001, #15017, #15267) - **Structured output** β Thinking params for structured output, Bedrock structured generation, and DeepSeek `generateObject` tool choice. (#15051, #15174, #15054) - **Cost** β Chat cost estimate support; preserve usage cost in custom streams. (#14876, #15218) --- ## π¬ Chat & User Experience - **Follow-up chips** β Extend follow-up chip suggestions to general chat with scene-specific model config. (#15101, #14797) - **Input drafts** β Persist unsent input drafts across tab switches and prevent repeated draft restore. (#14992, #15024) - **Command menu** β Order topic/message search by recency and promote inline type filters. (#15094, #14986) - **Zoom HUD** β Show a zoom-level HUD on Cmd +/β and Cmd 0. (#15294) - **Copy** β Unescape markdown escapes when copying user messages. (#15253) --- ## π₯οΈ Desktop - **App Nap fix** β Prevent App Nap from dropping the gateway WebSocket during display sleep. (#14994) - **File preview** β Preview `.cjs`/`.mjs`/no-extension files instead of binary fallback and expand `~` when opening local files. (#15168, #15284) - **Cross-platform settings** β Open settings via main-window navigation on Windows/Linux and restore the route after an update restart. (#15036, #14922) - **Token refresh** β Prevent frequent logout from token-refresh retries. (#14928) --- ## π Observability - **OTel GenAI** β Instrument Agent Runtime with OpenTelemetry GenAI semantic conventions. (#15123) - **Generation tracing** β Per-call `llm_generation_tracing` with a pre-allocated tracingId and recordFeedback router. (#15124, #15146) - **Error classification** β Persist `ERROR_CODE_SPECS` classification on operation errors. (#15273) --- ## ποΈ Database Migrations - **Batch migrations** β Topic usage stats, push tokens, `tasks.editor_data`, and document shares. (#15280) - **Tracing & eval tables** β Add `llm_generation_tracing` and agent eval experiment tables. (#15126) > Self-hosted operators should run the database migration (`pnpm db:migrate`, or restart with auto-migrate enabled) after upgrading. The changes are additive and backwards-compatible. --- ## π Security & Reliability - **Security:** Remove the `getPlaintextCred` tool to prevent plaintext credential exposure. (#14998) - **Security:** Prompt account selection for Google OAuth and add `prompt=consent` to the OIDC authorization URL to fix missing refresh tokens. (#15234, #15010) - **Reliability:** Preserve streamed content across a mid-stream cancel. (#15173) - **Reliability:** Bound the Redis command timeout and configure the Anthropic client timeout. (#15091, #15042) - **Reliability:** Prevent infinite recursion in the assistant chain. (#15288) --- ## π₯ Contributors Huge thanks to **15 contributors** who shipped **220 merged PRs** this cycle. @AnotiaWang Β· @sxjeru Β· @algojogacor Β· @hardy-one Β· @arvinxx Β· @Innei Β· @tjx666 Β· @lijian Β· @AmAzing129 Β· @rdmclin2 Β· @neko Β· @cy948 Β· @CanisMinor Β· @sudongyuer Β· @rivertwilight Plus @lobehubbot and renovate[bot] for maintenance. --- **Full Changelog**: v2.2.0...release/weekly-20260528
π» Change Type
π Related Issue
Fixes LOBE-8927
Fixes LOBE-8928
π Description of Change
Platform Agent (OpenClaw / Hermes) β end-to-end support for remote device agents
Unlike local CLI agents (Claude Code, Codex) that spawn as desktop subprocesses, platform agents run on a remote device connected via
lh connect. This PR introduces the full stack for creating, configuring, and running them.Creation flow
device.checkCapabilitytRPC endpoint probes whether the selected platform binary is installed and returns its versiondevice.getAgentProfiletRPC endpoint reads agent identity from the platform CLI (e.g.openclaw agents list --json) and falls back to workspaceIDENTITY.md/SOUL.mdAgent profile editor
RemoteAgentConfigCardshows the bound device status (online/offline), platform capability, and a "change device" action with live capability re-checkRuntime routing
selectRuntimeTypecorrectly routes openclaw/hermes togatewayon both web and desktop; local CLI agents (claude-code, codex) remain on theheteropath on desktopdispatchNonHeteroSubAgent) eliminates per-entry-point runtime selection duplication (LOBE-8927 / LOBE-8928)Task execution and messaging
executeToolCall('runHeteroTask')over the device gateway WS (notdispatchAgentRunβlh connectonly handlestool_call_request)agentNotifyrouter:lh notifyCLI writes messages to DB and publishesnotify_update/agent_runtime_endevents to the gateway WS stream, which the frontend subscribes to in real timelh notifycall without amessageIdreuses the placeholderassistantMessageIdseeded byexecAgentinstead of creating a second empty bubbleinterruptTaskdispatchescancelHeteroTaskto the bound device (SIGINT) when a running remote hetero operation is detected viatopic.metadata.runningOperationDevice guard (chat input)
HeterogeneousChatInputwhen the bound device is offline, the platform is unavailable, or no device is bound β with refresh and configure shortcutsExtensibility
REMOTE_HETEROGENEOUS_AGENT_CONFIGSinpackages/heterogeneous-agentsis the single source of truth for remote platform types; UI components, type guards, display labels, and the device router's zod enum are all derived from it β adding a new platform requires changes only to this config and the CLI implementationFeature flag
Security
agentNotifyvalidates that the providedmessageIdbelongs to the giventopicIdbefore updating, preventing cross-conversation data writesπ§ͺ How to Test
runHeteroTaskandlh notifyoutput appears in real time