Skip to main content
MossInference is the Python client for Moss Inference, a drop-in for OpenAI’s chat completions. Its chat.completions.create takes OpenAI’s arguments, searches your indexes in the cloud, adds what it finds to the prompt, and returns the reply with OpenAI’s field names.
Requires moss 1.21.0 or later, installed as in Install. The API is async only.

Create a client

The project id and key come from the Moss portal. Build one client and reuse it for every call. await client.close(), or the end of an async with client: block, closes its connections. With MOSS_PROJECT_ID and MOSS_PROJECT_KEY set, from moss import inference gives the same inference.chat.completions.create with no client to build.

Get a reply

completion.request_id is the response’s X-Moss-Request-Id, and so is stream.request_id on a stream. Include it when you report a problem. Both are None when the response has none.

Stream a reply

To stop early, break out of the loop: leaving the async with stream: block closes the connection, which stops the model. Only the last chunk carries usage, and it has no choices, which is why the loop checks chunk.choices.

Errors

A failed call raises moss.inference.InferenceError, from the async for loop once a stream has started. status is the HTTP status of a refused request, type names the failure, and message, also str(error), describes it. code is the error code Moss Inference sent, such as "rate_limit_exceeded", request_id is the response’s X-Moss-Request-Id, and retry_after is the wait in seconds that a Retry-After header asks for. A field the failure lacks is None. The SDK sets these types itself, with status None: Every other error reports what Moss Inference sent. See Errors, and Limits for a 429.

Tool calls

Pass OpenAI function tools in tools. When the reply calls tools, append its message to messages, then one tool message per call, and call again, as in Tool calls:
Here lookup_order is your own function, and it returns text. stream.get_final_completion() joins every chunk into the ChatCompletion that create returns without stream=True, and raises InferenceError with type incomplete_stream when the stream closed before its end. Append the message itself, not dataclasses.asdict(message), so each tool call goes back with every field the model sent.

MCP servers

An McpServer in tools names an MCP server whose tools Moss Inference runs for the model, so your code sends no tool messages for them:
Steps arrive in chunk.tool_step and completion.tool_steps, and MCP failures raise InferenceError with status, type, code and retry_after, as in MCP servers.

Options

MossInference(project_id, project_key, ...): chat.completions.create(...) takes keyword arguments only: