diff --git a/application/single_app/config.py b/application/single_app/config.py
index 624ae367..0f46400c 100644
--- a/application/single_app/config.py
+++ b/application/single_app/config.py
@@ -94,7 +94,7 @@
EXECUTOR_TYPE = 'thread'
EXECUTOR_MAX_WORKERS = 30
SESSION_TYPE = 'filesystem'
-VERSION = "0.241.002"
+VERSION = "0.241.004"
SECRET_KEY = os.getenv('SECRET_KEY', 'dev-secret-key-change-in-production')
diff --git a/application/single_app/functions_settings.py b/application/single_app/functions_settings.py
index fe1f9b3e..324f82fc 100644
--- a/application/single_app/functions_settings.py
+++ b/application/single_app/functions_settings.py
@@ -262,7 +262,7 @@ def get_settings(use_cosmos=False, include_source=False):
'enable_conversation_archiving': False,
# Processing Thoughts
- 'enable_thoughts': False,
+ 'enable_thoughts': True,
# Search and Extract
'azure_ai_search_endpoint': '',
diff --git a/application/single_app/functions_thoughts.py b/application/single_app/functions_thoughts.py
index b7721253..7d20441b 100644
--- a/application/single_app/functions_thoughts.py
+++ b/application/single_app/functions_thoughts.py
@@ -25,7 +25,7 @@ def __init__(self, conversation_id, message_id, thread_id, user_id):
self.user_id = user_id
self.current_index = 0
settings = get_settings()
- self.enabled = settings.get('enable_thoughts', False)
+ self.enabled = settings.get('enable_thoughts', True)
def add_thought(self, step_type, content, detail=None):
"""Write a thought step to Cosmos immediately.
diff --git a/application/single_app/route_backend_thoughts.py b/application/single_app/route_backend_thoughts.py
index bab0fd9a..69aed271 100644
--- a/application/single_app/route_backend_thoughts.py
+++ b/application/single_app/route_backend_thoughts.py
@@ -21,7 +21,7 @@ def api_get_message_thoughts(conversation_id, message_id):
return jsonify({'error': 'User not authenticated'}), 401
settings = get_settings()
- if not settings.get('enable_thoughts', False):
+ if not settings.get('enable_thoughts', True):
return jsonify({'thoughts': [], 'enabled': False}), 200
try:
@@ -59,7 +59,7 @@ def api_get_pending_thoughts(conversation_id):
return jsonify({'error': 'User not authenticated'}), 401
settings = get_settings()
- if not settings.get('enable_thoughts', False):
+ if not settings.get('enable_thoughts', True):
return jsonify({'thoughts': [], 'enabled': False}), 200
try:
diff --git a/application/single_app/templates/profile.html b/application/single_app/templates/profile.html
index 87985b55..42826cde 100644
--- a/application/single_app/templates/profile.html
+++ b/application/single_app/templates/profile.html
@@ -135,52 +135,6 @@
animation: spin 1s linear infinite;
}
- .preference-card-icon {
- align-items: center;
- background: linear-gradient(135deg, rgba(13, 110, 253, 0.12), rgba(13, 202, 240, 0.18));
- border-radius: 14px;
- color: var(--bs-primary);
- display: inline-flex;
- font-size: 1.25rem;
- height: 52px;
- justify-content: center;
- width: 52px;
- }
-
- .preference-status {
- min-height: 1.5rem;
- }
-
- .fact-memory-summary-card {
- background: linear-gradient(135deg, rgba(13, 110, 253, 0.08), rgba(13, 202, 240, 0.12));
- border: 1px solid rgba(13, 110, 253, 0.14);
- border-radius: 16px;
- padding: 1.25rem;
- }
-
- .fact-memory-count {
- font-size: 2rem;
- font-weight: 700;
- line-height: 1;
- }
-
- .fact-memory-modal-list {
- max-height: 55vh;
- overflow-y: auto;
- }
-
- .fact-memory-modal-card {
- border: 1px solid var(--bs-border-color);
- border-radius: 14px;
- padding: 1rem;
- background: var(--bs-body-bg);
- }
-
- .fact-memory-pagination-summary {
- min-height: 1.5rem;
- }
-
-
.preference-card-icon {
align-items: center;
background: linear-gradient(135deg, rgba(13, 110, 253, 0.12), rgba(13, 202, 240, 0.18));
@@ -498,117 +452,6 @@
Fact Memory
-
-
-
-
-
-
-
-
Tutorial Preferences
-
Control whether the floating guided tutorial buttons appear on Chat and Personal Workspace for your account.
-
These launchers are shown by default. You can hide them now and turn them back on later from this page.
-
-
- {% if app_settings.enable_support_menu and app_settings.enable_support_latest_features and app_settings.support_latest_features_has_visible_items %}
-
- View Latest Feature Notes
-
- {% endif %}
-
-
-
-
-
-
-
- Show tutorial buttons on Chat and Personal Workspace
-
- Turn this off if you already know the interface and want to remove the floating walkthrough launchers.
-
-
-
-
- Save Tutorial Preference
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Fact Memory
-
Save durable facts for your account, then manage the full memory list from a compact popup editor.
- {% if app_settings.enable_fact_memory_plugin %}
-
Enabled by admin
-
Supported chat and mini-SK flows can use these memories when fact memory is enabled.
- {% else %}
-
Disabled by admin
-
You can still manage saved memories here. They will stay inactive until an administrator turns fact memory back on.
- {% endif %}
-
-
-
-
-
-
-
Add a memory
-
-
-
- Memory type
-
- Instruction: always apply to future responses
- Fact: recall only when relevant
-
-
-
-
Use instruction memories for durable preferences like tone or formatting. Use fact memories for details about you that the model should recall only when relevant.
-
- Add Memory
-
-
-
-
-
-
Saved Memories
-
0
-
No memories saved yet.
-
0 instructions, 0 facts
-
-
-
- Manage Memories
-
-
- Refresh
-
-
-
Use the popup editor for search, paging, and updates.
-
-
-
-
-
-
-
{% if app_settings.enable_retention_policy_personal %}
@@ -961,88 +804,6 @@
-
-
-
-
-
-
Delete this saved memory? This cannot be undone, and supported chats will stop receiving it immediately.
-
-
-
-
-
-
-
-
@@ -1117,16 +878,6 @@
let pendingFactMemoryDeleteId = null;
let factMemoryDeleteModalInstance = null;
let factMemoryManagerModalInstance = null;
-let factMemoryEntries = [];
-let filteredFactMemoryEntries = [];
-let factMemoryCurrentPage = 1;
-const FACT_MEMORY_PAGE_SIZE = 5;
-const FACT_MEMORY_TYPE_INSTRUCTION = 'instruction';
-const FACT_MEMORY_TYPE_FACT = 'fact';
-const FACT_MEMORY_TYPE_LEGACY_DESCRIBER = 'describer';
-let pendingFactMemoryDeleteId = null;
-let factMemoryDeleteModalInstance = null;
-let factMemoryManagerModalInstance = null;
console.log('Profile page script loaded - preparing to initialize');
@@ -1229,43 +980,6 @@
});
}
- const nextPageButton = document.getElementById('fact-memory-next-page');
- if (nextPageButton) {
- nextPageButton.addEventListener('click', function() {
- const totalPages = Math.max(1, Math.ceil(filteredFactMemoryEntries.length / FACT_MEMORY_PAGE_SIZE));
- if (factMemoryCurrentPage < totalPages) {
- factMemoryCurrentPage += 1;
- renderFactMemoryModalList();
- }
- });
- }
-
- const factMemorySearchInput = document.getElementById('fact-memory-search-input');
- if (factMemorySearchInput) {
- factMemorySearchInput.addEventListener('input', function() {
- factMemoryCurrentPage = 1;
- renderFactMemoryModalList();
- });
- }
-
- const factMemoryTypeFilter = document.getElementById('fact-memory-type-filter');
- if (factMemoryTypeFilter) {
- factMemoryTypeFilter.addEventListener('change', function() {
- factMemoryCurrentPage = 1;
- renderFactMemoryModalList();
- });
- }
-
- const previousPageButton = document.getElementById('fact-memory-prev-page');
- if (previousPageButton) {
- previousPageButton.addEventListener('click', function() {
- if (factMemoryCurrentPage > 1) {
- factMemoryCurrentPage -= 1;
- renderFactMemoryModalList();
- }
- });
- }
-
const nextPageButton = document.getElementById('fact-memory-next-page');
if (nextPageButton) {
nextPageButton.addEventListener('click', function() {
@@ -1875,545 +1589,6 @@
});
}
-function updateTutorialPreferenceStatus(message, type = 'muted') {
- const statusElement = document.getElementById('tutorial-preference-status');
- if (!statusElement) {
- return;
- }
-
- const classMap = {
- muted: 'text-muted',
- info: 'text-info',
- success: 'text-success',
- danger: 'text-danger'
- };
-
- statusElement.textContent = message || '';
- statusElement.className = `preference-status small mt-3 ${classMap[type] || classMap.muted}`;
-}
-
-function updateFactMemoryStatus(message, type = 'muted') {
- const statusElement = document.getElementById('fact-memory-status');
- if (!statusElement) {
- return;
- }
-
- const classMap = {
- muted: 'text-muted',
- info: 'text-info',
- success: 'text-success',
- danger: 'text-danger'
- };
-
- statusElement.textContent = message || '';
- statusElement.className = `preference-status small mt-3 ${classMap[type] || classMap.muted}`;
-}
-
-function formatFactMemoryTimestamp(value) {
- if (!value) {
- return 'Unknown time';
- }
-
- const parsedDate = new Date(value);
- if (Number.isNaN(parsedDate.getTime())) {
- return value;
- }
-
- return parsedDate.toLocaleString();
-}
-
-function formatFactMemoryDate(value) {
- if (!value) {
- return 'Unknown date';
- }
-
- const parsedDate = new Date(value);
- if (Number.isNaN(parsedDate.getTime())) {
- return value;
- }
-
- return parsedDate.toLocaleDateString();
-}
-
-function normalizeFactMemoryType(memoryType) {
- if (memoryType === FACT_MEMORY_TYPE_INSTRUCTION) {
- return FACT_MEMORY_TYPE_INSTRUCTION;
- }
- if (memoryType === FACT_MEMORY_TYPE_LEGACY_DESCRIBER) {
- return FACT_MEMORY_TYPE_FACT;
- }
- return FACT_MEMORY_TYPE_FACT;
-}
-
-function getFactMemoryTypeLabel(memoryType) {
- return normalizeFactMemoryType(memoryType) === FACT_MEMORY_TYPE_INSTRUCTION ? 'Instruction' : 'Fact';
-}
-
-function getFactMemoryTypeBadgeClass(memoryType) {
- return normalizeFactMemoryType(memoryType) === FACT_MEMORY_TYPE_INSTRUCTION ? 'bg-primary-subtle text-primary-emphasis' : 'bg-secondary-subtle text-secondary-emphasis';
-}
-
-function buildFactMemoryMetaText(fact) {
- return `${getFactMemoryTypeLabel(fact.memory_type)} memory · Updated ${formatFactMemoryDate(fact.updated_at)}`;
-}
-
-function updateFactMemorySummary() {
- const countElement = document.getElementById('fact-memory-count');
- const updatedElement = document.getElementById('fact-memory-last-updated');
- const typeSummaryElement = document.getElementById('fact-memory-type-summary');
- const modalSummaryElement = document.getElementById('fact-memory-modal-summary');
- const instructionCount = factMemoryEntries.filter((fact) => normalizeFactMemoryType(fact.memory_type) === FACT_MEMORY_TYPE_INSTRUCTION).length;
- const factCount = factMemoryEntries.length - instructionCount;
-
- if (countElement) {
- countElement.textContent = String(factMemoryEntries.length);
- }
-
- if (updatedElement) {
- if (!factMemoryEntries.length) {
- updatedElement.textContent = 'No memories saved yet.';
- } else {
- updatedElement.textContent = `Last updated ${formatFactMemoryDate(factMemoryEntries[0].updated_at)}.`;
- }
- }
-
- if (typeSummaryElement) {
- typeSummaryElement.textContent = `${instructionCount} instruction${instructionCount === 1 ? '' : 's'}, ${factCount} fact${factCount === 1 ? '' : 's'}`;
- }
-
- if (modalSummaryElement) {
- modalSummaryElement.textContent = `${filteredFactMemoryEntries.length} matching mem${filteredFactMemoryEntries.length === 1 ? 'ory' : 'ories'} · ${instructionCount} instruction${instructionCount === 1 ? '' : 's'} · ${factCount} fact${factCount === 1 ? '' : 's'}`;
- }
-}
-
-function getFilteredFactMemoryEntries() {
- const searchInput = document.getElementById('fact-memory-search-input');
- const typeFilter = document.getElementById('fact-memory-type-filter');
- const query = searchInput ? searchInput.value.trim().toLowerCase() : '';
- const selectedType = typeFilter ? typeFilter.value : 'all';
-
- return factMemoryEntries.filter((fact) => {
- const value = String(fact.value || '').toLowerCase();
- const memoryType = normalizeFactMemoryType(fact.memory_type);
- const matchesQuery = !query || value.includes(query) || memoryType.includes(query);
- const matchesType = selectedType === 'all' || memoryType === selectedType;
- return matchesQuery && matchesType;
- });
-}
-
-function renderFactMemoryModalList() {
- const listElement = document.getElementById('fact-memory-modal-list');
- const emptyState = document.getElementById('fact-memory-modal-empty-state');
- const paginationSummary = document.getElementById('fact-memory-pagination-summary');
- const previousPageButton = document.getElementById('fact-memory-prev-page');
- const nextPageButton = document.getElementById('fact-memory-next-page');
- if (!listElement || !emptyState) {
- return;
- }
-
- filteredFactMemoryEntries = getFilteredFactMemoryEntries();
- const totalPages = Math.max(1, Math.ceil(filteredFactMemoryEntries.length / FACT_MEMORY_PAGE_SIZE));
- if (factMemoryCurrentPage > totalPages) {
- factMemoryCurrentPage = totalPages;
- }
-
- const startIndex = (factMemoryCurrentPage - 1) * FACT_MEMORY_PAGE_SIZE;
- const endIndex = startIndex + FACT_MEMORY_PAGE_SIZE;
- const currentPageItems = filteredFactMemoryEntries.slice(startIndex, endIndex);
-
- listElement.innerHTML = '';
-
- if (!filteredFactMemoryEntries.length) {
- emptyState.classList.remove('d-none');
- if (paginationSummary) {
- paginationSummary.textContent = 'No results';
- }
- if (previousPageButton) {
- previousPageButton.disabled = true;
- }
- if (nextPageButton) {
- nextPageButton.disabled = true;
- }
- updateFactMemorySummary();
- return;
- }
-
- emptyState.classList.add('d-none');
- if (paginationSummary) {
- paginationSummary.textContent = `Page ${factMemoryCurrentPage} of ${totalPages}`;
- }
- if (previousPageButton) {
- previousPageButton.disabled = factMemoryCurrentPage <= 1;
- }
- if (nextPageButton) {
- nextPageButton.disabled = factMemoryCurrentPage >= totalPages;
- }
-
- currentPageItems.forEach((fact) => {
- const itemContainer = document.createElement('div');
- itemContainer.className = 'fact-memory-modal-card';
- itemContainer.dataset.factMemoryId = fact.id;
-
- const headerRow = document.createElement('div');
- headerRow.className = 'd-flex flex-column flex-md-row justify-content-between align-items-md-center gap-2 mb-2';
-
- const typeBadge = document.createElement('span');
- typeBadge.className = `badge ${getFactMemoryTypeBadgeClass(fact.memory_type)}`;
- typeBadge.textContent = getFactMemoryTypeLabel(fact.memory_type);
-
- const typeSelect = document.createElement('select');
- typeSelect.className = 'form-select form-select-sm';
- typeSelect.id = `fact-memory-type-${fact.id}`;
- typeSelect.style.maxWidth = '220px';
- typeSelect.setAttribute('aria-label', 'Fact memory type');
-
- const instructionOption = document.createElement('option');
- instructionOption.value = FACT_MEMORY_TYPE_INSTRUCTION;
- instructionOption.textContent = 'Instruction';
-
- const factOption = document.createElement('option');
- factOption.value = FACT_MEMORY_TYPE_FACT;
- factOption.textContent = 'Fact';
-
- typeSelect.appendChild(instructionOption);
- typeSelect.appendChild(factOption);
- typeSelect.value = normalizeFactMemoryType(fact.memory_type);
- typeSelect.addEventListener('change', () => {
- typeBadge.className = `badge ${getFactMemoryTypeBadgeClass(typeSelect.value)}`;
- typeBadge.textContent = getFactMemoryTypeLabel(typeSelect.value);
- });
-
- headerRow.appendChild(typeBadge);
- headerRow.appendChild(typeSelect);
-
- const textArea = document.createElement('textarea');
- textArea.className = 'form-control';
- textArea.id = `fact-memory-value-${fact.id}`;
- textArea.rows = 3;
- textArea.value = fact.value || '';
- textArea.setAttribute('aria-label', 'Fact memory value');
-
- const metaText = document.createElement('div');
- metaText.className = 'small text-muted mt-2';
- metaText.textContent = buildFactMemoryMetaText(fact);
-
- const actions = document.createElement('div');
- actions.className = 'd-flex flex-wrap gap-2 mt-3';
-
- const saveButton = document.createElement('button');
- saveButton.type = 'button';
- saveButton.className = 'btn btn-primary btn-sm';
- saveButton.setAttribute('aria-label', 'Save memory');
- saveButton.innerHTML = ' Save';
- saveButton.addEventListener('click', () => saveFactMemory(fact.id));
-
- const deleteButton = document.createElement('button');
- deleteButton.type = 'button';
- deleteButton.className = 'btn btn-outline-danger btn-sm';
- deleteButton.setAttribute('aria-label', 'Delete memory');
- deleteButton.innerHTML = ' Delete';
- deleteButton.addEventListener('click', () => requestFactMemoryDelete(fact.id));
-
- actions.appendChild(saveButton);
- actions.appendChild(deleteButton);
-
- itemContainer.appendChild(headerRow);
- itemContainer.appendChild(textArea);
- itemContainer.appendChild(metaText);
- itemContainer.appendChild(actions);
- listElement.appendChild(itemContainer);
- });
-
- updateFactMemorySummary();
-}
-
-function openFactMemoryModal() {
- const modalElement = document.getElementById('factMemoryManagerModal');
- if (!modalElement || typeof bootstrap === 'undefined') {
- return;
- }
-
- if (!factMemoryManagerModalInstance) {
- factMemoryManagerModalInstance = new bootstrap.Modal(modalElement);
- }
-
- factMemoryCurrentPage = 1;
- renderFactMemoryModalList();
- factMemoryManagerModalInstance.show();
-}
-
-async function loadFactMemory() {
- const refreshButton = document.getElementById('fact-memory-refresh-btn');
- const originalButtonHtml = refreshButton ? refreshButton.innerHTML : '';
- if (refreshButton) {
- refreshButton.disabled = true;
- refreshButton.innerHTML = ' Loading...';
- }
-
- updateFactMemoryStatus('Loading saved fact memories...', 'info');
-
- try {
- const response = await fetch('/api/profile/fact-memory');
- const data = await response.json();
- if (!response.ok) {
- throw new Error(data.error || 'Failed to load fact memory');
- }
-
- factMemoryEntries = (Array.isArray(data.facts) ? data.facts : []).map((fact) => ({
- ...fact,
- memory_type: normalizeFactMemoryType(fact.memory_type)
- }));
- factMemoryCurrentPage = 1;
- renderFactMemoryModalList();
-
- const enabledBadge = document.getElementById('fact-memory-enabled-badge');
- if (enabledBadge) {
- enabledBadge.textContent = data.enabled ? 'Enabled by admin' : 'Disabled by admin';
- enabledBadge.className = `badge ${data.enabled ? 'bg-success' : 'bg-secondary'}`;
- }
-
- updateFactMemoryStatus(
- data.enabled
- ? 'Fact memory is enabled for supported chats and mini-SK analysis.'
- : 'Fact memory is currently disabled by admin. You can still edit your saved memories here.',
- 'muted'
- );
- } catch (error) {
- console.error('Error loading fact memory:', error);
- updateFactMemoryStatus('Unable to load fact memory right now. Please try again.', 'danger');
- } finally {
- if (refreshButton) {
- refreshButton.disabled = false;
- refreshButton.innerHTML = originalButtonHtml;
- }
- }
-}
-
-async function createFactMemory() {
- const textArea = document.getElementById('fact-memory-new-value');
- const typeSelect = document.getElementById('fact-memory-new-type');
- const addButton = document.getElementById('fact-memory-add-btn');
- if (!textArea || !typeSelect || !addButton) {
- return;
- }
-
- const value = textArea.value.trim();
- const memoryType = normalizeFactMemoryType(typeSelect.value);
- if (!value) {
- updateFactMemoryStatus('Enter a memory before saving.', 'danger');
- return;
- }
-
- const originalButtonHtml = addButton.innerHTML;
- addButton.disabled = true;
- addButton.innerHTML = ' Saving...';
- updateFactMemoryStatus('Saving new fact memory...', 'info');
-
- try {
- const response = await fetch('/api/profile/fact-memory', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify({ value, memory_type: memoryType })
- });
- const data = await response.json();
- if (!response.ok) {
- throw new Error(data.error || 'Failed to create fact memory');
- }
-
- textArea.value = '';
- typeSelect.value = FACT_MEMORY_TYPE_FACT;
- await loadFactMemory();
- updateFactMemoryStatus('Fact memory saved.', 'success');
- if (typeof showToastMessage === 'function') {
- showToastMessage('Fact memory saved successfully', 'success');
- }
- } catch (error) {
- console.error('Error creating fact memory:', error);
- updateFactMemoryStatus(error.message || 'Failed to save fact memory.', 'danger');
- } finally {
- addButton.disabled = false;
- addButton.innerHTML = originalButtonHtml;
- }
-}
-
-async function saveFactMemory(factId) {
- const textArea = document.getElementById(`fact-memory-value-${factId}`);
- const typeSelect = document.getElementById(`fact-memory-type-${factId}`);
- const itemContainer = document.querySelector(`[data-fact-memory-id="${factId}"]`);
- if (!textArea || !typeSelect || !itemContainer) {
- return;
- }
-
- const value = textArea.value.trim();
- const memoryType = normalizeFactMemoryType(typeSelect.value);
- if (!value) {
- updateFactMemoryStatus('Memory text cannot be empty.', 'danger');
- return;
- }
-
- const saveButton = itemContainer.querySelector('button[aria-label="Save memory"]');
- const originalButtonHtml = saveButton ? saveButton.innerHTML : '';
- if (saveButton) {
- saveButton.disabled = true;
- saveButton.innerHTML = ' Saving...';
- }
-
- updateFactMemoryStatus('Updating fact memory...', 'info');
-
- try {
- const response = await fetch(`/api/profile/fact-memory/${encodeURIComponent(factId)}`, {
- method: 'PUT',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify({ value, memory_type: memoryType })
- });
- const data = await response.json();
- if (!response.ok) {
- throw new Error(data.error || 'Failed to update fact memory');
- }
-
- await loadFactMemory();
- updateFactMemoryStatus('Fact memory updated.', 'success');
- if (typeof showToastMessage === 'function') {
- showToastMessage('Fact memory updated successfully', 'success');
- }
- } catch (error) {
- console.error('Error updating fact memory:', error);
- updateFactMemoryStatus(error.message || 'Failed to update fact memory.', 'danger');
- } finally {
- if (saveButton) {
- saveButton.disabled = false;
- saveButton.innerHTML = originalButtonHtml;
- }
- }
-}
-
-function requestFactMemoryDelete(factId) {
- pendingFactMemoryDeleteId = factId;
- const modalElement = document.getElementById('factMemoryDeleteModal');
- if (!modalElement || typeof bootstrap === 'undefined') {
- return;
- }
-
- if (!factMemoryDeleteModalInstance) {
- factMemoryDeleteModalInstance = new bootstrap.Modal(modalElement);
- }
-
- factMemoryDeleteModalInstance.show();
-}
-
-async function confirmDeleteFactMemory() {
- if (!pendingFactMemoryDeleteId) {
- return;
- }
-
- const deleteButton = document.getElementById('confirm-delete-fact-memory-btn');
- const originalButtonHtml = deleteButton ? deleteButton.innerHTML : '';
- if (deleteButton) {
- deleteButton.disabled = true;
- deleteButton.innerHTML = ' Deleting...';
- }
-
- updateFactMemoryStatus('Deleting fact memory...', 'info');
-
- try {
- const response = await fetch(`/api/profile/fact-memory/${encodeURIComponent(pendingFactMemoryDeleteId)}`, {
- method: 'DELETE'
- });
- const data = await response.json();
- if (!response.ok) {
- throw new Error(data.error || 'Failed to delete fact memory');
- }
-
- if (factMemoryDeleteModalInstance) {
- factMemoryDeleteModalInstance.hide();
- }
- pendingFactMemoryDeleteId = null;
- await loadFactMemory();
- updateFactMemoryStatus('Fact memory deleted.', 'success');
- if (typeof showToastMessage === 'function') {
- showToastMessage('Fact memory deleted successfully', 'success');
- }
- } catch (error) {
- console.error('Error deleting fact memory:', error);
- updateFactMemoryStatus(error.message || 'Failed to delete fact memory.', 'danger');
- } finally {
- if (deleteButton) {
- deleteButton.disabled = false;
- deleteButton.innerHTML = originalButtonHtml;
- }
- }
-}
-
-function loadTutorialPreferences() {
- const toggle = document.getElementById('show-tutorial-buttons-toggle');
- if (!toggle) {
- return;
- }
-
- fetch('/api/user/settings')
- .then(response => response.json())
- .then(data => {
- toggle.checked = data.settings?.showTutorialButtons !== false;
- updateTutorialPreferenceStatus('Tutorial launchers are shown by default until you change this setting.');
- })
- .catch(error => {
- console.error('Error loading tutorial preferences:', error);
- updateTutorialPreferenceStatus('Unable to refresh tutorial preference from the server. The current page state is still shown.', 'danger');
- });
-}
-
-function saveTutorialPreferences() {
- const toggle = document.getElementById('show-tutorial-buttons-toggle');
- const button = document.getElementById('save-tutorial-preferences-btn');
- if (!toggle || !button) {
- return;
- }
-
- const originalHtml = button.innerHTML;
- button.disabled = true;
- button.innerHTML = ' Saving...';
- updateTutorialPreferenceStatus('Saving your tutorial preference...', 'info');
-
- fetch('/api/user/settings', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify({
- settings: {
- showTutorialButtons: toggle.checked
- }
- })
- })
- .then(response => {
- if (!response.ok) {
- throw new Error('Failed to save tutorial preference');
- }
-
- return response.json();
- })
- .then(() => {
- const message = toggle.checked
- ? 'Tutorial buttons will stay visible on Chat and Personal Workspace.'
- : 'Tutorial buttons are now hidden for your account. You can turn them back on here any time.';
-
- updateTutorialPreferenceStatus(message, 'success');
- showToastMessage('Tutorial preference saved successfully', 'success');
- })
- .catch(error => {
- console.error('Error saving tutorial preference:', error);
- updateTutorialPreferenceStatus('Failed to save tutorial preference. Please try again.', 'danger');
- })
- .finally(() => {
- button.disabled = false;
- button.innerHTML = originalHtml;
- });
-}
-
function loadActivityChartData() {
// Fetch activity trends data
fetch('/api/user/activity-trends?days=30')
diff --git a/docs/_data/latest_release_features.yml b/docs/_data/latest_release_features.yml
new file mode 100644
index 00000000..cf347855
--- /dev/null
+++ b/docs/_data/latest_release_features.yml
@@ -0,0 +1,441 @@
+current_release:
+ label: "Current Release Features"
+ description: "These guides map to the feature set currently highlighted in the app for end users."
+ badge: "Shared in the app"
+ slugs:
+ - guided-tutorials
+ - background-chat
+ - gpt-selection
+ - tabular-analysis
+ - citation-improvements
+ - document-versioning
+ - summaries-and-export
+ - agent-operations
+ - ai-transparency
+ - fact-memory
+ - deployment
+ - redis-and-key-vault
+ - send-feedback
+ - support-menu
+
+previous_release_groups:
+ - label: "Previous Release Features"
+ description: "The earlier v0.239.001 release guides remain available for reference."
+ badge: "Earlier release"
+ release_version: "0.239.001"
+ slugs:
+ - export-conversation
+ - retention-policy
+ - workspace-scope-lock
+ - tags-grid-view-chat-filtering
+ highlights:
+ - "Owner-only group agent management lets admins restrict group agent and action edits to group owners."
+ - "Multi-workspace scope management expanded grounded chat across personal, group, and public sources."
+ - "Tag folders, grid view, and chat filtering shipped together as one broader workspace workflow upgrade."
+ bug_fixes:
+ - "Citation parsing fixes resolved edge cases where page range references failed to create the right clickable links."
+ - "Public workspace activation fixed a 403 path for non-owner users activating a public workspace for chat."
+
+lookup:
+ guided-tutorials:
+ title: "Guided Tutorials"
+ description: "How guided walkthroughs help users learn chat and workspace flows inside the app"
+ summary: "Step-by-step walkthroughs help users discover core chat, workspace, and onboarding flows in context instead of hunting through the interface first."
+ why: "The fastest way to learn a new workflow is usually inside the workflow itself, with the right controls highlighted as you go."
+ icon: "bi-signpost-split"
+ accent: "blue"
+ url: "/latest-release/guided-tutorials/"
+ release_label: "Current Release"
+ image: "/images/latest-release/guided_tutorials_chat.png"
+ image_alt: "Guided chat tutorial screenshot"
+ images:
+ - path: "/images/latest-release/guided_tutorials_chat.png"
+ alt: "Guided chat tutorial screenshot"
+ title: "Guided Chat Tutorial"
+ caption: "Guided walkthrough entry point for the live chat experience."
+ label: "Chat Tutorial"
+ - path: "/images/latest-release/guided_tutorials_workspace.png"
+ alt: "Workspace guided tutorial screenshot"
+ title: "Guided Workspace Tutorial"
+ caption: "Walkthrough entry point for Personal Workspace uploads, filters, tools, and tags."
+ label: "Workspace Tutorial"
+
+ background-chat:
+ title: "Background Chat"
+ description: "How long-running chat requests can finish in the background while you keep working"
+ summary: "Long-running chat requests can finish after you leave the chat page, so larger prompts and uploads stop blocking the rest of your work."
+ why: "Long-running work no longer makes the app feel blocked while the assistant is still processing."
+ icon: "bi-hourglass-split"
+ accent: "teal"
+ url: "/latest-release/background-chat/"
+ release_label: "Current Release"
+ image: "/images/latest-release/background_completion_notifications-01.png"
+ image_alt: "Background completion notification screenshot"
+ images:
+ - path: "/images/latest-release/background_completion_notifications-01.png"
+ alt: "Background completion notification screenshot"
+ title: "Background Completion Notification"
+ caption: "Notification example showing that a chat response completed after the user moved away."
+ label: "Completion Notification"
+ - path: "/images/latest-release/background_completion_notifications-02.png"
+ alt: "Background completion deep link screenshot"
+ title: "Notification Deep Link"
+ caption: "Notification detail showing how users can jump back into the finished chat result."
+ label: "Return to Finished Chat"
+
+ gpt-selection:
+ title: "GPT Selection"
+ description: "How users can choose among available GPT models for different tasks"
+ summary: "Visible model selection helps users match a task to the right tradeoff in speed, cost, and reasoning depth when multiple options are available."
+ why: "Different prompts often need different tradeoffs, so a clearer picker makes model choice practical instead of hidden."
+ icon: "bi-sliders2"
+ accent: "violet"
+ url: "/latest-release/gpt-selection/"
+ release_label: "Current Release"
+ image: "/images/latest-release/model_selection_chat_selector.png"
+ image_alt: "User chat model selector screenshot"
+ images:
+ - path: "/images/latest-release/model_selection_chat_selector.png"
+ alt: "User chat model selector screenshot"
+ title: "User Chat Model Selector"
+ caption: "Chat composer model selector showing multiple available GPT choices."
+ label: "Chat Model Selector"
+ - path: "/images/latest-release/model_selection_multi_endpoint_admin.png"
+ alt: "Admin multi-endpoint model management screenshot"
+ title: "Admin Multi-Endpoint Model Management"
+ caption: "Admin endpoint table showing configured Azure OpenAI and Foundry model endpoints."
+ label: "Admin Endpoint Table"
+
+ tabular-analysis:
+ title: "Tabular Analysis"
+ description: "How CSV and spreadsheet workflows support grounded exploration and follow-up analysis"
+ summary: "CSV and spreadsheet workflows keep getting stronger for grounded exploration, filtering, and follow-up analysis against real rows and columns."
+ why: "Table-heavy questions are more useful when users can explore filters and follow-ups without losing provenance."
+ icon: "bi-table"
+ accent: "emerald"
+ url: "/latest-release/tabular-analysis/"
+ release_label: "Current Release"
+ image: "/images/latest-release/tabular_analysis_enhanced_citations.png"
+ image_alt: "Tabular analysis enhanced citations screenshot"
+ images:
+ - path: "/images/latest-release/tabular_analysis_enhanced_citations.png"
+ alt: "Tabular analysis enhanced citations screenshot"
+ title: "Tabular Analysis with Enhanced Citations"
+ caption: "Tabular analysis preview showing the improved citation-backed experience for spreadsheet content."
+ label: "Tabular Analysis Preview"
+
+ citation-improvements:
+ title: "Citation Improvements"
+ description: "How enhanced citations improve source traceability and follow-up grounding"
+ summary: "Enhanced citations improve source traceability, document previews, and history-aware grounding so users can inspect where answers came from."
+ why: "Traceable answers are easier to trust, revisit, and defend in follow-up conversations."
+ icon: "bi-journal-richtext"
+ accent: "amber"
+ url: "/latest-release/citation-improvements/"
+ release_label: "Current Release"
+ image: "/images/latest-release/citation_improvements_history_replay.png"
+ image_alt: "Conversation history citation replay screenshot"
+ images:
+ - path: "/images/latest-release/citation_improvements_history_replay.png"
+ alt: "Conversation history citation replay screenshot"
+ title: "Conversation History Citation Replay"
+ caption: "Follow-up chat where prior citation summaries are replayed into the next turn's reasoning context."
+ label: "History Citation Replay"
+ - path: "/images/latest-release/citation_improvements_amplified_results.png"
+ alt: "Citation amplification details screenshot"
+ title: "Citation Amplification Details"
+ caption: "Expanded citation detail showing amplified supporting evidence and fuller artifact-backed results."
+ label: "Amplified Citation Detail"
+
+ document-versioning:
+ title: "Document Versioning"
+ description: "How same-name uploads become revisions so users can work with the right document version"
+ summary: "Same-name uploads now behave like revisions, making it easier to keep document history visible instead of silently replacing useful versions."
+ why: "Revision-aware documents keep history available when teams need to compare or verify what changed."
+ icon: "bi-clock-history"
+ accent: "rose"
+ url: "/latest-release/document-versioning/"
+ release_label: "Current Release"
+ image: "/images/latest-release/document_revision_workspace.png"
+ image_alt: "Document revision workspace screenshot"
+ images:
+ - path: "/images/latest-release/document_revision_workspace.png"
+ alt: "Document revision workspace screenshot"
+ title: "Current Revision in Workspace"
+ caption: "Workspace document list showing the current revision state for same-name uploads."
+ label: "Current Revision View"
+ - path: "/images/latest-release/document_revision_delete_compare.png"
+ alt: "Document revision actions and comparison screenshot"
+ title: "Revision Actions and Comparison"
+ caption: "Version-aware actions such as comparison, analysis of previous revisions, or current-versus-all-versions deletion choices."
+ label: "Revision Actions"
+
+ summaries-and-export:
+ title: "Summaries and Export"
+ description: "How conversation summaries and export actions help users reuse and share chat content"
+ summary: "Conversation summaries and export actions keep expanding so users can package, review, and share useful chat outcomes more quickly."
+ why: "People reuse chat outcomes faster when they can summarize and package them for someone else without manual cleanup."
+ icon: "bi-box-arrow-down"
+ accent: "orange"
+ url: "/latest-release/summaries-and-export/"
+ release_label: "Current Release"
+ image: "/images/latest-release/conversation_summary_card.png"
+ image_alt: "Conversation summary card screenshot"
+ images:
+ - path: "/images/latest-release/conversation_summary_card.png"
+ alt: "Conversation summary card screenshot"
+ title: "Conversation Summary Card"
+ caption: "Conversation summary panel preview in the chat experience."
+ label: "Summary Card"
+ - path: "/images/latest-release/pdf_export_option.png"
+ alt: "PDF export option screenshot"
+ title: "PDF Export Option"
+ caption: "PDF export entry in the conversation export workflow."
+ label: "PDF Export"
+ - path: "/images/latest-release/per_message_export_menu.png"
+ alt: "Per-message export menu screenshot"
+ title: "Per-Message Export Menu"
+ caption: "Expanded per-message export and reuse actions."
+ label: "Per-Message Actions"
+
+ agent-operations:
+ title: "Agent Operations"
+ description: "How agent and action workflows are easier to browse, manage, and validate"
+ summary: "Agent creation, organization, and operational controls keep getting smoother for teams that rely on more advanced agent and action scenarios."
+ why: "Advanced agent setups are easier to adopt when browsing, defaults, and validation are clearer."
+ icon: "bi-diagram-3"
+ accent: "cyan"
+ url: "/latest-release/agent-operations/"
+ release_label: "Current Release"
+ image: "/images/latest-release/agent_action_grid_view.png"
+ image_alt: "Agent and action grid view screenshot"
+ images:
+ - path: "/images/latest-release/agent_action_grid_view.png"
+ alt: "Agent and action grid view screenshot"
+ title: "Agent and Action Grid View"
+ caption: "Grid browsing experience for agents and actions."
+ label: "Grid View"
+ - path: "/images/latest-release/sql_test_connection.png"
+ alt: "SQL test connection screenshot"
+ title: "SQL Test Connection"
+ caption: "Inline SQL connection test preview before save."
+ label: "SQL Test Connection"
+
+ ai-transparency:
+ title: "AI Transparency"
+ description: "How processing-thought visibility gives users clearer feedback during response generation"
+ summary: "Thought and reasoning transparency options give users clearer feedback about what the assistant is doing while a response is being prepared."
+ why: "Visible processing cues reduce uncertainty while the system is working and make delays easier to interpret."
+ icon: "bi-eye"
+ accent: "blue"
+ url: "/latest-release/ai-transparency/"
+ release_label: "Current Release"
+ image: "/images/latest-release/thoughts_visibility.png"
+ image_alt: "Processing thoughts visibility screenshot"
+ images:
+ - path: "/images/latest-release/thoughts_visibility.png"
+ alt: "Processing thoughts visibility screenshot"
+ title: "Processing Thoughts Visibility"
+ caption: "Processing thoughts state and timing details preview."
+ label: "Processing Thoughts"
+
+ fact-memory:
+ title: "Fact Memory"
+ description: "How Instructions and Facts help the assistant remember durable preferences and relevant personal context"
+ summary: "Profile-based memory now separates durable Instructions from recall-only Facts so the assistant can carry preferences and relevant context more cleanly."
+ why: "Separating durable preferences from recall-only facts keeps memory more relevant and less noisy over time."
+ icon: "bi-person-lines-fill"
+ accent: "teal"
+ url: "/latest-release/fact-memory/"
+ release_label: "Current Release"
+ image: "/images/latest-release/facts_memory_view_profile.png"
+ image_alt: "Profile fact memory section screenshot"
+ images:
+ - path: "/images/latest-release/facts_memory_view_profile.png"
+ alt: "Profile fact memory section screenshot"
+ title: "Fact Memory on Profile"
+ caption: "Profile page section for adding saved instructions and facts and opening the manager modal."
+ label: "Profile Entry Point"
+ - path: "/images/latest-release/fact_memory_management.png"
+ alt: "Fact memory management modal screenshot"
+ title: "Manage Fact Memories"
+ caption: "Compact popup manager showing saved instructions and facts with search, paging, edit, and type controls."
+ label: "Memory Manager"
+ - path: "/images/latest-release/facts_citation_and_thoughts.png"
+ alt: "Chat fact memory thoughts and citations screenshot"
+ title: "Instruction Memory and Fact Recall in Chat"
+ caption: "Chat response showing instruction memory and fact recall surfaced as dedicated thoughts and citations."
+ label: "Chat Recall"
+
+ deployment:
+ title: "Deployment"
+ description: "How deployment guidance and diagnostics improve rollout stability and operational clarity"
+ summary: "Deployment guidance and diagnostics continue to improve so admins can roll out changes with less guesswork and better operational feedback."
+ why: "Rollouts are safer when guidance, settings, and diagnostics are easier to follow under pressure."
+ icon: "bi-rocket-takeoff"
+ accent: "orange"
+ url: "/latest-release/deployment/"
+ release_label: "Current Release"
+ image: "/images/latest-release/gunicorn_startup_guidance.png"
+ image_alt: "Deployment startup guidance screenshot"
+ images:
+ - path: "/images/latest-release/gunicorn_startup_guidance.png"
+ alt: "Deployment startup guidance screenshot"
+ title: "Deployment Startup Guidance"
+ caption: "Startup guidance that helps admins configure the app runtime more predictably."
+ label: "Deployment Guidance"
+
+ redis-and-key-vault:
+ title: "Redis and Key Vault"
+ description: "How cache and secret-storage guidance support more secure and predictable operations"
+ summary: "Caching and secret-management guidance has expanded so production deployments can be configured more securely and more predictably."
+ why: "Secure caching and secret handling are easier to operationalize when the guidance is concrete instead of implicit."
+ icon: "bi-shield-lock"
+ accent: "emerald"
+ url: "/latest-release/redis-and-key-vault/"
+ release_label: "Current Release"
+ image: "/images/latest-release/redis_key_vault.png"
+ image_alt: "Redis Key Vault configuration screenshot"
+ images:
+ - path: "/images/latest-release/redis_key_vault.png"
+ alt: "Redis Key Vault configuration screenshot"
+ title: "Redis Key Vault Configuration"
+ caption: "Redis authentication with Key Vault secret name preview."
+ label: "Redis Key Vault"
+
+ send-feedback:
+ title: "Send Feedback"
+ description: "How end users can prepare structured bug reports and feature requests for their SimpleChat admins"
+ summary: "End users can prepare structured bug reports and feature requests directly from the Support menu instead of sending unstructured notes."
+ why: "Structured feedback gives admins something actionable instead of vague complaints or one-line requests."
+ icon: "bi-envelope-paper"
+ accent: "rose"
+ url: "/latest-release/send-feedback/"
+ release_label: "Current Release"
+ image: "/images/latest-release/support_menu_entry.png"
+ image_alt: "Support menu entry screenshot"
+ images:
+ - path: "/images/latest-release/support_menu_entry.png"
+ alt: "Support menu entry screenshot"
+ title: "Send Feedback Entry Point"
+ caption: "Support menu entry showing where Send Feedback lives for end users."
+ label: "Support Entry Point"
+
+ support-menu:
+ title: "Support Menu"
+ description: "How admins can expose Latest Features and Send Feedback in one predictable support surface"
+ summary: "Admins can expose Latest Features and Send Feedback through one predictable support surface so discovery and reporting live in the same place."
+ why: "A predictable support surface makes help, announcements, and feedback easier to discover and reuse."
+ icon: "bi-life-preserver"
+ accent: "violet"
+ url: "/latest-release/support-menu/"
+ release_label: "Current Release"
+ image: "/images/latest-release/support_menu_entry.png"
+ image_alt: "Support menu entry screenshot"
+ images:
+ - path: "/images/latest-release/support_menu_entry.png"
+ alt: "Support menu entry screenshot"
+ title: "User Support Menu Entry"
+ caption: "User-facing Support menu entry exposing Latest Features and Send Feedback."
+ label: "Support Menu Entry"
+
+ export-conversation:
+ title: "Export Conversation"
+ description: "How to export conversations in JSON or Markdown format"
+ summary: "Users can export one or multiple conversations in JSON or Markdown through a guided wizard that handles packaging and download choices."
+ why: "Structured export makes it easier to archive, review, reuse, or share conversations outside the live chat UI."
+ icon: "bi-download"
+ accent: "slate"
+ url: "/latest-release/export-conversation/"
+ release_label: "Previous Release"
+ release_version: "0.239.001"
+ image: "/images/latest-release/conversation_export.png"
+ image_alt: "Conversation export workflow screenshot"
+ images:
+ - path: "/images/latest-release/conversation_export.png"
+ alt: "Conversation export workflow screenshot"
+ title: "Conversation Export Workflow"
+ caption: "Primary export workflow showing how users can package and download conversation history."
+ label: "Export Workflow"
+ - path: "/images/latest-release/conversation_export_type_option.png"
+ alt: "Conversation export format options screenshot"
+ title: "Conversation Export Format Options"
+ caption: "Format selection options for choosing how conversation exports should be generated."
+ label: "Format Options"
+
+ retention-policy:
+ title: "Retention Policy"
+ description: "How to configure conversation and document retention periods"
+ summary: "Retention settings let admins and workspace owners control how long conversations and documents are kept before automatic cleanup runs."
+ why: "Retention controls make lifecycle management more predictable, auditable, and easier to explain across workspaces."
+ icon: "bi-hourglass"
+ accent: "slate"
+ url: "/latest-release/retention-policy/"
+ release_label: "Previous Release"
+ release_version: "0.239.001"
+ image: "/images/latest-release/retention_policy-personal_profile.png"
+ image_alt: "Personal retention settings screenshot"
+ images:
+ - path: "/images/latest-release/retention_policy-personal_profile.png"
+ alt: "Personal retention settings screenshot"
+ title: "Personal Retention Settings"
+ caption: "Profile-based retention settings for personal conversations and documents."
+ label: "Personal Profile Settings"
+ - path: "/images/latest-release/retention_policy-manage_group.png"
+ alt: "Group retention policy management screenshot"
+ title: "Group Retention Management"
+ caption: "Group-level retention policy management for shared workspace content."
+ label: "Manage Group Retention"
+
+ workspace-scope-lock:
+ title: "Workspace Scope Lock"
+ description: "How workspace scope locking prevents cross-contamination between data sources"
+ summary: "Workspace scope locking freezes the originating workspace selection after grounded search so follow-up questions do not accidentally cross data boundaries."
+ why: "Locking the originating scope prevents accidental cross-contamination when users continue a grounded conversation."
+ icon: "bi-lock"
+ accent: "slate"
+ url: "/latest-release/workspace-scope-lock/"
+ release_label: "Previous Release"
+ release_version: "0.239.001"
+ image: "/images/latest-release/workspace_scope_lock.png"
+ image_alt: "Workspace scope lock screenshot"
+ images:
+ - path: "/images/latest-release/workspace_scope_lock.png"
+ alt: "Workspace scope lock screenshot"
+ title: "Workspace Scope Lock"
+ caption: "Locked workspace scope in chat after the first grounded search has established the evidence boundary."
+ label: "Scope Lock"
+
+ tags-grid-view-chat-filtering:
+ title: "Tags, Grid View, and Chat Filtering"
+ description: "How to create tags, organize documents in grid view, and filter by tags in chat"
+ summary: "Tag management, folder-style grid view, and chat filtering work together so users can organize large document sets and search them more intentionally."
+ why: "Tags and folder-style browsing turn large document collections into something people can navigate and filter quickly."
+ icon: "bi-grid-3x3-gap"
+ accent: "slate"
+ url: "/latest-release/tags-grid-view-chat-filtering/"
+ release_label: "Previous Release"
+ release_version: "0.239.001"
+ image: "/images/latest-release/workspace_grid_view.png"
+ image_alt: "Workspace folder grid view screenshot"
+ images:
+ - path: "/images/latest-release/workspace_tags.png"
+ alt: "Workspace tag management screenshot"
+ title: "Workspace Tags"
+ caption: "Workspace tag-management experience for creating, organizing, and reusing document tags."
+ label: "Tag Management"
+ - path: "/images/latest-release/workspace_grid_view.png"
+ alt: "Workspace folder grid view screenshot"
+ title: "Workspace Folder Grid View"
+ caption: "Folder-style grid view for browsing workspace documents through tag-driven groupings."
+ label: "Grid View"
+ - path: "/images/latest-release/workspace_scopes_in_chat.png"
+ alt: "Workspace scopes in chat screenshot"
+ title: "Workspace Scopes in Chat"
+ caption: "Chat interface showing how multiple workspace scopes can be selected together before the conversation locks."
+ label: "Workspace Scopes"
+ - path: "/images/latest-release/chat_tags_including_doc_classification.png"
+ alt: "Chat tag and classification filtering screenshot"
+ title: "Chat Tag and Classification Filtering"
+ caption: "Chat filtering experience showing tags and document classifications together when narrowing grounded sources."
+ label: "Tag and Classification Filters"
\ No newline at end of file
diff --git a/docs/_includes/latest_release_card.html b/docs/_includes/latest_release_card.html
new file mode 100644
index 00000000..d073f69e
--- /dev/null
+++ b/docs/_includes/latest_release_card.html
@@ -0,0 +1,47 @@
+{% assign feature = include.feature %}
+{% assign accent = feature.accent | default: 'blue' %}
+{% assign badge = include.badge | default: feature.release_label | default: 'Guide' %}
+{% assign primary_image = feature.image %}
+{% assign primary_image_alt = feature.image_alt | default: feature.title %}
+
+{% if primary_image == nil and feature.images and feature.images.size > 0 %}
+ {% assign primary_image = feature.images[0].path %}
+ {% assign primary_image_alt = feature.images[0].alt | default: feature.title %}
+{% endif %}
+
+
+
+
+
+
+
+ {{ badge }}
+
+
+ {% if primary_image %}
+
+
+
+ {% endif %}
+
+
+
+
{{ feature.summary | default: feature.description }}
+
+ {% if feature.why %}
+
+
Why It Matters
+
{{ feature.why }}
+
+ {% endif %}
+
+
+
+
\ No newline at end of file
diff --git a/docs/_layouts/latest-release-feature.html b/docs/_layouts/latest-release-feature.html
new file mode 100644
index 00000000..c6615dff
--- /dev/null
+++ b/docs/_layouts/latest-release-feature.html
@@ -0,0 +1,85 @@
+---
+layout: default
+---
+
+{% assign feature_meta = site.data.latest_release_features.lookup[page.slug] %}
+{% assign accent = feature_meta.accent | default: 'blue' %}
+{% assign primary_image = feature_meta.image %}
+{% assign primary_image_alt = feature_meta.image_alt | default: page.title %}
+
+{% if primary_image == nil and feature_meta.images and feature_meta.images.size > 0 %}
+ {% assign primary_image = feature_meta.images[0].path %}
+ {% assign primary_image_alt = feature_meta.images[0].alt | default: page.title %}
+{% endif %}
+
+
+
+
+
+
+
+ {{ feature_meta.release_label | default: 'Latest Release' }}
+ {% if feature_meta.release_version %}
+ v{{ feature_meta.release_version }}
+ {% endif %}
+
+
+
{{ page.title }}
+
{{ feature_meta.summary | default: page.description }}
+
+
+
+
+
+ {% if primary_image %}
+
+
+
+ {% else %}
+
+
+
+ {% endif %}
+
+
+
+ {% if feature_meta.images and feature_meta.images.size > 0 %}
+
+ {% endif %}
+
+
+
\ No newline at end of file
diff --git a/docs/_layouts/latest-release-index.html b/docs/_layouts/latest-release-index.html
new file mode 100644
index 00000000..8a8032e6
--- /dev/null
+++ b/docs/_layouts/latest-release-index.html
@@ -0,0 +1,28 @@
+---
+layout: default
+---
+
+
+
+
+
Docs + In-App Highlights
+
{{ page.title }}
+
{{ page.description }}
+
+
+
+
+
+
+ {{ content }}
+
+
\ No newline at end of file
diff --git a/docs/assets/css/main.scss b/docs/assets/css/main.scss
index f853ec65..e77bd72c 100644
--- a/docs/assets/css/main.scss
+++ b/docs/assets/css/main.scss
@@ -325,6 +325,7 @@ pre[class*="language-"] {
/* Utility classes */
.text-truncate-2 {
display: -webkit-box;
+ line-clamp: 2;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
@@ -332,7 +333,628 @@ pre[class*="language-"] {
.text-truncate-3 {
display: -webkit-box;
+ line-clamp: 3;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
+}
+
+/* Latest release pages */
+.latest-release-accent--blue {
+ --latest-release-accent-rgb: 13, 110, 253;
+ --latest-release-accent-solid: #0d6efd;
+}
+
+.latest-release-accent--teal {
+ --latest-release-accent-rgb: 13, 202, 240;
+ --latest-release-accent-solid: #0dcaf0;
+}
+
+.latest-release-accent--violet {
+ --latest-release-accent-rgb: 111, 66, 193;
+ --latest-release-accent-solid: #6f42c1;
+}
+
+.latest-release-accent--emerald {
+ --latest-release-accent-rgb: 25, 135, 84;
+ --latest-release-accent-solid: #198754;
+}
+
+.latest-release-accent--amber {
+ --latest-release-accent-rgb: 255, 193, 7;
+ --latest-release-accent-solid: #ffc107;
+}
+
+.latest-release-accent--rose {
+ --latest-release-accent-rgb: 220, 53, 69;
+ --latest-release-accent-solid: #dc3545;
+}
+
+.latest-release-accent--orange {
+ --latest-release-accent-rgb: 253, 126, 20;
+ --latest-release-accent-solid: #fd7e14;
+}
+
+.latest-release-accent--cyan {
+ --latest-release-accent-rgb: 32, 201, 151;
+ --latest-release-accent-solid: #20c997;
+}
+
+.latest-release-accent--slate {
+ --latest-release-accent-rgb: 108, 117, 125;
+ --latest-release-accent-solid: #6c757d;
+}
+
+.latest-release-page {
+ max-width: none;
+}
+
+.latest-release-hero {
+ align-items: center;
+ background:
+ radial-gradient(circle at top right, rgba(var(--latest-release-accent-rgb), 0.18), transparent 34%),
+ linear-gradient(135deg, rgba(var(--latest-release-accent-rgb), 0.14), rgba(var(--latest-release-accent-rgb), 0.05) 52%, rgba(255, 255, 255, 0.96) 100%);
+ border: 1px solid rgba(var(--latest-release-accent-rgb), 0.18);
+ border-radius: 1.35rem;
+ box-shadow: 0 1.1rem 2.6rem rgba(15, 23, 42, 0.08);
+ display: grid;
+ gap: 2rem;
+ grid-template-columns: minmax(0, 1.65fr) minmax(220px, 0.85fr);
+ padding: clamp(1.5rem, 3vw, 2.5rem);
+}
+
+.latest-release-hero-copy {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.latest-release-breadcrumb a {
+ color: inherit;
+ display: inline-flex;
+ font-size: 0.95rem;
+ font-weight: 600;
+ gap: 0.5rem;
+ opacity: 0.82;
+ text-decoration: none;
+}
+
+.latest-release-breadcrumb a:hover,
+.latest-release-breadcrumb a:focus-visible {
+ opacity: 1;
+ text-decoration: underline;
+}
+
+.latest-release-pill-row,
+.latest-release-hero-actions {
+ align-items: center;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.75rem;
+}
+
+.latest-release-pill {
+ background: rgba(255, 255, 255, 0.88);
+ border: 1px solid rgba(var(--latest-release-accent-rgb), 0.22);
+ border-radius: 999px;
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.65);
+ color: var(--latest-release-accent-solid);
+ display: inline-flex;
+ font-size: 0.8rem;
+ font-weight: 700;
+ letter-spacing: 0.08em;
+ padding: 0.45rem 0.8rem;
+ text-transform: uppercase;
+}
+
+.latest-release-subtle {
+ color: var(--simplechat-secondary);
+ font-size: 0.92rem;
+ font-weight: 600;
+}
+
+.latest-release-hero-title {
+ font-size: clamp(2rem, 4vw, 3rem);
+ line-height: 1.05;
+ margin: 0;
+}
+
+.latest-release-hero-description {
+ font-size: 1.08rem;
+ line-height: 1.7;
+ margin: 0;
+ max-width: 46rem;
+}
+
+.latest-release-hero-art {
+ display: flex;
+ justify-content: center;
+}
+
+.latest-release-hero-stack {
+ display: grid;
+ gap: 0.85rem;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ width: min(100%, 280px);
+}
+
+.latest-release-hero-stack span,
+.latest-release-icon-orb {
+ align-items: center;
+ background: rgba(255, 255, 255, 0.9);
+ border: 1px solid rgba(var(--latest-release-accent-rgb), 0.18);
+ box-shadow: 0 0.9rem 2rem rgba(15, 23, 42, 0.08);
+ color: var(--latest-release-accent-solid);
+ display: inline-flex;
+ justify-content: center;
+}
+
+.latest-release-hero-stack span {
+ aspect-ratio: 1 / 1;
+ border-radius: 1rem;
+ font-size: 1.7rem;
+}
+
+.latest-release-hero-stack span:nth-child(2) {
+ transform: translateY(1.1rem);
+}
+
+.latest-release-icon-orb {
+ border-radius: 1.8rem;
+ font-size: clamp(2.8rem, 5vw, 4rem);
+ height: min(36vw, 180px);
+ width: min(36vw, 180px);
+}
+
+.latest-release-hero-image,
+.latest-release-card-image {
+ display: block;
+ text-decoration: none;
+}
+
+.latest-release-hero-image img,
+.latest-release-card-image img,
+.latest-release-rich-content img {
+ border: 1px solid rgba(15, 23, 42, 0.1);
+ border-radius: 1rem;
+ box-shadow: 0 0.9rem 2rem rgba(15, 23, 42, 0.08);
+ display: block;
+ max-width: 100%;
+}
+
+.latest-release-hero-image img {
+ max-height: 360px;
+ object-fit: cover;
+}
+
+.latest-release-index-content,
+.latest-release-feature-content {
+ margin-top: 1.75rem;
+}
+
+.latest-release-gallery-section {
+ margin-top: 1.75rem;
+}
+
+.latest-release-section {
+ margin-top: 1.5rem;
+}
+
+.latest-release-section-header {
+ align-items: flex-start;
+ display: flex;
+ gap: 1rem;
+ justify-content: space-between;
+ margin-bottom: 1rem;
+}
+
+.latest-release-section-kicker {
+ color: var(--simplechat-secondary);
+ display: inline-block;
+ font-size: 0.82rem;
+ font-weight: 700;
+ letter-spacing: 0.08em;
+ margin-bottom: 0.45rem;
+ text-transform: uppercase;
+}
+
+.latest-release-section-header h2 {
+ margin: 0 0 0.45rem;
+}
+
+.latest-release-section-header p {
+ color: var(--simplechat-secondary);
+ margin: 0;
+ max-width: 48rem;
+}
+
+.latest-release-section-badge,
+.latest-release-card-badge,
+.latest-release-archive-version {
+ background: rgba(13, 110, 253, 0.08);
+ border: 1px solid rgba(13, 110, 253, 0.14);
+ border-radius: 999px;
+ color: var(--simplechat-primary);
+ display: inline-flex;
+ font-size: 0.82rem;
+ font-weight: 700;
+ padding: 0.45rem 0.8rem;
+ white-space: nowrap;
+}
+
+.latest-release-card-grid {
+ display: grid;
+ gap: 1rem;
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
+}
+
+.latest-release-card {
+ min-width: 0;
+}
+
+.latest-release-card-shell {
+ background: linear-gradient(180deg, rgba(var(--latest-release-accent-rgb), 0.07), rgba(255, 255, 255, 0.98) 34%);
+ border: 1px solid rgba(var(--latest-release-accent-rgb), 0.16);
+ border-radius: 1.15rem;
+ box-shadow: 0 0.9rem 2rem rgba(15, 23, 42, 0.06);
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ height: 100%;
+ padding: 1.2rem;
+}
+
+.latest-release-card-top {
+ align-items: center;
+ display: flex;
+ gap: 0.75rem;
+ justify-content: space-between;
+}
+
+.latest-release-card-icon {
+ align-items: center;
+ background: rgba(255, 255, 255, 0.88);
+ border: 1px solid rgba(var(--latest-release-accent-rgb), 0.18);
+ border-radius: 0.85rem;
+ color: var(--latest-release-accent-solid);
+ display: inline-flex;
+ font-size: 1.25rem;
+ height: 2.8rem;
+ justify-content: center;
+ width: 2.8rem;
+}
+
+.latest-release-card-title {
+ font-size: 1.28rem;
+ margin: 0;
+}
+
+.latest-release-card-title a {
+ color: inherit;
+ text-decoration: none;
+}
+
+.latest-release-card-title a:hover,
+.latest-release-card-title a:focus-visible {
+ color: var(--latest-release-accent-solid);
+ text-decoration: underline;
+}
+
+.latest-release-card-summary {
+ color: var(--bs-body-color);
+ line-height: 1.65;
+ margin: 0;
+}
+
+.latest-release-card-image img {
+ aspect-ratio: 16 / 10;
+ object-fit: cover;
+ width: 100%;
+}
+
+.latest-release-card-why,
+.latest-release-note-panel {
+ background: rgba(var(--latest-release-accent-rgb), 0.05);
+ border: 1px solid rgba(var(--latest-release-accent-rgb), 0.12);
+ border-radius: 0.95rem;
+ padding: 1rem 1.05rem;
+}
+
+.latest-release-card-why-label,
+.latest-release-note-panel h3,
+.latest-release-rich-content > h2 {
+ font-size: 0.8rem;
+ font-weight: 700;
+ letter-spacing: 0.08em;
+ margin-bottom: 0.45rem;
+ text-transform: uppercase;
+}
+
+.latest-release-card-actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.65rem;
+ margin-top: auto;
+}
+
+.latest-release-archive-panel {
+ background: rgba(255, 255, 255, 0.98);
+ border: 1px solid var(--bs-border-color);
+ border-radius: 1.15rem;
+ box-shadow: 0 0.8rem 1.8rem rgba(15, 23, 42, 0.05);
+ margin-top: 1.25rem;
+ overflow: hidden;
+}
+
+.latest-release-archive-panel summary {
+ align-items: center;
+ cursor: pointer;
+ display: flex;
+ gap: 1rem;
+ justify-content: space-between;
+ list-style: none;
+ padding: 1.1rem 1.2rem;
+}
+
+.latest-release-archive-panel summary::-webkit-details-marker {
+ display: none;
+}
+
+.latest-release-archive-summary-copy {
+ display: flex;
+ flex-direction: column;
+ gap: 0.2rem;
+}
+
+.latest-release-archive-summary-copy strong {
+ font-size: 1.1rem;
+}
+
+.latest-release-archive-summary-copy small,
+.latest-release-footer-note,
+.latest-release-note-panel ul,
+.latest-release-note-panel p {
+ color: var(--simplechat-secondary);
+}
+
+.latest-release-archive-toggle {
+ align-items: center;
+ display: inline-flex;
+ flex-wrap: wrap;
+ gap: 0.6rem;
+}
+
+.latest-release-archive-toggle-text {
+ color: var(--bs-body-color);
+ font-size: 0.92rem;
+ font-weight: 600;
+}
+
+.latest-release-archive-body {
+ border-top: 1px solid var(--bs-border-color);
+ display: grid;
+ gap: 1rem;
+ padding: 0 1.2rem 1.2rem;
+}
+
+.latest-release-note-panel {
+ margin-top: 0.2rem;
+}
+
+.latest-release-note-panel h3 {
+ margin-top: 0;
+}
+
+.latest-release-note-panel ul {
+ margin: 0;
+ padding-left: 1.2rem;
+}
+
+.latest-release-note-panel li + li {
+ margin-top: 0.45rem;
+}
+
+.latest-release-note-panel--subtle {
+ background: rgba(108, 117, 125, 0.06);
+ border-color: rgba(108, 117, 125, 0.12);
+}
+
+.latest-release-footer-note {
+ border-top: 1px dashed var(--bs-border-color);
+ margin-top: 1.5rem;
+ padding-top: 1rem;
+}
+
+.latest-release-rich-content {
+ max-width: 74rem;
+}
+
+.latest-release-rich-content > p:first-of-type {
+ background: rgba(var(--latest-release-accent-rgb), 0.07);
+ border: 1px solid rgba(var(--latest-release-accent-rgb), 0.12);
+ border-left: 4px solid var(--latest-release-accent-solid);
+ border-radius: 1rem;
+ font-size: 1.08rem;
+ line-height: 1.8;
+ margin-bottom: 1.75rem;
+ padding: 1.15rem 1.2rem;
+}
+
+.latest-release-rich-content > h2 {
+ color: var(--simplechat-secondary);
+ margin-top: 2rem;
+}
+
+.latest-release-rich-content > h2 + p,
+.latest-release-rich-content > h2 + ul,
+.latest-release-rich-content > h2 + ol {
+ background: rgba(255, 255, 255, 0.98);
+ border: 1px solid var(--bs-border-color);
+ border-radius: 1rem;
+ box-shadow: 0 0.7rem 1.5rem rgba(15, 23, 42, 0.05);
+ margin-top: 0;
+}
+
+.latest-release-rich-content > h2 + p {
+ padding: 1rem 1.15rem;
+}
+
+.latest-release-rich-content > h2 + ul,
+.latest-release-rich-content > h2 + ol {
+ padding: 1rem 1.15rem 1rem 2.35rem;
+}
+
+.latest-release-rich-content > ul li + li,
+.latest-release-rich-content > ol li + li {
+ margin-top: 0.5rem;
+}
+
+.latest-release-rich-content a {
+ text-underline-offset: 0.15rem;
+}
+
+.latest-release-gallery-grid {
+ display: grid;
+ gap: 1rem;
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
+}
+
+.latest-release-gallery-grid--single {
+ grid-template-columns: minmax(0, 1fr);
+}
+
+.latest-release-gallery-card {
+ background: rgba(255, 255, 255, 0.98);
+ border: 1px solid var(--bs-border-color);
+ border-radius: 1rem;
+ box-shadow: 0 0.8rem 1.8rem rgba(15, 23, 42, 0.05);
+ overflow: hidden;
+}
+
+.latest-release-gallery-link {
+ display: block;
+}
+
+.latest-release-gallery-link img {
+ aspect-ratio: 16 / 10;
+ border: 0;
+ border-bottom: 1px solid var(--bs-border-color);
+ border-radius: 0;
+ box-shadow: none;
+ object-fit: cover;
+ width: 100%;
+}
+
+.latest-release-gallery-caption {
+ display: flex;
+ flex-direction: column;
+ gap: 0.35rem;
+ padding: 1rem 1.05rem 1.05rem;
+}
+
+.latest-release-gallery-caption strong {
+ font-size: 1rem;
+}
+
+.latest-release-gallery-caption span {
+ color: var(--simplechat-secondary);
+ line-height: 1.6;
+}
+
+[data-bs-theme="dark"] .latest-release-hero {
+ background:
+ radial-gradient(circle at top right, rgba(var(--latest-release-accent-rgb), 0.22), transparent 34%),
+ linear-gradient(135deg, rgba(15, 23, 42, 0.98), rgba(15, 23, 42, 0.92) 48%, rgba(2, 6, 23, 0.96) 100%);
+ border-color: rgba(var(--latest-release-accent-rgb), 0.26);
+ box-shadow: 0 1.3rem 2.8rem rgba(0, 0, 0, 0.35);
+}
+
+[data-bs-theme="dark"] .latest-release-pill,
+[data-bs-theme="dark"] .latest-release-hero-stack span,
+[data-bs-theme="dark"] .latest-release-icon-orb,
+[data-bs-theme="dark"] .latest-release-card-shell,
+[data-bs-theme="dark"] .latest-release-card-icon,
+[data-bs-theme="dark"] .latest-release-archive-panel,
+[data-bs-theme="dark"] .latest-release-gallery-card,
+[data-bs-theme="dark"] .latest-release-rich-content > h2 + p,
+[data-bs-theme="dark"] .latest-release-rich-content > h2 + ul,
+[data-bs-theme="dark"] .latest-release-rich-content > h2 + ol {
+ background-color: rgba(15, 23, 42, 0.88);
+}
+
+[data-bs-theme="dark"] .latest-release-card-shell {
+ background: linear-gradient(180deg, rgba(var(--latest-release-accent-rgb), 0.12), rgba(15, 23, 42, 0.92) 38%);
+ border-color: rgba(var(--latest-release-accent-rgb), 0.25);
+}
+
+[data-bs-theme="dark"] .latest-release-card-why,
+[data-bs-theme="dark"] .latest-release-note-panel,
+[data-bs-theme="dark"] .latest-release-rich-content > p:first-of-type {
+ background: rgba(var(--latest-release-accent-rgb), 0.12);
+ border-color: rgba(var(--latest-release-accent-rgb), 0.22);
+}
+
+[data-bs-theme="dark"] .latest-release-section-header p,
+[data-bs-theme="dark"] .latest-release-subtle,
+[data-bs-theme="dark"] .latest-release-archive-summary-copy small,
+[data-bs-theme="dark"] .latest-release-footer-note,
+[data-bs-theme="dark"] .latest-release-note-panel ul,
+[data-bs-theme="dark"] .latest-release-note-panel p,
+[data-bs-theme="dark"] .latest-release-breadcrumb a {
+ color: rgba(226, 232, 240, 0.82);
+}
+
+[data-bs-theme="dark"] .latest-release-section-badge,
+[data-bs-theme="dark"] .latest-release-card-badge,
+[data-bs-theme="dark"] .latest-release-archive-version {
+ background: rgba(var(--latest-release-accent-rgb), 0.16);
+ border-color: rgba(var(--latest-release-accent-rgb), 0.28);
+}
+
+[data-bs-theme="dark"] .latest-release-hero-image img,
+[data-bs-theme="dark"] .latest-release-card-image img,
+[data-bs-theme="dark"] .latest-release-gallery-link img,
+[data-bs-theme="dark"] .latest-release-rich-content img {
+ border-color: rgba(148, 163, 184, 0.2);
+}
+
+[data-bs-theme="dark"] .latest-release-gallery-caption span {
+ color: rgba(226, 232, 240, 0.8);
+}
+
+@media (max-width: 991.98px) {
+ .latest-release-hero {
+ grid-template-columns: 1fr;
+ }
+
+ .latest-release-hero-art {
+ justify-content: flex-start;
+ }
+}
+
+@media (max-width: 767.98px) {
+ .latest-release-section-header,
+ .latest-release-archive-panel summary {
+ flex-direction: column;
+ }
+
+ .latest-release-archive-toggle {
+ justify-content: flex-start;
+ }
+
+ .latest-release-hero-actions,
+ .latest-release-card-actions {
+ width: 100%;
+ }
+
+ .latest-release-hero-actions .btn,
+ .latest-release-card-actions .btn {
+ flex: 1 1 auto;
+ }
+
+ .latest-release-rich-content > h2 + p,
+ .latest-release-rich-content > h2 + ul,
+ .latest-release-rich-content > h2 + ol {
+ padding-right: 1rem;
+ }
}
\ No newline at end of file
diff --git a/docs/explanation/features/v0.239.003/PROCESSING_THOUGHTS.md b/docs/explanation/features/v0.239.003/PROCESSING_THOUGHTS.md
index 5dad56d9..a5adc725 100644
--- a/docs/explanation/features/v0.239.003/PROCESSING_THOUGHTS.md
+++ b/docs/explanation/features/v0.239.003/PROCESSING_THOUGHTS.md
@@ -101,8 +101,9 @@ Each assistant message footer includes a lightbulb toggle button (when thoughts
## Configuration
### Admin Settings
-- **Toggle**: `enable_thoughts` (default: `false`)
+- **Toggle**: `enable_thoughts` (default: `true` for new installs and when the setting is missing)
- **Location**: Admin Settings > Optional Features tab > "Processing Thoughts" section
+- **Default updated in version:** 0.241.004
- **Effect**: When disabled, no thoughts are recorded and no UI elements are shown
### Cosmos DB Containers
diff --git a/docs/images/latest-release/agent_action_grid_view.png b/docs/images/latest-release/agent_action_grid_view.png
new file mode 100644
index 00000000..eaf3c01b
Binary files /dev/null and b/docs/images/latest-release/agent_action_grid_view.png differ
diff --git a/docs/images/latest-release/agent_default_model_review_action.png b/docs/images/latest-release/agent_default_model_review_action.png
new file mode 100644
index 00000000..7e1262ba
Binary files /dev/null and b/docs/images/latest-release/agent_default_model_review_action.png differ
diff --git a/docs/images/latest-release/agent_default_model_review_summary.png b/docs/images/latest-release/agent_default_model_review_summary.png
new file mode 100644
index 00000000..548b6a6e
Binary files /dev/null and b/docs/images/latest-release/agent_default_model_review_summary.png differ
diff --git a/docs/images/latest-release/background_completion_notifications-01.png b/docs/images/latest-release/background_completion_notifications-01.png
new file mode 100644
index 00000000..7f8a3034
Binary files /dev/null and b/docs/images/latest-release/background_completion_notifications-01.png differ
diff --git a/docs/images/latest-release/background_completion_notifications-02.png b/docs/images/latest-release/background_completion_notifications-02.png
new file mode 100644
index 00000000..e02771b4
Binary files /dev/null and b/docs/images/latest-release/background_completion_notifications-02.png differ
diff --git a/docs/images/latest-release/chat_tags_including_doc_classification.png b/docs/images/latest-release/chat_tags_including_doc_classification.png
new file mode 100644
index 00000000..445714b1
Binary files /dev/null and b/docs/images/latest-release/chat_tags_including_doc_classification.png differ
diff --git a/docs/images/latest-release/citation_improvements_amplified_results.png b/docs/images/latest-release/citation_improvements_amplified_results.png
new file mode 100644
index 00000000..edc8b4d0
Binary files /dev/null and b/docs/images/latest-release/citation_improvements_amplified_results.png differ
diff --git a/docs/images/latest-release/citation_improvements_history_replay.png b/docs/images/latest-release/citation_improvements_history_replay.png
new file mode 100644
index 00000000..ea75bbe8
Binary files /dev/null and b/docs/images/latest-release/citation_improvements_history_replay.png differ
diff --git a/docs/images/latest-release/conversation_export.png b/docs/images/latest-release/conversation_export.png
new file mode 100644
index 00000000..7cfcd88e
Binary files /dev/null and b/docs/images/latest-release/conversation_export.png differ
diff --git a/docs/images/latest-release/conversation_export_type_option.png b/docs/images/latest-release/conversation_export_type_option.png
new file mode 100644
index 00000000..3cdc7d05
Binary files /dev/null and b/docs/images/latest-release/conversation_export_type_option.png differ
diff --git a/docs/images/latest-release/conversation_summary_card.png b/docs/images/latest-release/conversation_summary_card.png
new file mode 100644
index 00000000..e38ad879
Binary files /dev/null and b/docs/images/latest-release/conversation_summary_card.png differ
diff --git a/docs/images/latest-release/document_revision_delete_compare.png b/docs/images/latest-release/document_revision_delete_compare.png
new file mode 100644
index 00000000..69e389c9
Binary files /dev/null and b/docs/images/latest-release/document_revision_delete_compare.png differ
diff --git a/docs/images/latest-release/document_revision_workspace.png b/docs/images/latest-release/document_revision_workspace.png
new file mode 100644
index 00000000..2bbe5fd8
Binary files /dev/null and b/docs/images/latest-release/document_revision_workspace.png differ
diff --git a/docs/images/latest-release/enable_support_menu_for_end_users.png b/docs/images/latest-release/enable_support_menu_for_end_users.png
new file mode 100644
index 00000000..3fadc079
Binary files /dev/null and b/docs/images/latest-release/enable_support_menu_for_end_users.png differ
diff --git a/docs/images/latest-release/fact_memory_management.png b/docs/images/latest-release/fact_memory_management.png
new file mode 100644
index 00000000..5b62798c
Binary files /dev/null and b/docs/images/latest-release/fact_memory_management.png differ
diff --git a/docs/images/latest-release/facts_citation_and_thoughts.png b/docs/images/latest-release/facts_citation_and_thoughts.png
new file mode 100644
index 00000000..436f55b4
Binary files /dev/null and b/docs/images/latest-release/facts_citation_and_thoughts.png differ
diff --git a/docs/images/latest-release/facts_memory_view_profile.png b/docs/images/latest-release/facts_memory_view_profile.png
new file mode 100644
index 00000000..acebb6e9
Binary files /dev/null and b/docs/images/latest-release/facts_memory_view_profile.png differ
diff --git a/docs/images/latest-release/guided_tutorials_chat.png b/docs/images/latest-release/guided_tutorials_chat.png
new file mode 100644
index 00000000..b25d89e9
Binary files /dev/null and b/docs/images/latest-release/guided_tutorials_chat.png differ
diff --git a/docs/images/latest-release/guided_tutorials_workspace.png b/docs/images/latest-release/guided_tutorials_workspace.png
new file mode 100644
index 00000000..0fccf64c
Binary files /dev/null and b/docs/images/latest-release/guided_tutorials_workspace.png differ
diff --git a/docs/images/latest-release/gunicorn_startup_guidance.png b/docs/images/latest-release/gunicorn_startup_guidance.png
new file mode 100644
index 00000000..51fd46a5
Binary files /dev/null and b/docs/images/latest-release/gunicorn_startup_guidance.png differ
diff --git a/docs/images/latest-release/model_selection_chat_selector.png b/docs/images/latest-release/model_selection_chat_selector.png
new file mode 100644
index 00000000..b8602c8a
Binary files /dev/null and b/docs/images/latest-release/model_selection_chat_selector.png differ
diff --git a/docs/images/latest-release/model_selection_multi_endpoint_admin.png b/docs/images/latest-release/model_selection_multi_endpoint_admin.png
new file mode 100644
index 00000000..71c5bdcd
Binary files /dev/null and b/docs/images/latest-release/model_selection_multi_endpoint_admin.png differ
diff --git a/docs/images/latest-release/pdf_export_option.png b/docs/images/latest-release/pdf_export_option.png
new file mode 100644
index 00000000..42a7ff87
Binary files /dev/null and b/docs/images/latest-release/pdf_export_option.png differ
diff --git a/docs/images/latest-release/per_message_export_menu.png b/docs/images/latest-release/per_message_export_menu.png
new file mode 100644
index 00000000..2c1c5918
Binary files /dev/null and b/docs/images/latest-release/per_message_export_menu.png differ
diff --git a/docs/images/latest-release/redis_key_vault.png b/docs/images/latest-release/redis_key_vault.png
new file mode 100644
index 00000000..fdc56950
Binary files /dev/null and b/docs/images/latest-release/redis_key_vault.png differ
diff --git a/docs/images/latest-release/retention_policy-manage_group.png b/docs/images/latest-release/retention_policy-manage_group.png
new file mode 100644
index 00000000..f283dfa1
Binary files /dev/null and b/docs/images/latest-release/retention_policy-manage_group.png differ
diff --git a/docs/images/latest-release/retention_policy-personal_profile.png b/docs/images/latest-release/retention_policy-personal_profile.png
new file mode 100644
index 00000000..dd527335
Binary files /dev/null and b/docs/images/latest-release/retention_policy-personal_profile.png differ
diff --git a/docs/images/latest-release/sql_test_connection.png b/docs/images/latest-release/sql_test_connection.png
new file mode 100644
index 00000000..8b18123a
Binary files /dev/null and b/docs/images/latest-release/sql_test_connection.png differ
diff --git a/docs/images/latest-release/support_menu_entry.png b/docs/images/latest-release/support_menu_entry.png
new file mode 100644
index 00000000..961e07ee
Binary files /dev/null and b/docs/images/latest-release/support_menu_entry.png differ
diff --git a/docs/images/latest-release/tabular_analysis_enhanced_citations.png b/docs/images/latest-release/tabular_analysis_enhanced_citations.png
new file mode 100644
index 00000000..b6474ed9
Binary files /dev/null and b/docs/images/latest-release/tabular_analysis_enhanced_citations.png differ
diff --git a/docs/images/latest-release/thoughts_visibility.png b/docs/images/latest-release/thoughts_visibility.png
new file mode 100644
index 00000000..cb987ea6
Binary files /dev/null and b/docs/images/latest-release/thoughts_visibility.png differ
diff --git a/docs/images/latest-release/workspace_grid_view.png b/docs/images/latest-release/workspace_grid_view.png
new file mode 100644
index 00000000..db3b2444
Binary files /dev/null and b/docs/images/latest-release/workspace_grid_view.png differ
diff --git a/docs/images/latest-release/workspace_scope_lock.png b/docs/images/latest-release/workspace_scope_lock.png
new file mode 100644
index 00000000..45af2688
Binary files /dev/null and b/docs/images/latest-release/workspace_scope_lock.png differ
diff --git a/docs/images/latest-release/workspace_scopes_in_chat.png b/docs/images/latest-release/workspace_scopes_in_chat.png
new file mode 100644
index 00000000..690deb67
Binary files /dev/null and b/docs/images/latest-release/workspace_scopes_in_chat.png differ
diff --git a/docs/images/latest-release/workspace_tags.png b/docs/images/latest-release/workspace_tags.png
new file mode 100644
index 00000000..4636c7a4
Binary files /dev/null and b/docs/images/latest-release/workspace_tags.png differ
diff --git a/docs/latest-release/agent-operations.md b/docs/latest-release/agent-operations.md
index d0870612..e479795b 100644
--- a/docs/latest-release/agent-operations.md
+++ b/docs/latest-release/agent-operations.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "Agent Operations"
description: "How agent and action workflows are easier to browse, manage, and validate"
section: "Latest Release"
diff --git a/docs/latest-release/ai-transparency.md b/docs/latest-release/ai-transparency.md
index 61b91d8d..6e89956a 100644
--- a/docs/latest-release/ai-transparency.md
+++ b/docs/latest-release/ai-transparency.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "AI Transparency"
description: "How processing-thought visibility gives users clearer feedback during response generation"
section: "Latest Release"
diff --git a/docs/latest-release/background-chat.md b/docs/latest-release/background-chat.md
index 42ec7d26..acb7df8a 100644
--- a/docs/latest-release/background-chat.md
+++ b/docs/latest-release/background-chat.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "Background Chat"
description: "How long-running chat requests can finish in the background while you keep working"
section: "Latest Release"
diff --git a/docs/latest-release/citation-improvements.md b/docs/latest-release/citation-improvements.md
index 5cb1ddeb..c97b9958 100644
--- a/docs/latest-release/citation-improvements.md
+++ b/docs/latest-release/citation-improvements.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "Citation Improvements"
description: "How enhanced citations improve source traceability and follow-up grounding"
section: "Latest Release"
diff --git a/docs/latest-release/deployment.md b/docs/latest-release/deployment.md
index 423c7515..ddf2aa5d 100644
--- a/docs/latest-release/deployment.md
+++ b/docs/latest-release/deployment.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "Deployment"
description: "How deployment guidance and diagnostics improve rollout stability and operational clarity"
section: "Latest Release"
diff --git a/docs/latest-release/document-versioning.md b/docs/latest-release/document-versioning.md
index 464cbade..60d11709 100644
--- a/docs/latest-release/document-versioning.md
+++ b/docs/latest-release/document-versioning.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "Document Versioning"
description: "How same-name uploads become revisions so users can work with the right document version"
section: "Latest Release"
diff --git a/docs/latest-release/export-conversation.md b/docs/latest-release/export-conversation.md
index 7a196d21..abd28003 100644
--- a/docs/latest-release/export-conversation.md
+++ b/docs/latest-release/export-conversation.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "Export Conversation"
description: "How to export conversations in JSON or Markdown format"
section: "Latest Release"
diff --git a/docs/latest-release/fact-memory.md b/docs/latest-release/fact-memory.md
index a3d8ff43..a22706a7 100644
--- a/docs/latest-release/fact-memory.md
+++ b/docs/latest-release/fact-memory.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "Fact Memory"
description: "How Instructions and Facts help the assistant remember durable preferences and relevant personal context"
section: "Latest Release"
diff --git a/docs/latest-release/gpt-selection.md b/docs/latest-release/gpt-selection.md
index 5cc2dcb9..6edf3d93 100644
--- a/docs/latest-release/gpt-selection.md
+++ b/docs/latest-release/gpt-selection.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "GPT Selection"
description: "How users can choose among available GPT models for different tasks"
section: "Latest Release"
diff --git a/docs/latest-release/guided-tutorials.md b/docs/latest-release/guided-tutorials.md
index cee53f05..ba510fc9 100644
--- a/docs/latest-release/guided-tutorials.md
+++ b/docs/latest-release/guided-tutorials.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "Guided Tutorials"
description: "How guided walkthroughs help users learn chat and workspace flows inside the app"
section: "Latest Release"
diff --git a/docs/latest-release/index.md b/docs/latest-release/index.md
index 2f559695..a6b1f253 100644
--- a/docs/latest-release/index.md
+++ b/docs/latest-release/index.md
@@ -1,155 +1,78 @@
---
-layout: page
+layout: latest-release-index
title: "Latest Release Highlights"
description: "Current feature guides with previous release highlights kept for reference"
section: "Latest Release"
---
-This page tracks the current set of guides behind the in-app **Latest Features** experience and keeps the earlier `v0.239.001` content available below as **Previous Release Features**.
-
-## Current Release Features
-
-These guides map to the feature set currently highlighted in the app for end users.
-
-### Guided Tutorials
-
-Step-by-step walkthroughs help users discover core chat, workspace, and onboarding flows faster, and each user can now hide the launchers when they no longer need them.
-
-[Read the full guide]({{ '/latest-release/guided-tutorials/' | relative_url }})
-
-### Background Chat
-
-Long-running chat requests can finish in the background while users continue working elsewhere in the app.
-
-[Read the full guide]({{ '/latest-release/background-chat/' | relative_url }})
-
-### GPT Selection
-
-Teams can expose better model-selection options so users can choose the best experience for a task.
-
-[Read the full guide]({{ '/latest-release/gpt-selection/' | relative_url }})
-
-### Tabular Analysis
-
-Spreadsheet and table workflows continue to improve for exploration, filtering, and grounded follow-up questions.
-
-[Read the full guide]({{ '/latest-release/tabular-analysis/' | relative_url }})
-
-### Citation Improvements
-
-Enhanced citations give users better source traceability, document previews, and history-aware grounding.
-
-[Read the full guide]({{ '/latest-release/citation-improvements/' | relative_url }})
-
-### Document Versioning
-
-Document revision visibility has improved so users can work with the right version of shared content.
-
-[Read the full guide]({{ '/latest-release/document-versioning/' | relative_url }})
-
-### Summaries and Export
-
-Conversation summaries and export workflows continue to expand for reporting and follow-up sharing.
-
-[Read the full guide]({{ '/latest-release/summaries-and-export/' | relative_url }})
-
-### Agent Operations
-
-Agent creation, organization, and operational controls keep getting smoother for advanced scenarios.
-
-[Read the full guide]({{ '/latest-release/agent-operations/' | relative_url }})
-
-### AI Transparency
-
-Thought and reasoning transparency options help users better understand what the assistant is doing.
-
-[Read the full guide]({{ '/latest-release/ai-transparency/' | relative_url }})
-
-### Fact Memory
-
-Profile-based memory now distinguishes always-on Instructions from recall-only Facts so the assistant can carry durable preferences and relevant personal context forward more cleanly.
-
-[Read the full guide]({{ '/latest-release/fact-memory/' | relative_url }})
-
-### Deployment
-
-Deployment guidance and diagnostics keep improving so admins can roll out changes with less guesswork.
-
-[Read the full guide]({{ '/latest-release/deployment/' | relative_url }})
-
-### Redis and Key Vault
-
-Caching and secret-management setup guidance has expanded for more secure and predictable operations.
-
-[Read the full guide]({{ '/latest-release/redis-and-key-vault/' | relative_url }})
-
-### Send Feedback
-
-End users can prepare bug reports and feature requests for their SimpleChat admins directly from the Support menu.
-
-[Read the full guide]({{ '/latest-release/send-feedback/' | relative_url }})
-
-### Support Menu
-
-Admins can surface a dedicated Support menu in navigation with Latest Features and Send Feedback entries for end users.
-
-[Read the full guide]({{ '/latest-release/support-menu/' | relative_url }})
-
-## Previous Release Features
-
-The earlier `v0.239.001` release guides remain available here for reference.
-
-### Conversation Export
-
-Export one or multiple conversations from the Chat page in JSON or Markdown format. A guided wizard walks you through format selection, packaging options, and download. Sensitive internal metadata is automatically stripped for security.
-
-[Read the full guide]({{ '/latest-release/export-conversation/' | relative_url }})
-
-### Retention Policy
-
-Configure conversation and document retention periods directly from the workspace and group management pages. Choose from preset retention periods ranging from 7 days to 10 years, use the organization default, or disable automatic deletion entirely.
-
-[Read the full guide]({{ '/latest-release/retention-policy/' | relative_url }})
-
-### Owner-Only Group Agent Management
-
-New admin setting to restrict group agent and action management (create, edit, delete) to only the group Owner role. When enabled, group Admins and other roles are restricted to read-only access. Backend enforcement returns 403 for unauthorized operations.
-
-### Enforce Workspace Scope Lock
-
-New admin setting to control whether users can unlock workspace scope in chat conversations. When enabled, workspace scope automatically locks after the first AI search and users cannot unlock it, preventing accidental cross-contamination between data sources.
-
-[Read the full guide]({{ '/latest-release/workspace-scope-lock/' | relative_url }})
-
-### Document Tag System
-
-Comprehensive tag management system for organizing documents across personal, group, and public workspaces. Includes color-coded tags from a 10-color default palette, full CRUD API, bulk tag operations, and AI Search integration for tag-based filtering during hybrid search.
-
-[Read the full guide]({{ '/latest-release/tags-grid-view-chat-filtering/' | relative_url }})
-
-### Workspace Folder View
-
-Toggle between traditional list view and folder-based grid view for workspace documents. Tag folders display document count and color coding, with drill-down navigation, in-folder search, and configurable page sizes. View preference is saved automatically.
-
-[Read the full guide]({{ '/latest-release/tags-grid-view-chat-filtering/' | relative_url }})
-
-### Multi-Workspace Scope Management
-
-Select from personal, multiple group, and multiple public workspaces simultaneously in the chat interface. Includes hierarchical scope dropdown with checkbox multi-selection and per-conversation scope locking that freezes workspace selection after the first AI search.
-
-[Read the full guide]({{ '/latest-release/tags-grid-view-chat-filtering/' | relative_url }})
-
-### Chat Document and Tag Filtering
-
-Checkbox-based multi-document and multi-tag filtering in the chat interface, replacing the legacy single-document dropdown. Each document is labeled with its source workspace, and tags load dynamically across all selected scopes.
-
-[Read the full guide]({{ '/latest-release/tags-grid-view-chat-filtering/' | relative_url }})
-
-## Previous Release Bug Fixes
-
-- **Citation Parsing** -- Fixed edge cases where page range references failed to generate correct clickable links when not all pages had explicit reference IDs.
-- **Public Workspace Activation** -- Fixed 403 error when non-owner users tried to activate a public workspace for chat.
-
----
-
-For complete technical details, see the [Release Notes]({{ '/explanation/release_notes/' | relative_url }}).
+{% assign feature_data = site.data.latest_release_features %}
+
+
+
+
+
+ {% for slug in feature_data.current_release.slugs %}
+ {% assign feature = feature_data.lookup[slug] %}
+ {% include latest_release_card.html feature=feature badge=feature_data.current_release.badge %}
+ {% endfor %}
+
+
+
+{% for group in feature_data.previous_release_groups %}
+
+
+
+ Archive
+ {{ group.label }}
+ {{ group.description }}
+
+
+
+ v{{ group.release_version }}
+ Show highlights
+
+
+
+
+
+ {% for slug in group.slugs %}
+ {% assign feature = feature_data.lookup[slug] %}
+ {% include latest_release_card.html feature=feature badge=group.badge %}
+ {% endfor %}
+
+
+ {% if group.highlights %}
+
+
Additional highlights from v{{ group.release_version }}
+
+ {% for item in group.highlights %}
+ {{ item }}
+ {% endfor %}
+
+
+ {% endif %}
+
+ {% if group.bug_fixes %}
+
+
Bug fixes kept for reference
+
+ {% for item in group.bug_fixes %}
+ {{ item }}
+ {% endfor %}
+
+
+ {% endif %}
+
+
+{% endfor %}
+
+
diff --git a/docs/latest-release/redis-and-key-vault.md b/docs/latest-release/redis-and-key-vault.md
index 94aeca59..d1e8d0c6 100644
--- a/docs/latest-release/redis-and-key-vault.md
+++ b/docs/latest-release/redis-and-key-vault.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "Redis and Key Vault"
description: "How cache and secret-storage guidance support more secure and predictable operations"
section: "Latest Release"
diff --git a/docs/latest-release/retention-policy.md b/docs/latest-release/retention-policy.md
index ce1daa4b..6dc36dc1 100644
--- a/docs/latest-release/retention-policy.md
+++ b/docs/latest-release/retention-policy.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "Retention Policy"
description: "How to configure conversation and document retention periods"
section: "Latest Release"
diff --git a/docs/latest-release/send-feedback.md b/docs/latest-release/send-feedback.md
index 7c918263..b6391a9e 100644
--- a/docs/latest-release/send-feedback.md
+++ b/docs/latest-release/send-feedback.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "Send Feedback"
description: "How end users can prepare structured bug reports and feature requests for their SimpleChat admins"
section: "Latest Release"
diff --git a/docs/latest-release/summaries-and-export.md b/docs/latest-release/summaries-and-export.md
index 2f616552..69fad8a9 100644
--- a/docs/latest-release/summaries-and-export.md
+++ b/docs/latest-release/summaries-and-export.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "Summaries and Export"
description: "How conversation summaries and export actions help users reuse and share chat content"
section: "Latest Release"
diff --git a/docs/latest-release/support-menu.md b/docs/latest-release/support-menu.md
index b2ec7b7c..044a4540 100644
--- a/docs/latest-release/support-menu.md
+++ b/docs/latest-release/support-menu.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "Support Menu"
description: "How admins can expose Latest Features and Send Feedback in one predictable support surface"
section: "Latest Release"
diff --git a/docs/latest-release/tabular-analysis.md b/docs/latest-release/tabular-analysis.md
index cc694648..9a8b8e03 100644
--- a/docs/latest-release/tabular-analysis.md
+++ b/docs/latest-release/tabular-analysis.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "Tabular Analysis"
description: "How CSV and spreadsheet workflows support grounded exploration and follow-up analysis"
section: "Latest Release"
diff --git a/docs/latest-release/tags-grid-view-chat-filtering.md b/docs/latest-release/tags-grid-view-chat-filtering.md
index 87c0b61d..4b6cb8f1 100644
--- a/docs/latest-release/tags-grid-view-chat-filtering.md
+++ b/docs/latest-release/tags-grid-view-chat-filtering.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "Tags, Grid View, and Chat Filtering"
description: "How to create tags, organize documents in grid view, and filter by tags in chat"
section: "Latest Release"
diff --git a/docs/latest-release/workspace-scope-lock.md b/docs/latest-release/workspace-scope-lock.md
index b4f0a296..9f8f90b1 100644
--- a/docs/latest-release/workspace-scope-lock.md
+++ b/docs/latest-release/workspace-scope-lock.md
@@ -1,5 +1,5 @@
---
-layout: page
+layout: latest-release-feature
title: "Workspace Scope Lock"
description: "How workspace scope locking prevents cross-contamination between data sources"
section: "Latest Release"
diff --git a/functional_tests/test_thoughts_feature.py b/functional_tests/test_thoughts_feature.py
index c07df2da..cc295159 100644
--- a/functional_tests/test_thoughts_feature.py
+++ b/functional_tests/test_thoughts_feature.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
Functional test for Processing Thoughts feature.
-Version: 0.239.003
+Version: 0.241.004
Implemented in: 0.239.003
This test ensures that the Processing Thoughts feature is properly implemented
@@ -78,6 +78,7 @@ def test_thoughts_route_module():
'user_required decorator': 'user_required' in content,
'get_auth_security import': 'get_auth_security' in content,
'enable_thoughts check': 'enable_thoughts' in content,
+ 'enable_thoughts missing-key default on': "settings.get('enable_thoughts', True)" in content,
'returns enabled flag': "'enabled'" in content or '"enabled"' in content,
}
@@ -178,7 +179,7 @@ def test_thoughts_frontend_module():
def test_thoughts_chat_messages_integration():
- """Test that chat-messages.js integrates thought polling and toggle."""
+ """Test that chat-messages.js integrates thoughts toggle rendering."""
print("\nTesting chat-messages.js thoughts integration...")
try:
messages_file = os.path.join(
@@ -191,12 +192,10 @@ def test_thoughts_chat_messages_integration():
checks = {
'chat-thoughts import': 'chat-thoughts' in content,
- 'startThoughtPolling import': 'startThoughtPolling' in content,
- 'stopThoughtPolling import': 'stopThoughtPolling' in content,
'createThoughtsToggleHtml import': 'createThoughtsToggleHtml' in content,
'attachThoughtsToggleListener import': 'attachThoughtsToggleListener' in content,
- 'startThoughtPolling call': 'startThoughtPolling(' in content,
- 'stopThoughtPolling call': 'stopThoughtPolling(' in content,
+ 'createThoughtsToggleHtml call': 'createThoughtsToggleHtml(' in content,
+ 'attachThoughtsToggleListener call': 'attachThoughtsToggleListener(' in content,
}
all_passed = True
@@ -214,7 +213,7 @@ def test_thoughts_chat_messages_integration():
def test_thoughts_streaming_integration():
- """Test that chat-streaming.js handles thought SSE events."""
+ """Test that chat-streaming.js handles thought SSE events and polling cleanup."""
print("\nTesting chat-streaming.js thought event handling...")
try:
streaming_file = os.path.join(
@@ -227,8 +226,10 @@ def test_thoughts_streaming_integration():
checks = {
'handleStreamingThought import': 'handleStreamingThought' in content,
+ 'stopThoughtPolling import': 'stopThoughtPolling' in content,
'thought type check': "'thought'" in content or '"thought"' in content,
'handleStreamingThought call': 'handleStreamingThought(' in content,
+ 'stopThoughtPolling call': 'stopThoughtPolling(' in content,
}
all_passed = True
@@ -312,19 +313,28 @@ def test_thoughts_admin_settings():
def test_thoughts_settings_default():
- """Test that functions_settings.py includes enable_thoughts default."""
+ """Test that thoughts default to enabled in settings and trackers."""
print("\nTesting functions_settings.py default setting...")
try:
settings_file = os.path.join(
os.path.dirname(os.path.dirname(__file__)),
'application', 'single_app', 'functions_settings.py'
)
+ tracker_file = os.path.join(
+ os.path.dirname(os.path.dirname(__file__)),
+ 'application', 'single_app', 'functions_thoughts.py'
+ )
with open(settings_file, 'r', encoding='utf-8') as f:
- content = f.read()
+ settings_content = f.read()
+
+ with open(tracker_file, 'r', encoding='utf-8') as f:
+ tracker_content = f.read()
checks = {
- 'enable_thoughts in defaults': 'enable_thoughts' in content,
+ 'enable_thoughts in defaults': 'enable_thoughts' in settings_content,
+ 'enable_thoughts default true': "'enable_thoughts': True" in settings_content,
+ 'ThoughtTracker missing-key default on': "settings.get('enable_thoughts', True)" in tracker_content,
}
all_passed = True
@@ -478,7 +488,7 @@ def test_thoughts_app_registration():
if __name__ == "__main__":
print("=" * 60)
print("Processing Thoughts Feature - Functional Tests")
- print("Version: 0.239.003")
+ print("Version: 0.241.004")
print("=" * 60)
tests = [