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

Unified pluggable interface for AI/LLM service integration. More...

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
Include dependency graph for ai.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  csilk_ai_stats_t
 AI Engine statistics. More...
 
struct  csilk_ai_message_t
 A single message in a chat conversation. More...
 
struct  csilk_ai_tool_function_t
 A function tool definition for the AI model. More...
 
struct  csilk_ai_tool_t
 A tool that can be called by the model. More...
 
struct  csilk_ai_tool_call_t
 a tool call requested by the model. More...
 
struct  csilk_ai_chat_request_t
 Request parameters for chat completion. More...
 
struct  csilk_ai_chat_response_t
 Response data from a chat completion. More...
 
struct  csilk_ai_embeddings_response_t
 Response data for embeddings. More...
 
struct  csilk_ai_driver_t
 Virtual function table implemented by each AI provider backend. More...
 
struct  csilk_ai_context_t
 Helper to manage conversation context and history. More...
 

Typedefs

typedef void(* csilk_ai_stream_cb) (const char *chunk, void *user_data)
 Callback for streaming mode.
 
typedef void(* csilk_ai_chat_async_cb) (int status, csilk_ai_chat_response_t *res, void *user_data)
 Callback for asynchronous chat completion.
 
typedef void(* csilk_ai_embeddings_async_cb) (int status, csilk_ai_embeddings_response_t *res, void *user_data)
 Callback for asynchronous embeddings.
 

Functions

void csilk_ai_get_stats (csilk_ai_stats_t *stats)
 Get current AI engine statistics.
 
char * csilk_ai_stats_to_json (const csilk_ai_stats_t *stats)
 Convert AI statistics to a JSON string.
 
void csilk_ai_register_monitor (void *c)
 Register a WebSocket monitor for real-time AI events.
 
csilk_ai_t * csilk_ai_new (const char *driver_name, const char *api_key, const char *base_url)
 Create a new AI instance with a specific driver.
 
int csilk_ai_chat (csilk_ai_t *ai, const csilk_ai_chat_request_t *req, csilk_ai_chat_response_t *res)
 Perform a chat completion.
 
void csilk_ai_chat_async (csilk_ai_t *ai, const csilk_ai_chat_request_t *req, csilk_ai_chat_async_cb cb, void *user_data)
 Perform an asynchronous chat completion.
 
int csilk_ai_embeddings (csilk_ai_t *ai, const char *model, const char **input, size_t count, csilk_ai_embeddings_response_t *res)
 Generate embeddings for the given input strings.
 
void csilk_ai_embeddings_async (csilk_ai_t *ai, const char *model, const char **input, size_t count, csilk_ai_embeddings_async_cb cb, void *user_data)
 Generate embeddings asynchronously.
 
void csilk_ai_free (csilk_ai_t *ai)
 Free an AI handle.
 
void csilk_ai_chat_response_free (csilk_ai_chat_response_t *res)
 Free a chat response structure.
 
void csilk_ai_embeddings_response_free (csilk_ai_embeddings_response_t *res)
 Free an embeddings response structure.
 
void csilk_ai_register_driver (const csilk_ai_driver_t *driver)
 Register a new AI driver.
 
csilk_ai_context_tcsilk_ai_context_new (size_t max_history)
 Initialize a new conversation context.
 
void csilk_ai_context_add (csilk_ai_context_t *ctx, const char *role, const char *content)
 Add a message to the context.
 
void csilk_ai_context_clear (csilk_ai_context_t *ctx)
 Clear all messages from the context.
 
void csilk_ai_context_free (csilk_ai_context_t *ctx)
 Free a conversation context.
 

Detailed Description

Unified pluggable interface for AI/LLM service integration.

Provides a provider-agnostic abstraction for chat completions, embeddings, streaming, and tool/function calling. Supports multiple backend drivers (OpenAI, Claude, Ollama, etc.) registered via csilk_ai_register_driver.

Architecture

The AI layer has three tiers:

  1. Driver — a csilk_ai_driver_t vtable implementing the actual HTTP/REST calls to a specific provider.
  2. Instance — created by csilk_ai_new(), wraps a driver + API config.
  3. Contextcsilk_ai_context_t manages conversation history with a sliding-window FIFO (for maintaining chat context across turns).

Thread Safety

The driver functions are synchronous by default. Asynchronous variants (csilk_ai_chat_async) offload work to libuv's thread pool and invoke the callback on the main event loop, making them safe for use from request handlers.


Data Structure Documentation

◆ csilk_ai_stats_t

struct csilk_ai_stats_t

AI Engine statistics.

Data Fields
uint64_t completion_tokens

Total completion tokens.

uint64_t duration_us_total

Cumulative duration in microseconds.

uint64_t errors_total

Total failed AI calls.

uint64_t prompt_tokens

Total prompt tokens.

uint64_t requests_total

Total chat/embeddings calls.

uint64_t tokens_total

Total tokens (prompt + completion).

◆ csilk_ai_message_t

struct csilk_ai_message_t

A single message in a chat conversation.

Data Fields
const char * content

Message text content.

const char * role

Message role (e.g., "system", "user", "assistant").

◆ csilk_ai_tool_function_t

struct csilk_ai_tool_function_t

A function tool definition for the AI model.

Data Fields
const char * description

Description of what the function does.

const char * name

Function name.

void * parameters_json

JSON Schema of parameters (cJSON*).

◆ csilk_ai_tool_t

struct csilk_ai_tool_t

A tool that can be called by the model.

Collaboration diagram for csilk_ai_tool_t:
Data Fields
csilk_ai_tool_function_t function
const char * type

Currently only "function" is supported.

◆ csilk_ai_tool_call_t

struct csilk_ai_tool_call_t

a tool call requested by the model.

Data Fields
char * arguments

JSON-formatted arguments string.

char * id

Unique call ID.

char * name

Function name to call.

◆ csilk_ai_chat_request_t

struct csilk_ai_chat_request_t

Request parameters for chat completion.

Collaboration diagram for csilk_ai_chat_request_t:
Data Fields
double frequency_penalty

Penalty for repetitive tokens (-2.0 to 2.0).

int max_tokens

Maximum tokens to generate.

size_t message_count

Number of messages in the array.

csilk_ai_message_t * messages

Array of conversation messages.

const char * model

Provider-specific model name (e.g., "gpt-4").

csilk_ai_stream_cb on_chunk

Callback invoked for each chunk in stream mode.

double presence_penalty

Penalty for new topics (-2.0 to 2.0).

const char ** stop

Array of stop sequences.

size_t stop_count

Number of stop sequences.

bool stream

Enable streaming mode.

double temperature

Sampling temperature (0.0 to 2.0).

int timeout_ms

Request timeout in milliseconds (0 for default).

const char * tool_choice

"none", "auto", or "required".

size_t tool_count

Number of tools.

csilk_ai_tool_t * tools

Available tools for the model.

double top_p

Nucleus sampling probability.

const char * user

Unique identifier for the end-user.

void * user_data

User context for the stream callback.

◆ csilk_ai_chat_response_t

struct csilk_ai_chat_response_t

Response data from a chat completion.

Collaboration diagram for csilk_ai_chat_response_t:
Data Fields
int completion_tokens

Tokens used in the generation.

char * content

Generated text content (heap-allocated).

char * error_message

Detailed error message if call failed (heap-allocated).

int prompt_tokens

Tokens used in the prompt.

char * raw_response

Full raw JSON response (optional, heap-allocated).

size_t tool_call_count

Number of tool calls.

csilk_ai_tool_call_t * tool_calls

Array of tool calls (heap-allocated).

int total_tokens

Total tokens used.

◆ csilk_ai_embeddings_response_t

struct csilk_ai_embeddings_response_t

Response data for embeddings.

Data Fields
size_t count

Number of vectors in the array.

size_t dimension

Dimension of a single vector.

char * error_message
int prompt_tokens
int total_tokens
float * values

Flattened array of vector values.

◆ csilk_ai_context_t

struct csilk_ai_context_t

Helper to manage conversation context and history.

Collaboration diagram for csilk_ai_context_t:
Data Fields
size_t capacity

Allocated capacity.

size_t count

Number of messages.

size_t max_history

Maximum messages to keep (0 for unlimited).

csilk_ai_message_t * messages

Array of history messages.

Typedef Documentation

◆ csilk_ai_chat_async_cb

typedef void(* csilk_ai_chat_async_cb) (int status, csilk_ai_chat_response_t *res, void *user_data)

Callback for asynchronous chat completion.

◆ csilk_ai_embeddings_async_cb

typedef void(* csilk_ai_embeddings_async_cb) (int status, csilk_ai_embeddings_response_t *res, void *user_data)

Callback for asynchronous embeddings.

◆ csilk_ai_stream_cb

typedef void(* csilk_ai_stream_cb) (const char *chunk, void *user_data)

Callback for streaming mode.

Parameters
chunkThe text content delta.
user_dataUser-provided context.

Function Documentation

◆ csilk_ai_chat()

int csilk_ai_chat ( csilk_ai_t *  ai,
const csilk_ai_chat_request_t req,
csilk_ai_chat_response_t res 
)

Perform a chat completion.

Parameters
aiAI handle.
reqChat request parameters.
res[out] Chat response to populate.
Returns
0 on success, -1 on failure.

Perform a chat completion.

Algorithm:

  1. Zero out the response struct for each attempt.
  2. Call the driver's chat() implementation.
  3. On success (status == 0), return immediately.
  4. On failure, check the error message for known transient error patterns (CURL transport errors, HTTP 429 rate limit, 502/503 server errors).
  5. If retryable and attempts remain, sleep with exponential backoff (1s, 2s) and retry. Non-retryable errors break immediately.
Parameters
aiAI engine handle (must not be NULL).
reqChat request parameters (model, messages, temperature, tools).
res[out] Receives the chat response, including content, tool calls, and token usage. Zeroed on each retry attempt.
Returns
0 on success, -1 if all retries are exhausted or parameters invalid.
Note
Not thread-safe. The caller must serialize access to the same csilk_ai_t handle.

◆ csilk_ai_chat_async()

void csilk_ai_chat_async ( csilk_ai_t *  ai,
const csilk_ai_chat_request_t req,
csilk_ai_chat_async_cb  cb,
void *  user_data 
)

Perform an asynchronous chat completion.

Note
Uses the framework's internal thread pool. The callback is invoked on the main loop.

Perform an asynchronous chat completion.

Allocates a work request and an async context on the heap, queues the work via uv_queue_work(), and returns immediately. The callback fires on the main loop thread after the driver's chat() completes. The response is valid only during the callback invocation.

Ownership: The caller retains ownership of req. The response res is owned by the async context and is freed after the callback returns. If the caller needs the response beyond the callback, it must deep-copy it.

Parameters
aiAI engine handle.
reqChat request (must remain valid until the callback fires).
cbCompletion callback (required).
user_dataOpaque pointer passed through to the callback.
Note
Thread-safe to call from any thread (libuv queues the work). On allocation failure, this is a silent no-op.

◆ csilk_ai_chat_response_free()

void csilk_ai_chat_response_free ( csilk_ai_chat_response_t res)

Free a chat response structure.

Free a chat response structure.

Parameters
resResponse struct to clean (may be NULL). Safe to call on a zero-initialized struct.

◆ csilk_ai_context_add()

void csilk_ai_context_add ( csilk_ai_context_t ctx,
const char *  role,
const char *  content 
)

Add a message to the context.

Note
Strings are duplicated internally.

Add a message to the context.

Algorithm:

  1. If the internal message array is full, double its capacity.
  2. If max_history > 0 and count >= max_history, remove the oldest message (free its role and content strings, shift remaining messages left via memmove, decrement count).
  3. strdup the role and content, append to the message array.
Parameters
ctxConversation context.
roleMessage role (e.g., "user", "assistant", "system").
contentMessage content text.
Note
The role and content strings are deep-copied internally.

◆ csilk_ai_context_clear()

void csilk_ai_context_clear ( csilk_ai_context_t ctx)

Clear all messages from the context.

Clear all messages from the context.

Parameters
ctxConversation context (may be NULL).

◆ csilk_ai_context_free()

void csilk_ai_context_free ( csilk_ai_context_t ctx)

Free a conversation context.

Free a conversation context.

Parameters
ctxContext to free (may be NULL).

◆ csilk_ai_context_new()

csilk_ai_context_t * csilk_ai_context_new ( size_t  max_history)

Initialize a new conversation context.

Parameters
max_historyMaximum number of messages to keep (FIFO sliding window).

Initialize a new conversation context.

Allocates a context struct that manages a rolling window of message history. When max_history messages are reached, the oldest message is evicted on each new add().

Parameters
max_historyMaximum number of messages to retain (0 = unlimited).
Returns
A new context handle, or NULL on allocation failure.
Note
The caller must free the handle with csilk_ai_context_free().

◆ csilk_ai_embeddings()

int csilk_ai_embeddings ( csilk_ai_t *  ai,
const char *  model,
const char **  input,
size_t  count,
csilk_ai_embeddings_response_t res 
)

Generate embeddings for the given input strings.

Parameters
aiAI handle.
modelModel name (e.g., "text-embedding-3-small").
inputArray of strings to embed.
countNumber of strings.
res[out] Embeddings response to populate.
Returns
0 on success, -1 on failure.

Generate embeddings for the given input strings.

Checks that the driver supports embeddings (optional operation), then delegates to the driver's embeddings() implementation.

Parameters
aiAI engine handle.
modelModel name (e.g., "text-embedding-3-small").
inputArray of input strings to embed.
countNumber of input strings.
res[out] Receives the embeddings values and error message.
Returns
0 on success, -1 if the driver lacks embeddings support or parameters are invalid.
Note
Not thread-safe on the same csilk_ai_t handle.

◆ csilk_ai_embeddings_async()

void csilk_ai_embeddings_async ( csilk_ai_t *  ai,
const char *  model,
const char **  input,
size_t  count,
csilk_ai_embeddings_async_cb  cb,
void *  user_data 
)

Generate embeddings asynchronously.

Generate embeddings asynchronously.

Allocates a work request and async context on the heap, queues via uv_queue_work(), and returns immediately. The callback fires on the main loop thread after completion.

Parameters
aiAI engine handle.
modelModel name.
inputArray of input strings (must remain valid until callback).
countNumber of input strings.
cbCompletion callback (required).
user_dataOpaque pointer passed through to callback.
Note
The response is valid only during the callback invocation. Thread-safe to call from any thread.

◆ csilk_ai_embeddings_response_free()

void csilk_ai_embeddings_response_free ( csilk_ai_embeddings_response_t res)

Free an embeddings response structure.

Free an embeddings response structure.

Parameters
resResponse struct to clean (may be NULL).

◆ csilk_ai_free()

void csilk_ai_free ( csilk_ai_t *  ai)

Free an AI handle.

Free an AI handle.

Parameters
aiThe handle to free (may be NULL).

◆ csilk_ai_get_stats()

void csilk_ai_get_stats ( csilk_ai_stats_t stats)

Get current AI engine statistics.

Parameters
stats[out] Pointer to stats struct to populate.

◆ csilk_ai_new()

csilk_ai_t * csilk_ai_new ( const char *  driver_name,
const char *  api_key,
const char *  base_url 
)

Create a new AI instance with a specific driver.

Parameters
driver_name"openai", "ollama", or other registered driver names.
api_keyAPI key for the provider (may be NULL for Ollama).
base_urlOptional custom base URL (pass NULL for provider default).
Returns
New AI handle, or NULL if driver not found or init failed.

Create a new AI instance with a specific driver.

On the very first call, lazy-initializes the built-in driver registry (OpenAI and Ollama). Subsequent calls reuse the already-registered drivers. If the named driver is not found or its init() fails, returns NULL.

Parameters
driver_nameBackend name (e.g., "openai", "ollama").
api_keyAPI key for authentication (e.g., OpenAI API key).
base_urlOptional custom base URL (NULL for driver default).
Returns
Newly allocated csilk_ai_t, or NULL on failure.
Note
The caller owns the returned handle and must free with csilk_ai_free(). On allocation failure, the driver state is freed internally to avoid leaks.

◆ csilk_ai_register_driver()

void csilk_ai_register_driver ( const csilk_ai_driver_t driver)

Register a new AI driver.

Note
Not thread-safe during registration. Call at startup.

Register a new AI driver.

Parameters
driverDriver vtable with name, init, chat, embeddings, free.

◆ csilk_ai_register_monitor()

void csilk_ai_register_monitor ( void *  c)

Register a WebSocket monitor for real-time AI events.

Parameters
cFramework context (WebSocket connection).

◆ csilk_ai_stats_to_json()

char * csilk_ai_stats_to_json ( const csilk_ai_stats_t stats)

Convert AI statistics to a JSON string.

Parameters
statsPointer to stats struct.
Returns
Heap-allocated JSON string (must be freed).