feat(astrolabe): add admin search settings and enhanced UI

Add comprehensive admin controls for the unified search provider and enhance the frontend UI with filtering and visualization improvements.

**Admin Settings:**
- Configure default search algorithm (hybrid, semantic, bm25)
- Set fusion method for hybrid search (rrf, dbsf)
- Adjust minimum score threshold (0-100%)
- Set result limit (1-100 results)

**Frontend Enhancements:**
- Add score-based result filtering with slider control
- Add expandable excerpts for search results
- Improve result visualization and formatting
- Add algorithm badge to show search method used

**API Changes:**
- Add `/api/admin/search-settings` POST endpoint
- Add `searchForUnifiedSearch()` method to McpServerClient
- Load and apply admin settings in SemanticSearchProvider

**Technical Details:**
- Settings stored in app config table
- Defaults: hybrid algorithm, rrf fusion, 0% threshold, 20 results
- SemanticSearchProvider respects admin-configured limits

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2025-12-18 00:01:19 +01:00
co-authored by Claude Sonnet 4.5
parent 24e63a967a
commit 4cce4f6392
10 changed files with 440 additions and 12 deletions
+86
View File
@@ -173,6 +173,92 @@ style('astroglobe', 'astroglobe-settings');
</div>
<?php endif; ?>
<!-- Search Settings -->
<?php if ($_['vectorSyncEnabled']): ?>
<div class="mcp-status-card" id="search-settings">
<h3><?php p($l->t('AI Search Provider Settings')); ?></h3>
<p class="mcp-settings-description">
<?php p($l->t('Configure the default search parameters for the AI Search provider in Nextcloud unified search.')); ?>
</p>
<form id="astroglobe-search-settings-form" class="mcp-settings-form">
<div class="mcp-form-group">
<label for="search-algorithm"><?php p($l->t('Search Algorithm')); ?></label>
<select id="search-algorithm" name="algorithm" class="mcp-select">
<option value="hybrid" <?php if ($_['searchSettings']['algorithm'] === 'hybrid') echo 'selected'; ?>>
<?php p($l->t('Hybrid (Recommended)')); ?>
</option>
<option value="semantic" <?php if ($_['searchSettings']['algorithm'] === 'semantic') echo 'selected'; ?>>
<?php p($l->t('Semantic Only')); ?>
</option>
<option value="bm25" <?php if ($_['searchSettings']['algorithm'] === 'bm25') echo 'selected'; ?>>
<?php p($l->t('Keyword (BM25) Only')); ?>
</option>
</select>
<p class="mcp-help-text">
<?php p($l->t('Hybrid combines semantic understanding with keyword matching. Semantic finds conceptually similar content. BM25 matches exact keywords.')); ?>
</p>
</div>
<div class="mcp-form-group">
<label for="search-fusion"><?php p($l->t('Fusion Method')); ?></label>
<select id="search-fusion" name="fusion" class="mcp-select">
<option value="rrf" <?php if ($_['searchSettings']['fusion'] === 'rrf') echo 'selected'; ?>>
<?php p($l->t('RRF - Reciprocal Rank Fusion (Recommended)')); ?>
</option>
<option value="dbsf" <?php if ($_['searchSettings']['fusion'] === 'dbsf') echo 'selected'; ?>>
<?php p($l->t('DBSF - Distribution-Based Score Fusion')); ?>
</option>
</select>
<p class="mcp-help-text">
<?php p($l->t('Only applies to hybrid search. RRF balances results well for most queries. DBSF may work better when keyword matches are over/under-weighted.')); ?>
</p>
</div>
<div class="mcp-form-group">
<label for="search-score-threshold">
<?php p($l->t('Minimum Score Threshold')); ?>:
<span id="score-threshold-value"><?php p($_['searchSettings']['scoreThreshold']); ?>%</span>
</label>
<input type="range"
id="search-score-threshold"
name="scoreThreshold"
min="0"
max="100"
step="5"
value="<?php p($_['searchSettings']['scoreThreshold']); ?>"
class="mcp-range" />
<p class="mcp-help-text">
<?php p($l->t('Filter out results below this relevance score. Set to 0 to show all results.')); ?>
</p>
</div>
<div class="mcp-form-group">
<label for="search-limit"><?php p($l->t('Maximum Results')); ?></label>
<input type="number"
id="search-limit"
name="limit"
min="5"
max="100"
step="5"
value="<?php p($_['searchSettings']['limit']); ?>"
class="mcp-input" />
<p class="mcp-help-text">
<?php p($l->t('Maximum number of results to return per search query (5-100).')); ?>
</p>
</div>
<div class="mcp-form-actions">
<button type="submit" class="primary">
<?php p($l->t('Save Settings')); ?>
</button>
<span id="search-settings-status" class="mcp-status-message"></span>
</div>
</form>
</div>
<?php endif; ?>
<!-- Capabilities -->
<div class="mcp-status-card">
<h3><?php p($l->t('Capabilities')); ?></h3>