mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
Follow-up to #26862 ("remove direct chat routing"), which collapsed the routing discriminated union into a single `aiGatewayModelRoute` but left a one-path dispatch shim behind in `model_routing.go`. Removes `resolveModelRouteForConfig`/`resolveModelRouteForProviderType`/`newModel` wrapper functions that did nothing but call their `*AIGateway*` counterparts, and renames the `*AIGateway*` targets to take over those names directly. Also collapses a redundant if/else in `title_override.go` where both branches called the same function with the same effective argument, and has `chatutil.NormalizedStringPointer` delegate to the existing `coderd/util/strings.EmptyToNil` instead of reimplementing empty-string-to-nil logic. No behavior change. <details> <summary>Investigation notes / decision log</summary> Two independent read-only investigations were run over `coderd/x/chatd` looking for cleanup opportunities following #26862: one focused on residue from that PR specifically, one a general over-engineering pass on the whole package. Both independently converged on the `model_routing.go` shim as the top finding (verified zero divergent call sites). Other candidates considered and explicitly deferred/rejected for this PR: - Renaming away the vestigial `AIGateway` prefix package-wide: cosmetic-only, touches many call sites, skipped. - Inlining the `chatcost` subpackage into `chatd`: unrelated to #26862, skipped. - Deleting the deprecated `AIGatewayRoutingEnabled` deployment flag: confirmed dead/no-op, but intentionally kept as a back-compat shim per #26862; removal should follow the same deprecation cadence as other deprecated deployment options, as a separate, differently-timed change. - Folding `chatutil` entirely into `chatprovider`/`chatopenai`: `NormalizedStringPointer` overlapped with `coderd/util/strings.EmptyToNil` (now reused), but `NormalizedEnumValue` has no equivalent elsewhere in the repo and still has 2 real call sites, so the package stays. </details> --- Generated by Coder Agents on behalf of @johnstcn.
87 lines
2.7 KiB
Go
87 lines
2.7 KiB
Go
package chatd
|
|
|
|
import (
|
|
"context"
|
|
|
|
"charm.land/fantasy"
|
|
"github.com/google/uuid"
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/coder/coder/v2/coderd/database"
|
|
"github.com/coder/coder/v2/coderd/database/dbauthz"
|
|
"github.com/coder/coder/v2/coderd/x/chatd/chatprovider"
|
|
)
|
|
|
|
const titleGenerationOverrideContext = "title_generation"
|
|
|
|
func readTitleGenerationModelOverride(
|
|
ctx context.Context,
|
|
db database.Store,
|
|
) (string, error) {
|
|
//nolint:gocritic // Chatd is internal, not a user, so this read uses AsChatd.
|
|
chatdCtx := dbauthz.AsChatd(ctx)
|
|
raw, err := db.GetChatTitleGenerationModelOverride(chatdCtx)
|
|
if err != nil {
|
|
return "", xerrors.Errorf(
|
|
"get chat title generation model override: %w",
|
|
err,
|
|
)
|
|
}
|
|
return raw, nil
|
|
}
|
|
|
|
// resolveTitleGenerationModelOverride resolves the deployment-wide title
|
|
// generation model override. overrideSet is true when an override was
|
|
// configured; in that case any returned error is a hard failure. When
|
|
// overrideSet is false, callers may fall back to the default title model.
|
|
func (p *Server) resolveTitleGenerationModelOverride(
|
|
ctx context.Context,
|
|
chat database.Chat,
|
|
modelOpts modelBuildOptions,
|
|
) (database.ChatModelConfig, fantasy.LanguageModel, aiGatewayModelRoute, bool, error) {
|
|
raw, err := readTitleGenerationModelOverride(ctx, p.db)
|
|
if err != nil {
|
|
return database.ChatModelConfig{}, nil, aiGatewayModelRoute{}, false, xerrors.Errorf(
|
|
"read title generation model override: %w",
|
|
err,
|
|
)
|
|
}
|
|
|
|
modelConfig, overrideSet, err := p.resolveConfiguredModelOverride(
|
|
ctx,
|
|
titleGenerationOverrideContext,
|
|
raw,
|
|
chat.OwnerID,
|
|
p.resolveModelConfigAndNormalizedProvider,
|
|
func(ctx context.Context, ownerID uuid.UUID, aiProviderID uuid.UUID) (chatprovider.ProviderAPIKeys, error) {
|
|
return p.resolveUserProviderAPIKeys(ctx, ownerID, aiProviderID)
|
|
},
|
|
modelOverrideFailureModeHard,
|
|
)
|
|
if err != nil {
|
|
return database.ChatModelConfig{}, nil, aiGatewayModelRoute{}, overrideSet, err
|
|
}
|
|
if !overrideSet {
|
|
return database.ChatModelConfig{}, nil, aiGatewayModelRoute{}, false, nil
|
|
}
|
|
|
|
//nolint:gocritic // Title overrides need chatd-scoped provider reads for user-owned chats.
|
|
route, err := p.resolveModelRouteForConfig(dbauthz.AsChatd(ctx), chat.OwnerID, modelConfig)
|
|
if err != nil {
|
|
return database.ChatModelConfig{}, nil, aiGatewayModelRoute{}, true, err
|
|
}
|
|
model, err := p.newModel(ctx, modelClientRequest{
|
|
Chat: chat,
|
|
ModelName: modelConfig.Model,
|
|
UserAgent: chatprovider.UserAgent(),
|
|
ExtraHeaders: chatprovider.CoderHeaders(chat),
|
|
}, route, modelOpts)
|
|
if err != nil {
|
|
return database.ChatModelConfig{}, nil, aiGatewayModelRoute{}, true, xerrors.Errorf(
|
|
"create title generation model override: %w",
|
|
err,
|
|
)
|
|
}
|
|
return modelConfig, model, route, true, nil
|
|
}
|