( _ context.Context, req modelClientRequest, route aiGatewayModelRoute, opts modelBuildOptions, )
| 114 | } |
| 115 | |
| 116 | func (p *Server) newAIGatewayModel( |
| 117 | _ context.Context, |
| 118 | req modelClientRequest, |
| 119 | route aiGatewayModelRoute, |
| 120 | opts modelBuildOptions, |
| 121 | ) (fantasy.LanguageModel, error) { |
| 122 | if route.Provider.ID == uuid.Nil { |
| 123 | return nil, xerrors.New("AI Gateway routing requires a concrete AI provider") |
| 124 | } |
| 125 | if route.Provider.Name == "" { |
| 126 | return nil, xerrors.New("AI Gateway routing requires an AI provider name") |
| 127 | } |
| 128 | if opts.ActiveAPIKeyID == "" { |
| 129 | return nil, chaterror.WithClassification( |
| 130 | xerrors.New("AI Gateway routing requires the active turn API key ID"), |
| 131 | chaterror.ClassifiedError{ |
| 132 | Kind: codersdk.ChatErrorKindMissingKey, |
| 133 | Retryable: false, |
| 134 | Detail: "If this error persists after resending, please report it as a bug.", |
| 135 | }, |
| 136 | ) |
| 137 | } |
| 138 | |
| 139 | if err := ValidateAIGatewayProviderModel(route.Provider, req.ModelName); err != nil { |
| 140 | return nil, chaterror.WithClassification( |
| 141 | err, |
| 142 | chaterror.ClassifiedError{ |
| 143 | Kind: codersdk.ChatErrorKindConfig, |
| 144 | Retryable: false, |
| 145 | Detail: "Ask an administrator to change the AI provider type to openrouter or openai-compat.", |
| 146 | }, |
| 147 | ) |
| 148 | } |
| 149 | |
| 150 | factoryPtr := p.aibridgeTransportFactory |
| 151 | if factoryPtr == nil { |
| 152 | return nil, xerrors.New("AI Gateway transport factory is not configured") |
| 153 | } |
| 154 | factory := factoryPtr.Load() |
| 155 | if factory == nil || *factory == nil { |
| 156 | return nil, xerrors.New("AI Gateway transport factory is not configured") |
| 157 | } |
| 158 | rt, err := (*factory).TransportFor(route.Provider.Name, aibridge.SourceAgents) |
| 159 | if err != nil { |
| 160 | return nil, xerrors.Errorf("create AI Gateway transport: %w", err) |
| 161 | } |
| 162 | baseRT := http.RoundTripper(&aiGatewayRoundTripper{ |
| 163 | base: rt, |
| 164 | apiKeyID: opts.ActiveAPIKeyID, |
| 165 | providerAuth: route.ProviderAuth, |
| 166 | }) |
| 167 | if opts.RecordHTTP { |
| 168 | baseRT = &chatdebug.RecordingTransport{Base: baseRT} |
| 169 | } |
| 170 | |
| 171 | config := fantasyConfigForAIBridge(route.Provider.Type) |
| 172 | return newLanguageModel( |
| 173 | config.ProviderHint, |
no test coverage detected