# gloq
[](https://hex.pm/packages/gloq)
[](https://hexdocs.pm/gloq/)
[](https://github.com/AryaanSheth/gloq/actions/workflows/test.yml)
A Gleam library for the [GroqCloud](https://console.groq.com) inference API.
Build type-safe chat completion requests using a fluent builder, then send
them with any HTTP client you choose.
```sh
gleam add gloq
```
After adding, run `gleam deps download` if prompted.
---
## Quick start
```gleam
import gleam/httpc
import gleam/io
import gloq
import gloq/response
pub fn main() {
let assert Ok(res) =
gloq.default_groq_request()
|> gloq.with_key("YOUR_API_KEY")
|> gloq.with_context("What is the capital of France?")
|> gloq.build()
|> httpc.send()
let assert Ok(completion) = response.decode(res.body)
io.println(response.content(completion))
}
```
---
## Choosing a model
Import constants from `gloq/models` instead of using raw strings:
```gleam
import gloq
import gloq/models
gloq.default_groq_request()
|> gloq.with_key(api_key)
|> gloq.with_model(models.llama_3_3_70b_versatile)
|> gloq.with_context("Explain monads in one sentence.")
|> gloq.build()
```
Available model constants (see [`gloq/models`](src/gloq/models.gleam) for the full list):
| Constant | Model ID |
|---|---|
| `models.llama_3_3_70b_versatile` | `llama-3.3-70b-versatile` |
| `models.llama_3_1_8b_instant` | `llama-3.1-8b-instant` *(default)* |
| `models.llama_3_1_70b_versatile` | `llama-3.1-70b-versatile` |
| `models.mixtral_8x7b_32768` | `mixtral-8x7b-32768` |
| `models.gemma2_9b_it` | `gemma2-9b-it` |
| `models.deepseek_r1_distill_llama_70b` | `deepseek-r1-distill-llama-70b` |
---
## Multi-turn conversations
Use `add_user_message`, `add_assistant_message`, and `with_system_prompt` to
build a full conversation thread:
```gleam
gloq.default_groq_request()
|> gloq.with_key(api_key)
|> gloq.with_model(models.llama_3_3_70b_versatile)
|> gloq.with_system_prompt("You are a terse assistant. Reply in one sentence.")
|> gloq.add_user_message("What is Gleam?")
|> gloq.add_assistant_message("Gleam is a type-safe language that runs on the Erlang VM.")
|> gloq.add_user_message("What is its mascot?")
|> gloq.build()
```
---
## Structured JSON output
Pass `"json_object"` to `with_response_format` and instruct the model to
return JSON in the system prompt:
```gleam
gloq.default_groq_request()
|> gloq.with_key(api_key)
|> gloq.with_system_prompt("Respond only with valid JSON.")
|> gloq.with_context("Give me a person with a name and age.")
|> gloq.with_response_format("json_object")
|> gloq.build()
```
---
## Decoding responses
`gloq/response` provides types and a decoder for the API response:
```gleam
import gloq/response
case response.decode(res.body) {
Ok(completion) -> {
io.println(response.content(completion))
// completion.usage.total_tokens
// completion.model
// response.all_contents(completion)
}
Error(_) ->
// Try decoding an API error instead
case response.decode_error(res.body) {
Ok(err) -> io.println(err.message)
Error(_) -> io.println("Unknown error")
}
}
```
---
## All builder options
| Function | Type | Default | Description |
|---|---|---|---|
| `with_key` | `String` | `""` | GroqCloud API key |
| `with_model` | `String` | `"llama-3.1-8b-instant"` | Model to use |
| `with_context` | `String` | `""` | Single-turn prompt |
| `with_user` | `String` | `"user"` | Role label for single-turn message |
| `with_system_prompt` | `String` | — | System message prepended to every request |
| `add_user_message` | `String` | — | Append a user turn |
| `add_assistant_message` | `String` | — | Append an assistant turn |
| `with_messages` | `List(Message)` | `[]` | Replace the full message list |
| `with_temperature` | `Float` | `1.0` | 0–2, higher = more random |
| `with_top_p` | `Float` | `1.0` | Nucleus sampling threshold |
| `with_max_tokens` | `Int` | *(model default)* | Max tokens to generate |
| `with_frequency_penalty` | `Float` | `0.0` | -2.0–2.0, penalises repetition |
| `with_presence_penalty` | `Float` | `0.0` | -2.0–2.0, encourages new topics |
| `with_seed` | `Int` | — | Enables deterministic sampling |
| `with_stop` | `String` | — | Stop sequence |
| `with_stream` | `Bool` | `False` | Enable SSE streaming |
| `with_n` | `Int` | `1` | Number of completions (only 1 supported) |
| `with_logprobs` | `Bool` | — | Return token log probabilities |
| `with_parallel_tool_calls` | `Bool` | `True` | Allow parallel tool calls |
| `with_response_format` | `String` | — | `"json_object"` for structured output |
---
## Model listing
```gleam
import gleam/httpc
import gloq
// List all available models
let req = gloq.list_models(api_key)
// Get a specific model's details
let req = gloq.get_model(api_key, "llama-3.1-8b-instant")
```
---
## Migration from v1.x
### Changed defaults
- Default model changed from `"llama3-8b-8192"` to `"llama-3.1-8b-instant"`.
Set the model explicitly if you need the old default.
### `new_groq_request` behaviour
- `new_groq_request()` now returns `None` for all optional fields instead of
inheriting defaults. If you relied on `new_groq_request()` giving you
temperature `1.0` etc., switch to `default_groq_request()`.
### JSON body fix
- Optional fields that are `None` are no longer serialised. Previously `seed: None`
would send `"seed": 0` to the API; now it is omitted entirely.
### New fields on `GroqRequestBuilder`
- Three new fields were added: `system_prompt`, `messages`, `response_format`.
If you construct `GroqRequestBuilder(...)` directly (rather than using the
builder functions) you must add these fields. Recommended: use
`default_groq_request()` or `new_groq_request()` as a base.
### Removed dependencies
- `dot_env`, `dotenv`, and `gleam_httpc` were removed from the package
dependencies (they were never used). Run `gleam deps download` after updating.
### `send` is still present but deprecated
- `send/1` still works but remains deprecated. Use `build/1` with your own
HTTP client.
---
Further documentation at <https://hexdocs.pm/gloq>.