Files
Luminary/internal/prediction/models.go
T
renjue 9988ac9b5f
CI / docker (push) Successful in 4m19s
Split ingress keys into text and image protocols with dedicated API docs.
Text keys use OpenAI routes; image keys use Replicate predictions and model listing, with admin UI whitelist filtering and per-key documentation pages.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 21:41:06 +08:00

91 lines
2.5 KiB
Go

package prediction
import (
"context"
"fmt"
"strings"
"time"
"github.com/rose_cat707/luminary/internal/model"
"github.com/rose_cat707/luminary/internal/store/cache"
)
func splitOwnerName(ingressID, providerName string) (owner, name string) {
if i := strings.Index(ingressID, "/"); i > 0 {
return ingressID[:i], ingressID[i+1:]
}
owner = providerName
if owner == "" {
owner = "luminary"
}
name = ingressID
if name == "" {
name = "model"
}
return owner, name
}
func modelDescription(m model.ModelEntry) string {
if m.DisplayName != "" {
return m.DisplayName
}
switch m.WorkflowType {
case model.WorkflowImg2Img:
return "Image-to-image workflow"
default:
return "Text-to-image workflow"
}
}
// ListPublicModels returns Replicate-compatible model objects visible to the ingress key.
func (s *Service) ListPublicModels(ctx context.Context, ingress *model.IngressKey, baseURL string) ([]map[string]any, error) {
_ = ctx
allowedProviders := cache.ParseJSONList(ingress.AllowedProvidersJSON)
allowedModels := cache.ParseJSONList(ingress.AllowedModelsJSON)
baseURL = strings.TrimRight(baseURL, "/")
var results []map[string]any
for _, p := range s.cache.ListProviders() {
if p.Category != model.CategoryImage || !p.Enabled {
continue
}
if !cache.MatchesList(allowedProviders, p.Name) && !cache.MatchesList(allowedProviders, string(p.Type)) && !cache.MatchesList(allowedProviders, "*") {
continue
}
for _, m := range s.cache.GetModels(p.ID) {
if !m.Enabled || m.VersionHash == "" {
continue
}
ingressID := m.IngressID()
if !cache.MatchesList(allowedModels, ingressID) && !cache.MatchesList(allowedModels, m.ModelID) && !cache.MatchesList(allowedModels, m.VersionHash) && !cache.MatchesList(allowedModels, "*") {
continue
}
owner, name := splitOwnerName(ingressID, p.Name)
createdAt := m.CreatedAt
if createdAt.IsZero() {
createdAt = time.Now()
}
results = append(results, map[string]any{
"url": fmt.Sprintf("%s/v1/models/%s/%s", baseURL, owner, name),
"owner": owner,
"name": name,
"description": modelDescription(m),
"visibility": "public",
"latest_version": map[string]any{
"id": m.VersionHash,
"created_at": createdAt.UTC().Format(time.RFC3339),
"cog_version": "",
"openapi_schema": map[string]any{
"info": map[string]any{
"title": name,
"version": "1.0.0",
"description": modelDescription(m),
},
},
},
})
}
}
return results, nil
}