# How to Integrate Cloud Agents Like Codex Cloud and Devin with OmniRoute

> Learn to integrate cloud agents like Codex Cloud and Devin with OmniRoute. This guide explains registering, configuring, and calling agents via HTTP or SDK.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: how-to-guide
- Published: 2026-08-22

---

**OmniRoute treats cloud agents as first-class components that you register in the cloud-agent registry, configure via the public-creds system, and call through standard HTTP endpoints or the internal SDK.**

Integrating external AI agents such as **Codex Cloud**, **Devin**, and **Jules Task Management** into the OmniRoute framework follows a consistent registration pattern defined in the `diegosouzapw/OmniRoute` repository. The architecture abstracts each cloud agent behind a unified interface, allowing your application to orchestrate complex tasks across multiple providers without hard-coding provider-specific logic into your routes.

## Understanding OmniRoute's Cloud Agent Architecture

OmniRoute organizes cloud agent functionality into a dedicated layer under `src/lib/cloudAgent/`. This separation ensures that credentials, request handling, and provider-specific implementations remain isolated from your core business logic.

### The Cloud Agent Registry

The system discovers available agents through a central registry located at [`src/lib/cloudAgent/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/registry.ts). At startup, the server iterates over the `src/lib/cloudAgent/agents/` directory and maps each agent name to its implementing class using a simple registry pattern:

```typescript
// src/lib/cloudAgent/registry.ts
cloudAgentRegistry.set('codex', CodexCloudAgent);

```

This registry stores entries in a map structure of `{ name → AgentClass }`, which the request router consults at runtime via [`open-sse/handlers/agentHandler.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/handlers/agentHandler.ts) to delegate incoming requests.

### Secure Credential Management

All cloud agents access upstream credentials through the **public-creds** system to satisfy security hard rule #11: *Never embed public upstream credentials in source code*. The utility function `resolvePublicCred()` from [`open-sse/utils/publicCreds.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/utils/publicCreds.ts) retrieves OAuth client IDs, API keys, and secrets from environment variables or secure vaults.

When implementing a new agent, you call `resolvePublicCred()` within the constructor to fetch values like `PUBLIC_CLOUD_CODEX_CLIENT_ID` and `PUBLIC_CLOUD_CODEX_CLIENT_SECRET` without exposing them in your codebase.

### The CloudAgentBase Interface

Every cloud agent must implement the abstract `CloudAgentBase` interface, which standardizes the following methods:

- **`createTask()`** – Initializes a new task on the remote agent
- **`getStatus()`** – Polls the current execution state  
- **`approvePlan()`** – Authorizes multi-step agent workflows
- **`sendMessage()`** – Transmits context or follow-up instructions
- **`listSources()`** – Retrieves files or references generated by the agent

## Step-by-Step Integration Process

Adding support for Codex Cloud, Devin, or Jules requires three specific actions: registration, credential configuration, and API exposure.

### Step 1: Register the Agent Class

Import your agent implementation and register it with a canonical name in the registry. For Codex Cloud, this involves importing the class from [`src/lib/cloudAgent/agents/codex.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/agents/codex.ts):

```typescript
import { CodexCloudAgent } from '@/lib/cloudAgent/agents/codex';

cloudAgentRegistry.set('codex', CodexCloudAgent);

```

This registration enables the dynamic route handler at `src/app/api/v1/agents/[agent]/route.ts` to instantiate the correct class when it receives requests targeting `/v1/agents/codex`.

### Step 2: Configure Environment Credentials

Create environment variables following the public-creds naming convention. Add these to your `.env` file:

```bash
PUBLIC_CLOUD_CODEX_CLIENT_ID=your-client-id
PUBLIC_CLOUD_CODEX_CLIENT_SECRET=your-client-secret

```

The agent class automatically reads these values via `resolvePublicCred()` during initialization, ensuring the same code operates in both local development and production without modification.

### Step 3: Route Requests Through the API

OmniRoute exposes cloud agents through auto-generated API routes that execute a validation pipeline before delegation. The flow follows: **CORS handling → Zod schema validation → optional authentication → agent handler invocation**. Errors are sanitized through `buildErrorBody()` per hard rule #12 before returning to the client.

## Practical Implementation Example

The following examples demonstrate how to enable and consume the Codex Cloud agent after completing the registration steps.

### Registering Codex Cloud

Ensure your registry file imports and exposes the agent:

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

export const cloudAgentRegistry = new Map<string, new () => CloudAgentBase>();

cloudAgentRegistry.set('codex', CodexCloudAgent);

```

### Calling the Agent via HTTP

Use standard fetch requests to create tasks and poll for completion:

```typescript
// Create a new task
const response = await fetch('http://localhost:20128/v1/agents/codex/tasks', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    prompt: 'Refactor this function to use async/await',
    model: 'codex-latest'
  })
});

const { taskId } = await response.json();

// Poll until completion
let status = 'pending';
while (status !== 'completed' && status !== 'failed') {
  await new Promise(r => setTimeout(r, 2000));
  const check = await fetch(`http://localhost:20128/v1/agents/codex/tasks/${taskId}`);
  status = (await check.json()).status;
}

```

### Using the Internal SDK

For server-side usage, import the typed client from [`src/lib/cloudAgent/sdk.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/sdk.ts):

```typescript
import { CloudAgentClient } from '@/lib/cloudAgent/sdk';

const client = new CloudAgentClient({ baseUrl: 'http://localhost:20128' });

const task = await client.createTask('codex', { 
  prompt: 'Generate unit tests for the auth module' 
});

const result = await client.waitForCompletion('codex', task.taskId);
console.log(result.messages);

```

## Extending to Devin and Jules Task Management

The same architectural pattern applies to Devin and Jules Task Management. Create new files in [`src/lib/cloudAgent/agents/devin.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/agents/devin.ts) and [`src/lib/cloudAgent/agents/jules.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/agents/jules.ts) that extend `CloudAgentBase`, implement the five required methods, and register them in [`registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/registry.ts). No other parts of the codebase require modification, ensuring your integration remains maintainable as OmniRoute evolves.

## Summary

- **Register agents** in [`src/lib/cloudAgent/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/registry.ts) using `cloudAgentRegistry.set()` to make them discoverable at runtime
- **Store credentials** using the public-creds system (`resolvePublicCred()`) to comply with security hard rule #11
- **Implement** the five abstract methods from `CloudAgentBase` to standardize task lifecycle management
- **Access agents** through the auto-generated REST API at `/v1/agents/[agent]/` or via the `CloudAgentClient` SDK
- **Extend effortlessly** to new providers by following the established file structure and registration pattern

## Frequently Asked Questions

### How does OmniRoute handle authentication for cloud agent API calls?

OmniRoute delegates authentication to the public-creds utility, which retrieves OAuth tokens or API keys from environment variables at runtime. The agent implementations in `src/lib/cloudAgent/agents/*.ts` call `resolvePublicCred()` to access these secrets, ensuring they never appear in logs or source control.

### Can I use multiple cloud agents in a single OmniRoute deployment?

Yes. The registry architecture supports multiple simultaneous agents. Simply register each agent class with a unique name in [`src/lib/cloudAgent/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/registry.ts), and the dynamic route handler at `src/app/api/v1/agents/[agent]/route.ts` will route requests to the correct implementation based on the URL parameter.

### What is the difference between using the HTTP API and the internal SDK?

The HTTP API at `localhost:20128/v1/agents/` accepts raw JSON requests and returns standardized responses suitable for external clients, while the internal SDK in [`src/lib/cloudAgent/sdk.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/cloudAgent/sdk.ts) provides TypeScript types, automatic polling via `waitForCompletion()`, and direct method calls for server-side orchestration without network overhead.

### Where are cloud agent errors handled and sanitized?

All errors pass through the centralized error handler that invokes `buildErrorBody()` before reaching the client, as required by hard rule #12. This occurs in the request pipeline after the agent handler executes, ensuring sensitive stack traces or internal details never leak to API consumers.