First public release v2.3.1

This commit is contained in:
2026-02-19 16:39:23 +01:00
parent 52e3d0c07e
commit f3d673ab27
15 changed files with 1032 additions and 60 deletions

View File

@@ -418,6 +418,40 @@ final class DatabaseService: Sendable {
)
}
/// Update an existing conversation in-place: rename it, replace all its messages.
nonisolated func updateConversation(id: UUID, name: String, messages: [Message], primaryModel: String?) throws {
let nowString = isoFormatter.string(from: Date())
let messageRecords = messages.enumerated().compactMap { index, msg -> MessageRecord? in
guard msg.role != .system else { return nil }
return MessageRecord(
id: UUID().uuidString,
conversationId: id.uuidString,
role: msg.role.rawValue,
content: msg.content,
tokens: msg.tokens,
cost: msg.cost,
timestamp: isoFormatter.string(from: msg.timestamp),
sortOrder: index,
modelId: msg.modelId
)
}
try dbQueue.write { db in
try db.execute(
sql: "UPDATE conversations SET name = ?, updatedAt = ?, primaryModel = ? WHERE id = ?",
arguments: [name, nowString, primaryModel, id.uuidString]
)
try db.execute(
sql: "DELETE FROM messages WHERE conversationId = ?",
arguments: [id.uuidString]
)
for record in messageRecords {
try record.insert(db)
}
}
}
nonisolated func loadConversation(id: UUID) throws -> (Conversation, [Message])? {
try dbQueue.read { db in
guard let convRecord = try ConversationRecord.fetchOne(db, key: id.uuidString) else {
@@ -435,7 +469,8 @@ final class DatabaseService: Sendable {
let timestamp = self.isoFormatter.date(from: record.timestamp)
else { return nil }
return Message(
let starred = (try? MessageMetadataRecord.fetchOne(db, key: record.id))?.user_starred == 1
var message = Message(
id: msgId,
role: role,
content: record.content,
@@ -444,6 +479,8 @@ final class DatabaseService: Sendable {
timestamp: timestamp,
modelId: record.modelId
)
message.isStarred = starred
return message
}
guard let convId = UUID(uuidString: convRecord.id),