| @@ -71,14 +71,8 @@ | ||
| 71 | 71 | <strong>User Query:</strong> |
| 72 | 72 | <div id="last-query" class="query-display">Waiting for next query...</div> |
| 73 | 73 | </div> |
| 74 | 74 | <div class="mxchat-test-info"> |
| 75 | - <strong>Approved URLs for Citations:</strong> | |
| 76 | - <div class="mxchat-test-results approved-urls-container" id="approved-urls"> | |
| 77 | - <div class="no-data-message">No URL data yet</div> | |
| 78 | - </div> | |
| 79 | - </div> | |
| 80 | - <div class="mxchat-test-info"> | |
| 81 | 75 | <strong>Document Matches:</strong> |
| 82 | 76 | <div class="mxchat-test-results similarity-container" id="similarity-scores"> |
| 83 | 77 | <div class="no-data-message">No query data yet</div> |
| 84 | 78 | </div> |
| @@ -253,14 +247,10 @@ | ||
| 253 | 247 | this.log('📊 Chat data captured from response'); |
| 254 | 248 | |
| 255 | 249 | // Update query analysis section |
| 256 | 250 | this.updateLastQuery(testingData.query || 'No query', testingData.top_matches || []); |
| 251 | + this.updateTopMatches(testingData.top_matches || [], testingData.similarity_threshold || 0.75); | |
| 257 | 252 | |
| 258 | - // NEW: Update approved URLs | |
| 259 | - this.updateApprovedUrls(testingData.approved_urls || []); | |
| 260 | - | |
| 261 | - this.updateTopMatches(testingData.top_matches || [], testingData.similarity_threshold || 0.75, testingData.sources_used || 0, testingData.total_chunks_used || 0); | |
| 262 | - | |
| 263 | 253 | // NEW: Update action matches |
| 264 | 254 | this.updateActionMatches(testingData.action_matches || []); |
| 265 | 255 | |
| 266 | 256 | // Log additional info |
| @@ -270,13 +260,8 @@ | ||
| 270 | 260 | if (testingData.similarity_threshold) { |
| 271 | 261 | this.log(`🎯 Similarity Threshold: ${(testingData.similarity_threshold * 100)}%`); |
| 272 | 262 | } |
| 273 | 263 | |
| 274 | - // NEW: Log approved URLs count | |
| 275 | - if (testingData.approved_urls && testingData.approved_urls.length > 0) { | |
| 276 | - this.log(`🔗 Approved URLs for citations: ${testingData.approved_urls.length}`); | |
| 277 | - } | |
| 278 | - | |
| 279 | 264 | // Show summary in debug console |
| 280 | 265 | if (testingData.top_matches && testingData.top_matches.length > 0) { |
| 281 | 266 | const aboveThreshold = testingData.top_matches.filter(match => match.above_threshold).length; |
| 282 | 267 | const belowThreshold = testingData.top_matches.length - aboveThreshold; |
| @@ -301,50 +286,8 @@ | ||
| 301 | 286 | this.log('📝 No actions checked'); |
| 302 | 287 | } |
| 303 | 288 | } |
| 304 | 289 | |
| 305 | -updateApprovedUrls(approvedUrls) { | |
| 306 | - const urlsEl = this.panel.querySelector('#approved-urls'); | |
| 307 | - | |
| 308 | - // Safety check: ensure approvedUrls is an array | |
| 309 | - if (!approvedUrls || !Array.isArray(approvedUrls) || approvedUrls.length === 0) { | |
| 310 | - urlsEl.innerHTML = '<div class="no-data-message">No approved URLs (AI cannot cite links)</div>'; | |
| 311 | - return; | |
| 312 | - } | |
| 313 | - | |
| 314 | - let html = `<div class="urls-header"> | |
| 315 | - <strong>${approvedUrls.length} URL${approvedUrls.length !== 1 ? 's' : ''} approved for AI citations</strong> | |
| 316 | - </div>`; | |
| 317 | - | |
| 318 | - approvedUrls.forEach((url, index) => { | |
| 319 | - // Extract domain for display | |
| 320 | - let displayUrl = url; | |
| 321 | - try { | |
| 322 | - const urlObj = new URL(url); | |
| 323 | - displayUrl = urlObj.hostname + urlObj.pathname; | |
| 324 | - } catch (e) { | |
| 325 | - // Keep original if URL parsing fails | |
| 326 | - } | |
| 327 | - | |
| 328 | - html += ` | |
| 329 | - <div class="url-card"> | |
| 330 | - <div class="url-line"> | |
| 331 | - <span class="url-icon">🔗</span> | |
| 332 | - <a href="${url}" target="_blank" rel="noopener noreferrer" class="url-link" title="${url}"> | |
| 333 | - ${displayUrl} | |
| 334 | - </a> | |
| 335 | - </div> | |
| 336 | - </div> | |
| 337 | - `; | |
| 338 | - }); | |
| 339 | - | |
| 340 | - html += `<div class="urls-note"> | |
| 341 | - ℹ️ The AI can only cite these URLs. Any other URLs will be automatically removed from responses. | |
| 342 | - </div>`; | |
| 343 | - | |
| 344 | - urlsEl.innerHTML = html; | |
| 345 | -} | |
| 346 | - | |
| 347 | 290 | updateActionMatches(actionMatches) { |
| 348 | 291 | const actionsEl = this.panel.querySelector('#action-scores'); |
| 349 | 292 | |
| 350 | 293 | if (!actionMatches || actionMatches.length === 0) { |
| @@ -391,144 +334,60 @@ | ||
| 391 | 334 | |
| 392 | 335 | actionsEl.innerHTML = html; |
| 393 | 336 | } |
| 394 | 337 | |
| 395 | - updateTopMatches(topMatches, threshold, sourcesUsed = 0, totalChunksUsed = 0) { | |
| 338 | + updateTopMatches(topMatches, threshold) { | |
| 396 | 339 | const scoresEl = this.panel.querySelector('#similarity-scores'); |
| 397 | - | |
| 340 | + | |
| 398 | 341 | if (!topMatches || topMatches.length === 0) { |
| 399 | 342 | scoresEl.innerHTML = '<div class="no-data-message">No similarity data available</div>'; |
| 400 | 343 | return; |
| 401 | 344 | } |
| 402 | - | |
| 403 | - // Group matches by source URL | |
| 404 | - const groupedByUrl = {}; | |
| 405 | - topMatches.forEach((match) => { | |
| 406 | - const url = match.source_display || 'Unknown'; | |
| 407 | - if (!groupedByUrl[url]) { | |
| 408 | - groupedByUrl[url] = { | |
| 409 | - url: url, | |
| 410 | - isUrl: url.startsWith('http'), | |
| 411 | - bestScore: 0, | |
| 412 | - usedForContext: false, | |
| 413 | - totalChunks: match.total_chunks || 1, | |
| 414 | - matchedChunks: [], | |
| 415 | - isChunked: match.is_chunk || false | |
| 416 | - }; | |
| 417 | - } | |
| 418 | - | |
| 419 | - // Track best score | |
| 420 | - if (match.similarity_percentage > groupedByUrl[url].bestScore) { | |
| 421 | - groupedByUrl[url].bestScore = match.similarity_percentage; | |
| 422 | - } | |
| 423 | - | |
| 424 | - // Track if any chunk was used for context | |
| 425 | - if (match.used_for_context) { | |
| 426 | - groupedByUrl[url].usedForContext = true; | |
| 427 | - } | |
| 428 | - | |
| 429 | - // Add chunk info | |
| 430 | - groupedByUrl[url].matchedChunks.push({ | |
| 431 | - chunkIndex: match.chunk_index, | |
| 432 | - score: match.similarity_percentage, | |
| 433 | - usedForContext: match.used_for_context, | |
| 434 | - aboveThreshold: match.above_threshold | |
| 435 | - }); | |
| 436 | - }); | |
| 437 | - | |
| 438 | - // Convert to array and sort by best score | |
| 439 | - const urlGroups = Object.values(groupedByUrl).sort((a, b) => b.bestScore - a.bestScore); | |
| 440 | - | |
| 441 | - // Use backend counts if available, otherwise fall back to frontend calculation | |
| 442 | - const usedUrlCount = sourcesUsed > 0 ? sourcesUsed : urlGroups.filter(g => g.usedForContext).length; | |
| 443 | - const chunksInfo = totalChunksUsed > 0 ? `${totalChunksUsed} chunks sent to AI` : `${topMatches.length} chunk matches`; | |
| 444 | - | |
| 345 | + | |
| 445 | 346 | let html = `<div class="matches-header"> |
| 446 | - <strong>${usedUrlCount} source${usedUrlCount === 1 ? '' : 's'} used for AI context</strong> | |
| 447 | - <span class="matches-subheader">(${chunksInfo})</span> | |
| 347 | + <strong>Top ${topMatches.length} matches</strong> | |
| 448 | 348 | </div>`; |
| 449 | - | |
| 450 | - urlGroups.forEach((group, groupIndex) => { | |
| 451 | - const cardClass = group.usedForContext ? 'above-threshold' : 'below-threshold'; | |
| 452 | - const statusIcon = group.usedForContext ? '✓' : '✗'; | |
| 453 | - const contextLabel = group.usedForContext ? 'Used for AI context' : 'Not used'; | |
| 454 | - | |
| 455 | - // Build chunk summary | |
| 456 | - let chunkSummary = ''; | |
| 457 | - if (group.isChunked && group.totalChunks > 1) { | |
| 458 | - const usedChunkCount = group.matchedChunks.filter(c => c.usedForContext).length; | |
| 459 | - chunkSummary = `<span class="chunk-summary">${usedChunkCount}/${group.totalChunks} chunks matched</span>`; | |
| 349 | + | |
| 350 | + topMatches.forEach((match, index) => { | |
| 351 | + const isAboveThreshold = match.above_threshold; | |
| 352 | + const isUsedForContext = match.used_for_context; // Use the actual flag from PHP | |
| 353 | + const statusIcon = isAboveThreshold ? '✓' : '✗'; | |
| 354 | + | |
| 355 | + // Determine the correct label based on actual usage | |
| 356 | + let contextLabel; | |
| 357 | + if (isUsedForContext) { | |
| 358 | + contextLabel = 'Used for AI context'; | |
| 359 | + } else if (isAboveThreshold) { | |
| 360 | + contextLabel = 'Above threshold (not used)'; | |
| 361 | + } else { | |
| 362 | + contextLabel = 'Below threshold'; | |
| 460 | 363 | } |
| 461 | - | |
| 462 | - // Check if this entry has multiple matched chunks to show expand toggle | |
| 463 | - const hasMultipleChunks = group.matchedChunks.length > 1; | |
| 464 | - const expandToggle = hasMultipleChunks | |
| 465 | - ? `<span class="chunk-expand-toggle" data-group="${groupIndex}">▶ Show chunks</span>` | |
| 466 | - : ''; | |
| 467 | - | |
| 364 | + | |
| 365 | + // Determine card styling - should be based on whether it was actually used | |
| 366 | + const cardClass = isUsedForContext ? 'above-threshold' : 'below-threshold'; | |
| 367 | + | |
| 468 | 368 | html += ` |
| 469 | 369 | <div class="match-card ${cardClass}"> |
| 470 | 370 | <div class="match-header"> |
| 471 | 371 | <div class="match-title"> |
| 472 | 372 | <span class="status-icon">${statusIcon}</span> |
| 473 | - <span class="similarity-score">${group.bestScore}%</span> | |
| 474 | - ${chunkSummary} | |
| 373 | + <span class="similarity-score">${match.similarity_percentage}%</span> | |
| 475 | 374 | </div> |
| 476 | 375 | <span class="context-label">${contextLabel}</span> |
| 477 | 376 | </div> |
| 478 | 377 | <div class="match-source"> |
| 479 | - ${group.isUrl ? | |
| 480 | - `<span class="source-icon link-icon">🔗</span> ${group.url}` : | |
| 481 | - `<span class="source-icon doc-icon">📄</span> ${group.url}` | |
| 378 | + ${match.source_display.startsWith('http') ? | |
| 379 | + `<span class="source-icon link-icon">🔗</span> ${match.source_display}` : | |
| 380 | + `<span class="source-icon doc-icon">📄</span> ${match.source_display}` | |
| 482 | 381 | } |
| 483 | 382 | </div> |
| 484 | - ${expandToggle} | |
| 485 | - ${hasMultipleChunks ? this.renderChunkDetails(group.matchedChunks, groupIndex) : ''} | |
| 486 | 383 | </div> |
| 487 | 384 | `; |
| 488 | 385 | }); |
| 489 | - | |
| 386 | + | |
| 490 | 387 | scoresEl.innerHTML = html; |
| 491 | - | |
| 492 | - // Add click handlers for expand toggles | |
| 493 | - scoresEl.querySelectorAll('.chunk-expand-toggle').forEach(toggle => { | |
| 494 | - toggle.addEventListener('click', (e) => { | |
| 495 | - const groupId = e.target.dataset.group; | |
| 496 | - const details = scoresEl.querySelector(`.chunk-details[data-group="${groupId}"]`); | |
| 497 | - if (details) { | |
| 498 | - const isExpanded = details.classList.toggle('expanded'); | |
| 499 | - e.target.textContent = isExpanded ? '▼ Hide chunks' : '▶ Show chunks'; | |
| 500 | - } | |
| 501 | - }); | |
| 502 | - }); | |
| 503 | 388 | } |
| 504 | 389 | |
| 505 | - renderChunkDetails(chunks, groupIndex) { | |
| 506 | - // Sort chunks by chunk index | |
| 507 | - const sortedChunks = [...chunks].sort((a, b) => (a.chunkIndex || 0) - (b.chunkIndex || 0)); | |
| 508 | - | |
| 509 | - let html = `<div class="chunk-details" data-group="${groupIndex}">`; | |
| 510 | - | |
| 511 | - sortedChunks.forEach(chunk => { | |
| 512 | - const chunkNum = (chunk.chunkIndex !== null && chunk.chunkIndex !== undefined) | |
| 513 | - ? chunk.chunkIndex + 1 | |
| 514 | - : '?'; | |
| 515 | - const statusClass = chunk.usedForContext ? 'chunk-used' : 'chunk-not-used'; | |
| 516 | - const statusIcon = chunk.usedForContext ? '✓' : '○'; | |
| 517 | - | |
| 518 | - html += ` | |
| 519 | - <div class="chunk-detail-row ${statusClass}"> | |
| 520 | - <span class="chunk-detail-icon">${statusIcon}</span> | |
| 521 | - <span class="chunk-detail-num">Chunk ${chunkNum}</span> | |
| 522 | - <span class="chunk-detail-score">${chunk.score}%</span> | |
| 523 | - </div> | |
| 524 | - `; | |
| 525 | - }); | |
| 526 | - | |
| 527 | - html += '</div>'; | |
| 528 | - return html; | |
| 529 | - } | |
| 530 | - | |
| 531 | 390 | updateLastQuery(query, topMatches) { |
| 532 | 391 | const queryEl = this.panel.querySelector('#last-query'); |
| 533 | 392 | queryEl.textContent = query; |
| 534 | 393 | |
| @@ -539,49 +398,28 @@ | ||
| 539 | 398 | }; |
| 540 | 399 | } |
| 541 | 400 | |
| 542 | 401 | clearChatSession() { |
| 543 | - // Determine the active bot ID from MxChatInstances | |
| 544 | - let botId = 'default'; | |
| 545 | - if (typeof MxChatInstances !== 'undefined' && typeof MxChatInstances.getAllBotIds === 'function') { | |
| 546 | - const botIds = MxChatInstances.getAllBotIds(); | |
| 547 | - if (botIds.length > 0) { | |
| 548 | - botId = botIds[0]; | |
| 549 | - } | |
| 550 | - } | |
| 551 | - | |
| 552 | - // Get current session ID using the correct bot-suffixed cookie name | |
| 553 | - const cookieName = 'mxchat_session_id_' + botId; | |
| 554 | - const sessionId = this.getCookie(cookieName) || this.getCookie('mxchat_session_id') || this.getCurrentSessionId(); | |
| 555 | - | |
| 402 | + // Get current session ID from cookie (most reliable) | |
| 403 | + const sessionId = this.getCookie('mxchat_session_id') || this.getCurrentSessionId(); | |
| 404 | + | |
| 556 | 405 | if (!sessionId) { |
| 557 | - this.log('No active session found'); | |
| 406 | + this.log('❌ No active session found'); | |
| 558 | 407 | return; |
| 559 | 408 | } |
| 560 | - | |
| 561 | - this.log('Current session ID: ' + sessionId); | |
| 562 | - this.log('Starting fresh session...'); | |
| 563 | - | |
| 564 | - // Use MxChatInstances.resetChatSession to properly reset in-memory state + cookie | |
| 565 | - if (typeof MxChatInstances !== 'undefined' && typeof MxChatInstances.resetChatSession === 'function') { | |
| 566 | - MxChatInstances.resetChatSession(botId); | |
| 567 | - } | |
| 568 | - | |
| 569 | - // Get the new session ID that was just set by resetChatSession | |
| 570 | - let newSessionId = ''; | |
| 571 | - if (typeof MxChatInstances !== 'undefined' && typeof MxChatInstances.getChatSession === 'function') { | |
| 572 | - newSessionId = MxChatInstances.getChatSession(botId); | |
| 573 | - } | |
| 574 | - | |
| 575 | - // Fallback if MxChatInstances wasn't available | |
| 576 | - if (!newSessionId) { | |
| 577 | - newSessionId = 'mxchat_chat_' + Math.random().toString(36).substr(2, 9); | |
| 578 | - this.clearMxChatCookie(botId); | |
| 579 | - this.setChatSession(newSessionId, botId); | |
| 580 | - } | |
| 581 | - | |
| 582 | - this.log('New session ID: ' + newSessionId); | |
| 583 | - | |
| 409 | + | |
| 410 | + this.log(`🔍 Current session ID: ${sessionId}`); | |
| 411 | + this.log('🧹 Starting fresh session...'); | |
| 412 | + | |
| 413 | + // Generate new session ID (using your existing format) | |
| 414 | + const newSessionId = 'mxchat_chat_' + Math.random().toString(36).substr(2, 9); | |
| 415 | + | |
| 416 | + // Clear the old cookie and set new one immediately | |
| 417 | + this.clearMxChatCookie(); | |
| 418 | + this.setChatSession(newSessionId); | |
| 419 | + | |
| 420 | + this.log(`🆕 New session ID: ${newSessionId}`); | |
| 421 | + | |
| 584 | 422 | // Call backend to clear old session data |
| 585 | 423 | fetch(mxchatTestData.ajaxUrl, { |
| 586 | 424 | method: 'POST', |
| 587 | 425 | headers: { |
| @@ -596,36 +434,35 @@ | ||
| 596 | 434 | }) |
| 597 | 435 | .then(response => response.json()) |
| 598 | 436 | .then(data => { |
| 599 | 437 | if (data.success) { |
| 600 | - this.log('Backend session cleared: ' + data.data.message); | |
| 601 | - | |
| 438 | + this.log('✅ Backend session cleared: ' + data.data.message); | |
| 439 | + | |
| 602 | 440 | // Update the session ID everywhere in the DOM |
| 603 | 441 | this.updateSessionIdEverywhere(newSessionId); |
| 604 | - | |
| 442 | + | |
| 605 | 443 | // Clear the chat UI |
| 606 | 444 | this.clearChatUI(); |
| 607 | - | |
| 445 | + | |
| 608 | 446 | // Show popular questions again |
| 609 | 447 | const popularQuestions = document.querySelector('#mxchat-popular-questions'); |
| 610 | 448 | if (popularQuestions) { |
| 611 | 449 | popularQuestions.style.display = 'block'; |
| 612 | 450 | } |
| 613 | - | |
| 451 | + | |
| 614 | 452 | // Clear testing data displays |
| 615 | 453 | this.updateLastQuery('New session started', []); |
| 616 | 454 | this.updateTopMatches([], 0); |
| 617 | - this.updateApprovedUrls([]); | |
| 618 | - | |
| 619 | - this.log('Fresh session started successfully'); | |
| 620 | - | |
| 455 | + | |
| 456 | + this.log('🎉 Fresh session started successfully'); | |
| 457 | + | |
| 621 | 458 | } else { |
| 622 | - this.log('Error clearing session: ' + (data.data?.message || 'Unknown error')); | |
| 459 | + this.log('❌ Error clearing session: ' + (data.data?.message || 'Unknown error')); | |
| 623 | 460 | } |
| 624 | 461 | }) |
| 625 | 462 | .catch(error => { |
| 626 | 463 | console.error('Error clearing chat session:', error); |
| 627 | - this.log('Connection error when clearing session'); | |
| 464 | + this.log('🔌 Connection error when clearing session'); | |
| 628 | 465 | }); |
| 629 | 466 | } |
| 630 | 467 | |
| 631 | 468 | // Helper function to get cookie (same as your existing one) |
| @@ -634,21 +471,19 @@ | ||
| 634 | 471 | let parts = value.split("; " + name + "="); |
| 635 | 472 | if (parts.length == 2) return parts.pop().split(";").shift(); |
| 636 | 473 | } |
| 637 | 474 | |
| 638 | - // Helper function to set session cookie (matches chat-script.js format) | |
| 639 | - setChatSession(sessionId, botId) { | |
| 640 | - botId = botId || 'default'; | |
| 641 | - document.cookie = 'mxchat_session_id_' + botId + '=' + sessionId + '; path=/; max-age=86400; SameSite=Lax'; | |
| 475 | + // Helper function to set session cookie (same as your existing one) | |
| 476 | + setChatSession(sessionId) { | |
| 477 | + // Set the cookie with a 24-hour expiration (86400 seconds) | |
| 478 | + document.cookie = "mxchat_session_id=" + sessionId + "; path=/; max-age=86400; SameSite=Lax"; | |
| 642 | 479 | } |
| 643 | 480 | |
| 644 | 481 | // Helper function to clear the MxChat session cookie |
| 645 | - clearMxChatCookie(botId) { | |
| 646 | - botId = botId || 'default'; | |
| 647 | - // Clear both bot-suffixed and legacy cookie formats | |
| 648 | - document.cookie = 'mxchat_session_id_' + botId + '=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax'; | |
| 649 | - document.cookie = 'mxchat_session_id=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax'; | |
| 650 | - this.log('Session cookie cleared'); | |
| 482 | + clearMxChatCookie() { | |
| 483 | + // Clear the cookie by setting it to expire in the past | |
| 484 | + document.cookie = "mxchat_session_id=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax"; | |
| 485 | + this.log('🍪 Session cookie cleared'); | |
| 651 | 486 | } |
| 652 | 487 | |
| 653 | 488 | updateSessionIdEverywhere(newSessionId) { |
| 654 | 489 | // Update global session ID variable if it exists |
| @@ -707,23 +542,9 @@ | ||
| 707 | 542 | } |
| 708 | 543 | } |
| 709 | 544 | |
| 710 | 545 | getCurrentSessionId() { |
| 711 | - // Try MxChatInstances first (most reliable — matches chat-script.js) | |
| 712 | - if (typeof MxChatInstances !== 'undefined' && typeof MxChatInstances.getChatSession === 'function') { | |
| 713 | - const botIds = typeof MxChatInstances.getAllBotIds === 'function' ? MxChatInstances.getAllBotIds() : ['default']; | |
| 714 | - const botId = botIds.length > 0 ? botIds[0] : 'default'; | |
| 715 | - const instanceSession = MxChatInstances.getChatSession(botId); | |
| 716 | - if (instanceSession) { | |
| 717 | - return instanceSession; | |
| 718 | - } | |
| 719 | - } | |
| 720 | - | |
| 721 | - // Try bot-suffixed cookie, then legacy cookie | |
| 722 | - const botCookieId = this.getCookie('mxchat_session_id_default'); | |
| 723 | - if (botCookieId) { | |
| 724 | - return botCookieId; | |
| 725 | - } | |
| 546 | + // First try to get from cookie (most reliable) | |
| 726 | 547 | const cookieSessionId = this.getCookie('mxchat_session_id'); |
| 727 | 548 | if (cookieSessionId) { |
| 728 | 549 | return cookieSessionId; |
| 729 | 550 | } |
| @@ -784,63 +605,36 @@ | ||
| 784 | 605 | }); |
| 785 | 606 | } |
| 786 | 607 | |
| 787 | 608 | updateSystemPrompt() { |
| 788 | - const promptEl = this.panel.querySelector('#system-prompt'); | |
| 789 | - promptEl.textContent = 'Loading system prompt...'; | |
| 790 | - | |
| 791 | - fetch(mxchatTestData.ajaxUrl, { | |
| 792 | - method: 'POST', | |
| 793 | - headers: { | |
| 794 | - 'Content-Type': 'application/x-www-form-urlencoded', | |
| 795 | - }, | |
| 796 | - body: new URLSearchParams({ | |
| 797 | - action: 'mxchat_get_system_info', | |
| 798 | - nonce: mxchatTestData.nonce | |
| 609 | + const promptEl = this.panel.querySelector('#system-prompt'); | |
| 610 | + promptEl.textContent = 'Loading system prompt...'; | |
| 611 | + | |
| 612 | + fetch(mxchatTestData.ajaxUrl, { | |
| 613 | + method: 'POST', | |
| 614 | + headers: { | |
| 615 | + 'Content-Type': 'application/x-www-form-urlencoded', | |
| 616 | + }, | |
| 617 | + body: new URLSearchParams({ | |
| 618 | + action: 'mxchat_get_system_info', | |
| 619 | + nonce: mxchatTestData.nonce | |
| 620 | + }) | |
| 799 | 621 | }) |
| 800 | - }) | |
| 801 | - .then(response => response.json()) | |
| 802 | - .then(data => { | |
| 803 | - if (data.success) { | |
| 804 | - promptEl.textContent = data.data.system_prompt || 'No system prompt configured'; | |
| 805 | - | |
| 806 | - // Enhanced model display with OpenRouter support | |
| 807 | - if (data.data.is_openrouter) { | |
| 808 | - this.log(`🤖 Model: OpenRouter`); | |
| 809 | - this.log(` └─ Using: ${data.data.openrouter_model}`); | |
| 810 | - } else { | |
| 622 | + .then(response => response.json()) | |
| 623 | + .then(data => { | |
| 624 | + if (data.success) { | |
| 625 | + promptEl.textContent = data.data.system_prompt || 'No system prompt configured'; | |
| 811 | 626 | this.log(`🤖 Model: ${data.data.selected_model}`); |
| 812 | - } | |
| 813 | - | |
| 814 | - // Enhanced API status with OpenRouter | |
| 815 | - const apiStatus = data.data.api_status; | |
| 816 | - const configuredApis = Object.keys(apiStatus).filter(key => apiStatus[key]); | |
| 817 | - | |
| 818 | - if (configuredApis.length > 0) { | |
| 819 | - this.log(`🔑 Configured APIs: ${configuredApis.map(api => { | |
| 820 | - // Capitalize and format API names | |
| 821 | - if (api === 'openai') return 'OpenAI'; | |
| 822 | - if (api === 'xai') return 'X.AI'; | |
| 823 | - if (api === 'openrouter') return 'OpenRouter'; | |
| 824 | - return api.charAt(0).toUpperCase() + api.slice(1); | |
| 825 | - }).join(', ')}`); | |
| 627 | + this.log(`🔑 API Status: ${JSON.stringify(data.data.api_status)}`); | |
| 826 | 628 | } else { |
| 827 | - this.log(`⚠️ No API keys configured`); | |
| 629 | + promptEl.textContent = 'Error loading system prompt'; | |
| 828 | 630 | } |
| 829 | - | |
| 830 | - // Specific warning for OpenRouter if selected but no key | |
| 831 | - if (data.data.is_openrouter && !apiStatus.openrouter) { | |
| 832 | - this.log(`❌ WARNING: OpenRouter selected but no API key configured!`); | |
| 833 | - } | |
| 834 | - } else { | |
| 835 | - promptEl.textContent = 'Error loading system prompt'; | |
| 836 | - } | |
| 837 | - }) | |
| 838 | - .catch(error => { | |
| 839 | - console.error('Error fetching system info:', error); | |
| 840 | - promptEl.textContent = 'Connection error'; | |
| 841 | - }); | |
| 842 | -} | |
| 631 | + }) | |
| 632 | + .catch(error => { | |
| 633 | + console.error('Error fetching system info:', error); | |
| 634 | + promptEl.textContent = 'Connection error'; | |
| 635 | + }); | |
| 636 | + } | |
| 843 | 637 | |
| 844 | 638 | updateKnowledgeBaseStatus() { |
| 845 | 639 | const statusEl = this.panel.querySelector('#kb-status'); |
| 846 | 640 | statusEl.innerHTML = 'Checking...'; |