mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
Categorises the terminal error of a failed interception and persists it on the interception record, then surfaces it on the AI Gateway API. - Categorise into an enum (`bad_request`, `unauthorized`, `rate_limited`, `overloaded`, `server_error`, `unknown`), unwrapping the ResponseError envelope, the upstream Anthropic/OpenAI SDK errors, and key-pool exhaustion so blocking and streaming paths agree. - Thread the type and raw message through the recorder dRPC into the `aibridge_interceptions` row (optional proto fields; NULL on success). - Expose the error on the AI Gateway thread API from the root interception. *This PR was produced by opencode (agent) using the `anthropic/claude-opus-4-8` model, under human direction and review.*
52 lines
2.0 KiB
Go
52 lines
2.0 KiB
Go
package provider
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"go.opentelemetry.io/otel/trace"
|
|
|
|
"cdr.dev/slog/v3"
|
|
"github.com/coder/coder/v2/aibridge/config"
|
|
"github.com/coder/coder/v2/aibridge/intercept"
|
|
"github.com/coder/coder/v2/aibridge/keypool"
|
|
"github.com/coder/coder/v2/aibridge/recorder"
|
|
)
|
|
|
|
// DisabledStub is a Provider placeholder for a configured-but-disabled
|
|
// provider. Only Name and Enabled return meaningful values; all other
|
|
// methods return empty/nil so the stub never influences routing.
|
|
type DisabledStub struct {
|
|
name string
|
|
providerType string
|
|
}
|
|
|
|
// NewDisabledStub returns a Provider stub that reports Enabled() == false.
|
|
// The type string is preserved so callers can distinguish provider families.
|
|
func NewDisabledStub(name, providerType string) *DisabledStub {
|
|
return &DisabledStub{name: name, providerType: providerType}
|
|
}
|
|
|
|
func (d *DisabledStub) Type() string { return d.providerType }
|
|
func (d *DisabledStub) Name() string { return d.name }
|
|
func (*DisabledStub) Enabled() bool { return false }
|
|
func (*DisabledStub) BaseURL() string { return "" }
|
|
func (d *DisabledStub) RoutePrefix() string {
|
|
return fmt.Sprintf("/%s", d.name)
|
|
}
|
|
func (*DisabledStub) BridgedRoutes() []string { return nil }
|
|
func (*DisabledStub) PassthroughRoutes() []string { return nil }
|
|
func (*DisabledStub) AuthHeader() string { return "" }
|
|
func (*DisabledStub) KeyPool() *keypool.Pool { return nil }
|
|
func (*DisabledStub) KeyFailoverConfig(_ slog.Logger) keypool.KeyFailoverConfig {
|
|
return keypool.KeyFailoverConfig{}
|
|
}
|
|
func (*DisabledStub) CircuitBreakerConfig() *config.CircuitBreaker { return nil }
|
|
func (*DisabledStub) APIDumpDir() string { return "" }
|
|
func (*DisabledStub) CategorizeError(error) *recorder.ErrorType { return nil }
|
|
|
|
func (*DisabledStub) CreateInterceptor(_ http.ResponseWriter, _ *http.Request, _ trace.Tracer) (intercept.Interceptor, error) {
|
|
//nolint:nilnil // disabled providers never reach the interceptor.
|
|
return nil, nil
|
|
}
|