-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathllm.go
More file actions
92 lines (78 loc) · 2.36 KB
/
llm.go
File metadata and controls
92 lines (78 loc) · 2.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package main
import (
"context"
"github.com/sashabaranov/go-openai"
)
// LLMStream represents a streaming response from an LLM provider.
// It yields deltas that may contain text content or tool call fragments.
type LLMStream interface {
// Recv returns the next streaming delta. Returns io.EOF when the stream is complete.
Recv() (LLMStreamDelta, error)
// Close closes the stream.
Close()
}
// LLMStreamDelta represents a single chunk from a streaming response.
type LLMStreamDelta struct {
// Content is a text fragment from the assistant's response.
Content string
// ToolCalls contains tool call fragments being streamed.
// A tool call with a non-empty ID signals a new tool call;
// subsequent deltas with empty ID append to the last tool call's arguments.
ToolCalls []openai.ToolCall
}
// LLMClient abstracts an LLM provider for creating streaming chat completions.
type LLMClient interface {
// CreateChatCompletionStream starts a streaming chat completion.
CreateChatCompletionStream(
model string,
messages []openai.ChatCompletionMessage,
tools []openai.Tool,
) (LLMStream, error)
}
// openAILLMClient wraps the go-openai client to implement LLMClient.
type openAILLMClient struct {
client *openai.Client
}
func newOpenAILLMClient(client *openai.Client) LLMClient {
return &openAILLMClient{client: client}
}
func (c *openAILLMClient) CreateChatCompletionStream(
model string,
messages []openai.ChatCompletionMessage,
tools []openai.Tool,
) (LLMStream, error) {
stream, err := c.client.CreateChatCompletionStream(
context.Background(),
openai.ChatCompletionRequest{
Model: model,
Messages: messages,
Tools: tools,
})
if err != nil {
return nil, err
}
return &openAILLMStream{stream: stream}, nil
}
// openAILLMStream wraps the go-openai stream to implement LLMStream.
type openAILLMStream struct {
stream *openai.ChatCompletionStream
}
func (s *openAILLMStream) Recv() (LLMStreamDelta, error) {
response, err := s.stream.Recv()
if err != nil {
return LLMStreamDelta{}, err
}
if len(response.Choices) == 0 {
return LLMStreamDelta{}, nil
}
delta := LLMStreamDelta{
Content: response.Choices[0].Delta.Content,
ToolCalls: response.Choices[0].Delta.ToolCalls,
}
return delta, nil
}
func (s *openAILLMStream) Close() {
s.stream.Close()
}
var _ LLMClient = (*openAILLMClient)(nil)
var _ LLMStream = (*openAILLMStream)(nil)