fafccd0d74
- Updated the worker initialization process to include the new GLM SDK, enhancing the worker's capabilities for translation tasks. - Modified the InitWorker function and NewNoticeWorker constructor to accept the GLM service, ensuring a cohesive integration. - Implemented the GLM service initialization and logging for successful setup, improving maintainability and usability. - Updated the NoticeWorker to utilize the GLM SDK for translating notice titles and descriptions, enhancing functionality and user experience.
278 lines
8.0 KiB
Go
278 lines
8.0 KiB
Go
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) {
|
|
cfg := DefaultConfig()
|
|
if config.BaseURL != "" {
|
|
cfg.BaseURL = config.BaseURL
|
|
}
|
|
if config.APIKey != "" {
|
|
cfg.APIKey = config.APIKey
|
|
}
|
|
if config.Timeout != 0 {
|
|
cfg.Timeout = config.Timeout
|
|
}
|
|
if config.RetryAttempts != 0 {
|
|
cfg.RetryAttempts = config.RetryAttempts
|
|
}
|
|
if config.RetryDelay != 0 {
|
|
cfg.RetryDelay = config.RetryDelay
|
|
}
|
|
if config.EnableLogging {
|
|
cfg.EnableLogging = config.EnableLogging
|
|
}
|
|
if config.UserAgent != "" {
|
|
cfg.UserAgent = config.UserAgent
|
|
}
|
|
if config.DefaultModel != "" {
|
|
cfg.DefaultModel = config.DefaultModel
|
|
}
|
|
if config.DefaultMaxTokens != 0 {
|
|
cfg.DefaultMaxTokens = config.DefaultMaxTokens
|
|
}
|
|
if config.DefaultTopP != 0 {
|
|
cfg.DefaultTopP = config.DefaultTopP
|
|
}
|
|
if config.DefaultTemperature != 0 {
|
|
cfg.DefaultTemperature = config.DefaultTemperature
|
|
}
|
|
if config.DefaultFrequencyPenalty != 0 {
|
|
cfg.DefaultFrequencyPenalty = config.DefaultFrequencyPenalty
|
|
}
|
|
if config.DefaultPresencePenalty != 0 {
|
|
cfg.DefaultPresencePenalty = config.DefaultPresencePenalty
|
|
}
|
|
if config.EnableStreaming {
|
|
cfg.EnableStreaming = config.EnableStreaming
|
|
}
|
|
if config.EnableThinking {
|
|
cfg.EnableThinking = config.EnableThinking
|
|
}
|
|
if config.TranslationOptions.Model != "" {
|
|
cfg.TranslationOptions.Model = config.TranslationOptions.Model
|
|
}
|
|
if config.TranslationOptions.MaxTokens != 0 {
|
|
cfg.TranslationOptions.MaxTokens = config.TranslationOptions.MaxTokens
|
|
}
|
|
if config.TranslationOptions.Temperature != 0 {
|
|
cfg.TranslationOptions.Temperature = config.TranslationOptions.Temperature
|
|
}
|
|
if config.TranslationOptions.FrequencyPenalty != 0 {
|
|
cfg.TranslationOptions.FrequencyPenalty = config.TranslationOptions.FrequencyPenalty
|
|
}
|
|
if config.TranslationOptions.PresencePenalty != 0 {
|
|
cfg.TranslationOptions.PresencePenalty = config.TranslationOptions.PresencePenalty
|
|
}
|
|
if config.TranslationOptions.TopP != 0 {
|
|
cfg.TranslationOptions.TopP = config.TranslationOptions.TopP
|
|
}
|
|
if config.TranslationOptions.EnableThinking {
|
|
cfg.TranslationOptions.EnableThinking = config.TranslationOptions.EnableThinking
|
|
}
|
|
|
|
client, err := NewClient(cfg, logger)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
service := NewService(client)
|
|
|
|
return &SDK{
|
|
service: service,
|
|
client: client,
|
|
config: cfg,
|
|
}, 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
|
|
}
|