diff --git a/docs/integrations/bigquery-agent-analytics.md b/docs/integrations/bigquery-agent-analytics.md index 37ae1e7dad..832c222233 100644 --- a/docs/integrations/bigquery-agent-analytics.md +++ b/docs/integrations/bigquery-agent-analytics.md @@ -7,8 +7,8 @@ catalog_tags: ["observability", "google"] # BigQuery Agent Analytics plugin for ADK -
- Supported in ADKPython v1.21.0Java v1.5.0 +
+ Supported in ADKPython v1.21.0Java v1.5.0Kotlin v0.8.0
The BigQuery Agent Analytics Plugin significantly enhances Agent Development Kit @@ -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 @@ -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 diff --git a/examples/kotlin/build.gradle.kts b/examples/kotlin/build.gradle.kts index b057c5cd7f..bbca101f99 100644 --- a/examples/kotlin/build.gradle.kts +++ b/examples/kotlin/build.gradle.kts @@ -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") diff --git a/examples/kotlin/snippets/integrations/BigQueryAnalyticsExample.kt b/examples/kotlin/snippets/integrations/BigQueryAnalyticsExample.kt new file mode 100644 index 0000000000..eeafd52b9d --- /dev/null +++ b/examples/kotlin/snippets/integrations/BigQueryAnalyticsExample.kt @@ -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] diff --git a/tools/kotlin-snippets/files_to_test.txt b/tools/kotlin-snippets/files_to_test.txt index b1902c362c..794f972e9d 100644 --- a/tools/kotlin-snippets/files_to_test.txt +++ b/tools/kotlin-snippets/files_to_test.txt @@ -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