Skip to main content
MossInference is the Kotlin client for Moss Inference on Android. It searches your indexes and answers in the shape of OpenAI’s Responses API, with camelCase fields. responses.create returns the whole response, and createStreaming streams its events.

Install

Then add the AAR in app/build.gradle.kts:
MossInference needs the moss-android AAR 0.29.0 or later. For the rest of the SDK setup, see Install.

Create a client

projectId and projectKey are your project id and key. Copy them from the Moss portal. Build one client and reuse it for every call, from any thread. Calls and stream reads block. On the main thread they throw MossException, so run them from Dispatchers.IO. The examples below use this inference client inside a coroutine.

Get a response

response.outputText joins the text of the response’s messages. response.output holds its items: OutputItem.Message, FunctionCall, McpCall, or Other for any other type. Each item has its JSON in raw. response.requestId is the response’s X-Moss-Request-Id. A stream has the same stream.requestId. Include it when you report a problem. Both are null when the response has none. Moss stores no response, so input holds the whole conversation. Build messages with InputItem.user, system, developer and assistant. Add the output items of earlier responses with InputItem.of(item). See Conversations.

Stream a response

Each ResponseStreamEvent has OpenAI’s type, such as response.output_text.delta, and the fields of that type. The stream ends after one of two events:
  • response.completed, whose event.response is the whole response.
  • response.incomplete, when maxOutputTokens or a content filter cut the response short.
To stop early, leave use with a break or return. That closes the connection, which stops the model. Cancelling the coroutine alone does not. So the loop calls ensureActive(), whose throw leaves use the same way. Streaming lists every event.

Ground it in your indexes

Moss searches the 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 in model. The search of your indexes works the same for every model. Models lists them all.

On the Moss key

Without your own key, a listed vendor model runs on the Moss key and bills your credits. Routes shows who bills each call. A listed model that is not served right now throws InferenceError with code "model_not_enabled". Send moss/fastlane-1 or use your own key.

With your own key

Pass your OpenAI, Anthropic or Google key to a client as apiKey:
openaiKey is your OpenAI key. It goes in the X-Moss-Provider-Key header, never in the body. To use a key for one call only, pass apiKey to responses.create or createStreaming. Bring your own key covers model names and billing.

Tool calls

Pass tools as the flat function tools of OpenAI’s Responses API. Each call the model makes comes as an OutputItem.FunctionCall item of output. Append every output item with InputItem.of(item), which sends it back unchanged. Add one InputItem.functionCallOutput(callId, output) per call, and call again until the response has no calls:
lookupOrder stands for your own code. It takes the call’s JSON arguments and returns the result as text. InputItem.of(item) keeps every field the model sent, such as the signature Gemini needs back in the next turn. Tool calling covers toolChoice, parallelToolCalls and structured output.

MCP servers

A Tool.mcp entry in tools names an MCP server. Moss Inference runs its tools for the model during the same call, so your code sends no functionCallOutput for them.
crmToken is your CRM token. McpServer also takes allowedTools and transport, which is McpServer.Transport.STREAMABLE_HTTP or SSE. Each call comes as an OutputItem.McpCall. It arrives in response.output_item.added when it starts, and in response.output_item.done when it ends. The same items are in the response’s output. An McpCall has the serverLabel, name and arguments of the call. Once the call ends, it also has its status, output or error, and durationMs. Send the items back in input with the rest of output. The model then sees the earlier tool results. MCP failures throw InferenceError with status, type, code and retryAfterMs. 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 throws InferenceError. Once a stream has started, it throws from the for loop. A response.failed event throws it too. A field the failure lacks is null. The SDK raises these errors itself. All but the first are an InferenceError with that type and status null: Every other error carries what Moss Inference sent. Errors and limits lists every code. For a 429, see Limits.

Options

MossInference(...): responses.create and createStreaming take the same parameters, input first: