vibe-aigc 0.7.0__tar.gz → 0.7.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {vibe_aigc-0.7.0/vibe_aigc.egg-info → vibe_aigc-0.7.1}/PKG-INFO +1 -1
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/pyproject.toml +1 -1
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/tools_comfyui.py +17 -7
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/vibe_backend.py +58 -1
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1/vibe_aigc.egg-info}/PKG-INFO +1 -1
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/LICENSE +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/README.md +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/setup.cfg +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_adaptive_replanning.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_agents.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_assets.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_auto_checkpoint.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_automatic_checkpoints.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_checkpoint_serialization.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_error_handling.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_executor.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_feedback_system.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_integration.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_knowledge_base.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_metaplanner_resume.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_metaplanner_visualization.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_models.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_parallel_execution.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_pipeline.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_planner.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_progress_callbacks.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_tools.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_visualization.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/tests/test_workflow_resume.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/__init__.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/agents.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/assets.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/audio.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/character.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/cli.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/comfyui.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/composer_general.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/discovery.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/executor.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/fidelity.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/knowledge.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/llm.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/model_registry.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/models.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/mv_pipeline.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/persistence.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/pipeline.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/planner.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/tools.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/tools_audio.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/tools_multimodal.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/tools_utility.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/tools_video.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/tools_vision.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/video.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/visualization.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/vlm_feedback.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/workflow_backend.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/workflow_composer.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/workflow_executor.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/workflow_registry.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/workflow_strategies.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc/workflows.py +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc.egg-info/SOURCES.txt +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc.egg-info/dependency_links.txt +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc.egg-info/entry_points.txt +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc.egg-info/requires.txt +0 -0
- {vibe_aigc-0.7.0 → vibe_aigc-0.7.1}/vibe_aigc.egg-info/top_level.txt +0 -0
|
@@ -8,7 +8,7 @@ exclude = ["tests*", "docs*", "examples*", "landing*"]
|
|
|
8
8
|
|
|
9
9
|
[project]
|
|
10
10
|
name = "vibe-aigc"
|
|
11
|
-
version = "0.7.
|
|
11
|
+
version = "0.7.1"
|
|
12
12
|
description = "A New Paradigm for Content Generation via Agentic Orchestration"
|
|
13
13
|
authors = [{name = "Vibe AIGC Contributors"}]
|
|
14
14
|
license = "MIT"
|
|
@@ -232,8 +232,9 @@ class VideoGenerationTool(BaseTool):
|
|
|
232
232
|
"""
|
|
233
233
|
Video generation tool using local ComfyUI.
|
|
234
234
|
|
|
235
|
-
|
|
236
|
-
|
|
235
|
+
Supports two modes:
|
|
236
|
+
- With image_url: Uses I2V (Image-to-Video) to animate existing image
|
|
237
|
+
- Without image_url: Uses T2V (Text-to-Video) to generate from scratch
|
|
237
238
|
"""
|
|
238
239
|
|
|
239
240
|
def __init__(self, comfyui_url: str = "http://127.0.0.1:8188"):
|
|
@@ -244,13 +245,14 @@ class VideoGenerationTool(BaseTool):
|
|
|
244
245
|
def spec(self) -> ToolSpec:
|
|
245
246
|
return ToolSpec(
|
|
246
247
|
name="video_generation",
|
|
247
|
-
description="Generate videos using local AI models
|
|
248
|
+
description="Generate videos using local AI models. Pass image_url to animate an existing image (I2V), or just prompt for text-to-video.",
|
|
248
249
|
category=ToolCategory.VIDEO,
|
|
249
250
|
input_schema={
|
|
250
251
|
"type": "object",
|
|
251
252
|
"required": ["prompt"],
|
|
252
253
|
"properties": {
|
|
253
|
-
"prompt": {"type": "string", "description": "Video description"},
|
|
254
|
+
"prompt": {"type": "string", "description": "Video/motion description"},
|
|
255
|
+
"image_url": {"type": "string", "description": "Source image URL to animate (enables I2V mode)"},
|
|
254
256
|
"negative_prompt": {"type": "string", "description": "What to avoid"},
|
|
255
257
|
"style": {"type": "string", "description": "Visual style hints"},
|
|
256
258
|
"motion": {"type": "string", "description": "Motion description"},
|
|
@@ -269,7 +271,7 @@ class VideoGenerationTool(BaseTool):
|
|
|
269
271
|
},
|
|
270
272
|
examples=[
|
|
271
273
|
{
|
|
272
|
-
"input": {"prompt": "
|
|
274
|
+
"input": {"prompt": "gentle breeze, swaying flowers", "image_url": "http://.../image.png"},
|
|
273
275
|
"output": {"video_url": "http://...", "duration_seconds": 2.0}
|
|
274
276
|
}
|
|
275
277
|
]
|
|
@@ -299,6 +301,7 @@ class VideoGenerationTool(BaseTool):
|
|
|
299
301
|
prompt = inputs.get("prompt", "")
|
|
300
302
|
style = inputs.get("style", "")
|
|
301
303
|
motion = inputs.get("motion", "")
|
|
304
|
+
image_url = inputs.get("image_url")
|
|
302
305
|
|
|
303
306
|
# Incorporate knowledge base hints
|
|
304
307
|
if context and "technical_specs" in context:
|
|
@@ -316,15 +319,22 @@ class VideoGenerationTool(BaseTool):
|
|
|
316
319
|
frames = inputs.get("frames", 33)
|
|
317
320
|
fps = inputs.get("fps", 16)
|
|
318
321
|
|
|
322
|
+
# Choose capability based on whether we have a source image
|
|
323
|
+
if image_url:
|
|
324
|
+
capability = Capability.IMAGE_TO_VIDEO
|
|
325
|
+
else:
|
|
326
|
+
capability = Capability.TEXT_TO_VIDEO
|
|
327
|
+
|
|
319
328
|
result = await backend.generate(GenerationRequest(
|
|
320
329
|
prompt=prompt,
|
|
321
|
-
capability=
|
|
330
|
+
capability=capability,
|
|
322
331
|
negative_prompt=inputs.get("negative_prompt", ""),
|
|
323
332
|
width=inputs.get("width", 832),
|
|
324
333
|
height=inputs.get("height", 480),
|
|
325
334
|
frames=frames,
|
|
326
335
|
steps=20,
|
|
327
|
-
cfg=5.0
|
|
336
|
+
cfg=5.0,
|
|
337
|
+
image_url=image_url # Pass source image for I2V
|
|
328
338
|
))
|
|
329
339
|
|
|
330
340
|
if result.success:
|
|
@@ -41,6 +41,7 @@ class GenerationRequest:
|
|
|
41
41
|
steps: int = 20
|
|
42
42
|
cfg: float = 7.0
|
|
43
43
|
seed: Optional[int] = None
|
|
44
|
+
image_url: Optional[str] = None # Source image for I2V/img2img
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
@dataclass
|
|
@@ -150,10 +151,18 @@ class VibeBackend:
|
|
|
150
151
|
import random
|
|
151
152
|
request.seed = random.randint(0, 2**32 - 1)
|
|
152
153
|
|
|
153
|
-
# Special handling for
|
|
154
|
+
# Special handling for video capabilities
|
|
154
155
|
if request.capability == Capability.TEXT_TO_VIDEO:
|
|
155
156
|
return await self._generate_video_via_i2v(request)
|
|
156
157
|
|
|
158
|
+
# IMAGE_TO_VIDEO: animate a provided image
|
|
159
|
+
if request.capability == Capability.IMAGE_TO_VIDEO:
|
|
160
|
+
if request.image_url:
|
|
161
|
+
return await self._animate_image(request)
|
|
162
|
+
else:
|
|
163
|
+
# No image provided, fall back to T2V pipeline
|
|
164
|
+
return await self._generate_video_via_i2v(request)
|
|
165
|
+
|
|
157
166
|
# Try to get workflow
|
|
158
167
|
workflow = await self._get_workflow(request)
|
|
159
168
|
if not workflow:
|
|
@@ -467,6 +476,54 @@ class VibeBackend:
|
|
|
467
476
|
print(f" Video: {video_result.output_path}")
|
|
468
477
|
return video_result
|
|
469
478
|
|
|
479
|
+
async def _animate_image(self, request: GenerationRequest) -> GenerationResult:
|
|
480
|
+
"""Animate an existing image with I2V.
|
|
481
|
+
|
|
482
|
+
Uses provided image_url instead of generating a new base image.
|
|
483
|
+
"""
|
|
484
|
+
print(f"\n[I2V] Animating provided image...")
|
|
485
|
+
print(f" Source: {request.image_url}")
|
|
486
|
+
|
|
487
|
+
# Download the source image
|
|
488
|
+
async with aiohttp.ClientSession() as session:
|
|
489
|
+
async with session.get(request.image_url) as resp:
|
|
490
|
+
if resp.status != 200:
|
|
491
|
+
return GenerationResult(
|
|
492
|
+
success=False,
|
|
493
|
+
error=f"Failed to download image: HTTP {resp.status}"
|
|
494
|
+
)
|
|
495
|
+
image_data = await resp.read()
|
|
496
|
+
|
|
497
|
+
# Upload to ComfyUI
|
|
498
|
+
form = aiohttp.FormData()
|
|
499
|
+
form.add_field('image', image_data, filename='input.png', content_type='image/png')
|
|
500
|
+
|
|
501
|
+
async with session.post(f"{self.url}/upload/image", data=form) as resp:
|
|
502
|
+
upload_result = await resp.json()
|
|
503
|
+
uploaded_name = upload_result.get("name", "input.png")
|
|
504
|
+
print(f" Uploaded: {uploaded_name}")
|
|
505
|
+
|
|
506
|
+
# Create I2V workflow
|
|
507
|
+
i2v_workflow = self._create_wan_i2v_workflow(
|
|
508
|
+
uploaded_image=uploaded_name,
|
|
509
|
+
prompt=request.prompt,
|
|
510
|
+
negative=request.negative_prompt,
|
|
511
|
+
width=request.width,
|
|
512
|
+
height=request.height,
|
|
513
|
+
frames=request.frames,
|
|
514
|
+
seed=request.seed
|
|
515
|
+
)
|
|
516
|
+
|
|
517
|
+
video_result = await self._execute_workflow(i2v_workflow)
|
|
518
|
+
if not video_result.success:
|
|
519
|
+
return GenerationResult(
|
|
520
|
+
success=False,
|
|
521
|
+
error=f"Animation failed: {video_result.error}"
|
|
522
|
+
)
|
|
523
|
+
|
|
524
|
+
print(f" Video: {video_result.output_path}")
|
|
525
|
+
return video_result
|
|
526
|
+
|
|
470
527
|
def _create_flux_image_workflow(
|
|
471
528
|
self, prompt: str, negative: str, width: int, height: int, seed: int
|
|
472
529
|
) -> Dict[str, Any]:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|