adds the ability to rename chats

This commit is contained in:
2026-05-28 22:22:55 -07:00
parent f79e5e02c5
commit cb8ea935fa
10 changed files with 455 additions and 59 deletions

View File

@@ -9,6 +9,7 @@ private struct MockClientCallSnapshot: Sendable {
var listSearches = 0
var createChat = 0
var getChat = 0
var updateChatTitle = 0
var getSearch = 0
var getActiveRuns = 0
var runCompletionStream = 0
@@ -32,6 +33,7 @@ private actor MockSybilClient: SybilAPIClienting {
private let chatDetails: [String: ChatDetail]
private let searchDetails: [String: SearchDetail]
private let createChatResponse: ChatSummary?
private let updateChatTitleResponses: [String: ChatSummary]
private let activeRunsResponse: ActiveRunsResponse
private var snapshot = MockClientCallSnapshot()
@@ -57,6 +59,7 @@ private actor MockSybilClient: SybilAPIClienting {
chatDetails: [String: ChatDetail] = [:],
searchDetails: [String: SearchDetail] = [:],
createChatResponse: ChatSummary? = nil,
updateChatTitleResponses: [String: ChatSummary] = [:],
activeRunsResponse: ActiveRunsResponse = ActiveRunsResponse(),
workspaceItemsResponse: [WorkspaceItem]? = nil
) {
@@ -66,6 +69,7 @@ private actor MockSybilClient: SybilAPIClienting {
self.chatDetails = chatDetails
self.searchDetails = searchDetails
self.createChatResponse = createChatResponse
self.updateChatTitleResponses = updateChatTitleResponses
self.activeRunsResponse = activeRunsResponse
}
@@ -182,6 +186,14 @@ private actor MockSybilClient: SybilAPIClienting {
return detail
}
func updateChatTitle(chatID: String, title: String) async throws -> ChatSummary {
snapshot.updateChatTitle += 1
guard let summary = updateChatTitleResponses[chatID] else {
throw UnexpectedClientCall()
}
return summary
}
func deleteChat(chatID: String) async throws {
throw UnexpectedClientCall()
}
@@ -461,6 +473,42 @@ private func makeSearchDetail(id: String, date: Date, answer: String) -> SearchD
#expect(viewModel.selectedChat?.messages.first?.content == "refreshed transcript")
}
@MainActor
@Test func renameChatUpdatesSidebarAndSelectedTranscriptTitle() async throws {
let date = Date(timeIntervalSince1970: 1_700_000_150)
let original = makeChatSummary(id: "chat-rename", date: date)
let renamed = ChatSummary(
id: "chat-rename",
title: "Renamed chat",
createdAt: date,
updatedAt: date.addingTimeInterval(60),
initiatedProvider: .openai,
initiatedModel: "gpt-4.1-mini",
lastUsedProvider: .openai,
lastUsedModel: "gpt-4.1-mini"
)
let detail = makeChatDetail(id: "chat-rename", date: date, body: "existing transcript")
let client = MockSybilClient(
chatsResponse: [original],
updateChatTitleResponses: ["chat-rename": renamed]
)
let viewModel = SybilViewModel(settings: testSettings(named: #function)) { _ in client }
viewModel.isAuthenticated = true
viewModel.isCheckingSession = false
viewModel.chats = [original]
viewModel.workspaceItems = [WorkspaceItem(chat: original)]
viewModel.selectedItem = .chat("chat-rename")
viewModel.selectedChat = detail
await viewModel.renameChat(chatID: "chat-rename", title: " Renamed chat ")
let snapshot = await client.currentSnapshot()
#expect(snapshot.updateChatTitle == 1)
#expect(viewModel.sidebarItems.first?.title == "Renamed chat")
#expect(viewModel.selectedChat?.title == "Renamed chat")
#expect(viewModel.errorMessage == nil)
}
@MainActor
@Test func foregroundSearchRefreshReloadsSelectedSearch() async throws {
let date = Date(timeIntervalSince1970: 1_700_000_200)