scope session search by selected profile (#889)

This commit is contained in:
ekko
2026-05-21 09:48:31 +08:00
committed by GitHub
parent 3612a76735
commit 529065f023
6 changed files with 56 additions and 14 deletions
+2 -1
View File
@@ -71,11 +71,12 @@ export async function fetchHermesSessions(source?: string, limit?: number): Prom
return res.sessions
}
export async function searchSessions(q: string, source?: string, limit?: number): Promise<SessionSearchResult[]> {
export async function searchSessions(q: string, source?: string, limit?: number, profile?: string): Promise<SessionSearchResult[]> {
const params = new URLSearchParams()
params.set('q', q)
if (source) params.set('source', source)
if (limit) params.set('limit', String(limit))
if (profile) params.set('profile', profile)
const query = params.toString()
const res = await request<{ results: SessionSearchResult[] }>(`/api/hermes/search/sessions?${query}`)
return res.results
@@ -86,7 +86,7 @@ const showRenameModal = ref(false);
const renameValue = ref("");
const renameSessionId = ref<string | null>(null);
const renameInputRef = ref<InstanceType<typeof NInput> | null>(null);
const sessionProfileFilter = ref<string | null>(null);
const sessionProfileFilter = computed(() => chatStore.sessionProfileFilter);
const profileFilterOptions = computed(() => [
{ label: t("chat.allProfiles"), value: "__all__" },
...profilesStore.profiles.map((profile) => ({
@@ -96,8 +96,8 @@ const profileFilterOptions = computed(() => [
]);
async function handleProfileFilterChange(value: string) {
sessionProfileFilter.value = value === "__all__" ? null : value;
await chatStore.loadSessions(sessionProfileFilter.value);
chatStore.sessionProfileFilter = value === "__all__" ? null : value;
await chatStore.loadSessions(chatStore.sessionProfileFilter);
}
function sortSessionsWithActiveFirst(items: Session[]): Session[] {
@@ -311,7 +311,7 @@ async function handleBatchDelete() {
// Remove deleted sessions from local store (without calling API again)
// Use loadSessions to refresh from server instead of manual filtering
await chatStore.loadSessions();
await chatStore.loadSessions(chatStore.sessionProfileFilter);
message.success(t("chat.batchDeleteSuccess", { count: result.deleted }));
if (result.failed > 0) {
@@ -19,6 +19,7 @@ const recentSessions = ref<SessionSummary[]>([])
const searchResults = ref<SessionSearchResult[]>([])
const activeIndex = ref(0)
const inputRef = ref<InstanceType<typeof NInput> | null>(null)
const profileFilter = computed(() => chatStore.sessionProfileFilter || undefined)
let debounceTimer: ReturnType<typeof setTimeout> | null = null
let requestSeq = 0
@@ -79,7 +80,9 @@ async function loadRecentSessions() {
const seq = ++requestSeq
loading.value = true
try {
const sessions = await fetchSessions(undefined, 8)
const sessions = profileFilter.value
? await fetchSessions(undefined, 8, profileFilter.value)
: await fetchSessions(undefined, 8)
if (seq !== requestSeq) return
recentSessions.value = sessions
searchResults.value = []
@@ -99,7 +102,9 @@ async function runSearch(text: string) {
loading.value = true
try {
const results = text.trim()
? await searchSessions(text.trim(), undefined, 10)
? profileFilter.value
? await searchSessions(text.trim(), undefined, 10, profileFilter.value)
: await searchSessions(text.trim(), undefined, 10)
: []
if (seq !== requestSeq) return
searchResults.value = results
@@ -116,7 +121,7 @@ async function runSearch(text: string) {
async function ensureChatSessionsLoaded() {
if (chatStore.sessions.length === 0) {
await chatStore.loadSessions()
await chatStore.loadSessions(chatStore.sessionProfileFilter)
}
}
@@ -125,6 +130,23 @@ async function openItem(item: SearchItem) {
sessionSearchOpen.value = false
await ensureChatSessionsLoaded()
if (!chatStore.sessions.some(session => session.id === item.id) && typeof chatStore.addOrUpdateSession === 'function') {
chatStore.addOrUpdateSession({
id: item.id,
profile: item.profile || 'default',
title: item.title || '',
source: item.source,
messages: [],
createdAt: Math.round(item.started_at * 1000),
updatedAt: Math.round((item.last_active || item.ended_at || item.started_at) * 1000),
model: item.model,
provider: item.provider || item.billing_provider || '',
messageCount: item.message_count,
endedAt: item.ended_at != null ? Math.round(item.ended_at * 1000) : null,
lastActiveAt: item.last_active != null ? Math.round(item.last_active * 1000) : undefined,
workspace: item.workspace || null,
})
}
await chatStore.switchSession(item.id, messageId)
if (router.currentRoute.value.name !== 'hermes.chat') {
await router.push({ name: 'hermes.chat' })
@@ -333,6 +333,7 @@ export const useChatStore = defineStore('chat', () => {
const streamStates = ref<Map<string, { abort: () => void }>>(new Map())
/** sessionId → server-reported isWorking status */
const serverWorking = ref<Set<string>>(new Set())
const sessionProfileFilter = ref<string | null>(null)
/** sessionId → queued message count */
const queueLengths = ref<Map<string, number>>(new Map())
/** sessionId → queued user messages not yet visible in the transcript */
@@ -1945,6 +1946,7 @@ export const useChatStore = defineStore('chat', () => {
isStreaming,
isRunActive,
isSessionLive,
sessionProfileFilter,
compressionState,
abortState,
isAborting,