Skip to main content
Conversations & Sessions

Session Control

By default the SDK starts a brand-new session on every call (TypeScript's query()) or connection (Python's QoderSDKClient; Java's client.query() / client.openSession()). A few fields in options let you specify a session ID, resume a historical session, or fork an existing one.

Concepts

A session corresponds to a persisted conversation history on the CLI side (including context, tool call records, compaction boundaries, etc.), identified by a UUID. The init system message contains the current session_id, which also serves as the anchor point for subsequent resume/fork operations. The authentication in the examples below can be replaced with whichever method your project uses; see SDK Authentication.

Creating New Sessions

Default

Without passing any session-related fields, a new session is created each time:
import { accessTokenFromEnv, query } from '@qoder-ai/qoder-agent-sdk';

const q = query({
  prompt: 'Hello',
  options: { auth: accessTokenFromEnv() },
});

Specifying a Session ID (TypeScript, Python)

Let the caller determine the session UUID (suitable when the host manages its own session index):
import { randomUUID } from 'node:crypto';

const sessionId = randomUUID();
const q = query({
  prompt: 'Hello',
  options: {
    auth: accessTokenFromEnv(),
    sessionId,
  },
});

Resuming Sessions

Resume by ID

const q = query({
  prompt: 'Continue the previous conversation',
  options: {
    auth: accessTokenFromEnv(),
    resume: 'previous-session-id',
  },
});
Java's resume(...) accepts only IDs made of ASCII letters, digits, _, and -; any other character makes build() throw InvalidOptionsException.

Resume the Most Recent

When you don't know the session ID, use continue: true (TypeScript) / continue_conversation=True (Python) / continueSession(true) (Java) to pick up the most recently modified session:
const q = query({
  prompt: 'Continue',
  options: {
    auth: accessTokenFromEnv(),
    continue: true,
  },
});
Do not pass resume together with continue (continue_conversation in Python). In Java, setting both resume(...) and continueSession(true) makes build() throw InvalidOptionsException.

Forking Sessions

Derive a new session from an existing one, preserving the original context but obtaining a new session ID. The original session is unaffected:
const q = query({
  prompt: 'Based on the prior context, explore a different direction',
  options: {
    auth: accessTokenFromEnv(),
    resume: 'source-session-id',
    forkSession: true,
  },
});
Java's forkSession(true) must be combined with resume(...) or continueSession(true); otherwise build() throws InvalidOptionsException. To specify an ID for the forked new session (TypeScript, Python):
options: {
  auth: accessTokenFromEnv(),
  resume: 'source-session-id',
  forkSession: true,
  sessionId: 'my-new-session-id',
}

Field Reference

Field (TypeScript / Python / Java)TypeBehavior
sessionId / session_id / —string / strAlone: create a new session with this ID; with the fork field: the ID of the forked session
resume / resume / resume(String)string / str / StringThe session ID to resume
continue / continue_conversation / continueSession(boolean)boolean / bool / booleantrue resumes the most recent session
forkSession / fork_session / forkSession(boolean)boolean / bool / booleanUsed with resume to fork instead of continuing

Opening sessions with SessionRepository (Java)

The Java options above also apply to client.openSession(options). You can also open a multi-turn session directly through the SessionRepository returned by client.sessions():
Java
SessionRepository sessions = client.sessions();

QoderSession resumed = sessions.continueSession("previous-session-id", options)
        .toCompletableFuture().join();
QoderSession forked = sessions.fork("source-session-id", options)
        .toCompletableFuture().join();
continueSession(null, options) continues the most recent session; the session ID passed to fork must not be null. Each call starts a new CLI process, and the caller closes the returned session. The repository's list(), get(), and delete() require external session storage; see External session storage.

Getting the Current Session ID

Listen for the init system message; in Python, ResultMessage also carries session_id—either works for bookkeeping. In Java, read sessionId() from the initialization() result; messages also carry the session ID in sessionId():
for await (const msg of q) {
  if (msg.type === 'system' && msg.subtype === 'init') {
    console.log('session_id:', msg.session_id);
  }
}

User data directory

The user data directory stores session history, resources, logs, and other user-level CLI data. Set QODER_CONFIG_DIR through options.env (putEnvironment(...) in Java) to select this directory:
import { accessTokenFromEnv, query } from '@qoder-ai/qoder-agent-sdk';

const q = query({
  prompt: 'Analyze this repository',
  options: {
    auth: accessTokenFromEnv(),
    env: {
      ...process.env,
      QODER_CONFIG_DIR: '/var/lib/my-agent/qoder',
    },
  },
});
Java's CLI subprocess inherits only PATH by default (plus system directory variables such as TEMP on Windows), so you do not need to spread process.env as in TypeScript. Pass any other variable the CLI needs explicitly; see Subprocess environment.