# GLM SDK

A Go SDK for interacting with the GLM (Zhipu AI) API, specifically designed for chat completions and text generation tasks.

## Features

- **Chat Completions**: Perform conversational AI interactions
- **Streaming Support**: Real-time streaming responses
- **Translation Helper**: Built-in convenience methods for translation tasks
- **Model Management**: List available models
- **Health Checks**: Service availability monitoring
- **Retry Logic**: Automatic retry with configurable attempts
- **Structured Logging**: Comprehensive logging support
- **Error Handling**: Detailed error types and handling

## Installation

```bash
go get tm/pkg/glm
```

## Quick Start

```go
package main

import (
    "context"
    "log"
    "tm/pkg/glm"
    "tm/pkg/logger"
)

func main() {
    // Create configuration
    config := &glm.Config{
        APIKey: "your-api-key-here",
        BaseURL: "https://api.z.ai",
    }

    // Create logger (you can use your preferred logger)
    logger := logger.NewLogger()

    // Create SDK instance
    sdk, err := glm.New(config, logger)
    if err != nil {
        log.Fatal(err)
    }

    // Simple chat
    ctx := context.Background()
    response, err := sdk.QuickChat(ctx, "Hello, how are you?")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(response)

    // Translation example (matching the provided curl request)
    translated, err := sdk.Translate(ctx, "IT-stöd för projekt- och portföljstyrning", "Swedish", "English")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(translated)
}
```

## Configuration

```go
config := &glm.Config{
    BaseURL:                "https://api.z.ai",        // API base URL
    APIKey:                 "your-api-key",            // Authentication key
    Timeout:                300 * time.Second,         // Request timeout
    RetryAttempts:          3,                         // Number of retries
    RetryDelay:             2 * time.Second,           // Delay between retries
    EnableLogging:          true,                      // Enable request logging
    UserAgent:              "MyApp/1.0",               // Custom user agent
    DefaultModel:           "glm-4.5",                 // Default model
    DefaultMaxTokens:       4096,                      // Default max tokens
    DefaultTopP:            1.0,                       // Default top_p
    DefaultTemperature:     0.7,                       // Default temperature
    EnableStreaming:        false,                     // Enable streaming by default
    EnableThinking:         false,                     // Enable thinking mode
}
```

## API Methods

### Chat Completion

```go
req := &glm.ChatCompletionRequest{
    Model: "glm-4.5",
    Messages: []glm.Message{
        {
            Role:    glm.MessageRoleSystem,
            Content: "You are a helpful assistant.",
        },
        {
            Role:    glm.MessageRoleUser,
            Content: "Explain quantum computing.",
        },
    },
    MaxTokens:        4096,
    TopP:             1.0,
    Temperature:      0.7,
    FrequencyPenalty: 0,
    PresencePenalty:  0,
    Thinking: &glm.Thinking{
        Type: "false",
    },
}

resp, err := sdk.ChatCompletion(ctx, req)
if err != nil {
    log.Fatal(err)
}

fmt.Println(resp.Choices[0].Message.Content)
```

### Streaming Chat Completion

```go
req := &glm.ChatCompletionRequest{
    Model: "glm-4.5",
    Messages: []glm.Message{
        {
            Role:    glm.MessageRoleUser,
            Content: "Tell me a long story.",
        },
    },
    Stream: true,
}

err := sdk.StreamChatCompletion(ctx, req, func(chunk *glm.StreamChatCompletionResponse) error {
    if len(chunk.Choices) > 0 {
        fmt.Print(chunk.Choices[0].Delta.Content)
    }
    return nil
})
```

### Convenience Methods

```go
// Simple chat
response, err := sdk.QuickChat(ctx, "Hello!")

// Chat with system prompt
response, err := sdk.QuickChatWithSystem(ctx, "You are a poet.", "Write a haiku about coding.")

// Translation (matching the curl example)
translated, err := sdk.Translate(ctx, "IT-stöd för projekt- och portföljstyrning", "Swedish", "English")

// Streaming chat
err := sdk.StreamQuickChat(ctx, "Tell me a story", func(chunk string) error {
    fmt.Print(chunk)
    return nil
})
```

## Error Handling

The SDK provides detailed error types:

```go
resp, err := sdk.ChatCompletion(ctx, req)
if err != nil {
    var glmErr *glm.Error
    if errors.As(err, &glmErr) {
        switch glmErr.Code {
        case glm.ErrCodeAuthentication:
            // Handle auth errors
        case glm.ErrCodeRateLimit:
            // Handle rate limits
        case glm.ErrCodeServerError:
            // Handle server errors
        }
    }
}
```

## Environment Variables

You can configure the SDK using environment variables:

```bash
export GLM_BASE_URL="https://api.z.ai"
export GLM_API_KEY="your-api-key"
export GLM_TIMEOUT="300s"
export GLM_RETRY_ATTEMPTS="3"
export GLM_DEFAULT_MODEL="glm-4.5"
export GLM_DEFAULT_MAX_TOKENS="4096"
```

## Testing

```bash
go test ./pkg/glm/...
```

## License

This SDK is part of the Tender Management system and follows the same licensing terms.
