How to Set Up and Authenticate OmniRoute Cloud Agents (Codex, Cursor, Devin, Jules)
OmniRoute provides a modular Cloud Agent framework where you authenticate Codex, Cursor, Devin, and Jules by creating an AgentCredentials object containing an apiKey and passing it to provider-specific agent classes that inherit from CloudAgentBase.
The OmniRoute repository (diegosouzapw/OmniRoute) ships a unified interface for orchestrating third-party AI agents through a modular Cloud Agent framework. To set up and authenticate OmniRoute cloud agents, you instantiate provider-specific classes—CodexCloudAgent, CursorCloudAgent, DevinAgent, and JulesAgent—and supply credentials explicitly via the AgentCredentials type. This design keeps authentication explicit and testable, ensuring your API keys never leak to the client while enabling seamless integration with OpenAI Codex, Cursor AI, Devin AI, and Google Jules.
Understanding the Cloud Agent Architecture
OmniRoute abstracts cloud agents behind a uniform API defined in src/lib/cloudAgent/baseAgent.ts. The CloudAgentBase abstract class implements shared functionality such as ID generation, generic status mapping, and the public interface (createTask, getStatus, sendMessage, approvePlan, listSources).
Concrete implementations reside in src/lib/cloudAgent/agents/:
CodexCloudAgenthandles OpenAI Codex Cloud REST calls.CursorCloudAgentmanages Cursor Cloud Agents.DevinAgentinterfaces with Devin AI.JulesAgentcontrols Google Jules sessions.
The CloudAgentRegistry in src/lib/cloudAgent/registry.ts acts as a factory, resolving provider IDs (codex-cloud, cursor-cloud, devin, jules) to the correct concrete class. Shared type definitions—including CloudAgentTask, CloudAgentActivity, and CloudAgentStatus—live in src/lib/cloudAgent/types.ts.
Authentication Requirements and Credentials
All agents rely on the AgentCredentials type defined in src/lib/cloudAgent/credentials.ts. This interface requires:
apiKey: A string obtained from the respective service dashboard (OpenAI, Cursor, Devin, or Google).baseUrl(optional): Override the default API endpoint (commonly used for Cursor staging environments).
Crucially, agents do not read environment variables directly. You must construct the credentials object and pass it to every method call. This explicit pattern ensures type safety and prevents accidental key exposure.
Step-by-Step Setup for Each Provider
Below are minimal, runnable TypeScript snippets demonstrating how to configure credentials and instantiate each agent. Replace placeholder values with real API keys from your service dashboards.
OpenAI Codex Cloud Agent
The CodexCloudAgent class in src/lib/cloudAgent/agents/codex.ts implements the POST /codex/cloud/tasks endpoint and status polling logic.
import { CodexCloudAgent } from '@omniroute/cloudAgent/agents/codex';
import type { AgentCredentials } from '@omniroute/cloudAgent/credentials';
const codex = new CodexCloudAgent();
const credentials: AgentCredentials = {
apiKey: process.env.CODEX_API_KEY || ''
};
const task = await codex.createTask(
{
prompt: 'Explain why the sky is blue.',
source: { repoUrl: 'https://github.com/example/repo', repoName: 'repo' },
options: {}
},
credentials
);
console.log('Codex task created, external id:', task.externalId);
// Poll status until completed
let statusResult = await codex.getStatus(task.externalId, credentials);
while (statusResult.status !== 'COMPLETED') {
await new Promise(r => setTimeout(r, 2_000));
statusResult = await codex.getStatus(task.externalId, credentials);
}
console.log('Result:', statusResult.result);
Cursor Cloud Agent
Implemented in src/lib/cloudAgent/agents/cursor.ts, the CursorCloudAgent maps proprietary status enums to the shared CLOUD_AGENT_STATUS map. You may optionally override the baseUrl for staging environments.
import { CursorCloudAgent } from '@omniroute/cloudAgent/agents/cursor';
const cursor = new CursorCloudAgent();
const credentials = {
apiKey: process.env.CURSOR_API_KEY || '',
baseUrl: 'https://staging.api.cursor.com/v0' // Optional override
};
const task = await cursor.createTask(
{
prompt: 'Refactor this function to be async.',
source: { repoUrl: 'https://github.com/example/repo', repoName: 'repo' },
options: { autoCreatePr: true }
},
credentials
);
console.log('Cursor task created, external id:', task.externalId);
Devin AI Agent
The DevinAgent in src/lib/cloudAgent/agents/devin.ts posts to https://api.devin.ai/v1/sessions and translates provider-specific status codes via the mapStatus method.
import { DevinAgent } from '@omniroute/cloudAgent/agents/devin';
const devin = new DevinAgent();
const credentials = { apiKey: process.env.DEVIN_API_KEY || '' };
const task = await devin.createTask(
{
prompt: 'Write a unit test for function foo().',
source: { repoUrl: 'https://github.com/example/repo', repoName: 'repo' },
options: {}
},
credentials
);
console.log('Devin task created, external id:', task.externalId);
Google Jules Agent
Unique among the four, JulesAgent (in src/lib/cloudAgent/agents/jules.ts) supports plan approval workflows via the approvePlan method. It constructs Google-specific source resources (sources/github/<owner>/<repo>) and handles the plan-approval endpoint.
import { JulesAgent } from '@omniroute/cloudAgent/agents/jules';
const jules = new JulesAgent();
const credentials = { apiKey: process.env.JULES_API_KEY || '' };
const task = await jules.createTask(
{
prompt: 'Add type safety to this TypeScript file.',
source: {
repoUrl: 'https://github.com/example/repo',
repoName: 'my-repo',
branch: 'main'
},
options: { autoCreatePr: true, planApprovalRequired: true }
},
credentials
);
console.log('Jules session created, id:', task.externalId);
// Approve the generated plan
await jules.approvePlan(task.externalId, credentials);
Factory Pattern with CloudAgentRegistry
If you prefer dynamic resolution over hard-coded imports, use the CloudAgentRegistry from src/lib/cloudAgent/registry.ts. This factory returns the appropriate agent instance based on a provider ID string.
import { CloudAgentRegistry } from '@omniroute/cloudAgent/registry';
const registry = new CloudAgentRegistry();
const agent = registry.getAgent('cursor-cloud'); // Returns CursorCloudAgent instance
const credentials = { apiKey: process.env.CURSOR_API_KEY || '' };
const task = await agent.createTask({ /* ... */ }, credentials);
Supported provider IDs include:
codex-cloudcursor-clouddevinjules
Summary
- OmniRoute cloud agents inherit from
CloudAgentBaseand implement provider-specific REST calls insrc/lib/cloudAgent/agents/. - Authentication requires an
AgentCredentialsobject with anapiKey(and optionalbaseUrlfor Cursor) passed explicitly to each method. - The four supported providers are instantiated via
CodexCloudAgent,CursorCloudAgent,DevinAgent, andJulesAgent. - Use
CloudAgentRegistryto resolve agent instances dynamically using provider IDs likecodex-cloudorjules. - All agents expose a uniform interface (
createTask,getStatus,approvePlan) while handling provider-specific headers and endpoints internally.
Frequently Asked Questions
What authentication format does OmniRoute require for cloud agents?
OmniRoute expects an AgentCredentials object containing at least an apiKey string. For Cursor, you may optionally include a baseUrl to override the default endpoint. According to the source code in src/lib/cloudAgent/credentials.ts, the agents do not read environment variables directly; you must pass the credentials object to every method call.
How do I switch between different AI providers without changing my code?
Use the CloudAgentRegistry class from src/lib/cloudAgent/registry.ts. By calling registry.getAgent(providerId) with identifiers like codex-cloud, cursor-cloud, devin, or jules, you obtain the correct instantiated agent without hard-coding the specific class imports, enabling provider-agnostic workflows.
Does OmniRoute store my API keys or send them to the client?
No. The agent classes in src/lib/cloudAgent/agents/ inject credentials into HTTP headers during REST calls to the respective services (Codex, Cursor, Devin, Jules). The keys remain server-side and are never exposed to the client, as implemented in the base class and provider-specific agents.
Which OmniRoute cloud agent supports plan approval workflows?
The JulesAgent class in src/lib/cloudAgent/agents/jules.ts specifically implements the approvePlan method, which calls a dedicated endpoint to approve generated plans after task creation. This capability is unique to the Google Jules integration among the four supported agents.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →