hygate-c
A small, dependency-light C port of the Hygate gateway that exposes a
Gradio-hosted Hunyuan model (hy3) behind an OpenAI-compatible REST API.
It translates OpenAI chat/completions requests into Gradio's queue API
(POST /gradio_api/call/chat → GET /gradio_api/call/chat/{event_id} SSE
stream) and translates the Gradio stream back into OpenAI streaming and
non-streaming responses, including tool calls and reasoning content.
Build
Requires libcurl and json-c (auto-detected via pkg-config); falls back
to -lcurl -ljson-c if pkg-config is unavailable.
make # dynamic binary -> bin/hygate
make static # static binary -> bin/hygate.static
make clean
Build is POSIX-portable (Linux, FreeBSD, macOS) and compiles clean with
-Wall -Wextra.
Run
./bin/hygate [options]
Options
| Flag | Default | Description |
|---|---|---|
-port <n> |
8080 |
Listen port (binds 0.0.0.0). |
-endpoint <url> |
https://tencent-hy3.hf.space |
Upstream Gradio Space base URL (trailing slash trimmed). |
-model <name> |
hy3 |
Model name reported in /v1/models and responses. |
-user-agent <ua> / -ua <ua> |
built-in Firefox UA | Outgoing User-Agent. Empty string => default. |
-max-body <bytes> |
5242880 (5 MiB) |
Maximum request body size. Oversized requests are rejected with 413. |
-max-conn <n> |
16 |
Maximum concurrent connections (worker threads). Excess connections queue in the kernel listen backlog. |
Flag forms: -key value or -key=value.
Example — listen on 9090, allow 8 MiB bodies, cap at 32 concurrent connections:
./bin/hygate -port 9090 -max-body 8388608 -max-conn 32
Endpoints
| Method | Path | Notes |
|---|---|---|
GET |
/v1/models, /models |
Returns the configured model (served locally, no upstream call). |
POST |
/v1/chat/completions, /chat/completions |
OpenAI-style chat completion. Supports stream, tools/tool_calls, and reasoning_content. |
OPTIONS |
any of the above | CORS preflight. |
CORS is enabled for all origins (Access-Control-Allow-Origin: *).
Request / response notes
- OpenAI
messagesare mapped into Gradio's[message, system, history, "high", temperature, max_tokens, top_p, null, functions_json]payload. max_tokens/max_completion_tokensare honored; defaults to131072when omitted.- Upstream calls use Fibonacci-backoff retries (up to
MAX_RETRIES = 5, 300 s timeout).
Token usage counting
Responses include an OpenAI-style usage object with prompt_tokens,
completion_tokens, total_tokens, and completion_tokens_details
(reasoning_tokens). These are computed locally by an embedded cl100k_base
BPE tokenizer (vocabulary data in tokenizer_data.c, logic in tokenizer.c)
— no upstream token counts are available from the Gradio backend.
prompt_tokenssums the activesystemprompt, each message'scontent(or individual multi-part content parts),reasoning_content,tool_calls/function_call(nameandarguments),toolresult wrappers, and any requesttoolsfunction definitions (name,description,parameters).completion_tokenssums the assistantcontent,reasoning_content, and any emittedtool_calls(nameandarguments), withreasoning_tokensbroken out undercompletion_tokens_details.total_tokens = prompt_tokens + completion_tokens.
cl100k_base is OpenAI's canonical multilingual tokenizer and is used as the
best available approximation for Hunyuan; the resulting counts are
deterministic subword counts and may differ slightly from the exact Hunyuan
vocabulary. No per-message formatting overhead (the +3/priming tokens
OpenAI applies) is added.
Security considerations
- The server binds all interfaces (
0.0.0.0) and currently enforces no authentication — it is an open relay to the configured upstream. Do not expose it to untrusted networks without a fronting proxy or auth layer. -max-bodyand-max-connexist to bound resource usage (memory and thread count) against abusive clients.
Source layout
| File | Role |
|---|---|
main.c |
Entry point, flag parsing, TCP listen, thread-per-connection with concurrency cap. |
server.c |
HTTP parsing, routing, SSE emitters, libcurl upstream calls, streaming state machine. |
jsonapi.c |
OpenAI <-> Gradio payload translation and stream parsing. |
util.c |
Growable string buffer (strbuf), UUID, backoff, helpers. |
hygate.h |
Shared types and declarations. |
Credits
Created by Luxferre in 2026, released into the public domain with no warranties.