# 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) · 🇨🇿 [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) · 🇮🇱 [he](../../../he/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) · 🇮🇳 [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) --- 🌐 **ភាសា:** 🇺🇸 [English](./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) | 🇨🇿 [Č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) ឯកសារយោងស្នូលសម្រាប់ OmniRoute API។ ឯកសារនេះគ្របដណ្តប់លើផ្ទៃសាធារណៈ `/v1` និងចំណុចបញ្ចប់សម្រាប់ការគ្រប់គ្រងដែលប្រើញឹកញាប់បំផុត។ ឯកសារ [`docs/openapi.yaml`](../openapi.yaml) ដែលម៉ាស៊ីនអាចអានបាន និងមែកធាងផ្លូវក្រោម `src/app/api/` គឺជាប្រភពពេញលេញគ្រប់ជ្រុងជ្រោយ។ --- ## មាតិកា - [ការបំពេញការជជែក](#chat-completions) - [ការជួលសម័យដែលបានគ្រប់គ្រងផ្តាច់មុខ](#exclusive-managed-session-leases) - [វ៉ិចទ័របង្កប់](#embeddings) - [ការបង្កើតរូបភាព](#image-generation) - [OCR ឯកសារ](#document-ocr) - [បញ្ជីម៉ូដែល](#list-models) - [Manifest កម្មវិធីជំនួយរបស់អ្នកផ្តល់សេវា](#provider-plugin-manifest) - [Endpoint ភាពឆបគ្នា](#compatibility-endpoints) - [Files API](#files-api) - [Batches API](#batches-api) - [Search API](#search-api) - [ការស្ទ្រីមតាម WebSocket](#websocket-streaming) - [ការរាយការណ៍អំពីកូតា និងបញ្ហា](#quotas--issues-reporting) - [ឃ្លាំងសម្ងាត់តាមអត្ថន័យ](#semantic-cache) - [ផ្ទាំងគ្រប់គ្រង និងការគ្រប់គ្រង](#dashboard--management) - [ការគ្រប់គ្រង Combo](#combo-management) - [Webhooks](#webhooks) - [កូនសោដែលបានចុះឈ្មោះ (ការគ្រប់គ្រងដោយស្វ័យប្រវត្តិ)](#registered-keys-auto-management) - [ពិធីការ Agents](#agents-protocol) - [ប្រូកស៊ីគ្រប់គ្រង](#management-proxies) - [ភាពធន់ (បន្ថែម)](#resilience-extended) - [ជំនាញ](#skills) - [អង្គចងចាំ](#memory) - [ម៉ាស៊ីនមេ MCP](#mcp-server) - [ម៉ាស៊ីនមេ A2A](#a2a-server) - [Cloud, Evals និង Assess](#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": "សរសេរមុខងារមួយដើម្បី..."} ], "stream": true } ``` ### Header ផ្ទាល់ខ្លួន | Header | ទិសដៅ | ការពិពណ៌នា | | ------------------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `X-OmniRoute-No-Cache` | សំណើ | កំណត់ជា `true` ដើម្បីរំលងឃ្លាំងសម្ងាត់ | | `x-omniroute-no-memory` | សំណើ | កំណត់ជា `true` ដើម្បីរំលងការបញ្ចូលអង្គចងចាំ + ជំនាញសម្រាប់សំណើនេះ (ដូចនឹងការមិនប្រើឃ្លាំងសម្ងាត់; ជៀសវាងការចំណាយ token/ថ្លៃដើមក្នុងការហៅនីមួយៗ) | | `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-Cache` | ការឆ្លើយតប | `HIT` ឬ `MISS` (មិនមែនការស្ទ្រីម) | | `X-OmniRoute-Idempotent` | ការឆ្លើយតប | `true` ប្រសិនបើត្រូវបានលុបធាតុស្ទួន | | `X-OmniRoute-Progress` | ការឆ្លើយតប | `enabled` ប្រសិនបើការតាមដានវឌ្ឍនភាពត្រូវបានបើក | | `X-OmniRoute-Session-Id` | ការឆ្លើយតប | ID សម័យជាក់ស្តែងដែល OmniRoute បានប្រើ | | `X-OmniRoute-Request-Id` | ការឆ្លើយតប | ID សម្រាប់ភ្ជាប់ទំនាក់ទំនងសំណើ (នៅពេលស្គាល់) | | `X-OmniRoute-Version` | ការឆ្លើយតប | កំណែ build របស់ OmniRoute (មានជានិច្ច) | | `X-OmniRoute-Cost-Saved` | ការឆ្លើយតប | ចំនួន USD ដែលឃ្លាំងសម្ងាត់បានជួយសន្សំនៅពេល `HIT` (សម្រាប់តែការចូលប្រើឃ្លាំងសម្ងាត់ដែលត្រូវគ្នាប៉ុណ្ណោះ) | | `X-OmniRoute-Decision` | ការឆ្លើយតប | ដាននៃការកំណត់ផ្លូវ៖ `strategy=; provider=; latency_ms=` (`` គឺជាយុទ្ធសាស្ត្រ combo ឬ `single` សម្រាប់សំណើដែលមិនមែនជា combo) — មានជានិច្ចនៅក្នុងការឆ្លើយតបពេលបញ្ចប់ | > ចំណាំអំពី Nginx៖ ប្រសិនបើអ្នកពឹងផ្អែកលើ header ដែលមានសញ្ញាគូសក្រោម (ឧទាហរណ៍ `x_session_id`) សូមបើក `underscores_in_headers on;`។ > **បឋមកថាទូរមាត្រចំណាយ:** ការឆ្លើយតបជោគជ័យដែលមិនមែនជាស្ទ្រីម ក៏មានសំណុំទូរមាត្រចំណាយ `X-OmniRoute-*` ផងដែរ — `X-OmniRoute-Response-Cost` (USD, ទសភាគថេរ 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`, **និង endpoint មេឌៀនានា** — `/v1/embeddings`, `/v1/images/generations`, `/v1/audio/speech`, `/v1/audio/transcriptions`, `/v1/rerank`, `/v1/videos/generations`, `/v1/music/generations` និង `/v1/moderations` (មានតម្លៃ `0` ជានិច្ច)។ ចំណាយមេឌៀត្រូវបានគណនាតាមមូដាលីតេនីមួយៗ (ក្នុងមួយរូបភាព, ក្នុងមួយវិនាទី, ក្នុងមួយតួអក្សរ, ក្នុងមួយឯកតាស្វែងរក) នៅពេលមានព័ត៌មានតម្លៃ បើមិនដូច្នោះទេគឺ `0` (fail-open)។ > **ន័យនៃចំណាយពេល cache hit:** នៅពេល semantic cache HIT (`X-OmniRoute-Cache-Hit: true`) មិនមានការហៅទៅ upstream ទេ ដូច្នេះ `X-OmniRoute-Response-Cost` គឺ `0.0000000000` (ចំណាយ **បន្ថែម** សម្រាប់ការបម្រើ hit នោះ)។ ចំណាយដើម/ចំណាយដែលនឹងកើតមាន ត្រូវបានរាយការណ៍ដាច់ដោយឡែកនៅក្នុង `X-OmniRoute-Cost-Saved`។ អ្នកប្រើប្រាស់ទិន្នន័យវិក្កយបត្រគួរបូកសរុប `X-OmniRoute-Response-Cost` (hit មិនមានចំណាយទេ); ការវិភាគ cache អាចសរុប `X-OmniRoute-Cost-Saved`។ ## ការជួលសម័យដែលបានគ្រប់គ្រងផ្តាច់មុខ ការជួលសម័យដែលបានគ្រប់គ្រងផ្តាច់មុខ គឺជាកិច្ចសន្យាកំណត់ផ្លូវដែលអាចជ្រើសរើសប្រើ និងមិនអាស្រ័យលើម៉ាស៊ីនភ្ញៀវ៖ ម្ចាស់សកម្មតែមួយ កាន់កាប់ការតភ្ជាប់ OmniRoute ដែលមានសិទ្ធិមួយ។ វាមិនជួលម៉ូដែល មិនតម្រូវឱ្យមាន OAuth មិនកំណត់អត្តសញ្ញាណ ម៉ាស៊ីនភ្ញៀវជាក់លាក់ណាមួយ និងមិនតម្រូវឱ្យមានអ្នកផ្តល់សេវាជាក់លាក់ណាមួយទេ។ API key ដែលប្រើសម្រាប់ការផ្ទៀងផ្ទាត់ត្រូវតែមានវិសាលភាព `lease:exclusive` និងបញ្ជី `allowedConnections` ដែលបានបញ្ជាក់យ៉ាងច្បាស់ និងមិនទទេ។ ព្រំដែននៃការកែប្រែមូលដ្ឋានទិន្នន័យអនុវត្តលក្ខខណ្ឌទាំងពីររួមគ្នា នៅពេល បង្កើត key និងធ្វើបច្ចុប្បន្នភាពមួយផ្នែក។ ```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"} ``` ការឆ្លើយតបដែលជោគជ័យសម្រាប់ការទទួល ការបន្ត និងការដោះលែង បង្ហាញ timestamp, `state` និង `generation` វិជ្ជមានពិតប្រាកដ ប៉ុន្តែមិនបង្ហាញការតភ្ជាប់ ឬព័ត៌មានសម្ងាត់ដែលបានជ្រើសរើសឡើយ។ ការបន្ត និងការដោះលែង ផ្តល់ generation នៅក្នុង JSON body៖ ```json { "action": "renew", "generation": 1 } ``` ```json { "action": "release", "generation": 1, "reason": "OWNER_EXIT" } ``` ម្ចាស់ lease សកម្មអាចស្នើសុំយ៉ាងច្បាស់នូវ metadata សម្រាប់បង្ហាញដែលការពារឯកជនភាព សម្រាប់ binding បច្ចុប្បន្នរបស់ខ្លួន៖ ```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" } } ``` សកម្មភាព status ដែលត្រូវជ្រើសរើសប្រើនេះ ត្រូវបានហ៊ុមព័ទ្ធដោយ owner ស្រអាប់, managed API key ដែលបានផ្ទៀងផ្ទាត់ និង generation សកម្មពិតប្រាកដ នៅក្នុង transaction មូលដ្ឋានទិន្នន័យតែមួយ។ `displayName` គឺគ្រាន់តែជាឈ្មោះ ការតភ្ជាប់ដែលបានកំណត់រចនាសម្ព័ន្ធ និងបានដកដកឃ្លាជុំវិញចេញប៉ុណ្ណោះ; វាគឺ `null` នៅពេលមិនមានឈ្មោះដែលបានកំណត់រចនាសម្ព័ន្ធ និងមានសុវត្ថិភាព។ OmniRoute មិនដែលជំនួសវាដោយ អ៊ីមែល ឬអត្តសញ្ញាណគណនីដែលបានបង្កើតទេ។ តម្លៃ provider គឺជាស្លាកបង្ហាញដែលមិនរសើប ហើយមិនមែនជា អត្តសញ្ញាណអ្នកផ្តល់សេវាដែលឆបគ្នា និងត្រូវបានបង្កើតឡើយ។ ព័ត៌មានសម្ងាត់, token, cookie, ID ដើមរបស់ connection ឬ API key, owner hash, fencing secret និងទិន្នន័យកំណត់ផ្លូវខាងក្នុង ត្រូវបានដកចេញ។ ការស្វែងរកដោយប្រើ key ខុស, owner ខុស, generation ចាស់, បាត់, ផុតកំណត់, បានដោះលែង និងបានធ្វើឱ្យអសកម្ម សុទ្ធតែ ត្រឡប់កំហុស `409 LEASE_FENCE_STALE` ដូចគ្នា ដោយគ្មាន metadata របស់ការតភ្ជាប់។ ម៉ាស៊ីនភ្ញៀវដែលបានទទួលការឆ្លើយតបឱ្យរង់ចាំសមត្ថភាព មិនមាន binding សកម្មសម្រាប់ត្រួតពិនិត្យទេ។ នៅពេលការកំណត់ផ្លូវផ្លាស់ប្តូរ lease សកម្ម generation ដដែលនៅតែមានសុពលភាព ហើយ status នឹងត្រឡប់ binding ថ្មីដោយអាតូមិក មិនមែន binding ចាស់ឡើយ។ ម៉ាស៊ីនភ្ញៀវដែលមានស្រាប់នៅតែមិនផ្លាស់ប្តូរ ពីព្រោះការឆ្លើយតប acquire, renew, release និង waiting រក្សា ទម្រង់ពីមុនរបស់វា។ កិច្ចសន្យារបស់ម៉ាស៊ីនមេនេះមិនផ្លាស់ប្តូរ OpenAI Codex `/status` ដើមទេ។ បច្ចុប្បន្ន Codex ដើមរាយការណ៍អំពី អ្នកផ្តល់ម៉ូដែល និងស្ថានភាពការផ្ទៀងផ្ទាត់/គណនីដែលភ្ជាប់មកជាមួយ ប៉ុន្តែមិនបង្ហាញ metadata គណនីរបស់ អ្នកផ្តល់សេវាផ្ទាល់ខ្លួនតាមអំពើចិត្តទេ; ការរួមបញ្ចូលជាមួយម៉ាស៊ីនភ្ញៀវនៅពេលក្រោយ ត្រូវតែហៅសកម្មភាពនេះ ហើយសម្រេចថាត្រូវ បង្ហាញ `connection.displayName` ដោយរបៀបណា។ បន្ទាប់មក រាល់សំណើ inference ដែលបានគ្រប់គ្រង ផ្តល់ control header ទាំងពីរ៖ ```http X-OmniRoute-Lease-Owner: vlo_<43-base64url-characters> X-OmniRoute-Lease-Generation: 1 ``` owner, generation, ការតភ្ជាប់សកម្ម និង API key ដែលបានផ្ទៀងផ្ទាត់ពិតប្រាកដ ត្រូវបានហ៊ុមព័ទ្ធភ្លាមៗ មុនការព្យាយាម upstream នីមួយៗដែលគាំទ្រ។ ការចាក់ឡើងវិញនូវ owner និង generation ជាមួយ key ផ្សេង នឹងបរាជ័យ សូម្បីតែ នៅពេល key នោះអនុញ្ញាតឱ្យប្រើការតភ្ជាប់ដូចគ្នាក៏ដោយ។ owner ដើមមិនត្រូវបានរក្សាទុក, កត់ត្រាក្នុង log, រក្សាទុកក្នុង request snapshot ឬបញ្ជូនបន្តទៅ upstream ទេ។ ការប្រជែងបណ្តោះអាសន្ន ត្រឡប់ HTTP `429` ជាមួយ `Retry-After` និង៖ ```json { "state": "WAITING_FOR_CAPACITY", "error": { "type": "lease_error", "code": "LEASE_CAPACITY_UNAVAILABLE" }, "reason": "NO_FREE_ELIGIBLE_CONNECTION", "retryAfter": 30 } ``` ការឆ្លើយតបនេះមានន័យត្រឹមតែថា សំណុំដែលមានសិទ្ធិធម្មតាមិនទទេ ហើយបេក្ខភាពទំនេរទាំងអស់ត្រូវបាន កាន់កាប់ដោយ lease សកម្មបរទេស។ ម៉ូដែល/អ្នកផ្តល់សេវាដែលមិនគាំទ្រ, ភាពមិនត្រូវគ្នានឹងគោលការណ៍, cooldown, quota, សុខភាព និងការបរាជ័យផ្នែកសិទ្ធិធម្មតាផ្សេងទៀត នៅតែរក្សាការឆ្លើយតប OmniRoute ដែលមានស្រាប់។ ### `x-omniroute-compression` ការកំណត់ជំនួសផែនការបង្ហាប់សម្រាប់សំណើនីមួយៗ។ មានអាទិភាពខ្ពស់បំផុត — ឈ្នះលើការកំណត់ជំនួស routing-combo, profile សកម្ម, auto-trigger និង Default របស់ panel។ តម្លៃ៖ | តម្លៃ | ប្រសិទ្ធភាព | | ------------- | ------------------------------------------------------------------------------------ | | `off` | គ្មានការបង្ហាប់សម្រាប់សំណើនេះ។ | | `default` | Profile Default ដែលកំណត់ដោយ panel (មិនអើពើ profile សកម្ម)។ | | `engine:` | Engine តែមួយនៅពេលបានបើកប្រើ ឧ. `engine:rtk`។ | | `` | Combo ដែលមានឈ្មោះ ដោយផ្គូផ្គងតាមឈ្មោះមុនគេ (មិនប្រកាន់តួអក្សរធំតូច) បន្ទាប់មកតាម id។ | ចំណាំ៖ - តម្លៃដែលមិនស្គាល់ត្រូវបានមិនអើពើ (សំណើមិនត្រូវបានបដិសេធឡើយ); ការដោះស្រាយនឹងបន្តទៅលំដាប់អាទិភាពប្រតិបត្តិករធម្មតា។ - ប្រសិនបើ combo ច្រើនមានឈ្មោះដូចគ្នា សូមបញ្ជូន **id** របស់ combo ដើម្បីទទួលបានការផ្គូផ្គងដែលកំណត់ច្បាស់លាស់។ - Combo ដែលមានឈ្មោះ `off` ឬ `default` មិនអាចត្រូវបានជ្រើសរើសតាមឈ្មោះទេ (ពាក្យគន្លឹះទាំងនោះត្រូវបានបកស្រាយជាមុន); សូមយោងទៅ combo បែបនោះតាម id របស់វា។ - កុងតាក់បង្ហាប់មេគឺជាច្រករារាំងដាច់ខាត៖ នៅពេលការបង្ហាប់ត្រូវបានបិទជាសកល header នេះមិនអាចបើកវាបានទេ។ ផែនការដែលបានអនុវត្តត្រូវបានបញ្ជូនត្រឡប់នៅក្នុង response header៖ ``` X-OmniRoute-Compression: ; source= ``` ដែល `` គឺជាតម្លៃមួយក្នុងចំណោម `request-header`, `routing-override`, `active-profile`, `auto-trigger`, `default` ឬ `off`។ --- ## Embeddings ```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`) ក៏អាចត្រូវបានដោះស្រាយផងដែរ។ ប្រតិបត្តិការ embed/rerank/classify/segment របស់ Jina ប្រើព័ត៌មានសម្គាល់អត្តសញ្ញាណ `jina-ai` ពីផ្ទាំងគ្រប់គ្រងជាមុនសិន; `JINA_AI_API_KEY` ជាជម្រើសបម្រុងតែក្នុងករណីដែលមិនមាន key ក្នុងផ្ទាំងគ្រប់គ្រងប៉ុណ្ណោះ។ កាត `jina-reader` គឺសម្រាប់តែ Reader / `r.jina.ai` (`POST /v1/web/fetch`) ប៉ុណ្ណោះ ហើយមិនដែលផ្តល់សេវា embeddings ឬ rerank ទេ។ ម៉ូដែលក្នុងបញ្ជីចុះឈ្មោះដែលប្រកាសថាគាំទ្រពហុមធ្យោបាយ ក៏ទទួលយកធាតុដែលមានរចនាសម្ព័ន្ធអព្យាក្រឹតចំពោះអ្នកផ្តល់សេវាបានរហូតដល់ 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 សាធារណៈ, `data:` URI ឬ base64 ដើម។ OmniRoute មិនបម្លែងអ对象ទាំងនោះទៅជាខ្សែអក្សរ ឬទាញយក URL រូបភាពដើមនោះទេ — Jina ទាញយក មេឌៀសាធារណៈដោយខ្លួនឯង។ វាល Jina បន្ថែម (`task`, `normalized`, `truncate`, `embedding_type`) ត្រូវបាន បញ្ជូនបន្ត។ SKU របស់ Jina ដែលគាំទ្រតែអត្ថបទ នៅតែបដិសេធឯកសារដែលមិនមែនជាអត្ថបទ។ ដែនកំណត់សុវត្ថិភាព និងការបញ្ជូន៖ - URL មេឌៀពីចម្ងាយត្រូវតែជា HTTPS សាធារណៈ។ ធាតុ `{type,source:url}` ស្តង់ដារត្រូវបានទាញយក នៅផ្នែកម៉ាស៊ីនមេ (ការផ្ទៀងផ្ទាត់ការបញ្ជូនបន្តឡើងវិញ, timeout, ដែនកំណត់ទំហំ, DNS សាធារណៈ, ការចាក់សោការតភ្ជាប់) និង បង្កប់មុនពេលហៅអ្នកផ្តល់សេវា។ ធាតុដើមរបស់ Jina `{image:"https://..."}` ត្រូវបានបញ្ជូនបន្តដូចដើម បន្ទាប់ពីការត្រួតពិនិត្យ HTTPS សាធារណៈដូចគ្នា; Jina ទាញយក URL នោះ។ - មេឌៀ base64 ដែលបង្កប់ផ្ទាល់ ត្រូវបានកំណត់ត្រឹម 8 MiB ដែលបានឌិកូដក្នុងមួយធាតុ និង 16 MiB ដែលបានឌិកូដសរុបក្នុងសំណើទាំងមូល។ ការបម្លែងតាមអ្នកផ្តល់សេវា (ធាតុស្តង់ដារមិនដែលត្រូវបានបញ្ជូនបន្តដោយគ្មានការផ្លាស់ប្តូរទេ)៖ - ម៉ូដែលពហុមធ្យោបាយរបស់ Jina៖ ធាតុកម្រិតកំពូលនីមួយៗក្លាយជាអ对象មួយដែលមាន key តាមប្រភេទមធ្យោបាយ (`text` / `image` / `audio` / `video` / `pdf`) ដោយប្រើ data URI សម្រាប់មេឌៀដែលបង្កប់ផ្ទាល់; វ៉ិចទ័រមួយក្នុង មួយធាតុកម្រិតកំពូល។ - ត្រកូល Gemini Embedding 2៖ អារេកម្រិតកំពូលមួយក្លាយជាសំណើដើមតែមួយ `models/{model}:embedContent` ដែលមាន `content.parts` (`text` ឬ `inline_data`)។ - ម៉ូដែលមិនស្គាល់/ថាមវន្តដែលគ្មានមេតាទិន្នន័យប្រភេទមធ្យោបាយច្បាស់លាស់ នឹងបដិសេធ input ដែលមានរចនាសម្ព័ន្ធដោយ 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 ជំនួសឱ្យការបង្ខំបម្លែងធាតុ។ វាលផ្នែកបន្ថែមដែលមិនមែនជា input នៅលើសំណើខ្សែអក្សរ/token ចាស់ៗ នឹងបន្តឆ្លងកាត់ដោយគ្មានការផ្លាស់ប្តូរ។ ```bash # រាយបញ្ជីម៉ូដែល embedding ទាំងអស់ 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**, SD WebUI (មូលដ្ឋាន), ComfyUI (មូលដ្ឋាន)។ ```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 key របស់ការតភ្ជាប់ គឺជា ព័ត៌មានសម្គាល់អត្តសញ្ញាណ Service Account JSON (ដែលត្រូវបានប្តូរយកថូខឹនចូលប្រើ OAuth អាយុកាលខ្លីតាមរយៈលំហូរ JWT-bearer) ឬជាថូខឹនចូលប្រើ OAuth ដែលបានបង្កើតរួច និងត្រូវបានប្រើតាមដែលមាន។ URL ចំណុចបញ្ចប់របស់ប្រភពខាងលើគឺជា ចំណុចបញ្ចប់ដៃគូទូទៅ `openapi/chat/completions` របស់ Vertex ដែលត្រូវបានបង្កើតពីគម្រោង និង តំបន់របស់ការតភ្ជាប់ — `providerSpecificData.project`/`providerSpecificData.region` ដែលបានបញ្ជាក់ជាក់លាក់តែងតែមានអាទិភាព; បើមិនដូច្នោះទេ គម្រោងត្រូវបានយកពី `project_id` របស់ Service Account JSON ហើយតំបន់ ប្រើ `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 → ត្រឡប់ម៉ូដែលជជែក ម៉ូដែល embedding និងម៉ូដែលរូបភាពទាំងអស់ + បន្សំជាទម្រង់ OpenAI ``` ### បុព្វបទ id របស់ម៉ូដែល (`?prefix=`) ម៉ូដែលភាគច្រើនត្រូវបានបង្ហាញក្រោម **បុព្វបទរបស់អ្នកផ្តល់សេវា**។ បុព្វបទដែលអ្នកទទួលបានត្រូវបានគ្រប់គ្រងដោយ feature flag `MODELS_CATALOG_PREFIX_MODE` ហើយអាចបដិសេធការកំណត់នោះ **សម្រាប់សំណើនីមួយៗ** តាមរយៈ query parameter — វាមានប្រយោជន៍សម្រាប់ client ដែលចង់បានបញ្ជីស្អាត ដោយមិនផ្លាស់ប្តូរការកំណត់ទូទាំង server សម្រាប់អ្នកផ្សេងទៀត៖ ```bash GET /v1/models?prefix=alias # id មួយក្នុងមួយម៉ូដែល — បុព្វបទ alias ខ្លី GET /v1/models?prefix=dual # ទម្រង់ទាំងពីរ (លំនាំដើមរបស់ server) GET /v1/models?prefix=canonical # មានតែបុព្វបទ provider-id ពេញលេញ ``` | របៀប | បញ្ចេញ | កំណត់សម្គាល់ | | ----------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `dual` | `cc/claude-sonnet-4-6` **និង** `claude/claude-sonnet-4-6` | **លំនាំដើម។** id ទាំងពីរនាំផ្លូវទៅកាន់ម៉ូដែលតែមួយ។ វាត្រូវបានរក្សាទុកដើម្បីឱ្យ config របស់ client ដែលបានកំណត់ទម្រង់ណាមួយដោយផ្ទាល់នៅតែដំណើរការ។ វាធ្វើឱ្យ catalog មានទំហំប្រហែលទ្វេដង។ | | `alias` | `cc/claude-sonnet-4-6` | ធាតុមួយក្នុងមួយម៉ូដែល។ អ្នកផ្តល់សេវាដែលគ្មាន alias ដាច់ដោយឡែកនៅតែបញ្ចេញធាតុរបស់ពួកគេ ដូច្នេះគ្មានអ្វីត្រូវបានបាត់បង់ទេ។ | | `canonical` | `claude/claude-sonnet-4-6` | ធាតុមួយក្នុងមួយម៉ូដែលក្រោមបុព្វបទ provider-id ពេញលេញ។ អ្នកផ្តល់សេវាដែលគ្មាន alias ដាច់ដោយឡែក (ឧ. `antigravity/…`, `agy/…`) ក៏បញ្ចេញ id តែមួយរបស់ពួកគេនៅទីនេះដែរ ដូច្នេះគ្មានអ្វីត្រូវបានបាត់បង់ទេ។ | mirror ក្នុងរបៀប `dual` ក៏អាចត្រូវបានស្គាល់ដោយមិនចាំបាច់ប្រើ query parameter ផងដែរ៖ វាមាន field `parent` ដែលចង្អុលទៅកាន់ id ចម្បង។ client ដែលបង្ហាញឧបករណ៍ជ្រើសរើសម៉ូដែលគួរតែស្នើ `?prefix=alias` — នេះជាអ្វីដែល [ផ្នែកបន្ថែម OmniCopilot សម្រាប់ VS Code](../guides/VSCODE-COPILOT.md) ប្រើ។ ### វ៉ារ្យ៉ង់ម៉ូដែលដែលមិនគិត សម្រាប់ម៉ូដែល Claude ដែលអាចគិតបាន `/v1/models` ក៏ផ្សព្វផ្សាយវ៉ារ្យ៉ង់ **ដែលមិនគិត** ផងដែរ ដែល id របស់វាត្រូវបានដាក់បុព្វបទ `claude-3-omniroute-no-thinking/`៖ ``` claude-3-omniroute-no-thinking// ``` ការជ្រើសរើស id នេះ (ឧ. ក្នុង config របស់ Claude Code ដែលតែងតែភ្ជាប់ block `thinking`) នឹងដោះស្រាយត្រឡប់ទៅកាន់ `/` ពិតប្រាកដ ដោយបិទការវែកញែក — `thinking:{type:"disabled"}` នៅលើ path `/v1/messages` ឬទម្លាក់ field `reasoning`/`reasoning_effort` នៅលើ path `/v1/chat/completions`។ វ៉ារ្យ៉ង់នេះត្រូវបានរាយតែសម្រាប់ម៉ូដែលក្នុងត្រកូល Claude ដែលគាំទ្រការគិត **និង** ទទួលយក `disabled` ប៉ុណ្ណោះ (ដូច្នេះ ឧ. ម៉ូដែល adaptive-only ដែលបដិសេធ `disabled` មិនត្រូវបានរាប់បញ្ចូលទេ)។ ប្រតិបត្តិករអាចបង្ខំបើក ឬបិទវ៉ារ្យ៉ង់នេះសម្រាប់ម៉ូដែលនីមួយៗតាមរយៈ `ModelSpec.noThinkingAlias`។ --- ## ម៉ានីហ្វេស្តកម្មវិធីជំនួយអ្នកផ្តល់សេវា ```bash GET /api/v1/provider-plugin-manifest ``` ត្រឡប់ម៉ានីហ្វេស្តកម្មវិធីជំនួយអ្នកផ្តល់សេវាដែលមានសុវត្ថិភាពសម្រាប់ JSON ដែលប្រើដោយ Bifrost, CLIProxyAPI និង រ៉ោតទ័រ sidecar នាពេលអនាគត។ ការឆ្លើយតបត្រូវបានបង្កើតពីបញ្ជីចុះឈ្មោះអ្នកផ្តល់សេវា TypeScript ហើយដោយចេតនាមិនរួមបញ្ចូលសោសម្ងាត់ OAuth របស់ម៉ាស៊ីនភ្ញៀវ ការដោះស្រាយបរិស្ថានពេលដំណើរការ មុខងារប្រតិបត្តិ បឋមកថាសំណើ និងទិន្នន័យគណនីឡើយ។ ប្រើ endpoint នេះ នៅពេល sidecar ដំណើរការនៅក្រៅដំណើរការមេ ហើយមិនអាច import `open-sse/config/providerPluginManifestRegistry.ts` ដោយផ្ទាល់បាន។ --- ## Endpoint សម្រាប់ភាពត្រូវគ្នា | វិធីសាស្ត្រ | ផ្លូវ | ទ្រង់ទ្រាយ | | ----------- | ----------------------------------------- | --------------------------------------------- | | 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 (កែសម្រួល/inpaint) | | POST | `/v1/videos/generations` | ការបង្កើតវីដេអូបែប OpenAI | | POST | `/v1/music/generations` | ការបង្កើតតន្ត្រីបែប OpenAI | | POST | `/v1/audio/transcriptions` | OpenAI Audio (STT) | | 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/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 ដែលមាន token | | POST | `/api/v1/vscode/{token}/responses` | ឈ្មោះក្លែងក្លាយ OpenAI Responses ដែលមាន token | | POST | `/api/v1/vscode/{token}/api/chat` | ឈ្មោះក្លែងក្លាយ Ollama ដែលមាន token | | GET | `/api/v1/vscode/{token}/api/tags` | ឈ្មោះក្លែងក្លាយស្លាក Ollama ដែលមាន token | Route POST ទាំងអស់ប្រើទម្រង់ដូចគ្នា៖ `Bearer your-api-key` + ខ្លឹមសារ JSON ដែលបានផ្ទៀងផ្ទាត់ដោយ Zod (`v1RerankSchema`, `v1ModerationSchema`, `v1AudioSpeechSchema` ជាដើម សូមមើល `src/shared/validation/schemas.ts`)។ 4xx នឹងត្រូវបានត្រឡប់ នៅពេលការផ្ទៀងផ្ទាត់ schema បរាជ័យ។ សម្រាប់ម៉ាស៊ីនភ្ញៀវដែលមិនអាចភ្ជាប់ `Authorization: Bearer ...` បាន OmniRoute ក៏ទទួលយក API key នៅក្នុង URL តាមរយៈភាពត្រូវគ្នាជាមួយ query string (`?token=...`, `?apiKey=...`, `?api_key=...`, `?key=...`) ឬ endpoint `/api/v1/vscode/{token}/...` ដាច់ដោយឡែក ដែលបានចងក្រងជាឯកសារខាងក្រោម។ ```bash # រៀបលំដាប់ឡើងវិញ 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" } # ការកែសម្រួលរូបភាព (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": "suno/v3.5", "prompt": "..." } ``` ### Route អ្នកផ្តល់សេវាដាច់ដោយឡែក ```bash POST /v1/providers/{provider}/chat/completions POST /v1/providers/{provider}/embeddings POST /v1/providers/{provider}/images/generations ``` បុព្វបទអ្នកផ្តល់សេវានឹងត្រូវបានបន្ថែមដោយស្វ័យប្រវត្តិ ប្រសិនបើបាត់។ ម៉ូដែលដែលមិនត្រូវគ្នានឹងត្រឡប់ `400`។ --- ## Files API ចំណុចចុងក្រោយឯកសារដែលឆបគ្នាជាមួយ OpenAI សម្រាប់ការបញ្ចូល/បញ្ចេញជាបាច់ និងការផ្ទុកឡើងតាមគោលបំណងនៃឯកសារ។ | វិធីសាស្ត្រ | ផ្លូវ | សេចក្ដីពិពណ៌នា | | ----------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------- | | POST | `/v1/files` | ផ្ទុកឯកសារឡើង (multipart: `file`, `purpose`, `expires_after[anchor]`, `expires_after[seconds]`) — អតិបរមា 512 MiB | | GET | `/v1/files` | រាយបញ្ជីឯកសារសម្រាប់ API key ដែលបានផ្ទៀងផ្ទាត់អត្តសញ្ញាណ | | GET | `/v1/files/[id]` | ទាញយកទិន្នន័យមេតារបស់ឯកសារ | | DELETE | `/v1/files/[id]` | លុបឯកសារ | | GET | `/v1/files/[id]/content` | ស្ទ្រីមខ្លឹមសារដើមរបស់ឯកសារត្រឡប់មកវិញ | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** Bearer API key — ឯកសារត្រូវបានកំណត់វិសាលភាពតាម API key នីមួយៗតាមរយៈ `getApiKeyRequestScope`។ Key មួយ អាចមើលឃើញ ទាញយក និងលុបបានតែឯកសាររបស់ខ្លួនប៉ុណ្ណោះ; សម័យ dashboard ដែលគ្មាន key អាចអានបានទូទាំង instance; ឯកសារដែលគ្មានម្ចាស់ (ការផ្ទុកឡើងដោយអនាមិក ឬតាមសម័យ dashboard) ត្រូវបានបដិសេធចំពោះអ្នកហៅទាំងអស់ ដែលមិនមែនជាសម័យ។ `GET /v1/files` បដិសេធអ្នកហៅអនាមិក — និង key ដែលបានផ្ដល់ប៉ុន្តែមិនអាចផ្ទៀងផ្ទាត់បាន — ដោយប្រើ `401` ទោះបីជា `REQUIRE_API_KEY=false` ក៏ដោយ ជំនួសឱ្យការរាយបញ្ជីឯកសាររបស់ tenant ទាំងអស់ (GHSA-m3hp-hq9g-fpmv, GHSA-2jm2-mpx8-6523)។ --- ## Batches 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` | បោះបង់បាច់ដែលកំពុងដំណើរការ | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** កូនសោ Bearer API។ បាច់ត្រូវបានកំណត់វិសាលភាពតាមកូនសោ API នីមួយៗ ក្រោមច្បាប់បីផ្លូវដូចគ្នានឹង ឯកសារ៖ ចូលប្រើបានតែកូនសោផ្ទាល់ខ្លួនប៉ុណ្ណោះ, សម័យ dashboard អាចចូលប្រើបានទូទាំង instance, កំណត់ត្រាដែលគ្មានម្ចាស់ត្រូវបានបដិសេធចំពោះអ្នកហៅ ដែលមិនមែនជាសម័យទាំងអស់ (ការទាញយក, ការលុប, ការបោះបង់ និងការត្រួតពិនិត្យ `input_file_id` ពេលបង្កើត)។ `GET /v1/batches` បដិសេធអ្នកហៅអនាមិកដោយលេខកូដ `401` ទោះបីជា `REQUIRE_API_KEY=false` ក៏ដោយ។ --- ## Search API ស្រទាប់អរូបីសម្រាប់អ្នកផ្ដល់សេវាវិប/ស្វែងរក (Tavily, Brave, Exa, Serper ជាដើម)។ | វិធីសាស្ត្រ | ផ្លូវ | សេចក្ដីពិពណ៌នា | | ----------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | GET | `/v1/search` | រាយបញ្ជីអ្នកផ្ដល់សេវាស្វែងរកដែលបានកំណត់រចនាសម្ព័ន្ធ + សមត្ថភាព | | POST | `/v1/search` | ដំណើរការសំណួរស្វែងរក — តួសំណើត្រូវបានផ្ទៀងផ្ទាត់ដោយ `v1SearchSchema` និងគាំទ្រការរក្សាទុកក្នុងឃ្លាំងសម្ងាត់/ការរួមបញ្ចូលសំណើ | | GET | `/v1/search/analytics` | ស្ថិតិចំនួនលទ្ធផល/រយៈពេលឆ្លើយតប/ឃ្លាំងសម្ងាត់តាមអ្នកផ្ដល់សេវានីមួយៗ | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** Bearer API key (`extractApiKey` + `isValidApiKey`)។ គោលការណ៍ស្វែងរកត្រូវបានអនុវត្តតាមរយៈ `enforceApiKeyPolicy`។ --- ## Web Fetch API ស្រង់មាតិកាពី URL តាមរយៈអ្នកផ្តល់សេវា web-fetch ដែលបានកំណត់រចនាសម្ព័ន្ធ (Firecrawl, Jina Reader, Tavily Extract, TinyFish Fetch, Nimble Extract)។ | វិធីសាស្ត្រ | ផ្លូវ | សេចក្ដីពិពណ៌នា | | ----------- | --------------- | --------------------------------------------------------------------------- | | POST | `/v1/web/fetch` | ទាញយក/ប្រមូលទិន្នន័យពី URL — body ត្រូវបានផ្ទៀងផ្ទាត់ដោយ `v1WebFetchSchema` | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** Bearer API key (`extractApiKey` + `isValidApiKey`)។ គោលការណ៍ត្រូវបានអនុវត្តតាមរយៈ `enforceApiKeyPolicy`។ **ការប្ដូរទៅជម្រើសបម្រុងដោយគិតគូរពីកូតា (#8297):** នៅពេលមិនបានបញ្ជាក់ `provider` ជាក់លាក់ pool (`firecrawl` → `jina-reader` → `tavily-search` → `tinyfish` → `nimble-search`) នឹងត្រូវបាន ឆ្លងកាត់តាមលំដាប់អាទិភាពថេរ (fill-first) — អ្នកផ្តល់សេវាដែលបានកំណត់រចនាសម្ព័ន្ធ ប៉ុន្តែត្រូវបានកម្រិតអត្រា នឹងត្រូវរំលង ជំនួសឱ្យការបញ្ចប់សំណើភ្លាមៗ ហើយការបរាជ័យពី upstream ដែលអាចសាកល្បងឡើងវិញបាន/ទាក់ទងនឹងកូតា (HTTP 429 ជានិច្ច; 402/403 សម្រាប់កម្រិតឥតគិតថ្លៃដែលមានលក្ខណៈកូតារបស់ Firecrawl/Tavily/TinyFish — មិនមែនសម្រាប់ Jina Reader ហើយក៏មិនដែលសម្រាប់សំណើខុសធម្មតា 400 ឡើយ) នឹងបន្តទៅ អ្នកផ្តល់សេវាបន្ទាប់ដែលមានព័ត៌មានសម្ងាត់ និងមិនទាន់បានសាកល្បង នៅពេលដំណើរការសំណើ។ នៅពេលអ្នកផ្តល់សេវាទាំងអស់ក្នុង pool អស់លទ្ធភាព endpoint នឹងត្រឡប់ `429` តែមួយ (ជាមួយ header `Retry-After`) ជំនួសឱ្យ `400` ទូទៅពីមុន។ នៅពេលស្នើ `provider` ជាក់លាក់ នឹងមិនមាន ការប្ដូរទៅជម្រើសបម្រុងដោយស្ងាត់ៗទេ — អ្នកផ្តល់សេវាជាក់លាក់ដែលត្រូវបានកម្រិតអត្រា ឬបរាជ័យ នឹងបង្ហាញកំហុសរបស់ខ្លួន (`429` ប្រសិនបើត្រូវបានកម្រិតអត្រា បើមិនដូច្នោះទេ គឺស្ថានភាព upstream)។ --- ## ការស្ទ្រីមតាម WebSocket ```bash GET /v1/ws?handshake=1 ``` ផ្ទៀងផ្ទាត់ WebSocket upgrade handshake ហើយត្រឡប់សារឧទាហរណ៍នៃ wire protocol (`request`, `cancel`)។ WS frames ជាក់ស្ដែងត្រូវបានដំណើរការដោយម៉ាស៊ីនមេ WS ដែលភ្ជាប់មកជាមួយ នៅខាងក្រៅតារាង route របស់ Next.js។ **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** Bearer API key ក្នុងអំឡុងពេល handshake។ ### Responses API តាម WebSocket (សម្រាប់តែ codex) ```bash # ម៉ាស៊ីនមេ host:port ដូចគ្នានឹង HTTP API (លំនាំដើម 20128); ដំឡើងកម្រិតការតភ្ជាប់៖ wscat -c "ws://localhost:20128/v1/responses?api_key=" # (ឬ៖ -H "Authorization: Bearer ") # frame ដំបូងត្រូវតែជា response.create៖ { "type": "response.create", "model": "gpt-5.5", "input": [ { "role": "user", "content": "hi" } ] } ``` ប្រូកស៊ី Responses-API-over-WebSocket ត្រូវបានភ្ជាប់ **ផ្តាច់មុខទៅ `codex`** (ChatGPT backend)។ វាស្តាប់នៅលើ port ដូចគ្នានឹង API/dashboard តាមផ្លូវ `/v1/responses`, `/responses` និង `/api/v1/responses`។ នៅលើ frame `response.create` ដំបូង វា ផ្ទៀងផ្ទាត់អត្តសញ្ញាណ + រៀបចំតាមរយៈ bridge `codex-responses-ws` ខាងក្នុង ជ្រើសរើស ការតភ្ជាប់ codex OAuth មួយ ហើយបញ្ជូនជាផ្លូវរូងទៅ `wss://chatgpt.com/backend-api/codex/responses` តាមរយៈ transport `wreq-js`។ **ម៉ូដែលដែលមិនមែនជា codex នឹងត្រូវបានបដិសេធ** (`codex_ws_provider_required`)។ សម្រាប់ quota-share routing សូមប្រើ `model: "qtSd//codex/"`។ បានអនុវត្តនៅក្នុង `app/server-ws.mjs` + `scripts/dev/responses-ws-proxy.mjs` + `src/app/api/internal/codex-responses-ws/route.ts`។ **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** Bearer API key ក្នុងអំឡុងពេល handshake។ ម៉ាស៊ីនមេ HTTP ដែលភ្ជាប់មកជាមួយ (`server-ws.mjs`) ត្រូវតែជា entrypoint ដែលកំពុងដំណើរការ (តាមលំនាំដើម វាជា entrypoint នៅពេលមាន `app/server-ws.mjs`)។ #### លេខសម្គាល់ម៉ូដែល៖ ប្រើលេខសម្គាល់ ChatGPT ដើម (គ្មានបុព្វបទ `codex/`) OpenAI **Codex CLI** ផ្ទៀងផ្ទាត់ឈ្មោះម៉ូដែលនៅផ្នែក client នៅពេល `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`)។ bridge របស់ OmniRoute គាំទ្រតែ codex ដូច្នេះវាដោះស្រាយលេខសម្គាល់ដើមឡើងវិញជា codex model (`resolveCodexWsModelInfo`) មុនពេលបញ្ជូនជាផ្លូវរូងទៅ upstream — ទោះបីជា `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" # គ្មានសញ្ញា slash នៅខាងចុង; WS URL ត្រូវបានបង្កើតចេញពីនេះ (ប្រើ https/wss ក្នុង production) wire_api = "responses" # តម្លៃតែមួយគត់ដែលគាំទ្រចាប់តាំងពី Feb 2026 supports_websockets = true # បើកដំណើរការ transport Responses-over-WS env_key = "OMNIROUTE_API_KEY" # រក្សាទុក OmniRoute API key (Bearer) ``` ```bash export OMNIROUTE_API_KEY=sk-... # OmniRoute API key មួយ (key ណាមួយ ប្រសិនបើ REQUIRE_API_KEY=false) codex exec "Responda apenas: PONG" ``` CLI ដំឡើងកម្រិត `base_url + /responses` ទៅជា WebSocket ហើយ OmniRoute បញ្ជូនវា ជាផ្លូវរូងទៅការតភ្ជាប់ codex OAuth ដែលបានជ្រើសរើស។ បានផ្ទៀងផ្ទាត់ពីដើមដល់ចប់ជាមួយម៉ាស៊ីនមេ ក្នុងមូលដ្ឋាន៖ ChatGPT ត្រឡប់ `codex.rate_limits` + `response.created` ហើយស្ទ្រីម ការបំពេញ។ --- ## កូតា និងការរាយការណ៍បញ្ហា | វិធីសាស្ត្រ | ផ្លូវ | ការពិពណ៌នា | | ----------- | ------------------- | ------------------------------------------------------------------------------------ | | GET | `/v1/quotas/check` | ផ្ទៀងផ្ទាត់កូតាជាមុនសម្រាប់ `provider` + `accountId` មុនពេលចេញសោដែលបានចុះឈ្មោះ | | POST | `/v1/issues/report` | រាយការណ៍ការបរាជ័យក្នុងការចេញកូតា/សោទៅ GitHub (ត្រូវការ `GITHUB_ISSUES_REPO` + token) | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** សោ Bearer API (`isAuthenticated`)។ --- ## ការប្រើប្រាស់ដោយខ្លួនឯង (`/api/usage/om-usage`) សោ API ណាមួយអាចមើលការប្រើប្រាស់ និងកូតា **ផ្ទាល់ខ្លួនរបស់វា** បាន ដោយមិនត្រូវការការផ្ទៀងផ្ទាត់អត្តសញ្ញាណសម្រាប់ការគ្រប់គ្រង។ នេះគឺជា endpoint ដែល client (CLI ឬផ្ទាំង OmniCopilot) ប្រើដើម្បីបង្ហាញម្ចាស់សោអំពីការចំណាយរបស់ពួកគេ។ ```bash # ទម្រង់អត្ថបទ (កិច្ចសន្យាពីមុន — អត្ថបទធម្មតាសម្រាប់ terminal) curl -H "Authorization: Bearer " \ http://localhost:20128/api/usage/om-usage # ទម្រង់មានរចនាសម្ព័ន្ធ — ទម្រង់ដែល UI ប្រើប្រាស់ curl -H "Authorization: Bearer " \ "http://localhost:20128/api/usage/om-usage?format=json" ``` សោត្រូវតែបានបើក **`allowUsageCommand`** (បិទតាមលំនាំដើម — កម្មវិធីគ្រប់គ្រងសោ API របស់ dashboard បើក ឬបិទវាសម្រាប់សោនីមួយៗ)។ ប្រសិនបើមិនបើកទេ endpoint នឹងឆ្លើយតបដោយ `403`។ `?format=json` ត្រឡប់រចនាសម្ព័ន្ធដែលមានសញ្ញាសម្គាល់ខុសគ្នា ដូច្នេះអ្នកហៅនឹងមិនអានវាលទិន្នន័យពី ការបដិសេធឡើយ។ នៅពេលជោគជ័យ៖ ```jsonc { "allowed": true, // មានតែនៅពេលសោបានជ្រើសប្រើដែនកំណត់ការប្រើប្រាស់ក្នុងមួយសោ (USD ប្រចាំថ្ងៃ/ប្រចាំសប្ដាហ៍)៖ "personal": { "dailySpentUsd": 1.25, "dailyLimitUsd": 5, "dailyResetAtIso": "…", "weeklySpentUsd": 8, "weeklyLimitUsd": 20, "weeklyResetAtIso": "…" /* … */, }, // ទិដ្ឋភាពកូតារបស់ provider ដែលបានជ្រើស ឬ null នៅពេលមិនទាន់មានអ្វីត្រូវបានរក្សាទុកក្នុង cache៖ "provider": { "connectionId": "…", "provider": "claude", "plan": "…", "quotas": {/* … */}, }, // ទិដ្ឋភាពរបស់ connection ទាំងអស់ ដើម្បីឱ្យ UI អាចបង្ហាញ provider ជាច្រើននៅក្បែរគ្នា៖ "providers": [ { "connectionId": "…", "provider": "claude" /* … */ }, { "provider": "codex" /* … */ }, ], } ``` នៅពេលបដិសេធ (`401` សោមិនត្រឹមត្រូវ / `403` មិនត្រូវបានអនុញ្ញាត) route ដដែលនេះនឹងត្រឡប់ `{ "allowed": false, "error": { "message": "…" } }` — `personal`/`provider` ដែលមានវត្តមានប៉ុន្តែទទេ (សោត្រូវបានអនុញ្ញាត ប៉ុន្តែមិនទាន់ទទួលបានទិន្នន័យ) គឺជាស្ថានភាពខុសពីការបដិសេធ ហើយមានតែទម្រង់ JSON ប៉ុណ្ណោះដែលអាចបែងចែកស្ថានភាពទាំងនេះបាន។ **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** សោ Bearer API ផ្ទាល់ខ្លួនរបស់អ្នកហៅ ដែលត្រូវបានផ្ទៀងផ្ទាត់ដោយ `isValidApiKey` — នេះ _មិនមែនជា_ ផ្ទៃគ្រប់គ្រង (`/api/keys/…`) ទេ ដែលនៅតែត្រូវបានការពារដោយ `requireManagementAuth`។ --- ## Cache តាមអត្ថន័យ ```bash # ទទួលយកស្ថិតិ cache GET /api/cache/stats # សម្អាត cache ទាំងអស់ DELETE /api/cache/stats ``` ឧទាហរណ៍ការឆ្លើយតប៖ ```json { "semanticCache": { "memorySize": 42, "memoryMaxSize": 500, "dbSize": 128, "hitRate": 0.65 }, "idempotency": { "activeKeys": 3, "windowMs": 5000 } } ``` ### ផលប៉ះពាល់លើភាពយឺត ការរកឃើញក្នុង semantic cache (HIT) ផ្ដល់ការឆ្លើយតបពី cache **ដោយគ្មានការហៅទៅ upstream ឡើយ** ដូច្នេះ `X-OmniRoute-Response-Latency` ដែលបានរាយការណ៍មានតម្លៃជិតសូន្យ (ដោយមិនគិតពីភាពយឺត upstream ដើម)។ client ដែលយកចិត្តទុកដាក់ចំពោះភាពយឺត (ការវាស់ស្ទង់សមត្ថភាព ការត្រួតពិនិត្យ p50/p99) គួរតែពិនិត្យ response header `X-OmniRoute-Cache-Latency`៖ | តម្លៃ | អត្ថន័យ | | ----------- | --------------------------------------------------------------------------- | | `synthetic` | ការឆ្លើយតបត្រូវបានផ្ដល់ពី cache; ភាពយឺតមិនមែនជាពេលវេលា upstream ពិតប្រាកដទេ | | _(មិនមាន)_ | ការឆ្លើយតបពីការហៅទៅ upstream ពិតប្រាកដ | ### ការរំលង cache តាមសោនីមួយៗ សោ API អាចជ្រើសមិនប្រើការអានពី semantic cache តាមរយៈ `cacheDefaultMode`៖ | តម្លៃ | ឥរិយាបថ | | -------- | --------------------------------------------------------- | | `legacy` | ឥរិយាបថ cache ធម្មតា (លំនាំដើម) | | `bypass` | រំលងការស្វែងរកក្នុង cache ទាំងស្រុង ហើយតែងតែហៅទៅ upstream | កំណត់នៅពេលបង្កើតសោ (`POST /api/keys`) ឬធ្វើបច្ចុប្បន្នភាព (`PATCH /api/keys/[id]`)៖ ```json { "cacheDefaultMode": "bypass" } ``` ### ការរំលងតាមសំណើនីមួយៗ សំណើណាមួយអាចរំលង cache បាន ដោយមិនគិតពីការកំណត់សោ៖ ``` X-OmniRoute-No-Cache: true ``` --- ## ផ្ទាំងគ្រប់គ្រង និងការគ្រប់គ្រង Route សម្រាប់ការគ្រប់គ្រង (`/api/*` លើកលែងតែ auth/login សាធារណៈ) **មិនត្រូវបាន** ផ្តល់សិទ្ធិដោយ API key សម្រាប់ inference ធម្មតាទេ។ សម្រាប់ប្រភេទ credential, scope និងឧទាហរណ៍ curl សូមមើល៖ [ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណសម្រាប់ការគ្រប់គ្រង](../guides/MANAGEMENT-AUTH.md)។ ### ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ | Endpoint | Method | ការពិពណ៌នា | | ----------------------------- | ------- | -------------------------- | | `/api/auth/login` | POST | ចូលគណនី | | `/api/auth/logout` | POST | ចាកចេញពីគណនី | | `/api/settings/require-login` | GET/PUT | បិទ/បើកការតម្រូវឱ្យចូលគណនី | ### ការគ្រប់គ្រង Provider | Endpoint | Method | ការពិពណ៌នា | | ---------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------ | | `/api/providers` | GET/POST | បង្ហាញបញ្ជី / បង្កើត provider | | `/api/providers/[id]` | GET/PUT/DELETE | គ្រប់គ្រង provider មួយ | | `/api/providers/[id]/test` | POST | សាកល្បងការតភ្ជាប់របស់ provider | | `/api/providers/[id]/models` | GET | បង្ហាញបញ្ជី model របស់ provider | | `/api/providers/validate` | POST | ផ្ទៀងផ្ទាត់ config របស់ provider | | `/api/providers/bulk` | POST | បន្ថែម API key ជាច្រើនសម្រាប់ provider តែមួយ | | `/api/providers/import` | POST | នាំចូលបញ្ជី provider ចម្រុះពីឯកសារ CSV/JSON ដែលបាន parse (#6836); លទ្ធផលបរាជ័យដោយផ្នែកសម្រាប់ជួរនីមួយៗ | | `/api/provider-nodes*` | ផ្សេងៗ | ការគ្រប់គ្រង node របស់ provider | | `/api/provider-models` | GET/POST/PATCH/DELETE | model ផ្ទាល់ខ្លួន (បន្ថែម ធ្វើបច្ចុប្បន្នភាព លាក់/បង្ហាញ លុប) | ### លំហូរ OAuth | Endpoint | Method | ការពិពណ៌នា | | -------------------------------- | ------ | ------------------------------ | | `/api/oauth/[provider]/[action]` | ផ្សេងៗ | OAuth ជាក់លាក់សម្រាប់ provider | ### ការកំណត់ Route និង Config | Endpoint | Method | ការពិពណ៌នា | | --------------------- | -------- | ---------------------------------- | | `/api/models/alias` | GET/POST | ឈ្មោះក្លែងក្លាយរបស់ model | | `/api/models/catalog` | GET | model ទាំងអស់តាម provider + ប្រភេទ | | `/api/combos*` | ផ្សេងៗ | ការគ្រប់គ្រង combo | | `/api/keys*` | ផ្សេងៗ | ការគ្រប់គ្រង API key | | `/api/pricing` | GET | តម្លៃរបស់ model | ### ការប្រើប្រាស់ និងការវិភាគ | Endpoint | Method | Description | | -------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `/api/usage/history` | GET | ប្រវត្តិការប្រើប្រាស់ | | `/api/usage/logs` | GET | កំណត់ហេតុការប្រើប្រាស់ | | `/api/usage/request-logs` | GET | កំណត់ហេតុកម្រិតសំណើ | | `/api/usage/[connectionId]` | GET | ការប្រើប្រាស់តាមការតភ្ជាប់នីមួយៗ | | `/api/usage/token-limits` | GET/POST/DELETE | ថវិកាកំណត់ចំនួន token សម្រាប់ API key នីមួយៗ | | `/api/usage/model-latency-stats` | GET | ស្ថិតិសរុបវិលជុំនៃរយៈពេលពន្យារតាម provider/model (មធ្យម/p50/p95/p99, អត្រាជោគជ័យ); តម្រង៖ `windowHours`/`minSamples`/`maxRows`/`provider`/`model` (#6873) | | `/api/usage/cache-health` | GET | សេចក្តីសង្ខេបអំពីស្ថានភាព prompt-cache លើ `call_logs` — សមាមាត្រសរសេរ/អាន, ការចែកចាយទំហំសរសេរ p50/p90/p99, កំហាប់នៃការសរសេរច្រើន, ការបែងចែកតាម model និងការវិនិច្ឆ័យ `healthy`/`degraded`/`thrash`/`no-data`; query params `range` (`1h`\|`24h`\|`7d`\|`30d`, លំនាំដើម `24h`) និង `model` ជាជម្រើស (#8827) | ### ការកំណត់ | Endpoint | Method | Description | | ------------------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `/api/settings` | GET/PUT/PATCH | ការកំណត់ទូទៅ | | `/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/reasoning (passthrough / auto-strip / custom / adaptive)។ ឯករាជ្យពីការបង្ហាប់។ សូមមើល [THINKING_BUDGET.md](../guides/THINKING_BUDGET.md)។ | | `/api/settings/system-prompt` | GET/PUT | system prompt សកល | | `/api/settings/compression` | GET/PUT | ការកំណត់រចនាសម្ព័ន្ធការបង្ហាប់សកល | | `/api/settings/purge-request-history` | POST | សម្អាតជួរដេកកំណត់ហេតុសំណើ និង artifact នៃ call-log មូលដ្ឋាន | ### Context និងការបង្ហាប់ | ចំណុចចុង (Endpoint) | វិធីសាស្ត្រ | សេចក្ដីពិពណ៌នា | | -------------------------------------- | -------------- | -------------------------------------------------------------------------- | | `/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 | ឈ្មោះក្លែងក្លាយសម្រាប់ការវិភាគការបង្ហាប់ | ### ការត្រួតពិនិត្យ | ចំណុចចុង (Endpoint) | វិធីសាស្ត្រ | សេចក្ដីពិពណ៌នា | | ------------------------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `/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 | ការពិនិត្យ trusted-loopback យ៉ាងតឹងរ៉ឹង មុនការផ្ទៀងផ្ទាត់សិទ្ធិគ្រប់គ្រង/ការស្ទង់ពិនិត្យ; ស្ថានភាពអាចប្រើបាន និងកំណែរបស់ FFmpeg/ffprobe ដែលបានសម្អាតព័ត៌មានរសើប (មិនរក្សាទុក) | | `/api/modality-bridge/video/extract` | POST | ឈ្មួញកណ្ដាលបៃដែលបានផ្ទៀងផ្ទាត់សិទ្ធិ និងជា trusted-loopback សម្រាប់ប្រើផ្ទៃក្នុង; ទិន្នន័យចូល 50 MiB, ជួររង់ចាំមានដែនកំណត់/ទិន្នន័យចេញ 32 MiB, `503` សម្រាប់អស់សមត្ថភាព, `499` សម្រាប់ការផ្ដាច់ និង `504` សម្រាប់ផុតកំណត់ពេល; មិនមែនជា API ផ្ទុកឯកសារឡើងសាធារណៈទេ | ### ការបម្រុងទុក និងការនាំចេញ/នាំចូល | Endpoint | Method | Description | | --------------------------- | ------ | ------------------------------------------------- | | `/api/db-backups` | GET | រាយបញ្ជីការបម្រុងទុកដែលមាន | | `/api/db-backups` | PUT | បង្កើតការបម្រុងទុកដោយដៃ | | `/api/db-backups` | POST | ស្ដារពីការបម្រុងទុកជាក់លាក់មួយ | | `/api/db-backups/export` | GET | ទាញយកមូលដ្ឋានទិន្នន័យជាឯកសារ .sqlite | | `/api/db-backups/import` | POST | ផ្ទុកឡើងឯកសារ .sqlite ដើម្បីជំនួសមូលដ្ឋានទិន្នន័យ | | `/api/db-backups/exportAll` | GET | ទាញយកការបម្រុងទុកពេញលេញជាបណ្ណសារ .tar.gz | ### ការធ្វើសមកាលកម្មលើ Cloud | Endpoint | Method | Description | | ---------------------- | ------ | ---------------------------------- | | `/api/sync/cloud` | ផ្សេងៗ | ប្រតិបត្តិការធ្វើសមកាលកម្មលើ Cloud | | `/api/sync/initialize` | POST | ចាប់ផ្ដើមការធ្វើសមកាលកម្ម | | `/api/cloud/*` | ផ្សេងៗ | ការគ្រប់គ្រង Cloud | ### Tunnels | Endpoint | Method | Description | | -------------------------- | ------ | ---------------------------------------------------------------------------- | | `/api/tunnels/cloudflared` | GET | អានស្ថានភាពដំឡើង/ដំណើរការរបស់ Cloudflare Quick Tunnel សម្រាប់ផ្ទាំងគ្រប់គ្រង | | `/api/tunnels/cloudflared` | POST | បើក ឬបិទ Cloudflare Quick Tunnel (`action=enable/disable`) | | `/api/tunnels/ngrok` | GET | អានស្ថានភាពដំណើរការរបស់ ngrok Tunnel សម្រាប់ផ្ទាំងគ្រប់គ្រង | | `/api/tunnels/ngrok` | POST | បើក ឬបិទ ngrok Tunnel (`action=enable/disable`) | ### ឧបករណ៍ CLI | Endpoint | Method | Description | | ---------------------------------- | ------ | --------------------- | | `/api/cli-tools/claude-settings` | GET | ស្ថានភាព Claude CLI | | `/api/cli-tools/codex-settings` | GET | ស្ថានភាព Codex CLI | | `/api/cli-tools/droid-settings` | GET | ស្ថានភាព Droid CLI | | `/api/cli-tools/openclaw-settings` | GET | ស្ថានភាព OpenClaw CLI | | `/api/cli-tools/runtime/[toolId]` | GET | ពេលដំណើរការ CLI ទូទៅ | ការឆ្លើយតបរបស់ CLI រួមមាន៖ `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`។ ### ភ្នាក់ងារ ACP | Endpoint | Method | Description | | ----------------- | ------ | --------------------------------------------------------------------------- | | `/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)។ ### ភាពធន់ និងដែនកំណត់អត្រា | Endpoint | Method | Description | | --------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------- | | `/api/resilience` | GET/PATCH | ទទួលយក/ធ្វើបច្ចុប្បន្នភាពជួរសំណើ រយៈពេលរង់ចាំនៃការតភ្ជាប់ ឧបករណ៍ផ្ដាច់សៀគ្វីរបស់អ្នកផ្ដល់ និងការកំណត់ការរង់ចាំ | | `/api/resilience/reset` | POST | កំណត់ឧបករណ៍ផ្ដាច់សៀគ្វីរបស់អ្នកផ្ដល់ឡើងវិញ | | `/api/resilience/model-cooldowns` | GET | រាយបញ្ជីការចាក់សោសកម្មតាម (អ្នកផ្ដល់ ការតភ្ជាប់ ម៉ូដែល) ដែលបានតម្រៀបតាមពេលវេលានៅសល់ | | `/api/resilience/model-cooldowns` | DELETE | សម្អាតការចាក់សោម៉ូដែល — body `{provider, model}` ឬ `{all: true}` ដើម្បីលុបអ្វីៗទាំងអស់ | | `/api/rate-limits` | GET | ស្ថានភាពដែនកំណត់អត្រាតាមគណនី | | `/api/rate-limit` | GET | ការកំណត់រចនាសម្ព័ន្ធដែនកំណត់អត្រាសកល | > ផ្លូវទាំងបួន `/api/resilience/*` តម្រូវឱ្យមាន **ការផ្ទៀងផ្ទាត់ភាពត្រឹមត្រូវសម្រាប់ការគ្រប់គ្រង** (`requireManagementAuth`)។ សូមមើល [ភាពធន់ (បន្ថែម)](#resilience-extended) សម្រាប់ការបកស្រាយលម្អិតពេញលេញអំពីភាពខុសគ្នារវាងឧបករណ៍ផ្ដាច់សៀគ្វីរបស់អ្នកផ្ដល់ រយៈពេលរង់ចាំនៃការតភ្ជាប់ និងការចាក់សោម៉ូដែល។ ### ការវាយតម្លៃ | Endpoint | Method | Description | | ------------ | -------- | ------------------------------------------------ | | `/api/evals` | GET/POST | រាយបញ្ជីសំណុំតេស្តវាយតម្លៃ / ដំណើរការការវាយតម្លៃ | ### គោលការណ៍ | Endpoint | Method | Description | | --------------- | --------------- | --------------------------- | | `/api/policies` | GET/POST/DELETE | គ្រប់គ្រងគោលការណ៍កំណត់ផ្លូវ | ### អនុលោមភាព | Endpoint | Method | Description | | --------------------------- | ------ | -------------------------------------- | | `/api/compliance/audit-log` | GET | កំណត់ហេតុសវនកម្មអនុលោមភាព (N ចុងក្រោយ) | ### v1beta (ឆបគ្នាជាមួយ Gemini) | Endpoint | Method | Description | | -------------------------- | ------ | -------------------------------------- | | `/v1beta/models` | GET | រាយបញ្ជីម៉ូដែលតាមទម្រង់ Gemini | | `/v1beta/models/{...path}` | POST | endpoint `generateContent` របស់ Gemini | endpoint ទាំងនេះឆ្លុះតាមទម្រង់ API របស់ Gemini សម្រាប់ client ដែលរំពឹងថានឹងមានភាពឆបគ្នាជាមួយ Gemini SDK ដើម។ ### API ផ្ទៃក្នុង / ប្រព័ន្ធ | Endpoint | វិធីសាស្ត្រ | សេចក្តីពិពណ៌នា | | ------------------------ | ----------- | ----------------------------------------------------------------- | | `/api/init` | GET | ពិនិត្យការចាប់ផ្តើមកម្មវិធី (ប្រើនៅពេលដំណើរការលើកដំបូង) | | `/api/tags` | GET | ស្លាកម៉ូដែលដែលត្រូវគ្នាជាមួយ Ollama (សម្រាប់កម្មវិធីភ្ញៀវ Ollama) | | `/api/restart` | POST | ចាប់ផ្តើមម៉ាស៊ីនមេឡើងវិញដោយរលូន | | `/api/shutdown` | POST | បិទម៉ាស៊ីនមេដោយរលូន | | `/api/system/env/repair` | POST | ជួសជុលអថេរបរិស្ថានរបស់អ្នកផ្តល់សេវា OAuth | > **ចំណាំ៖** Endpoint ទាំងនេះត្រូវបានប្រើនៅខាងក្នុងដោយប្រព័ន្ធ ឬសម្រាប់ភាពត្រូវគ្នាជាមួយកម្មវិធីភ្ញៀវ 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 POST /v1/audio/transcriptions Authorization: Bearer your-api-key Content-Type: multipart/form-data ``` ចម្លងឯកសារសំឡេងជាអត្ថបទដោយប្រើអ្នកផ្តល់សេវា STT ណាមួយដែលបានកំណត់រចនាសម្ព័ន្ធ។ ផ្នែកផ្លូវដំបូង ជ្រើសរើសអ្នកផ្តល់សេវាដើម (`openai/…`, `deepgram/…`)។ Gateway ដែល នាំចេញម៉ូដែលរបស់ក្រុមហ៊ុនផ្គត់ផ្គង់ផ្សេងឡើងវិញ ប្រើ id ដែលមានការបញ្ជាក់ពេញលេញ (`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": "សួស្តី នេះគឺជាខ្លឹមសារសំឡេងដែលបានចម្លងជាអត្ថបទ។", "task": "transcribe", "language": "en", "duration": 12.5 } ``` **ឧទាហរណ៍ model ids:** `openai/whisper-1` (ទាមទារ OpenAI key), `openrouter/deepgram/nova-3` (ទាមទារ OpenRouter key), `deepgram/nova-3` (ទាមទារ Deepgram key ដើម)។ សំណើ `deepgram/nova-3` ផ្ទាល់ **មិន** ប្រើ OpenRouter ទេ។ **ទម្រង់ដែលគាំទ្រ:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`។ --- ## ភាពត្រូវគ្នាជាមួយ Ollama សម្រាប់ client ដែលប្រើទម្រង់ API របស់ Ollama៖ ```bash # Endpoint សម្រាប់ការជជែក (ទម្រង់ Ollama) POST /v1/api/chat # បញ្ជីម៉ូដែល (ទម្រង់ Ollama) GET /api/tags ``` សំណើត្រូវបានបកប្រែដោយស្វ័យប្រវត្តិរវាងទម្រង់ Ollama និងទម្រង់ខាងក្នុង។ ## Alias ដែលមាន Token សម្រាប់ VS Code / មិនត្រូវការ Header ប្រើ alias ទាំងនេះ នៅពេល integration មិនអាចបញ្ចូល `Authorization` header ហើយត្រូវការបង្កប់ API key នៅក្នុង base URL។ ```bash # Alias កាតាឡុកតាមរចនាប័ទ្ម OpenAI GET /api/v1/vscode/{token}/ GET /api/v1/vscode/{token}/models # Alias ការជជែកតាមរចនាប័ទ្ម OpenAI POST /api/v1/vscode/{token}/chat/completions POST /api/v1/vscode/{token}/responses # Alias តាមរចនាប័ទ្ម 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"}]}' ``` ចំណាំ៖ - Alias ដែលមាន token ប្រើ handler ដូចគ្នានឹង `/v1/*` និង `/api/tags`; រចនាសម្ព័ន្ធនៃការឆ្លើយតបនៅតែដូចគ្នា។ - គួរប្រើ `Authorization: Bearer ...` នៅពេលណាដែល client គាំទ្រ header ផ្ទាល់ខ្លួន។ - Token ដែលផ្អែកលើ URL អាចបង្ហាញនៅក្នុង log របស់ reverse proxy, ប្រវត្តិ browser និង telemetry នៅខាងក្រៅ OmniRoute។ ចាត់ទុកវាជាជម្រើសសម្រាប់ភាពត្រូវគ្នា មិនមែនជារបៀបផ្ទៀងផ្ទាត់អត្តសញ្ញាណលំនាំដើមទេ។ --- ## Telemetry ```bash # ទទួលយកសេចក្តីសង្ខេប telemetry នៃ latency (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 key ទាំងអស់ 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" } ``` > **កំណត់សម្គាល់អំពី schema** (`setBudgetSchema`): `apiKeyId` គឺចាំបាច់; យ៉ាងហោចណាស់មួយក្នុងចំណោម `dailyLimitUsd`, `weeklyLimitUsd` ឬ `monthlyLimitUsd` ត្រូវតែធំជាងសូន្យ។ Field ជាជម្រើស៖ `warningThreshold` (0–1), `resetInterval` (`daily` | `weekly` | `monthly`), `resetTime` (`HH:MM`)។ រចនាសម្ព័ន្ធចាស់ `{keyId, limit, period}` ត្រឡប់ `400 Bad Request`។ ## ដែនកំណត់ Token កញ្ចប់ថវិកា **token** ក្នុងមួយ API key (ខុសពីថវិកាផ្អែកលើ USD ខាងលើ)។ ដែនកំណត់ទាំងនេះត្រូវបានអនុវត្តផ្ទាល់នៅលើផ្លូវសំណើ៖ នៅពេលការប្រើប្រាស់ក្នុងចន្លោះពេលបច្ចុប្បន្នរបស់ key មួយឈានដល់ដែនកំណត់របស់វា សំណើនឹងត្រូវបានបដិសេធដោយមានកូដ `429 Too Many Requests`។ ដែនកំណត់អាចកំណត់វិសាលភាពទៅលើ `model` ជាក់លាក់មួយ ឬ `provider` មួយ ឬអនុវត្តជា `global` នៅទូទាំង key នោះ។ នៅពេលដែនកំណត់ជាច្រើនត្រូវគ្នានឹងសំណើមួយ ដែនកំណត់ដែលតឹងរ៉ឹងបំផុតនឹងត្រូវបានអនុវត្ត។ ```bash # រាយដែនកំណត់ token របស់ key មួយ (រួមបញ្ចូលការប្រើប្រាស់ផ្ទាល់ក្នុងចន្លោះពេលបច្ចុប្បន្ន) GET /api/usage/token-limits?apiKeyId=key-123 # បង្កើត ឬធ្វើបច្ចុប្បន្នភាពដែនកំណត់ token POST /api/usage/token-limits Content-Type: application/json { "apiKeyId": "key-123", "scopeType": "model", "scopeValue": "openai/gpt-4o", "tokenLimit": 1000000, "resetInterval": "monthly", "enabled": true } # លុបដែនកំណត់ token តាម id DELETE /api/usage/token-limits?id=tl-abc ``` > **កំណត់សម្គាល់អំពី Schema** (`setTokenLimitSchema`)៖ `apiKeyId` និង `scopeType` (`model` | `provider` | `global`) គឺចាំបាច់។ `scopeValue` គឺចាំបាច់ លុះត្រាតែ `scopeType` ជា `global` (ឧ. model id សម្រាប់វិសាលភាព `model` ឬ provider id សម្រាប់វិសាលភាព `provider`)។ `tokenLimit` ត្រូវតែជាចំនួនគត់វិជ្ជមាន (បម្លែងពី string)។ ជម្រើស៖ `id` (មិនត្រូវបញ្ចូលដើម្បីបង្កើតថ្មី ហើយបញ្ចូលដើម្បីធ្វើបច្ចុប្បន្នភាព), `resetInterval` (`daily` | `weekly` | `monthly`, លំនាំដើម `monthly`), `resetTime` (`HH:MM`), `enabled` (លំនាំដើម `true`)។ ការឆ្លើយតបពី `GET` បន្ថែមព័ត៌មានទៅដែនកំណត់នីមួយៗដោយមាន `tokensUsed`, `remaining`, `windowStart`, `periodStartAt` និង `nextResetAt`។ នេះជា endpoint ប្រភេទគ្រប់គ្រង (ការផ្ទៀងផ្ទាត់សិទ្ធិត្រូវបានអនុវត្តជាកណ្ដាលដោយ authz pipeline)។ ## ដំណើរការសំណើ 1. Client ផ្ញើសំណើទៅកាន់ `/v1/*` 2. Route handler ហៅ `handleChat`, `handleEmbedding`, `handleAudioTranscription` ឬ `handleImageGeneration` 3. Model ត្រូវបានកំណត់ (provider/model ផ្ទាល់ ឬ alias/combo) 4. Credentials ត្រូវបានជ្រើសរើសពី DB មូលដ្ឋានដោយមានការចម្រោះតាមភាពអាចប្រើបានរបស់ account 5. សម្រាប់ chat៖ `handleChatCore` ពិនិត្យ semantic/signature cache និងកំណត់ការកំណត់ combo compression 6. Proactive compression ដំណើរការមុនការបកប្រែរបស់ provider នៅពេលបានបើកប្រើ (`lite`, Caveman, RTK ឬ stacked) 7. Provider executor ផ្ញើសំណើទៅ upstream 8. Response ត្រូវបានបកប្រែត្រឡប់ទៅជាទម្រង់របស់ client (chat) ឬត្រឡប់ដូចដើម (embeddings/images/audio) 9. Usage, compression analytics និង request logs ត្រូវបានកត់ត្រា 10. Fallback ត្រូវបានអនុវត្តនៅពេលមានកំហុស ស្របតាមច្បាប់ combo ឯកសារយោងអំពីស្ថាបត្យកម្មពេញលេញ៖ [`ARCHITECTURE.md`](../architecture/ARCHITECTURE.md) --- ## ការគ្រប់គ្រង Combo Routing combos កម្រិតខ្ពស់ (ដែលបានសង្ខេបរួចហើយនៅក្រោម `/api/combos*`) ក៏អាចត្រូវបានផ្គូផ្គងក្នុងសមាមាត្រ 1:1 ពីលំនាំ model id ផងដែរ ដែលអនុញ្ញាតឱ្យបង្វែរទិស model id បែប OpenAI ទៅកាន់ combo មួយដោយរលូន។ | វិធីសាស្ត្រ | ផ្លូវ | ការពិពណ៌នា | | ----------- | -------------------------------- | --------------------------------------------------------------------------------- | | GET | `/api/model-combo-mappings` | រាយការផ្គូផ្គង model→combo ទាំងអស់ | | POST | `/api/model-combo-mappings` | បង្កើតការផ្គូផ្គង — body៖ `{pattern, comboId, priority?, enabled?, description?}` | | GET | `/api/model-combo-mappings/[id]` | ទាញយកការផ្គូផ្គងតែមួយ | | PUT | `/api/model-combo-mappings/[id]` | ធ្វើបច្ចុប្បន្នភាព fields នៃការផ្គូផ្គងដែលមានស្រាប់ | | DELETE | `/api/model-combo-mappings/[id]` | លុបការផ្គូផ្គង | **Auth៖** management session/API key (`requireManagementAuth`)។ --- ## Webhooks ការជាវ webhook ចេញសម្រាប់ព្រឹត្តិការណ៍ OmniRoute (ការបញ្ចប់សំណើ ការប្រើកូតាអស់ ការប្ដូរសោ ជាដើម)។ | វិធីសាស្ត្រ | ផ្លូវ | សេចក្ដីពិពណ៌នា | | ----------- | ------------------------- | --------------------------------------------------------------------- | | GET | `/api/webhooks` | រាយបញ្ជី webhooks (សម្ងាត់ត្រូវបានបិទបាំងជា `...`) | | POST | `/api/webhooks` | បង្កើត webhook — body: `{url, events?: ["*"], secret?, description?}` | | GET | `/api/webhooks/[id]` | ទាញយក webhook មួយ | | PUT | `/api/webhooks/[id]` | ធ្វើបច្ចុប្បន្នភាព url/events/secret/description | | DELETE | `/api/webhooks/[id]` | លុប webhook មួយ | | POST | `/api/webhooks/[id]/test` | ផ្ញើ payload សាកល្បងទៅកាន់ URL របស់ webhook ហើយត្រឡប់ស្ថានភាពបញ្ជូន | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** សម័យគ្រប់គ្រង/API key (`requireManagementAuth`)។ --- ## សោដែលបានចុះបញ្ជី (ការគ្រប់គ្រងស្វ័យប្រវត្តិ) ត្រូវបានប្រើដោយប្រព័ន្ធរងគ្រប់គ្រងសោស្វ័យប្រវត្តិ ដើម្បីចេញ និងប្ដូរ API keys ជាមួយ provider/account គាំទ្រ ដោយមានកូតាប្រចាំថ្ងៃ/ប្រចាំម៉ោង។ | វិធីសាស្ត្រ | ផ្លូវ | សេចក្ដីពិពណ៌នា | | ----------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/v1/registered-keys` | រាយបញ្ជីសោដែលបានចុះបញ្ជី (បង្ហាញតែ prefix ដែលបានបិទបាំង) | | POST | `/api/v1/registered-keys` | ចេញសោដែលបានចុះបញ្ជីថ្មី — body: `{name, provider?, accountId?, idempotencyKey?, expiresAt?, dailyBudget?, hourlyBudget?}`។ ត្រឡប់សោដើមតែ **ម្តងប៉ុណ្ណោះ**។ ត្រឡប់ `429` នៅពេលកូតាបដិសេធ។ | | GET | `/api/v1/registered-keys/[id]` | ទាញយក metadata របស់សោដែលបានចុះបញ្ជី (គ្មានទិន្នន័យសោដើម) | | DELETE | `/api/v1/registered-keys/[id]` | ដកហូតសោដែលបានចុះបញ្ជី | | POST | `/api/v1/registered-keys/[id]/revoke` | endpoint សម្រាប់ដកហូតដោយជាក់លាក់ (មានប្រសិទ្ធភាពដូច DELETE) | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** Bearer API key (`isAuthenticated`)។ សូមមើលផងដែរ `/v1/quotas/check` និង `/v1/issues/report`។ --- ## ពិធីការភ្នាក់ងារ កិច្ចការភ្នាក់ងារ Cloud (Claude Code, Codex Cloud, OpenHands ជាដើម) ដែលត្រូវបានប្រតិបត្តិពីចម្ងាយជំនួសអ្នកប្រើប្រាស់ OmniRoute។ | វិធីសាស្ត្រ | ផ្លូវ | ការពិពណ៌នា | | ----------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | GET | `/api/v1/agents/tasks` | រាយបញ្ជីកិច្ចការ — ជម្រើស `?provider=`, `?status=`, `?limit=` (1–500, លំនាំដើម 50) | | POST | `/api/v1/agents/tasks` | បង្កើតកិច្ចការ — body ត្រូវបានផ្ទៀងផ្ទាត់ដោយ `CreateCloudAgentTaskSchema` (`providerId`, `prompt`, `source`, `options?`)។ ត្រឡប់ `201` ជាមួយ envelope របស់កិច្ចការ | | DELETE | `/api/v1/agents/tasks?id=...` | លុបកិច្ចការមួយ | | GET | `/api/v1/agents/tasks/[id]` | អានកិច្ចការ — ធ្វើបច្ចុប្បន្នភាពស្ថានភាពដោយសមកាលកម្មពីភ្នាក់ងារ Cloud ខាងលើ នៅពេលបានកំណត់ `external_id` | | POST | `/api/v1/agents/tasks/[id]` | សកម្មភាពដែលបែងចែកតាមប្រភេទ៖ `{action: "approve"}`, `{action: "message", message}` ឬ `{action: "cancel"}` | | DELETE | `/api/v1/agents/tasks/[id]` | លុបកិច្ចការជាក់លាក់មួយតាម id | > **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ៖** តម្រូវឱ្យមានការផ្ទៀងផ្ទាត់អត្តសញ្ញាណសម្រាប់ការគ្រប់គ្រងនៅគ្រប់វិធីសាស្ត្រ (`requireCloudAgentManagementAuth`)។ មុន v3.8.0 ផ្លូវទាំងនេះមិនតម្រូវឱ្យមានការផ្ទៀងផ្ទាត់អត្តសញ្ញាណទេ — សូមមើល commit `588a0333` សម្រាប់ការផ្លាស់ប្តូរដែលមិនឆបគ្នានេះ។ ```bash # បង្កើតកិច្ចការ Cloud របស់ 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":"..."}}' ``` --- ## ប្រូកស៊ីគ្រប់គ្រង ប្រូកស៊ី HTTP(S)/SOCKS សម្រាប់ចរាចរចេញ ដែលអាចផ្ដល់ទៅឱ្យអ្នកផ្ដល់សេវា គណនី ឬកំណត់ជាសកល។ | វិធីសាស្ត្រ | ផ្លូវ | ការពិពណ៌នា | | ----------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/v1/management/proxies` | រាយបញ្ជីប្រូកស៊ី (ជាមួយ `?id=` ត្រឡប់មួយ; ជាមួយ `?id=&where_used=1` ត្រឡប់ក្រាហ្វនៃការផ្ដល់) | | POST | `/api/v1/management/proxies` | បង្កើតប្រូកស៊ី — body ត្រូវបានផ្ទៀងផ្ទាត់ដោយ `createProxyRegistrySchema` | | PATCH | `/api/v1/management/proxies` | ធ្វើបច្ចុប្បន្នភាពប្រូកស៊ី — body ត្រូវបានផ្ទៀងផ្ទាត់ដោយ `updateProxyRegistrySchema` (តម្រូវឱ្យមាន `id`) | | DELETE | `/api/v1/management/proxies?id=...&force=1` | លុបប្រូកស៊ី (ប្រើ `force=1` ដើម្បីផ្ដាច់ការផ្ដល់) | | GET | `/api/v1/management/proxies/assignments` | រាយបញ្ជីការផ្ដល់ — អាចត្រងតាម `proxy_id`, `scope`, `scope_id`; បញ្ជូន `resolve_connection_id=` ដើម្បីកំណត់ប្រូកស៊ីសកម្មសម្រាប់ការតភ្ជាប់ | | PUT | `/api/v1/management/proxies/assignments` | ផ្ដល់ — body ត្រូវបានផ្ទៀងផ្ទាត់ដោយ `proxyAssignmentSchema` (`{scope, scopeId?, proxyId?}`)។ សម្អាតឃ្លាំងសម្ងាត់របស់ dispatcher | | PUT | `/api/v1/management/proxies/bulk-assign` | ផ្ដល់ជាច្រើនក្នុងពេលតែមួយ — body ត្រូវបានផ្ទៀងផ្ទាត់ដោយ `bulkProxyAssignmentSchema` (`{scope, scopeIds[], proxyId?}`) | | GET | `/api/v1/management/proxies/health?hours=24` | សរុបស្ថានភាពប្រូកស៊ី (ចំនួនជោគជ័យ/បរាជ័យ និងភាពយឺតយ៉ាវ) ក្នុងចន្លោះពេលមួយ | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ៖** session/API key សម្រាប់ការគ្រប់គ្រងនៅគ្រប់ route (`requireManagementAuth`)។ > `POST /api/v1/management/proxies/[id]/assignments` និង `POST /api/v1/management/proxies/[id]/health` ក្នុងការពិពណ៌នាកិច្ចការ ត្រូវបានបម្រើដោយ route រាបស្មើ `/assignments` និង `/health` ដែលបង្ហាញខាងលើ — មិនមាន subroute តាម id នៅក្នុង codebase ទេ។ --- ## ភាពធន់ (បន្ថែម) OmniRoute ផ្តល់យន្តការឯករាជ្យចំនួនបីសម្រាប់ការបរាជ័យបណ្ដោះអាសន្ន។ ចំណុចបញ្ចប់សម្រាប់ការគ្រប់គ្រងខាងក្រោមអនុញ្ញាតឱ្យប្រតិបត្តិករអាន និងកំណត់ពួកវាឡើងវិញ៖ | វិសាលភាព | កន្លែងផ្ទុកស្ថានភាព | អាន | កំណត់ឡើងវិញ / សម្អាត | | ----------------------------- | ------------------------------------------------ | ----------------------------------------- | ----------------------------------------------------------------------- | | ឧបករណ៍ផ្ដាច់របស់អ្នកផ្តល់សេវា | `domain_circuit_breakers` + ក្នុងអង្គចងចាំ | `/api/monitoring/health` | `POST /api/resilience/reset` | | រយៈពេលផ្អាកការតភ្ជាប់ | `rateLimitedUntil` លើការតភ្ជាប់របស់អ្នកផ្តល់សេវា | `/api/rate-limits`, `/api/providers/[id]` | (បើកដំណើរការឡើងវិញដោយស្វ័យប្រវត្តិនៅពេលប្រើ; សម្អាតតាមរយៈ provider 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) → "ស្ថានភាពពេលដំណើរការនៃភាពធន់"។ --- ## ជំនាញ ក្របខណ្ឌជំនាញសម្រាប់ពង្រីក OmniRoute ដោយប្រើកម្មវិធីដោះស្រាយដែលអាចប្រតិបត្តិបានតាមបំណង រួមទាំងការរួមបញ្ចូលជាមួយទីផ្សារផងដែរ។ | វិធីសាស្ត្រ | ផ្លូវ | ការពិពណ៌នា | | ----------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------- | | GET | `/api/skills` | រាយជំនាញដែលបានដំឡើង — អាចត្រងតាម `?q=`, `?mode=on\|off\|auto`, `?source=skillsmp\|skillssh\|local` និងបែងចែកជាទំព័រ | | GET | `/api/skills/[id]` | ទាញយកជំនាញមួយ | | PUT | `/api/skills/[id]` | ធ្វើបច្ចុប្បន្នភាពជំនាញ (ឈ្មោះ ការពិពណ៌នា របៀប schema កម្មវិធីដោះស្រាយ និងស្លាក) | | DELETE | `/api/skills/[id]` | លុបការដំឡើងជំនាញមួយ | | POST | `/api/skills/install` | ដំឡើងជំនាញពី manifest ដើម — body: `{name, version, description, schema:{input, output}, handlerCode, apiKeyId?}` | | GET | `/api/skills/executions` | រាយការប្រតិបត្តិជំនាញថ្មីៗ (កំណត់ត្រាសវនកម្មជាមួយធាតុបញ្ចូល/លទ្ធផល/រយៈពេល) | | GET | `/api/skills/marketplace?q=...` | ស្វែងរក/បញ្ជីពេញនិយមពីទីផ្សារ SkillsMP (តម្រូវឱ្យកំណត់ `skillsmpApiKey`) | | POST | `/api/skills/marketplace/install` | ដំឡើងជំនាញតាម id ពី SkillsMP | | GET | `/api/skills/skillssh?q=&limit=` | ស្វែងរកក្នុងបញ្ជីឈ្មោះ skills.sh | | POST | `/api/skills/skillssh/install` | ដំឡើងជំនាញតាម id ពី skills.sh | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ៖** សម័យគ្រប់គ្រង/API key។ ផ្លូវស្វែងរកទីផ្សារទទួលយកទាំងការផ្ទៀងផ្ទាត់អត្តសញ្ញាណសម្រាប់ការគ្រប់គ្រង ឬ Bearer API key (`isAuthenticated`)។ --- ## អង្គចងចាំ ឃ្លាំងផ្ទុកអង្គចងចាំសម្រាប់ការសន្ទនា/ការពិតដែលរក្សាទុកជាអចិន្ត្រៃយ៍ និងកំណត់វិសាលភាពតាម API key / session នីមួយៗ។ | វិធីសាស្ត្រ | ផ្លូវ | ការពិពណ៌នា | | ----------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------ | | GET | `/api/memory` | រាយបញ្ជីអង្គចងចាំ — `?apiKeyId=`, `?type=`, `?sessionId=`, `?q=`, ជាមួយការបែងចែកទំព័រដោយ `offset/limit` ឬ `page/limit` | | POST | `/api/memory` | បង្កើតអង្គចងចាំ — body ត្រូវបានផ្ទៀងផ្ទាត់ដោយ Zod៖ `{content, key, type?, sessionId?, apiKeyId?, metadata?, expiresAt?}` | | GET | `/api/memory/[id]` | ទាញយកអង្គចងចាំមួយ | | DELETE | `/api/memory/[id]` | លុបអង្គចងចាំមួយ | | GET | `/api/memory/health` | ស្ថានភាពសុខភាពរបស់ប្រព័ន្ធរងអង្គចងចាំ (ការតភ្ជាប់ DB, backend របស់ embeddings, ស្ថានភាព vector index) | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ៖** management session/API key (`requireManagementAuth`)។ enum `type`៖ `FACTUAL`, `EPISODIC`, `SEMANTIC`, `PROCEDURAL` (សូមមើល `MemoryType` ក្នុង `src/lib/memory/types.ts`)។ --- ## ម៉ាស៊ីនមេ MCP OmniRoute ភ្ជាប់មកជាមួយម៉ាស៊ីនមេ Model Context Protocol ដែលបានបង្កប់ ដោយមាន transport ចំនួន 3 (stdio, SSE, streamable-http) និង tools ដែលមានវិសាលភាពកំណត់។ endpoints របស់ dashboard ខាងក្រោមអានទិន្នន័យស្ថានភាព/សវនកម្ម និងធ្វើ proxy សម្រាប់ HTTP transports។ | វិធីសាស្ត្រ | ផ្លូវ | ការពិពណ៌នា | | ------ | ---------------------- | ------------------------------------------------------------------------------------------------ | -------------------- | | GET | `/api/mcp/status` | heartbeat, transport, ស្ថានភាព online, ការហៅចុងក្រោយ, tools ពេញនិយមបំផុត, អត្រាជោគជ័យក្នុងរយៈពេល 24 ម៉ោង | | GET | `/api/mcp/tools` | បញ្ជី MCP tools ដែលមាន `name`, `description`, `scopes`, `phase`, `auditLevel`, `sourceEndpoints` | | GET | `/api/mcp/sse` | បើក SSE stream សម្រាប់ SSE transport (ត្រឡប់ `503` ប្រសិនបើ MCP ត្រូវបានបិទ ឬ transport មិនត្រូវគ្នា) | | POST | `/api/mcp/sse` | ផ្ញើ JSON-RPC frame នៅលើ SSE transport | | GET | `/api/mcp/stream` | បើកផ្នែក SSE នៃ Streamable HTTP transport (សារដែលផ្ដើមដោយម៉ាស៊ីនមេ) | | POST | `/api/mcp/stream` | ផ្ញើ JSON-RPC frame នៅលើ Streamable HTTP transport | | DELETE | `/api/mcp/stream` | បញ្ចប់ Streamable HTTP session មួយ | | GET | `/api/mcp/audit` | សាកសួរកំណត់ហេតុសវនកម្ម — `?limit=`, `?offset=`, `?tool=`, `?success=true | false`, `?apiKeyId=` | | GET | `/api/mcp/audit/stats` | ស្ថិតិសវនកម្មសរុប (ចំនួនសរុប, អត្រាជោគជ័យ, រយៈពេលមធ្យម, tools ពេញនិយមបំផុត) | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ៖** transports `sse`/`stream` គោរពតាមផ្ទៃការផ្ទៀងផ្ទាត់អត្តសញ្ញាណជាក់លាក់របស់ MCP (Bearer API key ដែលមាន scope `mcp`); routes `status`/`tools`/`audit*` អាចអានបានពី dashboard (មិនតម្រូវឱ្យមានការផ្ទៀងផ្ទាត់អត្តសញ្ញាណបន្ថែម ក្រៅពីអាចចូលទៅដល់ dashboard host)។ > HTTP transports ទាំងពីរត្រូវបានគ្រប់គ្រងដោយ `settings.mcpEnabled` និង `settings.mcpTransport` — transport មិនត្រូវគ្នានឹងត្រឡប់ `400` ខណៈស្ថានភាពដែល MCP ត្រូវបានបិទនឹងត្រឡប់ `503`។ --- ## ម៉ាស៊ីនបម្រើ A2A OmniRoute ផ្តល់ endpoint A2A (Agent-to-Agent) JSON-RPC 2.0 រួមជាមួយ REST wrapper សម្រាប់ការត្រួតពិនិត្យ និងការប្រើប្រាស់ dashboard។ ### 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` | ដំណើរការ skill បែបសមកាលកម្ម; ត្រឡប់ `{task, artifacts, metadata}` | | `message/stream` | ដំណើរការ SSE បែប streaming សម្រាប់សំណុំ skill ដូចគ្នា | | `tasks/get` | ទាញយក task តាម `taskId` | | `tasks/cancel` | បោះបង់ task តាម `taskId` | skill ដែលមានស្រាប់៖ `smart-routing`, `quota-management`, `provider-discovery`, `cost-analysis`, `health-report`។ ### កាត Agent ```bash GET /.well-known/agent.json ``` ត្រឡប់កាត agent A2A សាធារណៈ (ឈ្មោះ ការពិពណ៌នា សមត្ថភាព បញ្ជី skill និងគ្រោងការណ៍ auth) — ត្រូវបាន cache ជាសាធារណៈរយៈពេល 1 ម៉ោង។ មិនតម្រូវឱ្យមាន auth ទេ។ ### ឧបករណ៍ជំនួយ REST | វិធីសាស្ត្រ | Path | ការពិពណ៌នា | | ----------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------ | | GET | `/api/a2a/status` | ស្ថានភាពបើក A2A + ស្ថិតិ task + សេចក្ដីសង្ខេបកាត agent ដែលបាន cache | | GET | `/api/a2a/tasks` | រាយបញ្ជី task — `?state=submitted\|working\|completed\|failed\|cancelled`, `?skill=`, `?limit=` (≤200), `?offset=` | | POST | `/api/a2a/tasks` | (មិនទាន់បានអនុវត្តជា REST helper ទេ — បង្កើតតាម JSON-RPC `message/send`) | | GET | `/api/a2a/tasks/[id]` | ទាញយក task មួយ | | POST | `/api/a2a/tasks/[id]/cancel` | បោះបង់ task មួយ | **Auth៖** REST helper ដំណើរការដោយមិនត្រូវការ management auth (dashboard អាចអានបាន); route JSON-RPC `/a2a` ប្រើ Bearer `OMNIROUTE_API_KEY` ប្រសិនបើបានកំណត់រចនាសម្ព័ន្ធ។ --- ## Cloud, Evals និង Assess | វិធីសាស្ត្រ | Path | ការពិពណ៌នា | | ------ | ------------------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------- | ----------------------------------- | | POST | `/api/cloud/auth` | ផ្ទៀងផ្ទាត់ Bearer key ហើយត្រឡប់ connection របស់ provider ដែលបានបិទបាំង + alias របស់ model សម្រាប់ client ធ្វើ cloud sync | | POST | `/api/cloud/credentials/update` | ធ្វើបច្ចុប្បន្នភាព credential ដែលបានអ៊ិនគ្រីបសម្រាប់ provider ដែលបាន sync ជាមួយ cloud | | POST | `/api/cloud/model/resolve` | កំណត់ model id ឡូជីខលទៅជា provider/model ជាក់លាក់ដោយប្រើតារាង routing មូលដ្ឋាន | | GET | `/api/cloud/models/alias` | រាយបញ្ជី alias របស់ model ដូចដែលបានបង្ហាញសម្រាប់ cloud sync | | GET | `/api/assess` | អានការចាត់ប្រភេទ assessment ចុងក្រោយបំផុត (តាម provider/model នីមួយៗ) | | POST | `/api/assess` | ដំណើរការ assessment មួយ — body៖ `{scope: {type:"all"} | {type:"provider", providerId} | {type:"model", modelId}, trigger?}` | | GET | `/api/evals` | រាយបញ្ជី eval suite ដែលមានស្រាប់ + ការដំណើរការថ្មីៗបំផុត | | POST | `/api/evals` | ចាប់ផ្ដើមការដំណើរការ eval | | POST | `/api/evals/suites` | បង្កើត eval suite ផ្ទាល់ខ្លួន — body ត្រូវបានផ្ទៀងផ្ទាត់ដោយ `evalSuiteSaveSchema` | | GET | `/api/evals/suites/[id]` | ទាញយក eval suite ផ្ទាល់ខ្លួនមួយ | **Auth៖** `/api/cloud/auth` ផ្ទៀងផ្ទាត់ Bearer key ដោយផ្ទាល់; route `/api/cloud/*`, `/api/evals/*` និង `/api/assess` ផ្សេងទៀត តម្រូវឱ្យមាន management session/API key។ POST `/api/assess` ប្រើ `validateBody` ជាមួយ schema scope ប្រភេទ discriminated-union។ --- ## ការគ្រប់គ្រង ACP (Agent Client Protocol) ជាដំណើរការរង។ Endpoint ទាំងនេះគ្រប់គ្រងការរកឃើញភ្នាក់ងារ ACP និងការចុះឈ្មោះភ្នាក់ងារផ្ទាល់ខ្លួន។ | វិធីសាស្ត្រ | ផ្លូវ | សេចក្តីពិពណ៌នា | | ----------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/acp/agents` | រាយបញ្ជីភ្នាក់ងារ CLI ដែលស្គាល់ទាំងអស់ (មានស្រាប់ + ផ្ទាល់ខ្លួន) ព្រមទាំងស្ថានភាពដំឡើង កំណែ និង binary | | POST | `/api/acp/agents` | ចុះឈ្មោះភ្នាក់ងារ ACP ផ្ទាល់ខ្លួន ឬធ្វើឱ្យ cache ស្រស់ឡើងវិញ — body: `{id, name, binary, versionCommand, providerAlias, spawnArgs, protocol}` ឬ `{action: "refresh"}` | | DELETE | `/api/acp/agents` | លុបភ្នាក់ងារ ACP ផ្ទាល់ខ្លួន — query param: `?id=` | **ឧទាហរណ៍ response** (`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 } ``` **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** តម្រូវឱ្យមាន management session (cookie `auth_token` របស់ dashboard) ឬ API key ដែលមាន scope សម្រាប់ការគ្រប់គ្រង។ សូមមើល [ACP Framework](../frameworks/ACP.md) សម្រាប់ព័ត៌មានលម្អិតពេញលេញ។ --- ## ការវិភាគ និងភាពអាចសង្កេតបាន Endpoint វិភាគតាមពេលវេលាជាក់ស្តែងសម្រាប់ត្រួតពិនិត្យ routing, compression និងភាពចម្រុះនៃ provider។ Endpoint ទាំងនេះផ្គត់ផ្គង់ទិន្នន័យដល់ទំព័រ `/dashboard/analytics/*`។ ### ការវិភាគ auto-routing | វិធីសាស្ត្រ | ផ្លូវ | សេចក្តីពិពណ៌នា | | ----------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------- | | GET | `/api/analytics/auto-routing` | ស្ថិតិ auto-routing សរុប៖ ចំនួន call សរុប ការបែងចែកតាមយុទ្ធសាស្ត្រ ការបែងចែកតាម tier និង provider កំពូល | | GET | `/api/analytics/auto-routing?days=7` | ស្ថិតិក្នុងចន្លោះពេលកំណត់ (លំនាំដើម 24h) | **ឧទាហរណ៍ response**: ```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 } ] } ``` ### ការវិភាគ compression | វិធីសាស្ត្រ | ផ្លូវ | សេចក្តីពិពណ៌នា | | ----------- | ---------------------------- | ---------------------------------------------------------------------------------------------------- | | GET | `/api/analytics/compression` | ស្ថិតិ compression សរុប៖ token ដែលបានសន្សំ ភាគរយនៃការសន្សំ ការបែងចែកតាម mode និងការប្រើប្រាស់ engine | **ឧទាហរណ៍ response**: ```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 } } ``` ### ការតាមដានភាពចម្រុះនៃ provider | វិធីសាស្ត្រ | ផ្លូវ | សេចក្តីពិពណ៌នា | | ----------- | -------------------------- | ------------------------------------------------------------------------------------------------- | | GET | `/api/analytics/diversity` | ការតាមដានភាពចម្រុះដោយផ្អែកលើ Shannon entropy៖ ការពារចំណុចបរាជ័យតែមួយដោយវាស់ការចែកចាយរបស់ provider | **ឧទាហរណ៍ response**: ```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"] } ``` **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** តម្រូវឱ្យមាន management session ឬ API key ដែលមាន scope សម្រាប់ការគ្រប់គ្រង។ --- ## ប្រតិបត្តិការរដ្ឋបាល Endpoint សម្រាប់តែអ្នកគ្រប់គ្រង ដើម្បីគ្រប់គ្រងប្រតិបត្តិការ។ | វិធីសាស្ត្រ | Path | ការពិពណ៌នា | | ----------- | ------------------------ | ------------------------------------------------------------------------------------------------------ | | GET | `/api/admin/concurrency` | អានកម្រិត concurrency បច្ចុប្បន្ន (ជាសកល + តាម provider នីមួយៗ) | | POST | `/api/admin/concurrency` | ធ្វើបច្ចុប្បន្នភាពកម្រិត concurrency — body: `{global?: number, perProvider?: Record}` | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** តម្រូវឱ្យមាន management session ដែលមាន admin scope។ --- ## ការគ្រប់គ្រងឧបករណ៍ CLI គ្រប់គ្រងឧបករណ៍ CLI ដែលរួមបញ្ចូលជាមួយ OmniRoute (antigravity, chipotle, commandCode, devin-cli ជាដើម)។ សូមមើល [ឯកសារយោងអំពី Provider](./PROVIDER_REFERENCE.md) សម្រាប់បញ្ជីពេញលេញ។ | វិធីសាស្ត្រ | Path | ការពិពណ៌នា | | ----------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GET | `/api/cli-tools/all-statuses` | ស្ថានភាពឧបករណ៍ CLI ទាំងអស់ (បានដំឡើង កំណែ និងពេលបានឃើញចុងក្រោយ) | | GET | `/api/cli-tools/status` | ព័ត៌មានលម្អិតអំពីស្ថានភាពរបស់ឧបករណ៍ CLI មួយ (`?tool=` query) | | POST | `/api/cli-tools/apply` | សរសេរ config ដែលបានបង្កើតរបស់ឧបករណ៍ (`dryRun` បង្ហាញជាមុន; `422` + `containerEphemeralTarget` នៅពេលដំណើរការក្នុង container; `migration` កត់សម្គាល់អំពី Codex YAML ចាស់) | | GET | `/api/cli-tools/backups` | រាយបញ្ជី backup នៃ configuration របស់ឧបករណ៍ CLI | | POST | `/api/cli-tools/backups` | បង្កើត backup នៃ configuration របស់ឧបករណ៍ CLI ទាំងអស់ | | POST | `/api/cli-tools/backups` | ស្ដារឡើងវិញ៖ endpoint ដូចគ្នាដែលមាន `{tool, backupId}` ក្នុង body នឹងស្ដារ backup នោះ | | GET | `/api/cli-tools/antigravity-mitm` | ស្ថានភាព proxy Antigravity MITM (ឧបករណ៍ CLI "antigravity-mitm") | | POST | `/api/cli-tools/antigravity-mitm/alias` | កំណត់រចនាសម្ព័ន្ធ alias របស់ antigravity-mitm | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** តម្រូវឱ្យមាន management session។ --- ## ជំនាញ Agent គ្រប់គ្រងជំនាញរបស់ AI agent (ស្រដៀងនឹង custom GPTs របស់ OpenAI ប៉ុន្តែសម្រាប់ agent)។ | វិធីសាស្ត្រ | Path | ការពិពណ៌នា | | ----------- | ---------------------------- | ----------------------------------------------------------------------------------------- | | GET | `/api/agent-skills` | រាយបញ្ជីជំនាញ agent ទាំងអស់ (មានស្រាប់ + ផ្ទាល់ខ្លួន) | | GET | `/api/agent-skills/[id]` | ទាញយកជំនាញ agent ជាក់លាក់មួយ | | POST | `/api/agent-skills` | បង្កើតជំនាញ agent ផ្ទាល់ខ្លួន — body: `{name, description, prompt, model?, temperature?}` | | PUT | `/api/agent-skills/[id]` | ធ្វើបច្ចុប្បន្នភាពជំនាញ agent ផ្ទាល់ខ្លួន | | DELETE | `/api/agent-skills/[id]` | លុបជំនាញ agent ផ្ទាល់ខ្លួន | | GET | `/api/agent-skills/[id]/raw` | ទាញយក prompt ដើម + metadata (មិនមានការប្រតិបត្តិ) | | POST | `/api/agent-skills/generate` | ប្រើ AI ដើម្បីបង្កើតជំនាញថ្មីពីការពិពណ៌នាជាភាសាធម្មជាតិ | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** តម្រូវឱ្យមាន management session ឬ API key ដែលមាន management scope។ --- ## ការគ្រប់គ្រងឃ្លាំងសម្ងាត់ គ្រប់គ្រងឃ្លាំងសម្ងាត់បែបអត្ថន័យ និងឃ្លាំងសម្ងាត់សម្រាប់ការវែកញែក។ | វិធីសាស្ត្រ | ផ្លូវ | ការពិពណ៌នា | | ----------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | 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 key ដែលមានវិសាលភាពគ្រប់គ្រង។ --- ## 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) សម្រាប់ប្រភេទព្រឹត្តិការណ៍ទាំងអស់។ --- ## ក្របខណ្ឌ Skills គ្រប់គ្រង Skills (ក្របខណ្ឌផ្នែកបន្ថែមបែប agentic)។ | វិធីសាស្ត្រ | ផ្លូវ | សេចក្ដីពិពណ៌នា | | ----------- | ------------------------ | ---------------------------------------------------------------------------- | | GET | `/api/skills` | រាយបញ្ជី skills ដែលបានដំឡើងទាំងអស់ (មានស្រាប់ + ផ្ទាល់ខ្លួន) | | POST | `/api/skills/install` | ដំឡើង skill ពីផ្លូវមូលដ្ឋាន ឬ URL | | DELETE | `/api/skills/[id]` | លុបការដំឡើង skill | | PUT | `/api/skills/[id]` | បើក ឬបិទ skill — body: `{enabled?: boolean, mode?: "on" \| "off" \| "auto"}` | | POST | `/api/skills/executions` | ប្រតិបត្តិ skill — body: `{skillName, apiKeyId, input?, sessionId?}` | | GET | `/api/skills/executions` | រាយប្រវត្តិការប្រតិបត្តិសម្រាប់ skills ទាំងអស់ (ត្រងតាម `?apiKeyId=`) | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** តម្រូវឱ្យមានសម័យគ្រប់គ្រង ឬ API key ដែលមានវិសាលភាពគ្រប់គ្រង។ សូមមើល [ក្របខណ្ឌ Skills](../frameworks/SKILLS.md) សម្រាប់ព័ត៌មានលម្អិតពេញលេញ។ --- ## Plugins គ្រប់គ្រង plugins របស់ OmniRoute (ផ្នែកបន្ថែមពីភាគីទីបី)។ | វិធីសាស្ត្រ | ផ្លូវ | សេចក្ដីពិពណ៌នា | | ----------- | ---------------------------------- | --------------------------------------------- | | GET | `/api/plugins` | រាយបញ្ជី plugins ដែលបានដំឡើង | | POST | `/api/plugins/marketplace/install` | ដំឡើង plugin ពី marketplace | | DELETE | `/api/plugins/[name]` | លុបការដំឡើង plugin | | POST | `/api/plugins/[name]/activate` | ធ្វើឱ្យ plugin សកម្ម | | POST | `/api/plugins/[name]/deactivate` | ធ្វើឱ្យ plugin អសកម្ម | | GET | `/api/plugins/[name]/config` | ទទួលយកការកំណត់រចនាសម្ព័ន្ធ plugin | | PUT | `/api/plugins/[name]/config` | ធ្វើបច្ចុប្បន្នភាពការកំណត់រចនាសម្ព័ន្ធ plugin | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** តម្រូវឱ្យមានសម័យគ្រប់គ្រង។ សូមមើល [ក្របខណ្ឌ Plugins](../frameworks/PLUGIN_SDK.md) សម្រាប់ព័ត៌មានលម្អិតពេញលេញ។ --- ## Shadow Routing ការប្រៀបធៀបអ្នកផ្ដល់សេវាតាម Shadow / A-B **មិនមែនជា REST surface ឯករាជ្យទេ** — វាត្រូវបានកំណត់រចនាសម្ព័ន្ធតាមរយៈ combo routing (សូមមើល [Auto-Combo](../routing/AUTO-COMBO.md))។ រង្វាស់ប្រៀបធៀបតាម combo នីមួយៗត្រូវបានផ្ដល់ដោយ `GET /api/combos/metrics`។ --- ## Guardrails ពិនិត្យមើល guardrails ពេលដំណើរការ (ការរកឃើញ PII, ការរកឃើញការបញ្ចូល prompt និង vision bridging)។ Guardrails ដំណើរការលើគ្រប់សំណើទាំងអស់។ ការដកខ្លួនចេញសម្រាប់ការហៅនីមួយៗធ្វើឡើងតាម request header `x-omniroute-disabled-guardrails` — មិនមានចំណុចប្រទាក់សម្រាប់រក្សាទុកការបើក/បិទទេ។ | វិធីសាស្ត្រ | ផ្លូវ | សេចក្ដីពិពណ៌នា | | ----------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------- | | GET | `/api/guardrails` | រាយបញ្ជី guardrails ដែលបានចុះបញ្ជី និងស្ថានភាពរបស់ពួកវា (ឈ្មោះ / បានបើក / អាទិភាព) | | POST | `/api/guardrails/test` | ដំណើរការសាកល្បងដោយមិនអនុវត្តជាក់ស្ដែងលើ pipeline មុនពេលហៅ ដោយប្រើ input គំរូ — body: `{input, disabledGuardrails?}` | **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ:** តម្រូវឱ្យមានសម័យគ្រប់គ្រង។ សូមមើល [សុវត្ថិភាព > Guardrails](../security/GUARDRAILS.md) សម្រាប់ព័ត៌មានលម្អិតពេញលេញ។ --- --- ## ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ សូមមើល [ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណសម្រាប់ការគ្រប់គ្រង](../guides/MANAGEMENT-AUTH.md) សម្រាប់ព័ត៌មានអំពីព័ត៌មានសម្ងាត់ទាំងបួនប្រភេទ (សម័យ dashboard, token របស់ CLI មូលដ្ឋាន, `oma_live_…` Access Token និង API key ដែលមានវិសាលភាពគ្រប់គ្រង) និងភាពខុសគ្នារបស់ពួកវាពី inference keys។ - ផ្លូវ dashboard (`/dashboard/*`) ប្រើ cookie `auth_token` - ការចូលប្រើប្រើ hash ពាក្យសម្ងាត់ដែលបានរក្សាទុក; បើមិនអាចប្រើបាន វានឹងប្រើ `INITIAL_PASSWORD` - អាចបិទបើក `requireLogin` តាមរយៈ `/api/settings/require-login` - ផ្លូវ `/v1/*` អាចតម្រូវឱ្យមាន Bearer API key នៅពេល `REQUIRE_API_KEY=true` - "management token" / "management-scoped API key" នៅក្នុងឯកសារយោងនេះ សំដៅលើប្រភេទណាមួយក្នុងចំណោមប្រភេទដែលមាននៅក្នុងមគ្គុទ្ទេសក៍នោះ — មិនមែនជាប្រភេទព័ត៌មានសម្ងាត់បន្ថែមដែលមិនបានកំណត់នោះទេ > **ការផ្លាស់ប្តូរដែលប៉ះពាល់ដល់ភាពត្រូវគ្នា (v3.8.0)** — `/api/v1/agents/tasks/*` និងចំណុចចុងសម្រាប់ការគ្រប់គ្រង cooldown ឥឡូវនេះតម្រូវឱ្យមាន **ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណសម្រាប់ការគ្រប់គ្រង** (cookie `auth_token` របស់ dashboard ឬ API key ដែលមានវិសាលភាពគ្រប់គ្រង)។ កម្មវិធីភ្ញៀវដែលពីមុនបានហៅផ្លូវទាំងនេះដោយគ្មានការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ នឹងទទួលបាន `401 Unauthorized`។ សូមមើល commit `588a0333` (`fix(auth): require management auth for agent and cooldown APIs`)។