Csilk 0.2.1
A lightweight, high-performance C HTTP web framework
Loading...
Searching...
No Matches
ai_openai.c File Reference

OpenAI-compatible driver for the AI unified interface. More...

#include "csilk/drivers/ai.h"
#include <curl/curl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cJSON.h"
Include dependency graph for ai_openai.c:

Data Structures

struct  openai_state_t
 Per-instance state for the OpenAI-compatible driver. More...
 
struct  curl_response
 Accumulates a complete HTTP response body in memory. More...
 
struct  curl_context
 Per-request context passed to the streaming write callback. Holds both the request (for on_chunk callback) and response (to accumulate final content), plus a line-buffer for SSE frame reassembly. More...
 

Functions

static void * openai_init (const char *api_key, const char *base_url)
 Initialize the OpenAI driver state.
 
static void openai_free (void *state_ptr)
 Free the OpenAI driver state and associated resources.
 
static size_t write_cb_simple (void *contents, size_t size, size_t nmemb, void *userp)
 libcurl write callback for simple (non-streaming) response accumulation. Appends data to a growing buffer.
 
static void process_stream_line (struct curl_context *ctx, const char *line)
 Process a single SSE line from the streaming response.
 
static size_t write_cb (void *contents, size_t size, size_t nmemb, void *userp)
 libcurl write callback that handles both streaming and non-streaming responses.
 
static int openai_chat (void *state_ptr, const csilk_ai_chat_request_t *req, csilk_ai_chat_response_t *res)
 Execute a chat completion against the OpenAI /chat/completions endpoint.
 
static int openai_embeddings (void *state_ptr, const char *model, const char **input, size_t count, csilk_ai_embeddings_response_t *res)
 Generate embeddings for a batch of input strings.
 
void csilk_ai_openai_init_driver (void)
 Register the OpenAI driver with the AI subsystem. Called during startup to make "openai" available to csilk_ai_new().
 

Variables

static const csilk_ai_driver_t openai_driver
 Driver vtable for the OpenAI-compatible AI backend.
 

Detailed Description

OpenAI-compatible driver for the AI unified interface.

Implements the csilk_ai_driver_t vtable for the OpenAI Chat Completions and Embeddings APIs. Also compatible with any OpenAI-API-proxy (Azure, Together, local推理 servers) since it only relies on the standard endpoint shapes:

  • POST /chat/completions (with optional SSE streaming)
  • POST /embeddings

Key design points:

  • Streaming uses libcurl's write callback to parse SSE "data: " lines.
  • Tool / function calling is fully supported.
  • Token usage is read from the "usage" object in non-streaming responses.

Data Structure Documentation

◆ openai_state_t

struct openai_state_t

Per-instance state for the OpenAI-compatible driver.

Data Fields
char * api_key

Bearer token sent as Authorization header.

char * base_url

API root (e.g., https://api.openai.com/v1).

◆ curl_response

struct curl_response

Accumulates a complete HTTP response body in memory.

Accumulates a complete HTTP response body (used for embeddings).

Data Fields
char * body

Heap-allocated body buffer (grown on each write callback).

Heap-allocated body buffer.

size_t size

Current length of data in body (excluding NUL terminator).

Current length of data in body.

◆ curl_context

struct curl_context

Per-request context passed to the streaming write callback. Holds both the request (for on_chunk callback) and response (to accumulate final content), plus a line-buffer for SSE frame reassembly.

Collaboration diagram for curl_context:
Data Fields
char * body

Accumulated response body (non-streaming path).

char * line_buf

Partial SSE line buffer (streaming path).

size_t line_size

Current length of buffered SSE data.

const csilk_ai_chat_request_t * req
csilk_ai_chat_response_t * res
size_t size

Current length of accumulated body.

Function Documentation

◆ csilk_ai_openai_init_driver()

void csilk_ai_openai_init_driver ( void  )

Register the OpenAI driver with the AI subsystem. Called during startup to make "openai" available to csilk_ai_new().

◆ openai_chat()

static int openai_chat ( void *  state_ptr,
const csilk_ai_chat_request_t req,
csilk_ai_chat_response_t res 
)
static

Execute a chat completion against the OpenAI /chat/completions endpoint.

Flow:

  1. Serialise the request into JSON (messages, sampling params, tools, stop sequences, stream flag).
  2. POST to <base_url>/chat/completions with Bearer auth header.
  3. On transport or HTTP error, populate res->error_message and return -1. 4a. Streaming path: content is accumulated incrementally in write_cb / process_stream_line; here we just check whether content was captured. 4b. Non-streaming path: parse the full JSON response, extracting content, tool_calls (id, name, arguments), and usage statistics.

Tool calls are extracted from "message"."tool_calls" in the first choice.

◆ openai_embeddings()

static int openai_embeddings ( void *  state_ptr,
const char *  model,
const char **  input,
size_t  count,
csilk_ai_embeddings_response_t res 
)
static

Generate embeddings for a batch of input strings.

Flow:

  1. Build a JSON body with the model name and "input" array.
  2. POST to <base_url>/embeddings with Bearer auth.
  3. Parse the "data" array – each entry contains an "embedding" vector. Vectors are flattened into a single float[] in input order.
  4. Extract usage statistics if present.
Note
The response dimension is inferred from the first embedding vector. All vectors in a batch must have the same dimension.

◆ openai_free()

static void openai_free ( void *  state_ptr)
static

Free the OpenAI driver state and associated resources.

◆ openai_init()

static void * openai_init ( const char *  api_key,
const char *  base_url 
)
static

Initialize the OpenAI driver state.

Note
api_key is required (returns NULL if absent). Allocates state and performs one-shot libcurl global init.

◆ process_stream_line()

static void process_stream_line ( struct curl_context ctx,
const char *  line 
)
static

Process a single SSE line from the streaming response.

Expects the standard OpenAI SSE format: data: {"choices":[{"delta":{"content":"text"}}]} The special "[DONE]" token signals stream completion.

For each delta chunk, the function:

  1. Appends the content to the accumulated response.
  2. Calls the user's on_chunk callback for real-time consumption.

◆ write_cb()

static size_t write_cb ( void *  contents,
size_t  size,
size_t  nmemb,
void *  userp 
)
static

libcurl write callback that handles both streaming and non-streaming responses.

Non-streaming path: Appends raw bytes to ctx->body (same as write_cb_simple).

Streaming path (SSE): Appends bytes to a line reassembly buffer (ctx->line_buf), then extracts complete lines delimited by '
'. Each complete line is forwarded to process_stream_line(). A trailing partial line is preserved in the buffer for the next callback invocation.

Returns
Number of bytes consumed, or 0 to abort on OOM.

◆ write_cb_simple()

static size_t write_cb_simple ( void *  contents,
size_t  size,
size_t  nmemb,
void *  userp 
)
static

libcurl write callback for simple (non-streaming) response accumulation. Appends data to a growing buffer.

Returns
Number of bytes consumed, or 0 to abort on OOM.

Variable Documentation

◆ openai_driver

const csilk_ai_driver_t openai_driver
static
Initial value:
= {
.name = "openai",
.init = openai_init,
.chat = openai_chat,
.embeddings = openai_embeddings,
.free = openai_free,
}
static void * openai_init(const char *api_key, const char *base_url)
Initialize the OpenAI driver state.
Definition ai_openai.c:40
static int openai_embeddings(void *state_ptr, const char *model, const char **input, size_t count, csilk_ai_embeddings_response_t *res)
Generate embeddings for a batch of input strings.
Definition ai_openai.c:474
static int openai_chat(void *state_ptr, const csilk_ai_chat_request_t *req, csilk_ai_chat_response_t *res)
Execute a chat completion against the OpenAI /chat/completions endpoint.
Definition ai_openai.c:257
static void openai_free(void *state_ptr)
Free the OpenAI driver state and associated resources.
Definition ai_openai.c:67

Driver vtable for the OpenAI-compatible AI backend.