<mindset-agent> element exposes methods you call directly on the DOM node. They fall into three groups:
- State setters and readers: sync, safe to call once the SDK script has loaded and
mindset.init()has completed. - Turn-driving: sync, throws if the agent is busy.
- Thread CRUD: async, throws if the element isn’t initialized.
document.querySelector('mindset-agent') (or React refs, or any other DOM lookup) and call methods on it directly:
State setters and readers
These methods are synchronous. Call them once the SDK is ready, see § When the element is ready to call below. Last write wins per slot.agent.setPageTools(tools)
Register page tools for this agent. Page tools are functions on the host page that the agent can call during a turn. The agent sees the tool’s name, description, and argument schema; you handle the call and return a result. See the page tools guide for the full feature walkthrough, scenarios, and security notes.
Signature:
- Replaces the entire page-tools list for this agent. Pass an empty array to clear.
- Last write wins: calling it twice keeps only the second list.
agent.setSituationalAwareness(sa)
Pass structured context about the current page or user state to the agent. The agent reads this on every turn so it can personalize responses without the user having to repeat themselves. See the situational awareness guide for the full feature walkthrough, scenarios, and best practices.
Signature:
- Replaces the situational awareness object for this agent.
- Default character limit: 10,000. Lift to 20,000 with
extendedSituationalAwareness: trueinmindset.init().
agent.setPassthroughParams(params)
Pass parameters that the agent forwards to its tool calls. Useful for injecting tenant IDs, authorization tokens, or routing hints that tools need but the agent shouldn’t see in its prompt. See the pass-through parameters guide for the full feature walkthrough including targeted vs wildcard keys and the platform-managed parameters story.
Signature:
- Replaces the passthrough params object.
- Available as a tool-call argument; not surfaced to the LLM.
agent.isAgentBusy()
Check whether the agent is processing a turn. Returns false if the element isn’t bound yet.
Signature:
mindset:agent-busy and mindset:agent-idle events.
Turn-driving
agent.sendMessage(text, options?)
Send a user message and start a turn. Sync, returns void. The turn runs asynchronously, listen for mindset:complete (or the streaming events) to see the response.
Signature:
- Throws if the agent is currently busy. Wait for
mindset:agent-idlefirst, or checkagent.isAgentBusy().
- Programmatic priming. Inject an instruction so the agent responds as if a precondition occurred, without polluting the chat with the instruction.
- Background context injection. Let the host page steer the agent without user-visible noise.
- Widget action follow-ups. When a non-text user action should drive the agent without showing a synthetic “user said X” bubble.
Waiting for the agent to be ready
sendMessage throws if the agent is currently busy. Calling it on first load is the most common place this trips people up: if the agent is configured with an icebreaker (a turn that fires automatically when the agent starts), the lifecycle looks like this:
mindset:agent-idle and immediately call sendMessage, your call lands while the icebreaker is in flight and throws.
The recommended pattern handles both cases (icebreaker or no icebreaker) without you needing to know which:
- If the agent is idle right now, send straight away.
- If the agent is busy (could be the icebreaker still running, could be a previous turn finishing), wait for the next
mindset:agent-idleand recurse. The recursion re-checks busy state, so it’s safe across any sequence of idle/busy flips.
mindset:complete, now you send again), the agent is guaranteed to be idle and a plain agent.sendMessage(text) is fine.
Programmatic resume after
mindset:interrupt is on the roadmap. There’s no agent.resume() method on the element today. When the agent pauses on a UI-interrupt tool, render UI based on the event detail and drive the next turn with agent.sendMessage().Vote and widget-action methods are on the roadmap. Submitting feedback on a message or driving a tool widget’s actions programmatically is not yet exposed on the element. Use the built-in chat UI for these flows for now, or open a request describing your use case.
agent.stop()
Cancel the turn that’s currently running — halting both tool execution and response streaming. Sync, returns void. Calling stop() when no turn is running is a no-op (it does not throw).
Signature:
sendMessage starts a fresh turn. The element dispatches mindset:turn-aborted once the cancellation completes.
In the built-in chat UI the Send button becomes a Stop button that calls this for you. In headless mode there is no chat UI, so agent.stop() is the only way to cancel a turn.
Thread CRUD
These methods are async because they hit the network. They throw if the element isn’t bound to a runtime yet. The host needs to wait for the agent to initialize before calling them. Use themindset:agent-idle event as your signal.
Thread uids are exposed only after the user engages. A freshly-created thread doesn’t have a customer-visible uid until a user-message turn completes and the thread persists server-side. This means
agent.newThread() doesn’t return a uid, and agent.threadUid returns null until the user sends a message. See Thread-uid persistence semantics below.agent.newThread()
Start a new thread. The agent’s local state resets and a fresh thread is created. Customers don’t get a uid back from this call. The new thread isn’t persisted server-side until the user sends a message. Listen for mindset:thread-changed to know when the persisted uid is available.
Signature:
agent.switchThread(threadUid)
Switch to an existing persisted thread. The uid must come from agent.listThreads() or a prior mindset:thread-changed event. These are the only sources of uids that are guaranteed to be switchable.
Signature:
- Throws
<mindset-agent>.switchThread: thread "<uid>" not found. Only persisted threads (returned by agent.listThreads() or surfaced via mindset:thread-changed events) are switchable.if the uid is not in the persisted thread list. - Resolves cleanly if the switch succeeds.
mindset:thread-changedfires once with{ threadUid: <target>, previous: <prior> }.
agent.deleteThread(threadUid)
Delete a thread. If you delete the active thread, a new one is created automatically and mindset:thread-changed fires.
Signature:
true on success, false if the thread couldn’t be deleted.
agent.renameThread(threadUid, title)
Rename a thread. Useful when you let users name their threads manually.
Signature:
true on success.
agent.listThreads(options?)
List the user’s threads, oldest-first by default. Pass a pageToken from a previous response to continue paging.
Signature:
Promise<ListThreadsResponse>:
Each
ThreadSummary:
Properties
agent.threadUid
A sync getter that reads the active thread’s UID, but only when the thread is persisted server-side. Returns null while the thread is local-only (just created via newThread(), no completed user-message turn yet) or while the element isn’t bound to a runtime yet.
Type: string | null
mindset:thread-changed reports in event.detail.threadUid. Use the property when you need the current value on demand; use the event when you want to react to changes.
See Thread-uid persistence semantics for the full transition matrix.
Thread-uid persistence semantics
agent.threadUid and mindset:thread-changed only surface a uid once the thread is persisted server-side. This deliberately matches the chat-UI thread list, which only displays threads the user has engaged with, so the headless API never exposes a uid that wouldn’t also appear in the UI list, can’t be loaded later, or can’t be passed back to agent.switchThread().
Why this shape: three reasons converge.
- Matches the chat-UI thread list semantics. The chat UI only shows threads the user has engaged with. The headless API uses the same gate so the customer never gets a uid that isn’t visible, listable, or switchable.
switchThread(uid)only works for persisted threads. Uids the customer received viamindset:thread-changedorlistThreads()are always switchable. Stale or invented uids throw immediately.- No silent failures.
switchThreadthrows on a uid that isn’t in the persisted thread list, surfacing the problem at the call site rather than disappearing.
agent.newThread() and clear your message list, but not try to read the new uid until either:
- The next
mindset:thread-changedevent fires (after the user sends a message), or - You call
agent.listThreads()again later to pick up the persisted entry.
When the element is ready to call
Element methods must be called after both of the following:- The SDK script has loaded, i.e. the
<mindset-agent>custom element is defined. mindset.init()has completed, i.e. the runtime is bound to the element.
mindset:agent-idle event is the signal that both have happened. Listen for it once before driving the agent:
mindset:agent-idle also fires after every turn ends, so you can keep listening for it to drive subsequent turns reactively. For one-shot setup like the above, use { once: true }.
If you load the SDK script asynchronously (document.createElement('script'), framework dynamic imports, Webpack code-splitting), wait for the script to load before reading the element off the DOM and calling methods on it.
For sendMessage specifically, see § Waiting for the agent to be ready. sendMessage throws if the agent is currently busy (e.g. the icebreaker turn is in flight), and the sendWhenIdle helper handles that case automatically.
Errors
State setters never throw on init order or busy state.
Method-to-event reference
When a method drives the agent or changes its state, the corresponding events fire as follows:
See the DOM events reference for full event payload shapes and the order they fire in.