chore: rename project and all references to qorona

This commit is contained in:
Luxferre
2026-08-27 14:08:50 +03:00
parent d68efdbf59
commit f60f7b0c49
6 changed files with 49 additions and 36 deletions
+4 -4
View File
@@ -1,8 +1,8 @@
all: q38max all: qorona
q38max: qorona:
mkdir -p bin mkdir -p bin
go build -trimpath -ldflags="-s -w" -o bin/q38max main.go go build -trimpath -ldflags="-s -w" -o bin/qorona main.go
test: test:
go test -v ./... go test -v ./...
@@ -10,4 +10,4 @@ test:
clean: clean:
rm -rf bin rm -rf bin
.PHONY: all q38max test clean .PHONY: all qorona test clean
+11 -10
View File
@@ -1,15 +1,16 @@
# q38max # qorona
Standalone, zero-dependency OpenAI-compatible proxy gateway in Go for the **Qwen 3.8 Max** model (`Qwen/Qwen3.8-Max`) hosted on Hugging Face Spaces (`harpreetsahota-qwen38-max-openlogo-demo.hf.space`). Standalone, zero-dependency OpenAI-compatible proxy gateway in Go for the **Qwen 3.8 Max** model (`Qwen/Qwen3.8-Max`) hosted on Hugging Face Spaces (`harpreetsahota-qwen38-max-openlogo-demo.hf.space`).
## Overview ## Overview
`q38max` reverse-engineers the FiftyOne plugin backend operator interface of the Hugging Face space and transforms it into a standard, production-ready OpenAI API endpoint (`/v1/chat/completions` and `/v1/models`). `qorona` reverse-engineers the FiftyOne plugin backend operator interface of the Hugging Face space and transforms it into a standard, production-ready OpenAI API endpoint (`/v1/chat/completions` and `/v1/models`).
### Features ### Features
- **OpenAI Standard Compatibility**: Full drop-in replacement for OpenAI API clients (Curl, Python `openai`, LangChain, LiteLLM, Open-WebUI). - **OpenAI Standard Compatibility**: Full drop-in replacement for OpenAI API clients (Curl, Python `openai`, LangChain, LiteLLM, Open-WebUI).
- **Zero External Dependencies**: Pure standard library Go implementation (`net/http`, `encoding/json`, `crypto/rand`, `time`). - **Zero External Dependencies**: Pure standard library Go implementation (`net/http`, `encoding/json`, `crypto/rand`, `time`).
- **Fully Headless & Browserless**: No Chromium, Playwright, or X11 required. Runs directly on bare servers, containers, or embedded systems.
- **Live Streaming SSE & Reasoning**: Streams real-time tokens with separation of reasoning content (`delta.reasoning_content`) and message content (`delta.content`). - **Live Streaming SSE & Reasoning**: Streams real-time tokens with separation of reasoning content (`delta.reasoning_content`) and message content (`delta.content`).
- **Function / Tool Calling Interception**: Supports OpenAI `tools` specification, system prompt tool schema injection, and stateful streaming interception of tool calls (`delta.tool_calls` and `finish_reason: "tool_calls"`). - **Function / Tool Calling Interception**: Supports OpenAI `tools` specification, system prompt tool schema injection, and stateful streaming interception of tool calls (`delta.tool_calls` and `finish_reason: "tool_calls"`).
- **Session Lifecycle Management**: Thread-safe automatic session creation (`/__session/start`), periodic background heartbeats (`/__session/heartbeat`), and auto-reconnect recovery. - **Session Lifecycle Management**: Thread-safe automatic session creation (`/__session/start`), periodic background heartbeats (`/__session/heartbeat`), and auto-reconnect recovery.
@@ -21,7 +22,7 @@ Standalone, zero-dependency OpenAI-compatible proxy gateway in Go for the **Qwen
``` ```
+---------------------------+ OpenAI HTTP / SSE +------------------------+ +---------------------------+ OpenAI HTTP / SSE +------------------------+
| Client (Python / Curl / | ===========================> | q38max Gateway | | Client (Python / Curl / | ===========================> | qorona Gateway |
| OpenAI SDK / Open-WebUI) | | (localhost:8080) | | OpenAI SDK / Open-WebUI) | | (localhost:8080) |
+---------------------------+ +------------------------+ +---------------------------+ +------------------------+
| |
@@ -48,14 +49,14 @@ Standalone, zero-dependency OpenAI-compatible proxy gateway in Go for the **Qwen
### Build ### Build
```bash ```bash
make q38max make qorona
``` ```
Binary is output to `bin/q38max`. Binary is output to `bin/qorona`.
### Run ### Run
```bash ```bash
./bin/q38max -port 8080 ./bin/qorona -port 8080
``` ```
### CLI Flags ### CLI Flags
@@ -84,7 +85,7 @@ curl http://localhost:8080/v1/models
curl -X POST http://localhost:8080/v1/chat/completions \ curl -X POST http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{ -d '{
"model": "qwen-3.8-max", "model": "qorona",
"messages": [ "messages": [
{"role": "user", "content": "What is the capital of Germany? Answer in 1 word."} {"role": "user", "content": "What is the capital of Germany? Answer in 1 word."}
], ],
@@ -98,7 +99,7 @@ curl -X POST http://localhost:8080/v1/chat/completions \
curl -N -X POST http://localhost:8080/v1/chat/completions \ curl -N -X POST http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{ -d '{
"model": "qwen-3.8-max", "model": "qorona",
"messages": [ "messages": [
{"role": "user", "content": "Calculate 25 * 25 and explain in one sentence."} {"role": "user", "content": "Calculate 25 * 25 and explain in one sentence."}
], ],
@@ -113,7 +114,7 @@ curl -N -X POST http://localhost:8080/v1/chat/completions \
curl -X POST http://localhost:8080/v1/chat/completions \ curl -X POST http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{ -d '{
"model": "qwen-3.8-max", "model": "qorona",
"messages": [ "messages": [
{"role": "user", "content": "What is the weather in Berlin?"} {"role": "user", "content": "What is the weather in Berlin?"}
], ],
@@ -147,7 +148,7 @@ client = OpenAI(
) )
response = client.chat.completions.create( response = client.chat.completions.create(
model="qwen-3.8-max", model="qorona",
messages=[ messages=[
{"role": "user", "content": "Write a short haiku about computers."} {"role": "user", "content": "Write a short haiku about computers."}
], ],
+1 -1
View File
@@ -1,3 +1,3 @@
module q38max module qorona
go 1.22 go 1.22
+25 -13
View File
@@ -1,4 +1,4 @@
// q38max: Standalone OpenAI-compatible gateway for Qwen 3.8 Max HuggingFace Spaces // qorona: Standalone OpenAI-compatible gateway for Qwen 3.8 Max HuggingFace Spaces
// Created by Luxferre in 2026, released into the public domain // Created by Luxferre in 2026, released into the public domain
package main package main
@@ -1086,7 +1086,7 @@ func PrepareConversation(req ChatCompletionRequest) (history []map[string]interf
// Main Gateway Service // Main Gateway Service
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type Q38Gateway struct { type QoronaGateway struct {
spaceURL string spaceURL string
samplePath string samplePath string
modelID string modelID string
@@ -1094,7 +1094,7 @@ type Q38Gateway struct {
sessionMgr *FiftyOneSessionManager sessionMgr *FiftyOneSessionManager
} }
func NewQ38Gateway(spaceURL string, samplePath string, modelID string, timeout time.Duration) *Q38Gateway { func NewQoronaGateway(spaceURL string, samplePath string, modelID string, timeout time.Duration) *QoronaGateway {
tr := &http.Transport{ tr := &http.Transport{
MaxIdleConns: 100, MaxIdleConns: 100,
MaxIdleConnsPerHost: 20, MaxIdleConnsPerHost: 20,
@@ -1104,7 +1104,7 @@ func NewQ38Gateway(spaceURL string, samplePath string, modelID string, timeout t
Transport: tr, Transport: tr,
Timeout: timeout, Timeout: timeout,
} }
return &Q38Gateway{ return &QoronaGateway{
spaceURL: strings.TrimRight(spaceURL, "/"), spaceURL: strings.TrimRight(spaceURL, "/"),
samplePath: samplePath, samplePath: samplePath,
modelID: modelID, modelID: modelID,
@@ -1113,7 +1113,7 @@ func NewQ38Gateway(spaceURL string, samplePath string, modelID string, timeout t
} }
} }
func (gw *Q38Gateway) HandleModels(w http.ResponseWriter, r *http.Request) { func (gw *QoronaGateway) HandleModels(w http.ResponseWriter, r *http.Request) {
EnableCORS(w) EnableCORS(w)
if r.Method == http.MethodOptions { if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)
@@ -1130,6 +1130,18 @@ func (gw *Q38Gateway) HandleModels(w http.ResponseWriter, r *http.Request) {
Created: now, Created: now,
OwnedBy: "qwen", OwnedBy: "qwen",
}, },
{
ID: "qorona",
Object: "model",
Created: now,
OwnedBy: "qwen",
},
{
ID: "qwen-3.8-max",
Object: "model",
Created: now,
OwnedBy: "qwen",
},
{ {
ID: "qwen3.8-max", ID: "qwen3.8-max",
Object: "model", Object: "model",
@@ -1155,7 +1167,7 @@ func (gw *Q38Gateway) HandleModels(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(resp) json.NewEncoder(w).Encode(resp)
} }
func (gw *Q38Gateway) HandleChatCompletions(w http.ResponseWriter, r *http.Request) { func (gw *QoronaGateway) HandleChatCompletions(w http.ResponseWriter, r *http.Request) {
EnableCORS(w) EnableCORS(w)
if r.Method == http.MethodOptions { if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)
@@ -1599,7 +1611,7 @@ func main() {
ConfiguredToken = *hfToken ConfiguredToken = *hfToken
} }
gw := NewQ38Gateway(*spaceURL, *samplePath, *modelID, time.Duration(*timeoutSec)*time.Second) gw := NewQoronaGateway(*spaceURL, *samplePath, *modelID, time.Duration(*timeoutSec)*time.Second)
mux := http.NewServeMux() mux := http.NewServeMux()
@@ -1613,28 +1625,28 @@ func main() {
mux.HandleFunc("/__health", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/__health", func(w http.ResponseWriter, r *http.Request) {
EnableCORS(w) EnableCORS(w)
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"status":"ok","gateway":"q38max"}`)) w.Write([]byte(`{"status":"ok","gateway":"qorona"}`))
}) })
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
EnableCORS(w) EnableCORS(w)
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"status":"ok","gateway":"q38max"}`)) w.Write([]byte(`{"status":"ok","gateway":"qorona"}`))
}) })
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
EnableCORS(w) EnableCORS(w)
if r.URL.Path == "/" { if r.URL.Path == "/" {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"service":"q38max","description":"OpenAI-compatible gateway for Qwen 3.8 Max","models_endpoint":"/v1/models","completions_endpoint":"/v1/chat/completions"}`)) w.Write([]byte(`{"service":"qorona","description":"OpenAI-compatible gateway for Qwen 3.8 Max","models_endpoint":"/v1/models","completions_endpoint":"/v1/chat/completions"}`))
return return
} }
http.NotFound(w, r) http.NotFound(w, r)
}) })
addr := fmt.Sprintf(":%d", *port) addr := fmt.Sprintf(":%d", *port)
log.Printf("[q38max] Listening on http://localhost%s (Upstream: %s)", addr, *spaceURL) log.Printf("[qorona] Listening on http://localhost%s (Upstream: %s)", addr, *spaceURL)
log.Printf("[q38max] OpenAI compatible endpoints: http://localhost%s/v1/chat/completions", addr) log.Printf("[qorona] OpenAI compatible endpoints: http://localhost%s/v1/chat/completions", addr)
if err := http.ListenAndServe(addr, mux); err != nil { if err := http.ListenAndServe(addr, mux); err != nil {
log.Fatalf("[q38max] Server failed: %v", err) log.Fatalf("[qorona] Server failed: %v", err)
} }
} }
+4 -4
View File
@@ -1,4 +1,4 @@
// Unit and integration tests for q38max // Unit and integration tests for qorona
// Created by Luxferre in 2026, released into the public domain // Created by Luxferre in 2026, released into the public domain
package main package main
@@ -86,7 +86,7 @@ func TestPrepareConversation(t *testing.T) {
} }
func TestModelsHandler(t *testing.T) { func TestModelsHandler(t *testing.T) {
gw := NewQ38Gateway("https://mock.hf.space", "/dummy/path.jpg", "qwen-3.8-max", 5*time.Second) gw := NewQoronaGateway("https://mock.hf.space", "/dummy/path.jpg", "qwen-3.8-max", 5*time.Second)
req := httptest.NewRequest("GET", "/v1/models", nil) req := httptest.NewRequest("GET", "/v1/models", nil)
w := httptest.NewRecorder() w := httptest.NewRecorder()
@@ -108,12 +108,12 @@ func TestModelsHandler(t *testing.T) {
found := false found := false
for _, m := range res.Data { for _, m := range res.Data {
if m.ID == "qwen-3.8-max" { if m.ID == "qorona" || m.ID == "qwen-3.8-max" {
found = true found = true
break break
} }
} }
if !found { if !found {
t.Fatalf("qwen-3.8-max not found in models list") t.Fatalf("model not found in models list")
} }
} }
+4 -4
View File
@@ -12,7 +12,7 @@ echo "=== 2. Testing Non-Streaming Chat Completion ==="
curl -s -X POST "${BASE_URL}/v1/chat/completions" \ curl -s -X POST "${BASE_URL}/v1/chat/completions" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{ -d '{
"model": "qwen-3.8-max", "model": "qorona",
"messages": [ "messages": [
{"role": "user", "content": "What is the capital of Italy? Answer in 1 word."} {"role": "user", "content": "What is the capital of Italy? Answer in 1 word."}
], ],
@@ -25,7 +25,7 @@ echo "=== 3. Testing Streaming SSE Completion (with reasoning) ==="
curl -N -s -X POST "${BASE_URL}/v1/chat/completions" \ curl -N -s -X POST "${BASE_URL}/v1/chat/completions" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{ -d '{
"model": "qwen-3.8-max", "model": "qorona",
"messages": [ "messages": [
{"role": "user", "content": "Calculate 25 * 25 and explain briefly in one sentence."} {"role": "user", "content": "Calculate 25 * 25 and explain briefly in one sentence."}
], ],
@@ -39,7 +39,7 @@ echo "=== 4. Testing Function/Tool Calling ==="
curl -s -X POST "${BASE_URL}/v1/chat/completions" \ curl -s -X POST "${BASE_URL}/v1/chat/completions" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{ -d '{
"model": "qwen-3.8-max", "model": "qorona",
"messages": [ "messages": [
{"role": "user", "content": "What is the weather in Berlin?"} {"role": "user", "content": "What is the weather in Berlin?"}
], ],
@@ -64,4 +64,4 @@ curl -s -X POST "${BASE_URL}/v1/chat/completions" \
}' | jq . }' | jq .
echo "" echo ""
echo "=== All integration tests finished successfully! ===" echo "=== All qorona integration tests finished successfully! ==="