צ'אט ה-AI הוא עוזר שיושב בכל מסך של האדמין, מבין את הפאנל הפתוח וכותב ישירות לשדות, מחפש בטבלאות ומפעיל כלים. הוא מורכב מאפליקציית Vue בדפדפן שמדברת ישירות עם שרת ה-stream של WizzoAI, ומ-API קטן בצד ה-CMS (admin/ai_chat.php) ששומר שיחות, זיכרון והעלאות. הדף מתאר את שני הצדדים ואת נקודות ההרחבה שלהם.
תנאי טעינה#
הצ'אט נטען בתבנית admin_panel כש-market_service::is_active("wizzoai") מחזיר אמת, ורק אם לא כובה בקוד:
// application/... (קוד שרץ לפני רינדור האדמין)
MISC::$GLOBALS["allow_ai_chat"] = false; // הצ'אט לא ייטען
כשהוא נטען מוזרק window.aiChatConfig עם adminId, adminName, streamUrl, adminUrl, רשימת עמודי האדמין, והפקודות המותאמות הפעילות מ-CRM_ai_commands (לפי sort_order), וגם apiKey, מפתח WizzoAI של האתר.
מפתח ה-WizzoAI מוזרק לדפדפן של כל מנהל, משום שהדפדפן מדבר עם ה-stream ישירות (ממצא AI-01 בביקורת). מי שיש לו גישה לאדמין יכול לקרוא אותו. באתרים שבהם יש מנהלים שלא צריכים לסמוך עליהם, כבו את הצ'אט עם allow_ai_chat, וסובבו את המפתח כשמנהל עוזב.
הארכיטקטורה#
| צד | תפקיד |
|---|---|
הדפדפן (ai_chat_agent.js, ai_chat.js) | הלולאה של המודל, כלי הצ'אט, ה-UI |
| ה-stream | POST {streamUrl}/ai/stream (תשובה ב-SSE), POST /ai/image, GET /models. האימות: Authorization: <apiKey> |
ה-CMS (/{admin}/ai_chat/<action>?pmode=empg) | שיחות, הודעות, זיכרון, העלאות, גישה לנתונים וקריאה לכלי מוצרים |
הלולאה עוצרת אחרי מספר מוגבל של קריאות כלי לתור, ואישור פעולות הרסניות נעשה בכפתור ב-UI ולא בטקסט.
ה-API של admin/ai_chat#
כל הפעולות הן {admin}/ai_chat/<action>?pmode=empg, גוף JSON (או $_POST), תשובה {"success": true, "data": ...}. שיחות, הודעות וזיכרון מסוננים לפי המנהל המחובר.
| action | קלט | מה עושה |
|---|---|---|
conversations | ?search, ?page (30 בעמוד) | שיחות לא מאורכבות של המנהל |
conversation_create | title, model, system_prompt | יוצר שיחה |
conversation_update | id ושדות לשינוי (כולל is_pinned, is_archived) | |
conversation_delete | id | |
messages | ?conversation_id | הודעות שיחה (רק של המנהל) |
message_save | conversation_id, role, content, message_type, tool_call_id, tool_name, tool_data, metadata, attachments | שומר הודעה |
memory_list | - | הזיכרון של המנהל |
memory_save | memory_key, memory_value, category, conversation_id | יוצר או מעדכן לפי המפתח |
memory_delete | id | |
get_custom_instructions | - | הנחיות פעילות (content, panel_name) |
automations_get | ?slugs=a,b | כללי אוטומציה לפי slug |
upload_image | FormData file, name | נשמר ב-STORAGE כ-webp |
save_image | base64 או url, name | שומר תמונה ל-STORAGE |
upload_file | FormData file (עד 15MB) | מחלץ טקסט (txt, csv, doc, docx, pdf, xls, xlsx) להקשר המודל |
generate_title | conversation_id | כותרת אוטומטית |
db_tables | - | רשימת הטבלאות עם ספירת שורות (מטמון) |
db_table_schema | table | עמודות, אינדקסים ו-3 שורות דוגמה |
db_query | sql או sql_encoded (base64), limit | שאילתת קריאה בלבד |
mcp_tools | - | external_mcp::by_server(), למנהלים בלבד |
mcp_call | server, tool, arguments | external_mcp::call("<server>_<tool>", ...), למנהלים בלבד |
המחלקה ADMINMODULE_ai_chat מוגדרת עם skip_permission_check = true, ולכן בדיקות ההרשאה של הפאנלים לא חלות עליה. הפעולות db_tables, db_table_schema ו-db_query זמינות לכל מנהל מחובר, כולל מנהל ללא הרשאה לפאנל כלשהו: הוא יכול לקרוא כל טבלה, גם כאלה שמכילות סיסמאות מגובבות או טוקנים, וגם db_table_schema מחזירה שורות דוגמה (ממצא AI-03 בביקורת). הפעולות מגבילות לקריאה בלבד (SELECT, SHOW, DESCRIBE, EXPLAIN), פקודה אחת בלבד, ו-LIMIT ברירת מחדל 50 ומקסימום 200, אבל לא מסננות טבלאות. אם יש באתר מנהלים בהרשאות מוגבלות, כבו את הצ'אט להם או את allow_ai_chat.
הכלים שהמודל רואה#
הכלים מוגדרים ב-JS של הצ'אט:
| קבוצה | כלים |
|---|---|
| תוכן ושדות | update_field, insert_file_to_field, save_form, form_action |
| מדיה | generate_image, import_media, capture_screenshot |
| נתונים | db_explore, db_query, table_get_rows, table_row_action, table_bulk_action, table_edit_cell, table_add_item |
| ניווט וזיכרון | navigate, save_memory |
| עבודה ארוכה | start_managed_task (לולאה בדפדפן על panel_table), stop_managed_task, start_background_job, propose_agent |
| כלי מוצרים | <server>_<tool> לכל כלי מ-mcp_tools (external_mcp) |
| פקודות מותאמות | custom_<id> לכל שורה פעילה ב-CRM_ai_commands מסוג tool |
start_background_job קורא ל-{admin}/ai_agents/chat_job ומתחיל משימת רקע בשרת, והצ'אט שואל את chat_job_status עד לסיום. propose_agent שומר טיוטת סוכן ב-stream (לא פעיל) ומחזיר קישור למסך הבנייה.
התאמה אישית#
הנחיות לפי פאנל#
הטבלה CRM_ai_chat_instructions (פאנל ai_chat_settings): title, content, panel_name (ריק פירושו כללי), is_active, ord. התוכן מוזרק להנחיית המערכת של המודל, ומסונן לפי הפאנל הפתוח.
פקודות מותאמות#
הטבלה CRM_ai_commands (פאנל ai_commands) מגדירה כלי שהמודל יכול לקרוא לו: title, icon, description, json_schema (סכמת הפרמטרים), examples, api_url, is_active, sort_order. הקריאה היא POST {admin}/<api_url>?pmode=empg עם גוף שבנוי מהארגומנטים ועוד _context: {item_id, page_url, table}. בנו את ה-endpoint כמו כל פאנל אדמין, כך שההרשאות שלו חלות.
אוטומציות#
הטבלה CRM_ai_chat_automations (פאנל ai_chat_automations_settings) מגדירה כללי שמירה בעזרת מודל. לכל אוטומציה יש slug ייחודי ו-rules כמערך JSON:
[
{"text": "הכותרת חייבת לכלול את שם המוצר", "behavior": "gate", "strictness": "0.85", "auto_fix": true}
]
behavior הוא gate (חוסם שמירה) או warn. strictness הוא אחד מ-0.95, 0.85, 0.70, 0.50, 0.30. השאר: watch_fields, fail_policy, is_active, ord. ה-JS (automations_interceptor.js) מיירט שמירת טופס, שולח למודל את ערכי הטופס, וחוסם, מזהיר או מתקן לפי ההחלטה. אפשר להפעיל ידנית עם WizzoAutomations.run(slug).
צ'אט מנהלים#
בנפרד מצ'אט ה-AI יש צ'אט פנימי בין מנהלים (admin/admin_chat.php, הטבלאות CRM_admin_chat ו-CRM_admin_chat_read). הודעות מוגבלות ל-1000 תווים וקבצים ל-10MB. סוכנים מדווחים אליו דרך notify_admin ו-close_run.
טבלאות#
| טבלה | שימוש |
|---|---|
CRM_ai_chat_conversations | שיחות |
CRM_ai_chat_messages | הודעות |
CRM_ai_chat_memory | זיכרון לכל מנהל |
CRM_ai_chat_instructions | הנחיות |
CRM_ai_chat_automations | אוטומציות |
CRM_ai_commands | פקודות מותאמות |
רוב הטבלאות נוצרות על ידי עדכון הליבה. טבלאות ההנחיות והאוטומציות נוצרות בפתיחת הפאנל הראשונה שלהן.