# devin

> Devin CLI + API as an iii worker; devin::run/start/stop/status/sessions::list follow the agent-worker family and stream AgentEvent frames onto agent::events, devin::session::* wrap the Devin cloud session lifecycle, devin::pr-review::* exposes Devin's review surface, and devin::api reaches any Devin v1/v3 endpoint.

| field | value |
|-------|-------|
| version | 0.1.6 |
| type | binary |
| license | Apache-2.0 |
| repo | https://github.com/iii-hq/workers |
| supported_targets | x86_64-apple-darwin, aarch64-apple-darwin, i686-pc-windows-msvc, x86_64-pc-windows-msvc, aarch64-pc-windows-msvc, x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu, x86_64-unknown-linux-musl, armv7-unknown-linux-gnueabihf |
| author | iii |

## installation

```sh
iii worker add devin@0.1.6
```

## configuration

```yaml
- api_key: ${DEVIN_API_KEY}
  base_url: https://api.devin.ai/v1
  cli_extra_args:
    - --permission-mode
    - dangerous
  devin_executable: 
  events_stream: agent::events
  iii_context: true
  org_id: ${DEVIN_ORG_ID}
  raw_events_stream: devin::events
  request_timeout_secs: 120
```

## readme

# devin

[Devin](https://docs.devin.ai) as an iii worker: the Devin coding agent exposed as functions and streams on the iii bus. Devin has two distinct products and this worker exposes both. The local [Devin CLI](https://cli.devin.ai/docs) is a SWE-1.6 coding agent that runs on your machine; `devin::run` drives it headless and, with the iii runtime context, lets it discover and operate your engine on its own. The [Devin cloud](https://docs.devin.ai) agent runs in a VM, reached over the REST API: `devin::session::*` wrap the session lifecycle, `devin::pr-review::*` run reviews, and `devin::api` reaches any v1/v3 endpoint the typed wrappers do not cover.

This worker is deliberately thin. It does not re-implement scheduling, sub-agents, or persistence that the engine already provides. Schedule a Devin session with the `cron` worker, fan Devin runs out with `harness::spawn`, and let the engine trace and persist every call. The worker's job is to put Devin on the bus, nothing more.

## Install

```bash
iii worker add devin
```

For the API surface (`devin::session::*`, `devin::api`), set `DEVIN_API_KEY` in the worker environment. Get a key from the [Devin settings page](https://app.devin.ai/settings/api-keys).

For the CLI surface (`devin::run` / `devin::start`), install the local [Devin CLI](https://cli.devin.ai/docs) (`brew install --cask devin-cli`, or `curl -fsSL https://cli.devin.ai/install.sh | bash`) and run `devin auth login`. This is the local coding agent (SWE-1.6), distinct from the Devin cloud the API targets: the worker drives it in non-interactive `--print` mode, so the agent runs on the host, works with the local files under `cwd`, and returns its reply in `result`. Because it runs locally, an `iii_context` turn can reach the engine at `localhost` with no exposure.

## Skills

Install the `devin` agent skill for Claude Code, Cursor, and 30+ other agents:

```bash
npx skills add iii-hq/workers --skill devin
```

## Quickstart

From zero to a Devin cloud session over the bus:

```bash
curl -fsSL https://install.iii.dev/iii/main/install.sh | sh
export DEVIN_API_KEY=...       # personal token (v1) or service key (cog_..., v3)
# service-key users only: also `export DEVIN_ORG_ID=org_...` and set base_url to v3
iii worker add devin
iii   # starts the engine + worker
```

The API has two shapes and the worker picks one from your config. A **personal token** uses the flat v1 API and is the default (leave `org_id` empty, `base_url` stays `.../v1`). A **service key** (`cog_...`) uses the v3 API scoped to an organization: set `org_id` and `base_url` to `https://api.devin.ai/v3`. The `devin::pr-review::*` functions are v3 features.

Start a cloud session and read it back:

```bash
# start an autonomous Devin session in the cloud
iii trigger devin::session::create --timeout-ms 60000 \
  --json '{"prompt":"Open a PR that adds a /health endpoint to the api repo","title":"health endpoint"}'
# { "session_id": "devin-...", "url": "https://app.devin.ai/sessions/...", ... }

# poll its status, output, and messages
iii trigger devin::session::get session_id=devin-...

# send a follow-up
iii trigger devin::session::message \
  --json '{"session_id":"devin-...","message":"Also add a test for it"}'

# list recent sessions
iii trigger devin::api --json '{"method":"GET","path":"sessions","query":{"limit":10}}'
```

`devin::session::create` returns a real Devin cloud session over the bus (session id, url, tags):

![devin::session::create returning a real Devin cloud session id and url over the iii bus](https://raw.githubusercontent.com/iii-hq/workers/main/devin/assets/session-create.png)

The same session runs in the Devin app and replies:

![The Devin cloud session opened via devin::session::create, replying in the Devin app](https://raw.githubusercontent.com/iii-hq/workers/main/devin/assets/session-reply.png)

Run the local CLI as one turn and stream it onto the bus:

```bash
iii trigger devin::run --timeout-ms 600000 \
  --json '{"prompt":"summarize what this repo does","cwd":"/path/to/repo"}'
# streams raw stdout onto devin::events, AgentEvent frames onto agent::events
```

Reach any endpoint the typed wrappers do not cover:

```bash
# paths are relative to base_url. v1 (personal token) uses flat paths:
iii trigger devin::api --json '{"method":"GET","path":"sessions","query":{"limit":5}}'

# v3 (service key) paths are org-scoped:
iii trigger devin::api --json '{"method":"GET","path":"organizations/org_.../sessions"}'
```

Ask the engine for any function's contract:

```bash
iii trigger devin::session::create --help
```

## Functions

The worker follows the same base surface as the grok, codex, claude-code, and opencode agent workers (`run` / `start` / `stop` / `status` / `sessions::list` / `events`), then adds the functions unique to Devin's cloud (session lifecycle, PR review, and a passthrough for the rest).

| Function | Surface | Purpose |
| --- | --- | --- |
| `devin::run` | CLI | Run one local CLI turn, wait, return the result |
| `devin::start` | CLI | Start a turn and return immediately; progress on the streams |
| `devin::stop` | CLI | Interrupt a live CLI run |
| `devin::status` | CLI | A recorded run's state: live flag, status, linked Devin session id |
| `devin::sessions::list` | CLI | Every run this worker has recorded (each linked to its Devin session) |
| `devin::session::create` | Cloud | Start a Devin cloud session from a prompt |
| `devin::session::get` | Cloud | Fetch one session (status, messages, output) |
| `devin::session::message` | Cloud | Send a follow-up message to a running session |
| `devin::pr-review::trigger` | Cloud | Start a Devin review for a pull/merge request |
| `devin::pr-review::status` | Cloud | Latest Devin review for a pull/merge request |
| `devin::api` | Cloud | Raw authenticated call to any v1/v3 endpoint |

To list all Devin cloud sessions org-wide, use `devin::api {method: GET, path: sessions}` (v1) or `{path: organizations/{org_id}/sessions}` (v3); `devin::sessions::list` is scoped to the runs this worker made, matching the family convention.

`devin::run` / `devin::start` accept either a bare `prompt` string or a `messages` array (`[{ role: 'user', content: [{ type: 'text', text }] }]`), the same input contract as the claude-code and grok workers, so the acp worker can drive it with `--brain-fn devin::run`.

Because the CLI agent runs locally with the iii runtime context, a plain question makes Devin discover and operate your engine on its own, no commands spelled out:

```bash
iii trigger devin::run --json '{"prompt":"What workers are connected to this iii engine and what does each do?","cwd":"/tmp"}' | jq -r '.result'
```

![Devin answering a plain question by discovering the live iii mesh through the iii CLI](https://raw.githubusercontent.com/iii-hq/workers/main/devin/assets/iii-discovery.png)

Or ask it to map the whole engine by capability area, and it groups what it finds itself:

![Devin grouping the engine's backend capabilities by area, discovered live](https://raw.githubusercontent.com/iii-hq/workers/main/devin/assets/capabilities.png)

`devin::session::create` accepts `prompt` plus the union of the v1 and v3 create fields (`title`, `tags`, `playbook_id`, `knowledge_ids`, `secret_ids`, `max_acu_limit`; v3 `devin_mode`, `repos`, `attachment_urls`, `resumable`, `bypass_approval`; v1 `snapshot_id`, `unlisted`, `idempotent`); each is omitted from the body when not supplied, so populate the ones your token's API version accepts. `devin::session::*` follow the v1 flat paths by default and switch to v3 org-scoped paths when `org_id` is set.

### PR review

`devin::pr-review::trigger` starts a Devin review for a `pr_url`; `devin::pr-review::status` returns the latest review for that PR. Bind a GitHub PR-opened trigger to `devin::pr-review::trigger` for automatic reviews. Devin's other cloud surfaces (knowledge, playbooks, secrets, repos, code scan, org admin) are reachable through `devin::api` when a token has access to them.

### The passthrough

`devin::api` is the escape hatch for the full v3 surface (roughly 250 endpoints: knowledge, playbooks, secrets, repos, PR review, code scan, org and usage admin). It takes `{ method, path, query?, body? }`, adds the bearer token and organization header, and returns the parsed response. Reach for it whenever a capability is not one of the typed wrappers above; graduate a wrapper only when a call proves common.

### Streams and observability

`devin::run` mirrors every stdout line from the CLI verbatim onto `devin::events` (group_id = session_id) and emits a terminal AgentEvent frame onto `agent::events`, so the iii console renders a Devin CLI turn like any other agent worker. The cloud functions return their JSON directly and do not stream; poll `devin::session::get` for progress, or bind a `cron` trigger to poll on a schedule instead of looping.

Every `devin::*` call is a traced invocation on the engine with no extra instrumentation: the input payload, output, duration, and ok/error land in the console's trace explorer, including the `iii trigger` calls a `devin::run` agent makes on its own.

![Every devin::run call traced in the iii console, with input prompt and output result](https://raw.githubusercontent.com/iii-hq/workers/main/devin/assets/traces.png)

## Configuration

Managed by the `configuration` worker; `config.yaml` is the seed installed on first registration and the live value hot-reloads.

```yaml
api_key: "${DEVIN_API_KEY}"       # env-expanded on load; empty disables the API surface
org_id: "${DEVIN_ORG_ID}"         # empty = v1 personal mode; set = v3 org-scoped mode
base_url: https://api.devin.ai/v1 # set to .../v3 alongside org_id for a service key
request_timeout_secs: 120
devin_executable: ""                          # path to the devin CLI; empty = PATH
cli_extra_args: ["--permission-mode", "dangerous"]  # before `--print --`; dangerous lets the agent run iii trigger
events_stream: agent::events                  # AgentEvent frames
raw_events_stream: devin::events              # verbatim CLI stdout
iii_context: true                             # prepend iii runtime context to a CLI prompt
```

`api_key` and `org_id` are referenced as `${DEVIN_API_KEY}` and `${DEVIN_ORG_ID}` and expanded from the environment on load (an unset var becomes empty), so neither secret lives in the repo. An empty `api_key` disables the API surface while the CLI surface still works if the local `devin` binary is authenticated. `org_id` selects the API shape: empty uses the flat v1 session paths (personal tokens), set uses the v3 org-scoped paths (service keys) and becomes the required path segment for pr-review.

`iii_context` defaults on: a `devin::run` turn is prepended with the iii runtime context so the local agent discovers and calls engine functions through the `iii` CLI (turn it off per turn with `iii_context: false`). `cli_extra_args` defaults to `--permission-mode dangerous`, which is the only devin CLI mode that auto-approves command execution, so a headless run can actually run `iii trigger` against the engine; the local agent then auto-approves all tools, so drop to `accept-edits` or `auto` to restrict it.

## Dependent workers

- `configuration` (required): holds the API key, base URL, and stream names; hot-reloads changes.
- `cron` (optional): schedule `devin::session::create` or poll `devin::session::get` without a polling loop.
- `harness` (optional): fan multiple Devin runs out as sub-agents with `harness::spawn`.

## Permissions

`devin::run`, `devin::start`, `devin::session::create`, `devin::session::message`, and `devin::api` drive or mutate a Devin agent and spend ACUs, so they stay at the `needs_approval` default; an agent invoking them without human approval is a privilege escalation. The read-only introspection functions (`devin::status`, `devin::sessions::list`, `devin::session::get`, `devin::pr-review::status`) and `devin::stop` are allow-listed in `iii-permissions.yaml`.

## How it maps

| Devin | iii |
| --- | --- |
| one local `devin --print -- <prompt>` turn (SWE-1.6 agent) | `devin::run` invocation |
| every CLI stdout line, verbatim | `devin::events` stream frame |
| a Devin cloud session | `devin::session::create` / `::get` / `::message` |
| a Devin PR review | `devin::pr-review::trigger` / `::status` |
| any other v1/v3 endpoint | `devin::api` passthrough |
| scheduling a run | `cron` worker trigger, not a worker feature |
| fanning runs out | `harness::spawn`, not a worker feature |

## api reference

```json
{
  "functions": [
    {
      "description": "Raw authenticated call to any Devin v3 endpoint: {method, path, query?, body?}. Use for anything the typed devin::session::* wrappers do not cover.",
      "metadata": {},
      "name": "devin::api",
      "request_schema": {
        "description": "A raw pass-through call to any Devin v3 endpoint. Use this for anything the typed wrappers do not cover. Paths are relative to the configured base URL (e.g. `organizations/{org_id}/sessions`).",
        "properties": {
          "body": {
            "description": "Optional JSON request body."
          },
          "method": {
            "description": "HTTP method: GET, POST, PUT, PATCH, or DELETE.",
            "type": "string"
          },
          "path": {
            "description": "Path relative to the configured base URL, e.g. `organizations/{org_id}/sessions`.",
            "type": "string"
          },
          "query": {
            "description": "Optional query parameters as a flat object."
          }
        },
        "required": [
          "method",
          "path"
        ],
        "title": "ApiRequest",
        "type": "object"
      },
      "response_schema": {
        "additionalProperties": true,
        "type": "object"
      }
    },
    {
      "description": "Internal: reload devin configuration when it changes.",
      "metadata": {},
      "name": "devin::on-config-change",
      "request_schema": {
        "properties": {},
        "type": "object"
      },
      "response_schema": {
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "type": "object"
      }
    },
    {
      "description": "Get the latest Devin review status for a pull/merge request.",
      "metadata": {},
      "name": "devin::pr-review::status",
      "request_schema": {
        "description": "Look up the latest Devin PR review for a pull/merge request.",
        "properties": {
          "commit_sha": {
            "description": "Commit SHA (full or short); defaults to the PR head when omitted.",
            "type": [
              "string",
              "null"
            ]
          },
          "pr_url": {
            "description": "Full URL of the pull/merge request to look up.",
            "type": "string"
          }
        },
        "required": [
          "pr_url"
        ],
        "title": "PrReviewStatusRequest",
        "type": "object"
      },
      "response_schema": {
        "additionalProperties": true,
        "type": "object"
      }
    },
    {
      "description": "Trigger a Devin review for a pull/merge request by its URL.",
      "metadata": {},
      "name": "devin::pr-review::trigger",
      "request_schema": {
        "description": "Trigger a Devin PR review for a pull/merge request.",
        "properties": {
          "pr_url": {
            "description": "Full URL of the pull/merge request to review.",
            "type": "string"
          }
        },
        "required": [
          "pr_url"
        ],
        "title": "PrReviewTriggerRequest",
        "type": "object"
      },
      "response_schema": {
        "additionalProperties": true,
        "type": "object"
      }
    },
    {
      "description": "Run one Devin CLI turn and wait for the result. Accepts `prompt` or a `messages` array; streams raw CLI stdout onto devin::events, terminal AgentEvent frames onto agent::events, and returns {session_id, devin_session_id, url, result, stop_reason, is_error}.",
      "metadata": {},
      "name": "devin::run",
      "request_schema": {
        "definitions": {
          "Message": {
            "properties": {
              "content": {
                "description": "Either a plain string or an array of content blocks."
              },
              "role": {
                "type": "string"
              }
            },
            "required": [
              "content",
              "role"
            ],
            "type": "object"
          }
        },
        "properties": {
          "cwd": {
            "default": null,
            "description": "Working directory the CLI runs in. Empty = the worker's process directory.",
            "type": [
              "string",
              "null"
            ]
          },
          "iii_context": {
            "default": null,
            "description": "Prepend the iii runtime discovery prompt as leading instructions (default from config).",
            "type": [
              "boolean",
              "null"
            ]
          },
          "messages": {
            "description": "Alternative to prompt: role/content messages; the last user entry becomes the prompt.",
            "items": {
              "$ref": "#/definitions/Message"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "prompt": {
            "default": null,
            "description": "The prompt handed to the `devin` CLI for this turn.",
            "type": [
              "string",
              "null"
            ]
          },
          "session_id": {
            "default": null,
            "description": "iii session id; reuse to keep the same local record. Omit to generate one.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "RunRequest",
        "type": "object"
      },
      "response_schema": {
        "properties": {
          "busy": {
            "type": "boolean"
          },
          "devin_session_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_error": {
            "type": "boolean"
          },
          "num_turns": {
            "type": "integer"
          },
          "reason": {
            "type": "string"
          },
          "result": {
            "type": "string"
          },
          "session_id": {
            "type": "string"
          },
          "stop_reason": {
            "type": "string"
          },
          "url": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "type": "object"
      }
    },
    {
      "description": "Create a Devin cloud session from a prompt. Optional fields (title, tags, playbook_id, snapshot_id, idempotent, max_acu_limit, secret_ids, knowledge_ids, unlisted) map to POST /sessions.",
      "metadata": {},
      "name": "devin::session::create",
      "request_schema": {
        "definitions": {
          "Message": {
            "properties": {
              "content": {
                "description": "Either a plain string or an array of content blocks."
              },
              "role": {
                "type": "string"
              }
            },
            "required": [
              "content",
              "role"
            ],
            "type": "object"
          }
        },
        "description": "Create a Devin session. `prompt` (or a user `messages` entry) is required. The remaining fields are the union of the v1 (`POST /v1/sessions`) and v3 (`POST /v3/organizations/{org_id}/sessions`) bodies; each is omitted when absent, so populate the ones your token's API version accepts.",
        "properties": {
          "attachment_urls": {
            "default": null,
            "description": "(v3) File attachment URLs.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "bypass_approval": {
            "default": null,
            "description": "(v3) Skip approval workflows for this session.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "devin_mode": {
            "default": null,
            "description": "(v3) Agent mode: normal, fast, lite, ultra, or fusion.",
            "type": [
              "string",
              "null"
            ]
          },
          "idempotent": {
            "default": null,
            "description": "(v1) Reuse an existing matching session instead of creating a duplicate.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "knowledge_ids": {
            "default": null,
            "description": "Knowledge ids to attach to the session.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "max_acu_limit": {
            "default": null,
            "description": "Cap the session's ACU consumption.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "messages": {
            "description": "Alternative to prompt: role/content messages; the last user entry becomes the prompt.",
            "items": {
              "$ref": "#/definitions/Message"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "playbook_id": {
            "default": null,
            "description": "Playbook id to run.",
            "type": [
              "string",
              "null"
            ]
          },
          "prompt": {
            "default": null,
            "description": "The task prompt for the new Devin session.",
            "type": [
              "string",
              "null"
            ]
          },
          "repos": {
            "default": null,
            "description": "(v3) Repository identifiers to attach to the session.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "resumable": {
            "default": null,
            "description": "(v3) Preserve VM state so the session can be resumed (default true).",
            "type": [
              "boolean",
              "null"
            ]
          },
          "secret_ids": {
            "default": null,
            "description": "Secret ids to expose to the session.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "snapshot_id": {
            "default": null,
            "description": "(v1) Machine snapshot id to start the session from.",
            "type": [
              "string",
              "null"
            ]
          },
          "tags": {
            "default": null,
            "description": "Tags to apply to the session.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "title": {
            "default": null,
            "description": "Human-readable session title.",
            "type": [
              "string",
              "null"
            ]
          },
          "unlisted": {
            "default": null,
            "description": "(v1) Create the session as unlisted.",
            "type": [
              "boolean",
              "null"
            ]
          }
        },
        "title": "SessionCreateRequest",
        "type": "object"
      },
      "response_schema": {
        "additionalProperties": true,
        "type": "object"
      }
    },
    {
      "description": "Fetch one Devin cloud session (status, messages, output) by session id.",
      "metadata": {},
      "name": "devin::session::get",
      "request_schema": {
        "properties": {
          "session_id": {
            "description": "iii session id (devin::run) or Devin cloud session id (devin::session::*).",
            "type": "string"
          }
        },
        "required": [
          "session_id"
        ],
        "title": "SessionIdRequest",
        "type": "object"
      },
      "response_schema": {
        "additionalProperties": true,
        "type": "object"
      }
    },
    {
      "description": "Send a follow-up message to a running Devin cloud session.",
      "metadata": {},
      "name": "devin::session::message",
      "request_schema": {
        "description": "Send a follow-up message to a running Devin session.",
        "properties": {
          "message": {
            "description": "The message to send.",
            "type": "string"
          },
          "session_id": {
            "description": "Devin cloud session id (returned by devin::session::create).",
            "type": "string"
          }
        },
        "required": [
          "message",
          "session_id"
        ],
        "title": "SessionMessageRequest",
        "type": "object"
      },
      "response_schema": {
        "additionalProperties": true,
        "type": "object"
      }
    },
    {
      "description": "List every devin::run / devin::start session this worker has recorded, each linked to its Devin session id. For all Devin cloud sessions org-wide, use devin::api {method: GET, path: sessions}.",
      "metadata": {},
      "name": "devin::sessions::list",
      "request_schema": {
        "properties": {},
        "type": "object"
      },
      "response_schema": {
        "properties": {
          "sessions": {
            "items": {
              "type": "object"
            },
            "type": "array"
          }
        },
        "type": "object"
      }
    },
    {
      "description": "Start a Devin CLI turn and return immediately; watch devin::events / agent::events (group_id = session_id) for progress and turn_end.",
      "metadata": {},
      "name": "devin::start",
      "request_schema": {
        "definitions": {
          "Message": {
            "properties": {
              "content": {
                "description": "Either a plain string or an array of content blocks."
              },
              "role": {
                "type": "string"
              }
            },
            "required": [
              "content",
              "role"
            ],
            "type": "object"
          }
        },
        "properties": {
          "cwd": {
            "default": null,
            "description": "Working directory the CLI runs in. Empty = the worker's process directory.",
            "type": [
              "string",
              "null"
            ]
          },
          "iii_context": {
            "default": null,
            "description": "Prepend the iii runtime discovery prompt as leading instructions (default from config).",
            "type": [
              "boolean",
              "null"
            ]
          },
          "messages": {
            "description": "Alternative to prompt: role/content messages; the last user entry becomes the prompt.",
            "items": {
              "$ref": "#/definitions/Message"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "prompt": {
            "default": null,
            "description": "The prompt handed to the `devin` CLI for this turn.",
            "type": [
              "string",
              "null"
            ]
          },
          "session_id": {
            "default": null,
            "description": "iii session id; reuse to keep the same local record. Omit to generate one.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "RunRequest",
        "type": "object"
      },
      "response_schema": {
        "properties": {
          "session_id": {
            "type": "string"
          },
          "started": {
            "type": "boolean"
          }
        },
        "type": "object"
      }
    },
    {
      "description": "Point-in-time status of a local devin::run session.",
      "metadata": {},
      "name": "devin::status",
      "request_schema": {
        "properties": {
          "session_id": {
            "description": "iii session id (devin::run) or Devin cloud session id (devin::session::*).",
            "type": "string"
          }
        },
        "required": [
          "session_id"
        ],
        "title": "SessionIdRequest",
        "type": "object"
      },
      "response_schema": {
        "properties": {
          "live": {
            "type": "boolean"
          },
          "record": {
            "type": [
              "object",
              "null"
            ]
          },
          "session_id": {
            "type": "string"
          }
        },
        "type": "object"
      }
    },
    {
      "description": "Interrupt a live devin::run CLI turn for a session.",
      "metadata": {},
      "name": "devin::stop",
      "request_schema": {
        "properties": {
          "session_id": {
            "description": "iii session id (devin::run) or Devin cloud session id (devin::session::*).",
            "type": "string"
          }
        },
        "required": [
          "session_id"
        ],
        "title": "SessionIdRequest",
        "type": "object"
      },
      "response_schema": {
        "properties": {
          "reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "session_id": {
            "type": "string"
          },
          "stopped": {
            "type": "boolean"
          }
        },
        "type": "object"
      }
    }
  ],
  "triggers": []
}
```
