Add GLM SDK Implementation

- Introduced a new GLM SDK for interacting with the GLM (Zhipu AI) API, designed for chat completions and text generation tasks.
- Implemented core components including Client, Service, and SDK layers following Clean Architecture principles.
- Added configuration management, error handling, and structured logging for improved usability and maintainability.
- Included comprehensive documentation and usage examples to facilitate integration and understanding of the SDK's functionality.
- Enhanced the API with features such as chat completion, streaming responses, and model management, ensuring robust interaction with the GLM service.
This commit is contained in:
n.nakhostin
2025-11-04 16:09:44 +03:30
parent dae8eb44e2
commit a5d3a94c97
9 changed files with 1495 additions and 0 deletions
+213
View File
@@ -0,0 +1,213 @@
package glm
import (
"context"
"fmt"
"tm/pkg/logger"
)
// SDK provides a high-level interface for the GLM service
type SDK struct {
service GLMService
client *Client
config *Config
}
// New creates a new GLM SDK with the provided configuration and logger
func New(config *Config, logger logger.Logger) (*SDK, error) {
if config == nil {
config = DefaultConfig()
}
client, err := NewClient(config, logger)
if err != nil {
return nil, err
}
service := NewService(client)
return &SDK{
service: service,
client: client,
config: config,
}, nil
}
// ChatCompletion performs a chat completion request
func (s *SDK) ChatCompletion(ctx context.Context, req *ChatCompletionRequest) (*ChatCompletionResponse, error) {
return s.service.ChatCompletion(ctx, req)
}
// StreamChatCompletion performs a streaming chat completion request
func (s *SDK) StreamChatCompletion(ctx context.Context, req *ChatCompletionRequest, onChunk func(*StreamChatCompletionResponse) error) error {
return s.service.StreamChatCompletion(ctx, req, onChunk)
}
// ListModels lists available models
func (s *SDK) ListModels(ctx context.Context) (*ModelsResponse, error) {
return s.service.ListModels(ctx)
}
// Health checks if the GLM service is available
func (s *SDK) Health(ctx context.Context) error {
return s.service.Health(ctx)
}
// QuickChat is a convenience method for simple chat interactions
func (s *SDK) QuickChat(ctx context.Context, userMessage string) (string, error) {
req := &ChatCompletionRequest{
Model: s.config.DefaultModel,
Messages: []Message{
{
Role: MessageRoleUser,
Content: userMessage,
},
},
MaxTokens: s.config.DefaultMaxTokens,
TopP: s.config.DefaultTopP,
Temperature: s.config.DefaultTemperature,
FrequencyPenalty: s.config.DefaultFrequencyPenalty,
PresencePenalty: s.config.DefaultPresencePenalty,
}
if s.config.EnableThinking {
req.Thinking = &Thinking{Type: "true"}
}
resp, err := s.ChatCompletion(ctx, req)
if err != nil {
return "", err
}
if len(resp.Choices) == 0 {
return "", ErrInvalidResponse("no choices returned")
}
return resp.Choices[0].Message.Content, nil
}
// QuickChatWithSystem is a convenience method for chat with system prompt
func (s *SDK) QuickChatWithSystem(ctx context.Context, systemPrompt, userMessage string) (string, error) {
req := &ChatCompletionRequest{
Model: s.config.DefaultModel,
Messages: []Message{
{
Role: MessageRoleSystem,
Content: systemPrompt,
},
{
Role: MessageRoleUser,
Content: userMessage,
},
},
MaxTokens: s.config.DefaultMaxTokens,
TopP: s.config.DefaultTopP,
Temperature: s.config.DefaultTemperature,
FrequencyPenalty: s.config.DefaultFrequencyPenalty,
PresencePenalty: s.config.DefaultPresencePenalty,
}
if s.config.EnableThinking {
req.Thinking = &Thinking{Type: "true"}
}
resp, err := s.ChatCompletion(ctx, req)
if err != nil {
return "", err
}
if len(resp.Choices) == 0 {
return "", ErrInvalidResponse("no choices returned")
}
return resp.Choices[0].Message.Content, nil
}
// TranslateOptions represents options for translation
type TranslateOptions struct {
Model string `json:"model,omitempty"`
MaxTokens int `json:"max_tokens,omitempty"`
Temperature float64 `json:"temperature,omitempty"`
FrequencyPenalty float64 `json:"frequency_penalty,omitempty"`
PresencePenalty float64 `json:"presence_penalty,omitempty"`
TopP float64 `json:"top_p,omitempty"`
EnableThinking *bool `json:"enable_thinking,omitempty"`
}
// Translate is a convenience method for translation tasks using dynamic configuration parameters optimized for translation
func (s *SDK) Translate(ctx context.Context, text, fromLang, toLang string) (string, error) {
systemPrompt := "You are a high-precision translator specializing in professional tender documents. Always respond with only the translated text — no explanations, notes, or markdown formatting."
userMessage := fmt.Sprintf("Translate the following text from %s to %s accurately and professionally:\n\"%s\"", fromLang, toLang, text)
// Build request with custom options or defaults
req := &ChatCompletionRequest{
Model: s.config.TranslationOptions.Model,
Messages: []Message{
{
Role: MessageRoleSystem,
Content: systemPrompt,
},
{
Role: MessageRoleUser,
Content: userMessage,
},
},
MaxTokens: s.config.TranslationOptions.MaxTokens,
TopP: s.config.TranslationOptions.TopP,
Temperature: s.config.TranslationOptions.Temperature,
FrequencyPenalty: s.config.TranslationOptions.FrequencyPenalty,
PresencePenalty: s.config.TranslationOptions.PresencePenalty,
}
resp, err := s.ChatCompletion(ctx, req)
if err != nil {
return "", err
}
if len(resp.Choices) == 0 {
return "", ErrInvalidResponse("no choices returned")
}
return resp.Choices[0].Message.Content, nil
}
// StreamQuickChat is a convenience method for streaming chat interactions
func (s *SDK) StreamQuickChat(ctx context.Context, userMessage string, onChunk func(string) error) error {
req := &ChatCompletionRequest{
Model: s.config.DefaultModel,
Messages: []Message{
{
Role: MessageRoleUser,
Content: userMessage,
},
},
MaxTokens: s.config.DefaultMaxTokens,
TopP: s.config.DefaultTopP,
Temperature: s.config.DefaultTemperature,
FrequencyPenalty: s.config.DefaultFrequencyPenalty,
PresencePenalty: s.config.DefaultPresencePenalty,
Stream: true,
}
if s.config.EnableThinking {
req.Thinking = &Thinking{Type: "true"}
}
return s.StreamChatCompletion(ctx, req, func(chunk *StreamChatCompletionResponse) error {
if len(chunk.Choices) > 0 && chunk.Choices[0].Delta.Content != "" {
return onChunk(chunk.Choices[0].Delta.Content)
}
return nil
})
}
// GetService returns the underlying service for advanced usage
func (s *SDK) GetService() GLMService {
return s.service
}
// GetConfig returns the current configuration
func (s *SDK) GetConfig() *Config {
return s.config
}