#ifndef HYGATE_H #define HYGATE_H #include #include #include #define DEFAULT_UA "Mozilla/5.0 (X11; Linux x86_64; rv:153.0) Gecko/20100101 Firefox/153.0" #define DEFAULT_PORT "8080" #define DEFAULT_ENDPOINT "https://tencent-hy3.hf.space" #define DEFAULT_MODEL "hy3" #define MAX_RETRIES 5 #define UPSTREAM_TIMEOUT 300L #define MAX_CONCURRENT_THREADS 16 #define MAX_BODY_BYTES (5u * 1024u * 1024u) /* 5 MiB request body cap */ /* ------------------------------------------------------------------ */ /* Dynamic string buffer (always NUL terminated) */ /* ------------------------------------------------------------------ */ typedef struct { char *buf; size_t len; size_t cap; } strbuf; void sb_init(strbuf *s); void sb_free(strbuf *s); int sb_append(strbuf *s, const char *data, size_t n); int sb_append_str(strbuf *s, const char *str); void sb_reset(strbuf *s); /* ------------------------------------------------------------------ */ /* Small utilities */ /* ------------------------------------------------------------------ */ void generate_uuid(char out[37]); long fib_delay(int attempt); int write_all(int fd, const char *buf, size_t n); int iequals(const char *a, const char *b); /* ------------------------------------------------------------------ */ /* Tool call representation (parsed from Gradio stream) */ /* ------------------------------------------------------------------ */ typedef struct { char *id; char *type; char *name; char *arguments; } tool_call_t; void free_toolcalls(tool_call_t *tc, int n); /* Parse a single Gradio SSE data payload: [["content","reasoning",[...]]] * Returns 1 on success (caller frees *out_content, *out_reasoning, * *out_tc via free_toolcalls). */ int parse_gradio_stream(const char *data_json, char **out_content, char **out_reasoning, tool_call_t **out_tc, int *out_n_tc); /* ------------------------------------------------------------------ */ /* JSON request <-> Gradio payload translation */ /* ------------------------------------------------------------------ */ /* Build the Gradio call payload {"data":[...]} from an OpenAI chat * completion request object. Caller frees the result. Returns NULL on * malformed input. */ char *build_gradio_payload(void *req_obj, const char *model_default); /* Build a non-streaming OpenAI completion response JSON string. Caller * frees the result. */ char *build_completion_response(const char *id, long created, const char *model, const char *content, const char *reasoning, tool_call_t *tc, int n_tc, int prompt_tokens); /* Token counting (embedded cl100k_base BPE tokenizer). Counts are * deterministic subword counts; the served model (Hunyuan) uses a * different tokenizer, so these are an approximation, not exact. */ int tok_count(const char *text, int len); int tok_count_str(const char *text); /* Count tokens across an OpenAI request's messages (prompt side). */ int count_messages_tokens(void *req_obj); /* Count tokens of a generated completion (content + reasoning + tool calls). */ int count_completion_tokens(const char *content, const char *reasoning, tool_call_t *tc, int n_tc); /* Build a streaming tool-call delta JSON array (first emission: full * tool call with index). Caller frees the result. */ char *toolcall_delta_json(tool_call_t *tc, int idx); /* Build a streaming tool-call argument-delta JSON array (index + * function.arguments only). Caller frees the result. */ char *toolcall_delta_argdelta(int idx, const char *delta); /* ------------------------------------------------------------------ */ /* Server / request handling */ /* ------------------------------------------------------------------ */ typedef struct { const char *port; const char *endpoint; const char *model; const char *user_agent; /* empty string => use DEFAULT_UA */ long max_body_bytes; int max_connections; } config_t; typedef struct { char method[16]; char path[4096]; char content_type[256]; long content_length; char ua_override[1024]; bool has_x_ua; char *body; size_t body_len; } http_req_t; void http_req_free(http_req_t *r); /* Read the full HTTP request header block from fd into buf. Returns 0 * on success, -1 on error/timeout. */ int read_headers(int fd, strbuf *buf); /* Parse a buffered HTTP request. Returns 0 on success. */ int parse_http_request(strbuf *buf, int fd, http_req_t *req, long max_body_bytes); /* Handle one accepted client connection (reads request, routes, * writes response). */ void handle_connection(int fd, const config_t *cfg); #endif /* HYGATE_H */