@@ -773,42 +773,48 @@ func (c *Config) Resolver() VariableResolver {
775func (c *ProviderConfig) TestConnection(resolver VariableResolver) error {
775func (c *ProviderConfig) TestConnection(resolver VariableResolver) error {
777+ providerID = catwalk.InferenceProvider(c.ID)
776− testURL := ""
778+ testURL = ""
777− headers := make(map[string]string)
779+ headers = make(map[string]string)
778− apiKey, _ := resolver.ResolveValue(c.APIKey)
780+ apiKey, _ = resolver.ResolveValue(c.APIKey)
779 switch c.Type {
783 switch c.Type {
780 case catwalk.TypeOpenAI, catwalk.TypeOpenAICompat, catwalk.TypeOpenRouter:
784 case catwalk.TypeOpenAI, catwalk.TypeOpenAICompat, catwalk.TypeOpenRouter:
781 baseURL, _ := resolver.ResolveValue(c.BaseURL)
785 baseURL, _ := resolver.ResolveValue(c.BaseURL)
783− baseURL = "https://api.openai.com/v1"
786+ baseURL = cmp.Or(baseURL, "https://api.openai.com/v1")
785− if c.ID == string(catwalk.InferenceProviderOpenRouter) {
789+ case catwalk.InferenceProviderOpenRouter:
786 testURL = baseURL + "/credits"
790 testURL = baseURL + "/credits"
787− } else {
791+ default:
788 testURL = baseURL + "/models"
792 testURL = baseURL + "/models"
790 headers["Authorization"] = "Bearer " + apiKey
795 headers["Authorization"] = "Bearer " + apiKey
791 case catwalk.TypeAnthropic:
796 case catwalk.TypeAnthropic:
792 baseURL, _ := resolver.ResolveValue(c.BaseURL)
797 baseURL, _ := resolver.ResolveValue(c.BaseURL)
794− baseURL = "https://api.anthropic.com/v1"
798+ baseURL = cmp.Or(baseURL, "https://api.anthropic.com/v1")
796− testURL = baseURL + "/models"
800+ switch providerID {
797− // TODO: replace with const when catwalk is released
801+ case catwalk.InferenceKimiCoding:
798− if c.ID == "kimi-coding" {
799 testURL = baseURL + "/v1/models"
802 testURL = baseURL + "/v1/models"
804+ testURL = baseURL + "/models"
801 headers["x-api-key"] = apiKey
807 headers["x-api-key"] = apiKey
802 headers["anthropic-version"] = "2023-06-01"
808 headers["anthropic-version"] = "2023-06-01"
803 case catwalk.TypeGoogle:
809 case catwalk.TypeGoogle:
804 baseURL, _ := resolver.ResolveValue(c.BaseURL)
810 baseURL, _ := resolver.ResolveValue(c.BaseURL)
806− baseURL = "https://generativelanguage.googleapis.com"
811+ baseURL = cmp.Or(baseURL, "https://generativelanguage.googleapis.com")
808 testURL = baseURL + "/v1beta/models?key=" + url.QueryEscape(apiKey)
812 testURL = baseURL + "/v1beta/models?key=" + url.QueryEscape(apiKey)
810 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
815 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
811 defer cancel()
816 defer cancel()
812 client := &http.Client{}
818 client := &http.Client{}
813 req, err := http.NewRequestWithContext(ctx, "GET", testURL, nil)
819 req, err := http.NewRequestWithContext(ctx, "GET", testURL, nil)
814 if err != nil {
820 if err != nil {
@@ -820,17 +826,19 @@ func (c *ProviderConfig) TestConnection(resolver VariableResolver) error {
820 for k, v := range c.ExtraHeaders {
826 for k, v := range c.ExtraHeaders {
821 req.Header.Set(k, v)
827 req.Header.Set(k, v)
823 resp, err := client.Do(req)
830 resp, err := client.Do(req)
824 if err != nil {
831 if err != nil {
825 return fmt.Errorf("failed to create request for provider %s: %w", c.ID, err)
832 return fmt.Errorf("failed to create request for provider %s: %w", c.ID, err)
827 defer resp.Body.Close()
834 defer resp.Body.Close()
828− if c.ID == string(catwalk.InferenceProviderZAI) {
837+ case catwalk.InferenceProviderZAI:
829 if resp.StatusCode == http.StatusUnauthorized {
838 if resp.StatusCode == http.StatusUnauthorized {
830− // For z.ai just check if the http response is not 401.
831 return fmt.Errorf("failed to connect to provider %s: %s", c.ID, resp.Status)
839 return fmt.Errorf("failed to connect to provider %s: %s", c.ID, resp.Status)
833− } else {
841+ default:
834 if resp.StatusCode != http.StatusOK {
842 if resp.StatusCode != http.StatusOK {
835 return fmt.Errorf("failed to connect to provider %s: %s", c.ID, resp.Status)
843 return fmt.Errorf("failed to connect to provider %s: %s", c.ID, resp.Status)