GoogleCloudPlatform / GoogleCloudPlatform/BigQuery-Agent-Analytics-SDK
adk-2.0 consumer: long_running_tool_durations view (full key, pause_kind='tool', orphan rows)
- Dominant language
- Python
- Stars
- 47
- Forks
- 21
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 33
Description
Parent tracker: #190 (v18 contract).
Wave: 5 — Consumer views.
Blocked by: #195 (`attributes.adk.app_name` identity stamping — the full-key join reads it directly), #199 (producer TOOL_PAUSED/TOOL_COMPLETED), #210 (cross-event deployment plumbing).
## Contract
### Healthy pairs
Pair `TOOL_PAUSED` → `TOOL_COMPLETED` on the **full key**:
`(JSON_VALUE(attributes, '$.adk.app_name'), user_id, session_id, JSON_VALUE(attributes, '$.adk.function_call_id'))`
**Filter to `attributes.adk.pause_kind = 'tool'` on both rows** so HITL synthetic waits never enter tool-duration analytics.
**Exclude orphan-tagged completions from the healthy-pair stream.** A `TOOL_COMPLETED` with `attributes.adk.pause_orphan = true` was tagged orphan at write time because the matching `TOOL_PAUSED` was not visible. By the time of a later query the paused row can be visible, so without an explicit filter the same completion can appear as both a healthy duration AND an orphan row. The healthy-pair completed stream must therefore filter:
```sql
COALESCE(SAFE_CAST(JSON_VALUE(attributes, '$.adk.pause_orphan') AS BOOL), FALSE) = FALSE
```
Emit `MIN(pause_ts) → MAX(complete_ts)` elapsed time. **Do not rely on `invoke_node` span duration** — paused tools can cross invocation boundaries.
### Orphan completions
`TOOL_COMPLETED` with `attributes.adk.pause_orphan = true` AND `attributes.adk.pause_kind = 'tool'` (HITL orphans excluded — see also defense in fixture #218) appear with:
- `status = 'orphan_completion'`
- `pause_ts = NULL`
- `complete_ts = `
### Dedupe — separate streams
Dedupe must run **separately per event stream** so a duplicate `TOOL_PAUSED` does not collide with a real `TOOL_COMPLETED` under the same full key. A single `ROW_NUMBER() OVER (PARTITION BY ORDER BY timestamp)` across both event types would order the earliest row first — usually the `TOOL_PAUSED` — and could drop the matching `TOOL_COMPLETED`, making healthy pairs vanish.
Concrete shape:
```sql
WITH paused_dedup AS (
SELECT *, ROW_NUMBER() OVER (
PARTITION BY
JSON_VALUE(attributes, '$.adk.app_name'), user_id, session_id,
JSON_VALUE(attributes, '$.adk.function_call_id')
ORDER BY timestamp
) AS rn
FROM ``
WHERE event_type = 'TOOL_PAUSED'
AND JSON_VALUE(attributes, '$.adk.pause_kind') = 'tool'
),
completed_dedup AS (
SELECT *, ROW_NUMBER() OVER (
PARTITION BY
JSON_VALUE(attributes, '$.adk.app_name'), user_id, session_id,
JSON_VALUE(attributes, '$.adk.function_call_id')
ORDER BY timestamp
) AS rn
FROM ``
WHERE event_type = 'TOOL_COMPLETED'
AND JSON_VALUE(attributes, '$.adk.pause_kind') = 'tool'
AND COALESCE(SAFE_CAST(JSON_VALUE(attributes, '$.adk.pause_orphan') AS BOOL), FALSE) = FALSE
)
-- then JOIN paused_dedup rn=1 with completed_dedup rn=1; UNION orphan completions
-- (TOOL_COMPLETED with pause_orphan = true AND pause_kind = 'tool', deduped separately).
```
Equivalent: include `event_type` in the partition. Either form is acceptable — the constraint is that a duplicate paused row cannot displace the matching completion row.
## Acceptance
- [ ] Healthy pair: `pause_kind = 'tool'` only; full-key join; **healthy-pair completed stream excludes `pause_orphan = true`**.
- [ ] Orphan: included when `pause_orphan = true AND pause_kind = 'tool'`; HITL orphans excluded.
- [ ] **HITL-orphan exclusion test** (consumes the synthetic fixture row from #218): a synthetic `TOOL_COMPLETED` with `pause_kind = 'hitl_confirmation'` and `pause_orphan = true` is asserted **absent** from this view.
- [ ] **Orphan double-count test**: a fixture with a visible `TOOL_PAUSED` and a `TOOL_COMPLETED` (`pause_orphan = true`) for the same full key produces exactly **one** `status = 'orphan_completion'` row and **no** healthy duplicate.
- [ ] Cross-invocation pause/resume produces correct end-to-end wall-clock duration.
- [ ] Dedupe runs separately per event stream (or with `event_type` included in the partition).
- [ ] **Dedupe robustness test**: a fixture with duplicate `TOOL_PAUSED` rows **and** duplicate `TOOL_COMPLETED` rows for the same full key returns exactly one healthy duration row.
## References
- #190 (v18 consumer view 4; v13-v15 orphan + HITL contracts; v17 orphan double-count exclusion).
Contributor guide
Assessment
This issue has not been assessed yet.