fix(tui): search session references by title

This commit is contained in:
Yichen Jiang
2026-07-28 11:05:53 +08:00
parent e7bf303827
commit a43a2032ec
13 changed files with 183 additions and 51 deletions

View File

@@ -10,7 +10,7 @@ import z from 'schemastery'
import type { Agent, HookContext } from '@deepseek-ai/dsh-agent'
import type { ContentBlock } from '@deepseek-ai/dsh-llm'
import type { JsonValue, SessionId } from '@deepseek-ai/dsh-session'
import type { SessionSurfaceSnapshot } from '@deepseek-ai/dsh-session-query'
import type { SessionSurfaceSnapshot, SessionTitleObservationResult } from '@deepseek-ai/dsh-session-query'
import {
DEFAULT_CANDIDATE_LIMIT,
DEFAULT_MAX_REFERENCE_BYTES,
@@ -102,7 +102,7 @@ export class SessionReferenceService extends Service {
/**
* List reference candidates, ranked by working-directory affinity.
* @param agent - target agent; self is excluded and its cwd drives ranking.
* @param query - optional case-insensitive session-id/cwd substring.
* @param query - optional case-insensitive session-id/cwd/title substring.
* @param limit - optional positive result cap.
* @param signal - optional cancellation boundary for host autocomplete teardown.
* @returns candidates labeled by latest title or, when absent, session id.
@@ -119,27 +119,42 @@ export class SessionReferenceService extends Service {
const needle = query.toLocaleLowerCase()
const targetCwd = agent.session.header.cwd
assertNotCancelled(signal)
const records = (await settleWithCancellation(this.ctx.sessionQuery.listSessions(), signal))
const records = (await settleWithCancellation(this.ctx.sessionQuery.listSessions(signal), signal))
.filter(record => record.header.id !== agent.id)
.filter((record) => {
if (needle === '') return true
return record.header.id.toLocaleLowerCase().includes(needle)
|| record.header.cwd?.toLocaleLowerCase().includes(needle) === true
})
.map((record, index) => ({ record, index }))
.sort((a, b) => candidateRank(a.record.header.cwd, targetCwd) - candidateRank(b.record.header.cwd, targetCwd)
|| a.index - b.index)
.slice(0, limit)
const titles = await settleWithCancellation(
Promise.all(records.map(({ record }) => this.ctx.sessionQuery.readTitle(record.header.id))),
const inspected = needle === ''
? records
.sort((a, b) => candidateRank(a.record.header.cwd, targetCwd) - candidateRank(b.record.header.cwd, targetCwd)
|| a.index - b.index)
.slice(0, limit)
: records
const observations = await settleWithCancellation(
this.ctx.sessionQuery.readTitleSnapshots(inspected.map(({ record }) => record.header.id), signal),
signal,
)
return records.map(({ record }, index) => ({
sessionId: record.header.id,
label: titles[index]?.title ?? record.header.id,
...record.header.cwd === undefined ? {} : { cwd: record.header.cwd },
createdAt: record.header.createdAt,
}))
return inspected.map(({ record, index }, observationIndex) => {
const observation = observations[observationIndex] as SessionTitleObservationResult
return {
record,
index,
label: observation.status === 'fulfilled'
? observation.value.title?.title ?? record.header.id
: record.header.id,
}
}).filter(({ record, label }) => {
if (needle === '') return true
return record.header.id.toLocaleLowerCase().includes(needle)
|| record.header.cwd?.toLocaleLowerCase().includes(needle) === true
|| label.toLocaleLowerCase().includes(needle)
}).sort((a, b) => candidateRank(a.record.header.cwd, targetCwd) - candidateRank(b.record.header.cwd, targetCwd)
|| a.index - b.index)
.slice(0, limit)
.map(({ record, label }) => ({
sessionId: record.header.id,
label,
...record.header.cwd === undefined ? {} : { cwd: record.header.cwd },
createdAt: record.header.createdAt,
}))
}
/**