{"id":48341295,"url":"https://github.com/dvaji/infera","last_synced_at":"2026-04-22T04:02:52.099Z","repository":{"id":346247961,"uuid":"1174748099","full_name":"dvaJi/infera","owner":"dvaJi","description":"A fast, provider-agnostic CLI for discovering, connecting, and executing AI apps and models from multiple providers through one consistent interface.","archived":false,"fork":false,"pushed_at":"2026-03-23T15:39:51.000Z","size":186395,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-23T20:31:51.458Z","etag":null,"topics":["ai","ai-providers","cli","falai","openrouter","replicate","tool"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dvaJi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-06T19:50:48.000Z","updated_at":"2026-03-23T19:40:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dvaJi/infera","commit_stats":null,"previous_names":["dvaji/infera"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/dvaJi/infera","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvaJi%2Finfera","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvaJi%2Finfera/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvaJi%2Finfera/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvaJi%2Finfera/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dvaJi","download_url":"https://codeload.github.com/dvaJi/infera/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvaJi%2Finfera/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31424931,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T02:22:46.605Z","status":"ssl_error","status_checked_at":"2026-04-05T02:22:33.263Z","response_time":75,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["ai","ai-providers","cli","falai","openrouter","replicate","tool"],"created_at":"2026-04-05T05:01:31.227Z","updated_at":"2026-04-22T04:02:52.093Z","avatar_url":"https://github.com/dvaJi.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# infs\n\nA fast, provider-agnostic CLI for discovering, connecting, and executing AI apps and models from multiple providers through one consistent interface.\n\n## What is infs?\n\n`infs` lets you run AI models from multiple providers using a single, unified command-line interface. Instead of learning each provider's SDK or API, you use one tool with a consistent command structure.\n\n```\ninfs app run openrouter/anthropic/claude-sonnet-4-5 --input '{\"prompt\":\"Explain quantum computing\"}'\ninfs app run falai/fal-ai/flux/dev --input '{\"prompt\":\"a cat astronaut in space\"}'\ninfs app list --category image\n```\n\n## Why this exists\n\nEvery AI provider has its own API shape, auth flow, and SDK. `infs` wraps them behind a single interface so developers and coding agents can:\n\n- **Discover** what models are available across providers\n- **Connect** to providers with a single interactive command\n- **Run** any model using a consistent input/output contract\n- **Script** AI workflows without provider-specific boilerplate\n\n## Current Status\n\n| Provider | Category | Status | Auth | App Listing |\n|---|---|---|---|---|\n| OpenRouter | LLM | ✅ Fully implemented | API key | Live from API when connected, static fallback when not |\n| fal.ai | Image | ✅ Listing live + run implemented | API key | Live from `api.fal.ai/v1/models` when connected |\n| Replicate | Image | ✅ Listing live + run implemented | API key | Live from `api.replicate.com/v1/models` when connected |\n| WaveSpeed AI | Image/Video | ✅ Listing live + run implemented | API key | Live from `api.wavespeed.ai/api/v3/models` when connected |\n\n**OpenRouter** is the reference implementation: full end-to-end API key auth and model execution work today. When connected, `app list` fetches live from the OpenRouter API.\n\n**WaveSpeed AI** is also fully implemented: model listing and image/video generation both work end-to-end. When connected, `app list` fetches live from the WaveSpeed API, and `app run` submits an inference task and polls for the result.\n\n**fal.ai** and **Replicate** are also fully implemented: live model listing and inference both work. `app run` submits a job and polls for the result.\n\n## Installation\n\n### Quick install (recommended)\n\n**macOS / Linux:**\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/dvaji/infera/main/install.sh | bash\n```\n\n**Windows (PowerShell):**\n\n```powershell\niex \"\u0026 { $(irm https://raw.githubusercontent.com/dvaji/infera/main/install.ps1) }\"\n```\n\nThe installer will download the latest release and place it in `~/.local/bin` (Unix) or `%USERPROFILE%\\.local\\bin` (Windows). You may need to add this directory to your PATH.\n\n### Download a pre-built binary\n\nPre-built binaries are attached to every [GitHub Release](https://github.com/dvaJi/infera/releases/latest).\nDownload the binary for your platform and place it somewhere on your `PATH`:\n\n| Platform | File |\n|---|---|\n| Linux x86_64 | `infs-linux-x86_64` |\n| Linux aarch64 (ARM) | `infs-linux-aarch64` |\n| macOS aarch64 (Apple Silicon) | `infs-macos-aarch64` |\n| Windows x86_64 | `infs-windows-x86_64.exe` |\n\n### Chocolatey (Windows)\n\n```powershell\nchoco install infs\n```\n\nThe package installs `infs.exe` and adds the `infs` command to your PATH.\n\n**macOS / Linux quick-install example:**\n\n```bash\n# Replace \u003cversion\u003e and \u003cplatform\u003e with the appropriate values\ncurl -fsSL https://github.com/dvaji/infera/releases/download/\u003cversion\u003e/infs-\u003cplatform\u003e \\\n  -o infs\nchmod +x infs\nsudo mv infs /usr/local/bin/\n# Or install to a user-writable path (no sudo required):\n# mkdir -p ~/.local/bin \u0026\u0026 mv infs ~/.local/bin/\n```\n\n### Self-update\n\nOnce installed, `infs` can update itself:\n\n```bash\n# Check for updates\ninfs self check\n\n# Update to the latest version\ninfs self update\n\n# Skip confirmation prompt\ninfs self update --yes\n```\n\n### Build from source\n\n```bash\ngit clone https://github.com/dvaji/infera\ncd infera\ncargo build --release\n# Binary is at ./target/release/infs\n```\n\nTo install globally:\n\n```bash\ncargo install --path .\n```\n\n**Requirements:** Rust 1.75+ ([install via rustup](https://rustup.rs))\n\n## Usage\n\n### Provider management\n\n```bash\n# List all providers and their connection status\ninfs provider list\n\n# Connect to a provider (interactive)\ninfs provider connect openrouter\n\n# Show details for a specific provider\ninfs provider show openrouter\n\n# Disconnect from a provider\ninfs provider disconnect openrouter\n```\n\n### App/model management\n\n```bash\n# List providers and whether they are ready to use\ninfs app list\n\n# List all models for a specific provider\ninfs app list openrouter\ninfs app list falai\n\n# Filter by category\ninfs app list --category image\ninfs app list --category llm\n\n# Filter a provider's models by category\ninfs app list openrouter --category llm\n\n# Paginate results (page number and items per page)\ninfs app list openrouter --page 2 --per-page 50\n\n# Show details for a specific app\ninfs app show openrouter/anthropic/claude-sonnet-4-5\n```\n\n`infs app list` has two modes:\n\n- Without a provider, it shows providers with status like `available` or `needs credentials`\n- With a provider argument, it lists that provider's models and supports pagination (`--page` and `--per-page` flags)\n\n### Running apps\n\n```bash\n# Run an LLM via OpenRouter\ninfs app run openrouter/anthropic/claude-sonnet-4-5 --input '{\"prompt\":\"Explain quantum computing\"}'\n\n# Run GPT-4o\ninfs app run openrouter/openai/gpt-4o --input '{\"prompt\":\"Write a haiku about Rust\"}'\n\n# Run a free model\ninfs app run openrouter/meta-llama/llama-3.1-8b-instruct --input '{\"prompt\":\"What is 2+2?\"}'\n\n# Stream LLM response token by token\ninfs app run openrouter/openai/gpt-4o --input '{\"prompt\":\"Count to 10\"}' --stream\n\n# Image generation via WaveSpeed AI\ninfs app run wavespeed/wavespeed-ai/flux-schnell --input '{\"prompt\":\"a cat astronaut in space\"}'\n\n# Nano Banana 2 text-to-image via WaveSpeed AI\ninfs app run wavespeed/google/nano-banana-2 --input '{\"prompt\":\"a serene mountain lake at sunset\"}'\n\n# Image generation via fal.ai\ninfs app run falai/fal-ai/flux/dev --input '{\"prompt\":\"a cat astronaut in space\"}'\n\n# Save generated image to file (auto-detects extension)\ninfs app run wavespeed/google/nano-banana-2 --input '{\"prompt\":\"a cat\"}' --output image\n\n# Save generated image with specific extension\ninfs app run wavespeed/google/nano-banana-2 --input '{\"prompt\":\"a cat\"}' --output image.png\n\n# Use local image file with multimodal model (OpenRouter)\ninfs app run openrouter/openai/gpt-4o --file photo.jpg --prompt \"What's in this image?\"\n\n# Use local image file with WaveSpeed image editing\ninfs app run wavespeed/google/nano-banana-2/edit --file input.png --prompt \"Make it sepia\"\n\n# Multiple image files\ninfs app run openrouter/openai/gpt-4o --file img1.png --file img2.jpg --prompt \"Compare these images\"\n```\n\n### Utilities\n\n```bash\n# Show config file location\ninfs config path\n\n# Check connection status and diagnose issues\ninfs doctor\n```\n\n## Providers\n\n### OpenRouter\n\nOpenRouter provides a unified API for hundreds of LLM models from OpenAI, Anthropic, Google, Meta, Mistral, and many more.\n\n**Website:** https://openrouter.ai  \n**Get an API key:** https://openrouter.ai/keys\n\n**Models included in built-in catalog:**\n- `openrouter/openai/gpt-4o` — GPT-4o\n- `openrouter/openai/gpt-4o-mini` — GPT-4o Mini\n- `openrouter/anthropic/claude-sonnet-4-5` — Claude Sonnet 4.5\n- `openrouter/google/gemini-flash-1.5` — Gemini Flash 1.5\n- `openrouter/meta-llama/llama-3.1-8b-instruct` — Llama 3.1 8B (free)\n- `openrouter/mistralai/mistral-7b-instruct` — Mistral 7B (free)\n\nAny model available on OpenRouter can be run using its OpenRouter model ID (e.g., `openrouter/cohere/command-r-plus`).\n\n### fal.ai\n\nfal.ai provides fast, serverless image generation APIs.\n\n**Website:** https://fal.ai  \n**Get an API key:** https://fal.ai/dashboard/keys  \n**Status:** ✅ Fully implemented — live model listing and `app run` both work. Submits a job via `POST https://queue.fal.run/\u003capp_id\u003e` and polls for the result.\n\n### Replicate\n\nReplicate runs machine learning models in the cloud.\n\n**Website:** https://replicate.com  \n**Get an API key:** https://replicate.com/account/api-tokens  \n**Status:** ✅ Fully implemented — live model listing and `app run` both work. Creates a prediction via the Replicate API and polls until complete.\n\n### WaveSpeed AI\n\nWaveSpeed AI provides fast image and video generation.\n\n**Website:** https://wavespeed.ai  \n**Get an API key:** https://wavespeed.ai/dashboard  \n**Status:** ✅ Fully implemented — live model listing and inference both work.\n\n**How it works:** `app run` submits a generation task via `POST /api/v3/\u003cmodel_id\u003e` and then polls `GET /api/v3/predictions/\u003ctask_id\u003e` until the task completes (up to ~2 minutes). The generated image URLs are printed to stdout.\n\n**Models included in built-in catalog:**\n- `wavespeed/wavespeed-ai/flux-dev` — FLUX Dev\n- `wavespeed/wavespeed-ai/flux-schnell` — FLUX Schnell\n- `wavespeed/wavespeed-ai/wan2.1-t2v-480p` — Wan2.1 Text-to-Video 480p\n- `wavespeed/google/nano-banana-2` — Google Nano Banana 2 (text-to-image)\n\nAny model available on WaveSpeed can be run using its WaveSpeed model ID.\n\n## Authentication\n\n`infs` stores configuration in your OS's standard config directory:\n\n- **Linux:** `~/.config/infs/`\n- **macOS:** `~/Library/Application Support/infs/infs/`\n- **Windows:** `%APPDATA%\\infs\\infs\\`\n\nTwo files are used:\n- `config.toml` — provider settings and metadata (non-sensitive)\n- `credentials.toml` — API keys and secrets\n\n\u003e **Note:** On Unix, `credentials.toml` is written with file mode `0600` (owner read/write only). A future version will optionally integrate with the OS keychain via the `keyring` crate.\n\n### Environment Variables (.env)\n\n`infs` can automatically load provider credentials from environment variables. This is useful for:\n- **CI/CD pipelines** — inject secrets via environment variables\n- **Monorepos** — share a single `.env` file across multiple projects\n- **Quick setup** — skip the interactive `provider connect` flow\n\n#### How it works\n\n1. Create a `.env` file in your project directory (or any parent directory up to 3 levels)\n2. Set the environment variables for your providers\n3. Run `infs` commands — credentials are automatically detected\n\n#### Supported environment variables\n\n| Provider | Environment Variable |\n|----------|---------------------|\n| OpenRouter | `OPENROUTER_API_KEY` |\n| fal.ai | `FALAI_API_KEY` |\n| Replicate | `REPLICATE_API_TOKEN` |\n| WaveSpeed | `WAVESPEED_API_KEY` |\n\n#### Example `.env` file\n\n```bash\n# .env\nOPENROUTER_API_KEY=sk-or-v1-xxxxxxxxxxxxx\nFALAI_API_KEY=xxxxxxxxxxxxx\nREPLICATE_API_TOKEN=r8_xxxxxxxxxxxxx\nWAVESPEED_API_KEY=xxxxxxxxxxxxx\n```\n\n#### Credentials priority\n\nWhen multiple sources are available, `infs` uses this priority (highest wins):\n\n1. **OS keychain** — most secure, managed via `infs provider connect`\n2. **credentials.toml** — fallback file storage\n3. **.env / environment variables** — lowest priority, good for defaults\n\n#### Disabling .env loading\n\nTo skip `.env` loading and use only the credentials manager:\n\n```bash\ninfs --no-env provider list\n```\n\nThis is useful when you want to ensure only stored credentials are used, ignoring any environment variables.\n\n\u003e **Security note:** Never commit `.env` files to version control. Add `.env` to your `.gitignore`.\n\n### Connecting to OpenRouter\n\n```bash\ninfs provider connect openrouter\n```\n\nYou will be prompted:\n\n```\nConnecting to OpenRouter\nAuth method: API Key\n? Enter your OpenRouter API key: [hidden]\n✓ Connected to OpenRouter\n```\n\n## Examples\n\n### Quick start with .env (recommended for development)\n\nCreate a `.env` file with your API keys:\n\n```bash\n# .env\nOPENROUTER_API_KEY=sk-or-v1-xxxxxxxxxxxxx\n```\n\nThen run any command — no `provider connect` needed:\n\n```bash\ninfs app list\ninfs app list openrouter\ninfs app run openrouter/meta-llama/llama-3.1-8b-instruct --input '{\"prompt\":\"What is the capital of France?\"}'\n```\n\n### Ask a question (interactive setup)\n\n```bash\ninfs provider connect openrouter  # First time only\ninfs app run openrouter/meta-llama/llama-3.1-8b-instruct --input '{\"prompt\":\"What is the capital of France?\"}'\n```\n\n### Use advanced message format\n\nOpenRouter also accepts the full messages format:\n\n```bash\ninfs app run openrouter/openai/gpt-4o --input '{\n  \"messages\": [\n    {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n    {\"role\": \"user\", \"content\": \"What is Rust?\"}\n  ]\n}'\n```\n\n### Browse image models\n\n```bash\ninfs app list --category image\n```\n\n### Generate an image with WaveSpeed AI\n\n```bash\ninfs provider connect wavespeed  # First time only — enter your API key\ninfs app run wavespeed/google/nano-banana-2 --input '{\"prompt\":\"a serene mountain lake at sunset\"}'\n# Outputs one or more image URLs once generation completes\n```\n\n### Check what is configured\n\n```bash\ninfs doctor\n```\n\n## Agent Skills\n\n`infs` ships ready-to-use [agent skills](https://skills.sh) that teach AI coding assistants how to use the CLI. Install them with the [`skills`](https://github.com/vercel-labs/skills) CLI:\n\n```bash\n# Install all skills\nnpx skills add dvaJi/infera\n\n# Install a specific skill\nnpx skills add dvaJi/infera --skill infs-cli\nnpx skills add dvaJi/infera --skill infs-llm\nnpx skills add dvaJi/infera --skill infs-image\n```\n\nAvailable skills:\n\n| Skill | Description |\n|---|---|\n| `infs-cli` | Full CLI reference — providers, apps, configuration, and all commands |\n| `infs-llm` | Run LLMs (Claude, GPT-4o, Gemini, Llama, Mistral) via OpenRouter |\n| `infs-image` | Generate images via fal.ai, Replicate, or WaveSpeed AI |\n\nWorks with OpenCode, Claude Code, Cursor, Codex, and [40+ other agents](https://github.com/vercel-labs/skills#supported-agents).\n\n## Development\n\n### Architecture\n\n```\nsrc/\n├── main.rs              # Entry point\n├── error.rs             # InfsError type\n├── types.rs             # Shared types (AppId, AppDescriptor, RunResponse, etc.)\n├── config/              # Config loading/saving\n├── auth/                # Auth method abstractions\n├── providers/           # Provider trait + registry + adapters\n│   ├── mod.rs           # Provider trait\n│   ├── registry.rs      # ProviderRegistry\n│   ├── openrouter.rs    # ✅ Full implementation\n│   ├── falai.rs         # ✅ Full implementation (image, async queue)\n│   ├── replicate.rs     # ✅ Full implementation (image, prediction polling)\n│   └── wavespeed.rs     # ✅ Full implementation\n├── catalog/             # App catalog (aggregates provider listings)\n└── cli/                 # CLI commands\n    ├── mod.rs\n    ├── provider.rs      # provider list/connect/show/disconnect\n    ├── app.rs           # app list/run/show\n    ├── config.rs        # config path\n    └── doctor.rs        # doctor\n```\n\n### Adding a new provider\n\n1. Create `src/providers/myprovider.rs`\n2. Implement the `Provider` trait:\n\n```rust\nuse async_trait::async_trait;\nuse crate::providers::Provider;\nuse crate::config::ProviderConfig;\nuse crate::error::InfsError;\nuse crate::types::{AppDescriptor, AuthMethod, ProviderDescriptor, RunResponse};\n\npub struct MyProvider { descriptor: ProviderDescriptor }\n\n#[async_trait]\nimpl Provider for MyProvider {\n    fn descriptor(\u0026self) -\u003e \u0026ProviderDescriptor { \u0026self.descriptor }\n    fn supported_auth_methods(\u0026self) -\u003e Vec\u003cAuthMethod\u003e { vec![AuthMethod::ApiKey] }\n    async fn list_apps(\u0026self, config: \u0026ProviderConfig) -\u003e Result\u003cVec\u003cAppDescriptor\u003e, InfsError\u003e { /* fetch and return available apps from the provider API */ }\n    async fn run_app(\u0026self, app_id: \u0026str, input: serde_json::Value, config: \u0026ProviderConfig) -\u003e Result\u003cRunResponse, InfsError\u003e { /* call the provider's inference API */ }\n    fn validate_config(\u0026self, config: \u0026ProviderConfig) -\u003e Result\u003c(), InfsError\u003e { /* check that required credentials are present */ }\n}\n```\n\n3. Register it in `src/providers/registry.rs`:\n\n```rust\npub fn build_registry() -\u003e ProviderRegistry {\n    let mut registry = ProviderRegistry::new();\n    // ...existing providers...\n    registry.register(Box::new(myprovider::MyProvider::new()));\n    registry\n}\n```\n\n### Running tests\n\n```bash\ncargo test\n```\n\n### Environment variables\n\n| Variable | Purpose |\n|---|---|\n| `RUST_LOG` | Log level (`error`, `warn`, `info`, `debug`, `trace`) |\n\n## Known Limitations\n\n- Model listing requires an API key for fal.ai, Replicate, and WaveSpeed; a static fallback is shown when not connected\n\n## Roadmap\n\nSee [ROADMAP.md](ROADMAP.md) for the full roadmap. Summary:\n\n**Completed:**\n- [x] fal.ai, Replicate, and WaveSpeed AI execution\n- [x] OS keychain integration for credential storage (`keyring` crate)\n- [x] `--json` output flag for machine-friendly output\n- [x] Shell completion scripts (`infs completions bash/zsh/fish/powershell/elvish`)\n- [x] Retry logic with exponential backoff\n- [x] Self-update functionality (`infs self update`)\n- [x] Streaming LLM responses (`--stream` flag)\n- [x] Paginated model listing (`--page` and `--per-page` flags)\n- [x] File output for image generation (`--output` flag)\n- [x] File input support (`--file` flag for multimodal models)\n- [ ] More providers (ElevenLabs, Stability AI, etc.)\n- [ ] OAuth support for providers that require it\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdvaji%2Finfera","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdvaji%2Finfera","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdvaji%2Finfera/lists"}