Skip to content

feat(metadata): Add token usage and execution metrics to A2A task responses#127

Merged
edenreich merged 23 commits intomainfrom
claude/issue-126-20251215-1247
Dec 30, 2025
Merged

feat(metadata): Add token usage and execution metrics to A2A task responses#127
edenreich merged 23 commits intomainfrom
claude/issue-126-20251215-1247

Conversation

@edenreich
Copy link
Copy Markdown
Contributor

@edenreich edenreich commented Dec 15, 2025

Summary

Implements token usage and execution metrics tracking in A2A task responses through the Task.Metadata field, enabling clients to monitor resource consumption, costs, and performance.

Closes #126

Changes

Core Infrastructure

  • UsageTracker: New component that aggregates metrics during task execution
    • Token usage: prompt_tokens, completion_tokens, total_tokens
    • Execution statistics: iterations, messages, tool_calls, failed_tools
    • Thread-safe implementation with mutex protection

Task Handler Enhancements

  • Modified DefaultBackgroundTaskHandler to track and populate usage metadata
  • Modified DefaultStreamingTaskHandler to track and populate usage metadata
  • Automatic metadata injection into completed tasks via populateTaskMetadata()
  • Metrics only populated when actual usage is detected

Agent Integration

  • Updated RunWithStream() to create and inject UsageTracker into context
  • Tool execution tracking in executeToolCallsWithEvents()
  • Iteration and message counting during agent loops
  • Token usage collection from LLM streaming responses

Configuration

  • Added EnableUsageMetadata field to AgentConfig (default: true)
  • Environment variable: AGENT_CLIENT_ENABLE_USAGE_METADATA
  • Applied to both background and streaming task handlers

Metadata Structure

{
  "usage": {
    "prompt_tokens": 156,
    "completion_tokens": 89,
    "total_tokens": 245
  },
  "execution_stats": {
    "iterations": 2,
    "messages": 4,
    "tool_calls": 1,
    "failed_tools": 0
  }
}

Testing

  • Unit Tests: Comprehensive coverage for UsageTracker operations
  • Integration Tests: End-to-end validation for both background and streaming handlers
  • All existing tests pass with no regressions

Breaking Changes

None - metadata is additive and backward compatible.


🤖 Generated with Claude Code

…ponses

Implements comprehensive usage tracking for token consumption and execution statistics:

**Token Usage Tracking:**
- Track prompt_tokens, completion_tokens, and total_tokens from LLM responses
- Support both streaming and non-streaming LLM interactions
- Aggregate usage across multiple LLM calls in iterative agent execution

**Execution Statistics:**
- Track iteration count (number of agent execution loops)
- Track message count (total messages in conversation)
- Track tool_calls count (total tool invocations)
- Track failed_tools count (number of failed tool executions)

**Implementation:**
- Created UsageTracker component to aggregate metrics during execution
- Integrated tracker into agent streaming execution (RunWithStream)
- Inject tracker via context in both background and streaming task handlers
- Populate Task.Metadata field with collected metrics on task completion
- Added configuration option AGENT_CLIENT_ENABLE_USAGE_METADATA (default: true)

**Testing:**
- Comprehensive unit tests for UsageTracker with thread-safety verification
- Integration tests for both background and streaming task handlers
- All existing tests pass without modification

**API Changes:**
Task responses now include metadata section with usage statistics:
{
  "task": {
    "id": "task-123",
    "status": { "state": "completed" },
    "metadata": {
      "usage": {
        "prompt_tokens": 156,
        "completion_tokens": 89,
        "total_tokens": 245
      },
      "execution_stats": {
        "iterations": 2,
        "messages": 4,
        "tool_calls": 1,
        "failed_tools": 0
      }
    }
  }
}

Closes #126

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Eden Reich <edenreich@users.noreply.github.com>
@edenreich
Copy link
Copy Markdown
Contributor Author

@claude Please add an example that explains how to use this feature - follow the convention of existing examples.

@claude
Copy link
Copy Markdown
Contributor

claude bot commented Dec 15, 2025

Claude finished @edenreich's task in 5m 16s —— View job


I'll analyze this and get back to you.

claude and others added 3 commits December 15, 2025 14:31
…tracking

Add comprehensive example showing how to track and access token usage and
execution metrics through the Task.Metadata field. This example demonstrates:

- Automatic token usage tracking (prompt_tokens, completion_tokens, total_tokens)
- Execution statistics collection (iterations, messages, tool_calls, failed_tools)
- Configuration via A2A_AGENT_CLIENT_ENABLE_USAGE_METADATA environment variable
- Client-side metadata access and display
- Integration with default task handlers

The example includes:
- Server with calculator tool demonstrating tool call tracking
- Client with formatted metadata display
- Complete Docker Compose setup with Inference Gateway
- Comprehensive README with use cases and troubleshooting
- Updated examples/README.md to reference the new example

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Eden Reich <edenreich@users.noreply.github.com>
Signed-off-by: Eden Reich <eden.reich@gmail.com>
@edenreich
Copy link
Copy Markdown
Contributor Author

@claude fix the CI errors.

@claude
Copy link
Copy Markdown
Contributor

claude bot commented Dec 15, 2025

Claude finished @edenreich's task in 2m 14s —— View job


I'll analyze this and get back to you.

claude and others added 11 commits December 15, 2025 21:12
Co-authored-by: Eden Reich <edenreich@users.noreply.github.com>
Signed-off-by: Eden Reich <eden.reich@gmail.com>
Fix type compatibility issues in task metadata handling after A2A proto schema migration. The Metadata field is now a pointer to map[string]any (*Struct), requiring proper pointer initialization and dereferencing.

Changes:
- Fix task.Metadata initialization to use pointer assignment
- Update metadata access to dereference pointer properly
- Use types.NewTextPart() utility in tests for message parts
- Fix TaskStateCanceled to TaskStateCancelled enum name

Signed-off-by: Eden Reich <eden.reich@gmail.com>
Signed-off-by: Eden Reich <eden.reich@gmail.com>
Signed-off-by: Eden Reich <eden.reich@gmail.com>
Signed-off-by: Eden Reich <eden.reich@gmail.com>
@edenreich edenreich merged commit 1f49f97 into main Dec 30, 2025
1 of 2 checks passed
@edenreich edenreich deleted the claude/issue-126-20251215-1247 branch December 30, 2025 20:34
ig-semantic-release-bot bot added a commit that referenced this pull request Dec 30, 2025
## [0.17.0](v0.16.2...v0.17.0) (2025-12-30)

### ✨ Features

* **metadata:** Add token usage and execution metrics to A2A task responses ([#127](#127)) ([1f49f97](1f49f97)), closes [#126](#126)

### ♻️ Improvements

* Migrate to the latest A2A proto schema ([#129](#129)) ([02c2bc1](02c2bc1))

### 👷 CI

* Bump generator tool to 0.2.2 ([fc58ab9](fc58ab9))

### 🔧 Miscellaneous

* **deps:** Bump claude-code 2.0.65 to 2.0.76 ([47f0a79](47f0a79))
* **deps:** Bump generator tool ([659aec4](659aec4))
* **deps:** Update dependencies and infer configuration ([#128](#128)) ([0fa9d33](0fa9d33))
* **deps:** Update infer config ([76589af](76589af))
@ig-semantic-release-bot
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 0.17.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Expose Token Usage and Execution Metrics in A2A Responses

2 participants