docs: improve skill docs for better agent integration
- Rename skill from iib-api to iib for simpler installation: npx skills add https://github.com/zanllp/infinite-image-browsing --skill iib - Rewrite SKILL.md following agentskills.io best practices - Use curl examples instead of Python for simpler agent execution - Add "Before You Start" section: ask user for port, test connectivity first - Add --noproxy flag to bypass proxy for localhost connections - Add service status check and daemon startup instructions - Add quick reference table for common operations - Add agent-guide.md with decision tree and workflow patterns - Update README.md with AI agent usage section Co-Authored-By: Claude <noreply@anthropic.com>pull/922/head
parent
fb2a8878af
commit
61d18d7f1a
28
README.md
28
README.md
|
|
@ -52,10 +52,11 @@ If you would like to support more software, please refer to: [parsers](https://g
|
||||||
- Improved video streaming Range handling for large files.
|
- Improved video streaming Range handling for large files.
|
||||||
|
|
||||||
### 💻 Multiple Usage Methods
|
### 💻 Multiple Usage Methods
|
||||||
- You can install it as an extension on SD-webui.
|
- You can install it as an extension on SD-webui.
|
||||||
- You can run it independently using Python.
|
- You can run it independently using Python.
|
||||||
- The desktop app version is also available.
|
- The desktop app version is also available.
|
||||||
- Supports multiple popular AI software.
|
- Supports multiple popular AI software.
|
||||||
|
- **NEW**: Use with AI agents (Claude Code, Cursor, OpenClaw, etc.) via Agent Skills.
|
||||||
|
|
||||||
|
|
||||||
### 🎵 TikTok-Style View
|
### 🎵 TikTok-Style View
|
||||||
|
|
@ -151,6 +152,31 @@ If you need to compile it yourself, please refer to https://github.com/zanllp/sd
|
||||||
|
|
||||||
Use iframe to access IIB and use it as a file browser for your application. Refer to https://github.com/zanllp/sd-webui-infinite-image-browsing/blob/main/vue/usage.md
|
Use iframe to access IIB and use it as a file browser for your application. Refer to https://github.com/zanllp/sd-webui-infinite-image-browsing/blob/main/vue/usage.md
|
||||||
|
|
||||||
|
## With AI Agents (Claude Code, Cursor, OpenClaw, etc.)
|
||||||
|
|
||||||
|
IIB can be used as an [Agent Skill](https://agentskills.io), allowing AI agents to search, browse, tag, and organize your images through natural language.
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx skills add https://github.com/zanllp/infinite-image-browsing --skill iib
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
1. Start IIB service first:
|
||||||
|
```bash
|
||||||
|
python app.py --port 7866
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Then ask your AI agent to help with image tasks:
|
||||||
|
- "Find all images with 'sunset' in the prompt"
|
||||||
|
- "Tag these images as favorites"
|
||||||
|
- "Organize my Downloads folder by theme"
|
||||||
|
- "Show me the generation parameters of this image"
|
||||||
|
|
||||||
|
The agent will use IIB's API to perform these operations. See [skills/iib/SKILL.md](skills/iib/SKILL.md) for the full API documentation.
|
||||||
|
|
||||||
|
|
||||||
# Preview
|
# Preview
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,268 +0,0 @@
|
||||||
---
|
|
||||||
name: IIB API
|
|
||||||
description: Access IIB (Infinite Image Browsing) APIs for image searching, browsing, tagging, and AI-powered organization.
|
|
||||||
---
|
|
||||||
|
|
||||||
# IIB (Infinite Image Browsing) API Skill
|
|
||||||
|
|
||||||
IIB is a powerful image/video browsing, searching, and management tool with support for parsing metadata from multiple AI generation tools.
|
|
||||||
|
|
||||||
## Starting the Service
|
|
||||||
|
|
||||||
### Method 1: Standalone Mode (Recommended)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Basic startup
|
|
||||||
python app.py --port 8000 --host 127.0.0.1
|
|
||||||
|
|
||||||
# With extra scan paths
|
|
||||||
python app.py --port 8000 --extra_paths /path/to/images /another/path
|
|
||||||
|
|
||||||
# Update index on startup
|
|
||||||
python app.py --port 8000 --extra_paths /path/to/images --update_image_index
|
|
||||||
|
|
||||||
# Enable CORS for external access
|
|
||||||
python app.py --port 8000 --allow_cors
|
|
||||||
|
|
||||||
# Full example
|
|
||||||
python app.py --port 8000 --host 0.0.0.0 --allow_cors --extra_paths /my/images --update_image_index
|
|
||||||
```
|
|
||||||
|
|
||||||
### Method 2: As SD WebUI Extension
|
|
||||||
|
|
||||||
Place the project in `extensions/sd-webui-infinite-image-browsing` directory and start with SD WebUI.
|
|
||||||
|
|
||||||
API Base URL: `http://localhost:7860/infinite_image_browsing`
|
|
||||||
|
|
||||||
### Method 3: Python Code Integration
|
|
||||||
|
|
||||||
```python
|
|
||||||
from app import launch_app, AppUtils
|
|
||||||
from fastapi import FastAPI
|
|
||||||
|
|
||||||
# Option A: Direct launch
|
|
||||||
launch_app(port=8000, extra_paths=["/my/images"], allow_cors=True)
|
|
||||||
|
|
||||||
# Option B: Mount to existing FastAPI app
|
|
||||||
app = FastAPI()
|
|
||||||
app_utils = AppUtils(extra_paths=["/my/images"], allow_cors=True)
|
|
||||||
app_utils.wrap_app(app)
|
|
||||||
|
|
||||||
# Option C: Async launch for Jupyter Notebook
|
|
||||||
import asyncio
|
|
||||||
await async_launch_app(port=8000, extra_paths=["/my/images"])
|
|
||||||
```
|
|
||||||
|
|
||||||
### Environment Variables
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Authentication key (optional, enables API authentication)
|
|
||||||
export IIB_SECRET_KEY="your_secret_key"
|
|
||||||
|
|
||||||
# AI features configuration (required for clustering, smart organization)
|
|
||||||
export OPENAI_API_KEY="sk-xxx"
|
|
||||||
export OPENAI_BASE_URL="https://api.openai.com/v1" # or compatible endpoint
|
|
||||||
export AI_MODEL="gpt-4o-mini"
|
|
||||||
export EMBEDDING_MODEL="text-embedding-3-small"
|
|
||||||
|
|
||||||
# Access control
|
|
||||||
export IIB_ACCESS_CONTROL_ALLOWED_PATHS="/path1,/path2"
|
|
||||||
export IIB_ACCESS_CONTROL_PERMISSION="read-write" # read-only | read-write | write-only
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Core Feature: Image Search
|
|
||||||
|
|
||||||
IIB provides multiple image search methods - this is its core capability.
|
|
||||||
|
|
||||||
> **Note:** The examples below use Python for illustration, but you can use any language (Node.js, Go, Rust, etc.) that supports HTTP requests. The API is language-agnostic REST.
|
|
||||||
|
|
||||||
### 1. Substring Search (Fuzzy Search)
|
|
||||||
|
|
||||||
Search images by text in file path or generation parameters.
|
|
||||||
|
|
||||||
```python
|
|
||||||
import requests
|
|
||||||
|
|
||||||
BASE_URL = "http://localhost:8000/infinite_image_browsing"
|
|
||||||
|
|
||||||
# Search images containing "landscape"
|
|
||||||
resp = requests.post(f"{BASE_URL}/db/search_by_substr", json={
|
|
||||||
"surstr": "landscape", # Search keyword
|
|
||||||
"cursor": "", # Pagination cursor, empty for first page
|
|
||||||
"regexp": "", # Regular expression (optional)
|
|
||||||
"size": 100, # Results per page
|
|
||||||
"folder_paths": [], # Limit to specific directories (optional)
|
|
||||||
"media_type": "image" # "all" | "image" | "video"
|
|
||||||
})
|
|
||||||
|
|
||||||
result = resp.json()
|
|
||||||
for file in result["files"]:
|
|
||||||
print(file["fullpath"], file["size"])
|
|
||||||
|
|
||||||
# Pagination
|
|
||||||
if result["cursor"]["has_next"]:
|
|
||||||
next_resp = requests.post(f"{BASE_URL}/db/search_by_substr", json={
|
|
||||||
"surstr": "landscape",
|
|
||||||
"cursor": result["cursor"]["next"],
|
|
||||||
"regexp": "",
|
|
||||||
"size": 100
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Regular Expression Search
|
|
||||||
|
|
||||||
Use regex for precise pattern matching.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Search images with filenames starting with numbers
|
|
||||||
resp = requests.post(f"{BASE_URL}/db/search_by_substr", json={
|
|
||||||
"surstr": "",
|
|
||||||
"cursor": "",
|
|
||||||
"regexp": r"^\d+.*\.png$", # Regex pattern
|
|
||||||
"size": 100
|
|
||||||
})
|
|
||||||
|
|
||||||
# Search images with specific prompt format
|
|
||||||
resp = requests.post(f"{BASE_URL}/db/search_by_substr", json={
|
|
||||||
"surstr": "",
|
|
||||||
"cursor": "",
|
|
||||||
"regexp": r"masterpiece.*1girl.*blue eyes",
|
|
||||||
"size": 100
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Tag-based Search
|
|
||||||
|
|
||||||
Search by custom tags with AND/OR/NOT logic.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# First get all tags
|
|
||||||
tags_resp = requests.get(f"{BASE_URL}/db/basic_info")
|
|
||||||
all_tags = tags_resp.json()["tags"]
|
|
||||||
# tags format: [{"id": 1, "name": "favorites", "type": "custom"}, ...]
|
|
||||||
|
|
||||||
# Search: (tag_id=1 AND tag_id=2) OR tag_id=3, excluding tag_id=4
|
|
||||||
resp = requests.post(f"{BASE_URL}/db/match_images_by_tags", json={
|
|
||||||
"and_tags": [1, 2], # Must have all these tags
|
|
||||||
"or_tags": [3], # Have any of these
|
|
||||||
"not_tags": [4], # Exclude these tags
|
|
||||||
"cursor": "",
|
|
||||||
"size": 100,
|
|
||||||
"folder_paths": [], # Limit to directories (optional)
|
|
||||||
"random_sort": False # Random order
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Directory Browsing
|
|
||||||
|
|
||||||
List files and subdirectories in a folder.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# List directory contents
|
|
||||||
resp = requests.get(f"{BASE_URL}/files", params={
|
|
||||||
"folder_path": "/path/to/images"
|
|
||||||
})
|
|
||||||
|
|
||||||
files = resp.json()["files"]
|
|
||||||
for f in files:
|
|
||||||
if f["type"] == "dir":
|
|
||||||
print(f"[DIR] {f['name']}")
|
|
||||||
else:
|
|
||||||
print(f"[FILE] {f['name']} - {f['size']}")
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Random Images
|
|
||||||
|
|
||||||
Get random images from the database.
|
|
||||||
|
|
||||||
```python
|
|
||||||
resp = requests.get(f"{BASE_URL}/db/random_images")
|
|
||||||
random_images = resp.json() # Returns 128 random images
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6. AI Semantic Clustering
|
|
||||||
|
|
||||||
Cluster images by semantic similarity of generation parameters.
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Start clustering job
|
|
||||||
start_resp = requests.post(f"{BASE_URL}/db/cluster_iib_output_job_start", json={
|
|
||||||
"folder_paths": ["/path/to/images"],
|
|
||||||
"threshold": 0.85, # Similarity threshold
|
|
||||||
"min_cluster_size": 3, # Minimum cluster size
|
|
||||||
"lang": "en", # Title language
|
|
||||||
"recursive": True # Include subdirectories
|
|
||||||
})
|
|
||||||
job_id = start_resp.json()["job_id"]
|
|
||||||
|
|
||||||
# Poll for completion
|
|
||||||
import time
|
|
||||||
while True:
|
|
||||||
status = requests.get(f"{BASE_URL}/db/cluster_iib_output_job_status",
|
|
||||||
params={"job_id": job_id}).json()
|
|
||||||
if status.get("status") == "completed":
|
|
||||||
clusters = status["result"]["clusters"]
|
|
||||||
for c in clusters:
|
|
||||||
print(f"Topic: {c['title']}, Count: {c['size']}")
|
|
||||||
print(f" Keywords: {c['keywords']}")
|
|
||||||
print(f" Files: {c['paths'][:3]}...")
|
|
||||||
break
|
|
||||||
time.sleep(2)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Common Operations
|
|
||||||
|
|
||||||
### Batch Tagging
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Create a tag
|
|
||||||
tag = requests.post(f"{BASE_URL}/db/add_custom_tag",
|
|
||||||
json={"tag_name": "favorites"}).json()
|
|
||||||
|
|
||||||
# Batch add tag to images
|
|
||||||
requests.post(f"{BASE_URL}/db/batch_update_image_tag", json={
|
|
||||||
"img_paths": ["/path/to/img1.png", "/path/to/img2.png"],
|
|
||||||
"action": "add",
|
|
||||||
"tag_id": tag["id"]
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
### Get Image Generation Parameters
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Single image
|
|
||||||
geninfo = requests.get(f"{BASE_URL}/image_geninfo",
|
|
||||||
params={"path": "/path/to/image.png"}).text
|
|
||||||
|
|
||||||
# Batch get
|
|
||||||
batch_info = requests.post(f"{BASE_URL}/image_geninfo_batch", json={
|
|
||||||
"paths": ["/path/to/img1.png", "/path/to/img2.png"]
|
|
||||||
}).json()
|
|
||||||
```
|
|
||||||
|
|
||||||
### Smart File Organization
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Start organization job
|
|
||||||
job = requests.post(f"{BASE_URL}/db/organize_files_start", json={
|
|
||||||
"folder_paths": ["/messy/folder"],
|
|
||||||
"dest_folder": "/organized/folder",
|
|
||||||
"threshold": 0.85,
|
|
||||||
"lang": "en"
|
|
||||||
}).json()
|
|
||||||
|
|
||||||
# Wait for completion then confirm
|
|
||||||
requests.post(f"{BASE_URL}/db/organize_files_confirm", json={
|
|
||||||
"job_id": job["job_id"]
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Reference Documentation
|
|
||||||
|
|
||||||
See detailed API documentation: [references/api-reference.md](references/api-reference.md)
|
|
||||||
|
|
@ -0,0 +1,252 @@
|
||||||
|
---
|
||||||
|
name: iib
|
||||||
|
description: Interact with IIB (Infinite Image Browsing) service for searching, browsing, tagging, and organizing AI-generated images. Use when the user needs to search images by prompt/keyword, manage image tags, organize files into folders, get image generation parameters, or work with an image library.
|
||||||
|
---
|
||||||
|
|
||||||
|
# IIB (Infinite Image Browsing)
|
||||||
|
|
||||||
|
IIB is an image/video browsing and management tool that parses metadata from AI generation tools (Stable Diffusion, ComfyUI, etc.).
|
||||||
|
|
||||||
|
## Before You Start
|
||||||
|
|
||||||
|
**IMPORTANT:** Always do these two things first:
|
||||||
|
|
||||||
|
1. **Ask the user for the port** if they started the service themselves (common ports: `7866` standalone, `7860` SD WebUI extension)
|
||||||
|
2. **Test connectivity** with a hello request before any other operation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --noproxy "*" -s http://127.0.0.1:<PORT>/infinite_image_browsing/hello
|
||||||
|
# Returns: "hello" if service is running
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: Use `--noproxy "*"` to bypass proxy for localhost connections.
|
||||||
|
|
||||||
|
**If service is not running**, start it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /path/to/sd-webui-infinite-image-browsing
|
||||||
|
python app.py --port 7866
|
||||||
|
```
|
||||||
|
|
||||||
|
To run as a background daemon:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nohup python app.py --port 7866 > iib.log 2>&1 &
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
| Task | Method | Endpoint |
|
||||||
|
|------|--------|----------|
|
||||||
|
| Search images | POST | `/db/search_by_substr` |
|
||||||
|
| Search by tags | POST | `/db/match_images_by_tags` |
|
||||||
|
| Random images | GET | `/db/random_images` |
|
||||||
|
| List folder | GET | `/files?folder_path=...` |
|
||||||
|
| Move files | POST | `/move_files` |
|
||||||
|
| Copy files | POST | `/copy_files` |
|
||||||
|
| Tag images | POST | `/db/batch_update_image_tag` |
|
||||||
|
| Get image metadata | GET | `/image_geninfo?path=...` |
|
||||||
|
| Add library path | POST | `/db/extra_paths` |
|
||||||
|
| Remove library path | DELETE | `/db/extra_paths` |
|
||||||
|
|
||||||
|
Base URL: `http://127.0.0.1:7866/infinite_image_browsing`
|
||||||
|
|
||||||
|
## Core Operations
|
||||||
|
|
||||||
|
### Search Images
|
||||||
|
|
||||||
|
Search by keyword in file path or generation parameters:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/search_by_substr \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"surstr": "landscape", "cursor": "", "size": 50}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Search with regex pattern:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/search_by_substr \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"surstr": "", "regexp": "masterpiece.*1girl", "cursor": "", "size": 50}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Limit to specific folders:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/search_by_substr \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"surstr": "portrait", "folder_paths": ["/path/to/folder"], "cursor": "", "size": 50}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Response:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"files": [{"fullpath": "/path/to/image.png", "name": "image.png", "size": "1.2 MB", ...}],
|
||||||
|
"cursor": {"has_next": true, "next": "cursor_string"}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tag Management
|
||||||
|
|
||||||
|
Get all tags:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://127.0.0.1:7866/infinite_image_browsing/db/basic_info
|
||||||
|
# Response includes: {"tags": [{"id": 1, "name": "favorites", "type": "custom"}, ...]}
|
||||||
|
```
|
||||||
|
|
||||||
|
Create a tag:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/add_custom_tag \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"tag_name": "favorites"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Tag multiple images:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/batch_update_image_tag \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"img_paths": ["/path/to/img1.png", "/path/to/img2.png"], "action": "add", "tag_id": 1}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Search by tags (AND/OR/NOT logic):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/match_images_by_tags \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"and_tags": [1], "or_tags": [], "not_tags": [2], "cursor": "", "size": 50}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### File Operations
|
||||||
|
|
||||||
|
List folder contents:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl "http://127.0.0.1:7866/infinite_image_browsing/files?folder_path=/path/to/images"
|
||||||
|
```
|
||||||
|
|
||||||
|
Move files:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/move_files \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"file_paths": ["/path/to/img1.png"], "dest": "/new/folder", "create_dest_folder": true}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy files:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/copy_files \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"file_paths": ["/path/to/img1.png"], "dest": "/backup/folder", "create_dest_folder": true}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Delete files:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/delete_files \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"file_paths": ["/path/to/unwanted.png"]}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Image Metadata
|
||||||
|
|
||||||
|
Get generation parameters (prompt, seed, model, etc.):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl "http://127.0.0.1:7866/infinite_image_browsing/image_geninfo?path=/path/to/image.png"
|
||||||
|
```
|
||||||
|
|
||||||
|
Batch get metadata:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/image_geninfo_batch \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"paths": ["/path/to/img1.png", "/path/to/img2.png"]}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Library Management
|
||||||
|
|
||||||
|
List registered paths:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://127.0.0.1:7866/infinite_image_browsing/db/extra_paths
|
||||||
|
```
|
||||||
|
|
||||||
|
Add a folder to library:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/extra_paths \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"path": "/new/image/folder", "types": ["scanned"]}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Remove a folder (also cleans up orphaned image records):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X DELETE http://127.0.0.1:7866/infinite_image_browsing/db/extra_paths \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"path": "/old/folder", "types": ["scanned"]}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Rebuild index after adding paths:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/rebuild_index
|
||||||
|
```
|
||||||
|
|
||||||
|
Path types:
|
||||||
|
- `scanned`: Indexed, appears in search results
|
||||||
|
- `scanned-fixed`: Like scanned, but pinned in UI
|
||||||
|
- `walk`: Browse only, not indexed
|
||||||
|
|
||||||
|
## AI Features
|
||||||
|
|
||||||
|
### Smart File Organization
|
||||||
|
|
||||||
|
Automatically organize images into themed folders:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start organization job
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/organize_files_start \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"folder_paths": ["/messy/folder"],
|
||||||
|
"dest_folder": "/organized/folder",
|
||||||
|
"threshold": 0.85,
|
||||||
|
"lang": "en",
|
||||||
|
"action": "move"
|
||||||
|
}'
|
||||||
|
# Returns: {"job_id": "uuid"}
|
||||||
|
|
||||||
|
# Check status
|
||||||
|
curl "http://127.0.0.1:7866/infinite_image_browsing/db/organize_files_status?job_id=<job_id>"
|
||||||
|
|
||||||
|
# Confirm and execute
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/organize_files_confirm \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"job_id": "<job_id>"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Image Clustering
|
||||||
|
|
||||||
|
Analyze images and group by semantic similarity:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/cluster_iib_output_job_start \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"folder_paths": ["/path/to/images"],
|
||||||
|
"threshold": 0.85,
|
||||||
|
"min_cluster_size": 3,
|
||||||
|
"lang": "en",
|
||||||
|
"recursive": true
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
See [references/api-reference.md](references/api-reference.md) for complete API documentation.
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
# Agent Guide
|
||||||
|
|
||||||
|
Task-oriented patterns for common IIB operations.
|
||||||
|
|
||||||
|
## Decision Tree
|
||||||
|
|
||||||
|
```
|
||||||
|
User wants to find images
|
||||||
|
├── By keyword/prompt text → POST /db/search_by_substr (surstr)
|
||||||
|
├── By regex pattern → POST /db/search_by_substr (regexp)
|
||||||
|
├── By tag → POST /db/match_images_by_tags
|
||||||
|
└── Random selection → GET /db/random_images
|
||||||
|
|
||||||
|
User wants to organize images
|
||||||
|
├── Move specific files → POST /move_files
|
||||||
|
├── Copy specific files → POST /copy_files
|
||||||
|
├── Auto-organize by theme → POST /db/organize_files_start
|
||||||
|
└── Delete files → POST /delete_files
|
||||||
|
|
||||||
|
User wants image info
|
||||||
|
├── Generation params → GET /image_geninfo
|
||||||
|
├── Batch metadata → POST /image_geninfo_batch
|
||||||
|
└── File listing → GET /files
|
||||||
|
|
||||||
|
User wants to manage tags
|
||||||
|
├── List all tags → GET /db/basic_info
|
||||||
|
├── Create tag → POST /db/add_custom_tag
|
||||||
|
├── Apply tag to images → POST /db/batch_update_image_tag
|
||||||
|
└── Search by tag → POST /db/match_images_by_tags
|
||||||
|
|
||||||
|
User wants to manage library
|
||||||
|
├── List paths → GET /db/extra_paths
|
||||||
|
├── Add folder → POST /db/extra_paths
|
||||||
|
├── Remove folder → DELETE /db/extra_paths
|
||||||
|
└── Rebuild index → POST /db/rebuild_index
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Workflows
|
||||||
|
|
||||||
|
### Find and tag images
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Search for images
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/search_by_substr \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"surstr": "sunset", "cursor": "", "size": 100}'
|
||||||
|
# Note the fullpath values from response
|
||||||
|
|
||||||
|
# 2. Check existing tags
|
||||||
|
curl http://127.0.0.1:7866/infinite_image_browsing/db/basic_info
|
||||||
|
# Note tag IDs, or create new tag:
|
||||||
|
|
||||||
|
# 3. Create tag if needed
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/add_custom_tag \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"tag_name": "sunset-photos"}'
|
||||||
|
# Returns: {"id": 5, "name": "sunset-photos", ...}
|
||||||
|
|
||||||
|
# 4. Apply tag to found images
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/batch_update_image_tag \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"img_paths": ["/path/to/img1.png", "/path/to/img2.png"], "action": "add", "tag_id": 5}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Organize messy folder
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Start AI organization
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/organize_files_start \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"folder_paths": ["/Downloads/ai-images"],
|
||||||
|
"dest_folder": "/Pictures/organized",
|
||||||
|
"threshold": 0.85,
|
||||||
|
"lang": "en",
|
||||||
|
"action": "move"
|
||||||
|
}'
|
||||||
|
# Returns: {"job_id": "abc123"}
|
||||||
|
|
||||||
|
# 2. Poll for completion
|
||||||
|
curl "http://127.0.0.1:7866/infinite_image_browsing/db/organize_files_status?job_id=abc123"
|
||||||
|
# Wait until status is "completed"
|
||||||
|
|
||||||
|
# 3. Confirm and execute
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/organize_files_confirm \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"job_id": "abc123"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add new folder to library
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Add path
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/extra_paths \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"path": "/new/image/folder", "types": ["scanned"]}'
|
||||||
|
|
||||||
|
# 2. Trigger index update
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/update_image_data \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"path": "/new/image/folder"}'
|
||||||
|
|
||||||
|
# 3. Verify images are indexed
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/search_by_substr \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"surstr": "", "folder_paths": ["/new/image/folder"], "cursor": "", "size": 10}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Paginate large results
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# First page
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/search_by_substr \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"surstr": "landscape", "cursor": "", "size": 100}'
|
||||||
|
# Response: {"files": [...], "cursor": {"has_next": true, "next": "cursor_abc"}}
|
||||||
|
|
||||||
|
# Next page
|
||||||
|
curl -X POST http://127.0.0.1:7866/infinite_image_browsing/db/search_by_substr \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"surstr": "landscape", "cursor": "cursor_abc", "size": 100}'
|
||||||
|
# Continue until has_next is false
|
||||||
|
```
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Status | Meaning | Action |
|
||||||
|
|--------|---------|--------|
|
||||||
|
| 200 | Success | Parse response |
|
||||||
|
| 400 | Bad request | Check JSON syntax and parameters |
|
||||||
|
| 404 | Not found | Verify file path exists |
|
||||||
|
| 500 | Server error | Check IIB logs |
|
||||||
|
| Connection refused | Service not running | Start IIB service |
|
||||||
|
|
||||||
|
## Performance Tips
|
||||||
|
|
||||||
|
1. Use `folder_paths` to limit search scope when possible
|
||||||
|
2. Use batch endpoints (`image_geninfo_batch`, `batch_update_image_tag`) for multiple items
|
||||||
|
3. Use pagination for large result sets
|
||||||
|
4. Call `update_image_data` for specific folders instead of full `rebuild_index`
|
||||||
Loading…
Reference in New Issue