Revert "feat: add inference.sh integration (infsh tool + skill) (#1682)" (#1684)

This reverts commit 6020db0243.
This commit is contained in:
Teknium
2026-03-17 03:01:30 -07:00
committed by GitHub
parent 6d1c5d4491
commit c3d626eb07
10 changed files with 0 additions and 1264 deletions

View File

@@ -95,7 +95,6 @@ def _discover_tools():
"tools.send_message_tool",
"tools.honcho_tools",
"tools.homeassistant_tool",
"tools.infsh_tool",
]
import importlib
for mod_name in _modules:

View File

@@ -1,23 +0,0 @@
# inference.sh
Run 150+ AI applications in the cloud via the [inference.sh](https://inference.sh) platform.
**One API key for everything** - Access all AI services with a single account. No need to manage separate API keys for FLUX, Veo, Claude, Tavily, Twitter, etc. You can also bring your own keys if you prefer.
## Available Skills
- **cli**: The inference.sh CLI (`infsh`) for running AI apps
## What's Included
- **Image Generation**: FLUX, Reve, Seedream, Grok Imagine, Gemini
- **Video Generation**: Veo, Wan, Seedance, OmniHuman, HunyuanVideo
- **LLMs**: Claude, Gemini, Kimi, GLM-4 (via OpenRouter)
- **Search**: Tavily, Exa
- **3D**: Rodin
- **Social**: Twitter/X automation
- **Audio**: TTS, voice cloning
## Tools
This category provides the `infsh` and `infsh_install` tools in the `inference` toolset.

View File

@@ -1,372 +0,0 @@
---
name: inference-sh-cli
description: "Run 150+ AI apps via inference.sh CLI (infsh) - image generation, video creation, LLMs, search, 3D, Twitter automation. Models: FLUX, Veo, Gemini, Grok, Claude, Seedance, OmniHuman, Tavily, Exa, OpenRouter. Triggers: inference.sh, infsh, ai apps, serverless ai, flux, veo, image generation, video generation"
version: 1.0.0
author: inference.sh
license: MIT
metadata:
hermes:
tags: [AI, image-generation, video, LLM, search, inference, FLUX, Veo, Claude]
requires_tools: [infsh]
---
# inference.sh CLI
Run 150+ AI apps in the cloud with a simple CLI. No GPU required.
**One API key for everything** - Manage all AI services (FLUX, Veo, Claude, Tavily, X/Twitter, and more) with a single inference.sh account. No need to sign up for dozens of different providers. You can also bring your own API keys if you prefer.
## Tools
This skill is backed by the `infsh` and `infsh_install` tools:
- **infsh**: Run any infsh command (app list, app run, etc.)
- **infsh_install**: Install the CLI if not already present
## Quick Start
```bash
# Install (if needed)
infsh_install
# List available apps
infsh app list
# Search for apps
infsh app list --search flux
infsh app list --search video
# Run an app
infsh app run falai/flux-dev-lora --input '{"prompt": "a cat astronaut"}' --json
```
## Local File Uploads
The CLI automatically uploads local files when you provide a file path instead of a URL:
```bash
# Upscale a local image
infsh app run falai/topaz-image-upscaler --input '{"image": "/path/to/photo.jpg", "upscale_factor": 2}' --json
# Image-to-video from local file
infsh app run falai/wan-2-5-i2v --input '{"image": "/path/to/image.png", "prompt": "make it come alive"}' --json
# Video generation with local first frame
infsh app run bytedance/seedance-1-5-pro --input '{"prompt": "dancing figure", "image": "./first-frame.png"}' --json
```
## Image Generation
```bash
# Gemini 2.5 Flash Image (Google) - fast, high quality
infsh app run google/gemini-2-5-flash-image --input '{"prompt": "futuristic city", "num_images": 1}' --json
# Gemini 3 Pro Image Preview (Google) - latest model
infsh app run google/gemini-3-pro-image-preview --input '{"prompt": "photorealistic landscape"}' --json
# Gemini 3.1 Flash Image Preview (Google)
infsh app run google/gemini-3-1-flash-image-preview --input '{"prompt": "artistic portrait"}' --json
# FLUX Dev with LoRA support
infsh app run falai/flux-dev-lora --input '{"prompt": "sunset over mountains", "num_images": 1}' --json
# FLUX 2 Klein with LoRA
infsh app run falai/flux-2-klein-lora --input '{"prompt": "portrait photo"}' --json
# Reve - stylized generation and editing
infsh app run falai/reve --input '{"prompt": "cyberpunk city"}' --json
# Seedream 5 Lite - high-quality 2K-3K (ByteDance)
infsh app run bytedance/seedream-5-lite --input '{"prompt": "nature scene"}' --json
# Seedream 4.5 - 2K-4K images
infsh app run bytedance/seedream-4-5 --input '{"prompt": "detailed illustration"}' --json
# Seedream 3.0 - cinematic quality
infsh app run bytedance/seedream-3-0-t2i --input '{"prompt": "fantasy landscape"}' --json
# Grok Imagine - xAI image generation
infsh app run xai/grok-imagine-image --input '{"prompt": "abstract art"}' --json
# Grok Imagine Pro - higher quality
infsh app run xai/grok-imagine-image-pro --input '{"prompt": "photorealistic portrait"}' --json
# Qwen Image 2 Pro (Alibaba)
infsh app run alibaba/qwen-image-2-pro --input '{"prompt": "anime character"}' --json
```
## Video Generation
```bash
# Veo 3.1 Fast (Google)
infsh app run google/veo-3-1-fast --input '{"prompt": "drone shot of coastline"}' --json
# Veo 3.1 (higher quality)
infsh app run google/veo-3-1 --input '{"prompt": "cinematic scene"}' --json
# Veo 3 Fast
infsh app run google/veo-3-fast --input '{"prompt": "nature documentary shot"}' --json
# Veo 2
infsh app run google/veo-2 --input '{"prompt": "slow motion water splash"}' --json
# Grok Imagine Video - xAI
infsh app run xai/grok-imagine-video --input '{"prompt": "timelapse of clouds"}' --json
# Seedance 1.5 Pro - ByteDance
infsh app run bytedance/seedance-1-5-pro --input '{"prompt": "dancing figure", "resolution": "1080p"}' --json
# Seedance 1.0 Pro
infsh app run bytedance/seedance-1-0-pro --input '{"prompt": "walking through forest"}' --json
# Seedance 1.0 Pro Fast
infsh app run bytedance/seedance-1-0-pro-fast --input '{"prompt": "quick motion"}' --json
# Seedance 1.0 Lite - 720p lightweight
infsh app run bytedance/seedance-1-0-lite --input '{"prompt": "simple animation"}' --json
# Wan 2.5 - text-to-video
infsh app run falai/wan-2-5 --input '{"prompt": "person walking through city"}' --json
# Wan 2.5 Image-to-Video
infsh app run falai/wan-2-5-i2v --input '{"image": "/path/to/image.png", "prompt": "make it move naturally"}' --json
# LTX Video
infsh app run infsh/ltx-video --input '{"prompt": "realistic scene"}' --json
# Magi 1
infsh app run infsh/magi-1 --input '{"prompt": "creative video"}' --json
```
## Avatar & Lipsync
```bash
# OmniHuman 1.5 - multi-character audio-driven avatars
infsh app run bytedance/omnihuman-1-5 --input '{"audio": "/path/to/audio.mp3", "image": "/path/to/face.jpg"}' --json
# OmniHuman 1.0
infsh app run bytedance/omnihuman-1-0 --input '{"audio": "/path/to/speech.wav", "image": "/path/to/portrait.png"}' --json
# Fabric 1.0 - image animation
infsh app run falai/fabric-1-0 --input '{"image": "/path/to/photo.jpg"}' --json
# PixVerse Lipsync
infsh app run falai/pixverse-lipsync --input '{"audio": "/path/to/audio.mp3", "video": "/path/to/video.mp4"}' --json
```
## Upscaling
```bash
# Topaz Image Upscaler - up to 4x
infsh app run falai/topaz-image-upscaler --input '{"image": "/path/to/photo.jpg", "upscale_factor": 2}' --json
# Topaz Video Upscaler
infsh app run falai/topaz-video-upscaler --input '{"video": "/path/to/video.mp4"}' --json
# Real-ESRGAN - image enhancement
infsh app run infsh/real-esrgan --input '{"image": "/path/to/image.jpg"}' --json
# Thera - upscale to any size
infsh app run infsh/thera --input '{"image": "/path/to/image.jpg"}' --json
```
## LLMs (via OpenRouter)
```bash
# Claude Opus 4.6
infsh app run openrouter/claude-opus-46 --input '{"prompt": "Explain quantum computing"}' --json
# Claude Sonnet 4.5
infsh app run openrouter/claude-sonnet-45 --input '{"prompt": "Write a poem"}' --json
# Claude Haiku 4.5
infsh app run openrouter/claude-haiku-45 --input '{"prompt": "Quick question"}' --json
# Gemini 3 Pro Preview
infsh app run openrouter/gemini-3-pro-preview --input '{"prompt": "Analyze this"}' --json
# Kimi K2 Thinking
infsh app run openrouter/kimi-k2-thinking --input '{"prompt": "Solve this step by step"}' --json
# GLM 4.6
infsh app run openrouter/glm-46 --input '{"prompt": "Help me with"}' --json
# MiniMax M2.5
infsh app run openrouter/minimax-m-25 --input '{"prompt": "Creative writing"}' --json
# Intellect 3
infsh app run openrouter/intellect-3 --input '{"prompt": "Research question"}' --json
```
## Web Search
```bash
# Tavily Search Assistant - comprehensive results
infsh app run tavily/search-assistant --input '{"query": "latest AI news", "include_answer": true}' --json
# Tavily Extract - get content from URLs
infsh app run tavily/extract --input '{"urls": ["https://example.com"]}' --json
# Exa Search - neural search
infsh app run exa/search --input '{"query": "machine learning tutorials"}' --json
# Exa Answer - LLM-powered answers
infsh app run exa/answer --input '{"query": "what is transformers architecture"}' --json
# Exa Extract - extract web content
infsh app run exa/extract --input '{"url": "https://example.com"}' --json
```
## 3D Generation
```bash
# Rodin 3D Generator
infsh app run infsh/rodin-3d-generator --input '{"prompt": "a wooden chair"}' --json
# HunyuanImage to 3D
infsh app run infsh/hunyuan-image-to-3d-2 --input '{"image": "/path/to/object.png"}' --json
```
## Text-to-Speech
```bash
# Kokoro TTS - lightweight
infsh app run falai/kokoro-tts --input '{"text": "Hello, this is a test."}' --json
# Dia TTS - realistic dialogue
infsh app run falai/dia-tts --input '{"text": "Two characters talking"}' --json
```
## Twitter/X Automation
```bash
# Post a tweet
infsh app run x/post-tweet --input '{"text": "Hello from AI!"}' --json
# Create post with media
infsh app run x/post-create --input '{"text": "Check this out", "media": "/path/to/image.jpg"}' --json
# Send DM
infsh app run x/dm-send --input '{"recipient_id": "123456", "text": "Hi there!"}' --json
# Follow user
infsh app run x/user-follow --input '{"user_id": "123456"}' --json
# Like a post
infsh app run x/post-like --input '{"post_id": "123456789"}' --json
# Retweet
infsh app run x/post-retweet --input '{"post_id": "123456789"}' --json
# Get user profile
infsh app run x/user-get --input '{"username": "elonmusk"}' --json
# Get post
infsh app run x/post-get --input '{"post_id": "123456789"}' --json
# Delete post
infsh app run x/post-delete --input '{"post_id": "123456789"}' --json
```
## Utilities
```bash
# Browser automation
infsh app run infsh/agent-browser --function open --session new --input '{"url": "https://example.com"}' --json
# Media merger - combine videos/images
infsh app run infsh/media-merger --input '{"files": ["/path/to/video1.mp4", "/path/to/video2.mp4"]}' --json
# Video audio extractor
infsh app run infsh/video-audio-extractor --input '{"video": "/path/to/video.mp4"}' --json
# Video audio merger
infsh app run infsh/video-audio-merger --input '{"video": "/path/to/video.mp4", "audio": "/path/to/audio.mp3"}' --json
# Caption videos
infsh app run infsh/caption-videos --input '{"video": "/path/to/video.mp4"}' --json
# Stitch images
infsh app run infsh/stitch-images --input '{"images": ["/path/to/1.jpg", "/path/to/2.jpg"]}' --json
# Python executor
infsh app run infsh/python-executor --input '{"code": "print(2+2)"}' --json
# HTML to image
infsh app run infsh/html-to-image --input '{"html": "<h1>Hello</h1>"}' --json
# NSFW detection
infsh app run infsh/falconsai-nsfw-detection --input '{"image": "/path/to/image.jpg"}' --json
# Media analyzer
infsh app run infsh/media-analyzer --input '{"file": "/path/to/media.jpg"}' --json
```
## Common Patterns
### Generate + Upscale Pipeline
```bash
# Generate image, capture URL, then upscale
infsh app run falai/flux-dev-lora --input '{"prompt": "portrait photo"}' --json --save result.json
# Extract URL and upscale (using jq)
IMG=$(cat result.json | jq -r '.images[0].url')
infsh app run falai/topaz-image-upscaler --input "{\"image\": \"$IMG\", \"upscale_factor\": 2}" --json
```
### Get App Schema
```bash
# See what inputs an app accepts
infsh app get falai/flux-dev-lora
# Generate sample input
infsh app sample falai/flux-dev-lora
# Save sample to file, edit, then run
infsh app sample falai/flux-dev-lora --save input.json
# edit input.json...
infsh app run falai/flux-dev-lora --input input.json --json
```
### Long-running Tasks
```bash
# Start without waiting
infsh app run google/veo-3-1 --input '{"prompt": "..."}' --no-wait
# Check status later
infsh task get <task-id>
# Save result when done
infsh task get <task-id> --save result.json
```
## Available Categories
| Category | Apps |
|----------|------|
| **Image** | google/nano-banana, google/nano-banana-pro, google/nano-banana-2, falai/flux-dev-lora, bytedance/seedream-5-lite, falai/reve, xai/grok-imagine-image |
| **Video** | google/veo-*, xai/grok-imagine-video, bytedance/seedance-*, falai/wan-2-5*, infsh/ltx-video, infsh/magi-1 |
| **Avatar** | bytedance/omnihuman-*, falai/fabric-1-0, falai/pixverse-lipsync |
| **Upscale** | falai/topaz-image-upscaler, falai/topaz-video-upscaler, infsh/real-esrgan, infsh/thera |
| **LLMs** | openrouter/claude-*, openrouter/gemini-*, openrouter/kimi-*, openrouter/glm-* |
| **Search** | tavily/search-assistant, tavily/extract, exa/search, exa/answer, exa/extract |
| **3D** | infsh/rodin-3d-generator, infsh/hunyuan-image-to-3d-2 |
| **TTS** | falai/kokoro-tts, falai/dia-tts |
| **Social** | x/post-tweet, x/post-create, x/dm-send, x/user-follow, x/post-like, x/post-retweet |
| **Utils** | infsh/agent-browser, infsh/media-merger, infsh/caption-videos, infsh/stitch-images |
## Reference Files
- [Authentication & Setup](references/authentication.md)
- [Discovering Apps](references/app-discovery.md)
- [Running Apps](references/running-apps.md)
- [CLI Reference](references/cli-reference.md)
## Documentation
- [inference.sh Docs](https://inference.sh/docs)
- [CLI Setup Guide](https://inference.sh/docs/extend/cli-setup)
- [Apps Overview](https://inference.sh/docs/apps/overview)

View File

@@ -1,112 +0,0 @@
# Discovering Apps
## List All Apps
```bash
infsh app list
```
## Pagination
```bash
infsh app list --page 2
```
## Filter by Category
```bash
infsh app list --category image
infsh app list --category video
infsh app list --category audio
infsh app list --category text
infsh app list --category other
```
## Search
```bash
infsh app search "flux"
infsh app search "video generation"
infsh app search "tts" -l
infsh app search "image" --category image
```
Or use the flag form:
```bash
infsh app list --search "flux"
infsh app list --search "video generation"
infsh app list --search "tts"
```
## Featured Apps
```bash
infsh app list --featured
```
## Newest First
```bash
infsh app list --new
```
## Detailed View
```bash
infsh app list -l
```
Shows table with app name, category, description, and featured status.
## Save to File
```bash
infsh app list --save apps.json
```
## Your Apps
List apps you've deployed:
```bash
infsh app my
infsh app my -l # detailed
```
## Get App Details
```bash
infsh app get falai/flux-dev-lora
infsh app get falai/flux-dev-lora --json
```
Shows full app info including input/output schema.
## Popular Apps by Category
### Image Generation
- `falai/flux-dev-lora` - FLUX.2 Dev (high quality)
- `falai/flux-2-klein-lora` - FLUX.2 Klein (fastest)
- `infsh/sdxl` - Stable Diffusion XL
- `google/gemini-3-pro-image-preview` - Gemini 3 Pro
- `xai/grok-imagine-image` - Grok image generation
### Video Generation
- `google/veo-3-1-fast` - Veo 3.1 Fast
- `google/veo-3` - Veo 3
- `bytedance/seedance-1-5-pro` - Seedance 1.5 Pro
- `infsh/ltx-video-2` - LTX Video 2 (with audio)
- `bytedance/omnihuman-1-5` - OmniHuman avatar
### Audio
- `infsh/dia-tts` - Conversational TTS
- `infsh/kokoro-tts` - Kokoro TTS
- `infsh/fast-whisper-large-v3` - Fast transcription
- `infsh/diffrythm` - Music generation
## Documentation
- [Browsing the Grid](https://inference.sh/docs/apps/browsing-grid) - Visual app browsing
- [Apps Overview](https://inference.sh/docs/apps/overview) - Understanding apps
- [Running Apps](https://inference.sh/docs/apps/running) - How to run apps

View File

@@ -1,59 +0,0 @@
# Authentication & Setup
## Install the CLI
```bash
curl -fsSL https://cli.inference.sh | sh
```
## Login
```bash
infsh login
```
This opens a browser for authentication. After login, credentials are stored locally.
## Check Authentication
```bash
infsh me
```
Shows your user info if authenticated.
## Environment Variable
For CI/CD or scripts, set your API key:
```bash
export INFSH_API_KEY=your-api-key
```
The environment variable overrides the config file.
## Update CLI
```bash
infsh update
```
Or reinstall:
```bash
curl -fsSL https://cli.inference.sh | sh
```
## Troubleshooting
| Error | Solution |
|-------|----------|
| "not authenticated" | Run `infsh login` |
| "command not found" | Reinstall CLI or add to PATH |
| "API key invalid" | Check `INFSH_API_KEY` or re-login |
## Documentation
- [CLI Setup](https://inference.sh/docs/extend/cli-setup) - Complete CLI installation guide
- [API Authentication](https://inference.sh/docs/api/authentication) - API key management
- [Secrets](https://inference.sh/docs/secrets/overview) - Managing credentials

View File

@@ -1,104 +0,0 @@
# CLI Reference
## Installation
```bash
curl -fsSL https://cli.inference.sh | sh
```
## Global Commands
| Command | Description |
|---------|-------------|
| `infsh help` | Show help |
| `infsh version` | Show CLI version |
| `infsh update` | Update CLI to latest |
| `infsh login` | Authenticate |
| `infsh me` | Show current user |
## App Commands
### Discovery
| Command | Description |
|---------|-------------|
| `infsh app list` | List available apps |
| `infsh app list --category <cat>` | Filter by category (image, video, audio, text, other) |
| `infsh app search <query>` | Search apps |
| `infsh app list --search <query>` | Search apps (flag form) |
| `infsh app list --featured` | Show featured apps |
| `infsh app list --new` | Sort by newest |
| `infsh app list --page <n>` | Pagination |
| `infsh app list -l` | Detailed table view |
| `infsh app list --save <file>` | Save to JSON file |
| `infsh app my` | List your deployed apps |
| `infsh app get <app>` | Get app details |
| `infsh app get <app> --json` | Get app details as JSON |
### Execution
| Command | Description |
|---------|-------------|
| `infsh app run <app> --input <file>` | Run app with input file |
| `infsh app run <app> --input '<json>'` | Run with inline JSON |
| `infsh app run <app> --input <file> --no-wait` | Run without waiting for completion |
| `infsh app sample <app>` | Show sample input |
| `infsh app sample <app> --save <file>` | Save sample to file |
## Task Commands
| Command | Description |
|---------|-------------|
| `infsh task get <task-id>` | Get task status and result |
| `infsh task get <task-id> --json` | Get task as JSON |
| `infsh task get <task-id> --save <file>` | Save task result to file |
### Development
| Command | Description |
|---------|-------------|
| `infsh app init` | Create new app (interactive) |
| `infsh app init <name>` | Create new app with name |
| `infsh app test --input <file>` | Test app locally |
| `infsh app deploy` | Deploy app |
| `infsh app deploy --dry-run` | Validate without deploying |
| `infsh app pull <id>` | Pull app source |
| `infsh app pull --all` | Pull all your apps |
## Environment Variables
| Variable | Description |
|----------|-------------|
| `INFSH_API_KEY` | API key (overrides config) |
## Shell Completions
```bash
# Bash
infsh completion bash > /etc/bash_completion.d/infsh
# Zsh
infsh completion zsh > "${fpath[1]}/_infsh"
# Fish
infsh completion fish > ~/.config/fish/completions/infsh.fish
```
## App Name Format
Apps use the format `namespace/app-name`:
- `falai/flux-dev-lora` - fal.ai's FLUX 2 Dev
- `google/veo-3` - Google's Veo 3
- `infsh/sdxl` - inference.sh's SDXL
- `bytedance/seedance-1-5-pro` - ByteDance's Seedance
- `xai/grok-imagine-image` - xAI's Grok
Version pinning: `namespace/app-name@version`
## Documentation
- [CLI Setup](https://inference.sh/docs/extend/cli-setup) - Complete CLI installation guide
- [Running Apps](https://inference.sh/docs/apps/running) - How to run apps via CLI
- [Creating an App](https://inference.sh/docs/extend/creating-app) - Build your own apps
- [Deploying](https://inference.sh/docs/extend/deploying) - Deploy apps to the cloud

View File

@@ -1,171 +0,0 @@
# Running Apps
## Basic Run
```bash
infsh app run user/app-name --input input.json
```
## Inline JSON
```bash
infsh app run falai/flux-dev-lora --input '{"prompt": "a sunset over mountains"}'
```
## Version Pinning
```bash
infsh app run user/app-name@1.0.0 --input input.json
```
## Local File Uploads
The CLI automatically uploads local files when you provide a file path instead of a URL. Any field that accepts a URL also accepts a local path:
```bash
# Upscale a local image
infsh app run falai/topaz-image-upscaler --input '{"image": "/path/to/photo.jpg", "upscale_factor": 2}'
# Image-to-video from local file
infsh app run falai/wan-2-5-i2v --input '{"image": "./my-image.png", "prompt": "make it move"}'
# Avatar with local audio and image
infsh app run bytedance/omnihuman-1-5 --input '{"audio": "/path/to/speech.mp3", "image": "/path/to/face.jpg"}'
# Post tweet with local media
infsh app run x/post-create --input '{"text": "Check this out!", "media": "./screenshot.png"}'
```
Supported paths:
- Absolute paths: `/home/user/images/photo.jpg`
- Relative paths: `./image.png`, `../data/video.mp4`
- Home directory: `~/Pictures/photo.jpg`
## Generate Sample Input
Before running, generate a sample input file:
```bash
infsh app sample falai/flux-dev-lora
```
Save to file:
```bash
infsh app sample falai/flux-dev-lora --save input.json
```
Then edit `input.json` and run:
```bash
infsh app run falai/flux-dev-lora --input input.json
```
## Workflow Example
### Image Generation with FLUX
```bash
# 1. Get app details
infsh app get falai/flux-dev-lora
# 2. Generate sample input
infsh app sample falai/flux-dev-lora --save input.json
# 3. Edit input.json
# {
# "prompt": "a cat astronaut floating in space",
# "num_images": 1,
# "image_size": "landscape_16_9"
# }
# 4. Run
infsh app run falai/flux-dev-lora --input input.json
```
### Video Generation with Veo
```bash
# 1. Generate sample
infsh app sample google/veo-3-1-fast --save input.json
# 2. Edit prompt
# {
# "prompt": "A drone shot flying over a forest at sunset"
# }
# 3. Run
infsh app run google/veo-3-1-fast --input input.json
```
### Text-to-Speech
```bash
# Quick inline run
infsh app run falai/kokoro-tts --input '{"text": "Hello, this is a test."}'
```
## Task Tracking
When you run an app, the CLI shows the task ID:
```
Running falai/flux-dev-lora
Task ID: abc123def456
```
For long-running tasks, you can check status anytime:
```bash
# Check task status
infsh task get abc123def456
# Get result as JSON
infsh task get abc123def456 --json
# Save result to file
infsh task get abc123def456 --save result.json
```
### Run Without Waiting
For very long tasks, run in background:
```bash
# Submit and return immediately
infsh app run google/veo-3 --input input.json --no-wait
# Check later
infsh task get <task-id>
```
## Output
The CLI returns the app output directly. For file outputs (images, videos, audio), you'll receive URLs to download.
Example output:
```json
{
"images": [
{
"url": "https://cloud.inference.sh/...",
"content_type": "image/png"
}
]
}
```
## Error Handling
| Error | Cause | Solution |
|-------|-------|----------|
| "invalid input" | Schema mismatch | Check `infsh app get` for required fields |
| "app not found" | Wrong app name | Check `infsh app list --search` |
| "quota exceeded" | Out of credits | Check account balance |
## Documentation
- [Running Apps](https://inference.sh/docs/apps/running) - Complete running apps guide
- [Streaming Results](https://inference.sh/docs/api/sdk/streaming) - Real-time progress updates
- [Setup Parameters](https://inference.sh/docs/apps/setup-parameters) - Configuring app inputs

View File

@@ -1,114 +0,0 @@
"""Tests for tools/infsh_tool.py — inference.sh CLI integration."""
import json
import subprocess
from unittest.mock import patch, MagicMock
import pytest
from tools.infsh_tool import (
check_infsh_requirements,
infsh_tool,
infsh_install,
)
class TestCheckRequirements:
def test_returns_bool(self):
result = check_infsh_requirements()
assert isinstance(result, bool)
def test_returns_true_when_infsh_on_path(self, monkeypatch):
monkeypatch.setattr("shutil.which", lambda cmd: "/usr/local/bin/infsh" if cmd == "infsh" else None)
assert check_infsh_requirements() is True
def test_returns_false_when_missing(self, monkeypatch):
monkeypatch.setattr("shutil.which", lambda cmd: None)
assert check_infsh_requirements() is False
class TestInfshTool:
def test_not_installed_returns_error(self, monkeypatch):
monkeypatch.setattr("tools.infsh_tool.check_infsh_requirements", lambda: False)
result = json.loads(infsh_tool("app list"))
assert result["success"] is False
assert "not installed" in result["error"].lower()
def test_successful_command(self, monkeypatch):
monkeypatch.setattr("tools.infsh_tool.check_infsh_requirements", lambda: True)
mock_result = MagicMock()
mock_result.returncode = 0
mock_result.stdout = '{"apps": ["flux", "veo"]}'
mock_result.stderr = ""
with patch("subprocess.run", return_value=mock_result) as mock_run:
result = json.loads(infsh_tool("app list --search flux"))
assert result["success"] is True
mock_run.assert_called_once()
call_cmd = mock_run.call_args[0][0]
assert "infsh app list --search flux" in call_cmd
def test_failed_command(self, monkeypatch):
monkeypatch.setattr("tools.infsh_tool.check_infsh_requirements", lambda: True)
mock_result = MagicMock()
mock_result.returncode = 1
mock_result.stdout = ""
mock_result.stderr = "unknown command"
with patch("subprocess.run", return_value=mock_result):
result = json.loads(infsh_tool("badcommand"))
assert result["success"] is False
assert result["exit_code"] == 1
def test_timeout_handled(self, monkeypatch):
monkeypatch.setattr("tools.infsh_tool.check_infsh_requirements", lambda: True)
with patch("subprocess.run", side_effect=subprocess.TimeoutExpired("infsh", 300)):
result = json.loads(infsh_tool("app run something", timeout=300))
assert result["success"] is False
assert "timed out" in result["error"].lower()
def test_json_output_parsed(self, monkeypatch):
monkeypatch.setattr("tools.infsh_tool.check_infsh_requirements", lambda: True)
mock_result = MagicMock()
mock_result.returncode = 0
mock_result.stdout = '{"url": "https://example.com/image.png"}'
mock_result.stderr = ""
with patch("subprocess.run", return_value=mock_result):
result = json.loads(infsh_tool("app run flux --json"))
assert result["success"] is True
assert isinstance(result["output"], dict)
assert result["output"]["url"] == "https://example.com/image.png"
class TestInfshInstall:
def test_already_installed(self, monkeypatch):
monkeypatch.setattr("tools.infsh_tool.check_infsh_requirements", lambda: True)
monkeypatch.setattr("tools.infsh_tool._get_infsh_path", lambda: "/usr/local/bin/infsh")
mock_result = MagicMock()
mock_result.returncode = 0
mock_result.stdout = "infsh v1.2.3"
with patch("subprocess.run", return_value=mock_result):
result = json.loads(infsh_install())
assert result["success"] is True
assert result["already_installed"] is True
class TestToolRegistration:
def test_tools_registered(self):
from tools.registry import registry
assert "infsh" in registry._tools
assert "infsh_install" in registry._tools
def test_infsh_in_inference_toolset(self):
from toolsets import TOOLSETS
assert "inference" in TOOLSETS
assert "infsh" in TOOLSETS["inference"]["tools"]
assert "infsh_install" in TOOLSETS["inference"]["tools"]
def test_infsh_not_in_core_tools(self):
from toolsets import _HERMES_CORE_TOOLS
assert "infsh" not in _HERMES_CORE_TOOLS
assert "infsh_install" not in _HERMES_CORE_TOOLS

View File

@@ -1,302 +0,0 @@
#!/usr/bin/env python3
"""
Inference.sh Tool Module
A simple tool for running AI apps via the inference.sh CLI (infsh).
Provides two functions:
- infsh_install: Install the infsh CLI
- infsh: Run any infsh command
This is a lightweight wrapper that gives agents direct access to 150+ AI apps
including image generation (FLUX, Reve), video (Veo, Wan), LLMs, search, and more.
Usage:
from tools.infsh_tool import infsh_tool, infsh_install
# Install the CLI
result = infsh_install()
# Search for apps first (always do this!)
result = infsh_tool("app list --search flux")
# Run an app
result = infsh_tool("app run falai/flux-dev-lora --input '{\"prompt\": \"a cat\"}' --json")
"""
import json
import logging
import os
import shutil
import subprocess
from typing import Optional
logger = logging.getLogger(__name__)
# ---------------------------------------------------------------------------
# Configuration
# ---------------------------------------------------------------------------
DEFAULT_TIMEOUT = 300 # 5 minutes for long-running AI tasks
INSTALL_TIMEOUT = 60
# ---------------------------------------------------------------------------
# Availability check
# ---------------------------------------------------------------------------
def check_infsh_requirements() -> bool:
"""Check if infsh is available in PATH."""
return shutil.which("infsh") is not None
def _get_infsh_path() -> Optional[str]:
"""Get the path to infsh binary."""
return shutil.which("infsh")
# ---------------------------------------------------------------------------
# Install function
# ---------------------------------------------------------------------------
def infsh_install() -> str:
"""
Install the inference.sh CLI.
Downloads and installs the infsh binary using the official installer script.
The installer detects OS/arch, downloads the correct binary, verifies checksum,
and places it in PATH.
Returns:
JSON string with success/error status
"""
try:
# Check if already installed
if check_infsh_requirements():
infsh_path = _get_infsh_path()
# Get version
version_result = subprocess.run(
["infsh", "--version"],
capture_output=True,
text=True,
timeout=10
)
version = version_result.stdout.strip() if version_result.returncode == 0 else "unknown"
return json.dumps({
"success": True,
"message": f"infsh is already installed at {infsh_path}",
"version": version,
"already_installed": True
})
# Run the installer
result = subprocess.run(
["sh", "-c", "curl -fsSL https://cli.inference.sh | sh"],
capture_output=True,
text=True,
timeout=INSTALL_TIMEOUT,
env={**os.environ, "NONINTERACTIVE": "1"}
)
if result.returncode != 0:
return json.dumps({
"success": False,
"error": f"Installation failed: {result.stderr}",
"stdout": result.stdout
})
# Verify installation
if not check_infsh_requirements():
return json.dumps({
"success": False,
"error": "Installation completed but infsh not found in PATH. You may need to restart your shell or add ~/.local/bin to PATH.",
"stdout": result.stdout
})
return json.dumps({
"success": True,
"message": "infsh installed successfully",
"stdout": result.stdout,
"next_step": "Run 'infsh login' to authenticate, or set INFSH_API_KEY environment variable"
})
except subprocess.TimeoutExpired:
return json.dumps({
"success": False,
"error": f"Installation timed out after {INSTALL_TIMEOUT}s"
})
except Exception as e:
logger.exception("infsh_install error: %s", e)
return json.dumps({
"success": False,
"error": f"Installation error: {type(e).__name__}: {e}"
})
# ---------------------------------------------------------------------------
# Main tool function
# ---------------------------------------------------------------------------
def infsh_tool(
command: str,
timeout: Optional[int] = None,
) -> str:
"""
Execute an infsh CLI command.
Args:
command: The infsh command to run (without the 'infsh' prefix).
Examples: "app list", "app run falai/flux-schnell --input '{}'"
timeout: Command timeout in seconds (default: 300)
Returns:
JSON string with output, exit_code, and error fields
"""
try:
effective_timeout = timeout or DEFAULT_TIMEOUT
# Check if infsh is installed
if not check_infsh_requirements():
return json.dumps({
"success": False,
"error": "infsh CLI is not installed. Use infsh_install to install it first.",
"hint": "Call the infsh_install tool to set up the CLI"
})
# Build the full command
full_command = f"infsh {command}"
# Execute
result = subprocess.run(
full_command,
shell=True,
capture_output=True,
text=True,
timeout=effective_timeout,
env=os.environ
)
output = result.stdout
error = result.stderr
# Try to parse JSON output if present
parsed_output = None
if output.strip():
try:
parsed_output = json.loads(output)
except json.JSONDecodeError:
pass # Not JSON, keep as string
response = {
"success": result.returncode == 0,
"exit_code": result.returncode,
"output": parsed_output if parsed_output is not None else output,
}
if error:
response["stderr"] = error
return json.dumps(response, indent=2)
except subprocess.TimeoutExpired:
return json.dumps({
"success": False,
"error": f"Command timed out after {effective_timeout}s",
"hint": "For long-running tasks, consider using --no-wait flag"
})
except Exception as e:
logger.exception("infsh_tool error: %s", e)
return json.dumps({
"success": False,
"error": f"Execution error: {type(e).__name__}: {e}"
})
# ---------------------------------------------------------------------------
# Registry
# ---------------------------------------------------------------------------
from tools.registry import registry
INFSH_TOOL_DESCRIPTION = """Run AI apps via inference.sh CLI. Access 150+ apps for image generation, video, LLMs, search, 3D, and more.
One API key for everything - manage all AI services (FLUX, Veo, Claude, Tavily, etc.) with a single inference.sh account. You can also bring your own API keys.
IMPORTANT: Always use 'app list --search <query>' first to find the exact app ID before running. App names change frequently.
Commands:
- app list --search <query>: Find apps (ALWAYS DO THIS FIRST)
- app run <app-id> --input '<json>' --json: Run an app
- app get <app-id>: Get app schema before running
Verified app examples (use --search to confirm current names):
- Image: google/nano-banana, google/nano-banana-pro, google/nano-banana-2, falai/flux-dev-lora, bytedance/seedream-5-lite, falai/reve, xai/grok-imagine-image
- Video: google/veo-3-1-fast, bytedance/seedance-1-5-pro, falai/wan-2-5
- Upscale: falai/topaz-image-upscaler
- Search: tavily/search-assistant, exa/search
- LLM: openrouter/claude-sonnet-45
Workflow: ALWAYS search first, then run:
1. app list --search image
2. app run falai/flux-dev-lora --input '{"prompt": "a sunset"}' --json"""
INFSH_SCHEMA = {
"name": "infsh",
"description": INFSH_TOOL_DESCRIPTION,
"parameters": {
"type": "object",
"properties": {
"command": {
"type": "string",
"description": "The infsh command (without 'infsh' prefix). ALWAYS use 'app list --search <query>' first to find correct app IDs, then 'app run <id> --input <json> --json'"
},
"timeout": {
"type": "integer",
"description": "Max seconds to wait (default: 300). AI tasks like video generation may take 1-2 minutes.",
"minimum": 1
}
},
"required": ["command"]
}
}
INFSH_INSTALL_SCHEMA = {
"name": "infsh_install",
"description": "Install the inference.sh CLI (infsh). Downloads and installs the binary. Run this first if infsh is not available.",
"parameters": {
"type": "object",
"properties": {},
"required": []
}
}
def _handle_infsh(args, **kw):
return infsh_tool(
command=args.get("command", ""),
timeout=args.get("timeout"),
)
def _handle_infsh_install(args, **kw):
return infsh_install()
# Register both tools under the "inference" toolset
registry.register(
name="infsh",
toolset="inference",
schema=INFSH_SCHEMA,
handler=_handle_infsh,
check_fn=check_infsh_requirements,
requires_env=[],
)
registry.register(
name="infsh_install",
toolset="inference",
schema=INFSH_INSTALL_SCHEMA,
handler=_handle_infsh_install,
check_fn=lambda: True, # Always available - it's the installer
requires_env=[],
)

View File

@@ -183,12 +183,6 @@ TOOLSETS = {
"tools": ["execute_code"],
"includes": []
},
"inference": {
"description": "inference.sh CLI (infsh) — run 150+ AI apps: image gen (FLUX, Reve), video (Veo, Wan), LLMs, search (Tavily, Exa), 3D, and more",
"tools": ["infsh", "infsh_install"],
"includes": []
},
"delegation": {
"description": "Spawn subagents with isolated context for complex subtasks",