groq

package
v0.0.0-...-0071670 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 25, 2025 License: Apache-2.0 Imports: 18 Imported by: 1

Documentation

Overview

Package groq implements a client for the Groq API.

It is described at https://console.groq.com/docs/api-reference

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ChatRequest

type ChatRequest struct {
	FrequencyPenalty  float64   `json:"frequency_penalty,omitzero"` // [-2.0, 2.0]
	MaxChatTokens     int64     `json:"max_completion_tokens,omitzero"`
	Messages          []Message `json:"messages"`
	Model             string    `json:"model"`
	ParallelToolCalls bool      `json:"parallel_tool_calls,omitzero"`
	PresencePenalty   float64   `json:"presence_penalty,omitzero"` // [-2.0, 2.0]
	ReasoningFormat   string    `json:"reasoning_format,omitzero"`
	ResponseFormat    struct {
		Type string `json:"type,omitzero"` // "json_object"
	} `json:"response_format,omitzero"`
	Seed          int64    `json:"seed,omitzero"`
	ServiceTier   string   `json:"service_tier,omitzero"` // "on_demand", "auto", "flex"
	Stop          []string `json:"stop,omitzero"`         // keywords to stop completion
	Stream        bool     `json:"stream"`
	StreamOptions struct {
		IncludeUsage bool `json:"include_usage,omitzero"`
	} `json:"stream_options,omitzero"`
	Temperature float64 `json:"temperature,omitzero"` // [0, 2]
	Tools       []Tool  `json:"tools,omitzero"`
	// Alternative when forcing a specific function. This can probably be achieved
	// by providing a single tool and ToolChoice == "required".
	// ToolChoice struct {
	// 	Type     string `json:"type,omitzero"` // "function"
	// 	Function struct {
	// 		Name string `json:"name,omitzero"`
	// 	} `json:"function,omitzero"`
	// } `json:"tool_choice,omitzero"`
	ToolChoice string  `json:"tool_choice,omitzero"` // "none", "auto", "required"
	TopP       float64 `json:"top_p,omitzero"`       // [0, 1]
	User       string  `json:"user,omitzero"`
}

https://console.groq.com/docs/api-reference#chat-create

func (*ChatRequest) Init

func (c *ChatRequest) Init(msgs genai.Messages, opts genai.Validatable) error

Init initializes the provider specific completion request with the generic completion request.

type ChatResponse

type ChatResponse struct {
	Choices []struct {
		// FinishReason is one of "stop", "length", "content_filter" or "tool_calls".
		FinishReason string          `json:"finish_reason"`
		Index        int64           `json:"index"`
		Message      MessageResponse `json:"message"`
		Logprobs     struct{}        `json:"logprobs"`
	} `json:"choices"`
	Created Time   `json:"created"`
	ID      string `json:"id"`
	Model   string `json:"model"`
	Object  string `json:"object"` // "chat.completion"
	Usage   struct {
		QueueTime    float64 `json:"queue_time"`
		PromptTokens int64   `json:"prompt_tokens"`
		PromptTime   float64 `json:"prompt_time"`
		ChatTokens   int64   `json:"completion_tokens"`
		ChatTime     float64 `json:"completion_time"`
		TotalTokens  int64   `json:"total_tokens"`
		TotalTime    float64 `json:"total_time"`
	} `json:"usage"`
	SystemFingerprint string `json:"system_fingerprint"`
	Xgroq             struct {
		ID string `json:"id"`
	} `json:"x_groq"`
}

func (*ChatResponse) ToResult

func (c *ChatResponse) ToResult() (genai.ChatResult, error)

type ChatStreamChunkResponse

type ChatStreamChunkResponse struct {
	ID                string `json:"id"`
	Object            string `json:"object"`
	Created           Time   `json:"created"`
	Model             string `json:"model"`
	SystemFingerprint string `json:"system_fingerprint"`
	Choices           []struct {
		Index int64 `json:"index"`
		Delta struct {
			Role    string `json:"role"`
			Content string `json:"content"`
		} `json:"delta"`
		Logprobs     struct{} `json:"logprobs"`
		FinishReason string   `json:"finish_reason"` // stop
	} `json:"choices"`
	Xgroq struct {
		ID    string `json:"id"`
		Usage struct {
			QueueTime    float64 `json:"queue_time"`
			PromptTokens int64   `json:"prompt_tokens"`
			PromptTime   float64 `json:"prompt_time"`
			ChatTokens   int64   `json:"completion_tokens"`
			ChatTime     float64 `json:"completion_time"`
			TotalTokens  int64   `json:"total_tokens"`
			TotalTime    float64 `json:"total_time"`
		} `json:"usage"`
	} `json:"x_groq"`
}

type Client

type Client struct {
	// Client is exported for testing replay purposes.
	Client httpjson.Client
	// contains filtered or unexported fields
}

Client implements the REST JSON based API.

func New

func New(apiKey, model string) (*Client, error)

New creates a new client to talk to the Groq platform API.

If apiKey is not provided, it tries to load it from the GROQ_API_KEY environment variable. If none is found, it returns an error. Get your API key at https://console.groq.com/keys If no model is provided, only functions that do not require a model, like ListModels, will work. To use multiple models, create multiple clients. Use one of the model from https://console.groq.com/dashboard/limits or https://console.groq.com/docs/models

func (*Client) Chat

func (c *Client) Chat(ctx context.Context, msgs genai.Messages, opts genai.Validatable) (genai.ChatResult, error)
Example (Tool_use)
package main

import (
	"context"
	"fmt"
	"log"

	_ "embed"
	"github.com/maruel/genai"
	"github.com/maruel/genai/groq"
)

func main() {
	// We must select a model that supports tool use. Use the smallest one.
	// See https://console.groq.com/docs/tool-use
	c, err := groq.New("", "llama-3.1-8b-instant")
	if err != nil {
		log.Fatal(err)
	}
	msgs := genai.Messages{
		genai.NewTextMessage(genai.User, "I wonder if Canada is a better country than the US? Call the tool best_country to tell me which country is the best one."),
	}
	var got struct {
		Country string `json:"country" jsonschema:"enum=Canada,enum=USA"`
	}
	opts := genai.ChatOptions{
		Seed:        1,
		Temperature: 0.01,
		MaxTokens:   50,
		Tools: []genai.ToolDef{
			{
				Name:        "best_country",
				Description: "A tool to determine the best country",
				InputsAs:    &got,
			},
		},
	}
	resp, err := c.Chat(context.Background(), msgs, &opts)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("Raw response: %#v", resp)
	if len(resp.ToolCalls) != 1 || resp.ToolCalls[0].Name != "best_country" {
		log.Fatal("Unexpected response")
	}
	if err := resp.ToolCalls[0].Decode(&got); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Best: %v\n", got.Country)
	// This would Output: Best: Canada
}
Output:

Example (Vision_and_JSON)
package main

import (
	"bytes"
	"context"
	"fmt"
	"log"

	_ "embed"
	"github.com/maruel/genai"
	"github.com/maruel/genai/groq"
)

// See the 3kib banana jpg online at
// https://github.com/maruel/genai/blob/main/groq/testdata/banana.jpg
//
//go:embed testdata/banana.jpg
var bananaJpg []byte

func main() {
	// We must select a model that supports vision *and* JSON mode (not
	// necessarily tool use).
	// See "JSON Mode with Images" at https://console.groq.com/docs/vision
	c, err := groq.New("", "llama-3.2-11b-vision-preview")
	if err != nil {
		log.Fatal(err)
	}
	msgs := genai.Messages{
		{
			Role: genai.User,
			Contents: []genai.Content{
				{Text: "Is it a banana? Reply as JSON with the form {\"banana\": false} or {\"banana\": true}."},
				{Filename: "banana.jpg", Document: bytes.NewReader(bananaJpg)},
			},
		},
	}
	opts := genai.ChatOptions{
		Seed:        1,
		Temperature: 0.01,
		MaxTokens:   50,
		ReplyAsJSON: true,
	}
	resp, err := c.Chat(context.Background(), msgs, &opts)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("Raw response: %#v", resp)
	if len(resp.Contents) != 1 {
		log.Fatal("Unexpected response")
	}
	var got struct {
		Banana bool `json:"banana"`
	}
	if err := resp.Contents[0].Decode(&got); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Banana: %v\n", got.Banana)
	// This would Output: Banana: true
}
Output:

func (*Client) ChatRaw

func (c *Client) ChatRaw(ctx context.Context, in *ChatRequest, out *ChatResponse) error

func (*Client) ChatStream

func (c *Client) ChatStream(ctx context.Context, msgs genai.Messages, opts genai.Validatable, chunks chan<- genai.MessageFragment) error
Example
package main

import (
	"context"
	"fmt"
	"log"
	"strings"

	_ "embed"
	"github.com/maruel/genai"
	"github.com/maruel/genai/groq"
)

func main() {
	// Using very small model for testing.
	// See https://console.groq.com/docs/models
	c, err := groq.New("", "llama-3.2-1b-preview")
	if err != nil {
		log.Fatal(err)
	}
	ctx := context.Background()
	msgs := genai.Messages{
		genai.NewTextMessage(genai.User, "Say hello. Use only one word."),
	}
	opts := genai.ChatOptions{
		Seed:        1,
		Temperature: 0.01,
		MaxTokens:   50,
	}
	chunks := make(chan genai.MessageFragment)
	end := make(chan genai.Message, 10)
	go func() {
		var pendingMsgs genai.Messages
		defer func() {
			for _, m := range pendingMsgs {
				end <- m
			}
			close(end)
		}()
		for {
			select {
			case <-ctx.Done():
				return
			case pkt, ok := <-chunks:
				if !ok {
					return
				}
				var err2 error
				if pendingMsgs, err2 = pkt.Accumulate(pendingMsgs); err2 != nil {
					end <- genai.NewTextMessage(genai.Assistant, fmt.Sprintf("Error: %v", err2))
					return
				}
			}
		}
	}()
	err = c.ChatStream(ctx, msgs, &opts, chunks)
	close(chunks)
	var responses genai.Messages
	for m := range end {
		responses = append(responses, m)
	}
	log.Printf("Raw responses: %#v", responses)
	if err != nil {
		log.Fatal(err)
	}
	if len(responses) != 1 {
		log.Fatal("Unexpected response")
	}
	resp := responses[0]
	if len(resp.Contents) != 1 {
		log.Fatal("Unexpected response")
	}
	// Normalize some of the variance. Obviously many models will still fail this test.
	fmt.Printf("Response: %s\n", strings.TrimRight(strings.TrimSpace(strings.ToLower(resp.Contents[0].Text)), ".!"))
	// This would Output: Response: hello
}
Output:

func (*Client) ChatStreamRaw

func (c *Client) ChatStreamRaw(ctx context.Context, in *ChatRequest, out chan<- ChatStreamChunkResponse) error

func (*Client) ListModels

func (c *Client) ListModels(ctx context.Context) ([]genai.Model, error)
Example
package main

import (
	"context"
	"fmt"
	"os"

	_ "embed"
	"github.com/maruel/genai/groq"
)

func main() {
	// Print something so the example runs.
	fmt.Println("Got models")
	c, err := groq.New("", "")
	if err != nil {
		fmt.Fprintf(os.Stderr, "Couldn't connect: %v\n", err)
		return
	}
	models, err := c.ListModels(context.Background())
	if err != nil {
		fmt.Printf("Failed to get models: %v\n", err)
		return
	}
	for _, model := range models {
		// The list of models will change over time. Print them to stderr so the
		// test doesn't capture them.
		fmt.Fprintf(os.Stderr, "- %s\n", model)
	}
}
Output:

Got models

type Content

type Content struct {
	Type string `json:"type,omitzero"` // "text", "image_url"

	// Type == "text"
	Text string `json:"text,omitzero"`

	// Type == "image_url"
	ImageURL struct {
		Detail string `json:"detail,omitzero"` // "auto", "low", "high"
		URL    string `json:"url,omitzero"`    // URL or base64 encoded image
	} `json:"image_url,omitzero"`
}

func (*Content) From

func (c *Content) From(in *genai.Content) error

type Message

type Message struct {
	Role       string     `json:"role"`          // "system", "assistant", "user"
	Name       string     `json:"name,omitzero"` // An optional name for the participant. Provides the model information to differentiate between participants of the same role.
	Content    []Content  `json:"content,omitzero"`
	ToolCalls  []ToolCall `json:"tool_calls,omitzero"`
	ToolCallID string     `json:"tool_call_id,omitzero"` // Docs says to not use.
}

https://console.groq.com/docs/api-reference#chat-create

func (*Message) From

func (m *Message) From(in *genai.Message) error

type MessageResponse

type MessageResponse struct {
	Role      genai.Role `json:"role"`
	Content   string     `json:"content"`
	ToolCalls []ToolCall `json:"tool_calls"`
}

func (*MessageResponse) To

func (m *MessageResponse) To(out *genai.Message) error

type Model

type Model struct {
	ID            string   `json:"id"`
	Object        string   `json:"object"`
	Created       Time     `json:"created"`
	OwnedBy       string   `json:"owned_by"`
	Active        bool     `json:"active"`
	ContextWindow int64    `json:"context_window"`
	PublicApps    []string `json:"public_apps"`
}

func (*Model) Context

func (m *Model) Context() int64

func (*Model) GetID

func (m *Model) GetID() string

func (*Model) String

func (m *Model) String() string

type Time

type Time int64

func (*Time) AsTime

func (t *Time) AsTime() time.Time

type Tool

type Tool struct {
	Type     string `json:"type,omitzero"` // "function"
	Function struct {
		Name        string             `json:"name,omitzero"`
		Description string             `json:"description,omitzero"`
		Parameters  *jsonschema.Schema `json:"parameters,omitzero"`
	} `json:"function,omitzero"`
}

type ToolCall

type ToolCall struct {
	Type     string `json:"type,omitzero"` // "function"
	ID       string `json:"id,omitzero"`
	Function struct {
		Name      string `json:"name,omitzero"`
		Arguments string `json:"arguments,omitzero"`
	} `json:"function,omitzero"`
}

func (*ToolCall) From

func (t *ToolCall) From(in *genai.ToolCall)

func (*ToolCall) To

func (t *ToolCall) To(out *genai.ToolCall)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL