Skip to main content
This reference describes MiniMax Code v3.1.6. The page entry is window.mcode?.miniapp?.agent; the Node entry is context.agent. For usage and interaction examples, see Working with the Agent. The types below describe injected host interfaces; no runtime SDK is required. Other host interfaces are covered by Client API and Node API.

Access and session ownership

Declare the required entries in miniapp/miniapp.json, such as agentAccess: ["session.run", "session.read"]. The two grants are independent and users can switch each off in plugin details. Node injects context.agent when at least one entry is declared. A page object’s presence does not establish permission to call its methods.run and answer only continue root sessions created by this Mini App. reply may answer approvals from delegated child sessions, using the child’s IDs from the event. session.read does not permit continuing user sessions, approving their tools, or answering their questionnaires. Other Mini Apps’ sessions and sub-Agent sessions are outside the readable scope.A new session takes its agent, workspace, and model as follows. Continuing preserves its agent and workspace; only an explicit model switches its model.

run(input, options?)

Run one turn. The page can supply a cancellation ID; Node uses an AbortSignal in the second argument.
A busy session rejects a call without whenBusy. queue runs the text as a later, separate turn and returns that turn’s result. steer hands it to the running turn; once read, the call resolves with status: 'steered', while the original call receives the reply. If the running turn answers before reading it, the text becomes the next turn. Both modes start a turn immediately when the session is idle.After the user stops a session, its message queue may be paused. A follow-up can wait for the user to resume it while retaining a run slot. Cancelling a queued call removes its text. A steer already handed over cannot be withdrawn; cancelling it before it is read may yield an unknown outcome without stopping the original turn.

Run result

sessionId is always present. turnId can be absent when an answer did not start a continuation turn; model can be absent when no turn ran or the result is steered. text is the final reply and is not guaranteed. status: 'error' is a turn execution failure, separate from a rejected Promise. aborted is returned only after the host confirms the abort. A questionnaire pause supplies pendingQuestion.request to render and pendingQuestion.requestId to pass to answer.

reply(input)

The page and Node share this signature. Success resolves with undefined:
requestId comes from permission.requested, not the page’s cancellation ID. Only a one-time allow or deny is accepted; this method cannot write global rules. Unknown or settled requests reject. An approval can arrive before the first run() returns and can be answered immediately. For delegated asks, preserve the child’s sessionId and requestId from the event.

answer(input, options?)

Answer a questionnaire and observe its continuation. The two surfaces use different fields for the questionnaire ID:
Page questionId and Node requestId both take question.requested.requestId or result.pendingQuestion.requestId. The page may additionally pass its own requestId to cancel this answer/continuation call. Supply one answer per questionnaire step.Wait for the paused run to resolve before calling answer; it still occupies the session until then, so an earlier answer can reject as busy. The result is the same as run. If the answer was recorded but the continuation was not observed, the outcome is unknown; do not automatically answer again. An explicit model switches before questionnaire lookup, so even a questionnaire-not-found failure may have changed the model.

cancel(requestId)

Page only. Node cancels run, answer, or observe by aborting the supplied signal.
This returns undefined without waiting for confirmation. Unknown or completed IDs are ignored. A call waiting for a run slot or in the session queue rejects after cancellation. An executing call resolves aborted only after a confirmed abort; otherwise its outcome can be unknown. Cancelling an observer ends its subscription normally. Reloading or closing the page also cancels its active calls and subscriptions.

open(sessionId)

Page only. Show one of this Mini App’s own root sessions in the host chat’s side panel:
Any page or Node call may have created the target, but this Mini App must own it. A page with no associated chat rejects. While the side-panel tab remains open, users can read the session and answer its approvals and questionnaires in the host. After it closes, handle approvals in the call’s onEvent or open the tab again. Reopen after a host-window reload, runtime restart, or deletion of the original chat. Opening is idempotent, so retrying an open after an unknown result is safe.

models() and model selection

models is the user’s available catalog. default can be passed directly as model to run or answer. A page associated with a chat can also receive host, the chat’s current selection or the default if it has none. Node has no host field.For a catalog entry, copy providerId and modelId; optionally select a variant from variants or a thinking.effort from thinking.efforts. Preserve variant: '': it explicitly turns thinking off. Catalog thinking.default describes the default effort; input takes one thinking.effort. The method rejects when no usable default exists. An invalid model selection also rejects, while an offered model with missing BYOK credentials can end a turn with status: 'error'.

agents()

name is the canonical agent value for a new session, displayName is for display, and primary identifies the default agent. Use catalog names rather than the main alias. A session cannot change agent midway; create another session instead. Selecting an agent does not change the page’s inherited project directory or model.

create(input?)

The page and Node share this signature:
Create a session without running a turn or taking a host run slot. Omitting the argument or passing an empty object uses the defaults under Access and ownership. A page can pass its created session ID to Node for continuation. A page call reaching the host’s 60-second deadline can reject with runtime_unavailable even though the session may already exist; retrying may create another session.

observe(target, options)

Pass exactly one of sessionId or all: true; onEvent is required. An ID follows that session’s progress across turns. all: true receives only starts, final replies, and finishes across user sessions, as described under Observed events. Observing grants no right to answer approvals or questionnaires.On the page, pass your own requestId to end the subscription with cancel(requestId); it shares the unique-ID scope with active run and answer calls. Node uses signal in the second argument. There is no fixed subscription timeout. Cancellation, session deletion, page end, service stop/replacement, or read-access revocation ends the subscription. A start or runtime failure rejects; a normal end resolves with undefined. At most 4 observers are allowed per Mini App, apart from run slots and the start budget.

sessions()

Return up to 50 user sessions, ordered by most recently updated. Mini App, scheduled-task, and sub-Agent sessions are excluded. Requires session.read; there is no pagination or custom count argument. Fields are defined under Session types.

session(sessionId?)

An explicit ID returns that session’s details or rejects when missing or outside the readable scope. On the page, omitting the ID reads the user chat that opened this page and needs session.read; outside a chat it resolves undefined. Node serves multiple pages and has no current chat, so it requires an ID, which the page can obtain with session() and pass along. This API does not return full chat history: only details and the latest available final reply.

Data types

Session summary and detail

workspaceDir is the recorded absolute project directory and may no longer exist. isDefaultWorkspace means the session has no project and uses the default directory. createdAtMs and updatedAtMs are Unix milliseconds. An unrecorded model is omitted; error is present only for an error status with a recorded message; lastAssistantText is absent without an available final reply. List entries do not include detail-only fields.

Questionnaires and answers

These rules apply to questionnaires returned through question.requested.request or pendingQuestion.request on the page and Node. Optional host fields may be absent. Submit answers using the separate MiniAppAgentQuestionAnswer type.

Render the questionnaire

  • Render every entry in steps. Render question and option strings as plain text.
  • selectionMode selects single or multiple choice. Chosen IDs must come from the current step’s options.
  • allowOther and required are always true; otherPlaceholder is always Others....
  • image.src supports HTTPS URLs or app attachment paths beginning with /mavis/api/, rather than local file:// URLs.
  • recommended is a display marker. For v2 requests, it does not automatically select or submit an answer.
  • presentation supplies composer-replacement, progress, and back-navigation hints.

Submit answers

Each answer contains only stepId, selectedOptionIds, and selectedOther, plus optional otherText and skipped. Answer the supplied steps and options without adding other fields.
  • Free text uses selectedOther and otherText.
  • skipped: true explicitly skips a step even though it is required.
  • Returned prefillAnswers can prefill the form. Do not copy its contextImages or other returned metadata into answer().
The host supplies these fields when available for display or compatibility with existing questionnaires. They are not answer() inputs and do not establish additional Mini App business APIs, such as a Goal API.These state fields are snapshots. The Agent API has no questionnaire.state event.

Events

run and answer pass this discriminated union to onEvent. Ignore unrecognized type values.

Observed events

A single-session observer can receive all of the progress events above. all: true receives only turn.started, the final reply’s message.committed, and turn.finished, with optional session title. An observed turn.started.model is optional. If the host cannot read the final reply, it sends no message.committed and omits text from turn.finished. Observers receive no queue, steer, approval, or questionnaire events. Backpressure can drop text fragments and tool progress; do not treat every progress fragment as a reliable persistent record.

Concurrency and cancellation limits

  • agentConcurrency is 1–32, default 4; each session has one turn at a time. Extra run / answer calls wait in order, in a queue of at most four times the concurrency.
  • A whenBusy follow-up shares a slot already held for that session by this plugin. Such extra in-flight follow-ups are also capped at four times the concurrency. The start budget per 60 seconds is max(12, 5 × agentConcurrency) and survives Mini App restarts; waiting for a slot or a refused call does not count.
  • Approvals wait only while the call supplied onEvent or the session remains open in a chat side-panel tab. Otherwise they are denied; a questionnaire can be returned as pendingQuestion. Approval waiting has no timeout, and ignoring an approval event retains the run slot.
  • Per Node process, up to 16 ordinary requests can be pending across Agent run, answer, models, agents, create, sessions, and session, together with all Tool and Connector methods. Agent reply has a separate limit of 16 pending calls; observe has its own limit of 4. An Agent call reaching the ordinary or reply limit rejects with retryable AGENT_UNAVAILABLE before dispatch. These process limits also apply while calls wait for run slots, queued turns, or approval.
  • Revoking access aborts affected running turns, refuses waiting calls, or ends read subscriptions. Objects may remain present; new calls work after access is enabled again. After a Node signal aborts, no further event callbacks are delivered, including events already in transit.

Errors

Page rejections are Error objects; rely on the code in message. Custom properties such as busy.reason are not guaranteed to survive the host bridge. Node rejects with MiniAppAgentError, carrying code, retryable, and optional reason. See Agent error codes for exact mappings and handling.A rejected Promise alone does not justify retrying: result_unknown / AGENT_OUTCOME_UNKNOWN means an operation may have applied. observe, sessions, and session do not change a session, and lost read/subscription settlement reports unavailability. The page’s models, agents, and create share a catalog call path whose transport failure can still report result_unknown. Handle a normal run result with status: 'error' separately from these call rejections.