Skip to content

Commit df3434d

Browse files
AbhiPrasadlforst
andauthored
feat(google-adk): add ADK instrumentation and e2e coverage (#1765)
resolves #1477 Add Braintrust instrumentation for `@google/adk` with **auto-instrumentation support by default** when users run with Braintrust's loader hook. This adds tracing for: - `Runner.runAsync` - `BaseAgent.runAsync` and subclasses - `FunctionTool.runAsync` It also adds Google ADK e2e coverage for both hook-driven and wrapped execution. Because ADK uses `@google/genai` under the hood, underlying LLM spans continue to come from the existing Google GenAI instrumentation. ## Recommended usage: auto-instrumentation The primary way users should adopt this is via Braintrust auto-instrumentation: ```bash node --import braintrust/hook.mjs app.mjs ``` Then they can use `@google/adk` normally and Braintrust will trace supported ADK operations automatically. Example: ```ts import * as adk from "@google/adk"; import { initLogger } from "braintrust"; initLogger({ projectName: "my-google-adk-app" }); const agent = new adk.LlmAgent({ name: "weather_agent", model: "gemini-2.5-flash-lite", instruction: "Answer weather questions", }); const runner = new adk.InMemoryRunner({ agent, appName: "weather-app" }); await runner.sessionService.createSession({ appName: runner.appName, userId: "user-1", sessionId: "session-1", }); for await (const event of runner.runAsync({ userId: "user-1", sessionId: "session-1", newMessage: { role: "user", parts: [{ text: "What's the weather in Paris?" }], }, })) { console.log(event); } ``` If needed, it can be disabled with: ```bash BRAINTRUST_DISABLE_INSTRUMENTATION=google-adk node --import braintrust/hook.mjs app.mjs ``` ## Manual usage Manual wrapping is also available for cases where users want explicit control: ```ts import * as adk from "@google/adk"; import { wrapGoogleADK } from "braintrust"; const wrapped = wrapGoogleADK(adk); ``` ## Screenshot <img width="347" height="254" alt="image" src="https://github.com/user-attachments/assets/5fe15b68-5486-4f84-ae87-e8ee4b4f3971" /> --------- Co-authored-by: Luca Forstner <luca.forstner@gmail.com>
1 parent c16f6ba commit df3434d

29 files changed

Lines changed: 11639 additions & 105 deletions

e2e/config/pr-comment-scenarios.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@
2222
{ "variantKey": "anthropic-v0800", "label": "v0.80.0" }
2323
]
2424
},
25+
{
26+
"scenarioDirName": "google-adk-instrumentation",
27+
"label": "Google ADK Instrumentation",
28+
"metadataScenario": "google-adk-instrumentation",
29+
"variants": [{ "variantKey": "google-adk-v061", "label": "v0.6.1" }]
30+
},
2531
{
2632
"scenarioDirName": "google-genai-instrumentation",
2733
"label": "Google GenAI Instrumentation",
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
[
2+
{
3+
"metadata": {
4+
"scenario": "google-adk-instrumentation"
5+
},
6+
"metrics": {
7+
"start": 0
8+
},
9+
"name": "google-adk-instrumentation-root",
10+
"type": "task"
11+
},
12+
{
13+
"metadata": {
14+
"operation": "simple-run"
15+
},
16+
"metrics": {
17+
"start": 0
18+
},
19+
"name": "adk-simple-run-operation",
20+
"type": null
21+
},
22+
{
23+
"input": {
24+
"messages": [
25+
{
26+
"content": "What is the weather in Paris, France?",
27+
"role": "user"
28+
}
29+
]
30+
},
31+
"metadata": {
32+
"google_adk.session_id": "test-session-1",
33+
"google_adk.user_id": "test-user",
34+
"provider": "google-adk"
35+
},
36+
"metrics": {
37+
"start": 0
38+
},
39+
"name": "Google ADK Runner",
40+
"type": "task"
41+
},
42+
{
43+
"metadata": {
44+
"google_adk.agent_name": "weather_agent",
45+
"model": "gemini-2.5-flash-lite",
46+
"provider": "google-adk"
47+
},
48+
"metrics": {
49+
"start": 0
50+
},
51+
"name": "Agent: weather_agent",
52+
"type": "task"
53+
},
54+
{
55+
"input": {
56+
"location": "Paris, France"
57+
},
58+
"metadata": {
59+
"google_adk.tool_call_id": "adk-<uuid:1>",
60+
"google_adk.tool_name": "get_weather",
61+
"provider": "google-adk"
62+
},
63+
"metrics": {
64+
"duration": 0,
65+
"end": 0,
66+
"start": 0
67+
},
68+
"name": "tool: get_weather",
69+
"output": {
70+
"condition": "sunny",
71+
"location": "Paris, France",
72+
"temperature": 72
73+
},
74+
"type": "tool"
75+
},
76+
{
77+
"metadata": {
78+
"google_adk.agent_name": "weather_agent",
79+
"model": "gemini-2.5-flash-lite",
80+
"provider": "google-adk"
81+
},
82+
"metrics": {
83+
"duration": 0,
84+
"end": 0,
85+
"start": 0
86+
},
87+
"name": "Agent: weather_agent",
88+
"output": {
89+
"author": "weather_agent",
90+
"content": "<text>",
91+
"role": "model"
92+
},
93+
"type": "task"
94+
},
95+
{
96+
"input": {
97+
"messages": [
98+
{
99+
"content": "What is the weather in Paris, France?",
100+
"role": "user"
101+
}
102+
]
103+
},
104+
"metadata": {
105+
"google_adk.session_id": "test-session-1",
106+
"google_adk.user_id": "test-user",
107+
"provider": "google-adk"
108+
},
109+
"metrics": {
110+
"completion_tokens": "<number>",
111+
"duration": 0,
112+
"end": 0,
113+
"prompt_tokens": "<number>",
114+
"start": 0,
115+
"tokens": "<number>"
116+
},
117+
"name": "Google ADK Runner",
118+
"output": {
119+
"author": "weather_agent",
120+
"content": "<text>",
121+
"role": "model"
122+
},
123+
"type": "task"
124+
},
125+
{
126+
"metadata": {
127+
"operation": "simple-run"
128+
},
129+
"metrics": {
130+
"end": 0,
131+
"start": 0
132+
},
133+
"name": "adk-simple-run-operation",
134+
"type": null
135+
},
136+
{
137+
"metadata": {
138+
"scenario": "google-adk-instrumentation"
139+
},
140+
"metrics": {
141+
"end": 0,
142+
"start": 0
143+
},
144+
"name": "google-adk-instrumentation-root",
145+
"type": "task"
146+
}
147+
]
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
[
2+
{
3+
"has_input": false,
4+
"has_output": false,
5+
"metadata": {
6+
"scenario": "google-adk-instrumentation"
7+
},
8+
"metric_keys": [],
9+
"name": "google-adk-instrumentation-root",
10+
"root_span_id": "<span:1>",
11+
"span_id": "<span:1>",
12+
"span_parents": [],
13+
"type": "task"
14+
},
15+
{
16+
"has_input": false,
17+
"has_output": false,
18+
"metadata": {
19+
"operation": "simple-run"
20+
},
21+
"metric_keys": [],
22+
"name": "adk-simple-run-operation",
23+
"root_span_id": "<span:1>",
24+
"span_id": "<span:2>",
25+
"span_parents": [
26+
"<span:1>"
27+
],
28+
"type": null
29+
},
30+
{
31+
"has_input": true,
32+
"has_output": false,
33+
"metadata": {
34+
"google_adk.session_id": "test-session-1",
35+
"google_adk.user_id": "test-user",
36+
"provider": "google-adk"
37+
},
38+
"metric_keys": [],
39+
"name": "Google ADK Runner",
40+
"root_span_id": "<span:1>",
41+
"span_id": "<span:3>",
42+
"span_parents": [
43+
"<span:2>"
44+
],
45+
"type": "task"
46+
},
47+
{
48+
"has_input": false,
49+
"has_output": false,
50+
"metadata": {
51+
"google_adk.agent_name": "weather_agent",
52+
"model": "gemini-2.5-flash-lite",
53+
"provider": "google-adk"
54+
},
55+
"metric_keys": [],
56+
"name": "Agent: weather_agent",
57+
"root_span_id": "<span:1>",
58+
"span_id": "<span:4>",
59+
"span_parents": [
60+
"<span:3>"
61+
],
62+
"type": "task"
63+
},
64+
{
65+
"has_input": true,
66+
"has_output": true,
67+
"metadata": {
68+
"google_adk.tool_call_id": "adk-<uuid:5>",
69+
"google_adk.tool_name": "get_weather",
70+
"provider": "google-adk"
71+
},
72+
"metric_keys": [
73+
"duration"
74+
],
75+
"name": "tool: get_weather",
76+
"root_span_id": "<span:1>",
77+
"span_id": "<span:5>",
78+
"span_parents": [
79+
"<span:4>"
80+
],
81+
"type": "tool"
82+
},
83+
{
84+
"has_input": false,
85+
"has_output": true,
86+
"metadata": {
87+
"google_adk.agent_name": "weather_agent",
88+
"model": "gemini-2.5-flash-lite",
89+
"provider": "google-adk"
90+
},
91+
"metric_keys": [
92+
"duration"
93+
],
94+
"name": "Agent: weather_agent",
95+
"root_span_id": "<span:1>",
96+
"span_id": "<span:4>",
97+
"span_parents": [
98+
"<span:3>"
99+
],
100+
"type": "task"
101+
},
102+
{
103+
"has_input": true,
104+
"has_output": true,
105+
"metadata": {
106+
"google_adk.session_id": "test-session-1",
107+
"google_adk.user_id": "test-user",
108+
"provider": "google-adk"
109+
},
110+
"metric_keys": [
111+
"completion_tokens",
112+
"duration",
113+
"prompt_tokens",
114+
"tokens"
115+
],
116+
"name": "Google ADK Runner",
117+
"root_span_id": "<span:1>",
118+
"span_id": "<span:3>",
119+
"span_parents": [
120+
"<span:2>"
121+
],
122+
"type": "task"
123+
}
124+
]

0 commit comments

Comments
 (0)