# Remote Mode (ខ្មែរ) 🌐 **Languages:** 🇺🇸 [English](../../../../guides/REMOTE-MODE.md) · 🇪🇹 [am](../../../am/docs/guides/REMOTE-MODE.md) · 🇸🇦 [ar](../../../ar/docs/guides/REMOTE-MODE.md) · 🇦🇿 [az](../../../az/docs/guides/REMOTE-MODE.md) · 🇧🇬 [bg](../../../bg/docs/guides/REMOTE-MODE.md) · 🇧🇩 [bn](../../../bn/docs/guides/REMOTE-MODE.md) · 🇧🇦 [bs](../../../bs/docs/guides/REMOTE-MODE.md) · 🇨🇿 [cs](../../../cs/docs/guides/REMOTE-MODE.md) · 🇩🇰 [da](../../../da/docs/guides/REMOTE-MODE.md) · 🇩🇪 [de](../../../de/docs/guides/REMOTE-MODE.md) · 🇬🇷 [el](../../../el/docs/guides/REMOTE-MODE.md) · 🇪🇸 [es](../../../es/docs/guides/REMOTE-MODE.md) · 🇪🇪 [et](../../../et/docs/guides/REMOTE-MODE.md) · 🇮🇷 [fa](../../../fa/docs/guides/REMOTE-MODE.md) · 🇫🇮 [fi](../../../fi/docs/guides/REMOTE-MODE.md) · 🇫🇷 [fr](../../../fr/docs/guides/REMOTE-MODE.md) · 🇮🇪 [ga](../../../ga/docs/guides/REMOTE-MODE.md) · 🇮🇳 [gu](../../../gu/docs/guides/REMOTE-MODE.md) · 🇳🇬 [ha](../../../ha/docs/guides/REMOTE-MODE.md) · 🇮🇱 [he](../../../he/docs/guides/REMOTE-MODE.md) · 🇮🇳 [hi](../../../hi/docs/guides/REMOTE-MODE.md) · 🇭🇷 [hr](../../../hr/docs/guides/REMOTE-MODE.md) · 🇭🇺 [hu](../../../hu/docs/guides/REMOTE-MODE.md) · 🇦🇲 [hy](../../../hy/docs/guides/REMOTE-MODE.md) · 🇮🇩 [id](../../../id/docs/guides/REMOTE-MODE.md) · 🇳🇬 [ig](../../../ig/docs/guides/REMOTE-MODE.md) · 🇮🇹 [it](../../../it/docs/guides/REMOTE-MODE.md) · 🇯🇵 [ja](../../../ja/docs/guides/REMOTE-MODE.md) · 🇬🇪 [ka](../../../ka/docs/guides/REMOTE-MODE.md) · 🇮🇳 [kn](../../../kn/docs/guides/REMOTE-MODE.md) · 🇰🇷 [ko](../../../ko/docs/guides/REMOTE-MODE.md) · 🇱🇹 [lt](../../../lt/docs/guides/REMOTE-MODE.md) · 🇱🇻 [lv](../../../lv/docs/guides/REMOTE-MODE.md) · 🇮🇳 [ml](../../../ml/docs/guides/REMOTE-MODE.md) · 🇮🇳 [mr](../../../mr/docs/guides/REMOTE-MODE.md) · 🇲🇾 [ms](../../../ms/docs/guides/REMOTE-MODE.md) · 🇲🇹 [mt](../../../mt/docs/guides/REMOTE-MODE.md) · 🇲🇲 [my](../../../my/docs/guides/REMOTE-MODE.md) · 🇳🇵 [ne](../../../ne/docs/guides/REMOTE-MODE.md) · 🇳🇱 [nl](../../../nl/docs/guides/REMOTE-MODE.md) · 🇳🇴 [no](../../../no/docs/guides/REMOTE-MODE.md) · 🇮🇳 [or](../../../or/docs/guides/REMOTE-MODE.md) · 🇮🇳 [pa](../../../pa/docs/guides/REMOTE-MODE.md) · 🇵🇭 [phi](../../../phi/docs/guides/REMOTE-MODE.md) · 🇵🇱 [pl](../../../pl/docs/guides/REMOTE-MODE.md) · 🇵🇹 [pt](../../../pt/docs/guides/REMOTE-MODE.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/guides/REMOTE-MODE.md) · 🇷🇴 [ro](../../../ro/docs/guides/REMOTE-MODE.md) · 🇷🇺 [ru](../../../ru/docs/guides/REMOTE-MODE.md) · 🇱🇰 [si](../../../si/docs/guides/REMOTE-MODE.md) · 🇸🇰 [sk](../../../sk/docs/guides/REMOTE-MODE.md) · 🇸🇮 [sl](../../../sl/docs/guides/REMOTE-MODE.md) · 🇷🇸 [sr](../../../sr/docs/guides/REMOTE-MODE.md) · 🇸🇪 [sv](../../../sv/docs/guides/REMOTE-MODE.md) · 🇰🇪 [sw](../../../sw/docs/guides/REMOTE-MODE.md) · 🇮🇳 [ta](../../../ta/docs/guides/REMOTE-MODE.md) · 🇮🇳 [te](../../../te/docs/guides/REMOTE-MODE.md) · 🇹🇭 [th](../../../th/docs/guides/REMOTE-MODE.md) · 🇹🇷 [tr](../../../tr/docs/guides/REMOTE-MODE.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/guides/REMOTE-MODE.md) · 🇵🇰 [ur](../../../ur/docs/guides/REMOTE-MODE.md) · 🇺🇿 [uz](../../../uz/docs/guides/REMOTE-MODE.md) · 🇻🇳 [vi](../../../vi/docs/guides/REMOTE-MODE.md) · 🇳🇬 [yo](../../../yo/docs/guides/REMOTE-MODE.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/guides/REMOTE-MODE.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/guides/REMOTE-MODE.md) --- ដំណើរការ CLI `omniroute` នៅលើកុំព្យូទ័រយួរដៃរបស់អ្នក ខណៈដែល OmniRoute ដំណើរការនៅកន្លែងផ្សេង (VPS, ម៉ាស៊ីនមេនៅផ្ទះ ឬម៉ាស៊ីនមួយផ្សេងទៀតនៅលើ Tailnet របស់អ្នក)។ អ្នកចូលប្រើតែម្តងដោយប្រើ `omniroute connect` ហើយចាប់ពីពេលនោះតទៅ ពាក្យបញ្ជា CLI **ទាំងអស់** នឹងកំណត់គោលដៅទៅកាន់ម៉ាស៊ីនមេពីចម្ងាយនោះ — ពាក្យបញ្ជាដូចគ្នា លទ្ធផលដូចគ្នា គ្រាន់តែប្រតិបត្តិប្រឆាំងនឹងម៉ាស៊ីនមេពីចម្ងាយប៉ុណ្ណោះ។ មិនមានឧបករណ៍ទីពីរដែលត្រូវដំឡើងទេ៖ របៀបពីចម្ងាយគឺជា CLI `omniroute` ធម្មតា បូកនឹង **ថូខឹនចូលប្រើ** ដែលមានវិសាលភាពកំណត់។ ```bash npm install -g omniroute # CLI ធម្មតា omniroute connect 192.168.0.15 # ចូលប្រើ (ពាក្យសម្ងាត់ → ថូខឹនមានវិសាលភាពកំណត់) omniroute models list # ← ឥឡូវនេះរាយម៉ូដែលរបស់ម៉ាស៊ីនមេពីចម្ងាយ omniroute configure codex # ← សរសេរប្រូហ្វាល់ Codex មូលដ្ឋានពីកាតាឡុកពីចម្ងាយ ``` --- ## របៀបដែលវាដំណើរការ ``` កុំព្យូទ័រយួរដៃរបស់អ្នក OmniRoute ពីចម្ងាយ (VPS) ┌────────────────────┐ ┌───────────────────────────────┐ │ omniroute CLI │ POST /api/cli/connect (ពាក្យសម្ងាត់ → ថូខឹន) │ │ បរិបទ៖ vps │ ───────────────► │ បង្កើតថូខឹនចូលប្រើមានវិសាលភាពកំណត់ │ │ baseUrl, token │ Authorization: Bearer oma_live_… │ │ │ ───────────────► │ គ្រប់ route គ្រប់គ្រង ត្រូវបានពិនិត្យ │ │ សរសេរការកំណត់រចនាសម្ព័ន្ធ │ ◄─────────────── │ តាមវិសាលភាពរបស់ថូខឹន │ │ នៅក្នុងម៉ាស៊ីនមូលដ្ឋាន │ └───────────────────────────────┘ └────────────────────┘ ``` - **បរិបទ** នីមួយៗរក្សាទុកម៉ាស៊ីនមេមួយ (`~/.omniroute/config.json`, `chmod 600`)។ `omniroute contexts use ` ប្តូរម៉ាស៊ីនមេដែលកំពុងសកម្ម។ `default` គឺជាម៉ាស៊ីនមូលដ្ឋាន។ - **ថូខឹនចូលប្រើ** (`oma_live_…`) ផ្តល់សិទ្ធិដល់ពាក្យបញ្ជាគ្រប់គ្រង។ ពួកវា ខុសពីកូនសោ API សម្រាប់ inference (`sk-…` ដែលប្រើសម្រាប់ `/v1/chat/completions`)។ - មានតែ hash SHA-256 របស់ថូខឹនប៉ុណ្ណោះដែលត្រូវបានរក្សាទុកនៅខាងម៉ាស៊ីនមេ។ អត្ថបទធម្មតាត្រូវបានបង្ហាញ **តែម្តងគត់** នៅពេលបង្កើត។ --- ## ការតភ្ជាប់ ### ជាមួយពាក្យសម្ងាត់គ្រប់គ្រង (ការចាប់ផ្ដើមដំបូង) ```bash omniroute connect 192.168.0.15 # ពាក្យសម្ងាត់គ្រប់គ្រងសម្រាប់ http://192.168.0.15:20128: ******** # ✔ បានតភ្ជាប់ទៅ http://192.168.0.15:20128 — បរិបទ '192.168.0.15' (វិសាលភាព៖ admin) ``` លំហូរដែលប្រើពាក្យសម្ងាត់នឹងបង្កើតថូខឹន **admin** តាមលំនាំដើម (អ្នកកាន់ពាក្យសម្ងាត់ ដូច្នេះ អ្នកមានការគ្រប់គ្រងពេញលេញរួចហើយ)។ បន្ថយវិសាលភាពដោយប្រើ `--scope`៖ ```bash omniroute connect 192.168.0.15 --scope write ``` ជម្រើស៖ `--port

` (នៅពេល host មិនមាន port), `--name ` (ឈ្មោះបរិបទ), `--scope read|write|admin`។ URL ពេញលេញត្រូវបានគោរពតាមដូចដែលបានផ្តល់៖ `omniroute connect https://omni.example.com`។ ### ជាមួយថូខឹនដែលបានបង្កើតជាមុន បង្កើតថូខឹនមានវិសាលភាពកំណត់នៅក្នុង dashboard (ឬដោយប្រើ `omniroute tokens create`) ហើយ បិទភ្ជាប់វា — មិនត្រូវការពាក្យសម្ងាត់ទេ៖ ```bash omniroute connect 192.168.0.15 --key oma_live_xxxxxxxx ``` CLI ផ្ទៀងផ្ទាត់វាតាមរយៈ `GET /api/cli/whoami` ហើយរក្សាទុកវាជាបរិបទសកម្ម។ --- ## វិសាលភាព មានបីកម្រិត តាមឋានានុក្រម (`admin ⊃ write ⊃ read`)៖ | វិសាលភាព | អាចធ្វើបាន | | -------- | ------------------------------------------------------------------------------------- | | `read` | រាយ/ត្រួតពិនិត្យ — `models list`, `providers status`, `logs`, `usage`, `cost` | | `write` | read **+** កំណត់រចនាសម្ព័ន្ធ/អនុវត្ត — `setup-codex`, `keys add`, `config set`, បន្សំ | | `admin` | write **+** គ្រប់គ្រង — CRUD របស់ `tokens`, បន្ថែម providers, services, policy, oauth | ម៉ាស៊ីនមេកំណត់វិសាលភាពដែល route នីមួយៗត្រូវការ ដោយផ្អែកលើ HTTP method (`GET`→read, ការកែប្រែ→write) បូកនឹងបញ្ជីអនុញ្ញាត admin សម្រាប់ផ្នែកសំខាន់ៗ (`/api/cli/tokens`, ការកែប្រែ `/api/providers`, `/api/oauth`, `/api/services`, …)។ ថូខឹនដែលមានវិសាលភាពមិនគ្រប់គ្រាន់នឹងទទួលបាន `403` ជាមួយសារច្បាស់លាស់។ > Routes ដែលបង្កើត process (`/api/services/*`, `/api/mcp/*`, …) នៅតែ > **អាចចូលប្រើបានតែពី loopback** — ថូខឹនពីចម្ងាយមិនអាចចូលដល់ពួកវាបានឡើយ ទោះមានវិសាលភាពកម្រិតណាក៏ដោយ។ --- ## ការតភ្ជាប់ Antigravity លើការដំឡើងពីចម្ងាយ Antigravity ប្រើអេក្រង់យល់ព្រម firstparty/nativeapp របស់ Google។ Google បញ្ចេញ កូដអនុញ្ញាតតែនៅពេលដែល **loopback redirect** (`http://127.0.0.1:/callback`) **អាចចូលដំណើរការបានពីកម្មវិធីរុករកដែល អនុម័តការចូលគណនី**។ លើការដំឡើង VPS ពីចម្ងាយ loopback នោះស្ថិតនៅលើ ម៉ាស៊ីនមេ មិនមែនលើម៉ាស៊ីនរបស់អ្នកទេ ដូច្នេះអេក្រង់យល់ព្រម **ជាប់គាំងជារៀងរហូត និងមិន បញ្ចេញកូដឡើយ** — ជម្រើសបម្រុងធម្មតា "បិទភ្ជាប់ callback URL" គ្មានអ្វីសម្រាប់ បិទភ្ជាប់ទេ។ (នេះជាកំហិតពីខាង Google៖ ការជាប់គាំងដូចគ្នានេះកើតឡើងនៅក្នុង proxy ណាមួយដែលប្រើ bundled Antigravity desktop client មិនមែនតែ OmniRoute ប៉ុណ្ណោះទេ។) ផ្ទាំងគ្រប់គ្រងរកឃើញបញ្ហានេះមុនពេលអ្នកជាប់គាំង៖ ការបើក **Providers → Antigravity → Connect** ពីអាសយដ្ឋានដែលមិនមែនជា localhost នឹងជំនួសសេចក្តីជូនដំណឹងទូទៅ "ចម្លង callback URL" ដោយដំណោះស្រាយពីរខាងក្រោម ដែលដំណោះស្រាយនីមួយៗបានបំពេញ host និង port របស់អ្នករួចជាស្រេច។ (អាសយដ្ឋាន LAN ក៏ត្រូវបានរាប់បញ្ចូលដែរ — `192.168.x.x` មិនមែនជា localhost ទេ សម្រាប់ callback នេះ។) មានវិធីដែលគាំទ្រចំនួនពីរ ដើម្បីតភ្ជាប់ Antigravity ទៅកាន់ OmniRoute ពីចម្ងាយ។ ### ជម្រើស A — កម្មវិធីជំនួយចូលគណនីក្នុងម៉ាស៊ីនមូលដ្ឋាន (បានណែនាំ) ដំណើរការ OAuth លើ **កុំព្យូទ័ររបស់អ្នកផ្ទាល់** ដែលអាចចូលដំណើរការ `127.0.0.1` បាន។ កម្មវិធីជំនួយ ទាក់ទងជាមួយ Google ដោយផ្ទាល់ ដូច្នេះការយល់ព្រមអាចបញ្ចប់នៅទីដែលកំណែរបស់ផ្ទាំងគ្រប់គ្រង មិនអាចធ្វើបាន។ **ប្រសិនបើអ្នកបានតភ្ជាប់រួចហើយ** (`omniroute connect `) អ្នកមិនចាំបាច់ ចម្លងអ្វីទេ — កម្មវិធីជំនួយបញ្ជូនព័ត៌មានសម្គាល់ទៅកាន់ការដំឡើងនោះឱ្យអ្នក៖ ```bash # លើម៉ាស៊ីន LOCAL របស់អ្នក (ត្រូវការ Node.js + កម្មវិធីរុករក)៖ omniroute connect 192.168.0.15 # ម្តង — បង្កើត context token ដែលមានវិសាលភាពជា admin npx omniroute login antigravity # ↳ បើកការយល់ព្រមរបស់ Google ចាប់យក callback លើ loopback port មូលដ្ឋាន # ប្តូរវា និង POST ព័ត៌មានសម្គាល់ទៅកាន់ context ដែលកំពុងសកម្ម៖ # # Antigravity បានតភ្ជាប់នៅលើ http://192.168.0.15:20128 (ការតភ្ជាប់ abc123)។ # មិនចាំបាច់បិទភ្ជាប់អ្វីទេ — អ្នកអាចបិទ terminal នេះបាន។ ``` ការបញ្ជូនកើតឡើងដោយស្វ័យប្រវត្តិ នៅពេលណាដែល context សកម្មចង្អុលទៅម៉ាស៊ីនផ្សេង។ បង្ខំវាតាមទិសណាមួយដោយប្រើ `--push` / `--no-push` ឬកំណត់គោលដៅទៅ context ជាក់លាក់ ដោយប្រើ `--context `។ **ប្រសិនបើម៉ាស៊ីនរបស់អ្នកមិនអាចចូលដំណើរការ VPS បាន** (ត្រូវបានរារាំងដោយ firewall គ្មាន SSH ឬតុការងារដែលផ្តាច់ពីបណ្តាញ) កម្មវិធីជំនួយនៅតែដំណើរការ — វា _ត្រូវការ_ តែ Google ប៉ុណ្ណោះ។ ប្រើ `--no-push` ឬគ្រាន់តែអនុញ្ញាតឱ្យការបញ្ជូនបរាជ័យ៖ វានឹងត្រឡប់ទៅបោះពុម្ព blob ជំនួសឱ្យការបោះបង់ការអនុញ្ញាតដែលអ្នកបានបញ្ចប់រួចហើយ។ ```bash npx omniroute login antigravity --no-push # omniroute-cred-v1.eyJ2IjoxLCJ... ``` បន្ទាប់មក នៅក្នុងផ្ទាំងគ្រប់គ្រង **ពីចម្ងាយ**៖ **Providers → Antigravity → Connect** ហើយបិទភ្ជាប់ blob `omniroute-cred-v1.…` ទៅក្នុងវាល **Step 2** (វាទទួលយកទាំង callback URL ឬ credential blob)។ OmniRoute ឌិកូដវា ដំណើរការ Cloud Code onboarding នៅខាងម៉ាស៊ីនមេ និងរក្សាទុកការតភ្ជាប់។ > blob មាន refresh token — ចាត់ទុកវាដូចជាពាក្យសម្ងាត់។ តាមផ្លូវបញ្ជូន វា > ត្រូវបានផ្ញើម្តងតាមការតភ្ជាប់ដែលបានផ្ទៀងផ្ទាត់របស់ context អ្នក ហើយតាមផ្លូវបិទភ្ជាប់ វាត្រូវបានផ្ញើតាម > ការតភ្ជាប់ផ្ទាំងគ្រប់គ្រងរបស់អ្នក។ មិនថាតាមវិធីណាក៏ដោយ វាត្រូវបានរក្សាទុកដោយអ៊ិនគ្រីបនៅពេលសម្រាក ហើយ > ការបញ្ជូនដែលជោគជ័យមិនបោះពុម្ពវាទៅកាន់ terminal របស់អ្នកឡើយ។ Flags៖ `--no-browser` (បោះពុម្ព URL ជំនួសឱ្យការបើកដោយស្វ័យប្រវត្តិ), `--port ` (កំណត់ loopback port), `--timeout `, `--push` / `--no-push` (សរសេរជាន់លើ ការបញ្ជូនដោយស្វ័យប្រវត្តិ), `--context ` (កំណត់គោលដៅទៅ context ជាក់លាក់)។ ### ជម្រើស B — SSH local-forward tunnel ប្រសិនបើអ្នកមានសិទ្ធិចូលប្រើ SSH ទៅកាន់ VPS សូមបញ្ជូនបន្ត port របស់ផ្ទាំងគ្រប់គ្រង ដើម្បីឱ្យ loopback callback ត្រូវបានបញ្ជូនត្រឡប់ទៅម៉ាស៊ីនមេតាម tunnel៖ ```bash # លើម៉ាស៊ីន LOCAL របស់អ្នក៖ ssh -L 20128:127.0.0.1:20128 user@your-vps # បន្ទាប់មកបើក http://localhost:20128 ក្នុងកម្មវិធីរុករក LOCAL របស់អ្នក ហើយតភ្ជាប់ Antigravity # តាមធម្មតា — ឥឡូវនេះ 127.0.0.1:20128/callback redirect អាចទៅដល់ VPS តាមរយៈ SSH។ ``` ដោយសារអ្នកចូលទៅកាន់ផ្ទាំងគ្រប់គ្រងជា `localhost:20128` ការយល់ព្រមរបស់ Google នឹងបញ្ចប់ ហើយ callback ត្រូវបានបញ្ជូនទៅម៉ាស៊ីនមេតាម tunnel ដដែល — មិនត្រូវការ blob ទេ។ ទុក tunnel ឱ្យបើករហូតដល់ការតភ្ជាប់បង្ហាញថាសកម្ម។ ខុសពី providers ដែលមាន fixed-loopback ខាងក្រោម **ការបញ្ជូនបន្តតែមួយគឺគ្រប់គ្រាន់** នៅទីនេះ៖ callback របស់ Antigravity ប្រើ port របស់ផ្ទាំងគ្រប់គ្រងផ្ទាល់ ដូច្នេះមិនមាន port ទីពីរដែលជាក់លាក់សម្រាប់ provider ដើម្បីធ្វើ tunnel ទេ។ > ជម្រើស headless ពេញលេញ (គ្មានកម្មវិធីជំនួយ គ្មាន tunnel) គឺកំណត់រចនាសម្ព័ន្ធព័ត៌មានសម្គាល់ > Google OAuth web **ផ្ទាល់ខ្លួន** របស់អ្នក + base URL សាធារណៈ។ សូមមើល environment variables > OAuth របស់ provider។ ជម្រើសពីរខាងលើមិនត្រូវការការដំឡើង Google បន្ថែមទេ។ --- ## ការភ្ជាប់ Codex / Grok លើការដំឡើងពីចម្ងាយ (អ្នកផ្តល់សេវាដែលប្រើ loopback ថេរ) Codex, xAI (`xai-oauth`) និង Grok CLI (`grok-cli`) ចុះឈ្មោះ `redirect_uri` ជា loopback **ថេរ** ជាមួយកម្មវិធី OAuth ដើមរបស់ពួកគេ។ OmniRoute មិនអាចផ្លាស់ប្តូរវាបានទេ — អ្នកផ្តល់សេវាតែងតែបញ្ជូនកម្មវិធីរុករកត្រឡប់ទៅអាសយដ្ឋានដែលបានកំណត់ថេរដូចគ្នា៖ | អ្នកផ្តល់សេវា | callback ថេរដែលអ្នកផ្តល់សេវាបញ្ជូនបន្តទៅ | | ------------- | ---------------------------------------- | | `codex` | `http://localhost:1455/auth/callback` | | `xai-oauth` | `http://127.0.0.1:56121/callback` | | `grok-cli` | `http://127.0.0.1:56122/callback` | `localhost` នៅទីនោះសំដៅលើ **ម៉ាស៊ីនដែលកំពុងដំណើរការកម្មវិធីរុករក** ខណៈដែលម៉ាស៊ីនមេ callback PKCE របស់ OmniRoute ស្តាប់នៅលើ loopback របស់ **ម៉ាស៊ីនមេ**។ បើកផ្ទាំងគ្រប់គ្រងនៅអាសយដ្ឋាន LAN ដូចជា `http://192.168.0.15:20128` នោះទាំងពីរនឹងមិនអាចភ្ជាប់គ្នាបានទេ៖ កូដអនុញ្ញាតត្រូវបានបញ្ជូនទៅ `localhost:1455` របស់កុំព្យូទ័រយួរដៃផ្ទាល់ខ្លួនរបស់អ្នក ដែលគ្មានអ្វីកំពុងស្តាប់ ហើយអ្នកផ្តល់សេវានឹងបរាជ័យក្នុងការចូលដោយមិនបង្ហាញកំហុស។ ផ្ទាំងគ្រប់គ្រងរកឃើញបញ្ហានេះមុនពេលបើកផ្ទាំងលេចឡើង ហើយបង្ហាញពាក្យបញ្ជា tunnel ជំនួសឱ្យការអនុញ្ញាតឱ្យការចូលបរាជ័យដោយស្ងៀមស្ងាត់ (#8046)។ ### ដំណោះស្រាយ — បញ្ជូនបន្តច្រក **ទាំងពីរ** ```bash # នៅលើម៉ាស៊ីនដែលកំពុងដំណើរការកម្មវិធីរុករក៖ ssh -L 20128:127.0.0.1:20128 -L 1455:127.0.0.1:1455 @192.168.0.15 # បន្ទាប់មកចូលទៅ http://localhost:20128 ហើយភ្ជាប់ Codex ពីទីនោះ ``` ត្រូវការការបញ្ជូនបន្តពីរ ហើយការបញ្ជូនបន្តតែមួយនៅតែបរាជ័យ៖ - **`20128`** (ច្រកផ្ទាំងគ្រប់គ្រង) ធ្វើឱ្យ origin ក្លាយជា localhost ពិតប្រាកដ ដែលជាអ្វីដែលធ្វើឱ្យ OmniRoute ចាប់ផ្តើមម៉ាស៊ីនមេ callback PKCE — origin LAN មិនដែលឈានដល់ branch នោះទេ។ - **`1455`** (ច្រក callback ថេររបស់អ្នកផ្តល់សេវា) គឺជាកន្លែងដែលកម្មវិធីរុករកត្រូវបានបញ្ជូនត្រឡប់ទៅ ហើយវាត្រូវតែឆ្លងកាត់ tunnel ទៅកាន់ loopback របស់ម៉ាស៊ីនមេ។ ប្តូរ `1455` ជា `56121`/`56122` នៅពេលភ្ជាប់ xAI ឬ Grok CLI ហើយប្តូរ `20128` ជាច្រកផ្ទាំងគ្រប់គ្រងជាក់ស្តែងរបស់អ្នក។ រក្សា tunnel ឱ្យបើករហូតដល់ការតភ្ជាប់បង្ហាញថាសកម្ម។ > **មិនមានសិទ្ធិចូលប្រើ SSH មែនទេ?** Codex និង Grok CLI ក៏ទទួលយក token ដែលបានបិទភ្ជាប់ផងដែរ — ផ្ទាំង **Paste API > Key** / **Import auth.json** នៅក្នុងប្រអប់តភ្ជាប់។ វិធីនេះមិនមាន callback > loopback ទេ ដូច្នេះវាដំណើរការពី origin ណាមួយ។ Codex ក៏ទទួលយក access > token ធម្មតា ឬទិន្នន័យ session `~/.codex/auth.json` ផងដែរ។ --- ## ការគ្រប់គ្រង token ```bash omniroute tokens create --name "laptop" --scope write [--expires 30] # ↳ បង្ហាញ secret តែម្តងប៉ុណ្ណោះ — ចម្លងវាឥឡូវនេះ omniroute tokens list # បានបិទបាំង៖ id, name, scope, prefix, status, expiry omniroute tokens revoke # ដកហូតភ្លាមៗ omniroute tokens scopes # ពន្យល់អំពី scope ទាំងបី ``` ពាក្យបញ្ជា `tokens` ត្រូវការព័ត៌មានសម្គាល់អត្តសញ្ញាណ **admin**។ អ្នកក៏អាចគ្រប់គ្រង token នៅក្នុងផ្ទាំងគ្រប់គ្រងក្រោម **Settings → Access Tokens** (បង្កើត ដកហូត ចម្លងបានតែម្តង)។ --- ## ការកំណត់រចនាសម្ព័ន្ធ CLI សម្រាប់ការសរសេរកូដពីកាតាឡុកពីចម្ងាយ `omniroute configure` អានកាតាឡុក model ផ្ទាល់របស់ **ម៉ាស៊ីនមេសកម្ម** ហើយសរសេរការកំណត់រចនាសម្ព័ន្ធមួយនៅលើម៉ាស៊ីន **របស់អ្នក**។ ```bash omniroute configure codex # អ្នកផ្តល់សេវា៖ glm, kmc, ollamacloud, opencode-go, … # អ្នកផ្តល់សេវា៖ glm # ID របស់ model៖ glm/glm-5.2 # ✔ បានសរសេរ ~/.codex/glm52.config.toml # ប្រើវា៖ codex --profile glm52 # មិនប្រើអន្តរកម្ម omniroute configure codex --provider glm --model glm/glm-5.2 --name glm52 # រក្សា model ដែលប្រើញឹកញាប់នៅផ្នែកខាងលើនៃឧបករណ៍ជ្រើសរើសអន្តរកម្ម omniroute configure codex --provider glm --model glm/glm-5.2 --favorite --yes ``` ឧបករណ៍ជ្រើសរើសរក្សាទុកតែ ID របស់ model ប៉ុណ្ណោះ (មិនរក្សាទុក URL ឬព័ត៌មានសម្គាល់អត្តសញ្ញាណឡើយ) នៅក្នុងឯកសារ `model-preferences.json` មូលដ្ឋាន ដោយកំណត់វិសាលភាពតាម context និងគោលដៅ CLI។ ចំណូលចិត្តត្រូវបានបង្ហាញមុនជម្រើសថ្មីៗ សូមប្រើ `--unfavorite` ដើម្បីដក model ដែលបានជ្រើសចេញពីបញ្ជី context/គោលដៅនោះ។ profile ដែលបានសរសេរយោងទៅ inference key តាមរយៈ env var (`OMNIROUTE_API_KEY`) — secret មិនត្រូវបានសរសេរទៅ disk ឡើយ។ សម្រាប់ការដំឡើង Codex មូលដ្ឋានតែម្តង (ប្លុក `[model_providers.omniroute]`) សូមមើល [CODEX-CLI-CONFIGURATION.md](./CODEX-CLI-CONFIGURATION.md)។ ### ការបើកដំណើរការ CLI ទល់នឹងម៉ាស៊ីនពីចម្ងាយ (មិនមានការសរសេរការកំណត់រចនាសម្ព័ន្ធ) `omniroute run ` ក៏គោរពតាម context សកម្មផងដែរ៖ URL មូលដ្ឋានពីចម្ងាយ និងព័ត៌មានសម្គាល់អត្តសញ្ញាណរបស់ context ត្រូវបានបញ្ចូលតែទៅក្នុង process ដែលបានបង្កើតប៉ុណ្ណោះ។ ```bash omniroute connect 192.168.0.15 omniroute run claude --model openai/gpt-5.4 # Claude Code → ម៉ាស៊ីនពីចម្ងាយ omniroute run gemini --model glm/glm-5.2 -- --skip-trust -p "hello" omniroute run opencode --model glm/glm-5.2 -- run "reply OK" # មើលជាមុនឱ្យច្បាស់នូវអ្វីដែលនឹងត្រូវបានបង្កើត (តែឈ្មោះ KEY របស់ env ប៉ុណ្ណោះ មិនមែនតម្លៃឡើយ)៖ omniroute run codex --dry-run --json ``` គោលដៅ៖ `claude`, `codex`, `aider`, `goose`, `opencode`, `qwen`, `gemini` (ប្រភពតែមួយ៖ `bin/cli/cli-manifest.mjs`)។ Qwen និង Gemini ដំណើរការជាមួយ home ដាច់ដោយឡែកបណ្តោះអាសន្ន ដែលត្រូវបានលុបចេញពេលបញ្ចប់ ដូច្នេះការបើកដំណើរការមិនប៉ះពាល់ — ឬលេចធ្លាយចូលទៅក្នុង — ការកំណត់រចនាសម្ព័ន្ធឧបករណ៍ផ្ទាល់ខ្លួនរបស់អ្នកឡើយ។ ### ពាក្យបញ្ជាដំឡើងតាម CLI នីមួយៗ CLI ដែលគាំទ្រនីមួយៗមានពាក្យបញ្ជាដំឡើងដែលយល់ដឹងអំពីម៉ាស៊ីនពីចម្ងាយ (ទាំងអស់គោរពតាម context សកម្ម ឬ `--remote --api-key `)៖ | CLI | ពាក្យបញ្ជា | អ្វីដែលវាសរសេរ | | ----------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Codex | `omniroute setup-codex` | ប្រូហ្វាល់ `~/.codex/.config.toml` (មួយសម្រាប់ម៉ូដែលនីមួយៗ) | | Claude Code | `omniroute setup-claude` | `~/.claude/profiles//settings.json` (មួយសម្រាប់ម៉ូដែលនីមួយៗ) | | OpenCode | `omniroute setup-opencode` | `~/.config/opencode/opencode.json` — provider `omniroute` ដែលឆបគ្នាជាមួយ OpenAI និងមានគ្រប់ម៉ូដែលក្នុងកាតាឡុក (ដំណើរការ `opencode -m omniroute/`) | | Cline | `omniroute setup-cline` | `~/.cline/data/{globalState,secrets}.json` (របៀប CLI) + បង្ហាញការកំណត់ extension របស់ VS Code សម្រាប់បិទភ្ជាប់ (ឆបគ្នាជាមួយ OpenAI, Base URL **គ្មាន** `/v1`) | | Kilo Code | `omniroute setup-kilo` | `~/.local/share/kilo/auth.json` (CLI) + ការកំណត់ `kilocode.*` របស់ VS Code — ឆបគ្នាជាមួយ OpenAI, Base URL **មាន** `/v1` | | Continue | `omniroute setup-continue` | `~/.continue/config.yaml` (VS Code/JetBrains + `cn` CLI) — `provider: openai`, `apiBase` **មាន** `/v1`, key តាមរយៈ `${{ secrets.OMNIROUTE_API_KEY }}` | | Cursor | `omniroute setup-cursor` | បង្ហាញជំហាននៅក្នុងកម្មវិធី (Settings → Models → Override OpenAI Base URL **មាន** `/v1` + key + model)។ ការកំណត់របស់ Cursor ជា SQLite ដែលមិនអាចមើលឃើញខាងក្នុងបាន — សម្រាប់តែផ្ទាំងជជែកប៉ុណ្ណោះ | | Roo Code | `omniroute setup-roo` | សរសេរ JSON សម្រាប់ import របស់ Roo (`~/.omniroute/roo-settings.json`) + កំណត់ `roo-cline.autoImportSettingsPath` + បង្ហាញជំហាន UI (ឆបគ្នាជាមួយ OpenAI, Base URL **មាន** `/v1`) | | Crush | `omniroute setup-crush` | `~/.config/crush/crush.json` — provider `openai-compat`, `base_url` **មាន** `/v1`, key តាមរយៈ `$OMNIROUTE_API_KEY` | | Goose | `omniroute setup-goose` | `~/.config/goose/config.yaml` (`GOOSE_PROVIDER=openai` + `OPENAI_HOST` **គ្មាន** `/v1` + `GOOSE_MODEL`) + រូបមន្តកំណត់ env | | Aider | `omniroute setup-aider` | `~/.aider.conf.yml` (`openai-api-base` **គ្មាន** `/v1` + `model: openai/`) + រូបមន្តកំណត់ env (`aider --message --yes`) | | Qwen Code | `omniroute setup-qwen` | ធាតុ V4 `modelProviders.openai` ក្នុង `~/.qwen/settings.json` + `OMNIROUTE_API_KEY` ក្នុង `~/.qwen/.env` | ```bash # OpenCode (provider ដែលឆបគ្នាជាមួយ OpenAI, ម៉ូដែលទាំងអស់ក្នុងកាតាឡុក, VPS ពីចម្ងាយ) omniroute setup-opencode --remote http://192.168.0.15:20128 --api-key oma_live_xxx omniroute setup-opencode --only glm,kimi # រក្សាទុកតែម៉ូដែលដែលផ្គូផ្គង opencode -m omniroute/glm/glm-5.2 "..." # export OMNIROUTE_API_KEY ជាមុន ``` > OpenCode ក៏មានការរួមបញ្ចូលតាម **plugin** ដែលសម្បូរមុខងារជាងនេះផងដែរ៖ `omniroute setup opencode` > (ឥឡូវគាំទ្រការប្រើពីចម្ងាយតាមរយៈ `--remote`) ដំឡើង `@omniroute/opencode-plugin`។ > `setup-opencode` គឺជាជម្រើសស្រាលដែលឆបគ្នាជាមួយ OpenAI។ API key > ត្រូវបានយោងតាមរយៈ `{env:OMNIROUTE_API_KEY}` — មិនត្រូវបានសរសេរទៅ disk ឡើយ។ > > នៅលើ OpenCode v2 សូមប្រើ `@omniroute/opencode-plugin-v2` ជំនួសវិញ៖ កាតាឡុកដូចគ្នា > ប៉ុន្តែ loader contract ខុសគ្នា។ វាអាន key ពីកន្លែងផ្ទុក credential ផ្ទាល់របស់ OpenCode > នៅពេលការរួមបញ្ចូលត្រូវបានភ្ជាប់ ដូច្នេះ gateway ពីចម្ងាយមិនត្រូវការ key នៅក្នុង > `opencode.json` ទាល់តែសោះ។ --- ## ការគ្រប់គ្រងបរិបទ (ប្តូររវាងម៉ាស៊ីនមេ) **បរិបទ (context)** គឺជាម៉ាស៊ីនមេដែលបានរក្សាទុក (baseUrl + credential + scope)។ `omniroute connect` បង្កើតបរិបទមួយហើយធ្វើឱ្យវាសកម្ម; ចាប់ពីពេលនោះមក រាល់ពាក្យបញ្ជាទាំងអស់នឹងកំណត់គោលដៅទៅវា។ គ្រប់គ្រង និងប្តូររវាងពួកវាដោយប្រើ `omniroute contexts`៖ ```bash omniroute contexts list # all contexts; the active one is marked ● omniroute contexts current # the active server, auth status, scope ``` ```text | Name | Base URL | Auth | Scope | Description ● | vps | http://100.67.86.91:20128 | token | admin | Remote OmniRoute (…) | default | http://localhost:20128 | ✗ | | ``` **ប្តូរម៉ាស៊ីនមេ** — រាល់ពាក្យបញ្ជាបន្តបន្ទាប់ទាំងអស់នឹងអនុវត្តតាមបរិបទដែលសកម្ម៖ ```bash omniroute contexts use vps # → all commands now hit the remote VPS omniroute tokens list # (runs against the VPS) omniroute contexts use default # → back to localhost omniroute tokens list # (runs against the local server) ``` **បន្ថែមបរិបទដោយដៃ** (ជំនួសឱ្យ `connect`) ពិនិត្យមើល ឬប្តូរឈ្មោះ៖ ```bash omniroute contexts add staging --url https://staging.example.com:20128 \ --access-token oma_live_xxxx --scope write --description "staging box" omniroute contexts show staging # full details for one context omniroute contexts rename staging stg ``` **លុបបរិបទ** — នឹងសួររកការបញ្ជាក់; ប្រើ `--yes` ដើម្បីរំលងវា (តម្រូវសម្រាប់ស្គ្រីប / shells ដែលមិនអន្តរកម្ម ដែលបើមិនដូច្នេះទេនឹងបដិសេធដោយសុវត្ថិភាព)៖ ```bash omniroute contexts remove stg --yes ``` > `default` (localhost) មិនអាចលុបបានទេ។ ការលុបបរិបទដែលសកម្មនឹងត្រឡប់ទៅ `default` វិញ។ គន្លឹះ៖ ការលុបបរិបទគ្រាន់តែលុប credentials ដែលបានរក្សាទុក **ក្នុងមូលដ្ឋាន** ប៉ុណ្ណោះ — ដកហូត token នៅលើម៉ាស៊ីនមេដោយប្រើ `omniroute tokens revoke ` ដើម្បីបិទការចូលប្រើប្រាស់ពិតប្រាកដ។ **នាំចេញ / នាំចូលបរិបទ** (ឧទាហរណ៍ ដើម្បីផ្លាស់ទីពួកវាទៅរវាងម៉ាស៊ីន)។ ការនាំចេញនឹងលុប credentials ចេញតាមលំនាំដើម រួមទាំង credentials ដែលបានរក្សាទុកដោយ file fallback។ ប្រើ `--include-secrets` ដោយផ្ទាល់នៅពេលដែលត្រូវការការបម្រុងទុកដែលមាន credentials ដែលអាចចល័តបាន៖ ```bash omniroute contexts export --out contexts.json # redacted; default destination: stdout omniroute contexts export --include-secrets --out private-contexts.json omniroute contexts import contexts.json # overwrite; --merge to keep existing omniroute contexts migrate --yes # move legacy plaintext tokens to keychain ``` `--include-secrets` ដោះស្រាយឯកសារយោង keychain មុនពេលនាំចេញ ហើយនឹងបរាជ័យប្រសិនបើ credentials ដែលបានយោងណាមួយមិនអាចអានបាន។ `--no-secrets` តែងតែមានអាទិភាព។ ឯកសារនាំចេញត្រូវបានសរសេរដោយស្វ័យប្រវត្តិជាមួយនឹង mode `0600`។ ចាត់ទុកការនាំចេញដែលមានសម្ងាត់ដោយផ្ទាល់ថាជាសម្ភារៈសម្ងាត់។ នៅលើប្រព័ន្ធ headless ដែលគ្មាន OS keychain ដែលអាចប្រើបាន CLI នឹងត្រឡប់ទៅ `config.json` វិញជាមួយនឹង mode `0600` ហើយបោះពុម្ពការព្រមានតែមួយដង; ការនាំចេញតាមលំនាំដើមនៅតែត្រូវបានកែសម្រួលក្នុងរបៀបនេះ។ --- ## ការត្រួតពិនិត្យពីដើមដល់ចប់យ៉ាងរហ័ស វដ្ដជីវិតដែលអាចចម្លង-បិទភ្ជាប់បាន ដើម្បីផ្ទៀងផ្ទាត់ការដំឡើងពីចម្ងាយតាំងពីដំបូង — ភ្ជាប់ បង្កើត token ដែលមានវិសាលភាព បញ្ជូនពាក្យបញ្ជា ប្ដូរត្រឡប់ និងរុះរើ។ ជំនួស `192.168.0.15` ដោយ host/IP របស់ម៉ាស៊ីនមេរបស់អ្នក (Tailscale, LAN ឬ URL សាធារណៈ `https://…`)។ ```bash # 1. ភ្ជាប់ (ពាក្យសម្ងាត់ → admin token ដែលបានរក្សាទុកជាបរិបទ ហើយក្លាយជាបរិបទសកម្ម) omniroute connect 192.168.0.15 # ឬ៖ --key oma_live_xxxx (មិនប្រើពាក្យសម្ងាត់) omniroute contexts current # បង្ហាញម៉ាស៊ីនមេពីចម្ងាយ + វិសាលភាព # 2. ប្រើវា — ឥឡូវនេះ ពាក្យបញ្ជាគ្រប់គ្រងដំណើរការជាមួយម៉ាស៊ីនមេពីចម្ងាយ omniroute tokens create --name laptop --scope read # បង្កើត token ដែលមានវិសាលភាពកាន់តែចង្អៀត omniroute tokens list # បញ្ជីដែលបានបិទបាំង ពីម៉ាស៊ីនមេពីចម្ងាយ # 3. ប្ដូរទៅមក omniroute contexts use default # → មូលដ្ឋាន omniroute contexts use 192-168-0-15 # → ពីចម្ងាយម្ដងទៀត (ឈ្មោះពី `contexts list`) # 4. រុះរើ។ ចំណាំ៖ `contexts remove` លុបតែព័ត៌មានសម្គាល់អត្តសញ្ញាណក្នុងម៉ាស៊ីនមូលដ្ឋានប៉ុណ្ណោះ — # វាមិនដកហូត token នៅលើម៉ាស៊ីនមេទេ។ ដកហូតនៅផ្នែកម៉ាស៊ីនមេជាមុន ប្រសិនបើអ្នក # ចង់បញ្ឈប់សិទ្ធិចូលប្រើប្រាស់ជាក់ស្ដែង។ omniroute tokens revoke # បញ្ឈប់សិទ្ធិចូលប្រើប្រាស់នៅលើម៉ាស៊ីនមេ omniroute contexts remove 192-168-0-15 --yes # លុបបរិបទមូលដ្ឋាន (ទោះបីជាសកម្មក៏ដោយ → ត្រឡប់ទៅ default) ដោយគ្មានការសួរបញ្ជាក់ ``` > `--yes` ធ្វើឱ្យ `contexts remove` មិនមានអន្តរកម្ម (តម្រូវក្នុងស្គ្រីប/CI; បើគ្មាន > វា shell ដែលមិនអន្តរកម្មនឹងបដិសេធដោយសុវត្ថិភាព ជំនួសឱ្យការជាប់គាំង)។ ការលុប > បរិបទ **សកម្ម** នឹងត្រឡប់ទៅ `default` ដោយស្វ័យប្រវត្តិ។ --- ## កំណត់សម្គាល់អំពីសុវត្ថិភាព - ថូខឹនជាអត្ថបទធម្មតាត្រូវបានបង្ហាញតែម្តងប៉ុណ្ណោះ ហើយមានតែហាស SHA-256 ប៉ុណ្ណោះដែលត្រូវបានរក្សាទុកជាអចិន្ត្រៃយ៍ (ដូចគ្នានឹង API keys)។ - `omniroute connect` ប្រើឡើងវិញនូវការចាក់សោទប់ស្កាត់ការសាកល្បងចូលប្រើដោយប្រើកម្លាំងបង្ខំ + ការកត់ត្រាសវនកម្ម។ - គួរប្រើ HTTPS ឬ Tailnet សម្រាប់ការបញ្ជូនទិន្នន័យ។ ម៉ាស៊ីនមេដែលមិនមាន protocol កំណត់ នឹងប្រើ `http://` តាមលំនាំដើម ដើម្បីផ្តល់ភាពងាយស្រួលសម្រាប់ LAN/Tailscale — សូមបញ្ជូន URL `https://…` ពេញលេញ ដើម្បីប្រើ TLS។ - ឯកសារបរិបទមូលដ្ឋានដែលបានណែនាំគឺ `~/.omniroute/config.json` (`chmod 600`) ដែលមានតែ `credentialRef` មួយប៉ុណ្ណោះ។ ថូខឹនផ្ទាល់ត្រូវបានរក្សាទុកក្នុងឃ្លាំងសោរបស់ប្រព័ន្ធប្រតិបត្តិការ (`keytar`) ហើយមិនត្រូវបានបោះពុម្ពក្នុងកំណត់ហេតុឡើយ។ ការដំឡើងបែបគ្មានចំណុចប្រទាក់ដែលមិនមាន ឃ្លាំងសោដើមដែលដំណើរការ នឹងប្រើឯកសារ `0600` ដូចគ្នាជាជម្រើសបម្រុងដែលបានកំណត់យ៉ាងច្បាស់ និង បញ្ចេញការព្រមានម្តង។ ប្រើ `omniroute contexts migrate --yes` បន្ទាប់ពីដំឡើង ផ្នែកខាងក្រោយនៃឃ្លាំងសោ។ --- ## ចំណុចបញ្ចប់ API (ឯកសារយោង) | វិធីសាស្ត្រ | ផ្លូវ | ការផ្ទៀងផ្ទាត់អត្តសញ្ញាណ | វិសាលភាព | | ----------- | --------------------- | ------------------------ | ------------------------------------ | | POST | `/api/cli/connect` | ពាក្យសម្ងាត់គ្រប់គ្រង | — (សាធារណៈ តម្រូវឱ្យមានពាក្យសម្ងាត់) | | GET | `/api/cli/whoami` | ថូខឹនចូលប្រើ | អាន | | GET | `/api/cli/tokens` | ថូខឹនចូលប្រើ | អ្នកគ្រប់គ្រង | | POST | `/api/cli/tokens` | ថូខឹនចូលប្រើ | អ្នកគ្រប់គ្រង | | DELETE | `/api/cli/tokens/:id` | ថូខឹនចូលប្រើ | អ្នកគ្រប់គ្រង | សូមមើល [openapi.yaml](../openapi.yaml) សម្រាប់គ្រោងការណ៍ពេញលេញ។