Heterogeneous Agent Development

SkillAI & models

Helps your agent build or debug LobeHub adapters that connect external CLI agents like Claude Code or Codex.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Heterogeneous Agent Development skill

About this capability

Implement or debug LobeHub heterogeneous agents. Use for Claude Code/Codex adapters, external CLI agents, event mapping, IPC, persistence, tool-call chains, sessions, traces, or adapter bugs.

What this skill tells your AI

The instructions your AI receives, as published by lobehub/lobehub in .agents/skills/heterogeneous-agent/SKILL.md and read by ahel’s review.

Use this skill when the bug or feature lives in the external CLI agent pipeline, not the normal server-side agent runtime.

Use This Skill For

  • Adding or changing a driver under apps/desktop/src/main/modules/heterogeneousAgent/drivers/
  • Editing an adapter under packages/heterogeneous-agents/src/adapters/
  • Debugging heteroAgentRawLine transport, window.__HETERO_AGENT_TRACE, or executeHeterogeneousAgent
  • Fixing Claude Code stream-json bugs such as duplicate partial/full chunks, broken message.id boundaries, missing tool_result, TodoWrite state drift, or subagent thread routing
  • Fixing Codex JSONL bugs such as mixed multi-tool messages, broken turn boundaries, or missing tool-result mapping
  • Fixing step-boundary, tool persistence, subagent thread, or resume bugs in Claude Code / Codex flows
  • Reproducing multi-tool mixing, orphan tool messages, or stuck tool-result loading

Pipeline Map

  1. CLI raw stdout / JSONL
  2. Electron main spawns the CLI and broadcasts heteroAgentRawLine
  3. Adapter maps raw provider events into HeterogeneousAgentEvent
  4. executeHeterogeneousAgent persists assistant/tool messages and forwards stream events
  5. createGatewayEventHandler hydrates the UI
  6. Only after this path looks correct should you move on to agent-tracing or context-engine debugging

Read These Files First

  • apps/desktop/src/main/controllers/HeterogeneousAgentCtr.ts
  • apps/desktop/src/main/modules/heterogeneousAgent/drivers/claudeCode.ts
  • apps/desktop/src/main/modules/heterogeneousAgent/drivers/codex.ts
  • packages/heterogeneous-agents/src/adapters/claudeCode.ts
  • packages/heterogeneous-agents/src/adapters/codex.ts
  • src/store/chat/slices/agentRun/actions/transports/hetero/heterogeneousAgentExecutor.ts
  • src/store/chat/slices/agentRun/actions/__tests__/heterogeneousAgentExecutor.test.ts

Default Debug Order

  1. Prove whether the raw CLI output is correct before touching UI code. The app records every real session — read the most recent one via cat .heerogeneous-tracing/.last-live-trace rather than hand-rolling a claude -p repro (see references/debug-workflow.md §2).
  2. If raw output is correct, compare it with adapter output. In dev, executeHeterogeneousAgent exposes window.__HETERO_AGENT_TRACE.
  3. If adapted events look correct, inspect persistToolBatch, persistToolResult, step transitions, and subagent routing.
  4. Turn the repro into a focused test before fixing.
  5. Only after the transport/adapter/executor path looks sound should you debug later-stage message processing.

Critical Invariants

  • One raw tool item must map to one stable ToolCallPayload.id.
  • A new main-agent step must emit a boundary signal before events are forwarded to the new assistant.
  • In Claude Code, multiple assistant events with the same message.id are one turn, not multiple turns.
  • In Claude Code, tool_result lives in type: 'user' events, not assistant events.
  • In Claude Code partial mode, message_delta.usage is authoritative; do not trust echoed usage on every assistant block.
  • persistToolBatch must pre-register assistant tools[] before creating tool messages.
  • Every tool message must keep parentId equal to the owning assistant and tool_call_id equal to the tool id.
  • tool_result must resolve an existing toolMsgIdByCallId.
  • Subagent chunks must stay in thread scope and must not be forwarded into the main assistant stream.
  • Never clear the global toolMsgIdByCallId map at main step boundaries.

Common Bug Patterns

  • Claude Code duplicates text or thinking: check whether partial deltas and the later full assistant block are both being emitted.
  • Claude Code opens too many assistant messages: check whether the adapter is cutting steps on every assistant event instead of only on message.id changes.
  • Claude Code tool results never land: check whether type: 'user' tool_result blocks are being ignored because the code only inspects assistant events.
  • Claude Code TodoWrite cards look stale: check whether synthesized pluginState.todos is being attached at tool-result time.
  • Claude Code subagent transcript leaks into the main bubble: check parent_tool_use_id handling and whether subagent chunks are being forwarded to the main gateway handler.
  • Multiple Codex tools collapse into one assistant message: first check whether the adapter emits a usable step boundary such as newStep or an equivalent turn-change signal.
  • Orphan tool messages: first check step-transition ordering and whether persistToolBatch Phase 1 ran before tool message creation.
  • Tool bubble stays loading: look for tool_result for unknown toolCallId and missing result_msg_id backfill.
  • Subagent tools show up in the main bubble: check for subagent chunks reaching the main gateway handler.
  • Wrong terminal-error guide (e.g. "usage limit reached" shown for a network drop): a classifier is branching on a structured field whose mere presence isn't its meaning. Grep the field across all event states in a real trace before trusting it — see references/debug-workflow.md §8 (CC rate_limit_info rides on status: "allowed" too).

References

Signals

GitHub stars
82k
Forks
16k
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
heterogeneous-agent-lobehub
Source
github.com/lobehub/lobehub