From 25eb8b41380bbe6382d6aeb13a019e4a62bde4ef Mon Sep 17 00:00:00 2001 From: Sam Xu Date: Mon, 4 May 2026 00:49:58 -0700 Subject: [PATCH] fix(v2-inspector): make 'Talk to' gate runtime-based, not name-hardcoded MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dmable check at V2PodInspector.tsx:35 was hardcoded to `agent.name === 'openclaw'`, which silently hid the Talk-to button for every other runtime — Claude Code, Codex, stub, webhook, native. Anyone installing an agent via `commonly agent attach ` got an agent that worked end-to-end (auth, posting, mentions, memory) EXCEPT that the inspector never offered a Talk-to button to start a 1:1 with it. Required a UI workaround (Agent Hub > Talk to from a different surface) or a hand-built agent-room call. Fix: gate on `runtime.runtimeType !== 'internal'`. Tier 1 native services (commonly-bot, pod-summarizer) stay non-dmable because they have no chat runtime. Everything else gets the button. Net diff: 6-line replacement. Surfaced while staging the YC demo with local-CLI agents (Nova/Cody/Pixel via claude/codex/stub adapters); the Talk-to button should be a first-class affordance for them since they all hold real chat runtimes. Co-Authored-By: Claude Opus 4.7 (1M context) --- frontend/src/v2/components/V2PodInspector.tsx | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/frontend/src/v2/components/V2PodInspector.tsx b/frontend/src/v2/components/V2PodInspector.tsx index 943ce727..50b0084d 100644 --- a/frontend/src/v2/components/V2PodInspector.tsx +++ b/frontend/src/v2/components/V2PodInspector.tsx @@ -29,12 +29,25 @@ interface V2PodInspectorProps { onOpenInvite?: () => void; } -// Only openclaw-runtime agents can hold a real DM session — they have a chat -// runtime that responds. commonly-bot is the internal Tier 1 summarizer (no -// chat runtime); pod-summarizer is Tier 1 native (also no DM). -const isAgentDmable = (agent: { name?: string; agentName?: string }): boolean => { - const n = agent.name || agent.agentName; - return n === 'openclaw'; +// Any agent with a real chat runtime can hold a DM session. The Tier 1 +// internal services (commonly-bot summarizer, pod-summarizer) don't have a +// runtime that responds to chat — they're cron / event-driven only. +// +// Previously this was hardcoded to `agent.name === 'openclaw'`, which +// silently excluded every other runtime — Claude Code wrappers, Codex +// wrappers, stub adapters, webhook bots, native runtime agents. Anyone +// installing an agent via `commonly agent attach ` +// got an agent that worked end-to-end EXCEPT that the inspector's +// "Talk to" button never appeared. +// +// Gate now reads from the resolved runtime: any non-internal runtime +// is dmable. Falls back to `false` for unknown payload shapes. +const isAgentDmable = (agent: { runtime?: { runtimeType?: string } | null }): boolean => { + const t = agent?.runtime?.runtimeType; + if (!t) return false; + // Tier 1 native services — no chat runtime, no DM target. + if (t === 'internal') return false; + return true; }; interface AgentTaskMap {