إنتقل إلى المحتوى الرئيسي

مرجع SDK

SDK البرامج المصغرة هو مكتبة JavaScript بحجم ~2 كيلوبايت يتم حقنها في كل iframe برنامج مصغر. يوفر فضاء الأسماء window.ais مع طرق للتفاعل مع منصة AISCouncil عبر جسر postMessage آمن.

كيف يعمل SDK

يتم حقن SDK كعلامة <script> قبل HTML تطبيقك في srcdoc الـ iframe. لا تحتاج لتضمينه بنفسك -- إنه متاح دائماً كـ window.ais عند تشغيل كودك.

كل استدعاء طريقة (باستثناء خصائص platform.*) يرسل رسالة إلى الصفحة المضيفة ويعيد Promise. يتحقق المضيف من الأذونات، ينفذ الطلب، ويرسل النتيجة مرة أخرى.

كود تطبيقك                SDK                    المنصة المضيفة
| | |
|-- ais.chat.send("hi")-->| |
| |-- postMessage({ |
| | method: "chat.send", |
| | args: {text: "hi"} |
| | }) ---------------------->|
| | |-- فحص الأذونات
| | |-- تنفيذ AIS.Chat.send()
| |<-- postMessage({result}) --|
|<-- Promise يُحل -------| |
معلومات

جميع طرق SDK متاحة بشكل متزامن كمراجع دوال، لكنها تعيد Promises تُحل بشكل غير متزامن. استخدم دائماً await أو .then() للحصول على النتائج.

دعم TypeScript

تعريفات أنواع TypeScript متاحة في sdk/ais.d.ts. أضف مرجعاً لمشروعك:

/// <reference path="./ais.d.ts" />

ais.ready(async () => {
const history = await ais.chat.getHistory(10);
// history مُعرف النوع كـ ais.ChatMessage[]
});

أو انسخ أنواع AisManifest و AisPermission للتحقق من البيان في أدوات البناء الخاصة بك.


دورة الحياة

ais.ready(callback)

سجّل callback يتم إطلاقه عندما يتم توصيل جسر المنصة ويصبح جاهزاً. هذه هي نقطة الدخول لتطبيقك -- غلّف كل منطق التهيئة داخل هذا callback.

المعاملالنوعالوصف
callback() => voidالدالة التي يتم استدعاؤها عندما يكون الجسر جاهزاً
ais.ready(async function () {
// المنصة متصلة، استدعاءات SDK ستعمل الآن
const user = await ais.auth.getUser();
document.getElementById("greeting").textContent = "مرحباً، " + user.name;
});
حذر

لا تستدعِ طرق ais.* الأخرى قبل إطلاق ais.ready(). قد لا يكون جسر postMessage قد أُنشئ بعد، وستعلق الاستدعاءات إلى الأبد.

ais.onShow(callback)

سجّل callback يتم إطلاقه في كل مرة يصبح فيها البرنامج المصغر مرئياً (مثلاً، يعود المستخدم إلى علامة تبويب التطبيق).

المعاملالنوعالوصف
callback() => voidالدالة التي يتم استدعاؤها عند العرض
ais.onShow(function () {
// حدّث البيانات عندما يعود المستخدم إلى التطبيق
refreshDashboard();
});

ais.onHide(callback)

سجّل callback يتم إطلاقه عندما يتم إخفاء البرنامج المصغر (مثلاً، ينتقل المستخدم إلى المحادثة أو تطبيق آخر).

المعاملالنوعالوصف
callback() => voidالدالة التي يتم استدعاؤها عند الإخفاء
ais.onHide(function () {
// أوقف العمليات المكلفة
stopPolling();
});

ais.close()

أغلق البرنامج المصغر وعد إلى عرض المحادثة. يتم تدمير iframe بعد هذا الاستدعاء.

يعيد: Promise<boolean>

document.getElementById("done-btn").addEventListener("click", function () {
ais.close();
});

التخزين

تخزين قيم-مفتاح معزل لكل تطبيق مدعوم بـ IndexedDB. يتم تلقائياً إضافة فضاء أسماء للمفاتيح مع mp:{app-name}: بحيث لا يمكن للتطبيقات الوصول لبيانات بعضها.

الإذن: مسموح به دائماً -- لا حاجة لإذن.

ais.storage.get(key)

استرجع قيمة بالمفتاح. يعيد undefined إذا لم يكن المفتاح موجوداً.

المعاملالنوعالوصف
keystringمفتاح التخزين

يعيد: Promise<unknown> -- القيمة المخزنة، أو undefined

const count = await ais.storage.get("visit-count");
console.log("الزيارات:", count); // رقم، نص، كائن، مصفوفة، أو undefined

ais.storage.set(key, value)

خزّن زوج قيم-مفتاح. يمكن أن تكون القيمة أي نوع قابل للتسلسل كـ JSON (نص، رقم، منطقي، كائن، مصفوفة، null).

المعاملالنوعالوصف
keystringمفتاح التخزين
valueunknownالقيمة للتخزين (يجب أن تكون قابلة للتسلسل كـ JSON)

يعيد: Promise<boolean> -- true عند النجاح

await ais.storage.set("visit-count", 42);
await ais.storage.set("preferences", { theme: "dark", fontSize: 16 });

ais.storage.remove(key)

احذف مفتاحاً من التخزين.

المعاملالنوعالوصف
keystringالمفتاح للحذف

يعيد: Promise<boolean> -- true عند النجاح

await ais.storage.remove("temporary-data");

ais.storage.keys()

اسرد جميع المفاتيح المخزنة بواسطة هذا البرنامج المصغر (بدون البادئة الداخلية mp:{name}:).

يعيد: Promise<string[]>

const keys = await ais.storage.keys();
console.log("المفاتيح المخزنة:", keys); // ['visit-count', 'preferences']

المحادثة

اقرأ سجل المحادثة، أرسل رسائل، واشترك في الرسائل الجديدة في المحادثة النشطة.

الأذونات المطلوبة: chat:read للقراءة، chat:write للإرسال.

ais.chat.getHistory(limit?)

احصل على الرسائل الأخيرة من جلسة المحادثة النشطة.

المعاملالنوعالافتراضيالوصف
limitnumber50الحد الأقصى لعدد الرسائل للإرجاع

يعيد: Promise<ChatMessage[]>

interface ChatMessage {
role: "user" | "assistant" | "system";
content: string;
timestamp?: number;
}
const messages = await ais.chat.getHistory(20);
messages.forEach(function (msg) {
console.log(msg.role + ": " + msg.content);
});

ais.chat.send(text)

أرسل رسالة كمستخدم. هذا يحفز نموذج الذكاء الاصطناعي النشط لتوليد استجابة.

المعاملالنوعالوصف
textstringنص الرسالة للإرسال

يعيد: Promise<boolean> -- true عند النجاح

await ais.chat.send("لخص آخر 5 رسائل");
تحذير

استدعاء ais.chat.send() يحفز استدعاء API فعلي لموفر الذكاء الاصطناعي المُكوّن لدى المستخدم. هذا يستهلك رموزاً وقد يتكبد تكاليف. استخدمه بمسؤولية وأبلغ المستخدم دائماً قبل إرسال رسائل برمجياً.

ais.chat.onMessage(callback)

اشترك في رسائل المحادثة الجديدة. يتم إطلاق callback لكل رسالة جديدة (سواء من المستخدم أو المساعد).

المعاملالنوعالوصف
callback(msg: ChatMessage) => voidالمعالج للرسائل الواردة
ais.chat.onMessage(function (msg) {
if (msg.role === "assistant") {
// نموذج الذكاء الاصطناعي استجاب
updateResponseDisplay(msg.content);
}
});

الإعدادات

اقرأ إعدادات البوت النشط (الموفر، النموذج، موجه النظام، إلخ).

الإذن المطلوب: config:read

ais.config.get()

احصل على كائن إعدادات البوت الكامل.

يعيد: Promise<BotConfig>

interface BotConfig {
n?: string; // اسم البوت
p?: string; // معرف الموفر (مثلاً، 'anthropic'، 'openai'، 'gemini')
m?: string; // معرف النموذج (مثلاً، 'claude-sonnet-4-20250514')
s?: string; // موجه النظام
t?: number; // الحرارة (0.0 - 2.0)
x?: number; // الحد الأقصى لرموز المخرجات
[key: string]: unknown;
}
const config = await ais.config.get();
console.log("باستخدام النموذج:", config.m);
console.log("موجه النظام:", config.s);

ais.config.getProvider()

احصل على معرف الموفر النشط.

يعيد: Promise<string> -- مثلاً، 'anthropic'، 'openai'، 'gemini'، 'xai'، 'openrouter'، 'ollama'

const provider = await ais.config.getProvider();
if (provider === "ollama") {
showLocalModelBanner();
}

ais.config.getModel()

احصل على معرف النموذج النشط.

يعيد: Promise<string> -- مثلاً، 'claude-sonnet-4-20250514'، 'gpt-4o'، 'gemini-2.5-flash'

const model = await ais.config.getModel();
document.getElementById("model-name").textContent = model;

واجهة المستخدم

أظهر الإشعارات، مربعات حوار التأكيد، وحدّث عنوان لوحة التطبيقات.

ais.ui.toast(message, duration?)

اعرض إشعار toast مؤقت في واجهة المستخدم للمنصة.

المعاملالنوعالافتراضيالوصف
messagestring--نص الإشعار (حد أقصى 200 حرف)
durationnumber3000المدة بالميلي ثانية

يعيد: Promise<boolean>

الإذن: ui:toast (موصى به لكن غير مفروض بصرامة -- toast منخفض التأثير)

await ais.ui.toast("تم حفظ الملف بنجاح!");
await ais.ui.toast("جاري المعالجة...", 5000); // toast لمدة 5 ثواني

ais.ui.confirm(title, message)

أظهر مربع حوار تأكيد وانتظر استجابة المستخدم.

المعاملالنوعالوصف
titlestringعنوان مربع الحوار (حد أقصى 100 حرف)
messagestringنص متن مربع الحوار (حد أقصى 500 حرف)

يعيد: Promise<boolean> -- true إذا نقر المستخدم موافق، false إذا أُلغي**

الإذن المطلوب: ui:modal

const confirmed = await ais.ui.confirm(
"حذف جميع البيانات؟",
"سيؤدي هذا إلى إزالة جميع العناصر المحفوظة نهائياً. لا يمكن التراجع عن هذا الإجراء.",
);
if (confirmed) {
await clearAllData();
}

ais.ui.setTitle(title)

عيّن النص المعروض في شريط عنوان لوحة التطبيقات.

المعاملالنوعالوصف
titlestringنص العنوان (حد أقصى 100 حرف)

يعيد: Promise<boolean>

ais.ui.setTitle("عداد الكلمات - 1,234 كلمة");

المصادقة

اقرأ معلومات عن المستخدم المسجل حالياً.

الإذن المطلوب: auth:read

ais.auth.getUser()

احصل على معلومات الملف الشخصي للمستخدم الحالي.

يعيد: Promise<UserInfo | null> -- null إذا لم يكن مسجلاً

interface UserInfo {
name: string; // اسم العرض
email: string; // عنوان البريد الإلكتروني
picture: string; // URL صورة الملف الشخصي
}
const user = await ais.auth.getUser();
if (user) {
document.getElementById("avatar").src = user.picture;
document.getElementById("name").textContent = user.name;
} else {
document.getElementById("name").textContent = "زائر";
}

ais.auth.getTier()

احصل على مستوى اشتراك المستخدم.

يعيد: Promise<string> -- مثلاً، 'free'، 'pro'، 'team'

const tier = await ais.auth.getTier();
if (tier === "free") {
showUpgradePrompt();
}

الأسرار

اقرأ واكتب مفاتيح API لسيناريوهات النقل بين الأجهزة. هذه واجهة برمجة تطبيقات مميزة تستخدمها تطبيقات مثل مزامنة الجهاز.

الإذن المطلوب: secrets:sync

حذر

إذن secrets:sync يمنح الوصول لمفاتيح API المخزنة لدى المستخدم. اطلب هذا الإذن فقط إذا كان تطبيقك يحتاج فعلاً لنقل أو نسخ احتياطي للاعتمادات. سيرى المستخدمون تحذيراً واضحاً في مربع حوار الأذونات.

ais.secrets.list()

اسرد أسماء الموفرين الذين لديهم مفاتيح API مخزنة.

يعيد: Promise<string[]> -- مثلاً، ['anthropic', 'openai', 'gemini']

ais.secrets.get(provider)

احصل على قيمة مفتاح API باسم الموفر.

المعاملالنوعالوصف
providerstringاسم الموفر (مثلاً، 'anthropic'، 'openai')

يعيد: Promise<string | null>

ais.secrets.set(provider, value)

خزّن مفتاح API لموفر.

المعاملالنوعالوصف
providerstringاسم الموفر
valuestringقيمة مفتاح API (حد أقصى 1024 حرف)

يعيد: Promise<boolean>


المزامنة

زامن الملفات الشخصية، الإعدادات، وإشارات WebRTC للنقل بين الأجهزة.

الإذن المطلوب: secrets:sync

ais.sync.getProfiles()

احصل على جميع الملفات الشخصية للمستخدم من المنصة المضيفة.

يعيد: Promise<Profile[]>

ais.sync.setProfiles(profiles)

استورد ملفات شخصية إلى المنصة المضيفة.

المعاملالنوعالوصف
profilesProfile[]مصفوفة كائنات الملفات الشخصية للاستيراد

يعيد: Promise<number> -- عدد الملفات الشخصية المستوردة

ais.sync.getSettings()

احصل على إعدادات التطبيق (المظهر، اللغة، إلخ) من المضيف.

يعيد: Promise<Record<string, string>>

ais.sync.setSettings(settings)

اكتب إعدادات التطبيق إلى المضيف.

المعاملالنوعالوصف
settingsRecord<string, string>إعدادات قيم-مفتاح للكتابة

يعيد: Promise<boolean>

ais.sync.signal(code, type, sdp)

انشر عرض/إجابة SDP إلى مرحل API لإشارات WebRTC.

المعاملالنوعالوصف
codestringرمز الاقتران
type'offer' | 'answer'نوع SDP
sdpRTCSessionDescriptionInitبيانات SDP

يعيد: Promise<boolean>

ais.sync.pollSignal(code, type)

استطلع عرض/إجابة SDP من مرحل API.

المعاملالنوعالوصف
codestringرمز الاقتران
type'offer' | 'answer'نوع SDP للاستطلاع عنه

يعيد: Promise<RTCSessionDescriptionInit | null>


الخطافات

سجّل وأطلق أحداث خطافات مخصصة لتوسيع سلوك المنصة أو التواصل بين التطبيقات.

الأذونات المطلوبة: hooks:action لإطلاق الأحداث، hooks:filter لتسجيل معالجات التصفية.

ais.hooks.on(hookName, handler)

استمع لحدث خطاف مُسمّى.

المعاملالنوعالوصف
hookNamestringاسم الخطاف (مثلاً، 'chat:before-send')
handler(data: unknown) => voidمعالج الحدث

يعيد: Promise<boolean>

ais.hooks.on("chat:before-send", function (data) {
console.log("رسالة على وشك الإرسال:", data);
});

ais.hooks.fire(hookName, data?)

أطلق حدث خطاف مُسمّى. سيتم استدعاء جميع المعالجات المسجلة لهذا الخطاف.

المعاملالنوعالوصف
hookNamestringاسم الخطاف للإطلاق
dataunknownحمولة بيانات اختيارية

يعيد: Promise<unknown>

await ais.hooks.fire("my-app:data-updated", { count: 42 });

الصفحات

انشر صفحات ويب إلى bcz.co مع اسم مخصص. يستخدمها البرنامج المصغر منشئ التطبيقات.

الإذن المطلوب: pages:publish

ais.pages.getInfo()

احصل على معلومات عن صفحة المستخدم المنشورة.

يعيد: Promise<PageInfo>

interface PageInfo {
slug: string | null;
url: string | null;
title: string | null;
updatedAt: number | null;
hasPage: boolean;
}

ais.pages.claim(slug)

احجز اسماً (اسم المستخدم) لـ bcz.co/@slug.

المعاملالنوعالوص
slugstringالاسم المطلوب

يعيد: Promise<{ slug: string; url: string }>

ais.pages.publish(specBase64, opts?)

انشر أو حدّث صفحة. spec هو مستند PDL مُشفّر بـ base64.

المعاملالنوعالوصف
specBase64stringمواصفات صفحة مُشفّرة بـ base64
opts{ title?: string; description?: string }بيانات وصفية اختيارية

يعيد: Promise<PublishResult>

ais.pages.unpublish()

ألغِ النشر وأطلق الاسم.

يعيد: Promise<boolean>


معلومات المنصة

خصائص للقراءة فقط مع بيانات وصفية للمنصة. هذه متزامنة -- لا Promise، لا إذن مطلوب.

ais.platform.version

سلسلة إصدار المنصة (semver).

النوع: string -- حالياً '1.0.0'

ais.platform.abi

رقم إصدار ABI. يُستخدم للتحقق من التوافق بين SDK والمنصة المضيفة.

النوع: number -- حالياً 1

if (ais.platform.abi !== 1) {
ais.ui.toast("هذا التطبيق يتطلب إصدار ABI 1");
ais.close();
}

معالجة الأخطاء

جميع استدعاءات SDK التي تتطلب أذونات سترفض بخطأ PermissionDenied إذا لم يكن للتطبيق الإذن المطلوب:

try {
const history = await ais.chat.getHistory();
} catch (err) {
if (err.message.includes("PermissionDenied")) {
console.log("التطبيق ليس لديه إذن chat:read");
}
}

الطرق غير المعروفة تعيد خطأ بالرسالة Unknown method: {method}.

إذا واجهت المنصة المضيفة خطأ غير متوقع، يرفض Promise برسالة الخطأ كسلسلة.

تلميح

غلف دائماً استدعاءات SDK في كتل try/catch، خاصة لواجهات برمجة التطبيقات المقيدة بالأذونات. هذا يجعل تطبيقك مرناً حتى لو اختلف إصدار منصة المستخدم عما اختبرته عليه.


مثال كامل

تطبيق بسيط يستخدم ميزات SDK متعددة:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
body {
font-family: system-ui;
padding: 16px;
color: #e0e0e0;
background: #1a1a2e;
}
button {
min-height: 48px;
padding: 8px 16px;
font-size: 16px;
border: 1px solid #444;
border-radius: 6px;
background: #2a2a4e;
color: #e0e0e0;
cursor: pointer;
}
button:hover {
background: #3a3a5e;
}
pre {
background: #111;
padding: 12px;
border-radius: 6px;
overflow: auto;
}
</style>
</head>
<body>
<h2>مفتش المحادثات</h2>
<button id="load">تحميل السجل</button>
<button id="close">إغلاق</button>
<pre id="output">انقر "تحميل السجل" للبدء...</pre>

<script>
ais.ready(async function () {
// أظهر النموذج النشط
var model = await ais.config.getModel();
ais.ui.setTitle("مفتش المحادثات - " + model);

document
.getElementById("load")
.addEventListener("click", async function () {
var messages = await ais.chat.getHistory(25);
var output = messages
.map(function (m) {
return "[" + m.role + "] " + m.content.slice(0, 100);
})
.join("\n");
document.getElementById("output").textContent =
output || "(لا رسائل)";
ais.ui.toast("تم تحميل " + messages.length + " رسالة");
});

document.getElementById("close").addEventListener("click", function () {
ais.close();
});

// اشترك في الرسائل الجديدة في الوقت الفعلي
ais.chat.onMessage(function (msg) {
var el = document.getElementById("output");
el.textContent += "\n[" + msg.role + "] " + msg.content.slice(0, 100);
});
});
</script>
</body>
</html>

البيان لهذا المثال:

{
"name": "chat-inspector",
"version": "1.0.0",
"abi": 1,
"type": "mini-program",
"description": "عرض ومراقبة سجل المحادثات",
"entry": "index.html",
"base_url": "https://your-cdn.com/chat-inspector/",
"permissions": ["chat:read", "config:read", "ui:toast"]
}