1 line
82 KiB
JSON
1 line
82 KiB
JSON
{"repo": "autolove111/fitters", "files": {"health-app/study/aid_learning_agent/assets/README/README_TH.md": {"1d1a93717421d10f6294c917a377ace11cb3c248": {"t": 1785595182.7709954, "n": 41588, "h": "5783901a5b4e35da", "c": "<div align=\"center\">\n\n<img src=\"../../assets/logo.png\" alt=\"AidLearning\" width=\"140\" style=\"border-radius: 15px;\">\n\n# AidLearning: ผู้ช่วยติวส่วนบุคคลแบบ Agent-Native\n\n<a href=\"https://trendshift.io/repositories/17099\" target=\"_blank\"><img src=\"https://trendshift.io/api/badge/repositories/17099\" alt=\"HKUDS%2FAidLearning | Trendshift\" style=\"width: 250px; height: 55px;\" width=\"250\" height=\"55\"/></a>\n\n[](https://www.python.org/downloads/)\n[](https://nextjs.org/)\n[](../../LICENSE)\n[](https://github.com/HKUDS/AidLearning/releases)\n[](https://arxiv.org/abs/2604.26962)\n\n[](https://discord.gg/eRsjPgMU4t)\n[](../../Communication.md)\n[](https://github.com/HKUDS/AidLearning/issues/78)\n\n[คุณสมบัติเด่น](#-คุณสมบัติเด่น) · [เริ่มต้นใช้งาน](#-เริ่มต้นใช้งาน) · [สำรวจความสามารถ](#-สำรวจ-aidlearning) · [TutorBot](#-tutorbot--ติวเตอร์-ai-แบบถาวรและอัตโนมัติ) · [CLI](#%EF%B8%8F-aidlearning-cli--อินเทอร์เฟซแบบ-agent-native) · [ชุมชน](#-ชุมชนและระบบนิเวศ)\n\n[🇺🇸 English](../../README.md) · [🇨🇳 中文](README_CN.md) · [🇯🇵 日本語](README_JA.md) · [🇪🇸 Español](README_ES.md) · [🇫🇷 Français](README_FR.md) · [🇸🇦 العربية](README_AR.md) · [🇷🇺 Русский](README_RU.md) · [🇮🇳 हिन्दी](README_HI.md) · [🇵🇹 Português](README_PT.md) · [🇹🇭 ภาษาไทย](README_TH.md) · 🇵🇱 [Polski](README_PL.md)\n\n</div>\n\n---\n\n> 🤝 **ยินดีรับทุกรูปแบบการมีส่วนร่วม!** ดู [คู่มือการมีส่วนร่วม](../../CONTRIBUTING.md) สำหรับกลยุทธ์สาขา มาตรฐานโค้ด และจุดเริ่มต้น\n\n### 📦 ประวัติการเผยแพร่\n\n> **[2026.5.10]** [v1.3.10](https://github.com/HKUDS/AidLearning/releases/tag/v1.3.10) — แก้ CORS สำหรับ Docker ระยะไกล, `DISABLE_SSL_VERIFY` ใน SDK providers, citation ใน code block และแยก Matrix E2EE เป็น add-on\n\n> **[2026.5.9]** [v1.3.9](https://github.com/HKUDS/AidLearning/releases/tag/v1.3.9) — TutorBot รองรับ Zulip และ NVIDIA NIM, routing ของ thinking-model ปลอดภัยขึ้น, `aidlearning start`, tooltip ใน sidebar, และ session-store parity\n\n> **[2026.5.8]** [v1.3.8](https://github.com/HKUDS/AidLearning/releases/tag/v1.3.8) — deployment แบบ multi-user ที่เปิดได้ตามต้องการ พร้อม workspace แยกผู้ใช้, admin grants, auth routes, และ scoped runtime access\n\n> **[2026.5.4]** [v1.3.7](https://github.com/HKUDS/AidLearning/releases/tag/v1.3.7) — แก้ไข thinking-model/provider, แสดงประวัติ Knowledge index, และ Co-Writer clear/template editing ปลอดภัยขึ้น\n\n> **[2026.5.3]** [v1.3.6](https://github.com/HKUDS/AidLearning/releases/tag/v1.3.6) — เลือกโมเดลจากคาตาล็อกสำหรับแชตและ TutorBot, RAG re-indexing ปลอดภัยขึ้น, แก้ token-limit ของ OpenAI Responses, และตรวจสอบ Skills editor\n\n> **[2026.5.2]** [v1.3.5](https://github.com/HKUDS/AidLearning/releases/tag/v1.3.5) — ตั้งค่าการเปิดใช้งานในเครื่องราบรื่นขึ้น, RAG queries ปลอดภัยขึ้น, local embedding auth ชัดเจนขึ้น, และปรับแต่ง dark-mode ของ Settings\n\n> **[2026.5.1]** [v1.3.4](https://github.com/HKUDS/AidLearning/releases/tag/v1.3.4) — Chat persistence บนหน้าหนังสือและ rebuild flows, อ้างอิงจากแชตไปหนังสือ, จัดการภาษา/การให้เหตุผลแข็งแกร่งขึ้น, เสริมความแข็งแกร่งการดึงเอกสาร RAG\n\n> **[2026.4.30]** [v1.3.3](https://github.com/HKUDS/AidLearning/releases/tag/v1.3.3) — รองรับ embedding NVIDIA NIM และ Gemini, Space context รวมสำหรับประวัติแชต / สกิล / หน่วยความจำ, snapshot ของเซสชัน, ความทนทานของการทำดัชนี RAG ใหม่\n\n> **[2026.4.29]** [v1.3.2](https://github.com/HKUDS/AidLearning/releases/tag/v1.3.2) — URL ปลายทาง embedding โปร่งใส, ความทนทาน re-index RAG เมื่อเวกเตอร์ที่ persist ไม่ถูกต้อง, ทำความสะอาดหน่วยความจำสำหรับเอาต์พุตโมเดล thinking, แก้รันไทม์ Deep Solve\n\n> **[2026.4.28]** [v1.3.1](https://github.com/HKUDS/AidLearning/releases/tag/v1.3.1) — เสถียรภาพ: RAG routing ปลอดภัยขึ้นและตรวจสอบ embedding, Docker persistence, อินพุตปลอดภัยกับ IME, ความทนทาน Windows/GBK\n\n> **[2026.4.27]** [v1.3.0](https://github.com/HKUDS/AidLearning/releases/tag/v1.3.0) — ดัชนี KB แบบมีเวอร์ชันพร้อมเวิร์กโฟลว์ re-index, รีบิลด์ Knowledge workspace, embedding auto-discovery กับอะแดปเตอร์ใหม่, Space hub\n\n<details>\n<summary><b>รุ่นที่ผ่านมา (มากกว่า 2 สัปดาห์ที่แล้ว)</b></summary>\n\n> **[2026.4.25]** [v1.2.5](https://github.com/HKUDS/AidLearning/releases/tag/v1.2.5) — แนบไฟล์ในแชตถาวรพร้อมลิ้นชักพรีวิว, pipeline ความสามารถที่รับรู้แนบไฟล์, ส่งออก Markdown ของ TutorBot\n\n> **[2026.4.25]** [v1.2.4](https://github.com/HKUDS/AidLearning/releases/tag/v1.2.4) — แนบข้อความ / โค้ด / SVG, Setup Tour คำสั่งเดียว, ส่งออกแชต Markdown, UI จัดการ KB แบบกะทัดรัด\n\n> **[2026.4.24]** [v1.2.3](https://github.com/HKUDS/AidLearning/releases/tag/v1.2.3) — แนบเอกสาร (PDF/DOCX/XLSX/PPTX), แสดงบล็อกการคิดของโมเดลให้เหตุผล, ตัวแก้เทมเพลต Soul, บันทึก Co-Writer ลงสมุด\n\n> **[2026.4.22]** [v1.2.2](https://github.com/HKUDS/AidLearning/releases/tag/v1.2.2) — ระบบ Skills ที่ผู้ใช้สร้าง, ปรับประสิทธิ์อินพุตแชต, TutorBot สตาร์ทอัตโนมัติ, UI ห้องสมุดหนังสือ, โหมดเต็มจอของการแสดงผล\n\n> **[2026.4.21]** [v1.2.1](https://github.com/HKUDS/AidLearning/releases/tag/v1.2.1) — จำกัดโทเคนต่อขั้นตอน, สร้างคำตอบใหม่ได้ทุกจุดเข้า, แก้ความเข้ากันได้ของ RAG และ Gemma\n\n> **[2026.4.20]** [v1.2.0](https://github.com/HKUDS/AidLearning/releases/tag/v1.2.0) — คอมไพเลอร์ Book Engine «หนังสือมีชีวิต», Co-Writer หลายเอกสาร, การแสดงผล HTML แบบโต้ตอบ, @-mention ธนาคารคำถามในแชต\n\n> **[2026.4.18]** [v1.1.2](https://github.com/HKUDS/AidLearning/releases/tag/v1.1.2) — แท็บ Channels แบบ schema-driven, รวม RAG เป็น pipeline เดียว, แยก chat prompts ออกเป็นไฟล์ภายนอก\n\n> **[2026.4.17]** [v1.1.1](https://github.com/HKUDS/AidLearning/releases/tag/v1.1.1) — ปุ่ม \"ตอบเลย\" ครอบคลุมทุกความสามารถ, Co-Writer scroll sync, แผงตั้งค่ารวม, ปุ่ม Stop ระหว่างสตรีม\n\n> **[2026.4.15]** [v1.1.0](https://github.com/HKUDS/AidLearning/releases/tag/v1.1.0) — ปรับปรุงการ parse LaTeX block math, ตั้งค่า LLM probe ผ่าน agents.yaml, forward extra headers ใน LLM factory, แก้ UUID ของ SaveToNotebookModal, คำแนะนำ Docker + local LLM และขยาย test suite\n\n> **[2026.4.14]** [v1.1.0-beta](https://github.com/HKUDS/AidLearning/releases/tag/v1.1.0-beta) — URL-based chat routing พร้อม bookmark ได้, ธีม Snow, WebSocket heartbeat & auto-reconnect พร้อม resume, ปรับ ChatComposer ให้เร็วขึ้น, overhaul embedding provider registry, Serper search provider, streaming idle timeout และขยาย test suite\n\n> **[2026.4.13]** [v1.0.3](https://github.com/HKUDS/AidLearning/releases/tag/v1.0.3) — Question Notebook สำหรับทบทวนแบบทดสอบรวมศูนย์พร้อม bookmark & หมวดหมู่, รองรับ Mermaid diagram ใน Visualize, ตรวจจับ embedding model ไม่ตรง, รวม system message สำหรับ Qwen/vLLM, รองรับ LM Studio & llama.cpp และธีม Glass\n\n> **[2026.4.11]** [v1.0.2](https://github.com/HKUDS/AidLearning/releases/tag/v1.0.2) — ปรับโครงสร้าง search consolidation ให้ง่ายขึ้นพร้อม SearXNG fallback, แก้ไข provider switch fix, ตั้ง runtime config ชัดเจนใน test runner และแก้ resource leak ฝั่ง frontend\n\n> **[2026.4.10]** [v1.0.1](https://github.com/HKUDS/AidLearning/releases/tag/v1.0.1) — เพิ่ม Visualize capability ใหม่พร้อม Chart.js/SVG rendering pipeline, ป้องกัน quiz ซ้ำด้วย generation history, รองรับ o4-mini model และปรับปรุง server logging\n\n> **[2026.4.10]** [v1.0.0-beta.4](https://github.com/HKUDS/AidLearning/releases/tag/v1.0.0-beta.4) — แสดงความคืบหน้า Embedding พร้อม retry เมื่อเจอ HTTP 429, จัดการ dependency ข้ามแพลตฟอร์มใน start tour และแก้ MIME validation ให้ case-insensitive\n\n> **[2026.4.8]** [v1.0.0-beta.3](https://github.com/HKUDS/AidLearning/releases/tag/v1.0.0-beta.3) — ลบ litellm dependency ใช้ native OpenAI/Anthropic SDK providers แทน, รองรับ Math Animator บน Windows, parse JSON จาก LLM ให้ robust ขึ้น, แก้ KaTeX & navigation ใน Guided Learning และ i18n ภาษาจีนครบ\n\n> **[2026.4.7]** [v1.0.0-beta.2](https://github.com/HKUDS/AidLearning/releases/tag/v1.0.0-beta.2) — ล้าง runtime cache สำหรับ hot settings reload, รองรับ MinerU nested output, แก้ mimic WebSocket, กำหนดขั้นต่ำ Python 3.11+ และปรับปรุง CI\n\n> **[2026.4.4]** [v1.0.0-beta.1](https://github.com/HKUDS/AidLearning/releases/tag/v1.0.0-beta.1) — เขียนสถาปัตยกรรมใหม่แบบ Agent-native (~200k บรรทัด) พร้อมโมเดลปลั๊กอิน 2 ชั้น (Tools + Capabilities), CLI & SDK entry points, TutorBot มัลติแชนแนล, Co-Writer, Guided Learning และ persistent memory\n\n> **[2026.1.23]** [v0.6.0](https://github.com/HKUDS/AidLearning/releases/tag/v0.6.0) — Session persistence, อัปโหลดเอกสารเพิ่มทีละไฟล์, import RAG pipeline ที่ยืดหยุ่น และ localization ภาษาจีนครบ\n\n> **[2026.1.18]** [v0.5.2](https://github.com/HKUDS/AidLearning/releases/tag/v0.5.2) — รองรับ Docling สำหรับ RAG-Anything, ปรับ logging system และแก้บั๊ก\n\n> **[2026.1.15]** [v0.5.0](https://github.com/HKUDS/AidLearning/releases/tag/v0.5.0) — Unified service configuration, เลือก RAG pipeline ต่อ knowledge base, ปรับ question generation ใหม่ และปรับแต่ง sidebar\n\n> **[2026.1.9]** [v0.4.0](https://github.com/HKUDS/AidLearning/releases/tag/v0.4.0) — รองรับ Multi-provider LLM & embedding, หน้า home ใหม่, แยก RAG module และ refactor environment variable\n\n> **[2026.1.5]** [v0.3.0](https://github.com/HKUDS/AidLearning/releases/tag/v0.3.0) — สถาปัตยกรรม PromptManager รวม, GitHub Actions CI/CD และ Docker image สำเร็จรูปบน GHCR\n\n> **[2026.1.2]** [v0.2.0](https://github.com/HKUDS/AidLearning/releases/tag/v0.2.0) — Docker deployment, อัปเกรด Next.js 16 & React 19, WebSocket security hardening และแก้ช่องโหว่สำคัญ\n\n</details>\n\n### 📰 ข่าวสาร\n\n> **[2026.4.19]** 🎉 ครบ 20k ดาวหลัง 111 วัน! ขอบคุณที่สนับสนุน — เราจะพัฒนาต่อเพื่อติวเตอร์เชิงบุคคลและฉลาดอย่างแท้จริง\n\n> **[2026.4.10]** 📄 งานวิจัยของเราลง arXiv แล้ว! อ่าน [พรีปรินต์](https://arxiv.org/abs/2604.26962) เพื่อทำความเข้าใจการออกแบบและแนวคิดของ AidLearning\n\n> **[2026.4.4]** นานมาแล้ว ✨ AidLearning v1.0.0 มาถึงแล้ว — วิวัฒนาการแบบ agent-native ที่เขียนสถาปัตยกรรมใหม่ตั้งแต่ต้น พร้อม TutorBot และการสลับโหมดอย่างยืดหยุ่น ภายใต้สัญญาอนุญาต Apache-2.0 บทใหม่เริ่มต้นขึ้น เรื่องราวของเรายังดำเนินต่อไป!\n\n> **[2026.2.6]** 🚀 เราไปถึง 10,000 ดาวภายในเพียง 39 วัน! ขอบคุณชุมชนที่ยอดเยี่ยมของเราสำหรับการสนับสนุน!\n\n> **[2026.1.1]** สวัสดีปีใหม่! มาร่วม [Discord](https://discord.gg/eRsjPgMU4t), [WeChat](https://github.com/HKUDS/AidLearning/issues/78) หรือ [Discussions](https://github.com/HKUDS/AidLearning/discussions) ของเรา — มาร่วมกำหนดอนาคตของ AidLearning กัน!\n\n> **[2025.12.29]** AidLearning เปิดตัวอย่างเป็นทางการ!\n\n## ✨ คุณสมบัติเด่น\n\n- **พื้นที่แชตแบบรวมศูนย์** — 6 โหมดในเธรดเดียว: Chat, Deep Solve, Quiz Generation, Deep Research, Math Animator และ Visualize ใช้บริบทร่วมกัน เริ่มจากถามง่าย ไปสู่การแก้ปัญหาแบบหลายเอเจนต์ สร้างภาพความคิด ออกแบบทดสอบ และเจาะลึกงานวิจัยโดยไม่เสียประวัติ\n- **AI Co-Writer** — พื้นที่ Markdown หลายเอกสาร AI เป็นผู้ร่วมเขียนระดับแรก: Rewrite, Expand, Shorten ดึงบริบทจาก knowledge base และเว็บ\n- **Book Engine** — เปลี่ยนวัสดุของคุณเป็น «หนังสือมีชีวิต» แบบมีโครงสร้างและโต้ตอบได้ ไปป์ไลน์หลายเอเจนต์ 13 ประเภทบล็อก (แบบทดสอบ แฟลชการ์ด ไทม์ไลน์ กราฟแนวคิด ฯลฯ)\n- **Knowledge Hub** — สร้าง knowledge base แบบ RAG-ready สมุดบันทึกสีสัน ธนาคารคำถาม และ Skills กำหนดสไตล์การสอน\n- **Persistent Memory** — AidLearning สร้างโปรไฟล์ผู้เรียนที่เติบโตอยู่ตลอดเวลา ใช้ร่วมกันข้ามทุกฟีเจอร์และทุก TutorBot ยิ่งใช้ยิ่งแม่นยำ\n- **TutorBot ส่วนตัว** — ไม่ใช่แค่ chatbot แต่เป็นติวเตอร์อัตโนมัติที่มี workspace, memory, บุคลิก และทักษะของตัวเอง ขับเคลื่อนโดย [nanobot](https://github.com/HKUDS/nanobot)\n- **Agent-Native CLI** — ทุกความสามารถ, knowledge base, session และ TutorBot ผ่านคำสั่งเดียว Rich และ JSON มอบ [`SKILL.md`](../../SKILL.md) ให้ agent\n\n---\n\n## 🚀 เริ่มต้นใช้งาน\n\n### ข้อกำหนดเบื้องต้น\n\nก่อนเริ่ม ตรวจสอบว่ามีเครื่องมือต่อไปนี้ติดตั้งแล้ว:\n\n| ข้อกำหนด | เวอร์ชัน | ตรวจสอบ | หมายเหตุ |\n|:---|:---|:---|:---|\n| [Git](https://git-scm.com/) | ใดก็ได้ | `git --version` | สำหรับ clone โปรเจกต์ |\n| [Python](https://www.python.org/downloads/) | 3.11+ | `python --version` | รัน backend |\n| [Node.js](https://nodejs.org/) | 20.9+ | `node --version` | frontend runtime สำหรับการติดตั้ง Web ในเครื่อง |\n| [npm](https://www.npmjs.com/) | มากับ Node.js | `npm --version` | ติดตั้งพร้อม Node.js |\n\nคุณยังต้องมี **API Key** จากผู้ให้บริการ LLM อย่างน้อยหนึ่งราย (เช่น [OpenAI](https://platform.openai.com/api-keys), [DeepSeek](https://platform.deepseek.com/), [Anthropic](https://console.anthropic.com/)) Setup Tour จะนำทางการกรอก\n\n### ตัวเลือก A — Setup Tour (แนะนำ)\n\n**สคริปต์ CLI แบบโต้ตอบเพียงตัวเดียว** พาคุณจาก clone สดใหม่ไปจนถึงแอปที่รันได้ — ไม่ต้อง `pip install` หรือ `npm install` หรือแก้ `data/user/settings/*.json` เอง ทุกอย่างถูกตรวจหา ติดตั้ง และตั้งค่าในขั้นแนะนำ 7 ขั้น\n\n```bash\ngit clone https://github.com/HKUDS/AidLearning.git\ncd AidLearning\n\n# สร้าง Python virtual environment (เลือกอย่างใดอย่างหนึ่ง):\nconda create -n aidlearning python=3.11 && conda activate aidlearning # Anaconda/Miniconda\npython -m venv .venv && source .venv/bin/activate # macOS/Linux\npython -m venv .venv && .venv\\Scripts\\activate # Windows\n\n# เริ่ม guided tour\npython scripts/start_tour.py\n```\n\nเมื่อตัวช่วยจบ:\n\n```bash\npython scripts/start_web.py\n```\n\n> **การเปิดใช้งานประจำวัน** — โดยทั่วไปรัน Tour แค่ครั้งเดียว หลังจากนั้นใช้ `python scripts/start_web.py` เพื่อสตาร์ท backend กับ frontend พร้อมกัน (URL ฝั่ง frontend แสดงในเทอร์มินัล) รัน `start_tour.py` อีกครั้งเฉพาะเมื่อต้องตั้งค่า provider ใหม่ เปลี่ยนพอร์ต หรือติดตั้งส่วนเสริมที่ขาด ในหน้า **Settings** ของเว็บกด **Run Tour** เพื่อเล่น walkthrough แบบเน้นจุดอีกครั้ง\n\n### ตัวเลือก B — ติดตั้งเองแบบ Local\n\nหากคุณต้องการควบคุมทุกขั้นตอนด้วยตัวเอง ให้ติดตั้งและตั้งค่าตามนี้\n\n**1. ติดตั้ง dependency**\n\n```bash\ngit clone https://github.com/HKUDS/AidLearning.git\ncd AidLearning\n\nconda create -n aidlearning python=3.11 && conda activate aidlearning\npip install -e \".[server]\"\n\n# Frontend\ncd web && npm install && cd ..\n```\n\n**2. ตั้งค่า runtime settings**\n\n```bash\npython scripts/start_tour.py\n```\n\nแก้ไขไฟล์ `data/user/settings/*.json` และกรอกค่าที่จำเป็นอย่างน้อยดังนี้:\n\n```jsonc\n// Runtime configuration now lives in data/user/settings/.\n// Model/provider credentials: model_catalog.json\n// Ports/CORS/attachments: system.json\n// Auth settings: auth.json (JWT secret stays in multi-user/_system/auth/auth_secret)\n// PocketBase and sidecars: integrations.json\n```\n\n<details>\n<summary><b>ผู้ให้บริการ LLM ที่รองรับ</b></summary>\n\n| ผู้ให้บริการ | Binding | Base URL เริ่มต้น |\n|:--|:--|:--|\n| AiHubMix | `aihubmix` | `https://aihubmix.com/v1` |\n| Anthropic | `anthropic` | `https://api.anthropic.com/v1` |\n| Azure OpenAI | `azure_openai` | — |\n| BytePlus | `byteplus` | `https://ark.ap-southeast.bytepluses.com/api/v3` |\n| BytePlus Coding Plan | `byteplus_coding_plan` | `https://ark.ap-southeast.bytepluses.com/api/coding/v3` |\n| Custom | `custom` | — |\n| Custom (Anthropic API) | `custom_anthropic` | — |\n| DashScope | `dashscope` | `https://dashscope.aliyuncs.com/compatible-mode/v1` |\n| DeepSeek | `deepseek` | `https://api.deepseek.com` |\n| Gemini | `gemini` | `https://generativelanguage.googleapis.com/v1beta/openai/` |\n| GitHub Copilot | `github_copilot` | `https://api.githubcopilot.com` |\n| Groq | `groq` | `https://api.groq.com/openai/v1` |\n| llama.cpp | `llama_cpp` | `http://localhost:8080/v1` |\n| LM Studio | `lm_studio` | `http://localhost:1234/v1` |\n| MiniMax | `minimax` | `https://api.minimaxi.com/v1` |\n| MiniMax (Anthropic) | `minimax_anthropic` | `https://api.minimaxi.com/anthropic` |\n| Mistral | `mistral` | `https://api.mistral.ai/v1` |\n| Moonshot | `moonshot` | `https://api.moonshot.cn/v1` |\n| Ollama | `ollama` | `http://localhost:11434/v1` |\n| OpenAI | `openai` | `https://api.openai.com/v1` |\n| OpenAI Codex | `openai_codex` | `https://chatgpt.com/backend-api` |\n| OpenRouter | `openrouter` | `https://openrouter.ai/api/v1` |\n| OpenVINO Model Server | `ovms` | `http://localhost:8000/v3` |\n| Qianfan | `qianfan` | `https://qianfan.baidubce.com/v2` |\n| SiliconFlow | `siliconflow` | `https://api.siliconflow.cn/v1` |\n| Step Fun | `stepfun` | `https://api.stepfun.com/v1` |\n| vLLM/Local | `vllm` | — |\n| VolcEngine | `volcengine` | `https://ark.cn-beijing.volces.com/api/v3` |\n| VolcEngine Coding Plan | `volcengine_coding_plan` | `https://ark.cn-beijing.volces.com/api/coding/v3` |\n| Xiaomi MIMO | `xiaomi_mimo` | `https://api.xiaomimimo.com/v1` |\n| Zhipu AI | `zhipu` | `https://open.bigmodel.cn/api/paas/v4` |\n\n</details>\n\n<details>\n<summary><b>ผู้ให้บริการ Embedding ที่รองรับ</b></summary>\n\n| ผู้ให้บริการ | Binding | ตัวอย่างโมเดล | Dimension เริ่มต้น |\n|:--|:--|:--|:--|\n| OpenAI | `openai` | `text-embedding-3-large` | 3072 |\n| Azure OpenAI | `azure_openai` | deployment name | — |\n| Cohere | `cohere` | `embed-v4.0` | 1024 |\n| Jina | `jina` | `jina-embeddings-v3` | 1024 |\n| Ollama | `ollama` | `nomic-embed-text` | 768 |\n| vLLM / LM Studio | `vllm` | โมเดล embedding ใดก็ได้ | — |\n| OpenAI-compatible | `custom` | — | — |\n\nผู้ให้บริการที่เข้ากันได้กับ OpenAI (DashScope, SiliconFlow ฯลฯ) ใช้ผ่าน binding `custom` หรือ `openai` ได้\n\n</details>\n\n<details>\n<summary><b>ผู้ให้บริการ Web Search ที่รองรับ</b></summary>\n\n| ผู้ให้บริการ | Env Key | หมายเหตุ |\n|:--|:--|:--|\n| Brave | `BRAVE_API_KEY` | แนะนำ, มี free tier |\n| Tavily | `TAVILY_API_KEY` | |\n| Serper | `SERPER_API_KEY` | ผลการค้นหา Google ผ่าน Serper |\n| Jina | `JINA_API_KEY` | |\n| SearXNG | — | Self-hosted, ไม่ต้องใช้ API key |\n| DuckDuckGo | — | ไม่ต้องใช้ API key |\n| Perplexity | `PERPLEXITY_API_KEY` | ต้องใช้ API key |\n\n</details>\n\n**3. เริ่มบริการ**\n\nวิธีที่เร็วที่สุด:\n\n```bash\npython scripts/start_web.py\n```\n\nคำสั่งนี้จะสตาร์ททั้ง backend และ frontend พร้อมเปิดเบราว์เซอร์ให้โดยอัตโนมัติ\n\nหรือรันแยกเทอร์มินัล:\n\n```bash\n# Backend (FastAPI)\npython -m aidlearning.api.run_server\n\n# Frontend (Next.js) — เปิดอีกเทอร์มินัลหนึ่ง\ncd web && npm run dev -- -p 3782\n```\n\n| Service | Port เริ่มต้น |\n|:---:|:---:|\n| Backend | `8001` |\n| Frontend | `3782` |\n\nเปิด [http://localhost:3782](http://localhost:3782) แล้วพร้อมใช้งาน\n\n### ตัวเลือก C — ติดตั้งด้วย Docker\n\nDocker ช่วยรวม backend และ frontend ไว้ในคอนเทนเนอร์เดียว จึงไม่จำเป็นต้องติดตั้ง Python หรือ Node.js บนเครื่องโดยตรง\n\n**1. สร้าง runtime settings** (จำเป็นสำหรับทุกตัวเลือก)\n\n```bash\ngit clone https://github.com/HKUDS/AidLearning.git\ncd AidLearning\npython scripts/start_tour.py\n```\n\nแก้ไข `data/user/settings/*.json` และกรอกค่าที่จำเป็น (เหมือน [ตัวเลือก B](#ตัวเลือก-b--ติดตั้งเองแบบ-local) ด้านบน)\n\n**2a. ดึง image ทางการ (แนะนำ)**\n\nImage ทางการเผยแพร่ที่ [GitHub Container Registry](https://github.com/HKUDS/AidLearning/pkgs/container/aidlearning) ทุกครั้งที่ release สำหรับ `linux/amd64` และ `linux/arm64`\n\n```bash\npython scripts/docker_compose.py -f docker-compose.ghcr.yml up -d\n```\n\nหากต้องการ pin เวอร์ชันเฉพาะ ให้แก้ image tag ใน `docker-compose.ghcr.yml`:\n\n```yaml\nimage: ghcr.io/hkuds/aidlearning:1.0.0 # หรือ :latest\n```\n\n**2b. Build จาก source**\n\n```bash\npython scripts/docker_compose.py up -d\n```\n\nคำสั่งนี้จะ build image จาก `Dockerfile` และเริ่มคอนเทนเนอร์\n\n**3. ตรวจสอบและจัดการ**\n\nเปิด [http://localhost:3782](http://localhost:3782) เมื่อคอนเทนเนอร์พร้อมแล้ว\n\n```bash\npython scripts/docker_compose.py logs -f # ดู log\npython scripts/docker_compose.py down # หยุดและลบคอนเทนเนอร์\n```\n\n<details>\n<summary><b>Deploy บน Cloud / เซิร์ฟเวอร์ระยะไกล</b></summary>\n\nเมื่อ deploy บนเซิร์ฟเวอร์ระยะไกล เบราว์เซอร์ต้องรู้ URL สาธารณะของ backend API เพิ่มตัวแปรอีกหนึ่งตัวใน `data/user/settings/*.json`:\n\n```json\n{\n \"next_public_api_base_external\": \"https://your-server.com:8001\"\n}\n```\n\nFrontend startup script จะใช้ค่านี้ตอน runtime — ไม่ต้อง rebuild\n\n</details>\n\n<details>\n<summary><b>การยืนยันตัวตน (สำหรับการ deploy สาธารณะ)</b></summary>\n\nการยืนยันตัวตน **ปิดใช้งานโดยค่าเริ่มต้น** — ไม่ต้องเข้าสู่ระบบบน localhost สำหรับการ deploy แบบ multi-tenant ดูส่วน [มัลติยูเซอร์](#multi-user) ด้านล่าง\n\n**ผู้ใช้คนเดียวแบบ headless (ไม่มีขั้นตอน `/register`):** กำหนดค่าล่วงหน้าผ่าน env vars:\n\n```bash\npython -c \"from aidlearning.services.auth import hash_password; print(hash_password('yourpassword'))\"\n```\n\n```jsonc\n// Runtime configuration now lives in data/user/settings/.\n// Model/provider credentials: model_catalog.json\n// Ports/CORS/attachments: system.json\n// Auth settings: auth.json (JWT secret stays in multi-user/_system/auth/auth_secret)\n// PocketBase and sidecars: integrations.json\n```\n\n</details>\n\n<details>\n<summary><b>PocketBase sidecar (ยืนยันตัวตนและจัดเก็บข้อมูลเสริม)</b></summary>\n\nPocketBase เป็น backend เบาแบบ optional ที่แทนที่การยืนยันตัวตน SQLite/JSON ในตัว\n\n> ⚠️ **PocketBase mode ใช้ได้กับผู้ใช้คนเดียวเท่านั้นในปัจจุบัน** สคีมาเริ่มต้นไม่มีฟิลด์ `role` ใน `users` และ queries ไม่ถูกกรองตาม `user_id` Multi-user: ปล่อย `integrations.pocketbase_url` ว่างไว้\n\n```bash\npython scripts/docker_compose.py up -d\nopen http://localhost:8090/_/\npip install pocketbase\npython scripts/pb_setup.py\n```\n\n```jsonc\n// Runtime configuration now lives in data/user/settings/.\n// Model/provider credentials: model_catalog.json\n// Ports/CORS/attachments: system.json\n// Auth settings: auth.json (JWT secret stays in multi-user/_system/auth/auth_secret)\n// PocketBase and sidecars: integrations.json\n```\n\n</details>\n\n<details>\n<summary><b>Development mode (hot-reload)</b></summary>\n\nเพิ่ม dev override เพื่อ mount source code และเปิด hot-reload สำหรับทั้งสองบริการ:\n\n```bash\npython scripts/docker_compose.py -f docker-compose.yml -f docker-compose.dev.yml up\n```\n\nการเปลี่ยนแปลงใน `aidlearning/`, `aidlearning_cli/`, `scripts/` และ `web/` จะมีผลทันที\n\n</details>\n\n<details>\n<summary><b>กำหนด Port เอง</b></summary>\n\nแก้ไข port เริ่มต้นใน `data/user/settings/*.json`:\n\n```json\n{\n \"backend_port\": 9001,\n \"frontend_port\": 4000\n}\n```\n\nจากนั้นรีสตาร์ท:\n\n```bash\npython scripts/docker_compose.py up -d # หรือ python scripts/docker_compose.py -f docker-compose.ghcr.yml up -d\n```\n\n</details>\n\n<details>\n<summary><b>การเก็บข้อมูลถาวร (Data persistence)</b></summary>\n\nข้อมูลผู้ใช้และ knowledge base เก็บผ่าน Docker volume ที่ map กับ directory ในเครื่อง:\n\n| Container path | Host path | เนื้อหา |\n|:---|:---|:---|\n| `/app/data/user` | `./data/user` | Settings, workspace, sessions, logs |\n| `/app/data/memory` | `./data/memory` | หน่วยความจำระยะยาวที่ใช้ร่วมกัน (`SUMMARY.md`, `PROFILE.md`) |\n| `/app/data/knowledge_bases` | `./data/knowledge_bases` | เอกสารที่อัปโหลด & vector indices |\n\nDirectory เหล่านี้จะอยู่หลังจาก `python scripts/docker_compose.py down` และถูกนำมาใช้ใหม่เมื่อ `python scripts/docker_compose.py up` ครั้งต่อไป\n\n</details>\n\n<details>\n<summary><b>Runtime settings / deployment overrides</b></summary>\n\nRuntime settings live in `data/user/settings/*.json`; `model_catalog.json` is the source of truth for model, embedding, and search provider credentials. Non-model runtime settings live in `system.json`, `auth.json`, and `integrations.json`.\n\nDocker startup is JSON-driven via `scripts/docker_compose.py`; use `data/user/settings/*.json` rather than the project-root `.env` or legacy `BACKEND_PORT` / `FRONTEND_PORT` variables.\n\n</details>\n\n### ตัวเลือก D — ใช้เฉพาะ CLI\n\nหากคุณต้องการเฉพาะ command-line interface โดยไม่ใช้เว็บ frontend:\n\n```bash\npip install -e \".[cli]\"\naidlearning chat # Interactive REPL\naidlearning run chat \"Explain Fourier transform\" # เรียกใช้ capability แบบ one-shot\naidlearning run deep_solve \"Solve x^2 = 4\" # แก้ปัญหาแบบหลายเอเจนต์\naidlearning kb create my-kb --doc textbook.pdf # สร้าง knowledge base\n```\n\n> ดูรายละเอียดเพิ่มเติมที่ [AidLearning CLI](#%EF%B8%8F-aidlearning-cli--อินเทอร์เฟซแบบ-agent-native)\n\n---\n\n## 📖 สำรวจ AidLearning\n\n<div align=\"center\">\n<img src=\"../../assets/figs/aidlearning-architecture.png\" alt=\"สถาปัตยกรรม AidLearning\" width=\"800\">\n</div>\n\n### 💬 Chat — พื้นที่ทำงานอัจฉริยะแบบรวม\n\n<div align=\"center\">\n<img src=\"../../assets/figs/dt-chat.png\" alt=\"พื้นที่ Chat\" width=\"800\">\n</div>\n\nAidLearning รวม 6 โหมดหลักไว้ใน workspace เดียว โดยใช้ **ระบบจัดการบริบทร่วมกัน** ทำให้ประวัติการสนทนา knowledge base และแหล่งอ้างอิงต่อเนื่องข้ามโหมดได้ — สลับไปมาได้อิสระในหัวข้อเดียวกัน\n\n| โหมด | หน้าที่ |\n|:---|:---|\n| **Chat** | สนทนาแบบยืดหยุ่น พร้อมเปิดใช้ RAG, web search, code execution, deep reasoning, brainstorming และ paper search ได้ตามต้องการ |\n| **Deep Solve** | แก้ปัญหาแบบหลายเอเจนต์ โดยวางแผน สืบค้น แก้โจทย์ และตรวจสอบ พร้อม citation อย่างเป็นระบบ |\n| **Quiz Generation** | สร้างแบบทดสอบจาก knowledge base พร้อมตรวจสอบคุณภาพของคำถาม |\n| **Deep Research** | แยกหัวข้อออกเป็นประเด็นย่อย ส่งเอเจนต์ค้นคว้าแบบขนานจาก RAG, เว็บ และงานวิชาการ แล้วสรุปเป็นรายงานที่มีอ้างอิง |\n| **Math Animator** | เปลี่ยนแนวคิดคณิตศาสตร์ให้เป็นภาพเคลื่อนไหวและ storyboard ด้วย Manim |\n| **Visualize** | สร้าง SVG, Chart.js, Mermaid หรือหน้า HTML แบบรวมไฟล์เดียวจากคำอธิบายภาษาธรรมดา |\n\nเครื่องมือ **แยกอิสระจาก workflow** — ในทุกโหมด คุณเลือกได้ว่าจะเปิดเครื่องมือตัวไหน ใช้กี่ตัว หรือจะไม่ใช้เลย Workflow จัดการเรื่องการให้เหตุผล ส่วนเครื่องมือเป็นของคุณที่จะประกอบเข้าด้วยกัน\n\n> เริ่มจากถามคำถามง่าย ๆ ยกระดับเป็น Deep Solve เมื่อยากขึ้น แสดงภาพความคิด สร้างแบบทดสอบเพื่อตรวจสอบตัวเอง จากนั้นเปิด Deep Research เพื่อลงลึก — ทั้งหมดในเธรดเดียว\n\n### ✍️ Co-Writer — พื้นที่เขียนหลายเอกสารกับ AI\n\n<div align=\"center\">\n<img src=\"../../assets/figs/dt-cowriter.png\" alt=\"Co-Writer\" width=\"800\">\n</div>\n\nสร้างและจัดการหลายเอกสาร แต่ละไฟล์ถูกเก็บถาวร — ไม่ใช่แค่ฉบับร่างครั้งเดียว: Markdown เต็มรูปแบบที่ AI เป็นผู้ร่วมเขียนระดับแรก เลือกข้อความแล้วสั่ง **Rewrite**, **Expand** หรือ **Shorten** ดึงบริบทจาก knowledge base หรือเว็บ undo/redo เต็มรูปแบบ บันทึกลง notebook ได้\n\n### 📖 Book Engine — หนังสือมีชีวิตแบบโต้ตอบ\n\n<div align=\"center\">\n<img src=\"../../assets/figs/dt-book-0.png\" alt=\"ห้องสมุด\" width=\"270\"><img src=\"../../assets/figs/dt-book-1.png\" alt=\"ตัวอ่าน\" width=\"270\"><img src=\"../../assets/figs/dt-book-2.png\" alt=\"แอนิเมชัน\" width=\"270\">\n</div>\n\nระบุหัวข้อชี้ไปที่ knowledge base — ได้หนังสือที่มีโครงสร้างและโต้ตอบได้ ไม่ใช่ไฟล์ส่งออกคงที่ แต่เป็นเอกสารมีชีวิตสำหรับอ่าน ทดสอบตัวเอง และพูดคุยในบริบท\n\nเบื้องหลังเป็นไปป์ไลน์หลายเอเจนต์: เสนอโครงร่าง ดึงแหล่งอ้างอิง รวมต้นไม้บท วางแผนหน้า และคอมไพล์บล็อก คุณยังคุมได้: ตรวจโครงร่าง จัดเรียบบท แชตข้างหน้าใดก็ได้\n\n13 ประเภทบล็อก — ข้อความ callout แบบทดสอบ แฟลชการ์ด โค้ด รูป ดำดิ่งลึก แอนิเมชัน แบบโต้ตอบ ไทม์ไลน์ กราฟแนวคิด ส่วน โน้ตผู้ใช้ — แต่ละแบบมีคอมโพเนนต์โต้ตอบ ไทม์ไลน์ความคืบหน้าแบบเรียลไทม์\n\n### 📚 การจัดการความรู้ — โครงสร้างพื้นฐานการเรียนของคุณ\n\n<div align=\"center\">\n<img src=\"../../assets/figs/dt-knowledge.png\" alt=\"การจัดการความรู้\" width=\"800\">\n</div>\n\nคอลเลกชันเอกสาร โน้ต และบุคลิกการสอน\n\n- **Knowledge Bases** — อัปโหลด PDF, TXT หรือ Markdown เพิ่มทีละไฟล์\n- **Notebooks** — บันทึกจาก Chat, Co-Writer, Book หรือ Deep Research จัดหมวดและสี\n- **Question Bank** — ทบทวนคำถามที่สร้างแล้ว บุ๊กมาร์กและ @ ในแชตเพื่อวิเคราะห์ผลในอดีต\n- **Skills** — สร้างบุคลิกการสอนด้วย `SKILL.md`: ชื่อ คำอธิบาย ทริกเกอร์ (ถ้ามี) และ Markdown ที่ฉีดเข้า system prompt เมื่อเปิดใช้\n\nKnowledge base ของคุณไม่ใช่แค่ที่เก็บ — มันมีส่วนร่วมอย่างแข็งขันในทุกการสนทนา ทุกเซสชันวิจัย และทุกเส้นทางการเรียนรู้\n\n### 🧠 Memory — AidLearning เรียนรู้ไปพร้อมกับคุณ\n\n<div align=\"center\">\n<img src=\"../../assets/figs/dt-memory.png\" alt=\"Memory\" width=\"800\">\n</div>\n\nAidLearning มี memory แบบถาวรที่เติบโตอยู่ตลอดเวลาผ่าน 2 มิติ:\n\n- **Summary** — สรุปว่าคุณเรียนอะไรไปแล้ว สำรวจประเด็นใดบ้าง และความเข้าใจพัฒนาอย่างไร\n- **Profile** — โปรไฟล์ผู้เรียน เช่น ระดับความรู้ เป้าหมาย สไตล์การสื่อสาร และความชอบ — ปรับปรุงอัตโนมัติผ่านทุกการโต้ตอบ\n\nMemory นี้ถูกใช้ร่วมกันข้ามทุกฟีเจอร์และทุก TutorBot ยิ่งคุณใช้ AidLearning มากเท่าไร มันก็ยิ่งตอบได้เฉพาะตัวและมีประสิทธิภาพมากขึ้น\n\n---\n\n### 🦞 TutorBot — ติวเตอร์ AI แบบถาวรและอัตโนมัติ\n\n<div align=\"center\">\n<img src=\"../../assets/figs/tutorbot-architecture.png\" alt=\"สถาปัตยกรรม TutorBot\" width=\"800\">\n</div>\n\nTutorBot ไม่ใช่ chatbot ธรรมดา แต่เป็น **เอเจนต์แบบถาวร หลายอินสแตนซ์** ที่ทำงานบน [nanobot](https://github.com/HKUDS/nanobot) โดยแต่ละ TutorBot รัน agent loop เป็นของตัวเองพร้อม workspace, memory และบุคลิกแยกจากกัน คุณสามารถสร้างติวเตอร์คณิตศาสตร์แบบโสเครติส, โค้ชการเขียนที่ใจเย็น หรือผู้ช่วยวิจัยที่เข้มงวดได้พร้อมกันหลายตัว แต่ละตัวเติบโตไปพร้อมกับคุณ\n\n<div align=\"center\">\n<img src=\"../../assets/figs/tb.png\" alt=\"TutorBot\" width=\"800\">\n</div>\n\n- **Soul Templates** — กำหนดบุคลิก โทนการสอน และปรัชญาการสอนผ่านไฟล์ Soul ที่แก้ไขได้ เลือกจาก archetype ในตัว (โสเครติส, ให้กำลังใจ, เข้มงวด) หรือออกแบบเอง — soul กำหนดทุกการตอบ\n- **Independent Workspace** — แต่ละบอตมี directory ของตัวเองพร้อม memory, sessions, skills และ config แยกจากกัน — แยกตัวเต็มที่แต่ยังเข้าถึงชั้นความรู้ร่วมของ AidLearning ได้\n- **Proactive Heartbeat** — บอตไม่ใช่แค่ตอบ — มันริเริ่มเอง ระบบ Heartbeat ในตัวเปิดให้เช็กอินการเรียนซ้ำ เตือนทบทวน และจัดตารางงาน ติวเตอร์ของคุณมาหาแม้คุณไม่เริ่ม\n- **Full Tool Access** — ทุกบอตเข้าถึงเครื่องมือครบชุดของ AidLearning: RAG retrieval, code execution, web search, academic paper search, deep reasoning และ brainstorming\n- **Skill Learning** — สอนบอตความสามารถใหม่โดยเพิ่มไฟล์ skill ลงใน workspace ของมัน เมื่อความต้องการของคุณเปลี่ยน ความสามารถของติวเตอร์ก็เปลี่ยนตาม\n- **Multi-Channel Presence** — เชื่อมต่อกับ Telegram, Discord, Slack, Feishu, WeChat Work, DingTalk, Email และช่องทางอื่น ๆ ติวเตอร์ไปหาคุณไม่ว่าคุณจะอยู่ที่ไหน\n- **Team & Sub-Agents** — สร้าง sub-agent ทำงานเบื้องหลังหรือจัด multi-agent team ภายในบอตเดียวสำหรับงานซับซ้อนและใช้เวลานาน\n\n```bash\naidlearning bot create math-tutor --persona \"Socratic math teacher who uses probing questions\"\naidlearning bot create writing-coach --persona \"Patient, detail-oriented writing mentor\"\naidlearning bot list # ดูติวเตอร์ทั้งหมดที่กำลังทำงาน\n```\n\n---\n\n### ⌨️ AidLearning CLI — อินเทอร์เฟซแบบ Agent-Native\n\n<div align=\"center\">\n<img src=\"../../assets/figs/cli-architecture.png\" alt=\"สถาปัตยกรรม AidLearning CLI\" width=\"800\">\n</div>\n\nAidLearning รองรับ CLI อย่างเต็มรูปแบบ ทุก capability, knowledge base, session, memory และ TutorBot อยู่ห่างแค่คำสั่งเดียว — ไม่ต้องเปิดเบราว์เซอร์ CLI ให้บริการทั้งมนุษย์ (แสดงผลสวยงามในเทอร์มินัล) และ AI agent (ส่งออกเป็น JSON ที่มีโครงสร้าง)\n\nมอบ [`SKILL.md`](../../SKILL.md) ที่ root ของโปรเจกต์ให้ agent ที่ใช้เครื่องมือ ([nanobot](https://github.com/HKUDS/nanobot) หรือ LLM ใดก็ตามที่มี tool access) แล้วมันจะตั้งค่าและใช้งาน AidLearning ได้เอง\n\n**One-shot execution** — เรียกใช้ capability ใดก็ได้จากเทอร์มินัล:\n\n```bash\naidlearning run chat \"Explain the Fourier transform\" -t rag --kb textbook\naidlearning run deep_solve \"Prove that √2 is irrational\" -t reason\naidlearning run deep_question \"Linear algebra\" --config num_questions=5\naidlearning run deep_research \"Attention mechanisms in transformers\"\naidlearning run visualize \"Draw the architecture of a transformer\"\n```\n\n**Interactive REPL** — เซสชันแชตแบบถาวรพร้อมสลับโหมดขณะใช้งาน:\n\n```bash\naidlearning chat --capability deep_solve --kb my-kb\n# ภายใน REPL: /cap, /tool, /kb, /history, /notebook, /config เพื่อสลับขณะใช้งาน\n```\n\n**Knowledge base lifecycle** — สร้าง ค้นหา และจัดการคลัง RAG-ready ทั้งหมดจากเทอร์มินัล:\n\n```bash\naidlearning kb create my-kb --doc textbook.pdf # สร้างจากเอกสาร\naidlearning kb add my-kb --docs-dir ./papers/ # เพิ่มโฟลเดอร์เอกสาร\naidlearning kb search my-kb \"gradient descent\" # ค้นหาโดยตรง\naidlearning kb set-default my-kb # ตั้งเป็น KB เริ่มต้น\n```\n\n**Dual output mode** — แสดงผลสวยงามสำหรับมนุษย์, JSON สำหรับ pipeline:\n\n```bash\naidlearning run chat \"Summarize chapter 3\" -f rich # แสดงผลสี สวยงาม\naidlearning run chat \"Summarize chapter 3\" -f json # JSON events แบบ line-delimited\n```\n\n**Session continuity** — กลับมาทำต่อจากจุดที่ค้างไว้:\n\n```bash\naidlearning session list # แสดงรายการเซสชัน\naidlearning session open <id> # กลับมาทำต่อใน REPL\n```\n\n<details>\n<summary><b>ตารางอ้างอิงคำสั่ง CLI ทั้งหมด</b></summary>\n\n**คำสั่งหลัก**\n\n| คำสั่ง | คำอธิบาย |\n|:---|:---|\n| `aidlearning run <capability> <message>` | เรียกใช้ capability แบบ single turn (`chat`, `deep_solve`, `deep_question`, `deep_research`, `math_animator`, `visualize`) |\n| `aidlearning chat` | Interactive REPL พร้อมตัวเลือก `--capability`, `--tool`, `--kb`, `--language` |\n| `aidlearning serve` | เริ่ม AidLearning API server |\n\n**`aidlearning bot`**\n\n| คำสั่ง | คำอธิบาย |\n|:---|:---|\n| `aidlearning bot list` | แสดงรายการ TutorBot ทั้งหมด |\n| `aidlearning bot create <id>` | สร้างและเริ่มบอตใหม่ (`--name`, `--persona`, `--model`) |\n| `aidlearning bot start <id>` | เริ่มบอต |\n| `aidlearning bot stop <id>` | หยุดบอต |\n\n**`aidlearning kb`**\n\n| คำสั่ง | คำอธิบาย |\n|:---|:---|\n| `aidlearning kb list` | แสดงรายการ knowledge base ทั้งหมด |\n| `aidlearning kb info <name>` | แสดงรายละเอียด knowledge base |\n| `aidlearning kb create <name>` | สร้างจากเอกสาร (`--doc`, `--docs-dir`) |\n| `aidlearning kb add <name>` | เพิ่มเอกสารทีละไฟล์ |\n| `aidlearning kb search <name> <query>` | ค้นหา knowledge base |\n| `aidlearning kb set-default <name>` | ตั้งเป็น KB เริ่มต้น |\n| `aidlearning kb delete <name>` | ลบ knowledge base (`--force`) |\n\n**`aidlearning memory`**\n\n| คำสั่ง | คำอธิบาย |\n|:---|:---|\n| `aidlearning memory show [file]` | ดู memory (`summary`, `profile` หรือ `all`) |\n| `aidlearning memory clear [file]` | ล้าง memory (`--force`) |\n\n**`aidlearning session`**\n\n| คำสั่ง | คำอธิบาย |\n|:---|:---|\n| `aidlearning session list` | แสดงรายการเซสชัน (`--limit`) |\n| `aidlearning session show <id>` | ดูข้อความในเซสชัน |\n| `aidlearning session open <id>` | กลับมาทำต่อใน REPL |\n| `aidlearning session rename <id>` | เปลี่ยนชื่อเซสชัน (`--title`) |\n| `aidlearning session delete <id>` | ลบเซสชัน |\n\n**`aidlearning notebook`**\n\n| คำสั่ง | คำอธิบาย |\n|:---|:---|\n| `aidlearning notebook list` | แสดงรายการ notebook |\n| `aidlearning notebook create <name>` | สร้าง notebook (`--description`) |\n| `aidlearning notebook show <id>` | ดูบันทึกใน notebook |\n| `aidlearning notebook add-md <id> <path>` | นำเข้า markdown เป็นบันทึก |\n| `aidlearning notebook replace-md <id> <rec> <path>` | เปลี่ยนบันทึก markdown |\n| `aidlearning notebook remove-record <id> <rec>` | ลบบันทึก |\n\n**`aidlearning book`**\n\n| คำสั่ง | คำอธิบาย |\n|:---|:---|\n| `aidlearning book list` | แสดงรายการหนังสือทั้งหมดใน workspace |\n| `aidlearning book health <book_id>` | ตรวจ KB drift และสุขภาพของหนังสือ |\n| `aidlearning book refresh-fingerprints <book_id>` | รีเฟรช fingerprint ของ KB และล้างหน้าที่ล้าสมัย |\n\n**`aidlearning config` / `plugin` / `provider`**\n\n| คำสั่ง | คำอธิบาย |\n|:---|:---|\n| `aidlearning config show` | แสดงสรุป configuration ปัจจุบัน |\n| `aidlearning plugin list` | แสดงรายการ tools และ capabilities ที่ลงทะเบียน |\n| `aidlearning plugin info <name>` | แสดงรายละเอียด tool หรือ capability |\n| `aidlearning provider login <provider>` | ยืนยันตัวตนกับผู้ให้บริการ (OAuth กับ `openai-codex`; `github-copilot` ตรวจเซสชัน Copilot ที่มีอยู่) |\n\n</details>\n\n---\n\n<a id=\"multi-user\"></a>\n### 👥 มัลติยูเซอร์ — การ deploy ร่วมกันพร้อม workspace แยกต่อผู้ใช้\n\n<div align=\"center\">\n<img src=\"../../assets/figs/dt-multi-user.png\" alt=\"มัลติยูเซอร์\" width=\"800\">\n</div>\n\nเปิดใช้การยืนยันตัวตน และ AidLearning จะกลายเป็น deployment แบบ multi-tenant พร้อม **workspace แยกต่อผู้ใช้** และ **ทรัพยากรที่ผู้ดูแลจัดการ** ผู้ที่ลงทะเบียนคนแรกจะเป็นผู้ดูแล บัญชีถัดไปสร้างโดยผู้ดูแล (แบบ invite-only) แต่ละคนได้รับประวัติแชต/หน่วยความจำ/สมุดบันทึก/ฐานความรู้ของตนเอง\n\n**เริ่มต้นด่วน (5 ขั้นตอน):**\n\n```bash\n# 1. เปิดใช้การยืนยันตัวตนใน data/user/settings/*.json ที่ root ของโปรเจกต์\n# Set auth.json enabled=true\n# JWT secret is stored in multi-user/_system/auth/auth_secret\n\n# 2. รีสตาร์ท web stack\npython scripts/start_web.py\n\n# 3. เปิด http://localhost:3782/register และสร้างบัญชีแรก\n# การลงทะเบียนครั้งแรกเป็นครั้งเดียวที่เปิดสาธารณะ ผู้ใช้นั้น\n# จะเป็นผู้ดูแล และ /register จะถูกปิดอัตโนมัติ\n\n# 4. ในฐานะผู้ดูแล ไปที่ /admin/users → \"เพิ่มผู้ใช้\"\n\n# 5. สำหรับแต่ละผู้ใช้ คลิกไอคอนสไลเดอร์ → กำหนด LLM profiles,\n# knowledge bases, และ skills → บันทึก\n```\n\n**สิ่งที่ผู้ดูแลเห็น:**\n\n- **หน้า Settings ครบ** ที่ `/settings` — LLM/embedding/search, API keys, model catalog\n- **จัดการผู้ใช้** ที่ `/admin/users` — สร้าง เลื่อนตำแหน่ง ลดตำแหน่ง ลบบัญชี\n- **Grant editor** — เลือก model profiles, KBs, skills สำหรับผู้ใช้ที่ไม่ใช่ผู้ดูแล; grants มีแค่ **logical IDs** ไม่มี API key ข้ามขอบเขต\n- **Audit trail** — ทุกการเปลี่ยนแปลง grant บันทึกใน `multi-user/_system/audit/usage.jsonl`\n\n**สิ่งที่ผู้ใช้ทั่วไปได้รับ:**\n\n- **Workspace แยก** ใต้ `multi-user/<uid>/` — `chat_history.db`, หน่วยความจำ, สมุดบันทึก, KB ส่วนตัว\n- **สิทธิ์อ่านอย่างเดียว** สำหรับ KBs/skills ที่ผู้ดูแลกำหนด พร้อมป้าย \"กำหนดโดยผู้ดูแล\"\n- **หน้า Settings แบบจำกัด** — ธีม ภาษา และสรุป models ที่ได้รับ ไม่มี API keys\n- **LLM ที่กำหนด** — การสนทนาผ่าน model ที่ผู้ดูแลกำหนด; ไม่มี grant จะถูกปฏิเสธตั้งแต่ต้น\n\n**โครงสร้าง workspace:**\n\n```\nmulti-user/\n├── _system/\n│ ├── auth/users.json\n│ ├── auth/auth_secret\n│ ├── grants/<uid>.json\n│ └── audit/usage.jsonl\n└── <uid>/\n ├── user/\n │ ├── chat_history.db\n │ ├── settings/interface.json\n │ └── workspace/{chat,co-writer,book,...}\n ├── memory/{SUMMARY.md,PROFILE.md}\n └── knowledge_bases/...\n```\n\n**Configuration reference:**\n\nRuntime settings live in `data/user/settings/*.json`. For headless single-user bootstrap, set `username` and `password_hash` in `auth.json`; for multi-user registration, leave those blank and use the identity store.\n\n> ⚠️ **PocketBase mode (`integrations.pocketbase_url` ตั้งค่า) ใช้ได้กับผู้ใช้คนเดียวเท่านั้น** — ไม่มีฟิลด์ `role`, ไม่มีการกรองตาม `user_id` Multi-user: ปล่อย `integrations.pocketbase_url` ว่างไว้\n\n> ⚠️ **แนะนำ single process** การเลื่อนตำแหน่งผู้ดูแลคนแรกป้องกันด้วย `threading.Lock` หลาย workers: สร้างผู้ดูแลคนแรกแบบออฟไลน์\n\n## 🗺️ แผนงานในอนาคต\n\n| สถานะ | หมุดหมาย |\n|:---:|:---|\n| 🎯 | **Authentication & Login** — รองรับหน้าเข้าสู่ระบบแบบเลือกใช้สำหรับการ deploy สาธารณะและผู้ใช้หลายคน |\n| 🎯 | **Themes & Appearance** — ธีมและการปรับแต่งหน้าตา UI ที่หลากหลายขึ้น |\n| 🎯 | **Interaction Improvement** — ปรับปรุง icon และรายละเอียดการโต้ตอบ |\n| 🔜 | **Better Memories** — ยกระดับระบบจัดการ memory |\n| 🔜 | **LightRAG Integration** — รวม [LightRAG](https://github.com/HKUDS/LightRAG) เป็น knowledge base engine ขั้นสูง |\n| 🔜 | **Documentation Site** — เว็บไซต์เอกสารที่ครบถ้วนขึ้น ทั้งคู่มือ, API reference และ tutorial |\n\n> หาก AidLearning มีประโยชน์สำหรับคุณ [ฝากกดดาว](https://github.com/HKUDS/AidLearning/stargazers) — มันช่วยให้เราพัฒนาต่อไปได้!\n\n---\n\n## 🌐 ชุมชนและระบบนิเวศ\n\nAidLearning สร้างขึ้นบนโครงการโอเพนซอร์สคุณภาพหลายตัว:\n\n| โครงการ | บทบาทใน AidLearning |\n|:---|:---|\n| [**nanobot**](https://github.com/HKUDS/nanobot) | เอนจินเอเจนต์น้ำหนักเบาที่ขับเคลื่อน TutorBot |\n| [**LlamaIndex**](https://github.com/run-llama/llama_index) | แกนหลักสำหรับ RAG pipeline และการทำดัชนีเอกสาร |\n| [**ManimCat**](https://github.com/Wing900/ManimCat) | ระบบสร้างแอนิเมชันคณิตศาสตร์สำหรับ Math Animator |\n\n**จาก ecosystem ของ HKUDS:**\n\n| [⚡ LightRAG](https://github.com/HKUDS/LightRAG) | [🤖 AutoAgent](https://github.com/HKUDS/AutoAgent) | [🔬 AI-Researcher](https://github.com/HKUDS/AI-Researcher) | [🧬 nanobot](https://github.com/HKUDS/nanobot) |\n|:---:|:---:|:---:|:---:|\n| Simple & Fast RAG | Zero-Code Agent Framework | Automated Research | Ultra-Lightweight AI Agent |\n\n## 🤝 การมีส่วนร่วม\n\n<div align=\"center\">\n\nเราหวังว่า AidLearning จะเป็นของขวัญแก่ชุมชน 🎁\n\n<a href=\"https://github.com/HKUDS/AidLearning/graphs/contributors\">\n <img src=\"https://contrib.rocks/image?repo=HKUDS/AidLearning&max=999\" alt=\"Contributors\" />\n</a>\n\n</div>\n\nอ่าน [CONTRIBUTING.md](../../CONTRIBUTING.md) สำหรับคำแนะนำเกี่ยวกับการตั้งค่าสภาพแวดล้อมสำหรับนักพัฒนา มาตรฐานโค้ด และขั้นตอนการส่ง pull request\n\n## ⭐ ประวัติดาว\n\n<div align=\"center\">\n\n<a href=\"https://www.star-history.com/#HKUDS/AidLearning&type=timeline&legend=top-left\">\n <picture>\n <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://api.star-history.com/svg?repos=HKUDS/AidLearning&type=timeline&theme=dark&legend=top-left\" />\n <source media=\"(prefers-color-scheme: light)\" srcset=\"https://api.star-history.com/svg?repos=HKUDS/AidLearning&type=timeline&legend=top-left\" />\n <img alt=\"Star History Chart\" src=\"https://api.star-history.com/svg?repos=HKUDS/AidLearning&type=timeline&legend=top-left\" />\n </picture>\n</a>\n\n</div>\n\n<p align=\"center\">\n <a href=\"https://www.star-history.com/hkuds/aidlearning\">\n <picture>\n <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://api.star-history.com/badge?repo=HKUDS/AidLearning&theme=dark\" />\n <source media=\"(prefers-color-scheme: light)\" srcset=\"https://api.star-history.com/badge?repo=HKUDS/AidLearning\" />\n <img alt=\"Star History Rank\" src=\"https://api.star-history.com/badge?repo=HKUDS/AidLearning\" />\n </picture>\n </a>\n</p>\n\n<div align=\"center\">\n\n**[Data Intelligence Lab @ HKU](https://github.com/HKUDS)**\n\n[⭐ กดดาว](https://github.com/HKUDS/AidLearning/stargazers) · [🐛 รายงานบั๊ก](https://github.com/HKUDS/AidLearning/issues) · [💬 Discussions](https://github.com/HKUDS/AidLearning/discussions)\n\n---\n\nเผยแพร่ภายใต้สัญญาอนุญาต [Apache License 2.0](../../LICENSE)\n\n<p>\n <img src=\"https://visitor-badge.laobi.icu/badge?page_id=HKUDS.AidLearning&style=for-the-badge&color=00d4ff\" alt=\"Views\">\n</p>\n\n</div>\n"}}, "health-app/study/aid_learning_agent/aidlearning/services/provider_registry.py": {"1d1a93717421d10f6294c917a377ace11cb3c248": {"t": 1785674679.0273073, "n": 15354, "h": "308ab01652b61f3c", "c": "\"\"\"Provider Registry — LLM Provider 元数据注册表\n\n【调用链路位置】factory.py → find_by_name/find_by_model → ProviderSpec\n\nProviderSpec 定义每个 Provider 的属性:\n - name/keywords: 名称和匹配关键词\n - backend: 使用哪个实现(openai_compat/anthropic/azure_openai 等)\n - default_api_base: 默认 API 地址\n - is_gateway/is_local/is_oauth: 类型标记\n - supports_prompt_caching: 是否支持 prompt 缓存\n\n新增 Provider 只需在 PROVIDERS 列表中添加一个 ProviderSpec。\n\"\"\"\n\nfrom __future__ import annotations\n\nfrom dataclasses import dataclass\nfrom typing import Any\n\nfrom pydantic.alias_generators import to_snake\n\n\n@dataclass(frozen=True)\nclass ProviderSpec:\n \"\"\"单个 Provider 元数据条目。\n\n env_extras 值中的占位符:\n {api_key} — 用户的 API 密钥\n {api_base} — 配置中的 api_base,或此规格的 default_api_base\n \"\"\"\n\n name: str\n keywords: tuple[str, ...]\n env_key: str\n display_name: str = \"\"\n\n # 使用哪个 Provider 实现:\n # \"openai_compat\" | \"anthropic\" | \"azure_openai\" | \"openai_codex\" | \"github_copilot\"\n backend: str = \"openai_compat\"\n\n env_extras: tuple[tuple[str, str], ...] = ()\n is_gateway: bool = False\n is_local: bool = False\n detect_by_key_prefix: str = \"\"\n detect_by_base_keyword: str = \"\"\n default_api_base: str = \"\"\n strip_model_prefix: bool = False\n supports_max_completion_tokens: bool = False\n supports_prompt_caching: bool = False\n supports_stream_options: bool = True\n model_overrides: tuple[tuple[str, dict[str, Any]], ...] = ()\n is_oauth: bool = False\n is_direct: bool = False\n thinking_style: str = \"\"\n # 子串模式(不区分大小写),标记需要展示原生推理轨迹的模型。\n # 当调用方未传入显式 reasoning_effort 时,Provider 会自动注入 \"high\",\n # 以便发送 thinking_style 标志(如 extra_body.thinking.type=enabled)。\n reasoning_model_patterns: tuple[str, ...] = ()\n\n @property\n def mode(self) -> str:\n if self.is_oauth:\n return \"oauth\"\n if self.is_direct:\n return \"direct\"\n if self.is_gateway:\n return \"gateway\"\n if self.is_local:\n return \"local\"\n return \"standard\"\n\n @property\n def label(self) -> str:\n return self.display_name or self.name.title()\n\n\nPROVIDER_ALIASES = {\n \"azure\": \"azure_openai\",\n \"azure-openai\": \"azure_openai\",\n \"azureopenai\": \"azure_openai\",\n \"google\": \"gemini\",\n \"google_genai\": \"gemini\",\n \"claude\": \"anthropic\",\n \"openai_compatible\": \"custom\",\n \"openai-compatible\": \"custom\",\n \"anthropic_compatible\": \"custom_anthropic\",\n \"anthropic-compatible\": \"custom_anthropic\",\n \"volcenginecodingplan\": \"volcengine_coding_plan\",\n \"volcengineCodingPlan\": \"volcengine_coding_plan\",\n \"bytepluscodingplan\": \"byteplus_coding_plan\",\n \"byteplusCodingPlan\": \"byteplus_coding_plan\",\n \"github-copilot\": \"github_copilot\",\n \"openai-codex\": \"openai_codex\",\n \"lm-studio\": \"lm_studio\",\n}\n\n\ndef canonical_provider_name(name: str | None) -> str | None:\n \"\"\"标准化传入的 Provider 名称和旧版别名。\"\"\"\n if not name:\n return None\n key = name.strip()\n if not key:\n return None\n key = to_snake(key.replace(\"-\", \"_\"))\n return PROVIDER_ALIASES.get(key, key)\n\n\n# ---------------------------------------------------------------------------\n# PROVIDERS — 注册表。顺序 = 优先级。\n# ---------------------------------------------------------------------------\n\nPROVIDERS: tuple[ProviderSpec, ...] = (\n # === 直连(用户自行配置,无自动检测)================================\n ProviderSpec(\n name=\"custom\",\n keywords=(),\n env_key=\"\",\n display_name=\"Custom\",\n backend=\"openai_compat\",\n is_direct=True,\n ),\n ProviderSpec(\n name=\"custom_anthropic\",\n keywords=(),\n env_key=\"\",\n display_name=\"Custom (Anthropic API)\",\n backend=\"anthropic\",\n is_direct=True,\n ),\n ProviderSpec(\n name=\"azure_openai\",\n keywords=(\"azure\", \"azure_openai\"),\n env_key=\"\",\n display_name=\"Azure OpenAI\",\n backend=\"azure_openai\",\n is_direct=True,\n ),\n # === 网关(通过 api_key / api_base 检测,可路由任意模型)================\n ProviderSpec(\n name=\"openrouter\",\n keywords=(\"openrouter\",),\n env_key=\"OPENROUTER_API_KEY\",\n display_name=\"OpenRouter\",\n backend=\"openai_compat\",\n is_gateway=True,\n detect_by_key_prefix=\"sk-or-\",\n detect_by_base_keyword=\"openrouter\",\n default_api_base=\"https://openrouter.ai/api/v1\",\n supports_prompt_caching=True,\n ),\n ProviderSpec(\n name=\"aihubmix\",\n keywords=(\"aihubmix\",),\n env_key=\"OPENAI_API_KEY\",\n display_name=\"AiHubMix\",\n backend=\"openai_compat\",\n is_gateway=True,\n detect_by_base_keyword=\"aihubmix\",\n default_api_base=\"https://aihubmix.com/v1\",\n strip_model_prefix=True,\n ),\n ProviderSpec(\n name=\"siliconflow\",\n keywords=(\"siliconflow\",),\n env_key=\"OPENAI_API_KEY\",\n display_name=\"SiliconFlow\",\n backend=\"openai_compat\",\n is_gateway=True,\n detect_by_base_keyword=\"siliconflow\",\n default_api_base=\"https://api.siliconflow.cn/v1\",\n ),\n ProviderSpec(\n name=\"volcengine\",\n keywords=(\"volcengine\", \"volces\", \"ark\"),\n env_key=\"OPENAI_API_KEY\",\n display_name=\"VolcEngine\",\n backend=\"openai_compat\",\n is_gateway=True,\n detect_by_base_keyword=\"volces\",\n default_api_base=\"https://ark.cn-beijing.volces.com/api/v3\",\n thinking_style=\"thinking_type\",\n ),\n ProviderSpec(\n name=\"volcengine_coding_plan\",\n keywords=(\"volcengine-plan\",),\n env_key=\"OPENAI_API_KEY\",\n display_name=\"VolcEngine Coding Plan\",\n backend=\"openai_compat\",\n is_gateway=True,\n default_api_base=\"https://ark.cn-beijing.volces.com/api/coding/v3\",\n strip_model_prefix=True,\n thinking_style=\"thinking_type\",\n ),\n ProviderSpec(\n name=\"byteplus\",\n keywords=(\"byteplus\",),\n env_key=\"OPENAI_API_KEY\",\n display_name=\"BytePlus\",\n backend=\"openai_compat\",\n is_gateway=True,\n detect_by_base_keyword=\"bytepluses\",\n default_api_base=\"https://ark.ap-southeast.bytepluses.com/api/v3\",\n strip_model_prefix=True,\n thinking_style=\"thinking_type\",\n ),\n ProviderSpec(\n name=\"byteplus_coding_plan\",\n keywords=(\"byteplus-plan\",),\n env_key=\"OPENAI_API_KEY\",\n display_name=\"BytePlus Coding Plan\",\n backend=\"openai_compat\",\n is_gateway=True,\n default_api_base=\"https://ark.ap-southeast.bytepluses.com/api/coding/v3\",\n strip_model_prefix=True,\n thinking_style=\"thinking_type\",\n ),\n # === 标准 Provider(通过模型名称关键词匹配)============================\n ProviderSpec(\n name=\"anthropic\",\n keywords=(\"anthropic\", \"claude\"),\n env_key=\"ANTHROPIC_API_KEY\",\n display_name=\"Anthropic\",\n backend=\"anthropic\",\n default_api_base=\"https://api.anthropic.com/v1\",\n supports_prompt_caching=True,\n ),\n ProviderSpec(\n name=\"openai\",\n keywords=(\"openai\", \"gpt\"),\n env_key=\"OPENAI_API_KEY\",\n display_name=\"OpenAI\",\n backend=\"openai_compat\",\n default_api_base=\"https://api.openai.com/v1\",\n supports_max_completion_tokens=True,\n ),\n ProviderSpec(\n name=\"openai_codex\",\n keywords=(\"openai-codex\",),\n env_key=\"\",\n display_name=\"OpenAI Codex\",\n backend=\"openai_codex\",\n detect_by_base_keyword=\"codex\",\n is_oauth=True,\n default_api_base=\"https://chatgpt.com/backend-api\",\n ),\n ProviderSpec(\n name=\"github_copilot\",\n keywords=(\"github_copilot\", \"copilot\"),\n env_key=\"\",\n display_name=\"GitHub Copilot\",\n backend=\"github_copilot\",\n is_oauth=True,\n default_api_base=\"https://api.githubcopilot.com\",\n strip_model_prefix=True,\n supports_max_completion_tokens=True,\n ),\n ProviderSpec(\n name=\"deepseek\",\n keywords=(\"deepseek\",),\n env_key=\"DEEPSEEK_API_KEY\",\n display_name=\"DeepSeek\",\n backend=\"openai_compat\",\n default_api_base=\"https://api.deepseek.com\",\n thinking_style=\"thinking_type\",\n reasoning_model_patterns=(\"deepseek-v4-pro\", \"deepseek-reasoner\"),\n ),\n ProviderSpec(\n name=\"gemini\",\n keywords=(\"gemini\",),\n env_key=\"GEMINI_API_KEY\",\n display_name=\"Gemini\",\n backend=\"openai_compat\",\n default_api_base=\"https://generativelanguage.googleapis.com/v1beta/openai/\",\n ),\n ProviderSpec(\n name=\"zhipu\",\n keywords=(\"zhipu\", \"glm\", \"zai\"),\n env_key=\"ZAI_API_KEY\",\n display_name=\"Zhipu AI\",\n backend=\"openai_compat\",\n env_extras=((\"ZHIPUAI_API_KEY\", \"{api_key}\"),),\n default_api_base=\"https://open.bigmodel.cn/api/paas/v4\",\n ),\n ProviderSpec(\n name=\"dashscope\",\n keywords=(\"qwen\", \"dashscope\"),\n env_key=\"DASHSCOPE_API_KEY\",\n display_name=\"DashScope\",\n backend=\"openai_compat\",\n default_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n thinking_style=\"enable_thinking\",\n ),\n ProviderSpec(\n name=\"moonshot\",\n keywords=(\"moonshot\", \"kimi\"),\n env_key=\"MOONSHOT_API_KEY\",\n display_name=\"Moonshot\",\n backend=\"openai_compat\",\n default_api_base=\"https://api.moonshot.cn/v1\",\n model_overrides=(\n (\"kimi-k2.5\", {\"temperature\": 1.0}),\n (\"kimi-k2.6\", {\"temperature\": 1.0}),\n ),\n ),\n ProviderSpec(\n name=\"minimax\",\n keywords=(\"minimax\",),\n env_key=\"MINIMAX_API_KEY\",\n display_name=\"MiniMax\",\n backend=\"openai_compat\",\n default_api_base=\"https://api.minimaxi.com/v1\",\n thinking_style=\"reasoning_split\",\n ),\n ProviderSpec(\n name=\"minimax_anthropic\",\n keywords=(\"minimax_anthropic\",),\n env_key=\"MINIMAX_API_KEY\",\n display_name=\"MiniMax (Anthropic)\",\n backend=\"anthropic\",\n default_api_base=\"https://api.minimaxi.com/anthropic\",\n ),\n ProviderSpec(\n name=\"mistral\",\n keywords=(\"mistral\",),\n env_key=\"MISTRAL_API_KEY\",\n display_name=\"Mistral\",\n backend=\"openai_compat\",\n default_api_base=\"https://api.mistral.ai/v1\",\n ),\n ProviderSpec(\n name=\"stepfun\",\n keywords=(\"stepfun\", \"step\"),\n env_key=\"STEPFUN_API_KEY\",\n display_name=\"Step Fun\",\n backend=\"openai_compat\",\n default_api_base=\"https://api.stepfun.com/v1\",\n ),\n ProviderSpec(\n name=\"xiaomi_mimo\",\n keywords=(\"xiaomi_mimo\", \"mimo\"),\n env_key=\"XIAOMIMIMO_API_KEY\",\n display_name=\"Xiaomi MIMO\",\n backend=\"openai_compat\",\n default_api_base=\"https://api.xiaomimimo.com/v1\",\n ),\n # === 本地部署 ==========================================================\n ProviderSpec(\n name=\"vllm\",\n keywords=(\"vllm\",),\n env_key=\"HOSTED_VLLM_API_KEY\",\n display_name=\"vLLM/Local\",\n backend=\"openai_compat\",\n is_local=True,\n ),\n ProviderSpec(\n name=\"ollama\",\n keywords=(\"ollama\", \"nemotron\"),\n env_key=\"OLLAMA_API_KEY\",\n display_name=\"Ollama\",\n backend=\"openai_compat\",\n is_local=True,\n detect_by_base_keyword=\"11434\",\n default_api_base=\"http://localhost:11434/v1\",\n ),\n ProviderSpec(\n name=\"lm_studio\",\n keywords=(\"lm-studio\", \"lmstudio\", \"lm_studio\"),\n env_key=\"LM_STUDIO_API_KEY\",\n display_name=\"LM Studio\",\n backend=\"openai_compat\",\n is_local=True,\n detect_by_base_keyword=\"1234\",\n default_api_base=\"http://localhost:1234/v1\",\n ),\n ProviderSpec(\n name=\"llama_cpp\",\n keywords=(\"llama_cpp\", \"llama.cpp\"),\n env_key=\"\",\n display_name=\"llama.cpp\",\n backend=\"openai_compat\",\n is_local=True,\n detect_by_base_keyword=\"8080\",\n default_api_base=\"http://localhost:8080/v1\",\n ),\n ProviderSpec(\n name=\"ovms\",\n keywords=(\"openvino\", \"ovms\"),\n env_key=\"\",\n display_name=\"OpenVINO Model Server\",\n backend=\"openai_compat\",\n is_direct=True,\n is_local=True,\n default_api_base=\"http://localhost:8000/v3\",\n ),\n # === 辅助 ============================================================\n ProviderSpec(\n name=\"nvidia_nim\",\n keywords=(\"nvidia_nim\", \"nvidia-nim\", \"nim\"),\n env_key=\"NVIDIA_NIM_API_KEY\",\n display_name=\"NVIDIA NIM\",\n backend=\"openai_compat\",\n is_gateway=True,\n detect_by_key_prefix=\"nvapi-\",\n detect_by_base_keyword=\"api.nvidia.com\",\n default_api_base=\"https://integrate.api.nvidia.com/v1\",\n supports_stream_options=False,\n ),\n ProviderSpec(\n name=\"groq\",\n keywords=(\"groq\",),\n env_key=\"GROQ_API_KEY\",\n display_name=\"Groq\",\n backend=\"openai_compat\",\n default_api_base=\"https://api.groq.com/openai/v1\",\n ),\n ProviderSpec(\n name=\"qianfan\",\n keywords=(\"qianfan\", \"ernie\"),\n env_key=\"QIANFAN_API_KEY\",\n display_name=\"Qianfan\",\n backend=\"openai_compat\",\n default_api_base=\"https://qianfan.baidubce.com/v2\",\n ),\n)\n\n\nNANOBOT_LLM_PROVIDERS: tuple[str, ...] = tuple(spec.name for spec in PROVIDERS)\n\n\ndef find_by_name(name: str | None) -> ProviderSpec | None:\n canonical = canonical_provider_name(name)\n if not canonical:\n return None\n for spec in PROVIDERS:\n if spec.name == canonical:\n return spec\n return None\n\n\ndef find_by_model(model: str | None) -> ProviderSpec | None:\n if not model:\n return None\n model_lower = model.lower()\n model_normalized = model_lower.replace(\"-\", \"_\")\n model_prefix = model_lower.split(\"/\", 1)[0] if \"/\" in model_lower else \"\"\n normalized_prefix = model_prefix.replace(\"-\", \"_\")\n standard_specs = [s for s in PROVIDERS if not s.is_gateway and not s.is_local]\n\n for spec in standard_specs:\n if model_prefix and normalized_prefix == spec.name:\n return spec\n for spec in standard_specs:\n if any(\n kw in model_lower or kw.replace(\"-\", \"_\") in model_normalized for kw in spec.keywords\n ):\n return spec\n return None\n\n\ndef find_gateway(\n provider_name: str | None = None,\n api_key: str | None = None,\n api_base: str | None = None,\n) -> ProviderSpec | None:\n spec = find_by_name(provider_name)\n if spec and (spec.is_gateway or spec.is_local):\n return spec\n\n for spec in PROVIDERS:\n if spec.detect_by_key_prefix and api_key and api_key.startswith(spec.detect_by_key_prefix):\n return spec\n if spec.detect_by_base_keyword and api_base and spec.detect_by_base_keyword in api_base:\n return spec\n return None\n\n\ndef strip_provider_prefix(model: str, spec: ProviderSpec | None) -> str:\n \"\"\"如果适用,从模型名称中去除 provider/ 前缀。\"\"\"\n if not model or not spec:\n return model\n if spec.strip_model_prefix and \"/\" in model:\n return model.split(\"/\", 1)[1]\n return model\n\n\n__all__ = [\n \"ProviderSpec\",\n \"PROVIDERS\",\n \"NANOBOT_LLM_PROVIDERS\",\n \"PROVIDER_ALIASES\",\n \"canonical_provider_name\",\n \"find_by_name\",\n \"find_by_model\",\n \"find_gateway\",\n \"strip_provider_prefix\",\n]\n"}}}} |