Skip to content

Commit

Permalink
Add Tool Interaction Views (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
LeonNissen authored Dec 12, 2024
1 parent 940ffbe commit 2fa1a93
Show file tree
Hide file tree
Showing 13 changed files with 278 additions and 29 deletions.
4 changes: 2 additions & 2 deletions Sources/SpeziChat/ChatView+SpeechButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,14 @@ extension View {

#if DEBUG
#Preview {
@State var chat: Chat = .init(
@Previewable @State var chat: Chat = .init(
[
ChatEntity(role: .user, content: "User Message!"),
ChatEntity(role: .hidden(type: .unknown), content: "Hidden Message!"),
ChatEntity(role: .assistant, content: "Assistant Message!")
]
)
@State var muted = true
@Previewable @State var muted = true


return NavigationStack {
Expand Down
10 changes: 5 additions & 5 deletions Sources/SpeziChat/ChatView+SpeechOutput.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ extension View {

#if DEBUG
#Preview("ChatView") {
@State var chat: Chat = .init(
@Previewable @State var chat: Chat = .init(
[
ChatEntity(role: .user, content: "User Message!"),
ChatEntity(role: .hidden(type: .unknown), content: "Hidden Message!"),
Expand All @@ -129,12 +129,12 @@ extension View {
}

#Preview("ChatViewSpeechOutput") {
@State var chat: Chat = .init(
@Previewable @State var chat: Chat = .init(
[
ChatEntity(role: .assistant, content: "Assistant Message!")
]
)
@State var muted = false
@Previewable @State var muted = false


return NavigationStack {
Expand All @@ -144,12 +144,12 @@ extension View {
}

#Preview("ChatViewSpeechOutputDisabled") {
@State var chat: Chat = .init(
@Previewable @State var chat: Chat = .init(
[
ChatEntity(role: .assistant, content: "Assistant Message!")
]
)
@State var muted = true
@Previewable @State var muted = true


return NavigationStack {
Expand Down
2 changes: 1 addition & 1 deletion Sources/SpeziChat/MessageInputView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ public struct MessageInputView: View {

#if DEBUG
#Preview {
@State var chat = [
@Previewable @State var chat = [
ChatEntity(role: .user, content: "User Message!"),
ChatEntity(role: .hidden(type: .unknown), content: "Hidden Message!"),
ChatEntity(role: .assistant, content: "Assistant Message!")
Expand Down
28 changes: 25 additions & 3 deletions Sources/SpeziChat/MessageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public struct MessageView: View {

private var shouldDisplayMessage: Bool {
switch chat.role {
case .user, .assistant: return true
case .user, .assistant, .assistantToolCall, .assistantToolResponse: return true
case .hidden(let type):
if case .custom(let hiddenMessageTypes) = hideMessages {
return !hiddenMessageTypes.contains(type)
Expand All @@ -55,14 +55,30 @@ public struct MessageView: View {
}
}

private var isToolInteraction: Bool {
switch chat.role {
case .assistantToolCall, .assistantToolResponse:
true
default:
false
}
}

public var body: some View {
if shouldDisplayMessage {
HStack {
if chat.alignment == .trailing {
Spacer(minLength: 32)
}
Text(chat.attributedContent)
.chatMessageStyle(alignment: chat.alignment)
VStack(alignment: chat.horziontalAlignment) {
if isToolInteraction {
ToolInteractionView(entity: chat)
} else {
Text(chat.attributedContent)
.chatMessageStyle(alignment: chat.alignment)
}
}

if chat.alignment == .leading {
Spacer(minLength: 32)
}
Expand All @@ -89,6 +105,12 @@ public struct MessageView: View {
MessageView(ChatEntity(role: .assistant, content: "Assistant Message!"))
MessageView(ChatEntity(role: .user, content: "Long User Message that spans over two lines!"))
MessageView(ChatEntity(role: .assistant, content: "Long Assistant Message that spans over two lines!"))
MessageView(ChatEntity(role: .assistantToolCall, content: "assistent_too_call(parameter: value)"))
MessageView(ChatEntity(role: .assistantToolResponse, content: """
{
"some": "response"
}
"""))
MessageView(ChatEntity(role: .hidden(type: .unknown), content: "Hidden message! (invisible)"))
MessageView(
ChatEntity(
Expand Down
2 changes: 2 additions & 0 deletions Sources/SpeziChat/MessagesView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ public struct MessagesView: View {
[
ChatEntity(role: .user, content: "User Message!"),
ChatEntity(role: .hidden(type: .unknown), content: "Hidden Message (but still visible)!"),
ChatEntity(role: .assistantToolCall, content: "Assistant Message!"),
ChatEntity(role: .assistantToolResponse, content: "Assistant Message!f jiodsjfiods \n fudshfdusi"),
ChatEntity(role: .assistant, content: "Assistant Message!")
],
hideMessages: .custom(hiddenMessageTypes: [])
Expand Down
14 changes: 12 additions & 2 deletions Sources/SpeziChat/Models/ChatEntity+Alignment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

import Foundation
import SwiftUI


extension ChatEntity {
Expand All @@ -21,9 +22,18 @@ extension ChatEntity {
var alignment: Alignment {
switch self.role {
case .user:
return .trailing
.trailing
default:
return .leading
.leading
}
}

var horziontalAlignment: HorizontalAlignment {
switch self.alignment {
case .leading:
.leading
case .trailing:
.trailing
}
}
}
4 changes: 4 additions & 0 deletions Sources/SpeziChat/Models/ChatEntity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ public struct ChatEntity: Codable, Equatable, Hashable, Identifiable {
public enum Role: Codable, Equatable, Hashable {
case user
case assistant
case assistantToolCall
case assistantToolResponse
case hidden(type: ChatEntity.HiddenMessageType)


var rawValue: String {
switch self {
case .user: "user"
case .assistant: "assistant"
case .assistantToolCall: "assistant_tool_call"
case .assistantToolResponse: "assistant_tool_response"
case .hidden(let type): "hidden_\(type.name)"
}
}
Expand Down
120 changes: 118 additions & 2 deletions Sources/SpeziChat/Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,69 @@
}
}
},
"EQUAL_SIGN" : {
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gleichzeichen"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Equal Sign"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Signo igual"
}
}
}
},
"EXPORT_CHAT_BUTTON" : {
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Chat exportieren"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Export the Chat"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Exportar el chat"
}
}
}
},
"FUNCTION_F_OF_X" : {
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Funktion F von X"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Function F of X"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Función F de X"
}
}
}
},
Expand Down Expand Up @@ -75,6 +131,28 @@
}
}
},
"SEE_MORE" : {
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Details anzeigen"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Show Details"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ver detalles"
}
}
}
},
"SEND_MESSAGE" : {
"localizations" : {
"de" : {
Expand All @@ -98,18 +176,56 @@
}
},
"Text to speech is disabled, press to enable text to speech." : {

"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Die Spracheingabe ist deaktiviert, tippe um die Eingabe zu aktivieren."
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "La función de texto a voz está desactivada, pulse para activarla."
}
}
}
},
"Text to speech is enabled, press to disable text to speech." : {

"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Die Spracheingabe is aktiviert, tippe um die Eingabe zu dekativieren"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "La función de texto a voz está activada, pulse para desactivarla."
}
}
}
},
"TYPING_INDICATOR" : {
"localizations" : {
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Schreibanzeige"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Typing Indicator"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Indicador de mecanografía"
}
}
}
}
Expand Down
Loading

0 comments on commit 2fa1a93

Please sign in to comment.