Skip to content

🎨 style(claude-code): tool inspectors + heterogeneous-agent follow-ups#14030

Merged
arvinxx merged 9 commits into
canaryfrom
fix/lobe-7365-cc-monitor-parentid-chain
Apr 22, 2026
Merged

🎨 style(claude-code): tool inspectors + heterogeneous-agent follow-ups#14030
arvinxx merged 9 commits into
canaryfrom
fix/lobe-7365-cc-monitor-parentid-chain

Conversation

@arvinxx

@arvinxx arvinxx commented Apr 22, 2026

Copy link
Copy Markdown
Member

💻 Change Type

  • ✨ feat
  • 🐛 fix
  • ♻️ refactor
  • 🎨 style

🔗 Related Issue

Follow-up polish after LOBE-7365 / #14024 landed in canary.

🔀 Description of Change

Nine commits across five independent threads; no shared code path so each can be reviewed in isolation.

CC tool inspectors (new)

  • f96e06201f ✨ render dedicated inspectors for ScheduleWakeup (self-paced /loop), TaskOutput (read from background task), and TaskStop (terminate background task). These three were falling back to the generic (param:value 等 N 个参数) row. TaskStop accepts both task_id and the legacy shell_id field name since older CC builds still emit the latter.
  • 6391860a9f 🎨 align those inspectors with the existing ToolSearch shape: drop the leading lucide icon, add the : label suffix, and put ScheduleWakeup's human-readable reason in the chip with delaySeconds trailing as secondary context.

Heterogeneous-agent subagent regression fix

  • 3d6fd113e8 🐛 retain subagent tool-call lookup across turn boundaries. findRunByInnerToolCallId consulted run.state.persistedIds, but that set is wiped each time ensureSubagentRun advances subagentMessageId. A delayed tool_result for a prior turn's tool_use therefore missed the lookup and skipped the thread-bucket run.stream.update, leaving the in-thread tool bubble stuck on its loading spinner until the user re-opened the Thread (main-topic fetchAndReplaceMessages does not rehydrate thread buckets). Adds a run-lifetime lifetimeToolCallIds set (append-only) and routes the lookup through it; state.persistedIds stays turn-scoped for persistToolBatch's dedupe.

Chat input placeholder for CC sessions

  • 08ddddebc2 ✨ swap the generic chat-input placeholder for a task-specific variant when the active agent is backed by a heterogeneous provider (e.g. "Ask Claude Code to do a task"). Suppresses the @-mention assignment hint in that mode since heterogeneous agents don't yet route to sibling agents.
  • fb52b7d6d6 🌐 en-US + zh-CN dev preview translations for the new placeholder key (CI regenerates locale JSON on release).
  • 0517b6b7f9 🎨 drop the trailing ⌘↵ hotkey hint for the heterogeneous variant — it read awkwardly attached to a short single-clause prompt.

Workflow summary polish

  • 732137e145 ♻️ unify both branches of getWorkflowSummaryText onto one suffix structure: list · 共 N 种工具 · 共 X 次调用 · N 次失败. Replaces the inline per-tool (failed) marker with the global error suffix.
  • 3151d2bb7f ♻️ hide the kinds/calls suffixes when they would duplicate what the per-tool list already shows (N kinds only when truncated, X calls only when at least one tool was called more than once).

Sidebar topic filter

  • 67ea4c6858 🐛 stop completed topics from leaking past the sidebar filter. The outer Topic and inner List / TopicListContent each mounted useFetchTopics with different args — outer passed excludeStatuses: ['completed'], inner called it bare. Since excludeStatuses is part of the SWR key, both fired independent requests whose onData handlers wrote back to the same topicDataMap[containerKey] slot, and whichever landed last won. Introduces useFetchChatTopics as the single call site so every sibling mounts with identical args and SWR dedupes to one request.

🧪 How to Test

  • Tested locally
  • Added/updated tests
  • No tests needed

Regression test added to src/store/chat/slices/aiChat/actions/__tests__/heterogeneousAgentExecutor.test.ts under CC subagent thread-container > routes delayed tool_result to thread bucket when it arrives after subagent turn has rolled over: subagent emits turn-1 tool_use, turn advances (subagentMessageId changes), turn-1's delayed tool_result lands — asserts the thread-scoped updateMessage dispatch still fires with the result content. Verified the test fails on the pre-fix lookup.

Manual smoke:

  • CC session with a multi-step subagent that spawns background tools — confirm the new inspector chips render and any delayed tool_result clears the loading spinner without reopening the Thread.
  • Claude Code agent chat input — confirm placeholder reads "Ask Claude Code to do a task" / "让 Claude Code 帮你完成任务" with no trailing hotkey hint.
  • Sidebar with "Include completed" toggle off — confirm completed topics stay hidden across session switches and SWR revalidations.
  • Workflow summary after a CC run — confirm the suffix reads cleanly and doesn't duplicate the per-tool list.

📸 Screenshots / Videos

ToolSearch-style inspector layout shared inline in the review thread.

📝 Additional Information

No breaking changes, no migrations. useFetchChatTopics is a thin wrapper over useFetchTopics — the popup and mobile-modal call sites intentionally keep using raw useFetchTopics because they need the unfiltered set to resolve titles for already-completed topics.

@vercel

vercel Bot commented Apr 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lobehub Ready Ready Preview, Comment Apr 22, 2026 5:14am

Request Review

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've reviewed this pull request using the Sourcery rules engine

@codecov

codecov Bot commented Apr 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 69.44444% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.93%. Comparing base (b02b727) to head (3d6fd11).
⚠️ Report is 6 commits behind head on canary.

Additional details and impacted files
@@            Coverage Diff             @@
##           canary   #14030      +/-   ##
==========================================
+ Coverage   66.86%   66.93%   +0.07%     
==========================================
  Files        2100     2103       +3     
  Lines      179535   179818     +283     
  Branches    21192    17792    -3400     
==========================================
+ Hits       120038   120363     +325     
+ Misses      59373    59331      -42     
  Partials      124      124              
Flag Coverage Δ
app 59.60% <69.44%> (+0.12%) ⬆️
database 92.27% <ø> (ø)
packages/agent-runtime 79.72% <ø> (ø)
packages/context-engine 83.18% <ø> (ø)
packages/conversation-flow 92.40% <ø> (ø)
packages/file-loaders 87.02% <ø> (ø)
packages/memory-user-memory 74.74% <ø> (ø)
packages/model-bank 99.86% <ø> (ø)
packages/model-runtime 84.22% <ø> (ø)
packages/prompts 69.08% <ø> (ø)
packages/python-interpreter 92.90% <ø> (ø)
packages/ssrf-safe-fetch 0.00% <ø> (ø)
packages/utils 87.95% <ø> (ø)
packages/web-crawler 88.66% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
Store 66.60% <95.33%> (+0.22%) ⬆️
Services 51.71% <ø> (ø)
Server 66.80% <72.50%> (+0.03%) ⬆️
Libs 52.57% <ø> (ø)
Utils 80.59% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0260d94b34

ℹ️ 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".

/** Look up a subagent run by the tool_call_id of ANY tool inside it. */
const findRunByInnerToolCallId = (toolCallId: string): SubagentRunState | undefined => {
for (const run of subagentRuns.values()) {
if (run.state.persistedIds.has(toolCallId)) return run;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve subagent tool-call lookup across turn boundaries

findRunByInnerToolCallId only checks run.state.persistedIds, but that set is turn-scoped and gets replaced when subagentMessageId advances in ensureSubagentRun. If a subagent tool_result is delayed until after a turn transition, this lookup returns no run, so the thread-bucket updateMessage path is skipped and the tool bubble can remain stuck in loading state until the thread is reopened (main fetchAndReplaceMessages does not hydrate thread buckets).

Useful? React with 👍 / 👎.

arvinxx and others added 9 commits April 22, 2026 13:03
… inspector

CC emits three tool calls we were previously rendering as raw JSON:
`ScheduleWakeup` (self-paced /loop), `TaskOutput` (read from background
task), `TaskStop` (terminate background task). Add dedicated inspectors
and register them alongside the existing CC tool set.

`TaskStop` accepts both `task_id` and the legacy `shell_id` field name
since older CC builds still emit the latter.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…r filter

Two sibling components in each chat-topic sidebar were both calling
`useFetchTopics`, but with different args: the outer `Topic` passed the
preference-driven `excludeStatuses: ['completed']` filter while the
inner `List` / `TopicListContent` called it bare. Since `excludeStatuses`
is part of the SWR key, both calls fired independent requests whose
`onData` handlers wrote back to the same `topicDataMap[containerKey]`
slot — whichever response landed last won, and when the un-filtered
sibling won, completed topics reappeared in the sidebar despite the
"Include completed" preference being off.

Introduce `useFetchChatTopics` as the single call site for chat-topic
fetching. It reads `topicIncludeCompleted` from preferences and pins
`excludeTriggers` to the always-excluded cron/eval set, so every
sibling mounts with identical args, collapses onto one SWR key, and
SWR dedupes them to a single request. Group sidebars now also exclude
cron/eval triggers for parity with the agent sidebar (groups don't
produce either trigger today, so this is a no-op in practice but
prevents divergence if the rules change).

Popup and mobile-modal call sites keep using the raw `useFetchTopics`
because they deliberately need the unfiltered set — the popup has to
resolve a specific (possibly completed) topic's title from the map.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…essions

When the active agent is backed by a heterogeneous provider (currently
only `claude-code`), swap the generic "Ask, create, or start a task"
placeholder for a task-specific variant that names the provider
(e.g. "Ask Claude Code to do a task"). @-mention assignment hint is
suppressed in that mode since heterogeneous agents don't yet route to
sibling agents.
Local preview translations for the new heterogeneous-agent chat input
placeholder; en-US mirrors the default, zh-CN carries the Chinese
copy. CI regenerates locale JSON on release so this commit only seeds
dev preview.
…and calls

Both branches of getWorkflowSummaryText now share the same suffix structure:
list · 共 N 种工具 · 共 X 次调用 · N 次失败. summaryMoreTools changes from
remaining count ("+N more" / "等 N 种工具") to total count, and the inline
(failed) per-tool marker is dropped in favor of the global error suffix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Show "N tool kinds" only when the displayed list is truncated, and "X calls
total" only when at least one tool was called more than once. Otherwise the
aggregates duplicate information already visible in the per-tool list.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Heterogeneous-agent placeholder (e.g. "让 Claude Code 帮你完成任务…") no
longer trails the "press ⌘↵ to insert a line break" hotkey hint, which read
awkwardly attached to a short single-clause prompt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…Search

Drop leading lucide icons, add `:` suffix so the label row reads like
ToolSearch, and promote ScheduleWakeup's `reason` into the chip with
`delaySeconds` trailing as secondary context.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…turn boundaries

`findRunByInnerToolCallId` consulted `run.state.persistedIds`, but that
set is wiped every time `ensureSubagentRun` advances `subagentMessageId`.
A `tool_result` delayed past the owning turn therefore failed the lookup
and skipped the thread-bucket `run.stream.update`, leaving the in-thread
tool bubble stuck on its loading spinner until the user re-opened the
Thread (main-topic `fetchAndReplaceMessages` doesn't rehydrate thread
buckets). Add a run-lifetime `lifetimeToolCallIds` set that only grows
and route the lookup through it; leave `state.persistedIds` as-is so
`persistToolBatch`'s turn-scoped dedupe is untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@arvinxx arvinxx force-pushed the fix/lobe-7365-cc-monitor-parentid-chain branch from 8e8cf96 to 3d6fd11 Compare April 22, 2026 05:04
@arvinxx arvinxx changed the title 🐛 fix(cc): subagent parent-id chain, streaming, and sidebar polish ✨ feat(claude-code): tool inspectors + heterogeneous-agent follow-ups Apr 22, 2026
@arvinxx arvinxx changed the title ✨ feat(claude-code): tool inspectors + heterogeneous-agent follow-ups 🎨 style(claude-code): tool inspectors + heterogeneous-agent follow-ups Apr 22, 2026
@arvinxx arvinxx merged commit 1f61e96 into canary Apr 22, 2026
35 checks passed
@arvinxx arvinxx deleted the fix/lobe-7365-cc-monitor-parentid-chain branch April 22, 2026 05:23
@arvinxx arvinxx mentioned this pull request Apr 27, 2026
arvinxx added a commit that referenced this pull request Apr 27, 2026
# 🚀 LobeHub v2.1.53 (20260427)

**Release Date:** April 27, 2026
**Since v2.1.52:** 194 merged PRs · 17 contributors

> Introduce Heterogeneous Agent — Claude Code and Codex run as
first-class desktop runtimes, paired with a new Agent Signal package,
sharper desktop UX, and a wave of flagship model additions.

---

## ✨ Highlights

- **Introduce Heterogeneous Agent** — Claude Code and Codex run as
first-class desktop agents: subagent rendering, partial-message
streaming, multi-turn resume, terminal error surfacing, rich tool
inspectors, and runtime polish. (#14162, #13754, #14067, #14001, #13970,
#13942)
- **Screen capture & Quick Chat tray** — New desktop screen capture
overlay (macOS permission-gated) with Quick Chat tray and upload
pipeline improvements; chat input auto-focuses on overlay mount.
(#13818, #14097, #14105)
- **Desktop topic & tab UX** — Dedicated topic popup window with
cross-window sync, Cmd+W/Cmd+T tab shortcuts, TabBar polish, recent
working directories expanded to 20, and human approval notifications.
(#13957, #13983, #13972, #14036, #14092)
- **Git workflow built-in** — One-click pull/push from the branch chip,
ahead/behind badge, and submodule/worktree repo detection. (#14041,
#13980, #13978)
- **Agent Signal package** — New `@lobechat/agent-signal` runtime for
dynamic memory feedback signals, with OTel metrics and self-iteration in
Lab. (#14157, #14170, #14159, #14169, #14187)
- **New models** — Claude Opus 4.7 with `xhigh` effort tier, GPT-5.5,
DeepSeek V4 Flash/Pro with reasoning slider, Kimi K2.6, MiMo-V2.5/Pro,
gpt-image-2, Qwen3.6 Flash/Plus, and Pixverse-c1. (#13903, #14147,
#14114, #14004, #14089, #14039, #13923)
- **New providers** — OpenCode Zen, OpenCode Go, and Azure OpenAI Router
runtime. (#13943, #14064, #13823)
- **Mobile settings overhaul** — Full settings menu and responsive
profile layout for mobile. (#14019)

---

## 🏗️ Heterogeneous Agent

- Claude Code runtime, working-directory awareness, and sidebar polish.
(#13970)
- CC subagent rendering with persistent streamed text; parallel-tool
orphan fix. (#14001, #13968, #14024)
- Per-step usage persisted to each step assistant message. (#13964)
- Per-phase workflow expand defaults; full-expand toggle with
three-level expansion. (#14171, #13906)
- Hetero-mode actions bar; tool inspector polish. (#13963, #14034,
#14030)
- Codex desktop integration with rich tool rendering and devtools
preview. (#14067, #14100)
- Codex terminal error surfacing and CLI output tracing. (#14166)
- Tighten `isCanUseVision` default and add aggregator fallback. (#14172)
- Persist `ccSessionId` in topic metadata for CC multi-turn resume.
(#13902)
- CC account card, topic filter, and integration polish. (#13955,
#13942, #13950)
- Token-level deltas streamed via `--include-partial-messages`. (#13929)

---

## 🧠 Agent Signal & Self-Iteration

- New `@lobechat/agent-signal` package with dynamic feedback signals.
(#14157)
- AgentSignalRuntime wired through agent-tracing and observability-otel
metrics. (#14170, #14159)
- Self-iteration feature flag added to Lab; front-side flag check.
(#14169, #14186)
- Signal policy for receiving memory feedback dynamically. (#14187)

---

## 💬 Conversation

- Queue follow-up sends during running CC turns. (#14179)
- Persist per-topic chat scroll position; pin user message + fold long
messages. (#14191, #14056)
- Inline resend when editing last user message. (#14080)
- Disable first-block markdown streaming to prevent flicker. (#14193,
#13904)
- Prevent Markdown stream replay when vlist remounts streaming items.
(#14086)
- Stop repinning after manual scroll; unify scroll-to-user + spacer
hooks. (#14099, #14132)

---

## 📱 Platforms & Integrations

### Desktop / Electron

- Screen capture overlay, Quick Chat tray, and upload pipeline
improvements. (#13818)
- macOS permission gate for screen capture; auto-focus chat panel input.
(#14097, #14105)
- Dedicated topic popup window with cross-window sync. (#13957)
- TabBar polish: `+` button for new topic, dark theme blend, close icon
by default. (#13972, #14203, #13973)
- Recent working directories expanded from 5 to 20; submodule/worktree
repo detection. (#14036, #13978)
- Cmd+W / Cmd+T tab shortcuts and global shortcut consolidation.
(#13983, #13880)
- Linux icon configuration; human approval desktop notifications.
(#14042, #14092)

### Git Workflow

- One-click pull/push from branch chip; ahead/behind badge with
refactored GitCtr. (#14041, #13980)

### Mobile

- Full settings menu and responsive profile layout. (#14019)
- Agent route added to mobile router; mobile agent topic route
registered. (#14103, #14158)
- Session list skeleton row layout corrected. (#14040)

### Bot / Messaging

- DM strategy support; bot emoji and markdown render optimization.
(#14201, #14091, #14140)
- Slack webhook fix; bot platform setup guide reference. (#14052,
#14121)

---

## 🤖 Models & Providers

### New models

- **Claude Opus 4.7** with `xhigh` effort tier; strip temperature/top_p.
(#13903, #13909)
- **GPT-5.5**. (#14147)
- **DeepSeek V4** Flash/Pro cards with reasoning slider; cache-hit and
Pro discount pricing. (#14114, #14209, #14196, #14131)
- **Kimi K2.6** model with LobeHub-hosted card. (#14004, #14006)
- **MiMo-V2.5 / V2.5-Pro**. (#14089)
- **gpt-image-2**, **Qwen3.6 Flash/Plus**, **Pixverse-c1**. (#14039,
#13923)

### New providers

- **OpenCode Zen** and **OpenCode Go** with env-var support. (#13943,
#14064)
- **Azure OpenAI Router** runtime support. (#13823)
- Model alias mapping for image and video runtimes. (#13896)
- Seedance video models migrated to Dreamina. (#14144)

### Runtime reliability

- Sanitize invalid tool_call arguments to unbreak strict providers.
(#14033)
- Tolerate null `function.name` in streaming tool_call deltas. (#14139)
- Preserve Gemini 3 `thoughtSignature` in `call_tools_batch`
normalization. (#14032)
- Downgrade `image_url` parts when target model lacks vision. (#14029)
- Preserve Cloudflare provider error context. (#14136)
- Use `safety_identifier` for OpenAI Responses API. (#14148)
- Unwrap underlying PG error in `formatErrorEventData`. (#14038)

---

## 🖥️ User Experience

- **Onboarding** — Preset agent naming suggestions, structured hunk ops
for `updateDocument`, persona analytics snapshot, footer promotion
pipeline, wrap-up button. (#13931, #13989, #13930, #13853, #13934)
- **Document workflow** — Agent documents promoted as primary workspace
panel; history management and compare workflow; web-crawl docs
associated with agent documents. (#13924, #13725, #13893)
- **cmdk** — Agent identity surfaced on topic search results;
topic/message search scoped to current agent. (#14204, #13960)
- **Floating chat panel** and workspace improvements. (#13887)
- **Topic completion status** with dropdown action and filter. (#14005)

---

## 🔧 Tooling

- Redis-backed feature flag provider for runtime config. (#14098)
- Vite upgraded to 8.0.0 with Rolldown strict execution order. (#12720,
#14058)
- `@lobechat/model-bank` automated npm release with provenance. (#14015,
#14017, #14018)
- Skill activation fallback when `activateTools` cannot find identifier.
(#14010)
- Cron tool: timezone and existing jobs injected into system prompt;
clarified `lobe-gtd` and `lobe-cron` descriptions. (#14012, #14013)

---

## 🔒 Security & Reliability

- **Security:** uuid bumped to v14 (advisory). (#14083)
- **Security:** validate avatar URL and scope old-avatar deletion to
owner. (#13982)
- **Security:** clear OIDC sessions on better-auth signout; return 401
(not 500) for expired OIDC JWT. (#13916, #14014)
- **Reliability:** scope pending-approval check to current assistant
turn. (#14182)
- **Reliability:** sanitize heterogeneous-agent attachment cache
filenames. (#13937)
- **Reliability:** reduce subagent task status error noise. (#14026)

---

## 👥 Contributors

Huge thanks to **17 contributors** who shipped **194 merged PRs** this
week.

@hardy · @shaun0927 · @hezhijie0327 · @sxjeru · @arvinxx · @Innei ·
@tjx666 · @lijian · @neko · @rdmclin2 · @AmAzing129 · @sudongyuer ·
@CanisMinor · @rivertwilight

Plus @lobehubbot and renovate[bot] for maintenance.

---

**Full Changelog**:
v2.1.52...v2.1.53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant