feat(coderd/database): add error columns to aibridge interception records (#26960)

Adds a nullable `aibridge_interception_error_type` enum and an
`error_message` column to `aibridge_interceptions`, so a failed
interception's terminal upstream error can be persisted.

Schema only: the write path and API exposure land in the stacked
backend PR.

*This PR was produced by opencode (agent) using the `anthropic/claude-opus-4-8` model, under human direction and review.*
This commit is contained in:
Danny Kopping
2026-07-09 15:06:44 +02:00
committed by GitHub
parent cd1a676232
commit 63497ee9d8
7 changed files with 136 additions and 6 deletions
+77
View File
@@ -16,6 +16,79 @@ import (
"github.com/sqlc-dev/pqtype"
)
type AIBridgeInterceptionErrorType string
const (
AibridgeInterceptionErrorTypeBadRequest AIBridgeInterceptionErrorType = "bad_request"
AibridgeInterceptionErrorTypeUnauthorized AIBridgeInterceptionErrorType = "unauthorized"
AibridgeInterceptionErrorTypeRateLimited AIBridgeInterceptionErrorType = "rate_limited"
AibridgeInterceptionErrorTypeOverloaded AIBridgeInterceptionErrorType = "overloaded"
AibridgeInterceptionErrorTypeServerError AIBridgeInterceptionErrorType = "server_error"
AibridgeInterceptionErrorTypeTimeout AIBridgeInterceptionErrorType = "timeout"
AibridgeInterceptionErrorTypeUnknown AIBridgeInterceptionErrorType = "unknown"
)
func (e *AIBridgeInterceptionErrorType) Scan(src interface{}) error {
switch s := src.(type) {
case []byte:
*e = AIBridgeInterceptionErrorType(s)
case string:
*e = AIBridgeInterceptionErrorType(s)
default:
return fmt.Errorf("unsupported scan type for AIBridgeInterceptionErrorType: %T", src)
}
return nil
}
type NullAIBridgeInterceptionErrorType struct {
AIBridgeInterceptionErrorType AIBridgeInterceptionErrorType `json:"aibridge_interception_error_type"`
Valid bool `json:"valid"` // Valid is true if AIBridgeInterceptionErrorType is not NULL
}
// Scan implements the Scanner interface.
func (ns *NullAIBridgeInterceptionErrorType) Scan(value interface{}) error {
if value == nil {
ns.AIBridgeInterceptionErrorType, ns.Valid = "", false
return nil
}
ns.Valid = true
return ns.AIBridgeInterceptionErrorType.Scan(value)
}
// Value implements the driver Valuer interface.
func (ns NullAIBridgeInterceptionErrorType) Value() (driver.Value, error) {
if !ns.Valid {
return nil, nil
}
return string(ns.AIBridgeInterceptionErrorType), nil
}
func (e AIBridgeInterceptionErrorType) Valid() bool {
switch e {
case AibridgeInterceptionErrorTypeBadRequest,
AibridgeInterceptionErrorTypeUnauthorized,
AibridgeInterceptionErrorTypeRateLimited,
AibridgeInterceptionErrorTypeOverloaded,
AibridgeInterceptionErrorTypeServerError,
AibridgeInterceptionErrorTypeTimeout,
AibridgeInterceptionErrorTypeUnknown:
return true
}
return false
}
func AllAIBridgeInterceptionErrorTypeValues() []AIBridgeInterceptionErrorType {
return []AIBridgeInterceptionErrorType{
AibridgeInterceptionErrorTypeBadRequest,
AibridgeInterceptionErrorTypeUnauthorized,
AibridgeInterceptionErrorTypeRateLimited,
AibridgeInterceptionErrorTypeOverloaded,
AibridgeInterceptionErrorTypeServerError,
AibridgeInterceptionErrorTypeTimeout,
AibridgeInterceptionErrorTypeUnknown,
}
}
type AIProviderType string
const (
@@ -4570,6 +4643,10 @@ type AIBridgeInterception struct {
AgentFirewallSessionID uuid.NullUUID `db:"agent_firewall_session_id" json:"agent_firewall_session_id"`
// The Agent Firewall sequence number from the request header. Used to determine exact ordering of network requests relative to Agent Firewall audit events. NULL when the request did not pass through Agent Firewall.
AgentFirewallSequenceNumber sql.NullInt32 `db:"agent_firewall_sequence_number" json:"agent_firewall_sequence_number"`
// Categorised terminal upstream error for a failed interception; NULL when the interception succeeded.
ErrorType NullAIBridgeInterceptionErrorType `db:"error_type" json:"error_type"`
// Raw terminal upstream error message for a failed interception; NULL when the interception succeeded.
ErrorMessage sql.NullString `db:"error_message" json:"error_message"`
}
// Audit log of model thinking in intercepted requests in AI Bridge