| from typing import Literal, TypedDict |
|
|
| import aiohttp |
|
|
| from astrbot.core import logger |
| from astrbot.core.utils.http_ssl import build_tls_connector |
|
|
|
|
| class LLMModalities(TypedDict): |
| input: list[Literal["text", "image", "audio", "video"]] |
| output: list[Literal["text", "image", "audio", "video"]] |
|
|
|
|
| class LLMLimit(TypedDict): |
| context: int |
| output: int |
|
|
|
|
| class LLMMetadata(TypedDict): |
| id: str |
| reasoning: bool |
| tool_call: bool |
| knowledge: str |
| release_date: str |
| modalities: LLMModalities |
| open_weights: bool |
| limit: LLMLimit |
|
|
|
|
| LLM_METADATAS: dict[str, LLMMetadata] = {} |
|
|
|
|
| async def update_llm_metadata() -> None: |
| url = "https://models.dev/api.json" |
| try: |
| async with aiohttp.ClientSession( |
| trust_env=True, connector=build_tls_connector() |
| ) as session: |
| async with session.get(url) as response: |
| data = await response.json() |
| global LLM_METADATAS |
| models = {} |
| for info in data.values(): |
| for model in info.get("models", {}).values(): |
| model_id = model.get("id") |
| if not model_id: |
| continue |
| models[model_id] = LLMMetadata( |
| id=model_id, |
| reasoning=model.get("reasoning", False), |
| tool_call=model.get("tool_call", False), |
| knowledge=model.get("knowledge", "none"), |
| release_date=model.get("release_date", ""), |
| modalities=model.get( |
| "modalities", {"input": [], "output": []} |
| ), |
| open_weights=model.get("open_weights", False), |
| limit=model.get("limit", {"context": 0, "output": 0}), |
| ) |
| |
| LLM_METADATAS.clear() |
| LLM_METADATAS.update(models) |
| logger.info(f"Successfully fetched metadata for {len(models)} LLMs.") |
| except Exception as e: |
| logger.error(f"Failed to fetch LLM metadata: {e}") |
| return |
|
|