vibe-proxy/backend/internal/client/grokbuild/grokbuild.go
2026-08-24 00:10:41 +02:00

78 lines
2.1 KiB
Go

package grokbuild
import "strings"
// ModelInfo represents input model information to be formatted.
type ModelInfo struct {
ID string
DisplayName string
ContextLength int
ReasoningLevels []string
}
// ReasoningEffort represents reasoning effort level in Grok Shell model entries.
type ReasoningEffort struct {
Value string `json:"value"`
}
// ModelEntry represents a single model entry formatted for Grok Shell.
type ModelEntry struct {
ID string `json:"id"`
Model string `json:"model"`
Name string `json:"name"`
ContextWindow int `json:"context_window,omitempty"`
APIBackend string `json:"api_backend"`
SupportedInAPI bool `json:"supported_in_api"`
ReasoningEfforts []ReasoningEffort `json:"reasoning_efforts,omitempty"`
}
// Response represents the model list response envelope formatted for Grok Shell.
type Response struct {
Object string `json:"object"`
Data []ModelEntry `json:"data"`
}
// IsGrokShellUserAgent checks if the User-Agent header indicates a Grok Shell client.
func IsGrokShellUserAgent(userAgent string) bool {
return strings.Contains(strings.ToLower(userAgent), "grok-shell")
}
// BuildResponse constructs the Grok Shell formatted model list response.
func BuildResponse(models []ModelInfo) Response {
entries := make([]ModelEntry, 0, len(models))
for _, m := range models {
name := m.DisplayName
if name == "" {
name = m.ID
}
var efforts []ReasoningEffort
for _, level := range m.ReasoningLevels {
trimmed := strings.TrimSpace(level)
if trimmed != "" {
efforts = append(efforts, ReasoningEffort{Value: trimmed})
}
}
entry := ModelEntry{
ID: m.ID,
Model: m.ID,
Name: name,
APIBackend: "responses",
SupportedInAPI: true,
ReasoningEfforts: efforts,
}
if m.ContextLength > 0 {
entry.ContextWindow = m.ContextLength
}
entries = append(entries, entry)
}
return Response{
Object: "list",
Data: entries,
}
}