11import AppKit
2+ import Foundation
23import LangChain
34import OpenAIService
45import PlaygroundSupport
56import SwiftUI
67
78struct QAForm : View {
8- @State var intermediateAnswers = [ String] ( )
9+ @State var intermediateAnswers = [ RefineDocumentChain . IntermediateAnswer] ( )
10+ @State var relevantDocuments = [ ( document: Document, distance: Float) ] ( )
11+ @State var duration : TimeInterval = 0
912 @State var answer : String = " "
1013 @State var question : String = " What is Swift macros? "
1114 @State var isProcessing : Bool = false
1215 @State var url : String = " https://developer.apple.com/documentation/swift/applying-macros "
1316
1417 var body : some View {
15- Form {
16- Section ( header: Text ( " Input " ) ) {
17- TextField ( " URL " , text: $url)
18- TextField ( " Question " , text: $question)
19- Button ( " Ask " ) {
20- Task {
21- do {
22- try await ask ( )
23- } catch {
24- answer = error. localizedDescription
18+ HStack ( spacing: 0 ) {
19+ ScrollView {
20+ Form {
21+ Section ( header: Text ( " Input " ) ) {
22+ TextField ( " URL " , text: $url)
23+ TextField ( " Question " , text: $question)
24+ HStack {
25+ Button ( " Ask " ) {
26+ Task {
27+ do {
28+ try await ask ( )
29+ } catch {
30+ answer = error. localizedDescription
31+ }
32+ }
33+ }
34+ . disabled ( isProcessing)
35+
36+ Text ( " \( duration) seconds " )
37+ }
38+ }
39+ Section ( header: Text ( " Answer " ) ) {
40+ Text ( answer)
41+ }
42+ Section ( header: Text ( " Intermediate Answers " ) ) {
43+ ForEach ( 0 ..< intermediateAnswers. endIndex, id: \. self) { index in
44+ let answer = intermediateAnswers [ index]
45+ VStack ( alignment: . leading) {
46+ Text ( answer. answer)
47+ VStack ( alignment: . leading) {
48+ Text ( " Usefulness: \( answer. usefulness) " )
49+ Text ( " Needs more context: \( answer. more ? " Yes " : " No " ) " )
50+ }
51+ . padding ( )
52+ . background {
53+ RoundedRectangle ( cornerRadius: 8 )
54+ . fill ( Color ( NSColor . textBackgroundColor) )
55+ }
56+ Divider ( )
57+ }
58+ . textSelection ( . enabled)
2559 }
2660 }
2761 }
28- . disabled ( isProcessing )
62+ . formStyle ( . grouped )
2963 }
30- Section ( header: Text ( " Answer " ) ) {
31- Text ( answer)
32- }
33- Section ( header: Text ( " Intermediate Answers " ) ) {
34- ForEach ( intermediateAnswers, id: \. self) { answer in
35- Text ( answer)
36- Divider ( )
37- }
64+
65+ ScrollView {
66+ Form {
67+ Section ( header: Text ( " Relevant Documents " ) ) {
68+ ForEach ( 0 ..< relevantDocuments. endIndex, id: \. self) { index in
69+ let document = relevantDocuments [ index]
70+ VStack ( alignment: . leading) {
71+ Text ( " \( document. distance) " )
72+ Text ( document. document. pageContent)
73+ Divider ( )
74+ }
75+ . textSelection ( . enabled)
76+ }
77+ }
78+ } . formStyle ( . grouped)
3879 }
3980 }
40- . formStyle ( . grouped)
4181 }
4282
4383 func ask( ) async throws {
84+ let start = Date ( ) . timeIntervalSince1970
85+ answer = " "
86+ relevantDocuments = [ ]
4487 intermediateAnswers = [ ]
88+ duration = 0
4589 isProcessing = true
4690 defer { isProcessing = false }
4791 guard let url = URL ( string: url) else {
4892 answer = " Invalid URL "
4993 return
5094 }
51- let chatGPTConfiguration = UserPreferenceChatGPTConfiguration ( )
52- . overriding { $0. temperature = 0 }
5395 let embeddingConfiguration = UserPreferenceEmbeddingConfiguration ( ) . overriding ( )
5496 let embedding = OpenAIEmbedding ( configuration: embeddingConfiguration)
5597 let store : VectorStore = try await {
@@ -72,8 +114,7 @@ struct QAForm: View {
72114
73115 let qa = RetrievalQAChain (
74116 vectorStore: store,
75- embedding: embedding,
76- chatModelFactory: { OpenAIChat ( configuration: chatGPTConfiguration, stream: false ) }
117+ embedding: embedding
77118 )
78119 answer = try await qa. run (
79120 question,
@@ -82,15 +123,19 @@ struct QAForm: View {
82123 $0. on ( CallbackEvents . RetrievalQADidGenerateIntermediateAnswer. self) {
83124 intermediateAnswers. append ( $0)
84125 }
126+ $0. on ( CallbackEvents . RetrievalQADidExtractRelevantContent. self) {
127+ relevantDocuments = $0
128+ }
85129 } ,
86130 ]
87131 )
132+ duration = Date ( ) . timeIntervalSince1970 - start
88133 }
89134}
90135
91136let hostingView = NSHostingController (
92137 rootView: QAForm ( )
93- . frame ( width: 600 , height: 800 )
138+ . frame ( width: 800 , height: 800 )
94139)
95140
96141PlaygroundPage . current. needsIndefiniteExecution = true
0 commit comments