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

# CloudSession

> A session running in Devin's cloud, driven over the ACP WebSocket.

```typescript
class CloudSession extends AcpSession
```

## Constructor

```typescript
CloudSession(id: string, connection: JsonRpcConnection): CloudSession
```

### Parameters

**id** `string` *required*

**connection** `JsonRpcConnection` *required*

### Returns

`CloudSession`

## Properties

**configOptions** `undefined | readonly SessionConfigOption[]` *required*

**Type:** `undefined | readonly SessionConfigOption[]`

The session settings the agent exposes (`model`, `mode`, …) with their
current and accepted values, as last reported on a `session/new`,
`session/load` or `session/set_config_option` result. `undefined` until
the agent has reported any.

**connection** `JsonRpcConnection` *required*

**id** `string` *required*

**meta** `undefined | Readonly\<CognitionSessionMeta\>` *required*

**Type:** `undefined | Readonly<CognitionSessionMeta>`

The latest session-level snapshot the agent stamped on an update
(`cognition.ai/session`): status, URL, finished outcome, whether input is
disabled, what the user must do. Cloud sessions carry it on most
notifications, so this is current without waiting for a `status` event.

**onExtension** `undefined | (notification: CognitionExtensionNotification) =\> void` *required*

**Type:** `undefined | (notification: CognitionExtensionNotification) => void`

Called with each typed `_cognition.ai/*` extension notification for this
session (agent stopped, compaction, connection retries, …).

**onPermission** `undefined | PermissionHandler` *required*

**Type:** `undefined | PermissionHandler`

Answer this session's permission requests (e.g. running a shell command).
Takes precedence over the client-level `onPermission` for this session;
when neither is set, requests are rejected so unattended runs are safe by
default. Settable via `createSession({ onPermission })` or directly.

**url** `undefined | string` *required*

The session's web URL (`cognition.ai/url` session meta), once the agent
has stamped it on an update — cloud sessions carry it from the first
notification; local sessions have none.

## Methods

### acceptPlan()

```typescript
acceptPlan(params: SessionScopedParams<typeof void>): Promise<PlanAcceptResponse>
```

Accept a plan the agent proposed so it starts executing.

#### Parameters

**params** `SessionScopedParams\<typeof void\>` *required*

**Type:** `SessionScopedParams<typeof void>`

#### Returns

`Promise<PlanAcceptResponse>`

### beginReplay()

```typescript
beginReplay(): void
```

Route updates into a replay buffer instead of the turn stream while a
`session/load` request is in flight (the agent replays the session's
transcript as `session/update` notifications before responding).

### cancel()

```typescript
cancel(): void
```

Cancel the in-flight turn, if any.

### configOption()

```typescript
configOption(id: string): undefined | SessionConfigOption
```

The config option with this id (`id` on ACP v1, `configId` on v2), if reported.

#### Parameters

**id** `string` *required*

#### Returns

`undefined | SessionConfigOption`

### decideRepoIndex()

```typescript
decideRepoIndex(sourceEventId: string, decision: RepoIndexDecision): Promise<RepoIndexDecideResponse>
```

Answer the agent's offer to index a repository (`sourceEventId` is the offer's event).

#### Parameters

**sourceEventId** `string` *required*

**decision** `RepoIndexDecision` *required*

#### Returns

`Promise<RepoIndexDecideResponse>`

### editPlan()

```typescript
editPlan(params: SessionScopedParams<typeof void>): Promise<PlanEditResponse>
```

Replace the body (and optionally title / summary) of a proposed plan.

#### Parameters

**params** `SessionScopedParams\<typeof void\>` *required*

**Type:** `SessionScopedParams<typeof void>`

#### Returns

`Promise<PlanEditResponse>`

### enableTurnStateUpdates()

```typescript
enableTurnStateUpdates(): void
```

On ACP v2 connections the `session/prompt` response is an immediate ack;
turns end on the idle `state_update` notification instead.

### endReplay()

```typescript
endReplay(): SessionUpdate[]
```

Stop capturing replay updates and return them.

#### Returns

`SessionUpdate[]`

### enrichPermissionRequest()

```typescript
enrichPermissionRequest(request: PermissionRequest): PermissionRequest
```

Enrich a permission request with the merged snapshot of the tool call it
gates: agents often send only a `toolCallId` reference (the full tool
call was already streamed as a `tool_call` update).

#### Parameters

**request** `PermissionRequest` *required*

#### Returns

`PermissionRequest`

### events()

```typescript
events(options?: ObserveOptions): AsyncGenerator<SessionEvent>
```

Every live update for this session as typed [SessionEvent](https://docs.devin.ai/sdk/reference/types/SessionEvent.md)s — the
session-wide counterpart of `stream`. `status` events say when Devin
starts working, is waiting on the user, or finishes; `lifecycle` when its
runtime sleeps or exits; `activity` and `typing` what it is doing right
now; `message_delta`, `thought_delta`, `user_message`, `tool_call`, `plan`
and `pull_request` cover the transcript.

```ts
const session = await devin.attach("devin-…");
for await (const event of session.events()) {
  if (event.type === "status") console.log(event.status, event.userActionRequired);
}
```

#### Parameters

**options** `ObserveOptions`

#### Returns

`AsyncGenerator<SessionEvent>`

### extNotify()

```typescript
extNotify(method: M, params: SessionScopedParams<M>): void
```

Send a session-scoped `_cognition.ai/*` notification (no response).

#### Parameters

**method** `M` *required*

**params** `SessionScopedParams\<M\>` *required*

**Type:** `SessionScopedParams<M>`

```typescript
extNotify(method: string, params?: unknown): void
```

Send a session-scoped `_cognition.ai/*` notification (no response).

#### Parameters

**method** `string` *required*

**params** `unknown`

### extRequest()

```typescript
extRequest(method: M, params: SessionScopedParams<M>): Promise<CognitionRequestResult<M>>
```

Send a session-scoped `_cognition.ai/*` request with this session's id
filled in. Typed when the method is in the generated registry
(`CognitionAgentResponseMap`); any other `_cognition.ai/*` method is
accepted untyped. Use this for Cognition methods that have no dedicated
helper yet, e.g.
`session.extRequest(SESSION_RENAME_METHOD, { title: "Fix flaky test" })`.
An explicit directory variant is sent without adding a session id.

#### Parameters

**method** `M` *required*

**params** `SessionScopedParams\<M\>` *required*

**Type:** `SessionScopedParams<M>`

#### Returns

`Promise<CognitionRequestResult<M>>`

```typescript
extRequest(method: string, params?: unknown): Promise<T>
```

Send a session-scoped `_cognition.ai/*` request with this session's id
filled in. Typed when the method is in the generated registry
(`CognitionAgentResponseMap`); any other `_cognition.ai/*` method is
accepted untyped. Use this for Cognition methods that have no dedicated
helper yet, e.g.
`session.extRequest(SESSION_RENAME_METHOD, { title: "Fix flaky test" })`.
An explicit directory variant is sent without adding a session id.

#### Parameters

**method** `string` *required*

**params** `unknown`

#### Returns

`Promise<T>`

### getNetPolicy()

```typescript
getNetPolicy(): Promise<NetPolicyGetResponse>
```

The session's network allowlist policy.

#### Returns

`Promise<NetPolicyGetResponse>`

### handleConnectionClosed()

```typescript
handleConnectionClosed(error: ConnectionClosedError): void
```

The connection dropped: fail the in-flight turn (on v2 its prompt
response was only an ack, so nothing else would ever end it) and release
any drain barrier so callers aren't stranded.

#### Parameters

**error** `ConnectionClosedError` *required*

### handleExtension()

```typescript
handleExtension(method: string, params: unknown): void
```

#### Parameters

**method** `string` *required*

**params** `unknown` *required*

### handleReleased()

```typescript
handleReleased(): void
```

The client stopped routing notifications to this session (it was
released or closed): nothing more will arrive, so end the session-wide
iterators, present and future.

### handleResult()

```typescript
handleResult(result: unknown): void
```

Record the session snapshot a `session/new`, `session/resume`,
`session/set_config_option` or `session/prompt` result carries, so `meta`,
`url` and `configOptions` are set without waiting for a live update.

#### Parameters

**result** `unknown` *required*

### handleUpdate()

```typescript
handleUpdate(__namedParameters: Pick<SessionNotification, "update" | "_meta">): void
```

Route one `session/update` notification. Cloud agents stamp the session
snapshot on the notification's `_meta` rather than the update's, so both
are consulted.

#### Parameters

**\_\_namedParameters** `Pick\<SessionNotification, "update" | "_meta"\>` *required*

**Type:** `Pick<SessionNotification, "update" | "_meta">`

### heartbeat()

```typescript
heartbeat(): Promise<void>
```

Keep the session's VM from idling out while a client is attached
(`_cognition.ai/session/heartbeat`). Send periodically during long
unattended waits.

#### Returns

`Promise<void>`

### instrument()

```typescript
instrument(observer: SessionObserver): void
```

Report this session's prompts, live updates, extensions and replay to
`observer` until the session detaches.

#### Parameters

**observer** `SessionObserver` *required*

### listSecrets()

```typescript
listSecrets(): Promise<SecretListResponse>
```

The secrets (names only) available to this session.

#### Returns

`Promise<SecretListResponse>`

### loadPage()

```typescript
loadPage(startIndex: number, limit?: number): Promise<HistoryPage>
```

Backfill older history after a tail replay
(`_cognition.ai/session/loadPage`): the dense page of events whose
ordinals are strictly below `startIndex` (start with
`LoadedCloudSession.tail.olderIndex`). The server defaults `limit` to
its page size and caps it.

#### Parameters

**startIndex** `number` *required*

**limit** `number`

#### Returns

`Promise<HistoryPage>`

### markRead()

```typescript
markRead(isUnread?: boolean): Promise<void>
```

Mark the session read (or unread again) for the current user.

#### Parameters

**isUnread** `boolean`

#### Returns

`Promise<void>`

### postMessage()

```typescript
postMessage(input: PromptInput, options?: PromptOptions): Promise<PromptResult>
```

Inject a user message into the in-flight turn. The agent folds the
message into the running turn (interrupting the current inference if one
is streaming) — it is not queued as a separate turn. Sent as a concurrent
`session/prompt`; the returned promise settles when the turn ends, with
the same result the original prompt resolves to.

#### Parameters

**input** `PromptInput` *required*

**options** `PromptOptions`

#### Returns

`Promise<PromptResult>`

### provideSecret()

```typescript
provideSecret(params: SessionScopedParams<typeof void>): Promise<SecretProvideResponse>
```

Hand the agent a secret it asked for (`request_secret`), optionally saving it.

#### Parameters

**params** `SessionScopedParams\<typeof void\>` *required*

**Type:** `SessionScopedParams<typeof void>`

#### Returns

`Promise<SecretProvideResponse>`

### reboot()

```typescript
reboot(): Promise<void>
```

Reboot the session's VM (`_cognition.ai/session/reboot`).

#### Returns

`Promise<void>`

### rename()

```typescript
rename(title: string): Promise<void>
```

Rename the session (`_cognition.ai/session/rename`). Available on both
cloud and local agents; check `devin.supports("cognition.ai/sessionRename")`.

#### Parameters

**title** `string` *required*

#### Returns

`Promise<void>`

### respondToPermission()

```typescript
respondToPermission(params: SessionScopedParams<typeof void>): Promise<PermissionRespondResponse>
```

Answer a permission request by id — for requests surfaced as
`permission_request` tool calls in the transcript (e.g. raised while no
client was attached), as opposed to live `session/request_permission`
requests, which go through `onPermission`.

#### Parameters

**params** `SessionScopedParams\<typeof void\>` *required*

**Type:** `SessionScopedParams<typeof void>`

#### Returns

`Promise<PermissionRespondResponse>`

### run()

```typescript
run(input: PromptInput, options: RunOptions<T> & { output: StandardSchema<T> }): Turn<T>
```

Send a prompt and get a [Turn](https://docs.devin.ai/sdk/reference/classes/Turn.md): `for await` it for typed
[SessionEvent](https://docs.devin.ai/sdk/reference/types/SessionEvent.md)s, `await` it for the [SessionOutcome](https://docs.devin.ai/sdk/reference/interfaces/SessionOutcome.md)
(stop reason, accumulated text, tool calls — and structured output
validated against `options.output`, e.g. a zod schema).

```ts
const outcome = await session.run("Summarize the repo", {
  output: z.object({ summary: z.string() }),
});
outcome.output.summary;
```

With an `output` schema the outcome's `output` is the validated `T`
(validation failure rejects the turn; a turn that stops without
`end_turn` resolves, but reading `output` throws); without one it is
`undefined`.

#### Parameters

**input** `PromptInput` *required*

**options** `RunOptions\<T\> & \{ output: StandardSchema\<T\> \}` *required*

**Type:** `RunOptions<T> & { output: StandardSchema<T> }`

#### Returns

`Turn<T>`

```typescript
run(input: PromptInput, options?: Omit<RunOptions<unknown>, "output"> & { output: undefined }): Turn
```

Send a prompt and get a [Turn](https://docs.devin.ai/sdk/reference/classes/Turn.md): `for await` it for typed
[SessionEvent](https://docs.devin.ai/sdk/reference/types/SessionEvent.md)s, `await` it for the [SessionOutcome](https://docs.devin.ai/sdk/reference/interfaces/SessionOutcome.md)
(stop reason, accumulated text, tool calls — and structured output
validated against `options.output`, e.g. a zod schema).

```ts
const outcome = await session.run("Summarize the repo", {
  output: z.object({ summary: z.string() }),
});
outcome.output.summary;
```

With an `output` schema the outcome's `output` is the validated `T`
(validation failure rejects the turn; a turn that stops without
`end_turn` resolves, but reading `output` throws); without one it is
`undefined`.

#### Parameters

**input** `PromptInput` *required*

**options** `Omit\<RunOptions\<unknown\>, "output"\> & \{ output: undefined \}`

**Type:** `Omit<RunOptions<unknown>, "output"> & { output: undefined }`

#### Returns

`Turn`

```typescript
run(input: PromptInput, options: RunOptions<T>): Turn<undefined | T>
```

Send a prompt and get a [Turn](https://docs.devin.ai/sdk/reference/classes/Turn.md): `for await` it for typed
[SessionEvent](https://docs.devin.ai/sdk/reference/types/SessionEvent.md)s, `await` it for the [SessionOutcome](https://docs.devin.ai/sdk/reference/interfaces/SessionOutcome.md)
(stop reason, accumulated text, tool calls — and structured output
validated against `options.output`, e.g. a zod schema).

```ts
const outcome = await session.run("Summarize the repo", {
  output: z.object({ summary: z.string() }),
});
outcome.output.summary;
```

With an `output` schema the outcome's `output` is the validated `T`
(validation failure rejects the turn; a turn that stops without
`end_turn` resolves, but reading `output` throws); without one it is
`undefined`.

#### Parameters

**input** `PromptInput` *required*

**options** `RunOptions\<T\>` *required*

**Type:** `RunOptions<T>`

#### Returns

`Turn<undefined | T>`

### saveSecret()

```typescript
saveSecret(params: SessionScopedParams<typeof void>): Promise<SecretSaveResponse>
```

Decide on a `suggest_save_secret` request from the agent.

#### Parameters

**params** `SessionScopedParams\<typeof void\>` *required*

**Type:** `SessionScopedParams<typeof void>`

#### Returns

`Promise<SecretSaveResponse>`

### send()

```typescript
send(input: PromptInput, options?: PromptOptions): Promise<PromptResult>
```

Send a prompt and wait for the turn to finish, discarding updates. Pass a
string for plain text, or content blocks (see the `prompt` builders) to
attach images, audio, or embedded resources.

#### Parameters

**input** `PromptInput` *required*

**options** `PromptOptions`

#### Returns

`Promise<PromptResult>`

### sendFeedback()

```typescript
sendFeedback(params: SessionScopedParams<typeof void>): Promise<SessionFeedbackResponse>
```

Rate the session, or a single message when `eventId` is given.

#### Parameters

**params** `SessionScopedParams\<typeof void\>` *required*

**Type:** `SessionScopedParams<typeof void>`

#### Returns

`Promise<SessionFeedbackResponse>`

### setMode()

```typescript
setMode(modeId: string): Promise<void>
```

Switch the session's permission mode (e.g. `"ask"`, `"accept-edits"`).

#### Parameters

**modeId** `string` *required*

#### Returns

`Promise<void>`

### setOrg()

```typescript
setOrg(orgId: string, repos?: string[]): Promise<void>
```

Select the organization the session is created in (before the first
prompt), optionally with its repositories in the same request (see
`setRepos`). Changing the organization resets any repositories
set earlier, since they are scoped to it.

#### Parameters

**orgId** `string` *required*

**repos** `string[]`

#### Returns

`Promise<void>`

### setRepos()

```typescript
setRepos(repos: string[]): Promise<void>
```

Repositories this session is about, set before the first prompt — the
web app's repository picker. Devin treats them as the relevant repos
(prompt hint, knowledge and routing scope), runs their configured setup
on boot when the organization has one, and clones anything else on
demand; access is still decided by the organization's git permissions.
Names are the ones `devin.api.repositories.listRepositories` returns
(`owner/repo` on github.com, `host/path` elsewhere) — only repositories
granted to the organization are selectable, though Devin can still clone
public ones when asked in the prompt. Throws a `DevinError` naming any
repository the organization cannot access instead of letting the agent
drop it silently.

#### Parameters

**repos** `string[]` *required*

#### Returns

`Promise<void>`

### setSpendingLimit()

```typescript
setSpendingLimit(maxCredits: number, options?: SpendingLimitOptions): Promise<SessionSpendingLimitSetResponse>
```

Cap the ACUs this session may spend.

#### Parameters

**maxCredits** `number` *required*

**options** `SpendingLimitOptions`

#### Returns

`Promise<SessionSpendingLimitSetResponse>`

### stream()

```typescript
stream(input: PromptInput, options?: PromptOptions): AsyncGenerator<SessionEvent, PromptResult, undefined>
```

Send a prompt and yield typed [SessionEvent](https://docs.devin.ai/sdk/reference/types/SessionEvent.md)s as they stream
(message/thought deltas, merged tool-call snapshots, plans…), returning
the turn result once the agent stops. Use `streamUpdates` for the
raw ACP notifications.

#### Parameters

**input** `PromptInput` *required*

**options** `PromptOptions`

#### Returns

`AsyncGenerator<SessionEvent, PromptResult, undefined>`

### streamUpdates()

```typescript
streamUpdates(input: PromptInput, options?: PromptOptions): AsyncGenerator<SessionUpdate, PromptResult, undefined>
```

Send a prompt and yield the agent's raw `session/update` notifications
as they stream, returning the turn result once the agent stops.

#### Parameters

**input** `PromptInput` *required*

**options** `PromptOptions`

#### Returns

`AsyncGenerator<SessionUpdate, PromptResult, undefined>`

### togglePlanConfirmMode()

```typescript
togglePlanConfirmMode(planEventId: string): Promise<PlanToggleConfirmModeResponse>
```

Toggle whether the agent must confirm before acting on the plan at `planEventId`.

#### Parameters

**planEventId** `string` *required*

#### Returns

`Promise<PlanToggleConfirmModeResponse>`

### updateNetPolicy()

```typescript
updateNetPolicy(params: SessionScopedParams<typeof void>): Promise<NetPolicyUpdateResponse>
```

Replace the network policy, or answer a `request_network_access` from
the agent (`networkAccessRequestId` + `networkAccessDomains` /
`denyNetworkAccessRequest`).

#### Parameters

**params** `SessionScopedParams\<typeof void\>` *required*

**Type:** `SessionScopedParams<typeof void>`

#### Returns

`Promise<NetPolicyUpdateResponse>`

### updateQueue()

```typescript
updateQueue(op: SessionScopedParams<"_cognition.ai/queuedMessages/update">): Promise<QueuedMessagesUpdateResponse>
```

Edit the send queue: messages held to be delivered once the agent is
ready (`op: "add" | "edit" | "remove" | "send_now" | "hold" | "reorder" |
"clear"`). The agent echoes the new queue via
`_cognition.ai/messages_in_queued`.

#### Parameters

**op** `SessionScopedParams\<"_cognition.ai/queuedMessages/update"\>` *required*

**Type:** `SessionScopedParams<"_cognition.ai/queuedMessages/update">`

#### Returns

`Promise<QueuedMessagesUpdateResponse>`

### updates()

```typescript
updates(__namedParameters?: ObserveOptions): AsyncGenerator<SessionUpdate>
```

Every live `session/update` for this session as it arrives — from turns
this client started and from turns driven elsewhere alike. Subscribes on
the first pull; ends when the consumer stops (`break`, `return()`, or
`signal`) or the session is released, and throws
[ConnectionClosedError](https://docs.devin.ai/sdk/reference/classes/ConnectionClosedError.md) when the connection drops. Replayed history
from `loadSession()` is not delivered here.

#### Parameters

**\_\_namedParameters** `ObserveOptions`

#### Returns

`AsyncGenerator<SessionUpdate>`


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.