> ## Documentation Index
> Fetch the complete documentation index at: https://docs.corti.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent SDK API reference

> Full method and type reference for the Corti Agent SDK in TypeScript and Python.

<Warning>
  The Corti Agent SDK is in **alpha v2 private preview**. The API may change between releases. Contact [help@corti.ai](mailto:help@corti.ai) to request access.
</Warning>

This page is a complete reference for every public class, method, and type exported by the SDK.

## AgentsClient and AgentsResource

In TypeScript, agent CRUD lives on `client.agents` (`AgentsResource`). In Python, it lives on `AgentsClient(client)`.

| Method                                  | Returns                                                 | Description                                |
| --------------------------------------- | ------------------------------------------------------- | ------------------------------------------ |
| `create(body)` / `create(...)`          | `Agent` (TS) / `AgentHandle` (Python)                   | Create a new agent                         |
| `get(agentId)` / `get(agent_id)`        | `Agent` (TS) / `AgentHandle` (Python)                   | Fetch an existing agent by ID              |
| `list(params?)` / `list()`              | `AgentListResponse` (TS) / `list[AgentHandle]` (Python) | List agents in the tenant                  |
| `update(agentId, body)` / `update(...)` | `Agent` (TS) / `AgentHandle` (Python)                   | Partial update via JSON Merge Patch        |
| `delete(agentId)` / `delete()`          | `void`                                                  | Delete an agent                            |
| `wrap(agent)` (Python only)             | `AgentHandle`                                           | Wrap a raw API dict without a network call |

In TypeScript, `create()` and `get()` return raw `Agent` objects. Wrap them with `new AgentHandle(agent, client)` to get conversation helpers.

## AgentHandle

| Member                                           | Type                               | Description                                         |
| ------------------------------------------------ | ---------------------------------- | --------------------------------------------------- |
| `id`                                             | `string`                           | Agent ID (server-assigned)                          |
| `name`                                           | `string`                           | Agent name                                          |
| `description`                                    | `string \| undefined`              | Agent description                                   |
| `systemPrompt` / `system_prompt`                 | `string \| undefined`              | System prompt                                       |
| `model`                                          | `string \| undefined` (TS only)    | Model the agent uses                                |
| `visibility`                                     | `string`                           | `private`, `unlisted`, or `public`                  |
| `lifecycle`                                      | `string`                           | `ephemeral` or `persistent`                         |
| `connectors`                                     | `Connector[]`                      | Attached connectors                                 |
| `labels`                                         | `Record<string, string>` (TS only) | Free-form labels                                    |
| `raw`                                            | `Agent` / `Dict`                   | Underlying API response object                      |
| `createContext(opts?)` / `create_context(...)`   | `AgentContext`                     | Open a new conversation thread (lazy)               |
| `getContext(id, opts?)` / `get_context(id, ...)` | `AgentContext`                     | Resume an existing thread by ID                     |
| `run(input, opts?)`                              | `Promise<MessageResponse>`         | One-shot invoke: create context, send, return reply |
| `stream(input, opts?)` (TS only)                 | `AsyncGenerator<StreamResponse>`   | One-shot streaming invoke                           |
| `update(patch)` / `update(...)`                  | `Promise<AgentHandle>`             | Partially update the agent, returns a new handle    |
| `refresh()`                                      | `Promise<AgentHandle>`             | Re-fetch the agent from the API                     |
| `delete()`                                       | `Promise<void>`                    | Delete the agent                                    |

## AgentContext

| Member                                                              | Type                             | Description                                                    |
| ------------------------------------------------------------------- | -------------------------------- | -------------------------------------------------------------- |
| `id`                                                                | `string \| undefined`            | Thread ID, `undefined` / `None` until the first turn completes |
| `sendText(text, opts?)` / `send_text(text, ...)`                    | `Promise<MessageResponse>`       | Send plain text                                                |
| `sendMessage(parts, opts?)` / `send_message(parts, ...)`            | `Promise<MessageResponse>`       | Send arbitrary `Part[]` (text, data, file)                     |
| `streamMessage(parts, opts?)` / `stream_message(parts)`             | `AsyncGenerator<StreamResponse>` | Stream incremental events for the reply                        |
| `getTask(taskId, opts?)` / `get_task(task_id, ...)` (TS only)       | `Promise<Task>`                  | Fetch a task by ID                                             |
| `cancelTask(taskId, opts?)` / `cancel_task(task_id, ...)` (TS only) | `Promise<Task>`                  | Cancel a running task                                          |

### SendMessageOptions

| Field                                     | Type                      | Description                               |
| ----------------------------------------- | ------------------------- | ----------------------------------------- |
| `historyLength`                           | `number`                  | Number of history messages to include     |
| `blocking`                                | `boolean`                 | Wait for task completion before returning |
| `acceptedOutputModes`                     | `string[]`                | Output modes the client accepts           |
| `metadata`                                | `Record<string, unknown>` | Free-form metadata                        |
| `timeoutInSeconds` / `timeout_in_seconds` | `number`                  | Per-request timeout override (default 60) |
| `abortSignal` (TS only)                   | `AbortSignal`             | Abort the request                         |
| `credentials` (Python only)               | `CredentialStore`         | MCP auth credentials                      |

## MessageResponse

| Member                     | Type                           | Description                                                                             |
| -------------------------- | ------------------------------ | --------------------------------------------------------------------------------------- |
| `text`                     | `string \| null`               | All text parts from the agent reply, joined                                             |
| `status`                   | `string`                       | Task state: `completed`, `failed`, `working`, `submitted`, `canceled`, `input-required` |
| `state` (TS only)          | `TaskState`                    | Raw task state enum value                                                               |
| `message` (TS only)        | `Message \| undefined`         | The agent's reply message                                                               |
| `task` (TS only)           | `Task \| undefined`            | The full A2A task object                                                                |
| `taskId` / `task_id`       | `string \| undefined`          | Task ID for this invocation                                                             |
| `contextId` / `context_id` | `string \| undefined`          | Thread ID, set after the first turn                                                     |
| `artifacts`                | `Artifact[]`                   | Structured outputs, deduplicated by parts content                                       |
| `raw`                      | `SendMessageResponse` / `Dict` | Full, unmodified API response                                                           |

## Composition primitives

| Function                                                 | Returns                     | Description                                               |
| -------------------------------------------------------- | --------------------------- | --------------------------------------------------------- |
| `workflow(steps)`                                        | `Workflow`                  | Build a deterministic pipeline                            |
| `Workflow.run(input)`                                    | `Promise<WorkflowResult>`   | Execute the pipeline                                      |
| `parallel(steps)`                                        | `Parallel`                  | Build a fan-out block                                     |
| `Parallel.run(input)`                                    | `Promise<ParallelResult>`   | Run all steps concurrently                                |
| `stateGraph<TState>()` / `stateGraph()`                  | `StateGraph<TState>`        | Build a graph with cycles and typed shared state          |
| `StateGraph.addNode(name, nodeFn)` / `add_node(...)`     | `StateGraph`                | Register a node. Use `agentNode()` for agent-backed nodes |
| `StateGraph.addEdge(from, to)` / `add_edge(...)`         | `StateGraph`                | `to` may be a node name, `END`, or an `EdgeRouter`        |
| `StateGraph.run(start, state, opts?)`                    | `Promise<StateGraphResult>` | Execute. `opts.maxIterations` bounds cycles (default 25)  |
| `agentNode(agent, inputFn, mergeFn)` / `agent_node(...)` | `NodeFn<TState>`            | Wrap an agent as a graph node                             |
| `END`                                                    | `EndType`                   | Sentinel to terminate a `StateGraph` run                  |

## Connector helpers

### TypeScript

| Helper                                     | Returns                   | Description                                     |
| ------------------------------------------ | ------------------------- | ----------------------------------------------- |
| `connectors.registry(name, opts?)`         | `RegistryConnectorCreate` | Use a published Corti registry connector        |
| `connectors.mcp({ name, url, auth? })`     | `McpConnectorCreate`      | Attach an MCP server                            |
| `connectors.agent(agentId, opts?)`         | `AgentConnectorCreate`    | Wire another Corti agent as a sub-agent         |
| `connectors.a2a(url, opts?)`               | `A2AConnectorCreate`      | Connect to a remote A2A agent                   |
| `connectors.schema({ name, schema, ... })` | `SchemaConnectorCreate`   | Define a JSON Schema tool for structured output |

### Python

| Helper                                                              | Returns               | Description                                  |
| ------------------------------------------------------------------- | --------------------- | -------------------------------------------- |
| `connectors.registry(name, *, system_prompt?)`                      | `RegistryConnector`   | Use a named expert from the registry         |
| `connectors.mcp(mcp_url, *, name?, transport?, auth_type?, token?)` | `McpConnector`        | Attach an MCP server                         |
| `connectors.from_agent(agent_id)`                                   | `CortiAgentConnector` | Reference another Corti agent as a sub-agent |
| `connectors.a2a(a2a_url)`                                           | `A2AConnector`        | A2A protocol (reserved, not yet supported)   |

### Auth helpers (TypeScript only)

| Helper                                        | Returns         | Description                                             |
| --------------------------------------------- | --------------- | ------------------------------------------------------- |
| `auth.none()`                                 | `ConnectorAuth` | No auth required                                        |
| `auth.bearer()`                               | `ConnectorAuth` | Bearer token auth                                       |
| `auth.apiKey(ref?)`                           | `ConnectorAuth` | API key auth, optionally with a stored secret reference |
| `auth.oauth2({ scope?, redirectUrl?, ref? })` | `ConnectorAuth` | OAuth2 auth                                             |

## Types

### Parts

| Type       | Shape                                          | Notes                          |
| ---------- | ---------------------------------------------- | ------------------------------ |
| `Part`     | `TextPart \| DataPart \| FilePart`             | Message content                |
| `TextPart` | `{ text: string }`                             | Plain text                     |
| `DataPart` | `{ data: unknown }`                            | Structured payload             |
| `FilePart` | `{ file: { name?, mimeType?, bytes?, uri? } }` | Send `bytes` (base64) or `uri` |

### Tasks and messages

| Type        | Shape                                                                       | Notes                                                      |
| ----------- | --------------------------------------------------------------------------- | ---------------------------------------------------------- |
| `Task`      | Full A2A task object                                                        | Exposed via `MessageResponse.task` / `MessageResponse.raw` |
| `Message`   | `{ role, parts, messageId, contextId?, taskId? }`                           | An A2A message                                             |
| `Artifact`  | `{ artifactId, name?, parts }`                                              | Structured output from the agent                           |
| `TaskState` | `submitted \| working \| input-required \| completed \| canceled \| failed` | Returned in `MessageResponse.status`                       |

### Composition types

| Type                       | Shape                                                                            | Notes                                                   |
| -------------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------- |
| `Runnable`                 | `{ run(input): Promise<MessageResponse> }`                                       | What `workflow`/`parallel` accept besides `AgentHandle` |
| `WorkflowStep`             | `AgentHandle \| Parallel \| { agent, when?, transform?, retries?, retryDelay? }` | A workflow step                                         |
| `WorkflowResult`           | `{ output, steps, stoppedEarly }`                                                | Result of `Workflow.run()`                              |
| `ParallelStep`             | `AgentHandle \| { agent, input?, credentials? }`                                 | A parallel step                                         |
| `ParallelResult`           | `{ results, fulfilled, rejected }`                                               | Result of `Parallel.run()`                              |
| `EdgeRouter<TState>`       | `(state: S) => string \| END`                                                    | Function form of `addEdge`                              |
| `NodeFn<TState>`           | `(state: S) => Promise<Partial<S>> \| Partial<S>`                                | Custom graph node function                              |
| `StateGraphStep<TState>`   | `{ node: string, delta: Partial<S> }`                                            | Per-step trace entry                                    |
| `StateGraphResult<TState>` | `{ state, steps, iterations, terminatedBy }`                                     | Result of `StateGraph.run()`                            |

### Error types

| Type              | Description                                                               |
| ----------------- | ------------------------------------------------------------------------- |
| `CortiError`      | Base class for all SDK errors                                             |
| `ManagementError` | Management-plane error (agent CRUD, connectors, etc.)                     |
| `A2AError`        | A2A-plane error (message send, stream, task operations)                   |
| `HttpError`       | HTTP error when the response body cannot be parsed as a known error shape |

## TypeScript vs Python naming

The wire format (A2A JSON-RPC) is identical: both SDKs talk to the same API. The naming conventions differ:

| TypeScript                  | Python                                               |
| --------------------------- | ---------------------------------------------------- |
| `new CortiClient({...})`    | `async with CortiClient(...) as client:`             |
| `sendText()`                | `await send_text()`                                  |
| `sendMessage()`             | `await send_message()`                               |
| `streamMessage()`           | `stream_message()`                                   |
| `createContext()`           | `create_context()`                                   |
| `getContext(id)`            | `get_context(id)`                                    |
| `systemPrompt`              | `system_prompt`                                      |
| `timeoutInSeconds`          | `timeout_in_seconds=` (keyword-only)                 |
| `connectors.agent(agentId)` | `connectors.from_agent(agent_id)`                    |
| `connectors.mcp({ url })`   | `connectors.mcp(mcp_url=...)`                        |
| `agentNode()`               | `agent_node()`                                       |
| `stateGraph()`              | `stateGraph()` (same: Python also exports camelCase) |
| `terminatedBy`              | `terminated_by`                                      |
| `stoppedEarly`              | `stopped_early`                                      |
| `retryDelay`                | `retry_delay`                                        |
