Skip to content

Commit 90ad547

Browse files
Add feedback
1 parent 283572d commit 90ad547

File tree

832 files changed

+78227
-865
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

832 files changed

+78227
-865
lines changed

Sources/TranscriptDebugMenu/TranscriptDebugMenu.swift

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ import AppKit
99
#endif
1010
import SwiftUI
1111
import FoundationModels
12+
import OSLog
1213

13-
/// A SwiftUI view that displays a debug menu for viewing and copying `LanguageModelSession` transcripts.
14+
/// A SwiftUI view for inspecting, copying, and capturing feedback for `LanguageModelSession` transcripts.
1415
///
15-
/// `TranscriptDebugMenu` provides a list interface for inspecting
16-
/// language model session transcripts. Each transcript entry can be viewed and copied to the
17-
/// clipboard using a context menu.
16+
/// `TranscriptDebugMenu` shows transcript entries in a list with a context menu to copy any entry.
17+
/// It also lets you mark the conversation sentiment and automatically
18+
/// generates a `LanguageModelFeedbackAttachment` JSON file that can be submitted to Apple using [Feedback Assistant](https://feedbackassistant.apple.com/).
1819
///
1920
/// ## Usage
2021
///
@@ -38,10 +39,18 @@ import FoundationModels
3839
///}
3940
/// ```
4041
public struct TranscriptDebugMenu: View {
41-
4242
/// The language model session containing the transcript to display.
4343
let session: LanguageModelSession
4444

45+
private let feedbackFileURL: URL = FileManager.default
46+
.temporaryDirectory
47+
.appendingPathComponent(UUID().uuidString)
48+
.appendingPathExtension("json")
49+
50+
@State private var sentiment: LanguageModelFeedbackAttachment.Sentiment?
51+
@State private var feedbackDataFileSaved: Bool = false
52+
private let logger = Logger(subsystem: "com.artemnovichkov.TranscriptDebugMenu", category: "TranscriptDebugMenu")
53+
4554
/// Creates a new transcript debug menu for the specified session.
4655
///
4756
/// - Parameter session: The `LanguageModelSession` whose transcript will be displayed.
@@ -69,11 +78,62 @@ public struct TranscriptDebugMenu: View {
6978
}
7079
.overlay {
7180
if session.transcript.isEmpty {
72-
ContentUnavailableView("No entries", systemImage: "apple.intelligence", description: Text("The transcript is empty"))
81+
ContentUnavailableView("No entries",
82+
systemImage: "apple.intelligence",
83+
description: Text("The transcript is empty"))
7384

7485
}
7586
}
7687
.navigationTitle("Transcript")
88+
.toolbar {
89+
toolbar
90+
}
91+
.onAppear {
92+
saveFeedbackAttachment(sentiment: sentiment)
93+
}
94+
.onChange(of: sentiment) { _, newValue in
95+
saveFeedbackAttachment(sentiment: newValue)
96+
}
97+
}
98+
}
99+
100+
// MARK: - Private
101+
102+
@ToolbarContentBuilder
103+
private var toolbar: some ToolbarContent {
104+
ToolbarItem {
105+
Button {
106+
sentiment = sentiment == .negative ? nil : .negative
107+
} label: {
108+
Label("Negative",
109+
systemImage: "hand.thumbsdown" + (sentiment == .negative ? ".fill" : ""))
110+
}
111+
}
112+
ToolbarItem {
113+
Button {
114+
sentiment = sentiment == .positive ? nil : .positive
115+
} label: {
116+
Label("Positive",
117+
systemImage: "hand.thumbsup" + (sentiment == .positive ? ".fill" : "" ))
118+
}
119+
}
120+
ToolbarSpacer()
121+
ToolbarItem {
122+
ShareLink(item: feedbackFileURL)
123+
.disabled(!feedbackDataFileSaved)
124+
}
125+
}
126+
127+
/// Generates a `LanguageModelFeedbackAttachment` from the current `session` and `sentiment`,
128+
/// writes it as JSON to `feedbackFileURL`, and updates `fileSaved` accordingly.
129+
private func saveFeedbackAttachment(sentiment: LanguageModelFeedbackAttachment.Sentiment?) {
130+
let feedbackData = session.logFeedbackAttachment(sentiment: sentiment)
131+
do {
132+
try feedbackData.write(to: feedbackFileURL)
133+
feedbackDataFileSaved = true
134+
} catch {
135+
feedbackDataFileSaved = false
136+
logger.error("Failed to save feedback attachment: \(error.localizedDescription)")
77137
}
78138
}
79139
}

docs/data/documentation/transcriptdebugmenu.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
"doc://TranscriptDebugMenu/documentation/TranscriptDebugMenu/TranscriptDebugMenu": {
8989
"abstract" : [
9090
{
91-
"text" : "A SwiftUI view that displays a debug menu for viewing and copying ",
91+
"text" : "A SwiftUI view for inspecting, copying, and capturing feedback for ",
9292
"type" : "text"
9393
},
9494
{

docs/data/documentation/transcriptdebugmenu/transcriptdebugmenu.json

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"abstract" : [
33
{
4-
"text" : "A SwiftUI view that displays a debug menu for viewing and copying ",
4+
"text" : "A SwiftUI view for inspecting, copying, and capturing feedback for ",
55
"type" : "text"
66
},
77
{
@@ -113,23 +113,40 @@
113113
"type" : "codeVoice"
114114
},
115115
{
116-
"text" : " provides a list interface for inspecting",
116+
"text" : " shows transcript entries in a list with a context menu to copy any entry.",
117117
"type" : "text"
118118
},
119119
{
120120
"text" : " ",
121121
"type" : "text"
122122
},
123123
{
124-
"text" : "language model session transcripts. Each transcript entry can be viewed and copied to the",
124+
"text" : "It also lets you mark the conversation sentiment and automatically",
125125
"type" : "text"
126126
},
127127
{
128128
"text" : " ",
129129
"type" : "text"
130130
},
131131
{
132-
"text" : "clipboard using a context menu.",
132+
"text" : "generates a ",
133+
"type" : "text"
134+
},
135+
{
136+
"code" : "LanguageModelFeedbackAttachment",
137+
"type" : "codeVoice"
138+
},
139+
{
140+
"text" : " JSON file that can be submitted to Apple using ",
141+
"type" : "text"
142+
},
143+
{
144+
"identifier" : "https:\/\/feedbackassistant.apple.com\/",
145+
"isActive" : true,
146+
"type" : "reference"
147+
},
148+
{
149+
"text" : ".",
133150
"type" : "text"
134151
}
135152
],
@@ -248,7 +265,7 @@
248265
"doc://TranscriptDebugMenu/documentation/TranscriptDebugMenu/TranscriptDebugMenu": {
249266
"abstract" : [
250267
{
251-
"text" : "A SwiftUI view that displays a debug menu for viewing and copying ",
268+
"text" : "A SwiftUI view for inspecting, copying, and capturing feedback for ",
252269
"type" : "text"
253270
},
254271
{
@@ -390,6 +407,18 @@
390407
"identifier" : "doc:\/\/TranscriptDebugMenu\/s8SendableP",
391408
"title" : "Swift.Sendable",
392409
"type" : "unresolvable"
410+
},
411+
"https://feedbackassistant.apple.com/": {
412+
"identifier" : "https:\/\/feedbackassistant.apple.com\/",
413+
"title" : "Feedback Assistant",
414+
"titleInlineContent" : [
415+
{
416+
"text" : "Feedback Assistant",
417+
"type" : "text"
418+
}
419+
],
420+
"type" : "link",
421+
"url" : "https:\/\/feedbackassistant.apple.com\/"
393422
}
394423
}
395424
}

docs/data/documentation/transcriptdebugmenu/transcriptdebugmenu/accentcolor(_:).json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@
259259
"doc://TranscriptDebugMenu/documentation/TranscriptDebugMenu/TranscriptDebugMenu": {
260260
"abstract" : [
261261
{
262-
"text" : "A SwiftUI view that displays a debug menu for viewing and copying ",
262+
"text" : "A SwiftUI view for inspecting, copying, and capturing feedback for ",
263263
"type" : "text"
264264
},
265265
{

docs/data/documentation/transcriptdebugmenu/transcriptdebugmenu/accessibility(activationpoint:)-1cpab.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@
270270
"doc://TranscriptDebugMenu/documentation/TranscriptDebugMenu/TranscriptDebugMenu": {
271271
"abstract" : [
272272
{
273-
"text" : "A SwiftUI view that displays a debug menu for viewing and copying ",
273+
"text" : "A SwiftUI view for inspecting, copying, and capturing feedback for ",
274274
"type" : "text"
275275
},
276276
{

docs/data/documentation/transcriptdebugmenu/transcriptdebugmenu/accessibility(activationpoint:)-25mio.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@
270270
"doc://TranscriptDebugMenu/documentation/TranscriptDebugMenu/TranscriptDebugMenu": {
271271
"abstract" : [
272272
{
273-
"text" : "A SwiftUI view that displays a debug menu for viewing and copying ",
273+
"text" : "A SwiftUI view for inspecting, copying, and capturing feedback for ",
274274
"type" : "text"
275275
},
276276
{

docs/data/documentation/transcriptdebugmenu/transcriptdebugmenu/accessibility(addtraits:).json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@
278278
"doc://TranscriptDebugMenu/documentation/TranscriptDebugMenu/TranscriptDebugMenu": {
279279
"abstract" : [
280280
{
281-
"text" : "A SwiftUI view that displays a debug menu for viewing and copying ",
281+
"text" : "A SwiftUI view for inspecting, copying, and capturing feedback for ",
282282
"type" : "text"
283283
},
284284
{

docs/data/documentation/transcriptdebugmenu/transcriptdebugmenu/accessibility(hidden:).json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@
270270
"doc://TranscriptDebugMenu/documentation/TranscriptDebugMenu/TranscriptDebugMenu": {
271271
"abstract" : [
272272
{
273-
"text" : "A SwiftUI view that displays a debug menu for viewing and copying ",
273+
"text" : "A SwiftUI view for inspecting, copying, and capturing feedback for ",
274274
"type" : "text"
275275
},
276276
{

docs/data/documentation/transcriptdebugmenu/transcriptdebugmenu/accessibility(hint:).json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@
270270
"doc://TranscriptDebugMenu/documentation/TranscriptDebugMenu/TranscriptDebugMenu": {
271271
"abstract" : [
272272
{
273-
"text" : "A SwiftUI view that displays a debug menu for viewing and copying ",
273+
"text" : "A SwiftUI view for inspecting, copying, and capturing feedback for ",
274274
"type" : "text"
275275
},
276276
{

docs/data/documentation/transcriptdebugmenu/transcriptdebugmenu/accessibility(identifier:).json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@
270270
"doc://TranscriptDebugMenu/documentation/TranscriptDebugMenu/TranscriptDebugMenu": {
271271
"abstract" : [
272272
{
273-
"text" : "A SwiftUI view that displays a debug menu for viewing and copying ",
273+
"text" : "A SwiftUI view for inspecting, copying, and capturing feedback for ",
274274
"type" : "text"
275275
},
276276
{

0 commit comments

Comments
 (0)