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[]Required

A string is sent as one user message. A list is the whole conversation, 1 to 1,000 messages. Each message has a role: system, developer, user, assistant, or tool. A user message’s content is a string, or a list of text and image_url parts; see Send images. An assistant message can hold tool_calls, and a tool message needs the tool_call_id it answers; see Call tools.

options.modelstring

The 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, the model set in createSpace is used. With neither, the call fails with validation_failed.

options.fallbacksstring[]

1 to 3 other models to try, in order, when model cannot answer right now, such as ["openai/gpt-oss-20b"]. Each must take the same request, with its tools, images, and maxTokens, or the call fails with validation_failed. A stream falls back only before it starts. The reply’s model names the model that answered.

options.streamboolean

true returns a chat stream instead of a chat reply. false by default.

options.maxTokensinteger

The most tokens the answer may have, from 1. Without it, the model’s default output applies. Sent as max_tokens.

options.temperaturenumber

0 to 2. Higher is more varied.

options.topPnumber

0 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.seedinteger

Ask for the same answer to the same request, where the model can.

options.jsonboolean

true makes the answer a JSON object, parsed into the reply’s json. Sent as response_format: { type: "json_object" }.

options.schemazod schema

The 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 or json, 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.maxStepsinteger

How 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 maxSteps when any rule is true after a step, such as toolCalled("answer"). A rule is a function that gets { steps } and returns true to stop.

options.toolChoicestring or object

none, auto, required, or { tool: "name" } to require one tool. Sent as tool_choice.

options.parallelToolCallsboolean

Whether the model may ask for several tools at once. Sent as parallel_tool_calls.

options.reasoningEffortstring

low, medium, or high: how much a reasoning model thinks before it answers. Only for models marked for reasoning. Sent as reasoning_effort.

options.promptobject

A 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; and variables, a string for each {{name}} in it. See Use stored prompts.

options.userstring

Your own ID for the person using your app, 1 to 256 characters. It is never sent to the model.

options.signalAbortSignal

Cancels the call, including a stream that is still being read.

options.timeoutMsnumber

How long the call may take, in milliseconds, including reading a stream. 600,000 (10 minutes) when you leave it out, whatever timeoutMs is in createSpace.

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

CodeWhen
validation_failedNo model is named, or the input or an option breaks a rule above. issues names each field
model_not_foundThere is no model with that name
context_too_longThe messages and maxTokens do not fit in the model’s context
prompt_not_foundThe project has no stored prompt with that name, or no such version of it
unit_limit_reachedThe call could go over the AI units the project may use this month
tokens_over_limitOne call asks for more tokens than the plan allows in a whole minute
rate_limitedThe project sent more requests or tokens this minute than its plan allows
model_unavailableThe model, and every one of fallbacks, cannot answer right now, or it stopped partway through a stream
answer_invalidThe model did not answer with a JSON object, or it does not match schema. issues names each field
answer_cut_offThe answer reached maxTokens before its JSON finished
stream_interruptedA stream ended before the answer finished
timeoutThe 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

chat.ts
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

tools.ts
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

json.ts
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

stream.ts
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