Chat with a project
You drive a project by chatting with it. Aura reads files, edits inputs, runs the solver, and replies. One message plus everything it triggers is a turn.
Send a message and wait
Section titled “Send a message and wait”const reply = await aura.chat(project.id, "Solve this and summarize the result.");console.log(reply.content);reply = await aura.chat(project.id, "Solve this and summarize the result.")print(reply.content)# one message in, one reply out, then exitaura chat --project <project-id> --message "Solve this and summarize the result."
# or the interactive terminal UIaura chat --project <project-id>How the wait works
Section titled “How the wait works”chat() connects to the project WebSocket, dispatches the message, and returns the completed
reply. In an environment that blocks WebSockets it falls back to polling /chat/sync — same
result, later. It gives up after five minutes; the timeout and the fallback’s poll interval are
both adjustable.
Two details matter on a project several callers share:
- You get your own reply. The match is on the dispatched message’s sequence number, not on a message count, so another caller’s turn is never handed back to you.
- The wait is pinned to one conversation — the one your dispatch landed in. Activating or creating another conversation mid-turn does not redirect it.
const reply = await aura.chat(project.id, "Re-solve with a 30 minute budget.", { conversationId, // omit to use the project's active conversation pollIntervalMs: 2000, timeoutMs: 15 * 60_000, // long solves need a longer wait});reply = await aura.chat( project.id, "Re-solve with a 30 minute budget.", conversation_id=conversation_id, # omit for the active conversation poll_interval=2.0, timeout=15 * 60,)Watching a turn as it happens
Section titled “Watching a turn as it happens”onDelta receives assistant text as it is generated, and onToolActivity fires as the agent
starts and finishes tools. Both are no-ops on the poll fallback, so treat them as progress
reporting rather than a delivery guarantee — chat() still returns the completed reply.
await aura.chat(project.id, "Solve this and summarize the result.", { onDelta: (text) => process.stdout.write(text), onToolActivity: (activity) => console.error(`[${activity.status}] ${activity.tool}`),});Choosing a conversation
Section titled “Choosing a conversation”A project can hold several conversations. Without one named, chat uses the project’s active conversation.
const conversation = await aura.createConversation(project.id, "budget sweep");
await aura.chat(project.id, "Try a 20% larger fleet.", { conversationId: conversation.id });
const all = await aura.listConversations(project.id);conversation = await aura.create_conversation(project.id, "budget sweep")
await aura.chat(project.id, "Try a 20% larger fleet.", conversation_id=conversation.id)
all_conversations = await aura.list_conversations(project.id)aura conversation list --project <project-id>aura chat --project <project-id> --conversation <conversation-id>
# start a fresh threadaura chat --project <project-id> --new-conversation --title "budget sweep"A session pins one conversation id and sends it with every turn, so the transcript stays in sync even if the project’s active conversation changes elsewhere.
Stopping a turn
Section titled “Stopping a turn”import { AuraTurnCancelledError } from "@strangeworks/aura-sdk";
const controller = new AbortController();
// e.g. a Ctrl-C handler — stop both sidesprocess.on("SIGINT", () => { void aura.cancel(project.id, conversationId); controller.abort();});
const reply = await aura .chat(project.id, "Solve this.", { conversationId, signal: controller.signal }) .catch((err) => { if (err instanceof AuraTurnCancelledError) return err.partialContent; throw err; });from aura_sdk import AuraTurnCancelledError, AuraTurnTimeoutError
try: reply = await aura.chat(project.id, "Solve this.", timeout=300)except AuraTurnTimeoutError as timed_out: # still running server-side await aura.cancel(project.id, timed_out.conversation_id) raiseexcept AuraTurnCancelledError as cancelled: partial = cancelled.partial_contentWhile the agent is working, Esc (or Ctrl-C) cancels the turn and keeps you in the session; a
second Ctrl-C quits. This stops the turn server-side, and whatever the agent produced first is
shown dimmed under ⊘ cancelled. Ctrl-C during --message does the same and exits 130.
cancel(projectId, conversationId) returns whether anything was stopped. Omitting the conversation
id cancels any running turn in the project, including one someone else started.
Driving the poll yourself
Section titled “Driving the poll yourself”To avoid blocking, dispatch the message and read state on your own schedule.
const dispatched = await aura.sendMessage(project.id, { content: "Solve this." });
for (;;) { const status = await aura.getAgentStatus(project.id); if (!status.running) break; await new Promise((r) => setTimeout(r, 2000));}
const state = await aura.getConversationState(project.id, dispatched.message.conversation_id);const reply = state.messages.at(-1);dispatched = await aura.send_message(project.id, "Solve this.")
while (await aura.get_agent_status(project.id)).running: await asyncio.sleep(2)
state = await aura.get_conversation_state(project.id, dispatched.message.conversation_id)reply = state.messages[-1]The interactive TUI
Section titled “The interactive TUI”aura chat --project <id> without --message opens a full-screen terminal UI: a pinned header, a
scrolling transcript, and a composer at the bottom. It uses the alternate screen buffer, so your
shell’s scrollback is untouched, and prints the command to resume the session on exit.
| Key | Does |
|---|---|
enter |
Send |
shift+enter (or alt+enter) |
Newline — compose a multi-line message |
↑ ↓ |
Recall history; move between lines within a multi-line message |
pgup pgdn, wheel |
Scroll the transcript |
esc |
Cancel the running turn, stay in the session |
/help, /exit |
In-session commands — a leading / acts locally rather than sending a turn |
ctrl-c twice, or exit |
Quit |
The CLI reference has the full key list, including word motion, line editing and the quick-reply picker.
- Read results — executions, output files, the solution.
- Errors — the three ways a turn can end badly, and which is which.