OpenRouter Chat Completion Agent
This integration calls OpenRouter's chat completions API with your input text and returns the model's text output. OpenRouter gives you access to many models behind a single key.
Required secrets
| Secret | What it is |
|---|---|
OPENROUTER_API_KEY | API key for calling OpenRouter chat completions. |
Where to get the credentials
Generate an API key in your OpenRouter account settings, then store it as a
project secret named OPENROUTER_API_KEY.
Turn support
Single-turn. Each evaluation case is sent as an independent request. For a conversational variant, use the OpenRouter Multi-Turn Chat Completion Agent.
Limitations and notes
- The model and system prompt are set in the copied agent code. Edit the agent if you need to change them.
- Calls are billed to your own OpenRouter account, subject to its quotas and rate limits.
How the agent works
The copied agent is a single JavaScript function. This walkthrough follows the real code so you can adapt the same pattern to point at a different service.
The entry point is process(input), where input is the per-case text the
platform sends you:
export async function process(input) {
try {
const apiKey = String(env.OPENROUTER_API_KEY ?? "").trim();
const parsed = parseInput(input);
// ...
The secret is read from the ambient env object by key —
env.OPENROUTER_API_KEY — and trimmed. See Required secrets
for the key you must declare.
parseInput accepts either plain text or a JSON object. A bare string is used
as-is; a JSON object lets a case override the prompt, model, and system prompt:
const parsed = JSON.parse(raw);
// ...
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
return {
text: String(parsed.text ?? parsed.prompt ?? parsed.input ?? "").trim(),
model: String(parsed.model ?? DEFAULT_MODEL).trim() || DEFAULT_MODEL,
system: String(
parsed.system ?? parsed.instructions ?? DEFAULT_SYSTEM_PROMPT,
).trim(),
};
}
buildMessages turns the parsed input into the chat-completions messages
array, prepending a system message only when a system prompt is set:
const buildMessages = ({ text, system }) => {
const messages = [];
const systemPrompt = String(system ?? DEFAULT_SYSTEM_PROMPT).trim();
if (systemPrompt) {
messages.push({ role: "system", content: systemPrompt });
}
messages.push({ role: "user", content: text });
return messages;
};
The HTTP request is a POST with a Bearer auth header plus OpenRouter's
attribution headers, and a JSON body of { model, messages }:
const response = await fetch(ENDPOINT, {
method: "POST",
headers: {
authorization: `Bearer ${apiKey}`,
"content-type": "application/json",
"HTTP-Referer": ATTRIBUTION_REFERER,
"X-Title": ATTRIBUTION_TITLE,
},
body: JSON.stringify({
model: parsed.model,
messages: buildMessages(parsed),
}),
});
The response text is parsed as JSON, then extractResponseText reads the first
choice's message.content (a plain string, or an array of parts joined together):
const extractResponseText = (payload) => {
const choices = Array.isArray(payload?.choices) ? payload.choices : [];
for (const choice of choices) {
const content = choice?.message?.content;
if (typeof content === "string" && content.trim()) {
return content.trim();
}
// ...
}
// ...
return "";
};
On success the function returns { ok: true, text, id, model }. Every failure
path — missing input, a non-2xx status, or an empty reply — returns an object
with ok: false rather than throwing, and the outer try/catch converts any
unexpected exception into the same shape:
if (!response.ok) {
return {
ok: false,
error: "openrouter_request_failed",
status: response.status,
details: extractErrorMessage(payload, responseText),
};
}
Adapting it for your own agent
To repoint this skeleton at a different service, change a handful of things:
ENDPOINT— the URL youPOSTto.- The auth header (and the attribution headers, which are OpenRouter-specific).
- The request body shape —
{ model, messages }here; match your provider's schema. extractResponseText— read the field your provider returns the text in.- The secret key read from
env(and its entry in Required secrets).
Set it up
- Copy this integration from the registry — see Registry integrations.
- Create the project secret above — see Project secrets.
- Preview the agent to confirm it works.