@@ -4,10 +4,10 @@ import (
44 "context"
55 "encoding/json"
66 "fmt"
7+ "iter"
78 "sync"
89
9- "github.com/google/generative-ai-go/genai"
10- "google.golang.org/api/option"
10+ "google.golang.org/genai"
1111)
1212
1313const DefaultModel = "gemini-2.5-flash"
@@ -16,101 +16,117 @@ const DefaultModel = "gemini-2.5-flash"
1616type ChatSession struct {
1717 ctx context.Context
1818
19- client * genai.Client
20- model * genai.GenerativeModel
21- session * genai.ChatSession
19+ client * genai.Client
20+ chat * genai.Chat
21+ config * genai.GenerateContentConfig
22+ model string
2223
2324 loadModels sync.Once
2425 models []string
2526}
2627
2728// NewChatSession returns a new [ChatSession].
28- func NewChatSession (
29- ctx context.Context , modelBuilder * GenerativeModelBuilder , apiKey string ,
30- ) (* ChatSession , error ) {
31- client , err := genai .NewClient (ctx , option .WithAPIKey (apiKey ))
29+ func NewChatSession (ctx context.Context , model string , safetySettings []* genai.SafetySetting ) (* ChatSession , error ) {
30+ client , err := genai .NewClient (ctx , nil )
3231 if err != nil {
33- return nil , err
32+ return nil , fmt .Errorf ("failed to create client: %w" , err )
33+ }
34+
35+ config := & genai.GenerateContentConfig {SafetySettings : safetySettings }
36+ chat , err := client .Chats .Create (ctx , model , config , nil )
37+ if err != nil {
38+ return nil , fmt .Errorf ("failed to create chat: %w" , err )
3439 }
3540
36- generativeModel := modelBuilder .build (client )
3741 return & ChatSession {
38- ctx : ctx ,
39- client : client ,
40- model : generativeModel ,
41- session : generativeModel .StartChat (),
42+ ctx : ctx ,
43+ client : client ,
44+ chat : chat ,
45+ config : config ,
46+ model : model ,
4247 }, nil
4348}
4449
4550// SendMessage sends a request to the model as part of a chat session.
4651func (c * ChatSession ) SendMessage (input string ) (* genai.GenerateContentResponse , error ) {
47- return c .session .SendMessage (c .ctx , genai .Text ( input ) )
52+ return c .chat .SendMessage (c .ctx , genai.Part { Text : input } )
4853}
4954
5055// SendMessageStream is like SendMessage, but with a streaming request.
51- func (c * ChatSession ) SendMessageStream (input string ) * genai.GenerateContentResponseIterator {
52- return c .session .SendMessageStream (c .ctx , genai .Text (input ))
53- }
54-
55- // SetModel sets a new generative model configured with the builder and starts
56- // a new chat session. It preserves the history of the previous chat session.
57- func (c * ChatSession ) SetModel (modelBuilder * GenerativeModelBuilder ) {
58- history := c .session .History
59- c .model = modelBuilder .build (c .client )
60- c .session = c .model .StartChat ()
61- c .session .History = history
62- }
63-
64- // CopyModelBuilder returns a copy builder for the chat generative model.
65- func (c * ChatSession ) CopyModelBuilder () * GenerativeModelBuilder {
66- return newCopyGenerativeModelBuilder (c .model )
56+ func (c * ChatSession ) SendMessageStream (input string ) iter.Seq2 [* genai.GenerateContentResponse , error ] {
57+ return c .chat .SendMessageStream (c .ctx , genai.Part {Text : input })
6758}
6859
6960// ModelInfo returns information about the chat generative model in JSON format.
7061func (c * ChatSession ) ModelInfo () (string , error ) {
71- modelInfo , err := c .model . Info (c .ctx )
62+ modelInfo , err := c .client . Models . Get (c .ctx , c . model , nil )
7263 if err != nil {
7364 return "" , err
7465 }
66+
7567 encoded , err := json .MarshalIndent (modelInfo , "" , " " )
7668 if err != nil {
7769 return "" , fmt .Errorf ("error encoding model info: %w" , err )
7870 }
71+
7972 return string (encoded ), nil
8073}
8174
8275// ListModels returns a list of the supported generative model names.
8376func (c * ChatSession ) ListModels () []string {
8477 c .loadModels .Do (func () {
8578 c .models = []string {DefaultModel }
86- iter := c .client .ListModels (c .ctx )
87- for {
88- modelInfo , err := iter .Next ()
79+ for model , err := range c .client .Models .All (c .ctx ) {
8980 if err != nil {
90- break
81+ continue
9182 }
92- c .models = append (c .models , modelInfo .Name )
83+ c .models = append (c .models , model .Name )
9384 }
9485 })
9586 return c .models
9687}
9788
89+ // SetModel sets the chat generative model.
90+ func (c * ChatSession ) SetModel (model string ) error {
91+ chat , err := c .client .Chats .Create (c .ctx , model , c .config , c .GetHistory ())
92+ if err != nil {
93+ return fmt .Errorf ("failed to set model: %w" , err )
94+ }
95+
96+ c .model = model
97+ c .chat = chat
98+ return nil
99+ }
100+
98101// GetHistory returns the chat session history.
99102func (c * ChatSession ) GetHistory () []* genai.Content {
100- return c .session .History
103+ return c .chat .History ( true )
101104}
102105
103106// SetHistory sets the chat session history.
104- func (c * ChatSession ) SetHistory (content []* genai.Content ) {
105- c .session .History = content
107+ func (c * ChatSession ) SetHistory (history []* genai.Content ) error {
108+ chat , err := c .client .Chats .Create (c .ctx , c .model , c .config , history )
109+ if err != nil {
110+ return fmt .Errorf ("failed to set history: %w" , err )
111+ }
112+
113+ c .chat = chat
114+ return nil
106115}
107116
108117// ClearHistory clears the chat session history.
109- func (c * ChatSession ) ClearHistory () {
110- c . session . History = make ([] * genai. Content , 0 )
118+ func (c * ChatSession ) ClearHistory () error {
119+ return c . SetHistory ( nil )
111120}
112121
113- // Close closes the chat session.
114- func (c * ChatSession ) Close () error {
115- return c .client .Close ()
122+ // SetSystemInstruction sets the chat session system instruction.
123+ func (c * ChatSession ) SetSystemInstruction (systemInstruction * genai.Content ) error {
124+ c .config .SystemInstruction = systemInstruction
125+ chat , err := c .client .Chats .Create (c .ctx , c .model , c .config , c .GetHistory ())
126+ if err != nil {
127+ return fmt .Errorf ("failed to set system instruction: %w" , err )
128+ }
129+
130+ c .chat = chat
131+ return nil
116132}
0 commit comments