mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
refactor!: remove interceptions API, request logs view, and associated code (#26213)
## Summary Removes the deprecated `/api/v2/aibridge/interceptions` endpoint and the Request Logs frontend page, both replaced by the session-based view. Closes https://linear.app/codercom/issue/AIGOV-266 Closes https://linear.app/codercom/issue/AIGOV-324 ## Changes ### Backend - Remove `GET /api/v2/aibridge/interceptions` HTTP handler and route - Remove SDK types and client method (`AIBridgeInterception`, `AIBridgeTokenUsage`, `AIBridgeUserPrompt`, `AIBridgeToolUsage`, `AIBridgeListInterceptionsResponse`, `AIBridgeListInterceptionsFilter`) - Remove SQL queries `CountAIBridgeInterceptions` and `ListAIBridgeInterceptions` - Remove `searchquery.AIBridgeInterceptions` parser - Remove dbauthz wrappers, in-memory implementations, metrics, and mocks for the interceptions list queries - Remove the `coder aibridge interceptions list` CLI command and golden files - Regenerate API docs, swagger, mocks, and metrics The `/models`, `/clients`, and `/sessions` endpoints stay; the sessions list page still consumes all three. ### Frontend - Delete the entire `RequestLogsPage/` directory (page, view, row, filter, stories, tests) - Remove the `/aibridge/request-logs` route and its lazy import - Remove the `getAIBridgeInterceptions` API method, `paginatedInterceptions` query, and mock interception entities - `git mv` the shared filter and icon components used by the sessions pages: - `RequestLogsPage/RequestLogsFilter/{Client,Model,Provider}Filter.tsx` → `AIBridgePage/filters/` - `RequestLogsPage/icons/AIBridge{Client,Model,Provider}Icon.tsx` → `AIBridgePage/icons/` - Drop the `getProviderIconName` hack and the duplicate `anthropic-neue` icon case now that the FIXME no longer applies ## Commits 1. `refactor: remove interceptions API and request logs view` — the bulk removal, with explicit renames for the shared filter/icon files. 2. `refactor(site/src/pages/AIBridgePage): drop getProviderIconName hack` — cleanup of the FIXME that depended on RequestLogsPage existing. > [!NOTE] > Generated by Coder Agents on behalf of @dannykopping
This commit is contained in:
@@ -12,61 +12,6 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type AIBridgeInterception struct {
|
||||
ID uuid.UUID `json:"id" format:"uuid"`
|
||||
APIKeyID *string `json:"api_key_id"`
|
||||
Initiator MinimalUser `json:"initiator"`
|
||||
Provider string `json:"provider"`
|
||||
ProviderName string `json:"provider_name"`
|
||||
Model string `json:"model"`
|
||||
Client *string `json:"client"`
|
||||
Metadata map[string]any `json:"metadata"`
|
||||
StartedAt time.Time `json:"started_at" format:"date-time"`
|
||||
EndedAt *time.Time `json:"ended_at" format:"date-time"`
|
||||
TokenUsages []AIBridgeTokenUsage `json:"token_usages"`
|
||||
UserPrompts []AIBridgeUserPrompt `json:"user_prompts"`
|
||||
ToolUsages []AIBridgeToolUsage `json:"tool_usages"`
|
||||
}
|
||||
|
||||
type AIBridgeTokenUsage struct {
|
||||
ID uuid.UUID `json:"id" format:"uuid"`
|
||||
InterceptionID uuid.UUID `json:"interception_id" format:"uuid"`
|
||||
ProviderResponseID string `json:"provider_response_id"`
|
||||
InputTokens int64 `json:"input_tokens"`
|
||||
OutputTokens int64 `json:"output_tokens"`
|
||||
CacheReadInputTokens int64 `json:"cache_read_input_tokens"`
|
||||
CacheWriteInputTokens int64 `json:"cache_write_input_tokens"`
|
||||
Metadata map[string]any `json:"metadata"`
|
||||
CreatedAt time.Time `json:"created_at" format:"date-time"`
|
||||
}
|
||||
|
||||
type AIBridgeUserPrompt struct {
|
||||
ID uuid.UUID `json:"id" format:"uuid"`
|
||||
InterceptionID uuid.UUID `json:"interception_id" format:"uuid"`
|
||||
ProviderResponseID string `json:"provider_response_id"`
|
||||
Prompt string `json:"prompt"`
|
||||
Metadata map[string]any `json:"metadata"`
|
||||
CreatedAt time.Time `json:"created_at" format:"date-time"`
|
||||
}
|
||||
|
||||
type AIBridgeToolUsage struct {
|
||||
ID uuid.UUID `json:"id" format:"uuid"`
|
||||
InterceptionID uuid.UUID `json:"interception_id" format:"uuid"`
|
||||
ProviderResponseID string `json:"provider_response_id"`
|
||||
ServerURL string `json:"server_url"`
|
||||
Tool string `json:"tool"`
|
||||
Input string `json:"input"`
|
||||
Injected bool `json:"injected"`
|
||||
InvocationError string `json:"invocation_error"`
|
||||
Metadata map[string]any `json:"metadata"`
|
||||
CreatedAt time.Time `json:"created_at" format:"date-time"`
|
||||
}
|
||||
|
||||
type AIBridgeListInterceptionsResponse struct {
|
||||
Count int64 `json:"count"`
|
||||
Results []AIBridgeInterception `json:"results"`
|
||||
}
|
||||
|
||||
type AIBridgeSession struct {
|
||||
ID string `json:"id"`
|
||||
Initiator MinimalUser `json:"initiator"`
|
||||
@@ -194,70 +139,6 @@ type AIBridgeListSessionsFilter struct {
|
||||
FilterQuery string `json:"q,omitempty"`
|
||||
}
|
||||
|
||||
// @typescript-ignore AIBridgeListInterceptionsFilter
|
||||
type AIBridgeListInterceptionsFilter struct {
|
||||
// Limit defaults to 100, max is 1000.
|
||||
// Offset based pagination is not supported for AI Bridge interceptions. Use
|
||||
// cursor pagination instead with after_id.
|
||||
Pagination Pagination `json:"pagination,omitempty"`
|
||||
|
||||
// Initiator is a user ID, username, or "me".
|
||||
Initiator string `json:"initiator,omitempty"`
|
||||
StartedBefore time.Time `json:"started_before,omitempty" format:"date-time"`
|
||||
StartedAfter time.Time `json:"started_after,omitempty" format:"date-time"`
|
||||
// Provider matches the runtime provider type column (openai,
|
||||
// anthropic, copilot). The runtime type collapses the configured
|
||||
// ai_provider_type: azure, google, openai-compat, openrouter, and
|
||||
// vercel route through openai; bedrock routes through anthropic.
|
||||
// Retained for backward compatibility; new clients should prefer
|
||||
// ProviderName, which scopes to a specific configured row.
|
||||
Provider string `json:"provider,omitempty"`
|
||||
ProviderName string `json:"provider_name,omitempty"`
|
||||
Model string `json:"model,omitempty"`
|
||||
Client string `json:"client,omitempty"`
|
||||
|
||||
FilterQuery string `json:"q,omitempty"`
|
||||
}
|
||||
|
||||
// asRequestOption returns a function that can be used in (*Client).Request.
|
||||
// It modifies the request query parameters.
|
||||
func (f AIBridgeListInterceptionsFilter) asRequestOption() RequestOption {
|
||||
return func(r *http.Request) {
|
||||
var params []string
|
||||
// Make sure all user input is quoted to ensure it's parsed as a single
|
||||
// string.
|
||||
if f.Initiator != "" {
|
||||
params = append(params, fmt.Sprintf("initiator:%q", f.Initiator))
|
||||
}
|
||||
if !f.StartedBefore.IsZero() {
|
||||
params = append(params, fmt.Sprintf("started_before:%q", f.StartedBefore.Format(time.RFC3339Nano)))
|
||||
}
|
||||
if !f.StartedAfter.IsZero() {
|
||||
params = append(params, fmt.Sprintf("started_after:%q", f.StartedAfter.Format(time.RFC3339Nano)))
|
||||
}
|
||||
if f.Provider != "" {
|
||||
params = append(params, fmt.Sprintf("provider:%q", f.Provider))
|
||||
}
|
||||
if f.ProviderName != "" {
|
||||
params = append(params, fmt.Sprintf("provider_name:%q", f.ProviderName))
|
||||
}
|
||||
if f.Model != "" {
|
||||
params = append(params, fmt.Sprintf("model:%q", f.Model))
|
||||
}
|
||||
if f.Client != "" {
|
||||
params = append(params, fmt.Sprintf("client:%q", f.Client))
|
||||
}
|
||||
if f.FilterQuery != "" {
|
||||
// If custom stuff is added, just add it on here.
|
||||
params = append(params, f.FilterQuery)
|
||||
}
|
||||
|
||||
q := r.URL.Query()
|
||||
q.Set("q", strings.Join(params, " "))
|
||||
r.URL.RawQuery = q.Encode()
|
||||
}
|
||||
}
|
||||
|
||||
// asRequestOption returns a function that can be used in (*Client).Request.
|
||||
func (f AIBridgeListSessionsFilter) asRequestOption() RequestOption {
|
||||
return func(r *http.Request) {
|
||||
@@ -299,24 +180,6 @@ func (f AIBridgeListSessionsFilter) asRequestOption() RequestOption {
|
||||
}
|
||||
}
|
||||
|
||||
// AIBridgeListInterceptions returns AI Bridge interceptions with the given
|
||||
// filter.
|
||||
//
|
||||
// Deprecated: Use AIBridgeListSessions instead, which provides richer
|
||||
// session-level aggregation including threads and agentic actions.
|
||||
func (c *Client) AIBridgeListInterceptions(ctx context.Context, filter AIBridgeListInterceptionsFilter) (AIBridgeListInterceptionsResponse, error) {
|
||||
res, err := c.Request(ctx, http.MethodGet, "/api/v2/aibridge/interceptions", nil, filter.asRequestOption(), filter.Pagination.asRequestOption(), filter.Pagination.asRequestOption())
|
||||
if err != nil {
|
||||
return AIBridgeListInterceptionsResponse{}, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return AIBridgeListInterceptionsResponse{}, ReadBodyAsError(res)
|
||||
}
|
||||
var resp AIBridgeListInterceptionsResponse
|
||||
return resp, json.NewDecoder(res.Body).Decode(&resp)
|
||||
}
|
||||
|
||||
// AIBridgeListSessions returns AI Bridge sessions with the given filter.
|
||||
func (c *Client) AIBridgeListSessions(ctx context.Context, filter AIBridgeListSessionsFilter) (AIBridgeListSessionsResponse, error) {
|
||||
res, err := c.Request(ctx, http.MethodGet, "/api/v2/aibridge/sessions", nil, filter.asRequestOption(), filter.Pagination.asRequestOption())
|
||||
|
||||
Reference in New Issue
Block a user