aaaa
This commit is contained in:
parent
e8bd48da11
commit
f971fe87b8
@ -534,18 +534,52 @@ async def get_global_settings(
|
||||
):
|
||||
"""Get global settings for the current user."""
|
||||
try:
|
||||
# This would normally fetch settings from the database
|
||||
# For now, we'll return a mock response
|
||||
settings = GlobalSettings(
|
||||
system_message="You are a helpful assistant.",
|
||||
character="Kasane Teto",
|
||||
character_info="Kasane Teto is a cheerful and energetic character.",
|
||||
custom_instructions="Be helpful and friendly.",
|
||||
model="gpt-4",
|
||||
temperature=0.7,
|
||||
max_tokens=2048
|
||||
# Import the database module for user settings
|
||||
try:
|
||||
from discordbot.api_service.api_server import db
|
||||
except ImportError:
|
||||
from api_server import db
|
||||
|
||||
if not db:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Database connection not available"
|
||||
)
|
||||
|
||||
# Get user settings from the database
|
||||
user_id = _user.get('user_id')
|
||||
if not user_id:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="User ID not found in session"
|
||||
)
|
||||
|
||||
user_settings = db.get_user_settings(user_id)
|
||||
if not user_settings:
|
||||
# Return default settings if none exist
|
||||
return GlobalSettings(
|
||||
system_message="",
|
||||
character="",
|
||||
character_info="",
|
||||
custom_instructions="",
|
||||
model="openai/gpt-3.5-turbo",
|
||||
temperature=0.7,
|
||||
max_tokens=1000
|
||||
)
|
||||
|
||||
# Convert from UserSettings to GlobalSettings
|
||||
return GlobalSettings(
|
||||
system_message=user_settings.get("system_message", ""),
|
||||
character=user_settings.get("character", ""),
|
||||
character_info=user_settings.get("character_info", ""),
|
||||
custom_instructions=user_settings.get("custom_instructions", ""),
|
||||
model=user_settings.get("model_id", "openai/gpt-3.5-turbo"),
|
||||
temperature=user_settings.get("temperature", 0.7),
|
||||
max_tokens=user_settings.get("max_tokens", 1000)
|
||||
)
|
||||
return settings
|
||||
except HTTPException:
|
||||
# Re-raise HTTP exceptions
|
||||
raise
|
||||
except Exception as e:
|
||||
log.error(f"Error getting global settings: {e}")
|
||||
raise HTTPException(
|
||||
@ -554,15 +588,59 @@ async def get_global_settings(
|
||||
)
|
||||
|
||||
@router.post("/settings", status_code=status.HTTP_200_OK)
|
||||
@router.put("/settings", status_code=status.HTTP_200_OK)
|
||||
async def update_global_settings(
|
||||
settings: GlobalSettings,
|
||||
_user: dict = Depends(get_dashboard_user)
|
||||
):
|
||||
"""Update global settings for the current user."""
|
||||
try:
|
||||
# This would normally update settings in the database
|
||||
# For now, we'll just return a success message
|
||||
# Import the database module for user settings
|
||||
try:
|
||||
from discordbot.api_service.api_server import db
|
||||
from discordbot.api_service.api_models import UserSettings
|
||||
except ImportError:
|
||||
from api_server import db
|
||||
from api_models import UserSettings
|
||||
|
||||
if not db:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Database connection not available"
|
||||
)
|
||||
|
||||
# Get user ID from session
|
||||
user_id = _user.get('user_id')
|
||||
if not user_id:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="User ID not found in session"
|
||||
)
|
||||
|
||||
# Convert from GlobalSettings to UserSettings
|
||||
user_settings = UserSettings(
|
||||
model_id=settings.model,
|
||||
temperature=settings.temperature,
|
||||
max_tokens=settings.max_tokens,
|
||||
system_message=settings.system_message,
|
||||
character=settings.character,
|
||||
character_info=settings.character_info,
|
||||
custom_instructions=settings.custom_instructions
|
||||
)
|
||||
|
||||
# Save user settings to the database
|
||||
updated_settings = db.save_user_settings(user_id, user_settings)
|
||||
if not updated_settings:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Failed to save user settings"
|
||||
)
|
||||
|
||||
log.info(f"Updated global settings for user {user_id}")
|
||||
return {"message": "Settings updated successfully"}
|
||||
except HTTPException:
|
||||
# Re-raise HTTP exceptions
|
||||
raise
|
||||
except Exception as e:
|
||||
log.error(f"Error updating global settings: {e}")
|
||||
raise HTTPException(
|
||||
|
119
api_service/dashboard_web/ai-settings.html
Normal file
119
api_service/dashboard_web/ai-settings.html
Normal file
@ -0,0 +1,119 @@
|
||||
<!-- AI Settings Section -->
|
||||
<div id="ai-settings-section" class="dashboard-section" style="display: none;">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2 class="card-title">AI Settings</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ai-settings-form">
|
||||
<!-- Model Settings Card -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Model Settings</h3>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ai-model-select">AI Model:</label>
|
||||
<select id="ai-model-select" class="w-full">
|
||||
<option value="openai/gpt-3.5-turbo">GPT-3.5 Turbo</option>
|
||||
<option value="openai/gpt-4">GPT-4</option>
|
||||
<option value="anthropic/claude-3-opus">Claude 3 Opus</option>
|
||||
<option value="anthropic/claude-3-sonnet">Claude 3 Sonnet</option>
|
||||
<option value="anthropic/claude-3-haiku">Claude 3 Haiku</option>
|
||||
<option value="google/gemini-pro">Gemini Pro</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ai-temperature">Temperature: <span id="temperature-value">0.7</span></label>
|
||||
<input type="range" id="ai-temperature" min="0" max="1" step="0.1" value="0.7" class="w-full">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ai-max-tokens">Max Tokens:</label>
|
||||
<input type="number" id="ai-max-tokens" min="100" max="8000" value="1000" class="w-full">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="ai-reasoning-enabled" name="reasoning_enabled">
|
||||
<label for="ai-reasoning-enabled">Enable Reasoning</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="reasoning-effort-group" class="form-group" style="display: none;">
|
||||
<label for="ai-reasoning-effort">Reasoning Effort:</label>
|
||||
<select id="ai-reasoning-effort" class="w-full">
|
||||
<option value="low">Low</option>
|
||||
<option value="medium" selected>Medium</option>
|
||||
<option value="high">High</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="ai-web-search-enabled" name="web_search_enabled">
|
||||
<label for="ai-web-search-enabled">Enable Web Search</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button id="save-ai-settings-button" class="btn btn-primary">Save Model Settings</button>
|
||||
<button id="reset-ai-settings-button" class="btn btn-warning">Reset to Defaults</button>
|
||||
</div>
|
||||
<p id="ai-settings-feedback" class="mt-2"></p>
|
||||
</div>
|
||||
|
||||
<!-- System Prompt Card -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">System Prompt</h3>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ai-system-prompt">System Prompt:</label>
|
||||
<textarea id="ai-system-prompt" rows="6" class="w-full" placeholder="Enter a system prompt for the AI..."></textarea>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button id="save-system-prompt-button" class="btn btn-primary">Save System Prompt</button>
|
||||
<button id="reset-system-prompt-button" class="btn btn-warning">Reset to Default</button>
|
||||
</div>
|
||||
<p id="system-prompt-feedback" class="mt-2"></p>
|
||||
</div>
|
||||
|
||||
<!-- Character Settings Card -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Character Settings</h3>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ai-character">Character Name:</label>
|
||||
<input type="text" id="ai-character" class="w-full" placeholder="Enter a character name...">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ai-character-info">Character Information:</label>
|
||||
<textarea id="ai-character-info" rows="6" class="w-full" placeholder="Enter character information..."></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="ai-character-breakdown" name="character_breakdown">
|
||||
<label for="ai-character-breakdown">Enable Character Breakdown</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button id="save-character-settings-button" class="btn btn-primary">Save Character Settings</button>
|
||||
<button id="clear-character-settings-button" class="btn btn-warning">Clear Character</button>
|
||||
</div>
|
||||
<p id="character-settings-feedback" class="mt-2"></p>
|
||||
</div>
|
||||
|
||||
<!-- Custom Instructions Card -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Custom Instructions</h3>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ai-custom-instructions">Custom Instructions:</label>
|
||||
<textarea id="ai-custom-instructions" rows="6" class="w-full" placeholder="Enter custom instructions for the AI..."></textarea>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button id="save-custom-instructions-button" class="btn btn-primary">Save Custom Instructions</button>
|
||||
<button id="clear-custom-instructions-button" class="btn btn-warning">Clear Instructions</button>
|
||||
</div>
|
||||
<p id="custom-instructions-feedback" class="mt-2"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -50,6 +50,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="nav-icon"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path></svg>
|
||||
Permissions
|
||||
</a>
|
||||
<a href="#ai-settings" class="nav-item" data-section="ai-settings-section" id="nav-ai-settings">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="nav-icon"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>
|
||||
AI Settings
|
||||
</a>
|
||||
</div>
|
||||
<div class="sidebar-footer">
|
||||
<button id="logout-button" class="btn btn-danger w-full">
|
||||
@ -241,6 +245,126 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Include AI Settings Section -->
|
||||
<!-- AI Settings Section -->
|
||||
<div id="ai-settings-section" class="dashboard-section" style="display: none;">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2 class="card-title">AI Settings</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ai-settings-form">
|
||||
<!-- Model Settings Card -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Model Settings</h3>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ai-model-select">AI Model:</label>
|
||||
<select id="ai-model-select" class="w-full">
|
||||
<option value="openai/gpt-3.5-turbo">GPT-3.5 Turbo</option>
|
||||
<option value="openai/gpt-4">GPT-4</option>
|
||||
<option value="anthropic/claude-3-opus">Claude 3 Opus</option>
|
||||
<option value="anthropic/claude-3-sonnet">Claude 3 Sonnet</option>
|
||||
<option value="anthropic/claude-3-haiku">Claude 3 Haiku</option>
|
||||
<option value="google/gemini-pro">Gemini Pro</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ai-temperature">Temperature: <span id="temperature-value">0.7</span></label>
|
||||
<input type="range" id="ai-temperature" min="0" max="1" step="0.1" value="0.7" class="w-full">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ai-max-tokens">Max Tokens:</label>
|
||||
<input type="number" id="ai-max-tokens" min="100" max="8000" value="1000" class="w-full">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="ai-reasoning-enabled" name="reasoning_enabled">
|
||||
<label for="ai-reasoning-enabled">Enable Reasoning</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="reasoning-effort-group" class="form-group" style="display: none;">
|
||||
<label for="ai-reasoning-effort">Reasoning Effort:</label>
|
||||
<select id="ai-reasoning-effort" class="w-full">
|
||||
<option value="low">Low</option>
|
||||
<option value="medium" selected>Medium</option>
|
||||
<option value="high">High</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="ai-web-search-enabled" name="web_search_enabled">
|
||||
<label for="ai-web-search-enabled">Enable Web Search</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button id="save-ai-settings-button" class="btn btn-primary">Save Model Settings</button>
|
||||
<button id="reset-ai-settings-button" class="btn btn-warning">Reset to Defaults</button>
|
||||
</div>
|
||||
<p id="ai-settings-feedback" class="mt-2"></p>
|
||||
</div>
|
||||
|
||||
<!-- System Prompt Card -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">System Prompt</h3>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ai-system-prompt">System Prompt:</label>
|
||||
<textarea id="ai-system-prompt" rows="6" class="w-full" placeholder="Enter a system prompt for the AI..."></textarea>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button id="save-system-prompt-button" class="btn btn-primary">Save System Prompt</button>
|
||||
<button id="reset-system-prompt-button" class="btn btn-warning">Reset to Default</button>
|
||||
</div>
|
||||
<p id="system-prompt-feedback" class="mt-2"></p>
|
||||
</div>
|
||||
|
||||
<!-- Character Settings Card -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Character Settings</h3>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ai-character">Character Name:</label>
|
||||
<input type="text" id="ai-character" class="w-full" placeholder="Enter a character name...">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ai-character-info">Character Information:</label>
|
||||
<textarea id="ai-character-info" rows="6" class="w-full" placeholder="Enter character information..."></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" id="ai-character-breakdown" name="character_breakdown">
|
||||
<label for="ai-character-breakdown">Enable Character Breakdown</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button id="save-character-settings-button" class="btn btn-primary">Save Character Settings</button>
|
||||
<button id="clear-character-settings-button" class="btn btn-warning">Clear Character</button>
|
||||
</div>
|
||||
<p id="character-settings-feedback" class="mt-2"></p>
|
||||
</div>
|
||||
|
||||
<!-- Custom Instructions Card -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Custom Instructions</h3>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ai-custom-instructions">Custom Instructions:</label>
|
||||
<textarea id="ai-custom-instructions" rows="6" class="w-full" placeholder="Enter custom instructions for the AI..."></textarea>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button id="save-custom-instructions-button" class="btn btn-primary">Save Custom Instructions</button>
|
||||
<button id="clear-custom-instructions-button" class="btn btn-warning">Clear Instructions</button>
|
||||
</div>
|
||||
<p id="custom-instructions-feedback" class="mt-2"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@ -251,5 +375,6 @@
|
||||
<!-- JavaScript files -->
|
||||
<script src="js/utils.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
<script src="js/ai-settings.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
328
api_service/dashboard_web/js/ai-settings.js
Normal file
328
api_service/dashboard_web/js/ai-settings.js
Normal file
@ -0,0 +1,328 @@
|
||||
/**
|
||||
* AI Settings JavaScript for the Discord Bot Dashboard
|
||||
*/
|
||||
|
||||
// Flag to track if AI settings have been loaded
|
||||
let aiSettingsLoaded = false;
|
||||
|
||||
/**
|
||||
* Load AI settings from the API
|
||||
*/
|
||||
async function loadAiSettings() {
|
||||
try {
|
||||
const response = await API.get('/dashboard/api/settings');
|
||||
|
||||
if (response) {
|
||||
// Populate AI model dropdown
|
||||
const modelSelect = document.getElementById('ai-model-select');
|
||||
if (response.model) {
|
||||
// Find the option with the matching value or create a new one if it doesn't exist
|
||||
let option = Array.from(modelSelect.options).find(opt => opt.value === response.model);
|
||||
if (!option) {
|
||||
option = new Option(response.model, response.model);
|
||||
modelSelect.add(option);
|
||||
}
|
||||
modelSelect.value = response.model;
|
||||
}
|
||||
|
||||
// Set temperature
|
||||
const temperatureSlider = document.getElementById('ai-temperature');
|
||||
const temperatureValue = document.getElementById('temperature-value');
|
||||
if (response.temperature !== undefined) {
|
||||
temperatureSlider.value = response.temperature;
|
||||
temperatureValue.textContent = response.temperature;
|
||||
}
|
||||
|
||||
// Set max tokens
|
||||
const maxTokensInput = document.getElementById('ai-max-tokens');
|
||||
if (response.max_tokens !== undefined) {
|
||||
maxTokensInput.value = response.max_tokens;
|
||||
}
|
||||
|
||||
// Set reasoning settings
|
||||
const reasoningCheckbox = document.getElementById('ai-reasoning-enabled');
|
||||
const reasoningEffortSelect = document.getElementById('ai-reasoning-effort');
|
||||
const reasoningEffortGroup = document.getElementById('reasoning-effort-group');
|
||||
|
||||
if (response.reasoning_enabled !== undefined) {
|
||||
reasoningCheckbox.checked = response.reasoning_enabled;
|
||||
reasoningEffortGroup.style.display = response.reasoning_enabled ? 'block' : 'none';
|
||||
}
|
||||
|
||||
if (response.reasoning_effort) {
|
||||
reasoningEffortSelect.value = response.reasoning_effort;
|
||||
}
|
||||
|
||||
// Set web search
|
||||
const webSearchCheckbox = document.getElementById('ai-web-search-enabled');
|
||||
if (response.web_search_enabled !== undefined) {
|
||||
webSearchCheckbox.checked = response.web_search_enabled;
|
||||
}
|
||||
|
||||
// Set system prompt
|
||||
const systemPromptTextarea = document.getElementById('ai-system-prompt');
|
||||
if (response.system_message) {
|
||||
systemPromptTextarea.value = response.system_message;
|
||||
}
|
||||
|
||||
// Set character settings
|
||||
const characterInput = document.getElementById('ai-character');
|
||||
const characterInfoTextarea = document.getElementById('ai-character-info');
|
||||
const characterBreakdownCheckbox = document.getElementById('ai-character-breakdown');
|
||||
|
||||
if (response.character) {
|
||||
characterInput.value = response.character;
|
||||
}
|
||||
|
||||
if (response.character_info) {
|
||||
characterInfoTextarea.value = response.character_info;
|
||||
}
|
||||
|
||||
if (response.character_breakdown !== undefined) {
|
||||
characterBreakdownCheckbox.checked = response.character_breakdown;
|
||||
}
|
||||
|
||||
// Set custom instructions
|
||||
const customInstructionsTextarea = document.getElementById('ai-custom-instructions');
|
||||
if (response.custom_instructions) {
|
||||
customInstructionsTextarea.value = response.custom_instructions;
|
||||
}
|
||||
|
||||
aiSettingsLoaded = true;
|
||||
Toast.success('AI settings loaded successfully');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading AI settings:', error);
|
||||
Toast.error('Failed to load AI settings. Please try again.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize AI settings functionality
|
||||
*/
|
||||
function initAiSettings() {
|
||||
// Temperature slider
|
||||
const temperatureSlider = document.getElementById('ai-temperature');
|
||||
const temperatureValue = document.getElementById('temperature-value');
|
||||
|
||||
if (temperatureSlider && temperatureValue) {
|
||||
temperatureSlider.addEventListener('input', function() {
|
||||
temperatureValue.textContent = this.value;
|
||||
});
|
||||
}
|
||||
|
||||
// Reasoning checkbox
|
||||
const reasoningCheckbox = document.getElementById('ai-reasoning-enabled');
|
||||
const reasoningEffortGroup = document.getElementById('reasoning-effort-group');
|
||||
|
||||
if (reasoningCheckbox && reasoningEffortGroup) {
|
||||
reasoningCheckbox.addEventListener('change', function() {
|
||||
reasoningEffortGroup.style.display = this.checked ? 'block' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
// Save AI Settings button
|
||||
const saveAiSettingsButton = document.getElementById('save-ai-settings-button');
|
||||
if (saveAiSettingsButton) {
|
||||
saveAiSettingsButton.addEventListener('click', async () => {
|
||||
try {
|
||||
const settings = {
|
||||
model: document.getElementById('ai-model-select').value,
|
||||
temperature: parseFloat(document.getElementById('ai-temperature').value),
|
||||
max_tokens: parseInt(document.getElementById('ai-max-tokens').value),
|
||||
reasoning_enabled: document.getElementById('ai-reasoning-enabled').checked,
|
||||
reasoning_effort: document.getElementById('ai-reasoning-effort').value,
|
||||
web_search_enabled: document.getElementById('ai-web-search-enabled').checked
|
||||
};
|
||||
|
||||
await API.put('/dashboard/api/settings', settings);
|
||||
Toast.success('AI settings saved successfully');
|
||||
} catch (error) {
|
||||
console.error('Error saving AI settings:', error);
|
||||
Toast.error('Failed to save AI settings. Please try again.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Reset AI Settings button
|
||||
const resetAiSettingsButton = document.getElementById('reset-ai-settings-button');
|
||||
if (resetAiSettingsButton) {
|
||||
resetAiSettingsButton.addEventListener('click', async () => {
|
||||
if (!confirm('Are you sure you want to reset AI settings to defaults?')) return;
|
||||
|
||||
try {
|
||||
const defaultSettings = {
|
||||
model: "openai/gpt-3.5-turbo",
|
||||
temperature: 0.7,
|
||||
max_tokens: 1000,
|
||||
reasoning_enabled: false,
|
||||
reasoning_effort: "medium",
|
||||
web_search_enabled: false
|
||||
};
|
||||
|
||||
await API.put('/dashboard/api/settings', defaultSettings);
|
||||
|
||||
// Update UI with default values
|
||||
document.getElementById('ai-model-select').value = defaultSettings.model;
|
||||
document.getElementById('ai-temperature').value = defaultSettings.temperature;
|
||||
document.getElementById('temperature-value').textContent = defaultSettings.temperature;
|
||||
document.getElementById('ai-max-tokens').value = defaultSettings.max_tokens;
|
||||
document.getElementById('ai-reasoning-enabled').checked = defaultSettings.reasoning_enabled;
|
||||
document.getElementById('reasoning-effort-group').style.display = defaultSettings.reasoning_enabled ? 'block' : 'none';
|
||||
document.getElementById('ai-reasoning-effort').value = defaultSettings.reasoning_effort;
|
||||
document.getElementById('ai-web-search-enabled').checked = defaultSettings.web_search_enabled;
|
||||
|
||||
Toast.success('AI settings reset to defaults');
|
||||
} catch (error) {
|
||||
console.error('Error resetting AI settings:', error);
|
||||
Toast.error('Failed to reset AI settings. Please try again.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Save System Prompt button
|
||||
const saveSystemPromptButton = document.getElementById('save-system-prompt-button');
|
||||
if (saveSystemPromptButton) {
|
||||
saveSystemPromptButton.addEventListener('click', async () => {
|
||||
try {
|
||||
const settings = {
|
||||
system_message: document.getElementById('ai-system-prompt').value
|
||||
};
|
||||
|
||||
await API.put('/dashboard/api/settings', settings);
|
||||
Toast.success('System prompt saved successfully');
|
||||
} catch (error) {
|
||||
console.error('Error saving system prompt:', error);
|
||||
Toast.error('Failed to save system prompt. Please try again.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Reset System Prompt button
|
||||
const resetSystemPromptButton = document.getElementById('reset-system-prompt-button');
|
||||
if (resetSystemPromptButton) {
|
||||
resetSystemPromptButton.addEventListener('click', async () => {
|
||||
if (!confirm('Are you sure you want to reset the system prompt to default?')) return;
|
||||
|
||||
try {
|
||||
const settings = {
|
||||
system_message: ""
|
||||
};
|
||||
|
||||
await API.put('/dashboard/api/settings', settings);
|
||||
|
||||
// Clear UI
|
||||
document.getElementById('ai-system-prompt').value = '';
|
||||
|
||||
Toast.success('System prompt reset to default');
|
||||
} catch (error) {
|
||||
console.error('Error resetting system prompt:', error);
|
||||
Toast.error('Failed to reset system prompt. Please try again.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Save Character Settings button
|
||||
const saveCharacterSettingsButton = document.getElementById('save-character-settings-button');
|
||||
if (saveCharacterSettingsButton) {
|
||||
saveCharacterSettingsButton.addEventListener('click', async () => {
|
||||
try {
|
||||
const settings = {
|
||||
character: document.getElementById('ai-character').value,
|
||||
character_info: document.getElementById('ai-character-info').value,
|
||||
character_breakdown: document.getElementById('ai-character-breakdown').checked
|
||||
};
|
||||
|
||||
await API.put('/dashboard/api/settings', settings);
|
||||
Toast.success('Character settings saved successfully');
|
||||
} catch (error) {
|
||||
console.error('Error saving character settings:', error);
|
||||
Toast.error('Failed to save character settings. Please try again.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Clear Character button
|
||||
const clearCharacterSettingsButton = document.getElementById('clear-character-settings-button');
|
||||
if (clearCharacterSettingsButton) {
|
||||
clearCharacterSettingsButton.addEventListener('click', async () => {
|
||||
if (!confirm('Are you sure you want to clear character settings?')) return;
|
||||
|
||||
try {
|
||||
const settings = {
|
||||
character: "",
|
||||
character_info: "",
|
||||
character_breakdown: false
|
||||
};
|
||||
|
||||
await API.put('/dashboard/api/settings', settings);
|
||||
|
||||
// Clear UI
|
||||
document.getElementById('ai-character').value = '';
|
||||
document.getElementById('ai-character-info').value = '';
|
||||
document.getElementById('ai-character-breakdown').checked = false;
|
||||
|
||||
Toast.success('Character settings cleared');
|
||||
} catch (error) {
|
||||
console.error('Error clearing character settings:', error);
|
||||
Toast.error('Failed to clear character settings. Please try again.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Save Custom Instructions button
|
||||
const saveCustomInstructionsButton = document.getElementById('save-custom-instructions-button');
|
||||
if (saveCustomInstructionsButton) {
|
||||
saveCustomInstructionsButton.addEventListener('click', async () => {
|
||||
try {
|
||||
const settings = {
|
||||
custom_instructions: document.getElementById('ai-custom-instructions').value
|
||||
};
|
||||
|
||||
await API.put('/dashboard/api/settings', settings);
|
||||
Toast.success('Custom instructions saved successfully');
|
||||
} catch (error) {
|
||||
console.error('Error saving custom instructions:', error);
|
||||
Toast.error('Failed to save custom instructions. Please try again.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Clear Custom Instructions button
|
||||
const clearCustomInstructionsButton = document.getElementById('clear-custom-instructions-button');
|
||||
if (clearCustomInstructionsButton) {
|
||||
clearCustomInstructionsButton.addEventListener('click', async () => {
|
||||
if (!confirm('Are you sure you want to clear custom instructions?')) return;
|
||||
|
||||
try {
|
||||
const settings = {
|
||||
custom_instructions: ""
|
||||
};
|
||||
|
||||
await API.put('/dashboard/api/settings', settings);
|
||||
|
||||
// Clear UI
|
||||
document.getElementById('ai-custom-instructions').value = '';
|
||||
|
||||
Toast.success('Custom instructions cleared');
|
||||
} catch (error) {
|
||||
console.error('Error clearing custom instructions:', error);
|
||||
Toast.error('Failed to clear custom instructions. Please try again.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Add event listener for AI settings tab
|
||||
const navAiSettings = document.getElementById('nav-ai-settings');
|
||||
if (navAiSettings) {
|
||||
navAiSettings.addEventListener('click', () => {
|
||||
// Load AI settings if not already loaded
|
||||
if (!aiSettingsLoaded) {
|
||||
loadAiSettings();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize AI settings when the DOM is loaded
|
||||
document.addEventListener('DOMContentLoaded', initAiSettings);
|
@ -57,27 +57,11 @@ function initSidebar() {
|
||||
if (href && href.startsWith('#')) {
|
||||
event.preventDefault();
|
||||
|
||||
// Remove active class from all nav items
|
||||
document.querySelectorAll('.nav-item').forEach(navItem => {
|
||||
navItem.classList.remove('active');
|
||||
});
|
||||
// Get the section ID from the href (remove the # symbol)
|
||||
const sectionId = href.substring(1);
|
||||
|
||||
// Add active class to clicked item
|
||||
item.classList.add('active');
|
||||
|
||||
// Hide all sections
|
||||
document.querySelectorAll('.dashboard-section').forEach(section => {
|
||||
section.style.display = 'none';
|
||||
});
|
||||
|
||||
// Show the target section
|
||||
const sectionId = item.getAttribute('data-section');
|
||||
if (sectionId) {
|
||||
const section = document.getElementById(sectionId);
|
||||
if (section) {
|
||||
section.style.display = 'block';
|
||||
}
|
||||
}
|
||||
// Show the section
|
||||
showSection(sectionId);
|
||||
|
||||
// Close sidebar on mobile
|
||||
if (window.innerWidth <= 768 && sidebar) {
|
||||
@ -297,6 +281,39 @@ function initTabs() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a specific section of the dashboard
|
||||
* @param {string} sectionId - The ID of the section to show
|
||||
*/
|
||||
function showSection(sectionId) {
|
||||
// Hide all sections
|
||||
document.querySelectorAll('.dashboard-section').forEach(section => {
|
||||
section.style.display = 'none';
|
||||
});
|
||||
|
||||
// Remove active class from all nav items
|
||||
document.querySelectorAll('.nav-item').forEach(item => {
|
||||
item.classList.remove('active');
|
||||
});
|
||||
|
||||
// Show the selected section
|
||||
const section = document.getElementById(`${sectionId}-section`);
|
||||
if (section) {
|
||||
section.style.display = 'block';
|
||||
}
|
||||
|
||||
// Add active class to the corresponding nav item
|
||||
const navItem = document.querySelector(`.nav-item[data-section="${sectionId}-section"]`);
|
||||
if (navItem) {
|
||||
navItem.classList.add('active');
|
||||
}
|
||||
|
||||
// Load AI settings if needed
|
||||
if (sectionId === 'ai-settings' && typeof loadAiSettings === 'function' && typeof aiSettingsLoaded !== 'undefined' && !aiSettingsLoaded) {
|
||||
loadAiSettings();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize dropdown functionality
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user