Current section

Files

Jump to
gemini_ex lib gemini utils resource_names.ex
Raw

lib/gemini/utils/resource_names.ex

defmodule Gemini.Utils.ResourceNames do
@moduledoc """
Utilities for normalizing Google Cloud resource names for Gemini/Vertex AI.
"""
alias Gemini.Config
@doc """
Normalize cached content names for the active auth strategy.
- Gemini: ensures `cachedContents/` prefix.
- Vertex: expands short names to `projects/{project}/locations/{location}/cachedContents/{id}`.
"""
@spec normalize_cached_content_name(String.t(), keyword()) :: String.t()
def normalize_cached_content_name(name, opts \\ []) do
{auth_type, project_id, location} = resolve_auth(opts)
cond do
String.starts_with?(name, "projects/") ->
name
auth_type == :vertex_ai and String.starts_with?(name, "cachedContents/") ->
"projects/#{project_id}/locations/#{location}/#{name}"
auth_type == :vertex_ai and not String.contains?(name, "/") ->
"projects/#{project_id}/locations/#{location}/cachedContents/#{name}"
not String.starts_with?(name, "cachedContents/") ->
"cachedContents/#{name}"
true ->
name
end
end
@doc """
Normalize a cache model name for the active auth strategy.
- Gemini: ensures `models/` prefix.
- Vertex: expands to `projects/{project}/locations/{location}/publishers/google/models/{model}`.
"""
@spec normalize_cache_model_name(String.t(), keyword()) :: String.t()
def normalize_cache_model_name(model, opts \\ []) do
{auth_type, project_id, location} = resolve_auth(opts)
cond do
String.starts_with?(model, "projects/") ->
model
auth_type == :vertex_ai and String.starts_with?(model, "publishers/") ->
"projects/#{project_id}/locations/#{location}/#{model}"
auth_type == :vertex_ai and String.starts_with?(model, "models/") ->
trimmed = String.replace_prefix(model, "models/", "")
"projects/#{project_id}/locations/#{location}/publishers/google/models/#{trimmed}"
auth_type == :vertex_ai ->
"projects/#{project_id}/locations/#{location}/publishers/google/models/#{model}"
String.starts_with?(model, "models/") ->
model
true ->
"models/#{model}"
end
end
@doc """
Build the base cachedContents collection path for the active auth strategy.
"""
@spec cached_contents_path(keyword()) :: String.t()
def cached_contents_path(opts \\ []) do
{auth_type, project_id, location} = resolve_auth(opts)
case auth_type do
:vertex_ai -> "projects/#{project_id}/locations/#{location}/cachedContents"
_ -> "cachedContents"
end
end
defp resolve_auth(opts) do
auth_type = Keyword.get(opts, :auth) || auth_from_config()
project_id = Keyword.get(opts, :project_id) || credential(:project_id)
location = Keyword.get(opts, :location) || credential(:location)
if auth_type == :vertex_ai and (is_nil(project_id) or is_nil(location)) do
raise ArgumentError,
"project_id and location are required for Vertex AI cached content operations"
end
{auth_type, project_id, location}
end
defp auth_from_config do
case Config.auth_config() do
%{type: type} -> type
_ -> :gemini
end
end
defp credential(key) do
case Config.auth_config() do
%{credentials: creds} when is_map(creds) -> Map.get(creds, key)
_ -> nil
end
end
end