90 lines
3.4 KiB
Markdown
90 lines
3.4 KiB
Markdown
# 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.
|
|
|
|
```sh
|
|
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
|
|
|
|
```sh
|
|
./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:
|
|
|
|
```sh
|
|
./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 `messages` are mapped into Gradio's `[message, system, history,
|
|
"high", temperature, max_tokens, top_p, null, functions_json]` payload.
|
|
- `max_tokens` / `max_completion_tokens` are honored; defaults to `131072`
|
|
when omitted.
|
|
- Upstream calls use Fibonacci-backoff retries (up to `MAX_RETRIES = 5`,
|
|
300 s timeout).
|
|
|
|
## 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-body` and `-max-conn` exist 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.
|