# Cloud Agent Integrations in OmniRoute: How External AI Services Are Implemented as First-Class Providers

> Explore OmniRoute's cloud agent integrations, seamlessly incorporating external AI services like Jules, Devin, and Codex as first-class providers. Learn how.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: deep-dive
- Published: 2026-08-06

---

**OmniRoute integrates five cloud agents (Jules, Devin, Codex, Cursor, and Cursor-cloud) through a pluggable framework defined in [`src/lib/cloudAgent/baseAgent.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/baseAgent.ts), where each agent extends `CloudAgentBase` and implements four lifecycle methods: `createTask`, `getStatus`, `sendMessage`, and `listSources`.**

The **cloud agent integrations in OmniRoute** transform external AI coding services into native routing targets. Rather than treating these platforms as black-box APIs, OmniRoute's architecture—as implemented in `diegosouzapw/OmniRoute`—abstracts them through a common interface that inherits the router's resilience patterns, credential encryption, and task persistence.

## Supported Cloud Agents in OmniRoute

The current release (`v3.8.50`) ships with five built-in cloud agent integrations. Each maps to a unique provider ID and serves distinct AI-assisted development workflows.

| Agent | Provider ID | Core Purpose |
|-------|-------------|--------------|
| **Jules** | `jules` | Connects to the Jules.ai cloud API for chat-completion style interactions |
| **Devin** | `devin` | Drives the Devin CLI service for autonomous code-generation tasks |
| **Codex** | `codex` | Calls the OpenAI Codex endpoint via a thin TypeScript wrapper |
| **Cursor** | `cursor` | Uses Cursor's public REST API with API-key-only authentication |
| **Cursor-cloud** | `cursor-cloud` | OAuth-free variant added in v3.8.50 for streamlined background agents |

## The Cloud Agent Base Class Architecture

All cloud agent integrations in OmniRoute derive from a single abstract class defined in [`src/lib/cloudAgent/baseAgent.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/baseAgent.ts). This **common abstraction** enforces a four-method contract that every concrete agent must fulfill.

### Required Lifecycle Methods

| Method | Signature | Purpose |
|--------|-----------|---------|
| `createTask` | `(prompt: string, …): Promise<string>` | Starts a remote task and stores the external task ID |
| `getStatus` | `(taskId: string): Promise<CloudAgentStatus>` | Polls the remote service and maps status to `CREATING`, `RUNNING`, `FINISHED`, or `ERROR` |
| `sendMessage` | `(taskId: string, message: string): Promise<void>` | Sends incremental input to an already-running task |
| `listSources` | `(taskId: string): Promise<SourceFile[]>` | Retrieves generated artifacts or source files |

The `CloudAgentBase` constructor handles credential decryption and exposes `baseUrl` and authentication headers to subclasses, eliminating redundant security logic across agent implementations.

## How the Framework Is Wired Together

Four core modules orchestrate cloud agent integrations in OmniRoute:

**[`src/lib/cloudAgent/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/registry.ts)** — Provider Resolution

- Maintains a map `providerId → CloudAgentClass`
- Factory method instantiates agents with decrypted credentials
- New agents register via `cloudAgentRegistry.register('id', AgentClass)`

**[`src/lib/cloudAgent/credentials.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/credentials.ts)** — Secure Authentication

- Encrypts API keys and OAuth tokens in the `cloud_agent_credentials` SQLite table
- Decrypts on agent instantiation
- Supports per-provider credential schemas

**[`src/lib/cloudAgent/db.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/db.ts)** — Task Persistence

- Stores task records in `cloud_agent_tasks` linking OmniRoute task IDs to external `external_id` values
- Enables asynchronous polling and UI state synchronization

**[`src/lib/cloudAgent/api.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/api.ts) and [`src/lib/cloudAgent/index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/index.ts)** — Public REST API

- Exposes endpoints under `/api/v1/agents/*`
- Validates inputs with Zod schemas
- Enforces authentication before delegating to agent implementations

## Agent Implementation Pattern

Each concrete agent follows an identical skeleton. Here is the structural pattern from [`src/lib/cloudAgent/agents/jules.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/agents/jules.ts), [`agents/devin.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/agents/devin.ts), [`agents/cursor.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/agents/cursor.ts), and [`agents/codex.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/agents/codex.ts):

```typescript
export class XxxAgent extends CloudAgentBase {
  async createTask(prompt: string, …): Promise<string> {
    // HTTP POST to provider endpoint
    // Store returned external ID in cloud_agent_tasks table
  }

  async getStatus(taskId: string): Promise<CloudAgentStatus> {
    // HTTP GET to provider status endpoint
    // Map provider-specific enum to CloudAgentStatus union
  }

  async sendMessage(taskId: string, msg: string): Promise<void> {
    // HTTP PATCH or POST for incremental prompts
  }

  async listSources(taskId: string): Promise<SourceFile[]> {
    // HTTP GET to fetch generated files or code snippets
  }
}

```

All HTTP traffic routes through `open-sse/executors/`, inheriting OmniRoute's **retry logic**, **circuit breakers**, and **rate limiting**. Errors are sanitized through [`open-sse/utils/error.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/utils/error.ts) before client exposure.

## Request Flow Through the Cloud Agent System

Understanding the end-to-end flow clarifies how cloud agent integrations in OmniRoute maintain stateful, resilient interactions with external services.

1. **Client submits task** → `POST /api/v1/agents/tasks` with provider ID and prompt
2. **API handler** validates payload with Zod, resolves provider from registry
3. **Agent instantiation** → registry returns concrete class with decrypted credentials
4. **`createTask` execution** → HTTP POST to remote service, external ID persisted to `cloud_agent_tasks`
5. **Polling loop** → `GET /agents/tasks/:id` invokes `getStatus`, updates database, returns to client
6. **Continued interaction** → `sendMessage` for follow-up prompts, `listSources` for artifact retrieval

## Practical Code Examples

### Creating a Task with the Jules Agent

```typescript
import { cloudAgentRegistry } from '@/lib/cloudAgent/registry';

const agent = cloudAgentRegistry.get('jules'); // returns JulesAgent instance
const externalId = await agent.createTask('Write a TypeScript utility for parsing JSON streams');
// externalId stored in cloud_agent_tasks with status 'CREATING'

```

*Source: [`src/lib/cloudAgent/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/registry.ts)*

### Polling Task Status and Retrieving Results

```typescript
const status = await agent.getStatus(externalId);

if (status === 'FINISHED') {
  const files = await agent.listSources(externalId);
  // files: Array<{ path: string; content: string }>
} else if (status === 'ERROR') {
  // Handle failure per open-sse/utils/error.ts patterns
}

```

*Source: [`src/lib/cloudAgent/agents/jules.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/agents/jules.ts)*

### Registering a New Custom Agent

```typescript
// src/lib/cloudAgent/registry.ts
import { MyAIAgent } from './agents/myai';

cloudAgentRegistry.register('myai', MyAIAgent);

```

Only three steps required: extend `CloudAgentBase`, register in [`registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/registry.ts), and add credential definition if needed. No modifications to core routing logic.

## Key Files for Cloud Agent Integrations in OmniRoute

| File | Role |
|------|------|
| [`src/lib/cloudAgent/baseAgent.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/baseAgent.ts) | Abstract base class defining the cloud-agent contract |
| [`src/lib/cloudAgent/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/registry.ts) | Provider-ID to implementation mapping and factory |
| [`src/lib/cloudAgent/credentials.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/credentials.ts) | Encrypted storage and retrieval of API keys/tokens |
| [`src/lib/cloudAgent/db.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/db.ts) | SQLite persistence layer for tasks and credentials |
| [`src/lib/cloudAgent/api.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/api.ts) | Public HTTP endpoints for agent operations |
| [`src/lib/cloudAgent/agents/jules.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/agents/jules.ts) | Jules.ai integration implementation |
| [`src/lib/cloudAgent/agents/devin.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/agents/devin.ts) | Devin CLI service integration |
| [`src/lib/cloudAgent/agents/cursor.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/agents/cursor.ts) | Cursor REST API integration |
| [`src/lib/cloudAgent/agents/codex.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/agents/codex.ts) | OpenAI Codex wrapper implementation |

## Summary

- OmniRoute supports **five cloud agent integrations** (Jules, Devin, Codex, Cursor, Cursor-cloud) through a unified framework
- The **`CloudAgentBase` abstraction** in [`src/lib/cloudAgent/baseAgent.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/baseAgent.ts) enforces consistent lifecycle methods across all providers
- **Registry pattern** enables runtime provider resolution without core router modifications
- **Encrypted credential storage** and **SQLite task persistence** provide production-grade security and state management
- New agents require only three implementation steps; the framework inherits OmniRoute's **retry, circuit-breaker, and rate-limiting** capabilities automatically

## Frequently Asked Questions

### How do I add a new cloud agent integration to OmniRoute?

Extend `CloudAgentBase` from [`src/lib/cloudAgent/baseAgent.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/baseAgent.ts), implement the four required methods (`createTask`, `getStatus`, `sendMessage`, `listSources`), then register your class in [`src/lib/cloudAgent/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/registry.ts) with `cloudAgentRegistry.register('your-id', YourAgentClass)`. Add credential definitions in [`credentials.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/credentials.ts) if your service requires API keys or tokens.

### Where are cloud agent API keys stored in OmniRoute?

API keys and OAuth tokens are encrypted in the `cloud_agent_credentials` SQLite table, managed by [`src/lib/cloudAgent/credentials.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/credentials.ts). The `CloudAgentBase` constructor automatically decrypts credentials when instantiating agent classes, exposing `baseUrl` and auth headers to implementations without exposing secrets in code.

### What happens when a cloud agent task fails?

Errors propagate through [`open-sse/utils/error.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/utils/error.ts) for sanitization before reaching clients. The `getStatus` method returns `ERROR` status, which persists in the `cloud_agent_tasks` table. All HTTP calls inherit retry logic and circuit-breaker patterns from OmniRoute's executor layer in `open-sse/executors/`.

### How does OmniRoute track cloud agent task state across restarts?

The `cloud_agent_tasks` table in [`src/lib/cloudAgent/db.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/db.ts) persists the mapping between OmniRoute task IDs and provider `external_id` values. This allows polling endpoints to resume status checks after service restarts, and enables the UI to reconstruct task history from durable storage.