Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions backends/qdrant.js
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,16 @@ export class QdrantBackend extends VectorBackend {
model: getModelFromSettings(settings),
};

//Use queryVector if provided, otherwise searchText
if (queryVector) {
body.queryVector = queryVector;
} else if (searchText?.trim()) {
body.searchText = searchText;
} else {
console.warn('[Qdrant] No queryVector or searchText provided');
return { hashes: [], metadata: [] };
}

// Add content_type filter for multitenancy mode
if (settings.qdrant_multitenancy) {
body.filter = {
Expand Down Expand Up @@ -436,6 +446,18 @@ export class QdrantBackend extends VectorBackend {
model: getModelFromSettings(settings),
};


// Use queryVector if provided, otherwise searchText
if (queryVector) {
body.queryVector = queryVector;
} else if (searchText?.trim()) {
body.searchText = searchText;
} else {
console.warn(`[Qdrant] No queryVector or searchText for ${collectionId}`);
results[collectionId] = { hashes: [], metadata: [] };
continue;
}

// Add content_type filter for multitenancy mode
if (settings.qdrant_multitenancy) {
body.filter = {
Expand Down
54 changes: 43 additions & 11 deletions ui/chunk-visualizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,15 @@ function updateChunkData(hash, updates) {
const existing = pendingChanges.get(hash) || {};
pendingChanges.set(hash, { ...existing, ...updates });
hasUnsavedChanges = true;
// refresh the chunk data
allChunks.forEach(chunk => {
if (chunk.hash === hash) {
// merge pending changes into the chunk for fresh data if chunks end up with same hash somehow.
const stored = getChunkMetadata(hash) || {};
const pending = pendingChanges.get(hash) || {};
chunk.data = { ...chunk.data, ...pending };
}
});
}

async function saveAllChanges() {
Expand Down Expand Up @@ -856,7 +865,7 @@ function renderGroupsTab() {
<span>${stats.exclusiveGroups} exclusive</span>`
: ''
);

bindGroupsTabEvents();
if (groups.length === 0) {
container.html(`
<div class="vecthare-groups-empty">
Expand All @@ -877,9 +886,7 @@ function renderGroupsTab() {
<div class="vecthare-detail-empty">Select a group to view details</div>
</div>
`);

renderGroupList();
bindGroupsTabEvents();
renderGroupList();
}

/**
Expand Down Expand Up @@ -1088,11 +1095,11 @@ function openAddMemberDialog() {
});

// Click to add
$(document).on('click.addmember', '.vecthare-member-option', function() {
overlay.on('click', '.vecthare-member-option', function (e) {
e.stopPropagation(); // Prevent overlay close
const hash = $(this).data('hash');
addMemberToGroup(String(hash));
overlay.remove();
$(document).off('click.addmember');
});
}

Expand Down Expand Up @@ -1568,13 +1575,38 @@ function renderDetailPanel() {

function formatConditionRule(rule) {
if (!rule || !rule.type) return 'Unknown condition';

const negation = rule.negated ? 'NOT ' : '';
const value = rule.settings?.value || rule.value || ''; // Support both formats

switch (rule.type) {
case 'messageCount': return `${negation}messageCount ${rule.operator || '>='} ${rule.value}`;
case 'emotion': return `${negation}emotion: ${rule.value}`;
case 'isGroupChat': return `${negation}isGroupChat`;
case 'speaker': return `${negation}speaker: ${rule.value}`;
default: return `${negation}${rule.type}: ${rule.value || ''}`;
case 'pattern':
return `${negation}Pattern: "${value}"`;
case 'speaker':
return `${negation}Speaker: ${value || 'undefined'}`;
case 'messageCount':
// Extract operator and number if value is like ">=100" or just "100"
const match = value.match(/^([><=!]+)?(\d+)$/);
if (match) {
const operator = match[1] || '>=';
const count = match[2];
return `${negation}Message Count ${operator} ${count}`;
}
return `${negation}Message Count: ${value}`;
case 'emotion':
return `${negation}Emotion: ${value}`;
case 'isGroupChat':
return `${negation}Is Group Chat`;
case 'timeOfDay':
// Handle different time formats
if (!value) return `${negation}Time of Day: (no time set)`;
return `${negation}Time of Day: ${value}`;
case 'randomChance':
// Value should be a percentage
const percent = value || rule.settings?.percent || '50';
return `${negation}Random Chance: ${percent}%`;
default:
return `${negation}${rule.type}: ${value || '(empty)'}`;
}
}

Expand Down