Enable streaming UI updates for chat responses

This commit is contained in:
2025-10-01 20:09:40 +02:00
parent 4271ee3d73
commit a3e6b105d0
5 changed files with 375 additions and 162 deletions

View File

@@ -18,6 +18,7 @@ const defaultSessionPrefix = "session-"
// CompletionClient defines the subset of the OpenAI client used by the chat service.
type CompletionClient interface {
CreateChatCompletion(ctx context.Context, req openai.ChatCompletionRequest) (*openai.ChatCompletionResponse, error)
StreamChatCompletion(ctx context.Context, req openai.ChatCompletionRequest, handler openai.ChatCompletionStreamHandler) (*openai.ChatCompletionResponse, error)
}
// MessageRepository defines persistence hooks used by the chat service.
@@ -67,8 +68,9 @@ func NewService(logger *slog.Logger, modelCfg config.ModelConfig, client Complet
}, nil
}
// Send submits a user message and returns the assistant reply.
func (s *Service) Send(ctx context.Context, input string) (string, error) {
// Send submits a user message and returns the assistant reply. When streamHandler is provided and streaming is enabled,
// partial responses are forwarded to the handler as they arrive.
func (s *Service) Send(ctx context.Context, input string, streamHandler openai.ChatCompletionStreamHandler) (string, error) {
if s == nil {
return "", errors.New("service is nil")
}
@@ -99,7 +101,13 @@ func (s *Service) Send(ctx context.Context, input string) (string, error) {
s.logger.DebugContext(ctx, "sending chat completion", "model", s.model, "message_count", len(messages))
resp, err := s.client.CreateChatCompletion(ctx, req)
var resp *openai.ChatCompletionResponse
var err error
if s.stream {
resp, err = s.client.StreamChatCompletion(ctx, req, streamHandler)
} else {
resp, err = s.client.CreateChatCompletion(ctx, req)
}
if err != nil {
return "", err
}
@@ -127,6 +135,14 @@ func (s *Service) History() []openai.ChatMessage {
return historyCopy
}
// StreamingEnabled reports whether streaming completions are configured for this service.
func (s *Service) StreamingEnabled() bool {
if s == nil {
return false
}
return s.stream
}
// Reset clears the in-memory conversation history.
func (s *Service) Reset() {
if s == nil {