MossInference is the browser client for Moss Inference. Its responses.create takes OpenAI’s Responses arguments plus indexes, and returns OpenAI’s shapes.
Moss Inference searches your indexes in the cloud, so the page loads no index. The client works like the JavaScript client. This page covers what differs in the browser.
Install
MossInference needs @moss-dev/moss-web 1.8.0 or later. For the rest of the SDK setup, see Install.
Create a client
null for both and a baseURL path served by a route of yours that adds them:
client, which calls Moss Inference directly.
Get a response
response.output_text joins the text of the response’s messages. response.output holds its items.
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 undefined 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
type, such as response.output_text.delta. The stream ends after one of two events:
response.completed, whoseevent.responseis the whole response.response.incomplete, whenmax_output_tokensor a content filter cut the response short.
await stream.finalResponse() reads the rest of the stream and returns that response.
To stop early, leave the loop or call stream.controller.abort(), as the stop button does. Either one closes the connection, which stops the model, and neither throws.
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. Through a server route, the route picks the indexes instead.
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
InferenceError with errorCode "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 asapiKey:
X-Moss-Provider-Key header, never in the body. To use a key for one call only, pass { apiKey } as the second argument of responses.create.
Every visitor can read a key in page code, like a project key. On a public page, your server route sets X-Moss-Provider-Key itself.
Bring your own key covers model names and billing.
Tool calls
tools, tool_choice and parallel_tool_calls take OpenAI’s Responses shapes, so a function tool is flat. Each call the model makes comes as a function_call item of output, and your code runs it.
Push the output items onto input unchanged. Add one function_call_output item per call, and call again until the response has no calls:
lookupOrder stands for your own code, and it returns text. Push the items unchanged to keep every field the model sent.
finalResponse() also works without the for await loop. A second call returns the same response. It rejects with what the loop would throw, or with the signal’s reason after an abort. Without stream: true, create returns the response directly.
Tool calling covers tool_choice, parallel_tool_calls and structured output.
MCP servers
Add MCP entries in your server route, never in page code. Moss Inference calls the server’s tools for the model during the response, so your code sends nofunction_call_output items for them.
Each call comes as an mcp_call item. 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.
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, errorCode and retryAfter. A call that fails after a tool ran has errorCode "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
Every failure other than an abort throwsInferenceError. Once a stream has started, it throws from the for await loop.
A field the failure lacks is
undefined. A call without baseURL gets no retryAfter, because Moss Inference does not expose Retry-After to the page.
The SDK sets these types itself, with status undefined:
Every other error carries what Moss Inference sent. Errors and limits lists every code. For a
429, see Limits.
Options
new MossInference(projectId, projectKey, options?):
Each call resolves
baseURL against the page, so a client built during server rendering works in the browser.
responses.create(params, options?) takes OpenAI’s fields and the Moss fields in params. Settings for this call only go in options:
Keep the project key on your server
A public page calls Moss Inference through a route of yours. The route adds the project id and key on your server, so the key never reaches the page. This one servesPOST /moss/v1/responses:
403. It always sends X-Moss-Indexes, because a call without it does no search.
As a result, retrieve, cache, an empty indexes list and apiKey in page code do not reach Moss Inference. A route that wants them sets X-Moss-Retrieve, X-Moss-Cache or X-Moss-Provider-Key itself.
With null credentials, the client sends no Authorization header. A header you pass in headers, such as the visitor’s session token, then reaches the route.