One agent
Run a turn in one conversation, then attach to it, answer it, steer it or stop it
On this page(15 sections)
- Say something to an agent
- Watch a turn happen
- Answer a question the agent asked
- Interrupt a running turn
- Stop a turn now
- Reword a waiting message
- Take back a waiting message
- Let waiting messages go
- Reschedule waiting messages
- Run a refused turn again
- Move a conversation to another account
- Go back to an earlier message
- Shortcut commands the agent knows
- Choose what a new chat opens on
- The last time each provider said no
The surface most callers are here for. Starting a turn answers with a run id and nothing else: the work happens inside the sandbox whether or not anybody stays connected, and attaching is how you watch it, from the beginning or from wherever you had got to. The rest is the things a person does to a turn in flight — answer a question it asked, redirect it, stop it, or put the whole conversation back to an earlier point. Everything here addresses one conversation by id.
15 calls. Pick one to open it, or use the list on the right.
POST/agentSay something to an agent
Answers at once with what became of the message: it starts a turn when the conversation is free, is said into the running turn where that turn takes words mid-way, and otherwise waits in the conversation's queue for the next turn, where every window sees it. The work runs inside the sandbox whether or not anybody stays connected; watch it by attaching. Naming a conversation that does not exist yet opens it. Give the message an id, and sending it again after a lost answer is met with what became of it the first time rather than a second delivery.
What you send
| Field | Type | Where |
|---|---|---|
promptrequiredWhat to say to the agent | string | body |
errandWhat the words are for, when… | "land-conflict" | "verify-nudge" | "land-breakage" | "land-fix" … (10) | body |
messageIdYour id for this message | string | body |
titleA title for a conversation this… | string | body |
attachmentsFiles to hand the agent along… | string[] | body |
mentionsWorkspace paths the prompt mentions with… | string[] | body |
agentWhich model provider serves this turn | string | body |
harnessWhich agentic loop runs the turn | "native" | "claude-code" | body |
accountWhich of that provider's connected accounts… | string | body |
actsAsWhich persona the turn speaks as… | string | body |
sessionIdResume this provider session instead of… | string | body |
conversationIdThe conversation this turn belongs to | string | body |
isolatedWork in this conversation's own private… | boolean | body |
startInWhich folder the conversation opens in,… | string | body |
placementWhere this conversation runs: this sandbox… | object | body |
when kind is "local" | shape | body |
when kind is "runner" | shape | body |
idrequired | string | body |
worktreeBasePin a new private copy to… | object[] | body |
reporequired | string | body |
baserequired | string | body |
autoLandWhether this turn's work merges into… | boolean | body |
runRoleWhat started this turn, when it… | "commit-message" | "session-title" | "safety-judge" | "loop-verdict" … (13) | body |
originSet by the sandbox alone: this… | object | body |
automationIdrequired | string | body |
providerrequired | string | body |
channelId | string | body |
author | string | body |
forkOfWhere this conversation was cut from,… | object | body |
conversationIdrequiredThe conversation this one was cut… | string | body |
keeprequiredHow many of that conversation's messages… | integer | body |
filesrequiredWhich files the fork opens on:… | "then" | "now" | body |
modelWhich model to use | string | body |
unattendedNobody is watching this turn: a… | boolean | body |
outsideWakeContent from outside caused this turn,… | string | body |
permissionModeHow tool calls are gated: ask… | "default" | "plan" | "bypassPermissions" | body |
allowedToolsNarrow the turn to these tools | string[] | body |
effortHow hard the model should think,… | string | body |
thinkingWhether to show the model's reasoning… | boolean | body |
fastAsk for the same work at… | boolean | body |
autoPickedWhether this turn's model was chosen… | boolean | body |
editorContextWhat the user has open in… | object | body |
filerequiredThe file open in the editor,… | string | body |
startLineFirst line of the selection, counting… | integer | body |
endLineLast line of the selection, counting… | integer | body |
selectionThe selected text itself | string | body |
sendAtHold this message until then (epoch… | integer | body |
sendAfterHold this message until the conversation… | string | body |
conversationAutoLandWhether this conversation's finished work merges… | boolean | body |
continuesCarry the conversation on from where… | true | body |
What comes back
| Field | Type |
|---|---|
deliveredWhat became of the message: it… | "started" | "steered" | "queued" |
runThe run the message is in:… | string |
duplicateThe sandbox had already taken a… | true |
curl -X POST "$SANDBOX/agent" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"prompt":"Update the changelog for the last five commits.","errand":"land-conflict","messageId":"a1b2c3d4","title":"Update the changelog","attachments":["…","…"],"mentions":["…","…"],"agent":"…","harness":"native","account":"work","actsAs":"…","sessionId":"a1b2c3d4","conversationId":"nightly-changelog","isolated":true,"startIn":"…","placement":{"kind":"local"},"worktreeBase":[{"repo":"root","base":"…"},{"repo":"site","base":"…"}],"autoLand":true,"runRole":"commit-message","origin":{"automationId":"a1b2c3d4","provider":"claude","channelId":"a1b2c3d4","author":"Ada Lovelace"},"forkOf":{"conversationId":"nightly-changelog","keep":0,"files":"then"},"model":"claude-sonnet-4-6","unattended":true,"outsideWake":"…","permissionMode":"default","allowedTools":["…","…"],"effort":"…","thinking":true,"fast":true,"autoPicked":true,"editorContext":{"file":"…","startLine":1,"endLine":1,"selection":"…"},"sendAt":1,"sendAfter":"…","conversationAutoLand":true,"continues":true}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.run({
"prompt": "Update the changelog for the last five commits.",
"errand": "land-conflict",
"messageId": "a1b2c3d4",
"title": "Update the changelog",
"attachments": [
"…",
"…"
],
"mentions": [
"…",
"…"
],
"agent": "…",
"harness": "native",
"account": "work",
"actsAs": "…",
"sessionId": "a1b2c3d4",
"conversationId": "nightly-changelog",
"isolated": true,
"startIn": "…",
"placement": {
"kind": "local"
},
"worktreeBase": [
{
"repo": "root",
"base": "…"
},
{
"repo": "site",
"base": "…"
}
],
"autoLand": true,
"runRole": "commit-message",
"origin": {
"automationId": "a1b2c3d4",
"provider": "claude",
"channelId": "a1b2c3d4",
"author": "Ada Lovelace"
},
"forkOf": {
"conversationId": "nightly-changelog",
"keep": 0,
"files": "then"
},
"model": "claude-sonnet-4-6",
"unattended": true,
"outsideWake": "…",
"permissionMode": "default",
"allowedTools": [
"…",
"…"
],
"effort": "…",
"thinking": true,
"fast": true,
"autoPicked": true,
"editorContext": {
"file": "…",
"startLine": 1,
"endLine": 1,
"selection": "…"
},
"sendAt": 1,
"sendAfter": "…",
"conversationAutoLand": true,
"continues": true
});POST/agent/attachWatch a turn happenstream
Streams everything the agent does: its words, the tools it reaches for, and the answers it gets. It opens with the turn's transcript whole as it stands, then sends every change as it lands, so a reload or a dropped connection loses nothing: attaching again hands over the whole transcript again. The window that started the turn holds no special claim, and any number of watchers on any number of devices see the same thing.
What you send
| Field | Type | Where |
|---|---|---|
conversationIdrequiredWhich conversation to watch | string | body |
runThe run you were watching | string | body |
What comes back
| Field | Type |
|---|---|
when event is "message" | shape |
data | object |
when kind is "attached" | shape |
runThe run's id | string |
startedAtWhen it started, in milliseconds, so… | number |
seqHow many frames the run has… | number |
rowsThe turn's rows as they stand:… | object[] |
when kind is "patch" | shape |
seqIts position in the run, counting… | number |
patch | object |
when kind is "fact" | shape |
seqIts position in the run, counting… | number |
fact | object |
when kind is "end" | shape |
id | string |
retry | number |
when event is "done" | shape |
data | unknown |
id | string |
retry | number |
when event is "error" | shape |
data | unknown |
id | string |
retry | number |
curl -N -X POST "$SANDBOX/agent/attach" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"conversationId":"nightly-changelog","run":"run_8c2f41d9"}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.attach({
"conversationId": "nightly-changelog",
"run": "run_8c2f41d9"
});POST/agent/replyAnswer a question the agent asked
Un-parks a turn that is waiting on you: approving a plan, choosing between options, or permitting a tool. The turn picks up where it stopped.
What you send
| Field | Type | Where |
|---|---|---|
when kind is "plan" | shape | body |
requestIdrequiredWhich card you are answering, from… | string | body |
approverequiredWhether to go ahead | boolean | body |
feedbackWhy not, which goes back to… | string | body |
when kind is "question" | shape | body |
requestIdrequiredWhich card you are answering | string | body |
answersWhat you chose, keyed by the… | object | body |
attachmentsFiles that go with your own-words… | object | body |
cancelledDismissing it instead, which tells the… | boolean | body |
when kind is "permission" | shape | body |
requestIdrequiredWhich card you are answering | string | body |
decisionrequiredOnce allows this call alone; always… | "once" | "always" | "everything" | "deny" | body |
feedbackWhy not, which goes back to… | string | body |
childFor a request to start a… | object | body |
providerrequiredWhich provider serves it | string | body |
modelrequiredWhich of that provider's models | string | body |
harnessWhich agentic loop runs it | "native" | "claude-code" | body |
accountWhich of that provider's connected accounts… | string | body |
effortHow hard it thinks, where the… | string | body |
thinkingWhether it reasons before it answers,… | boolean | body |
fastWhether it asks for the faster… | boolean | body |
when kind is "browser_help" | shape | body |
requestIdrequiredWhich card you are answering | string | body |
helpedrequiredWhether you cleared it | boolean | body |
noteAnything the agent should know, which… | string | body |
when kind is "terminal_help" | shape | body |
requestIdrequiredWhich card you are answering | string | body |
helpedrequiredWhether you did it | boolean | body |
noteAnything the agent should know, which… | string | body |
when kind is "capability_offer" | shape | body |
requestIdrequiredWhich card you are answering | string | body |
connectrequiredYes keeps the agent waiting while… | boolean | body |
when kind is "payment_offer" | shape | body |
requestIdrequiredWhich card you are answering | string | body |
approverequiredYes releases exactly one payment | boolean | body |
when kind is "credential_offer" | shape | body |
requestIdrequiredWhich card you are answering | string | body |
approverequiredYes releases it, as far as… | boolean | body |
What comes back
| Field | Type |
|---|---|
okAlways true | true |
curl -X POST "$SANDBOX/agent/reply" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"kind":"plan","requestId":"a1b2c3d4","approve":true,"feedback":"…"}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.reply({
"kind": "plan",
"requestId": "a1b2c3d4",
"approve": true,
"feedback": "…"
});POST/agent/steerInterrupt a running turn
Slips a message into a turn already under way, without stopping it. This is how you redirect an agent mid-thought rather than waiting for it to finish being wrong. Give the message an id, and sending it again after a lost answer is met with what became of it the first time rather than saying it twice.
What you send
| Field | Type | Where |
|---|---|---|
conversationIdrequiredWhich running conversation to interrupt | string | body |
textrequiredWhat to say to it | string | body |
messageIdYour id for this message | string | body |
attachmentsFiles to send with it, as… | string[] | body |
mentionsWorkspace paths the message mentions with… | string[] | body |
editorContextWhat you have open, folded in… | object | body |
filerequiredThe file open in the editor,… | string | body |
startLineFirst line of the selection, counting… | integer | body |
endLineLast line of the selection, counting… | integer | body |
selectionThe selected text itself | string | body |
What comes back
| Field | Type |
|---|---|
deliveredWhat became of the message: it… | "started" | "steered" | "queued" |
runThe run the message is in:… | string |
duplicateThe sandbox had already taken a… | true |
curl -X POST "$SANDBOX/agent/steer" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"conversationId":"nightly-changelog","text":"export const start = () => listen(PORT);\n","messageId":"a1b2c3d4","attachments":["…","…"],"mentions":["…","…"],"editorContext":{"file":"…","startLine":1,"endLine":1,"selection":"…"}}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.steer({
"conversationId": "nightly-changelog",
"text": "export const start = () => listen(PORT);\n",
"messageId": "a1b2c3d4",
"attachments": [
"…",
"…"
],
"mentions": [
"…",
"…"
],
"editorContext": {
"file": "…",
"startLine": 1,
"endLine": 1,
"selection": "…"
}
});POST/agent/stopStop a turn now
Cancels the running turn inside the sandbox. Whatever it had already written to disk stays written, and whatever waits in the conversation's queue is held there, for everyone, until somebody resumes it. Name the run you mean: a stop that arrives after that run has ended cancels nothing, rather than whatever turn started next.
What you send
| Field | Type | Where |
|---|---|---|
conversationIdrequiredWhich conversation's running turn to cancel | string | body |
runrequiredThe run you mean to cancel,… | string | body |
What comes back
| Field | Type |
|---|---|
stoppedWhether a turn was cancelled | boolean |
runningThe run that is live instead… | string |
curl -X POST "$SANDBOX/agent/stop" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"conversationId":"nightly-changelog","run":"run_8c2f41d9"}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.stop({
"conversationId": "nightly-changelog",
"run": "run_8c2f41d9"
});POST/agent/queue/editReword a waiting message
Changes what a message waiting in the conversation's queue says, keeping its place. Name the revision you read it at: if somebody changed it since, on this device or another, nothing is changed and you are told so.
What you send
| Field | Type | Where |
|---|---|---|
conversationIdrequiredWhose queue | string | body |
idrequiredWhich waiting message | string | body |
revisionrequiredThe message's revision as you read… | integer | body |
textrequiredWhat the message should say instead | string | body |
What comes back
| Field | Type |
|---|---|
itemsWhat waits, in the order it… | object[] |
idThe message's id: what its sender… | string |
textThe words, as they will go… | string |
attachmentsFiles that go with it, as… | string[] |
voiceWho it is from: a person,… | "person" | "sandbox" | "agent" |
queuedAtWhen it joined the queue, in… | number |
revisionThe queue's revision when this message… | integer |
revisionMoves with every change to the… | integer |
pausedWhy nothing goes out by itself:… | "stopped" | "refused" | "scheduled" |
untilWhen scheduled messages go out by… | number |
afterThe conversation whose finished work must… | string |
curl -X POST "$SANDBOX/agent/queue/edit" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"conversationId":"nightly-changelog","id":"a1b2c3d4","revision":0,"text":"export const start = () => listen(PORT);\n"}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.queueEdit({
"conversationId": "nightly-changelog",
"id": "a1b2c3d4",
"revision": 0,
"text": "export const start = () => listen(PORT);\n"
});POST/agent/queue/removeTake back a waiting message
Removes a message from the conversation's queue before the agent gets it. Name the revision you read it at: a message somebody reworded since is left alone, so you never take back words you have not seen.
What you send
| Field | Type | Where |
|---|---|---|
conversationIdrequiredWhose queue | string | body |
idrequiredWhich waiting message | string | body |
revisionrequiredThe message's revision as you read… | integer | body |
What comes back
| Field | Type |
|---|---|
itemsWhat waits, in the order it… | object[] |
idThe message's id: what its sender… | string |
textThe words, as they will go… | string |
attachmentsFiles that go with it, as… | string[] |
voiceWho it is from: a person,… | "person" | "sandbox" | "agent" |
queuedAtWhen it joined the queue, in… | number |
revisionThe queue's revision when this message… | integer |
revisionMoves with every change to the… | integer |
pausedWhy nothing goes out by itself:… | "stopped" | "refused" | "scheduled" |
untilWhen scheduled messages go out by… | number |
afterThe conversation whose finished work must… | string |
curl -X POST "$SANDBOX/agent/queue/remove" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"conversationId":"nightly-changelog","id":"a1b2c3d4","revision":0}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.queueRemove({
"conversationId": "nightly-changelog",
"id": "a1b2c3d4",
"revision": 0
});POST/agent/queue/resumeLet waiting messages go
Releases a queue held after a stop or a refusal: what waits goes out now as one turn when nothing is running, or after the running turn otherwise. Name who serves that turn when the conversation has been re-pointed since the messages were queued.
What you send
| Field | Type | Where |
|---|---|---|
conversationIdrequiredWhose queue to let go | string | body |
routingWho serves the turn the waiting… | object | body |
agentrequiredWhich provider serves the re-run | string | body |
harnessrequiredWhich agentic loop runs it | "native" | "claude-code" | body |
accountWhich of that provider's accounts pays… | string | body |
modelWhich model | string | body |
carryWhen the account changes, keep the… | boolean | body |
What comes back
| Field | Type |
|---|---|
runThe turn the waiting messages started | string |
queueThe queue the release left: what… | object |
itemsWhat waits, in the order it… | object[] |
idThe message's id: what its sender… | string |
textThe words, as they will go… | string |
attachmentsFiles that go with it, as… | string[] |
voiceWho it is from: a person,… | "person" | "sandbox" | "agent" |
queuedAtWhen it joined the queue, in… | number |
revisionThe queue's revision when this message… | integer |
revisionMoves with every change to the… | integer |
pausedWhy nothing goes out by itself:… | "stopped" | "refused" | "scheduled" |
untilWhen scheduled messages go out by… | number |
afterThe conversation whose finished work must… | string |
curl -X POST "$SANDBOX/agent/queue/resume" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"conversationId":"nightly-changelog","routing":{"agent":"…","harness":"native","account":"work","model":"claude-sonnet-4-6","carry":true}}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.queueResume({
"conversationId": "nightly-changelog",
"routing": {
"agent": "…",
"harness": "native",
"account": "work",
"model": "claude-sonnet-4-6",
"carry": true
}
});POST/agent/queue/scheduleReschedule waiting messages
Books what waits in the conversation's queue to go out by itself at another instant, or once another conversation has finished and its work has landed, holding it until then. Works on a queue that is held for any reason, or on messages waiting behind a running turn. A time already past, or a conversation with nothing left to land, lets them go now.
What you send
| Field | Type | Where |
|---|---|---|
conversationIdrequiredWhose queue | string | body |
sendAtSend what waits at this instant… | integer | body |
sendAfterSend what waits once that conversation… | string | body |
What comes back
| Field | Type |
|---|---|
itemsWhat waits, in the order it… | object[] |
idThe message's id: what its sender… | string |
textThe words, as they will go… | string |
attachmentsFiles that go with it, as… | string[] |
voiceWho it is from: a person,… | "person" | "sandbox" | "agent" |
queuedAtWhen it joined the queue, in… | number |
revisionThe queue's revision when this message… | integer |
revisionMoves with every change to the… | integer |
pausedWhy nothing goes out by itself:… | "stopped" | "refused" | "scheduled" |
untilWhen scheduled messages go out by… | number |
afterThe conversation whose finished work must… | string |
curl -X POST "$SANDBOX/agent/queue/schedule" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"conversationId":"nightly-changelog","sendAt":1,"sendAfter":"…"}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.queueSchedule({
"conversationId": "nightly-changelog",
"sendAt": 1,
"sendAfter": "…"
});POST/agent/resumeRun a refused turn again
Sends the same turn again when the model provider's allowance refused it, with everything it originally carried except who serves it: the caller may name a different provider, harness or account, which is the usual answer to a spent allowance. It repeats the request rather than adding a new message to the conversation, so pressing it twice costs nothing and the agent is never told to continue work it has not started.
What you send
| Field | Type | Where |
|---|---|---|
conversationIdrequiredWhich conversation's held turn to run… | string | body |
routingWho serves the re-run, when the… | object | body |
agentrequiredWhich provider serves the re-run | string | body |
harnessrequiredWhich agentic loop runs it | "native" | "claude-code" | body |
accountWhich of that provider's accounts pays… | string | body |
modelWhich model | string | body |
carryWhen the account changes, keep the… | boolean | body |
What comes back
| Field | Type |
|---|---|
runThe id of the run that… | string |
curl -X POST "$SANDBOX/agent/resume" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"conversationId":"nightly-changelog","routing":{"agent":"…","harness":"native","account":"work","model":"claude-sonnet-4-6","carry":true}}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.resume({
"conversationId": "nightly-changelog",
"routing": {
"agent": "…",
"harness": "native",
"account": "work",
"model": "claude-sonnet-4-6",
"carry": true
}
});POST/agent/accountMove a conversation to another account
Points the conversation at another connected account of the provider it runs on, for every turn from now on. It starts nothing by itself: with `run`, a turn held by a spent allowance or a stop runs again at once on that account, which is how a refused turn continues elsewhere. Without `carry` the next turn opens a fresh session seeded from the record.
What you send
| Field | Type | Where |
|---|---|---|
conversationIdrequiredWhich conversation to move | string | body |
accountrequiredWhich of the conversation's provider's connected… | string | body |
carryKeep the provider session across the… | boolean | body |
runAlso run a turn that a… | boolean | body |
What comes back
| Field | Type |
|---|---|
runThe run that re-ran a held… | string |
curl -X POST "$SANDBOX/agent/account" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"conversationId":"nightly-changelog","account":"work","carry":true,"run":true}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.switchAccount({
"conversationId": "nightly-changelog",
"account": "work",
"carry": true,
"run": true
});POST/agent/rewindGo back to an earlier message
Puts the files back as they stood at that point, drops every message after it, and forgets what the model remembered, so the next thing you say starts from there cleanly. Refused while a turn is running, because a restore cannot overwrite files an agent is editing; refused for a message with no saved state to return to; and refused when that position no longer holds the message you named, because the conversation moved since you read it.
What you send
| Field | Type | Where |
|---|---|---|
conversationIdrequiredWhich conversation to rewind | string | body |
indexrequiredWhich message to go back to,… | integer | body |
messageIdrequiredThe id of the message at… | string | body |
What comes back
| Field | Type |
|---|---|
snapshotThe saved point the files were… | string |
droppedHow many messages were removed | integer |
curl -X POST "$SANDBOX/agent/rewind" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"conversationId":"nightly-changelog","index":0,"messageId":"a1b2c3d4"}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.rewind({
"conversationId": "nightly-changelog",
"index": 0,
"messageId": "a1b2c3d4"
});GET/agent/commandsShortcut commands the agent knows
The commands a provider published the last time one of its turns ran, so a composer can offer them before this conversation has run anything. A running turn's own list wins over this one.
What you send
| Field | Type | Where |
|---|---|---|
agentWhose commands to read | string | query |
What comes back
| Field | Type |
|---|---|
commandsThe shortcut commands, as the provider… | object[] |
nameWhat to type, without the leading… | string |
descriptionWhat it does | string |
hintWhat its argument should look like,… | string |
curl "$SANDBOX/agent/commands" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.commands();POST/agent/route-chatChoose what a new chat opens on
Reads a new chat's opening message once and answers whichever of two questions it still has: the model, effort and account that conversation should run on, from what is connected and still has allowance left, and which of this sandbox's personas should handle it. `model` and `persona` on the ask say which halves to answer, and only those are put to the model. Asked once per chat, on the message actually sent, and never again: every turn after it runs on what the chat is wearing, which you are free to change. Answers with nothing, and a reason, whenever it cannot choose — a chat is never held up by this.
What you send
| Field | Type | Where |
|---|---|---|
promptrequiredThe message a new chat is… | string | body |
pathsWorkspace paths the message names: uploads,… | string[] | body |
folderThe workspace folder the chat was… | string | body |
editorContextWhether the message carries a file… | boolean | body |
planModeWhether the chat opens in plan… | boolean | body |
modelrequiredWhether to choose the model, effort… | boolean | body |
personarequiredWhether to choose the persona: true… | boolean | body |
What comes back
| Field | Type |
|---|---|
personaThe persona half's answer, present only… | object |
idThe persona this message belongs to,… | string |
reasonWhy, in the one clause a… | string |
modelThe model half's answer, present only… | object |
pickWhat the conversation should run on,… | object |
providerWhich provider serves the conversation | string |
modelWhich of its models | string |
effortHow hard it should think, where… | string |
accountWhich connected account pays, by its… | string |
reasonWhy, in the one clause a… | string |
judgeWhich model answered, as `provider:model`, so… | string |
curl -X POST "$SANDBOX/agent/route-chat" \
-H "x-intentic-control: $INTENTIC_TOKEN" \
-H "content-type: application/json" \
-d '{"prompt":"Update the changelog for the last five commits.","paths":["src/app.ts","README.md"],"folder":"…","editorContext":true,"planMode":true,"model":true,"persona":true}'import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.routeChat({
"prompt": "Update the changelog for the last five commits.",
"paths": [
"src/app.ts",
"README.md"
],
"folder": "…",
"editorContext": true,
"planMode": true,
"model": true,
"persona": true
});GET/agent/refusalsThe last time each provider said no
What each model provider most recently refused and why. Read this alongside an account's usage: the usage says how full it was when last checked, this says whether it has since started turning work away.
What you send
Nothing. Call it as it is.
What comes back
| Field | Type |
|---|---|
refusalsThe most recent refusal per provider | object |
curl "$SANDBOX/agent/refusals" \
-H "x-intentic-control: $INTENTIC_TOKEN"import { sandbox } from "@intentic/sandbox-client";
const result = await sandbox.agent.refusals();