# `Gemini.APIs.Tokens`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.15.0/lib/gemini/apis/tokens.ex#L1)

Token counting functionality for Gemini API.

Provides comprehensive token counting capabilities including:
- Counting tokens for simple text content
- Counting tokens for multimodal content (text + images)
- Counting tokens for complete GenerateContentRequest structures
- Batch token counting operations

Token counting helps with:
- Request planning and validation
- Cost estimation and budgeting
- Content chunking and splitting
- Model selection based on token limits

## Examples

    # Simple text counting
    {:ok, response} = Tokens.count("Hello, world!")
    total_tokens = response.total_tokens

    # Multimodal content counting
    contents = [
      Content.text("What's in this image?"),
      Content.image("path/to/image.jpg")
    ]
    {:ok, response} = Tokens.count(contents)

    # Count tokens for a complete generation request
    {:ok, gen_request} = GenerateContentRequest.new("Hello", generation_config: config)
    {:ok, response} = Tokens.count_for_request(gen_request)

    # Batch counting for multiple inputs
    inputs = ["Text 1", "Text 2", "Text 3"]
    {:ok, results} = Tokens.count_batch(inputs)

# `check_fit`

```elixir
@spec check_fit(String.t() | [Gemini.Types.Content.t()], String.t() | nil, keyword()) ::
  {:ok, map()} | {:error, Gemini.Error.t()}
```

Check if content fits within a model's token limit.

## Parameters
- `content` - Content to check
- `model_name` - Model to check against (optional, uses default if not provided)
- `opts` - Options including:
  - `:buffer` - Safety buffer to subtract from limit (default: 100)
  - `:include_output` - Reserve space for output tokens (default: 1000)

## Returns
- `{:ok, %{fits: boolean(), tokens: integer(), limit: integer()}}` - Fit analysis
- `{:error, Error.t()}` - Error details

## Examples

    {:ok, analysis} = Tokens.check_fit("Hello world", "gemini-flash-lite-latest")
    # => {:ok, %{fits: true, tokens: 3, limit: 1000000, remaining: 999997}}

    # With output buffer
    {:ok, analysis} = Tokens.check_fit(long_text, include_output: 2000)

# `count`

```elixir
@spec count(
  String.t()
  | [Gemini.Types.Content.t()]
  | Gemini.Types.Request.GenerateContentRequest.t(),
  keyword()
) ::
  {:ok, Gemini.Types.Response.CountTokensResponse.t()}
  | {:error, Gemini.Error.t()}
```

Count tokens in the given content.

## Parameters
- `contents` - Content to count (string, list of Content structs, or GenerateContentRequest)
- `opts` - Options:
  - `:model` - Model name (default: from config)
  - `:generate_content_request` - Use full GenerateContentRequest for counting

## Returns
- `{:ok, CountTokensResponse.t()}` - Success with token count
- `{:error, Error.t()}` - Validation error, API error, or network failure

## Examples

    # Simple text
    {:ok, response} = Tokens.count("Hello, world!")
    # => %CountTokensResponse{total_tokens: 3}

    # Multiple contents
    contents = [
      Content.text("Hello"),
      Content.text("World")
    ]
    {:ok, response} = Tokens.count(contents)

    # With specific model
    {:ok, response} = Tokens.count("Hello", model: "gemini-2.5-pro")

    # Using GenerateContentRequest
    {:ok, gen_request} = GenerateContentRequest.new("Hello", generation_config: config)
    {:ok, response} = Tokens.count(gen_request)

# `count_batch`

```elixir
@spec count_batch(
  [String.t() | [Gemini.Types.Content.t()]],
  keyword()
) ::
  {:ok, [Gemini.Types.Response.CountTokensResponse.t()]}
  | {:error, Gemini.Error.t()}
```

Count tokens for multiple inputs in batch.

Efficiently counts tokens for multiple separate inputs, returning
results in the same order as the inputs.

## Parameters
- `inputs` - List of content inputs (strings or Content lists)
- `opts` - Options applied to all requests

## Returns
- `{:ok, [CountTokensResponse.t()]}` - List of token counts
- `{:error, Error.t()}` - Error details

## Examples

    inputs = [
      "Hello world",
      "How are you?",
      "Tell me a story about dragons"
    ]

    {:ok, results} = Tokens.count_batch(inputs)

    # Process results in your application code

    # With options
    {:ok, results} = Tokens.count_batch(inputs, model: "gemini-2.5-pro")

# `count_for_request`

```elixir
@spec count_for_request(
  Gemini.Types.Request.GenerateContentRequest.t(),
  keyword()
) ::
  {:ok, Gemini.Types.Response.CountTokensResponse.t()}
  | {:error, Gemini.Error.t()}
```

Count tokens for a GenerateContentRequest.

This is useful when you want to know the token count for a complete
generation request including all parameters, system instructions, etc.

## Parameters
- `generate_request` - A GenerateContentRequest struct
- `opts` - Options (model, etc.)

## Returns
- `{:ok, CountTokensResponse.t()}` - Token count for the complete request
- `{:error, Error.t()}` - Error details

## Examples

    # Create a generation request
    {:ok, gen_request} = GenerateContentRequest.new(
      "Explain quantum physics",
      generation_config: GenerationConfig.creative(),
      system_instruction: "You are a physics professor"
    )

    # Count tokens and use in your application code

# `estimate`

```elixir
@spec estimate(
  String.t() | [Gemini.Types.Content.t()] | map(),
  keyword()
) :: {:ok, integer()} | {:error, Gemini.Error.t()}
```

Estimate tokens for content without making an API call.

Provides a rough estimate of token count using heuristics.
Useful for quick validation and pre-filtering before actual counting.

## Parameters
- `content` - Content to estimate (string, Content list, or API map with :contents key)
- `opts` - Options (currently unused, for future expansion)

## Returns
- `{:ok, integer()}` - Estimated token count
- `{:error, Error.t()}` - Error if content is invalid

## Examples

    {:ok, estimate} = Tokens.estimate("Hello, world!")
    # => {:ok, 3}

    # For longer text
    text = "This is a longer piece of text that we want to estimate..."
    {:ok, estimate} = Tokens.estimate(text)

    # Also handles API maps (ADR-0001)
    {:ok, estimate} = Tokens.estimate(%{contents: [%{parts: [%{text: "Hello"}]}]})

## Note

This is a heuristic estimate and may not match the actual token count
from the API. Use `count/2` for accurate token counting.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
