ExAthena.ModelDiscovery (ExAthena v0.18.0)

Copy Markdown View Source

Generic HTTP-based model listing backed by an ETS TTL cache.

Reads the model_discovery block from a ProviderSpec and fetches the list of available model IDs from the provider's API endpoint. Results are cached in an ETS table for ttl_seconds (default: 300) before re-fetching.

model_discovery block

{
  "url": "https://openrouter.ai/api/v1/models",
  "path": "data.id",
  "headers": {"Authorization": "Bearer sk-or-..."},
  "ttl_seconds": 300
}
FieldRequiredDescription
urlyesHTTP GET endpoint that returns model metadata
pathnoDot-delimited path into the JSON response to extract IDs (default: "data.id")
headersnoAdditional request headers (e.g. auth)
ttl_secondsnoCache lifetime in seconds (default: 300)

Path extraction

path is a dot-delimited string. Traversal descends through map keys; when a list is encountered the remaining path is applied to each element and results are flattened. Examples:

  • "data.id" — extracts resp["data"][*]["id"]
  • "id" — extracts resp[*]["id"] when the root is a list
  • "" — returns root list elements (when they are strings)

Summary

Functions

Memoise fun's successful result under key for ttl_ms.

Returns a specification to start this module under a supervisor.

Return the list of available model IDs for the provider described by spec.

Functions

cached(key, ttl_ms, fun)

@spec cached(term(), non_neg_integer() | :no_cache, (-> result)) :: result
when result: term()

Memoise fun's successful result under key for ttl_ms.

This is the cache behind every kind of model listing in ExAthena — the ProviderSpec fetch above and the live endpoint enumeration in ExAthena.ModelListing both land here, so there is exactly one table, one TTL policy and one thing to clear in tests.

Only {:ok, _} is stored. Caching an error would turn a momentarily unreachable local daemon into an empty model picker for the rest of the TTL, which reads as "you have no models" rather than "I could not reach it".

Pass :no_cache as the TTL to force a fresh computation (and refresh the entry) — a user hitting "reload models" means it.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

list_models(spec)

@spec list_models(ExAthena.ProviderSpec.t()) :: {:ok, [String.t()]} | {:error, term()}

Return the list of available model IDs for the provider described by spec.

Returns {:ok, [String.t()]} from the ETS cache when a fresh entry exists, or fetches from the provider's model_discovery.url and caches the result.

Returns {:error, :no_model_discovery} when spec.model_discovery is nil.