Skip to content

MelisAIEngine

محرك الذكاء الاصطناعي المجرّد — عقد المزوّد، بيئة تشغيل الوكلاء/السيناريوهات، مخزن المحادثات، جسر MCP/الأدوات، جميع جداول قاعدة بيانات الذكاء الاصطناعي، ومكوّنات الدردشة المشتركة المبنية على React التي تشغّل الواجهة الخلفية للإصدار السادس (v6). الحزمة melisplatform/melis-ai-engine.

الغرض

يُعدّ MelisAIEngine حجر الأساس في مجموعة MelisAI. فهو يعرّف عقد المزوّد المجرّد (MelisAIEngineModelService) الذي ينفّذه كلٌّ من Claude وGemini، ويشغّل الوكلاء عبر سير عمل سيناريوهات متعدّدة الخطوات، ويدير جسر MCP/استدعاء الأدوات، ويملك جميع جداول قاعدة البيانات melis_ai_*. وليست له أداة مستقلّة خاصّة به — فهو محرك الدردشة الخفيّ في الواجهة الخلفية. وفي الإصدار السادس (React) يشحن أيضًا مكوّن React المشترك AiChatContainer وواجهة الدردشة الخلفية /melis/react-api/ai-engine/* التي تركّبها وحدة MelisAI داخل أدواتها المرئية.

تفعيله

أضِفه إلى config/melis.module.load.php:

php
return [
    'MelisAIEngine',
];

اعتماديّات Composer المطلوبة: melisplatform/melis-core وmelisplatform/melis-document-upload. يجب تثبيت وحدة مزوّد واحدة على الأقل (MelisAIEngineClaude أو MelisAIEngineGemini) لإجراء استدعاءات نماذج فعلية؛ ومن دون مزوّد نشط لشركة النموذج تُبلّغ الدردشة بالرسالة "The AI company module is not active."

الخدمات الرئيسية

اسم الخدمة المستعارالدور
MelisAIEngineModelServiceعقد المزوّد المجرّد. اشتقّ منه لإضافة مزوّد ذكاء اصطناعي جديد (§ عقد المزوّد).
MelisAIEngineServiceالسجلّ/المصنع: getActiveInstance()، getActiveAgent()، getActiveModel()، getActiveModelClass() (اختيار المزوّد)، getActiveAITools()، saveDailyUsage().
MelisAIEngineAgentServiceبيئة تشغيل السيناريوهات: runAgent($postValues, $files) تجتاز خطوات الوكيل وتقود MelisAIEngineModelService::send().
MelisAIEngineMcpServiceجسر MCP/استدعاء الأدوات: إدارة الخوادم، الاتصال عبر JSON-RPC، قاطع الدارة، getAvailableTools()، isMcpTool()، invokeTool()، formatToolsForAI()، getToolSchema().
MelisAIEngineConversationStoreحالة المحادثة المستمرّة متعدّدة الأدوار في melis_ai_conversation_state: get()، has()، set()، delete(). جمع تلقائي للمهملات بعد 48 ساعة.
MelisAIEngineFunctionServiceتنفيذات الأدوات المدمجة (غير MCP)، مثل get_table_structure وcreate_database_table.
MelisAIEngineFileServiceتنظيف الاحتفاظ بالمستندات المرفوعة عبر الذكاء الاصطناعي: deleteAIDocUploads().
MelisAIEngineGeneralServiceقاعدة مدركة للأحداث: sendEvent()، makeArrayFromParameters().

عقد المزوّد

الصنف MelisAIEngineModelService (src/Service/MelisAIEngineModelService.php) هو الصنف المجرّد الذي يجب على كل مزوّد أن يمدّده. المُنشئ: (ServiceManager $serviceManager, int $modelId, int $agentId).

الدوال المجرّدة التي يجب على المزوّد تنفيذها:

php
abstract public function setClient();
abstract public function addToolsToPayload($payload);
abstract public function addContentToPayload($payload, $role, $prompt, $files=[], $content=[]);
abstract public function constructContent($role, $prompt, $files=[]);
abstract public function getMessageKey(): string;            // 'messages' (Claude) | 'contents' (Gemini)
abstract public function sendCustomAI(?array $payload = []): array;
abstract public function getAllowedMimetypes(): array;
abstract public function setPromptTokenCount($responseData);
abstract public function setResponseTokenCount($responseData);
abstract public function setTotalTokenCount($responseData);
abstract public function processFiles($filesArr): array;
abstract public function processContextFiles($filesArr): array;

دورة حياة الدالة الأساسية send(array $contextArr): array ثابتة: addToolsToPayload()addContentToPayload() لكل مُدخل سياق ← sendCustomAI() ← عدّ الرموز ← تُرجع ['request','responseData','result','errors','needs_continuation','session_id','continuation_context','tool_results'].

الدوال المساعدة التي يوفّرها الصنف الأساسي: getModel()، getAgentFunctions()، getToolDeclarationByName()، دوال جلب الرموز، uploadDocument()، extractTextFromDocx()، extractTextFromXlsx()، getMimeType().

اختيار المزوّد

تختار الدالة MelisAIEngineService::getActiveModelClass($company, $modelId, $agentId) المزوّد بناءً على اسم شركة النموذج:

php
if (strpos($company, 'Google') !== false) {
    // builds MelisAIEngineModelGeminiService — requires MelisAIEngineGemini module
} elseif (strpos($company, 'Anthropic') !== false) {
    // builds MelisAIEngineModelClaudeService — requires MelisAIEngineClaude module
}

لإضافة مزوّد جديد (مثل OpenAI): مدّد MelisAIEngineModelService، ونفّذ الدوال المجرّدة، وسجّله كخدمة، وأضِف فرعًا هنا مفتاحه اسم الشركة. يتبع مزوّدا Ollama وOCI العقد نفسه.

نظام MCP / استدعاء الأدوات

تُعرَّف الأدوات في موضعين: config['plugins']['melisaiengine']['datas']['function_declarations'] (الاسم، الوصف، مخطط JSON، القيمة المنطقية mcp) وجدول melis_ai_tools. ويختار الوكيل الاشتراك في الأدوات عبر maa_agent_tools.

عند وقت الاستدعاء: تُرجع getAgentFunctions() التصريحات المسموح بها ← تحقنها addToolsToPayload() ← وعند استدعاء أداة يوجّه المزوّد المسار عبر MelisAIEngineMcpService::isMcpTool($name): تذهب أدوات MCP إلى invokeTool() (JSON-RPC عبر stdio، محميّة بقاطع الدارة)؛ وتذهب الأدوات المدمجة إلى MelisAIEngineFunctionService. تُعاد النتائج إلى النموذج وتستمرّ المحادثة حتى يشير النموذج إلى الاكتمال أو يُبلَغ حدّ الأمان.

تُهيَّأ خوادم MCP ضمن config['mcp']['servers'][<name>] = {enabled, command, args, tools, timeout}؛ وتشغّلها MelisAIEngineMcpService عبر proc_open وتتحدّث بروتوكول JSON-RPC 2.0 (tools/list، واستدعاء الأدوات).

جداول قاعدة البيانات

جميع جداول melis_ai_* مملوكة لهذه الوحدة (dbdeploy: true):

الجدوليحتوي على
melis_ai_modelsنماذج المزوّدين (الشركة، mam_generative_model، رابط مفتاح API).
melis_ai_companiesشركات الذكاء الاصطناعي (Google وAnthropic…).
melis_ai_platform_keysمفاتيح API لكل منصّة.
melis_ai_agentsالوكلاء (maa_name، رابط النموذج، maa_agent_tools بصيغة JSON، مفاتيح تبديل الملفات).
melis_ai_agents_toolsإسناد الوكيل ↔ الأداة.
melis_ai_toolsفهرس الأدوات (mat_name، mat_desc، mat_config بصيغة JSON).
melis_ai_instances / melis_ai_instance_transعمليات النشر المسمّاة (النسخ) وترجماتها.
melis_ai_scenario_steps / …_datas / …_datas_entryexitخطوات السيناريو وبياناتها ومعاملات الدخول/الخروج.
melis_ai_return_typesتعريفات أنواع الإرجاع للخطوات.
melis_ai_filesالملفات المرفقة بالخطوات/السياق.
melis_ai_daily_usageعدد الرموز والاستدعاءات لكل نموذج/وكيل/نسخة/يوم.
melis_ai_conversation_stateحالة المحادثة المستمرّة (macs_key، JSON، جمع تلقائي للمهملات).

مكوّنات الدردشة المبنية على React

ليس لـ MelisAIEngine أي brick ولا أي مُدخل في قائمة /melis-react. وبالنسبة إلى الواجهة الخلفية المبنية على React فإنه يعرض مكتبة مكوّنات بصيغة المصدر فقط ضمن ui-react/src/، يستوردها المستهلكون عبر الاسم المستعار في Vite @melis-ai-engine (المربوط بـ melis-ai-engine/ui-react/src). وهو يعرض سطح الدردشة بأكمله؛ أمّا النموذج اللغوي الفعلي فيوفّره دائمًا مزوّد وحدة.

التصديرالدور
AiChatContainer (الافتراضي)مكوّن التنسيق: يشغّل حلقة init → run → (continue×N) → validate بأكملها، ويحمل حالة الدردشة، ويربط المكوّنات الفرعية. ركّب هذا.
ChatHistory، TypingIndicator، StepInterfaceقائمة الرسائل القابلة للتمرير (markdown عبر window.marked عند توفّرها)، ومؤشّر التفكير، وبطاقات واجهة كل خطوة.
ChatFormBoxشريط الإدخال السفلي: منطقة نصّية، إرسال/تحقّق، قائمة + ← رفع ملف (user_file_upload[]) أو مكتبة الوسائط (userMediaFiles[]، MoxieManager)، وطبقة السحب والإفلات.
ChatDebugPanel، DebugEntryعرض التنقيح: حمولة الطلب (←) واستجابة النموذج الخام (←) بوصفها كتل JSON (فقط عند debugMode).
MelisPlanPanel، extractMelisPlan، looksLikeMelisPlanيعرض "خطة Melis" منظَّمة مقترحة من الذكاء الاصطناعي (مثل قائمة حقول نموذج) بهيئة جدول.
aiEngineInit/Run/Continue/Validate/Restartعميل مُنمَّط لنقاط النهاية ai-engine (§ واجهة الدردشة الخلفية).
parseResultActionString، dispatchResultAction، dispatchToolResultsموزّع تنقّل JS_ACTION بحلقة مغلقة (§ التنقّل بالحلقة المغلقة).

عقد التركيب — AiChatContainerProps:

tsx
type AiChatContainerProps = {
  maiInstanceId: string                        // required — e.g. "agenttool" or "newscontentcreator|42"
  agentId?: number | null                      // override the instance's default agent
  extraEntryParams?: Record<string, unknown>   // → extra_entry_param[key] context
  entryParamForm?: Record<string, string>      // → entry_param_form[key]
  debugMode?: boolean
  exitParamArr?: ExitParamArr
  showCloseButton?: boolean
  needExitParam?: boolean
  showHideButton?: boolean
  showHeader?: boolean
  clearSession?: boolean                        // clear the server session on init (fresh conversation)
  autoRun?: boolean                             // start the agent immediately after init
  initialMessage?: string                       // first user_chat when autoRun
  onClose?: () => void
  onHide?: () => void
  className?: string
  style?: React.CSSProperties
}

يحدّ المكوّن الحاوي عدد عمليات المتابعة عند MAX_CONTINUATION_HOPS = 20. ولإضافة دردشة ذكاء اصطناعي إلى أداة React، استورِد AiChatContainer وركّبه مع maiInstanceId — دون أي عمل على الواجهة الخلفية، فنقاط النهاية موجودة بالفعل. ويرفع المستهلكون قيمة key على العنصر المُركَّب لفرض جلسة خادم جديدة عند إعادة التشغيل.

أين يظهر

لن ترى MelisAIEngine أبدًا كعنصر قائمة؛ فسطوح دردشته تظهر داخل وحدة MelisAI، التي تركّب المكوّن نفسه AiChatContainer في ثلاثة مواضع (يختلف فيها maiInstanceId / agentId فقط):

  • AI Assistant — طبقة المساعد العائمة (دردشة عامة الغرض يمكنها التصرّف في الواجهة الخلفية، تُطلَق بـ autoRun).
  • Chat Dev Tool — ساحة اختبار للمطوّرين لإطلاق أي وكيل/نسخة والتحدّث إليه.
  • علامة تبويب "Run" الخاصّة بالوكيل — اختبار وكيل من أداة وكلاء MelisAI (maiInstanceId="agenttool").

واجهة الدردشة الخلفية — نقاط النهاية ai-engine

تُعرَّف المسارات في config/module.config.php (وليس في react-api.php)، والاسم المستعار للمتحكّم MelisAIEngine\Controller\React\MelisReactApiAiEngineMelisReactApiAiEngineController. ويحرس كلُّ إجراء نفسه بـ denyUnlessAuthenticated() (استجابة 401 من دون هوية MelisCore — دون بوّابة قدرات خاصّة بكل أداة، لأن هذا محرك مشترك). مظروف الاستجابة الموحّد: { success, data, error? }. وتحاكي نقاط النهاية هذه المتحكّم القديم AIController (/melis/MelisAIEngine/AI/*) وتستدعي الخدمة نفسها MelisAIEngineAgentService.

الطريقة والعنواندالة العميلالغرض
GET /melis/react-api/ai-engine/initaiEngineInitالتحقّق من النسخة←الوكيل←النموذج←المزوّد؛ وإرجاع label، finalInstanceId، agentId، isFileUploadActivated، isMediaLibraryActivated، hasExitParameter (أو errorType/errorMessage).
POST /melis/react-api/ai-engine/runaiEngineRunبدء دور/تقدّمه. JSON للنصّ، وmultipart/form-data عند إرفاق ملفات ← runAgent().
POST /melis/react-api/ai-engine/continueaiEngineContinueاستئناف دور متعدّد الخطوات (needs_continuation=true) ← continueConversation(sessionId, continuationContext).
POST /melis/react-api/ai-engine/validateaiEngineValidateقبول إجابة الذكاء الاصطناعي، والتقدّم إلى خطوة معامل الخروج، وإرجاع exitParams لدالة الاستدعاء الراجعة الخاصّة بالمضيف ← validateAnswer().
POST /melis/react-api/ai-engine/restartaiEngineRestartمسح الجلسة، وإرجاع finalInstanceId نفسه جاهزًا لإعادة الاستخدام.

تتضمّن RunResult الحقول chatHist، needs_continuation، session_id، continuation_context، payload/response (تنقيح)، exitParams، tool_results.

أبسط دور نصّي:

ts
import { aiEngineInit, aiEngineRun } from '@melis-ai-engine'

const cfg = await aiEngineInit({ maiInstanceId: 'agenttool', clearSession: true })
if (cfg.errorType) throw new Error(cfg.errorMessage)   // instance/agent/model/companyModule/exitParam

const res = await aiEngineRun({
  agentId:    cfg.agentId,
  instanceId: cfg.finalInstanceId,
  userText:   'Create a news article about our new store',
})
// res.chatHist, res.needs_continuation, res.session_id, res.tool_results …

التنقّل بالحلقة المغلقة

يقتصر عمل المحرك على التوزيع: يحلّل nav-actions.ts سلاسل الاستدعاء الراجعة JS_ACTION::action::k=v&… من tool_results الخاصّة باستجابة ما ويستدعي window.melisReactActionMap[action](args). أمّا الغلاف المضيف (melis-core) فهو من يسجّل تلك المعالِجات ويملك تنقّل React-Router وإدراك DOM. وقد يُرجع المعالِج ملاحظة من النوع Promise<string>، تنتظرها dispatchToolResults وتعيد تغذيتها بوصفها continuationContext.clientObservation — ما يؤسّس لدور النموذج التالي. ويبقي هذا الحزمتين المبنيّتين بشكل مستقلّ منفصلتين: فلا يربطهما سوى عقد window.

مثال (دالة مساعدة للعرض القديم)

لا تزال دالة المساعدة الكلاسيكية المعروضة من الخادم تعمل مع السياقات غير المبنية على React (.phtml):

php
// Render the chat box for a named instance
echo $this->AIChatViewHelper($maiInstanceId);

سجّل خادم MCP مخصّصًا وصرّح بأدواته حتى يتمكّن وكيل من استدعائها:

php
// In a module's config — register the MCP server
'mcp' => [
    'servers' => [
        'my-mcp-server' => [
            'enabled' => true,
            'command' => 'node',
            'args'    => ['/path/to/server.js'],
            'tools'   => ['my_tool'],
            'timeout' => 30,
        ],
    ],
],
// Declare the tool with mcp: true
'plugins' => [
    'melisaiengine' => [
        'datas' => [
            'function_declarations' => [
                [
                    'name'        => 'my_tool',
                    'description' => 'Does something useful',
                    'mcp'         => true,
                    // JSON schema for parameters…
                ],
            ],
        ],
    ],
],

الملفات الرئيسية

الشأنالمسار
عقد المزوّد (مجرّد)vendor/melisplatform/melis-ai-engine/src/Service/MelisAIEngineModelService.php
السجلّ + اختيار المزوّدvendor/melisplatform/melis-ai-engine/src/Service/MelisAIEngineService.php
بيئة تشغيل الوكيل/السيناريوvendor/melisplatform/melis-ai-engine/src/Service/MelisAIEngineAgentService.php
جسر MCP/الأدواتvendor/melisplatform/melis-ai-engine/src/Service/MelisAIEngineMcpService.php
مخزن المحادثة المستمرّvendor/melisplatform/melis-ai-engine/src/Service/MelisAIEngineConversationStore.php
الدوال المدمجةvendor/melisplatform/melis-ai-engine/src/Service/MelisAIEngineFunctionService.php
متحكّم الدردشة القديمvendor/melisplatform/melis-ai-engine/src/Controller/AIController.php
واجهة الدردشة الخلفية المبنية على Reactvendor/melisplatform/melis-ai-engine/src/Controller/React/MelisReactApiAiEngineController.php
مكتبة الدردشة المشتركة المبنية على Reactvendor/melisplatform/melis-ai-engine/ui-react/src/ (AiChatContainer.tsx، api.ts، nav-actions.ts…)
نماذج جداول قاعدة البياناتvendor/melisplatform/melis-ai-engine/src/Model/Tables/
تهيئة الوحدةvendor/melisplatform/melis-ai-engine/config/module.config.php

انظر أيضًا: MelisAI، MelisAIEngineClaude، MelisAIEngineGemini، MelisAIToolCreator.