diff --git a/pkg/backend/codewhisperer_internal.go b/pkg/backend/codewhisperer_internal.go index 7d45e5e..d55ab1b 100644 --- a/pkg/backend/codewhisperer_internal.go +++ b/pkg/backend/codewhisperer_internal.go @@ -603,6 +603,28 @@ func kiroEndpointForRegion(region string) string { return "https://runtime." + strings.TrimSpace(region) + ".kiro.dev/" } +// kiroListModelsEndpoint derives the q..amazonaws.com endpoint for ListModels. +// Falls back to the management endpoint if region cannot be determined. +func kiroListModelsEndpoint(runtimeEndpoint, profileARN string) string { + // Try to extract region from profile ARN (arn:aws:codewhisperer::...) + if parts := strings.Split(profileARN, ":"); len(parts) >= 4 && parts[3] != "" { + return "https://q." + parts[3] + ".amazonaws.com/" + } + // Try to extract region from runtime endpoint (runtime..kiro.dev) + host := strings.TrimPrefix(strings.TrimPrefix(runtimeEndpoint, "https://"), "http://") + host = strings.TrimSuffix(host, "/") + if strings.HasPrefix(host, "runtime.") && strings.HasSuffix(host, ".kiro.dev") { + region := strings.TrimPrefix(host, "runtime.") + region = strings.TrimSuffix(region, ".kiro.dev") + return "https://q." + region + ".amazonaws.com/" + } + // Fallback: use management endpoint + if mgmt, err := kiroManagementEndpointFor(runtimeEndpoint); err == nil { + return mgmt + } + return runtimeEndpoint +} + func kiroManagementEndpointFor(endpoint string) (string, error) { parsed, err := url.Parse(strings.TrimSpace(endpoint)) if err != nil { @@ -727,15 +749,12 @@ func (c *kiroAPIClient) ListModels(ctx context.Context, profileARN string) (*kir if err != nil { return nil, err } - // ListModels uses the management endpoint (management.*.kiro.dev) rather - // than the streaming endpoint (runtime.*.kiro.dev). - mgmtEndpoint, err := kiroManagementEndpointFor(c.endpoint) + // Use q..amazonaws.com (same as kiro-cli) rather than + // management.*.kiro.dev which is slower/less reliable. + listEndpoint := kiroListModelsEndpoint(c.endpoint, profileARN) + targetURL, err := url.Parse(listEndpoint) if err != nil { - mgmtEndpoint = c.endpoint // fall back to streaming endpoint - } - targetURL, err := url.Parse(mgmtEndpoint) - if err != nil { - return nil, fmt.Errorf("parse management endpoint: %w", err) + return nil, fmt.Errorf("parse list models endpoint: %w", err) } query := targetURL.Query() query.Set("origin", kiroDefaultOrigin)