GeezerVison is showing github.com — feat: show and filter by organization in AI Gateway sessions API by mollymaefraser · Pull Request #32057 · coder/coder
Conversation
Adds an organization filter to GET /api/v2/ai-gateway/sessions (and its /api/v2/aibridge/sessions alias) and returns the organization an interception was attributed to, and how it was chosen, on sessions, threads and agentic actions, as proposed in the surface definitions on AIGOV-754. No migration: aibridge_interceptions.organization_id and organization_source already exist (000634).
The filter accepts an organization name or ID and keeps sessions with at least one interception in that organization; the count uses the same rule so pagination totals match. Each session, on the list and detail responses, lists the organizations its interceptions were attributed to, ordered by name, with the distinct sources used for each, or [] when none was stored. Each thread carries the organization of its root interception and each agentic action carries its own, or null when none was stored. The new filter is listed in the AI Gateway monitoring docs.
Refs AIGOV-754
Open questions for reviewers
- Multi-org sessions (AIGOV-776): the filter is row-level, like provider and model. A session spanning two orgs is listed under each org's filter, and with the filter on,
threads, started_at and ended_at only cover the matching interceptions, while providers, models, tokens and organizations cover the whole session. Is that the desired behavior?
- Unknown org ID: an unknown org name returns 400, but an unknown org ID returns an empty page, because
parseOrganization does not look up UUIDs. This matches workspaces and templates, but the spec says 400.
Notes for reviewers
aiBridgeSessionOrganizations returns an empty list if the organizations JSON from the query can’t be decoded, rather than failing the whole request. The field is supplementary, so a decoding problem shouldn’t take down the sessions list, but it does mean a SQL bug here would show up as empty data rather than an error. The alternative is to log the error before returning the empty list.
- A thread’s organization is taken from its root interception only. If later requests in the same thread were attributed to a different organization, that shows on each agentic action’s own organization field.
Implementation notes
coderd/database/queries/aibridge.sql:
@organization_id filter in CountAIBridgeSessions and the session_page CTE of ListAIBridgeSessions.
- New
sorg lateral in ListAIBridgeSessions that groups the session's interceptions by organization, collects distinct sources, joins organizations (deleted orgs still resolve) and returns a JSON array.
ListAIBridgeSessionThreads resolves the organization name, display name and icon through a LEFT JOIN LATERAL in the final SELECT. A plain join on organizations is not safe there: the query has two @authorize_filter placeholders, and the injected filter can reference a bare id, which would be ambiguous next to organizations.id. The lateral only exposes the three selected columns. This answers the authorize-filter open question from the surface proposal.
coderd/database/modelqueries.go: the hand-written ListAuthorizedAIBridgeSessions, CountAuthorizedAIBridgeSessions and ListAuthorizedAIBridgeSessionThreads gain the new argument and scan columns. The compiler does not catch a mismatch here; it fails at runtime.
enterprise/coderd/aibridge.go: pass OrganizationID into CountAIBridgeSessionsParams, which is built field by field, and list the organization key in @Param q.
coderd/searchquery/search.go: organization key via parseOrganization.
codersdk/aibridge.go: AIBridgeInterceptionOrganizationSource enum, AIBridgeInterceptionOrganization, AIBridgeSessionOrganization, new response fields and AIBridgeListSessionsFilter.Organization, per the proposed Go definitions.
coderd/database/db2sdk/db2sdk.go: decode the session organizations JSON, never returning nil; AIBridgeInterceptionOrganizationSource converter; build one organization per interception while grouping thread rows, and use it for the thread (root interception) and each agentic action.
site/: add organizations: [] to two frontend mocks, now that the field is required in the generated types.
docs/ai-governance/ai-gateway/monitoring.md: organization added to the sessions API query filters.
- Tests:
TestAIBridgeSessions (name and ID parsing), TestAIBridgeListSessions/Filters (by name and ID, checks count and page), FilterErrors/UnknownOrganization, TestAIBridgeListSessions/Organizations (multi-org ordering and sources, no-org session returns [], filtering by either org returns the multi-org session and never the no-org one), TestAIBridgeGetSessionThreads/Organizations (thread uses the root's org, each action its own, null when none, session organizations on the detail endpoint), and TestAIBridgeInterceptionOrganizationSource (every database source maps to an SDK value).
- Remaining files are generated by
make gen.
Code written by @mollymaefraser, with Coder Agents used as a guide: explaining the existing code path, reviewing each step, and running tests.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
This branch was previously deployed
1 inactive
deployment
Uh oh!
There was an error while loading. Please reload this page.
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|