Typescript SDK

Run Qodo Command agents entirely in-process (no child process) from your Node/TypeScript app using QodoClient. It shares the same orchestration core as the CLI SDK mode and is designed for concurrency, quiet logs, and typed streaming.

Highlights:

  • Zero child processes – fully in-process

  • Per-client environment isolation (config + session + tools) for safe parallel use

  • Auto-approval of tools by default (configurable)

  • Stream rich events or run to completion

  • Programmatic agent configs (define in code) or load from file/string

Install / Import

Prerequisites: set QODO_API_KEY in your environment (and optional QODO_BASE_URL) so the client can reach the Qodo backend.

export QODO_API_KEY=your_api_key_here
# export QODO_BASE_URL=https://api.qodo.ai  # optional override
// From the main package
import { QodoClient, agent, command, mode, jsonSchema } from '@qodo/command';
// Types only (optional):
// import type { AgentFileObject, CommandConfig, ModeConfig, MCPConfig, OutputSchema } from '@qodo/command';

Quick Start (blocking)

const client = new QodoClient({
  agentFile: 'agents/example.toml',
  model: 'gpt-5-max',          // optional model override
  autoApproveTools: true,       // default true
  // New: Working directory UX
  cwd: '/path/to/project',      // default shell/git cwd if tool args omit cwd (auto-derives from agentFile if not provided)
  projectRoots: ['/path/to/project', '/path/to/shared-lib'], // allowed roots for filesystem/ripgrep
});

const final = await client.run('build', {
  args: { target: 'prod' },
});

// Prefer structured_output, fall back to final_output
console.log(final?.result?.structured_output ?? final?.result?.final_output);
await client.dispose();

Streaming (typed event feed)

You can define the agent configuration programmatically with strict types and sensible SDK defaults (execution_strategy defaults to 'act').

See also: docs/sdk/agent-object.md for more type-centric examples.

Using agent content strings

Per-call output schema override

You can supply an output_schema per call. Pass either a JSON string (validated) or a structured object (use jsonSchema helper).

Session context and resumability

  • withSessionIds: Prefetch and inject summaries from previous session IDs (useful for continuity):

  • Resuming a specific session: provide flags.sid. If the session is resumable, QodoClient will call resume under the hood.

Working directory and allowed roots

  • cwd (optional): Sets a preferred execution working directory for shell/git tools when their args omit cwd.

    • If not provided but agentFile is set, QodoClient defaults cwd = dirname(agentFile).

    • If neither is provided, falls back to process.cwd().

  • projectRoots (optional): Additional allowed directories for filesystem/ripgrep tools. QodoClient uses [cwd, ...projectRoots] for allowed roots.

  • You can still override per-tool: pass cwd in shell_execute arguments.

Command and mode selection

QodoClient resolves the run target as follows (priority):

  • flags.mode → selected as a command equivalent from the agent file

  • explicit command name passed to run()/stream()

  • flags.command → if provided

  • single command in the agent file → if only one exists

Tips:

  • For conversational chat, define a mode (e.g., chat) and call with flags.mode = 'chat'.

  • For free-form prompts, ensure your agent has a single default command or call with a dedicated mode.

Tool approvals

  • autoApproveTools (default true) will auto-approve all tool calls (non-interactive, CI-friendly).

  • Set autoApproveTools: false to disable auto-approval. Note: the client remains non-interactive; you are responsible for handling any user engagement prompts emitted via messages.

Event reference

QodoClient streams events with this shape:

  • init

    • data: { protocol: 'qodo.sdk.v1', model: string, pid: number }

  • hello

    • data: { message: string, mode: 'sdk', ready: true }

  • messages

    • data: { messages: { langchain: Array<{ type: string; data: any }>, openai: any[] } }

  • progress

    • data: any (JSON parsed from assistant progress messages)

  • isLoading

    • data: boolean

  • error

    • data: { message: string }

  • final

    • data: { success: boolean, error?: string, session_id: string, model: string, result: { structured_output?: any; final_output?: string }, messages: { langchain: any[]; openai: any[] }, meta: { tools_auto_approved: boolean; subagents_used: boolean } }

Flags and advanced options

  • model: Override the model at construction.

  • flags: Arbitrary CLI-style flags supported by the core (e.g., { mode: 'chat', tools: 'shell.exec,ripgrep.search', noTools: 'filesystem.*', sid: '...' }).

  • mcpFile: Path to an MCP servers file; also supports defining servers in the agent object under mcpServers.

  • debug: true to keep internal logs enabled (by default, QodoClient mutes internal logging while streaming).

  • debugChatMessages: true to pretty-print AI/chat messages and tool calls to stdout while streaming (useful for debugging agent behavior).

Cancellation and cleanup

Concurrency & isolation

You can safely create multiple QodoClient instances in parallel. Each instance owns its own logical "environment":

  • Independent config/session (agent config + SessionContext)

  • Its own MessageManager stream

  • Its own MCP server registry and MCPManager (tool list, approvals, connection state)

Some resources remain process-wide (shared across clients), such as:

  • Backend metadata/cache from ServerData

  • stdout/stderr and global console (unless muted via debug or debugChatMessages)

Example:

Troubleshooting

  • If you don’t see progress or messages, ensure your agent emits them and that tools are available. Use debug: true to surface internal logs.

  • If you pass a command name and your agent doesn’t contain it, QodoClient falls back to the default/selected command. Double‑check the command list in your agent config.

  • For structured outputs, validate your per-call outputSchema. QodoClient validates and will throw if invalid.

Last updated