package sub2api import ( "context" "encoding/json" "net/http" "strings" ) type GatewayAccessCheckRequest struct { APIKey string ExpectedModel string } type GatewayAccessResult struct { OK bool `json:"ok"` StatusCode int `json:"status_code"` Models []string `json:"models"` HasExpectedModel bool `json:"has_expected_model"` CompletionOK bool `json:"completion_ok"` CompletionStatus int `json:"completion_status"` CompletionType string `json:"completion_content_type,omitempty"` CompletionBody string `json:"completion_body_preview,omitempty"` } func (c *Client) CheckGatewayAccess(ctx context.Context, req GatewayAccessCheckRequest) (GatewayAccessResult, error) { gatewayClient := *c gatewayClient.apiKey = "" gatewayClient.bearerToken = strings.TrimSpace(req.APIKey) statusCode, _, body, err := gatewayClient.perform(ctx, http.MethodGet, "/v1/models", nil) if err != nil { return GatewayAccessResult{}, err } result := GatewayAccessResult{StatusCode: statusCode, OK: statusCode >= http.StatusOK && statusCode < http.StatusMultipleChoices} if !result.OK { return result, nil } result.Models = decodeGatewayModelIDs(body) for _, modelID := range result.Models { if modelID == strings.TrimSpace(req.ExpectedModel) { result.HasExpectedModel = true break } } return result, nil } func (c *Client) CheckGatewayCompletion(ctx context.Context, req GatewayCompletionCheckRequest) (GatewayCompletionResult, error) { gatewayClient := *c gatewayClient.apiKey = "" gatewayClient.bearerToken = strings.TrimSpace(req.APIKey) model := strings.TrimSpace(req.Model) if model == "" { return GatewayCompletionResult{}, nil } prompt := strings.TrimSpace(req.Prompt) if prompt == "" { prompt = "ping" } maxTokens := req.MaxTokens if maxTokens <= 0 { maxTokens = 8 } payload := map[string]any{ "model": model, "messages": []map[string]string{ {"role": "user", "content": prompt}, }, "max_tokens": maxTokens, "temperature": 0, } statusCode, headers, body, err := gatewayClient.perform(ctx, http.MethodPost, "/v1/chat/completions", payload) if err != nil { return GatewayCompletionResult{}, err } return GatewayCompletionResult{ OK: statusCode >= http.StatusOK && statusCode < http.StatusMultipleChoices, StatusCode: statusCode, ContentType: strings.TrimSpace(headers.Get("Content-Type")), BodyPreview: previewGatewayBody(body, 400), }, nil } func decodeGatewayModelIDs(body []byte) []string { var payload struct { Data []struct { ID string `json:"id"` } `json:"data"` } if err := json.Unmarshal(body, &payload); err == nil && len(payload.Data) > 0 { models := make([]string, 0, len(payload.Data)) for _, item := range payload.Data { if id := strings.TrimSpace(item.ID); id != "" { models = append(models, id) } } return models } return nil } func previewGatewayBody(body []byte, limit int) string { trimmed := strings.TrimSpace(string(body)) if limit <= 0 || len(trimmed) <= limit { return trimmed } return trimmed[:limit] }