Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions skills/venice_image/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Venice Image Skill Suite

Venice Image is a comprehensive skill suite for intelligent agents, enabling state-of-the-art AI image generation, enhancement, upscaling, and vision analysis using the [Venice AI API](https://venice.ai/). This suite offers a modular interface: each sub-tool covers a focused aspect of visual intelligence, while sharing unified configuration and error handling.

---

## Features

### 1. **Image Generation**
Prompt-based creation of new artworks or photorealistic images, with support for multiple leading AI models, extensive style presets, and negative prompting. Models include:
- **Fluently XL** (realism, professional art)
- **Flux Dev** (innovative research, art workflows)
- **Lustify SDXL** (photorealistic, NSFW/SFW)
- **Pony Realism** (anime/character detail, Danbooru tags)
- **Venice SD35 / Stable Diffusion 3.5** (Stability AI, creative design)

### 2. **Image Enhancement**
Stylize or refine *existing* images without changing their resolution—ideal for artistic edits, restoration, or visual polishing.

### 3. **Image Upscaling**
Increase resolution by 2x or 4x while preserving essential details (with optional noise/replication settings). Great for preparing web images for print or HD use.

### 4. **Image Vision**
Obtain highly detailed, context-rich textual descriptions of images—useful for content understanding, accessibility, indexing, or cognitive agents.

---

## How It Works

- Tools call the Venice API via secure network requests, automatically handling authentication, rate limiting, and error management.
- Any generated or processed images are transparently stored in an object store (S3 or compatible), with returned URLs ready for user consumption.
- Unified logging and troubleshooting: every tool shares a robust diagnostic backbone for consistent developer experience.

---

## Setup and Configuration

All skills require a **Venice API key** for operation.

### Required Configuration
- `enabled` *(bool)*: Enable or disable the overall skill suite.
- `api_key` *(string, sensitive)*: Your [Venice AI API key](https://venice.ai/).
- `states`: Enable/disable and set visibility for each sub-tool (public/private/disabled).

### Advanced Options
- `safe_mode` *(bool, default: true)*: If true, blurs images classified as adult/NSFW.
- `hide_watermark` *(bool, default: true)*: Request images without a Venice watermark (subject to Venice policy).
- `embed_exif_metadata` *(bool, default: false)*: Whether to embed prompt/config info in EXIF metadata.
- `negative_prompt` *(string)*: Default negative prompt, e.g. `(worst quality: 1.4), bad quality, nsfw`.
- `rate_limit_number` / `rate_limit_minutes`: (optional) Set a max request rate per agent.

For per-tool configuration, refer to the `states` section in [schema.json](./schema.json):
- Each tool (e.g. `image_generation_flux_dev`, `image_enhance`, etc.) can be set to `"public"` (all users), `"private"` (agent owner only), or `"disabled"` (hidden).

#### Example (YAML/JSON-like)
```json
{
"enabled": true,
"api_key": "<YOUR_VENICE_API_KEY>",
"safe_mode": true,
"states": {
"image_vision": "public",
"image_enhance": "private",
"image_upscale": "disabled",
"image_generation_flux_dev": "public"
}
}
```

---

## Usage Patterns

Each sub-tool has its own standardized input:
- URL-based tools (`image_enhance`, `image_upscale`, `image_vision`) require a web-accessible image URL.
- Generation tools require a *prompt* and offer flexible parameters (size, style, negative prompt, etc).

Errors and troubleshooting info are always returned in a structured dictionary, with clear separation of success and error fields.

---

## Output and Storage

- All generated/processed images are written to S3-compatible storage using a SHA256-based unique key.
- Returned URLs are agent-accessible and stable.
- For Vision and non-binary results, the output is returned inline as a dictionary.

---

## Security, License & Compliance

- Your Venice API key is required and kept confidential per config practices.
- Generated images and tool usage are subject to [Venice AI Terms of Service](https://venice.ai/) and the terms of the respective models (e.g. Stability AI, Black Forest Labs).
- Agents should implement their own access and moderation layers; Safe Mode and watermarking are best-effort.

---

## Included Sub-Tools

_(For detailed docs, see the respective sub-tool README entries.)_

- image_generation_fluently_xl
- image_generation_flux_dev
- image_generation_flux_dev_uncensored
- image_generation_lustify_sdxl
- image_generation_pony_realism
- image_generation_venice_sd35
- image_generation_stable_diffusion_3_5
- image_enhance
- image_upscale
- image_vision

---

## Contributing & Support

For issues, bugfixes, or requests, please open a GitHub issue or contact the maintainers. This suite is regularly updated as Venice AI evolves.

---
103 changes: 54 additions & 49 deletions skills/venice_image/__init__.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,38 @@
# venice_image/__init__.py

import logging
from typing import List, NotRequired, Optional, TypedDict
from typing import NotRequired, Optional, TypedDict

from abstracts.skill import SkillStoreABC
from skills.base import (
SkillConfig,
SkillState,
) # Assuming SkillState is like Literal["disabled", "public", "private"]
)

# Import the base tool and all specific model skill classes
from skills.venice_image.base import VeniceImageBaseTool
from skills.venice_image.image_generation_fluently_xl import ImageGenerationFluentlyXL
from skills.venice_image.image_generation_flux_dev import ImageGenerationFluxDev
from skills.venice_image.image_generation_flux_dev_uncensored import (
from skills.venice_image.image_enhance.image_enhance import ImageEnhance
from skills.venice_image.image_generation.image_generation_fluently_xl import (
ImageGenerationFluentlyXL,
)
from skills.venice_image.image_generation.image_generation_flux_dev import (
ImageGenerationFluxDev,
)
from skills.venice_image.image_generation.image_generation_flux_dev_uncensored import (
ImageGenerationFluxDevUncensored,
)
from skills.venice_image.image_generation_lustify_sdxl import ImageGenerationLustifySDXL
from skills.venice_image.image_generation_pony_realism import ImageGenerationPonyRealism
from skills.venice_image.image_generation_stable_diffusion_3_5 import (
from skills.venice_image.image_generation.image_generation_lustify_sdxl import (
ImageGenerationLustifySDXL,
)
from skills.venice_image.image_generation.image_generation_pony_realism import (
ImageGenerationPonyRealism,
)
from skills.venice_image.image_generation.image_generation_stable_diffusion_3_5 import (
ImageGenerationStableDiffusion35,
)
from skills.venice_image.image_generation_venice_sd35 import ImageGenerationVeniceSD35
from skills.venice_image.image_generation.image_generation_venice_sd35 import (
ImageGenerationVeniceSD35,
)
from skills.venice_image.image_upscale.image_upscale import ImageUpscale
from skills.venice_image.image_vision.image_vision import ImageVision

# Cache skills at the system level, because they are stateless and only depend on the store
_cache: dict[str, VeniceImageBaseTool] = {}
Expand All @@ -31,6 +42,9 @@

# Define the expected structure for the 'states' dictionary in the config
class SkillStates(TypedDict):
image_upscale: SkillState
image_enhance: SkillState
image_vision: SkillState
image_generation_flux_dev: SkillState
image_generation_flux_dev_uncensored: SkillState
image_generation_venice_sd35: SkillState
Expand All @@ -47,6 +61,7 @@ class Config(SkillConfig):

enabled: bool # Keep standard enabled flag
states: SkillStates
api_key_provider: str = "agent_owner"
api_key: NotRequired[Optional[str]] # Explicitly Optional
safe_mode: NotRequired[bool] # Defaults handled in base or usage
hide_watermark: NotRequired[bool] # Defaults handled in base or usage
Expand All @@ -55,25 +70,26 @@ class Config(SkillConfig):
rate_limit_minutes: NotRequired[Optional[int]] # Explicitly Optional


# Map skill names to their corresponding classes for the factory function
_SKILL_NAME_TO_CLASS_MAP = {
_SKILL_NAME_TO_CLASS_MAP: dict[str, type[VeniceImageBaseTool]] = {
"image_upscale": ImageUpscale,
"image_enhance": ImageEnhance,
"image_vision": ImageVision,
"image_generation_flux_dev": ImageGenerationFluxDev,
"image_generation_flux_dev_uncensored": ImageGenerationFluxDevUncensored,
"image_generation_venice_sd35": ImageGenerationVeniceSD35,
"image_generation_fluently_xl": ImageGenerationFluentlyXL,
"image_generation_lustify_sdxl": ImageGenerationLustifySDXL,
"image_generation_pony_realism": ImageGenerationPonyRealism,
"image_generation_stable_diffusion_3_5": ImageGenerationStableDiffusion35,
# Add new mappings here: "skill_name": SkillClassName
}


async def get_skills(
config: Config, # Use the specific Config TypedDict for better type hinting
config: "Config",
is_private: bool,
store: SkillStoreABC,
**_, # Allow for extra arguments if the loader passes them
) -> List[VeniceImageBaseTool]:
) -> list[VeniceImageBaseTool]:
"""Get all enabled Venice Image skills based on configuration and privacy level.

Args:
Expand All @@ -88,32 +104,28 @@ async def get_skills(
if not config.get("enabled", False):
return []

available_skills: List[VeniceImageBaseTool] = []
skill_states = config.get("states", {})

# Iterate through all known skills defined in the map
for skill_name in _SKILL_NAME_TO_CLASS_MAP:
state = skill_states.get(
skill_name, "disabled"
) # Default to disabled if not in config
available_skills: list[VeniceImageBaseTool] = []

# Include skills based on their state
for skill_name, state in config["states"].items():
if state == "disabled":
continue
elif state == "public" or (state == "private" and is_private):
# If enabled, get the skill instance using the factory function
skill_instance = get_venice_image_skill(skill_name, store)
if skill_instance:
available_skills.append(skill_instance)
else:
# This case should ideally not happen if the map is correct
logger.warning(f"Could not instantiate known skill: {skill_name}")
available_skills.append(skill_name)

return available_skills
# Get each skill using the cached getter
result = []
for name in available_skills:
skill = get_venice_image_skill(name, store, config)
if skill:
result.append(skill)
return result


def get_venice_image_skill(
name: str,
store: SkillStoreABC,
config: "Config",
) -> Optional[VeniceImageBaseTool]:
"""
Factory function to get a cached Venice Image skill instance by name.
Expand All @@ -125,25 +137,18 @@ def get_venice_image_skill(
Returns:
The requested Venice Image skill instance, or None if the name is unknown.
"""
# Check cache first

# Return from cache immediately if already exists
if name in _cache:
return _cache[name]

# Get the class from the map
skill_class = _SKILL_NAME_TO_CLASS_MAP.get(name)

if skill_class:
try:
# Instantiate the skill and add to cache
instance = skill_class(skill_store=store)
_cache[name] = instance
return instance
except Exception as e:
logger.error(
f"Failed to instantiate Venice Image skill '{name}': {e}", exc_info=True
)
return None # Failed to instantiate
else:
# This handles cases where a name might be in config but not in our map
logger.warning(f"Attempted to get unknown Venice Image skill: {name}")
if not skill_class:
logger.warning(f"Unknown Venice skill: {name}")
return None

# Cache and return the newly created instance
_cache[name] = skill_class(
skill_store=store,
)
return _cache[name]
Loading