مراحل طابور المهام والواجهة البرمجية للإضافات
الحالة: مُخطَّط (لم يُبنَ بعد). مراحل طابور المهام، والواجهة البرمجية للإضافات، ومقابض الوسائط، والصلاحيات الممنوحة، والإعدادات جزء من المرحلة 1؛ أما اللوحات والحوسبة المحلية فمن المرحلة 3. لم يُبنَ شيء من ذلك بعد. تصف هذه الصفحة التصميم الوارد في الملحمة 54، وهو قابل للتغيير.
المراحل والأحداث
لا ترتبط مراحل إضافتك أبدًا بأسماء المراحل الداخلية في مكتبة، فهي تتغير من إصدار إلى آخر. بل تتبع قائمة قصيرة من الأحداث الثابتة:
| الحدث | الموضوع | يقع عندما |
|---|---|---|
video.added |
فيديو | يُفحص فيديو جديد |
video.changed |
فيديو | يتغير ملفه |
audio.ready |
فيديو | يُستخرج الصوت |
transcript.ready |
فيديو | يُكتب نص مفرّغ أو يُستبدل |
subtitles.ready |
فيديو | تُكتب الترجمات المصاحبة |
thumbnails.ready |
فيديو | تُصنع الصور المصغّرة |
metadata.changed |
فيديو | يتغير العنوان أو الوسوم أو التجميع |
series.changed |
مسلسل | يتكوّن مسلسل أو موسم أو يتغير |
library.scanned |
مكتبة | ينتهي فحص المكتبة |
schedule |
فهرس | جدولك الزمني الخاص (كل N دقيقة، 15 دقيقة على الأقل) |
قائمة الأحداث جزء من إصدار الواجهة البرمجية للإضافات: لا تُحذف الأحداث إلا في إصدار رئيسي جديد.
تحصل المرحلة على مهمة بثلاث طرق:
- مُشغِّل:
[[stage.trigger]] event = "audio.ready". - جدول زمني:
[[schedule]]على مرحلة من نوعcatalog، مع قراءة الفاصل الزمني من حقل في الإعدادات. - طلب: تستدعي إحدى مراحلك
queue.requestلمرحلة مدرجة فيmay_requestالخاص بها. تُرفض الطلبات الموجّهة إلى مراحل مكتبة أو مراحل إضافات أخرى. الحد الأقصى 1,000 طلب لكل مهمة.
لا تعالج المراحل الجديدة مكتبتك الحالية بأثر رجعي إلا إذا فعّل المشرف خيار «التشغيل على مكتبتي الحالية» عند التفعيل.
كيف تُنفَّذ المهمة
لا تحجز المهام بنفسك. خط المعالجة هو من يملك طابور المهام: الحجز وإعادة المحاولة وفئات الإخفاق والتصريف والإيقاف المؤقت تعمل كما في مراحل مكتبة نفسها.
- يحجز عامل من خط المعالجة مهمة مرحلتك من مجموعة
plugins. - يطلب من الواجهة البرمجية رمز استدعاء (token) لتلك المهمة. تبنيه الواجهة البرمجية من الصلاحيات الممنوحة التي تخزّنها، لا مما يقوله العامل أو المضيف أبدًا.
- يرسل العامل المهمة إلى مضيف الإضافات، فينشئ بيئة معزولة جديدة ويستدعي التصدير
run(stage)في مكوّنك. توجّهها حزمة تطوير البرمجيات (SDK) إلى الدالة المسمّاة فيexport. - تستدعي شيفرتك واردات
maktaba:plugin. يُرفق المضيف الرمز، ولا تراه شيفرتك أبدًا. تتحقق الواجهة البرمجية من الرمز والقدرة والنطاق والحصة في كل استدعاء. - تُعيد نتيجة. تحوّلها مكتبة إلى: منجزة، أو متغيرة أو غير متغيرة، أو إعادة محاولة، أو إخفاق دائم (راجع العزل، قسم أسباب الإخفاق).
استخدم job.progress(pct) للإبلاغ عن التقدّم، وjob.checkpoint(bytes) لحفظ الحالة كي تستأنف
المهمة إن صُرِّفت أو أُعيدت محاولتها.
الواجهة البرمجية للإضافات
حزمة WIT واحدة، maktaba:plugin@1.x، بإصدارات وفق semver. لا يضيف الإصدار الفرعي إلا دوالًا،
لذا تعمل إضافة مبنية للإصدار 1.2 على أي مضيف 1.x بدءًا من 1.2 فما فوق. تدعم مكتبة الإصدار
الرئيسي الحالي والسابق مدة 12 شهرًا على الأقل بعد صدور إصدار رئيسي جديد.
| الواجهة | الدوال (مخطط أولي) | القدرة |
|---|---|---|
job |
subject()، payload()، settings()، grants()، progress(pct)، checkpoint(bytes) |
لا شيء |
log |
log(level, code, fields) |
لا شيء |
data |
get وput وdelete وlist في نطاق أسمائك الخاص |
لا شيء (تنطبق الحصة) |
library |
video(id)، series(id)، list(library, filter, page) |
library.read |
transcript |
segments(video)، words(video) |
transcript.read |
media |
open(video)، frame(video, t, size)، audio(video, t0, t1, rate) |
media.read، media.frames، media.audio |
write |
set-field، add-tags، set-chapters، add-subtitle، set-artwork |
metadata.write، tags.write، chapters.write، subtitles.write، artwork.write |
suggest |
suggest(subject, field, value, reason) إلى طابور مراجعة المشرف |
suggest |
queue |
request(stage, subject, payload) لمراحلك الخاصة |
jobs.enqueue |
notify |
admin(code, params)، إشعار من نصوصك |
notify.admin |
exports |
read(plugin, subject, key) لبيانات صدّرتها إضافة أخرى |
plugin-data.read:<id> |
compute (المرحلة 3) |
embed(texts)، generate(prompt, opts) |
compute.embed، compute.llm |
تبقى الواجهات التي لم تُمنح لك مربوطة، كي تتمكن من التراجع بسلاسة، لكن كل استدعاء لها يُجاب بخطأ قدرة.
قواعد تسري على كل استدعاء
- النطاق محصور في المهمة. تعمل
mediaوwriteعلى موضوع المهمة فقط، أو على عناصر في المكتبات الممنوحة بالنسبة لمهام المكتبة والفهرس. خارج النطاق:403 plugin_scope. - القدرات مُتحقَّق منها. دون الصلاحية:
403 plugin_capability، ويُسجَّل ويُحتسب ضمن قاطع الدائرة. - الحقول الأساسية محمية. لا يكتب
set-fieldإلاdescriptionوsort_titleوyearوcontent_ratingوoriginal_languageوlocal_ids.<your short id>. ولا يستبدل أبدًا عنوانًا حدّده المشرف؛ استخدمsuggestبدلًا من ذلك. - كل كتابة منسوبة إلى
plugin:<id>@<version>، فيستطيع المشرف عرضها والتراجع عنها لكل إضافة على حدة، وإبعادها عن كل ما يغادر الخادم المنزلي. - الترجمات المصاحبة تُحلَّل بصيغة WebVTT أو SRT وتعيد مكتبة كتابتها، بحجم يصل إلى 4 MB، تحت اسم تختاره مكتبة.
حالات رفض أخرى: plugin_field، plugin_quota، plugin_rate، 413 plugin_too_large،
401 plugin_token، 401 plugin_grants_changed.
مقابض الوسائط
| الاستدعاء | القدرة | ما تحصل عليه |
|---|---|---|
media.open(video)، ثم stream.read(offset, len) وstream.size() |
media.read |
بايتات خام، حتى 8 MB في كل قراءة |
media.frame(video, t-ms, max-edge) |
media.frames |
إطار واحد مفكوك الترميز، أطول ضلع فيه حتى 1,280 بكسل |
media.audio(video, t0-ms, t1-ms, rate) |
media.audio |
صوت أحادي PCM بدقة 16 بت بتردد 8 أو 16 أو 22.05 kHz، حتى 10 دقائق لكل استدعاء |
media.info(video) |
library.read |
المدة، والمسارات، والترميزات |
المقبض مرتبط بمهمتك وبالفيديو وببصمة محتوى الملف. إذا تغيّر الملف أثناء المهمة، تُجاب القراءات
بـ 409 media_changed. الميزانيات لكل مهمة: بايتات مقروءة حتى ضعف حجم الملف، و2,000 إطار،
وصوت حتى أربعة أضعاف المدة. لا ترى أبدًا المسارات ولا أسماء المشاركات ولا الملفات الأخرى في
المجلد.
الصلاحيات الممنوحة والأدوار
عند التثبيت يرى المشرف قدراتك بكلمات مكتبة نفسها، بالإنجليزية أو العربية، فيلغي تحديد
الاختيارية منها، ويحدد كل مكتبة يجوز لك استخدامها. لا تُحدَّد أي مكتبة افتراضيًا. إن لم
تُحدَّد أي مكتبة، تُثبَّت إضافتك وتعمل، لكن كل استدعاء ضمن نطاق مكتبة يُجاب بـ plugin_scope.
افحص job.grants() لتعرف ما لديك.
- التحديث الذي يضيف قدرة إلزامية ينتظر المشرف؛ ويستمر الإصدار القديم في العمل.
- تبقى القدرات الاختيارية الجديدة معطّلة حتى يحددها المشرف.
- يسري سحب الصلاحية من استدعائك التالي.
- يُعرض عند التثبيت تقييم من 1 إلى 6: يبدأ من 6 وينخفض مع كل قدرة متوسطة الخطورة، ومع غياب مراجعة المتجر، ومع قراءة بيانات إضافة أخرى.
لا يستطيع تثبيت الإضافات أو ضبطها أو رؤيتها إلا المشرفون. يرى المشاهدون مخرجات الإضافات بوصفها بيانات عادية (وسوم، وفصول، وترجمات مصاحبة) ولوحات، وذلك فقط على المواضيع التي يسمح بها وصولهم إلى المكتبات.
الإعدادات
صرّح عن نموذج للمشرف في ui/settings.schema.json، وهو مجموعة فرعية من JSON Schema:
- كائن جذر يضم حتى 40 خاصية، بمستوى تداخل واحد على الأكثر؛
- الأنواع
stringوintegerوnumberوboolean، وarrayمن سلاسل نصية تعدادية؛ - قيمة
defaultلكل خاصية؛ x-maktaba-titleوx-maktaba-helpبوصفهما مفاتيح إلى نصوصك؛x-maktaba-widget:text،textarea،select،slider،switch،library-picker،language-picker.
لا حقول سرية: لا format: password، ولا حقل باسم token أو password أو api_key أو
secret. الإضافة التي لا تتصل بالإنترنت ليس لديها ما تسجّل الدخول إليه. اقرأ القيم بـ
job.settings(). يعيد تغيير الإعدادات تشغيل المراحل التي تعتمد مدخلاتها عليه.
اللوحات (المرحلة 3)
يصرّح [[panel]] مع on = "video" (أو series أو library) ومخطط ui/panel.json عن كتل
للقراءة فقط ترسمها كل التطبيقات بواجهاتها الأصلية: kv، وbadges، وchips، وtable (حتى 50
صفًا)، وmarkers على الخط الزمني، وأداة image واحدة، وtext. تأتي القيم من data الخاصة
بك لذلك الموضوع. كل شيء نص عادي: لا روابط URL ولا HTML ولا markdown. تُعرض اللوحات لكل من في
الخادم المنزلي يستطيع رؤية الموضوع، وتخضع كل إضافة للوحة لمراجعة بشرية في المتجر.
الحوسبة المحلية (المرحلة 3)
compute.embed: تضمينات من نموذج البحث في الخادم المنزلي، حتى 64 نصًا لكل استدعاء.compute.llm:generateعلى النموذج اللغوي الخاص بالخادم المنزلي، حتى 1,024 رمزًا (token).
تمر الاستدعاءات عبر الواجهة البرمجية للإضافات إلى خدمات على الخادم المنزلي، لا إلى نموذج بعيد
أبدًا. إذا كان النموذج متوقفًا، يُجاب الاستدعاء بـ unavailable. تنطبق حصص يومية، ولا تُسجَّل
المطالبات.