الوثائق

المشغّلات الحتمية (Operators)

عُقد إجراء لا تمرّ عبر نموذج LLM — HTTP، قواعد البيانات، التحويلات، الحسابات — مع إدارة الأسرار وضمان عدم التكرار.

الـoperator عقدة تنفّذ إجراءً حتميًا: بلا LLM، وبلا عشوائية. ولأي إدخال معطى، يكون الإخراج متوقَّعًا.

لماذا تستخدمها

أي منطق يمكن كتابته صراحةً ينبغي أن يُكتب كذلك. فنموذج LLM الذي «يحسب مجموعًا» أو «يهيّئ تاريخًا» هو نمط مضادّ: فهو أبطأ وأغلى وقد يخطئ.

قاعدة عملية: إذا استطعت كتابة الدالة في 5 أسطر من Python، فهي operator — لا agent.

الأنواع المتاحة

webhook_action (استدعاء HTTP)

يجري استدعاء HTTP صادرًا. التهيئة:

  • عنوان URL، الطريقة، الترويسات ومعاملات الاستعلام (مع عناصر نائبة من السياق)
  • المتن: none، json، form، raw، multipart، أو mapper (متن تركّبه لغة الربط، انظر أدناه)
  • المصادقة: bearer، basic، api_key_header (ترويسة مخصّصة)، أو oauth2 (انظر أدناه)
  • حالات HTTP المقبولة، والمهلة القصوى، وعدد مرّات إعادة المحاولة (retry_count، 0 افتراضيًا، تراجع أُسّي)
  • مفتاح المخرج الذي تُنشَر تحته الاستجابة

database_query / database_manage

تقرأ database_query صفوفًا من قاعدة بيانات betool بلا كود أو من قاعدة بيانات خارجية (Postgres، MySQL، MongoDB) مُسجَّلة في التطبيقات ← قواعد البيانات ← الاتصالات: مرشِّح where، بحث نصّي كامل، حدّ. وتكتب فيها database_manage (create أو update)، ويُركَّب المحتوى بلغة الربط.

file_transform

يحوّل ملفًا. المحوّلات المدمجة:

  • pdf_extract_text — النصّ القابل للتحديد في ملف PDF (دون OCR: ملف PDF الممسوح لا يُعيد نصًّا)
  • pdf_split — تقسيم ملف PDF
  • pdf_to_images — تحويل صفحات ملف PDF إلى صور
  • xlsx_to_json / xls_to_json — قراءة مصنّف Excel على شكل صفوف JSON
  • unzip — استخراج أرشيف

يُسلِّم ملفات إلى طرف ثالث عبر رابط، دون وضع محتواها في التدفّق: لكل ملف في قائمة من السياق (ملفات تنزيل، مرفقات مستلَمة، صور فحص…)، تُنتج عقدة روابط التنزيل رابط تنزيل موقَّعًا بمدّة صلاحية محدودة. وتتولّى خطوة لاحقة تأليف ما يتلقّاه المستلِم: استجابة webhook وارد، بريد إلكتروني…

الإعدادالدور
قائمة الملفات المطلوب ربطها (input_path)موضع قراءة القائمة في التدفّق — يحمل كل إدخال path (مفتاح الملف في تخزين المؤسسة) واسم ملف اختياريًا. إلزامي.
المجلدات الفرعية المسموح بها (path_scope)اختياري: يقصر الملفات القابلة للتوقيع على مجلدات فرعية معيّنة من تخزين المؤسسة.
مدة صلاحية الروابط15 دقيقة افتراضيًا، من دقيقة واحدة إلى 24 ساعة.
الحد الأقصى لعدد الملفات (max_files)20 افتراضيًا، و100 كحدّ أقصى.
مفتاح الإخراج (output_key)الافتراضي linked.files.

يحتوي الإخراج على files (كل إدخال أصلي، مُثرًى بـurl وexpires_at)، وfile_count، وfailed، وrequested، وttl_seconds.

  • لا شيء خارج مؤسستك أبدًا: يُرفض أي ملف خارج تخزينها.
  • التحقّق من الوجود قبل التوقيع: لا يُوقَّع ملف غائب أبدًا.
  • لا شيء يُغفَل: الملف غير المربوط (خارج النطاق، غير موجود، بعد السقف، تعذّر التوقيع) يظهر في failed مع سببه.
  • تُعاد إنشاء الروابط عند كل تنفيذ، ويُسجَّل كل رابط صادر.

الرابط لحامله (bearer): كل من يملكه ينزّل الملف حتى انتهاء صلاحيته. أبقِ المدّة قصيرة، واملأ المجلدات الفرعية المسموح بها بمجرّد أن تأتي القائمة من بيانات قابلة للتعديل (صفّ في جدول) — وإلّا فإنّ كل من يستطيع كتابة تلك البيانات قد يجعل رابطًا يُوقَّع نحو أي ملف في المؤسسة.

compute

حسابات حتمية على بيانات السياق. العمليات المدمجة:

  • column_stats — لكل عمود من قائمة صفوف، كم منها يساوي قيمة معيّنة (count، total، pct)
  • compose_text — تركيب نصّ انطلاقًا من قالب ومن قيم التدفّق
  • regex_extract — استخراج قيم بتعبير نمطي
  • select_by_substring — توزيع قائمة على مجموعات وفق مُسنَدات «يحتوي / لا يحتوي»
  • list_compare — اتّساق عدّة قوائم حسب مفتاح محوري
  • multi_source_compliance — تدقيق امتثال متعدّد الأبعاد ومتعدّد المصادر
  • contact_extract — عناوين البريد الإلكتروني وأرقام الهاتف الموجودة في نصّ، مع مصدرها
  • free_slots — فترات فارغة مستنتَجة من فترات مشغولة
  • url_expand — تركيب عناوين URL انطلاقًا من قواعد ومسارات

لغة الربط

ليست عقدة: إنها اللغة التي تركّب حمولة إخراج من بيانات السياق (الدوال $now، $uuid، $concat…). وتُستخدَم في المتن mapper لـwebhook_action، وفي المحتوى الذي تكتبه database_manage، وفي متغيّرات المكالمة الصادرة phone_call.

data_to_file

تُنتج ملف Excel (.xlsx) من بيانات السياق — قائمة صفوف، أو شبكة، أو عدّة قوائم (ورقة لكل منها). الخيارات: اسم الملف (قابل للقولبة)، واسم الورقة، واختيار الأعمدة وترتيبها، وصفّ الترويسة. يُحفَظ الملف في مساحة التخزين الخاصة بمؤسستك، جاهزًا للإرسال بالبريد الإلكتروني أو للإيداع على Drive.

لدواعٍ أمنية، تُكتَب الخلايا التي تبدأ بـ = أو + أو - أو @ بوصفها نصًّا افتراضيًا (لا حقن لصيغ). وعندما تفرض حدود Excel القطع، يُعلَّم الملف على أنّه مقتطَع.

web_fetch

تقرأ صفحة ويب واحدة أو أكثر وتنشر نصّها المقروء في السياق (الافتراضي web.pages). الإعدادات: عدد الصفحات، والتزامن، والمهلة، والحجم الأقصى. يُحسَب حكم robots.txt دائمًا ويُبلَّغ عنه؛ ولا يُطبَّق إلا إذا فعّلته (respect_robots).

لا تُنفَّذ الصفحات التي تُعرَض بواسطة JavaScript فقط: يُقرأ الـ HTML المُقدَّم وحده. وتُبلَّغ الصفحة الفاشلة في النتيجة، دون أن يفشل الـpipeline.

من جهة الوكيل، أداتان مكافئتان:

  • web_scrape.fetch_page — تقرأ صفحة (العنوان، النص، روابط البريد الإلكتروني والهاتف الموجودة).
  • web_search.search — البحث على الويب عبر محرّك SearXNG تستضيفه المنصّة ذاتيًا: حتى 5 نتائج (العنوان، URL، مقتطف).

تمرّ جميع القراءات على الويب عبر حماية anti-SSRF نفسها: تُرفَض العناوين الداخلية والخاصة وعناوين البيانات الوصفية السحابية بعد حلّ DNS، ويُعاد التحقّق من عمليات إعادة التوجيه عند كل قفزة.

code_step

عندما يتجاوز المنطق الحتمي ما يستطيع compute التعامل معه، تنفّذ خطوة كود كودًا مخصّصًا في sandbox من نوع Starlark — قابلة للتحرير مباشرةً، وتُنفَّذ فور الحفظ، ومقيّدة بقائمة بيضاء (allowlist) من الأدوات. راجع خطوات الكود.

المصادقة والأسرار

المشغّلات التي تتواصل مع نظام خارجي (HTTP، DB) تشير إلى حساب مُسجَّل داخل المؤسسة. ولا تكون بيانات الاعتماد مرئية أبدًا داخل الـpipeline نفسه — بل يُشار إلى اسم حساب فقط.

نتيجةً لذلك، فإنّ تدوير كلمة مرور لا يتطلّب أي تعديل على أي pipeline.

عندما يُدخَل سرّ مباشرةً في عقدة (رمز bearer، أو كلمة مرور basic، أو قيمة api_key_header في webhook_action، أو كلمة مرور PDF أو أرشيف مشفَّر لـfile_transform)، فإنه يُخفى فور حفظه: لا يُظهر المحرّر والـAPI وأدوات MCP سوى علامة. انظر المحرّر المرئي، قسم الأسرار.

OAuth2 الصادر (client_credentials)

بالنسبة إلى واجهات API التي تتطلّب رمز OAuth2 مميّزًا (السحابة المؤسسية، ERP، مزوّدو الطرف الثالث)، يدعم operator HTTP وضع oauth2. تسجّل بيانات اعتماد OAuth2 في المؤسسة — token_url، client_id، client_secret، scope — ولا تشير العقدة إلا إلى مُعرِّف غير حسّاس.

عند وقت الاستدعاء، يحصل betool على رمز مميّز ويُعيد استخدامه ما دام صالحًا؛ ويجدّده بكسل (lazily) عند انتهاء الصلاحية، بلا مهمّة في الخلفية. ولا يُعيد الـadministration API الـclient_secret أبدًا (بل يُعرَض مؤشّر has_secret فقط)، ويوضَع الرمز المميّز المُحصَّل عليه بصيغة Authorization: Bearer … على الطلب الصادر.

تدوير السرّ بعد تدوير على جانب المزوّد لا يتطلّب أي تعديل على الـpipeline: فالاستدعاء التالي يجدّده تلقائيًا.

الخاصّية الاحترازية (Idempotency)

أي operator يُنتج أثرًا جانبيًا (HTTP POST، DB INSERT، إرسال بريد) يجب تصميمه ليكون احترازيًا على جانب الهدف. الممارسة المُوصى بها:

  • ضمِّن idempotency_key في الحمولة (عادةً exchange_id).
  • تحقّق على جانب الهدف مما إذا كان المفتاح قد عُولِج بالفعل.

خارج إعادات المحاولة التي تهيّئها صراحةً على webhook_action (retry_count)، لا يُعيد betool تلقائيًا محاولة operator فاشل: بل من مسؤولية الـpipeline لديك تنسيق استراتيجية إعادة المحاولة. كما أنّ webhook_action محمية من الإرسال المزدوج عند إعادة توزيع داخلية: الطلب الذي سبق تسليمه بحالة مقبولة لا يُعاد إرساله.