This topic describes the main ways to send prompts to the Cortex Code Agent SDK: single-prompt queries
when you want query() to manage the session lifecycle for you, streamed input for incremental prompt
delivery, and multi-turn sessions for interactive conversations that maintain context across exchanges.
The query() function is the simplest way to use the SDK. It can send either a single prompt string or an async
iterable of SDK user messages, and it streams back events until the agent produces a ResultMessage. In this mode,
“single prompt” refers to the input pattern: output still streams normally.
import { query } from"cortex-code-agent-sdk";
forawait (const message ofquery({
prompt: "Explain how the auth module works",
options: { cwd: process.cwd() },
})) {
if (message.type === "assistant") {
for (const block of message.content) {
if (block.type === "text") process.stdout.write(block.text);
}
}
}
import asyncio
from cortex_code_agent_sdk import query, AssistantMessage, CortexCodeAgentOptions
asyncdefmain():
asyncfor message in query(
prompt="Explain how the auth module works",
options=CortexCodeAgentOptions(cwd="."),
):
ifisinstance(message, AssistantMessage):
for block in message.content:
ifhasattr(block, "text"):
print(block.text, end="")
asyncio.run(main())
The query() function manages the full session lifecycle for you: it creates a session, sends the prompt,
yields events, and closes the session when the result arrives or the iterator is exhausted.
This is different from maxTurns / max_turns. A single-prompt query still allows the agent to take as many
internal turns as needed, subject to your configured turn limit. Setting maxTurns: 1 or max_turns=1 is a
separate constraint that limits the agent to one internal turn and can produce an error_max_turns result.
For conversations that require multiple exchanges, use a session. The agent retains context between turns, so
later prompts can reference files read, analysis performed, and topics discussed in earlier turns.
import { createCortexCodeSession } from"cortex-code-agent-sdk";
const session = awaitcreateCortexCodeSession({ cwd: process.cwd() });
// First turnawait session.send("Read the database connection module");
forawait (const event of session.stream()) {
if (event.type === "assistant") {
for (const b of event.content) {
if (b.type === "text") process.stdout.write(b.text);
}
}
if (event.type === "result") break;
}
// Second turn -- context from the first turn is preservedawait session.send("What error handling patterns does it use?");
forawait (const event of session.stream()) {
if (event.type === "assistant") {
for (const b of event.content) {
if (b.type === "text") process.stdout.write(b.text);
}
}
if (event.type === "result") break;
}
await session.close();
from cortex_code_agent_sdk import CortexCodeSDKClient, CortexCodeAgentOptions, AssistantMessage, ResultMessage
asyncwith CortexCodeSDKClient(CortexCodeAgentOptions(cwd=".")) as client:
# First turnawait client.query("Read the database connection module")
asyncfor msg in client.receive_response():
ifisinstance(msg, AssistantMessage):
for block in msg.content:
ifhasattr(block, "text"):
print(block.text, end="")
# Second turn -- context from the first turn is preservedawait client.query("What error handling patterns does it use?")
asyncfor msg in client.receive_response():
ifisinstance(msg, AssistantMessage):
for block in msg.content:
ifhasattr(block, "text"):
print(block.text, end="")
You can resume a conversation from a previous session. The agent loads the prior conversation history and continues
where it left off.
import { createCortexCodeSession } from"cortex-code-agent-sdk";
// Continue the most recent conversationconst session = awaitcreateCortexCodeSession({
cwd: process.cwd(),
continue: true,
});
await session.send("What were we working on?");
forawait (const event of session.stream()) {
if (event.type === "result") break;
}
await session.close();
from cortex_code_agent_sdk import CortexCodeSDKClient, CortexCodeAgentOptions
# Continue the most recent conversationasyncwith CortexCodeSDKClient(
CortexCodeAgentOptions(continue_conversation=True)
) as client:
await client.query("What were we working on?")
asyncfor msg in client.receive_response():
pass# process messages
Forking creates a new session that starts with the full conversation history of an existing session. The original
session is not modified. This is useful for exploring alternative approaches without losing the original conversation.
import { createCortexCodeSession } from"cortex-code-agent-sdk";
const forked = awaitcreateCortexCodeSession({
cwd: process.cwd(),
resume: "previous-session-id",
forkSession: true,
});
await forked.send("Let's try a different approach");
forawait (const event of forked.stream()) {
if (event.type === "result") break;
}
await forked.close();
from cortex_code_agent_sdk import CortexCodeSDKClient, CortexCodeAgentOptions
asyncwith CortexCodeSDKClient(
CortexCodeAgentOptions(resume="previous-session-id", fork_session=True)
) as client:
await client.query("Let's try a different approach")
asyncfor msg in client.receive_response():
pass# process messages
Your application can request an interrupt while the agent is processing a turn. This has the same effect as pressing
Esc in the CLI. The session stays alive for further prompts.
Call the interrupt() method to send an interrupt request directly:
import { createCortexCodeSession } from"cortex-code-agent-sdk";
const session = awaitcreateCortexCodeSession({ cwd: process.cwd() });
await session.send("Analyze every file in this large codebase");
// Interrupt after 10 secondssetTimeout(() => session.interrupt(), 10_000);
forawait (const event of session.stream()) {
if (event.type === "result") break;
}
// Session is still alive -- send another promptawait session.send("Just summarize the top-level structure instead");
forawait (const event of session.stream()) {
if (event.type === "result") break;
}
await session.close();
import asyncio
from cortex_code_agent_sdk import CortexCodeSDKClient, CortexCodeAgentOptions, ResultMessage
asyncwith CortexCodeSDKClient(CortexCodeAgentOptions(cwd=".")) as client:
await client.query("Analyze every file in this large codebase")
# Interrupt after 10 secondsasyncdefinterrupt_later():
await asyncio.sleep(10)
await client.interrupt()
asyncio.create_task(interrupt_later())
asyncfor msg in client.receive_response():
pass# Session is still alive -- send another promptawait client.query("Just summarize the top-level structure instead")
asyncfor msg in client.receive_response():
pass
You can also pass an abort signal at session creation time. When the signal fires, the SDK automatically sends the
same interrupt request.
import { createCortexCodeSession } from"cortex-code-agent-sdk";
const controller = newAbortController();
const session = awaitcreateCortexCodeSession({
cwd: process.cwd(),
abortController: controller,
});
await session.send("Analyze every file in this large codebase");
// Trigger interrupt from anywheresetTimeout(() => controller.abort(), 10_000);
forawait (const event of session.stream()) {
if (event.type === "result") break;
}
await session.close();
import asyncio
from cortex_code_agent_sdk import CortexCodeSDKClient, CortexCodeAgentOptions
abort_event = asyncio.Event()
asyncwith CortexCodeSDKClient(
CortexCodeAgentOptions(cwd=".", abort_event=abort_event)
) as client:
await client.query("Analyze every file in this large codebase")
# Trigger interrupt from anywhereasyncdeftrigger_abort():
await asyncio.sleep(10)
abort_event.set()
asyncio.create_task(trigger_abort())
asyncfor msg in client.receive_response():
pass
Note
In TypeScript, pass an AbortController whose abort() method triggers the interrupt request. In Python, pass
an asyncio.Event whose set() method triggers the interrupt request. In both cases, the session stays alive
after interruption.
Where your configuration of Cortex Code uses a model provided on the
Model and Service Pass-Through Terms,
your use of that model is further subject to the terms for that model on that page.
The data classification of inputs and outputs are as set forth in the following table.