From 61d18d7f1a8f1cb673dc98ec152fb77690e40de1 Mon Sep 17 00:00:00 2001 From: zanllp Date: Wed, 18 Feb 2026 20:11:08 +0800 Subject: [PATCH] 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 --- README.md | 28 +- skills/iib-api/SKILL.md | 268 ------------------ skills/iib/SKILL.md | 252 ++++++++++++++++ skills/iib/agent-guide.md | 140 +++++++++ .../references/api-reference.md | 0 5 files changed, 419 insertions(+), 269 deletions(-) delete mode 100644 skills/iib-api/SKILL.md create mode 100644 skills/iib/SKILL.md create mode 100644 skills/iib/agent-guide.md rename skills/{iib-api => iib}/references/api-reference.md (100%) diff --git a/README.md b/README.md index 1221852..e26bcfd 100644 --- a/README.md +++ b/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. ### 💻 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. - The desktop app version is also available. - Supports multiple popular AI software. +- **NEW**: Use with AI agents (Claude Code, Cursor, OpenClaw, etc.) via Agent Skills. ### 🎵 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 +## 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 diff --git a/skills/iib-api/SKILL.md b/skills/iib-api/SKILL.md deleted file mode 100644 index 1e83ac4..0000000 --- a/skills/iib-api/SKILL.md +++ /dev/null @@ -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) diff --git a/skills/iib/SKILL.md b/skills/iib/SKILL.md new file mode 100644 index 0000000..8cf5ffd --- /dev/null +++ b/skills/iib/SKILL.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:/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=" + +# 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": ""}' +``` + +### 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. diff --git a/skills/iib/agent-guide.md b/skills/iib/agent-guide.md new file mode 100644 index 0000000..33771c3 --- /dev/null +++ b/skills/iib/agent-guide.md @@ -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` diff --git a/skills/iib-api/references/api-reference.md b/skills/iib/references/api-reference.md similarity index 100% rename from skills/iib-api/references/api-reference.md rename to skills/iib/references/api-reference.md