# API Reference (עברית) 🌐 **Languages:** 🇺🇸 [English](../../../../reference/API_REFERENCE.md) · 🇪🇹 [am](../../../am/docs/reference/API_REFERENCE.md) · 🇸🇦 [ar](../../../ar/docs/reference/API_REFERENCE.md) · 🇦🇿 [az](../../../az/docs/reference/API_REFERENCE.md) · 🇧🇬 [bg](../../../bg/docs/reference/API_REFERENCE.md) · 🇧🇩 [bn](../../../bn/docs/reference/API_REFERENCE.md) · 🇧🇦 [bs](../../../bs/docs/reference/API_REFERENCE.md) · 🇨🇿 [cs](../../../cs/docs/reference/API_REFERENCE.md) · 🇩🇰 [da](../../../da/docs/reference/API_REFERENCE.md) · 🇩🇪 [de](../../../de/docs/reference/API_REFERENCE.md) · 🇬🇷 [el](../../../el/docs/reference/API_REFERENCE.md) · 🇪🇸 [es](../../../es/docs/reference/API_REFERENCE.md) · 🇪🇪 [et](../../../et/docs/reference/API_REFERENCE.md) · 🇮🇷 [fa](../../../fa/docs/reference/API_REFERENCE.md) · 🇫🇮 [fi](../../../fi/docs/reference/API_REFERENCE.md) · 🇫🇷 [fr](../../../fr/docs/reference/API_REFERENCE.md) · 🇮🇪 [ga](../../../ga/docs/reference/API_REFERENCE.md) · 🇮🇳 [gu](../../../gu/docs/reference/API_REFERENCE.md) · 🇳🇬 [ha](../../../ha/docs/reference/API_REFERENCE.md) · 🇮🇳 [hi](../../../hi/docs/reference/API_REFERENCE.md) · 🇭🇷 [hr](../../../hr/docs/reference/API_REFERENCE.md) · 🇭🇺 [hu](../../../hu/docs/reference/API_REFERENCE.md) · 🇦🇲 [hy](../../../hy/docs/reference/API_REFERENCE.md) · 🇮🇩 [id](../../../id/docs/reference/API_REFERENCE.md) · 🇳🇬 [ig](../../../ig/docs/reference/API_REFERENCE.md) · 🇮🇹 [it](../../../it/docs/reference/API_REFERENCE.md) · 🇯🇵 [ja](../../../ja/docs/reference/API_REFERENCE.md) · 🇬🇪 [ka](../../../ka/docs/reference/API_REFERENCE.md) · 🇰🇭 [km](../../../km/docs/reference/API_REFERENCE.md) · 🇮🇳 [kn](../../../kn/docs/reference/API_REFERENCE.md) · 🇰🇷 [ko](../../../ko/docs/reference/API_REFERENCE.md) · 🇱🇹 [lt](../../../lt/docs/reference/API_REFERENCE.md) · 🇱🇻 [lv](../../../lv/docs/reference/API_REFERENCE.md) · 🇮🇳 [ml](../../../ml/docs/reference/API_REFERENCE.md) · 🇮🇳 [mr](../../../mr/docs/reference/API_REFERENCE.md) · 🇲🇾 [ms](../../../ms/docs/reference/API_REFERENCE.md) · 🇲🇹 [mt](../../../mt/docs/reference/API_REFERENCE.md) · 🇲🇲 [my](../../../my/docs/reference/API_REFERENCE.md) · 🇳🇵 [ne](../../../ne/docs/reference/API_REFERENCE.md) · 🇳🇱 [nl](../../../nl/docs/reference/API_REFERENCE.md) · 🇳🇴 [no](../../../no/docs/reference/API_REFERENCE.md) · 🇮🇳 [or](../../../or/docs/reference/API_REFERENCE.md) · 🇮🇳 [pa](../../../pa/docs/reference/API_REFERENCE.md) · 🇵🇭 [phi](../../../phi/docs/reference/API_REFERENCE.md) · 🇵🇱 [pl](../../../pl/docs/reference/API_REFERENCE.md) · 🇵🇹 [pt](../../../pt/docs/reference/API_REFERENCE.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/reference/API_REFERENCE.md) · 🇷🇴 [ro](../../../ro/docs/reference/API_REFERENCE.md) · 🇷🇺 [ru](../../../ru/docs/reference/API_REFERENCE.md) · 🇱🇰 [si](../../../si/docs/reference/API_REFERENCE.md) · 🇸🇰 [sk](../../../sk/docs/reference/API_REFERENCE.md) · 🇸🇮 [sl](../../../sl/docs/reference/API_REFERENCE.md) · 🇷🇸 [sr](../../../sr/docs/reference/API_REFERENCE.md) · 🇸🇪 [sv](../../../sv/docs/reference/API_REFERENCE.md) · 🇰🇪 [sw](../../../sw/docs/reference/API_REFERENCE.md) · 🇮🇳 [ta](../../../ta/docs/reference/API_REFERENCE.md) · 🇮🇳 [te](../../../te/docs/reference/API_REFERENCE.md) · 🇹🇭 [th](../../../th/docs/reference/API_REFERENCE.md) · 🇹🇷 [tr](../../../tr/docs/reference/API_REFERENCE.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/reference/API_REFERENCE.md) · 🇵🇰 [ur](../../../ur/docs/reference/API_REFERENCE.md) · 🇺🇿 [uz](../../../uz/docs/reference/API_REFERENCE.md) · 🇻🇳 [vi](../../../vi/docs/reference/API_REFERENCE.md) · 🇳🇬 [yo](../../../yo/docs/reference/API_REFERENCE.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/reference/API_REFERENCE.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/reference/API_REFERENCE.md) --- 🌐 **שפות:** 🇺🇸 [אנגלית](./API_REFERENCE.md) | 🇪🇹 [አማርኛ](../i18n/am/docs/reference/API_REFERENCE.md) | 🇸🇦 [العربية](../i18n/ar/docs/reference/API_REFERENCE.md) | 🇦🇿 [Azərbaycan dili](../i18n/az/docs/reference/API_REFERENCE.md) | 🇧🇬 [Български](../i18n/bg/docs/reference/API_REFERENCE.md) | 🇧🇩 [বাংলা](../i18n/bn/docs/reference/API_REFERENCE.md) | 🇧🇦 [Bosanski](../i18n/bs/docs/reference/API_REFERENCE.md) | 🇨🇿 [Čeština](../i18n/cs/docs/reference/API_REFERENCE.md) | 🇩🇰 [Dansk](../i18n/da/docs/reference/API_REFERENCE.md) | 🇩🇪 [Deutsch](../i18n/de/docs/reference/API_REFERENCE.md) | 🇬🇷 [Ελληνικά](../i18n/el/docs/reference/API_REFERENCE.md) | 🇪🇸 [Español](../i18n/es/docs/reference/API_REFERENCE.md) | 🇪🇪 [Eesti](../i18n/et/docs/reference/API_REFERENCE.md) | 🇮🇷 [فارسی](../i18n/fa/docs/reference/API_REFERENCE.md) | 🇫🇮 [Suomi](../i18n/fi/docs/reference/API_REFERENCE.md) | 🇫🇷 [Français](../i18n/fr/docs/reference/API_REFERENCE.md) | 🇮🇪 [Gaeilge](../i18n/ga/docs/reference/API_REFERENCE.md) | 🇮🇳 [ગુજરાતી](../i18n/gu/docs/reference/API_REFERENCE.md) | 🇳🇬 [Hausa](../i18n/ha/docs/reference/API_REFERENCE.md) | 🇮🇱 [עברית](../i18n/he/docs/reference/API_REFERENCE.md) | 🇮🇳 [हिन्दी](../i18n/hi/docs/reference/API_REFERENCE.md) | 🇭🇷 [Hrvatski](../i18n/hr/docs/reference/API_REFERENCE.md) | 🇭🇺 [Magyar](../i18n/hu/docs/reference/API_REFERENCE.md) | 🇦🇲 [Հայերեն](../i18n/hy/docs/reference/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](../i18n/id/docs/reference/API_REFERENCE.md) | 🇳🇬 [Igbo](../i18n/ig/docs/reference/API_REFERENCE.md) | 🇮🇹 [Italiano](../i18n/it/docs/reference/API_REFERENCE.md) | 🇯🇵 [日本語](../i18n/ja/docs/reference/API_REFERENCE.md) | 🇬🇪 [ქართული](../i18n/ka/docs/reference/API_REFERENCE.md) | 🇰🇭 [ខ្មែរ](../i18n/km/docs/reference/API_REFERENCE.md) | 🇮🇳 [ಕನ್ನಡ](../i18n/kn/docs/reference/API_REFERENCE.md) | 🇰🇷 [한국어](../i18n/ko/docs/reference/API_REFERENCE.md) | 🇱🇹 [Lietuvių](../i18n/lt/docs/reference/API_REFERENCE.md) | 🇱🇻 [Latviešu](../i18n/lv/docs/reference/API_REFERENCE.md) | 🇮🇳 [മലയാളം](../i18n/ml/docs/reference/API_REFERENCE.md) | 🇮🇳 [मराठी](../i18n/mr/docs/reference/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](../i18n/ms/docs/reference/API_REFERENCE.md) | 🇲🇹 [Malti](../i18n/mt/docs/reference/API_REFERENCE.md) | 🇲🇲 [မြန်မာ](../i18n/my/docs/reference/API_REFERENCE.md) | 🇳🇵 [नेपाली](../i18n/ne/docs/reference/API_REFERENCE.md) | 🇳🇱 [Nederlands](../i18n/nl/docs/reference/API_REFERENCE.md) | 🇳🇴 [Norsk](../i18n/no/docs/reference/API_REFERENCE.md) | 🇮🇳 [ଓଡ଼ିଆ](../i18n/or/docs/reference/API_REFERENCE.md) | 🇮🇳 [ਪੰਜਾਬੀ](../i18n/pa/docs/reference/API_REFERENCE.md) | 🇵🇭 [Filipino](../i18n/phi/docs/reference/API_REFERENCE.md) | 🇵🇱 [Polski](../i18n/pl/docs/reference/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](../i18n/pt/docs/reference/API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](../i18n/pt-BR/docs/reference/API_REFERENCE.md) | 🇷🇴 [Română](../i18n/ro/docs/reference/API_REFERENCE.md) | 🇷🇺 [Русский](../i18n/ru/docs/reference/API_REFERENCE.md) | 🇱🇰 [සිංහල](../i18n/si/docs/reference/API_REFERENCE.md) | 🇸🇰 [Slovenčina](../i18n/sk/docs/reference/API_REFERENCE.md) | 🇸🇮 [Slovenščina](../i18n/sl/docs/reference/API_REFERENCE.md) | 🇷🇸 [Српски](../i18n/sr/docs/reference/API_REFERENCE.md) | 🇸🇪 [Svenska](../i18n/sv/docs/reference/API_REFERENCE.md) | 🇰🇪 [Kiswahili](../i18n/sw/docs/reference/API_REFERENCE.md) | 🇮🇳 [தமிழ்](../i18n/ta/docs/reference/API_REFERENCE.md) | 🇮🇳 [తెలుగు](../i18n/te/docs/reference/API_REFERENCE.md) | 🇹🇭 [ไทย](../i18n/th/docs/reference/API_REFERENCE.md) | 🇹🇷 [Türkçe](../i18n/tr/docs/reference/API_REFERENCE.md) | 🇺🇦 [Українська](../i18n/uk-UA/docs/reference/API_REFERENCE.md) | 🇵🇰 [اردو](../i18n/ur/docs/reference/API_REFERENCE.md) | 🇺🇿 [Oʻzbekcha](../i18n/uz/docs/reference/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](../i18n/vi/docs/reference/API_REFERENCE.md) | 🇳🇬 [Yorùbá](../i18n/yo/docs/reference/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](../i18n/zh-CN/docs/reference/API_REFERENCE.md) | 🇹🇼 [中文 (繁體)](../i18n/zh-TW/docs/reference/API_REFERENCE.md) מסמך עזר מרכזי עבור ה-API של OmniRoute. הוא מכסה את הממשק הציבורי `/v1` ואת נקודות הקצה הנפוצות ביותר לניהול; המקורות המקיפים הם [`docs/openapi.yaml`](../openapi.yaml) ועץ הנתיבים תחת `src/app/api/`. למידע הממוקד בפרוטוקול התואם ל-OpenAI ובמטריצת היכולות של הספקים, ראו [`OPENAI_COMPATIBILITY.md`](./OPENAI_COMPATIBILITY.md). --- ## תוכן העניינים - [השלמות צ'אט](#chat-completions) - [חכירות בלעדיות של סשנים מנוהלים](#exclusive-managed-session-leases) - [הטמעות](#embeddings) - [יצירת תמונות](#image-generation) - [OCR למסמכים](#document-ocr) - [רשימת מודלים](#list-models) - [מניפסט תוסף ספק](#provider-plugin-manifest) - [נקודות קצה לתאימות](#compatibility-endpoints) - [API לקבצים](#files-api) - [API לאצוות](#batches-api) - [API לחיפוש](#search-api) - [הזרמה באמצעות WebSocket](#websocket-streaming) - [דיווח על מכסות ובעיות](#quotas--issues-reporting) - [מטמון סמנטי](#semantic-cache) - [לוח בקרה וניהול](#dashboard--management) - [ניהול שילובים](#combo-management) - [Webhooks](#webhooks) - [מפתחות רשומים (ניהול אוטומטי)](#registered-keys-auto-management) - [פרוטוקול סוכנים](#agents-protocol) - [שרתי Proxy לניהול](#management-proxies) - [עמידות (מורחבת)](#resilience-extended) - [מיומנויות](#skills) - [זיכרון](#memory) - [שרת MCP](#mcp-server) - [שרת A2A](#a2a-server) - [ענן, הערכות ואומדן](#cloud-evals--assess) - [עיבוד בקשות](#request-processing) - [אימות](#authentication) --- ## השלמות צ'אט ```bash POST /v1/chat/completions Authorization: Bearer your-api-key Content-Type: application/json { "model": "cc/claude-opus-4-6", "messages": [ {"role": "user", "content": "Write a function to..."} ], "stream": true } ``` ### כותרות מותאמות אישית | כותרת | כיוון | תיאור | | ------------------------ | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `X-OmniRoute-No-Cache` | בקשה | יש להגדיר ל-`true` כדי לעקוף את המטמון | | `x-omniroute-no-memory` | בקשה | יש להגדיר ל-`true` כדי לדלג על הזרקת זיכרון ומיומנויות עבור בקשה זו (מקביל לאי-שימוש במטמון; מונע את תקורת האסימונים/העלות לכל קריאה) | | `X-OmniRoute-Progress` | בקשה | יש להגדיר ל-`true` עבור אירועי התקדמות | | `X-Session-Id` | בקשה | מפתח סשן דביק עבור שיוך סשן חיצוני | | `x_session_id` | בקשה | מתקבלת גם הגרסה עם קו תחתון (HTTP ישיר) | | `X-OmniRoute-Session-Id` | בקשה | תג סשן/שיחה שסופק על ידי הקורא (ומוזן גם לזיכרון). כאשר הוא קיים, הוא נשמר כלשונו ב-`call_logs.session_tag` לצורך שיוך עלויות לפי סשן (#8249) — ולעולם אינו נוצר כאשר הוא חסר | | `Idempotency-Key` | בקשה | מפתח למניעת כפילויות (חלון של 5 שניות) | | `X-Request-Id` | בקשה | מפתח חלופי למניעת כפילויות | | `x-omniroute-connection` | בקשה | הצמדת בקשה למודל יחיד לחיבור ספק (חשבון) אחד לפי המזהה שלו — ראו [הצמדת חשבון לפי בקשה](#account-pinning-per-request) | | `X-OmniRoute-Cache` | תגובה | `HIT` או `MISS` (ללא הזרמה) | | `X-OmniRoute-Idempotent` | תגובה | `true` אם נמנעה כפילות | | `X-OmniRoute-Progress` | תגובה | `enabled` אם מעקב ההתקדמות מופעל | | `X-OmniRoute-Session-Id` | תגובה | מזהה הסשן בפועל שבו OmniRoute משתמש | | `X-OmniRoute-Request-Id` | תגובה | מזהה מתאם של הבקשה (כאשר הוא ידוע) | | `X-OmniRoute-Version` | תגובה | גרסת ה-Build של OmniRoute (קיימת תמיד) | | `X-OmniRoute-Cost-Saved` | תגובה | הסכום בדולר ארה"ב שהמטמון חסך במקרה של `HIT` (פגיעות מטמון בלבד) | | `X-OmniRoute-Decision` | תגובה | עקבת ניתוב: `strategy=; provider=; latency_ms=` (`` היא אסטרטגיית השילוב, או `single` עבור בקשה שאינה שילוב) — קיימת תמיד בתגובות השלמה | > הערת Nginx: אם אתם מסתמכים על כותרות עם קווים תחתונים (לדוגמה `x_session_id`), הפעילו את `underscores_in_headers on;`. #### הצמדת חשבון לכל בקשה כאשר לספק יש כמה חיבורים (חשבונות או מפתחות), OmniRoute בדרך כלל בוחר אחד באמצעות אסטרטגיית בחירת החשבון שלו. במקום זאת, בקשה יכולה להיצמד לחיבור מסוים אחד באמצעות הכותרת `x-omniroute-connection`: ```bash curl http://localhost:20128/v1/chat/completions \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -H "x-omniroute-connection: " \ -d '{"model": "codex/gpt-5.5", "messages": [{"role": "user", "content": "hi"}]}' ``` - **היכן למצוא את המזהה.** פתחו את דף הספק בלוח הבקרה (**לוח בקרה → ספקים → **) ולחצו על תג המזהה `xxxxxxxx…` בשורת חיבור — פעולה זו מעתיקה את מזהה החיבור המלא. - **אילו בקשות מכבדות אותו.** בקשות למודל יחיד (`provider/model`) בנקודות הקצה `/v1/chat/completions`, `/v1/messages` ו-`/v1/responses`. שילובים מתעלמים מהכותרת: הצמידו חשבון לכל שלב בשילוב באמצעות החיבור של השלב עצמו. - **ההצמדה קשיחה, ולא רק העדפה.** נעשה שימוש בלעדי בחיבור המוצמד. כשל בתוך הבקשה מתעד את תקופת ההמתנה של החשבון, אך **אינו** עובר לחשבון מקביל של אותו ספק. - **תקופת המתנה ומכסה משחררות את ההצמדה.** בזמן שהחיבור המוצמד נמצא בתקופת המתנה, מיצה את המכסה או נחסם על ידי מדיניות מכסה, בקשות מאוחרות יותר עוברות לחיבורים האחרים של הספק, בדיוק כמו תעבורה ללא הצמדה. - **מזהים לא מוכרים או מושבתים גורמים לכשל.** מזהה שאינו נמצא במאגר הפעיל של הספק (נמחק, הושבת או שייך לספק אחר) אינו משאיר חשבון כשיר, ולכן הבקשה נכשלת במקום להיות מנותבת בשקט למקום אחר. Claude Code שולח כותרות מותאמות אישית באמצעות `ANTHROPIC_CUSTOM_HEADERS`. הוסיפו אותו לבלוק `env` של `~/.claude/settings.json`, או לקובץ `.claude/settings.json` ברמת הפרויקט כדי להצמיד חשבון שונה לכל פרויקט: ```jsonc { "env": { "ANTHROPIC_BASE_URL": "http://:20128", "ANTHROPIC_AUTH_TOKEN": "", "ANTHROPIC_CUSTOM_HEADERS": "x-omniroute-connection: ", }, } ``` מקור: `src/sse/handlers/chat.ts` (קריאת הכותרת), `src/sse/services/auth.ts` ו- `src/sse/services/sessionAffinityPin.ts` (שחרור ההצמדה והבדיקה אם החיבור חסר מהמאגר). > **כותרות טלמטריית עלויות:** תגובות הצלחה שאינן מוזרמות כוללות גם את ערכת טלמטריית העלויות `X-OmniRoute-*` —‏ `X-OmniRoute-Response-Cost` (בדולר ארה״ב, 10 ספרות קבועות אחרי הנקודה העשרונית; `0.0000000000` עבור שימוש חינמי או ללא תמחור), `X-OmniRoute-Tokens-In` / `X-OmniRoute-Tokens-Out`,‏ `X-OmniRoute-Model`,‏ `X-OmniRoute-Provider`,‏ `X-OmniRoute-Latency-Ms`,‏ `X-OmniRoute-Cache-Hit` ו-`X-OmniRoute-Fallback-Attempts` (רק כאשר > 0), וכן `X-OmniRoute-Request-Id` ו-`X-OmniRoute-Version`. כותרות אלה מופקות על ידי השלמות צ׳אט, `/v1/responses`,‏ `/v1/messages`, **וגם נקודות הקצה למדיה** —‏ `/v1/embeddings`,‏ `/v1/images/generations`,‏ `/v1/audio/speech`,‏ `/v1/audio/transcriptions`,‏ `/v1/rerank`,‏ `/v1/videos/generations`,‏ `/v1/music/generations` ו-`/v1/moderations` (העלות תמיד `0`). עלות המדיה מחושבת לפי סוג המדיה (לכל תמונה, לכל שנייה, לכל תו, לכל יחידת חיפוש) כאשר תמחור זמין; אחרת, העלות היא `0` (מעבר פתוח במקרה של כשל). > **סמנטיקת עלות של פגיעה במטמון:** בפגיעה במטמון הסמנטי (`X-OmniRoute-Cache-Hit: true`) לא מתבצעת קריאה לספק במעלה הזרם, ולכן `X-OmniRoute-Response-Cost` הוא `0.0000000000` (העלות **המצטברת** של אספקת הפגיעה). העלות המקורית או העלות שהייתה צפויה מדווחת בנפרד ב-`X-OmniRoute-Cost-Saved`. צרכני נתוני חיוב צריכים לסכם את `X-OmniRoute-Response-Cost` (פגיעות אינן עולות דבר); ניתוחי מטמון יכולים לצבור את `X-OmniRoute-Cost-Saved`. ## חכירות בלעדיות של הפעלות מנוהלות חכירה בלעדית של הפעלה מנוהלת היא חוזה ניתוב אופציונלי ובלתי תלוי בלקוח: בעלים פעיל אחד מחזיק בחיבור OmniRoute כשיר אחד. היא אינה מחכירה מודל, אינה דורשת OAuth, אינה מזהה לקוח מסוים ואינה דורשת ספק מסוים. מפתח ה-API המשמש לאימות חייב לכלול את ההרשאה `lease:exclusive` ורשימת `allowedConnections` מפורשת שאינה ריקה. גבול השינוי במסד הנתונים אוכף את שני השדות יחד בעת יצירת מפתח ובעדכונים חלקיים. ```http POST /api/v1/session-leases Authorization: Bearer Content-Type: application/json X-OmniRoute-Lease-Owner: vlo_<43-base64url-characters> {"action":"acquire","model":"glm/glm-4.6"} ``` תגובות מוצלחות לרכישה, לחידוש ולשחרור חושפות חותמות זמן, `state` ואת ערך `generation` החיובי המדויק, אך לעולם לא את החיבור שנבחר או את פרטי הגישה. בחידוש ובשחרור, הדור מסופק בגוף ה-JSON: ```json { "action": "renew", "generation": 1 } ``` ```json { "action": "release", "generation": 1, "reason": "OWNER_EXIT" } ``` בעלים של חכירה פעילה יכול לבקש במפורש מטא-נתונים לתצוגה השומרים על הפרטיות עבור השיוך הנוכחי שלו: ```json { "action": "status", "generation": 1 } ``` ```json { "state": "ACTIVE", "generation": 1, "acquiredAt": "2026-08-28T12:00:00.000Z", "renewedAt": "2026-08-28T12:00:30.000Z", "expiresAt": "2026-08-28T12:02:30.000Z", "connection": { "displayName": "Primary Codex", "provider": "codex" } } ``` פעולת סטטוס אופציונלית זו מוגנת באמצעות גידור לפי הבעלים האטום, מפתח ה-API המנוהל והמאומת, והדור הפעיל המדויק, במסגרת טרנזקציה אחת במסד הנתונים. `displayName` הוא רק שם החיבור המוגדר לאחר הסרת רווחים מיותרים; ערכו הוא `null` כאשר לא קיים שם מוגדר ובטוח. OmniRoute לעולם אינו מחליף אותו בכתובת דוא"ל או בזהות חשבון שנוצרה. ערך הספק הוא תווית תצוגה שאינה רגישה ולעולם אינו מזהה שנוצר עבור ספק תואם. פרטי גישה, אסימונים, קובצי Cookie, מזהים גולמיים של חיבורים או מפתחות API, גיבובי בעלים, סודות גידור ונתוני ניתוב פנימיים אינם נכללים. חיפושים עם מפתח שגוי, בעלים שגוי, דור מיושן, נתונים חסרים, חכירה שפג תוקפה, חכירה ששוחררה או חכירה שבוטלה מחזירים כולם את אותה שגיאת `409 LEASE_FENCE_STALE` ללא מטא-נתונים של החיבור. ללקוח שקיבל תגובת המתנה לקיבולת אין שיוך פעיל שניתן לבדוק. כאשר הניתוב מעביר חכירה פעילה, אותו דור נשאר תקף והסטטוס מחזיר באופן אטומי את השיוך החדש, ולעולם לא את הישן. לקוחות קיימים נותרים ללא שינוי, משום שתגובות הרכישה, החידוש, השחרור וההמתנה שומרות על המבנה הקודם שלהן. חוזה שרת זה אינו משנה את `/status` של OpenAI Codex הסטנדרטי. Codex הסטנדרטי מדווח כעת על ספק המודל שלו ועל מצב האימות/החשבון המובנה, אך אינו מציג מטא-נתוני חשבון שרירותיים של ספק מותאם אישית; שילוב עתידי בצד הלקוח חייב לקרוא לפעולה זו ולהחליט כיצד להציג את `connection.displayName`. לאחר מכן, כל בקשת הסקה מנוהלת מספקת את שתי כותרות הבקרה: ```http X-OmniRoute-Lease-Owner: vlo_<43-base64url-characters> X-OmniRoute-Lease-Generation: 1 ``` הבעלים המדויק, הדור, החיבור הפעיל ומפתח ה-API המאומת מוגנים באמצעות גידור מיד לפני כל ניסיון נתמך מול שירות במעלה הזרם. הפעלה חוזרת של הבעלים והדור עם מפתח אחר נכשלת גם כאשר מפתח זה מתיר את אותו חיבור. הבעלים הגולמיים אינם נשמרים, נרשמים ביומן, נשמרים בתמונת המצב של הבקשה או מועברים לשירות במעלה הזרם. התנגשות זמנית מחזירה HTTP `429` עם `Retry-After` ועם: ```json { "state": "WAITING_FOR_CAPACITY", "error": { "type": "lease_error", "code": "LEASE_CAPACITY_UNAVAILABLE" }, "reason": "NO_FREE_ELIGIBLE_CONNECTION", "retryAfter": 30 } ``` תגובה זו מציינת רק שקבוצת החיבורים הכשירים הרגילה לא הייתה ריקה ושכל מועמד פנוי הוחזק בידי חכירה פעילה זרה. מודלים/ספקים שאינם נתמכים, אי-התאמה למדיניות, תקופת צינון, מכסה, תקינות וכשלי כשירות רגילים אחרים ממשיכים להחזיר את תגובות OmniRoute הקיימות שלהם. ### `x-omniroute-compression` דריסה של תוכנית הדחיסה לפי בקשה. הקדימות הגבוהה ביותר — גוברת על דריסת שילוב הניתוב, הפרופיל הפעיל, ההפעלה האוטומטית וברירת המחדל של הלוח. ערכים: | ערך | השפעה | | ------------- | --------------------------------------------------------------------------------------- | | `off` | ללא דחיסה עבור בקשה זו. | | `default` | פרופיל ברירת המחדל הנגזר מהלוח (מתעלם מהפרופיל הפעיל). מנועים מאבדי מידע נשארים כבויים. | | `safe` | מניעת כפילויות וצמצום רווחים בלבד. | | `allow-lossy` | שמירת תוכנית המפעיל עבור בקשה זו, כולל סיכומים ושכתובי סגנון. | | `engine:` | מנוע יחיד, כאשר הוא מופעל, לדוגמה `engine:rtk`. הצטרפות לפי בקשה עבור מנוע זה. | | `` | שילוב בעל שם, המותאם תחילה לפי שם (ללא תלות ברישיות) ולאחר מכן לפי מזהה. | הערות: - המערכת מתעלמת מערכים לא מוכרים (הבקשה לעולם אינה נדחית); הפתרון ממשיך לפי סדר הקדימויות הרגיל של המפעיל. - אם כמה שילובים חולקים שם, העבירו את **המזהה** של השילוב לצורך התאמה דטרמיניסטית. - לא ניתן לבחור לפי שם שילוב ששמו `off` או `default` (מילות מפתח אלה מפורשות תחילה); יש להפנות לשילוב כזה לפי המזהה שלו. - מתג הדחיסה הראשי הוא שער קשיח: כאשר הדחיסה מושבתת באופן גלובלי, כותרת זו אינה יכולה להפעיל אותה. התוכנית שהוחלה מוחזרת בכותרת התגובה: ``` X-OmniRoute-Compression: ; source= ``` כאשר `` הוא אחד מבין `request-header`, `routing-override`, `active-profile`, `auto-trigger`, `default` או `off`. --- ## הטמעות ```bash POST /v1/embeddings Authorization: Bearer your-api-key Content-Type: application/json { "model": "nebius/Qwen/Qwen3-Embedding-8B", "input": "The food was delicious" } ``` ספקים זמינים: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA, **OpenRouter**, Jina AI. מזהי הקטלוג הם בתבנית `provider/model` (לדוגמה: `jina-ai/jina-embeddings-v5-omni-small`). גם מזהי מודלים של Jina ללא שם הספק, המופיעים במרשם (לדוגמה `jina-embeddings-v5-text-small`, `jina-reranker-v3.5`), ניתנים לפענוח. פעולות ההטמעה/דירוג מחדש/סיווג/פילוח של Jina משתמשות תחילה בפרטי הכניסה `jina-ai` מלוח הבקרה; `JINA_AI_API_KEY` משמש כחלופה רק כאשר לא קיים מפתח בלוח הבקרה. הכרטיס `jina-reader` מיועד רק ל-Reader / `r.jina.ai` ‏(`POST /v1/web/fetch`), ולעולם אינו מספק הטמעות או דירוג מחדש. מודלים במרשם שמצהירים על תמיכה מולטימודלית מקבלים גם עד 32 פריטים מובנים שאינם תלויים בספק. סוגי פריטי המדיה הם `text`, `image`, `audio`, `video` ו-`document`. שדה המדיה `source` שלהם הוא `{"type":"url","url":"https://..."}` או `{"type":"base64","data":"...","media_type":"..."}`. Jina v5 Omni ‏(`jina-ai/jina-embeddings-v5-omni-small`, `jina-ai/jina-embeddings-v5-omni-nano`, וכן הכינוי המשפחתי `jina-ai/jina-embeddings-v5-omni` → omni-small) מקבל גם מסמכי EmbeddingsV5Request מקוריים של Jina ו**מעביר אותם בשלמותם** אל `https://api.jina.ai/v1/embeddings`: ```json { "model": "jina-ai/jina-embeddings-v5-omni-small", "task": "retrieval.query", "normalized": true, "input": [ { "text": "a red bicycle" }, { "image": "https://example.com/bike.png" }, { "content": [{ "text": "caption" }, { "image": "data:image/png;base64,..." }] } ] } ``` ערכי `{ image | audio | video | pdf }` מקוריים יכולים להיות כתובת URL ציבורית מסוג HTTPS, כתובת URI מסוג `data:`, או base64 גולמי. OmniRoute אינו ממיר אובייקטים אלה למחרוזות ואינו מאחזר כתובות URL מקוריות של תמונות — Jina מאחזר את המדיה הציבורית בעצמו. שדות נוספים של Jina‏ (`task`, `normalized`, `truncate`, `embedding_type`) מועברים הלאה. מק"טים של Jina המיועדים לטקסט בלבד עדיין דוחים מסמכים שאינם טקסט. מגבלות אבטחה ותעבורה: - כתובות URL מרוחקות של מדיה חייבות להיות כתובות HTTPS ציבוריות. פריטים קנוניים מסוג `{type,source:url}` מאוחזרים בצד השרת (אימות מחדש של הפניות, מגבלת זמן, מגבלות גודל, DNS ציבורי והצמדת חיבור) ומוטמעים לפני הקריאה לספק. פריטים מקוריים של Jina מסוג `{image:"https://..."}` מועברים כפי שהם לאחר אותה בדיקת HTTPS ציבורי; Jina מאחזר את כתובת ה-URL. - מדיה מוטמעת בקידוד base64 מוגבלת ל-8 MiB מפוענחים לכל פריט ול-16 MiB מפוענחים בכל הבקשה. תרגום עבור ספקים (פריטים קנוניים לעולם אינם מועברים ללא שינוי): - מודלים מולטימודליים של Jina: כל פריט ברמה העליונה הופך לאובייקט אחד עם מפתח לפי סוג הקלט (`text` / `image` / `audio` / `video` / `pdf`), תוך שימוש בכתובות URI מסוג data עבור מדיה מוטמעת; וקטור אחד לכל פריט ברמה העליונה. - משפחת Gemini Embedding 2: מערך אחד ברמה העליונה הופך לבקשת `models/{model}:embedContent` מקורית יחידה עם `content.parts` ‏(`text` או `inline_data`). - llama.cpp ‏(`llama-cpp/`, כל מודל שהשרת המקומי טען): פריטי `text` קנוניים הופכים למחרוזות רגילות, ו-`image` / `audio` / `video` הופכים כל אחד לאובייקט `{"content": [part]}` יחיד, תוך שימוש בחלקי תוכן הצ'אט של llama-server ‏(`image_url`, ‏`input_audio` עם הפורמט `wav` / `mp3` / `flac`, וכן `input_video`) עם נתונים מוטמעים; וקטור אחד לכל פריט ברמה העליונה. השרת חייב לפעול עם `--embedding --mmproj …`; ללא מקרן הוא דוחה את המדיה בעצמו. `document` אינו נתמך. - מודלים לא מוכרים/דינמיים ללא מטא-נתונים מפורשים של סוגי קלט דוחים קלט מובנה עם HTTP 400. ```json { "model": "jina-ai/jina-embeddings-v5-omni-small", "input": [ { "type": "text", "text": "A red bicycle" }, { "type": "image", "source": { "type": "url", "url": "https://example.com/bicycle.png" } } ], "dimensions": 512, "encoding_format": "float" } ``` שילובים לא נתמכים של מודל וסוג קלט מחזירים HTTP 400 במקום לכפות המרה של הפריט. שדות הרחבה שאינם שדות קלט בבקשות מחרוזת/אסימון מדור קודם ממשיכים לעבור ללא שינוי. ```bash # הצגת כל מודלי ההטמעה GET /v1/embeddings ``` --- ## יצירת תמונות ```bash POST /v1/images/generations Authorization: Bearer your-api-key Content-Type: application/json { "model": "openai/gpt-image-2", "prompt": "A beautiful sunset over mountains", "size": "1024x1024" } ``` הספקים הזמינים כוללים את OpenAI (GPT Image 2),‏ xAI (Grok Image),‏ Together AI (FLUX),‏ Fireworks AI,‏ Nebius (FLUX),‏ Hyperbolic,‏ NanoBanana,‏ **OpenRouter**,‏ **ZenMux**,‏ SD WebUI (מקומי),‏ ComfyUI (מקומי). `n` מחזיר `n` תמונות בתוך `data[]`. עבור ספקים שממשק ה-API שלהם במעלה הזרם מחזיר תמונה אחת בכל קריאה (Black Forest Labs,‏ Stability AI,‏ Leonardo,‏ Ideogram,‏ Haiper,‏ Hyperbolic,‏ Magnific/Freepik, NVIDIA NIM,‏ Cloudflare Workers AI), מתבצעות `n` קריאות נפרדות במעלה הזרם, עם לכל היותר 4 קריאות פעילות במקביל. ערך `seed` קבוע מוזז לפי אינדקס הקריאה (`seed`,‏ `seed + 1`, …), כך שהתמונות שונות אך נשארות ניתנות לשחזור. הערך `n` מוגבל ל-10. הבקשה כולה נכשלת אם אחת מהקריאות נכשלת. רשימת הפורמטים לביצוע fan-out נמצאת ב-`SINGLE_IMAGE_FANOUT_FORMATS` בקובץ `open-sse/handlers/imageGeneration/fanOut.ts`. ZenMux עושה שימוש חוזר בחיבור הקיים של מפתח ה-API ומקבל קידומות `zenmux/` או `zm/`: - `zenmux/openai/gpt-image-2` משתמש ב-OpenAI Images API של ZenMux. האפשרויות כוללות את `size`, `quality`,‏ `n`,‏ `output_format`,‏ `output_compression`,‏ `background` ו-`response_format`. - מפרסמים אחרים, כגון `zm/meta/muse-image-1.0`, משתמשים בנקודת הקצה `:predict` של Vertex AI ב-ZenMux. הערך `n` ממופה אל `sampleCount`,‏ `aspect_ratio` אל `aspectRatio`, ו-`image_size` (`1K`,‏ `2K`,‏ `4K`) אל `sampleImageSize`. ערך `size` בפיקסלים מספק יחס גובה-רוחב בלבד, ולא ממדי פיקסלים מובטחים. היחסים, הרזולוציות והכמויות הנתמכים משתנים בהתאם למודל. - `zm/inclusionai/ming-image-0.1-design` בוחר את הממדים בעצמו. יש להשמיט את `size`, `aspect_ratio` ו-`image_size`; ערכים מפורשים מחזירים HTTP 400. ניתן לבקש PNG,‏ JPEG ו-WebP באמצעות `output_format`. שילוב זה תומך ביצירת תמונות מטקסט, ולא בעריכת תמונות עזר. הפלט של Vertex מנורמל אל `data[].b64_json`;‏ `response_format: "url"` מחזיר כתובת URL מסוג HTTPS ממעלה הזרם או כתובת URL של נתוני base64 כאשר זמינים רק בתים של תמונה. פלטים ריקים או מסוננים מחזירים שגיאה במקום הצלחה ריקה. הגישה למודלים תלויה בחשבון ZenMux. ראו [Vertex API של ZenMux](https://docs.zenmux.ai/api/vertexai/generate-images) ו- [OpenAI Images API](https://docs.zenmux.ai/api/openai/generate-an-image). ```bash # הצגת כל מודלי התמונות GET /v1/images/generations ``` --- ## OCR למסמכים ```bash POST /v1/ocr Authorization: Bearer your-api-key Content-Type: application/json { "model": "mistral/mistral-ocr-latest", "document": { "type": "document_url", "document_url": "https://example.com/invoice.pdf" } } ``` `model` בוחר את ספק ה-OCR באמצעות קידומת `provider/model`; מזהה מודל ללא קידומת (למשל `mistral-ocr-latest`) נפתר לספק הרשום שלו, ואם `model` מושמט, ברירת המחדל היא Mistral‏ (`mistral-ocr-latest`). ספקים רשומים (`open-sse/config/ocrRegistry.ts`): | מזהה ספק | מזהה מודל | ערך `model` | הערות | | ----------------------------- | -------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | | `mistral` | `mistral-ocr-latest` | `mistral/mistral-ocr-latest` (או `mistral-ocr-latest` ללא קידומת) | סינכרוני — התגובה מוחזרת ישירות מהקריאה היחידה במעלה הזרם. | | `azure-document-intelligence` | `prebuilt-read` | `azure-document-intelligence/prebuilt-read` | אסינכרוני במעלה הזרם (`analyze` + תשאול) — ראו להלן. | | `vertex-deepseek-ocr` | `deepseek-ocr-maas` | `vertex-deepseek-ocr/deepseek-ocr-maas` | סינכרוני, דרך נקודת הקצה לשותפים `openapi/chat/completions` של Vertex AI — לפרטי אימות וכתובת URL, ראו להלן. | כל שלושת הספקים מגיבים בגוף בעל אותו מבנה כמו Mistral: ```json { "pages": [{ "index": 0, "markdown": "# Extracted text..." }], "model": "mistral-ocr-latest", "usage_info": { "pages_processed": 1 } } ``` ### תהליך התשאול של Azure Document Intelligence ממשק ה-API‏ `analyze` של Azure Document Intelligence הוא אסינכרוני: הבקשה הראשונית מחזירה כותרת `Operation-Location` במקום גוף, ויש לתשאל כדי לקבל את התוצאה. המטפל (`open-sse/handlers/ocr.ts`) מתשאל את כתובת ה-URL הזאת בכל שנייה, עד 30 ניסיונות, נכשל מיד (ואינו ממשיך לתשאל) במקרה של תגובת תשאול שאינה `ok` או מצב `"failed"`, ומחזיר `504` אם הפעולה עדיין פועלת לאחר שמכסת הניסיונות מוצתה. התגובה הסופית של Azure מנורמלת לאותו מבנה `pages`/`markdown` שבו משתמש Mistral לפני שהיא מוחזרת למתקשר, כך שקוד הלקוח אינו צריך לטפל בספק כמקרה מיוחד. ### אימות ופתרון נקודת קצה עבור Vertex AI DeepSeek OCR `vertex-deepseek-ocr` עושה שימוש חוזר באותו אימות Vertex AI שבו OmniRoute כבר תומך עבור תעבורת צ'אט ותמונות (`open-sse/executors/vertex.ts`): מפתח ה-API של החיבור הוא אישור Service Account בפורמט JSON (שמוחלף באסימון גישה קצר-טווח מסוג OAuth באמצעות תהליך JWT-bearer) או אסימון גישה מסוג OAuth שכבר הונפק ונעשה בו שימוש כפי שהוא. כתובת ה-URL של נקודת הקצה במעלה הזרם היא נקודת הקצה הכללית לשותפים `openapi/chat/completions` של Vertex, שנבנית מהפרויקט ומהאזור של החיבור — ערך מפורש של `providerSpecificData.project`/`providerSpecificData.region` תמיד גובר; אחרת, הפרויקט נגזר מהערך `project_id` ב-JSON של ה-Service Account והאזור מקבל כברירת מחדל את `us-central1`. שני הפתרונות מתבצעים ב-`open-sse/handlers/ocr.ts` (`resolveVertexOcrAccessToken`,‏ `resolveVertexOcrBaseUrl`) ונצרכים על ידי `src/app/api/v1/ocr/route.ts` לפני ההעברה אל `handleOcr`. --- ## רשימת מודלים ```bash GET /v1/models Authorization: Bearer your-api-key → מחזיר את כל מודלי הצ'אט, ההטמעות והתמונות + שילובים בפורמט OpenAI ``` ### מחירי מודלים (`pricing`) רשומה מכילה אובייקט `pricing` כאשר OmniRoute יודע מהו מחיר המודל. המחיר מגיע מטבלת התמחור המשמשת לחישוב עלויות: ברירות מחדל מובנות, מחירים מסונכרנים ודריסות שהוגדרו באמצעות `/api/pricing`. אלה מחירי מחירון, ולכן גם ספקי מנויים מציגים מחיר לטוקן. ```json "pricing": { "prompt": "0.000005", "completion": "0.000025", "input_cache_read": "0.0000005", "input_cache_write": "0.00000625", "input": 5, "output": 25, "cached": 0.5, "cache_creation": 6.25 } ``` | שדות | יחידה | הערות | | --------------------------------------------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | `prompt`, `completion`, `input_cache_read`, `input_cache_write` | דולר ארה"ב לטוקן, מחרוזת עשרונית | תואם OpenRouter, לעולם לא בסימון מעריכי. שני שדות המטמון מופיעים רק כאשר קיים מחיר למטמון. | | `input`, `output`, `cached`, `cache_creation` | דולר ארה"ב למיליון טוקנים, מספר | שדות מגרסאות קודמות של הקטלוג, שנשמרו עבור לקוחות קיימים. גם `reasoning` ו-`long_context` מופיעים כאשר שורת התמחור כוללת אותם. | - **שילובים** מקבלים את המחיר של היעד הגלוי הראשון שלהם. שילובי `auto/*` מובנים בוחרים יעד בזמן הבקשה, ולכן אין להם `pricing`. - **מודלים חינמיים** מציגים `"0"` (וגם `0`) כאשר מחירם אפס. מודל ללא שורת תמחור מציג גם הוא `"0"` כאשר הקטלוג מסמן אותו כחינמי (`free: true`) או כאשר קטלוג המודלים החינמיים המובנה כולל אותו. - **מחיר לא ידוע:** לרשומה אין מפתח `pricing`. - **ספקים הנמדדים לפי נקודות זכות** (כגון Kiro) מחייבים לפי בקשה ולא לפי טוקן. הרשומות שלהם שומרות את השדות המספריים למיליון שהיו להן קודם, ואינן כוללות שדות מחרוזת לטוקן. - **וריאנטים** (מזהי רמת מאמץ להסקה, כינויים ללא חשיבה, ושיקופי גילוי ושער) מעתיקים את המחיר של המודל שאליו הם מנתבים. - השדות מכילים תעריפי בסיס בלבד. מדרגות הקשר ארוך (השדה המספרי `long_context`) ומכפילי רמת שירות (לדוגמה Codex מהיר או גמיש) אינם משנים את `prompt` או את `completion`. - האובייקט זהה בכל סגנונות האימות, כולל בקשה בסגנון Anthropic עם `x-api-key` ו-`anthropic-version` (התגובה נשארת `{ "object": "list", "data": [...] }`). מימוש: `src/app/api/v1/models/catalogPricing.ts`. ### קידומות מזהי מודלים (`?prefix=`) רוב המודלים מוצגים תחת **קידומת ספק**. הקידומת שתקבל נשלטת באמצעות דגל התכונה `MODELS_CATALOG_PREFIX_MODE`, וניתן לדרוס אותה **לכל בקשה בנפרד** באמצעות פרמטר שאילתה — שימושי עבור לקוח שרוצה רשימה נקייה מבלי לשנות את ההגדרה הכללית בשרת עבור כל השאר: ```bash GET /v1/models?prefix=alias # מזהה אחד לכל מודל — קידומת הכינוי הקצרה GET /v1/models?prefix=dual # שתי הצורות (ברירת המחדל של השרת) GET /v1/models?prefix=canonical # רק הקידומת המלאה של מזהה הספק ``` | מצב | פלט | הערות | | ----------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `dual` | `cc/claude-sonnet-4-6` **וגם** `claude/claude-sonnet-4-6` | **ברירת המחדל.** שני המזהים מנתבים לאותו מודל; נשמרו כדי שתצורות לקוח שבהן אחת מהצורות מקודדת באופן קשיח ימשיכו לפעול. מכפיל בקירוב את גודל הקטלוג. | | `alias` | `cc/claude-sonnet-4-6` | רשומה אחת לכל מודל. ספקים ללא כינוי נפרד עדיין מפיקים את הרשומה שלהם, כך שדבר אינו הולך לאיבוד. | | `canonical` | `claude/claude-sonnet-4-6` | רשומה אחת לכל מודל תחת הקידומת המלאה של מזהה הספק. ספקים ללא כינוי נפרד (למשל `antigravity/…`, `agy/…`) מפיקים גם כאן את המזהה היחיד שלהם, כך שדבר אינו הולך לאיבוד. | ניתן לזהות שיקוף במצב `dual` גם ללא פרמטר השאילתה: הוא מכיל שדה `parent` המצביע על המזהה הראשי. לקוחות המציגים בורר מודלים צריכים לבקש `?prefix=alias` — כך פועלת [הרחבת OmniCopilot עבור VS Code](../guides/VSCODE-COPILOT.md). ### מסנני גילוי (`?capability=`, `?min_context=`, `?kind=`, `?q=`) `GET /v1/models` מקבל מסנני גילוי אופציונליים. ללא אף אחד מהם, התגובה אינה משתנה. הם מצמצמים את הקטלוג שהמתקשר כבר רואה (הרשאות מפתח API מוחלות תחילה), והם פועלים לפני הדפדוף בסגנון OpenAI באמצעות `limit` / `after`: ```bash GET /v1/models?capability=vision&capability=tool_calling # כל יכולת שמופיעה חייבת להיות true GET /v1/models?capability=vision,reasoning&min_context=200000 GET /v1/models?kind=embedding # שדה `type` בקטלוג; שורות ללא שדה כזה הן `chat` GET /v1/models?q=sonnet&limit=10 # התאמה שאינה תלוית רישיות לפי מזהה או שם ``` | פרמטר | ערכים | | ------------- | --------------------------------------------------------------------------------------------------- | | `capability` | `attachment`, `reasoning`, `structured_output`, `temperature`, `thinking`, `tool_calling`, `vision` | | `min_context` | מספר שלם שאינו שלילי, המושווה ל־`context_length` | | `kind` | `chat`, `audio`, `embedding`, `image`, `moderation`, `music`, `rerank`, `video` | | `q` | 1–200 תווים | ערך לא מוכר, או `min_context` שאינו מספר שלם שאינו שלילי (לדוגמה `1.5`), מחזירים HTTP `400`, וההודעה מפרטת את הערכים התקינים. מימוש: `src/app/api/v1/models/catalogFilters.ts`. ### רשימת מודלים מצומצמת (`POST /v1/models/query`) `POST /v1/models/query` מחזיר רשימה קצרה ודטרמיניסטית מאותו קטלוג, עם אותם אימות והרשאות נראות לכל מפתח כמו `GET /v1/models`: ```bash POST /v1/models/query Authorization: Bearer your-api-key Content-Type: application/json { "capabilities": ["vision", "tool_calling"], "min_context": 128000, "max_output": 16000, "kind": "chat", "q": "gpt", "owned_by": "openai", "exclude": ["openai/gpt-4o"], "limit": 5 } → { "object": "list", "data": [ ...models ] } ``` כל שדה הוא אופציונלי. `capabilities` ו־`exclude` מקבלים מערך או מחרוזת מופרדת בפסיקים; `max_output` מושווה ל־`max_output_tokens`. התוצאות ממוינות לפי `owned_by`, ולאחר מכן לפי `id`. ערך ברירת המחדל של `limit` הוא `20`, וערכים מעל `100` מוגבלים ל־`100`. JSON לא תקין, שדה לא מוכר או ערך לא תקין מחזירים HTTP `400`. ### מודלי צ׳אט מוסתרים בנפרד מודל המסומן כ־**מוסתר** בדף הספק שלו אינו נכלל בקטלוג, ובקשה מפורשת עבורו נדחית עם HTTP `404` / `model_not_found`. הבדיקה משתמשת בספק ובמודל שנקבעו, לרבות כינויים של ספקים, תחיליות צמתים של ספקים תואמים וברירות מחדל של חיבורים. שילוב מדלג על יעדים מוסתרים ויכול להשתמש ביעד חלופי גלוי; כאשר לא נותר יעד שניתן להריץ, מוחזר אותו קוד שגיאה. ביטול ההסתרה נכנס לתוקף בבקשה הבאה. הגדרות נראות עוקפות לתמונות בלבד אינן מסתירות את מודל הצ׳אט בעל אותו מזהה. הגדרת מודל נפרדת זו אינה קשורה ל־ [רשימות ההרשאה/חסימה לחשיפת מודלים](../routing/MODEL_EXPOSURE_LIST.md), שמסננות את הצגת הקטלוג ואת המועמדים לניתוב אוטומטי, תוך שמירה על ניתוב מפורש. הרשאות מודלים של מפתחות API ממשיכות לחול באופן עצמאי. מצב תחילית הקטלוג המוגדר כברירת מחדל נשאר `dual`. ### וריאציות מודל ללא חשיבה עבור מודלי Claude התומכים בחשיבה, `/v1/models` מפרסם גם וריאציית **ללא חשיבה**, שהמזהה שלה מתחיל ב־`claude-3-omniroute-no-thinking/`: ``` claude-3-omniroute-no-thinking// ``` בחירת מזהה זה (לדוגמה, בתצורת Claude Code שתמיד מצרפת בלוק `thinking`) חוזרת אל `/` האמיתי תוך דיכוי ההסקה — `thinking:{type:"disabled"}` בנתיב `/v1/messages`, או הסרת השדות `reasoning`/`reasoning_effort` בנתיב `/v1/chat/completions`. הווריאציה מופיעה רק עבור מודלים ממשפחת Claude שתומכים בחשיבה **וגם** מכבדים `disabled` (כך שלדוגמה, מודלים אדפטיביים בלבד שדוחים `disabled` אינם נכללים). מפעילים יכולים לאלץ את הפעלת הווריאציה או את השבתתה עבור כל מודל באמצעות `ModelSpec.noThinkingAlias`. --- ## מניפסט תוסף ספק ```bash GET /api/v1/provider-plugin-manifest ``` מחזיר את מניפסט תוסף הספק הבטוח לשימוש ב-JSON, המשמש את Bifrost, את CLIProxyAPI ואת נתבי ה-sidecar העתידיים. התגובה נוצרת ממרשם הספקים של TypeScript ומחריגה במכוון סודות לקוח של OAuth, פתרון של סביבת זמן ריצה, פונקציות ביצוע, כותרות בקשות ונתוני חשבונות. השתמשו בנקודת קצה זו כאשר sidecar פועל מחוץ לתהליך ואינו יכול לייבא ישירות את `open-sse/config/providerPluginManifestRegistry.ts`. --- ## יצירת אודיו באמצעות ElevenLabs הגדירו ב-OmniRoute חיבור לספק `elevenlabs` באמצעות מפתח ה-API שלכם ב-ElevenLabs. לקוחות מבצעים אימות באמצעות מפתח **OmniRoute** שלהם (`Authorization: Bearer $OMNIROUTE_API_KEY`); השער מספק את מפתח הספק השמור בתור `xi-api-key`. לעולם אל תשלחו מפתח ElevenLabs בתור אסימון ה-bearer של השער. | שיטה | נתיב | תגובה | קטגוריית נקודת הקצה של מפתח ה-API | | ---- | --------------------------- | -------------------------------------- | --------------------------------- | | POST | `/v1/sound-generation` | בתים של אודיו מקורי | `elevenlabs` | | POST | `/v1/music` | בתים של אודיו מקורי | `music` | | POST | `/v1/music/stream` | בתים של אודיו מוזרם | `music` | | POST | `/v1/music/detailed` | אודיו multipart מקורי ותוכנית הלחנה | `music` | | POST | `/v1/music/detailed/stream` | מטא-נתונים מקוריים של SSE ומקטעי אודיו | `music` | | POST | `/v1/music/plan` | תוכנית הלחנה בפורמט JSON | `music` | נקודות קצה אלה משלימות את הנתיבים הקיימים `/v1/audio/speech`, `/v1/audio/transcriptions`, `/v1/voices`, `/v1/text-to-speech/{voiceId}` ו-`/v1/speech-to-text`. שדות JSON מקוריים ופרמטרי שאילתה כגון `output_format` ו-`enable_logging` נשמרים. התגובות של `/v1/music/detailed` שומרות על גבולות ה-multipart שלהן; יש לנתח אותן כ-multipart. `/v1/music/detailed/stream` מחזיר `text/event-stream` עם מטא-נתונים של ההלחנה ומקטעי אודיו בקידוד base64 באירועי SSE. כל ששת הנתיבים תומכים בבקשות קדם של CORS. ```bash export OMNIROUTE_BASE_URL="http://localhost:20128" export OMNIROUTE_API_KEY="your-omniroute-api-key" # אפקט צליל קצר. משך: 0.5 עד 30 שניות. curl --fail-with-body "$OMNIROUTE_BASE_URL/v1/sound-generation?output_format=mp3_44100_128" \ -H "Authorization: Bearer $OMNIROUTE_API_KEY" \ -H "Content-Type: application/json" \ -d '{"text":"A single soft bell chime","duration_seconds":1,"model_id":"eleven_text_to_sound_v2"}' \ --output effect.mp3 # משך המוזיקה מבוטא באלפיות השנייה: 3000 עד 600000. curl --fail-with-body "$OMNIROUTE_BASE_URL/v1/music?output_format=mp3_44100_128" \ -H "Authorization: Bearer $OMNIROUTE_API_KEY" \ -H "Content-Type: application/json" \ -d '{"prompt":"Gentle instrumental piano","music_length_ms":10000,"force_instrumental":true,"model_id":"music_v1"}' \ --output music.mp3 ``` השתמשו ב-`/v1/music/stream` עם אותו גוף JSON לצורך מסירה הדרגתית של האודיו. ההלחנה מקבלת בדיוק אחד מבין `prompt` או `composition_plan`; הנתיב `/v1/music/plan` דורש `prompt` ומקבל באופן אופציונלי את `source_composition_plan`. הסכמות המקוריות משמרות שדות ספק נוספים, כדי שגרסאות של תוכניות הלחנה ואפשרויות כוונון עדין יגיעו ל-ElevenLabs. נקודת הקצה המאוחדת `/v1/music/generations` מקבלת גם את `elevenlabs/music_v1`, `elevenlabs/music_v2` ואת `elevenlabs/music_v2_5`. כאשר קיים חיבור פעיל ל-ElevenLabs, מודלים אלה מוצגים בקטלוג המוזיקה. נקודת קצה זו מחזירה `{"created":...,"data":[{"b64_json":"...","format":"mp3"}]}`. השדה `duration` שלה נמדד בשניות וממופה אל `music_length_ms`; ערך מפורש של `music_length_ms` מקבל קדימות. `instrumental` ממופה אל `force_instrumental`, כאשר השדה המקורי מקבל קדימות. השתמשו בנקודות הקצה המקוריות להזרמה לצורך הזרמה, ובנקודת הקצה המקורית להלחנה עבור בקשות שמונעות רק באמצעות תוכנית הלחנה. ```bash curl --fail-with-body "$OMNIROUTE_BASE_URL/v1/music/generations" \ -H "Authorization: Bearer $OMNIROUTE_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"elevenlabs/music_v1","prompt":"Gentle instrumental piano","duration":10,"instrumental":true}' ``` הגבלות של נקודת קצה, מודל, תקציב וחיבור חלות לפני קריאה לשירות המקור. נתיבים מקוריים מחזירים את קודי הסטטוס ואת גופי השגיאות משירות המקור ללא שינוי, כולל `402` עבור הגבלה של תוכנית ו-`429` עבור מגבלת מכסה. הכותרות `character-cost`, `song-id`, `request-id` ו-`retry-after` נשמרות כאשר הן קיימות. יתרת זיכויים חינמית אינה מבטיחה גישה לכל מודל מוזיקה, פורמט פלט או תכונת API: ElevenLabs קובעת את הזכאות לכל בקשה. נקודת הקצה המאוחדת משמרת קודי סטטוס של שגיאות במעטפת השגיאות המנורמלת של OmniRoute. חוזי שירות המקור: [אפקטים קוליים](https://elevenlabs.io/docs/api-reference/text-to-sound-effects/convert), [הלחנת מוזיקה](https://elevenlabs.io/docs/api-reference/music/compose) ו- [פרטי מוזיקה מוזרמת](https://elevenlabs.io/docs/api-reference/music/compose-detailed-stream). --- ## נקודות קצה לתאימות | שיטה | נתיב | פורמט | | ---- | ----------------------------------------- | ----------------------------------------- | | POST | `/v1/chat/completions` | OpenAI | | POST | `/v1/messages` | Anthropic | | POST | `/v1/responses` | OpenAI Responses | | POST | `/v1/embeddings` | OpenAI | | POST | `/v1/images/generations` | OpenAI Images | | POST | `/v1/images/edits` | OpenAI Images (עריכה/השלמה) | | POST | `/v1/videos/generations` | יצירת וידאו בסגנון OpenAI | | POST | `/v1/music/generations` | יצירת מוזיקה בסגנון OpenAI | | POST | `/v1/audio/transcriptions` | OpenAI Audio (דיבור לטקסט) | | POST | `/v1/audio/speech` | OpenAI TTS (מחזיר גוף שמע) | | POST | `/v1/rerank` | דירוג מחדש בסגנון Cohere/Voyage | | POST | `/v1/classify` | סיווג של Jina (`api.jina.ai`) | | POST | `/v1/segment` | חלוקה למקטעים של Jina (`segment.jina.ai`) | | POST | `/v1/moderations` | OpenAI Moderations | | GET | `/v1/models` | OpenAI | | POST | `/v1/models/query` | רשימה מצומצמת ומסוננת של מודלים | | POST | `/v1/messages/count_tokens` | Anthropic | | GET | `/v1beta/models` | Gemini | | POST | `/v1beta/models/{...path}` | Gemini generateContent | | POST | `/v1/api/chat` | Ollama | | GET | `/api/v1/vscode/{token}/` | כינוי לקטלוג OpenAI | | GET | `/api/v1/vscode/{token}/models` | כינוי למודלים של OpenAI | | POST | `/api/v1/vscode/{token}/chat/completions` | כינוי OpenAI עם אסימון | | POST | `/api/v1/vscode/{token}/responses` | כינוי OpenAI Responses עם אסימון | | POST | `/api/v1/vscode/{token}/api/chat` | כינוי Ollama עם אסימון | | GET | `/api/v1/vscode/{token}/api/tags` | כינוי לתגיות Ollama עם אסימון | כל נתיבי ה-POST משתמשים באותו מבנה: `Bearer your-api-key` + גוף JSON המאומת באמצעות Zod (`v1RerankSchema`, `v1ModerationSchema`, `v1AudioSpeechSchema` וכו'; ראו `src/shared/validation/schemas.ts`). במקרה של כשל באימות הסכימה מוחזרת תגובת 4xx. עבור לקוחות שאינם יכולים לצרף `Authorization: Bearer ...`, ‏OmniRoute מקבל גם מפתחות API בכתובת ה-URL, באמצעות תאימות למחרוזת שאילתה (`?token=...`, `?apiKey=...`, `?api_key=...`, `?key=...`) או באמצעות נקודות הקצה הייעודיות `/api/v1/vscode/{token}/...` המתועדות להלן. ```bash # דירוג מחדש (ספק ממרשם הענן, או צומת ספק תואם OpenAI בתבנית "/") POST /v1/rerank { "model": "jina-ai/jina-reranker-v3.5", "query": "...", "documents": ["..."] } # סיווג של Jina (פרטי גישה ל-Foundation API) POST /v1/classify { "model": "jina-embeddings-v5-text-small", "input": ["..."], "labels": ["a", "b"] } # מחלק המקטעים של Jina POST /v1/segment { "content": "...", "return_chunks": true } # חיפוש Jina‏ (s.jina.ai; כינויי ספק: jina-search, jina-ai, jina) POST /v1/search { "query": "...", "provider": "jina-search" } # ניהול תוכן POST /v1/moderations { "model": "omni-moderation-latest", "input": "..." } # TTS — מחזיר גוף audio/mpeg (או בפורמט המבוקש) POST /v1/audio/speech { "model": "openai/tts-1", "input": "Hello", "voice": "alloy" } # Soniox TTS דורש שפה וקול: ערך ברירת המחדל של `language` הוא "en"; קול חסר # או שם של קול מובנה ב-OpenAI‏ (alloy, nova, …) הופך ל-"Adrian" POST /v1/audio/speech { "model": "soniox/tts-rt-v1", "input": "Xin chào", "voice": "Adrian", "language": "vi" } # עריכת תמונה (multipart) POST /v1/images/edits -F image=@input.png -F prompt="..." -F mask=@mask.png # יצירת וידאו / מוזיקה (מזהה מודל עם קידומת ספק) POST /v1/videos/generations { "model": "runway/gen-3", "prompt": "..." } POST /v1/music/generations { "model": "kie/suno-v4.0", "prompt": "..." } ``` > **צומתי ספק לדירוג מחדש:** `POST /v1/rerank` מנתב גם לצומתי ספק תואמי OpenAI > (oMLX, vLLM, Infinity, TEI מאחורי שער, …) שהכתובת שלהם היא `/`. צומתי > לולאה חוזרת (`localhost`, `127.0.0.1`, `172.16.0.0/12`) תמיד כשירים, וכך גם שמות מארחים > שהמפעיל מגדיר ב-`OMNIROUTE_LOCAL_PROVIDER_NODE_HOSTS` (למשל שם שירות של Docker/Compose כגון > `http://reranker:8080/v1`; הפנייה אליהם מתבצעת ישירות, לעולם לא דרך `HTTP(S)_PROXY` או דרך > פרוקסי מקובע של חיבור). צמתים בכל מארח אחר > — מחשב ברשת LAN או עמית Tailscale — כשירים רק כאשר המפעיל מפעיל את דגל התכונה > `RERANK_REMOTE_PROVIDER_NODES` **וגם** כתובת ה-URL הבסיסית של הצומת עוברת את מדיניות כתובות > ה-URL היוצאות של הספק (`OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS` / `OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS`). > שלב הדירוג מחדש של מנוע הזיכרון קורא לנתיב זה דרך > לולאה חוזרת, ולכן אותו כלל חל על `rerankProviderModel` בהגדרות הזיכרון. > > **תצורות שרת מקומי:** הקריאה לצומת מתבצעת ב-`/v1/rerank`, ובמקרה של 404, ב-`/rerank` > (Infinity, TEI). גוף הבקשה למעלה הזרם כולל הן את האיות של Cohere/OpenAI (`documents`, > `return_documents`) והן את האיות של TEI (`texts`, `return_text`), ותגובת השרת במעלה הזרם > מנורמלת למעטפת Cohere: המערך החשוף של TEI, ‏`[{index, score, text}]`, המבנה `{results: [{index, score}]}` > משערים רזים, והמבנה בסגנון Voyage ‏`{data: [...]}` — כולם מוחזרים ללקוח בתור > `{results: [{index, relevance_score, document?}]}`, ממוינים לפי ציון ומוגבלים ל-`top_n`. > **גילוי צומתי ספק:** מודלים בצומת ספק תואם OpenAI מופיעים ב-`GET /v1/models` > תחת קידומת הצומת. רשומות שאינן כוללות מטא-נתונים של נקודת קצה (כמקובל ברשימות `/v1/models` מקומיות) > יורשות את ה-`apiType` של הצומת, כך שהמודלים של צומת `embeddings` הם `type: "embedding"` והמודלים > של צומת `rerank` הם `type: "rerank"` במקום שברירת המחדל שלהם תהיה צ'אט; ערך מפורש של > `supportedEndpoints` ברשומה מסונכרנת או שנוספה ידנית עדיין מקבל קדימות. ### נתיבי ספק ייעודיים ```bash POST /v1/providers/{provider}/chat/completions POST /v1/providers/{provider}/embeddings POST /v1/providers/{provider}/images/generations ``` קידומת הספק מתווספת אוטומטית אם היא חסרה. מודלים שאינם תואמים מחזירים `400`. --- ## API לקבצים נקודת קצה תואמת OpenAI לקלט/פלט באצווה ולהעלאת קבצים לפי ייעוד. | שיטה | נתיב | תיאור | | ------ | ------------------------ | --------------------------------------------------------------------------------------------------------- | | POST | `/v1/files` | העלאת קובץ (multipart: `file`, `purpose`, `expires_after[anchor]`, `expires_after[seconds]`) — עד 512 MiB | | GET | `/v1/files` | הצגת רשימת הקבצים עבור מפתח ה-API המאומת | | GET | `/v1/files/[id]` | אחזור המטא-נתונים של קובץ | | DELETE | `/v1/files/[id]` | מחיקת קובץ | | GET | `/v1/files/[id]/content` | הזרמת גוף הקובץ הגולמי בחזרה | **אימות:** מפתח API מסוג Bearer — הקבצים משויכים לכל מפתח API באמצעות `getApiKeyRequestScope`. מפתח יכול להציג, להוריד ולמחוק את הקבצים שלו בלבד; סשן של לוח המחוונים ללא מפתח יכול לקרוא את המופע כולו; הגישה לקובץ ללא בעלים (העלאה אנונימית או דרך סשן של לוח המחוונים) נדחית עבור כל מי שאינו פונה מתוך סשן. `GET /v1/files` דוחה פונה אנונימי — וגם מפתח שסופק אך אינו ניתן לזיהוי — עם `401` גם כאשר `REQUIRE_API_KEY=false`, במקום להציג את הקבצים של כל הדיירים (GHSA-m3hp-hq9g-fpmv, GHSA-2jm2-mpx8-6523). --- ## API לאצוות עיבוד אצוות תואם OpenAI. | שיטה | נתיב | תיאור | | ------ | ------------------------- | --------------------------------------------------------------------------------------------------------- | | POST | `/v1/batches` | יצירת אצווה — הגוף מאומת באמצעות `v1BatchCreateSchema` (`input_file_id`, `endpoint`, `completion_window`) | | GET | `/v1/batches` | הצגת רשימת האצוות | | GET | `/v1/batches/[id]` | אחזור סטטוס האצווה ו-`request_counts` | | DELETE | `/v1/batches/[id]` | מחיקת אצווה שהסתיימה או נכשלה | | POST | `/v1/batches/[id]/cancel` | ביטול אצווה שנמצאת בתהליך | **אימות:** מפתח API מסוג Bearer. האצוות משויכות לכל מפתח API לפי אותו כלל משולש כמו הקבצים: מפתח הבעלים בלבד, גישה לכל המופע דרך סשן של לוח המחוונים, ורשומות ללא בעלים חסומות בפני כל מי שאינו פונה מתוך סשן (אחזור, מחיקה, ביטול ובדיקת `input_file_id` בעת היצירה). `GET /v1/batches` דוחה פונה אנונימי עם `401` גם כאשר `REQUIRE_API_KEY=false`. --- ## API לחיפוש הפשטה עבור ספקי חיפוש באינטרנט (Tavily, Brave, Exa, Serper וכו'). | שיטה | נתיב | תיאור | | ---- | ---------------------- | ----------------------------------------------------------------------------------------- | | GET | `/v1/search` | הצגת ספקי החיפוש המוגדרים והיכולות שלהם | | POST | `/v1/search` | הרצת שאילתת חיפוש — גוף הבקשה מאומת באמצעות `v1SearchSchema`, עם תמיכה במטמון/איחוד בקשות | | GET | `/v1/search/analytics` | נתוני פגיעות/זמן השהיה/מטמון לכל ספק | **אימות:** מפתח API מסוג Bearer ‏(`extractApiKey` + `isValidApiKey`). מדיניות החיפוש נאכפת באמצעות `enforceApiKeyPolicy`. ### אפשרויות `provider_options` של Exa ושל Tavily Exa ו-Tavily קוראים שדות ייעודיים לספק מתוך מאגר בעל מרחב שמות: `provider_options.exa` (או `provider_options["exa-search"]`) ו-`provider_options.tavily` (או `provider_options["tavily-search"]`). רק המפתחות שלהלן מועברים הלאה. כל אחד מהם נבדק מול סכמת Zod משלו ב-`open-sse/handlers/search/providerOptionsPassthrough.ts`, ומפתח מסוג שגוי מושמט. כל מפתח אחר אינו נלקח בחשבון, לרבות אימות, כתובת URL בסיסית, `stream` ו-`outputSchema`. המפתחות השטוחים שבהם משתמשים ספקים אחרים (`cx`, `depth`, ...) פועלים כמו קודם. | ספק | שדות ברמה העליונה | מקוננים | | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Exa | `type`, `category`, `userLocation`, `moderation`, `additionalQueries`, `objective`, `systemPrompt`, `compliance` (ערכים פרימיטיביים שטוחים), `startPublishedDate`, `endPublishedDate` | `contents.{text, highlights, summary, extras, subpages, subpageTarget, livecrawlTimeout, maxAgeHours}` ממוזג מעל ברירת המחדל `{ text: true, highlights: true }` | | Tavily | `search_depth`, `chunks_per_source`, `time_range`, `start_date`, `end_date`, `include_published_date`, `filter_by_published_date`, `include_answer`, `include_raw_content`, `include_images`, `include_image_descriptions`, `include_favicon`, `include_domains_mode`, `language`, `filter_by_language`, `auto_parameters`, `exact_match`, `include_usage`, `safe_search` | — | השדות הכלליים תמיד מקבלים עדיפות: `query`, `max_results`, `filters` (דומיינים), `country` והנושא הנגזר מ-`search_type`. ב-Exa, ‏`search_type: "news"` משמר את `category: "news"`. Tavily מקבל גם `search_type: "finance"` ‏(`topic: "finance"`). השדה הכללי `time_range` מגיע כעת לשני הספקים: Exa מקבל `startPublishedDate` (חותמת זמן בפורמט ISO) ו-Tavily מקבל `start_date` ‏(`YYYY-MM-DD`). תאריך מפורש ב-`provider_options` דורס את התאריך שמופה. תוצאות Exa שומרות את `id`, `highlight_scores`, `summary`, `subpages`, `entities` ו-`extras` בתוך `provider_raw`. תוצאות Tavily שומרות את `images` ואת `favicon`. חישוב העלויות עדיין משתמש במאגר השטוח `costPerQuery`. ‏Tavily מחייב יותר נקודות זכות לכל קריאה עבור `search_depth: "advanced"`, והפרש זה אינו משתקף ב-`usage.search_cost_usd`. --- ## Web Fetch API חילוץ תוכן מכתובת URL באמצעות ספק web-fetch מוגדר (Firecrawl, Jina Reader, Tavily Extract, TinyFish Fetch, Nimble Extract, Parallel Extract). Parallel Extract (`parallel-search`, אותו מפתח API כמו Parallel Search) מחזיר Markdown בלבד — כל `format` אחר גורר שגיאת `400` — ומגביל את התוכן ל-100,000 תווים. כאשר לא ניתן לחלץ את דף היעד עצמו, שירות המקור מדווח על כך בתוך HTTP 200; OmniRoute מציג זאת כשגיאת `422` עם הודעה קבועה. | שיטה | נתיב | תיאור | | ---- | --------------- | ------------------------------------------------------------------ | | POST | `/v1/web/fetch` | אחזור/גירוד כתובת URL — גוף הבקשה מאומת באמצעות `v1WebFetchSchema` | **אימות:** מפתח API מסוג Bearer (`extractApiKey` + `isValidApiKey`). המדיניות נאכפת באמצעות `enforceApiKeyPolicy`. **מעבר אוטומטי מודע למכסה (#8297):** כאשר לא מצוין `provider` מפורש, המאגר (`firecrawl` → `jina-reader` → `tavily-search` → `tinyfish` → `nimble-search` → `parallel-search`) נסרק בסדר עדיפויות קבוע (מילוי-ראשון) — מדלגים על ספק מוגדר שהוגבל בקצב במקום להפסיק מיד את הבקשה, וכשל ניתן לניסיון חוזר/הקשור למכסה אצל שירות המקור (HTTP 429 תמיד; 402/403 עבור שכבות חינמיות מבוססות-מכסה של Firecrawl/Tavily/TinyFish — לא עבור Jina Reader, ולעולם לא עבור בקשה שגויה רגילה מסוג 400) גורם למעבר לספק הבא שטרם נוסה ושיש עבורו פרטי גישה בזמן הבקשה. כאשר כל ספקי המאגר מוצו, נקודת הקצה מחזירה `429` יחיד (עם כותרת `Retry-After`) במקום שגיאת `400` הכללית הקודמת. כאשר מתבקש `provider` מפורש, **אין** מעבר אוטומטי שקט — ספק מפורש שהוגבל בקצב או שנכשל מציג את השגיאה שלו (`429` אם הוגבל בקצב, אחרת סטטוס שירות המקור). --- ## הזרמה באמצעות WebSocket ```bash GET /v1/ws?handshake=1 ``` מאמת לחיצת יד לשדרוג WebSocket ומחזיר את הודעות הדוגמה של פרוטוקול התקשורת (`request`, `cancel`). מסגרות WS בפועל מטופלות בידי שרת ה-WS המצורף, מחוץ לטבלת הנתיבים של Next.js. **אימות:** מפתח API מסוג Bearer במהלך לחיצת היד. ### Responses API באמצעות WebSocket (עבור codex בלבד) ```bash # אותו מארח ואותה יציאה כמו HTTP API (ברירת המחדל היא 20128); שדרגו את החיבור: wscat -c "ws://localhost:20128/v1/responses?api_key=" # (או: -H "Authorization: Bearer ") # המסגרת הראשונה חייבת להיות response.create: { "type": "response.create", "model": "gpt-5.5", "input": [ { "role": "user", "content": "hi" } ] } ``` מתווך Responses-API-over-WebSocket מחובר **באופן בלעדי אל `codex`** (קצה אחורי של ChatGPT). הוא מאזין באותה יציאה כמו ה-API/לוח הבקרה בנתיבים `/v1/responses`, `/responses` ו-`/api/v1/responses`. במסגרת `response.create` הראשונה הוא מבצע אימות והכנה באמצעות גשר `codex-responses-ws` הפנימי, בוחר חיבור OAuth של codex ומעביר את התעבורה אל `wss://chatgpt.com/backend-api/codex/responses` באמצעות תעבורת `wreq-js`. **מודלים שאינם codex נדחים** (`codex_ws_provider_required`). לניתוב שיתוף מכסה, השתמשו ב-`model: "qtSd//codex/"`. המימוש נמצא ב- `app/server-ws.mjs` + `scripts/dev/responses-ws-proxy.mjs` + `src/app/api/internal/codex-responses-ws/route.ts`. **אימות:** מפתח API מסוג Bearer במהלך לחיצת היד. שרת ה-HTTP המצורף (`server-ws.mjs`) חייב להיות נקודת הכניסה הפעילה (וכברירת מחדל הוא אכן כזה, כאשר `app/server-ws.mjs` קיים). #### מזהה מודל: השתמשו במזהה ChatGPT הגולמי (ללא הקידומת `codex/`) ה-**Codex CLI** של OpenAI מאמת את שם המודל בצד הלקוח כאשר `supports_websockets = true` ו**דוחה מזהים עם קידומת ספק** כגון `codex/gpt-5.5` (`The 'codex/gpt-5.5' model is not supported when using Codex with a ChatGPT account`). שלחו את המזהה **הגולמי** (לדוגמה, `gpt-5.5`). הגשר של OmniRoute מיועד ל-codex בלבד, ולכן הוא פותר מחדש מזהה גולמי כמודל codex (`resolveCodexWsModelInfo`) לפני העברת התעבורה לשירות המקור — אף שמזהה גולמי `gpt-5.5` היה מנותב אחרת לספק אחר באמצעות HTTP. #### הגדרת OpenAI Codex CLI הפנו את Codex CLI אל OmniRoute על ידי הוספת ספק מותאם אישית עם תמיכה ב-WebSocket אל `~/.codex/config.toml` (השתמשו ב-`CODEX_HOME` נפרד כדי להימנע משינוי תצורה קיימת): ```toml model = "gpt-5.5" # מזהה גולמי — לא "codex/gpt-5.5" model_provider = "omniroute" [model_providers.omniroute] name = "OmniRoute (WS)" base_url = "http://localhost:20128/v1" # ללא לוכסן מסיים; כתובת ה-WS נגזרת מכאן (השתמשו ב-https/wss בסביבת ייצור) wire_api = "responses" # הערך הנתמך היחיד מאז פברואר 2026 supports_websockets = true # מפעיל תעבורת Responses-over-WS env_key = "OMNIROUTE_API_KEY" # מכיל את מפתח ה-API של OmniRoute‏ (Bearer) ``` ```bash export OMNIROUTE_API_KEY=sk-... # מפתח API של OmniRoute‏ (כל מפתח אם REQUIRE_API_KEY=false) codex exec "Responda apenas: PONG" ``` ה-CLI משדרג את `base_url + /responses` ל-WebSocket, ו-OmniRoute מעביר את התעבורה לחיבור OAuth של codex שנבחר. התהליך אומת מקצה לקצה מול השרת המקומי: ChatGPT מחזיר `codex.rate_limits` + `response.created` ומזרים את ההשלמה. --- ## מכסות ודיווח על בעיות | שיטה | נתיב | תיאור | | ---- | ------------------- | ---------------------------------------------------------------------------- | | GET | `/v1/quotas/check` | אימות מקדים של המכסה עבור `provider` + `accountId` לפני הנפקת מפתח רשום | | POST | `/v1/issues/report` | דיווח על כשל במכסה/בהנפקת מפתח ל-GitHub (דורש `GITHUB_ISSUES_REPO` + אסימון) | **אימות:** מפתח API מסוג Bearer‏ (`isAuthenticated`). --- ## שימוש בשירות עצמי (`/api/usage/om-usage`) כל מפתח API יכול לקרוא את נתוני השימוש והמכסות **שלו עצמו** — ללא אימות ניהולי. זוהי נקודת הקצה שבה לקוח (CLI, הפאנל של OmniCopilot) משתמש כדי להציג לבעל המפתח את ההוצאות שלו. ```bash # תצורת טקסט (החוזה ההיסטורי — טקסט פשוט למסוף) curl -H "Authorization: Bearer " \ http://localhost:20128/api/usage/om-usage # תצורה מובנית — מה שממשק משתמש צורך curl -H "Authorization: Bearer " \ "http://localhost:20128/api/usage/om-usage?format=json" ``` במפתח חייבת להיות מופעלת האפשרות **`allowUsageCommand`** (כבויה כברירת מחדל — מנהל מפתחות ה-API בלוח הבקרה מפעיל או משבית אותה לכל מפתח). בלעדיה, נקודת הקצה מחזירה `403`. הפרמטר `?format=json` מחזיר מבנה מבחין, כך שקורא לעולם אינו קורא שדה נתונים מתוך סירוב. במקרה של הצלחה: ```jsonc { "allowed": true, // קיים רק כאשר המפתח הצטרף למגבלות שימוש לפי מפתח (יומיות/שבועיות בדולר ארה"ב): "personal": { "dailySpentUsd": 1.25, "dailyLimitUsd": 5, "dailyResetAtIso": "…", "weeklySpentUsd": 8, "weeklyLimitUsd": 20, "weeklyResetAtIso": "…" /* … */, }, // תמונת מצב של מכסת הספק שנבחר, או null כאשר דבר עדיין אינו שמור במטמון: "provider": { "connectionId": "…", "provider": "claude", "plan": "…", "quotas": {/* … */} }, // תמונות המצב של כל החיבורים, כדי שממשק משתמש יוכל להציג כמה ספקים זה לצד זה: "providers": [ { "connectionId": "…", "provider": "claude" /* … */ }, { "provider": "codex" /* … */ }, ], } ``` במקרה של סירוב (`401` מפתח שגוי / `403` אין הרשאה), אותו נתיב מחזיר `{ "allowed": false, "error": { "message": "…" } }` — מצב שבו `personal`/`provider` קיימים אך ריקים (המפתח מורשה, אך עדיין לא התקבל מידע) שונה מסירוב, ורק תצורת ה-JSON מבחינה ביניהם. **אימות:** מפתח ה-API מסוג Bearer של הקורא עצמו, המאומת באמצעות `isValidApiKey` — זהו _לא_ ממשק הניהול (`/api/keys/…`), שנותר מוגן באמצעות `requireManagementAuth`. ### אחוזי מכסה גולמיים לעומת אחוזים מותאמי סף בעת צריכת `/api/usage/om-usage`, על הקוראים לשים לב להבדל בין האחוזים המוצגים ב**פלט הטקסט הפשוט** לבין **פלט ה-JSON** המובנה: | היבט | תצורת טקסט פשוט (`/api/usage/om-usage` / `@@om-usage`) | תצורת JSON‏ (`?format=json`) | | :------------- | :------------------------------------------------------------------------------- | :------------------------------------------------------------------- | | **שדה פלט** | `NN% left` (למשל, `20% left`) | `provider.quotas` / `providers[].quotas` | | **מדידה** | **הקצאה זמינה מותאמת לסף**: הקיבולת שנותרה מעל סף הקיטוע | **מכסת ספק גולמית**: מדידת הספק ללא התאמות | | **התאמת הסף** | מותאמת באמצעות `effectiveRemainingPercent()` כך שהרזרבה המוגנת מוצגת כ-`0% left` | ללא (ערכי תמונת מצב גולמיים כפי שדווחו על ידי הספק) | | **נתוני סף** | משולבים באחוז המוצג | נשמרים ב-`quotaWindowThresholds` לכל חיבור (או כברירות מחדל של השרת) | | **צרכן עיקרי** | ממשקי CLI אינטראקטיביים, הנחיות מסוף, מפעילים אנושיים | אינטגרציות תכנותיות, לוחות בקרה, ניתוח נתונים, עוקבי חיוב | #### נוסחת התאמת הסף OmniRoute תומך בספי קיטוע יזומים של מכסות כדי למנוע מיצוי של משאבי הספק (מוגדרים באמצעות `quotaWindowThresholds` של החיבור, ברירות המחדל של הספק או הגדרות החוסן הגלובליות). כאשר סף קיטוע (למשל, `cutoff = 25%`) פעיל בחלון מכסה, מעבד הטקסט מחשב את ההקצאה שנותרה כך: - אם `remaining <= cutoff`: מוחזר `0%`. - אם `remaining > cutoff`: מוחזר `((remaining - cutoff) / (100 - cutoff)) * 100`. פלט הטקסט המעוצב מעגל זאת למספר השלם הקרוב ביותר (`Math.round(...)`). #### דוגמה להמחשה נניח חלון ספק עם **60% שימוש גולמי** (ולפיכך **40% מכסה גולמית שנותרה**) ועם סף מוגדר של **25% קיטוע מהמכסה שנותרה**: | ייצוג | חישוב | נותרו | שימוש משתמע | | :------------------------------ | :------------------------------------------------- | :-----: | :--------------------------------: | | **JSON גולמי (`?format=json`)** | תמונת מצב מהספק (`quotas[window]`) | **40%** | **60%** | | **תצורת טקסט (`NN% left`)** | `((40 - 25) / (100 - 25)) * 100 = (15 / 75) * 100` | **20%** | **80%** (בחישוב `100 - remaining`) | - **מדוע הטקסט מציג 20% שנותרו:** מתוך 40% מהמכסה הפיזית שנותרה בחשבון, 25% שמורים על ידי מדיניות הסף. לקורא נותרו רק 15% מתוך מרווח שמיש של 75% לפני שהנתב מפסיק לנתב לחיבור זה. ההתאמה מבטיחה שהחיבור יסמן מיצוי (`0% left`) בדיוק כאשר הניתוב ייפסק. - **מדוע JSON שומר על הערכים הגולמיים:** מטען ה-JSON מחזיר את תמונת המצב המדויקת של הספק (`UsageSnapshot`) כדי שלכלים חיצוניים תהיה גישה לנתוני המקור המדויקים של ניצולת הספק ול-`quotaWindowThresholds` ברמת החיבור, ללא התאמה מאבדת מידע בצד השרת. #### הנחיות להעברת צרכנים אם אינטגרציה חיצונית (כגון תוסף לעורך או הרחבת סוכן) חילצה בעבר את הנתונים מנקודת הקצה הטקסטואלית (`NN% left`) וחישבה את אחוז השימוש בתור `100 - NN`, המעבר אל `?format=json` משמעו: - קריאת ערכי JSON גולמיים תשקף את **הצריכה בפועל במעלה הזרם** (60% שימוש בדוגמה שלעיל). - אם האינטגרציה מעוניינת לשמר את סמנטיקת המכסה הזמינה של נקודת הקצה הטקסטואלית, היא יכולה לחשב בצד הלקוח את נוסחת היתרה האפקטיבית באמצעות `quotaWindowThresholds` לצורך דריסות ברמת החיבור. --- ## מטמון סמנטי ```bash # קבלת נתוני המטמון GET /api/cache/stats # ניקוי כל המטמונים DELETE /api/cache/stats ``` דוגמת תגובה: ```json { "semanticCache": { "memorySize": 42, "memoryMaxSize": 500, "dbSize": 128, "hitRate": 0.65 }, "idempotency": { "activeKeys": 3, "windowMs": 5000 } } ``` ### השפעה על זמן ההשהיה פגיעה במטמון הסמנטי (HIT) מספקת את התגובה מהמטמון **ללא קריאה לשירות במעלה הזרם**, ולכן הערך המדווח של `X-OmniRoute-Response-Latency` קרוב לאפס (ללא תלות בזמן ההשהיה המקורי במעלה הזרם). לקוחות הרגישים לזמן השהיה (מדידות ביצועים, ניטור p50/p99) צריכים לבדוק את כותרת התגובה `X-OmniRoute-Cache-Latency`: | ערך | משמעות | | ----------- | ---------------------------------------------------------- | | `synthetic` | התגובה סופקה מהמטמון; זמן ההשהיה אינו זמן אמיתי במעלה הזרם | | _(חסר)_ | תגובה מקריאה אמיתית לשירות במעלה הזרם | ### עקיפת מטמון לפי מפתח מפתחות API יכולים לוותר על קריאות מהמטמון הסמנטי באמצעות `cacheDefaultMode`: | ערך | התנהגות | | -------- | -------------------------------------------------- | | `legacy` | התנהגות מטמון רגילה (ברירת המחדל) | | `bypass` | דילוג מוחלט על חיפוש במטמון; פנייה תמיד במעלה הזרם | הגדירו בעת יצירת המפתח (`POST /api/keys`) או בעת עדכון (`PATCH /api/keys/[id]`): ```json { "cacheDefaultMode": "bypass" } ``` ### עקיפה לפי בקשה כל בקשה יכולה לעקוף את המטמון ללא תלות בהגדרות המפתח: ``` X-OmniRoute-No-Cache: true ``` --- ## לוח בקרה וניהול נתיבי ניהול (`/api/*` למעט אימות/כניסה ציבוריים) **אינם** מורשים באמצעות מפתחות API רגילים להסקה. משפחות פרטי כניסה, היקפי הרשאה ודוגמאות curl: [אימות לניהול](../guides/MANAGEMENT-AUTH.md). ### אימות | נקודת קצה | שיטה | תיאור | | ----------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `/api/auth/login` | POST | כניסה | | `/api/auth/logout` | POST | יציאה | | `/api/settings/require-login` | GET/POST | מצב כניסה (GET, ציבורי). POST מגדירה את הסיסמה / מפעילה או משביתה את חובת הכניסה: למפעיל בלבד לאחר שקיימת סיסמה (הפעלת לוח בקרה, CLI מקומי, או כניסה מושבתת — מפתחות API ואסימוני `oma_` מקבלים `403`); הפעלת לוח בקרה שולחת `currentPassword` כדי להחליף את הסיסמה | ### ניהול ספקים | נקודת קצה | שיטה | תיאור | | --------------------------------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | `/api/providers` | GET/POST | הצגת ספקים / יצירת ספקים | | `/api/providers/[id]` | GET/PUT/DELETE | ניהול ספק | | `/api/providers/[id]/test` | POST | בדיקת החיבור לספק | | `/api/providers/[id]/models` | GET | הצגת המודלים של הספק | | `/api/providers/validate` | POST | אימות תצורת הספק | | `/api/providers/bulk` | POST | הוספה מרוכזת של מפתחות API עבור ספק אחד | | `/api/providers/import` | POST | ייבוא רשימת ספקים הטרוגנית מקובץ CSV/JSON שנותח (#6836); תוצאות כשל חלקי לכל שורה | | `/api/provider-nodes*` | שונות | ניהול צומתי ספקים | | `/api/provider-models` | GET/POST/PUT/PATCH/DELETE | מודלים מותאמים אישית ודריסות לפי מודל (הוספה, עדכון, הסתרה/הצגה, מחיקה) | | `/api/provider-models/validate-and-add` | POST | אימות חיבור מחמיר הדורש אימות ניהול ומופעל בהסכמה, ורישום אטומי של מודל מותאם אישית; ראו [אימות מודלים](../guides/MODEL-VALIDATION.md) | עבור מודלים שסונכרנו/יובאו, `PUT /api/provider-models` מקבל את `provider`, את `modelId` ואת `maxOutputTokenOverride`: מספר שלם חיובי מגדיר את מגבלת אסימוני הפלט הידנית, ו-`null` מנקה אותה כדי לשחזר את ברירת המחדל. `GET /api/provider-models?provider=` מחזיר ערכים אלה בתוך `modelOutputOverrides`, כולל מודלים ללא רשומת מודל מותאם אישית. הדריסה משתמשת ביכולת זמן הריצה `max_output_tokens` ונשמרת גם לאחר סנכרון מחדש של מודל. דף הספק התואם ל-OpenAI מציע את אותם פקדי עריכה/ניקוי ומסמן מודלים בעלי תמיכה מפורשת בראייה. צומתי Chat Completions מותאמים אישית מתאימים ביטולי הסקה מפורשים למערכת הקצה במעלה הזרם. בדיקת חיבור מוצלחת בוחרת אוטומטית פקדי תבנית צ'אט עבור כל מזהה מודל מדויק שהרשומה שלו ב-`/models` מוכיחה ערך `owned_by` מוכר: `vllm`, `sglang` או `llamacpp`. מעטפות שקופות התואמות ל-OpenAI עשויות לשמר את רשומת המודל המקורית בתוך אובייקט `openai` מקונן; הזיהוי עוקב אחר עד שלוש מעטפות כאלה. מודלים עם בעלות חסרה, לא מוכרת או סותרת שומרים על התנהגות OpenAI רגילה. הזיהוי משתמש מחדש בבקשת הקטלוג הקיימת, אינו מייצר אסימוני השלמה, ותוקפו מבוטל כאשר נקודת הקצה של החיבור משתנה. כדי לקבע את ההתנהגות עבור מערכת קצה שאינה חושפת מטא-נתונים אלה, השתמשו ב-API הקיים לעדכון חלקי של ספק: ```json { "providerSpecificData": { "reasoningControl": "chat-template" } } ``` שלחו גוף זה באמצעות `PUT /api/providers/`. בחיבור זה, מאמץ הסקה מפורש של `none` נשלח בתור `chat_template_kwargs.thinking=false` וגם `chat_template_kwargs.enable_thinking=false`. ערכי תבנית מקוריים מפורשים נשארים בעלי הסמכות אלא אם כלל הסקה בצד השרת כופה רמת מאמץ. ההגדרה חלה רק כאשר חיבור מותאם אישית התואם ל-OpenAI שולח גוף של Chat Completions; בקשות Responses וספקים רגילים שומרים על מבנה הבקשה המקורי שלהם. הגדירו את `reasoningControl` ל-`openai` כדי לאלץ העברה רגילה של `reasoning_effort` אל OpenAI, או השמיטו אותו/הגדירו אותו ל-`null` כדי להשתמש בזיהוי אוטומטי. בקשות המסווג של Claude Code במצב אוטומטי מגדירות כברירת מחדל את ההסקה המקורית כמושבתת כאשר הן אינן מכילות פקדי הסקה מפורשים. הזיהוי משתמש בסמן המערכת של המסווג בבקשות בפורמט Claude, ולא בשמות מודלים או במגבלות השלמה. פקדים מפורשים בגוף הבקשה, כותרות מאמץ/הסקה נתמכות, כללי ניתוב ומאמץ מודל שכבר הוכרע שומרים על העדיפות הקיימת שלהם. שני שלבי המסווג שומרים על ההנחיות, מגבלות ההשלמה, רצפי העצירה והכרעות ההרשאה האמיתיות שלהם ממערכת הקצה במעלה הזרם; השלב השני עדיין יכול להפיק את ההסקה הגלויה שהתבקשה כטקסט רגיל. ### תהליכי OAuth | נקודת קצה | שיטה | תיאור | | -------------------------------- | ----- | ----------------- | | `/api/oauth/[provider]/[action]` | שונות | OAuth ייעודי לספק | ### ניתוב ותצורה | נקודת קצה | שיטה | תיאור | | --------------------- | -------- | ----------------------- | | `/api/models/alias` | GET/POST | כינויים למודלים | | `/api/models/catalog` | GET | כל המודלים לפי ספק וסוג | | `/api/combos*` | שונות | ניהול שילובים | | `/api/keys*` | שונות | ניהול מפתחות API | | `/api/pricing` | GET | תמחור מודלים | ### שימוש וניתוח נתונים | נקודת קצה | שיטה | תיאור | | -------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `/api/usage/history` | GET | היסטוריית שימוש | | `/api/usage/logs` | GET | יומני שימוש | | `/api/usage/request-logs` | GET | יומנים ברמת הבקשה | | `/api/usage/[connectionId]` | GET | שימוש לפי חיבור | | `/api/usage/token-limits` | GET/POST/DELETE | תקציבי מגבלת טוקנים לפי מפתח API | | `/api/usage/model-latency-stats` | GET | נתונים מצטברים מתגלגלים של השהיה לפי ספק/מודל (ממוצע/p50/p95/p99, שיעור הצלחה); מסננים: `windowHours`/`minSamples`/`maxRows`/`provider`/`model` (#6873) | | `/api/usage/cache-health` | GET | סיכום תקינות מטמון הפרומפטים על פני `call_logs` — יחס כתיבה/קריאה, התפלגות גודל כתיבה לפי p50/p90/p99, ריכוז כתיבות כבדות, חלוקה לפי מודל, והכרעה מסוג `healthy`/`degraded`/`thrash`/`no-data`; פרמטרי שאילתה: `range` (`1h`\|`24h`\|`7d`\|`30d`, ברירת המחדל היא `24h`) ו-`model` אופציונלי (#8827) | ### הרשאות מפתח API `PATCH /api/keys/{id}` מעדכן את ההרשאות של מפתח קיים. כמו כל נתיב `/api/keys*`, הוא דורש הרשאת ניהול (ראו [אימות ניהול](../guides/MANAGEMENT-AUTH.md)), ולא מפתח הסקה. שלחו רק את השדות שברצונכם לשנות; בקשה שאינה כוללת אף אחד מהם נדחית עם `No valid fields to update`. השדות המתקבלים מוגדרים על ידי `updateKeyPermissionsSchema` בקובץ `src/shared/validation/schemas/keys.ts`. | שדה | סוג | הערות | | ------------------------------------------- | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | | `name` | מחרוזת, 1-200 תווים | | | `isActive` | בוליאני | | | `isBanned` | בוליאני | | | `expiresAt` | תאריך ושעה בתקן ISO 8601 או `null` | `null` מנקה את מועד התפוגה | | `modelAccessMode` | `all` \| `restricted` | `allowedModels` חייב להיות ריק כאשר המצב הוא `all` | | `allowedModels`, `blockedModels` | מערך של מחרוזות, עד 1000 | | | `allowedCombos` | מערך של מחרוזות, עד 500 | קובע לאילו שילובים המפתח רשאי לקרוא; מודלים ישירים נשלטים על ידי `modelAccessMode` / `allowedModels` | | `connectionAccessMode` | `all` \| `restricted` | `allowedConnections` חייב להיות לא ריק כאשר המצב הוא `restricted`, וריק כאשר המצב הוא `all` | | `allowedConnections` | מערך של UUIDs, עד 100 | | | `allowAutoCombos` | בוליאני | `false` דוחה בקשות למודלים מסוג `auto/*` עם מפתח זה; מפתחות שמעולם לא הגדירו אותו מורשים | | `catalogScope` | `all` \| `combos` \| `models` | מה `GET /v1/models` מציג עבור מפתח זה (שילובים בלבד, מודלים בלבד או שניהם); הוא אינו משנה למה המפתח רשאי לקרוא | | `forcedModel` | מחרוזת באורך של עד 300 תווים, או `null` | מנתב בקשות צ'אט למודל/שילוב זה, בעדיפות על פני `X-Route-Model` ו-`body.model`; מגבלות המפתח עדיין חלות | | `noLog`, `autoResolve` | בוליאני | | | `throttleDelayMs` | מספר שלם, 0-300000 | | | `maxSessions` | מספר שלם, 0-10000 | | | `rateLimits` | מערך של `{ limit, window }` (מספרים שלמים חיוביים, עד 50) או `null` | `null` מנקה את המגבלות | | `accessSchedule` | אובייקט תזמון או `null` | `null` מנקה את לוח הזמנים | | `scopes` | מערך של מחרוזות, עד 32 | | | `allowedEndpoints` | מערך של מחרוזות, עד 20 | | | `streamDefaultMode` | `legacy` \| `json` | | | `cacheDefaultMode` | `legacy` \| `bypass` | ראו [עקיפת מטמון לפי מפתח](#per-key-cache-bypass) | | `compressionEnabled` | בוליאני | | | `codexServiceMode` | אחד ממצבי השירות של Codex | | | `disableNonPublicModels` | boolean | | | `allowUsageCommand` | boolean | | | `usageLimitEnabled` | boolean | | | `dailyUsageLimitUsd`, `weeklyUsageLimitUsd` | number >= 0 או `null` | | | `chaosModeEnabled` | boolean | | ```bash curl -X PATCH "$OMNIROUTE_URL/api/keys/$KEY_ID" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "allowAutoCombos": false, "catalogScope": "combos" }' ``` ### הגדרות | נקודת קצה | שיטה | תיאור | | ------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `/api/settings` | GET/PUT/PATCH | הגדרות כלליות. מפתחות מדיניות אבטחה (`requireLogin`, `newPassword`, `oidc*`, `corsOrigins`, `bruteForceProtection`) דורשים `currentPassword` ופרטי אימות של מפעיל — מפתחות API ואסימוני `oma_` מקבלים `403`; כל שינוי דורש את תחום אסימון הגישה `admin` | | `/api/settings/proxy` | GET/PUT | תצורת Proxy לרשת | | `/api/settings/proxy/test` | POST | בדיקת חיבור ה-Proxy | | `/api/settings/ip-filter` | GET/PUT | רשימת כתובות IP מורשות/חסומות | | `/api/settings/thinking-budget` | GET/PUT | מצב שכתוב **בקשות** חשיבה/הסקה (העברה ללא שינוי / הסרה אוטומטית / מותאם אישית / אדפטיבי). בלתי תלוי בדחיסה. ראו [THINKING_BUDGET.md](../guides/THINKING_BUDGET.md). | | `/api/settings/system-prompt` | GET/PUT | הנחיית מערכת גלובלית | | `/api/settings/compression` | GET/PUT | תצורת דחיסה גלובלית | | `/api/settings/purge-request-history` | POST | ניקוי שורות יומן הבקשות וארטיפקטים מקומיים של יומן הקריאות | ### הקשר ודחיסה | נקודת קצה | שיטה | תיאור | | -------------------------------------- | -------------- | ---------------------------------------------------------------------------- | | `/api/compression/preview` | POST | תצוגה מקדימה של דחיסה במצבי off/lite/standard/aggressive/ultra/RTK/stacked | | `/api/compression/language-packs` | GET | הצגת חבילות השפה הזמינות של Caveman | | `/api/compression/rules` | GET | הצגת מטא-נתונים של כללי Caveman | | `/api/context/caveman/config` | GET/PUT | כינוי להגדרות ספציפיות ל-Caveman | | `/api/context/rtk/config` | GET/PUT | הגדרות ספציפיות ל-RTK, כולל מסננים מותאמים אישית ושמירת פלט גולמי שעבר השחרה | | `/api/context/rtk/filters` | GET | קטלוג המסננים של RTK ואבחון מסננים מותאמים אישית | | `/api/context/rtk/test` | POST | הרצת תצוגה מקדימה/בדיקה של RTK מול מטען טקסט | | `/api/context/rtk/raw-output/[id]` | GET | קריאת פלט גולמי שמור שעבר השחרה לפי מזהה מצביע | | `/api/context/combos` | GET/POST | הצגה/יצירה של שילובי דחיסה | | `/api/context/combos/[id]` | GET/PUT/DELETE | פרטים/עדכון/מחיקה של שילוב דחיסה | | `/api/context/combos/[id]/assignments` | GET/PUT | הקצאת שילובי דחיסה לשילובי ניתוב | | `/api/context/analytics` | GET | כינוי לניתוח נתוני דחיסה | ### ניטור | נקודת קצה | שיטה | תיאור | | ------------------------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `/api/sessions` | GET | מעקב אחר הפעלות פעילות | | `/api/rate-limits` | GET | מגבלות קצב לפי חשבון | | `/api/monitoring/health` | GET | בדיקת תקינות + סיכום ספקים (`catalogCount`, `configuredCount`, `activeCount`, `monitoredCount`). תצוגת הניהול כוללת `credentialHealth`: ערכים סקלריים ממטמון הבדיקות, `failedConnections` כאשר `failed>0`, וכן `staleDbNonOkCount` (`test_status` דביק של SQLite, לא מד המחוון). ראו [MONITORING_GUIDE.md](../ops/MONITORING_GUIDE.md#credentialhealth-probe-cache-vs-sqlite-test_status). | | `/api/cache/stats` | GET/DELETE | סטטיסטיקות מטמון / ניקוי | | `/api/modality-bridge/stats` | GET | הנתונים שבזיכרון `attempts`, הצלחות/`bridged`, כשלונות, פגיעות מטמון, `totalLatencyMs`, `latencySamples`,‏ `averageLatencyMs` המבוסס על מספר הדגימות, וזמן השימוש האחרון (מתאפס בהפעלה מחדש; אימות ניהול) | | `/api/modality-bridge/video/runtime` | GET | בדיקת לולאה חוזרת מהימנה ומחמירה לפני אימות/בדיקת ניהול; זמינות וגרסאות מסוננות של FFmpeg/ffprobe ‏(no-store) | | `/api/modality-bridge/video/extract` | POST | מתווך בתים פנימי ומאומת דרך לולאה חוזרת מהימנה; קלט של 50 MiB, תור מוגבל/פלט של 32 MiB,‏ `503` לקיבולת, `499` לניתוק, `504` לחריגה ממועד היעד; אינו API ציבורי להעלאות | ### גיבוי וייצוא/ייבוא | נקודת קצה | שיטה | תיאור | | --------------------------- | ------ | ---------------------------------------------------------------------- | | `/api/db-backups` | GET | הצגת הגיבויים הזמינים | | `/api/db-backups` | PUT | יצירת גיבוי ידני | | `/api/db-backups` | POST | שחזור מגיבוי מסוים | | `/api/db-backups` | PATCH | שמירת הגדרות שימור הגיבויים (למפעילים בלבד) | | `/api/db-backups` | DELETE | צמצום הגיבויים המאוחסנים בהתאם להגדרות השימור (למפעילים בלבד) | | `/api/db-backups/export` | GET | הורדת מסד הנתונים כקובץ .sqlite | | `/api/db-backups/import` | POST | העלאת קובץ .sqlite להחלפת מסד הנתונים (`?dryRun=true` מבצע אימות בלבד) | | `/api/db-backups/exportAll` | GET | הורדת גיבוי מלא כארכיון .tar.gz | `/api/db-backups/export`, `/api/db-backups/exportAll` ו-`/api/settings/export-json` מוסרים כל פרטי גישה שמורים, ולכן הם דורשים את הפעלת לוח הבקרה או את ה-CLI המקומי (או שההתחברות מושבתת). מפתחות API מכל היקף ואסימוני גישה מסוג `oma_` מקבלים `403`. על פעולות השחזור חלה אותה מגבלה: `POST /api/db-backups/import` (כולל `dryRun=true`),‏ `POST /api/db-backups` (שחזור לפי id) ו-`POST /api/settings/import-json` מחליפים את מסד הנתונים או ההגדרות הפעילים, ולכן פרטי גישה של מכונה מקבלים גם שם `403`; הפקודה `omniroute sync import` שולחת את פרטי הגישה של ה-CLI המקומי. כך גם `DELETE /api/db-backups` (צמצום הגיבויים המאוחסנים) ו-`PATCH /api/db-backups` (הגדרות שימור: הערכים שנשמרו מנחים את הצמצום האוטומטי לאחר כל גיבוי). הצגת הרשימה (`GET`) ויצירת גיבוי ידני (`PUT`) ממשיכות להשתמש באימות ניהול רגיל. ### סנכרון ענן | נקודת קצה | שיטה | תיאור | | ---------------------- | ----- | ----------------- | | `/api/sync/cloud` | שונות | פעולות סנכרון ענן | | `/api/sync/initialize` | POST | אתחול הסנכרון | | `/api/cloud/*` | שונות | ניהול הענן | ### מנהרות | נקודת קצה | שיטה | תיאור | | -------------------------- | ---- | ------------------------------------------------------------------- | | `/api/tunnels/cloudflared` | GET | קריאת מצב ההתקנה/ההפעלה של Cloudflare Quick Tunnel עבור לוח הבקרה | | `/api/tunnels/cloudflared` | POST | הפעלה או השבתה של Cloudflare Quick Tunnel (`action=enable/disable`) | | `/api/tunnels/ngrok` | GET | קריאת מצב ההפעלה של מנהרת ngrok עבור לוח הבקרה | | `/api/tunnels/ngrok` | POST | הפעלה או השבתה של מנהרת ngrok (`action=enable/disable`) | ### כלי CLI | נקודת קצה | שיטה | תיאור | | ---------------------------------- | ---- | ---------------------- | | `/api/cli-tools/claude-settings` | GET | מצב ה-CLI של Claude | | `/api/cli-tools/codex-settings` | GET | מצב ה-CLI של Codex | | `/api/cli-tools/droid-settings` | GET | מצב ה-CLI של Droid | | `/api/cli-tools/openclaw-settings` | GET | מצב ה-CLI של OpenClaw | | `/api/cli-tools/runtime/[toolId]` | GET | סביבת הרצה כללית ל-CLI | תגובות ה-CLI כוללות: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`. ### סוכני ACP | נקודת קצה | שיטה | תיאור | | ----------------- | ------ | --------------------------------------------------------- | | `/api/acp/agents` | GET | הצגת כל הסוכנים שזוהו (מובנים + מותאמים אישית), כולל מצבם | | `/api/acp/agents` | POST | הוספת סוכן מותאם אישית או רענון מטמון הזיהוי | | `/api/acp/agents` | DELETE | הסרת סוכן מותאם אישית לפי פרמטר השאילתה `id` | תגובת GET כוללת את `agents[]` ‏(id, name, binary, version, installed, protocol, isCustom) ואת `summary` ‏(total, installed, notFound, builtIn, custom). ### עמידות ומגבלות קצב | נקודת קצה | שיטה | תיאור | | --------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `/api/resilience` | GET/PATCH | קבלה/עדכון של תור הבקשות, תקופת הצינון של החיבור, מפסק הספק והגדרות ההמתנה | | `/api/resilience/reset` | POST | איפוס מפסקי המעגל של הספקים | | `/api/resilience/model-cooldowns` | GET | הצגת נעילות פעילות לפי (ספק, חיבור, מודל), ממוינות לפי הזמן שנותר | | `/api/resilience/model-cooldowns` | DELETE | ניקוי נעילת מודל — גוף `{provider, model}` או `{all: true}` כדי למחוק הכול | | `/api/rate-limits` | GET/POST | מצב מגבלת הקצב לכל חשבון (GET), או הפעלה/השבתה של הגנת מגבלת הקצב עבור חיבור (POST עם `{connectionId, enabled}`). זהו נתיב הכתיבה הנתמך עבור `rateLimitProtection` (לעולם אינו משתנה דרך `PUT /api/providers/[id]`). הערה: `enabled: false` משבית הגנה מפורשת, אך אינו מחריג חיבור פעיל של מפתח API מרשת הביטחון הגלובלית להפעלה אוטומטית (`autoEnableApiKeyProviders`). | | `/api/rate-limit` | GET | תצורת מגבלת קצב גלובלית (הוצאה משימוש; כינוי עבור `/api/rate-limits`) | > כל ארבעת הנתיבים תחת `/api/resilience/*` דורשים **אימות ניהולי** (`requireManagementAuth`). לפירוט מלא על ההבדלים בין מפסק ספק, תקופת צינון של חיבור ונעילת מודל, ראו [עמידות (מורחב)](#resilience-extended). ### הערכות | נקודת קצה | שיטה | תיאור | | ------------ | -------- | ------------------------------ | | `/api/evals` | GET/POST | הצגת חבילות הערכה / הרצת הערכה | ### מדיניות | נקודת קצה | שיטה | תיאור | | --------------- | --------------- | ------------------- | | `/api/policies` | GET/POST/DELETE | ניהול מדיניות ניתוב | ### תאימות | נקודת קצה | שיטה | תיאור | | --------------------------- | ---- | ------------------------------- | | `/api/compliance/audit-log` | GET | יומן ביקורת תאימות (N האחרונים) | ### v1beta (תואם Gemini) | נקודת קצה | שיטה | תיאור | | -------------------------- | ---- | -------------------------------------- | | `/v1beta/models` | GET | הצגת מודלים בפורמט Gemini | | `/v1beta/models/{...path}` | POST | נקודת הקצה `generateContent` של Gemini | נקודות קצה אלה משקפות את פורמט ה-API של Gemini עבור לקוחות המצפים לתאימות מקורית עם ה-SDK של Gemini. ### ממשקי API פנימיים / של המערכת | נקודת קצה | שיטה | תיאור | | ------------------------ | ---- | ------------------------------------------------ | | `/api/init` | GET | בדיקת אתחול היישום (בשימוש בהפעלה הראשונה) | | `/api/tags` | GET | תגי מודלים התואמים ל-Ollama (עבור לקוחות Ollama) | | `/api/restart` | POST | הפעלת אתחול מבוקר של השרת | | `/api/shutdown` | POST | הפעלת כיבוי מבוקר של השרת | | `/api/system/env/repair` | POST | תיקון משתני הסביבה של ספק OAuth | | `/api/system/version` | GET | הגרסה הנוכחית/האחרונה, מצב העדכון וערוץ ההפצה | | `/api/system/version` | POST | התחלת עדכון מודע-פריסה לגרסה האחרונה | > **הערה:** נקודות קצה אלה משמשות את המערכת באופן פנימי או לצורך תאימות עם לקוחות Ollama. בדרך כלל משתמשי קצה אינם קוראים להן. ### תיקון סביבת OAuth _(v3.6.1+)_ ```bash POST /api/system/env/repair Content-Type: application/json { "provider": "claude-code" } ``` מתקן משתני סביבת OAuth חסרים או פגומים עבור ספק מסוים. מחזיר: ```json { "success": true, "repaired": ["CLAUDE_CODE_OAUTH_CLIENT_ID", "CLAUDE_CODE_OAUTH_CLIENT_SECRET"], "backupPath": "/home/user/.omniroute/backups/env-repair-2026-04-11.bak" } ``` ### גרסה וערוץ הפצה ```bash GET /api/system/version ``` נתיב ניהול המוגבל ל-loopback בלבד (אימות מנהל מערכת). מחזיר את הגרסה הפועלת, את הגרסה האחרונה שפורסמה ואת מצב העדכון האוטומטי. `releaseChannel` ו-`channels` הם שדות שנוספו במסלול 3.8.54; המשמעות של `channel` נשארת ללא שינוי — מצב הפריסה שבו משתמש מעדכן לוח הבקרה (`npm`, `source` או `docker-compose`). ```json { "current": "3.8.52", "latest": "3.8.52", "updateAvailable": false, "channel": "npm", "autoUpdateSupported": true, "autoUpdateError": null, "news": null, "releaseChannel": "latest", "channels": { "latest": "3.8.52", "next": "3.8.53-rc.1" } } ``` - `releaseChannel` — ערוץ ה-npm של גרסת ה-build הפועלת: `nightly` עבור גרסאות `-nightly.*`, `next` עבור גרסאות קדם-הפצה אחרות (`-rc.*`, `-beta.*`, `-alpha.*`),‏ `lts` עבור גרסה יציבה של גרסה ראשית ישנה יותר מזו שב-`channels.latest`, ובכל מקרה אחר `latest`. אותם כללים כמו ב-`scripts/release/dist-tag.mjs`, שבוחר את ה-dist-tag של npm בזמן הפרסום. - `channels` — הגרסה העדכנית שפורסמה בכל dist-tag, מתוך `npm view omniroute dist-tags` (עם גיבוי באמצעות HTTP של הרישום), שנשמרת במטמון עם אותו TTL של 10 דקות כמו `latest`. הערך `latest` קיים תמיד (עם חזרה לערך שבשדה `latest`, ולאחר מכן ל-`"unavailable"`); הערכים `next`,‏ `nightly` ו-`lts` מופיעים רק כאשר ה-dist-tag המתאים קיים. בקשה עם `Cache-Control: no-cache` מרעננת את שתי הבדיקות. מודל הערוצים (`latest` = v3 עד ההשקה הכללית של 4.0,‏ `next` = rc,‏ `nightly` = גרסאות build של `develop`, ‏`lts` = תיקוני v3 לאחר ההשקה הכללית של 4.0) מתואר ב-`docs/ops/RELEASE_STRATEGY.md`. --- ## תמלול אודיו ```bash POST /v1/audio/transcriptions Authorization: Bearer your-api-key Content-Type: multipart/form-data ``` תמללו קובצי אודיו באמצעות כל ספק STT שהוגדר. מקטע הנתיב הראשון בוחר את הספק המקורי (`openai/…`, `deepgram/…`). שערים שמייצאים מחדש מודל של ספק אחר משתמשים במזהה מוסמך (`openrouter/deepgram/nova-3`). **בקשה:** ```bash curl -X POST http://localhost:20128/v1/audio/transcriptions \ -H "Authorization: Bearer your-api-key" \ -F "file=@recording.mp3" \ -F "model=openai/whisper-1" ``` **תגובה:** ```json { "text": "Hello, this is the transcribed audio content.", "task": "transcribe", "language": "en", "duration": 12.5 } ``` **דוגמאות למזהי מודלים:** `openai/whisper-1` (דורש מפתח OpenAI), `openrouter/deepgram/nova-3` (דורש מפתח OpenRouter), `deepgram/nova-3` (דורש מפתח מקורי של Deepgram). בקשה ישירה אל `deepgram/nova-3` **אינה** משתמשת ב-OpenRouter. **פורמטים נתמכים:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`. --- ## תאימות ל-Ollama עבור לקוחות המשתמשים בפורמט ה-API של Ollama: ```bash # נקודת קצה לצ'אט (בפורמט Ollama) POST /v1/api/chat # הצגת רשימת מודלים (בפורמט Ollama) GET /api/tags ``` הבקשות מתורגמות אוטומטית בין הפורמטים של Ollama לבין הפורמטים הפנימיים. ## כינויים עם אסימון עבור VS Code / כינויים ללא כותרת השתמשו בכינויים אלה כאשר אינטגרציה אינה יכולה להוסיף כותרת `Authorization` וזקוקה למפתח ה-API כשהוא מוטמע בכתובת ה-URL הבסיסית. ```bash # כינוי קטלוג בסגנון OpenAI GET /api/v1/vscode/{token}/ GET /api/v1/vscode/{token}/models # כינויי צ'אט בסגנון OpenAI POST /api/v1/vscode/{token}/chat/completions POST /api/v1/vscode/{token}/responses # כינויים בסגנון Ollama POST /api/v1/vscode/{token}/api/chat GET /api/v1/vscode/{token}/api/tags ``` דוגמה: ```bash curl https://your-host.example/api/v1/vscode/YOUR_API_KEY/models curl -X POST https://your-host.example/api/v1/vscode/YOUR_API_KEY/chat/completions \ -H "Content-Type: application/json" \ -d '{"model":"auto","messages":[{"role":"user","content":"hello"}]}' ``` הערות: - הכינויים הכוללים אסימון משתמשים מחדש באותם מטפלים כמו `/v1/*` ו-`/api/tags`; מבני התגובות נשארים זהים. - העדיפו את `Authorization: Bearer ...` בכל פעם שהלקוח תומך בכותרות מותאמות אישית. - אסימונים המבוססים על כתובות URL עשויים להופיע ביומני רישום של פרוקסי הפוך, בהיסטוריית הדפדפן ובטלמטריה מחוץ ל-OmniRoute. התייחסו אליהם כאפשרות תאימות, ולא כמצב האימות המוגדר כברירת מחדל. --- ## טלמטריה ```bash # קבלת סיכום טלמטריית השהיה (p50/p95/p99 לכל ספק) GET /api/telemetry/summary ``` **תגובה:** ```json { "providers": { "claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 }, "github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 } } } ``` --- ## תקציב ```bash # קבלת מצב התקציב עבור כל מפתחות ה-API GET /api/usage/budget # הגדרה או עדכון של תקציב POST /api/usage/budget Content-Type: application/json { "apiKeyId": "key-123", "dailyLimitUsd": 5.00, "weeklyLimitUsd": 30.00, "monthlyLimitUsd": 100.00, "warningThreshold": 0.8, "resetInterval": "monthly" } ``` > **הערות סכימה** (`setBudgetSchema`): השדה `apiKeyId` הוא שדה חובה; לפחות אחד מבין `dailyLimitUsd`,‏ `weeklyLimitUsd` או `monthlyLimitUsd` חייב להיות גדול מאפס. שדות אופציונליים: `warningThreshold` (0–1),‏ `resetInterval` (`daily` | `weekly` | `monthly`),‏ `resetTime` (`HH:MM`). המבנה הקודם `{keyId, limit, period}` מחזיר `400 Bad Request`. ## מגבלות טוקנים מכסות **טוקנים** לכל מפתח API (בנפרד מהתקציב המבוסס על USD לעיל). האכיפה מתבצעת כחלק מנתיב הבקשה: כאשר השימוש של מפתח בחלון הנוכחי מגיע למגבלה שלו, בקשות נדחות עם `429 Too Many Requests`. ניתן להחיל מגבלות על `model` מסוים, על `provider`, או באופן `global`י על פני המפתח כולו; כאשר כמה מגבלות תואמות לבקשה, המגבלה המחמירה ביותר גוברת. ```bash # הצגת מגבלות הטוקנים של מפתח (כולל השימוש הנוכחי בחלון) GET /api/usage/token-limits?apiKeyId=key-123 # יצירה או עדכון של מגבלת טוקנים POST /api/usage/token-limits Content-Type: application/json { "apiKeyId": "key-123", "scopeType": "model", "scopeValue": "openai/gpt-4o", "tokenLimit": 1000000, "resetInterval": "monthly", "enabled": true } # מחיקת מגבלת טוקנים לפי מזהה DELETE /api/usage/token-limits?id=tl-abc ``` > **הערות לגבי הסכמה** (`setTokenLimitSchema`): השדות `apiKeyId` ו-`scopeType`‏ (`model` | `provider` | `global`) נדרשים. השדה `scopeValue` נדרש, אלא אם `scopeType` הוא `global` (לדוגמה, מזהה מודל עבור תחום `model`, או מזהה ספק עבור תחום `provider`). השדה `tokenLimit` חייב להיות מספר שלם חיובי (עם המרה ממחרוזת). אופציונלי: `id` (יש להשמיט כדי ליצור ולספק כדי לעדכן), `resetInterval`‏ (`daily` | `weekly` | `monthly`, ברירת המחדל היא `monthly`),‏ `resetTime`‏ (`HH:MM`),‏ `enabled` (ברירת המחדל היא `true`). תגובות `GET` מעשירות כל מגבלה בשדות `tokensUsed`,‏ `remaining`,‏ `windowStart`,‏ `periodStartAt` ו-`nextResetAt`. זוהי נקודת קצה מסוג ניהול (האימות נאכף באופן מרכזי על ידי תהליך ההרשאה). ## עיבוד בקשות 1. הלקוח שולח בקשה אל `/v1/*` 2. מטפל הנתיב קורא ל-`handleChat`,‏ `handleEmbedding`,‏ `handleAudioTranscription` או `handleImageGeneration` 3. המודל מזוהה (ספק/מודל ישיר או כינוי/שילוב) 4. פרטי ההזדהות נבחרים ממסד הנתונים המקומי, תוך סינון לפי זמינות החשבון 5. עבור צ'אט: `handleChatCore` בודק את מטמון הסמנטיקה/החתימות ומכריע את הגדרות הדחיסה של השילוב 6. דחיסה יזומה מתבצעת לפני התרגום לספק כאשר היא מופעלת (`lite`,‏ Caveman,‏ RTK או שילוב שכבות) 7. מנגנון הביצוע של הספק שולח את הבקשה לשירות במעלה הזרם 8. התגובה מתורגמת חזרה לפורמט הלקוח (צ'אט), או מוחזרת כפי שהיא (הטמעות/תמונות/שמע) 9. נתוני שימוש, ניתוחי דחיסה ויומני בקשות נרשמים 10. במקרה של שגיאות, מנגנון הגיבוי מופעל בהתאם לכללי השילוב הפניה לארכיטקטורה המלאה: [`ARCHITECTURE.md`](../architecture/ARCHITECTURE.md) --- ## ניהול שילובים ניתן גם למפות שילובי ניתוב ברמה גבוהה יותר (שכבר סוכמו תחת `/api/combos*`) ביחס של 1:1 מתבנית מזהה מודל, וכך לאפשר הפניה שקופה של מזהה מודל בסגנון OpenAI אל שילוב. | שיטה | נתיב | תיאור | | ------ | -------------------------------- | -------------------------------------------------------------------------------- | | GET | `/api/model-combo-mappings` | הצגת כל מיפויי מודל←שילוב | | POST | `/api/model-combo-mappings` | יצירת מיפוי — גוף הבקשה: `{pattern, comboId, priority?, enabled?, description?}` | | GET | `/api/model-combo-mappings/[id]` | אחזור מיפוי יחיד | | PUT | `/api/model-combo-mappings/[id]` | עדכון שדות של מיפוי קיים | | DELETE | `/api/model-combo-mappings/[id]` | הסרת מיפוי | **אימות:** הפעלת ניהול/מפתח API (`requireManagementAuth`). --- ## וובהוקים מינויים לוובהוקים יוצאים עבור אירועי OmniRoute (השלמת בקשה, מיצוי מכסה, רוטציית מפתחות וכו'). | שיטה | נתיב | תיאור | | ------ | ------------------------- | ------------------------------------------------------------------------ | | GET | `/api/webhooks` | הצגת רשימת הוובהוקים (הסודות מוסווים כ-`...`) | | POST | `/api/webhooks` | יצירת וובהוק — גוף הבקשה: `{url, events?: ["*"], secret?, description?}` | | GET | `/api/webhooks/[id]` | אחזור וובהוק | | PUT | `/api/webhooks/[id]` | עדכון כתובת URL, אירועים, סוד או תיאור | | DELETE | `/api/webhooks/[id]` | הסרת וובהוק | | POST | `/api/webhooks/[id]/test` | שליחת מטען בדיקה לכתובת ה-URL של הוובהוק והחזרת סטטוס המסירה | **אימות:** הפעלת ניהול/מפתח API (`requireManagementAuth`). --- ## מפתחות רשומים (ניהול אוטומטי) משמשים את תת-המערכת לניהול אוטומטי של מפתחות לצורך הנפקה ורוטציה של מפתחות API מול ספק/חשבון מגבה, עם מכסות יומיות/שעתיות. | שיטה | נתיב | תיאור | | ------ | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/v1/registered-keys` | הצגת רשימת המפתחות הרשומים (קידומת מוסווית בלבד) | | POST | `/api/v1/registered-keys` | הנפקת מפתח רשום חדש — גוף הבקשה: `{name, provider?, accountId?, idempotencyKey?, expiresAt?, dailyBudget?, hourlyBudget?}`. מחזיר את המפתח הגולמי **פעם אחת**. מחזיר `429` במקרה של סירוב עקב מכסה. | | GET | `/api/v1/registered-keys/[id]` | אחזור המטא-נתונים של מפתח רשום (ללא חומר המפתח הגולמי) | | DELETE | `/api/v1/registered-keys/[id]` | ביטול מפתח רשום | | POST | `/api/v1/registered-keys/[id]/revoke` | נקודת קצה מפורשת לביטול (בעלת אותה השפעה כמו DELETE) | **אימות:** הפעלת ניהול/מפתח API (`requireManagementAuth`) — אותו מנגנון הגנה כמו עבור `/api/keys`: הפעלת לוח בקרה, אסימון CLI מקומי או מפתח API עם תחום הרשאה `manage`/`admin`; מפתחות API להסקה בלבד מקבלים `403`. ראו גם `/v1/quotas/check` ו-`/v1/issues/report`. --- ## פרוטוקול סוכנים משימות סוכן בענן (Claude Code, Codex Cloud, OpenHands וכו׳) המבוצעות מרחוק עבור משתמשי OmniRoute. | שיטה | נתיב | תיאור | | ------ | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/v1/agents/tasks` | הצגת רשימת משימות — הפרמטרים `?provider=`, `?status=`, `?limit=` הם אופציונליים (1–500, ברירת מחדל 50) | | POST | `/api/v1/agents/tasks` | יצירת משימה — גוף הבקשה מאומת באמצעות `CreateCloudAgentTaskSchema` (`providerId`, `prompt`, `source`, `options?`). מחזיר `201` עם מעטפת המשימה | | DELETE | `/api/v1/agents/tasks?id=...` | מחיקת משימה | | GET | `/api/v1/agents/tasks/[id]` | קריאת משימה — מרענן באופן סינכרוני את הסטטוס מסוכן הענן במעלה הזרם כאשר מוגדר `external_id` | | POST | `/api/v1/agents/tasks/[id]` | פעולה מובחנת: `{action: "approve"}`, `{action: "message", message}`, או `{action: "cancel"}` | | DELETE | `/api/v1/agents/tasks/[id]` | מחיקת משימה מסוימת לפי מזהה | > **אימות:** נדרש אימות ניהולי בכל שיטה (`requireCloudAgentManagementAuth`). לפני v3.8.0 נקודות קצה אלה לא דרשו אימות — ראו commit `588a0333` לפרטים על השינוי השובר. ```bash # יצירת משימת ענן של Claude Code curl -X POST http://localhost:20128/api/v1/agents/tasks \ -H "Authorization: Bearer your-management-key" \ -H "Content-Type: application/json" \ -d '{"providerId":"claude-code-cloud","prompt":"Fix the failing test","source":{"repo":"...","branch":"..."}}' ``` --- ## שרתי Proxy ניהוליים שרתי Proxy יוצאים מסוג HTTP(S)/SOCKS שניתן להקצות לספקים, לחשבונות או באופן גלובלי. | שיטה | נתיב | תיאור | | ------ | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | GET | `/api/v1/management/proxies` | הצגת רשימת שרתי Proxy (עם `?id=` מוחזר שרת אחד; עם `?id=&where_used=1` מוחזר גרף ההקצאות) | | POST | `/api/v1/management/proxies` | יצירת שרת Proxy — גוף הבקשה מאומת באמצעות `createProxyRegistrySchema` | | PATCH | `/api/v1/management/proxies` | עדכון שרת Proxy — גוף הבקשה מאומת באמצעות `updateProxyRegistrySchema` (נדרש `id`) | | DELETE | `/api/v1/management/proxies?id=...&force=1` | מחיקת שרת Proxy (השתמשו ב-`force=1` כדי לנתק הקצאות) | | GET | `/api/v1/management/proxies/assignments` | הצגת רשימת הקצאות — ניתן לסנן לפי `proxy_id`, `scope`, `scope_id`; העבירו `resolve_connection_id=` כדי לזהות את שרת ה-Proxy הפעיל עבור חיבור | | PUT | `/api/v1/management/proxies/assignments` | הקצאה — גוף הבקשה מאומת באמצעות `proxyAssignmentSchema` (`{scope, scopeId?, proxyId?}`). מנקה את מטמון המשגר | | PUT | `/api/v1/management/proxies/bulk-assign` | הקצאה מרוכזת — גוף הבקשה מאומת באמצעות `bulkProxyAssignmentSchema` (`{scope, scopeIds[], proxyId?}`) | | GET | `/api/v1/management/proxies/health?hours=24` | תקינות מצטברת של שרתי Proxy (מספרי הצלחות/כישלונות, זמן השהיה) לאורך חלון זמן | **אימות:** נדרשים הפעלת ניהול/מפתח API בכל נתיב (`requireManagementAuth`). > הנתיבים `POST /api/v1/management/proxies/[id]/assignments` ו-`POST /api/v1/management/proxies/[id]/health` שבתיאור המשימה ניתנים דרך הנתיבים השטוחים `/assignments` ו-`/health` המוצגים לעיל — אין בבסיס הקוד נתיבי משנה לפי מזהה. --- ## עמידות (מורחב) OmniRoute חושף שלושה מנגנונים בלתי תלויים לטיפול בכשלים זמניים; נקודות הקצה לניהול שלהלן מאפשרות למפעילים לקרוא ולעקוף את הגדרותיהם: | תחום | אחסון מצב | קריאה | איפוס / ניקוי | | ------------ | ----------------------------------- | ----------------------------------------- | ---------------------------------------------------- | | מפסק ספק | `domain_circuit_breakers` + בזיכרון | `/api/monitoring/health` | `POST /api/resilience/reset` | | השהיית חיבור | `rateLimitedUntil` בחיבורי ספקים | `/api/rate-limits`, `/api/providers/[id]` | (מופעל מחדש באופן עצל; ניתן לניקוי באמצעות PUT לספק) | | נעילת מודל | מרשם זמינות מודלים בזיכרון | `GET /api/resilience/model-cooldowns` | `DELETE /api/resilience/model-cooldowns` | `PATCH /api/resilience` מקבל עקיפות למפסקי ספקים תחת `providerBreaker.oauth` ו-`providerBreaker.apikey`. כל פרופיל תומך ב-`degradationThreshold`, ב-`failureThreshold` וב-`resetTimeoutMs`; אותם שדות זמינים גם בלוח הבקרה ← הגדרות ← עמידות. ```bash # ניקוי נעילה של מודל יחיד curl -X DELETE http://localhost:20128/api/resilience/model-cooldowns \ -H "Cookie: auth_token=..." \ -H "Content-Type: application/json" \ -d '{"provider":"openai","model":"gpt-4o-mini"}' # מחיקת כל הנעילות curl -X DELETE http://localhost:20128/api/resilience/model-cooldowns \ -H "Cookie: auth_token=..." \ -d '{"all":true}' ``` לעיון מלא במושגים ובערכי ברירת המחדל של המפסקים: ראו [`CLAUDE.md`](../../CLAUDE.md) ← "מצב זמן הריצה של העמידות" וכן [`docs/architecture/RESILIENCE_GUIDE.md`](../architecture/RESILIENCE_GUIDE.md). ### תור הגבלת קצב ורשת ביטחון להפעלה אוטומטית - **נתיב הכתיבה הנתמך**: `POST /api/rate-limits` עם גוף `{"connectionId": "", "enabled": true|false}` הוא נקודת הקצה הנתמכת לניהול הפעלה או השבתה של הגנת הגבלת קצב עבור חיבור. `PUT /api/providers/[id]` אינו משנה או הופך בכוונה את `rateLimitProtection` (#11278). - **המשמעות של `enabled: false`**: הגדרת `enabled: false` מסירה את ההגנה המפורשת מהחיבור, אך **אינה** מוציאה חיבור פעיל המשתמש במפתח API מרשת הביטחון הגלובלית להפעלה אוטומטית (`autoEnableApiKeyProviders = true`). בתוך `reconcileEnabledConnections` ‏(`open-sse/services/rateLimitManager.ts`), הערכים `false` ו-`undefined` שקולים; חיבורים פעילים המשתמשים במפתח API וללא הגנה מפורשת נותרים מוגנים במסגרת רשת הביטחון להפעלה אוטומטית. - **השבתה גלובלית**: כדי להפעיל חיבורים המשתמשים במפתח API ללא תורי הגבלת קצב, השביתו את רשת הביטחון באופן גלובלי באמצעות `RATE_LIMIT_AUTO_ENABLE=false` (משתנה סביבה) או `resilienceSettings.requestQueue.autoEnableApiKeyProviders = false` (הגדרות ← עמידות / `PATCH /api/resilience`). --- ## מיומנויות מסגרת מיומנויות להרחבת OmniRoute באמצעות מטפלים מותאמים אישית הניתנים להפעלה, לצד שילובים עם זירות מסחר. | שיטה | נתיב | תיאור | | ------ | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/skills` | הצגת המיומנויות המותקנות — ניתן לסינון לפי `?q=`, ‏`?mode=on\|off\|auto`, ‏`?source=skillsmp\|skillssh\|local`, עם חלוקה לעמודים | | GET | `/api/skills/[id]` | אחזור מיומנות אחת | | PUT | `/api/skills/[id]` | עדכון מיומנות (שם, תיאור, מצב, סכמה, מטפל, תגיות) | | DELETE | `/api/skills/[id]` | הסרת התקנה של מיומנות | | POST | `/api/skills/install` | התקנת מיומנות ממניפסט גולמי — גוף: `{name, version, description, schema:{input, output}, handlerCode, apiKeyId?}` | | GET | `/api/skills/executions` | הצגת הפעלות מיומנות אחרונות (יומן ביקורת הכולל קלטים/פלטים/משך זמן) | | GET | `/api/skills/marketplace?q=...` | חיפוש/רשימת פריטים פופולריים מזירת המסחר SkillsMP (דורש את ההגדרה `skillsmpApiKey`) | | POST | `/api/skills/marketplace/install` | התקנת מיומנות לפי מזהה מ-SkillsMP | | GET | `/api/skills/skillssh?q=&limit=` | חיפוש במרשם skills.sh | | POST | `/api/skills/skillssh/install` | התקנת מיומנות לפי מזהה מ-skills.sh | **אימות:** סשן ניהול/מפתח API. נתיבי החיפוש בזירת המסחר מקבלים אימות ניהול או מפתח API מסוג Bearer (`isAuthenticated`). --- ## זיכרון מאגר מתמשך של זיכרון שיחתי/עובדתי, המוגדר לפי מפתח API / הפעלה. | שיטה | נתיב | תיאור | | ------ | -------------------- | ----------------------------------------------------------------------------------------------------------------- | | GET | `/api/memory` | הצגת זיכרונות — `?apiKeyId=`, `?type=`, `?sessionId=`, `?q=`, עם דפדוף באמצעות `offset/limit` או `page/limit` | | POST | `/api/memory` | יצירת זיכרון — גוף הבקשה מאומת באמצעות Zod: `{content, key, type?, sessionId?, apiKeyId?, metadata?, expiresAt?}` | | GET | `/api/memory/[id]` | אחזור זיכרון יחיד | | DELETE | `/api/memory/[id]` | מחיקת זיכרון | | GET | `/api/memory/health` | תקינות תת־מערכת הזיכרון (קישוריות למסד הנתונים, מנגנון הטמעות, מצב האינדקס הווקטורי) | **אימות:** הפעלת ניהול/מפתח API (`requireManagementAuth`). ערכי המנייה של `type`: `FACTUAL`, `EPISODIC`, `SEMANTIC`, `PROCEDURAL` (ראו `MemoryType` בקובץ `src/lib/memory/types.ts`). --- ## שרת MCP OmniRoute כולל שרת Model Context Protocol מובנה עם 3 תעבורות (stdio, SSE, streamable-http) וכלים בעלי טווחי הרשאה מוגדרים. נקודות הקצה של לוח הבקרה שלהלן קוראות נתוני מצב/ביקורת ומשמשות כמתווך עבור תעבורות ה-HTTP. | שיטה | נתיב | תיאור | | ------ | ---------------------- | ------------------------------------------------------------------------------------------------ | -------------------- | | GET | `/api/mcp/status` | אות חיים, תעבורה, מצב מקוון, קריאה אחרונה, כלים מובילים, שיעור הצלחה ב-24 השעות האחרונות | | GET | `/api/mcp/tools` | רשימת כלי MCP עם `name`, `description`, `scopes`, `phase`, `auditLevel`, `sourceEndpoints` | | GET | `/api/mcp/sse` | פתיחת זרם SSE עבור תעבורת SSE (מחזיר `503` אם MCP מושבת או אם קיימת אי־התאמה בתעבורה) | | POST | `/api/mcp/sse` | שליחת מסגרת JSON-RPC בתעבורת SSE | | GET | `/api/mcp/stream` | פתיחת צד ה-SSE של תעבורת Streamable HTTP (הודעות ביוזמת השרת) | | POST | `/api/mcp/stream` | שליחת מסגרת JSON-RPC בתעבורת Streamable HTTP | | DELETE | `/api/mcp/stream` | סיום הפעלת Streamable HTTP | | GET | `/api/mcp/audit` | שאילתת יומן הביקורת — `?limit=`, `?offset=`, `?tool=`, `?success=true | false`, `?apiKeyId=` | | GET | `/api/mcp/audit/stats` | נתוני ביקורת מצטברים (סכומים כוללים, שיעור הצלחה, משך ממוצע, כלים מובילים) | **אימות:** תעבורות `sse`/`stream` מכבדות את ממשק האימות הייעודי של MCP (מפתח API מסוג Bearer עם טווח `mcp`); הנתיבים `status`/`tools`/`audit*` ניתנים לקריאה מלוח הבקרה (לא נדרש אימות נוסף מעבר ליכולת להגיע למארח לוח הבקרה). > שתי תעבורות ה-HTTP מותנות ב-`settings.mcpEnabled` וב-`settings.mcpTransport` — אי־התאמה בתעבורה מחזירה `400`, ומצב שבו MCP מושבת מחזיר `503`. --- ## שרת A2A OmniRoute חושף נקודת קצה מסוג A2A (סוכן-לסוכן) בתקן JSON-RPC 2.0, וכן מעטפת REST לצורכי בדיקה ולוח בקרה. ### JSON-RPC ```bash POST /a2a Authorization: Bearer your-api-key # אופציונלי, אלא אם OMNIROUTE_API_KEY מוגדר Content-Type: application/json { "jsonrpc": "2.0", "id": 1, "method": "message/send", "params": { "skill": "smart-routing", "messages": [{"role": "user", "content": "Route this coding task"}] } } ``` שיטות נתמכות (כולן תלויות בהפעלת `settings.a2aEnabled`): | שיטה | תיאור | | ---------------- | ---------------------------------------------------------------- | | `message/send` | הפעלה סינכרונית של מיומנות; מחזירה `{task, artifacts, metadata}` | | `message/stream` | הפעלת SSE בזרימה של אותה קבוצת מיומנויות | | `tasks/get` | אחזור משימה לפי `taskId` | | `tasks/cancel` | ביטול משימה לפי `taskId` | מיומנויות מובנות: `smart-routing`, `quota-management`, `provider-discovery`, `cost-analysis`, `health-report`. ### כרטיס סוכן ```bash GET /.well-known/agent.json ``` מחזיר את כרטיס סוכן ה-A2A הציבורי (שם, תיאור, יכולות, קטלוג מיומנויות, סכמת אימות) — נשמר במטמון ציבורי למשך שעה. לא נדרש אימות. ### מסייעי REST | שיטה | נתיב | תיאור | | ---- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | GET | `/api/a2a/status` | מצב הפעלת A2A + נתוני משימות + תקציר כרטיס הסוכן השמור במטמון | | GET | `/api/a2a/tasks` | הצגת רשימת משימות — `?state=submitted\|working\|completed\|failed\|cancelled`, `?skill=`, `?limit=` (≤200), `?offset=` | | POST | `/api/a2a/tasks` | (לא ממומש כמסייע REST — יש ליצור באמצעות JSON-RPC‏ `message/send`) | | GET | `/api/a2a/tasks/[id]` | אחזור משימה אחת | | POST | `/api/a2a/tasks/[id]/cancel` | ביטול משימה | **אימות:** מסייעי REST פועלים ללא אימות ניהולי (ניתנים לקריאה מלוח הבקרה); הנתיב `/a2a` של JSON-RPC משתמש ב-Bearer‏ `OMNIROUTE_API_KEY` אם הוא מוגדר. --- ## ענן, הערכות ובחינה | שיטה | נתיב | תיאור | | ------ | ------------------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------- | ----------------------------------- | | POST | `/api/cloud/auth` | אימות מפתח Bearer והחזרת חיבורי ספקים מוסווים + כינויי מודלים עבור לקוחות סנכרון ענן | | POST | `/api/cloud/credentials/update` | עדכון פרטי גישה מוצפנים עבור ספק המסונכרן עם הענן | | POST | `/api/cloud/model/resolve` | המרת מזהה מודל לוגי לספק/מודל קונקרטי באמצעות טבלת הניתוב המקומית | | GET | `/api/cloud/models/alias` | הצגת כינויי מודלים כפי שהם נחשפים לסנכרון ענן | | GET | `/api/assess` | קריאת סיווגי ההערכה האחרונים (לפי ספק/מודל) | | POST | `/api/assess` | הרצת הערכה — גוף: `{scope: {type:"all"} | {type:"provider", providerId} | {type:"model", modelId}, trigger?}` | | GET | `/api/evals` | הצגת חבילות ההערכה המובנות + ההרצות האחרונות | | POST | `/api/evals` | הפעלת הרצת הערכה | | POST | `/api/evals/suites` | יצירת חבילת הערכה מותאמת אישית — הגוף מאומת באמצעות `evalSuiteSaveSchema` | | GET | `/api/evals/suites/[id]` | אחזור חבילת הערכה מותאמת אישית | **אימות:** `/api/cloud/auth` מאמת מפתח Bearer ישירות ומחזיר את המפתח המוסווה ואת `projectId` של כל חיבור רק עבור מפתח בעל ההרשאה `manage` / `admin`; יתר הנתיבים `/api/cloud/*`,‏ `/api/evals/*` ו-`/api/assess` דורשים הפעלת ניהול או מפתח API ניהולי. בקשת POST אל `/api/assess` משתמשת ב-`validateBody` עם סכמת תחום מסוג איחוד מובחן. --- ## ניהול ACP (פרוטוקול לקוח סוכן) כתהליכי צאצא. נקודות קצה אלה מנהלות זיהוי של סוכני ACP ורישום של סוכנים מותאמים אישית. | שיטה | נתיב | תיאור | | ------ | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/acp/agents` | הצגת כל סוכני ה-CLI המוכרים (מובנים + מותאמים אישית), כולל מצב התקנה, גרסה וקובץ בינארי | | POST | `/api/acp/agents` | רישום סוכן ACP מותאם אישית או רענון המטמון — גוף: `{id, name, binary, versionCommand, providerAlias, spawnArgs, protocol}` או `{action: "refresh"}` | | DELETE | `/api/acp/agents` | הסרת סוכן ACP מותאם אישית — פרמטר שאילתה: `?id=` | **דוגמת תגובה** (`GET /api/acp/agents`): ```json { "agents": [ { "id": "claude", "name": "Claude Code CLI", "binary": "claude", "version": "1.0.45", "installed": true, "protocol": "stdio", "providerAlias": "claude", "isCustom": false }, { "id": "my-custom-cli", "name": "My Custom CLI", "installed": false, "protocol": "stdio", "providerAlias": "my-provider", "isCustom": true } ], "cacheTtlMs": 60000, "cacheAge": 1234 } ``` **אימות:** נדרשת הפעלת ניהול (קובץ cookie בשם `auth_token` של לוח המחוונים) או מפתח API בעל הרשאת ניהול. לפרטים מלאים, ראו [מסגרת ACP](../frameworks/ACP.md). --- ## ניתוח נתונים וניטור נקודות קצה לניתוח נתונים בזמן אמת לצורך ניטור ניתוב, דחיסה וגיוון ספקים. אלה משמשות את דפי `/dashboard/analytics/*`. ### ניתוח ניתוב אוטומטי | שיטה | נתיב | תיאור | | ---- | ------------------------------------ | ----------------------------------------------------------------------------------------------------- | | GET | `/api/analytics/auto-routing` | נתונים סטטיסטיים מצטברים של ניתוב אוטומטי: סך הקריאות, התפלגות אסטרטגיות, התפלגות רמות וספקים מובילים | | GET | `/api/analytics/auto-routing?days=7` | נתונים סטטיסטיים בחלון זמן מוגדר (ברירת המחדל היא 24 שעות) | **דוגמת תגובה**: ```json { "window": "24h", "totalCalls": 1234, "strategyBreakdown": { "rules": 800, "cost": 200, "latency": 150, "sla-aware": 50, "lkgp": 34 }, "tierBreakdown": { "ultra": 100, "pro": 500, "standard": 400, "free": 234 }, "topProviders": [ { "provider": "openai", "calls": 500, "avgLatencyMs": 850 }, { "provider": "anthropic", "calls": 300, "avgLatencyMs": 1200 } ] } ``` ### ניתוח דחיסה | שיטה | נתיב | תיאור | | ---- | ---------------------------- | -------------------------------------------------------------------------------------------- | | GET | `/api/analytics/compression` | נתונים סטטיסטיים מצטברים של דחיסה: טוקנים שנחסכו, אחוז החיסכון, התפלגות מצבים ושימוש במנועים | **דוגמת תגובה**: ```json { "window": "24h", "totalOriginalTokens": 5000000, "totalCompressedTokens": 3500000, "totalSavings": 1500000, "savingsPct": 30.0, "modeBreakdown": { "lite": 400, "standard": 600, "aggressive": 100, "ultra": 50, "rtk": 84 }, "engineBreakdown": { "caveman": 800, "rtk": 434 } } ``` ### מעקב אחר גיוון ספקים | שיטה | נתיב | תיאור | | ---- | -------------------------- | -------------------------------------------------------------------------------------------- | | GET | `/api/analytics/diversity` | מעקב אחר גיוון המבוסס על אנטרופיית שאנון: מניעת נקודות כשל יחידות באמצעות מדידת פיזור הספקים | **דוגמת תגובה**: ```json { "window": "24h", "shannonEntropy": 2.45, "maxEntropy": 3.17, "diversityRatio": 0.77, "providerUsage": { "openai": 0.4, "anthropic": 0.25, "google": 0.2, "kiro": 0.15 }, "warnings": ["OpenAI accounts for 40% of traffic — consider diversifying"] } ``` **אימות:** נדרשת הפעלת ניהול או מפתח API בעל הרשאת ניהול. --- ## פעולות ניהול נקודות קצה למנהלי מערכת בלבד לצורך ניהול תפעולי. | שיטה | נתיב | תיאור | | ---- | ------------------------ | --------------------------------------------------------------------------------------------- | | GET | `/api/admin/concurrency` | קריאת מגבלות המקביליות הנוכחיות (גלובלית + לפי ספק) | | POST | `/api/admin/concurrency` | עדכון מגבלות המקביליות — גוף הבקשה: `{global?: number, perProvider?: Record}` | **אימות:** נדרשת הפעלת ניהול בעלת הרשאת מנהל מערכת. --- ## ניהול כלי CLI ניהול כלי CLI המשתלבים עם OmniRoute (antigravity, commandCode, devin-cli וכדומה). לרשימה המלאה, ראו [חומר עזר בנושא ספקים](./PROVIDER_REFERENCE.md). | שיטה | נתיב | תיאור | | ---- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/cli-tools/all-statuses` | הסטטוס של כל כלי ה-CLI (התקנה, גרסה, מועד הופעה אחרון) | | GET | `/api/cli-tools/status` | פרטי הסטטוס של כלי CLI אחד (שאילתת `?tool=`) | | POST | `/api/cli-tools/apply` | כתיבת התצורה שנוצרה עבור כלי (`dryRun` מציג תצוגה מקדימה; `422` + `containerEphemeralTarget` כאשר פועל בקונטיינר; `migration` מציין קובץ YAML ישן של Codex) | | GET | `/api/cli-tools/backups` | הצגת רשימת הגיבויים של תצורות כלי ה-CLI | | POST | `/api/cli-tools/backups` | יצירת גיבוי של כל תצורות כלי ה-CLI | | POST | `/api/cli-tools/backups` | שחזור: אותה נקודת קצה עם `{tool, backupId}` בגוף הבקשה משחזרת את הגיבוי | | GET | `/api/cli-tools/antigravity-mitm` | סטטוס פרוקסי MITM של Antigravity (כלי ה-CLI בשם "antigravity-mitm") | | POST | `/api/cli-tools/antigravity-mitm/alias` | הגדרת כינויים עבור antigravity-mitm | **אימות:** נדרשת הפעלת ניהול. --- ## מיומנויות סוכן ניהול מיומנויות של סוכני AI (בדומה ל-GPTs המותאמים אישית של OpenAI, אך עבור סוכנים). | שיטה | נתיב | תיאור | | ------ | ---------------------------- | ------------------------------------------------------------------------------------------------ | | GET | `/api/agent-skills` | הצגת כל מיומנויות הסוכן (מובנות + מותאמות אישית) | | GET | `/api/agent-skills/[id]` | קבלת מיומנות סוכן מסוימת | | POST | `/api/agent-skills` | יצירת מיומנות סוכן מותאמת אישית — גוף הבקשה: `{name, description, prompt, model?, temperature?}` | | PUT | `/api/agent-skills/[id]` | עדכון מיומנות סוכן מותאמת אישית | | DELETE | `/api/agent-skills/[id]` | מחיקת מיומנות סוכן מותאמת אישית | | GET | `/api/agent-skills/[id]/raw` | קבלת ההנחיה הגולמית והמטא-נתונים (ללא הפעלה) | | POST | `/api/agent-skills/generate` | יצירת מיומנות חדשה באמצעות AI מתוך תיאור בשפה טבעית | **אימות:** נדרשת הפעלת ניהול או מפתח API בעל הרשאת ניהול. --- ## ניהול מטמון ניהול המטמון הסמנטי ומטמון ההסקה. | שיטה | נתיב | תיאור | | ------ | ---------------------- | ------------------------------------------------------------------------------------------------------- | | GET | `/api/cache` | סקירת המטמון: מספר כולל של רשומות, שיעור פגיעות, גודל בדיסק | | GET | `/api/cache/entries` | הצגת רשומות שנשמרו במטמון (עם עימוד) | | DELETE | `/api/cache/entries` | מחיקת רשומות מהמטמון (סינון לפי פרמטרים של השאילתה) | | GET | `/api/cache/stats` | סטטיסטיקות מטמון מפורטות (לפי ספק ולפי מודל) | | GET | `/api/cache/reasoning` | מצב מטמון ההסקה (לצורך הפעלה חוזרת של הסקה) | | DELETE | `/api/cache/reasoning` | ניקוי מטמון ההסקה — פרמטרים של שאילתה: `?toolCallId=` (יחיד), `?provider=

` או ללא פרמטרים (הכול) | **אימות:** נדרשת הפעלת ניהול. --- ## מערכת זיכרון ניהול זיכרון מתמיד (FTS5 + הטמעות וקטוריות). | שיטה | נתיב | תיאור | | ------ | ------------------ | ------------------------------------------------------------------------ | | GET | `/api/memory` | הצגת רשומות זיכרון (סינון לפי תחום, סוג ושאילתת חיפוש) | | POST | `/api/memory` | יצירת רשומת זיכרון חדשה — גוף הבקשה: `{scope, type, content, metadata?}` | | GET | `/api/memory/[id]` | קבלת רשומת זיכרון מסוימת | | PUT | `/api/memory/[id]` | עדכון רשומת זיכרון | | DELETE | `/api/memory/[id]` | מחיקת רשומת זיכרון | | GET | `/api/memory?q=` | חיפוש בזיכרון (FTS5 + וקטור) — הסטטיסטיקות נכללות באותה תגובה | **אימות:** נדרשת הפעלת ניהול או מפתח API בעל הרשאת ניהול. --- ## Webhooks ניהול מינויים ל-webhook עבור אירועים. | שיטה | נתיב | תיאור | | ------ | ------------------------------- | ---------------------------------------------------------------------- | | GET | `/api/webhooks` | הצגת כל המינויים ל-webhook | | POST | `/api/webhooks` | יצירת מינוי ל-webhook — גוף הבקשה: `{url, events[], secret?, active?}` | | GET | `/api/webhooks/[id]` | קבלת מינוי מסוים ל-webhook | | PUT | `/api/webhooks/[id]` | עדכון מינוי ל-webhook | | DELETE | `/api/webhooks/[id]` | מחיקת מינוי ל-webhook | | GET | `/api/webhooks/[id]/deliveries` | הצגת היסטוריית המסירות עבור webhook (יומן הצלחות/כישלונות) | | POST | `/api/webhooks/[id]/test` | שליחת אירוע בדיקה ל-webhook | **אימות:** נדרשת הפעלת ניהול. לרשימה המלאה של סוגי האירועים, ראו [מסגרת Webhooks](../frameworks/WEBHOOKS.md). --- ## מסגרת המיומנויות ניהול מיומנויות (מסגרת ההרחבות הסוכניות). | מתודה | נתיב | תיאור | | ------ | ------------------------ | -------------------------------------------------------------------------------------------- | | GET | `/api/skills` | הצגת כל המיומנויות המותקנות (מובנות + מותאמות אישית) | | POST | `/api/skills/install` | התקנת מיומנות מנתיב מקומי או מכתובת URL | | DELETE | `/api/skills/[id]` | הסרת התקנה של מיומנות | | PUT | `/api/skills/[id]` | הפעלה או השבתה של מיומנות — גוף הבקשה: `{enabled?: boolean, mode?: "on" \| "off" \| "auto"}` | | POST | `/api/skills/executions` | הרצת מיומנות — גוף הבקשה: `{skillName, apiKeyId, input?, sessionId?}` | | GET | `/api/skills/executions` | הצגת היסטוריית ההרצות של כל המיומנויות (סינון לפי `?apiKeyId=`) | **אימות:** נדרשת הפעלת ניהול או מפתח API בעל הרשאות ניהול. לפרטים מלאים, ראו [מסגרת המיומנויות](../frameworks/SKILLS.md). --- ## תוספים ניהול תוספי OmniRoute (הרחבות של צד שלישי). | מתודה | נתיב | תיאור | | ------ | ---------------------------------- | --------------------- | | GET | `/api/plugins` | הצגת התוספים המותקנים | | POST | `/api/plugins/marketplace/install` | התקנת תוסף מהשוק | | DELETE | `/api/plugins/[name]` | הסרת התקנה של תוסף | | POST | `/api/plugins/[name]/activate` | הפעלת תוסף | | POST | `/api/plugins/[name]/deactivate` | השבתת תוסף | | GET | `/api/plugins/[name]/config` | קבלת תצורת התוסף | | PUT | `/api/plugins/[name]/config` | עדכון תצורת התוסף | **אימות:** נדרשת הפעלת ניהול. לפרטים מלאים, ראו [מסגרת התוספים](../frameworks/PLUGIN_SDK.md). --- ## ניתוב צללים השוואת צללים / A-B בין ספקים **אינה ממשק REST עצמאי** — היא מוגדרת באמצעות ניתוב משולב (ראו [שילוב אוטומטי](../routing/AUTO-COMBO.md)). מדדי השוואה לכל שילוב מסופקים על ידי `GET /api/combos/metrics`. --- ## מנגנוני הגנה בדיקת מנגנוני ההגנה בזמן ריצה (זיהוי מידע אישי מזהה, זיהוי הזרקת הנחיות, גישור ראייה). מנגנוני ההגנה פועלים בכל בקשה; ניתן לבטל את הפעלתם בכל קריאה באמצעות כותרת הבקשה `x-omniroute-disabled-guardrails` — אין ממשק מתמשך להפעלה או להשבתה. | מתודה | נתיב | תיאור | | ----- | ---------------------- | -------------------------------------------------------------------------------------------------- | | GET | `/api/guardrails` | הצגת מנגנוני ההגנה הרשומים והסטטוס שלהם (שם / מופעל / עדיפות) | | POST | `/api/guardrails/test` | הרצת ניסיון של צינור העיבוד שלפני הקריאה על קלט לדוגמה — גוף הבקשה: `{input, disabledGuardrails?}` | **אימות:** נדרשת הפעלת ניהול. לפרטים מלאים, ראו [אבטחה > מנגנוני הגנה](../security/GUARDRAILS.md). --- --- ## אימות ראו [אימות לניהול](../guides/MANAGEMENT-AUTH.md) למידע על ארבע משפחות פרטי האימות (הפעלת לוח המחוונים, אסימון CLI מקומי, אסימון גישה מסוג `oma_live_…`, מפתח API בהיקף ניהול) ועל ההבדלים ביניהן לבין מפתחות הסקה. - נתיבי לוח המחוונים (`/dashboard/*`) משתמשים בקובץ Cookie מסוג `auth_token` - ההתחברות משתמשת בגיבוב הסיסמה השמור; עם חזרה ל-`INITIAL_PASSWORD` במקרה הצורך - ניתן להפעיל או להשבית את `requireLogin` דרך `/api/settings/require-login` - נתיבי `/v1/*` דורשים באופן אופציונלי מפתח API מסוג Bearer כאשר `REQUIRE_API_KEY=true` - „אסימון ניהול” / „מפתח API בהיקף ניהול” במסמך עזר זה פירושם אחת מהמשפחות שבמדריך זה — ולא סוג נוסף ובלתי מוגדר של סוד > **שינוי שובר תאימות (v3.8.0)** — הנתיבים `/api/v1/agents/tasks/*` ונקודות הקצה לניהול תקופת הצינון דורשים כעת **אימות לניהול** (קובץ Cookie מסוג `auth_token` של לוח המחוונים או מפתח API בהיקף ניהול). לקוחות שקראו בעבר לנתיבים אלה ללא אימות יקבלו `401 Unauthorized`. ראו את ה-commit ‏`588a0333` (`fix(auth): require management auth for agent and cooldown APIs`).