How to Integrate Cloud Agents like Codex Cloud with OmniRoute
OmniRoute integrates cloud agents like Codex Cloud by registering the agent class in the central registry, configuring credentials through the public-creds system, and exposing standardized lifecycle methods through an auto-generated HTTP API or typed SDK.
OmniRoute provides a modular cloud-agent layer for orchestrating external AI services through a unified interface. The diegosouzapw/OmniRoute repository implements this architecture via the CloudAgentBase abstraction, allowing you to integrate Codex Cloud without hardcoding secrets or modifying core routing logic. This guide details the exact file paths, method signatures, and credential patterns required to register, authenticate, and invoke Codex Cloud agents.
Register the Agent in the Central Registry
OmniRoute discovers cloud agents at runtime through a central registry located in src/lib/cloudAgent/registry.ts. This file maintains a simple map that associates a canonical name with the agent class. To enable Codex Cloud, import the agent implementation and add it to the registry.
// src/lib/cloudAgent/registry.ts
import { CodexCloudAgent } from '@/lib/cloudAgent/agents/codex';
// Register under the canonical name "codex"
cloudAgentRegistry.set('codex', CodexCloudAgent);
When the server starts, the registry iterates over src/lib/cloudAgent/agents/* and registers each class that implements the CloudAgentBase interface. The request router in open-sse/handlers/agentHandler.ts consults this map to delegate incoming requests.
Configure Secure Credentials
Codex Cloud requires OAuth client credentials or API keys. OmniRoute enforces security rule #11—never embed public upstream credentials in source code—by storing secrets outside the codebase and accessing them via resolvePublicCred() from open-sse/utils/publicCreds.ts.
The Codex Cloud agent constructor in src/lib/cloudAgent/agents/codex.ts automatically pulls these values:
// Ensure these environment variables are set (never commit to repo)
// PUBLIC_CLOUD_CODEX_CLIENT_ID=your-client-id
// PUBLIC_CLOUD_CODEX_CLIENT_SECRET=your-client-secret
// The agent reads them automatically via:
const clientId = resolvePublicCred('PUBLIC_CLOUD_CODEX_CLIENT_ID');
const clientSecret = resolvePublicCred('PUBLIC_CLOUD_CODEX_CLIENT_SECRET');
This pattern allows the agent to function identically in local development and production without source-code changes.
Invoke the Agent via HTTP API
Once registered, each agent exposes a REST endpoint under src/app/api/v1/agents/[agent]/route.ts. The pipeline applies CORS headers, Zod validation, optional authentication, and error sanitization via buildErrorBody() (security rule #12) before delegating to the agent handler.
Create a task, poll for status, and retrieve messages:
// Create a task
const response = await fetch('http://localhost:20128/v1/agents/codex/tasks', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: 'Write a function that returns the Fibonacci series.',
// optional: model, temperature, etc.
}),
});
const task = await response.json(); // { taskId, status, ... }
// Poll status until completion
let status = task.status;
while (status !== 'completed' && status !== 'failed') {
await new Promise(r => setTimeout(r, 2000));
const statusRes = await fetch(
`http://localhost:20128/v1/agents/codex/tasks/${task.taskId}`
);
const statusData = await statusRes.json();
status = statusData.status;
}
// Retrieve final messages
if (status === 'completed') {
const msgRes = await fetch(
`http://localhost:20128/v1/agents/codex/tasks/${task.taskId}/messages`
);
const result = await msgRes.json();
console.log('Codex answer:', result.messages);
}
Use the Typed SDK for Programmatic Access
For internal services or server-side scripts, OmniRoute provides a typed client in src/lib/cloudAgent/sdk.ts that wraps the HTTP API:
import { CloudAgentClient } from '@/lib/cloudAgent/sdk';
const client = new CloudAgentClient({ baseUrl: 'http://localhost:20128' });
// Create and wait for completion in one flow
const task = await client.createTask('codex', {
prompt: 'Summarize the Agile manifesto.'
});
const answer = await client.waitForCompletion('codex', task.taskId);
console.log(answer);
The SDK handles polling logic, timeout management, and type-safe request/response shapes defined by the CloudAgentBase interface.
Architecture Overview
Agent Discovery
At startup, src/lib/cloudAgent/registry.ts scans src/lib/cloudAgent/agents/* and instantiates a registry map of { name → AgentClass }. This map drives dynamic routing so adding a new agent requires no changes to the API layer.
Credential Isolation
All upstream secrets flow through resolvePublicCred() in open-sse/utils/publicCreds.ts. This indirection ensures that sensitive values reside in environment variables or secret stores, not in src/lib/cloudAgent/agents/codex.ts or similar implementation files.
Standardized Interface
Every cloud agent extends CloudAgentBase and implements five abstract methods: createTask, getStatus, approvePlan, sendMessage, and listSources. The Codex Cloud agent provides concrete implementations for these, mapping OmniRoute's standardized calls to Codex Cloud's proprietary endpoints.
Request Routing
Incoming requests hit src/app/api/v1/agents/[agent]/route.ts, which validates the [agent] parameter against the registry. Valid requests are forwarded to open-sse/handlers/agentHandler.ts, which invokes the appropriate method on the registered class. Errors are sanitized through buildErrorBody() to prevent credential leakage.
Summary
- Register cloud agents in
src/lib/cloudAgent/registry.tsby importing the class and callingcloudAgentRegistry.set(name, AgentClass). - Isolate credentials using
resolvePublicCred()fromopen-sse/utils/publicCreds.tsto comply with OmniRoute's security rules. - Interact via the auto-generated REST API at
/v1/agents/[agent]/or theCloudAgentClientSDK insrc/lib/cloudAgent/sdk.ts. - Extend the system by implementing the
CloudAgentBaseinterface for new providers, placing the file undersrc/lib/cloudAgent/agents/.
Frequently Asked Questions
How does OmniRoute handle authentication for cloud agents?
OmniRoute uses the public-creds system accessed via resolvePublicCred() in open-sse/utils/publicCreds.ts. This utility reads environment variables at runtime, ensuring OAuth client IDs and API secrets are never hardcoded in src/lib/cloudAgent/agents/codex.ts or committed to version control.
What methods must a cloud agent implement to integrate with OmniRoute?
Every cloud agent must extend the abstract CloudAgentBase class and implement createTask, getStatus, approvePlan, sendMessage, and listSources. These methods form the contract that open-sse/handlers/agentHandler.ts expects when routing requests.
Can I run multiple cloud agents simultaneously in one OmniRoute instance?
Yes. The registry in src/lib/cloudAgent/registry.ts maintains a key-value map allowing multiple agents to coexist. Each agent is accessible via its own dynamic route generated by src/app/api/v1/agents/[agent]/route.ts, so you can register Codex Cloud alongside custom or third-party agents without conflicts.
How do I poll for task completion when using the Codex Cloud integration?
After creating a task via POST to /v1/agents/codex/tasks, poll GET /v1/agents/codex/tasks/{taskId} until the status field returns completed or failed. Alternatively, use the CloudAgentClient.waitForCompletion() method from src/lib/cloudAgent/sdk.ts to handle polling automatically.
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 →