AG Studio Launch Week 🚀🚀🚀 28 Sep - 2 Oct 2026 🚀🚀🚀 Join now

JavaScript Embedded AnalyticsCustom Harness

Version 3.0.0

A custom harness applies when the conversation, or the interface, is application code. There are three depths, and replacing the harness is the deepest of them:

You replaceYou keepUse
The loopThreads, persistence, chat UI, toolsCustom Runner, or Client Tool Runner if Studio should run its tools
The chat UIThreads, persistence, agents, toolsYour own UI, below
The conversation itselfTools and contextImplementing a harness, below

Your Own UI Copy Link

You can keep Studio's harness - agents, threads, persistence, tool execution - and render the conversation yourself. createAiHarness returns the harness, so hold on to it:

let harness: AgAiHarness;

const studioProperties = {
    ai: ({ api }) => {
        harness = createAiHarness(api, { adapter });
        return harness;
    },
    initialState: {
        ...myState,
        // Hide the built-in panel; your UI is the chat surface.
        panels: { ai: { collapsed: true } },
    },
};

Once Studio is running, drive a session from your own components:

const session = await harness.createThread({ agentId: 'lead' });

session.addEventListener('changed', () => render(session.messages, session.status));
session.sendMessage('Add a chart of sales by region');

Session snapshots are immutable and change reference when they change, so they drive a React or Vue render loop directly. See Sessions for the reader contract, and Chat UI for what the built-in panel does with them.

Implementing a Harness Copy Link

You can also implement the harness interface yourself and hand it to ai. Studio's panel will still render it, because the panel only ever reads the session surface.

const studioProperties = {
    ai: myHarness,
};
addEventListenerCopy Link
Function
Register a listener for harness-level changes (roster or thread list). The event carries no payload: re-read the snapshots when it fires. Remove it with AgAiHarness.removeEventListener.
removeEventListenerCopy Link
Function
Stop notifying a listener added with AgAiHarness.addEventListener.
agentsCopy Link
readonly AgAiAgentDescriptor[]
Agents that can speak. New reference on change.
modelsCopy Link
readonly AgAiModel[]
The models a reader may choose between, in the order they are offered. New reference on change. Absent or empty means this harness offers no choice, and the chat panel shows no model picker.
threadsCopy Link
readonly AgAiThreadSummary[]
Conversation catalogue. New reference on change. Empty is a valid state: Studio's own harness creates a conversation when the reader sends their first message, so a dashboard nobody has spoken to has no threads at all.
promptStartersCopy Link
readonly AgAiPromptStarter[]
Suggestions to offer in a conversation nobody has said anything in yet, shown above the message box until one is chosen or a message is typed. Absent or empty shows nothing.
getAgentCopy Link
Function
One agent from the roster, or undefined when nothing holds that id.
getThreadCopy Link
Function
One conversation's summary, or undefined when nothing holds that id.
openThreadCopy Link
Function
Idempotent: the same threadId returns the same live session.
createThreadCopy Link
Function
Start a conversation with the named agent and return its live session. Rejects when no agent holds that id.
deleteThreadCopy Link
Function
Remove a conversation, closing its session and taking any conversation nested below it with it. Does nothing when nothing holds that id.
getSessionCopy Link
Function
The live session for a thread if it is already open, without opening or hydrating one. Returns undefined for a thread not yet opened, or when the harness surfaces no such session (e.g. a delegate sub-run it does not track). Lets the UI bind to a sub-run mid-flight.
setThreadModelCopy Link
Function
Set the model a conversation uses from now on, as AgAiThreadSummary.model. A harness that offers models but does not implement this keeps no record of the choice, and the chat panel remembers it only for as long as it stays open.
disposeCopy Link
Function
Release any resources the harness holds (e.g. a persistence subscription).

Persistence is then yours, because the history option applies only to the harness createAiHarness builds. So are the plan store and the delegation registry, which is why a harness of your own is handed no harness-owned tools.

If you are going this far, consider whether you need a harness at all. Tools and context work with nothing above them - see Without a Harness.

Next Copy Link