Work with Sessions
Most real tasks are conversations, not single commands. A session is how the Syntic Agent SDK keeps Amara’s memory of a task alive across multiple turns. Rather than starting cold each time, you continue an existing exchange so Amara remembers the files it read, the decisions it made, and the results of earlier steps. This turns a series of isolated prompts into a coherent working relationship.
Session identifiers
When you begin a query, the SDK assigns the exchange a session identifier. Capture it from the stream and you hold a handle to that conversation. Passing the identifier back on a later query tells Amara to resume the same thread, complete with its accumulated context.
import { query } from "@syntic/agent-sdk";
let sessionId: string | undefined;
for await (const message of query({
prompt: "Read the config loader and explain how it resolves defaults.",
options: { cwd: process.cwd() },
})) {
if (message.type === "system") sessionId = message.sessionId;
if (message.type === "result") console.log(message.result);
}
// Continue the same conversation later in the process.
for await (const message of query({
prompt: "Now add support for environment overrides.",
options: { cwd: process.cwd(), resume: sessionId },
})) {
if (message.type === "result") console.log(message.result);
}Continuing a conversation
The follow-up prompt in the example above does not restate what the config loader is — Amara already knows, because the session carried that context forward. This is the difference between a stateless call and a stateful session: the second turn builds directly on the first.
import asyncio
from syntic_agent_sdk import query
async def main():
session_id = None
async for message in query(
prompt="Read the config loader and explain how it resolves defaults.",
options={"cwd": "."},
):
if message.type == "system":
session_id = message.session_id
async for message in query(
prompt="Now add support for environment overrides.",
options={"cwd": ".", "resume": session_id},
):
if message.type == "result":
print(message.result)
asyncio.run(main())In-memory versus durable
The sessions described here live in the memory of a single process — ideal for a script or a request that spans several turns. When you need a conversation to survive a restart or move between servers, you store its state externally. That is the subject of Persist Sessions, which builds directly on the identifiers you learned about here.