55// Created by Michel-Andre Chirita on 30/12/2024.
66//
77
8- import Combine
98import OllamaKit
109import SwiftUI
1110
1211struct ChatWithFormatView : View {
13-
12+
1413 enum ViewState {
1514 case idle
1615 case loading
1716 case error( String )
1817 }
19-
18+
2019 @Environment ( ViewModel . self) private var viewModel
21-
20+
2221 @State private var model : String ? = nil
2322 /// TIP: be sure to include "return as JSON" in your prompt
2423 @State private var prompt = " Lists of the 10 biggest countries in the world with their iso code as id, name and capital, return as JSON "
25- @State private var cancellables = Set < AnyCancellable > ( )
2624 @State private var viewState : ViewState = . idle
27-
25+
2826 @State private var responseItems : [ ResponseItem ] = [ ]
29-
27+
3028 var body : some View {
3129 NavigationStack {
3230 Form {
@@ -37,29 +35,28 @@ struct ChatWithFormatView: View {
3735 . tag ( model as String ? )
3836 }
3937 }
40-
38+
4139 TextField ( " Prompt " , text: $prompt, axis: . vertical)
4240 . lineLimit ( 5 )
4341 }
44-
42+
4543 Section {
4644 Button ( " Chat Async " , action: actionAsync)
47- Button ( " Chat Combine " , action: actionCombine)
4845 }
49-
46+
5047 switch viewState {
5148 case . idle:
5249 EmptyView ( )
53-
50+
5451 case . loading:
5552 ProgressView ( )
5653 . id ( UUID ( ) )
57-
54+
5855 case . error( let error) :
5956 Text ( error)
6057 . foregroundStyle ( . red)
6158 }
62-
59+
6360 Section ( " Response " ) {
6461 ForEach ( responseItems) { item in
6562 Text ( " Country: " + item. country + " , capital: " + item. capital)
@@ -73,16 +70,16 @@ struct ChatWithFormatView: View {
7370 }
7471 }
7572 }
76-
73+
7774 func actionAsync( ) {
7875 clearResponse ( )
79-
76+
8077 guard let model = model else { return }
8178 let messages = [ OKChatRequestData . Message ( role: . user, content: prompt) ]
8279 var data = OKChatRequestData ( model: model, messages: messages, format: getFormat ( ) )
8380 data. options = OKCompletionOptions ( temperature: 0 ) /// TIP: better results with temperature = 0
8481 self . viewState = . loading
85-
82+
8683 Task {
8784 do {
8885 var message : String = " "
@@ -101,38 +98,7 @@ struct ChatWithFormatView: View {
10198 }
10299 }
103100 }
104-
105- func actionCombine( ) {
106- clearResponse ( )
107-
108- guard let model = model else { return }
109- let messages = [ OKChatRequestData . Message ( role: . user, content: prompt) ]
110- var data = OKChatRequestData ( model: model, messages: messages, format: getFormat ( ) )
111- data. options = OKCompletionOptions ( temperature: 0 ) /// TIP: better results with temperature = 0
112- self . viewState = . loading
113-
114- var message : String = " "
115- viewModel. ollamaKit. chat ( data: data)
116- . compactMap { $0. message? . content }
117- . scan ( " " , { result, nextChunk in
118- result + nextChunk
119- } )
120- . sink { completion in
121- switch completion {
122- case . finished:
123- print ( " Finished " )
124- decodeResponse ( message)
125- self . viewState = . idle
126- case . failure( let error) :
127- print ( " Error: " , error. localizedDescription)
128- self . viewState = . error( error. localizedDescription)
129- }
130- } receiveValue: { value in
131- message = value
132- }
133- . store ( in: & cancellables)
134- }
135-
101+
136102 private func getFormat( ) -> OKJSONValue {
137103 return
138104 . object( [ " type " : . string( " array " ) ,
@@ -147,7 +113,7 @@ struct ChatWithFormatView: View {
147113 ] )
148114 ] )
149115 }
150-
116+
151117 private func decodeResponse( _ content: String ) {
152118 do {
153119 guard let data = content. data ( using: . utf8) else { return }
@@ -158,7 +124,7 @@ struct ChatWithFormatView: View {
158124 self . viewState = . error( error. localizedDescription)
159125 }
160126 }
161-
127+
162128 private func clearResponse( ) {
163129 self . responseItems = [ ]
164130 }
0 commit comments