space.ai.chat()
Send a prompt or a conversation to a model, let it use your tools, and get its answer whole or as it is written.
Sends a prompt or a conversation to a model and returns its answer. With tools, the model can ask your code to run them, and chat() runs them and sends the results back, for as many steps as maxSteps allows. With schema, the answer is a JSON object checked against it. With stream: true, it returns the answer as the model writes it.
function chat<Schema>(
input: string | Message[],
options: ChatOptions<Schema> & { stream: true }
): Promise<ChatStream<Schema>>
function chat<Schema>(
input: string | Message[],
options?: ChatOptions<Schema> & { stream?: false }
): Promise<ChatReply<Schema>>Parameters
inputstring or Message[]A string is sent as one
usermessage. A list is the whole conversation, 1 to 1,000 messages. Each message has arole:system,developer,user,assistant, ortool. Ausermessage’scontentis a string, or a list oftextandimage_urlparts; see Send images. Anassistantmessage can holdtool_calls, and atoolmessage needs thetool_call_idit answers; see Call tools.options.modelstringThe model to call, such as
openai/gpt-oss-120b: lowercase letters, digits, and-, a/, then lowercase letters, digits,., and-. Names from the catalogue autocomplete, and any other name is accepted. Without it, themodelset increateSpaceis used. With neither, the call fails withvalidation_failed.options.fallbacksstring[]1 to 3 other models to try, in order, when
modelcannot answer right now, such as["openai/gpt-oss-20b"]. Each must take the same request, with its tools, images, andmaxTokens, or the call fails withvalidation_failed. A stream falls back only before it starts. The reply’smodelnames the model that answered.options.streambooleantruereturns a chat stream instead of a chat reply.falseby default.options.maxTokensintegerThe most tokens the answer may have, from 1. Without it, the model’s default output applies. Sent as
max_tokens.options.temperaturenumber0 to 2. Higher is more varied.
options.topPnumber0 to 1. Sent as
top_p.options.presencePenaltynumber-2 to 2. Sent as
presence_penalty.options.frequencyPenaltynumber-2 to 2. Sent as
frequency_penalty.options.stopstring or string[]A sequence that ends the answer, or a list of 1 to 4. None can be empty.
options.seedintegerAsk for the same answer to the same request, where the model can.
options.jsonbooleantruemakes the answer a JSON object, parsed into the reply’sjson. Sent asresponse_format: { type: "json_object" }.options.schemazod schemaThe shape the answer must have, as a zod object. The answer is checked against it and returned, typed, in the reply’s
json. Set this orjson, not both.options.toolsRecord<string, Tool>1 to 128 tools the model may ask for, each made with
tool()and named by its key: 1 to 64 letters, digits,_, or-. Only for models marked for tools.options.maxStepsintegerHow many times the model may answer in one call, 1 to 50. After each answer that asks for tools,
chat()runs them and, while steps are left, sends the results back for the next answer. 1 by default, so the tools run but the model does not answer again.options.stopWhenStopRule or StopRule[]Stops before
maxStepswhen any rule is true after a step, such astoolCalled("answer"). A rule is a function that gets{ steps }and returnstrueto stop.options.toolChoicestring or objectnone,auto,required, or{ tool: "name" }to require one tool. Sent astool_choice.options.parallelToolCallsbooleanWhether the model may ask for several tools at once. Sent as
parallel_tool_calls.options.reasoningEffortstringlow,medium, orhigh: how much a reasoning model thinks before it answers. Only for models marked for reasoning. Sent asreasoning_effort.options.promptobjectA stored prompt to put first in the conversation:
id, its name;version, a whole number from 1 to pin one, or the newest without it; andvariables, a string for each{{name}}in it. See Use stored prompts.options.userstringYour own ID for the person using your app, 1 to 256 characters. It is never sent to the model.
options.signalAbortSignalCancels the call, including a stream that is still being read.
options.timeoutMsnumberHow long the call may take, in milliseconds, including reading a stream. 600,000 (10 minutes) when you leave it out, whatever
timeoutMsis increateSpace.
Every option is checked before the call is sent. An option this page does not list fails with validation_failed.
Returns
A promise of a chat reply, which settles when the last step has answered. With stream: true, a promise of a chat stream, which settles as soon as the answer starts to arrive. A call refused before the answer starts rejects the promise, streamed or not.
A chat call is not sent again after a network failure or a timeout, because the model may already have started. It is sent again, up to retries times, only when it was refused with 429 or 503 before any work began.
Errors
| Code | When |
|---|---|
validation_failed | No model is named, or the input or an option breaks a rule above. issues names each field |
model_not_found | There is no model with that name |
context_too_long | The messages and maxTokens do not fit in the model’s context |
prompt_not_found | The project has no stored prompt with that name, or no such version of it |
unit_limit_reached | The call could go over the AI units the project may use this month |
tokens_over_limit | One call asks for more tokens than the plan allows in a whole minute |
rate_limited | The project sent more requests or tokens this minute than its plan allows |
model_unavailable | The model, and every one of fallbacks, cannot answer right now, or it stopped partway through a stream |
answer_invalid | The model did not answer with a JSON object, or it does not match schema. issues names each field |
answer_cut_off | The answer reached maxTokens before its JSON finished |
stream_interrupted | A stream ended before the answer finished |
timeout | The call took longer than timeoutMs |
Every call can also fail with the codes shared by all of space, such as missing_api_key or network_error. See SpaceError, and for every AI code, AI errors.
Example
import { space } from "digitospace"
const reply = await space.ai.chat(
[
{ role: "system", content: "Answer in Swahili, in one short paragraph." },
{ role: "user", content: "Tell me about Zanzibar." },
],
{ model: "openai/gpt-oss-120b", maxTokens: 500 }
)
console.log(reply.text)
console.log(`${reply.usage?.units ?? 0} AI units, processed in ${reply.processedIn}`)Let the model use tools
import { space, tool } from "digitospace"
import { z } from "zod"
const weather = tool({
description: "The weather in a city right now",
input: z.object({ city: z.string() }),
run: async ({ city }) => getWeather(city),
})
const reply = await space.ai.chat("What is the weather in Dar es Salaam and Arusha?", {
model: "openai/gpt-oss-120b",
tools: { weather },
maxSteps: 5,
})
console.log(reply.text)
console.log(`${reply.steps.length} steps, ${reply.toolResults.length} tool results`)A tool that fails, or input that does not match its schema, goes back to the model as an error, so it can try again. A tool with no run ends the call with its calls in toolCalls, for your code to answer. See tool().
Get a JSON object
import { space } from "digitospace"
import { z } from "zod"
const meal = z.object({
foods: z.array(z.object({ name: z.string(), calories: z.number() })),
note: z.string(),
})
const reply = await space.ai.chat("rice and beans", {
model: "openai/gpt-oss-120b",
schema: meal,
})
console.log(reply.json?.foods)Stream the answer
import { space } from "digitospace"
const stream = await space.ai.chat("Andika shairi fupi kuhusu Dar es Salaam.", {
model: "openai/gpt-oss-120b",
stream: true,
})
for await (const event of stream) {
if (event.type === "text") process.stdout.write(event.text)
}
const { stopReason, usage } = await stream.done()
console.log(`\n${stopReason}, ${usage?.units ?? 0} AI units`)Last updated