feat(ai): add Google ADK (@google/adk) observability adapter - #4687
feat(ai): add Google ADK (@google/adk) observability adapter#4687AhmadHammad21 wants to merge 8 commits into
Conversation
Add a @posthog/ai/adk adapter that captures a full standard $ai_generation event for every model call an ADK agent makes. The adapter is a Google ADK BasePlugin (PostHogADKPlugin) that hooks beforeModelCallback to record input messages + start time, and afterModelCallback / onModelErrorCallback to record output, model, token usage, latency and finish reason. Everything funnels through the shared captureAiGeneration primitive so PostHog derives cost from the model and tokens (never hardcoded). - Maps ADK usageMetadata: promptTokenCount -> $ai_input_tokens, candidatesTokenCount -> $ai_output_tokens, thoughtsTokenCount -> $ai_reasoning_tokens, cachedContentTokenCount -> $ai_cache_read_input_tokens. - Emits $ai_input, $ai_output_choices, $ai_latency, $ai_model, $ai_provider, $ai_framework, trace id (invocation id), session id, distinct id and groups. - @google/adk declared as an optional peer dependency, mirroring the other provider adapters. - Adds the ./adk submodule export and rollup build entry. - Unit tests mirror the existing adapter tests (mock ADK callback payloads, assert the emitted event shape).
cba2e36 to
9716742
Compare
|
event ingested: {
"createdAt": "2026-08-31T12:27:56.302000+00:00",
"event": "$ai_generation",
"id": "01a057ca-6087-787c-a6cb-749a6605da82",
"properties": {
"$ai_model_parameters": {},
"$ai_stop_reason": "STOP",
"$ai_output_tokens": 8,
"$ai_http_status": 200,
"$ai_lib_version": "8.9.0",
"$ai_input_tokens": 39,
"$ai_trace_id": "e-aab8f721-28c8-452f-9019-b306c0328e6a",
"$lib": "posthog-node",
"$ai_model": "gemini-3.6-flash",
"$ai_provider": "gemini",
"$ai_session_id": "e019b890-206d-42de-84fa-e8f4827bb4f6",
"$ai_base_url": "",
"$ai_framework": "google-adk",
"$ai_agent_name": "posthog_adk_example",
"$ai_tokens_source": "sdk",
"$lib_version": "5.51.4",
"example": "example-ai-adk",
"$is_server": true,
"$ai_lib": "posthog-ai",
"$ai_latency": 2.204,
"$geoip_disable": true,
"$ai_reasoning_tokens": 85,
"$ip": "84.115.233.26",
"$sent_at": "2026-08-31T12:27:55.911Z",
"$ai_text_input_tokens": 39,
"$ai_cache_reporting_exclusive": false,
"$ai_input_cost_usd": 0.00002925,
"$ai_output_cost_usd": 0.00034875,
"$ai_request_cost_usd": 0,
"$ai_web_search_cost_usd": 0,
"$ai_total_cost_usd": 0.000378,
"$ai_model_cost_used": "google/gemini-3.6-flash",
"$ai_cost_model_source": "openrouter",
"$ai_cost_model_provider": "google-ai-studio",
"$ai_input": [
{
"content": "You are an agent. Your internal name is \"posthog_adk_example\".\n\nBe concise and helpful.",
"role": "system"
},
{
"content": [
{
"text": "-- Reply with exactly: PostHog ADK example passed.",
"type": "text"
}
],
"role": "user"
}
],
"$ai_output_choices": [
{
"content": [
{
"text": "PostHog ADK example passed.",
"type": "text"
}
],
"role": "assistant"
}
]
},
"sentiment": null
} |
|
thanks @AhmadHammad21 |
|
i pushed a few fixes and added the sample so its testable |
|
Possible follow-up (non-blocking): omit |
|
Thanks @marandaneto , really appreciate you testing it live. Happy to fold in the |
its not a blocker, and not harmful either, so ok as is for now |
Pushed it in Thank for your feedback! |
Widen the shared captureAiGeneration `baseURL` option to accept `null` as an explicit "no base URL" signal that omits `$ai_base_url` from the event, while `undefined`/omitted keeps the existing `''` default for backward compatibility. The ADK plugin passes `baseURL: null` since it has no base URL, so its $ai_generation event no longer emits an empty `$ai_base_url`. Claude-Session: https://claude.ai/code/session_01UyHb4igrAvRGgaFcPypmgB
85c6ee0 to
bbe4148
Compare
…conflicts # Conflicts: # packages/ai/package.json
Problem
I was setting up observability for an agent built on Google's Agent Development Kit (
@google/adk) and wanted to send its model calls to PostHog, but there was no adapter for it.@posthog/aialready ships observability adapters for OpenAI, Anthropic, Gemini, LangChain, OpenAI Agents, Vercel AI SDK and OpenTelemetry, yet nothing for ADK, so there is no first-class way to get PostHog LLM analytics ($ai_generationevents, cost, latency, token usage, traces) for the model calls an ADK agent makes. It felt like something other people building on ADK would want too, so I put this together to fill the gap.Changes
Adds a Google ADK observability adapter at
@posthog/ai/adk.PostHogADKPluginis an ADKBasePluginthat hooks the model-call lifecycle and emits one full standard$ai_generationevent per model call, funnelling through the sharedcaptureAiGenerationprimitive so PostHog derives cost from the model and token usage (never hardcoded):beforeModelCallbackrecords the input messages, model parameters and start time.afterModelCallback/onModelErrorCallbackrecord the output, model id, finish reason, latency and token usage (and errors).usageMetadata:promptTokenCount → $ai_input_tokens,candidatesTokenCount → $ai_output_tokens,thoughtsTokenCount → $ai_reasoning_tokens,cachedContentTokenCount → $ai_cache_read_input_tokens.$ai_input,$ai_output_choices,$ai_latency,$ai_model,$ai_provider,$ai_framework, plus trace id (invocation id), session id, distinct id and group analytics.Content.privacyMode,groups, extraproperties,captureImmediateand anonErrorhook, mirroring the other adapters' option shapes.@google/adk(and its@google/genaitypes) are declared as optional peer dependencies, mirroring how the Gemini and OpenAI Agents adapters declare their provider deps. Adds the./adksubmodule export inpackage.jsonand the rollup build entry. This complements the existingotelexporter rather than duplicating it: it produces the complete$ai_generationshape directly from ADK's plugin callbacks.Release info Sub-libraries affected
Libraries affected
Checklist
If releasing new changes
pnpm changesetto generate a changeset fileHow tested
packages/ai/tests/adk.test.ts(17 tests) mirroring the existing adapter test suites: mocks ADKbeforeModelCallback/afterModelCallback/onModelErrorCallbackpayloads and asserts the emitted$ai_generationevent shape, token mapping, latency, trace/session/distinct id resolution, privacy mode, error capture and group analytics.jestfor@posthog/ai: 17/17 passing.eslintonsrc/adkandtests/adk.test.ts: clean.rollupbuild: emitsdist/adk/index.{cjs,mjs,d.ts}.