{"id":30228233,"url":"https://github.com/carlolepelaars/irouter","last_synced_at":"2025-08-14T19:39:38.778Z","repository":{"id":307366776,"uuid":"1029139383","full_name":"CarloLepelaars/irouter","owner":"CarloLepelaars","description":"Access 100s of LLMs with minimal lines of code","archived":false,"fork":false,"pushed_at":"2025-08-07T10:19:48.000Z","size":2281,"stargazers_count":15,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-07T11:46:08.971Z","etag":null,"topics":["agents","api","llm","multimodal","openrouter"],"latest_commit_sha":null,"homepage":"https://carlolepelaars.github.io/irouter/","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CarloLepelaars.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-30T15:24:05.000Z","updated_at":"2025-08-07T10:19:35.000Z","dependencies_parsed_at":"2025-07-30T23:06:46.718Z","dependency_job_id":null,"html_url":"https://github.com/CarloLepelaars/irouter","commit_stats":null,"previous_names":["carlolepelaars/irouter"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/CarloLepelaars/irouter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CarloLepelaars%2Firouter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CarloLepelaars%2Firouter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CarloLepelaars%2Firouter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CarloLepelaars%2Firouter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CarloLepelaars","download_url":"https://codeload.github.com/CarloLepelaars/irouter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CarloLepelaars%2Firouter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270474728,"owners_count":24590069,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-14T02:00:10.309Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agents","api","llm","multimodal","openrouter"],"created_at":"2025-08-14T19:39:34.880Z","updated_at":"2025-08-14T19:39:38.768Z","avatar_url":"https://github.com/CarloLepelaars.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# irouter\n\n![PyPI version](https://img.shields.io/pypi/v/irouter)\n![PyPI Downloads](https://static.pepy.tech/badge/irouter)\n![Python Version](https://img.shields.io/badge/dynamic/toml?url=https://raw.githubusercontent.com/carlolepelaars/irouter/master/pyproject.toml\u0026query=%24.project%5B%22requires-python%22%5D\u0026label=python\u0026color=blue) \n[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)\n\n`irouter` provides a simple interface to access 100s of LLMs with minimal lines of code.\n\n## Installation\n\n1. Install `irouter` from PyPI:\n\n```bash\npip install irouter\n```\n\n2. Create an account on [OpenRouter](https://openrouter.ai) and generate an API key.\n\n3a. (recommended!) Set the OpenRouter API key as an environment variable:\n\n```bash\nexport OPENROUTER_API_KEY=your_openrouter_api_key\n```\n\nIn this way you can use `irouter` objects like `Call` and `Chat` without having to pass an API key.\n\n```python\nfrom irouter import Call\nc = Call(\"moonshotai/kimi-k2:free\")\nc(\"How are you?\")\n```\n\n3b. Alternatively, pass `api_key` to `irouter` objects like `Call` and `Chat`.\n\n```python\nfrom irouter import Call\nc = Call(\"moonshotai/kimi-k2:free\", api_key=\"your_openrouter_api_key\")\nc(\"How are you?\")\n```\n\n## Usage\n\nBelow are basic usage examples of functionality in `irouter`. For more detailed examples, check out the `nbs` folder.\n\n### Call\n\n`Call` is the simplest interface to have one-off interactions with one or more LLMs (without tool support).\n\nFor conversational interactions use `Chat`, which tracks message history, token usage, and supports tool calling.\n\n#### Single LLM\n```python\nfrom irouter import Call\nc = Call(\"moonshotai/kimi-k2:free\")\nc(\"Who are you?\")\n# \"I'm Kimi, your AI friend from Moonshot AI. I'm here to chat, answer your questions, and help you out whenever you need it.\"\n```\n\n#### Multiple LLMs\n```python\nfrom irouter import Call\nc = Call([\"moonshotai/kimi-k2:free\", \"google/gemini-2.0-flash-exp:free\"])\nc(\"Who are you?\")\n# {'moonshotai/kimi-k2:free': \"I'm Kimi, your AI friend from Moonshot AI. I'm here to chat, answer your questions, and help you out whenever you need it.\",\n#  'google/gemini-2.0-flash-exp:free': 'I am a large language model, trained by Google.\\n'}\n```\n\n### Chat\n\n`Chat` is an easy way to interface with one or more LLMs, while tracking message history, token usage, and supporting tool calling.\n\n#### Single LLM\n\n```python\nfrom irouter import Chat\nc = Chat(\"moonshotai/kimi-k2:free\")\nc(\"Who are you?\")\nprint(c.history) # {'moonshotai/kimi-k2:free': [...]}\nprint(c.usage) # {'moonshotai/kimi-k2:free': {'prompt_tokens': 8, 'completion_tokens': 8, 'total_tokens': 16}}\n```\n\n#### Multiple LLMs\n\n```python\nfrom irouter import Chat\nc = Chat([\"moonshotai/kimi-k2:free\", \"google/gemini-2.0-flash-exp:free\"])\nc(\"Who are you?\")\nprint(c.history) \n# {'moonshotai/kimi-k2:free': [...], \n# 'google/gemini-2.0-flash-exp:free': [...]}\nprint(c.usage) \n# {'moonshotai/kimi-k2:free': {'prompt_tokens': 8, 'completion_tokens': 8, 'total_tokens': 16}, \n# 'google/gemini-2.0-flash-exp:free': {'prompt_tokens': 8, 'completion_tokens': 10, 'total_tokens': 18}}\n```\n\n### Image\n\nBoth `Call` and `Chat` support images from image URLs or local images.\n\nAdding images is as simple as providing a list of strings with:\n- text and/or\n- image URL(s) and/or\n- image path(s)\n\nMake sure to select an LLM that supports image input, like `gpt-4o-mini`.\n\n\u003cimg src=\"https://www.petlandflorida.com/wp-content/uploads/2022/04/shutterstock_1290320698-1-scaled.jpg\" alt=\"Example image\" width=\"300\"\u003e\n\n```python\nfrom irouter import Chat\nic = Chat(\"gpt-4o-mini\")\n# Image URL\nic([\"https://www.petlandflorida.com/wp-content/uploads/2022/04/shutterstock_1290320698-1-scaled.jpg\", \n    \"What is in the image?\"])\n# or local image\n# ic([\"../assets/puppy.jpg\", \"What is in the image?\"])\n# Example output:\n# The image shows a cute puppy, ..., The background is blurred, \n# with green hues suggesting an outdoors setting.\n\n# Images are tracked in history\nprint(ic.history)\n# [{'role': 'system', 'content': 'You are a helpful assistant.'}, \n#  {'role': 'user', 'content': [{'type': 'image_url', 'image_url':\n#  {'url': '...'}}, {'type': 'text', 'text': 'What is in the image?'}]}, \n#  {'role': 'assistant', 'content': 'The image shows a cute puppy...'}]\n```\n\nFor more information on `Chat`, check out the `chat.ipynb` notebook in the `nbs` folder.\n\n### PDF\n\nBoth `Call` and `Chat` support PDF processing from URLs or local files.\n\n```python\nfrom irouter import Call\nc = Call(\"moonshotai/kimi-k2:free\")\nc([\"https://proceedings.neurips.cc/paper_files/paper/2017/file/3f5ee243547dee91fbd053c1c4a845aa-Paper.pdf\", \n   \"What is the main contribution of this paper?\"])\n# 'The main contribution of this paper is the introduction of the Transformer architecture...'\n```\n\n### Audio\n\nSome LLMs have native audio support. Simply pass a local filepath that points to a `.mp3` or `.wav` file with an instruction as a list of strings.\n\n```python\nfrom irouter import Call\nc = Call(\"google/gemini-2.5-flash\")\nc([\"../assets/bottles.mp3\", \"What do you hear?\"])\n# 'I hear the sound of a glass bottle being opened and closed...'\n```\n\n### Multiple Modalities\n\nCombine text, images, PDFs, and audio in a single request. Simply pass a list of strings containing URLs, filepaths and/or text.\n\n```python\nfrom irouter import Call\nc = Call(\"google/gemini-2.5-flash\")\nc([\"../assets/bottles.mp3\", \"../assets/puppy.jpg\", \"What do you hear and see?\"])\n# 'I hear sounds of glass and see a small, fluffy dog...'\n```\n\n### Tool Usage\n\n`Chat` supports (multi-turn) tool calling, allowing LLMs to execute functions you provide. Simply pass a list of functions as the `tools` parameter. `irouter` will take care of the rest.\n\nTo ensure the best tool usage experience:\n\n- Use the [reStructuredText](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html) convention for function docstrings with `:param` tags, like the function below. In that case the tool schema will specifically include descriptions for each parameter.\n\n- Consider using type hints so the LLM knows what types to provide.\n\n```python\nfrom datetime import datetime\nfrom zoneinfo import ZoneInfo\n\ndef get_time(fmt: str=\"%Y-%m-%d %H:%M:%S\", tz: str=None) -\u003e str:\n    \"\"\"Returns the current time formatted as a string.\n\n    :param fmt: Format string for strftime.\n    :param tz: Optional timezone name (e.g., \"UTC\"). If given, uses that timezone.\n    :returns: The formatted current time.\n    \"\"\"\n    return datetime.now(ZoneInfo(tz)) if tz else datetime.now().strftime(fmt)\n\nchat = Chat(\"gpt-4o-mini\")\nresult = chat(\"What is the current time in New York City?\", tools=[get_time])\n# \"'The current time in New York City is 7:45 AM on August 5, 2025.\\n'\"\n```\n\n### Misc\n\n#### `get_all_models`\n\nYou can easily get an overview of all 300+ models available using `get_all_models`.\n\nAlternatively, browse [OpenRouter's models page](https://openrouter.ai/models) to view supported models on `irouter`.\n\n```python\nfrom irouter.base import get_all_models\nget_all_models()\n# ['llm_provider1/model1', ... 'llm_providerx/modelx']\n```\n\n## Credits\n\nThis project is built on top of the [OpenRouter](https://openrouter.ai) API infrastructure, which provides access to LLMs through a unified interface.\n\nThis project is inspired by [Answer.AI's](https://www.answer.ai) projects like [cosette](https://github.com/AnswerDotAI/cosette) and [claudette](https://github.com/AnswerDotAI/claudette).\n\n`irouter` generalizes this idea to support 100s of LLMs, which includes OpenAI, Anthropic and more. `irouter` also provides additional modalities and functionality to work with. This is possible thanks to [OpenRouter's](https://openrouter.ai) infrastructure.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarlolepelaars%2Firouter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcarlolepelaars%2Firouter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarlolepelaars%2Firouter/lists"}