// groqqer: OpenAI-compatible LLM gateway for the Groq Streamlit space // Reverse engineers https://dromerosm-groq-chatbot.hf.space into an OpenAI proxy // Created by Luxferre in 2026, released into the public domain package main import ( "bufio" "context" "crypto/rand" "encoding/base64" "encoding/binary" "encoding/json" "flag" "fmt" "io" "log" "net" "net/http" "os" "os/exec" "os/signal" "regexp" "strconv" "strings" "sync" "sync/atomic" "syscall" "time" ) var ( DefaultUserAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36" DefaultTargetURL = "https://dromerosm-groq-chatbot.hf.space" DefaultModel = "llama-3.3-70b-versatile" cdpCmdCounter int64 ) // --------------------------------------------------------------------------- // OpenAI API Data Structures // --------------------------------------------------------------------------- type ModelItem struct { ID string `json:"id"` Object string `json:"object"` Created int64 `json:"created"` OwnedBy string `json:"owned_by"` } type ModelsResponse struct { Object string `json:"object"` Data []ModelItem `json:"data"` } type ToolCallFunction struct { Name string `json:"name"` Arguments string `json:"arguments"` } type ToolCall struct { Index *int `json:"index,omitempty"` ID string `json:"id,omitempty"` Type string `json:"type,omitempty"` Function ToolCallFunction `json:"function"` } type Tool struct { Type string `json:"type"` Function interface{} `json:"function"` } type ChatMessage struct { Role string `json:"role"` Content interface{} `json:"content"` ReasoningContent string `json:"reasoning_content,omitempty"` ToolCalls []ToolCall `json:"tool_calls,omitempty"` ToolCallID string `json:"tool_call_id,omitempty"` Name string `json:"name,omitempty"` } func (m *ChatMessage) GetContentString() string { if m.Content == nil { return "" } if str, ok := m.Content.(string); ok { return str } if parts, ok := m.Content.([]interface{}); ok { var sb strings.Builder for _, p := range parts { if str, ok := p.(string); ok { sb.WriteString(str) } else if itemMap, ok := p.(map[string]interface{}); ok { if textVal, ok := itemMap["text"].(string); ok { sb.WriteString(textVal) } } } return sb.String() } b, err := json.Marshal(m.Content) if err == nil { return string(b) } return fmt.Sprintf("%v", m.Content) } type ChatCompletionRequest struct { Model string `json:"model"` Messages []ChatMessage `json:"messages"` Tools []Tool `json:"tools,omitempty"` ToolChoice interface{} `json:"tool_choice,omitempty"` Stream bool `json:"stream"` MaxTokens int `json:"max_tokens"` MaxCompletionTokens int `json:"max_completion_tokens"` ReasoningEffort string `json:"reasoning_effort,omitempty"` } type ChatCompletionResponseChoice struct { Index int `json:"index"` Message ChatMessage `json:"message"` FinishReason string `json:"finish_reason"` } type Usage struct { PromptTokens int `json:"prompt_tokens"` CompletionTokens int `json:"completion_tokens"` TotalTokens int `json:"total_tokens"` } type ChatCompletionResponse struct { ID string `json:"id"` Object string `json:"object"` Created int64 `json:"created"` Model string `json:"model"` Choices []ChatCompletionResponseChoice `json:"choices"` Usage Usage `json:"usage"` } type StreamDelta struct { Role string `json:"role,omitempty"` Content string `json:"content,omitempty"` ReasoningContent string `json:"reasoning_content,omitempty"` ToolCalls []ToolCall `json:"tool_calls,omitempty"` } type StreamChoice struct { Index int `json:"index"` Delta StreamDelta `json:"delta"` FinishReason string `json:"finish_reason,omitempty"` } type StreamResponse struct { ID string `json:"id"` Object string `json:"object"` Created int64 `json:"created"` Model string `json:"model"` Choices []StreamChoice `json:"choices"` } // --------------------------------------------------------------------------- // UUID & Utility Functions // --------------------------------------------------------------------------- func GenerateUUID() string { var b [16]byte _, _ = rand.Read(b[:]) b[6] = (b[6] & 0x0f) | 0x40 b[8] = (b[8] & 0x3f) | 0x80 return fmt.Sprintf("%08x-%04x-%04x-%04x-%012x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:16]) } func getFreePort() (string, error) { listener, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { return "", err } defer listener.Close() return strconv.Itoa(listener.Addr().(*net.TCPAddr).Port), nil } func findFreeXDisplay() string { for d := 100; d < 200; d++ { lockFile := fmt.Sprintf("/tmp/.X%d-lock", d) sockFile := fmt.Sprintf("/tmp/.X11-unix/X%d", d) if _, err := os.Stat(lockFile); os.IsNotExist(err) { if _, err2 := os.Stat(sockFile); os.IsNotExist(err2) { return fmt.Sprintf(":%d", d) } } } return ":100" } // --------------------------------------------------------------------------- // SOCKS5 Proxy Client (RFC 1928 / RFC 1929) // --------------------------------------------------------------------------- type SOCKS5Config struct { Address string Username string Password string } func ParseSOCKS5URL(proxyURL string) (*SOCKS5Config, error) { cleanURL := strings.TrimSpace(proxyURL) if cleanURL == "" { return nil, nil } if strings.HasPrefix(cleanURL, "socks5://") { cleanURL = strings.TrimPrefix(cleanURL, "socks5://") } else if strings.HasPrefix(cleanURL, "socks5h://") { cleanURL = strings.TrimPrefix(cleanURL, "socks5h://") } cfg := &SOCKS5Config{} if atIdx := strings.LastIndex(cleanURL, "@"); atIdx != -1 { userPass := cleanURL[:atIdx] cfg.Address = cleanURL[atIdx+1:] if colonIdx := strings.Index(userPass, ":"); colonIdx != -1 { cfg.Username = userPass[:colonIdx] cfg.Password = userPass[colonIdx+1:] } else { cfg.Username = userPass } } else { cfg.Address = cleanURL } if !strings.Contains(cfg.Address, ":") { cfg.Address = cfg.Address + ":1080" } return cfg, nil } func DialSOCKS5(ctx context.Context, proxyURL, targetAddr string) (net.Conn, error) { cfg, err := ParseSOCKS5URL(proxyURL) if err != nil { return nil, fmt.Errorf("invalid socks5 proxy configuration: %w", err) } if cfg == nil { var d net.Dialer return d.DialContext(ctx, "tcp", targetAddr) } var d net.Dialer conn, err := d.DialContext(ctx, "tcp", cfg.Address) if err != nil { return nil, fmt.Errorf("failed to connect to socks5 proxy at %s: %w", cfg.Address, err) } deadline, ok := ctx.Deadline() if !ok { deadline = time.Now().Add(30 * time.Second) } conn.SetDeadline(deadline) defer conn.SetDeadline(time.Time{}) var greeting []byte if cfg.Username != "" { greeting = []byte{0x05, 0x02, 0x00, 0x02} } else { greeting = []byte{0x05, 0x01, 0x00} } if _, err := conn.Write(greeting); err != nil { conn.Close() return nil, fmt.Errorf("failed to write socks5 greeting: %w", err) } resp := make([]byte, 2) if _, err := io.ReadFull(conn, resp); err != nil { conn.Close() return nil, fmt.Errorf("failed to read socks5 greeting response: %w", err) } if resp[0] != 0x05 { conn.Close() return nil, fmt.Errorf("unsupported socks version: 0x%02x", resp[0]) } if resp[1] == 0x02 { if cfg.Username == "" { conn.Close() return nil, fmt.Errorf("socks5 proxy requires authentication, but no credentials provided") } uLen := byte(len(cfg.Username)) pLen := byte(len(cfg.Password)) authReq := []byte{0x01, uLen} authReq = append(authReq, []byte(cfg.Username)...) authReq = append(authReq, pLen) authReq = append(authReq, []byte(cfg.Password)...) if _, err := conn.Write(authReq); err != nil { conn.Close() return nil, fmt.Errorf("failed to send socks5 authentication: %w", err) } authResp := make([]byte, 2) if _, err := io.ReadFull(conn, authResp); err != nil { conn.Close() return nil, fmt.Errorf("failed to read socks5 auth response: %w", err) } if authResp[1] != 0x00 { conn.Close() return nil, fmt.Errorf("socks5 authentication failed with status 0x%02x", authResp[1]) } } else if resp[1] != 0x00 { conn.Close() return nil, fmt.Errorf("socks5 proxy rejected authentication methods: 0x%02x", resp[1]) } host, portStr, err := net.SplitHostPort(targetAddr) if err != nil { conn.Close() return nil, fmt.Errorf("invalid target address %s: %w", targetAddr, err) } port, err := strconv.Atoi(portStr) if err != nil || port < 1 || port > 65535 { conn.Close() return nil, fmt.Errorf("invalid port in target address %s", targetAddr) } reqBuf := []byte{0x05, 0x01, 0x00} ip := net.ParseIP(host) if ip4 := ip.To4(); ip4 != nil { reqBuf = append(reqBuf, 0x01) reqBuf = append(reqBuf, ip4...) } else if ip6 := ip.To16(); ip6 != nil { reqBuf = append(reqBuf, 0x04) reqBuf = append(reqBuf, ip6...) } else { reqBuf = append(reqBuf, 0x03, byte(len(host))) reqBuf = append(reqBuf, []byte(host)...) } reqBuf = append(reqBuf, byte(port>>8), byte(port&0xFF)) if _, err := conn.Write(reqBuf); err != nil { conn.Close() return nil, fmt.Errorf("failed to send socks5 connect request: %w", err) } respHdr := make([]byte, 4) if _, err := io.ReadFull(conn, respHdr); err != nil { conn.Close() return nil, fmt.Errorf("failed to read socks5 connect response: %w", err) } if respHdr[1] != 0x00 { conn.Close() return nil, fmt.Errorf("socks5 connect failed with reply code 0x%02x", respHdr[1]) } switch respHdr[3] { case 0x01: bnd := make([]byte, 6) io.ReadFull(conn, bnd) case 0x03: lenBuf := make([]byte, 1) io.ReadFull(conn, lenBuf) bnd := make([]byte, int(lenBuf[0])+2) io.ReadFull(conn, bnd) case 0x04: bnd := make([]byte, 18) io.ReadFull(conn, bnd) } return conn, nil } // --------------------------------------------------------------------------- // Tool and Message Processing // --------------------------------------------------------------------------- func BuildToolInstruction(tools []Tool, toolChoice interface{}) string { if len(tools) == 0 { return "" } toolsBytes, _ := json.Marshal(tools) var sb strings.Builder sb.WriteString("\n\n# Tool Calling Instructions\nYou have access to the following functions:\n\n") sb.WriteString(string(toolsBytes)) sb.WriteString("\n\n\nWhen you need to call a function, respond ONLY with a block formatted exactly as follows:\n\n{\"name\": \"\", \"arguments\": {}}\n\n\nDo not include conversational filler before or after the tool call.") if toolChoice != nil { if choiceStr, ok := toolChoice.(string); ok { if choiceStr == "required" { sb.WriteString("\n\nYou MUST invoke at least one tool from the list above.") } } else if choiceMap, ok := toolChoice.(map[string]interface{}); ok { if fnMap, ok := choiceMap["function"].(map[string]interface{}); ok { if fnName, ok := fnMap["name"].(string); ok && fnName != "" { sb.WriteString(fmt.Sprintf("\n\nYou MUST call the function %q.", fnName)) } } } } return sb.String() } func FormatPrompt(req ChatCompletionRequest) string { toolInstruction := BuildToolInstruction(req.Tools, req.ToolChoice) var systemInstructions []string var historyTurns []string var currentTurn string for i, msg := range req.Messages { contentStr := msg.GetContentString() switch msg.Role { case "system": if contentStr != "" { systemInstructions = append(systemInstructions, contentStr) } case "assistant": var sb strings.Builder if contentStr != "" { sb.WriteString(contentStr) } for _, tc := range msg.ToolCalls { if sb.Len() > 0 { sb.WriteString("\n") } args := tc.Function.Arguments if strings.TrimSpace(args) == "" { args = "{}" } sb.WriteString(fmt.Sprintf("\n{\"name\": %q, \"arguments\": %s}\n", tc.Function.Name, args)) } historyTurns = append(historyTurns, "Assistant: "+sb.String()) case "tool", "function": toolName := msg.Name if toolName == "" { toolName = msg.ToolCallID } var contentJSON []byte if json.Valid([]byte(contentStr)) { contentJSON = []byte(contentStr) } else { contentJSON, _ = json.Marshal(contentStr) } turnText := fmt.Sprintf("\n{\"name\": %q, \"content\": %s}\n", toolName, string(contentJSON)) if i == len(req.Messages)-1 { currentTurn = turnText } else { historyTurns = append(historyTurns, "Tool Result: "+turnText) } case "user": if i == len(req.Messages)-1 { currentTurn = contentStr } else { historyTurns = append(historyTurns, "User: "+contentStr) } } } var promptBuilder strings.Builder if len(systemInstructions) > 0 || toolInstruction != "" { promptBuilder.WriteString("[System Instructions]\n") for _, sys := range systemInstructions { promptBuilder.WriteString(sys) promptBuilder.WriteString("\n") } if toolInstruction != "" { promptBuilder.WriteString(strings.TrimSpace(toolInstruction)) promptBuilder.WriteString("\n") } promptBuilder.WriteString("\n") } if len(historyTurns) > 0 { promptBuilder.WriteString("[Conversation History]\n") for _, turn := range historyTurns { promptBuilder.WriteString(turn) promptBuilder.WriteString("\n") } promptBuilder.WriteString("\n") } if currentTurn != "" { if len(historyTurns) > 0 || len(systemInstructions) > 0 { promptBuilder.WriteString("[User]\n") } promptBuilder.WriteString(currentTurn) } return strings.TrimSpace(promptBuilder.String()) } func cleanJSONBlock(input string) string { s := strings.TrimSpace(input) if strings.HasPrefix(s, "```") { lines := strings.Split(s, "\n") if len(lines) >= 2 { if strings.HasPrefix(lines[len(lines)-1], "```") { lines = lines[1 : len(lines)-1] } else { lines = lines[1:] } s = strings.TrimSpace(strings.Join(lines, "\n")) } } return s } func sanitizeJSONValue(v interface{}) interface{} { switch val := v.(type) { case string: return strings.TrimSpace(val) case map[string]interface{}: cleanMap := make(map[string]interface{}) for k, childV := range val { cleanKey := strings.TrimSpace(k) cleanMap[cleanKey] = sanitizeJSONValue(childV) } return cleanMap case []interface{}: cleanSlice := make([]interface{}, len(val)) for i, childV := range val { cleanSlice[i] = sanitizeJSONValue(childV) } return cleanSlice default: return v } } var toolNameRegex = regexp.MustCompile(`"\s*(?:name|function|action|call)\s*"\s*:\s*"\s*([^"]+?)\s*"`) func repairToolCallJSON(jsonStr string) (ToolCall, bool) { nameMatch := toolNameRegex.FindStringSubmatch(jsonStr) if len(nameMatch) < 2 { return ToolCall{}, false } nameVal := strings.TrimSpace(nameMatch[1]) argsStr := "{}" argsKwList := []string{`"arguments"`, `" parameters "`, `"arguments "`, `" parameters"`, `"parameters"`, `"args"`, `"input"`} argsIdx := -1 for _, kw := range argsKwList { idx := strings.Index(jsonStr, kw) if idx >= 0 { argsIdx = idx + len(kw) break } } var targetStr string if argsIdx >= 0 { targetStr = strings.TrimSpace(jsonStr[argsIdx:]) if strings.HasPrefix(targetStr, ":") { targetStr = strings.TrimSpace(targetStr[1:]) } } else { targetStr = jsonStr } if strings.HasPrefix(targetStr, "{") { endIdx := strings.LastIndex(targetStr, "}") if endIdx > 0 { objCandidate := targetStr[:endIdx+1] var testMap map[string]interface{} if json.Unmarshal([]byte(objCandidate), &testMap) == nil { b, _ := json.Marshal(sanitizeJSONValue(testMap)) return ToolCall{ ID: "call_" + GenerateUUID()[:8], Type: "function", Function: ToolCallFunction{ Name: nameVal, Arguments: string(b), }, }, true } } } else if strings.HasPrefix(targetStr, `"`) { endIdx := strings.LastIndex(targetStr, `"`) if endIdx > 0 { val := strings.TrimSpace(targetStr[1:endIdx]) b, _ := json.Marshal(val) argsStr = string(b) } } return ToolCall{ ID: "call_" + GenerateUUID()[:8], Type: "function", Function: ToolCallFunction{ Name: nameVal, Arguments: argsStr, }, }, true } func parseSingleToolCall(jsonStr string) (ToolCall, bool) { cleaned := cleanJSONBlock(jsonStr) var raw map[string]interface{} if err := json.Unmarshal([]byte(cleaned), &raw); err == nil { sanitizedRaw, ok := sanitizeJSONValue(raw).(map[string]interface{}) if !ok { sanitizedRaw = raw } for _, wrapperKey := range []string{"function", "function_call", "tool_call"} { if fnObj, ok := sanitizedRaw[wrapperKey].(map[string]interface{}); ok { if nameVal, ok := fnObj["name"].(string); ok && nameVal != "" { argsStr := "{}" var argsVal interface{} if a, hasA := fnObj["arguments"]; hasA { argsVal = a } else if p, hasP := fnObj["parameters"]; hasP { argsVal = p } else if args, hasArgs := fnObj["args"]; hasArgs { argsVal = args } if argsVal != nil { if s, isStr := argsVal.(string); isStr { var innerObj interface{} if json.Unmarshal([]byte(s), &innerObj) == nil { b, _ := json.Marshal(sanitizeJSONValue(innerObj)) argsStr = string(b) } else { argsStr = strings.TrimSpace(s) } } else { b, _ := json.Marshal(sanitizeJSONValue(argsVal)) argsStr = string(b) } } return ToolCall{ ID: "call_" + GenerateUUID()[:8], Type: "function", Function: ToolCallFunction{ Name: nameVal, Arguments: argsStr, }, }, true } } } nameVal := "" for _, key := range []string{"name", "function", "action", "call"} { if n, ok := sanitizedRaw[key].(string); ok && n != "" { nameVal = n break } } if nameVal != "" { argsStr := "{}" var argsVal interface{} for _, key := range []string{"arguments", "parameters", "args", "input"} { if a, ok := sanitizedRaw[key]; ok { argsVal = a break } } if argsVal != nil { if s, isStr := argsVal.(string); isStr { var innerObj interface{} if json.Unmarshal([]byte(s), &innerObj) == nil { b, _ := json.Marshal(sanitizeJSONValue(innerObj)) argsStr = string(b) } else { argsStr = strings.TrimSpace(s) } } else { b, _ := json.Marshal(sanitizeJSONValue(argsVal)) argsStr = string(b) } } else { argsMap := make(map[string]interface{}) for k, v := range sanitizedRaw { if k != "name" && k != "function" && k != "type" && k != "action" && k != "call" { argsMap[k] = v } } if len(argsMap) > 0 { b, _ := json.Marshal(sanitizeJSONValue(argsMap)) argsStr = string(b) } } return ToolCall{ ID: "call_" + GenerateUUID()[:8], Type: "function", Function: ToolCallFunction{ Name: nameVal, Arguments: argsStr, }, }, true } } return repairToolCallJSON(cleaned) } func parseXMLToolCall(block string) (ToolCall, bool) { inner := strings.TrimSpace(block) if strings.HasPrefix(inner, "") { inner = strings.TrimPrefix(inner, "") } if strings.HasSuffix(inner, "") { inner = strings.TrimSuffix(inner, "") } inner = cleanJSONBlock(inner) if tc, ok := parseSingleToolCall(inner); ok { return tc, true } var fnName string if strings.Contains(inner, "") && strings.Contains(inner, "") { nStart := strings.Index(inner, "") + len("") nEnd := strings.Index(inner, "") if nStart < nEnd { fnName = strings.TrimSpace(inner[nStart:nEnd]) } } var argsStr string if strings.Contains(inner, "") && strings.Contains(inner, "") { aStart := strings.Index(inner, "") + len("") aEnd := strings.Index(inner, "") if aStart < aEnd { argsStr = strings.TrimSpace(inner[aStart:aEnd]) } } if fnName != "" { if argsStr == "" { argsStr = "{}" } return ToolCall{ ID: "call_" + GenerateUUID()[:8], Type: "function", Function: ToolCallFunction{ Name: fnName, Arguments: argsStr, }, }, true } return ToolCall{}, false } func ExtractToolCallBlocks(content string) (blocks []string, remaining string) { s := content remaining = content for strings.Contains(s, "") { sIdx := strings.Index(s, "") rest := s[sIdx+len(""):] relNextSIdx := strings.Index(rest, "") var nextSIdx int if relNextSIdx != -1 { nextSIdx = sIdx + len("") + relNextSIdx } else { nextSIdx = -1 } relEIdx := strings.Index(rest, "") var eIdx int if relEIdx != -1 { eIdx = sIdx + len("") + relEIdx } else { eIdx = -1 } var blockText string var blockEndPos int if eIdx != -1 && (nextSIdx == -1 || eIdx < nextSIdx) { blockEndPos = eIdx + len("") blockText = s[sIdx:blockEndPos] s = s[blockEndPos:] } else if nextSIdx != -1 { blockEndPos = nextSIdx blockText = s[sIdx:blockEndPos] s = s[blockEndPos:] } else { blockText = s[sIdx:] s = "" } blocks = append(blocks, blockText) } for strings.Contains(remaining, "") { st := strings.Index(remaining, "") rest := remaining[st+len(""):] relNext := strings.Index(rest, "") var nextSt int if relNext != -1 { nextSt = st + len("") + relNext } else { nextSt = -1 } relEn := strings.Index(rest, "") var en int if relEn != -1 { en = st + len("") + relEn } else { en = -1 } if en != -1 && (nextSt == -1 || en < nextSt) { remaining = strings.TrimSpace(remaining[:st] + remaining[en+len(""):]) } else if nextSt != -1 { remaining = strings.TrimSpace(remaining[:st] + remaining[nextSt:]) } else { remaining = strings.TrimSpace(remaining[:st]) } } return blocks, remaining } func DetectToolCalls(content string) ([]ToolCall, string, bool) { blocks, remaining := ExtractToolCallBlocks(content) var calls []ToolCall for _, block := range blocks { if toolCall, ok := parseXMLToolCall(block); ok { calls = append(calls, toolCall) } } if len(calls) > 0 { return calls, remaining, true } if tc, ok := parseSingleToolCall(strings.TrimSpace(content)); ok { return []ToolCall{tc}, "", true } return nil, content, false } func ExtractThinking(content string) (string, string) { if strings.Contains(content, "") && strings.Contains(content, "") { start := strings.Index(content, "") end := strings.Index(content, "") if start < end { reasoning := content[start+len("") : end] rem := content[:start] + content[end+len(""):] rem = strings.TrimPrefix(rem, "\n\n") rem = strings.TrimPrefix(rem, "\n") return strings.TrimSpace(rem), strings.TrimSpace(reasoning) } } return content, "" } // --------------------------------------------------------------------------- // Streaming Filters & Framing // --------------------------------------------------------------------------- type StreamThinkingFilter struct { inThinking bool buf string } func NewStreamThinkingFilter() *StreamThinkingFilter { return &StreamThinkingFilter{} } func hasPrefixOf(target string, prefixes []string) int { for _, p := range prefixes { if strings.HasSuffix(target, p) { return len(p) } } return 0 } func (f *StreamThinkingFilter) Feed(chunk string, onContent func(string), onReasoning func(string)) { f.buf += chunk thinkStartTag := "" thinkEndTag := "" thinkStartPrefixes := []string{"<", " 0 { if !f.inThinking { if idx := strings.Index(f.buf, thinkStartTag); idx != -1 { before := f.buf[:idx] if before != "" { onContent(before) } f.inThinking = true f.buf = f.buf[idx+len(thinkStartTag):] } else if matchLen := hasPrefixOf(f.buf, thinkStartPrefixes); matchLen > 0 { safe := f.buf[:len(f.buf)-matchLen] if safe != "" { onContent(safe) } f.buf = f.buf[len(f.buf)-matchLen:] break } else { onContent(f.buf) f.buf = "" break } } else { if idx := strings.Index(f.buf, thinkEndTag); idx != -1 { before := f.buf[:idx] if before != "" { onReasoning(before) } f.inThinking = false f.buf = f.buf[idx+len(thinkEndTag):] f.buf = strings.TrimPrefix(f.buf, "\n\n") f.buf = strings.TrimPrefix(f.buf, "\n") } else if matchLen := hasPrefixOf(f.buf, thinkEndPrefixes); matchLen > 0 { safe := f.buf[:len(f.buf)-matchLen] if safe != "" { onReasoning(safe) } f.buf = f.buf[len(f.buf)-matchLen:] break } else { onReasoning(f.buf) f.buf = "" break } } } } func (f *StreamThinkingFilter) Flush(onContent func(string), onReasoning func(string)) { if len(f.buf) > 0 { if f.inThinking { onReasoning(f.buf) } else { onContent(f.buf) } f.buf = "" } } type StreamToolCallFilter struct { inToolCall bool buf string toolCallBuf string toolIndex int emittedCall bool } func NewStreamToolCallFilter() *StreamToolCallFilter { return &StreamToolCallFilter{} } func (f *StreamToolCallFilter) Feed(chunk string, onContent func(string), onToolCall func(ToolCall)) { f.buf += chunk toolStartTag := "" toolEndTag := "" startPrefixes := []string{"<", " 0 { if !f.inToolCall { if idx := strings.Index(f.buf, toolStartTag); idx != -1 { before := f.buf[:idx] if before != "" { onContent(before) } f.inToolCall = true f.buf = f.buf[idx+len(toolStartTag):] } else if matchLen := hasPrefixOf(f.buf, startPrefixes); matchLen > 0 { safe := f.buf[:len(f.buf)-matchLen] if safe != "" { onContent(safe) } f.buf = f.buf[len(f.buf)-matchLen:] break } else { onContent(f.buf) f.buf = "" break } } else { if idx := strings.Index(f.buf, toolEndTag); idx != -1 { f.toolCallBuf += f.buf[:idx] f.buf = f.buf[idx+len(toolEndTag):] f.inToolCall = false if tc, ok := parseSingleToolCall(f.toolCallBuf); ok { idxCopy := f.toolIndex tc.Index = &idxCopy f.toolIndex++ f.emittedCall = true onToolCall(tc) } else if tc2, ok2 := parseXMLToolCall("" + f.toolCallBuf + ""); ok2 { idxCopy := f.toolIndex tc2.Index = &idxCopy f.toolIndex++ f.emittedCall = true onToolCall(tc2) } else { onContent("" + f.toolCallBuf + "") } f.toolCallBuf = "" } else if matchLen := hasPrefixOf(f.buf, endPrefixes); matchLen > 0 { safe := f.buf[:len(f.buf)-matchLen] f.toolCallBuf += safe f.buf = f.buf[len(f.buf)-matchLen:] break } else { f.toolCallBuf += f.buf f.buf = "" break } } } } func (f *StreamToolCallFilter) Flush(onContent func(string), onToolCall func(ToolCall)) { if f.inToolCall && len(f.toolCallBuf) > 0 { if tc, ok := parseSingleToolCall(f.toolCallBuf); ok { idxCopy := f.toolIndex tc.Index = &idxCopy f.emittedCall = true onToolCall(tc) } else if tc2, ok2 := parseXMLToolCall("" + f.toolCallBuf + ""); ok2 { idxCopy := f.toolIndex tc2.Index = &idxCopy f.emittedCall = true onToolCall(tc2) } else { onContent("" + f.toolCallBuf) } f.toolCallBuf = "" } if len(f.buf) > 0 { onContent(f.buf) f.buf = "" } } type Streamer struct { w http.ResponseWriter flusher http.Flusher id string created int64 model string } func NewStreamer(w http.ResponseWriter, flusher http.Flusher, id string, created int64, model string) *Streamer { w.Header().Set("Content-Type", "text/event-stream") w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Connection", "keep-alive") return &Streamer{w: w, flusher: flusher, id: id, created: created, model: model} } func (s *Streamer) Role() { sendStreamDelta(s.w, s.flusher, s.id, s.created, s.model, StreamDelta{Role: "assistant"}, "") } func (s *Streamer) Reasoning(text string) { if text != "" { sendStreamDelta(s.w, s.flusher, s.id, s.created, s.model, StreamDelta{ReasoningContent: text}, "") } } func (s *Streamer) Content(text string) { if text != "" { sendStreamDelta(s.w, s.flusher, s.id, s.created, s.model, StreamDelta{Content: text}, "") } } func (s *Streamer) ToolCall(tc ToolCall) { sendStreamDelta(s.w, s.flusher, s.id, s.created, s.model, StreamDelta{ToolCalls: []ToolCall{tc}}, "") } func (s *Streamer) Finish(reason string) { sendStreamDelta(s.w, s.flusher, s.id, s.created, s.model, StreamDelta{}, reason) fmt.Fprintf(s.w, "data: [DONE]\n\n") if s.flusher != nil { s.flusher.Flush() } } func sendStreamDelta(w http.ResponseWriter, flusher http.Flusher, id string, created int64, model string, delta StreamDelta, finishReason string) { chunk := StreamResponse{ ID: id, Object: "chat.completion.chunk", Created: created, Model: model, Choices: []StreamChoice{ { Index: 0, Delta: delta, FinishReason: finishReason, }, }, } b, _ := json.Marshal(chunk) fmt.Fprintf(w, "data: %s\n\n", b) if flusher != nil { flusher.Flush() } } func WriteCompletionResponse(w http.ResponseWriter, completionID string, created int64, model string, content string, reasoning string, toolCalls []ToolCall, finishReason string) { if finishReason == "" { finishReason = "stop" } var contentVal interface{} = content if len(toolCalls) > 0 && strings.TrimSpace(content) == "" { contentVal = nil } resp := ChatCompletionResponse{ ID: completionID, Object: "chat.completion", Created: created, Model: model, Choices: []ChatCompletionResponseChoice{ { Index: 0, Message: ChatMessage{ Role: "assistant", Content: contentVal, ReasoningContent: reasoning, ToolCalls: toolCalls, }, FinishReason: finishReason, }, }, Usage: Usage{ PromptTokens: 0, CompletionTokens: 0, TotalTokens: 0, }, } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(resp) } // --------------------------------------------------------------------------- // Pure Go Chromium CDP Engine & BrowserBridge // --------------------------------------------------------------------------- func findChromiumBinary(customPath string) string { if customPath != "" { if _, err := exec.LookPath(customPath); err == nil { return customPath } } candidates := []string{"chromium", "google-chrome", "chromium-browser", "chrome"} for _, c := range candidates { if p, err := exec.LookPath(c); err == nil { return p } } return "" } func dialCDPWebSocket(wsURL string) (net.Conn, *bufio.Reader, error) { parts := strings.TrimPrefix(wsURL, "ws://") slashIdx := strings.Index(parts, "/") if slashIdx == -1 { return nil, nil, fmt.Errorf("invalid websocket url: %s", wsURL) } host := parts[:slashIdx] path := parts[slashIdx:] conn, err := net.DialTimeout("tcp", host, 5*time.Second) if err != nil { return nil, nil, err } nonce := make([]byte, 16) _, _ = rand.Read(nonce) secKey := base64.StdEncoding.EncodeToString(nonce) req := fmt.Sprintf("GET %s HTTP/1.1\r\nHost: %s\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: %s\r\nSec-WebSocket-Version: 13\r\n\r\n", path, host, secKey) if _, err := conn.Write([]byte(req)); err != nil { conn.Close() return nil, nil, err } reader := bufio.NewReader(conn) statusLine, err := reader.ReadString('\n') if err != nil || !strings.Contains(statusLine, "101") { conn.Close() return nil, nil, fmt.Errorf("websocket upgrade failed: %s", statusLine) } for { line, err := reader.ReadString('\n') if err != nil || strings.TrimSpace(line) == "" { break } } return conn, reader, nil } func sendWSFrame(conn net.Conn, payload []byte) error { var header []byte header = append(header, 0x81) length := len(payload) var maskKey [4]byte _, _ = rand.Read(maskKey[:]) if length < 126 { header = append(header, byte(length)|0x80) } else if length < 65536 { header = append(header, 126|0x80) header = append(header, byte(length>>8), byte(length&0xff)) } else { header = append(header, 127|0x80) for i := 7; i >= 0; i-- { header = append(header, byte((length>>(i*8))&0xff)) } } header = append(header, maskKey[:]...) masked := make([]byte, length) for i := 0; i < length; i++ { masked[i] = payload[i] ^ maskKey[i%4] } _, err := conn.Write(append(header, masked...)) return err } func readWSFrame(conn net.Conn, reader *bufio.Reader) ([]byte, error) { conn.SetReadDeadline(time.Now().Add(35 * time.Second)) b1, err := reader.ReadByte() if err != nil { return nil, err } opcode := b1 & 0x0f if opcode == 0x08 { return nil, fmt.Errorf("websocket closed by server") } b2, err := reader.ReadByte() if err != nil { return nil, err } isMasked := (b2 & 0x80) != 0 length := int(b2 & 0x7f) if length == 126 { var extLen uint16 if err := binary.Read(reader, binary.BigEndian, &extLen); err != nil { return nil, err } length = int(extLen) } else if length == 127 { var extLen uint64 if err := binary.Read(reader, binary.BigEndian, &extLen); err != nil { return nil, err } length = int(extLen) } var maskKey [4]byte if isMasked { if _, err := io.ReadFull(reader, maskKey[:]); err != nil { return nil, err } } payload := make([]byte, length) if _, err := io.ReadFull(reader, payload); err != nil { return nil, err } if isMasked { for i := 0; i < length; i++ { payload[i] ^= maskKey[i%4] } } return payload, nil } func sendCDPCommand(conn net.Conn, reader *bufio.Reader, method string, params map[string]interface{}) (map[string]interface{}, error) { cmdID := int(atomic.AddInt64(&cdpCmdCounter, 1)) msg := map[string]interface{}{ "id": cmdID, "method": method, "params": params, } b, _ := json.Marshal(msg) if err := sendWSFrame(conn, b); err != nil { return nil, err } for { frame, err := readWSFrame(conn, reader) if err != nil { return nil, err } var res map[string]interface{} if err := json.Unmarshal(frame, &res); err == nil { if idVal, ok := res["id"].(float64); ok && int(idVal) == cmdID { return res, nil } } } } type BrowserBridge struct { mu sync.Mutex cmd *exec.Cmd xvfbCmd *exec.Cmd tmpDir string port string conn net.Conn reader *bufio.Reader browserBin string userAgent string headless bool useXvfb bool socksProxy string targetURL string availableModels []string selectedModel string } func NewBrowserBridge(browserBin, userAgent string, headless, useXvfb bool, socksProxy, targetURL string) *BrowserBridge { if userAgent == "" { userAgent = DefaultUserAgent } if targetURL == "" { targetURL = DefaultTargetURL } return &BrowserBridge{ browserBin: browserBin, userAgent: userAgent, headless: headless, useXvfb: useXvfb, socksProxy: socksProxy, targetURL: targetURL, } } func (bb *BrowserBridge) Start() error { bb.mu.Lock() defer bb.mu.Unlock() if bb.conn != nil { return nil } binPath := findChromiumBinary(bb.browserBin) if binPath == "" { return fmt.Errorf("no chromium or google-chrome binary found on system") } var effectiveDisplay string if bb.useXvfb { xvfbPath, err := exec.LookPath("Xvfb") if err != nil { xvfbPath, err = exec.LookPath("Xfbdev") } if err != nil { log.Printf("warning: Xvfb not found on system, falling back to offscreen flags") } else { vDisplay := findFreeXDisplay() xCmd := exec.Command(xvfbPath, vDisplay, "-screen", "0", "1280x800x24", "-ac", "-nolisten", "tcp") if err := xCmd.Start(); err == nil { bb.xvfbCmd = xCmd effectiveDisplay = vDisplay time.Sleep(300 * time.Millisecond) log.Printf("Virtual X server started on display %s", vDisplay) } else { log.Printf("warning: failed to start virtual X server: %v", err) } } } if effectiveDisplay == "" { effectiveDisplay = os.Getenv("DISPLAY") } tmpDir, err := os.MkdirTemp("", "groqqer_bridge_*") if err != nil { return fmt.Errorf("failed to create temp profile dir: %w", err) } bb.tmpDir = tmpDir port, err := getFreePort() if err != nil { port = "9559" } bb.port = port args := []string{ "--remote-debugging-port=" + port, "--user-data-dir=" + tmpDir, "--disable-gpu", "--no-sandbox", "--no-first-run", "--no-default-browser-check", "--disable-extensions", "--disable-default-apps", "--disable-background-networking", "--disable-sync", "--disable-translate", "--mute-audio", "--hide-scrollbars", "--window-size=1280,800", "--user-agent=" + bb.userAgent, } if bb.xvfbCmd != nil { args = append(args, "--window-position=0,0") } else { args = append(args, "--window-position=-3000,-3000") } if bb.headless && bb.xvfbCmd == nil { args = append(args, "--headless=new") } if bb.socksProxy != "" { proxyArg := bb.socksProxy if !strings.HasPrefix(proxyArg, "socks5://") && !strings.HasPrefix(proxyArg, "socks5h://") { proxyArg = "socks5://" + proxyArg } args = append(args, "--proxy-server="+proxyArg) } args = append(args, bb.targetURL) cmd := exec.Command(binPath, args...) if effectiveDisplay != "" { cmd.Env = append(os.Environ(), "DISPLAY="+effectiveDisplay) } else { cmd.Env = os.Environ() } if err := cmd.Start(); err != nil { return fmt.Errorf("failed to launch chromium: %w", err) } bb.cmd = cmd // Connect to CDP target var pageWS string for attempt := 0; attempt < 25; attempt++ { time.Sleep(500 * time.Millisecond) resp, err := http.Get("http://127.0.0.1:" + port + "/json/list") if err != nil { continue } var targets []map[string]interface{} if err := json.NewDecoder(resp.Body).Decode(&targets); err == nil { resp.Body.Close() for _, t := range targets { if t["type"] == "page" { if ws, ok := t["webSocketDebuggerUrl"].(string); ok && ws != "" { pageWS = ws break } } } if pageWS != "" { break } } else { resp.Body.Close() } } if pageWS == "" { return fmt.Errorf("timed out waiting for chromium CDP page target") } conn, reader, err := dialCDPWebSocket(pageWS) if err != nil { return fmt.Errorf("failed to dial CDP websocket: %w", err) } bb.conn = conn bb.reader = reader log.Printf("Browser bridge connected to %s", bb.targetURL) return nil } func (bb *BrowserBridge) Evaluate(js string) (interface{}, error) { res, err := sendCDPCommand(bb.conn, bb.reader, "Runtime.evaluate", map[string]interface{}{ "expression": js, "returnByValue": true, "awaitPromise": true, }) if err != nil { return nil, err } if r, ok := res["result"].(map[string]interface{}); ok { if r2, ok := r["result"].(map[string]interface{}); ok { return r2["value"], nil } } return nil, nil } func (bb *BrowserBridge) WaitForReady(timeout time.Duration) error { deadline := time.Now().Add(timeout) for time.Now().Before(deadline) { val, err := bb.Evaluate(`(() => { const sb = document.querySelector('[data-testid="stSelectbox"]'); const ta = document.querySelector('textarea'); return sb && ta && !ta.disabled ? true : false; })()`) if err == nil && val == true { return nil } time.Sleep(300 * time.Millisecond) } return fmt.Errorf("timed out waiting for Streamlit chat interface to render") } func (bb *BrowserBridge) DiscoverModels() ([]string, error) { if err := bb.WaitForReady(20 * time.Second); err != nil { return nil, err } res, err := bb.Evaluate(`(() => { const listbox = document.querySelector('[role="listbox"]'); if (!listbox) { const btn = document.querySelector('[data-testid="stSelectbox"] button[aria-label="Open"]'); if (btn) btn.click(); } return new Promise((resolve) => { const start = Date.now(); const interval = setInterval(() => { const options = Array.from(document.querySelectorAll('[role="option"]')).map(el => el.innerText.trim()).filter(Boolean); if (options.length > 0 || Date.now() - start > 3000) { clearInterval(interval); const btn = document.querySelector('[data-testid="stSelectbox"] button[aria-label="Open"]') || document.body; btn.click(); resolve(options); } }, 50); }); })()`) if err != nil { return nil, err } var rawList []string if arr, ok := res.([]interface{}); ok { for _, item := range arr { if str, ok := item.(string); ok && str != "" { rawList = append(rawList, str) } } } var modelIDs []string for _, item := range rawList { cleanID := item if idx := strings.Index(item, " ("); idx != -1 { cleanID = strings.TrimSpace(item[:idx]) } if cleanID != "" { modelIDs = append(modelIDs, cleanID) } } curr, _ := bb.Evaluate(`(() => { const input = document.querySelector('[data-testid="stSelectbox"] input'); return input ? input.value : ''; })()`) if currStr, ok := curr.(string); ok && currStr != "" { cleanCurr := currStr if idx := strings.Index(currStr, " ("); idx != -1 { cleanCurr = strings.TrimSpace(currStr[:idx]) } bb.selectedModel = cleanCurr } if len(modelIDs) > 0 { bb.availableModels = modelIDs } return modelIDs, nil } func (bb *BrowserBridge) SwitchModel(modelID string) error { if modelID == "" { return nil } targetSubstr := strings.ToLower(strings.TrimSpace(modelID)) if strings.Contains(targetSubstr, "/") { parts := strings.Split(targetSubstr, "/") targetSubstr = parts[len(parts)-1] } targetJSON, _ := json.Marshal(targetSubstr) js := fmt.Sprintf(`(() => { const target = %s; const input = document.querySelector('[data-testid="stSelectbox"] input'); if (input && input.value.toLowerCase().includes(target)) { return Promise.resolve({ success: true, model: input.value }); } const listbox = document.querySelector('[role="listbox"]'); if (!listbox) { const btn = document.querySelector('[data-testid="stSelectbox"] button[aria-label="Open"]') || input; if (btn) btn.click(); } return new Promise((resolve) => { const start = Date.now(); const interval = setInterval(() => { const options = Array.from(document.querySelectorAll('[role="option"]')); if (options.length > 0) { const matched = options.find(o => o.innerText.toLowerCase().includes(target)); if (matched) { clearInterval(interval); const chosenText = matched.innerText; matched.click(); resolve({ success: true, model: chosenText }); return; } } if (Date.now() - start > 3000) { clearInterval(interval); const btn = document.querySelector('[data-testid="stSelectbox"] button[aria-label="Open"]') || document.body; btn.click(); resolve({ success: false, model: '', error: 'Option not found' }); } }, 50); }); })()`, string(targetJSON)) res, err := bb.Evaluate(js) if err != nil { return err } if rMap, ok := res.(map[string]interface{}); ok { if success, _ := rMap["success"].(bool); success { chosen, _ := rMap["model"].(string) cleanCurr := chosen if idx := strings.Index(chosen, " ("); idx != -1 { cleanCurr = strings.TrimSpace(chosen[:idx]) } bb.selectedModel = cleanCurr log.Printf("Successfully switched model to: %s", cleanCurr) time.Sleep(1 * time.Second) return nil } } log.Printf("Model %s not found in selectbox, keeping current model %s", modelID, bb.selectedModel) return nil } func (bb *BrowserBridge) ResetChat() error { res, err := bb.Evaluate(`(() => { const msgs = document.querySelectorAll('[data-testid="stChatMessage"]'); const retryBtn = Array.from(document.querySelectorAll('button')).find(b => b.innerText.includes('Continue without retrying')); const clearBtn = Array.from(document.querySelectorAll('button')).find(b => b.innerText.includes('Clear Chat')); const ta = document.querySelector('textarea'); if (msgs.length === 0 && !retryBtn && ta && !ta.disabled) { return 'clean'; } if (clearBtn) { clearBtn.click(); return 'cleared'; } if (retryBtn) { retryBtn.click(); return 'retried'; } return 'none'; })()`) if err != nil { return err } if res == "clean" { return nil } deadline := time.Now().Add(6 * time.Second) for time.Now().Before(deadline) { time.Sleep(100 * time.Millisecond) ready, _ := bb.Evaluate(`(() => { const msgs = document.querySelectorAll('[data-testid="stChatMessage"]'); const ta = document.querySelector('textarea[data-testid="stChatInputTextArea"]') || document.querySelector('textarea'); const retryBtn = Array.from(document.querySelectorAll('button')).find(b => b.innerText.includes('Continue without retrying')); if (retryBtn) { retryBtn.click(); return false; } return msgs.length === 0 && ta && !ta.disabled; })()`) if ready == true { return nil } } return nil } func (bb *BrowserBridge) SubmitPrompt(promptText string) error { promptJSON, err := json.Marshal(promptText) if err != nil { return err } // Ensure textarea is present and enabled deadline := time.Now().Add(10 * time.Second) for time.Now().Before(deadline) { val, _ := bb.Evaluate(`(() => { const ta = document.querySelector('textarea'); return ta && !ta.disabled; })()`) if val == true { break } time.Sleep(100 * time.Millisecond) } js := fmt.Sprintf(`(() => { const ta = document.querySelector('textarea[data-testid="stChatInputTextArea"]') || document.querySelector('textarea'); if (!ta) return 'no textarea'; ta.focus(); const nativeSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value').set; nativeSetter.call(ta, %s); ta.dispatchEvent(new Event('input', { bubbles: true })); ta.dispatchEvent(new Event('change', { bubbles: true })); const btn = document.querySelector('button[data-testid="stChatInputSubmitButton"]'); if (btn) { btn.removeAttribute('disabled'); btn.disabled = false; btn.click(); return 'clicked'; } ta.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); return 'enter'; })()`, string(promptJSON)) _, err = bb.Evaluate(js) if err != nil { return err } // Verify that new message is accepted by checking if count > 0 confirmDeadline := time.Now().Add(4 * time.Second) for time.Now().Before(confirmDeadline) { currCountVal, _ := bb.Evaluate(`document.querySelectorAll('[data-testid="stChatMessage"]').length`) if c, ok := currCountVal.(float64); ok && int(c) > 0 { return nil } time.Sleep(100 * time.Millisecond) } // Retry clicking if not registered yet bb.Evaluate(`(() => { const btn = document.querySelector('button[data-testid="stChatInputSubmitButton"]'); if (btn) btn.click(); const ta = document.querySelector('textarea'); if (ta) ta.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true })); })()`) return nil } func (bb *BrowserBridge) Close() { bb.mu.Lock() defer bb.mu.Unlock() if bb.conn != nil { bb.conn.Close() bb.conn = nil } if bb.cmd != nil && bb.cmd.Process != nil { _ = bb.cmd.Process.Kill() _ = bb.cmd.Wait() bb.cmd = nil } if bb.xvfbCmd != nil && bb.xvfbCmd.Process != nil { _ = bb.xvfbCmd.Process.Kill() _ = bb.xvfbCmd.Wait() bb.xvfbCmd = nil } if bb.tmpDir != "" { _ = os.RemoveAll(bb.tmpDir) bb.tmpDir = "" } } // --------------------------------------------------------------------------- // Gateway Controller & Request Orchestration // --------------------------------------------------------------------------- type GroqqerGateway struct { bridge *BrowserBridge models []ModelItem modelsMu sync.RWMutex defaultModel string port int } func DefaultFallbackModels() []string { return []string{ "openai/gpt-oss-20b", "openai/gpt-oss-120b", "qwen/qwen3.6-27b", "qwen/qwen3.8-27b", "groq/compound", "groq/compound-mini", "allam-2-7b", "llama-3.3-70b-versatile", "llama-3.1-8b-instant", "meta-llama/llama-4-scout-17b-16e-instruct", } } func (g *GroqqerGateway) RefreshModels() { discovered, err := g.bridge.DiscoverModels() if err != nil || len(discovered) == 0 { discovered = DefaultFallbackModels() } g.modelsMu.Lock() defer g.modelsMu.Unlock() now := time.Now().Unix() var items []ModelItem for _, id := range discovered { items = append(items, ModelItem{ ID: id, Object: "model", Created: now, OwnedBy: "groq", }) } g.models = items } func (g *GroqqerGateway) GetModels() []ModelItem { g.modelsMu.RLock() defer g.modelsMu.RUnlock() if len(g.models) == 0 { now := time.Now().Unix() var items []ModelItem for _, id := range DefaultFallbackModels() { items = append(items, ModelItem{ ID: id, Object: "model", Created: now, OwnedBy: "groq", }) } return items } out := make([]ModelItem, len(g.models)) copy(out, g.models) return out } func (g *GroqqerGateway) HandleModels(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type") if r.Method == "OPTIONS" { w.WriteHeader(http.StatusOK) return } models := g.GetModels() resp := ModelsResponse{ Object: "list", Data: models, } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(resp) } func (g *GroqqerGateway) HandleChatCompletions(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type") if r.Method == "OPTIONS" { w.WriteHeader(http.StatusOK) return } if r.Method != "POST" { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } var req ChatCompletionRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, "Invalid JSON payload", http.StatusBadRequest) return } if len(req.Messages) == 0 { http.Error(w, "messages array must not be empty", http.StatusBadRequest) return } requestedModel := req.Model if requestedModel == "" { requestedModel = g.defaultModel } promptText := FormatPrompt(req) completionID := "chatcmpl-" + GenerateUUID() created := time.Now().Unix() // Lock bridge for exclusive session execution g.bridge.mu.Lock() defer g.bridge.mu.Unlock() log.Printf("Handling completion: model=%s, stream=%v, messages=%d", requestedModel, req.Stream, len(req.Messages)) // 1. Switch model if needed if err := g.bridge.SwitchModel(requestedModel); err != nil { log.Printf("model switch warning: %v", err) } // 2. Ensure chat session is clean before submitting if err := g.bridge.ResetChat(); err != nil { log.Printf("reset chat warning: %v", err) } // 3. Submit the prompt if err := g.bridge.SubmitPrompt(promptText); err != nil { log.Printf("submit prompt error: %v", err) http.Error(w, "Failed to submit prompt to target space: "+err.Error(), http.StatusInternalServerError) return } effectiveModel := g.bridge.selectedModel if effectiveModel == "" { effectiveModel = requestedModel } targetMinCount := 2 // 4. Handle response: streaming or non-streaming if req.Stream { flusher, ok := w.(http.Flusher) if !ok { http.Error(w, "Streaming unsupported", http.StatusInternalServerError) return } streamer := NewStreamer(w, flusher, completionID, created, effectiveModel) streamer.Role() thinkingFilter := NewStreamThinkingFilter() toolFilter := NewStreamToolCallFilter() lastLen := 0 start := time.Now() finishReason := "stop" var fullCaptured strings.Builder evalJS := fmt.Sprintf(`(() => { const msgs = Array.from(document.querySelectorAll('[data-testid="stChatMessage"]')); if (msgs.length < %d) { const alertEl = document.querySelector('[data-testid="stAlert"], [data-testid="stNotification"]'); if (alertEl) { return { text: '', done: true, error: alertEl.innerText }; } return { text: '', done: false, error: '' }; } const lastMsg = msgs[msgs.length - 1]; const md = lastMsg.querySelector('[data-testid="stMarkdownContainer"]'); const text = md ? md.innerText : ''; const ta = document.querySelector('textarea'); const hasModelCaption = lastMsg.innerText.includes('Model:') || !!lastMsg.querySelector('[data-testid="stCaptionContainer"]'); const alertEl = lastMsg.querySelector('[data-testid="stAlert"], [data-testid="stNotification"]'); const errText = alertEl ? alertEl.innerText : ''; const isDone = ((!ta || !ta.disabled) && hasModelCaption) || (errText !== ''); return { text, done: isDone, error: errText }; })()`, targetMinCount) for time.Since(start) < 120*time.Second { time.Sleep(35 * time.Millisecond) res, err := g.bridge.Evaluate(evalJS) if err != nil { continue } if rMap, ok := res.(map[string]interface{}); ok { txt, _ := rMap["text"].(string) done, _ := rMap["done"].(bool) errTxt, _ := rMap["error"].(string) if errTxt != "" && strings.TrimSpace(txt) == "" { txt = errTxt } if len(txt) > lastLen { delta := txt[lastLen:] lastLen = len(txt) fullCaptured.WriteString(delta) thinkingFilter.Feed(delta, func(cleanContent string) { toolFilter.Feed(cleanContent, func(userText string) { streamer.Content(userText) }, func(tc ToolCall) { streamer.ToolCall(tc) }, ) }, func(reasoning string) { streamer.Reasoning(reasoning) }, ) } if done && (len(txt) > 0 || errTxt != "") { break } } } thinkingFilter.Flush( func(cleanContent string) { toolFilter.Feed(cleanContent, func(userText string) { streamer.Content(userText) }, func(tc ToolCall) { streamer.ToolCall(tc) }, ) }, func(reasoning string) { streamer.Reasoning(reasoning) }, ) toolFilter.Flush( func(userText string) { streamer.Content(userText) }, func(tc ToolCall) { streamer.ToolCall(tc) }, ) if toolFilter.emittedCall { finishReason = "tool_calls" } streamer.Finish(finishReason) log.Printf("Streaming completion finished for %s in %v", effectiveModel, time.Since(start)) return } // Non-streaming response start := time.Now() var fullText string evalJS := fmt.Sprintf(`(() => { const msgs = Array.from(document.querySelectorAll('[data-testid="stChatMessage"]')); if (msgs.length < %d) { const alertEl = document.querySelector('[data-testid="stAlert"], [data-testid="stNotification"]'); if (alertEl) { return { text: '', done: true, error: alertEl.innerText }; } return { text: '', done: false, error: '' }; } const lastMsg = msgs[msgs.length - 1]; const md = lastMsg.querySelector('[data-testid="stMarkdownContainer"]'); const text = md ? md.innerText : ''; const ta = document.querySelector('textarea'); const hasModelCaption = lastMsg.innerText.includes('Model:') || !!lastMsg.querySelector('[data-testid="stCaptionContainer"]'); const alertEl = lastMsg.querySelector('[data-testid="stAlert"], [data-testid="stNotification"]'); const errText = alertEl ? alertEl.innerText : ''; const isDone = ((!ta || !ta.disabled) && hasModelCaption) || (errText !== ''); return { text, done: isDone, error: errText }; })()`, targetMinCount) for time.Since(start) < 120*time.Second { time.Sleep(50 * time.Millisecond) res, err := g.bridge.Evaluate(evalJS) if err != nil { continue } if rMap, ok := res.(map[string]interface{}); ok { txt, _ := rMap["text"].(string) done, _ := rMap["done"].(bool) errTxt, _ := rMap["error"].(string) if errTxt != "" && strings.TrimSpace(txt) == "" { txt = errTxt } fullText = txt if done && (len(txt) > 0 || errTxt != "") { break } } } cleanContent, reasoningContent := ExtractThinking(fullText) toolCalls, remainingContent, hasTools := DetectToolCalls(cleanContent) finishReason := "stop" if hasTools { finishReason = "tool_calls" cleanContent = remainingContent } WriteCompletionResponse(w, completionID, created, effectiveModel, cleanContent, reasoningContent, toolCalls, finishReason) log.Printf("Completion finished for %s in %v", effectiveModel, time.Since(start)) } // --------------------------------------------------------------------------- // Main Entrypoint & Signal Handling // --------------------------------------------------------------------------- func main() { port := flag.Int("port", 8080, "HTTP server listening port") targetURL := flag.String("target", DefaultTargetURL, "Groq Streamlit space URL") defaultModel := flag.String("default-model", DefaultModel, "Default model ID if unspecified") browserBin := flag.String("browser", "", "Path to Chromium/Chrome binary") userAgent := flag.String("user-agent", DefaultUserAgent, "User-Agent string") flag.StringVar(userAgent, "ua", DefaultUserAgent, "User-Agent string (alias)") useXvfb := flag.Bool("xvfb", true, "Manage virtual X server (Xvfb) for display isolation") noXvfb := flag.Bool("no-xvfb", false, "Disable virtual X server") headless := flag.Bool("headless", true, "Run Chromium in headless mode") socksProxy := flag.String("socks", "", "SOCKS5 proxy (e.g. socks5://127.0.0.1:1080)") flag.StringVar(socksProxy, "proxy", "", "Proxy address alias") flag.StringVar(socksProxy, "socks5", "", "SOCKS5 proxy alias") flag.Parse() effectiveXvfb := *useXvfb if *noXvfb { effectiveXvfb = false } effectiveProxy := *socksProxy if effectiveProxy == "" { for _, envVar := range []string{"ALL_PROXY", "all_proxy", "SOCKS5_PROXY", "socks5_proxy", "SOCKS_PROXY", "socks_proxy"} { if val := os.Getenv(envVar); val != "" { effectiveProxy = val break } } } bridge := NewBrowserBridge(*browserBin, *userAgent, *headless, effectiveXvfb, effectiveProxy, *targetURL) log.Println("Starting groqqer browser bridge...") if err := bridge.Start(); err != nil { log.Fatalf("failed to start browser bridge: %v", err) } gateway := &GroqqerGateway{ bridge: bridge, defaultModel: *defaultModel, port: *port, } // Initial discovery of live models go func() { log.Println("Discovering available models from Streamlit UI...") gateway.RefreshModels() models := gateway.GetModels() log.Printf("Ready with %d active models. Default: %s", len(models), gateway.defaultModel) }() mux := http.NewServeMux() mux.HandleFunc("/v1/models", gateway.HandleModels) mux.HandleFunc("/models", gateway.HandleModels) mux.HandleFunc("/v1/chat/completions", gateway.HandleChatCompletions) mux.HandleFunc("/chat/completions", gateway.HandleChatCompletions) // Root status handler mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]interface{}{ "service": "groqqer", "status": "running", "target": *targetURL, "default": *defaultModel, "models": "/v1/models", "endpoints": []string{"/v1/chat/completions", "/v1/models"}, }) }) server := &http.Server{ Addr: fmt.Sprintf(":%d", *port), Handler: mux, } // Graceful shutdown handling sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) go func() { <-sigChan log.Println("Shutting down groqqer...") ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() _ = server.Shutdown(ctx) bridge.Close() os.Exit(0) }() log.Printf("groqqer gateway listening on http://127.0.0.1:%d", *port) if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("server error: %v", err) } }