AI

AI: models paid from your NoClick balance, for code that isn't an agent, and your agents as models.

reply = noclick.AI.chat("Summarize this in one line: ...")
vectors = noclick.AI.embed(["first", "second"]).vectors
image = noclick.AI.image("A lighthouse at dusk, watercolor")
clip = noclick.AI.video("Waves rolling under a lighthouse at dusk").wait()
words = noclick.AI.transcribe("https://example.com/call.mp3")
answer = noclick.AI.chat("Where's my refund?", model="agent:support")

Every call is charged in US dollars to your account; inside as_user it is attributed to that user and counts against its spend cap. AI.base_url serves chat completions, responses, embeddings and the model list to any OpenAI client.

class AI

Models paid from your NoClick balance, for code that isn't an agent: chat, embeddings, images, videos and transcription; and your agents as agent:<name> models. Model ids are OpenRouter ids with the openrouter/ prefix; leave model out for NoClick's default of each kind.

Attributes
baseUrlstring

The OpenAI-compatible endpoint (https://api.noclick.com/v1/ai on the hosted API): point any OpenAI client at it with your NoClick key for chat completions, responses, embeddings and the model list.

chatstatic

static chat(
  messages: string | readonly (AIChatMessage | string)[],
  options?: AIChatOptions,
): Promise<ChatReply>

Send a conversation to a chat model: OpenAI-shaped messages, or a string as one user message. model: "agent:<name>" talks to one of your agents instead: it brings its own tools and keeps the conversation (conversation: reply.conversation continues it). The answer streams, so a long turn never times out. A request with no conversation whose messages end in an assistant reply the agent gave recently continues that reply's conversation, so a chat UI that resends the whole history keeps one thread (invite-only beta).

const reply = await AI.chat("Summarize: the meeting moved to Friday at 3pm.", { maxTokens: 200 });
console.log(reply.text, reply.costUsd);
Parameters
messagesstring | readonly (AIChatMessage | string)[]required
options.modelstring

An OpenRouter id with the openrouter/ prefix, or agent:<name> for one of your agents; NoClick's default when omitted.

options.maxTokensnumber
options.temperaturenumber
options.responseFormatJsonObject

Ask for JSON: { type: "json_schema", json_schema: ... }.

options.toolsJsonObject[]

OpenAI-format tool definitions, such as await toolkit.definitions({ format: "openai" }). An agent takes none.

options.conversationstring

An agent's conversation to continue (reply.conversation); only the messages after the last assistant message are sent.

options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

options.signalAbortSignal
Returns

The answer: its text, the message to append to the conversation, and the tokens it used and what it cost.

embedstatic

static embed(
  texts: string | readonly string[],
  options?: CallOptions & { model?: string; dimensions?: number },
): Promise<Embeddings>

Turn text into vectors: one string, or up to 2,048. dimensions shortens them, for models that allow it.

Parameters
textsstring | readonly string[]required
options.modelstring
options.dimensionsnumber
options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

Returns

One vector per text, in order, with their length and what the call cost.

imagestatic

static image(
  prompt: string,
  options?: CallOptions & { model?: string; size?: string },
): Promise<GeneratedImage>

Make one image, kept as one of your account's files (its url keeps working); size is "WIDTHxHEIGHT" in an aspect ratio the model makes (its own shape unless you say).

Parameters
promptstringrequired
options.modelstring
options.sizestring
options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

Returns

The image, kept as one of your account's files: a url that keeps working, its file_id, its size and what it cost.

videostatic

static video(
  prompt: string,
  options?: VideoOptions,
): Promise<Operation<GeneratedVideo>>

Start one video. It takes minutes, so it runs as an Operation whose wait() resolves to the GeneratedVideo, kept as one of your account's files. Its price is quoted before it starts (usdPerSecond in AI.models({ kind: "video" })) and charged when it's done.

const job = await AI.video("Waves rolling under a lighthouse at dusk", { seconds: 8, aspectRatio: "9:16" });
const clip = await job.wait({ timeoutS: 600 });
console.log(clip.url, clip.seconds, clip.costUsd);
Parameters
promptstringrequired
options.modelstring
options.secondsnumber

Among the lengths the model makes; about 8 when omitted.

options.resolutionstring

720p, 1080p, as the model makes them; 720p where it can when omitted.

options.aspectRatiostring

16:9, 9:16, as the model makes them.

options.audioboolean

Sound, where the model makes it (default true).

(default true)
options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

Returns

An Operation at once, whose wait() gives the GeneratedVideo, kept as one of your account's files.

transcribestatic

static transcribe(
  audio: TranscribeAudio,
  options: TranscribeOptions & { background: true },
): Promise<Operation<Transcript>>

Write down what is said in a recording: an https URL to it, or its bytes, up to 2 hours (25 MB as bytes, 200 MB behind a URL), in MP3, WAV, M4A, MP4, OGG, WebM, AAC, FLAC or AIFF. language (ISO 639-1) skips detection. The default model transcribes a recording over 10 minutes in pieces cut at pauses, each charged, and joins them into one transcript; a failed piece fails the call and says which.

speakers (invite-only beta) tells the voices apart, on noclick/transcribe-1, which takes the whole recording in one job so each voice keeps its label from start to end (a model that cuts recordings into pieces refuses it). true labels each segment's speaker speaker_1, speaker_2, ... in the order they first speak; a list of names (["rep", "customer"]) says how many voices there are, and NoClick works out which is which from what they say, giving a voice it can't tell the next unused name in speaking order. It's priced as usdPerMinuteWithSpeakers in AI.models.

{ background: true } (invite-only beta) returns an Operation at once, whose wait() resolves to the transcript: for a recording that takes longer than one request waits (90 seconds), as one with speakers over about an hour can. A call that doesn't run in the background and passes 90 seconds rejects with RequestTimeout naming its operation, which still finishes and holds the transcript.

Parameters
audioTranscribeAudiorequired
options.modelstring
options.languagestring
options.speakersboolean | string[]invite-only beta

Invite-only beta. true, or a name per voice.

options.backgroundbooleaninvite-only betarequired

Invite-only beta. Return an Operation at once instead of waiting.

options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

Returns

The transcript: its text, timed segments, the language and how long the audio was. With background=True, an Operation at once, whose wait() gives it.

headersstatic

static headers(options?: CallOptions): Promise<Record<string, string>>

The headers a call to AI.baseUrl needs: your key as the bearer and, inside asUser (or with user), the NoClick-User that attributes the call to that user and holds it to the user's spend cap. Give them to an OpenAI client as defaultHeaders; without the user header the account pays.

const gpt = new OpenAI({ baseURL: AI.baseUrl, apiKey: "-", defaultHeaders: await AI.headers({ user: "user_42" }) });
Parameters
options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

Returns

Authorization and, when a user is in scope, NoClick-User.

modelsstatic

static models(
  options?: CallOptions & { kind?: AIModelKind },
): Promise<AIModel[]>

The models you can call, the default of each kind first, with their prices in US dollars; agent lists the agents you (or the user you act for) can talk to as agent:<name>.

Parameters
options.kindAIModelKind
options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

Returns

Every matching model with its prices in US dollars, the default of each kind first.

ChatReply

interface ChatReply

A model's (or an agent's) answer: text, and the whole message to append to the conversation.

Attributes
textstring

The answer as text (empty when the model only called tools).

messageAIChatMessage

The assistant message as the API sent it (role, content, tool_calls).

modelstring | null
finishReasonstring | null

stop, length (maxTokens reached) or tool_calls.

usageRecord<string, number>

prompt_tokens, completion_tokens, total_tokens (none for an agent).

costUsdnumber | null

What the call cost, in US dollars.

rawJsonObject

The response JSON exactly as the API sent it.

toolCallsJsonObject[]

The tools the model asked to call (empty if none), in the shape toolkit.handleOpenAI runs. An agent runs its own.

conversationstring | null

An agent's conversation this reply is part of: pass it as conversation to continue it.

Embeddings

interface Embeddings

One vector per input, in the order you passed them.

Attributes
vectorsnumber[][]
dimensionsnumber

The length of each vector.

modelstring | null
usageRecord<string, number>

Tokens used: prompt_tokens, total_tokens.

costUsdnumber | null

What the call cost, in US dollars.

rawJsonObject

The response JSON exactly as the API sent it.

GeneratedImage

interface GeneratedImage

An image a model made, kept as one of your account's files.

Attributes
urlstring

A link to the image that keeps working.

widthnumber | null
heightnumber | null
modelstring | null
costUsdnumber | null

What the image cost, in US dollars.

expiresAtDate | null

When url stops working: null, since the file is kept.

fileIdstring | null

The file in your account's files.

rawJsonObject

The response JSON exactly as the API sent it.

GeneratedVideo

interface GeneratedVideo

A video a model made, kept as one of your account's files.

Attributes
urlstring

A link to the video that keeps working.

fileIdstring | null

The file in your account's files.

mimeTypestring | null
secondsnumber | null
resolutionstring | null
modelstring | null
costUsdnumber | null

What the video cost, in US dollars.

rawJsonObject

The response JSON exactly as the API sent it.

Transcript

interface Transcript

What was said in a recording, as one text and as timed segments.

Attributes
textstring
languagestring | null

The spoken language as an ISO 639-1 code (en), detected unless you passed one.

durationSnumber | null
segmentsTranscriptSegment[]
modelstring | null
costUsdnumber | null

What the transcription cost, in US dollars.

rawJsonObject

The response JSON exactly as the API sent it.

TranscriptSegment

interface TranscriptSegment

A stretch of speech: what was said between startS and endS, and by whom when you asked for speakers.

Attributes
startSnumber
endSnumber
textstring
speakerstring

Invite-only beta. Who said it: one of the names you gave speakers, or speaker_1, speaker_2, ... in the order the voices first speak (absent unless you asked).

AIModel

interface AIModel

A model you can call, and what it costs in US dollars (its provider's own price). Only the prices for its kind are set: per token for chat and embedding models, per token of the image an image model makes, per minute of audio (and per token of the transcript) for transcription ones, per second for video ones, none for an agent.

Attributes
idstring

The id to pass as model, like openrouter/anthropic/claude-sonnet-4.6 or agent:support.

namestring | null
kindAIModelKind

chat, embedding, image, transcription or agent.

contextLengthnumber | null

The most tokens a request can hold (chat and embedding models).

inputUsdPerTokennumber | null
outputUsdPerTokennumber | null
usdPerMinutenumber | null
usdPerMinuteWithSpeakersnumber | null

Invite-only beta. What a minute of audio costs with speakers; null for a model that can't tell voices apart.

usdPerSecondnumber | null

What a second of video costs, for the clip a call naming no length or resolution makes.

rawJsonObject

The response JSON exactly as the API sent it.