feat: add network calls summary to AI session threads API (#27417)

Backend for the AI session network summary. Exposes total/blocked
network calls and top destination domains on the session threads
endpoint (`GET /api/v2/ai-gateway/sessions/{id}`).

Total and blocked reuse the existing Agent Firewall aggregation from the
sessions list query, so the numbers match the sessions table. Top
domains are a new server-side aggregation
(`GetAIBridgeSessionTopDomains`) over boundary logs, using the same
interception-window correlation. There is no network-error state,
matching the current data model.

Frontend consuming these fields is in a separate stacked PR.

### PR map (merge strictly bottom-up)

This change is a 4-PR stack. Each PR depends on all the ones below it,
so merge in this exact order:

1. #27417 — backend network summary (base `main`)
2. #27418 — frontend summary rows (base #27417)
3. #27425 — backend per-call list `network_call_logs` (base #27418)
4. #27426 — frontend network-calls panel (base #27425)

Refs AIGOV-463

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Cian Johnston <cian@coder.com>
This commit is contained in:
Sas Swart
2026-07-30 13:09:46 +02:00
committed by GitHub
co-authored by Claude Opus 4.8 Cian Johnston
parent 3660ffecdd
commit 841a1765f7
16 changed files with 644 additions and 21 deletions
+11
View File
@@ -195,6 +195,17 @@ Alias: also available at /api/v2/aibridge/sessions/{session_id} for backward com
"models": [
"string"
],
"network_calls": {
"blocked": 0,
"total": 0
},
"network_domain_count": 0,
"network_top_domains": [
{
"count": 0,
"domain": "string"
}
],
"page_ended_at": "2019-08-24T14:15:22Z",
"page_started_at": "2019-08-24T14:15:22Z",
"providers": [
+45 -15
View File
@@ -655,6 +655,22 @@
| `blocked` | integer | false | | |
| `total` | integer | false | | |
## codersdk.AIBridgeSessionNetworkDomain
```json
{
"count": 0,
"domain": "string"
}
```
### Properties
| Name | Type | Required | Restrictions | Description |
|----------|---------|----------|--------------|-------------|
| `count` | integer | false | | |
| `domain` | string | false | | |
## codersdk.AIBridgeSessionThreadsResponse
```json
@@ -675,6 +691,17 @@
"models": [
"string"
],
"network_calls": {
"blocked": 0,
"total": 0
},
"network_domain_count": 0,
"network_top_domains": [
{
"count": 0,
"domain": "string"
}
],
"page_ended_at": "2019-08-24T14:15:22Z",
"page_started_at": "2019-08-24T14:15:22Z",
"providers": [
@@ -758,21 +785,24 @@
### Properties
| Name | Type | Required | Restrictions | Description |
|-----------------------|----------------------------------------------------------------------------------------|----------|--------------|-------------|
| `client` | string | false | | |
| `ended_at` | string | false | | |
| `id` | string | false | | |
| `initiator` | [codersdk.MinimalUser](#codersdkminimaluser) | false | | |
| `metadata` | object | false | | |
| » `[any property]` | any | false | | |
| `models` | array of string | false | | |
| `page_ended_at` | string | false | | |
| `page_started_at` | string | false | | |
| `providers` | array of string | false | | |
| `started_at` | string | false | | |
| `threads` | array of [codersdk.AIBridgeThread](#codersdkaibridgethread) | false | | |
| `token_usage_summary` | [codersdk.AIBridgeSessionThreadsTokenUsage](#codersdkaibridgesessionthreadstokenusage) | false | | |
| Name | Type | Required | Restrictions | Description |
|------------------------|------------------------------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `client` | string | false | | |
| `ended_at` | string | false | | |
| `id` | string | false | | |
| `initiator` | [codersdk.MinimalUser](#codersdkminimaluser) | false | | |
| `metadata` | object | false | | |
| » `[any property]` | any | false | | |
| `models` | array of string | false | | |
| `network_calls` | [codersdk.AIBridgeSessionNetworkCallSummary](#codersdkaibridgesessionnetworkcallsummary) | false | | Network calls summarizes the Agent Firewall network calls made during the session. A nil value means the session did not pass through Agent Firewall, so network call monitoring was not active, which the UI surfaces as "Disabled". |
| `network_domain_count` | integer | false | | |
| `network_top_domains` | array of [codersdk.AIBridgeSessionNetworkDomain](#codersdkaibridgesessionnetworkdomain) | false | | Network top domains lists the most contacted destination hosts, ordered by call count descending. NetworkDomainCount is the total number of distinct domains, used to render a "+N more" overflow beyond the listed domains. |
| `page_ended_at` | string | false | | |
| `page_started_at` | string | false | | |
| `providers` | array of string | false | | |
| `started_at` | string | false | | |
| `threads` | array of [codersdk.AIBridgeThread](#codersdkaibridgethread) | false | | |
| `token_usage_summary` | [codersdk.AIBridgeSessionThreadsTokenUsage](#codersdkaibridgesessionthreadstokenusage) | false | | |
## codersdk.AIBridgeSessionThreadsTokenUsage