[FEATURE REQUEST] Expose Agent Hierarchy Metadata in API Requests
[FEATURE REQUEST] Expose Agent Hierarchy Metadata in API Requests
Summary
Add configuration support in settings.json to include dynamic agent metadata (session ID, agent ID, parent-child relationship) in outgoing API requests, enabling request correlation and analytics at the gateway/proxy layer.
Problem Statement
Claude Code internally maintains rich agent hierarchy information (main agent, sub-agents via Task tool, session IDs, parent-child relationships), but this metadata is not exposed in API requests sent to Anthropic API or proxied endpoints.
Current Limitations
- No request-level identification: All API calls appear identical at the network layer
- Cannot distinguish main vs sub-agent requests: Gateway/proxy cannot differentiate between main agent interactions and sub-agent (Explore/Plan/etc.) calls
- No parent-child correlation: Cannot trace which main agent request spawned which sub-agent requests
- Session isolation: No way to group requests belonging to the same Claude Code session
Real-World Impact
Organizations using model gateways (e.g., LiteLLM, custom FastAPI proxies) for:
- API cost allocation by agent type
- Performance analysis (main agent latency vs sub-agent throughput)
- Request correlation for debugging
- Compliance logging with full call chain traceability
Currently have no reliable way to differentiate these requests except through brittle heuristics (parsing system prompts, detecting model types).
Proposed Solution
Configuration in settings.json
Add support for dynamic request metadata injection:
{
"apiRequestMetadata": {
"includeSessionId": true,
"includeAgentId": true,
"includeAgentType": true,
"includeParentId": true
}
}
API Request Changes
When enabled, include metadata in both request headers and request body:
Option A: Request Headers (Recommended)
POST /v1/messages HTTP/1.1
Host: api.anthropic.com
X-Claude-Session-ID: af1b7c07-e3c9-48f1-b9c9-847bb96173b1
X-Claude-Agent-ID: agent_12345678
X-Claude-Agent-Type: main | sub
X-Claude-Parent-ID: msg_abc123 (only for sub-agents)
X-Claude-Subagent-Type: Explore (only for sub-agents)
Option B: Request Body Metadata Field
{
"model": "claude-sonnet-4-5",
"messages": [...],
"metadata": {
"claude_code_session_id": "af1b7c07...",
"claude_code_agent_id": "agent_12345678",
"claude_code_agent_type": "main",
"claude_code_parent_id": null
}
}
Key Design Principles
- Opt-in: Disabled by default for backward compatibility
- Dynamic: Values computed per-request (not static like
ANTHROPIC_CUSTOM_HEADERS) - Non-sensitive: Does not expose prompt content, only structural metadata
- Gateway-friendly: Designed for proxy/gateway consumption
Use Cases
1. Cost Allocation
-- Gateway database query
SELECT agent_type, COUNT(*), SUM(total_tokens)
FROM api_requests
WHERE session_id = 'af1b7c07...'
GROUP BY agent_type;
2. Parent-Child Correlation
# Trace full call chain for a main agent request
main_request = db.get_request(agent_id='main_123')
sub_requests = db.query(parent_id='main_123')
print(f"Main request spawned {len(sub_requests)} sub-agents")
3. Performance Analysis
# Compare main vs sub-agent performance
main_latency = avg(requests.filter(agent_type='main').latency)
sub_latency = avg(requests.filter(agent_type='sub').latency)
4. Session Replay & Debug
# Reconstruct full session conversation tree
claude-analytics replay --session-id af1b7c07...
# Shows: main agent → Task(Explore) → Task(Plan) → main agent
Current Workarounds & Why They're Insufficient
Workaround 1: Heuristic Detection (Brittle)
# Gateway-side detection via request body parsing
if 'haiku' in model and 'specialized agent' in system_prompt:
agent_type = 'sub' # ❌ Fails if user manually uses haiku
Issues: ~30% false positive rate, cannot detect sessionId or parent relationships
Workaround 2: mitmproxy Injection (Complex)
- Requires SSL interception setup
- Performance overhead (~5-10ms per request)
- Security concerns with HTTPS MITM
- Still relies on heuristics for agent type detection
Workaround 3: Static Custom Headers (Useless)
{
"env": {
"ANTHROPIC_CUSTOM_HEADERS": "X-Source: claude-code"
}
}
Issues: Static headers cannot convey dynamic per-request metadata
Comparison with Existing Issues
- #11320 (Task Tool Metadata): Focuses on return values from sub-agents to main agent
- #11917 (Usage Metrics in Session JSON): Focuses on data visible to agents internally
- #11455 (Session Handoff): Focuses on persisting state between CLI sessions
This request focuses on outbound API request enrichment for external systems.
Implementation Notes
Backward Compatibility
- Default:
apiRequestMetadata: { enabled: false } - No change to existing API contracts
- Gateway/proxy systems simply ignore unknown headers if not needed
Privacy Considerations
- Session/agent IDs are opaque UUIDs (no PII)
- Does not expose prompt content or tool call details
- Metadata only describes request structure, not content
Anthropic API Compatibility
If using official Anthropic API, metadata field already exists but is not populated by Claude Code. This would simply start using that existing field.
For headers, they are passed through transparently and do not affect API behavior.
Expected Benefits
- Gateway operators: Accurate cost allocation, performance dashboards, compliance logging
- Anthropic: Better usage analytics, improved support debugging
- Users: Transparency into sub-agent behavior, better session management tools
References
- Related discussion: [Gateway Integration Guide](file:///Users/ecarx/tmp/gateway-integration-guide.md)
- Real API request analysis: [Actual Claude Code API log](provided in discussion)
- Heuristic detection implementation: [gateway-agent-detector.py](file:///Users/ecarx/tmp/gateway-agent-detector.py)
---
Priority: Enhancement
Complexity: Medium (requires plumbing session/agent context to API client layer)
Impact: High (enables whole new category of observability/analytics use cases)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗