# Local Model Service Protocol (LMSP) 1.0, مسودة > يصدر Made for Agent بروتوكولات مفتوحة مقروءة آليًا، تتيح لوكلاء الذكاء الاصطناعي والنماذج والأدوات أن يكتشف بعضها بعضًا وأن يتخاطب. ونبدأ بـ LMSP، وهو بروتوكول خدمة النماذج المحلية (Local Model Service Protocol). Source: https://madeforagent.com/ar/llms-full.txt Updated: 2026-11-08 --- # بروتوكول خدمة النماذج المحلية (LMSP) > LMSP بروتوكول مفتوح لاكتشاف نماذج اللغة التي تعمل على جهازك واستدعائها. يحدد اكتشاف الخدمات وفهرس النماذج والبث والمهام الدائمة والتوافق مع OpenAI. Source: https://madeforagent.com/ar/lmsp/ Language: ar Updated: 2026-11-08 ## ماذا يفعل LMSP {#what} LMSP (اختصار Local Model Service Protocol) بروتوكول مفتوح للبرمجيات التي تشغّل نماذج اللغة على جهاز المستخدم نفسه أو على شبكته المحلية، وللعملاء الذين يستخدمون تلك البرمجيات. تصف الخدمة المحلية المقيمة نفسها عند عنوان معروف (well-known) وتسرد نماذجها. وتجيب عن طلبات التوليد بصيغة JSON أو بأحداث يرسلها الخادم، وتشغّل عمليات التوليد الطويلة بوصفها مهامَّ محفوظة يمكن إلغاؤها ومتابعتها من جديد بعد انقطاع الاتصال. وتتحدث الخدمة نفسها كذلك واجهة OpenAI البرمجية، فيستمر عمل العملاء الموجودين اليوم. LMSP لا يحل محل واجهة OpenAI البرمجية ولا Ollama ولا MCP. إنه يجمع نقاط قوتها في طبقة بروتوكول مصممة للخدمات المحلية المقيمة. ## نظرة سريعة {#glance} | الموضوع | الخلاصة | | --- | --- | | العنوان الافتراضي | `http://127.0.0.1:17832` | | وصف الخدمة | `GET /.well-known/lmsp.json` | | الواجهة الأساسية | `/lmsp/v1`، صيغة JSON عبر HTTP، والبث بالأحداث التي يرسلها الخادم | | واجهات التوافق | `/v1` لعملاء OpenAI، و`/api` الاختيارية لعملاء Ollama | | الاكتشاف | عنوان يدوي، وفحص العناوين المحلية، وmDNS وDNS-SD الاختياريان (`_lmsp._tcp.local.`) | | المصادقة | رموز Bearer يُحصل عليها بالاقتران المحلي | | الحفظ الدائم | SQLite مضمّنة، مع مهام تنجو من إعادة التشغيل | | العقد | OpenAPI 3.2 | ## جرّبه {#try} إن كانت خدمة LMSP تعمل على جهازك، فهذه هي الدورة كاملة. أجرِ الاقتران أولًا للحصول على رمز، كما هو موضح في [القسم 10.2](https://madeforagent.com/ar/lmsp/1.0/security.md#pairing)، واحفظه في `LMSP_TOKEN`. ```sh # 1. اكتشاف الخدمة curl http://127.0.0.1:17832/.well-known/lmsp.json # 2. سرد النماذج المحلية curl http://127.0.0.1:17832/lmsp/v1/models \ -H "Authorization: Bearer $LMSP_TOKEN" # 3. توليد استجابة curl http://127.0.0.1:17832/lmsp/v1/responses \ -H "Authorization: Bearer $LMSP_TOKEN" \ -H "Content-Type: application/json" \ -d '{"model":"qwen3:14b-q4_k_m","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"Hello"}]}]}' ``` ## علاقة LMSP ببروتوكولات أخرى {#related} | البروتوكول | ما يغطيه | علاقته بـ LMSP | | --- | --- | --- | | واجهة OpenAI البرمجية | النماذج المستضافة. وواجهة Responses هي أحدث واجهاتها. | يتبع LMSP بنية Responses في واجهته الأساسية، وتعرض الخدمة إلى جانبها واجهة متوافقة مع OpenAI. | | Ollama | بيئة تشغيل محلية تقدّم أصلًا نقاط نهاية متوافقة مع OpenAI. | يمكن أن تقف خلف خدمة LMSP بوصفها محوّلًا، ويحدد LMSP نقاط نهاية اختيارية متوافقة مع Ollama. | | MCP | يربط الوكلاء بالأدوات والسياق. | يربط LMSP الوكلاء بالنماذج. وكلاهما يفضّل الاكتشاف عديم الحالة على الجلسات الإلزامية. | | A2A | التعاون بين الوكلاء. | يستعير LMSP بطاقات الخدمة وحالات المهام الصريحة لوصف الخدمة ولمهامه. | ## الموارد {#resources} - [المواصفة، الإصدار 1.0 (مسودة)](https://madeforagent.com/ar/lmsp/1.0.md). - عقد OpenAPI، بصيغة [JSON](https://madeforagent.com/lmsp/1.0/openapi.json) أو [YAML](https://madeforagent.com/lmsp/1.0/openapi.yaml). - [llms.txt](https://madeforagent.com/ar/llms.txt) و[llms-full.txt](https://madeforagent.com/ar/llms-full.txt)، للنماذج اللغوية. - كل صفحة متاحة بصيغة Markdown. استبدل الشرطة المائلة الأخيرة في عنوانها بـ `.md`، مثل [`/ar/lmsp/1.0/tasks.md`](https://madeforagent.com/ar/lmsp/1.0/tasks.md). ## الأسئلة الشائعة ### ما هو LMSP؟ LMSP، أي Local Model Service Protocol (بروتوكول خدمة النماذج المحلية)، بروتوكول مفتوح لخدمات نماذج اللغة التي تعمل على جهاز المستخدم نفسه أو على شبكته المحلية. وهو يحدد كيف يكتشف العملاء الخدمة، ويسردون نماذجها، ويطلبون الاستجابات، ويستقبلون المخرجات مبثوثة، ويشغّلون المهام الطويلة. ### هل يحل LMSP محل واجهة OpenAI البرمجية أو Ollama أو MCP؟ لا. يبني LMSP عليها. فواجهته الأساسية تتبع بنية OpenAI Responses، ويمكن للخدمة أن تعرض نقاط نهاية متوافقة مع OpenAI وOllama، ويستعير البروتوكول الاكتشاف عديم الحالة من MCP وحالات المهام من A2A. ### هل يمكن لعملاء OpenAI الحاليين استخدام خدمة LMSP؟ غالبًا نعم. يحتاجون إلى عنوان URL أساسي مختلف ورمز LMSP بوصفه مفتاح API. ولا يعثرون على الخدمة تلقائيًا، لأن الاكتشاف يتطلب عميلًا يدعم LMSP. ### كيف يعثر العميل على خدمة LMSP محلية؟ يجرب ثلاثة أمور بالترتيب. أولًا عنوانًا يُدخل يدويًا، ثم العنوان المحلي المتعارف عليه الذي يطلب منه /.well-known/lmsp.json، وأخيرًا، اختياريًا، التصفح عبر mDNS وDNS-SD بحثًا عن _lmsp._tcp.local. على الشبكة المحلية. ### هل خدمة النماذج على localhost آمنة؟ ليس تلقائيًا، لأن صفحات الويب قد تحاول الوصول إلى المنافذ المحلية. تلتزم خدمات LMSP افتراضيًا بعنوان loopback، وتشترط رموز Bearer يُحصل عليها بالاقتران المحلي، وتتحقق من ترويستي Origin وHost، وتشترط المصادقة في وضع LAN. ### ما حالة المواصفة؟ الإصدار 1.0 هو أول مسودة عامة، وقد يتغير بما لا يتوافق مع النسخة الحالية. النص الإنجليزي هو المعتمد، والترجمات مقدمة للتيسير. --- # نظرة عامة > نظرة عامة على مسودة LMSP 1.0. ما هو بروتوكول خدمة النماذج المحلية، والتصاميم التي يبني عليها، وبنيته الطبقية، وكيفية قراءة المواصفة، والمصطلحات المستخدمة في النص كله. Source: https://madeforagent.com/ar/lmsp/1.0/ Language: ar Specification: LMSP 1.0 (draft) Updated: 2026-11-08 ## 1.1 الملخص {#abstract} يحدد بروتوكول خدمة النماذج المحلية (LMSP) كيف يعثر العملاء على خدمات نماذج اللغة التي تعمل على جهاز المستخدم نفسه أو على شبكته المحلية، وكيف يستخدمونها. وهو يحدد اكتشاف الخدمات وفهرس النماذج والتوليد المتزامن والمبثوث والمهام غير المتزامنة التي تنجو من إعادة التشغيل. كما يحدد كيف تعرض الخدمة الواحدة واجهة متوافقة مع OpenAI إلى جانب واجهة LMSP، ليستمر عمل العملاء الحاليين. لا يحل LMSP محل واجهة OpenAI البرمجية ولا Ollama ولا MCP. إنه يجمع نقاط قوتها في طبقة بروتوكول مصممة لخدمة محلية مقيمة. ## 1.2 حالة هذا المستند {#status} هذه أول مسودة عامة لـ LMSP 1.0، نُشرت في 2026-11-08. «LMSP» اسم عملي مؤقت. النص مفتوح لتلقي الملاحظات وقد يتغير بما لا يتوافق مع النسخة الحالية إلى أن يصبح الإصدار 1.0 نهائيًا. النص الإنجليزي هو المعتمد. الترجمات مقدمة للتيسير؛ وعند الاختلاف يُعمل بالنص الإنجليزي. ## 1.3 أساس التصميم {#design-basis} يعيد LMSP استخدام تصاميم مجرَّبة بدلًا من ابتكار تصاميم جديدة: - **واجهة OpenAI Responses البرمجية.** عناصر مخرجات منظَّمة، وأحداث دلالية يرسلها الخادم، وتنفيذ في الخلفية مع الاستعلام والإلغاء للأعمال الطويلة. وهي المرجع لواجهة المحادثة الأساسية في LMSP. انظر [الاستجابات المبثوثة](https://developers.openai.com/api/docs/guides/streaming-responses) و[وضع الخلفية](https://developers.openai.com/api/docs/guides/background). - **Ollama.** يقدّم نقاط النهاية `/v1/models` و`/v1/chat/completions` و`/v1/responses` المتوافقة مع OpenAI، وهو ما يُظهر أن خدمة واحدة مع طبقة تكيّف مع OpenAI تخفض كلفة الاعتماد خفضًا كبيرًا. انظر [توافق Ollama مع OpenAI](https://docs.ollama.com/api/openai-compatibility). - **Model Context Protocol (MCP).** ينتقل أحدث تصميم له من تهيئة الجلسة الإلزامية إلى الاكتشاف عديم الحالة: كل طلب يحمل معلومات الإصدار الخاصة به، ويتعرف العملاء على القدرات عبر واجهة اكتشاف. وهذا يناسب الخدمات المحلية، حيث يجب ألا تُفسد إعادة التشغيل وأعطال العملاء وانقطاعات الاتصال حالة البروتوكول. انظر [MCP](https://modelcontextprotocol.io/). - **Agent2Agent (A2A).** تُلهم بطاقات الخدمة وحالات المهام الصريحة والاشتراك في المهام وإلغاؤها وصفَ الخدمة في LMSP ونموذج المهام غير المتزامنة فيه. انظر [A2A](https://a2a-protocol.org/). ## 1.4 البنية {#architecture} ينتظم LMSP في ثلاث طبقات، فوق المحوّلات التي تتحدث مع بيئات تشغيل النماذج: ```text +---------------------------------------------------------------+ | Discovery mDNS / DNS-SD + well-known service document | +---------------------------------------------------------------+ | Core model catalog, responses, SSE, async tasks | +---------------------------------------------------------------+ | Compatibility OpenAI API, optional Ollama API | +---------------------------------------------------------------+ | Adapters llama.cpp, Ollama, vLLM, custom runtimes | +---------------------------------------------------------------+ ``` - **الاكتشاف.** mDNS/DNS-SD ووثيقة وصف خدمة عند عنوان معروف ([الصفحة 3](https://madeforagent.com/ar/lmsp/1.0/discovery.md)). - **النواة.** فهرس النماذج، والاستجابات المتزامنة، والأحداث التي يرسلها الخادم، والمهام غير المتزامنة ([الصفحات 5 إلى 7](https://madeforagent.com/ar/lmsp/1.0/models.md)). - **التوافق.** واجهة متوافقة مع OpenAI، واختياريًا واجهة متوافقة مع Ollama ([الصفحة 8](https://madeforagent.com/ar/lmsp/1.0/compatibility.md)). - **المحوّلات.** جسور إلى llama.cpp أو Ollama أو vLLM أو بيئة تشغيل مخصصة. المبدأ الموجِّه هو **نواة تنفيذ نماذج واحدة، وعائلتان من الواجهات**. تعرض الخدمة واجهة LMSP وواجهة OpenAI فوق النواة نفسها، فيكون هناك مكان واحد تُحمَّل فيه النماذج وتُنفَّذ فيه الطلبات وتُتتبَّع فيه المهام. ## 1.5 لغة التوافق {#conformance} تُفسَّر الكلمات المفتاحية **يجب** (MUST) و**لا يجوز** (MUST NOT) و**إلزامي** (REQUIRED) و**ينبغي** (SHOULD) و**لا ينبغي** (SHOULD NOT) و**موصى به** (RECOMMENDED) و**يجوز** (MAY) و**اختياري** (OPTIONAL) في هذا المستند كما هو موصوف في [BCP 14](https://www.rfc-editor.org/info/bcp14) ([RFC 2119](https://www.rfc-editor.org/rfc/rfc2119) و[RFC 8174](https://www.rfc-editor.org/rfc/rfc8174)) عندما، وفقط عندما، تظهر بخط عريض. وفي غير ذلك تكون كلمات عادية. كل صفحة معلَّمة بأنها معيارية أو إرشادية. الصفحات المعيارية تحدد المتطلبات، والإرشادية تقدم التوجيه. الأمثلة إرشادية. صيغة JSON بترميز UTF-8، وأسماء الحقول بنمط `snake_case`. ## 1.6 المصطلحات {#terminology} | المصطلح | المعنى | | --- | --- | | الخدمة | عملية مقيمة تنفّذ LMSP وتشغّل النماذج عبر المحوّلات. | | العميل | برنامج يكتشف الخدمة ويستدعيها: وكيل أو تطبيق أو أداة. | | المحوّل | المكوّن الذي يربط الخدمة ببيئة تشغيل نماذج واحدة، مثل llama.cpp أو Ollama أو vLLM. | | النموذج | نموذج متاح محليًا، يُعرَّف بمعرّف `id` ثابت. | | الاستجابة | نتيجة طلب توليد واحد: عناصر المخرجات والاستخدام والحالة. | | المهمة | تنفيذ غير متزامن محفوظ لطلب استجابة، بحالة صريحة. | | الحدث | حدث واحد يرسله الخادم، برقم تسلسلي، يُصدر أثناء توليد الاستجابة. | --- # النقل والنشر > عناوين الاستماع الافتراضية والنقل وصيغة البث وتخطيط عناوين URL لخدمة LMSP، وكيف تعمل بوصفها خدمة لنظام التشغيل منفصلة عن عمليات النماذج. Source: https://madeforagent.com/ar/lmsp/1.0/transport/ Language: ar Specification: LMSP 1.0 (draft) Updated: 2026-11-08 ## 2.1 النشر الافتراضي {#deployment} **يجب** على الخدمة أن تستمع افتراضيًا إلى عنواني loopback وهما `127.0.0.1` و`::1`. المنفذ المتعارف عليه هو `17832`، ما يجعل العنوان الأساسي الافتراضي `http://127.0.0.1:17832`. | البند | القيمة | | --- | --- | | عناوين الاستماع | `127.0.0.1` و`::1` | | النقل | HTTP/1.1 أو HTTP/2 يحملان JSON | | البث | الأحداث التي يرسلها الخادم، `Content-Type: text/event-stream` | | بادئة الواجهة الأساسية | `/lmsp/v1` | | بادئة الواجهة المتوافقة مع OpenAI | `/v1` | | وصف الخدمة | `GET /.well-known/lmsp.json` | | العقد المقروء آليًا | `GET /lmsp/v1/openapi.json` | | قناة محلية اختيارية | مقبس نطاق Unix أو أنبوب مسمّى في Windows | الطلبات والاستجابات تستخدم JSON بترميز UTF-8 (`Content-Type: application/json`)، باستثناء التدفقات (`text/event-stream`) والأخطاء (`application/problem+json`). الطوابع الزمنية أعداد صحيحة: ثوانٍ منذ حقبة Unix. المعرّفات سلاسل معتمة؛ واستخدام بادئة نوع، مثل `resp_` أو `task_`، **موصى به**. عقد الواجهة وثيقة OpenAPI 3.2. ويستطيع OpenAPI 3.2 وصف الأحداث التي يرسلها الخادم وJSON Lines وJSON Sequences، ولذلك تُحدَّد نقاط نهاية البث في الوثيقة نفسها التي تُحدَّد فيها بقية النقاط. ويُنشر عقد هذا الإصدار في [`/lmsp/1.0/openapi.json`](https://madeforagent.com/lmsp/1.0/openapi.json). **يجوز** للخدمة أيضًا أن تقبل الاتصالات على مقبس نطاق Unix أو أنبوب مسمّى في Windows بدلالات HTTP نفسها. وفي الإصدار 1.0 يُترك إعلان نقاط النهاية هذه للامتدادات. ## 2.2 التشغيل الدائم {#operation} **ينبغي** أن يستضيف نظام التشغيل الخدمة: launchd على macOS، وsystemd على Linux، ومدير الخدمات على Windows. **ينبغي** أن تكون عملية الخدمة وعمليات النماذج منفصلة. و**ينبغي** أن يقتصر أثر تعطل نموذج على المهام التي تستخدم ذلك النموذج. و**لا ينبغي** أن يجعل هذا التعطل اكتشاف الخدمة أو فهرس النماذج أو الاستعلام عن المهام السابقة غير متاح. --- # اكتشاف الخدمات > كيف يعثر عملاء LMSP على خدمة محلية عبر الإعداد اليدوي وفحص عناوين loopback وmDNS/DNS-SD الاختياري، وكيف تُقرأ وثيقة وصف الخدمة المعروفة well-known. Source: https://madeforagent.com/ar/lmsp/1.0/discovery/ Language: ar Specification: LMSP 1.0 (draft) Updated: 2026-11-08 ## 3.1 طرق الاكتشاف {#methods} يكتشف العميل الخدمة بتجربة هذه الطرق بالترتيب: 1. **الإعداد اليدوي.** يُدخل المستخدم عنوان الخدمة مباشرة. 2. **فحص العناوين المحلية المتعارف عليها.** يطلب العميل `/.well-known/lmsp.json` من عناوين مرشحة. والعناوين المرشحة المتعارف عليها هي `http://127.0.0.1:17832` و`http://[::1]:17832`. 3. **الاكتشاف على الشبكة المحلية.** يتصفح العميل بحثًا عن `_lmsp._tcp.local.` باستخدام mDNS وDNS-SD. تنجح الطريقة عندما تُنتج وصف خدمة صالحًا ([القسم 3.3](https://madeforagent.com/ar/lmsp/1.0/discovery.md#service-description)). والعنوان الذي يُدخله المستخدم يدويًا له الأسبقية دائمًا على العناوين المكتشفة. ## 3.2 الإعلان على الشبكة المحلية {#mdns} يستخدم DNS-SD سجلات PTR للعثور على نسخ الخدمة، وسجلات SRV للحصول على المضيف والمنفذ، وسجلات TXT لحمل قدر صغير من المعلومات الإضافية. ومع mDNS يوفر اكتشافًا بلا إعداد على الشبكة المحلية ([RFC 6763](https://www.rfc-editor.org/rfc/rfc6763)، [RFC 6762](https://www.rfc-editor.org/rfc/rfc6762)). مثال على إعلان: ```text Service type: _lmsp._tcp.local. Instance name: Workstation LMSP._lmsp._tcp.local. TXT record: v=1 id=svc_01J8M4Y8K6M5E6K6Z7Z0Y8W3M2 path=/ auth=pairing ``` | مفتاح TXT | المعنى | | --- | --- | | `v` | إصدار صيغة الإعلان. `1` لـ LMSP 1.0. | | `id` | معرّف الخدمة، ويساوي `service.id` في وصف الخدمة. | | `path` | مسار URL لجذر الخدمة. يطلب العملاء `{path}.well-known/lmsp.json`. | | `auth` | تلميح للمصادقة. `pairing` يعني أن على العميل إجراء الاقتران قبل استخدام الخدمة. | القواعد: - **لا يجوز** للخدمة أن تضع رموز وصول أو قوائم نماذج أو مسارات ملفات أو أي معلومات حساسة أخرى في سجل TXT. فالسجل يحدد موقع الخدمة فحسب. و**يجب** أن تُقرأ القدرات الفعلية من وصف الخدمة. - **يجب** على الخدمة أن تُبقي إعلان mDNS معطلًا افتراضيًا. ولا يُفعَّل إلا عندما يشغّل المستخدم اكتشاف الشبكة المحلية صراحةً. والخدمة المستخدمة على الجهاز المحلي وحده لا تعلن عن نفسها. - الخدمة التي تعلن على الشبكة المحلية مضطرة إلى الاستماع خارج loopback، وهذا غير مسموح إلا في وضع LAN ([القسم 10.5](https://madeforagent.com/ar/lmsp/1.0/security.md#lan)). - **يجب** على العميل أن يعامل سجل TXT بوصفه تلميحًا غير موثَّق، وأن يؤكد الخدمة بقراءة وصفها. ## 3.3 وصف الخدمة {#service-description} ```http GET /.well-known/lmsp.json ``` **يجب** على الخدمة أن تقدّم هذه الوثيقة بصيغة `application/json` دون اشتراط مصادقة. ```json { "protocol": "lmsp", "versions": ["1.0"], "service": { "id": "svc_01J8M4Y8K6M5E6K6Z7Z0Y8W3M2", "name": "Workstation Local Models", "version": "1.0.0" }, "interfaces": [ { "kind": "lmsp", "version": "1.0", "url": "http://127.0.0.1:17832/lmsp/v1", "transport": "http+json" }, { "kind": "openai", "version": "responses+chat", "url": "http://127.0.0.1:17832/v1", "transport": "http+json" } ], "capabilities": { "streaming": true, "tasks": true, "event_resume": true, "conversations": true, "model_management": true }, "authentication": { "type": "bearer", "pairing_url": "http://127.0.0.1:17832/lmsp/v1/pair" }, "openapi": "http://127.0.0.1:17832/lmsp/v1/openapi.json" } ``` | الحقل | المعنى | | --- | --- | | `protocol` | دائمًا `"lmsp"`. | | `versions` | إصدارات LMSP التي تدعمها الخدمة، على هيئة سلاسل `major.minor`. | | `service` | `id` معرّف ثابت للخدمة، و`name` اسم للعرض، و`version` إصدار برنامج الخدمة. | | `interfaces` | الواجهات المعروضة. لكل واحدة `kind` (`lmsp` أو `openai` أو `ollama`) و`version` و`url` أساسي و`transport`. وفي حالة `openai` يسمّي `version` عائلات الواجهات البرمجية المقدَّمة، مثل `responses+chat`. | | `capabilities` | رايات منطقية للميزات، مذكورة أدناه. | | `authentication` | `type` هو `bearer`. و`pairing_url` هو المكان الذي يستبدل فيه العملاء رمز الاقتران برمز ([القسم 10.2](https://madeforagent.com/ar/lmsp/1.0/security.md#pairing)). | | `openapi` | عنوان URL لوثيقة OpenAPI التي تصف واجهة LMSP. | رايات القدرات: | الراية | المعنى | | --- | --- | | `streaming` | يمكن بث الاستجابات بوصفها أحداثًا يرسلها الخادم. **يجب** أن تكون `true` في الإصدار 1.0. | | `tasks` | المهام غير المتزامنة متاحة. **يجب** أن تكون `true` في الإصدار 1.0. | | `event_resume` | يمكن الاشتراك في تدفقات أحداث المهام واستئنافها (`GET /lmsp/v1/tasks/{task_id}/events`). | | `conversations` | تخزّن الخدمة الاستجابات، فيعمل `store` و`previous_response_id` ويتوافر `GET /lmsp/v1/responses/{response_id}`. | | `model_management` | يمكن تحميل النماذج وإلغاء تحميلها صراحةً. | ## 3.4 سلوك العميل {#client-behavior} العميل: - **ينبغي** أن يختار أعلى إصدار في `versions` يدعمه هو أيضًا. - **ينبغي** أن يختار واجهة LMSP أو واجهة OpenAI من `interfaces` بحسب ما يستطيع التحدث به. - **يجب** أن يقتصر على استخدام القدرات التي يعلنها الوصف. والراية الغائبة تعني `false`. - **يجب** أن يتجاهل حقول الامتداد التي لا يتعرف عليها. - **ينبغي** أن يعيد قراءة وصف الخدمة دوريًا وعند فشل أي طلب، بدلًا من تخزينه مؤقتًا إلى الأبد. - **ينبغي** أن يتذكر الخدمة المختارة بواسطة `service.id` لا بالعنوان، لأن العناوين قد تتغير. --- # نقاط النهاية > الجدول الكامل لنقاط نهاية LMSP 1.0 بطريقة كل منها ومسارها ومستوى إلزامها وغرضها، مع اصطلاحات المسارات والمصادقة ونقاط النهاية الاختيارية. Source: https://madeforagent.com/ar/lmsp/1.0/endpoints/ Language: ar Specification: LMSP 1.0 (draft) Updated: 2026-11-08 ## 4.1 جدول نقاط النهاية {#table} **يجب** على الخدمة المتوافقة أن تنفّذ كل نقطة نهاية موسومة بأنها إلزامية. و**يجوز** لها أن تنفّذ الاختيارية، وتشير إليها عبر رايات القدرات في [وصف الخدمة](https://madeforagent.com/ar/lmsp/1.0/discovery.md#service-description) الخاص بها. | الطريقة | المسار | الإلزام | الغرض | | --- | --- | --- | --- | | GET | `/.well-known/lmsp.json` | إلزامية | [اكتشاف الخدمة والقدرات](https://madeforagent.com/ar/lmsp/1.0/discovery.md#service-description) | | GET | `/lmsp/v1/openapi.json` | إلزامية | مواصفة الواجهة المقروءة آليًا | | GET | `/lmsp/v1/health` | إلزامية | [فحص الحياة والجاهزية](https://madeforagent.com/ar/lmsp/1.0/common-rules.md#health) | | POST | `/lmsp/v1/pair` | إلزامية | [استبدال رمز الاقتران برمز Bearer](https://madeforagent.com/ar/lmsp/1.0/security.md#pairing) | | GET | `/lmsp/v1/models` | إلزامية | [سرد النماذج المحلية](https://madeforagent.com/ar/lmsp/1.0/models.md#list) | | GET | `/lmsp/v1/models/{model_id}` | إلزامية | [الحصول على نموذج واحد](https://madeforagent.com/ar/lmsp/1.0/models.md#operations) | | POST | `/lmsp/v1/responses` | إلزامية | [توليد متزامن أو مبثوث](https://madeforagent.com/ar/lmsp/1.0/responses.md#request) | | GET | `/lmsp/v1/responses/{response_id}` | اختيارية | [استرجاع استجابة مخزَّنة](https://madeforagent.com/ar/lmsp/1.0/responses.md#sync) | | POST | `/lmsp/v1/tasks` | إلزامية | [إنشاء مهمة توليد غير متزامنة](https://madeforagent.com/ar/lmsp/1.0/tasks.md#create) | | GET | `/lmsp/v1/tasks/{task_id}` | إلزامية | [الحصول على مهمة غير متزامنة](https://madeforagent.com/ar/lmsp/1.0/tasks.md#create) | | POST | `/lmsp/v1/tasks/{task_id}/cancel` | إلزامية | [إلغاء مهمة غير متزامنة](https://madeforagent.com/ar/lmsp/1.0/tasks.md#cancel) | | GET | `/lmsp/v1/tasks/{task_id}/events` | اختيارية | [الاشتراك في تدفق الأحداث أو استئنافه](https://madeforagent.com/ar/lmsp/1.0/tasks.md#events) | | POST | `/lmsp/v1/models/{model_id}/load` | اختيارية | [تحميل نموذج مسبقًا](https://madeforagent.com/ar/lmsp/1.0/models.md#operations) | | POST | `/lmsp/v1/models/{model_id}/unload` | اختيارية | [إلغاء تحميل نموذج](https://madeforagent.com/ar/lmsp/1.0/models.md#operations) | نقاط النهاية المتوافقة مع OpenAI تحت `/v1` ونقاط النهاية الاختيارية المتوافقة مع Ollama مدرجة في [الصفحة 8](https://madeforagent.com/ar/lmsp/1.0/compatibility.md). ## 4.2 الاصطلاحات {#conventions} - **المتون.** متون الطلبات والاستجابات بصيغة JSON (`application/json`)، باستثناء تدفقات الأحداث (`text/event-stream`) والأخطاء (`application/problem+json`). - **معاملات المسار.** الاسم بين قوسين معقوفين، مثل `{model_id}`، عنصر نائب. و**يجب** أن تُرمَّز القيم بترميز النسبة المئوية. ويُرسَل معرّف نموذج مثل `qwen3:14b-q4_k_m` على هيئة `qwen3%3A14b-q4_k_m`. - **المصادقة.** تتطلب كل نقطة نهاية `Authorization: Bearer `، باستثناء `/.well-known/lmsp.json` و`/lmsp/v1/openapi.json` و`/lmsp/v1/health` و`/lmsp/v1/pair`. - **نقاط النهاية الاختيارية.** **يجب** أن ترد نقطة النهاية الاختيارية التي لا تنفذها الخدمة بـ `501 Not Implemented` مع رمز الخطأ `unsupported_capability`. - **الإصدارات والأخطاء.** قد تحمل الطلبات ترويسات إصدار، ويستخدم كل خطأ صيغة واحدة. وكلاهما معرَّف في [الصفحة 9](https://madeforagent.com/ar/lmsp/1.0/common-rules.md). - **العقد.** وثيقة OpenAPI المنشورة في [`/lmsp/1.0/openapi.json`](https://madeforagent.com/lmsp/1.0/openapi.json) هي الصورة المقروءة آليًا لهذه الصفحة. والنص هو المعياري حيث يختلف الاثنان. --- # فهرس النماذج > كيف تسرد خدمة LMSP نماذجها المحلية، وكائن النموذج ورايات قدراته، وحالات دورة حياة النموذج، ومعرّفات النماذج الثابتة، ونسخ الفهرس. Source: https://madeforagent.com/ar/lmsp/1.0/models/ Language: ar Specification: LMSP 1.0 (draft) Updated: 2026-11-08 ## 5.1 سرد النماذج {#list} ```http GET /lmsp/v1/models?capability=chat&ready_only=false Authorization: Bearer ``` | معامل الاستعلام | المعنى | | --- | --- | | `capability` | يعيد النماذج التي لها القدرة المسماة فقط، مثل `chat` أو `embeddings` أو `tools`. | | `ready_only` | عندما تكون `true` يعيد النماذج التي حالتها `status` هي `ready` فقط. والقيمة الافتراضية `false`. | ```json { "object": "list", "catalog_revision": "42", "data": [ { "id": "qwen3:14b-q4_k_m", "object": "model", "display_name": "Qwen3 14B Q4_K_M", "owned_by": "local", "family": "qwen3", "revision": "sha256:8f27c1a4e9b05d36f2a7c8e1b4d90a63c5e2f7b8a1d4c9e60b3f5a7d2c8e1b04", "status": "ready", "capabilities": { "chat": true, "completion": true, "embeddings": false, "tools": true, "vision": false, "structured_output": true, "streaming": true }, "input_modalities": ["text"], "output_modalities": ["text"], "context_window": 32768, "max_output_tokens": 8192, "runtime": { "backend": "llama.cpp", "device": "metal", "load_on_demand": true } } ] } ``` لتجنيب العملاء جلب الفهرس كاملًا مرارًا، **ينبغي** للخدمة أن تعيد ترويسة `ETag` أو الحقل `catalog_revision` أو كليهما: - `catalog_revision` سلسلة معتمة تتغير كلما تغير الفهرس. - **ينبغي** للخدمة التي ترسل `ETag` أن ترد على `If-None-Match` المطابق بـ `304 Not Modified`. ## 5.2 كائن النموذج {#object} | الحقل | المعنى | | --- | --- | | `id` | معرّف النموذج الثابت، ويُستخدم في كل طلب يسمّي نموذجًا. | | `object` | دائمًا `"model"`. | | `display_name` | اسم مقروء للبشر. يستطيع المستخدم تغييره. | | `aliases` | قائمة اختيارية بأسماء بديلة. وهي للإعلام فقط. | | `owned_by` | مصدر النموذج. `local` للنماذج المثبَّتة على هذا الجهاز. | | `family` | عائلة النموذج، مثل `qwen3`. | | `revision` | بصمة محتوى النموذج، مثل `sha256:8f27...`. | | `status` | حالة دورة الحياة ([القسم 5.3](https://madeforagent.com/ar/lmsp/1.0/models.md#lifecycle)). | | `capabilities` | رايات منطقية: `chat` و`completion` و`embeddings` و`tools` و`vision` و`structured_output` و`streaming`. | | `input_modalities`, `output_modalities` | أنواع المحتوى التي يقرؤها النموذج ويكتبها. و`text` هو النمط الوحيد المعرَّف في الإصدار 1.0. | | `context_window` | الحد الأقصى لعدد رموز السياق. | | `max_output_tokens` | الحد الأقصى لعدد الرموز في استجابة واحدة. | | `runtime` | `backend` (مثل `llama.cpp`) و`device` (مثل `metal`) و`load_on_demand`. | | `error` | موجود عندما تكون `status` هي `error`. كائن مشكلة ([القسم 9.3](https://madeforagent.com/ar/lmsp/1.0/common-rules.md#errors)). | **يجب** أن يكون `id` النموذج ثابتًا. ويستطيع المستخدم تغيير اسم العرض والأسماء البديلة، ولذلك **لا يجوز** استخدامهما مفتاحًا أساسيًا. ## 5.3 دورة حياة النموذج {#lifecycle} ```text installed --> loading --> ready --> unloading --> installed | +-----> error ``` | الحالة | المعنى | | --- | --- | | `installed` | النموذج موجود لكنه غير محمَّل. | | `loading` | تُخصَّص الذاكرة أو تُهيَّأ بيئة التشغيل. | | `ready` | يستطيع النموذج معالجة الطلبات فورًا. | | `unloading` | تُحرَّر الموارد. | | `error` | فشل التحميل. **ينبغي** أن يحمل كائن النموذج خطأً منظَّمًا. | طلب تحميل جديد ينقل النموذج من حالة `error` إلى `loading` من جديد. عندما يسمّي طلب نموذجًا حالته `installed` وقيمة `runtime.load_on_demand` له `true`، تحمّله الخدمة ضمن الطلب. وإذا تعذّر استخدام النموذج فورًا ولم يكن يُحمَّل عند الطلب، ترد الخدمة بـ `409` مع `model_not_ready`. وإذا فشل التحميل فالخطأ هو `model_load_failed`. ## 5.4 عمليات النماذج {#operations} يعيد `GET /lmsp/v1/models/{model_id}` كائن نموذج واحدًا. والمعرّف المجهول يعطي `404` مع `model_not_found`. نقطتا نهاية اختياريتان تتحكمان في التحميل صراحةً. وهما متاحتان عندما تكون القدرة `model_management` هي `true`، وتتطلبان النطاق `models:manage` ([القسم 10.3](https://madeforagent.com/ar/lmsp/1.0/security.md#scopes)): | نقطة النهاية | السلوك | | --- | --- | | `POST /lmsp/v1/models/{model_id}/load` | يحمّل النموذج مسبقًا. ويعيد كائن النموذج مع `202 Accepted` عندما يبدأ التحميل، أو `200` عندما يكون النموذج `ready` أصلًا. | | `POST /lmsp/v1/models/{model_id}/unload` | يلغي تحميل النموذج. ويعيد كائن النموذج. وتكرار الطلب غير ضار. | كلتاهما تقبل `Idempotency-Key` ([القسم 9.2](https://madeforagent.com/ar/lmsp/1.0/common-rules.md#idempotency)). --- # الاستجابات والبث > واجهة المحادثة الأساسية في LMSP، بطلبات وعناصر مخرجات على نمط Responses، وتوليد متزامن ومبثوث، وأنواع أحداث يرسلها الخادم، ومعرّفات الأحداث، وإعادة الاتصال، واستدعاءات الأدوات. Source: https://madeforagent.com/ar/lmsp/1.0/responses/ Language: ar Specification: LMSP 1.0 (draft) Updated: 2026-11-08 ## 6.1 الطلب {#request} ```http POST /lmsp/v1/responses Authorization: Bearer Content-Type: application/json Idempotency-Key: 01J8M5T7Z2K4N6Q8S0V3X5B9DG LMSP-Version: 1.0 ``` ```json { "model": "qwen3:14b-q4_k_m", "input": [ { "type": "message", "role": "user", "content": [ { "type": "input_text", "text": "Describe a local model service in one sentence." } ] } ], "stream": false, "max_output_tokens": 512, "temperature": 0.7, "response_format": { "type": "text" }, "store": true } ``` يستخدم البروتوكول الأساسي بنية `input` و`output` على نمط Responses بدلًا من قائمة بسيطة من سلاسل الرسائل، ليتسع شكل طلب واحد لما يلي: - رسائل متعددة الأدوار؛ - نصوصًا وصورًا وصوتًا وملفات؛ - استدعاءات أدوات ونتائجها؛ - مخرجات منظَّمة؛ - ملخصات الاستدلال؛ - مخرجات متعددة الوسائط. يحدد LMSP 1.0 المحتوى النصي فقط. أما أنواع محتوى الصور والصوت والملفات فمحجوزة للإصدارات اللاحقة. | الحقل | إلزامي | المعنى | | --- | --- | --- | | `model` | نعم | معرّف النموذج المراد استخدامه. | | `input` | نعم | مصفوفة عناصر الإدخال. عنصر `message` له `role` (`system` أو `user` أو `assistant`) ومصفوفة `content` من الأجزاء، مثل `input_text`. ويضيف استخدام الأدوات عنصري `function_call` و`function_call_output` ([القسم 6.5](https://madeforagent.com/ar/lmsp/1.0/responses.md#tools)). | | `stream` | لا | `true` لاستقبال أحداث يرسلها الخادم. والافتراضي `false`. | | `max_output_tokens` | لا | حد أعلى لعدد الرموز المولَّدة. | | `temperature` | لا | درجة حرارة أخذ العينات. | | `response_format` | لا | `{"type": "text"}` (الافتراضي)، أو `{"type": "json_schema", "json_schema": {"name": "...", "schema": {...}}}` للمخرجات المنظَّمة. يتطلب القدرة `structured_output`. | | `tools`, `tool_choice` | لا | أدوات دالّية يمكن للنموذج استدعاؤها ([القسم 6.5](https://madeforagent.com/ar/lmsp/1.0/responses.md#tools)). يتطلب القدرة `tools`. | | `store` | لا | يطلب من الخدمة الاحتفاظ بالاستجابة، لإمكان استرجاعها لاحقًا واستخدامها بوصفها `previous_response_id`. والافتراضي `false`. تتجاهله الخدمات التي لا تملك القدرة `conversations`. | | `previous_response_id` | لا | يواصل من استجابة مخزَّنة. يتطلب القدرة `conversations`. | | `extensions` | لا | امتدادات خاصة ([القسم 9.1](https://madeforagent.com/ar/lmsp/1.0/common-rules.md#versioning)). | يُرفض الطلب الذي يحتاج إلى قدرة ليست لدى النموذج بـ `400` مع `unsupported_capability`. ويُرفض الطلب الذي لا تتسع له نافذة السياق بـ `400` مع `context_length_exceeded`. **يجوز** للخدمة القادرة على تخزين المحادثات أن تدعم `previous_response_id` أيضًا. وإلا فإنه **يجب** أن يحمل كل طلب السياق كاملًا. و**لا يجوز** للخدمة أن تعتمد على اتصال HTTP لحفظ حالة المحادثة. ## 6.2 الاستجابة المتزامنة {#sync} عندما تكون `stream` هي `false`، تعيد الخدمة `200 OK` مع كائن استجابة بعد انتهاء التوليد. ```json { "id": "resp_01J8M6Q4W2T7N5R3V9X1Z8B0DF", "object": "response", "created_at": 1794200000, "status": "completed", "model": "qwen3:14b-q4_k_m", "output": [ { "id": "msg_01J8M6Q4W5C8H2K9P3S7Y1A6ZE", "type": "message", "role": "assistant", "content": [ { "type": "output_text", "text": "A local model service is a resident interface layer that discovers, manages and calls models on the user's own device." } ] } ], "usage": { "input_tokens": 28, "output_tokens": 31, "total_tokens": 59 }, "error": null, "incomplete_details": null } ``` | الحقل | المعنى | | --- | --- | | `id` | معرّف الاستجابة، مثل `resp_...`. | | `object` | دائمًا `"response"`. | | `created_at` | وقت الإنشاء بالثواني منذ حقبة Unix. | | `status` | `in_progress` أو `completed` أو `incomplete` أو `failed` أو `cancelled`. وتُعاد الاستجابة المتزامنة بحالة نهائية. | | `model` | معرّف النموذج الذي أنتج الاستجابة. | | `output` | مصفوفة عناصر المخرجات. | | `usage` | أعداد الرموز: `input_tokens` و`output_tokens` و`total_tokens`. | | `error` | `null`، أو كائن مشكلة ([القسم 9.3](https://madeforagent.com/ar/lmsp/1.0/common-rules.md#errors)) عندما تكون `status` هي `failed`. | | `incomplete_details` | `null`، أو كائن فيه `reason` مثل `max_output_tokens` عندما تكون `status` هي `incomplete`. | أنواع عناصر المخرجات: | نوع العنصر | الشكل | | --- | --- | | `message` | `id` و`role` (`assistant`) و`content`، وهي مصفوفة أجزاء `output_text` يحمل كل منها `text`. | | `function_call` | `id` و`call_id` و`name` و`arguments`، وهي سلسلة مرمَّزة بصيغة JSON. | | `reasoning` | `id` و`summary`، وهي مصفوفة أجزاء `summary_text` يحمل كل منها `text`. | إذا فشل التوليد، يُرد على الطلب المتزامن بحالة خطأ ومستند مشكلة ([القسم 9.3](https://madeforagent.com/ar/lmsp/1.0/common-rules.md#errors))، لا بكائن استجابة. وتظهر الحالة `failed` في التدفقات والمهام والاستجابات المخزَّنة. يعيد `GET /lmsp/v1/responses/{response_id}` استجابة خُزّنت بـ `store: true`. وهو اختياري ويتطلب القدرة `conversations`. والمعرّف المجهول يعطي `404` مع `response_not_found`. ## 6.3 البث {#streaming} للبث، اضبط `stream` في الطلب: ```json { "stream": true } ``` ترد الخدمة بـ `200 OK` مع `Content-Type: text/event-stream` وترسل أحداثًا دلالية. لكل حدث `id` واسم `event` وكائن JSON هو `data`: ```text id: 1 event: response.created data: {"response_id":"resp_01J8M6Q4W2T7N5R3V9X1Z8B0DF","status":"in_progress"} id: 2 event: response.output_item.added data: {"response_id":"resp_01J8M6Q4W2T7N5R3V9X1Z8B0DF","output_index":0,"item":{"id":"msg_01J8M6Q4W5C8H2K9P3S7Y1A6ZE","type":"message","role":"assistant","content":[]}} id: 3 event: response.output_text.delta data: {"response_id":"resp_01J8M6Q4W2T7N5R3V9X1Z8B0DF","item_id":"msg_01J8M6Q4W5C8H2K9P3S7Y1A6ZE","delta":"A local model "} id: 4 event: response.output_text.delta data: {"response_id":"resp_01J8M6Q4W2T7N5R3V9X1Z8B0DF","item_id":"msg_01J8M6Q4W5C8H2K9P3S7Y1A6ZE","delta":"service is a resident interface layer."} id: 5 event: response.output_item.done data: {"response_id":"resp_01J8M6Q4W2T7N5R3V9X1Z8B0DF","output_index":0,"item":{"id":"msg_01J8M6Q4W5C8H2K9P3S7Y1A6ZE","type":"message","role":"assistant","content":[{"type":"output_text","text":"A local model service is a resident interface layer."}]}} id: 6 event: response.completed data: {"response_id":"resp_01J8M6Q4W2T7N5R3V9X1Z8B0DF","status":"completed","usage":{"input_tokens":28,"output_tokens":12,"total_tokens":40}} ``` تُعرَّف هذه الأحداث على الأقل: | الحدث | المعنى | حقول البيانات | | --- | --- | --- | | `response.created` | أُنشئت الاستجابة. | `response_id`، `status` (`in_progress`) | | `response.output_item.added` | بدأ عنصر مخرجات جديد. | `response_id`، `output_index`، `item` | | `response.output_text.delta` | أُلحق نص بعنصر رسالة. | `response_id`، `item_id`، `delta` | | `response.output_item.done` | اكتمل عنصر مخرجات. | `response_id`، `output_index`، `item` | | `response.completed` | انتهت الاستجابة. الحدث الأخير. | `response_id`، `status`، `usage` | | `response.incomplete` | توقف التوليد مبكرًا، مثلًا عند حد الرموز. الحدث الأخير. | `response_id`، `status`، `incomplete_details`، `usage` | | `response.failed` | فشل التوليد. الحدث الأخير. | `response_id`، `status`، `error` | | `response.cancelled` | أُلغيت الاستجابة. الحدث الأخير. | `response_id`، `status` | | `error` | مشكلة غير مرتبطة باستجابة واحدة، ولا يمكن للتدفق أن يستمر بعدها. | `error`، وهو كائن مشكلة | تغلق الخدمة التدفق بعد حدث أخير أو حدث `error`. **يجوز** للخدمات إرسال أحداث إضافية، مثل أحداث لوسائط استدعاءات الأدوات والصور والصوت ودلتا JSON المنظَّم. و**يجب** على العملاء تجاهل أنواع الأحداث التي لا يعرفونها. إذا أغلق العميل اتصال طلب مبثوث، **ينبغي** للخدمة أن تتوقف عن التوليد. ## 6.4 معرّفات الأحداث وإعادة الاتصال {#reconnection} **يجب** أن يكون `id` الحدث رقمًا تسلسليًا صحيحًا يزداد بصرامة داخل الاستجابة، ويبدأ من 1. بعد انقطاع الاتصال، يستأنف العميل بإرسال آخر معرّف تلقّاه. ويفعل ذلك بترويسة: ```http Last-Event-ID: 2 ``` أو بمعامل استعلام: ```http GET /lmsp/v1/tasks/{task_id}/events?after=2 ``` وكلاهما يذهب إلى نقطة نهاية أحداث المهمة ([القسم 7.4](https://madeforagent.com/ar/lmsp/1.0/tasks.md#events)). وتعيد الخدمة إرسال الأحداث التي يزيد رقمها التسلسلي على 2 فقط. وإن وُجد الاثنان فالأسبقية لـ `after`. إذا كانت الأحداث المطلوبة أقدم من مدة الاحتفاظ، ترد الخدمة بـ `410 Gone` مع الخطأ `event_history_expired`. فيجلب العميل عندها النتيجة النهائية بدلًا من ذلك، بـ `GET /lmsp/v1/tasks/{task_id}`. الاستجابة المبثوثة مباشرةً من `POST /lmsp/v1/responses` تخص اتصال HTTP ذاك ولا يمكن استئنافها. و**ينبغي** للعميل الذي يحتاج إلى مخرجات قابلة للاستئناف أن ينشئ [مهمة](https://madeforagent.com/ar/lmsp/1.0/tasks.md) ويتابع أحداثها. ## 6.5 استدعاءات الأدوات {#tools} يحدد LMSP 1.0 أدوات دالّية ينفذها العميل. والخدمة لا تشغّل الأدوات بنفسها. والنطاق `tools:execute` محجوز للامتدادات التي تفعل ذلك ([القسم 10.3](https://madeforagent.com/ar/lmsp/1.0/security.md#scopes)). أولًا، يسرد العميل الأدوات. لكل إدخال `type` قيمته `function`، و`name`، و`description`، و`parameters` وهو كائن JSON Schema. وقيمة `tool_choice` هي `auto` (الافتراضي) أو `none` أو `required` أو `{"type": "function", "name": "get_weather"}`. ```json { "model": "qwen3:14b-q4_k_m", "input": [ { "type": "message", "role": "user", "content": [ { "type": "input_text", "text": "What is the weather in Hangzhou?" } ] } ], "tools": [ { "type": "function", "name": "get_weather", "description": "Get the current weather for a city.", "parameters": { "type": "object", "properties": { "city": { "type": "string" } }, "required": ["city"] } } ], "tool_choice": "auto" } ``` عندما يقرر النموذج استدعاء أداة، تحتوي الاستجابة على عنصر `function_call`. وتكون `arguments` فيه سلسلة مرمَّزة بصيغة JSON. وفي التدفق يصل العنصر كاملًا في `response.output_item.done`. ```json { "id": "resp_01J8M7B3N6Q9T2V5X8Z1C4D7FH", "object": "response", "created_at": 1794200050, "status": "completed", "model": "qwen3:14b-q4_k_m", "output": [ { "id": "fc_01J8M7B3N8R1S4W7Y0A3E6G9JK", "type": "function_call", "call_id": "call_01J8M7B3N9T2V5X8Z1C4D7F0HM", "name": "get_weather", "arguments": "{\"city\":\"Hangzhou\"}" } ], "usage": { "input_tokens": 74, "output_tokens": 18, "total_tokens": 92 }, "error": null, "incomplete_details": null } ``` ينفذ العميل الأداة، ثم يرسل طلبًا جديدًا يحمل السياق كاملًا: عناصر الإدخال السابقة، وعنصر `function_call` كما استُلم، وعنصر `function_call_output` بـ `call_id` نفسه. و`output` فيه سلسلة، وتكون عادةً مرمَّزة بصيغة JSON. ```json { "type": "function_call_output", "call_id": "call_01J8M7B3N9T2V5X8Z1C4D7F0HM", "output": "{\"temperature_c\":17,\"condition\":\"light rain\"}" } ``` --- # المهام غير المتزامنة > كيف يشغّل LMSP عمليات التوليد الطويلة بوصفها مهام محفوظة، مع إنشاء المهام وآلة حالاتها والإلغاء الآمن عند التكرار وتدفقات الأحداث وسياسات إعادة التشغيل للمهام غير المنتهية. Source: https://madeforagent.com/ar/lmsp/1.0/tasks/ Language: ar Specification: LMSP 1.0 (draft) Updated: 2026-11-08 ## 7.1 إنشاء مهمة {#create} ينشئ العميل مهمة بإرسال طلب الاستجابة الذي يريد تشغيله، ملفوفًا في مغلّف مهمة. ويُنصح باستخدام ترويسة `Idempotency-Key` ([القسم 9.2](https://madeforagent.com/ar/lmsp/1.0/common-rules.md#idempotency)). ```http POST /lmsp/v1/tasks Authorization: Bearer Idempotency-Key: 01J8M7C4Y3N5P8R2T6V9X1Z4BH ``` ```json { "type": "response", "input": { "model": "qwen3:14b-q4_k_m", "input": [ { "type": "message", "role": "user", "content": [ { "type": "input_text", "text": "Write a long report." } ] } ] }, "on_restart": "fail" } ``` | الحقل | إلزامي | المعنى | | --- | --- | --- | | `type` | نعم | `response`، وهو نوع المهمة الوحيد في 1.0. | | `input` | نعم | طلب استجابة، تمامًا كما في `POST /lmsp/v1/responses`. ويُتجاهل حقله `stream`. | | `on_restart` | لا | `fail` (الافتراضي) أو `retry` أو `resume`. انظر [القسم 7.5](https://madeforagent.com/ar/lmsp/1.0/tasks.md#restart). | **يجب** على الخدمة أن تحفظ المهمة قبل أن ترد. ثم تعيد: ```http HTTP/1.1 202 Accepted ``` ```json { "id": "task_01J8M8R5X3V7B2N4Q9T1W6Y0ZC", "object": "task", "type": "response", "status": "queued", "created_at": 1794200100, "updated_at": 1794200100, "response_id": "resp_01J8M8R5X4B9D2F6H1K3N7Q0ZW", "events_url": "/lmsp/v1/tasks/task_01J8M8R5X3V7B2N4Q9T1W6Y0ZC/events", "on_restart": "fail", "response": null, "error": null } ``` | حقل المهمة | المعنى | | --- | --- | | `id` | معرّف المهمة، مثل `task_...`. | | `object` | دائمًا `"task"`. | | `type` | `response`. | | `status` | الحالة الحالية ([القسم 7.2](https://madeforagent.com/ar/lmsp/1.0/tasks.md#states)). | | `created_at`, `updated_at` | أوقات بالثواني منذ حقبة Unix. | | `response_id` | معرّف الاستجابة التي تنتجها المهمة. ويُسند عند إنشاء المهمة. | | `events_url` | مسار تدفق الأحداث. موجود عندما تكون القدرة `event_resume` هي `true`. | | `on_restart` | سياسة إعادة التشغيل للمهمة. | | `response` | كائن الاستجابة عندما تكون `status` هي `succeeded`، وإلا `null`. | | `error` | كائن مشكلة ([القسم 9.3](https://madeforagent.com/ar/lmsp/1.0/common-rules.md#errors)) عندما تكون `status` هي `failed`، وإلا `null`. | يعيد `GET /lmsp/v1/tasks/{task_id}` كائن المهمة. والعملاء الذين لا يستخدمون تدفقات الأحداث يستعلمون من هذه النقطة دوريًا. والمعرّف المجهول يعطي `404` مع `task_not_found`. وتبدو المهمة المنتهية هكذا: ```json { "id": "task_01J8M8R5X3V7B2N4Q9T1W6Y0ZC", "object": "task", "type": "response", "status": "succeeded", "created_at": 1794200100, "updated_at": 1794200162, "response_id": "resp_01J8M8R5X4B9D2F6H1K3N7Q0ZW", "events_url": "/lmsp/v1/tasks/task_01J8M8R5X3V7B2N4Q9T1W6Y0ZC/events", "on_restart": "fail", "response": { "id": "resp_01J8M8R5X4B9D2F6H1K3N7Q0ZW", "object": "response", "created_at": 1794200100, "status": "completed", "model": "qwen3:14b-q4_k_m", "output": [ { "id": "msg_01J8M8R6A2C5E8G1J4M7P0S3VY", "type": "message", "role": "assistant", "content": [ { "type": "output_text", "text": "Local model services make on-device inference a shared, discoverable utility..." } ] } ], "usage": { "input_tokens": 12, "output_tokens": 1480, "total_tokens": 1492 }, "error": null, "incomplete_details": null }, "error": null } ``` ## 7.2 آلة الحالات {#states} ```text queued --> loading --> running --> succeeded | | | | | +--> failed | | +--> cancelling --> cancelled | +--------------> failed +--------------------------> cancelled ``` | الحالة | المعنى | الحالات التالية | | --- | --- | --- | | `queued` | مقبولة ومحفوظة، تنتظر البدء. | `loading`، `cancelled`، `failed` | | `loading` | يجري تحميل النموذج. | `running`، `cancelling`، `failed` | | `running` | النموذج يولّد. | `succeeded`، `failed`، `cancelling` | | `cancelling` | طُلب الإلغاء، ولم تتوقف الواجهة الخلفية بعد. | `cancelled` | | `succeeded` | نهائية. الاستجابة مكتملة. | لا شيء | | `failed` | نهائية. | لا شيء | | `cancelled` | نهائية. | لا شيء | الحالات النهائية هي `succeeded` و`failed` و`cancelled`. و**لا يجوز** أن تتغير مهمة في حالة نهائية مرة أخرى. والمهمة التي تنتهي استجابتها بحالة `incomplete`، مثلًا عند حد الرموز، تكون `succeeded`. كل انتقال ذري، فلا تكون المهمة ملغاة ومكتملة معًا أبدًا. ويفوز الانتقال الذي يُثبَّت أولًا. ## 7.3 الإلغاء {#cancel} ```http POST /lmsp/v1/tasks/{task_id}/cancel ``` تعيد الخدمة `200 OK` وكائن المهمة الحالي. وتصبح المهمة `queued` في حالة `cancelled` فورًا. وتصبح المهمة `loading` أو `running` في حالة `cancelling` إلى أن تتوقف الواجهة الخلفية، ثم `cancelled`. **يجب** أن يكون الإلغاء آمنًا عند التكرار (idempotent). فإلغاء مهمة هي أصلًا `cancelling` أو `cancelled` يعيد المهمة الحالية ولا يُنتج خطأً جديدًا. وإلغاء مهمة هي أصلًا `succeeded` أو `failed` يُرد عليه بـ `409` مع `task_not_cancelable`. والمعرّف المجهول يعطي `404` مع `task_not_found`. ## 7.4 تدفقات الأحداث {#events} ```http GET /lmsp/v1/tasks/{task_id}/events Accept: text/event-stream ``` نقطة النهاية هذه اختيارية. وهي متاحة عندما تكون القدرة `event_resume` هي `true`. - الأحداث هي أحداث الاستجابة الواردة في [القسم 6.3](https://madeforagent.com/ar/lmsp/1.0/responses.md#streaming)، للاستجابة التي تنتجها المهمة. ويتبع الترقيم والاستئناف [القسم 6.4](https://madeforagent.com/ar/lmsp/1.0/responses.md#reconnection). - يبدأ التدفق بـ `response.created` الذي يُسجَّل عند قبول المهمة. وينتهي بحدث أخير واحد يطابق النتيجة: `response.completed` أو `response.incomplete` أو `response.failed` أو `response.cancelled`. - العميل الذي يتصل متأخرًا يتلقى أولًا الأحداث التي فاتته، ثم الأحداث المباشرة. وتغلق الخدمة التدفق بعد الحدث الأخير. - تُحفظ الأحداث طوال مدة احتفاظ ([القسم 11.2](https://madeforagent.com/ar/lmsp/1.0/persistence.md#rules)). والأحداث الأقدم تعطي `410 Gone` مع `event_history_expired`. ## 7.5 دلالات إعادة التشغيل {#restart} يحدد `on_restart` ما يحدث لمهمة غير منتهية عند إعادة تشغيل الخدمة: | القيمة | السلوك | | --- | --- | | `fail` | الافتراضي. تعلّم الخدمة المهمة غير المنتهية بالحالة `failed`، مع رمز الخطأ `server_restarted`. | | `retry` | تشغّل الخدمة المهمة من جديد من البداية. | | `resume` | تتابع الخدمة من لقطة حالة. ولا يُسمح بذلك إلا عندما تدعم الواجهة الخلفية صراحةً لقطات قابلة للاستئناف. وإلا يُرفض طلب الإنشاء بـ `400` مع `unsupported_capability`. | المهمة التي تكون `cancelling` عند إعادة تشغيل الخدمة تُكمل إلغاءها وتصبح `cancelled`، أيًّا كانت سياستها. لا يُنصح بـ `retry` افتراضيًا، لأن المهمة ربما شغّلت أدوات بالفعل أو أحدثت آثارًا جانبية خارجية. و**يجب** على العميل الذي يختار `retry` أن يقرنه بـ `Idempotency-Key` وأن يجعل استدعاءات أدواته آمنة عند التكرار. --- # التوافق مع OpenAI وOllama > كيف تبقى خدمة LMSP متوافقة مع عملاء OpenAI وOllama الحاليين عبر طبقة رقيقة لتحويل البيانات فوق نواة تنفيذ واحدة، وأين ينتهي هذا التوافق. Source: https://madeforagent.com/ar/lmsp/1.0/compatibility/ Language: ar Specification: LMSP 1.0 (draft) Updated: 2026-11-08 ## 8.1 نقاط النهاية المتوافقة مع OpenAI {#openai} **ينبغي** للخدمة أن تعرض واجهة متوافقة مع OpenAI إلى جانب واجهة LMSP، وأن تعلنها في `interfaces` بـ `kind` يساوي `openai`. ولتغطية العملاء الحاليين، **يجب** على الخدمة التي تفعل ذلك أن تنفّذ هذه النقاط على الأقل تحت البادئة `/v1`: | نقطة النهاية | ملاحظات | | --- | --- | | `GET /v1/models` | يسرد نماذج فهرس LMSP. وكل `id` هو معرّف نموذج LMSP. | | `POST /v1/chat/completions` | Chat Completions، بالبث وبدونه. | | `POST /v1/responses` | شكل OpenAI Responses. | | `POST /v1/embeddings` | ليس في الواجهة الأساسية لـ LMSP 1.0 نقطة نهاية للتضمينات. ويخدم المحوّل هذه النقطة مباشرةً للنماذج التي تكون `capabilities.embeddings` فيها `true`. | تقبل هذه النقاط رموز Bearer نفسها التي تقبلها واجهة LMSP. والعميل الذي يتحدث بروتوكول OpenAI يضبط رمز LMSP بوصفه مفتاح API الخاص به. يمكن أن يبدأ التنفيذ الأول بـ `/v1/models` و`/v1/chat/completions` ([الصفحة 12](https://madeforagent.com/ar/lmsp/1.0/mvp.md)). ## 8.2 نقاط النهاية المتوافقة مع Ollama {#ollama} **ينبغي** للخدمة أن تقدّم أيضًا هذه النقاط، لتعمل كذلك العملاء المكتوبون لـ Ollama: | نقطة النهاية | ملاحظات | | --- | --- | | `GET /api/tags` | يسرد نماذج فهرس LMSP. | | `POST /api/chat` | محادثة. | | `POST /api/generate` | توليد نص بسيط. | تعلن الخدمة التي تقدّمها واجهةً بـ `kind` يساوي `ollama`. ## 8.3 نواة تنفيذ واحدة {#core} **يجب** أن تقتصر طبقة التوافق على تحويل البيانات. و**لا يجوز** لها أن تنشئ مجموعة ثانية من منطق إدارة النماذج. فالطلب على واجهة توافق يُربط باستجابة LMSP، ويعمل على النواة والمحوّل نفسيهما اللذين يعمل عليهما الطلب الأصلي، ويستخدم فهرس النماذج والمصادقة نفسيهما. ```text OpenAI Chat Completions | ربط الطلب v LMSP Response | التكيّف مع الواجهة الخلفية v llama.cpp / Ollama / vLLM / بيئات تشغيل أخرى ``` على نقاط النهاية `/v1` و`/api`، **ينبغي** للخدمة أن تبلغ عن الأخطاء بالصيغة التي تحددها الواجهة البرمجية المقابلة، لكي يستطيع العملاء غير المعدَّلين تحليلها. أما واجهة LMSP فتستخدم دائمًا `application/problem+json`. ## 8.4 الحدود {#boundaries} للتوافق حدود، ومن المفيد ذكرها بوضوح: - العميل الحالي المتوافق مع OpenAI لا يحتاج عادةً إلا إلى تغيير `base_url`. ولا يكتسب اكتشاف LMSP تلقائيًا. - العملاء الذين يدعمون LMSP وحدهم يستطيعون اكتشاف الخدمة تلقائيًا، وقراءة قدراتها التفصيلية، واستئناف تدفقات الأحداث، وإدارة المهام غير المتزامنة. - لا يستطيع أي بروتوكول من جهة الخادم أن يجعل عميلًا يعمل إذا كان لا يقبل الإعداد ولا يقبل إلا العناوين السحابية الرسمية. --- # القواعد العامة > قواعد تشترك فيها كل نقاط نهاية LMSP، وهي ترويسات الإصدار والامتدادات ومفاتيح التكرار الآمن وصيغة الأخطاء problem+json مع رموزها وفحص الصحة. Source: https://madeforagent.com/ar/lmsp/1.0/common-rules/ Language: ar Specification: LMSP 1.0 (draft) Updated: 2026-11-08 ## 9.1 الإصدارات والامتدادات {#versioning} **يجوز** أن يحمل كل طلب LMSP هذه الترويسات: ```http LMSP-Version: 1.0 LMSP-Client: example-client/1.2.0 ``` `LMSP-Version` هي إصدار البروتوكول الذي يستهدفه العميل. و`LMSP-Client` يعرّف برنامج العميل لأغراض التشخيص، بصيغة `name/version`. و**لا يجوز** للخدمة أن تغيّر سلوك البروتوكول بناءً على هذه الترويسة. القواعد: - يدل `v1` في المسار على الإصدار الرئيسي. - الطلب الذي يسمّي إصدارًا رئيسيًا مجهولًا يُرد عليه بـ `426 Upgrade Required` ورمز الخطأ `unsupported_protocol_version`. - **لا يجوز** للحقول الاختيارية الجديدة أن تكسر توافق 1.x. - **يجب** على الخدمات والعملاء تجاهل الحقول التي لا يعرفونها. - تُوضَع الامتدادات الخاصة في كائن `extensions` وتُسمّى بصيغة النطاق المعكوس: ```json { "extensions": { "com.example.cache": { "enabled": true } } } ``` ## 9.2 التكرار الآمن (Idempotency) {#idempotency} الطلبات التي تنشئ شيئًا، مثل إنشاء استجابة أو إنشاء مهمة أو تحميل نموذج، تقبل مفتاح تكرار آمن: ```http Idempotency-Key: ``` تخزّن الخدمة المفتاح مع بصمة متن الطلب والنتيجة: - المفتاح نفسه مع المتن نفسه يعيد النتيجة الأصلية. - المفتاح نفسه مع متن مختلف يُرد عليه بـ `409 Conflict` مع `idempotency_conflict`. نطاق المفتاح هو العميل ونقطة النهاية. و**ينبغي** أن يكون قيمة فريدة لا تتجاوز 255 حرفًا، مثل ULID أو UUID. و**ينبغي** للخدمة أن تحتفظ بالمفاتيح 24 ساعة على الأقل. **يجوز** للخدمة أن تتجاهل المفتاح في الطلبات المبثوثة. والعميل الذي يحتاج إلى إعادة محاولة آمنة يستخدم [مهمة](https://madeforagent.com/ar/lmsp/1.0/tasks.md). ## 9.3 الأخطاء {#errors} كل خطأ على واجهة LMSP يستخدم `application/problem+json` ([RFC 9457](https://www.rfc-editor.org/rfc/rfc9457)): ```json { "type": "urn:lmsp:error:model-not-found", "title": "Model not found", "status": 404, "code": "model_not_found", "detail": "No local model with id 'qwen3:14b-q4_k_m'", "request_id": "req_01J8M9S6Y4W8C3P5R1V7Z2A0DH", "retryable": false } ``` | الحقل | إلزامي | المعنى | | --- | --- | --- | | `type` | نعم | URI يحدد نوع الخطأ. يستخدم LMSP البادئة `urn:lmsp:error:` متبوعة بالرمز مع شرطات بدل الشرطات السفلية. | | `title` | نعم | ملخص قصير مقروء للبشر. | | `status` | نعم | رمز حالة HTTP. | | `code` | نعم | رمز خطأ مقروء آليًا، من القائمة أدناه. | | `detail` | لا | شرح مقروء للبشر لهذه الحالة. و**لا يجوز** أن يحتوي على أسرار أو مطالبات أو محتوى مولَّد. | | `request_id` | لا | معرّف الطلب، لربطه بسجلات الخدمة. | | `retryable` | نعم | هل يمكن أن ينجح تكرار الطلب لاحقًا. | رموز الأخطاء الشائعة: | الرمز | حالة HTTP | قابل لإعادة المحاولة | المعنى | | --- | --- | --- | --- | | `invalid_request` | 400 | لا | الطلب مشوَّه أو معاملاته غير صالحة. | | `unauthorized` | 401 | لا | الرمز مفقود أو غير صالح أو منتهي أو مسحوب، أو رمز الاقتران خاطئ. | | `forbidden` | 403 | لا | الرمز يفتقر إلى النطاق المطلوب، أو فشل فحص `Origin` أو `Host`. | | `model_not_found` | 404 | لا | لا نموذج محليًا بهذا المعرّف. | | `model_not_ready` | 409 | نعم | النموذج غير محمَّل ولا يُحمَّل عند الطلب. | | `model_load_failed` | 500 | نعم | فشل تحميل النموذج. | | `context_length_exceeded` | 400 | لا | المدخل لا تتسع له نافذة سياق النموذج. | | `unsupported_capability` | 400 أو 501 | لا | النموذج أو الخدمة لا يدعم ما يحتاجه الطلب. وترد نقطة النهاية الاختيارية غير المنفذة بـ 501. | | `unsupported_protocol_version` | 426 | لا | الخدمة لا تدعم الإصدار الرئيسي المطلوب. | | `response_not_found` | 404 | لا | لا استجابة مخزَّنة بهذا المعرّف. | | `task_not_found` | 404 | لا | لا مهمة بهذا المعرّف. | | `task_not_cancelable` | 409 | لا | المهمة نجحت أو فشلت أصلًا. | | `idempotency_conflict` | 409 | لا | استُخدم مفتاح التكرار الآمن من قبل مع متن طلب مختلف. | | `event_history_expired` | 410 | لا | الأحداث المطلوبة أقدم من مدة الاحتفاظ. | | `rate_limited` | 429 | نعم | طلبات كثيرة جدًا. | | `resource_exhausted` | 503 | نعم | نفدت ذاكرة الجهاز أو مورد آخر. | | `backend_unavailable` | 503 | نعم | يتعذر الوصول إلى بيئة تشغيل النموذج. | | `server_restarted` | 503 | نعم | أُعيد تشغيل الخدمة والمهمة غير منتهية. | | `internal_error` | 500 | يختلف | فشل غير متوقع داخل الخدمة. | الحقل `retryable` هو المرجع الحاكم. ويُظهر العمود أعلاه القيمة المعتادة. و**يجوز** للخدمة أن تعرّف رموزًا أخرى. و**يجب** على العميل أن يتعامل مع أي رمز لا يعرفه بحسب حالة HTTP والحقل `retryable`. ## 9.4 فحص الصحة {#health} ```http GET /lmsp/v1/health ``` ```json { "status": "ready", "service_id": "svc_01J8M4Y8K6M5E6K6Z7Z0Y8W3M2", "uptime_seconds": 86420, "loaded_models": 1, "active_tasks": 2, "storage": "ok" } ``` | الحقل | المعنى | | --- | --- | | `status` | `starting` أو `ready` أو `degraded` أو `stopping`. | | `service_id` | معرّف الخدمة من وصف الخدمة. | | `uptime_seconds` | الثواني منذ بدء الخدمة. | | `loaded_models` | عدد النماذج في حالة `ready`. | | `active_tasks` | عدد المهام التي هي `queued` أو `loading` أو `running` أو `cancelling`. | | `storage` | `ok` أو `error`. | تكون حالة HTTP هي `200 OK` عندما تكون `status` هي `ready` أو `degraded`، وإلا فهي `503 Service Unavailable`. تعيد نقطة نهاية الصحة الحالة التشغيلية فحسب. و**لا يجوز** لها أن تعيد مسارات النماذج أو المطالبات أو رموز الوصول أو أي معلومات حساسة أخرى. --- # الأمان المحلي > متطلبات الأمان لخدمات LMSP، وتشمل الارتباط بعنوان loopback والاقتران ورموز Bearer والنطاقات وفحوص Origin وHost ضد صفحات الويب الخبيثة ووضع LAN وقواعد التسجيل. Source: https://madeforagent.com/ar/lmsp/1.0/security/ Language: ar Specification: LMSP 1.0 (draft) Updated: 2026-11-08 ## 10.1 الأساس {#baseline} الاستماع إلى localhost وحده ليس أمانًا مطلقًا، فما زال بوسع صفحة ويب خبيثة أن تحاول الوصول إلى المنافذ المحلية. ولذلك يجمع LMSP بين عدة تدابير. - **يجب** على الخدمة أن ترتبط افتراضيًا بعناوين loopback. و**لا يجوز** لها أن تستمع إلى `0.0.0.0` أو أي عنوان آخر غير loopback ما لم يكن وضع LAN مفعّلًا ([القسم 10.5](https://madeforagent.com/ar/lmsp/1.0/security.md#lan)). - عند أول تشغيل، **ينبغي** للخدمة أن تولّد سرًّا عشوائيًا للخدمة عالي الإنتروبيا، وأن تستخدمه، بدلًا من أي قيمة افتراضية مضمَّنة، لإصدار الرموز والتحقق منها. - **يجب** أن يحمل كل طلب إلى الواجهة الأساسية رمز Bearer صالحًا، باستثناء نقاط نهاية التهيئة المذكورة في [القسم 4.2](https://madeforagent.com/ar/lmsp/1.0/endpoints.md#conventions). فالقدوم من loopback لا يكفي وحده أبدًا. ## 10.2 الاقتران والرموز {#pairing} يحصل العميل على رمز Bearer خاص به برمز اقتران محلي. يطلب المستخدم من الخدمة عرض رمز اقتران، بالطريقة التي تقدمها الخدمة، ويرسله العميل: ```http POST /lmsp/v1/pair Content-Type: application/json ``` ```json { "client_name": "example-client", "pairing_code": "K7QD-4M2X", "scopes": ["inference"] } ``` | حقل الطلب | المعنى | | --- | --- | | `client_name` | اسم العرض للعميل، ويظهر للمستخدم. | | `pairing_code` | الرمز الذي حصل عليه المستخدم من الخدمة. | | `scopes` | قائمة اختيارية بالنطاقات المطلوبة. والافتراضي `["inference"]`. | ترد الخدمة برمز. و`token_type` هو دائمًا `Bearer`: ```json { "client_id": "cli_01J8MAT3W6X9B2D5F8H1K4N7QZ", "access_token": "lmsp_example_3f9a1c52e7d84b60", "token_type": "Bearer", "scopes": ["inference"] } ``` ثم يرسل العميل `Authorization: Bearer ` مع كل طلب. - **يجب** أن يكون رمز الاقتران للاستخدام مرة واحدة، و**ينبغي** أن تنتهي صلاحيته خلال 5 دقائق. و**ينبغي** أن يحمل 40 بتًا من الإنتروبيا على الأقل. و**يجب** على الخدمة أن تحدّ من معدل المحاولات الفاشلة. والرمز الخاطئ أو المنتهي يُرد عليه بـ `401` مع `unauthorized`. - الرموز مستقلة لكل عميل، فيستطيع المستخدم سحب رمز عميل دون التأثير في الآخرين. و**ينبغي** للخدمة أن تتيح للمستخدم سرد العملاء المقترنين وسحب رموزهم. - **ينبغي** للعميل أن يحتفظ برمزه في سلسلة مفاتيح نظام التشغيل أو مدير بيانات الاعتماد فيه. و**ينبغي** للخدمة أن تخزّن تجزئة كل رمز فقط. - الرمز المفقود أو غير الصالح أو المسحوب يُرد عليه بـ `401` مع `unauthorized` وترويسة `WWW-Authenticate: Bearer`. والرمز الصالح الذي يفتقر إلى النطاق الذي تحتاجه نقطة النهاية يُرد عليه بـ `403` مع `forbidden`. ## 10.3 النطاقات {#scopes} الأذونات مقسمة إلى نطاقات منفصلة. فتنزيل النماذج وحذفها وتنفيذ الأدوات لا تركب أبدًا على نطاق الاستدلال. | النطاق | يتيح | | --- | --- | | `inference` | قراءة فهرس النماذج، وإنشاء الاستجابات والمهام، وقراءة مهام العميل نفسه وإلغاءها. | | `models:manage` | تحميل النماذج وإلغاء تحميلها. | | `models:install` | محجوز. تنزيل النماذج وحذفها. | | `tools:execute` | محجوز. تنفيذ الأدوات من جهة الخدمة. | المهام والاستجابات المخزَّنة تخص العميل الذي أنشأها. و**ينبغي** للخدمة أن ترد على طلب عميل آخر كأنها غير موجودة (`task_not_found` أو `response_not_found`). ## 10.4 حماية المتصفح والشبكة {#browser} - **يجب** على الخدمة أن ترفض طلبات المتصفح العابرة للمصادر افتراضيًا، وأن لا تسمح إلا بقيم `Origin` المضبوطة صراحةً. والطلب بأي `Origin` آخر يُرد عليه بـ `403` مع `forbidden`. - عندما يكون المصدر مسموحًا، ترد الخدمة على طلبات CORS التمهيدية (preflight) له وترسل `Access-Control-Allow-Origin` بذلك المصدر بعينه، وليس بـ `*` أبدًا. - **يجب** على الخدمة أن تتحقق من ترويسة `Host`، لمنع DNS rebinding. وهي لا تقبل إلا أسماء المضيف التي تخدمها: أسماء loopback وعناوينها، إضافةً إلى أي أسماء مضبوطة لوضع LAN. وأي قيمة أخرى يُرد عليها بـ `403` مع `forbidden`. ## 10.5 وضع LAN {#lan} وضع LAN يعني الاستماع خارج عناوين loopback. - **لا يجوز** للخدمة أن تفعّل وضع LAN ما لم يشغّله المستخدم صراحةً. - في وضع LAN **يجب** على الخدمة أن تشترط المصادقة، و**ينبغي** لها أن تفعّل TLS أيضًا. و**لا ينبغي** للعميل أن يرسل رمزًا عبر HTTP العادي إلى عنوان غير loopback ما لم يسمح المستخدم بذلك صراحةً. - إعلان mDNS مسموح في وضع LAN فقط، عندما يكون المستخدم قد شغّل أيضًا اكتشاف الشبكة المحلية ([القسم 3.2](https://madeforagent.com/ar/lmsp/1.0/discovery.md#mdns)). ## 10.6 التسجيل والخصوصية {#logging} - **لا يجوز** أن تظهر مسارات النماذج أو السجلات أو المطالبات أو المحتوى المولَّد في إعلانات mDNS. - افتراضيًا، **ينبغي** للخدمة أن تسجّل البيانات الوصفية فقط (الأوقات ونقاط النهاية ورموز الحالة والمعرّفات وأعداد الرموز والمدد). و**لا ينبغي** لها أن تسجّل المطالبات الكاملة أو المحتوى المولَّد. - **لا يجوز** أن تحتوي استجابات الصحة وتفاصيل الأخطاء على مسارات النماذج أو المطالبات أو رموز الوصول أو أي معلومات حساسة أخرى. --- # الحفظ الدائم > كيف تخزّن خدمة LMSP حالتها، بقاعدة بيانات SQLite مضمَّنة، والجداول التي ينبغي الاحتفاظ بها، والقواعد المعاملاتية للمهام والأحداث، ومدة الاحتفاظ، والاستعادة عند البدء. Source: https://madeforagent.com/ar/lmsp/1.0/persistence/ Language: ar Specification: LMSP 1.0 (draft) Updated: 2026-11-08 ## 11.1 التخزين {#storage} **ينبغي** للخدمة أن تحتفظ بحالتها في قاعدة بيانات [SQLite](https://www.sqlite.org/) مضمَّنة. مجموعة مقترحة من الجداول: | الجدول | المحتوى | | --- | --- | | `service_config` | هوية الخدمة وإعداداتها. | | `clients` | العملاء المقترنون، وتجزئات الرموز، والنطاقات. | | `models` | البيانات الوصفية للنماذج وبصمات المحتوى. | | `responses` | الاستجابات المخزَّنة. | | `tasks` | المهام غير المتزامنة. | | `task_events` | سجل أحداث كل مهمة، بأرقام تسلسلية. | | `idempotency_keys` | مفاتيح التكرار الآمن وبصمات الطلبات ونتائجها. | **يجب** أن تبقى ملفات النماذج خارج قاعدة البيانات. فالقاعدة تحتفظ بالبيانات الوصفية وبصمات المحتوى فقط. أسماء الجداول وتخطيطها خيار تنفيذ. أما ما يلاحظه العملاء، وما لا بد أن يكون متوافقًا بين التنفيذات، فهو السلوك الموصوف في القسمين التاليين. ## 11.2 القواعد {#rules} أيًّا كان التخزين الذي تستخدمه الخدمة، فإن القواعد التالية تسري عليها: - **يجب** أن تحفظ المهمة قبل أن تعيد `202 Accepted`. - **يجب** أن تحدّث الأرقام التسلسلية للأحداث وحالة المهمة في المعاملة نفسها. - **يجب** أن تجعل انتقال الإلغاء ذريًا، لتفادي سباق مهمة تُلغى ثم تكتمل. - **ينبغي** أن تحتفظ بالمهام والأحداث المنتهية طوال مدة احتفاظ قابلة للضبط. - **لا يجوز** أن تحذف المهام غير المنتهية أثناء تنظيف السجلات. - **يجب**، عند البدء، أن تفحص المهام المتبقية `queued` و`loading` و`running` و`cancelling` وتطبق سياسة إعادة التشغيل لكل منها ([القسم 7.5](https://madeforagent.com/ar/lmsp/1.0/tasks.md#restart)). ## 11.3 الاستعادة عند البدء {#recovery} يبيّن الجدول الحالة التي تنتقل إليها المهمة المتبقية بحسب سياسة `on_restart` الخاصة بها: | الحالة المكتشفة عند البدء | `fail` | `retry` | `resume` | | --- | --- | --- | --- | | `queued` | `failed` | `queued` | `queued` | | `loading` | `failed` | `queued` | `queued` | | `running` | `failed` | `queued` | `running`، بالمتابعة من اللقطة | | `cancelling` | `cancelled` | `cancelled` | `cancelled` | المهمة التي تنتقل إلى `failed` تتلقى رمز الخطأ `server_restarted` وحدث `response.failed`. والمهمة التي تنتقل إلى `cancelled` تتلقى حدث `response.cancelled`. وتُكتب الحالة الجديدة وحدثها في معاملة واحدة ([القسم 11.2](https://madeforagent.com/ar/lmsp/1.0/persistence.md#rules)). --- # الحد الأدنى القابل للتطبيق > نطاق مقترح لأول تنفيذ لـ LMSP، يضم القطع العشر التي تشكّل حلقة مغلقة قابلة للاستخدام، وأجزاء المواصفة التي يمكن أن تنتظر الإصدارات اللاحقة. Source: https://madeforagent.com/ar/lmsp/1.0/mvp/ Language: ar Specification: LMSP 1.0 (draft) Updated: 2026-11-08 ## 12.1 النسخة الأولى {#scope} لا يلزم أن تنفّذ النسخة الأولى كل ميزة متعددة الوسائط ولا تنزيل النماذج ولا الصوت الفوري. فهي تشكّل حلقة مغلقة قابلة للاستخدام متى وفّرت ما يلي: 1. اكتشاف الخدمة عبر `/.well-known/lmsp.json`. 2. إعلان اختياري على الشبكة المحلية لـ `_lmsp._tcp.local.`. 3. `GET /lmsp/v1/models`. 4. `POST /lmsp/v1/responses`، متزامنًا وكذلك بوصفه تدفق SSE. 5. المهام غير المتزامنة: إنشاء واستعلام وإلغاء، مع الحفظ الدائم في SQLite. 6. استئناف التدفقات المنقطعة بـ `Last-Event-ID` أو `after`. 7. رموز Bearer والاقتران المحلي وحماية `Origin` و`Host`. 8. نقطتا النهاية `/v1/models` و`/v1/chat/completions` المتوافقتان مع OpenAI. 9. ملف عقد OpenAPI 3.2، واختبارات توافق عابرة للغات. 10. واجهة خلفية حقيقية واحدة على الأقل، وفحص يتأكد من أن المهام تتعافى سليمة بعد إعادة تشغيل الخدمة. جوهر هذا التصميم: يوفر LMSP المجموعة الكاملة من القدرات، وتوفر واجهة OpenAI التوافق الجاهز، ويوفر mDNS ووصف الخدمة الاكتشاف التلقائي، ويوفر نموذج المهام في SQLite الحفظ الدائم المحلي. ## 12.2 ما يمكن أن ينتظر {#later} كل ما لا تذكره القائمة أعلاه يمكن أن يأتي في إصدارات لاحقة. ويشمل ذلك نقاط النهاية الاختيارية (الاستجابات المخزَّنة، وتحميل النماذج وإلغاء تحميلها)، ونقطتي OpenAI `/v1/responses` و`/v1/embeddings`، والواجهة المتوافقة مع Ollama، وكل نوع محتوى غير النص. هذا النطاق طريق إلى أول إصدار قابل للاستخدام، لا ملف تعريف توافق. فالخدمة التي تعلن التوافق مع LMSP 1.0 ما زالت تنفّذ كل نقطة نهاية إلزامية في [الصفحة 4](https://madeforagent.com/ar/lmsp/1.0/endpoints.md) والسلوك الإلزامي الموصوف في الصفحات الأخرى.