name: heterogeneous-agent description: '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.'
Heterogeneous Agent Development
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
heteroAgentRawLinetransport,window.__HETERO_AGENT_TRACE, orexecuteHeterogeneousAgent - Fixing Claude Code stream-json bugs such as duplicate partial/full chunks, broken
message.idboundaries, missingtool_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
- CLI raw stdout / JSONL
- Electron main spawns the CLI and broadcasts
heteroAgentRawLine - Adapter maps raw provider events into
HeterogeneousAgentEvent executeHeterogeneousAgentpersists assistant/tool messages and forwards stream eventscreateGatewayEventHandlerhydrates the UI- Only after this path looks correct should you move on to
agent-tracingor context-engine debugging
Read These Files First
apps/desktop/src/main/controllers/HeterogeneousAgentCtr.tsapps/desktop/src/main/modules/heterogeneousAgent/drivers/claudeCode.tsapps/desktop/src/main/modules/heterogeneousAgent/drivers/codex.tspackages/heterogeneous-agents/src/adapters/claudeCode.tspackages/heterogeneous-agents/src/adapters/codex.tssrc/store/chat/slices/aiChat/actions/heterogeneousAgentExecutor.tssrc/store/chat/slices/aiChat/actions/__tests__/heterogeneousAgentExecutor.test.ts
Default Debug Order
- 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-tracerather than hand-rolling aclaude -prepro (see references/debug-workflow.md §2). - If raw output is correct, compare it with adapter output. In dev,
executeHeterogeneousAgentexposeswindow.__HETERO_AGENT_TRACE. - If adapted events look correct, inspect
persistToolBatch,persistToolResult, step transitions, and subagent routing. - Turn the repro into a focused test before fixing.
- 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.idare one turn, not multiple turns. - In Claude Code,
tool_resultlives intype: 'user'events, not assistant events. - In Claude Code partial mode,
message_delta.usageis authoritative; do not trust echoed usage on every assistant block. persistToolBatchmust pre-register assistanttools[]before creating tool messages.- Every tool message must keep
parentIdequal to the owning assistant andtool_call_idequal to the tool id. tool_resultmust resolve an existingtoolMsgIdByCallId.- Subagent chunks must stay in thread scope and must not be forwarded into the main assistant stream.
- Never clear the global
toolMsgIdByCallIdmap 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.idchanges. - Claude Code tool results never land:
check whether
type: 'user'tool_resultblocks are being ignored because the code only inspects assistant events. - Claude Code TodoWrite cards look stale:
check whether synthesized
pluginState.todosis being attached at tool-result time. - Claude Code subagent transcript leaks into the main bubble:
check
parent_tool_use_idhandling 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
newStepor an equivalent turn-change signal. - Orphan tool messages:
first check step-transition ordering and whether
persistToolBatchPhase 1 ran before tool message creation. - Tool bubble stays loading:
look for
tool_result for unknown toolCallIdand missingresult_msg_idbackfill. - 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_inforides onstatus: "allowed"too).
References
- For commands, trace capture, invariants, and focused test commands, read references/debug-workflow.md.