Files
OmniRoute/docs/i18n/el/docs/frameworks/PLUGIN_SDK.md
Diego Rodrigues de Sa e Souza 8feea123bb feat(docs): mirror every docs/ page in all 65 locales (#14106)
* feat(docs): mirror every docs/ page in all 65 locales

Extends the documentation mirrors from the 22-page core set (#13940) to
every Markdown page under docs/: 152 sources x 65 locales = 9,880 mirrors
(6,208 new), language bars rewritten for the full locale list, state
adopted so the blocking drift gate now covers all 152 pages.

run-translation.mjs: an oversized block made only of table rows or list
items (PROVIDER_REFERENCE.md 244-row table, FREE_TIERS.md 71-item list) is
cut at item boundaries and rejoined without a blank line — the single
16-40 KB request outlived the backend socket for verbose scripts. 48
older mirrors whose tables had lost rows were retranslated with --force.

* docs(i18n): refresh mirrors for the sources the base changed since the branch cut

Section-level retranslation of the 29 docs (and README.md) whose source
or mirrors moved on release/v3.8.51 during the run, then state adoption;
the drift gate is green again on the merged tree.
2026-09-18 13:16:46 -03:00

14 KiB
Raw Blame History

OmniRoute Plugin SDK (Ελληνικά)

🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇦🇲 hy · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW


Γρήγορη εκκίνηση

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}`);
  },
});

Αναφορά API

definePlugin(def: PluginDefinition): Plugin

Συνάρτηση εργοστασίου που δημιουργεί ένα αντικείμενο Plugin με προεπιλεγμένες τιμές.

Παράμετροι:

  • name (string, απαιτείται) — Όνομα plugin σε μορφή kebab-case
  • priority (number, προαιρετικό, προεπιλογή: 100) — Η χαμηλότερη τιμή εκτελείται πρώτη
  • enabled (boolean, προαιρετικό, προεπιλογή: true) — Να ξεκινά ενεργοποιημένο;
  • onRequest (function, προαιρετικό) — Εκτελείται πριν από τον χειριστή συνομιλίας
  • onResponse (function, προαιρετικό) — Εκτελείται μετά τον χειριστή συνομιλίας
  • onError (function, προαιρετικό) — Εκτελείται σε περίπτωση σφάλματος του χειριστή

blockRequest(response?): BlockingHookResult

Αποκλείει το αίτημα και, προαιρετικά, επιστρέφει μια προσαρμοσμένη απόκριση.

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

modifyBody(body): PluginResult

Τροποποιεί το σώμα του αιτήματος πριν αυτό φτάσει στον πάροχο.

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

addMetadata(metadata): PluginResult

Επισυνάπτει μεταδεδομένα στο περιβάλλον του αιτήματος.

onRequest: (ctx) => {
  return addMetadata({ source: "my-plugin", version: "1.0.0" });
};

Περιβάλλον Plugin (PluginContext)

Πεδίο Τύπος Περιγραφή
requestId string Μοναδικό αναγνωριστικό αιτήματος
model string Όνομα ζητούμενου μοντέλου
provider string ID παρόχου προορισμού
body Record<string, unknown> Σώμα αιτήματος
headers Record<string, string> Κεφαλίδες αιτήματος
metadata Record<string, unknown> Μεταβλητά μεταδεδομένα
timestamp number Χρονοσήμανση αιτήματος

Δηλωτικό αρχείο (plugin.json)

{
  "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" }
  }
}

Προτεραιότητα Hook

Τα hooks μπορούν να διαμορφωθούν με προτεραιότητα (χαμηλότερη τιμή = εκτελείται πρώτο):

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

Ή ως απλές δυαδικές τιμές (προεπιλεγμένη προτεραιότητα 100):

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

Σύστημα Δικαιωμάτων

Τα πρόσθετα εκτελούνται σε περιβάλλον sandboxed VM. Η πρόσβαση σε εξωτερικούς πόρους απαιτεί ρητά δικαιώματα:

Δικαίωμα Παρέχει πρόσβαση σε
network fetch, AbortController, Headers, Request, Response
file-read fs.readFile, fs.readdir, fs.stat
file-write fs.writeFile, fs.mkdir, fs.rm
env Διακομιστής μεσολάβησης μόνο για ανάγνωση του process.env
exec child_process.exec, child_process.execSync

Χωρίς κάποιο δικαίωμα, τα αντίστοιχα globals απλώς δεν είναι διαθέσιμα στο sandbox.

Σχήμα Ρυθμίσεων

Ορίστε τις παραμετροποιήσιμες ρυθμίσεις στο configSchema:

{
  "configSchema": {
    "apiKey": { "type": "string", "description": "Κλειδί εξωτερικού API" },
    "maxRetries": { "type": "number", "min": 1, "max": 10, "default": 3 },
    "debug": { "type": "boolean", "default": false },
    "mode": { "type": "string", "enum": ["fast", "slow"], "default": "fast" }
  }
}

Τύποι πεδίων: string, number, boolean, select

Επιλογές πεδίων: default, min, max, enum, description

Οι τιμές των ρυθμίσεων αποθηκεύονται στη βάση δεδομένων και είναι προσβάσιμες μέσω της σελίδας ρυθμίσεων του πίνακα ελέγχου.

Ενσωματωμένα Συμβάντα

Συμβάν Πότε Ωφέλιμο φορτίο
onRequest Πριν από τον χειριστή συνομιλίας Περιβάλλον αιτήματος
onResponse Μετά τον χειριστή συνομιλίας Δεδομένα απόκρισης
onError Σε περίπτωση σφάλματος του χειριστή Αντικείμενο σφάλματος
onModelSelect Επιλέγεται μοντέλο για δρομολόγηση Πληροφορίες μοντέλου
onComboResolve Επιλύεται η συνδυαστική δρομολόγηση Προορισμοί συνδυασμού
onRateLimit Συμπληρώνεται το όριο ρυθμού Πληροφορίες ορίου
onQuotaExhaust Εξαντλείται το όριο χρήσης Πληροφορίες ορίου χρήσης
onProviderError Ο πάροχος επιστρέφει σφάλμα Λεπτομέρειες σφάλματος
onStreamStart Ξεκινά η ροή SSE Πληροφορίες ροής
onStreamEnd Τερματίζεται η ροή SSE Στατιστικά ροής
onInstall Εγκαθίσταται το πρόσθετο { name, version, manifest }
onActivate Ενεργοποιείται το πρόσθετο { name, version, manifest }
onDeactivate Απενεργοποιείται το πρόσθετο { name, version, manifest }
onUninstall Απεγκαθίσταται το πρόσθετο (πριν διαγραφούν τα αρχεία) { 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 λεπτό
    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;
  },
});