All three SDKs run the Agent in a local qodercli process. The SDK exchanges JSONL messages and control requests with qodercli; qodercli calls the model service and executes approved tools.
One local runtime session is owned by one qodercli process. A string-based
The default local session starts in this order:
Each Java SDK release pins one qodercli version. When no CLI path is specified, the first start downloads that version's archive, verifies its byte size and SHA-256, and installs it under
Replace
For the default process transport, each protocol message is one JSON object on one line. The SDK reads and writes this JSON Lines (JSONL) stream; applications should use the typed SDK messages rather than parse process output directly.
There are two logical traffic types:
qodercli repeatedly calls the model until the task finishes or reaches a configured limit. Tool results from one iteration become context for the next:
qodercli presents the model with only the tools available to the session:
qodercli owns the live conversation state. The SDK owns the application callbacks and converts protocol objects into TypeScript, Python, or Java message types.
As a session grows, qodercli monitors its model context usage. When needed, it compacts older history into a smaller representation before the next model request. This keeps a long task moving without requiring the application to rebuild the prompt, although important details should still be stored in files or explicit session state instead of relying on unlimited conversation memory.
When session persistence is enabled, qodercli can store a transcript and resume it later. Resume and checkpoint behavior is described in Session Storage and Checkpoint.
Applications should keep consuming messages until they receive a
The local process boundary does not mean the entire task stays on the local machine.
The runtime protocol is shared by all three SDKs, but each exposes a language-appropriate session API:
Architecture
query() normally closes that session after the final result. Multi-turn APIs keep it alive while the application sends more input.
Startup and handshake
The default local session starts in this order:
- Select the runtime. The SDK uses an explicitly configured qodercli path when provided; otherwise it finds the compatible runtime shipped with the package or available in the environment. The Java SDK does not bundle a runtime; it downloads and caches a pinned version instead. See Managed CLI (Java).
- Start SDK mode. The SDK launches qodercli with structured streaming input and output enabled. The process inherits the configured working directory and environment.
- Transfer authentication. The SDK resolves the selected authentication method and provides qodercli with a temporary, one-time authentication payload instead of writing the credential into the message stream.
- Initialize capabilities. Before sending the first task, the SDK and qodercli exchange an
initializecontrol request. This registers SDK-provided hooks, agents, skills, and in-process MCP servers, then returns the runtime capabilities and available resources. - Send the task. After initialization succeeds, the SDK sends the first user message and begins yielding qodercli messages to the application.
Managed CLI (Java)
Each Java SDK release pins one qodercli version. When no CLI path is specified, the first start downloads that version's archive, verifies its byte size and SHA-256, and installs it under ~/.qoder/runtimes/managed. Later starts reuse the cache. The SDK does not look up the latest version and never upgrades automatically. Managed platforms are macOS arm64/x64, Linux x64/arm64 (glibc and musl), and Windows x64. Other platforms, including Windows arm64, are not managed. Windows x64 requires Windows 10 1809 / Windows Server 2019 or later. The SDK does not check the OS version, so on older systems specify the CLI with qoderCliPath or QODERCLI_PATH.
At startup the SDK picks the CLI in this order and stops at the first match:
- The path set with
SessionOptions.Builder.qoderCliPath(Path). An invalid path fails immediately. - The
QODERCLI_PATHenvironment variable. - The managed CLI: reuse the cache, otherwise install it. An install failure raises
RuntimeInstallException; the SDK does not fall back to another CLI. This step is skipped when the current platform is not managed. - A same-version CLI left under
~/.qoder/runtimes/by an older SDK. ~/.local/bin/qodercli, thenPATH.
VERSION with the SDK version your application depends on, and use the actual path to that JAR. Each SDK version pins its own CLI version, so prewarming with a different JAR may cache a CLI your application does not use.
You can also ship the pinned archive with the application, use an enterprise mirror, or call QoderClient.installRuntime() to surface install problems early. For all settings, see ManagedRuntimeOptions.
SDK and qodercli communication
For the default process transport, each protocol message is one JSON object on one line. The SDK reads and writes this JSON Lines (JSONL) stream; applications should use the typed SDK messages rather than parse process output directly.
- Agent messages carry user input, assistant content, tool activity, progress, and the final result.
- Control messages perform initialization, interruption, session operations, permission decisions, hooks, and in-process MCP calls. A
request_idpairs each control response with its request, so several operations can be in flight without confusing their results.
The qodercli agent loop
qodercli repeatedly calls the model until the task finishes or reaches a configured limit. Tool results from one iteration become context for the next:
- Build context. qodercli combines the task, conversation history, system instructions, workspace configuration, available tools, and relevant hook context.
- Ask the model. Model output is streamed. Text can be surfaced immediately, while complete tool requests are sent to the execution pipeline.
- Authorize the action. qodercli applies tool availability, allow/ask/deny rules, permission callbacks, and pre-tool hooks. A denied tool produces a tool result explaining the denial; it is not executed.
- Execute tools. The runtime dispatches approved built-in tools, MCP tools, or subagents and captures their results. Independent tool calls can run concurrently when it is safe to do so.
- Continue with evidence. Tool results are appended to the conversation, and the model receives another turn to inspect the outcome and choose the next action.
- Finish or stop. The loop ends when the model has no more tool calls, a completion hook accepts the result, or a configured limit, interruption, cancellation, or error stops the task.
Tools, MCP, and subagents
qodercli presents the model with only the tools available to the session:
- Built-in tools read and edit files, search the project, run commands, and perform other local operations.
- MCP tools can come from an external MCP server or from an in-process server hosted by the SDK application. For an in-process server, qodercli sends an MCP control request to the SDK, the SDK calls the registered server, and the response returns over the same control channel.
- Subagents run a delegated task with their own prompt and context, usually with a narrower tool set. Their final output returns to the parent Agent as a tool result.
Context and session state
qodercli owns the live conversation state. The SDK owns the application callbacks and converts protocol objects into TypeScript, Python, or Java message types.
As a session grows, qodercli monitors its model context usage. When needed, it compacts older history into a smaller representation before the next model request. This keeps a long task moving without requiring the application to rebuild the prompt, although important details should still be stored in files or explicit session state instead of relying on unlimited conversation memory.
When session persistence is enabled, qodercli can store a transcript and resume it later. Resume and checkpoint behavior is described in Session Storage and Checkpoint.
Completion, errors, and cancellation
Applications should keep consuming messages until they receive a result or the iterator raises an error.
- A successful or failed Agent turn is summarized by the final
resultmessage, including status and available usage information. interruptasks qodercli to stop the active turn while keeping a long-lived session available where supported.- Closing or aborting the SDK stream closes the transport. The process transport first attempts a graceful shutdown and escalates if qodercli does not exit.
- A process start failure, invalid protocol message, lost runtime, or initialization timeout is surfaced as an SDK error rather than an Agent result.
Security and data flow
The local process boundary does not mean the entire task stays on the local machine.
- Authentication is passed to qodercli separately from the JSONL message stream through a temporary payload that the SDK cleans up.
- qodercli sends the model service the task context needed for inference, which can include prompt content, file excerpts, and tool results.
- Tools execute in the qodercli environment and may read, write, or call other systems according to their configuration.
cwd, tool allowlists, permission rules, hooks, sandboxing, and infrastructure isolation are complementary controls. Configure them according to the consequences of the task.
TypeScript, Python, and Java session shape
The runtime protocol is shared by all three SDKs, but each exposes a language-appropriate session API:
| Scenario | TypeScript | Python | Java |
|---|---|---|---|
| One prompt, one result | query({ prompt: string, ... }) | query(prompt=..., options=...) | client.query(OneShotQueryRequest.of(prompt)) |
| Multiple user messages | Pass an async message iterable to query() | Connect a QoderSDKClient and call query() again | client.openSession(options), then call send() repeatedly |
| Read output | for await over discriminated message unions | async for over typed message objects | Pull with MessageCursor or push with consume(); check message types with instanceof |
| Runtime controls | Methods on the returned query stream | Methods on QoderSDKClient | Methods on QoderQuery / QoderSession |
Next steps
- Quick Start — run the first TypeScript, Python, or Java task
- Streaming Output — handle full messages and partial events
- Permissions — design approval and tool policies
- Tools — provide custom tools to the Agent
- SDK References — find the exact API for each language