Add projects

This commit is contained in:
Alois 2026-08-24 00:10:41 +02:00
commit 8b607dd700
Signed by: alois
SSH key fingerprint: SHA256:GBzT2DXvAuGV9XIV5W3WrzVpjU54FThmxHXdbz95J24
1802 changed files with 503346 additions and 2 deletions

View file

@ -0,0 +1,78 @@
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,
}
}

View file

@ -0,0 +1,50 @@
package grokbuild
import "testing"
func TestIsGrokShellUserAgent(t *testing.T) {
tests := []struct {
name string
ua string
want bool
}{
{"shell", "grok-shell/0.2.119 (macos; aarch64)", true},
{"pager", "grok-pager/0.2.119 grok-shell/0.2.119 (macos; aarch64)", true},
{"case insensitive", "GROK-PAGER/1.0 GROK-SHELL/1.0", true},
{"ordinary client", "curl/8.7.1", false},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if got := IsGrokShellUserAgent(test.ua); got != test.want {
t.Fatalf("IsGrokShellUserAgent(%q) = %t, want %t", test.ua, got, test.want)
}
})
}
}
func TestBuildResponse(t *testing.T) {
response := BuildResponse([]ModelInfo{
{ID: "grok-4", DisplayName: "Grok 4", ContextLength: 256000, ReasoningLevels: []string{"high"}},
{ID: "plain-model", ContextLength: 0},
})
if response.Object != "list" || len(response.Data) != 2 {
t.Fatalf("response envelope = %#v", response)
}
entry := response.Data[0]
if entry.ID != "grok-4" || entry.Model != "grok-4" || entry.Name != "Grok 4" {
t.Fatalf("entry identity = %#v", entry)
}
if entry.ContextWindow != 256000 {
t.Fatalf("entry context = %#v", entry)
}
if entry.APIBackend != "responses" || !entry.SupportedInAPI {
t.Fatalf("entry fixed fields = %#v", entry)
}
if len(entry.ReasoningEfforts) != 1 || entry.ReasoningEfforts[0].Value != "high" {
t.Fatalf("reasoning efforts = %#v", entry.ReasoningEfforts)
}
if response.Data[1].Name != "plain-model" || response.Data[1].ContextWindow != 0 || response.Data[1].ReasoningEfforts != nil {
t.Fatalf("fallback/omitempty mapping = %#v", response.Data[1])
}
}

View file

@ -0,0 +1,84 @@
package grokbuild
import (
"bytes"
"context"
"net/http"
"slices"
"strings"
"github.com/gin-gonic/gin"
"github.com/tidwall/gjson"
)
var keepaliveSSEComment = []byte(": keepalive\n\n")
// KeepaliveSSEComment returns the standard SSE comment used for keepalive.
func KeepaliveSSEComment() []byte {
return bytes.Clone(keepaliveSSEComment)
}
// IsGrokClientUserAgent checks if the user agent contains "grok-pager" or "grok-shell".
func IsGrokClientUserAgent(userAgent string) bool {
ua := strings.ToLower(userAgent)
return strings.Contains(ua, "grok-pager") || strings.Contains(ua, "grok-shell")
}
// IsGrokClientHeaders checks if the provided HTTP headers indicate a Grok client.
func IsGrokClientHeaders(headers http.Header) bool {
if headers == nil {
return false
}
for key, values := range headers {
if strings.EqualFold(key, "User-Agent") {
if slices.ContainsFunc(values, IsGrokClientUserAgent) {
return true
}
}
}
return false
}
// IsGrokClientContext checks if either the context (e.g. Gin context) or headers indicate a Grok client.
func IsGrokClientContext(ctx context.Context, headers http.Header) bool {
if ctx != nil {
if ginCtx, ok := ctx.Value("gin").(*gin.Context); ok && ginCtx != nil && ginCtx.Request != nil {
if IsGrokClientHeaders(ginCtx.Request.Header) {
return true
}
}
}
return IsGrokClientHeaders(headers)
}
// IsKeepalivePayload reports whether a JSON payload has type "keepalive".
func IsKeepalivePayload(payload []byte) bool {
return gjson.GetBytes(payload, "type").String() == "keepalive"
}
// IsKeepaliveSSELine reports whether an SSE line represents a keepalive event or data frame.
func IsKeepaliveSSELine(line []byte) bool {
trimmed := bytes.TrimSpace(line)
if bytes.HasPrefix(trimmed, []byte("event:")) {
eventName := bytes.TrimSpace(trimmed[6:])
return bytes.Equal(eventName, []byte("keepalive"))
}
if bytes.HasPrefix(trimmed, []byte("data:")) {
data := bytes.TrimSpace(trimmed[5:])
return IsKeepalivePayload(data)
}
return false
}
// TransformKeepaliveSSELine transforms a keepalive SSE line into an SSE comment line
// when isGrokClient is true. If the line is not a keepalive line or isGrokClient is false,
// it returns the original line and false.
func TransformKeepaliveSSELine(line []byte, isGrokClient bool) ([]byte, bool) {
if !isGrokClient {
return line, false
}
if IsKeepaliveSSELine(line) {
return bytes.Clone(keepaliveSSEComment), true
}
return line, false
}

View file

@ -0,0 +1,156 @@
package grokbuild
import (
"bytes"
"context"
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
)
func TestIsGrokClientUserAgent(t *testing.T) {
tests := []struct {
ua string
want bool
}{
{"grok-shell/0.2.119 (macos; aarch64)", true},
{"grok-pager/1.0.5 grok-shell/1.0.5 (linux; x86_64)", true},
{"grok-pager/1.0.5", true},
{"GROK-PAGER/1.0", true},
{"GROK-SHELL/1.0", true},
{"curl/8.7.1", false},
{"openai-python/1.0.0", false},
{"", false},
}
for _, tc := range tests {
if got := IsGrokClientUserAgent(tc.ua); got != tc.want {
t.Errorf("IsGrokClientUserAgent(%q) = %v, want %v", tc.ua, got, tc.want)
}
}
}
func TestIsGrokClientHeaders(t *testing.T) {
tests := []struct {
name string
headers http.Header
want bool
}{
{
name: "User-Agent with grok-pager",
headers: http.Header{"User-Agent": []string{"grok-pager/1.0.5"}},
want: true,
},
{
name: "case insensitive header name",
headers: http.Header{"user-agent": []string{"grok-shell/0.2"}},
want: true,
},
{
name: "unrelated user agent",
headers: http.Header{"User-Agent": []string{"curl/8.7.1"}},
want: false,
},
{
name: "nil headers",
headers: nil,
want: false,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
if got := IsGrokClientHeaders(tc.headers); got != tc.want {
t.Errorf("IsGrokClientHeaders() = %v, want %v", got, tc.want)
}
})
}
}
func TestIsGrokClientContext(t *testing.T) {
gin.SetMode(gin.TestMode)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest(http.MethodPost, "/v1/responses", nil)
c.Request.Header.Set("User-Agent", "grok-pager/1.0.5 grok-shell/1.0.5")
ctx := context.WithValue(context.Background(), "gin", c)
if !IsGrokClientContext(ctx, nil) {
t.Error("expected IsGrokClientContext to detect gin context user agent")
}
plainCtx := context.Background()
headers := http.Header{"User-Agent": []string{"grok-shell/1.0"}}
if !IsGrokClientContext(plainCtx, headers) {
t.Error("expected IsGrokClientContext to detect headers when gin context is absent")
}
}
func TestIsKeepalivePayload(t *testing.T) {
tests := []struct {
payload []byte
want bool
}{
{[]byte(`{"type":"keepalive","sequence_number":3}`), true},
{[]byte(`{"type":"keepalive"}`), true},
{[]byte(`{"type":"response.created"}`), false},
{[]byte(`{"type":"response.reasoning.delta"}`), false},
{[]byte(``), false},
}
for _, tc := range tests {
if got := IsKeepalivePayload(tc.payload); got != tc.want {
t.Errorf("IsKeepalivePayload(%s) = %v, want %v", string(tc.payload), got, tc.want)
}
}
}
func TestIsKeepaliveSSELine(t *testing.T) {
tests := []struct {
line []byte
want bool
}{
{[]byte("event: keepalive"), true},
{[]byte("event: keepalive\n"), true},
{[]byte(" event: keepalive "), true},
{[]byte(`data: {"type":"keepalive","sequence_number":3}`), true},
{[]byte(`data: {"type":"keepalive"}`), true},
{[]byte("event: response.created"), false},
{[]byte("event: keepalive-other"), false},
{[]byte(`data: {"type":"response.created"}`), false},
{[]byte(""), false},
}
for _, tc := range tests {
if got := IsKeepaliveSSELine(tc.line); got != tc.want {
t.Errorf("IsKeepaliveSSELine(%s) = %v, want %v", string(tc.line), got, tc.want)
}
}
}
func TestTransformKeepaliveSSELine(t *testing.T) {
comment := KeepaliveSSEComment()
// Grok client: keepalive line is transformed
got, ok := TransformKeepaliveSSELine([]byte("event: keepalive"), true)
if !ok || !bytes.Equal(got, comment) {
t.Errorf("TransformKeepaliveSSELine(event: keepalive, true) = %q, %v, want %q, true", string(got), ok, string(comment))
}
got, ok = TransformKeepaliveSSELine([]byte(`data: {"type":"keepalive","sequence_number":3}`), true)
if !ok || !bytes.Equal(got, comment) {
t.Errorf("TransformKeepaliveSSELine(data: keepalive, true) = %q, %v, want %q, true", string(got), ok, string(comment))
}
// Grok client: normal line is untouched
normalLine := []byte(`data: {"type":"response.created"}`)
got, ok = TransformKeepaliveSSELine(normalLine, true)
if ok || !bytes.Equal(got, normalLine) {
t.Errorf("TransformKeepaliveSSELine(normalLine, true) = %q, %v, want unchanged, false", string(got), ok)
}
// Non-Grok client: keepalive line is untouched
keepaliveLine := []byte("event: keepalive")
got, ok = TransformKeepaliveSSELine(keepaliveLine, false)
if ok || !bytes.Equal(got, keepaliveLine) {
t.Errorf("TransformKeepaliveSSELine(event: keepalive, false) = %q, %v, want unchanged, false", string(got), ok)
}
}