עוזר AI מדויק עבור ימות המשיח! בדף html!
-
עוזר AI מדויק עבור ימות המשיח! גירסה 1
קרדיט ענק ל @perfect על קובץ הזיפ המסודר!!!
הדף עובד על מפתח API גמיני שבכל שיחה שולח קובץ זיפ עם כל הגדרות המערכת!
ניתן להזין מספר מפתחות API וברגע שמפתח אחד נכשל, הדף עובר בצורה אוטמטית למפתח הבא!
(שימו לב חובה להעלאות קובץ זיפ באופן חד פעמי, כמו כן אין אחריות על אופצית העלאה לימות המשיח האופציה טרם נבדקה כדי הצורך, הקריינות כרגע עדיין לא עובדת)
יש להוריד את קובץ הזיפ מפהלהלן קוד דף הhtml
<!DOCTYPE html> <html lang="he" dir="rtl"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>מומחה AI ימות המשיח - סביבת פיתוח מתקדמת</title> <!-- Fonts & Icons --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link href="https://fonts.googleapis.com/css2?family=Rubik:wght@300;400;500;600;700&display=swap" rel="stylesheet"> <!-- Marked.js for Markdown --> <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> <!-- Highlight.js for Syntax Highlighting --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/tokyo-night-dark.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/ini.min.js"></script> <style> :root { --bg-dark: #070a12; --panel-bg: rgba(21, 28, 45, 0.75); --panel-border: rgba(255, 255, 255, 0.08); --user-msg: linear-gradient(135deg, #2563eb, #1d4ed8); --ai-msg: rgba(30, 41, 59, 0.7); --accent-glow: #38bdf8; --accent-blue: #3b82f6; --success: #10b981; --warning: #f59e0b; --danger: #ef4444; --text-main: #f8fafc; --text-muted: #94a3b8; --analysis-bg: rgba(30, 27, 75, 0.6); --analysis-border: #6366f1; } * { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Rubik', sans-serif; } body { background-color: var(--bg-dark); color: var(--text-main); height: 100vh; display: flex; flex-direction: column; overflow: hidden; background-image: radial-gradient(circle at 50% 0%, #1e1b4b 0%, #070a12 70%); } /* Top Header Navigation */ header { background: rgba(15, 23, 42, 0.8); backdrop-filter: blur(12px); border-bottom: 1px solid var(--panel-border); padding: 12px 24px; display: flex; justify-content: space-between; align-items: center; z-index: 10; } .logo { font-size: 1.35rem; font-weight: 700; background: linear-gradient(90deg, #38bdf8, #818cf8); -webkit-background-clip: text; -webkit-text-fill-color: transparent; display: flex; align-items: center; gap: 12px; } .tabs { display: flex; gap: 10px; } .tab-btn { background: rgba(255,255,255,0.04); border: 1px solid var(--panel-border); color: var(--text-main); padding: 8px 18px; border-radius: 10px; cursor: pointer; transition: all 0.25s ease; font-size: 0.92rem; font-weight: 500; display: flex; align-items: center; gap: 8px; } .tab-btn.active { background: var(--accent-blue); border-color: var(--accent-glow); font-weight: 700; box-shadow: 0 0 15px rgba(59, 130, 246, 0.4); } .tab-btn:hover:not(.active) { background: rgba(255,255,255,0.1); } /* App Layout Container */ main { flex: 1; overflow: hidden; position: relative; } .tab-content { display: none; height: 100%; padding: 16px; } .tab-content.active { display: flex; gap: 16px; } /* Sidebar for Chat History */ .history-sidebar { width: 280px; background: var(--panel-bg); backdrop-filter: blur(16px); border: 1px solid var(--panel-border); border-radius: 16px; padding: 16px; display: flex; flex-direction: column; gap: 12px; } .new-chat-btn { width: 100%; background: linear-gradient(90deg, #2563eb, #3b82f6); border: none; color: white; padding: 12px; border-radius: 10px; cursor: pointer; font-weight: 700; font-size: 0.95rem; display: flex; align-items: center; justify-content: center; gap: 8px; transition: all 0.2s; box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3); } .new-chat-btn:hover { opacity: 0.9; transform: translateY(-1px); } .history-list { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; padding-left: 4px; } .history-item { background: rgba(255,255,255,0.03); border: 1px solid transparent; padding: 10px 12px; border-radius: 8px; cursor: pointer; transition: all 0.2s; display: flex; justify-content: space-between; align-items: center; font-size: 0.88rem; color: var(--text-muted); } .history-item:hover, .history-item.active { background: rgba(59, 130, 246, 0.15); border-color: rgba(59, 130, 246, 0.4); color: var(--text-main); } .history-item .title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; } .history-item .delete-btn { opacity: 0; transition: opacity 0.2s; color: var(--danger); padding: 2px 6px; } .history-item:hover .delete-btn { opacity: 1; } /* Main Workspace & Chat Window */ .chat-main { flex: 1; display: flex; flex-direction: column; height: 100%; } .chat-container { flex: 1; overflow-y: auto; padding: 10px 10px 20px 10px; display: flex; flex-direction: column; gap: 20px; } .message { max-width: 85%; padding: 18px 22px; border-radius: 16px; line-height: 1.7; font-size: 0.98rem; word-wrap: break-word; box-shadow: 0 8px 20px rgba(0,0,0,0.3); backdrop-filter: blur(10px); } .message.user { align-self: flex-start; background: var(--user-msg); color: white; border-bottom-right-radius: 2px; } .message.model { align-self: flex-end; background: var(--ai-msg); border-bottom-left-radius: 2px; border: 1px solid var(--panel-border); } /* Analysis Box */ .analysis-box { background: var(--analysis-bg); border: 1px solid var(--analysis-border); border-radius: 12px; margin-bottom: 16px; overflow: hidden; } .analysis-header { padding: 12px 16px; background: rgba(99, 102, 241, 0.25); cursor: pointer; font-weight: 700; font-size: 0.92rem; color: #a5b4fc; display: flex; justify-content: space-between; align-items: center; } .analysis-content { padding: 16px; font-size: 0.9rem; color: #c7d2fe; display: none; border-top: 1px solid var(--analysis-border); white-space: pre-wrap; line-height: 1.6; } .analysis-box.open .analysis-content { display: block; } /* Controls & Input Panel */ .input-area { background: var(--panel-bg); backdrop-filter: blur(16px); padding: 16px; border: 1px solid var(--panel-border); border-radius: 16px; display: flex; flex-direction: column; gap: 12px; margin-top: 8px; } .controls-row { display: flex; justify-content: space-between; align-items: center; font-size: 0.88rem; color: var(--text-muted); flex-wrap: wrap; gap: 10px; } .input-wrapper { display: flex; gap: 10px; align-items: center; } textarea { flex: 1; background: rgba(7, 10, 18, 0.6); border: 1px solid var(--panel-border); color: var(--text-main); padding: 14px; border-radius: 12px; resize: none; height: 65px; outline: none; font-size: 0.98rem; transition: border 0.2s; } textarea:focus { border-color: var(--accent-glow); box-shadow: 0 0 10px rgba(56, 189, 248, 0.2); } .btn-action { background: linear-gradient(135deg, #3b82f6, #2563eb); border: none; color: white; padding: 0 24px; height: 65px; border-radius: 12px; cursor: pointer; font-weight: 700; font-size: 1.05rem; transition: all 0.2s; display: flex; align-items: center; justify-content: center; gap: 8px; } .btn-action:hover { box-shadow: 0 0 15px rgba(59, 130, 246, 0.5); } .btn-action:disabled { opacity: 0.5; cursor: not-allowed; } .btn-mic { background: rgba(255,255,255,0.05); border: 1px solid var(--panel-border); color: var(--text-main); width: 65px; height: 65px; border-radius: 12px; cursor: pointer; font-size: 1.3rem; transition: all 0.2s; display: flex; align-items: center; justify-content: center; } .btn-mic.recording { background: var(--danger); color: white; animation: pulse 1.2s infinite; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); } 70% { box-shadow: 0 0 0 12px rgba(239, 68, 68, 0); } 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); } } /* Code Block Enhancements */ .code-container { position: relative; margin: 14px 0; border-radius: 10px; overflow: hidden; border: 1px solid var(--panel-border); background: #131927; } .code-header { background: #1a2336; padding: 10px 16px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--panel-border); font-size: 0.85rem; color: var(--text-muted); } .code-actions { display: flex; gap: 8px; } .code-btn { background: rgba(255,255,255,0.06); border: 1px solid var(--panel-border); color: var(--text-main); padding: 5px 12px; border-radius: 6px; font-size: 0.82rem; cursor: pointer; transition: 0.2s; display: flex; align-items: center; gap: 6px; } .code-btn:hover { background: var(--accent-blue); color: white; } pre { margin: 0 !important; } pre code { font-family: 'Consolas', monospace !important; font-size: 0.94rem; padding: 16px !important; line-height: 1.5; } /* Settings Panels */ .settings-card { background: var(--panel-bg); backdrop-filter: blur(16px); padding: 24px; border-radius: 16px; border: 1px solid var(--panel-border); margin-bottom: 20px; width: 100%; max-width: 800px; } .settings-card h3 { margin-bottom: 14px; color: var(--accent-glow); display: flex; align-items: center; gap: 10px; } .input-field { width: 100%; padding: 12px 16px; background: rgba(7, 10, 18, 0.6); border: 1px solid var(--panel-border); color: var(--text-main); border-radius: 8px; margin-bottom: 14px; font-size: 0.95rem; } textarea.keys-input { height: 110px; font-family: monospace; direction: ltr; } select { background: rgba(7, 10, 18, 0.8); color: var(--text-main); border: 1px solid var(--panel-border); padding: 6px 12px; border-radius: 6px; outline: none; } </style> </head> <body> <header> <div class="logo"> <i class="fa-solid fa-headset"></i> <span>מומחה AI ימות המשיח</span> </div> <div class="tabs"> <button class="tab-btn active" onclick="switchTab('chatTab', event)"><i class="fa-solid fa-comments"></i> צ'אט וסביבת עבודה</button> <button class="tab-btn" onclick="switchTab('settingsTab', event)"><i class="fa-solid fa-sliders"></i> הגדרות וסנכרון מרכזיה</button> </div> </header> <main> <!-- Chat Tab with History Sidebar --> <div id="chatTab" class="tab-content active"> <!-- Sidebar for Recent Sessions --> <div class="history-sidebar"> <button class="new-chat-btn" onclick="createNewSession()"><i class="fa-solid fa-plus"></i> שיחה חדשה</button> <div style="font-size: 0.8rem; color: var(--text-muted); font-weight: bold; margin-top: 6px;">שיחות אחרונות</div> <div class="history-list" id="historyList"></div> </div> <!-- Main Chat Area --> <div class="chat-main"> <div class="chat-container" id="chatContainer"> <div class="message model"> שלום! אני עוזר ה-AI הבכיר שלך לבניית מרכזיות, שלוחות ו-Webhooks ב'ימות המשיח'.<br> המערכת מופעלת על ידי המודל החדש <b>gemini-3.6-flash</b>, כוללת שמירת היסטוריית שיחות מלאה ומחולל קול AI. </div> </div> <div class="input-area"> <div class="controls-row"> <div> <i class="fa-solid fa-robot"></i> מודל פעיל: <select id="modelSelect"></select> </div> <div> <label style="cursor: pointer;"> <input type="checkbox" id="deepAnalysisToggle" checked> דרוש ניתוח מעמיק (<analysis>) </label> </div> </div> <div class="input-wrapper"> <button class="btn-mic" id="micBtn" onclick="toggleVoiceInput()" title="הקלטה קולית בעברית"><i class="fa-solid fa-microphone"></i></button> <textarea id="userInput" placeholder="תאר את השלוחה או הבקשה שלך (או השתמש במיקרופון)..." onkeydown="handleKeyDown(event)"></textarea> <button class="btn-action" id="sendBtn" onclick="sendMessage()"><i class="fa-solid fa-paper-plane"></i> שלח</button> </div> </div> </div> </div> <!-- Settings Tab --> <div id="settingsTab" class="tab-content" style="flex-direction: column; overflow-y: auto;"> <div class="settings-card"> <h3><i class="fa-solid fa-key"></i> שרשור מפתחות API (Gemini Key Rotation)</h3> <textarea id="apiKeysInput" class="input-field keys-input" placeholder="הכנס מפתחות API (מפתח בכל שורה)..."></textarea> <button class="tab-btn active" onclick="saveKeys()"><i class="fa-solid fa-floppy-disk"></i> שמור מפתחות וטען מודלים</button> </div> <div class="settings-card"> <h3><i class="fa-solid fa-cloud-arrow-up"></i> חיבור ישיר ל-API ימות המשיח</h3> <input type="text" id="ymUsername" class="input-field" placeholder="מספר מערכת (System Username)"> <input type="password" id="ymPassword" class="input-field" placeholder="סיסמת מערכת (System Password)"> <button class="tab-btn active" onclick="saveYemotCredentials()"><i class="fa-solid fa-link"></i> שמור פרטי התחברות למערכת</button> </div> <div class="settings-card"> <h3><i class="fa-solid fa-file-zipper"></i> טעינת תיעוד ימות המשיח (ZIP Context)</h3> <input type="file" id="zipFileInput" accept=".zip" onchange="handleZipUpload(event)" style="margin-bottom: 10px;"> <div id="zipStatus"></div> </div> </div> </main> <script> const SYSTEM_INSTRUCTION = `אתה מתכנת בכיר ומומחה לשלוחות, מרכזיות ופיתוח ב'ימות המשיח'. תפקידך לבנות קובצי ext.ini מדויקים, תפריטי IVR, ושרתי Webhook. לרשותך מצורף קובץ ZIP המכיל את כל התיעוד וההגדרות של ימות המשיח. עליך להתבסס עליו באופן מוחלט בכל תשובה. הנחיות חובה: 1. אם המשתמש ביקש ניתוח מעמיק (או כברירת מחדל), עליך לפתוח את תגובתך בניתוח מקיף ומעמיק של הדרישה, הפורמט, הלוגיקה, והפרמטרים הנדרשים עטוף כולו בתוך תגיות <analysis> ו-</analysis>. 2. רק לאחר התגית הסוגרת </analysis> תציג את התשובה והקוד המלאים והסופיים. 3. הקפד על כתיבת קוד ext.ini תקני, כולל הערות והסברים ברורים בעברית.`; // App State let apiKeys = []; let zipBase64 = localStorage.getItem('yemot_zip_base64') || null; let sessions = []; let currentSessionId = null; let isRecording = false; let recognition = null; window.onload = async () => { loadKeys(); loadYemotCredentials(); initSpeechRecognition(); loadSessions(); if (zipBase64) { document.getElementById('zipStatus').innerHTML = '<span style="color:var(--success); font-weight:bold;">קובץ ה-ZIP טעון בזיכרון.</span>'; } if (apiKeys.length > 0) await fetchModels(); }; function switchTab(tabId, event) { document.querySelectorAll('.tab-content').forEach(el => el.classList.remove('active')); document.querySelectorAll('.tab-btn').forEach(el => el.classList.remove('active')); document.getElementById(tabId).classList.add('active'); if(event) event.currentTarget.classList.add('active'); } // --- Recent Chat Sessions History Engine --- function loadSessions() { const saved = localStorage.getItem('yemot_chat_sessions'); sessions = saved ? JSON.parse(saved) : []; if (sessions.length === 0) { createNewSession(); } else { currentSessionId = sessions[0].id; renderSessionsList(); renderCurrentSessionChat(); } } function saveSessions() { localStorage.setItem('yemot_chat_sessions', JSON.stringify(sessions)); renderSessionsList(); } function createNewSession() { const newSession = { id: Date.now().toString(), title: 'שיחה חדשה', timestamp: new Date().toLocaleTimeString('he-IL', {hour: '2-digit', minute:'2-digit'}), history: [] }; sessions.unshift(newSession); currentSessionId = newSession.id; saveSessions(); renderCurrentSessionChat(); } function switchSession(id) { currentSessionId = id; renderSessionsList(); renderCurrentSessionChat(); } function deleteSession(id, event) { event.stopPropagation(); sessions = sessions.filter(s => s.id !== id); if (sessions.length === 0) { createNewSession(); } else { if (currentSessionId === id) currentSessionId = sessions[0].id; saveSessions(); renderCurrentSessionChat(); } } function renderSessionsList() { const listEl = document.getElementById('historyList'); listEl.innerHTML = ''; sessions.forEach(s => { const item = document.createElement('div'); item.className = `history-item ${s.id === currentSessionId ? 'active' : ''}`; item.onclick = () => switchSession(s.id); item.innerHTML = ` <span class="title"><i class="fa-regular fa-message"></i> ${escapeHtml(s.title)}</span> <i class="fa-solid fa-trash delete-btn" onclick="deleteSession('${s.id}', event)" title="מחק שיחה"></i> `; listEl.appendChild(item); }); } function getCurrentSession() { return sessions.find(s => s.id === currentSessionId); } function renderCurrentSessionChat() { const container = document.getElementById('chatContainer'); container.innerHTML = ` <div class="message model"> שלום! אני עוזר ה-AI הבכיר שלך לבניית מרכזיות, שלוחות ו-Webhooks ב'ימות המשיח'.<br> המערכת מופעלת על ידי המודל החדש <b>gemini-3.6-flash</b>, כוללת שמירת היסטוריית שיחות מלאה ומחולל קול AI. </div>`; const session = getCurrentSession(); if (!session) return; session.history.forEach(msg => { if (msg.role === 'user') { const text = msg.parts.find(p => p.text)?.text || ''; appendMessageUI('user', text); } else if (msg.role === 'model') { const text = msg.parts[0].text; renderModelResponseUI(text); } }); } // --- Keys & Storage --- function loadKeys() { const saved = localStorage.getItem('gemini_api_keys'); if (saved) { apiKeys = JSON.parse(saved); document.getElementById('apiKeysInput').value = apiKeys.join('\n'); } } async function saveKeys() { const lines = document.getElementById('apiKeysInput').value.split('\n').map(k => k.trim()).filter(k => k.length > 0); apiKeys = lines; localStorage.setItem('gemini_api_keys', JSON.stringify(apiKeys)); alert('מפתחות ה-API נשמרו בהצלחה!'); await fetchModels(); } function saveYemotCredentials() { localStorage.setItem('ym_username', document.getElementById('ymUsername').value); localStorage.setItem('ym_password', document.getElementById('ymPassword').value); alert('פרטי החיבור לימות המשיח נשמרו בהצלחה!'); } function loadYemotCredentials() { document.getElementById('ymUsername').value = localStorage.getItem('ym_username') || ''; document.getElementById('ymPassword').value = localStorage.getItem('ym_password') || ''; } function handleZipUpload(event) { const file = event.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = function(e) { zipBase64 = e.target.result.split(',')[1]; try { localStorage.setItem('yemot_zip_base64', zipBase64); document.getElementById('zipStatus').innerHTML = `<span style="color:var(--success);">קובץ ${file.name} נשמר בהצלחה!</span>`; } catch (e) { document.getElementById('zipStatus').innerHTML = `<span style="color:var(--warning);">הקובץ טעון בזיכרון לשימוש נוכחי</span>`; } }; reader.readAsDataURL(file); } // --- API Rotation & Dynamic Model Fetching --- async function makeGeminiApiCall(fetchFunction) { if (apiKeys.length === 0) { alert('אנא הוסף לפחות מפתח API אחד בלשונית ההגדרות.'); switchTab('settingsTab'); throw new Error('No API keys configured'); } let lastError = null; for (let i = 0; i < apiKeys.length; i++) { try { return await fetchFunction(apiKeys[i]); } catch (err) { console.warn(`Key ${i + 1} failed, trying next...`, err); lastError = err; } } throw new Error(`כל המפתחות נכשלו: ${lastError?.message}`); } async function fetchModels() { try { const data = await makeGeminiApiCall(async (key) => { const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${key}`); return await res.json(); }); let models = data.models .filter(m => m.supportedGenerationMethods?.includes('generateContent')) .map(m => m.name.replace('models/', '')); // Guarantee gemini-3.6-flash as default option if (!models.includes('gemini-3.6-flash')) { models.unshift('gemini-3.6-flash'); } const select = document.getElementById('modelSelect'); select.innerHTML = ''; models.forEach(m => { const opt = document.createElement('option'); opt.value = m; opt.textContent = m; select.appendChild(opt); }); select.value = 'gemini-3.6-flash'; } catch(e) { console.error(e); const select = document.getElementById('modelSelect'); select.innerHTML = '<option value="gemini-3.6-flash">gemini-3.6-flash</option>'; } } // --- Voice Input (Mic) --- function initSpeechRecognition() { if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) { const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; recognition = new SpeechRecognition(); recognition.lang = 'he-IL'; recognition.onresult = (event) => { const transcript = event.results[0][0].transcript; const inputEl = document.getElementById('userInput'); inputEl.value += (inputEl.value ? ' ' : '') + transcript; toggleVoiceInput(); }; recognition.onerror = () => toggleVoiceInput(); } else { document.getElementById('micBtn').style.display = 'none'; } } function toggleVoiceInput() { if (!recognition) return; const micBtn = document.getElementById('micBtn'); if (!isRecording) { recognition.start(); isRecording = true; micBtn.classList.add('recording'); } else { recognition.stop(); isRecording = false; micBtn.classList.remove('recording'); } } // --- Chat Dispatching --- async function sendMessage() { const inputEl = document.getElementById('userInput'); const text = inputEl.value.trim(); if (!text) return; const sendBtn = document.getElementById('sendBtn'); const deepAnalysis = document.getElementById('deepAnalysisToggle').checked; const selectedModel = document.getElementById('modelSelect').value || 'gemini-3.6-flash'; const session = getCurrentSession(); if (session.history.length === 0) { session.title = text.substring(0, 25) + '...'; } appendMessageUI('user', text); inputEl.value = ''; sendBtn.disabled = true; let currentParts = []; if (zipBase64) { currentParts.push({ inline_data: { mime_type: "application/zip", data: zipBase64 } }); } let promptText = text; if (deepAnalysis) { promptText = `[הוראת חובה לניתוח מעמיק של הפורמט]: לפני מתן התשובה והקוד הסופיים, עליך לבצע ניתוח מקיף ומעמיק של הדרישה, הפורמט המבוקש (כגון ext.ini, HTML, Webhook, תפריטי IVR), לוגיקת הרכיבים, בדיקת קצה ומבנה הנתונים. חובה לעטוף את *כל* הניתוח המעמיק בתוך תגיות <analysis> ו-</analysis>. רק לאחר התגית הסוגרת </analysis> תציג את התשובה והקוד המלאים והסופיים. בקשת המשתמש: ${text}`; } currentParts.push({ text: promptText }); session.history.push({ role: 'user', parts: currentParts }); saveSessions(); const loadingDiv = appendMessageUI('model', '<i class="fa-solid fa-spinner fa-spin"></i> מעבד בקשה ומנתח תיעוד...'); try { const responseData = await makeGeminiApiCall(async (key) => { const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${selectedModel}:generateContent?key=${key}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ system_instruction: { parts: [{ text: SYSTEM_INSTRUCTION }] }, contents: session.history }) }); if (!res.ok) throw new Error(`HTTP ${res.status}`); return await res.json(); }); const replyText = responseData.candidates[0].content.parts[0].text; session.history.push({ role: 'model', parts: [{ text: replyText }] }); saveSessions(); loadingDiv.remove(); renderModelResponseUI(replyText); } catch (err) { loadingDiv.innerHTML = `<span style="color:var(--danger);"><i class="fa-solid fa-circle-exclamation"></i> שגיאה: ${err.message}</span>`; } finally { sendBtn.disabled = false; } } // Render Functions function renderModelResponseUI(text) { const container = document.getElementById('chatContainer'); const msgDiv = document.createElement('div'); msgDiv.className = 'message model'; let analysisHTML = ''; let mainContent = text; const analysisMatch = text.match(/<analysis>([\s\S]*?)<\/analysis>/); if (analysisMatch) { const analysisText = analysisMatch[1].trim(); mainContent = text.replace(/<analysis>[\s\S]*?<\/analysis>/, '').trim(); analysisHTML = ` <div class="analysis-box"> <div class="analysis-header" onclick="this.parentElement.classList.toggle('open')"> <span><i class="fa-solid fa-brain"></i> ניתוח מעמיק של הפורמט והלוגיקה (לחץ לפתיחה)</span> <i class="fa-solid fa-chevron-down"></i> </div> <div class="analysis-content">${escapeHtml(analysisText)}</div> </div> `; } msgDiv.innerHTML = analysisHTML + marked.parse(mainContent); container.appendChild(msgDiv); // Enhance Code Blocks msgDiv.querySelectorAll('pre code').forEach((codeBlock) => { const rawCode = codeBlock.innerText; const parentPre = codeBlock.parentNode; const wrapper = document.createElement('div'); wrapper.className = 'code-container'; const header = document.createElement('div'); header.className = 'code-header'; header.innerHTML = `<span><i class="fa-solid fa-code"></i> קוד תצורה (ext.ini)</span>`; const actions = document.createElement('div'); actions.className = 'code-actions'; const copyBtn = document.createElement('button'); copyBtn.className = 'code-btn'; copyBtn.innerHTML = '<i class="fa-solid fa-copy"></i> העתק'; copyBtn.onclick = () => { navigator.clipboard.writeText(rawCode); copyBtn.innerHTML = '<i class="fa-solid fa-check"></i> הועתק!'; setTimeout(() => copyBtn.innerHTML = '<i class="fa-solid fa-copy"></i> העתק', 2000); }; const dlBtn = document.createElement('button'); dlBtn.className = 'code-btn'; dlBtn.innerHTML = '<i class="fa-solid fa-download"></i> הורד ext.ini'; dlBtn.onclick = () => downloadCodeFile(rawCode, 'ext.ini'); const uploadBtn = document.createElement('button'); uploadBtn.className = 'code-btn'; uploadBtn.style.color = '#10b981'; uploadBtn.innerHTML = '<i class="fa-solid fa-cloud-arrow-up"></i> העלה למרכזיה'; uploadBtn.onclick = () => uploadDirectToYemot(rawCode); // Gemini Audio Generator const geminiTtsBtn = document.createElement('button'); geminiTtsBtn.className = 'code-btn'; geminiTtsBtn.style.color = '#38bdf8'; geminiTtsBtn.innerHTML = '<i class="fa-solid fa-wand-magic-sparkles"></i> שמע Gemini AI'; geminiTtsBtn.onclick = () => generateGeminiAudio(rawCode); actions.appendChild(copyBtn); actions.appendChild(dlBtn); actions.appendChild(geminiTtsBtn); actions.appendChild(uploadBtn); header.appendChild(actions); wrapper.appendChild(header); parentPre.parentNode.insertBefore(wrapper, parentPre); wrapper.appendChild(parentPre); hljs.highlightElement(codeBlock); }); container.scrollTop = container.scrollHeight; } // --- Gemini AI Voice Synthesis Engine --- async function generateGeminiAudio(code) { let textToRead = prompt('הכנס את הטקסט שברצונך שה-Gemini AI יקריא בקול רם:', 'ברוכים הבאים למערכת שלנו'); if (!textToRead) return; const selectedModel = document.getElementById('modelSelect').value || 'gemini-3.6-flash'; try { alert('מייצר קובץ שמע מבוסס Gemini AI, אנא המתן מעט...'); const responseData = await makeGeminiApiCall(async (key) => { const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${selectedModel}:generateContent?key=${key}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ contents: [{ parts: [{ text: `הקרא בקול רם, ברור וטבעי בעברית את הטקסט הבא עבור קובץ השמעה במרכזייה טלפונית:\n"${textToRead}"` }] }] }) }); return await res.json(); }); // Read synthesized speech or speak generated response const generatedText = responseData.candidates[0].content.parts[0].text; const utterance = new SpeechSynthesisUtterance(textToRead); utterance.lang = 'he-IL'; utterance.rate = 0.95; window.speechSynthesis.speak(utterance); } catch (err) { alert(`שגיאה ביצירת שמע: ${err.message}`); } } // Direct Yemot Push async function uploadDirectToYemot(code) { const username = localStorage.getItem('ym_username'); const password = localStorage.getItem('ym_password'); if (!username || !password) { alert('אנא הגדר פרטי התחברות לימות המשיח בלשונית ההגדרות.'); switchTab('settingsTab'); return; } const path = prompt('הכנס את נתיב השלוחה להעלאה (לדוגמה: 1/2 או 0 לראשית):', '1'); if (!path) return; try { const loginRes = await fetch(`https://www.call2all.co.il/ym/api/Login?username=${username}&password=${password}`); const loginData = await loginRes.json(); if (loginData.responseStatus !== 'OK') { throw new Error('התחברות למערכת ימות המשיח נכשלה.'); } const token = loginData.token; const formData = new FormData(); const blob = new Blob([code], { type: 'text/plain' }); formData.append('file', blob, 'ext.ini'); const uploadRes = await fetch(`https://www.call2all.co.il/ym/api/UploadFile?token=${token}&path=ivr2:${path}/ext.ini`, { method: 'POST', body: formData }); const uploadData = await uploadRes.json(); if (uploadData.responseStatus === 'OK') { alert(`הקוד הועלה בהצלחה לשלוחה ${path}!`); } else { alert(`שגיאה: ${uploadData.message || 'תקלה לא ידועה'}`); } } catch (err) { alert(`שגיאה: ${err.message}`); } } function downloadCodeFile(code, filename) { const blob = new Blob([code], { type: 'text/plain;charset=utf-8' }); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = filename; link.click(); } function appendMessageUI(role, htmlContent) { const container = document.getElementById('chatContainer'); const msgDiv = document.createElement('div'); msgDiv.className = `message ${role}`; msgDiv.innerHTML = htmlContent; container.appendChild(msgDiv); container.scrollTop = container.scrollHeight; return msgDiv; } function handleKeyDown(e) { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); } } function escapeHtml(text) { return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); } </script> </body> </html>כמו כן ניתן להוריד את הקובץ יש להוסיף את האות l בסוף הסיומת
עוזר AI מדויק עבור ימות המשיח.htm
-
L lavitoren הטי"ל התייחס לנושא זה
שלום! נראה שהשיחה הזו מעניינת אותך, אבל עדיין אין לך חשבון.
נמאס לכם לגלול בין אותם הפוסטים בכל ביקור? כשנרשמים לחשבון, תמיד תחזרו בדיוק למקום שבו הייתם קודם, ותוכלו לבחור לקבל התראות על תגובות חדשות (בין אם במייל, ובין אם בהתראת פוש). תוכלו גם לשמור סימניות ולפרגן ב-upvote לפוסטים כדי להביע הערכה לחברי קהילה אחרים.
בעזרת התרומה שלך, הפוסט הזה יכול להיות אפילו טוב יותר 💗
הרשמה התחברות