feat(session-title): integrate queries ACP and TUI

This commit is contained in:
Tianyi Cui
2026-07-21 01:53:37 +08:00
parent 58dc5f94de
commit f71f96d292
131 changed files with 6142 additions and 5771 deletions

View File

@@ -39,6 +39,7 @@ import { errorChain } from '@deepseek-ai/dsh-llm'
import type { ContentBlock, StreamChunk, TokenUsage } from '@deepseek-ai/dsh-llm'
import type {} from '@deepseek-ai/dsh-llm-retry'
import { SessionId, type Session, type SessionEvent, type TodoItem } from '@deepseek-ai/dsh-session'
import { foldSessionTitle } from '@deepseek-ai/dsh-session-title'
import type {
FileDiff,
TerminalCallView,
@@ -286,7 +287,7 @@ function textBlocks(content: readonly ContentBlock[], type: 'text' | 'reasoning'
class HeaderComponent implements Component {
constructor(
private readonly agent: Agent,
private readonly welcome: string,
private readonly subtitle: () => string,
private readonly palette: Palette,
) {}
@@ -299,7 +300,7 @@ class HeaderComponent implements Component {
const detail = `${model}${displayText(this.agent.session.id)}`
const top = this.palette.accent(`${'─'.repeat(Math.max(0, width - 2))}`)
const bottom = this.palette.accent(`${'─'.repeat(Math.max(0, width - 2))}`)
const lines = [title, this.palette.muted(displayText(this.welcome)), this.palette.dim(detail)]
const lines = [title, this.palette.muted(displayText(this.subtitle())), this.palette.dim(detail)]
.flatMap(line => wrapTextWithAnsi(line, usable))
.map((line) => {
const clipped = truncateToWidth(line, usable, '')
@@ -858,7 +859,8 @@ export function createTuiChat(
let activeQuestion: PendingQuestion | undefined
const welcome = config.welcome ?? 'ready.'
const header = new HeaderComponent(agent, welcome, palette)
let sessionTitle = foldSessionTitle(agent.session.events)?.title
const header = new HeaderComponent(agent, () => sessionTitle ?? welcome, palette)
const footer = new FooterComponent(agent, palette, () => toolsExpanded, () => showReasoning, () => tokens)
ui.addChild(header)
ui.addChild(chat)
@@ -868,7 +870,12 @@ export function createTuiChat(
ui.addChild(editor)
ui.addChild(footer)
ui.setFocus(editor)
runtime.terminal.setTitle(displayText(resolved.title))
const updateTerminalTitle = (): void => {
runtime.terminal.setTitle(displayText(
sessionTitle === undefined ? resolved.title : `${sessionTitle}${resolved.title}`,
))
}
updateTerminalTitle()
const requestRender = (): void => {
footer.invalidate()
@@ -997,6 +1004,11 @@ export function createTuiChat(
case 'todo/write':
todo.update(event.data.todos)
break
case 'session/title':
sessionTitle = event.data.title
header.invalidate()
updateTerminalTitle()
break
case 'turn/end':
clearStreaming()
if (event.data.reason.kind === 'error') {