MossInference is the C client for Moss Inference. moss_inference_responses_create takes an OpenAI Responses request as JSON, searches your indexes, and returns OpenAI’s JSON.
Install
MossInference needs libmoss 0.29.0 or later. Set TARGET for your platform. The tarball holds the header, include/libmoss.h. A libmoss.h with these functions defines MOSS_INFERENCE_API_VERSION 3. For the other platforms and how to link the library, see Install.
Create a client
moss_inference_free once no call on it is running.
The examples below use this client.
Get a response
NULL for the callback, out_json gets the response as the JSON of one OpenAI Response. Free it with moss_free_string.
The text is in the output_text parts of the message items of output.
The response’s request_id is its X-Moss-Request-Id. Include it when you report a problem. It is left out when the response has none.
Moss stores no response, so input holds the whole conversation. Pass a string, or a list of items such as {"role": "user", "content": "Hi"} and the output items of earlier responses. See Conversations.
Stream a response
response.output_text.delta. That event carries the new text in delta. The stream ends after one of two events:
response.completed, when the response is done.response.incomplete, whenmax_output_tokensor a content filter cut the response short.
out_json too. It then gets the response of the last event.
To stop early, return a value other than 0 from the callback. The call then closes the connection, which stops the model, and returns OK.
Streaming lists every event.
Ground it in your indexes
faq index and adds what it finds to the prompt. The Quickstart creates that index.
Without indexes, Moss does not search and the model answers from input alone. You can name at most 32.
"retrieve": false skips the search on a call that names indexes.
Ground answers in your indexes covers the options and the cost.
Use a vendor model
Name a model from OpenAI, Anthropic or Google inmodel. The search of your indexes works the same for every model. Models lists them all.
On the Moss key
code "model_not_enabled" in moss_last_error_detail(). Send moss/fastlane-1 or use your own key.
With your own key
Pass your OpenAI, Anthropic or Google key to a client asapi_key in options_json:
X-Moss-Provider-Key header, never in the body. To use a key for one call only, put api_key in call_options_json.
The response’s model is the name you sent. Bring your own key covers model names and billing.
Tool calls
Pass OpenAI function tools intools of the request JSON. A function tool is flat, as in OpenAI’s Responses API. Your code runs the tools.
function_call item of output, with its call_id, name and arguments.
Put the output items back into input as they are. Add one item per call, such as {"type": "function_call_output", "call_id": "...", "output": "Shipped on Oct 20."}. Call again with the same tools until the response has no calls.
Each item keeps every field the model sent, such as the thought signature Gemini needs in the next turn.
Tool calling covers tool_choice, parallel_tool_calls and structured output.
MCP servers
Atools entry of type "mcp" names an MCP server. Moss Inference runs its tools for the model within the same call, so your code sends no function_call_output items for them.
print_event is the callback from Stream a response.
Each call comes as an mcp_call item. It arrives in a response.output_item.added event when it starts, and in response.output_item.done when it ends. The same items are in the response’s output.
Send the items back in input with the rest of output. The model then sees the earlier tool results.
MCP failures return a negative MossResult, with status, type, code and retry_after_ms in moss_last_error_detail(). A call that fails after a tool ran has code "failed_after_tool_call". The tool may already have changed data, so Moss Inference does not retry the call. Never replay a request that failed with failed_after_tool_call.
MCP servers covers the server fields and every MCP error.
Errors
A failed call returns a negativeMossResult. A streaming call returns it after the events the callback already got. A response.failed event fails the call too.
Right after the failed call, on the same thread, moss_last_error() holds the message. moss_last_error_detail() holds a JSON object with these fields:
A field the failure lacks is
null.
The SDK sets these types itself:
Every other error carries what Moss Inference sent. The call returns:
ERR_UNAUTHORIZEDforauthentication_errorandpermission_error.ERR_INVALID_ARGforinvalid_request_error.ERR_CLOUDfor the rest.
429, see Limits.
Options
options_json of moss_inference_new:
request_json of moss_inference_responses_create:
call_options_json of moss_inference_responses_create, which may be NULL:
Memory and the event callback
- The callback runs on the thread that made the call, once per event. It never runs after the call returns.
libmossnever reads or freesuser_data.- The next event is read only after the callback returns. A slow callback holds up the stream, and its time counts toward
timeout_ms.