first commit

This commit is contained in:
lining3
2025-07-09 19:33:35 +08:00
commit c7de566cc3
4 changed files with 225 additions and 0 deletions
+100
View File
@@ -0,0 +1,100 @@
# ComfyUI OneThing CV Node
This custom node for ComfyUI allows you to get detailed text descriptions of images using the OneThing AI Vision API. The node integrates with OneThing AI's powerful vision models to provide detailed descriptions of image content.
## Features
- Upload and process images in ComfyUI
- Get detailed descriptions of image content using OneThing AI's Vision API
- Configurable model selection and parameters
- Built-in retry mechanism for robust API communication
- Easy integration with existing ComfyUI workflows
## Installation
1. Clone this repository into your ComfyUI custom_nodes directory:
```bash
cd ComfyUI/custom_nodes
git clone https://github.com/OnethingAI/ComfyUI_Onething_CV.git
```
2. Install the required dependencies:
```bash
pip install -r requirements.txt
```
## Usage
1. Obtain an API key from OneThing AI
2. In ComfyUI, you'll find a new node called "OneThingAI Image Understanding" under the "OneThingAI/CV" category
3. Connect an image output to the node's image input
4. Configure the node parameters (see Parameters section below)
5. Run the workflow to get the image description
## Parameters
### Required Parameters
- `image`: The input image to be described (IMAGE type)
- `api_key`: Your OneThing AI API key (STRING type)
- `model`: The model to use for image understanding (default: "gpt4o")
- `retries`: Number of retry attempts for API calls (default: 3, range: 0-5)
- `timeout`: API request timeout in seconds (default: 20, range: 5-100)
- `max_tokens`: Maximum number of tokens in the response (default: 500, range: 100-10000, step: 100)
## Output
- `STRING`: A detailed description of the image content
## Example Workflow
1. Load Image Node -> OneThingAI Image Understanding Node
2. Configure the parameters:
```
api_key: "your-api-key-here"
model: "gpt4o"
retries: 3
timeout: 20
max_tokens: 500
```
3. The node will return a detailed description of the image content
## Error Handling
The node includes robust error handling:
- Automatic retries for failed API calls
- Exponential backoff strategy
- Timeout protection
- Detailed error messages
Common error status codes that trigger retries:
- 429: Too Many Requests
- 500: Internal Server Error
- 502: Bad Gateway
- 503: Service Unavailable
- 504: Gateway Timeout
## Notes
- Make sure to keep your API key secure and never share it publicly
- The API has rate limits, please check OneThing AI's documentation for details
- The node requires an active internet connection to work
- Larger max_tokens values will result in longer, more detailed descriptions but may take more time to process
- The retry mechanism helps handle temporary API issues automatically
- If you encounter persistent errors, try:
1. Increasing the timeout value
2. Checking your API key
3. Verifying your internet connection
4. Ensuring the image is in a supported format
## Support
If you encounter any issues or have questions:
1. Check the error message returned by the node
2. Verify your API key and parameters
3. Check OneThing AI's API status and documentation
4. Open an issue in the GitHub repository
## License
This project is licensed under the MIT License - see the LICENSE file for details.
+6
View File
@@ -0,0 +1,6 @@
from .onethingai_node import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS
__version__ = "1.0.0"
# Export the node mappings for ComfyUI to discover
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]
+117
View File
@@ -0,0 +1,117 @@
import torch
import requests
import base64
from PIL import Image
import io
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
class OneThingAIImageToTextNode:
def __init__(self):
self.api_key = None
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
"api_key": ("STRING", {"default": "", "multiline": False}),
"model": ("STRING", {"default": "gpt4o", "multiline": False}),
"retries": ("INT", {"default": 3, "min": 0, "max": 5}),
"timeout": ("INT", {"default": 20, "min": 5, "max": 100}),
"max_tokens": ("INT", {"default": 500, "min": 100, "max": 10000, "step": 100}),
}
}
RETURN_TYPES = ("STRING",)
FUNCTION = "describe_image"
CATEGORY = "OneThingAI/CV"
def describe_image(self, image, api_key, model, retries, timeout, max_tokens):
if not api_key:
raise ValueError("API key is required")
# Convert tensor to PIL Image
if isinstance(image, torch.Tensor):
# Ensure image is in the correct format (C,H,W) -> (H,W,C)
image = image.squeeze(0)
image = (image * 255).byte()
image = image.cpu().numpy()
if image.shape[0] == 3:
image = image.transpose(1, 2, 0)
pil_image = Image.fromarray(image)
else:
pil_image = image
# Convert PIL Image to base64
buffered = io.BytesIO()
pil_image.save(buffered, format="PNG")
img_str = base64.b64encode(buffered.getvalue()).decode()
# Prepare API request
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}
payload = {
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "Please describe this image in detail."
},
{
"type": "image_url",
"image_url": {
"url": f"data:image/png;base64,{img_str}"
}
}
]
}
],
"model": model,
"max_tokens": max_tokens
}
try:
# Configure retry strategy
retry_strategy = Retry(
total=retries,
backoff_factor=1,
status_forcelist=[429, 500, 502, 503, 504],
)
# Create session with retry strategy
session = requests.Session()
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("https://", adapter)
# Make the request with retry and timeout
response = session.post(
"https://api-model.onethingai.com/v1/chat/completions",
headers=headers,
json=payload,
timeout=timeout
)
response.raise_for_status()
result = response.json()
# Extract the description from the response
description = result['choices'][0]['message']['content']
return (description,)
except requests.exceptions.RequestException as e:
return (f"Error: {str(e)}",)
finally:
session.close()
NODE_CLASS_MAPPINGS = {
"OneThingAI ImageToText": OneThingAIImageToTextNode
}
NODE_DISPLAY_NAME_MAPPINGS = {
"OneThingAI ImageToText": "OneThingAI Image Understanding"
}
+2
View File
@@ -0,0 +1,2 @@
Pillow
requests