Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 49 additions & 2 deletions docs/integrations/bigquery-agent-analytics.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ catalog_tags: ["observability", "google"]

# BigQuery Agent Analytics plugin for ADK

<div class="language-support-tag">
<span class="lst-supported">Supported in ADK</span><span class="lst-python">Python v1.21.0</span><span class="lst-java">Java v1.5.0</span>
<div class="language-support-tag" title="Kotlin support covers invocation lifecycle logging only; see the Kotlin support note below.">
<span class="lst-supported">Supported in ADK</span><span class="lst-python">Python v1.21.0</span><span class="lst-java">Java v1.5.0</span><span class="lst-kotlin">Kotlin v0.8.0</span>
</div>

The BigQuery Agent Analytics Plugin significantly enhances Agent Development Kit
Expand Down Expand Up @@ -58,6 +58,22 @@ The plugin includes three reliability and observability fixes:
For information on costs, see the [BigQuery
documentation](https://cloud.google.com/bigquery/pricing?e=48754805&hl=en#data-ingestion-pricing).

!!! note "Kotlin support"

The **Kotlin** plugin covers a small subset of this page. It logs
`INVOCATION_STARTING` and `INVOCATION_COMPLETED` only; it fills the identity
columns and `content`, leaving `trace_id`, `span_id`, `latency_ms`,
`attributes` and the rest null; and it creates **no views**, so the `v_*`
views in the table below do not exist for Kotlin. Auto Schema Upgrade, tool
provenance, HITL tracing, drop stats and the ADK 2.0 workflow events are not
implemented.

It also ingests differently: rows go one at a time through
`tabledata.insertAll`, synchronously on the invocation path, not through the
gRPC Storage Write API described above. Those are separate billing lines:
inserted rows are charged with a 1 KB minimum each and no monthly free tier,
so cost scales with invocation count rather than bytes.

## Use cases

- **Agent workflow debugging and analysis:** Capture a wide range of *plugin
Expand Down Expand Up @@ -193,6 +209,37 @@ shows the BigQuery view optionally created when
}
```

=== "Kotlin"

Add the plugin to your agent's `App` object. For prerequisites, see
[Prerequisites](#prerequisites). The plugin is JVM-only and ships outside
core, so add the integrations artifact:

```kotlin title="build.gradle.kts"
implementation("com.google.adk:google-adk-kotlin-integrations:0.8.0")
```

```kotlin title="BigQueryAnalyticsExample.kt"
--8<-- "examples/kotlin/snippets/integrations/BigQueryAnalyticsExample.kt:quickstart"
```

`BigQueryLoggerConfig` is the whole Kotlin configuration surface —
`projectId`, `datasetId`, `enabled` (default `true`), `location` (default
`"US"`, passed to the BigQuery client), `tableName` (default
`"agent_events"`) and `credentials` (default: application default
credentials). The options under [Configuration
options](#configuration-options) are Python and Java only.

**Logging failures are swallowed.** If the table cannot be created or a row
cannot be inserted, the plugin logs and the invocation continues, so a
misconfigured agent looks healthy while writing nothing. When rows are
missing, raise the log level for
`com.google.adk.kt.plugins.agentanalytics.BigQueryAgentAnalyticsPlugin` —
logs are emitted under that class name, not under the plugin's ADK name.
Note also that Kotlin writes `content` as
`{"message": "Invocation started"}` rather than the `{}` shown for these two
event types below.


### Run and test agent

Expand Down
5 changes: 5 additions & 0 deletions examples/kotlin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ dependencies {
// own catalog; the spec and jsonrpc transport arrive transitively.
implementation("com.google.adk:google-adk-kotlin-a2a:0.8.0")
implementation("org.a2aproject.sdk:a2a-java-sdk-client:1.0.0.Final")
// BigQueryAgentAnalyticsPlugin lives in the integrations module. Unlike the
// a2a artifact above, this one publishes google-cloud-bigquery and
// google-auth on jvmApiElements, so the BigQuery types its constructor
// defaults name arrive on the compile classpath with no second line.
implementation("com.google.adk:google-adk-kotlin-integrations:0.8.0")
implementation("com.google.cloud:google-cloud-storage:2.48.2")
implementation("io.opentelemetry:opentelemetry-sdk:1.56.0")
implementation("io.opentelemetry:opentelemetry-exporter-otlp:1.56.0")
Expand Down
66 changes: 66 additions & 0 deletions examples/kotlin/snippets/integrations/BigQueryAnalyticsExample.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.adk.kt.examples.integrations

// --8<-- [start:quickstart]
import com.google.adk.kt.agents.Instruction
import com.google.adk.kt.agents.LlmAgent
import com.google.adk.kt.apps.App
import com.google.adk.kt.models.Gemini
import com.google.adk.kt.plugins.agentanalytics.BigQueryAgentAnalyticsPlugin
import com.google.adk.kt.plugins.agentanalytics.BigQueryLoggerConfig

val analyticsAgent =
LlmAgent(
name = "my_agent",
model = Gemini(name = "gemini-flash-latest"),
instruction = Instruction("You are a helpful assistant."),
)

/**
* Wraps [analyticsAgent] in an [App] whose invocations are logged to BigQuery.
*
* The plugin creates the day-partitioned table on first use, so the credentials
* in scope need permission to create a table in the dataset, not only to insert
* rows. Without explicit `credentials`, application default credentials are used.
*
* Logging failures never fail the turn: a table that cannot be created, or a row
* that cannot be inserted, is logged and the invocation carries on.
*/
fun analyticsApp(
projectId: String,
datasetId: String,
datasetLocation: String,
): App {
val plugin =
BigQueryAgentAnalyticsPlugin(
config =
BigQueryLoggerConfig(
projectId = projectId,
datasetId = datasetId,
// Defaults to "US"; pass your dataset's location instead.
location = datasetLocation,
),
)

return App(
appName = "my_agent",
rootAgent = analyticsAgent,
plugins = listOf(plugin),
)
}
// --8<-- [end:quickstart]
1 change: 1 addition & 0 deletions tools/kotlin-snippets/files_to_test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ snippets/tools/overview/UserPreferenceTools.kt
snippets/tools/overview/CustomerSupport.kt
snippets/tools/overview/DocAnalysisTools.kt
snippets/tools/overview/OrderTools.kt
snippets/integrations/BigQueryAnalyticsExample.kt
Loading