InteractiveSession handles bidirectional streaming for interactive mode.
(stream pb.ChatCLIService_InteractiveSessionServer)
| 103 | |
| 104 | // InteractiveSession handles bidirectional streaming for interactive mode. |
| 105 | func (h *Handler) InteractiveSession(stream pb.ChatCLIService_InteractiveSessionServer) error { |
| 106 | h.logger.Info(i18n.T("server.session.interactive_started")) |
| 107 | if h.sessionMetrics != nil { |
| 108 | h.sessionMetrics.ActiveSessions.Inc() |
| 109 | defer h.sessionMetrics.ActiveSessions.Dec() |
| 110 | } |
| 111 | |
| 112 | var ( |
| 113 | history []models.Message |
| 114 | mu sync.Mutex |
| 115 | ) |
| 116 | |
| 117 | for { |
| 118 | msg, err := stream.Recv() |
| 119 | if errors.Is(err, io.EOF) { |
| 120 | h.logger.Info(i18n.T("server.session.interactive_ended")) |
| 121 | return nil |
| 122 | } |
| 123 | if err != nil { |
| 124 | h.logger.Error(i18n.T("server.session.interactive_recv_error"), zap.Error(err)) |
| 125 | return err |
| 126 | } |
| 127 | |
| 128 | switch msg.Type { |
| 129 | case pb.SessionMessage_USER_INPUT: |
| 130 | mu.Lock() |
| 131 | history = append(history, models.Message{Role: "user", Content: msg.Content}) |
| 132 | |
| 133 | llmClient, err := h.getClient(msg.Metadata["provider"], msg.Metadata["model"], msg.Metadata["client_api_key"], nil) |
| 134 | if err != nil { |
| 135 | mu.Unlock() |
| 136 | sendErr := stream.Send(&pb.SessionMessage{ |
| 137 | Type: pb.SessionMessage_ERROR, |
| 138 | Content: i18n.T("server.session.interactive_llm_error", err), |
| 139 | }) |
| 140 | if sendErr != nil { |
| 141 | return sendErr |
| 142 | } |
| 143 | continue |
| 144 | } |
| 145 | |
| 146 | maxTokens := 0 // use default |
| 147 | enrichedContent := h.enrichPrompt(msg.Content) |
| 148 | response, err := llmClient.SendPrompt(stream.Context(), enrichedContent, history, maxTokens) |
| 149 | if err != nil { |
| 150 | mu.Unlock() |
| 151 | sendErr := stream.Send(&pb.SessionMessage{ |
| 152 | Type: pb.SessionMessage_ERROR, |
| 153 | Content: i18n.T("server.session.interactive_llm_response_error", err), |
| 154 | }) |
| 155 | if sendErr != nil { |
| 156 | return sendErr |
| 157 | } |
| 158 | continue |
| 159 | } |
| 160 | |
| 161 | history = append(history, models.Message{Role: "assistant", Content: response}) |
| 162 | mu.Unlock() |
nothing calls this directly
no test coverage detected