Skip to content

Select language

Current language: English

OmniRoute Plugin SDK

import { definePlugin } from "omniroute/plugins/sdk";
export default definePlugin({
name: "my-plugin",
priority: 50,
onRequest: async (ctx) => {
console.log(`Request ${ctx.requestId} for ${ctx.model}`);
},
onResponse: async (ctx, response) => {
console.log(`Response for ${ctx.requestId}`);
return response;
},
onError: async (ctx, error) => {
console.error(`Error: ${error.message}`);
},
});

definePlugin(def: PluginDefinition): Plugin

Section titled “definePlugin(def: PluginDefinition): Plugin”

Factory function that creates a Plugin object with defaults.

Parameters:

  • name (string, required) — Plugin name in kebab-case
  • priority (number, optional, default: 100) — Lower runs first
  • enabled (boolean, optional, default: true) — Start enabled?
  • onRequest (function, optional) — Runs before chat handler
  • onResponse (function, optional) — Runs after chat handler
  • onError (function, optional) — Runs on handler error

blockRequest(response?): BlockingHookResult

Section titled “blockRequest(response?): BlockingHookResult”

Block the request and optionally return a custom response.

onRequest: (ctx) => {
if (!ctx.headers["authorization"]) {
return blockRequest({ error: "Unauthorized", status: 401 });
}
};

Modify the request body before it reaches the provider.

onRequest: (ctx) => {
return modifyBody({ ...ctx.body, temperature: 0.7 });
};

Attach metadata to the request context.

onRequest: (ctx) => {
return addMetadata({ source: "my-plugin", version: "1.0.0" });
};
Field Type Description
requestId string Unique request identifier
model string Requested model name
provider string Target provider ID
body Record<string, unknown> Request body
headers Record<string, string> Request headers
metadata Record<string, unknown> Mutable metadata
timestamp number Request timestamp
{
"name": "my-plugin",
"version": "1.0.0",
"description": "A sample plugin",
"author": "your-name",
"main": "index.js",
"hooks": {
"onRequest": { "enabled": true, "priority": 50 },
"onResponse": true,
"onError": false
},
"requires": {
"permissions": ["network", "file-read"]
},
"enabledByDefault": false,
"configSchema": {
"apiKey": { "type": "string", "description": "API key for external service" },
"maxRetries": { "type": "number", "min": 1, "max": 10, "default": 3 },
"debug": { "type": "boolean", "default": false },
"mode": { "type": "string", "enum": ["fast", "slow"], "default": "fast" }
}
}

Hooks can be configured with priority (lower = runs first):

{
"hooks": {
"onRequest": { "enabled": true, "priority": 10 },
"onResponse": { "enabled": true, "priority": 100 }
}
}

Or as simple booleans (default priority 100):

{
"hooks": {
"onRequest": true,
"onResponse": true
}
}

Plugins run in a sandboxed VM context. Access to external resources requires explicit permissions:

Permission Grants
network fetch, AbortController, Headers, Request, Response
file-read fs.readFile, fs.readdir, fs.stat
file-write fs.writeFile, fs.mkdir, fs.rm
env Read-only process.env proxy
exec child_process.exec, child_process.execSync

Without a permission, the corresponding globals are simply not available in the sandbox.

Define configurable settings in configSchema:

{
"configSchema": {
"apiKey": { "type": "string", "description": "External API key" },
"maxRetries": { "type": "number", "min": 1, "max": 10, "default": 3 },
"debug": { "type": "boolean", "default": false },
"mode": { "type": "string", "enum": ["fast", "slow"], "default": "fast" }
}
}

Field types: string, number, boolean, select

Field options: default, min, max, enum, description

Config values are persisted in the database and accessible via the dashboard config page.

Event When Payload
onRequest Before chat handler Request context
onResponse After chat handler Response data
onError On handler error Error object
onModelSelect Model selected for routing Model info
onComboResolve Combo routing resolved Combo targets
onRateLimit Rate limit hit Limit info
onQuotaExhaust Quota exhausted Quota info
onProviderError Provider returned error Error details
onStreamStart SSE stream started Stream info
onStreamEnd SSE stream ended Stream stats
onInstall Plugin installed { name, version, manifest }
onActivate Plugin activated { name, version, manifest }
onDeactivate Plugin deactivated { name, version, manifest }
onUninstall Plugin uninstalled (before files deleted) { name, version, manifest }
import { definePlugin } from "omniroute/plugins/sdk";
export default definePlugin({
name: "request-logger",
onRequest: async (ctx) => {
console.log(`[${new Date().toISOString()}] ${ctx.method} ${ctx.model} -> ${ctx.provider}`);
},
});
import { definePlugin, blockRequest } from "omniroute/plugins/sdk";
const requests = new Map<string, number[]>();
export default definePlugin({
name: "rate-limiter",
priority: 10,
onRequest: async (ctx) => {
const key = ctx.headers["x-api-key"] || "anonymous";
const now = Date.now();
const window = 60000; // 1 minute
const maxRequests = 100;
const timestamps = (requests.get(key) || []).filter((t) => t > now - window);
timestamps.push(now);
requests.set(key, timestamps);
if (timestamps.length > maxRequests) {
return blockRequest({ error: "Rate limit exceeded", status: 429 });
}
},
});
import { definePlugin } from "omniroute/plugins/sdk";
export default definePlugin({
name: "response-transformer",
onResponse: async (ctx, response) => {
if (response.choices) {
response.choices = response.choices.map((c: any) => ({
...c,
message: { ...c.message, content: c.message.content.trim() },
}));
}
return response;
},
});

undefined (a58000c7685f)

HagiCode

HagiCode is an agentic coding workspace. Rich, convenient UI interactions make planning, agent execution, and project work approachable and easy to navigate, creating an engaging development experience.

Explore an engaging development experience through rich, convenient UI interactions.

Visit HagiCodeRead the documentation
  • SmartOpenSpec workflows turn intent into an executable path, from proposal to design, tasks, and a shipped change.
  • EfficientMulti-agent execution keeps research, implementation, and review moving in parallel, across several repositories and the Agent CLIs you already use.
  • InterestingRich, convenient UI interactions make planning, agent execution, and project work approachable and easy to navigate.

Download for Windows

Get it from Microsoft StoreAll downloads

Turn ideas into shipped software.

HagiCode is an agentic coding workspace. OpenSpec workflows plan the change, multi-agent execution carries it out, and Hero Scenario makes the long run visible, so ideas become shipped software.

Smart
OpenSpec workflows turn intent into a path from proposal to shipped change.
Efficient
Multi-agent execution runs research, build, and review in parallel.
Fun
Rich UI interactions make planning, agent work, and projects easier to follow.