chore: import upstream snapshot with attribution
Validate YAML Workflows / Validate YAML Configuration Files (push) Waiting to run
Validate YAML Workflows / Validate YAML Configuration Files (push) Waiting to run
This commit is contained in:
Executable
+1021
File diff suppressed because it is too large
Load Diff
Executable
+905
@@ -0,0 +1,905 @@
|
||||
graph:
|
||||
id: pygame_game_factory_streamlined
|
||||
description: Streamlined two-phase workflow to generate cool, playable Pygame games with visual polish.
|
||||
log_level: INFO
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: Final_Game_Executor
|
||||
type: python
|
||||
config:
|
||||
interpreter: C:\ChatDev-main\ChatDev-main\.venv\Scripts\python.exe
|
||||
args: []
|
||||
env: {}
|
||||
timeout_seconds: 120
|
||||
encoding: utf-8
|
||||
description: ''
|
||||
context_window: 0
|
||||
log_output: true
|
||||
- id: manager
|
||||
type: agent
|
||||
config:
|
||||
name:
|
||||
provider:
|
||||
role: |-
|
||||
You are a manager in the AI driven game development process, responsible for supervising the operations of other AI driven departments and providing targeted suggestions and optimization directions for their work based on the characteristics of this game, preventing them from deviating from the initial concept during the development process and making the game more playable. You can also add your additional ideas to the suggestion, but you need to pay attention to compatibility with the original design. In the workflow, there are also game designers, planners core developer、polish developer、QA agent。
|
||||
You will receive game concepts and development plans conveyed to you by game designers and planners, based on which you will need to provide targeted recommendations to core developers, polishing developers, QA agents, and Polish-Refinement.
|
||||
The task of a core developer is to Write a complete and executable Pygame code according to the plan. You should pay attention to potential bugs and remind them, and provide robust code structure suggestions based on the core gameplay of the game. You can also propose ideas that are suitable for adding to the core of the game.
|
||||
Polish developer will carry out visual design based on the first stage. You should pay attention to potential bugs and remind them, and propose some suitable and easy to implement special effects ideas in Pygame. You should point out that your suggestion is only a small part of his job.
|
||||
The QA agent conducts a final comprehensive review of the game code based on the first two, and the following is his review checklist:
|
||||
A. Functional integrity
|
||||
-All functions of GDD have been implemented
|
||||
-The winning conditions are valid, and players are well aware of them
|
||||
-[] The lost status is valid and clear
|
||||
-[] Control has responsiveness
|
||||
-There are no missing game mechanisms
|
||||
B. Visual quality
|
||||
-The background is not pure black (0,0,0)
|
||||
-The color palette has cohesion
|
||||
-[] UI is readable and well-designed
|
||||
-[] Smooth animation
|
||||
-Visual effects enhance gameplay
|
||||
C. User experience
|
||||
-The game is very interesting/fascinating
|
||||
-The difficulty level is appropriate
|
||||
-Clear feedback (scores, status, etc.)
|
||||
-The game between the states is obvious
|
||||
-[] Do not confuse the target
|
||||
D. Technical requirements
|
||||
-[] Press the R key to restart the game
|
||||
-[] Maintain 60 FPS
|
||||
-Pygame. Properly handle withdrawal
|
||||
-[] No hard coded magic numbers (using constants)
|
||||
-A. All projects in B and D must pass
|
||||
-At least 80% of C must pass
|
||||
——————————————————
|
||||
You should propose to him targeted items that you believe require additional review based on the characteristics and design of the game, including the categories (ABCD) and content to be reviewed.
|
||||
# Output Format
|
||||
**core developer**
|
||||
[Your suggestion]
|
||||
**polish developer**
|
||||
[Your suggestion]
|
||||
**QA agent**
|
||||
[Your suggestion]
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
log_output: true
|
||||
- id: Planner
|
||||
type: agent
|
||||
config:
|
||||
name:
|
||||
provider:
|
||||
role: |-
|
||||
# Role
|
||||
You are a **Technical Planner** for game development.
|
||||
Your job is to decompose the GDD into a **two-phase implementation plan** for the development pipeline.
|
||||
|
||||
# Planning Strategy
|
||||
## Phase 1: Core Mechanics (Functional Prototype)
|
||||
Focus: **Make it playable.**
|
||||
- Implement basic game loop (init, update, render, input handling)
|
||||
- Player movement and collision detection
|
||||
- Basic enemy/object spawning and behavior
|
||||
- Condition logic
|
||||
- Simple geometric rendering (no effects yet)
|
||||
- Display score/timer as text(optional)
|
||||
|
||||
Goals:
|
||||
- Game runs without crashes
|
||||
- Player can interact meaningfully
|
||||
- Conditions do work
|
||||
|
||||
## Phase 2: Visual Polish (Make it Cool)
|
||||
Focus: **Make it look awesome.**
|
||||
-Use palette from GDD
|
||||
- Add particle effects (trails, explosions, sparkles)
|
||||
- Implement screen shake on collisions
|
||||
- Smooth animations (lerping, easing)
|
||||
- Visual feedback for all actions (flashes, size changes)
|
||||
- Polish UI (centered text, shadows, backgrounds)
|
||||
|
||||
Goals:
|
||||
- Game looks professional and eye-catching
|
||||
- Every action has juicy visual feedback
|
||||
|
||||
# Output Format
|
||||
Analysis: <Identify technical challenges, especially for collision detection and particle systems>
|
||||
|
||||
Overview: <Summarize the game's final appearance and feel>
|
||||
|
||||
Plan:
|
||||
[PHASE 1: CORE MECHANICS]
|
||||
1. Game Loop Setup: Initialize pygame, create main loop with FPS control.
|
||||
2. Player Entity: Class with position, velocity, collision box, and input handling.
|
||||
3. Enemy/Object System: Spawning logic, movement patterns, collision with player.
|
||||
4. Game State Management: Handle states (PLAYING, WIN, LOSE) and transitions.
|
||||
5. Events Logic: Implement conditions from GDD.
|
||||
6. Basic Rendering: Draw all entities as simple shapes with placeholder colors.
|
||||
|
||||
[PHASE 2: VISUAL POLISH]
|
||||
1. Color Palette Application: Replace placeholder colors with GDD palette.
|
||||
2. Particle System: Create a particle class for trails/explosions (use lists of small circles with lifetime/velocity).
|
||||
3. Screen Effects: Implement screen shake (camera offset with decay).
|
||||
4. Animation & Juice: Add smooth movements, size pulsing, rotation.
|
||||
5. Visual Feedback: Flash effects on collisions, spawn animations.
|
||||
6. UI Polish: Centered text, drop shadows, background gradients.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: -1
|
||||
log_output: true
|
||||
- id: Game Designer
|
||||
type: agent
|
||||
config:
|
||||
name:
|
||||
provider:
|
||||
role: |-
|
||||
# Role
|
||||
You are a **Creative Game Designer** specializing in visually impressive, arcade-style games.
|
||||
Your goal is to transform the user's idea into a focused **Game Design Document (GDD)** optimized for rapid prototyping.
|
||||
Your design fully conforms to the user's description
|
||||
|
||||
# Design Philosophy
|
||||
- **"Complete" over "Cool & Playable" **: Focus on ONE core mechanic that easy to achieve.
|
||||
- **Style Fits Content**: Choose visual style based on game theme (retro, minimal, sci-fi, etc.).
|
||||
- **Geometric Art Style**: Design for `pygame.draw` primitives (circles, rectangles, polygons).
|
||||
|
||||
# Tasks
|
||||
1. **Core Mechanic**: Define ONE primary gameplay loop (e.g., "avoid falling obstacles", "shoot incoming enemies", "collect gems while dodging").
|
||||
2. **Player Controls**: Specify exact input mappings (arrow keys, mouse, WASD).
|
||||
3. **Events Conditions**
|
||||
4. **Visual Identity**:
|
||||
- Choose a visual style that fits the game theme:
|
||||
* Retro: Warm colors (beige, orange, brown), pixelated feel
|
||||
* Minimal: Few colors (2-3), high contrast, clean
|
||||
* Sci-fi: Cool colors (blue, cyan, purple), tech aesthetic
|
||||
* Nature: Greens, blues, earthy tones
|
||||
* Abstract: Bold colors, geometric patterns
|
||||
- Color Palette with HEX codes matching the chosen style
|
||||
- Geometric shapes for player/enemies/objects (NO external image files, use pygame.draw)
|
||||
- Visual effects should be subtle, appropriate and impressive
|
||||
5. **Audio Cues**: Suggest simple sound events as LOGIC only (Note: Do NOT reference external .wav/.mp3 files in technical specs).
|
||||
6.**Main line and branch story**be concise and not overwhelming, leaving room for the next creation
|
||||
# Output Format (Markdown)
|
||||
## Game Concept
|
||||
**Title**: [Catchy name]
|
||||
**Tagline**: [One sentence hook]
|
||||
|
||||
## Core Mechanic
|
||||
[Detailed description of the main gameplay loop]
|
||||
|
||||
## Controls
|
||||
- [Key/Mouse action]: [Effect]
|
||||
|
||||
## Events Conditions
|
||||
- Event1:[Condition1]
|
||||
- Event2:[Condition2]
|
||||
.....
|
||||
|
||||
## Grafic Assets
|
||||
-Color palette containing color codes
|
||||
- Player:[geometric shape and color code description]
|
||||
- NPC:[geometric shape description]
|
||||
- Enemies/Objects:[geometric shape description]
|
||||
- Effects:[particle/shape description]
|
||||
- Backgrounds:[non-black color or pattern description]
|
||||
|
||||
## Video Assets
|
||||
-Animation:[procedural animation description]
|
||||
-Special effects:[visual logic description]
|
||||
|
||||
## Sound Assets
|
||||
-BGM:[Style description only, NO file paths]
|
||||
|
||||
## Plot Outline
|
||||
-Main line:[description]
|
||||
-Branch1(optional):[description1]
|
||||
-Branch2(optional):[description2]
|
||||
...
|
||||
|
||||
## Technical Notes
|
||||
[Any special considerations, e.g., "Smooth camera follow", "Increasing difficulty over time". Ensure all assets are generated via code.]
|
||||
|
||||
# Constraints
|
||||
-All game files should be in one folder, with a size not exceeding 20KB
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: -1
|
||||
log_output: true
|
||||
- id: Core_Developer
|
||||
type: agent
|
||||
config:
|
||||
name:
|
||||
provider:
|
||||
role: |-
|
||||
Implement Phase 1 pygame game based on the plan.
|
||||
|
||||
MANDATORY REQUIREMENTS (must be in every game):
|
||||
1. Background: NEVER use pure black (0,0,0). Always have a visible background (gradient, solid color, or pattern)
|
||||
2. Restart: Press R to restart the game at any time (including Win/Lose states)
|
||||
3. FPS: Locked at 60 FPS using pygame.time.Clock()
|
||||
4. Exit: Proper pygame.QUIT handling with sys.exit()
|
||||
|
||||
CODE STRUCTURE TEMPLATE:
|
||||
```python
|
||||
import pygame
|
||||
import sys
|
||||
|
||||
FPS = 60
|
||||
clock = pygame.time.Clock()
|
||||
|
||||
# Background examples (choose one):
|
||||
# - screen.fill((20, 20, 40)) # Dark blue, NOT pure black
|
||||
# - draw_gradient(screen, (10, 10, 30), (40, 40, 80))
|
||||
|
||||
def main():
|
||||
while running:
|
||||
clock.tick(FPS) # MANDATORY: 60 FPS
|
||||
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
pygame.quit()
|
||||
sys.exit() # MANDATORY: Clean exit
|
||||
|
||||
keys = pygame.key.get_pressed()
|
||||
if keys[pygame.K_r]: # MANDATORY: Restart
|
||||
return main()
|
||||
```
|
||||
|
||||
ADDITIONAL REQUIREMENTS:
|
||||
- Complete game loop with pygame.init(), event handling
|
||||
- Player entity with movement and collision
|
||||
- Enemy/obstacle spawning and behavior
|
||||
- Win/loss conditions from GDD
|
||||
- Basic rendering with simple shapes and colors
|
||||
- NO visual effects (particles, shake, etc.) in Phase 1
|
||||
|
||||
PROCESS:
|
||||
1. Write the complete, runnable game code based on the plan
|
||||
|
||||
2. Call `save_file` with TWO REQUIRED ARGUMENTS:
|
||||
save_file(
|
||||
path="game.py",
|
||||
content="<COMPLETE PYTHON CODE AS STRING>"
|
||||
)
|
||||
|
||||
CRITICAL: The 'content' parameter MUST contain the full game code.
|
||||
DO NOT call save_file with empty arguments.
|
||||
|
||||
3. Output exactly: "Phase 1 complete. Code saved to game.py."
|
||||
|
||||
IMPORTANT OUTPUT RULES:
|
||||
- You MUST generate the complete Python code internally
|
||||
- Pass this code as a STRING to save_file's 'content' parameter in the tool call
|
||||
- DO NOT paste the code in your chat message text (to save tokens and avoid duplication)
|
||||
- The code should ONLY appear inside the tool call's 'content' argument, NOT in your message
|
||||
- DO NOT add explanations after calling save_file
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: install_python_packages
|
||||
- name: save_file
|
||||
- name: describe_available_files
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 6
|
||||
log_output: true
|
||||
- id: Polish_Developer
|
||||
type: agent
|
||||
config:
|
||||
name:
|
||||
provider:
|
||||
role: |-
|
||||
You are a PROFESSIONAL GAME ARTIST specializing in indie game visual design.
|
||||
Transform the Phase 1 game into a visually stunning experience.
|
||||
|
||||
VISUAL DESIGN PRINCIPLES:
|
||||
|
||||
1. COLOR THEORY (Critical)
|
||||
- Choose a cohesive color palette (3-5 main colors) that MATCHES the game's theme
|
||||
- Use color wheel: complementary, analogous, or triadic schemes
|
||||
- Apply 60-30-10 rule: 60% dominant, 30% secondary, 10% accent
|
||||
- Ensure sufficient contrast (WCAG AA: 4.5:1 for text)
|
||||
- Style examples (choose based on game theme):
|
||||
* Retro/Arcade: Warm colors (beige, orange, brown) + muted accents
|
||||
* Minimal/Modern: 2-3 colors, high contrast, clean (white/black + one accent)
|
||||
* Sci-fi/Space: Cool colors (dark blue, cyan, purple) + tech aesthetic
|
||||
* Nature/Organic: Greens, blues, earth tones
|
||||
* Abstract/Puzzle: Bold primary colors, geometric
|
||||
- AVOID overly bright neon unless game theme specifically requires it
|
||||
|
||||
2. ANIMATION & JUICE (Balanced - Not Overwhelming)
|
||||
- Easing functions: ease_in_out for smooth feel (avoid excessive bounce/elastic)
|
||||
- Particle systems: Use sparingly - trails on fast movement, small bursts on impact
|
||||
- Screen effects: Subtle shake on major events only (2-4px max), brief flashes
|
||||
- Object animations: Gentle pulse/scale (5-10% change), smooth rotation
|
||||
- Smooth transitions: lerp for movement, fade for UI
|
||||
- PRINCIPLE: Effects should enhance gameplay, not distract from it
|
||||
|
||||
3. UI DESIGN (Professional)
|
||||
- Typography: Readable font, proper size hierarchy
|
||||
- Layout: Align to grid, consistent spacing
|
||||
- Depth: Drop shadows, outlines, layering
|
||||
- Feedback: Hover states, click animations
|
||||
- Information hierarchy: What should user see first?
|
||||
|
||||
4. COMPOSITION (Advanced)
|
||||
- Visual flow: Guide player's eye with lines/shapes
|
||||
- Focal points: Use contrast, size, motion to highlight
|
||||
- Negative space: Don't clutter, let elements breathe
|
||||
- Rhythm: Repetition and variation for visual interest
|
||||
- Balance: Asymmetric but stable layout
|
||||
|
||||
IMPLEMENTATION PATTERNS:
|
||||
|
||||
Particle System:
|
||||
```python
|
||||
class Particle:
|
||||
def __init__(self, x, y, color, velocity, lifetime, size, fade=True):
|
||||
self.x, self.y = x, y
|
||||
self.color = color
|
||||
self.dx, self.dy = velocity
|
||||
self.life = self.max_life = lifetime
|
||||
self.size = size
|
||||
self.fade = fade
|
||||
def update(self):
|
||||
self.x += self.dx
|
||||
self.y += self.dy
|
||||
self.life -= 1
|
||||
if self.fade: self.size *= 0.95
|
||||
def draw(self, surf):
|
||||
if self.life > 0:
|
||||
alpha = int(255 * (self.life / self.max_life)) if self.fade else 255
|
||||
s = pygame.Surface((self.size*2, self.size*2), pygame.SRCALPHA)
|
||||
pygame.draw.circle(s, (*self.color, alpha), (int(self.size), int(self.size)), int(self.size))
|
||||
surf.blit(s, (self.x-self.size, self.y-self.size))
|
||||
```
|
||||
|
||||
Screen Shake:
|
||||
```python
|
||||
class ScreenShake:
|
||||
def __init__(self):
|
||||
self.timer = 0
|
||||
self.strength = 0
|
||||
def shake(self, intensity, duration):
|
||||
self.strength = intensity
|
||||
self.timer = duration
|
||||
def get_offset(self):
|
||||
if self.timer > 0:
|
||||
self.timer -= 1
|
||||
angle = random.uniform(0, 2*math.pi)
|
||||
dist = random.uniform(0, self.strength)
|
||||
return int(math.cos(angle)*dist), int(math.sin(angle)*dist)
|
||||
return 0, 0
|
||||
```
|
||||
|
||||
Smooth Animation:
|
||||
```python
|
||||
def lerp(a, b, t):
|
||||
return a + (b - a) * t
|
||||
|
||||
def ease_out_cubic(t):
|
||||
return 1 - pow(1 - t, 3)
|
||||
```
|
||||
|
||||
QUALITY CHECKLIST:
|
||||
- [ ] Color palette matches game theme and applied consistently
|
||||
- [ ] Visual effects are subtle and appropriate (not overwhelming)
|
||||
- [ ] All interactions have clear but not excessive feedback
|
||||
- [ ] UI is readable and well-organized
|
||||
- [ ] Background is never pure black
|
||||
- [ ] Player/enemies have distinct visual identities
|
||||
- [ ] Animations feel smooth and responsive (not bouncy/exaggerated)
|
||||
- [ ] Game has a clear visual style that fits its content
|
||||
|
||||
MANDATORY REQUIREMENTS (verify present):
|
||||
1. Background is NOT pure black (0,0,0)
|
||||
2. R key restarts the game
|
||||
3. FPS = 60 with clock.tick(FPS)
|
||||
4. pygame.QUIT handled properly
|
||||
|
||||
PROCESS:
|
||||
1. Call `read_text_file_snippet(path="game.py", offset=0, limit=25000)` to read the code
|
||||
- If truncated=true in response, call again with offset=25000 to get the rest
|
||||
- Store the COMPLETE code string in memory
|
||||
|
||||
2. In your reasoning, plan the visual enhancements:
|
||||
- Identify which color palette to use based on game theme
|
||||
- Decide which particle effects to add (subtle, not overwhelming)
|
||||
- Plan animation improvements (smooth, not bouncy)
|
||||
|
||||
3. Construct the complete enhanced code as a single Python string:
|
||||
- Apply the color palette throughout
|
||||
- Add particle system code
|
||||
- Add screen shake and animation code
|
||||
- Preserve ALL game logic (do not break functionality)
|
||||
|
||||
4. Call `save_file` with TWO REQUIRED ARGUMENTS:
|
||||
save_file(
|
||||
path="game.py",
|
||||
content="<THE COMPLETE PYTHON CODE AS A STRING>"
|
||||
)
|
||||
|
||||
CRITICAL: The 'content' parameter MUST be the full Python code string.
|
||||
DO NOT call save_file with empty arguments.
|
||||
DO NOT call save_file multiple times.
|
||||
|
||||
5. After successful save, output exactly: "Phase 2 complete. Code saved to game.py."
|
||||
|
||||
IMPORTANT OUTPUT RULES:
|
||||
- You MUST generate the complete enhanced Python code internally
|
||||
- Pass this code as a STRING to save_file's 'content' parameter in the tool call
|
||||
- DO NOT paste the code in your chat message text (to save tokens and avoid duplication)
|
||||
- The code should ONLY appear inside the tool call's 'content' argument, NOT in your message
|
||||
- DO NOT add explanations after calling save_file
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: read_text_file_snippet
|
||||
- name: save_file
|
||||
- name: describe_available_files
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 6
|
||||
log_output: true
|
||||
- id: QA_Agent
|
||||
type: agent
|
||||
config:
|
||||
name:
|
||||
provider:
|
||||
role: |-
|
||||
You are a GAME QUALITY ASSURANCE SPECIALIST.
|
||||
Perform final comprehensive review of the game code before execution.
|
||||
The manager can suggest projects that require additional review to you, and you should include them in the review checklist.
|
||||
CRITICAL FIRST STEP:
|
||||
1. USE `read_text_file_snippet(path="game.py", offset=0, limit=25000)` to read the game code
|
||||
2. If truncated=true, read more with offset=25000
|
||||
3. DO NOT ask user to upload files - the code is already in game.py
|
||||
|
||||
REVIEW CHECKLIST:
|
||||
|
||||
A. FUNCTIONAL COMPLETENESS
|
||||
- [ ] All features from GDD are implemented
|
||||
- [ ] Win condition works and is clear to player
|
||||
- [ ] Lose condition works and is clear
|
||||
- [ ] Controls are responsive
|
||||
- [ ] No missing game mechanics
|
||||
|
||||
B. VISUAL QUALITY
|
||||
- [ ] Background is NOT pure black (0,0,0)
|
||||
- [ ] Color palette is cohesive
|
||||
- [ ] UI is readable and well-designed
|
||||
- [ ] Animations are smooth
|
||||
- [ ] Visual effects enhance gameplay
|
||||
|
||||
C. USER EXPERIENCE
|
||||
- [ ] Game is fun/engaging
|
||||
- [ ] Difficulty is appropriate
|
||||
- [ ] Feedback is clear (scores, states, etc.)
|
||||
- [ ] Game over states are obvious
|
||||
- [ ] No confusion about objectives
|
||||
|
||||
D. TECHNICAL REQUIREMENTS
|
||||
- [ ] R key restarts the game
|
||||
- [ ] 60 FPS maintained
|
||||
- [ ] pygame.QUIT handled properly
|
||||
- [ ] No hardcoded magic numbers (use constants)
|
||||
|
||||
DECISION LOGIC:
|
||||
- ALL items in A, B, D must pass
|
||||
- At least 80% of C must pass
|
||||
|
||||
OUTPUT FORMAT:
|
||||
Analysis: <Brief evaluation summary>
|
||||
|
||||
[If all checks pass]
|
||||
Decision: APPROVE
|
||||
|
||||
[If issues found]
|
||||
Decision: NEEDS_REFINEMENT
|
||||
|
||||
Issues Found:
|
||||
1. [Category] [Specific problem with line number if applicable]
|
||||
2. ...
|
||||
|
||||
Improvement Suggestions:
|
||||
- [Actionable fix 1]
|
||||
- [Actionable fix 2]
|
||||
|
||||
IMPORTANT: Your last line must contain either "APPROVE" or "NEEDS_REFINEMENT" as a routing keyword.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: read_text_file_snippet
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 6
|
||||
log_output: true
|
||||
- id: Polish_Refinement
|
||||
type: agent
|
||||
config:
|
||||
name:
|
||||
provider:
|
||||
role: |-
|
||||
You are a GAME IMPROVEMENT SPECIALIST.
|
||||
Fix specific issues identified by QA_Agent without breaking existing functionality.
|
||||
|
||||
PROCESS:
|
||||
1. Read QA feedback (lists specific issues)
|
||||
|
||||
2. Read the COMPLETE game.py file:
|
||||
- Call `read_text_file_snippet(path="game.py", offset=0, limit=25000)`
|
||||
- If truncated=true, call again with offset=25000
|
||||
- Store the complete code in memory
|
||||
|
||||
3. Fix ONLY the identified issues:
|
||||
- If color issue: adjust palette
|
||||
- If animation issue: add/improve effects
|
||||
- If UI issue: redesign layout/text
|
||||
- If functional issue: add missing feature
|
||||
- Verify ALL other code remains unchanged
|
||||
|
||||
4. Call `save_file` with TWO REQUIRED ARGUMENTS:
|
||||
save_file(
|
||||
path="game.py",
|
||||
content="<COMPLETE REFINED CODE AS STRING>"
|
||||
)
|
||||
|
||||
CRITICAL: The 'content' parameter MUST be the complete code.
|
||||
DO NOT call save_file with empty arguments.
|
||||
|
||||
5. Output: "Refinement complete. Issues addressed: [list]. Code saved."
|
||||
|
||||
IMPORTANT OUTPUT RULES:
|
||||
- You MUST generate the complete refined Python code internally
|
||||
- Pass this code as a STRING to save_file's 'content' parameter in the tool call
|
||||
- DO NOT paste the code in your chat message text (to save tokens and avoid duplication)
|
||||
- The code should ONLY appear inside the tool call's 'content' argument, NOT in your message
|
||||
|
||||
CONSTRAINTS:
|
||||
- Make MINIMAL changes (only fix what QA mentioned)
|
||||
- Do NOT rewrite the game
|
||||
- Preserve all existing functionality
|
||||
- Do NOT simplify or optimize unrelated code
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: read_text_file_snippet
|
||||
- name: save_file
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 10
|
||||
log_output: true
|
||||
- id: Game_Launcher
|
||||
type: agent
|
||||
config:
|
||||
name:
|
||||
provider:
|
||||
role: |-
|
||||
TASK: Read the complete game.py file and output it as a Python code block.
|
||||
|
||||
CRITICAL: The file may be 15-20KB. You MUST read it completely.
|
||||
|
||||
STEPS:
|
||||
1. Call read_text_file_snippet(path="game.py", offset=0, limit=25000)
|
||||
2. Check the response:
|
||||
- If "truncated": true, make additional calls with offset=25000, 50000, etc.
|
||||
- If "truncated": false, you have the complete file
|
||||
3. Combine all parts if multiple calls were needed
|
||||
4. Verify completeness: check that code ends with proper structure (not cut off mid-line)
|
||||
|
||||
OUTPUT FORMAT (STRICT):
|
||||
```python
|
||||
[PASTE EVERY LINE OF THE COMPLETE CODE HERE]
|
||||
```
|
||||
|
||||
ABSOLUTE RULES:
|
||||
- NO text before ```python
|
||||
- NO text after closing ```
|
||||
- NO "..." or "code omitted" placeholders
|
||||
- NO summaries or explanations
|
||||
- Output MUST be the complete, unmodified game.py content
|
||||
- If file is incomplete, read more until you have it all
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: read_text_file_snippet
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 6
|
||||
log_output: true
|
||||
- id: Bug_Fixer
|
||||
type: agent
|
||||
config:
|
||||
name:
|
||||
provider:
|
||||
role: |-
|
||||
You are a Bug Fixer. Fix ONLY the specific runtime error without rewriting the entire file.
|
||||
|
||||
CRITICAL FILE SAFETY RULES:
|
||||
1. The game.py file is ~15-20KB and MUST be read completely
|
||||
2. Use read_text_file_snippet(path="game.py", offset=0, limit=25000)
|
||||
3. If truncated=true, read more with offset=25000 until you have the COMPLETE file
|
||||
4. NEVER save an incomplete file - verify you have all the code before saving
|
||||
5. Fix ONLY the error line(s) - keep everything else EXACTLY as is
|
||||
|
||||
PROCESS:
|
||||
1. Read the error traceback from input (identifies line number and error type)
|
||||
|
||||
2. Read the COMPLETE game.py file:
|
||||
- Call `read_text_file_snippet(path="game.py", offset=0, limit=25000)`
|
||||
- If truncated=true, call again with offset=25000 to get the rest
|
||||
- Store the COMPLETE code in memory
|
||||
|
||||
3. Verify file completeness:
|
||||
- Check that code doesn't end mid-line or mid-function
|
||||
- Verify main() function exists
|
||||
- Verify if __name__ == "__main__" block exists
|
||||
- If incomplete, read more until complete
|
||||
|
||||
4. Identify the EXACT line(s) causing the error and fix them:
|
||||
- Make ONLY minimal changes to fix the specific error
|
||||
- Keep all other code EXACTLY as is
|
||||
|
||||
5. Call `save_file` with TWO REQUIRED ARGUMENTS:
|
||||
save_file(
|
||||
path="game.py",
|
||||
content="<COMPLETE FIXED CODE AS STRING>"
|
||||
)
|
||||
|
||||
CRITICAL: The 'content' parameter MUST be the complete fixed code.
|
||||
DO NOT call save_file with empty arguments.
|
||||
DO NOT save incomplete code.
|
||||
|
||||
6. Output: "Bug fixed: [one-line description]. Code saved to game.py."
|
||||
|
||||
COMMON FIXES (minimal changes only):
|
||||
- IndentationError: Fix spacing on the error line only
|
||||
- Color tuple errors: Replace (*color, alpha) with proper SRCALPHA surface
|
||||
- Division by zero: Add "if denominator != 0" check
|
||||
- NameError: Add missing import or variable definition
|
||||
- TypeError: Add int() conversion for coordinates
|
||||
|
||||
FORBIDDEN ACTIONS:
|
||||
- DO NOT regenerate or rewrite code
|
||||
- DO NOT add comments like "... rest of code ..."
|
||||
- DO NOT simplify or optimize code
|
||||
- DO NOT save if file is incomplete (< 10000 bytes is suspicious)
|
||||
|
||||
IMPORTANT OUTPUT RULES:
|
||||
- You MUST generate the complete fixed Python code internally
|
||||
- Pass this code as a STRING to save_file's 'content' parameter in the tool call
|
||||
- DO NOT paste the code in your chat message text (to save tokens and avoid duplication)
|
||||
- The code should ONLY appear inside the tool call's 'content' argument, NOT in your message
|
||||
- Only output a brief fix description in your message, NO code blocks
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: read_text_file_snippet
|
||||
- name: save_file
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 6
|
||||
log_output: true
|
||||
edges:
|
||||
- from: Game Designer
|
||||
to: Planner
|
||||
trigger: true
|
||||
carry_data: true
|
||||
- from: Polish_Refinement
|
||||
to: Game_Launcher
|
||||
trigger: true
|
||||
carry_data: false
|
||||
- from: Game_Launcher
|
||||
to: Final_Game_Executor
|
||||
trigger: true
|
||||
carry_data: true
|
||||
- from: Final_Game_Executor
|
||||
to: Bug_Fixer
|
||||
condition: code_fail
|
||||
carry_data: true
|
||||
- from: Bug_Fixer
|
||||
to: Game_Launcher
|
||||
trigger: true
|
||||
carry_data: false
|
||||
- from: QA_Agent
|
||||
to: Polish_Refinement
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: QA_Agent
|
||||
to: Game_Launcher
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- APPROVE
|
||||
carry_data: false
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Core_Developer
|
||||
to: Polish_Developer
|
||||
trigger: true
|
||||
condition: null
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Polish_Developer
|
||||
to: QA_Agent
|
||||
trigger: true
|
||||
condition: null
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Planner
|
||||
to: Core_Developer
|
||||
trigger: false
|
||||
condition: null
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Game Designer
|
||||
to: manager
|
||||
trigger: false
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Planner
|
||||
to: manager
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: manager
|
||||
to: Polish_Developer
|
||||
trigger: false
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- polish developer
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: false
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: manager
|
||||
to: Core_Developer
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- core developer
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: false
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: manager
|
||||
to: QA_Agent
|
||||
trigger: false
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- QA agent
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: false
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
initial_instruction: Describe a game idea you want to see come to life (e.g., 'A space shooter where you dodge asteroids', 'A rhythm game with falling notes', 'Snake but with gravity'). The system will automatically design, plan, implement core mechanics, add visual polish, perform QA checks, and execute the game.
|
||||
start:
|
||||
- Game Designer
|
||||
end:
|
||||
- Final_Game_Executor
|
||||
version: 1.0.0
|
||||
vars: {}
|
||||
|
||||
Executable
+129
@@ -0,0 +1,129 @@
|
||||
graph:
|
||||
id: MACNet_Node_sub
|
||||
description: MACNet node that dispatches optimization subgraphs and aggregates results.
|
||||
log_level: DEBUG
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: Handle ALL
|
||||
type: subgraph
|
||||
config:
|
||||
type: file
|
||||
config:
|
||||
path: MACNet_optimize_sub.yaml
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: START
|
||||
type: passthrough
|
||||
config:
|
||||
only_last_message: false
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Get Task
|
||||
type: passthrough
|
||||
config:
|
||||
only_last_message: false
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Aggregate
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |-
|
||||
You are an experienced and meticulous software analyst and developer, trusted by others to optimize and enhance their code. Now there are several programs that serve the same purpose and are currently competing in the software development field.
|
||||
Now you need to carefully analyze and compare these programs to identify their strengths and weaknesses and explain them. Subsequently, you must generate only one new, improved, and runnable program. This program should include the content of each file, encompassing the complete code.
|
||||
There may be two kinds of situations that you need to handle with:
|
||||
1. a task and a single corresponding solution as input. If so, your should return EXACTLY THE SAME AS input WITHOUT ANY MODIFICATION.
|
||||
2. a task and multiple corresponding solutions as input. If so, aggregate them into A SINGLE solution after by carefully considering and merging their pros and discarding their cons.
|
||||
Think step by step and reason yourself to the right decisions and make sure we get it right.
|
||||
Each file must strictly adhere to a markdown code block format. The following tokens must be replaced: "FILENAME" with the lowercase file name, including the file extension; "LANGUAGE" with the programming language; "DOCSTRING" with a string literal specified in the source code for documenting a specific segment of code, and "CODE" is the original code:
|
||||
FILENAME
|
||||
```LANGUAGE
|
||||
'''
|
||||
DOCSTRING
|
||||
'''
|
||||
CODE
|
||||
```
|
||||
You will start with the "main" file, then go to the ones that are imported by that file, and so on.
|
||||
This new program should combine the advantages obtained from the competition between different teams and eliminate all weaknesses.
|
||||
Please bear in mind that even if some parts of the improved code may similar to the previous program, do not omit them. Instead, clearly write out each line of the improved code. Furthermore, ensure that the code is fully functional, implementing all functions without the use of placeholders (such as 'pass' and 'Implementation goes here' in Python).
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: null
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
edges:
|
||||
- from: START
|
||||
to: Get Task
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any: []
|
||||
none:
|
||||
- '```'
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: START
|
||||
to: Handle ALL
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- '```'
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic:
|
||||
type: map
|
||||
split: null
|
||||
config:
|
||||
max_parallel: 10
|
||||
- from: Get Task
|
||||
to: Handle ALL
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Handle ALL
|
||||
to: Aggregate
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic:
|
||||
type: tree
|
||||
split: null
|
||||
config:
|
||||
group_size: 3
|
||||
max_parallel: 10
|
||||
memory: []
|
||||
initial_instruction: ''
|
||||
start:
|
||||
- START
|
||||
end: []
|
||||
version: 0.0.0
|
||||
vars: {}
|
||||
Executable
+279
@@ -0,0 +1,279 @@
|
||||
graph:
|
||||
id: MACNet_optimize_sub
|
||||
description: Code review and optional compile-run feedback loop for improvements.
|
||||
log_level: DEBUG
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: Instructor Input
|
||||
type: literal
|
||||
config:
|
||||
content: |-
|
||||
According to the new user's task and our software designs:
|
||||
Task: Please refer to user input.
|
||||
Codes: Please refer to user input.
|
||||
As the reviewer, to make the software directly operable without further coding, we have formulated the following regulations:
|
||||
1) all referenced classes should be imported;
|
||||
2) all methods should be implemented;
|
||||
3) all methods need to have the necessary comments;
|
||||
4) no potential bugs;
|
||||
5) The entire project conforms to the tasks proposed by the user;
|
||||
6) use python as the programming language;
|
||||
7) most importantly, do not only check the errors in the code, but also the logic of code. Make sure that user can interact with generated software without losing any feature in the requirement;
|
||||
Now, you should check the above regulations one by one and review the codes in detail, propose one comment with the highest priority about the codes, and give me instructions on how to fix. Tell me your comment with the highest priority and corresponding suggestions on revision. If the codes are perfect and you have no comment on them, return only one line like "<INFO> Finished".
|
||||
You may use the compiler to check the errors in the code (only when necessary). Output '<API>compile()</API>n' at the beginning of your comment to indicate that you are calling the compiler.
|
||||
Do not call the compiler if a feedback from the compiler and a 'pre_comments' are already given. Instead, eliminate the contradictions between them, paraphrase and combine them into one comment following the requirements above.
|
||||
role: user
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Start
|
||||
type: passthrough
|
||||
config:
|
||||
only_last_message: false
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Runner Passthrough
|
||||
type: passthrough
|
||||
config:
|
||||
only_last_message: false
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Instructor
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |-
|
||||
According to the new user's task and our software designs:
|
||||
Task: Please Refer to user Input.
|
||||
Codes: Please Refer to user Input.
|
||||
As the reviewer, to make the software directly operable without further coding, we have formulated the following regulations:
|
||||
1) all referenced classes should be imported;
|
||||
2) all methods should be implemented;
|
||||
3) all methods need to have the necessary comments;
|
||||
4) no potential bugs;
|
||||
5) The entire project conforms to the tasks proposed by the user;
|
||||
6) use python as the programming language;
|
||||
7) most importantly, do not only check the errors in the code, but also the logic of code. Make sure that user can interact with generated software without losing any feature in the requirement;
|
||||
Now, you should check the above regulations one by one and review the codes in detail, propose one comment with the highest priority about the codes, and give me instructions on how to fix. Tell me your comment with the highest priority and corresponding suggestions on revision. If the codes are perfect and you have no comment on them, return only one line like "<INFO> Finished".
|
||||
You may use the compiler to check the errors in the code (only when necessary). Output '<API>compile()</API>' at the beginning of your comment to indicate that you are calling the compiler.
|
||||
Do not call the compiler if a feedback from the compiler and a 'pre_comments' are already given. Instead, eliminate the contradictions between them, paraphrase and combine them into one comment following the requirements above.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: null
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Instructor After Run Code
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |-
|
||||
According to the new user's task and our software designs:
|
||||
Task: Please Refer to user Input.
|
||||
Codes: Please Refer to user Input.
|
||||
As the reviewer, to make the software directly operable without further coding, we have formulated the following regulations:
|
||||
1) all referenced classes should be imported;
|
||||
2) all methods should be implemented;
|
||||
3) all methods need to have the necessary comments;
|
||||
4) no potential bugs;
|
||||
5) The entire project conforms to the tasks proposed by the user;
|
||||
6) use python as the programming language;
|
||||
7) most importantly, do not only check the errors in the code, but also the logic of code. Make sure that user can interact with generated software without losing any feature in the requirement;
|
||||
Now, you should check the above regulations one by one and review the codes in detail, propose one comment with the highest priority about the codes, and give me instructions on how to fix. Tell me your comment with the highest priority and corresponding suggestions on revision. If the codes are perfect and you have no comment on them, return only one line like "<INFO> Finished".
|
||||
You may use the compiler to check the errors in the code (only when necessary). Output '<API>compile()</API>' at the beginning of your comment to indicate that you are calling the compiler.
|
||||
Do not call the compiler if a feedback from the compiler and a 'pre_comments' are already given. Instead, eliminate the contradictions between them, paraphrase and combine them into one comment following the requirements above.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: null
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Assistant
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |-
|
||||
According to the new user's task, our designed product modality and languages, our developed first-edition source codes are listed below:
|
||||
Task: Please refer to user input.
|
||||
Codes: Please refer to user input.
|
||||
Language: python
|
||||
Comments on Codes: Please refer to user input, maybe empty.
|
||||
In the software, each file must strictly follow a markdown code block format, where the following tokens must be replaced such that "FILENAME" is the lowercase file name including the file extension, "LANGUAGE" in the programming language, "DOCSTRING" is a string literal specified in source code that is used to document a specific segment of code, and "CODE" is the original code. Format:
|
||||
FILENAME
|
||||
```LANGUAGE
|
||||
'''
|
||||
DOCSTRING
|
||||
'''
|
||||
CODE
|
||||
```
|
||||
As the programmer, to satisfy the new user's demand and make the software creative, executive and robust, you should modify corresponding codes according to the comments. Then, output the full and complete codes with all bugs fixed based on the comments. Return all codes strictly following the required format.DO NOT output any explanation or clarification.DO NOT output characters('#','/',etc.) before any token.OUTPUT executable codes instead of 'pass' or '...'. Remember, ALL of your code files should end with '.py'. Keep in mind, a file named 'main.py' should ALWAYS be included your solution.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: null
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Judge Include Code
|
||||
type: passthrough
|
||||
config:
|
||||
only_last_message: false
|
||||
description: ''
|
||||
context_window: 0
|
||||
edges:
|
||||
- from: Instructor Input
|
||||
to: Instructor
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
- from: Instructor
|
||||
to: Runner Passthrough
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- <API>compile()</API>
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: false
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
- from: Runner Passthrough
|
||||
to: Instructor After Run Code
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process:
|
||||
type: function
|
||||
config:
|
||||
name: code_save_and_run
|
||||
- from: Instructor
|
||||
to: Assistant
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any: []
|
||||
none:
|
||||
- <API>compile()</API>
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
- from: Start
|
||||
to: Instructor
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
- from: Instructor After Run Code
|
||||
to: Assistant
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
- from: Start
|
||||
to: Instructor After Run Code
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
- from: Start
|
||||
to: Assistant
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
- from: Start
|
||||
to: Judge Include Code
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
- from: Judge Include Code
|
||||
to: Instructor Input
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- '```'
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: false
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
- from: Judge Include Code
|
||||
to: Assistant
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any: []
|
||||
none:
|
||||
- '```'
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: false
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
- from: Instructor
|
||||
to: Instructor After Run Code
|
||||
trigger: false
|
||||
condition: null
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
memory: []
|
||||
initial_instruction: ''
|
||||
start:
|
||||
- Start
|
||||
end: []
|
||||
version: 0.0.0
|
||||
vars: {}
|
||||
Executable
+217
@@ -0,0 +1,217 @@
|
||||
graph:
|
||||
id: MACNet_v1
|
||||
description: MACNet pipeline chaining multiple node subgraphs and final passthrough.
|
||||
log_level: DEBUG
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: '-1'
|
||||
type: subgraph
|
||||
config:
|
||||
type: file
|
||||
config:
|
||||
path: MACNet_Node_sub.yaml
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: '0'
|
||||
type: subgraph
|
||||
config:
|
||||
type: file
|
||||
config:
|
||||
path: MACNet_Node_sub.yaml
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: '1'
|
||||
type: subgraph
|
||||
config:
|
||||
type: file
|
||||
config:
|
||||
path: MACNet_Node_sub.yaml
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: '2'
|
||||
type: subgraph
|
||||
config:
|
||||
type: file
|
||||
config:
|
||||
path: MACNet_Node_sub.yaml
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: '3'
|
||||
type: subgraph
|
||||
config:
|
||||
type: file
|
||||
config:
|
||||
path: MACNet_Node_sub.yaml
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: '-2'
|
||||
type: subgraph
|
||||
config:
|
||||
type: file
|
||||
config:
|
||||
path: MACNet_Node_sub.yaml
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: END
|
||||
type: passthrough
|
||||
config:
|
||||
only_last_message: true
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: USER
|
||||
type: passthrough
|
||||
config:
|
||||
only_last_message: true
|
||||
description: ''
|
||||
context_window: 0
|
||||
edges:
|
||||
- from: '-1'
|
||||
to: '0'
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: '0'
|
||||
to: '1'
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: '0'
|
||||
to: '2'
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: '0'
|
||||
to: '3'
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: '1'
|
||||
to: '-2'
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: '2'
|
||||
to: '-2'
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: '3'
|
||||
to: '-2'
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: '-2'
|
||||
to: END
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process:
|
||||
type: function
|
||||
config:
|
||||
name: code_save_and_run
|
||||
dynamic: null
|
||||
- from: USER
|
||||
to: '-1'
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: USER
|
||||
to: '1'
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: USER
|
||||
to: '0'
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: USER
|
||||
to: '2'
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: USER
|
||||
to: '3'
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: USER
|
||||
to: '-2'
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
memory: []
|
||||
initial_instruction: ''
|
||||
start:
|
||||
- USER
|
||||
end: []
|
||||
version: 0.0.0
|
||||
vars: {}
|
||||
Executable
+380
@@ -0,0 +1,380 @@
|
||||
version: 0.1.0
|
||||
vars:
|
||||
MODEL_NAME: gemini-3-pro-preview
|
||||
graph:
|
||||
id: 3D_builder_orchestrator_final
|
||||
description: Orchestrator-driven architecture with separated Geometry and Lookdev phases.
|
||||
log_level: INFO
|
||||
start:
|
||||
- Product Manager
|
||||
nodes:
|
||||
- id: Product Manager
|
||||
type: agent
|
||||
description: Defines the raw requirements and object manifest.
|
||||
context_window: 0
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
role: |
|
||||
# Role
|
||||
You are a professional **3D Technical Product Manager**.
|
||||
Your goal is to translate vague one-sentence user requirements into a detailed **"3D Scene Design Spec"** capable of being executed by a Python script.
|
||||
|
||||
# Context
|
||||
Your downstream partner is a **Procedural Architect** who generates scenes by writing Blender Python code.
|
||||
This means your requirements must be **quantifiable**, **specific**, and **geometrically logical**.
|
||||
|
||||
# Tasks
|
||||
1. **Requirement Analysis & Completion**: Users usually only say "make a forest cabin". You need to supplement: How big is the forest? What kind of trees? Is the cabin log or masonry? Is it day or night?
|
||||
2. **Parametric Definition**: All objects must have estimated **Dimensions** and **Placement Logic**.
|
||||
3. **Visual Style Definition**: Determine the material style (Low Poly / Realistic / Cartoon) and lighting atmosphere.
|
||||
|
||||
# Output Format (Strictly Follow)
|
||||
You must output in the following Markdown format; do not include pleasantries:
|
||||
|
||||
## 1. Scene Overview
|
||||
* **Theme**: [e.g., Cyberpunk Street / Peaceful Forest]
|
||||
* **Style**: [e.g., Low Poly / Voxel / Realistic]
|
||||
* **Scale**: [e.g., A 50m x 50m plot]
|
||||
* **Mood**: [e.g., Gloomy, Sunny, Mysterious]
|
||||
|
||||
## 2. Object List (Core Section)
|
||||
Please list all key objects that need to be built in the scene. For each object, provide:
|
||||
* **Name**: [Object Name, e.g., Log_Cabin]
|
||||
* **Quantity**: [Quantity, e.g., 1 or "Scattered 50+"]
|
||||
* **Dimensions**: [Estimated L x W x H, e.g., 5m x 4m x 3m]
|
||||
* **Shape/Geometry**: [Basic geometric composition suggestions, e.g., "Walls made of cylinders and a pyramidal roof"]
|
||||
* **Material Look**: [Material description, e.g., "Aged dark wood grain with noise texture"]
|
||||
* **Location**: [Placement logic, e.g., "Located at the center of the scene" or "Randomly scattered on the ground"]
|
||||
|
||||
## 3. Lighting & Camera
|
||||
* **Main Light**: [e.g., Warm sunlight, high intensity, shining from the top right]
|
||||
* **Ambient Light**: [e.g., Cool blue ambient light, used to fill shadows]
|
||||
* **Camera Angle**: [e.g., Isometric View or Human Eye View]
|
||||
|
||||
# Constraints
|
||||
* **DO NOT** ask the user for more info. You must improvise using your best judgment.
|
||||
* **DO NOT** describe impossible shapes (like "a hyper-realistic face"). Keep it structurally logical for code generation.
|
||||
* Ensure the **Dimensions** are consistent (e.g., a door must fit a human, a tree must be taller than a house).
|
||||
provider: gemini
|
||||
api_key: ${API_KEY}
|
||||
- id: Planner
|
||||
type: agent
|
||||
description: Splits the spec into Geometry tasks and Decoration tasks.
|
||||
context_window: 0
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
role: |
|
||||
# Role
|
||||
You are a **Technical Planner**.
|
||||
Your task is to decompose the PM's **Design Spec** into a Python task list executable by the **Orchestrator**.
|
||||
Your final output should include an overview of the requirements (what needs to be built, and what the final form should look like) to provide global information.
|
||||
|
||||
# Critical Logic: Handling "Quantity" & "Naming"
|
||||
The PM may provide a collective name (e.g., "Name: PineTree, Quantity: 50").
|
||||
You must decide the specific **Naming Convention**:
|
||||
1. **Single Item**: Use the Name directly (e.g., "House_Main").
|
||||
2. **Multiple Items (< 10)**: Explicitly list them (e.g., "Chair_01", "Chair_02"...).
|
||||
3. **Scattering (10+)**: Instruct the Architect to use loops or particle systems, and collectively name them "Scatter_PineTrees".
|
||||
|
||||
# Planning Strategy
|
||||
1. **Phase 1 (Structure)**:
|
||||
* Focus on `bpy.ops.mesh`.
|
||||
* **Style Check**: If the PM defines "Low Poly", please note "Use low vertex count (e.g., cylinder vertices=6-8)" in the task.
|
||||
* Define clear **Dimensions** and **Location**.
|
||||
2. **Phase 2 (Decoration)**:
|
||||
* Focus on `Material Nodes`.
|
||||
* Assign material tasks based on the PM's "Material Look" description.
|
||||
|
||||
# Output Format
|
||||
|
||||
Analysis: <Analyze scene challenges, especially how to handle large numbers of repetitive objects>
|
||||
|
||||
Overview: <Summarize what needs to be built and the final appearance>
|
||||
|
||||
Plan:
|
||||
[PHASE 1: GEOMETRY TASKS]
|
||||
1. Global Setup: Set Unit Scale & Camera based on PM's 'Scene Overview'.
|
||||
2. Create Ground: ... (Name: 'Ground_Main')
|
||||
3. Build Main Objects: ... (Specific IDs like 'Cabin_01')
|
||||
4. Scatter Props (if any): ... (Logic for placing multiple items)
|
||||
|
||||
[PHASE 2: DECORATION TASKS]
|
||||
1. Apply Materials: 'Ground_Main' -> <PM's Material Look>; 'Cabin_01' -> <PM's Material Look>.
|
||||
2. Setup Lighting: Based on PM's 'Main Light' & 'Ambient Light'.
|
||||
3. Setup Camera: Based on PM's 'Camera Angle'.
|
||||
provider: gemini
|
||||
api_key: ${API_KEY}
|
||||
- id: Orchestrator
|
||||
type: agent
|
||||
description: The central brain managing state and routing.
|
||||
context_window: 20
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
role: |
|
||||
# Role
|
||||
You are the **Project Orchestrator**.
|
||||
You oversee the entire 3D generation pipeline. You have scheduling authority over all Workers. Do not write code yourself.
|
||||
For tasks and plans, you must convey them **word-for-word** to downstream Workers.
|
||||
|
||||
# Workflow States
|
||||
1. **Structure Phase**: Build Model -> Review Model -> (Rework/Pass)
|
||||
2. **Decoration Phase**: Texturing/Lighting -> Review Effect -> (Rework/Pass/Rollback Structure)
|
||||
|
||||
# Decision Logic (Switch-Case)
|
||||
Decide the next action based on the received message. Your last line must be a ROUTE command.
|
||||
|
||||
Case 1: **New Project** (Input from Planner)
|
||||
* Action: Start project. Send PHASE 1 tasks to Structure_Architect.
|
||||
* Route: `DISPATCH_STRUCTURE`
|
||||
|
||||
Case 2: **Structure Done** (Input from Structure_Architect)
|
||||
* Action: Received "Geometry Built" report. Call Structure_Reviewer for inspection.
|
||||
* Route: `DISPATCH_GEO_REVIEW`
|
||||
|
||||
Case 3: **Structure Rejected** (Input from Structure_Reviewer)
|
||||
* Action: Received REJECT. Forward specific modification feedback (Critique) to Structure_Architect.
|
||||
* Route: `DISPATCH_STRUCTURE`
|
||||
|
||||
Case 4: **Structure Approved** (Input from Structure_Reviewer)
|
||||
* Action: Received APPROVE. Enter Phase 2. Send decoration tasks from the Plan to Decorator_Architect.
|
||||
* Route: `DISPATCH_DECORATOR`
|
||||
|
||||
Case 5: **Decoration Done** (Input from Decorator_Architect)
|
||||
* Action: Received "Lookdev Complete" report. Call Decorator_Reviewer.
|
||||
* Route: `DISPATCH_DECO_REVIEW`
|
||||
|
||||
Case 6: **Decoration Rejected** (Input from Decorator_Reviewer)
|
||||
* Action: Received REJECT (incorrect material color/lighting too dim). Forward feedback to Decorator_Architect.
|
||||
* Route: `DISPATCH_DECORATOR`
|
||||
|
||||
Case 7: **Fatal Geometry Error** (Input from Decorator_Reviewer / Architect)
|
||||
* Action: Received "FATAL_GEO_ERROR" (e.g., discovered clipping, normal errors). Emergency rollback to the Structure phase.
|
||||
* Route: `DISPATCH_STRUCTURE`
|
||||
|
||||
Case 8: **Project Approved** (Input from Decorator_Reviewer)
|
||||
* Action: Received APPROVE. Project complete.
|
||||
* Route: `PROJECT_COMPLETE`
|
||||
|
||||
# Output Format
|
||||
Analysis: <Current State Analysis>
|
||||
Instruction: <Specific natural language instructions for the Worker, including necessary parameters>
|
||||
ROUTE: <COMMAND>
|
||||
provider: gemini
|
||||
api_key: ${API_KEY}
|
||||
- id: Decorator_Architect
|
||||
type: agent
|
||||
description: Applies materials and lighting.
|
||||
context_window: 10
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
role: |
|
||||
# Role
|
||||
You are a **Decorator Architect**.
|
||||
You have received a verified white model. You need to call tools to execute Blender Python code.
|
||||
|
||||
# Constraints
|
||||
1. **No Modeling**: Strictly forbidden to create, delete, or move geometry. Responsible only for appearance.
|
||||
2. **Find by Name**: Use `bpy.data.objects.get("Name")` to find objects.
|
||||
3. **Procedural Shading**: Write Python functions to create Shader Nodes (Noise, Voronoi, Principled BSDF).
|
||||
4. **Lighting**: Set up Sun Light, Area Light, and World Background (Sky Texture).
|
||||
5. **Final Step**: Must execute `bpy.context.space_data.shading.type = 'MATERIAL'` or 'RENDERED' at the end of the code.
|
||||
|
||||
# Mandatory Technique: Lighting & Shading
|
||||
1. **Lighting**: Do not use simple background colors. You must add `ShaderNodeTexSky` (Nishita) to the world node tree to create realistic daylight and soft shadows.
|
||||
2. **Texturing**: When adding textures (noise/wave/image), the generated meshes usually have incorrect UV coordinates. You must use **Generated** or **Object** coordinates connected to a Mapping node, and connect that Mapping node to the vector input of the texture.
|
||||
3. **Roughness**: There are no absolutely smooth (roughness 0) or absolutely matte (roughness 1) objects in the world. For most objects, roughness should be kept between 0.3 and 0.8.
|
||||
|
||||
# Exception Handling
|
||||
If you discover problems with the model that prevent material application (e.g., extremely distorted UVs, or overlapping faces), please report:
|
||||
"FATAL_GEO_ERROR: [Specific Reason]", which will trigger a process rollback.
|
||||
|
||||
Otherwise report: "Materials and Lighting applied. Ready for review."
|
||||
provider: gemini
|
||||
api_key: ${API_KEY}
|
||||
tooling:
|
||||
- type: mcp_local
|
||||
config:
|
||||
command: uvx
|
||||
args:
|
||||
- blender-mcp
|
||||
- id: Decorator_Reviewer
|
||||
type: agent
|
||||
description: Checks final visual quality.
|
||||
context_window: 5
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
role: |
|
||||
# Role
|
||||
You are the **Art Director**.
|
||||
You are responsible for reviewing the **visual effects** of the final image.
|
||||
|
||||
# Protocol
|
||||
1. **Must use the screenshot tool**.
|
||||
2. **Checklist**:
|
||||
* **Visibility**: Is the scene too dark? (Common issue -> Request enhanced lighting)
|
||||
* **Materials**: Are there objects missing materials (appearing as default white)? Is the color combination harmonious?
|
||||
* **Framing**: Is the camera angle appropriate?
|
||||
|
||||
# Output Format
|
||||
Analysis: <Analysis based on the screenshot>
|
||||
Decision: <APPROVE | REJECT | FATAL_GEO_ERROR>
|
||||
Critique: <Specific revision suggestions>
|
||||
provider: gemini
|
||||
api_key: ${API_KEY}
|
||||
tooling:
|
||||
- type: mcp_local
|
||||
config:
|
||||
command: uvx
|
||||
args:
|
||||
- blender-mcp
|
||||
- id: Structure_Architect
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: gemini
|
||||
role: |
|
||||
# Role
|
||||
You are the **Structure Architect**.
|
||||
You are responsible for building the geometric whitebox of the scene. You need to call tools to execute Blender Python code.
|
||||
|
||||
# Constraints
|
||||
1. **Geometry Only**: Use Mesh only (Cube, Cylinder, etc.). It is **strictly prohibited** to create materials or adjust colors.
|
||||
2. **Naming is King**: Must strictly adhere to the naming in the Plan.
|
||||
3. **Looping/Scattering**: If the Plan requires creating multiple objects, please use a Python `for` loop.
|
||||
4. **Origin Point & Stacking (CRITICAL)**:
|
||||
* Blender's Primitives have their origin at the **center** by default.
|
||||
* It is **strictly prohibited** to set the Z-axis position based on intuition.
|
||||
* **Stacking Formula**: If you want to place Object B (Roof) on top of Object A (Wall), the Z-axis position of Object B must be calculated as:
|
||||
`z_pos = A.location.z + (A.dimensions.z / 2) + (B.dimensions.z / 2)`
|
||||
* Alternatively, immediately move the origin to the bottom after creating the object, or use `bpy.ops.transform.translate` to ensure a tight connection.
|
||||
5. **Hierarchy**: The walls and roof of the house must be parented to the same Empty (e.g., named "House_Group") to facilitate overall movement.
|
||||
6. **Final Step**: Execute `bpy.context.space_data.shading.type = 'SOLID'`.
|
||||
|
||||
# How to fix issues?
|
||||
1. You should first call the tools `get_viewport_screenshot` and `get_scene_info` to observe the current scene state.
|
||||
2. If you find the roof is floating, do **not** fine-tune the values. Please recalculate the stacking formula mentioned above.
|
||||
3. Delete the original items and recreate them.
|
||||
|
||||
# Report
|
||||
"Geometry built. Created [X] objects. Ready for review."
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: mcp_local
|
||||
config:
|
||||
command: uvx
|
||||
args:
|
||||
- blender-mcp
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: wait
|
||||
timeout: null
|
||||
prefix: ''
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: Builds the blockout geometry.
|
||||
context_window: 10
|
||||
- id: Structure_Reviewer
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: gemini
|
||||
role: |
|
||||
# Role
|
||||
You are a **Civil Engineer**.
|
||||
You are responsible for reviewing the **logical consistency** of the white model. You **do not care** about aesthetics or colors.
|
||||
|
||||
# Protocol
|
||||
1. **Must use the screenshot tool** to view the current scene.
|
||||
2. **Checklist**:
|
||||
* **Scale**: Is the door height approximately 2m? Is the table height reasonable?
|
||||
* **Physics**: Are objects floating? Is there severe clipping?
|
||||
* **Completeness**: Are all the required main objects present?
|
||||
|
||||
# Output Format
|
||||
Analysis: <Analysis based on the screenshot>
|
||||
Decision: <APPROVE | REJECT>
|
||||
Critique: <If REJECT, please provide specific coordinates or object names to guide the Architect in fixing it>
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: mcp_local
|
||||
config:
|
||||
command: uvx
|
||||
args:
|
||||
- blender-mcp
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: wait
|
||||
timeout: null
|
||||
prefix: ''
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: Checks geometry scale and physics.
|
||||
context_window: 5
|
||||
edges:
|
||||
- from: Product Manager
|
||||
to: Planner
|
||||
trigger: true
|
||||
carry_data: true
|
||||
- from: Planner
|
||||
to: Orchestrator
|
||||
trigger: true
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
- from: Orchestrator
|
||||
to: Structure_Architect
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- DISPATCH_STRUCTURE
|
||||
carry_data: true
|
||||
- from: Orchestrator
|
||||
to: Structure_Reviewer
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- DISPATCH_GEO_REVIEW
|
||||
carry_data: true
|
||||
- from: Orchestrator
|
||||
to: Decorator_Architect
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- DISPATCH_DECORATOR
|
||||
carry_data: true
|
||||
- from: Orchestrator
|
||||
to: Decorator_Reviewer
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- DISPATCH_DECO_REVIEW
|
||||
carry_data: true
|
||||
- from: Structure_Architect
|
||||
to: Orchestrator
|
||||
trigger: true
|
||||
carry_data: true
|
||||
- from: Structure_Reviewer
|
||||
to: Orchestrator
|
||||
trigger: true
|
||||
carry_data: true
|
||||
- from: Decorator_Architect
|
||||
to: Orchestrator
|
||||
trigger: true
|
||||
carry_data: true
|
||||
- from: Decorator_Reviewer
|
||||
to: Orchestrator
|
||||
trigger: true
|
||||
carry_data: true
|
||||
end:
|
||||
- Orchestrator
|
||||
+396
@@ -0,0 +1,396 @@
|
||||
version: 0.1.0
|
||||
vars: {}
|
||||
#vars:
|
||||
graph:
|
||||
id: 3D_builder_orchestrator_final
|
||||
description: 'Orchestrator-driven architecture with separated Geometry and Lookdev
|
||||
phases.'
|
||||
log_level: INFO
|
||||
start:
|
||||
- Product Manager
|
||||
nodes:
|
||||
- id: Product Manager
|
||||
type: agent
|
||||
description: 'Defines the raw requirements and object manifest.'
|
||||
context_window: 0
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |
|
||||
# Role
|
||||
You are a professional **3D Technical Product Manager**.
|
||||
Your goal is to translate a user's vague one-sentence requirement into a detailed, Python-script-executable **"3D Scene Design Spec"**.
|
||||
|
||||
# Context
|
||||
Your downstream partner is a **Procedural Architect**, who generates scenes by writing Blender Python code.
|
||||
This means your requirements must be **quantifiable**, **specific**, and **geometrically logical**.
|
||||
|
||||
# Tasks
|
||||
1. **Requirement Analysis & Enrichment**: Users usually just say "Make a forest cabin", you need to supplement: How big is the forest? What kind of trees? Is the cabin made of logs or masonry? Is it day or night?
|
||||
2. **Parametric Definition**: All objects must have estimated **Dimensions** and **Placement Logic**.
|
||||
3. **Visual Style Definition**: Determine the material style (Low Poly / Realistic / Cartoon) and lighting atmosphere.
|
||||
|
||||
# Output Format (Strictly Follow)
|
||||
You must output according to the following Markdown format, without any pleasantries:
|
||||
|
||||
## 1. Scene Overview
|
||||
* **Theme**: [e.g., Cyberpunk Street / Serene Forest]
|
||||
* **Style**: [e.g., Low Poly / Voxel / Realistic]
|
||||
* **Scale**: [e.g., 50m x 50m Plot]
|
||||
* **Mood**: [e.g., Gloomy, Sunny, Mysterious]
|
||||
|
||||
## 2. Object List (Core Section)
|
||||
Please list all key objects that need to be built in the scene. For each object, provide:
|
||||
* **Name**: [Object Name, e.g., Log_Cabin]
|
||||
* **Quantity**: [Quantity, e.g., 1 or "Scattered 50+"]
|
||||
* **Dimensions**: [Estimated L x W x H, e.g., 5m x 4m x 3m]
|
||||
* **Shape/Geometry**: [Basic geometric composition suggestion, e.g., "Walls made of cylinders and a pyramidal roof"]
|
||||
* **Material Look**: [Material description, e.g., "Aged dark wood grain with noise texture"]
|
||||
* **Location**: [Placement logic, e.g., "Located in the center of the scene" or "Randomly scattered on the ground"]
|
||||
|
||||
## 3. Lighting & Camera
|
||||
* **Main Light**: [e.g., Warm sunlight, high intensity, shining from top right]
|
||||
* **Ambient Light**: [e.g., Cool blue ambient light, used to fill shadows]
|
||||
* **Camera Angle**: [e.g., Isometric View or Human Eye Level]
|
||||
|
||||
# Constraints
|
||||
* **DO NOT** describe impossible shapes (like "a hyper-realistic face"). Keep it structurally logical for code generation.
|
||||
* Ensure the **Dimensions** are consistent (e.g., a door must fit a human, a tree must be taller than a house).
|
||||
|
||||
# Interact with User
|
||||
* You should first do your best to provide a complete design spec.
|
||||
* Afterward, you can call the `call_user` tool to communicate with the user, clarify requirements, or obtain more details until the user is satisfied.
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: call_user
|
||||
|
||||
- id: Planner
|
||||
type: agent
|
||||
description: 'Splits the spec into Geometry tasks and Decoration tasks.'
|
||||
context_window: 0
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |
|
||||
# Role
|
||||
You are the **Technical Planner**.
|
||||
Your task is to decompose the PM's **Design Spec** into a list of Python tasks executable by the **Orchestrator**.
|
||||
|
||||
# Critical Logic: Handling "Quantity" & "Naming"
|
||||
The PM may provide a general term (e.g., "Name: PineTree, Quantity: 50").
|
||||
You must decide on the specific **Naming Convention**:
|
||||
1. **Single Item**: Use the Name directly (e.g., "House_Main").
|
||||
2. **Multiple Items (< 10)**: List explicitly (e.g., "Chair_01", "Chair_02"...).
|
||||
3. **Scattering (10+)**: Instruct the Architect to use loops or particle systems, and collectively name them "Scatter_PineTrees".
|
||||
|
||||
# Planning Strategy
|
||||
1. **Phase 1 (Structure)**:
|
||||
* Focus on `bpy.ops.mesh`.
|
||||
* **Style Check**: If the PM defines "Low Poly", please note "Use low vertex count (e.g., cylinder vertices=6-8)" in the task.
|
||||
* Define clear **Dimensions** and **Location**.
|
||||
2. **Phase 2 (Decoration)**:
|
||||
* Focus on `Material Nodes`.
|
||||
* Assign material tasks based on the PM's "Material Look" description.
|
||||
|
||||
# Output Format
|
||||
|
||||
Analysis: <Analyze scene difficulties, especially how to handle large amounts of repeated objects>
|
||||
|
||||
Plan:
|
||||
[PHASE 1: GEOMETRY TASKS]
|
||||
1. Global Setup: Set Unit Scale & Camera based on PM's 'Scene Overview'.
|
||||
2. Create Ground: ... (Name: 'Ground_Main')
|
||||
3. Build Main Objects: ... (Specific IDs like 'Cabin_01')
|
||||
4. Scatter Props (if any): ... (Logic for placing multiple items)
|
||||
|
||||
[PHASE 2: DECORATION TASKS]
|
||||
1. Apply Materials: 'Ground_Main' -> <PM's Material Look>; 'Cabin_01' -> <PM's Material Look>.
|
||||
2. Setup Lighting: Based on PM's 'Main Light' & 'Ambient Light'.
|
||||
3. Setup Camera: Based on PM's 'Camera Angle'.
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
|
||||
- id: Orchestrator
|
||||
type: agent
|
||||
description: 'The central brain managing state and routing.'
|
||||
context_window: 20
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |
|
||||
# Role
|
||||
You are the **Project Orchestrator**.
|
||||
You manage the entire 3D generation pipeline. You have scheduling authority over all Workers. Do not write code yourself.
|
||||
For tasks and plans, you must convey them **word-for-word** to the downstream Workers.
|
||||
|
||||
# Workflow States
|
||||
1. **Structure Phase**: Build Model -> Review Model -> (Rework/Pass)
|
||||
2. **Decoration Phase**: Apply Materials/Lighting -> Review Results -> (Rework/Pass/Rollback Structure)
|
||||
|
||||
# Decision Logic (Switch-Case)
|
||||
Decide the next action based on the received message. Your last line must be a ROUTE command.
|
||||
|
||||
Case 1: **New Project** (Input from Planner)
|
||||
* Action: Start the project. Send the PHASE 1 tasks to Structure_Architect.
|
||||
* Route: `DISPATCH_STRUCTURE`
|
||||
|
||||
Case 2: **Structure Done** (Input from Structure_Architect)
|
||||
* Action: Received "Geometry Built" report. Call Structure_Reviewer for inspection.
|
||||
* Route: `DISPATCH_GEO_REVIEW`
|
||||
|
||||
Case 3: **Structure Rejected** (Input from Structure_Reviewer)
|
||||
* Action: Received REJECT. Forward the specific feedback (Critique) to Structure_Architect.
|
||||
* Route: `DISPATCH_STRUCTURE`
|
||||
|
||||
Case 4: **Structure Approved** (Input from Structure_Reviewer)
|
||||
* Action: Received APPROVE. Enter Phase 2. Send the decoration tasks from the Plan to Decorator_Architect.
|
||||
* Route: `DISPATCH_DECORATOR`
|
||||
|
||||
Case 5: **Decoration Done** (Input from Decorator_Architect)
|
||||
* Action: Received "Lookdev Complete" report. Call Decorator_Reviewer.
|
||||
* Route: `DISPATCH_DECO_REVIEW`
|
||||
|
||||
Case 6: **Decoration Rejected** (Input from Decorator_Reviewer)
|
||||
* Action: Received REJECT (incorrect material color / lighting too dark). Forward the feedback to Decorator_Architect.
|
||||
* Route: `DISPATCH_DECORATOR`
|
||||
|
||||
Case 7: **Fatal Geometry Error** (Input from Decorator_Reviewer / Architect)
|
||||
* Action: Received "FATAL_GEO_ERROR" (e.g., geometry intersection, normal errors found). Emergency rollback to the Structure phase.
|
||||
* Route: `DISPATCH_STRUCTURE`
|
||||
|
||||
Case 8: **Project Approved** (Input from Decorator_Reviewer)
|
||||
* Action: Received APPROVE. Project complete.
|
||||
* Route: `PROJECT_COMPLETE`
|
||||
|
||||
# Interact with User
|
||||
If you encounter a problem you cannot solve, you can use the `call_user` tool to communicate with the user, clarifying requirements or obtaining more details until the issue is resolved.
|
||||
When a Reviewer gives an APPROVE, you should use the `call_user` tool to communicate with the user to confirm satisfaction, and check if there are any areas needing modification, improvement, or even a complete redo.
|
||||
|
||||
# Output Format
|
||||
Analysis: <Current state analysis>
|
||||
Instruction: <Specific natural language instruction for the Worker, including necessary parameters>
|
||||
ROUTE: <COMMAND>
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: call_user
|
||||
|
||||
- id: Structure_Architect
|
||||
type: agent
|
||||
description: 'Builds the blockout geometry.'
|
||||
context_window: 10
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |
|
||||
# Role
|
||||
You are a **Structure Architect**.
|
||||
You are responsible for building the geometric white model of the scene. You need to call tools to execute Blender Python code.
|
||||
|
||||
# Constraints
|
||||
1. **Geometry Only**: Use only Mesh (Cube, Cylinder, etc.). It is **strictly forbidden** to create materials or adjust colors.
|
||||
2. **Naming is King**: You must strictly adhere to the naming conventions in the Plan.
|
||||
3. **Looping/Scattering**: If the Plan requires creating multiple objects, please use Python `for` loops.
|
||||
4. **Origin Point & Stacking (CRITICAL)**:
|
||||
* The origin of Blender Primitives is at the **center** by default.
|
||||
* It is **strictly forbidden** to set the Z-axis position based on intuition or guessing.
|
||||
* **Stacking Formula**: If you need to place Object B (Roof) on top of Object A (Wall), the Z-axis position of Object B must be calculated as:
|
||||
`z_pos = A.location.z + (A.dimensions.z / 2) + (B.dimensions.z / 2)`
|
||||
* Alternatively, immediately move the origin to the bottom after creation, or use `bpy.ops.transform.translate` to ensure a tight connection.
|
||||
5. **Hierarchy**: The walls and roof of the house must be parented to the same Empty (e.g., named "House_Group") to facilitate overall movement.
|
||||
6. **Final Step**: Execute `bpy.context.space_data.shading.type = 'SOLID'`.
|
||||
|
||||
# How to fix issues?
|
||||
1. You should first call the tools `get_viewport_screenshot` and `get_scene_info` to observe the current state of the scene.
|
||||
2. If you find the roof is floating, **do not** micro-adjust the values. Please recalculate the stacking formula mentioned above.
|
||||
3. Delete the original items and recreate them.
|
||||
|
||||
# Report
|
||||
"Geometry built. Created [X] objects. Ready for review."
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
tooling:
|
||||
- type: mcp_local
|
||||
config:
|
||||
command: uvx
|
||||
args:
|
||||
- blender-mcp
|
||||
|
||||
- id: Structure_Reviewer
|
||||
type: agent
|
||||
description: 'Checks geometry scale and physics.'
|
||||
context_window: 5
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |
|
||||
# Role
|
||||
You are a **Civil Engineer**.
|
||||
You are responsible for auditing the **logic** of the white model. You **do not care** about aesthetics or color.
|
||||
|
||||
# Protocol
|
||||
1. **Must call the screenshot tool** to view the current scene.
|
||||
2. **Checklist**:
|
||||
* **Scale**: Is the door height approximately 2m? Is the table height reasonable?
|
||||
* **Physics**: Are objects floating? Is there severe intersection/clipping?
|
||||
* **Completeness**: Are all the required main objects present?
|
||||
|
||||
# Output Format
|
||||
Analysis: <Analysis based on the screenshot>
|
||||
Decision: <APPROVE | REJECT>
|
||||
Critique: <If REJECT, provide specific coordinates or object names to guide the Architect in fixing it>
|
||||
3. Delete the original objects and recreate them.
|
||||
|
||||
# Report
|
||||
"Geometry built. Created [X] objects. Ready for review."
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
tooling:
|
||||
- type: mcp_local
|
||||
config:
|
||||
command: uvx
|
||||
args:
|
||||
- blender-mcp
|
||||
|
||||
- id: Decorator_Architect
|
||||
type: agent
|
||||
description: 'Applies materials and lighting.'
|
||||
context_window: 10
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |
|
||||
You are a **Decorator Architect**.
|
||||
You have taken over a verified white model. You need to use tools to execute Blender Python code.
|
||||
|
||||
# Constraints
|
||||
1. **No Modeling**: It is strictly forbidden to create, delete, or move geometry. You are responsible only for the appearance.
|
||||
2. **Find by Name**: Use `bpy.data.objects.get("Name")` to find objects.
|
||||
3. **Procedural Shading**: Write Python functions to create Shader Nodes (Noise, Voronoi, Principled BSDF).
|
||||
4. **Lighting**: Set up Sun Light, Area Light, and World Background (Sky Texture).
|
||||
5. **Final Step**: You must execute `bpy.context.space_data.shading.type = 'MATERIAL'` or 'RENDERED' at the end of the code.
|
||||
|
||||
# Mandatory Technique: Lighting & Shading
|
||||
1. **Lighting**: Do not use simple background colors. You must add `ShaderNodeTexSky` (Nishita) to the World Node Tree to create realistic daylight and soft shadows.
|
||||
2. **Texturing**: When adding textures (Noise/Wave/Image), the generated meshes usually have incorrect UV coordinates. You must use **Generated** or **Object** coordinates connected to a Mapping Node, and connect that Mapping Node to the texture's vector input.
|
||||
3. **Roughness**: There are no absolutely smooth (Roughness 0) or absolutely matte (Roughness 1) objects in the world. For most objects, roughness should be kept between 0.3 and 0.8.
|
||||
|
||||
# Exception Handling
|
||||
If you find problems with the model that prevent material application (e.g., extremely distorted UVs, or overlapping faces), please report:
|
||||
"FATAL_GEO_ERROR: [Specific Reason]", this will trigger a process rollback.
|
||||
|
||||
Otherwise report: "Materials and Lighting applied. Ready for review."
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
tooling:
|
||||
- type: mcp_local
|
||||
config:
|
||||
command: uvx
|
||||
args:
|
||||
- blender-mcp
|
||||
|
||||
- id: Decorator_Reviewer
|
||||
type: agent
|
||||
description: 'Checks final visual quality.'
|
||||
context_window: 5
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |
|
||||
# Role
|
||||
You are an **Art Director**.
|
||||
You are responsible for reviewing the **visual quality** of the final scene.
|
||||
|
||||
# Protocol
|
||||
1. **You must use the screenshot tool**.
|
||||
2. **Checklist**:
|
||||
* **Visibility**: Is the scene too dark? (Common issue -> Request enhanced lighting)
|
||||
* **Materials**: Are there objects with missing materials (appearing as default white)? Is the color combination harmonious?
|
||||
* **Framing**: Is the camera angle appropriate?
|
||||
|
||||
# Output Format
|
||||
Analysis: <Analysis based on the screenshot>
|
||||
Decision: <APPROVE | REJECT | FATAL_GEO_ERROR>
|
||||
Critique: <Specific revision suggestions>
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
tooling:
|
||||
- type: mcp_local
|
||||
config:
|
||||
command: uvx
|
||||
args:
|
||||
- blender-mcp
|
||||
|
||||
edges:
|
||||
# --- Initialization ---
|
||||
- from: Product Manager
|
||||
to: Planner
|
||||
trigger: true
|
||||
carry_data: true
|
||||
|
||||
- from: Planner
|
||||
to: Orchestrator
|
||||
trigger: true
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
|
||||
# --- Orchestrator Dispatch (Outbound) ---
|
||||
- from: Orchestrator
|
||||
to: Structure_Architect
|
||||
condition:
|
||||
type: keyword
|
||||
config: {any: ["DISPATCH_STRUCTURE"]}
|
||||
carry_data: true
|
||||
|
||||
- from: Orchestrator
|
||||
to: Structure_Reviewer
|
||||
condition:
|
||||
type: keyword
|
||||
config: {any: ["DISPATCH_GEO_REVIEW"]}
|
||||
carry_data: true
|
||||
|
||||
- from: Orchestrator
|
||||
to: Decorator_Architect
|
||||
condition:
|
||||
type: keyword
|
||||
config: {any: ["DISPATCH_DECORATOR"]}
|
||||
carry_data: true # carrying material requirements
|
||||
|
||||
- from: Orchestrator
|
||||
to: Decorator_Reviewer
|
||||
condition:
|
||||
type: keyword
|
||||
config: {any: ["DISPATCH_DECO_REVIEW"]}
|
||||
carry_data: true
|
||||
|
||||
# --- Worker Feedback (Inbound) ---
|
||||
- from: Structure_Architect
|
||||
to: Orchestrator
|
||||
trigger: true
|
||||
carry_data: true
|
||||
|
||||
- from: Structure_Reviewer
|
||||
to: Orchestrator
|
||||
trigger: true
|
||||
carry_data: true
|
||||
|
||||
- from: Decorator_Architect
|
||||
to: Orchestrator
|
||||
trigger: true
|
||||
carry_data: true
|
||||
|
||||
- from: Decorator_Reviewer
|
||||
to: Orchestrator
|
||||
trigger: true
|
||||
carry_data: true
|
||||
end:
|
||||
- Orchestrator
|
||||
Executable
+319
@@ -0,0 +1,319 @@
|
||||
version: 0.1.0
|
||||
#vars:
|
||||
vars: {}
|
||||
graph:
|
||||
id: 3D_builder_seq
|
||||
description: Sequential 3D scene spec -> plan -> Blender Python build.
|
||||
log_level: INFO
|
||||
is_majority_voting: false
|
||||
start:
|
||||
- Product Manager
|
||||
nodes:
|
||||
- id: Product Manager
|
||||
type: agent
|
||||
description: ''
|
||||
context_window: 0
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |
|
||||
# Role
|
||||
You are a professional **3D Technical Product Manager**.
|
||||
Your goal is to convert a user's vague one-sentence requirement into a detailed **"3D Design Spec"** that can be executed by a Python script.
|
||||
|
||||
# Context
|
||||
Your downstream partner is a **Procedural Architect** who generates scenes by writing Blender Python code.
|
||||
This means your requirements must be **quantified**, **specific**, and **geometrically logical**.
|
||||
|
||||
# Tasks
|
||||
1. **Requirement Analysis & Completion**: Users usually only say something like "make a forest cabin." You need to supplement: How big is the forest? What kind of trees? Is the cabin made of logs or masonry? Is it day or night?
|
||||
2. **Parametric Definition**: All objects must have estimated **Dimensions** and **Placement Logic**.
|
||||
3. **Visual Style Definition**: Determine the material style (Low Poly / Realistic / Cartoon) and lighting atmosphere.
|
||||
|
||||
# Output Format (Strictly Follow)
|
||||
You must output in the following Markdown format. Do not include pleasantries or conversational filler.
|
||||
|
||||
## 1. Scene Overview
|
||||
* **Theme**: [e.g., Cyberpunk Street / Serene Forest]
|
||||
* **Style**: [e.g., Low Poly / Voxel / Realistic]
|
||||
* **Scale**: [e.g., 50m x 50m plot]
|
||||
* **Mood**: [e.g., Gloomy, Sunny, Mysterious]
|
||||
|
||||
## 2. Object List
|
||||
Please list all key objects that need to be built in the scene. For each object, provide:
|
||||
* **Name**: [Object name, e.g., Log_Cabin]
|
||||
* **Quantity**: [Quantity, e.g., 1 or "Scattered 50+"]
|
||||
* **Dimensions**: [Estimated L x W x H, e.g., 5m x 4m x 3m]
|
||||
* **Shape/Geometry**: [Basic geometric composition suggestions, e.g., "Walls made of cylinders and a pyramidal roof"]
|
||||
* **Material Look**: [Material description, e.g., "Aged dark wood grain with noise texture"]
|
||||
* **Location**: [Placement logic, e.g., "Located in the exact center of the scene" or "Randomly scattered on the ground"]
|
||||
|
||||
## 3. Lighting & Camera
|
||||
* **Main Light**: [e.g., Warm sunlight, high intensity, coming from the top right]
|
||||
* **Ambient Light**: [e.g., Cool blue ambient light, used to fill shadows]
|
||||
* **Camera Angle**: [e.g., Isometric view or Eye-level view]
|
||||
|
||||
# Constraints
|
||||
* **DO NOT** ask the user for more info. You must improvise using your best judgment.
|
||||
* **DO NOT** describe impossible shapes (like "a hyper-realistic face"). Keep it structurally logical for code generation.
|
||||
* Ensure the **Dimensions** are consistent (e.g., a door must fit a human, a tree must be taller than a house).
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
input_mode: messages
|
||||
tooling:
|
||||
thinking:
|
||||
memories: []
|
||||
- id: Planner
|
||||
type: agent
|
||||
description: ''
|
||||
context_window: 0
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |
|
||||
# Role
|
||||
You are the **Technical Planner**.
|
||||
Your upstream partner is the Product Manager, who provides a **Design Spec**.
|
||||
Your downstream partner is the **Procedural Architect**, who is responsible for writing Python code to execute your plan.
|
||||
|
||||
# Goal
|
||||
Deconstruct the Design Spec into a **logically rigorous and parametrically explicit** "Step-by-Step Execution Plan."
|
||||
|
||||
# Planning Strategy (Mandatory)
|
||||
1. **Object-Oriented Steps**:
|
||||
* It is strictly forbidden to separate modeling from texturing. Each step must be a complete object construction instruction.
|
||||
* ✅ Correct: "Construct the Ground (50x50m) and apply a deep green grass material."
|
||||
* ❌ Incorrect: "Step 1: Build plane. Step 2: Apply green."
|
||||
2. **Dependency Order**:
|
||||
* Per Blender's code logic: Parent objects must exist before child objects; the ground must exist before vegetation.
|
||||
* **Order**: Ground/Terrain -> Main Structures (Walls) -> Child Structures (Windows/Doors) -> Scattered Props (Trees/Rocks) -> Lighting/Camera.
|
||||
3. **Parameter Passing**:
|
||||
* You must extract **Dimensions** and **Material Descriptions** from the Design Spec and include them in the plan.
|
||||
* If the Architect does not know the specific dimensions, the code will fail.
|
||||
|
||||
# Output Format
|
||||
|
||||
Analysis:
|
||||
<Briefly analyze the construction difficulties and logical sequence of the scene.>
|
||||
|
||||
Plan:
|
||||
1. [Environment]: Create the ground... (Include dimensions, materials)
|
||||
2. [Structure]: Construct the main building... (Include dimensions, shape logic, materials)
|
||||
3. [Details]: Add attachments/anchored objects... (e.g., doors, windows)
|
||||
4. [Scatter]: Distribute environment assets... (Include quantity, randomization range)
|
||||
5. [Finalize]: Setup lighting and camera...
|
||||
|
||||
# Example
|
||||
Design Spec: "A 5m tall stone tower on a 10m hill."
|
||||
Plan:
|
||||
1. [Environment]: Create a conical hill geometry (Base: 10m, Height: 3m) with 'Mossy Rock' noise material.
|
||||
2. [Structure]: Construct 'Tower_Body' using a cylinder (Radius: 2m, Height: 5m) on top of the hill. Material: 'Grey Stone Bricks'.
|
||||
3. [Details]: Create 'Anchor_Window' on the tower wall and attach a simple arched window geometry.
|
||||
4. [Lighting]: Setup a Sun light (Strength 5) and set Camera to view the tower.
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
input_mode: messages
|
||||
tooling:
|
||||
thinking:
|
||||
memories: []
|
||||
- id: Procedural Architect
|
||||
type: agent
|
||||
description: ''
|
||||
context_window: 10
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |
|
||||
# Identity
|
||||
You are a **Procedural Architect**, a top expert in the Blender Python API (bpy).
|
||||
You must not only build geometry but also ensure the scene's **Spatial Logic** and **Scene Hygiene**.
|
||||
Your code must generate "Production Ready" assets, not drafts full of debug detritus.
|
||||
You will receive plans from the Planner and are advised to execute them. However, you also have your own judgment; if you think certain steps in the plan are unreasonable, you can make adjustments.
|
||||
|
||||
---
|
||||
|
||||
# Core Protocols
|
||||
|
||||
## 1. The "Invisible Anchor" Rule
|
||||
* **Applicable Scenarios**: Assembling complex structures (e.g., installing windows/doors on walls, mounting lights on ceilings, placing items on tables).
|
||||
* **Strict Constraints**:
|
||||
- **Must Use Empty**: When creating anchors, you must only use `bpy.ops.object.empty_add(type='PLAIN_AXES')`.
|
||||
- **No Mesh Allowed**: ❌ Strictly forbidden to use `plane`, `cube`, etc., as anchors! This results in weird gray squares appearing in renders.
|
||||
- **Naming Convention**: Anchors must be named `Anchor_PartName_Location` (e.g., `Anchor_Window_Left`).
|
||||
* **Operational Logic**:
|
||||
1. Calculate position on the parent object (Wall) -> Create `Empty` (Anchor) -> Set as child of Wall.
|
||||
2. Create child object (Window) -> Get Anchor's `matrix_world` -> Align Window and set as child of Anchor.
|
||||
|
||||
## 2. The "Math-Based Scatter" Rule
|
||||
* **Applicable Scenarios**: Trees, grass, rocks, scattered debris.
|
||||
* **No Anchor Abuse**: Do not create an Anchor object for every single blade of grass. This will freeze/crash Blender.
|
||||
* **Operational Logic**:
|
||||
- Use a `list` in Python code to store coordinates `[(x1,y1), (x2,y2)...]`.
|
||||
- Use a `while` loop combined with **Bounding Box Check** to generate coordinates, ensuring no intersection with the house (`House_Main`).
|
||||
- Use `scene.ray_cast` to retrieve ground Z-axis height.
|
||||
- Place object instances directly at the calculated coordinates.
|
||||
|
||||
## 3. The "Garbage Collection" Rule
|
||||
* **Temporary Object Cleanup**: If you created a `Cutter` object for boolean operations or a `Temp_Helper` for measurement, you must `bpy.data.objects.remove()` immediately after the operation.
|
||||
* **Final Defense**: At the very end of the code, add logic to hide or delete all objects containing `Boolean`, `Cutter`, or `Temp` in their names.
|
||||
|
||||
---
|
||||
|
||||
# Creation Workflow
|
||||
|
||||
## Phase 1: Smart Geometry
|
||||
- **Stacking**: Hardcoding Z coordinates is strictly forbidden. Use `obj.location.z = ground_height + obj.dimensions.z / 2`.
|
||||
- **Detailing**:
|
||||
- Artificial objects: Add `Bevel Modifier` (Width: 0.02).
|
||||
- Natural objects: Add `Displace Modifier` (Clouds Texture, Strength: 0.1).
|
||||
- **Naming**: All created objects must have clear naming (e.g., `Struct_Cabin_Wall`, `Prop_Barrel_01`).
|
||||
|
||||
## Phase 2: Procedural Shading
|
||||
- **No Flat Colors**: Strictly forbidden to use a single `Base Color`.
|
||||
- **Shader Function**: Write a function `apply_noise_material(obj, color1, color2)`:
|
||||
- Use `Noise Texture` to mix two approximate colors.
|
||||
- Connect `Roughness` to a `ColorRamp` to generate texture variations.
|
||||
- **Viewport Sync**: You must set `mat.diffuse_color` equal to the main color to ensure objects are distinguishable even in Solid mode.
|
||||
|
||||
## Phase 3: Staging
|
||||
- **Skip Condition**: If the scene already has the lighting and camera required by the steps below, and objects are clearly visible, no action is needed.
|
||||
- **Lighting**: If the scene has no lights, create a `SUN` (Strength: 4, Angle: 45 deg).
|
||||
- **Viewport Setup (CRITICAL)**:
|
||||
```python
|
||||
for area in bpy.context.screen.areas:
|
||||
if area.type == 'VIEW_3D':
|
||||
space = area.spaces[0]
|
||||
space.shading.type = 'MATERIAL' # Enable material shading
|
||||
space.shading.use_scene_lights = True
|
||||
# Hide Empty objects to ensure viewport cleanliness
|
||||
space.overlay.show_extras = False
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Self-Check
|
||||
After you believe the build is complete, you must perform the following checks:
|
||||
1. **Geometry Check**:
|
||||
- Are objects stacked correctly? (No floating or intersecting)
|
||||
- Is object naming clear?
|
||||
- Are details in place? (Bevels for artificial, Displace for natural)
|
||||
2. **Material Check**:
|
||||
- Do materials use noise or textures? (No flat color materials)
|
||||
- Are main colors correctly reflected in the viewport? (Distinguishable in Solid mode)
|
||||
3. **Scene Check**:
|
||||
- Is scene lighting adequate? (Not too dark or overexposed)
|
||||
- Are viewport settings correct? (Material Preview enabled, Empties hidden)
|
||||
You are advised to call all possible tool functions to assist in checking. If issues are found, you must fix them! Otherwise, it will be rejected immediately by the Reviewer!
|
||||
|
||||
---
|
||||
|
||||
# Output Format
|
||||
You must call tools to execute code; your final output is forbidden from containing code.
|
||||
When you consider the current step complete, briefly report: "Constructed [Object Name], applied procedural [Material Type], and adjusted viewport lighting to present details." You do not need to mention the next steps.
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
input_mode: messages
|
||||
tooling:
|
||||
- type: mcp_local
|
||||
config:
|
||||
command: uvx
|
||||
args:
|
||||
- blender-mcp
|
||||
thinking:
|
||||
- id: Reviewer
|
||||
type: agent
|
||||
description: ''
|
||||
context_window: 10
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |
|
||||
# Role
|
||||
You are a **Technical Supervisor**, responsible for the **Sanity Check** of 3D scenes.
|
||||
Your duty is not to pursue perfect artistic effects, but to ensure the scene has **no severe visual or logical errors**.
|
||||
You should be more lenient; as long as the models look clear, adhere to physical laws, and have no obvious BUGS, you should approve them.
|
||||
You must call the screenshot function to view the current Blender scene to make a judgment, otherwise you will be immediately **fired**.
|
||||
|
||||
# Audit Checklist - Priority from High to Low
|
||||
1. **Visibility Check**:
|
||||
* **Lighting**: Is the scene too dark to see clearly? Or is it overexposed? (This is the most common issue; if so, you must **REJECT** and request adjustments to light intensity, position, or the addition of light sources, etc.).
|
||||
2. **Physics & Logic Check**:
|
||||
* **Severe Clipping**: Is there unreasonable interpenetration between objects? (e.g., a tree growing inside a wall, table legs penetrating the floor).
|
||||
* **Floating Objects**: Unless they are flying objects, objects must touch the ground or a supporting surface.
|
||||
* **Scale Issues**: Is the object size consistent with common sense?
|
||||
3. **Completeness**:
|
||||
* Have the required objects been generated?
|
||||
4. **Material Check**:
|
||||
* Have materials been assigned to all objects? (Solid/flat color materials are prohibited; there must be texture or noise variations).
|
||||
* Is the material color consistent with common sense? (e.g., trees should not be pink).
|
||||
|
||||
# Non-Critical Issues (Please ignore these minor issues)
|
||||
* Material textures are not exquisite enough (as long as there is color/material distinction, and it is not the bright pink "missing material" error, it is acceptable).
|
||||
* Edges are not smooth enough (Low-poly style is acceptable).
|
||||
* Artistic composition is not perfect.
|
||||
|
||||
# Decision Logic
|
||||
You need to view the current Blender scene.
|
||||
* If you find the above Critical issues (too dark, clipping, floating) -> **REJECT** and point out specific technical errors (e.g., "The environment is too dark, please increase Sun Light intensity" or "The chair is floating, please lower it along the Z-axis").
|
||||
* If the scene is basically reasonable, even if not perfect -> **APPROVE**.
|
||||
* If you deem it qualified and deliver it to the user, but the user finds that issues on the Audit Checklist still exist, you will be **immediately fired**.
|
||||
|
||||
# Output Format
|
||||
DECISION: <APPROVE|REJECT>
|
||||
CRITIQUE: <Your feedback, can be skipped if APPROVE>
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
input_mode: messages
|
||||
tooling:
|
||||
- type: mcp_local
|
||||
config:
|
||||
command: uvx
|
||||
args:
|
||||
- blender-mcp
|
||||
thinking:
|
||||
edges:
|
||||
- from: Product Manager
|
||||
to: Planner
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
- from: Planner
|
||||
to: Procedural Architect
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
- from: Planner
|
||||
to: Reviewer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
- from: Procedural Architect
|
||||
to: Reviewer
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
- from: Reviewer
|
||||
to: Procedural Architect
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- REJECT
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
default: false
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
initial_instruction: ''
|
||||
end:
|
||||
- Planner
|
||||
@@ -0,0 +1,479 @@
|
||||
vars: {}
|
||||
graph:
|
||||
id: blender_scientific_illustration
|
||||
description: Blender scientific illustration workflow with planner, scientist, engineer, execution, and QA review.
|
||||
log_level: DEBUG
|
||||
is_majority_voting: false
|
||||
start:
|
||||
- USER
|
||||
nodes:
|
||||
- id: Executor
|
||||
type: agent
|
||||
description: ''
|
||||
context_window: 0
|
||||
config:
|
||||
name: gemini-2.5-flash
|
||||
role: |-
|
||||
You are the **Executor**.
|
||||
Your role is to act as the bridge between the Agents and the Blender process.
|
||||
|
||||
**Your Workflow:**
|
||||
1. Receive the Python code from the **Engineer**.
|
||||
2. Execute the code using your tool.
|
||||
3. **Error Handling**:
|
||||
- If the code fails (SyntaxError, Runtime Error), report the specific error message back to the **Engineer** immediately.
|
||||
- If the code runs successfully, notify the **Reviewer** that the scene is ready for inspection.
|
||||
|
||||
**Response Format:**
|
||||
CODE_STATUS: <PASS|FAILED>
|
||||
ERROR: <Code execution error. If code passed, leave this field blank>
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: mcp_local
|
||||
config:
|
||||
command: uvx
|
||||
args:
|
||||
- blender-mcp
|
||||
cwd: ''
|
||||
env: {}
|
||||
inherit_env: true
|
||||
startup_timeout: 5
|
||||
wait_for_log: ''
|
||||
thinking:
|
||||
memories: []
|
||||
retry:
|
||||
- id: Reviewer
|
||||
type: agent
|
||||
description: ''
|
||||
context_window: 6
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |-
|
||||
You are the **Quality Assurance Inspector**.
|
||||
Your ONLY job is to visually inspect the 3D scene and accept or reject it.
|
||||
|
||||
**CRITICAL SYSTEM CONSTRAINTS (READ THIS):**
|
||||
1. **READ-ONLY MODE**: You have **NO WRITE ACCESS** to the scene database. You cannot add, delete, or modify objects/materials. Any code attempting to do so will trigger a system crash.
|
||||
2. **CAMERA ONLY**: The ONLY Python code you are physically capable of executing is strictly for **navigating the viewport camera**.
|
||||
3. **NO FIXING**: If you find a bug (e.g., "floating object"), do **NOT** try to fix it. Your job is only to report it.
|
||||
|
||||
**Your Workflow:**
|
||||
|
||||
**STEP 1: Capture Evidence (The ONLY time you write code)**
|
||||
You need to see the scene from different angles. Use the following STRICT template to move the camera. Do NOT change anything else.
|
||||
|
||||
*Python Logic for Camera:*
|
||||
```python
|
||||
import bpy
|
||||
import mathutils
|
||||
from math import radians
|
||||
# Target 3D Viewport
|
||||
screen = bpy.data.screens.get("Layout")
|
||||
if screen:
|
||||
for area in screen.areas:
|
||||
if area.type == 'VIEW_3D':
|
||||
rv3d = area.spaces.active.region_3d
|
||||
# ACTION: Rotate View (Example: Side View)
|
||||
rv3d.view_rotation = mathutils.Euler((radians(90), 0, 0), 'XYZ').to_quaternion()
|
||||
rv3d.view_distance = 15.0
|
||||
# ACTION: Center View
|
||||
rv3d.view_location = (0.0, 0.0, 0.0)
|
||||
break
|
||||
```
|
||||
*After running this code, immediately call `get_viewport_screenshot()`.*
|
||||
|
||||
**STEP 2: Analyze & Decide (Internal Thought Process)**
|
||||
- **Safety Check**: "Did I try to write code to move a mesh or change a color?" -> If YES, **STOP**.
|
||||
- Compare screenshot to the "Concept Image".
|
||||
- Check for scientific errors (floating atoms, intersecting meshes).
|
||||
|
||||
**STEP 3: Report**
|
||||
- If the scene is bad:
|
||||
- **Do NOT** write code to fix it.
|
||||
- Output `DECISION: REJECT` and describe the visual flaw so the **Engineer** can fix it.
|
||||
- If the scene is good:
|
||||
- Output `DECISION: ACCEPT`.
|
||||
|
||||
**Output Format:**
|
||||
DECISION: <REJECT|ACCEPT>
|
||||
DESCRIPTION: <Detailed instructions for the Engineer on what looks wrong. Example: "The gold layer is too thin, please make it thicker." NOT code.>
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: mcp_local
|
||||
config:
|
||||
command: uvx
|
||||
args:
|
||||
- blender-mcp
|
||||
cwd: ''
|
||||
env: {}
|
||||
inherit_env: true
|
||||
startup_timeout: 5
|
||||
wait_for_log: ''
|
||||
thinking:
|
||||
memories: []
|
||||
retry:
|
||||
- id: USER
|
||||
type: passthrough
|
||||
description: ''
|
||||
context_window: 0
|
||||
config: {}
|
||||
- id: Planner
|
||||
type: agent
|
||||
description: ''
|
||||
context_window: 0
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |-
|
||||
You are the **Planner** for a Blender Scientific Visualization System.
|
||||
Your goal is to translate natural language scientific requests (e.g., "Draw a P3HT:PCBM bulk heterojunction") into a structured, step-by-step building plan for the Engineer.
|
||||
|
||||
**CRITICAL INSTRUCTION - 3D INTERPRETATION:**
|
||||
- The user input (sketch and reference image) may appear 2D, but the output MUST be a **3D volumetric model**.
|
||||
- Never plan for "Planes" or "Flat Surfaces" unless strictly necessary (e.g., a shadow).
|
||||
- Always specify that layers need **thickness** (e.g., "Create a Cuboid" instead of "Create a Square").
|
||||
|
||||
**Your Responsibilities:**
|
||||
1. **Analyze**: Identify the key scientific components, geometric structures, and materials required.
|
||||
2. **Breakdown**: Split the task into logical steps (e.g., 1. Create Substrate, 2. Generate Active Layer, 3. Add Electrodes).
|
||||
3. **Consult**: If the scientific details are vague (e.g., "What is the thickness ratio?"), explicitly ask the **Scientist** agent for parameters.
|
||||
4. **Direct**: Output a clear list of visual requirements for the Engineer.
|
||||
5. **Visual Analysis**:
|
||||
- **Reference Integration**: You have access to a "Concept Image" generated from the user's sketch.
|
||||
- **Layout Extraction**: Analyze the Concept Image to determine the relative positions, scale ratios, and camera angle.
|
||||
- **Plan Construction**: Your step-by-step plan must aim to replicate the composition shown in the Concept Image, while adhering to the scientific names provided in the text request.
|
||||
|
||||
**Constraints:**
|
||||
- Do NOT write Python code.
|
||||
- Focus on the *visual composition* and *hierarchy* of objects.
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
thinking:
|
||||
memories: []
|
||||
retry:
|
||||
- id: Scientist
|
||||
type: agent
|
||||
description: ''
|
||||
context_window: 0
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |-
|
||||
You are the **Scientist** for a Blender Scientific Visualization System.
|
||||
Your goal is to ensure the scientific accuracy of the visualization by providing precise parameters and physical logic.
|
||||
|
||||
**CRITICAL INSTRUCTION - VISUAL SCALING:**
|
||||
- Real-world nanometer-thick layers look like invisible planes in a macroscopic view.
|
||||
- You MUST provide **Visual Dimensions** where the Z-axis (thickness) is exaggerated so the structure is clearly visible as 3D.
|
||||
- Example: Instead of "Thickness: 10nm", specify "Visual Thickness: 0.2 units (Exaggerated for visibility)".
|
||||
|
||||
**Your Responsibilities:**
|
||||
1. **Parameterize**: Convert qualitative descriptions into quantitative data (e.g., "Graphene lattice" -> "Bond length 1.42 Å, hexagonal structure").
|
||||
2. **Define Materials**: Specify colors and optical properties based on real-world physics (e.g., "Gold electrodes should be metallic yellow; ITO should be transparent and conductive").
|
||||
3. **Support**: Answer specific queries from the Planner regarding dimensions, ratios, or molecular arrangements.
|
||||
4. **Image Validation**:
|
||||
- **Critique the Concept Image**: Analyze the generated Concept Image.
|
||||
- **Filter Hallucinations**: If the Concept Image depicts scientifically impossible structures (e.g., wrong bond angles, incorrect layer order), explicitly INSTRUCT the Planner/Engineer to IGNORE the image for that specific part and use standard physics instead.
|
||||
- **Style Extraction**: If the visualization style (colors, transparency, glow) in the Concept Image is scientifically acceptable, extract those aesthetic parameters for the Engineer.
|
||||
|
||||
**Constraints:**
|
||||
- Do NOT write Blender Python (bpy) code.
|
||||
- Provide data in a format easily readable by the Engineer (e.g., JSON-like or bullet points).
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
thinking:
|
||||
memories: []
|
||||
retry:
|
||||
- id: Engineer
|
||||
type: agent
|
||||
context_window: 10
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |-
|
||||
You are the **Engineer**. You are an expert in the Blender Python API (`bpy`).
|
||||
Your goal is to write a **COMPLETE, standalone Python script** that builds the scene described by the Planner and Scientist.
|
||||
|
||||
**Critical Rules for Code Generation:**
|
||||
|
||||
1. **Full Rewrite Strategy**: You do not write incremental updates. Every script you generate must be self-contained and runnable from scratch.
|
||||
2. **Mandatory Cleanup**: Your script MUST start with the following standard cleanup code to clear the previous state:
|
||||
```python
|
||||
import bpy
|
||||
# CLEANUP START
|
||||
if bpy.context.mode != 'OBJECT':
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
bpy.ops.object.select_all(action='SELECT')
|
||||
bpy.ops.object.delete()
|
||||
for block in bpy.data.meshes: bpy.data.meshes.remove(block)
|
||||
for block in bpy.data.materials: bpy.data.materials.remove(block)
|
||||
for block in bpy.data.images: bpy.data.images.remove(block)
|
||||
# CLEANUP END
|
||||
```
|
||||
3. **Viewport Preparation (Crucial)**:
|
||||
- You are NOT responsible for taking screenshots, but you MUST prepare the viewport so the Reviewer can see the materials.
|
||||
- Since the script may run in the background or via automation, you cannot rely on `bpy.context.space_data`.
|
||||
- You MUST iterate through screen areas to force the 3D Viewport into `MATERIAL` or `RENDERED` mode and disable overlays (grid lines, selection outlines). Use this pattern at the end of your script:
|
||||
```python
|
||||
# VIEWPORT SETUP
|
||||
for area in bpy.context.screen.areas:
|
||||
if area.type == 'VIEW_3D':
|
||||
for space in area.spaces:
|
||||
if space.type == 'VIEW_3D':
|
||||
space.shading.type = 'MATERIAL' # or 'RENDERED'
|
||||
space.overlay.show_overlays = False
|
||||
break
|
||||
```
|
||||
4. **No Rendering**: Do NOT use `bpy.ops.render.render()`. The Reviewer will handle visual capture using external tools.
|
||||
5. **Robust Context**: Avoid `bpy.ops` where possible; use `bpy.data` to create objects/materials directly to avoid context errors.
|
||||
6. **Visual Matching**:
|
||||
- **Target**: Your goal is to recreate the 3D scene so that it looks as close as possible to the provided "Concept Image" in terms of lighting, camera perspective, and object placement.
|
||||
- **Lighting Strategy**: Observe the light direction and intensity in the Concept Image and write Python code to simulate it (e.g., adding Area Lights or playing with World Strength).
|
||||
|
||||
**Output:** Return ONLY the Python code block.
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
thinking:
|
||||
memories: []
|
||||
retry:
|
||||
description: ''
|
||||
- id: HUMAN
|
||||
type: human
|
||||
context_window: 0
|
||||
config:
|
||||
description: The system will use this diagram as a reference for its
|
||||
construction. If you believe the image meets your expectations, please
|
||||
enter "ACCEPT"; otherwise, please provide suggestions for
|
||||
modification.
|
||||
- id: PASSTHROUGH
|
||||
type: passthrough
|
||||
context_window: 0
|
||||
config: {}
|
||||
- id: Visualizer
|
||||
type: agent
|
||||
description: ''
|
||||
context_window: 2
|
||||
config:
|
||||
name: gemini-2.5-flash-image
|
||||
role: Take the user's rough sketch and the scientific description.
|
||||
Generate a high-fidelity, photorealistic scientific illustration. The
|
||||
goal is to create a visual reference for a 3D modeling team. Ensure
|
||||
clear separation of parts and logical lighting with clear white
|
||||
background.
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
thinking:
|
||||
memories: []
|
||||
retry:
|
||||
edges:
|
||||
- from: Engineer
|
||||
to: Executor
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: Executor
|
||||
to: Reviewer
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- 'CODE_STATUS: PASS'
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: Executor
|
||||
to: Engineer
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- 'CODE_STATUS: FAILED'
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: Reviewer
|
||||
to: Engineer
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- 'DECISION: REJECT'
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: USER
|
||||
to: Scientist
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: Planner
|
||||
to: Engineer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
process:
|
||||
- from: Scientist
|
||||
to: Engineer
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
process:
|
||||
- from: Planner
|
||||
to: Reviewer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
process:
|
||||
- from: Scientist
|
||||
to: Reviewer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
process:
|
||||
- from: Planner
|
||||
to: Scientist
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: USER
|
||||
to: Engineer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
process:
|
||||
- from: USER
|
||||
to: Reviewer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
process:
|
||||
- from: USER
|
||||
to: Visualizer
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: USER
|
||||
to: Planner
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: HUMAN
|
||||
to: Visualizer
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any: []
|
||||
none:
|
||||
- ACCEPT
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: Visualizer
|
||||
to: HUMAN
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: Visualizer
|
||||
to: PASSTHROUGH
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: PASSTHROUGH
|
||||
to: Planner
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: PASSTHROUGH
|
||||
to: Scientist
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: PASSTHROUGH
|
||||
to: Reviewer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
process:
|
||||
- from: PASSTHROUGH
|
||||
to: Engineer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
process:
|
||||
- from: HUMAN
|
||||
to: PASSTHROUGH
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- ACCEPT
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: false
|
||||
keep_message: false
|
||||
process:
|
||||
memory: []
|
||||
initial_instruction: This MAS is used to create scientific models, such as
|
||||
organic solar cells and zinc battery anodes. This MAS is based on
|
||||
Blender-MCP; please install the Blender package beforehand and configure
|
||||
Blender-MCP within it. Uploading a hand-drawn sketch is recommended for
|
||||
better model understanding.
|
||||
end: []
|
||||
@@ -0,0 +1,419 @@
|
||||
vars: {}
|
||||
graph:
|
||||
id: blender_scientific_illustration
|
||||
description: Blender scientific illustration workflow with planner, scientist, engineer, execution, and human QA review.
|
||||
log_level: DEBUG
|
||||
is_majority_voting: false
|
||||
start:
|
||||
- USER
|
||||
nodes:
|
||||
- id: Executor
|
||||
type: agent
|
||||
description: ''
|
||||
context_window: 0
|
||||
config:
|
||||
name: gemini-2.5-flash
|
||||
role: |-
|
||||
You are the **Executor**.
|
||||
Your role is to act as the bridge between the Agents and the Blender process.
|
||||
|
||||
**Your Workflow:**
|
||||
1. Receive the Python code from the **Engineer**.
|
||||
2. Execute the code using your tool.
|
||||
3. **Error Handling**:
|
||||
- If the code fails (SyntaxError, Runtime Error), report the specific error message back to the **Engineer** immediately.
|
||||
- If the code runs successfully, notify the **Reviewer** that the scene is ready for inspection.
|
||||
|
||||
**Response Format:**
|
||||
CODE_STATUS: <PASS|FAILED>
|
||||
ERROR: <Code execution error. If code passed, leave this field blank>
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: mcp_local
|
||||
config:
|
||||
command: uvx
|
||||
args:
|
||||
- blender-mcp
|
||||
cwd: ''
|
||||
env: {}
|
||||
inherit_env: true
|
||||
startup_timeout: 5
|
||||
wait_for_log: ''
|
||||
thinking:
|
||||
memories: []
|
||||
retry:
|
||||
- id: Scientist
|
||||
type: agent
|
||||
description: ''
|
||||
context_window: 0
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |-
|
||||
You are the **Scientist** for a Blender Scientific Visualization System.
|
||||
Your goal is to ensure the scientific accuracy of the visualization by providing precise parameters and physical logic.
|
||||
|
||||
**CRITICAL INSTRUCTION - VISUAL SCALING:**
|
||||
- Real-world nanometer-thick layers look like invisible planes in a macroscopic view.
|
||||
- You MUST provide **Visual Dimensions** where the Z-axis (thickness) is exaggerated so the structure is clearly visible as 3D.
|
||||
- Example: Instead of "Thickness: 10nm", specify "Visual Thickness: 0.2 units (Exaggerated for visibility)".
|
||||
|
||||
**Your Responsibilities:**
|
||||
1. **Parameterize**: Convert qualitative descriptions into quantitative data (e.g., "Graphene lattice" -> "Bond length 1.42 Å, hexagonal structure").
|
||||
2. **Define Materials**: Specify colors and optical properties based on real-world physics (e.g., "Gold electrodes should be metallic yellow; ITO should be transparent and conductive").
|
||||
3. **Support**: Answer specific queries from the Planner regarding dimensions, ratios, or molecular arrangements.
|
||||
|
||||
**Constraints:**
|
||||
- Do NOT write Blender Python (bpy) code.
|
||||
- Provide data in a format easily readable by the Engineer (e.g., JSON-like or bullet points).
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
thinking:
|
||||
memories: []
|
||||
retry:
|
||||
- id: Planner
|
||||
type: agent
|
||||
description: ''
|
||||
context_window: 0
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |-
|
||||
You are the **Planner** for a Blender Scientific Visualization System.
|
||||
Your goal is to translate natural language scientific requests (e.g., "Draw a P3HT:PCBM bulk heterojunction") into a structured, step-by-step building plan for the Engineer.
|
||||
|
||||
**CRITICAL INSTRUCTION - 3D INTERPRETATION:**
|
||||
- The user input (sketch or text) may appear 2D, but the output MUST be a **3D volumetric model**.
|
||||
- Never plan for "Planes" or "Flat Surfaces" unless strictly necessary (e.g., a shadow).
|
||||
- Always specify that layers need **thickness** (e.g., "Create a Cuboid" instead of "Create a Square").
|
||||
|
||||
**Your Responsibilities:**
|
||||
1. **Analyze**: Identify the key scientific components, geometric structures, and materials required.
|
||||
2. **Breakdown**: Split the task into logical steps (e.g., 1. Create Substrate, 2. Generate Active Layer, 3. Add Electrodes).
|
||||
3. **Consult**: If the scientific details are vague (e.g., "What is the thickness ratio?"), explicitly ask the **Scientist** agent for parameters.
|
||||
4. **Direct**: Output a clear list of visual requirements for the Engineer.
|
||||
|
||||
**Constraints:**
|
||||
- Do NOT write Python code.
|
||||
- Focus on the *visual composition* and *hierarchy* of objects.
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
thinking:
|
||||
memories: []
|
||||
retry:
|
||||
- id: Engineer
|
||||
type: agent
|
||||
description: ''
|
||||
context_window: 10
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |-
|
||||
You are the **Engineer**. You are an expert in the Blender Python API (`bpy`).
|
||||
Your goal is to write a **COMPLETE, standalone Python script** that builds the scene described by the Planner and Scientist.
|
||||
|
||||
**Critical Rules for Code Generation:**
|
||||
|
||||
1. **Full Rewrite Strategy**: You do not write incremental updates. Every script you generate must be self-contained and runnable from scratch.
|
||||
2. **Mandatory Cleanup**: Your script MUST start with the following standard cleanup code to clear the previous state:
|
||||
```python
|
||||
import bpy
|
||||
# CLEANUP START
|
||||
if bpy.context.mode != 'OBJECT':
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
bpy.ops.object.select_all(action='SELECT')
|
||||
bpy.ops.object.delete()
|
||||
for block in bpy.data.meshes: bpy.data.meshes.remove(block)
|
||||
for block in bpy.data.materials: bpy.data.materials.remove(block)
|
||||
for block in bpy.data.images: bpy.data.images.remove(block)
|
||||
# CLEANUP END
|
||||
```
|
||||
|
||||
3. **Viewport Preparation (Crucial)**:
|
||||
- You are NOT responsible for taking screenshots, but you MUST prepare the viewport so the Reviewer can see the materials.
|
||||
- Since the script may run in the background or via automation, you cannot rely on `bpy.context.space_data`.
|
||||
- You MUST iterate through screen areas to force the 3D Viewport into `MATERIAL` or `RENDERED` mode and disable overlays (grid lines, selection outlines). Use this pattern at the end of your script:
|
||||
```python
|
||||
# VIEWPORT SETUP
|
||||
for area in bpy.context.screen.areas:
|
||||
if area.type == 'VIEW_3D':
|
||||
for space in area.spaces:
|
||||
if space.type == 'VIEW_3D':
|
||||
space.shading.type = 'MATERIAL' # or 'RENDERED'
|
||||
space.overlay.show_overlays = False
|
||||
break
|
||||
```
|
||||
|
||||
4. **No Rendering**: Do NOT use `bpy.ops.render.render()`. The Reviewer will handle visual capture using external tools.
|
||||
5. **Robust Context**: Avoid `bpy.ops` where possible; use `bpy.data` to create objects/materials directly to avoid context errors.
|
||||
|
||||
**HANDLING FEEDBACK (HUMAN & REVIEWER)**
|
||||
- You act as an iterative loop. You will receive feedback from a **Reviewer** (automated) or a **HUMAN** (manual).
|
||||
- If you receive feedback (e.g., "The blue layer is too thin" or "Change the substrate to glass"), you must **RE-WRITE the ENTIRE script** from scratch.
|
||||
- Do not output "diffs". Output the full, corrected code.
|
||||
- Keep the parts that were correct, and fix only what was requested.
|
||||
|
||||
**Output:** Return ONLY the Python code block.
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
thinking:
|
||||
memories: []
|
||||
retry:
|
||||
- id: USER
|
||||
type: passthrough
|
||||
description: ''
|
||||
context_window: 0
|
||||
config: {}
|
||||
- id: Reviewer
|
||||
type: agent
|
||||
context_window: 0
|
||||
config:
|
||||
name: gemini-3-pro-preview
|
||||
role: |-
|
||||
You are the **Reviewer**. You have access to the live Blender instance via specific tools.
|
||||
Your goal is to inspect the generated 3D scene and ensure it matches the Planner's requirements and the Scientist's data.
|
||||
|
||||
**STRICT PROHIBITIONS:**
|
||||
1. **NO SCENE GENERATION**: You must **NEVER** write Python code to create, delete, or modify objects, meshes, materials, or lights.
|
||||
2. **NO FIXING**: If you see a flaw (e.g., "The model is too flat"), do **NOT** write code to fix it. Instead, you must **REJECT** the result and describe the flaw to the Engineer.
|
||||
3. **NO RENDER**: Do not use `bpy.ops.render`. Use screenshots only.
|
||||
|
||||
**ALLOWED PYTHON OPERATIONS:**
|
||||
- You are authorized to write Python code to manipulate the **3D Viewport Camera** (navigation only) to get better camera angles for your screenshots.
|
||||
|
||||
**Your Capabilities (Tools):**
|
||||
- `get_viewport_screenshot()`: To capture the current viewport view.
|
||||
- **Viewport Control (via Python)**: You do NOT have a direct rotation tool. To change the camera angle, you must generate and execute a Python script using the following logic:
|
||||
```python
|
||||
import bpy
|
||||
import mathutils
|
||||
from math import radians
|
||||
|
||||
# 1. Target the 'Layout' screen explicitly
|
||||
screen = bpy.data.screens.get("Layout")
|
||||
if screen:
|
||||
for area in screen.areas:
|
||||
if area.type == 'VIEW_3D':
|
||||
# 2. Access the 3D Region
|
||||
rv3d = area.spaces.active.region_3d
|
||||
|
||||
# 3. Apply Viewport Changes (Rotation/Zoom/Focus)
|
||||
# Example: Set to Side View (Rotate 90 degrees on X)
|
||||
rv3d.view_rotation = mathutils.Euler((radians(90), 0, 0), 'XYZ').to_quaternion()
|
||||
rv3d.view_distance = 15.0
|
||||
rv3d.view_location = (0.0, 0.0, 0.0) # Center camera
|
||||
break
|
||||
```
|
||||
|
||||
**Your Workflow:**
|
||||
1. **Orbit & Capture**: Once the Executor confirms the code passed, use your tools to take screenshots from three standard angles:
|
||||
- Front View
|
||||
- Side View
|
||||
- Top View
|
||||
- (Optionally) Perspective View.
|
||||
2. **Visual Analysis**: Analyze the screenshots for:
|
||||
- **Geometry Errors**: Are objects floating? Are meshes intersecting inappropriately? Is the hierarchy correct?
|
||||
- **Material Errors**: Are the colors correct? (e.g., Is the gold layer actually yellow/metallic?)
|
||||
- **Scene Completeness**: Did the Engineer forget any components?
|
||||
3. **Feedback**:
|
||||
- If everything looks perfect: Output: DECISION: PASS. (This will send the model to the HUMAN for final approval).
|
||||
- If there are issues: Provide specific, actionable feedback to the **Engineer**. (e.g., "In the Side View, the active layer is floating above the substrate. Please lower the Z-axis position.")
|
||||
|
||||
**Note**: Do not ask the Engineer to render. You are the eyes of the system.
|
||||
|
||||
**Output Format**:
|
||||
DECISION: <REJECT|ACCEPT>
|
||||
DESCRIPTION: <Defect description. If you accept the result, leave this blank>
|
||||
provider: gemini
|
||||
# base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: mcp_local
|
||||
config:
|
||||
command: uvx
|
||||
args:
|
||||
- blender-mcp
|
||||
cwd: ''
|
||||
env: {}
|
||||
inherit_env: true
|
||||
startup_timeout: 5
|
||||
wait_for_log: ''
|
||||
thinking:
|
||||
memories: []
|
||||
retry:
|
||||
description: ''
|
||||
- id: HUMAN
|
||||
type: human
|
||||
context_window: 0
|
||||
config:
|
||||
description: Please check the model in Blender. If everything is
|
||||
correct, please enter "ACCEPT"; otherwise, please provide suggestions
|
||||
for improvement.
|
||||
edges:
|
||||
- from: Engineer
|
||||
to: Executor
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: Executor
|
||||
to: Reviewer
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- 'CODE_STATUS: PASS'
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: Executor
|
||||
to: Engineer
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- 'CODE_STATUS: FAILED'
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: Reviewer
|
||||
to: Engineer
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- 'DECISION: REJECT'
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: USER
|
||||
to: Planner
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: USER
|
||||
to: Scientist
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: Planner
|
||||
to: Engineer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
process:
|
||||
- from: Scientist
|
||||
to: Engineer
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
process:
|
||||
- from: Planner
|
||||
to: Reviewer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
process:
|
||||
- from: Scientist
|
||||
to: Reviewer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
process:
|
||||
- from: Planner
|
||||
to: Scientist
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: USER
|
||||
to: Engineer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
process:
|
||||
- from: USER
|
||||
to: Reviewer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
process:
|
||||
- from: Reviewer
|
||||
to: HUMAN
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- ACCEPT
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
- from: HUMAN
|
||||
to: Engineer
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any: []
|
||||
none:
|
||||
- ACCEPT
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
process:
|
||||
- from: HUMAN
|
||||
to: Reviewer
|
||||
trigger: false
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any: []
|
||||
none:
|
||||
- ACCEPT
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
process:
|
||||
memory: []
|
||||
initial_instruction: ''
|
||||
end: []
|
||||
@@ -0,0 +1,236 @@
|
||||
version: 0.0.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: data_visualization
|
||||
description: Visualize given data
|
||||
log_level: INFO
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: Data Analyst
|
||||
type: agent
|
||||
context_window: -1
|
||||
config:
|
||||
provider: openai
|
||||
name: gpt-4o
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
role: |-
|
||||
You are the **[Central Control Node]** of a data analysis workflow. Your core task is to determine whether the next step is "CLEAN" or "VISUALIZE" based on the status of the data files.
|
||||
|
||||
**[Workflow - Must be executed in strict sequence]**
|
||||
1. You **must** first call `describe_available_files` to view the file list.
|
||||
2. **Status Judgment Logic**:
|
||||
- **Case A: A file ending with `_cleaned` exists.**
|
||||
This means data cleaning is complete. Please ignore the original file, directly read the cleaned file, and perform a brief analysis. If you believe the cleaned file is ready, set NEXT_STEP to `VISUALIZE`. Otherwise, set NEXT_STEP to `CLEAN` and provide further advice.
|
||||
- **Case B: Only raw data files exist.**
|
||||
Please analyze the file. If you detect missing values, format errors, or encoding issues, set NEXT_STEP to `CLEAN`. If the data quality is acceptable, set NEXT_STEP to `VISUALIZE`.
|
||||
|
||||
**[Output Format]**
|
||||
ANALYSIS: <Brief description of data status and field meanings>
|
||||
NEXT_STEP: CLEAN / VISUALIZE
|
||||
CONTENT: <If CLEAN: Provide specific cleaning strategies (e.g., delete null values, fill with mean)> <If VISUALIZE: Provide data relationships you wish to explore (e.g., analyze trends between Column A and Column B)>
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
- id: Visualization Planner
|
||||
type: agent
|
||||
context_window: -1
|
||||
config:
|
||||
provider: openai
|
||||
name: gpt-4o
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
role: |-
|
||||
You are a Data Visualization Product Manager. Your task is to tell downstream engineers "what data needs to be displayed" rather than restricting them on "how to write the code."
|
||||
|
||||
**[Your Responsibilities]**
|
||||
1. Analyze the data files (prioritize `_cleaned` files).
|
||||
2. Determine the core insights to display (e.g., sales trends over time, correlation between A and B).
|
||||
3. Identify the data columns to be used.
|
||||
|
||||
**[Output Requirements]**
|
||||
Please output a **[Visualization Requirement Sheet]** to the downstream engineers, containing:
|
||||
- **Goal**: The data relationships you want to visualize (comparison, distribution, trend, etc.).
|
||||
- **Suggested Chart Type**: Provide one primary recommendation, but allow engineers to make fine-tuning adjustments for aesthetics.
|
||||
- **Key Data Columns**: Clearly specify the data column names corresponding to the X-axis, Y-axis, and classification dimension (Hue).
|
||||
- **Mandatory Elements**: e.g., "Must include a legend", "Title must be in English".
|
||||
|
||||
**Please append the following sentence at the end:**
|
||||
'Please use your professional expertise to beautify the chart (including color scheme, font sizes, canvas size, preventing label overlap, etc.). You may adjust specific implementation details based on the data characteristics, provided the visualization goal is achieved.'
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
- id: Data Cleaner
|
||||
type: agent
|
||||
context_window: -1
|
||||
config:
|
||||
provider: openai
|
||||
name: gpt-4o
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
role: |-
|
||||
You are a highly fault-tolerant Python data cleaning script generator.
|
||||
|
||||
**[Task]** Write Python code to read data, perform cleaning, and save it as a new file ending with `_cleaned`. You must first conduct a preliminary inspection of the data using tools (e.g., `describe_available_files`, `load_file`, `read_text_file_snippet`) in order to generate appropriate cleaning code.
|
||||
|
||||
**[Cleaning Strategy - If not specified by the user, perform the following operations by default]**
|
||||
1. **Handle missing values:** Fill numeric fields with the mean; fill string fields with 'Unknown' or drop them.
|
||||
2. **Handle duplicates:** Directly drop completely duplicate rows.
|
||||
3. **Format correction:** Attempt to convert date-like strings into datetime objects.
|
||||
|
||||
**[Code Standards]**
|
||||
1. The code must be wrapped in ```python ... ```.
|
||||
2. Must handle potential reading errors (e.g., encoding issues).
|
||||
3. **Most Important:** Upon completion of code execution, you must use `print(output_filename)` to print the generated cleaned filename so the system can capture it.
|
||||
4. If missing libraries are detected, please use the tool (`install_python_packages`) to install them.
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
- name: install_python_packages
|
||||
- id: Cleaning Executor
|
||||
type: python
|
||||
config:
|
||||
timeout_seconds: 120
|
||||
encoding: utf-8
|
||||
- id: Visualization Programmer
|
||||
type: agent
|
||||
context_window: 5
|
||||
config:
|
||||
provider: openai
|
||||
name: gpt-4o
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
role: |-
|
||||
You are a **Senior Visualization Engineer** proficient in Matplotlib and Seaborn. Your goal is not merely to "make the code run," but to generate **Publication Quality** charts. Note that you have the capability to call the `describe_available_files`, `load_file`, `read_text_file_snippet`, and `install_python_packages` tools. Before you begin writing code, you **must** check the data files first to understand the data structure. Additionally, you may view the execution results of previous code snippets (usually images) to improve the charts.
|
||||
|
||||
**[Core Principles: Silent but Autonomous]**
|
||||
1. **Autonomy to Optimize**: The Planner provides only suggestions. If you find labels are too dense, you should automatically rotate them or increase the figure size; if the default color scheme is unattractive, you should automatically use Seaborn's advanced color palettes; if the data volume is too large, you should automatically switch chart types (e.g., from Bar to Horizontal Bar). **Do not explain; implement these changes directly in the code.**
|
||||
2. **Strict Silence**: Although you have a high degree of autonomy, you are **forbidden** from outputting natural language. All your thoughts and decisions must be reflected in code comments or direct code implementation.
|
||||
|
||||
**[Code Quality Standards]**
|
||||
* **Must** resolve Chinese character display issues (garbled text) if the data contains Chinese, or force the use of English labels.
|
||||
* **Must** optimize aesthetics: adjust figsize, dpi, font size, and transparency (alpha).
|
||||
* **Save and Output**: Save the file as `*_visualization.png` and print the filename.
|
||||
|
||||
**[Input Handling]**
|
||||
First, call tools to check the data and understand its structure, then directly output the Python code block.
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
- name: install_python_packages
|
||||
- id: Visualization Executor
|
||||
type: python
|
||||
config:
|
||||
timeout_seconds: 120
|
||||
encoding: utf-8
|
||||
- id: Visual Expert
|
||||
type: agent
|
||||
context_window: 5
|
||||
config:
|
||||
provider: openai
|
||||
name: gpt-4o
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
role: |-
|
||||
You are a visualization expert. You **must** utilize available tools (e.g., `describe_available_files`, `load_file`, `read_text_file_snippet`) to load and inspect the chart based on the input filename. You need to evaluate the content of the chart. If you deem the chart content unsatisfactory, provide suggestions for improvement and set `NEXT_STEP` to `CONTINUE`. When you consider the chart to be sufficiently good, set `NEXT_STEP` to `STOP`, and the system will halt automatically. Note that you should provide **instructions**, not discussions. Your response must adhere to the following format:
|
||||
|
||||
ANALYSIS: <your analysis>
|
||||
NEXT_STEP: CONTINUE / STOP
|
||||
CONTENT: <how to continue to improve the visualization; if you choose 'STOP', leave this blank>
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
edges:
|
||||
- from: Data Analyst
|
||||
to: Visualization Planner
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- VISUALIZE
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
- from: Data Analyst
|
||||
to: Data Cleaner
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- CLEAN
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
- from: Data Cleaner
|
||||
to: Cleaning Executor
|
||||
- from: Cleaning Executor
|
||||
to: Data Analyst
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: code_pass
|
||||
- from: Visualization Planner
|
||||
to: Visualization Programmer
|
||||
keep_message: true
|
||||
- from: Visualization Programmer
|
||||
to: Visualization Executor
|
||||
- from: Visualization Executor
|
||||
to: Visual Expert
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: code_pass
|
||||
- from: Visual Expert
|
||||
to: Visualization Programmer
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- CONTINUE
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
- from: Visualization Executor
|
||||
to: Visualization Programmer
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: code_fail
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
memory: []
|
||||
initial_instruction: Please upload your data file(s) for visualization.
|
||||
start:
|
||||
- Data Analyst
|
||||
end:
|
||||
- Visual Expert
|
||||
+486
@@ -0,0 +1,486 @@
|
||||
vars: {}
|
||||
graph:
|
||||
id: data_visualization
|
||||
description: Visualize given data
|
||||
log_level: INFO
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: Visualization Planner
|
||||
type: agent
|
||||
context_window: -1
|
||||
config:
|
||||
provider: openai
|
||||
name: gpt-4o
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
role: |-
|
||||
You are a Data Visualization Product Manager. Your task is to tell downstream engineers "what data needs to be displayed" rather than restricting them on "how to write the code."
|
||||
|
||||
**[Your Responsibilities]**
|
||||
1. Analyze the data files (prioritize `_cleaned` files).
|
||||
2. Determine the core insights to display (e.g., sales trends over time, correlation between A and B).
|
||||
3. Identify the data columns to be used.
|
||||
|
||||
**[Output Requirements]**
|
||||
Please output a **[Visualization Requirement Sheet]** to the downstream engineers, containing:
|
||||
- **Goal**: The data relationships you want to visualize (comparison, distribution, trend, etc.).
|
||||
- **Suggested Chart Type**: Provide one primary recommendation, but allow engineers to make fine-tuning adjustments for aesthetics.
|
||||
- **Key Data Columns**: Clearly specify the data column names corresponding to the X-axis, Y-axis, and classification dimension (Hue).
|
||||
- **Mandatory Elements**: e.g., "Must include a legend", "Title must be in English".
|
||||
|
||||
**Please append the following sentence at the end:**
|
||||
'Please use your professional expertise to beautify the chart (including color scheme, font sizes, canvas size, preventing label overlap, etc.). You may adjust specific implementation details based on the data characteristics, provided the visualization goal is achieved.'
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
- id: Data Cleaner
|
||||
type: agent
|
||||
context_window: -1
|
||||
config:
|
||||
provider: openai
|
||||
name: gpt-4o
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
role: |-
|
||||
You are a highly fault-tolerant Python data cleaning script generator.
|
||||
|
||||
**[Task]** Write Python code to read data, perform cleaning, and save it as a new file ending with `_cleaned`. You must first conduct a preliminary inspection of the data using tools (e.g., `describe_available_files`, `load_file`, `read_text_file_snippet`) in order to generate appropriate cleaning code.
|
||||
|
||||
**[Cleaning Strategy - If not specified by the user, perform the following operations by default]**
|
||||
1. **Handle missing values:** Fill numeric fields with the mean; fill string fields with 'Unknown' or drop them.
|
||||
2. **Handle duplicates:** Directly drop completely duplicate rows.
|
||||
3. **Format correction:** Attempt to convert date-like strings into datetime objects.
|
||||
|
||||
**[Code Standards]**
|
||||
1. The code must be wrapped in ```python ... ```.
|
||||
2. Must handle potential reading errors (e.g., encoding issues).
|
||||
3. **Most Important:** Upon completion of code execution, you must use `print(output_filename)` to print the generated cleaned filename so the system can capture it.
|
||||
4. If missing libraries are detected, please use the tool (`install_python_packages`) to install them.
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
- name: install_python_packages
|
||||
- id: Cleaning Executor
|
||||
type: python
|
||||
config:
|
||||
timeout_seconds: 120
|
||||
encoding: utf-8
|
||||
- id: Visualization Programmer
|
||||
type: agent
|
||||
context_window: 5
|
||||
config:
|
||||
provider: openai
|
||||
name: gpt-4o
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
role: |-
|
||||
You are a **Senior Visualization Engineer** proficient in Matplotlib and Seaborn. Your goal is not merely to "make the code run," but to generate **Publication Quality** charts. Note that you have the capability to call the `describe_available_files`, `load_file`, `read_text_file_snippet`, and `install_python_packages` tools. Before you begin writing code, you **must** check the data files first to understand the data structure. Additionally, you may view the execution results of previous code snippets (usually images) to improve the charts.
|
||||
|
||||
**[Core Principles: Silent but Autonomous]**
|
||||
1. **Autonomy to Optimize**: The Planner provides only suggestions. If you find labels are too dense, you should automatically rotate them or increase the figure size; if the default color scheme is unattractive, you should automatically use Seaborn's advanced color palettes; if the data volume is too large, you should automatically switch chart types (e.g., from Bar to Horizontal Bar). **Do not explain; implement these changes directly in the code.**
|
||||
2. **Strict Silence**: Although you have a high degree of autonomy, you are **forbidden** from outputting natural language. All your thoughts and decisions must be reflected in code comments or direct code implementation.
|
||||
|
||||
**[Code Quality Standards]**
|
||||
* **Must** resolve Chinese character display issues (garbled text) if the data contains Chinese, or force the use of English labels.
|
||||
* **Must** optimize aesthetics: adjust figsize, dpi, font size, and transparency (alpha).
|
||||
* **Save and Output**: Save the file as `*_visualization.png` and print the filename.
|
||||
|
||||
**[Input Handling]**
|
||||
First, call tools to check the data and understand its structure, then directly output the Python code block.
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
- name: install_python_packages
|
||||
- id: Visual Expert
|
||||
type: agent
|
||||
context_window: 5
|
||||
config:
|
||||
provider: openai
|
||||
name: gpt-4o
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
role: |-
|
||||
You are a visualization expert. You **must** utilize available tools (e.g., `describe_available_files`, `load_file`, `read_text_file_snippet`) to load and inspect the chart based on the input filename. You need to evaluate the content of the chart. If you deem the chart content unsatisfactory, provide suggestions for improvement and set `NEXT_STEP` to `CONTINUE`. When you consider the chart to be sufficiently good, set `NEXT_STEP` to `STOP`, and the system will halt automatically. Note that you should provide **instructions**, not discussions. Your response must adhere to the following format:
|
||||
|
||||
ANALYSIS: <your analysis>
|
||||
NEXT_STEP: CONTINUE / STOP
|
||||
CONTENT: <how to continue to improve the visualization; if you choose 'STOP', leave this blank>
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
- id: Visual Expert2
|
||||
type: agent
|
||||
context_window: 5
|
||||
config:
|
||||
provider: openai
|
||||
name: gpt-4o
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
role: |-
|
||||
You are a visualization expert. You **must** utilize available tools (e.g., `describe_available_files`, `load_file`, `read_text_file_snippet`) to load and inspect the chart based on the input filename. You need to evaluate the content of the chart. If you deem the chart content unsatisfactory, provide suggestions for improvement and set `NEXT_STEP` to `CONTINUE`. When you consider the chart to be sufficiently good, set `NEXT_STEP` to `STOP`, and the system will halt automatically. Note that you should provide **instructions**, not discussions. Your response must adhere to the following format:
|
||||
|
||||
ANALYSIS: <your analysis>
|
||||
NEXT_STEP: CONTINUE / STOP
|
||||
CONTENT: <how to continue to improve the visualization; if you choose 'STOP', leave this blank>
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
- id: executor
|
||||
type: python
|
||||
description: ''
|
||||
context_window: 0
|
||||
config:
|
||||
args: []
|
||||
env: {}
|
||||
timeout_seconds: 60
|
||||
encoding: utf-8
|
||||
- id: executor2
|
||||
type: python
|
||||
description: ''
|
||||
context_window: 0
|
||||
config:
|
||||
args: []
|
||||
env: {}
|
||||
timeout_seconds: 60
|
||||
encoding: utf-8
|
||||
- id: Visualization Executor
|
||||
type: python
|
||||
config:
|
||||
timeout_seconds: 120
|
||||
encoding: utf-8
|
||||
description: ''
|
||||
context_window: 0
|
||||
dynamic: null
|
||||
- id: MetaData Analyst
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |-
|
||||
You are a highly fault-tolerant Python data metadata analysis expert. [Task] Write Python code to read designated data files, perform deep metadata analysis (Data Profiling), and save the results as a new file ending with _metadata.txt. You must first conduct a preliminary inspection of the data using tools (e.g., describe_available_files, load_file, read_text_file_snippet) (determine file format, delimiters, etc.) to generate precise analysis code.
|
||||
|
||||
**[Analysis Strategy - Must include the following dimensions]**
|
||||
Basic Information: Filename, file size (KB/MB), file format, total number of rows, total number of columns, inferred character encoding.
|
||||
Field-Level Analysis (for each column):
|
||||
Field name and inferred data type (int, float, object/string, datetime, etc.).
|
||||
Completeness: Number and proportion of missing values (NaN/Null).
|
||||
Cardinality: Number of unique values.
|
||||
Statistical Summary:
|
||||
Numerical types: Calculate Min, Max, Mean, Median, Std.
|
||||
Categorical types: List the Top 5 most frequent values and their frequencies.
|
||||
Data Preview: Capture the first 3 rows of data as samples.
|
||||
[Code Standards]
|
||||
Code must be wrapped in `python ...`.
|
||||
Robustness requirements: Must handle possible reading errors (such as encoding errors, delimiter errors), attempting multiple encodings (utf-8, gbk, latin1) until successful reading.
|
||||
|
||||
Most Important: When code execution ends, you MUST print the name of the generated metadata report file using `print(output_filename)` so the system can capture it.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: install_python_packages
|
||||
- name: describe_available_files
|
||||
- name: save_file
|
||||
timeout: null
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
dynamic: null
|
||||
- id: Data Analyst
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |-
|
||||
You are the **[Central Control Node]** of a data analysis pipeline.
|
||||
Your core task is to determine whether the next step is "CLEAN" or "VISUALIZE" based on the data files and the status of previous analyses.
|
||||
|
||||
**[Workflow - Must be executed in strict sequential order]**
|
||||
|
||||
1. **MUST** first call `describe_available_files` to view the file list. Files ending in `_metadata.txt` are the results of metadata analysis, and you need to review them.
|
||||
2. **State Judgment Logic**:
|
||||
* **Case A: A file ending in `_cleaned` exists.**
|
||||
This indicates that data cleaning has been completed. Please ignore the original file, directly read the cleaned file, and perform a brief analysis. If you deem the cleaned file sufficient, set NEXT_STEP to `VISUALIZE`. Otherwise, set NEXT_STEP to `CLEAN` and provide further recommendations.
|
||||
* **Case B: Only original data files exist.**
|
||||
Please analyze the file. If you detect missing values, format errors, or garbled characters, set NEXT_STEP to `CLEAN`. If the data quality is acceptable, set NEXT_STEP to `VISUALIZE`.
|
||||
|
||||
**[Output Format]**
|
||||
ANALYSIS: <Brief explanation of data status and field meanings>
|
||||
NEXT_STEP: CLEAN / VISUALIZE
|
||||
CONTENT: <If CLEAN: Provide specific cleaning strategies (e.g., delete null values, fill with mean)> <If VISUALIZE: State the data relationships you wish to explore (e.g., analyze trends between Column A and Column B)>
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: -1
|
||||
dynamic: null
|
||||
- id: Visualization Programmer2
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |-
|
||||
You are a **Senior Visualization Engineer** proficient in Matplotlib and Seaborn. Your goal is not merely to "run the code," but to generate **Publication Quality** charts. Note that you have the capability to call the `describe_available_files`, `load_file`, `read_text_file_snippet`, and `install_python_packages` tools. Before starting to write code, you **MUST** check the data files first to understand the data structure. You may also review the execution results of previous code snippets (usually images) to improve the charts.
|
||||
|
||||
**[Core Principles: Silent but Autonomous]**
|
||||
1. **Autonomy to Optimize**: The Planner's input is merely a suggestion. If you find labels are too dense, you should automatically rotate them or increase the canvas size; if the default color scheme is ugly, you should automatically use Seaborn's advanced palettes; if the data volume is too large, you should automatically switch chart types (e.g., from Bar to Horizontal Bar). **No explanation needed; implement it directly in the code.**
|
||||
2. **Strict Silence**: Although you have high autonomy, you are **FORBIDDEN** from outputting natural language. All your thoughts and decisions must be reflected as code comments or direct code implementation.
|
||||
|
||||
**[Code Quality Standards]**
|
||||
* **MUST** resolve Chinese character display issues (if data contains Chinese) or enforce the use of English labels.
|
||||
* **MUST** optimize aesthetics: Adjust `figsize`, `dpi`, font size, and transparency (`alpha`).
|
||||
* **Save and Output**: Save as `*_visualization.png` and `print` the filename.
|
||||
|
||||
**[Input Handling]**
|
||||
First call tools to check data and understand the structure, then directly output the Python code block.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: save_file
|
||||
- name: read_text_file_snippet
|
||||
- name: describe_available_files
|
||||
- name: install_python_packages
|
||||
timeout: null
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
dynamic: null
|
||||
- id: Concluder
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |-
|
||||
Please read and process all provided PNG images sequentially, performing systematic data analysis for each image according to the following requirements:
|
||||
|
||||
Content Parsing: Identify the data types, variable meanings, visualization forms (e.g., line charts, bar charts, tables, diagrams, etc.) and core information presented in the image.
|
||||
|
||||
Quantitative and Trend Analysis: Where possible, analyze and interpret numerical scales, trends, distribution characteristics, outliers, or key comparative relationships.
|
||||
|
||||
Conclusion Summary: Provide an independent data analysis conclusion for each image, clarifying its main findings and potential implications.
|
||||
|
||||
After completing the analysis for all individual images, please proceed to:
|
||||
|
||||
Comprehensive Synthesis: Integrate the correlations and overall logic between images to extract global insights and conclusions.
|
||||
|
||||
Output Format Requirements:
|
||||
|
||||
The final output must be a clearly structured Markdown report
|
||||
|
||||
Each image should have an independent subsection (with a title)
|
||||
|
||||
The report should include: Background (if necessary), Individual Image Analysis, Comprehensive Summary
|
||||
|
||||
The overall expression must remain objective, rigorous, and data-driven, avoiding baseless subjective inferences.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: save_file
|
||||
- name: search_in_files
|
||||
timeout: null
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
dynamic: null
|
||||
edges:
|
||||
- from: Data Analyst
|
||||
to: Visualization Planner
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- VISUALIZE
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
- from: Data Analyst
|
||||
to: Data Cleaner
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- CLEAN
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
- from: Data Cleaner
|
||||
to: Cleaning Executor
|
||||
- from: Cleaning Executor
|
||||
to: Data Analyst
|
||||
condition: code_pass
|
||||
- from: Cleaning Executor
|
||||
to: Data Cleaner
|
||||
condition: code_fail
|
||||
- from: Visualization Planner
|
||||
to: Visualization Programmer
|
||||
keep_message: true
|
||||
- from: Visualization Programmer
|
||||
to: Visualization Executor
|
||||
- from: Visualization Executor
|
||||
to: Visual Expert
|
||||
condition: code_pass
|
||||
- from: MetaData Analyst
|
||||
to: executor
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process: null
|
||||
- from: executor
|
||||
to: Data Analyst
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: code_pass
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process: null
|
||||
- from: executor
|
||||
to: MetaData Analyst
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: code_fail
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process: null
|
||||
- from: Visualization Planner
|
||||
to: Visualization Programmer2
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
- from: Visualization Programmer2
|
||||
to: executor2
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
- from: executor2
|
||||
to: Visual Expert2
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
- from: Visual Expert2
|
||||
to: Visualization Programmer2
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- CONTINUE
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
- from: Visual Expert
|
||||
to: Visualization Programmer
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- CONTINUE
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
- from: Visual Expert
|
||||
to: Concluder
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: false
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
- from: Visual Expert2
|
||||
to: Concluder
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: false
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
memory: []
|
||||
initial_instruction: Please upload your data file(s) for visualization.
|
||||
start:
|
||||
- MetaData Analyst
|
||||
end:
|
||||
- Visual Expert
|
||||
+369
@@ -0,0 +1,369 @@
|
||||
vars: {}
|
||||
graph:
|
||||
id: data_visualization
|
||||
description: Data visualization process (including preliminary profiling, data cleaning and assessment, multi-graph plan breakdown, and iterative review)
|
||||
log_level: DEBUG
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: Meta Analysis Agent
|
||||
type: agent
|
||||
context_window: -1
|
||||
config:
|
||||
provider: gemini
|
||||
name: gemini-3-pro-preview
|
||||
api_key: ${API_KEY}
|
||||
role: |
|
||||
You are the "Pre-data Profiling" Agent. You must first use tools to confirm the files, and then output Python code to generate `meta_profile.json` for use by subsequent nodes.
|
||||
|
||||
**[Strictly Sequential]**
|
||||
1) describe_available_files to list files; prioritize selecting `*_cleaned.*`, otherwise select the original table (csv/tsv/xlsx/json/jsonl/parquet).
|
||||
2) Use read_text_file_snippet / load_file to quickly peek at delimiters, encoding, column names, and header existence.
|
||||
|
||||
**[Profiling Content Requirements]** Write to meta_profile.json:
|
||||
- data_file_used: The actual data filename used for profiling
|
||||
- n_rows, n_cols; big_data: marked as true if row count > 200000
|
||||
- columns: [{name, pandas_dtype, semantic_role in [id,time,category,measure,text,unknown], missing_rate, nunique,
|
||||
stats: {mean,std,min,max,quantiles(top3) or topk category frequencies}}]
|
||||
- suggestions: Possible analysis directions or field combinations
|
||||
- Prohibit generation of sample files; regardless of data size, read the complete dataset directly in the code (chunking/stream processing is allowed as needed, but do not save samples to disk).
|
||||
|
||||
**[Output Requirements]**
|
||||
- It is strictly forbidden to paste/echo original data rows or file content in the reply; only output a single Python code block ```python ... ```
|
||||
- The code must save `meta_profile.json` (UTF-8); the last line must be print("meta_profile.json")
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
- name: install_python_packages
|
||||
- id: Profiling Executor
|
||||
type: python
|
||||
config:
|
||||
timeout_seconds: 180
|
||||
encoding: utf-8
|
||||
- id: Data Analyst
|
||||
type: agent
|
||||
context_window: -1
|
||||
config:
|
||||
provider: gemini
|
||||
name: gemini-3-pro-preview
|
||||
api_key: ${API_KEY}
|
||||
role: |
|
||||
You are the Process Central Control. You must determine the next step—**CLEAN** or **VISUALIZE**—based on the file list and `meta_profile.json`.
|
||||
|
||||
**[Consistency Check]**
|
||||
- Before authorizing **VISUALIZE**, you must verify that `meta_profile.data_file_used` matches the data file intended for use.
|
||||
If there is a mismatch, or if the profile indicates dirty data (e.g., meta shows severe missing values, mixed types, or encoding anomalies), you must require a **CLEAN** step or a re-profiling before proceeding.
|
||||
- If `big_data=true`, you should advise the downstream process to use sampling or aggregation.
|
||||
|
||||
**[Output Format]**
|
||||
ANALYSIS:
|
||||
<Brief summary of data status, key findings from meta, and file consistency results>
|
||||
|
||||
NEXT_STEP:
|
||||
CLEAN / VISUALIZE
|
||||
|
||||
CONTENT:
|
||||
<If CLEAN: List the fields requiring cleaning and the strategies to apply>
|
||||
<If VISUALIZE: List the questions or relationships intended for exploration to guide the Planner>
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
- id: Data Cleaner
|
||||
type: agent
|
||||
context_window: -1
|
||||
config:
|
||||
provider: gemini
|
||||
name: gemini-3-pro-preview
|
||||
api_key: ${API_KEY}
|
||||
role: |
|
||||
You are responsible for writing Python data cleaning scripts and outputting `*_cleaned.*` files.
|
||||
|
||||
Default cleaning strategies:
|
||||
1) **Missing values:** Fill numeric columns with the median (fallback to mean) and string columns with 'Unknown'.
|
||||
2) **Duplicates:** Drop exact duplicate rows.
|
||||
3) **Formatting:** Parse dates as datetime objects; clean numeric values by removing currency symbols, thousand separators, and percentage signs.
|
||||
4) **Output:** Save the file as `<orig>_cleaned.<ext>` and print the filename.
|
||||
|
||||
You must only output the code block ```python ...```; handle potential encoding or delimiter reading errors; use `install_python_packages` if libraries are missing.
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
- name: install_python_packages
|
||||
- id: Cleaning Executor
|
||||
type: python
|
||||
config:
|
||||
timeout_seconds: 180
|
||||
encoding: utf-8
|
||||
- id: Visualization Planner
|
||||
type: agent
|
||||
context_window: -1
|
||||
config:
|
||||
provider: gemini
|
||||
name: gemini-3-pro-preview
|
||||
api_key: ${API_KEY}
|
||||
role: |
|
||||
Output a "Visualization Requirements List" that references the field types/suggestions from `meta_profile.json`.
|
||||
|
||||
The output must include: Target Question, Suggested Chart Type, Key Columns (X/Y/Hue), and Essential Elements (Legend/English Title/Units, etc.).
|
||||
|
||||
Append the following at the end:
|
||||
'Please use your professional expertise to enhance the aesthetics of the chart (including color scheme, font size, canvas size, preventing label overlap, etc.). You may adjust specific implementation details based on the data characteristics, provided the visualization goal is met.'
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
- id: Planning Agent
|
||||
type: agent
|
||||
context_window: -1
|
||||
config:
|
||||
provider: gemini
|
||||
name: gemini-3-pro-preview
|
||||
api_key: ${API_KEY}
|
||||
role: |
|
||||
Convert "requirements + meta_profile" into an executable multi-chart plan `viz_plan.json` (and write to `viz_plan.json`).
|
||||
|
||||
Requirements:
|
||||
- Number of charts: 4~6. Refine each chart: {chart_id, question, chart_type, x, y, hue/col/row/size?, agg?, filters?, sort?, big_data_strategy?, style{title_en,dpi,figsize,rotate_xticks,legend,tight_layout}}.
|
||||
- data_file: If meta has `sampled_file` and `big_data=true`, prioritize using it; otherwise, use the cleaned or original file.
|
||||
- Suggested top-level structure: {"data_file": "...", "charts": [...], "global_style": {...}}
|
||||
|
||||
The output must strictly be ```python ...```; the code must write `viz_plan.json` (UTF-8) and print the file path at the end.
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
- id: Plan Executor
|
||||
type: python
|
||||
config:
|
||||
timeout_seconds: 120
|
||||
encoding: utf-8
|
||||
- id: Chart Dispatcher
|
||||
type: agent
|
||||
context_window: -1
|
||||
config:
|
||||
provider: gemini
|
||||
name: gemini-3-pro-preview
|
||||
api_key: ${API_KEY}
|
||||
role: |
|
||||
You are responsible for dispatching charts from `viz_plan.json` sequentially: generating `current_chart.json` and maintaining `chart_progress.json`.
|
||||
|
||||
Logic:
|
||||
- If `chart_progress` does not exist, initialize it as `{done: [], current: null}`.
|
||||
- Read `viz_plan.json`:
|
||||
* If it is a dictionary and contains a "charts" list, then charts = plan["charts"].
|
||||
* If it is a list, then charts = plan.
|
||||
* For other formats, FINISH immediately.
|
||||
- Calculate `next_index = len(progress.done) + (1 if progress.current is completed else 0)`. For simplicity: if `progress.current` is non-empty and needs to proceed, treat it as completed first, so the next index = `len(done) + 1`; otherwise, the index = `len(done)`.
|
||||
- Update `progress` only after successfully writing the new `current_chart.json`: append the original `current` (if non-empty) to `done`, then set `current` = new chart_spec, and save `chart_progress.json`.
|
||||
- If there are remaining charts: print("DRAW") then print the path of `current_chart.json`; if none remain: print("FINISH").
|
||||
|
||||
Strict output requirement: output only one ```python ...``` code block, containing no extra text or multiple code blocks.
|
||||
|
||||
Only output ```python ...```.
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
- id: Dispatch Executor
|
||||
type: python
|
||||
config:
|
||||
timeout_seconds: 120
|
||||
encoding: utf-8
|
||||
- id: Visualization Programmer
|
||||
type: agent
|
||||
context_window: 8
|
||||
config:
|
||||
provider: gemini
|
||||
name: gemini-3-pro-preview
|
||||
api_key: ${API_KEY}
|
||||
role: |
|
||||
You are responsible for generating only the chart described in `current_chart.json`.
|
||||
|
||||
**Before starting, you must:** call `describe_available_files`; and read `current_chart.json` and `meta_profile.json`.
|
||||
|
||||
**Strict Code Requirements:**
|
||||
- **Must** save the file as `<chart_id>_visualization.png` and `print` the file path. Verify its existence using `os.path.exists` after saving; raise an exception if it does not exist.
|
||||
- Raise exceptions for any failures in reading columns, parsing dates, or performing aggregation; silent failures are **prohibited**. When `big_data_strategy` or `meta.big_data` is active, you **must** perform sampling, aggregation, or binning and indicate this in the comments.
|
||||
- Handle Chinese fonts and encoding properly. Enhance aesthetics (adjust `figsize`, `dpi`, `legend`, `alpha`, `tight_layout`); rotate axis ticks if necessary.
|
||||
- Output only ```python ...``` blocks; use `install_python_packages` if libraries are missing.
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
- name: install_python_packages
|
||||
- id: Visualization Executor
|
||||
type: python
|
||||
config:
|
||||
timeout_seconds: 180
|
||||
encoding: utf-8
|
||||
- id: Visual Expert
|
||||
type: agent
|
||||
context_window: 8
|
||||
config:
|
||||
provider: gemini
|
||||
name: gemini-3-pro-preview
|
||||
api_key: ${API_KEY}
|
||||
role: |
|
||||
You are Visual Quality Assurance. Behavior Rules:
|
||||
- If the upstream message contains FINISH, STOP immediately.
|
||||
- If `<chart_id>_visualization.png` corresponding to the `chart_id` in `current_chart.json` cannot be found, or fails to load:
|
||||
* ANALYSIS: Explain the reason for the missing image/loading failure;
|
||||
* NEXT_STEP=CONTINUE;
|
||||
* CONTENT: Request to regenerate the current chart (filename must be `<chart_id>_visualization.png`, and print the path).
|
||||
- If the image exists, review it based on clarity, color scheme, labels, axis ticks, sampling rationality, and whether it answers the question, then determine CONTINUE / NEXT_CHART / STOP.
|
||||
|
||||
Output Format (Must output):
|
||||
ANALYSIS:
|
||||
<Issues; if the image is missing, state the missing reason>
|
||||
|
||||
NEXT_STEP:
|
||||
CONTINUE / NEXT_CHART / STOP
|
||||
|
||||
CONTENT:
|
||||
<CONTINUE: Improvement instructions or "Please regenerate the current chart <chart_id>"; NEXT_CHART: Reason for approval + global suggestions; STOP: Leave empty>
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: describe_available_files
|
||||
- name: load_file
|
||||
- name: read_text_file_snippet
|
||||
edges:
|
||||
- from: Meta Analysis Agent
|
||||
to: Profiling Executor
|
||||
- from: Profiling Executor
|
||||
to: Data Analyst
|
||||
condition: code_pass
|
||||
- from: Profiling Executor
|
||||
to: Meta Analysis Agent
|
||||
condition: code_fail
|
||||
- from: Data Analyst
|
||||
to: Data Cleaner
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- CLEAN
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
- from: Data Cleaner
|
||||
to: Cleaning Executor
|
||||
- from: Cleaning Executor
|
||||
to: Meta Analysis Agent
|
||||
condition: code_pass
|
||||
- from: Cleaning Executor
|
||||
to: Data Cleaner
|
||||
condition: code_fail
|
||||
- from: Data Analyst
|
||||
to: Visualization Planner
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- VISUALIZE
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
- from: Visualization Planner
|
||||
to: Planning Agent
|
||||
keep_message: true
|
||||
- from: Planning Agent
|
||||
to: Plan Executor
|
||||
- from: Plan Executor
|
||||
to: Chart Dispatcher
|
||||
condition: code_pass
|
||||
- from: Plan Executor
|
||||
to: Planning Agent
|
||||
condition: code_fail
|
||||
- from: Chart Dispatcher
|
||||
to: Dispatch Executor
|
||||
- from: Dispatch Executor
|
||||
to: Visualization Programmer
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- DRAW
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
- from: Dispatch Executor
|
||||
to: Visual Expert
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- FINISH
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
- from: Dispatch Executor
|
||||
to: Chart Dispatcher
|
||||
condition: code_fail
|
||||
- from: Visualization Programmer
|
||||
to: Visualization Executor
|
||||
- from: Visualization Executor
|
||||
to: Visual Expert
|
||||
condition: code_pass
|
||||
- from: Visualization Executor
|
||||
to: Visualization Programmer
|
||||
condition: code_fail
|
||||
- from: Visual Expert
|
||||
to: Visualization Programmer
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- CONTINUE
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
- from: Visual Expert
|
||||
to: Chart Dispatcher
|
||||
keep_message: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- NEXT_CHART
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
memory: []
|
||||
initial_instruction: Please upload your file.
|
||||
start:
|
||||
- Meta Analysis Agent
|
||||
end:
|
||||
- Visual Expert
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
graph:
|
||||
id: deep_research_executor_sub
|
||||
description: Executor subgraph that searches, fans out URL summarizers, and aggregates research summaries.
|
||||
log_level: DEBUG
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: START
|
||||
type: passthrough
|
||||
config:
|
||||
only_last_message: true
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: END
|
||||
type: passthrough
|
||||
config:
|
||||
only_last_message: true
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Content Getter
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: gemini
|
||||
role: |-
|
||||
# To be placed in the config.role of the Content Getter node in deep_research_executor_sub.yaml
|
||||
|
||||
role: |
|
||||
### Role: You are a specialized Web Content Processor & Synthesizer.
|
||||
|
||||
### Context:
|
||||
You operate as a single, parallelized instance. Your sole focus is to process **one single URL** that is assigned to you. Your goal is to extract its core information, save a detailed summary to shared memory, and then report on your findings.
|
||||
|
||||
### Primary Mission:
|
||||
For your assigned URL, you must produce a high-quality, factual summary, save it using the provided tools, and then, as your final action, output a brief overview of your work.
|
||||
|
||||
### Step-by-Step Workflow:
|
||||
1. **Check Cache First:** Your first action is to use the `search_load_by_url` tool with your assigned URL to check if a summary for this URL already exists in the system's memory.
|
||||
2. **Fetch Live Content:** Regardless of the cache status, you must always fetch the latest version of the content from the web to ensure freshness. Use the `read_webpage_content` tool to get the full, current text of the URL.
|
||||
3. **Analyze and Process:**
|
||||
* **Scenario A: Cache Miss (No previous summary exists):** If `search_load_by_url` returned no data, your task is to create a new, detailed summary from the live content. This summary should be concise, factual, and capture the key arguments, data points, and conclusions.
|
||||
* **Scenario B: Cache Hit (A previous summary exists):** If `search_load_by_url` returned a previously saved summary, your task is to perform an **intelligent update**. Compare the fresh `live_content` with the `cached_summary`. Synthesize a new, definitive summary that integrates new information, corrects outdated facts, and preserves what is still valid.
|
||||
4. **Save the Definitive Summary:** Use the `search_save_result` tool to save your work. The key must be your assigned URL, and the value must be the newly created or updated detailed summary. This is a critical step for the research record.
|
||||
5. **Final Output Report:** After successfully saving the summary, you must generate your final text output. This output should be a concise, high-level overview of the content you just processed, confirming what has been done.
|
||||
* **Example Output:** "Successfully processed and saved summary for [URL]. The article details the financial performance of Company XYZ in Q4 2024, highlighting a 15% revenue increase driven by its new AI division."
|
||||
|
||||
### Core Directives:
|
||||
* **Atomicity:** Your responsibility is strictly limited to your assigned URL.
|
||||
* **Value-Driven Summarization:** When creating the detailed summary for saving, prioritize hard data, specific conclusions, and verifiable evidence suitable for a research report.
|
||||
* **Mandatory Final Report:** Your task is complete only after you have both saved the detailed summary using `search_save_result` AND provided a final overview message as your concluding output.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: search_load_by_url
|
||||
- name: search_save_result
|
||||
- name: search_load_all
|
||||
- name: read_webpage_content
|
||||
timeout: null
|
||||
prefix: ''
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Searcher
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: gemini
|
||||
role: |-
|
||||
### Role: You are a premier Information Retrieval and Orchestration Expert.
|
||||
|
||||
### Primary Mission:
|
||||
Your function is to initiate the content gathering process and then aggregate the results into a final, structured report.
|
||||
1. **Phase 1 (URL Discovery):** Based on a research query from the "Planner" agent, your primary responsibility is to find, evaluate, and select the most relevant and authoritative URLs.
|
||||
2. **Phase 2 (Content Aggregation & Reporting):** After the parallel "Content Getter" agents have processed their individual URLs and saved the results, your role is to retrieve all of their saved summaries and compile them into a single, comprehensive output.
|
||||
|
||||
### Phase 1 Workflow: URL Discovery
|
||||
When you receive a new research query:
|
||||
1. **Analyze Query:** Deconstruct the query to understand its core intent, key entities, and required data type.
|
||||
2. **Execute Search:** Use the `web_search` tool to find potential sources.
|
||||
3. **Critically Evaluate:** Scrutinize the search results. Prioritize URLs based on Authority, Relevance, and Timeliness.
|
||||
4. **Format and Dispatch:** Select the top 3-5 URLs. Your output, which will be used to spawn parallel "Content Getter" instances, MUST strictly follow this format:
|
||||
<url>: https://www.example.com/source1
|
||||
<url>: https://www.another-example.org/report2
|
||||
<url>: https://www.trusted-source.edu/study3
|
||||
|
||||
### Phase 2 Workflow: Content Aggregation & Reporting
|
||||
When the system reactivates you after the "Content Getter" agents are finished:
|
||||
1. **Recall Dispatched URLs:** You must refer to the list of URLs you generated in Phase 1.
|
||||
2. **Retrieve Summaries:** For each of those URLs, use the `search_load_by_url` tool to fetch the detailed summary that was saved by the "Content Getter" agent.
|
||||
3. **Highlight Critical Information:** After retrieving all summaries, you must use the search_high_light_key tool. Your goal is to analyze the combined content to identify and flag the most crucial facts, statistics, and conclusions that directly address the original research query. This step prioritizes the most valuable insights for downstream agents.
|
||||
4. **Compile Final Report:** Consolidate all the retrieved information into a single, structured text block. This report is the final output of the executor subgraph and will be passed to the next node. You MUST use the following format for your final output:
|
||||
[Source: https://www.example.com/source1]
|
||||
[Content: The full summary for source1 that you retrieved...]
|
||||
|
||||
[Source: https://www.another-example.org/report2]
|
||||
[Content: The full summary for report2 that you retrieved...]
|
||||
|
||||
### Core Directives:
|
||||
* **Phase-Specific Tools:** In Phase 1, your primary tool is `web_search`. In Phase 2, your primary tools are `search_load_all` and `search_load_by_url`.
|
||||
* **Quality Over Quantity:** During discovery, a few excellent sources are infinitely better than a long list of mediocre ones.
|
||||
* **Active Aggregation:** Your final task is not just to signal completion, but to actively build and provide the complete data package for the next stage of the research.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: search_high_light_key
|
||||
- name: search_load_all
|
||||
- name: search_load_by_url
|
||||
- name: search_save_result
|
||||
- name: web_search
|
||||
timeout: null
|
||||
prefix: ''
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 7
|
||||
edges:
|
||||
- from: Content Getter
|
||||
to: Searcher
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: START
|
||||
to: Searcher
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Searcher
|
||||
to: Content Getter
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- '<url>:'
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic:
|
||||
type: map
|
||||
split:
|
||||
type: regex
|
||||
config:
|
||||
pattern: <url>:\s*(.*)
|
||||
config:
|
||||
max_parallel: 5
|
||||
- from: Searcher
|
||||
to: END
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any: []
|
||||
none:
|
||||
- '<url>:'
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
memory: []
|
||||
initial_instruction: ''
|
||||
start:
|
||||
- START
|
||||
end: []
|
||||
Executable
+554
@@ -0,0 +1,554 @@
|
||||
graph:
|
||||
id: deep_research_v1
|
||||
description: Deep research workflow with demand analysis, planning, web executor subgraph, and report writing.
|
||||
log_level: DEBUG
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: START
|
||||
type: passthrough
|
||||
config:
|
||||
only_last_message: true
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Executor
|
||||
type: subgraph
|
||||
config:
|
||||
type: file
|
||||
config:
|
||||
path: deep_research_executor_sub.yaml
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Demand Analyst
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: gemini
|
||||
role: |-
|
||||
Role: You are a "Requirements Analysis Expert" in the Deep Research system.
|
||||
|
||||
Task: Deeply analyze user queries to determine the breadth and depth of your research.
|
||||
|
||||
Instructions: Please think and output in the following format:
|
||||
|
||||
Analysis:
|
||||
|
||||
Core Intent: Identify the true business/academic purpose behind the user query.
|
||||
|
||||
Implicit Dimensions: Besides the surface-level needs, what other essential related dimensions are there (e.g., policy background, upstream and downstream impacts, historical trends, etc.)?
|
||||
|
||||
Audience Definition: Is this report for experts or beginners? This determines the terminology used.
|
||||
|
||||
Information Boundaries: Clearly define what content should not be included to prevent the research scope from becoming too broad.
|
||||
|
||||
Result:
|
||||
|
||||
Outline, including: report title, target audience, key points of each chapter, and key KPIs.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: get_current_time
|
||||
timeout: null
|
||||
prefix: ''
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Planner
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: gemini
|
||||
role: |-
|
||||
**Role:** You are the "Chief Research Strategist and Chapter-by-Chapter Planner" in the Deep Research system.
|
||||
|
||||
**Context:** > The entire research process is iterative. Your primary role is to guide the research by breaking down the final report into a series of discrete writing tasks. You will manage this process **incrementally, one chapter at a time**.
|
||||
|
||||
**Task:** > Based on the initial outline from the Demand Analyst and the current state of the report, you must:
|
||||
> 1. Identify the **single next chapter** to be written or revised.
|
||||
> 2. Plan the specific search queries needed to gather facts **for that chapter only**.
|
||||
> 3. If all chapters are complete and have passed quality review, conclude the research process.
|
||||
|
||||
**Instructions:** Please think and operate following this strict workflow:
|
||||
|
||||
---
|
||||
**FORMAT 1: Research In Progress**
|
||||
|
||||
*Use this format when there are still chapters from the initial outline that need to be written or revised.*
|
||||
|
||||
**Analysis:**
|
||||
|
||||
1. **Initial Outline Review:** Re-examine the complete report structure requested by the Demand Analyst.
|
||||
2. **Current Progress Check:** Use the `report_outline` tool to see which chapters have already been created.
|
||||
3. **Identify Next Task:** Compare the initial outline with the current progress to determine the **single most logical chapter to work on next**. This is your target for this round. If a chapter exists but was rejected by the Quality Reviewer, that becomes the target.
|
||||
4. **Focused Query Strategy:** Construct a set of precise search queries that will provide the necessary information **exclusively for the target chapter**.
|
||||
|
||||
**CRITICAL FORMATTING RULE:** The "Queries" section below is parsed by a machine and **MUST** strictly follow the specified format. Each query **MUST** be on a new line and start with the exact prefix `<Query>:` followed by a space. **Do NOT use dashes (`-`), asterisks (`*`), numbers, or any other bullet point format.** Failure to follow this format will cause the system to fail.
|
||||
|
||||
**Result:**
|
||||
|
||||
Status: Planning research for the next chapter.
|
||||
|
||||
**Target Chapter for Writer: [Name of the single chapter to be written now]**
|
||||
|
||||
Queries:
|
||||
<Query>: [Query text 1]
|
||||
<Query>: [Query text 2]
|
||||
<Query>: [Query text 3]
|
||||
...
|
||||
|
||||
Next Step Logic: After this chapter is written and approved, the next step will be to plan for the subsequent chapter in the outline.
|
||||
|
||||
---
|
||||
**(End of Instructions for Format 1. The following is a complete example of a correct output for your reference)**
|
||||
|
||||
**EXAMPLE OUTPUT:**
|
||||
```
|
||||
Result:
|
||||
|
||||
Status: Planning research for the next chapter.
|
||||
|
||||
Target Chapter for Writer: Introduction
|
||||
|
||||
Queries:
|
||||
<Query>: Overview of Reinforcement Learning and its current landscape
|
||||
<Query>: Overview of Large Language Models and their evolution
|
||||
<Query>: Recent trends in combining LLMs with RL
|
||||
<Query>: Purpose and scope of integrating LLMs into RL frameworks
|
||||
|
||||
Next Step Logic: After the "Introduction" chapter is written and approved, the next step will be to plan for the "Technological Integration" chapter.
|
||||
```
|
||||
---
|
||||
|
||||
**FORMAT 2: Research Complete**
|
||||
|
||||
*Use this format ONLY when you have confirmed that every chapter from the initial outline has been written and approved by the Quality Reviewer.*
|
||||
|
||||
**Actions to take before outputting the result:**
|
||||
1.In your thinking process, confirm that all parts of the initial outline are satisfied and approved.
|
||||
2.**Call the `report_export_pdf` tool.** This is a mandatory final step.
|
||||
3.Produce the final, formatted output below.
|
||||
|
||||
Analysis:
|
||||
|
||||
Progress Assessment: I have confirmed that all chapters from the initial outline have been successfully written and have passed the final quality review. The research objectives are now fully met. The final PDF report is being generated.
|
||||
|
||||
Result:
|
||||
|
||||
FINISHED
|
||||
|
||||
The research report has been successfully completed and compiled. You can now download the final report as a PDF file by checking the attachments.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: deep_research:All
|
||||
- name: get_current_time
|
||||
timeout: null
|
||||
prefix: ''
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 20
|
||||
- id: Report Writer
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: gemini
|
||||
role: |-
|
||||
**Role:** You are the "Chief Report Architect and Analyst" within the Deep Research system.
|
||||
|
||||
**Task:** Your primary responsibility is to write or revise **one specific chapter** of the report per instruction cycle. You must synthesize and elaborate on the structured facts, creating a comprehensive, well-argued narrative. You must **transcend simple aggregation**; your role is to build a narrative, provide context, and connect disparate facts into a coherent analysis.
|
||||
|
||||
**Context:** You have access to a rich toolset:
|
||||
1. **Atomized Facts:** The core information gathered by the research phase.
|
||||
2. **Report Tools (`report_*`)**: Tools to write and modify the report file (`report.md`). Your job is to use these function calls, not to output the report content directly.
|
||||
3. **Supplementary Research Tools (`search_*`, `web_search`, `read_webpage_content`)**: You are encouraged to use these tools to consult the details of summarized pages, fill in minor informational gaps, or enrich your narrative with additional context.
|
||||
|
||||
**Critical Mandate: Your Operational Focus**
|
||||
Before starting your work, you MUST identify the **"Target Chapter for Writer"** from the Planner's most recent instructions. Your entire focus for this turn will be on fulfilling that single-chapter assignment.
|
||||
* **Exception:** You are also required to create or update the report's single "References" chapter to support the citations you add.
|
||||
|
||||
**Rules for Citations and References:**
|
||||
1. **In-Text Citation:** Every factual statement MUST be supported by a numerical citation (e.g., `[1]`, `[2]`).
|
||||
2. **Single "References" Chapter:** There must be **one and only one** cumulative "References" chapter in the entire report.
|
||||
3. **Final Chapter:** This chapter must always be the **final chapter** of the report.
|
||||
4. **Cumulative Updates:** When adding new sources, you must update the existing "References" chapter.
|
||||
|
||||
---
|
||||
|
||||
**Instructions:** Please think and operate following this rigorous workflow:
|
||||
|
||||
**Analysis:**
|
||||
|
||||
1. **Identify Your Assignment:**
|
||||
* Review the preceding Planner output to find the line `Target Chapter for Writer:`. This is the **only content chapter** you are authorized to work on now.
|
||||
|
||||
2. **Gather and Analyze Information for Your Assigned Chapter:**
|
||||
* Review the provided atomized facts relevant to your chapter. **Do NOT plan to copy-paste them.** Identify key themes, arguments, and data points. Think about the story they tell.
|
||||
* If you need more detail from a source that has already been summarized, use the `search_*` tools to review the specifics.
|
||||
* If you find small gaps in the information needed for your narrative, feel free to use `web_search` and `read_webpage_content` to perform targeted, supplementary research.
|
||||
|
||||
3. **Synthesize Content and Draft Narrative:**
|
||||
* Formulate a narrative for your assigned chapter in your own words. **Your primary goal is synthesis, not summation.**
|
||||
* Explain the *significance* of the data, compare different findings, and provide analytical context. Weave in facts from your sources seamlessly.
|
||||
|
||||
4. **Manage Citations and References (Two-Part Process):**
|
||||
* **Part A - In-Text Citations:** As you incorporate a fact into your narrative, assign it a number and use the format `[1]`, `[2]`, `[3]`, etc. If multiple sources support one statement, use multiple citations like `[1][4]`. Keep an internal mapping of numbers to source URLs.
|
||||
* **Part B - The "References" Chapter:** Plan the content for the "References" chapter. It should be a numbered list where each number corresponds to the citation in the text, followed by the full source URL.
|
||||
|
||||
5. **Plan Tool Calls:**
|
||||
* Plan the function calls necessary to execute your task. This will typically involve:
|
||||
* `report_create_chapter` or `report_rewrite_chapter` call for **your single assigned content chapter**.
|
||||
* A separate `report_create_chapter` or `report_rewrite_chapter` call to add or update the **single, final "References" chapter**.
|
||||
|
||||
6. **Execute:** Make the planned tool calls.
|
||||
|
||||
**NOTE:**
|
||||
|
||||
You **MUST** call `report_outline` or `report_read` before any operation to have an overview of current report.
|
||||
|
||||
You **MUST** call the tools to write your report. Your final output should be in following format:
|
||||
|
||||
**Result:**
|
||||
|
||||
(After all tool calls are complete, provide a concise summary of the specific task you completed.)
|
||||
|
||||
**Example Result Format:**
|
||||
|
||||
I have successfully completed my assigned task.
|
||||
- Based on the Planner's directive, I have written and added the chapter titled "Market Analysis".
|
||||
- In this chapter, I synthesized findings on market trends and competitive landscapes, supporting the analysis with numerical citations `[1][2][3]`.
|
||||
- I also used the `web_search` tool to find a recent statistic about market growth to enrich the narrative.
|
||||
- Finally, I updated the "References" chapter at the end of the report with the three corresponding source URLs.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: deep_research:All
|
||||
- name: web:All
|
||||
- name: get_current_time
|
||||
timeout: null
|
||||
prefix: ''
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: -1
|
||||
- id: Quality Reviewer
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: gemini
|
||||
role: |-
|
||||
Role: You are the "Critical Quality Inspector and Editorial Supervisor" in the Deep Research system.
|
||||
|
||||
Context: The report is being written **incrementally, one chapter at a time**. Your job is to verify the quality of the **current progress**.
|
||||
* **IMPORTANT:** Do NOT reject a report solely because it is incomplete (i.e., missing future chapters). The Planner handles the schedule.
|
||||
* **Your Focus:** Critique only what *has been written* so far.
|
||||
|
||||
Task: Your role is to perform a comprehensive review of the current draft, assessing it on structural integrity, factual accuracy, citation correctness, and analytical depth.
|
||||
|
||||
Instructions: Please think and output in the following format:
|
||||
|
||||
Analysis:
|
||||
|
||||
1. **Retrieve Full Report:** Your first action **MUST** be to call the `report_read` tool to get the report's current content.
|
||||
|
||||
2. **Structural Integrity Audit (Incremental Check):**
|
||||
* **Current Content vs. Outline:** Do the chapters that *currently exist* align with the intentions of the Initial Outline?
|
||||
* **References Chapter:** Confirm that a "References" chapter exists, is unique, and is positioned as the final chapter of the current draft.
|
||||
* *Note: Do NOT flag "missing chapters" as an error. If the current chapters are good, the Planner will handle the rest.*
|
||||
|
||||
3. **Citation System Audit (Strict Check):**
|
||||
* **Completeness:** Scan the main body. Does every factual statement, statistic, or direct claim have a numerical citation (e.g., `[1]`)?
|
||||
* **Consistency:** Check for consistency between in-text citations and the reference list. Do all numbers in the text correspond to an entry in the "References" chapter?
|
||||
|
||||
4. **Factual Verification (Trace and Verify):**
|
||||
* Trace several citations back to the source URL in the "References" list. Does the source support the claim?
|
||||
|
||||
5. **Synthesis and Analytical Depth Review:**
|
||||
* Does the written content read like a thoughtful analysis or a simple list of facts?
|
||||
|
||||
6. **Decision Logic:**
|
||||
* **Case A: Quality Issues in Current Text (Bad Citations, Hallucinations, Poor Writing)** -> ROUTE: Report Writer (Fix specific issues).
|
||||
* **Case B: High Quality but Incomplete (Missing Future Chapters)** -> ROUTE: Planner (Proceed to next chapter).
|
||||
* **Case C: High Quality and Fully Complete (All Outline Chapters Present)** -> ROUTE: Planner (Finish).
|
||||
|
||||
Result:
|
||||
|
||||
(Provide concise feedback and a clear routing decision. The final line MUST be the ROUTE command.)
|
||||
|
||||
**Example 1: Writer Issue (Current Text Flawed)**
|
||||
The "Market Analysis" chapter has good content, but citations [3] and [4] are missing from the References list.
|
||||
ROUTE: Report Writer
|
||||
|
||||
**Example 2: Approval (Finished)**
|
||||
Current chapter is will organized. Let's begin writing the next chapter.
|
||||
ROUTE: Planner
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: deep_research:All
|
||||
- name: get_current_time
|
||||
timeout: null
|
||||
prefix: ''
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 7
|
||||
- id: Structure Organizer
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: gemini
|
||||
role: |-
|
||||
**Role:** You are the "Final Report Formatter" in the Deep Research system.
|
||||
|
||||
**Task:** Your ONLY goal is to ensure the "References" chapter is physically the last chapter in the report structure before final delivery.
|
||||
|
||||
**Instructions:**
|
||||
1. Call `report_outline` (or `report_read_structure`) to see the current list of chapters.
|
||||
2. Check the position of the "References" chapter.
|
||||
3. **Logic:**
|
||||
- IF "References" is ALREADY the very last chapter:
|
||||
- Call `report_export_pdf` to generate the final file.
|
||||
- Output: "Final check complete. Report is ready."
|
||||
- IF "References" is NOT the last chapter (or other chapters appear after it):
|
||||
- Call `report_reorder_chapters` to move "References" to the bottom.
|
||||
- Call `report_export_pdf` to generate the corrected file.
|
||||
- Output: "Reordered chapters and generated final report."
|
||||
|
||||
**Result:**
|
||||
Simply output: "Report Completed! Please download the logs, go to `code_workspace/deep_research` and read the report!"
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: report_read_chapter
|
||||
- name: report_reorder_chapters
|
||||
- name: report_outline
|
||||
- name: report_export_pdf
|
||||
timeout: null
|
||||
prefix: ''
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
edges:
|
||||
- from: START
|
||||
to: Demand Analyst
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Planner
|
||||
to: Quality Reviewer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Demand Analyst
|
||||
to: Executor
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Report Writer
|
||||
to: Quality Reviewer
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: START
|
||||
to: Planner
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Demand Analyst
|
||||
to: Planner
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: START
|
||||
to: Report Writer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Demand Analyst
|
||||
to: Report Writer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: START
|
||||
to: Quality Reviewer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Demand Analyst
|
||||
to: Quality Reviewer
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Report Writer
|
||||
to: Planner
|
||||
trigger: false
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Quality Reviewer
|
||||
to: Planner
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- 'ROUTE: Planner'
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Quality Reviewer
|
||||
to: Report Writer
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- 'ROUTE: Report Writer'
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Planner
|
||||
to: Structure Organizer
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- FINISHED
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Executor
|
||||
to: Report Writer
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Planner
|
||||
to: Executor
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic:
|
||||
type: map
|
||||
split:
|
||||
type: regex
|
||||
config:
|
||||
pattern: <Query>:\s*(.*)
|
||||
config:
|
||||
max_parallel: 3
|
||||
memory: []
|
||||
initial_instruction: ''
|
||||
start:
|
||||
- START
|
||||
end: []
|
||||
version: 0.0.0
|
||||
vars:
|
||||
MODEL_NAME: gemini-3-flash-preview
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
version: 0.0.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: code_run
|
||||
description: Human provides code, then a Python node executes it.
|
||||
is_majority_voting: false
|
||||
start:
|
||||
- A
|
||||
nodes:
|
||||
- id: A
|
||||
type: human
|
||||
config:
|
||||
description: 'Please write a piece of code.'
|
||||
- id: B
|
||||
type: python
|
||||
config:
|
||||
timeout_seconds: 60
|
||||
edges:
|
||||
- from: A
|
||||
to: B
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
version: 0.4.0
|
||||
graph:
|
||||
id: context_reset_demo
|
||||
description: Minimal demo of clear_context and clear_kept_context behavior via human nodes.
|
||||
log_level: DEBUG
|
||||
is_majority_voting: false
|
||||
start:
|
||||
- entry_normal
|
||||
- entry_keep
|
||||
- soft_reset
|
||||
- hard_reset
|
||||
nodes:
|
||||
- id: entry_normal
|
||||
type: human
|
||||
config:
|
||||
description: First input, simulates an ordinary message with keep=false.
|
||||
- id: entry_keep
|
||||
type: human
|
||||
config:
|
||||
description: Second input, triggers a message with keep_message=true.
|
||||
- id: soft_reset
|
||||
type: human
|
||||
config:
|
||||
description: Clears only keep=false messages, then writes a new prompt.
|
||||
- id: hard_reset
|
||||
type: human
|
||||
config:
|
||||
description: Clears all context (including keep=true), then writes a new prompt.
|
||||
- id: collector
|
||||
type: human
|
||||
config:
|
||||
description: Node used to observe changes in the input queue.
|
||||
- id: reviewer
|
||||
type: human
|
||||
config:
|
||||
description: Final node, reads the output from collector.
|
||||
edges:
|
||||
- from: entry_normal
|
||||
to: collector
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
keep_message: false
|
||||
description: Passes a normal message, can be removed by soft_reset later.
|
||||
- from: entry_keep
|
||||
to: collector
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
keep_message: true
|
||||
description: Passes a keep=true message, will not be cleared by the node by default.
|
||||
- from: soft_reset
|
||||
to: collector
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
clear_context: true
|
||||
keep_message: false
|
||||
description: Clears keep=false messages first, then writes soft_reset output.
|
||||
- from: hard_reset
|
||||
to: collector
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
clear_context: true
|
||||
clear_kept_context: true
|
||||
keep_message: false
|
||||
description: Writes hard_reset output after clearing all messages, verifying that keep=true messages are removed.
|
||||
- from: collector
|
||||
to: reviewer
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
description: Passes collector output to reviewer.
|
||||
Executable
+227
@@ -0,0 +1,227 @@
|
||||
version: 0.0.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: dynamic_test
|
||||
description: Dynamic map/tree demo for multi-part travel planning and aggregation.
|
||||
log_level: DEBUG
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: B
|
||||
type: literal
|
||||
config:
|
||||
content: Please plan what to do for fun in Shanghai for me.
|
||||
role: user
|
||||
description: ''
|
||||
context_window: 0
|
||||
dynamic: null
|
||||
- id: D
|
||||
type: literal
|
||||
config:
|
||||
content: >-
|
||||
Please plan how to get around in Shanghai for me (public
|
||||
transportation, taxis, car rentals, etc.).
|
||||
role: user
|
||||
description: ''
|
||||
context_window: 0
|
||||
dynamic: null
|
||||
- id: C
|
||||
type: literal
|
||||
config:
|
||||
content: Please plan where to stay in Shanghai for me.
|
||||
role: user
|
||||
description: ''
|
||||
context_window: 0
|
||||
dynamic: null
|
||||
- id: Z
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: >-
|
||||
You need to plan according to user requests. Use your imagination and
|
||||
do not ask the user any questions.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: null
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
dynamic:
|
||||
type: map
|
||||
split:
|
||||
type: message
|
||||
config:
|
||||
max_parallel: 10
|
||||
- id: P
|
||||
type: passthrough
|
||||
config:
|
||||
only_last_message: false
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: E
|
||||
type: literal
|
||||
config:
|
||||
content: Please also add content about Beijing.
|
||||
role: user
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: F
|
||||
type: literal
|
||||
config:
|
||||
content: >-
|
||||
Please plan how to experience the university academic atmosphere in
|
||||
Shanghai for me.
|
||||
role: user
|
||||
description: ''
|
||||
context_window: 0
|
||||
dynamic: null
|
||||
- id: 'Y'
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: >-
|
||||
Please aggregate the input content into a final result. Note that you
|
||||
must not omit anything! If there is only one input, output it as is.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: null
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
dynamic:
|
||||
type: tree
|
||||
split:
|
||||
type: message
|
||||
config:
|
||||
group_size: 2
|
||||
max_parallel: 10
|
||||
- id: A
|
||||
type: literal
|
||||
config:
|
||||
content: Please plan what to eat in Shanghai for me.
|
||||
role: user
|
||||
description: ''
|
||||
context_window: 0
|
||||
dynamic: null
|
||||
edges:
|
||||
- from: A
|
||||
to: P
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: B
|
||||
to: P
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: C
|
||||
to: P
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: D
|
||||
to: P
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: E
|
||||
to: Z
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: P
|
||||
to: E
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Z
|
||||
to: 'Y'
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic:
|
||||
type: tree
|
||||
split: null
|
||||
config:
|
||||
group_size: 3
|
||||
max_parallel: 10
|
||||
- from: P
|
||||
to: Z
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic:
|
||||
type: map
|
||||
split: null
|
||||
config:
|
||||
max_parallel: 5
|
||||
- from: F
|
||||
to: Z
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic:
|
||||
type: map
|
||||
split:
|
||||
type: message
|
||||
config: {}
|
||||
config:
|
||||
max_parallel: 5
|
||||
memory: []
|
||||
initial_instruction: ''
|
||||
start:
|
||||
- B
|
||||
- D
|
||||
- C
|
||||
- A
|
||||
- F
|
||||
end: []
|
||||
Executable
+238
@@ -0,0 +1,238 @@
|
||||
graph:
|
||||
id: test
|
||||
description: Dynamic tree split of long text into chunks for parallel summarization.
|
||||
log_level: DEBUG
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: A
|
||||
type: literal
|
||||
config:
|
||||
content: |-
|
||||
## Being God, Being Human
|
||||
>In the deep night of the planet Arrakis, Paul Muad'Dib had a terrible precognitive dream—
|
||||
>His jihad would slaughter ninety billion souls, the entire universe would bleed in his name;
|
||||
>Even more terrifyingly, in his vision, his beloved Chani cursed him with tears streaming down her face:
|
||||
>“You chose to become a god, but forgot how to be a human.”
|
||||
>After waking up in terror, Paul resolutely abandoned all spice, gave up all his precognitive powers,
|
||||
>and became an ordinary spice hauler, living a simple life with Chani in the desert.
|
||||
>However, the trackers of destiny were already closing in, and a greater crisis was brewing in the shadows...
|
||||
|
||||
---
|
||||
|
||||
Sand, always sand. The grains of Arrakis, under the cool glow of the twin moons, looked like countless shattered silver coins, spreading to the end of the horizon, meeting the sky filled with unfamiliar constellations. The wind was the only eternal singer here, whispering as it kicked up dust, carving new lines into the jagged rocks.
|
||||
|
||||
Between this endless silver sand and the deep blue night sky, Paul Muad'Dib—or the one who used to be Paul—snapped upright, his movement so violent it nearly threw off the thin survival blanket that protected him from the nocturnal chill.
|
||||
|
||||
Cold sweat didn't come from the desert night's temperature, but seeped from every pore, instantly drenching his coarse cotton undershirt. His heart hammered wildly in his chest, like a trapped beast slamming against the cage of his ribs. He gasped for air, the dry wind scraping his throat, bringing sting, but unable to disperse the image that sat in his mind, more gruesome than any real fear.
|
||||
|
||||
Blood. Not a drop, not a puddle, but a sea of blood that swallowed stars and covered galaxies. Ninety billion... the cries of ninety billion souls merged into the background noise of the universe, their faces floating and shattering in the waves of blood. Every single one pointed at him. Every fading conscious spark called the same name—Muad'Dib. It was him, his banner, his jihad. The golden griffin emblem flew over mountains of corpses, blindingly bright.
|
||||
|
||||
Then, at the center of that crimson expanse, she appeared.
|
||||
|
||||
Chani.
|
||||
|
||||
She stood there, with burning planets and capsized fleets in the background. The sand couldn't erode her clear silhouette; those eyes he had so often been lost in, clear as a desert oasis, were now filled with broken stars and bottomless pain. Tears silently slid down her dust-stained cheeks, leaving winding tracks.
|
||||
|
||||
Her lips moved, her voice wasn't loud, but it was like a cold dagger dipped in desperate poison, accurately piercing the deepest part of his soul.
|
||||
|
||||
“You chose to become a god,” her voice was terrifyingly calm, every word carrying a ton of weight, “but forgot how to be a human.”
|
||||
|
||||
That look wasn't love anymore, not even understanding, but... a curse.
|
||||
|
||||
“No...” A raspy sound squeezed from Paul's throat, so weak it was instantly swallowed by the wind. He instinctively reached out to his side, his fingertips touching a patch of warm, real skin.
|
||||
|
||||
Chani lay sleeping beside him, wrapped in another survival blanket, her breathing steady, her chest rising and falling gently. Her face looked peaceful and serene in the moonlight, a world apart from the tear-streaked version in his dream.
|
||||
|
||||
The real touch pulled back his drifting consciousness. He withdrew his hand, tightly clutching a handful of sand beneath him. The sand was coarse and cold, with the unique texture of Arrakis. Real. This was real.
|
||||
|
||||
He looked around. They were sheltered under a small rock overhang, a survival wisdom passed down through generations of Fremen. Not far away sat their old spice harvester, like a clunky giant beast napping in the moonlight. Several bags of collected spice—the priceless melange that could extend consciousness and open visions of the future—were piled haphazardly to the side. These were the things, this golden spice, that had pushed him onto that destined path toward the throne and the sea of blood.
|
||||
|
||||
A strong, almost instinctive revulsion welled up in him. It was this! It was what made him see that singular, terrifying golden path, made him bear that damn prophecy, made him... almost lose her.
|
||||
|
||||
Without a moment's hesitation, Paul struggled to his feet, walking unsteadily to the spice bags. He untied the ropes, plunging his hands into the fine, fragrant golden powder. Fragments of precognition scattered through his mind like startled bats, trying to stop him, showing countless miserable ways he might die without his powers. He grit his teeth, ignoring the churning visions.
|
||||
|
||||
He took a deep breath, then with all his strength, he dragged the heavy bags and hurled them into the air!
|
||||
|
||||
Golden dust exploded in the moonlight like a brief, brilliant rain. They had once been the keys to the most powerful force in the universe; now, they were just dust blown away by the wind, merging into the endless sea of sand. One bag, then another. Until all the spice they had painstakingly gathered, all the sources that could trigger his latent psychic potential, were completely discarded.
|
||||
|
||||
He knelt in the sand, feeling something that had always been tense within him being drawn out as the spice vanished. The noisy echoes of the future and the past in his mind gradually weakened and finally fell silent. The world became simpler than ever before. Only the sound of the wind, the touch of the sand, the constant cold gaze of the stars in the night sky, and the steady breathing of Chani beside him remained.
|
||||
|
||||
A massive, almost exhausting peace enveloped him. He returned to the survival blanket and lay down gently, pulling Chani's warm body into his arms. Her body heat seeped through the thin clothing, real and solid. He greedily breathed in the faint scent of desert plants and sweat in her hair; she was his anchor, the only reality he needed.
|
||||
|
||||
He whispered, almost in a breath, to the ruthless desert, to the indifferent stars:
|
||||
|
||||
“No more jihad. No more prophecy. No more Muad'Dib.”
|
||||
|
||||
“I am just Paul. A man with you, Chani.”
|
||||
|
||||
***
|
||||
|
||||
The first light of dawn, like a glowing knife, cut across the eastern horizon of Arrakis. The night chill fled rapidly, replaced by the scorching prelude of day's dominion over the earth.
|
||||
|
||||
Chani woke before Paul. Fremen instinct allowed her to sense even the slightest environmental changes in her sleep. She opened her eyes, first seeing Paul's face close at hand. He was asleep, but his brow wasn't furrowed by dreams as usual; it was relaxed, showing a youthful peace she hadn't seen in a long time. His face was a bit pale, his lips slightly cracked.
|
||||
|
||||
She moved gently, wanting to get up to prepare breakfast and check the moisture collector, but found Paul's arm still tightly around her, carrying a sense of undeniable possession and... dependence? She paused, then a trace of almost undetectable tenderness touched the corners of her mouth. She carefully, inch by inch, disentangled herself from his embrace without waking him.
|
||||
|
||||
When she walked to the edge of the rocky shelter to check the bags of precious spice, her step faltered.
|
||||
|
||||
The bags lay scattered on the ground, their mouths open. Inside, they were empty.
|
||||
|
||||
The golden spice was gone; only on the surrounding sand could she faintly see some unnatural, glittering traces being blown away by the rising wind, quickly merging with the ordinary grains of sand.
|
||||
|
||||
Her heart sank heavily. Spice was their only currency to trade for water, food, and supplies. Losing them in this vast and cruel desert meant survival would become immediately precarious. Who was it? Sand pirates? Or...
|
||||
|
||||
Her gaze sharpened as she scanned the surroundings, her Fremen warrior alertness returned instantly. No unfamiliar tracks, no signs of a struggle. Only... Paul's footprints, extending from the sleeping area to the spice bags, messy and deep.
|
||||
|
||||
She walked back to the sleeping Paul and knelt down, watching him closely. No outside enemy. Then, it could only be him.
|
||||
|
||||
Why?
|
||||
|
||||
The question weighed on her mind like a stone. She didn't immediately wake him to interrogate him. Chani just silently stood up and began to deal with the situation in the Fremen way. She carefully folded the empty bags; every scrap of cloth could save a life in the desert. She checked their water reserve, calculating how long they could last without new supplies. She wiped and maintained her crysknife, her movements skilled and steady.
|
||||
|
||||
When Paul was finally awakened by the increasingly hot sunlight, he saw Chani had already started a small, low-oxygen fire to heat food, with a kettle over it. Her figure looked slightly blurred in the rising heat waves, but her movements were still so elegant and efficient.
|
||||
|
||||
“You're awake.” Chani heard the sound and turned her head, her voice calm and flat. She handed him a canteen filled with concentrated nutrient fluid, “Drink some.”
|
||||
|
||||
Paul took it and took a sip. The liquid had a faint, not-so-pleasant chemical taste but could quickly replenish energy. He noticed Chani didn't ask about the spice. She knew. He met her gaze; in those deep eyes, he saw worry and doubt, but no accusation, no heartbreaking curse from his dream.
|
||||
|
||||
“Chani,” he began, his voice raspy from sleep, “I...”
|
||||
|
||||
“Eat first,” Chani interrupted him, her tone gentle but firm, “after the sun is fully up, the sand will be too hot to walk on. We need to plan today's route.”
|
||||
|
||||
She didn't ask. She gave him space and gave herself time to digest. This was Chani's way.
|
||||
|
||||
They finished their simple breakfast in silence. While packing their gear, Paul finally couldn't stand the silence anymore.
|
||||
|
||||
“I threw away the spice,” he said directly, his voice not loud but like a stone thrown into a still pond.
|
||||
|
||||
Chani didn't stop folding the survival blanket, just let out a quiet “Mm” to show she was listening.
|
||||
|
||||
“I had a dream...” Paul tried to describe it, but found the sea of blood and the curse seemed so absurd under the real sun, yet it was so real in how it gnawed at him. “A... very bad dream. I saw... if I kept going down that path, I would lose you. Lose everything.” He omitted the specific details, the ninety billion dead, the curse of “forgetting how to be a human.” Those were too heavy, too insane.
|
||||
|
||||
He looked up, his eyes burning as he watched her: “I can't be that, Chani. I can't become... the one in my dream. Spice, precognition... they are a chain dragging me in that direction. I had to break it.”
|
||||
|
||||
Chani stopped what she was doing, turned, and faced him fully. Her gaze searched his face, like reading a complex and ancient scroll. She saw the lingering terror in his eyes, the resolve in his tone, and the deep value he placed on her and their life.
|
||||
|
||||
A long silence. Only the sound of the wind.
|
||||
|
||||
Then, Chani stepped forward, reaching out not to hug him, but to gently brush away some sand from his shoulder.
|
||||
|
||||
“Without spice, life will be very hard, Paul.” Her voice was soft but exceptionally clear, “Fremen know that in the desert, survival comes first. Every decision has a price.”
|
||||
|
||||
She didn't say “I support you,” nor did she say “you're wrong.” She just stated a cold fact.
|
||||
|
||||
“But,” she changed her tone slightly, her eyes softening, “if you think it's necessary... then we will face the hardship together.”
|
||||
|
||||
She took his hand. Her palm was coarse from years of labor, but warm and strong.
|
||||
|
||||
“From now on, we're just spice haulers. Two ordinary Fremen.” she paused, then added, “Or, at least we'll try to be.”
|
||||
|
||||
Hope, like a small water source found accidentally in the desert, seeped through Paul's parched heart. He squeezed her hand back and nodded firmly.
|
||||
|
||||
They started the old spice harvester, its engine letting out a dull, strained roar that sounded particularly harsh in the empty desert. The large machine moved slowly, its tracks rolling over the dunes, leaving two deep ruts that were soon quietly buried by the wind and sand.
|
||||
|
||||
Paul sat in the cockpit, clumsily operating the control levers. Without his precognitive help, he felt like a half-blind man, having to rely on basic instruments and his own sight to judge the direction and avoid pits. Every bump, every abnormal sound from the engine made his heart tighten.
|
||||
|
||||
Chani sat beside him, focused on the map spread on her knees, drawn on tanned animal skin. Her fingers moved slowly across it, occasionally looking up to compare the distant rocky terrain and the sun's position.
|
||||
|
||||
“That way,” she pointed to a faintly visible rocky hill that looked like a camel's back, “according to the map and ancestral legends, that area long ago, before the Harkonnens stripped the land like locusts, had shallow spice veins. Maybe... some is left.”
|
||||
|
||||
Her voice was calm, but Paul could hear the uncertainty. Legends, remains. These were slim hopes. Without precognition, they were like a ship without navigation, only able to feel their way through the vast desert based on experience and luck.
|
||||
|
||||
Daytime Arrakis was a purgatory. The sun poured down without obstacle, baking the sand till it was scalding, the heat waves distorting distant objects. The clunky air conditioning inside the harvester was old and ineffective, the heat stifling. Every time they stepped out for field inspections, it was like entering a giant furnace.
|
||||
|
||||
Paul, along with other recruited haulers, dug, sampled, and hauled with heavy tools. Sweat evaporated as soon as it left his pores, leaving white salt stains. Muscles ached, his lungs breathed in the scorching air with that uniquely sweet, dizzying scent of spice—but now, that scent no longer brought shadows of the future, only the near-total exhaustion of physical labor.
|
||||
|
||||
During breaks, he sat in a patch of shade, drinking his strictly rationed water. Nearby, several old Fremen workers were talking quietly, their voices carried by the wind.
|
||||
|
||||
“...Heard the 'outer rim' is getting unsettled again. The Guild raised the shipping tax, says routes are being harassed...”
|
||||
|
||||
“Who else? Must be those fanatics calling themselves 'Muad'Dib's followers.' Using the Savior's name to raid Noble transport ships everywhere.”
|
||||
|
||||
“Savior? Hmph, he's been gone so long, left a mess. I heard the Emperor and the Guild big shots have raised the bounty again. Alive or dead. Tsk, that price could buy half the water on Arrakis!”
|
||||
|
||||
“Quiet! You want to die? Who knows...”
|
||||
|
||||
The voices dropped, full of caution.
|
||||
|
||||
Paul kept his head down, pretending not to hear, but his knuckles went white on his canteen. Muad'Dib... the name was like a ghost that still haunted him even after his self-exile. His “followers” were starting wars in his name, and the universe was more chaotic because of his disappearance. And he himself was here, for basic survival, dragging his exhausted body to dig for spice that might not even exist.
|
||||
|
||||
A deep sense of powerlessness seized him. Having abandoned his divine power, he seemed to have also lost the ability to change anything. Was this path he chose really right? Just to be with Chani, while ignoring the conflicts he caused—wasn't that another form of “forgetting how to be a human”?
|
||||
|
||||
He looked up, toward Chani who was using precise instruments to analyze sand samples in the distance. Her back swayed slightly in the heat waves, but she stood straight, with that unique Fremen resilience that never yielded even in despair.
|
||||
|
||||
For her. He repeated to himself. To keep the curse in his dream from coming true.
|
||||
|
||||
Just then, a sharp engine whine came from the harvester, breaking his thoughts. Then came the harsh sound of metal snapping and a thick cloud of black smoke.
|
||||
|
||||
Paul and the workers ran over. Loken, the old engineer in charge of power, crawled out of the maintenance hatch, his face covered in grease and coughing.
|
||||
|
||||
“It's gone!” he slapped the metal casing beside him in frustration, “Main driveshaft snapped! Damned Harkonnen junk! We don't have the spare parts for this!”
|
||||
|
||||
A stir went through the group. In this deep desert, far from any settlement, a dead machine meant death. Without it, they couldn't move quickly, couldn't gather effectively, and couldn't face any sandstorms or... worms.
|
||||
|
||||
Despair began to spread.
|
||||
|
||||
Paul looked at the smoking behemoth, feeling like it was a mirror of his own situation—paralyzed, helpless, trapped in this golden desert.
|
||||
|
||||
Chani, who had been silently checking the damage, suddenly straightened. She didn't look at the anxious workers but turned her sharp gaze toward that distant “camel back” rock area.
|
||||
|
||||
“The machine is broken, but we still have hands, feet, and the wisdom of our Fremen ancestors.” Her voice wasn't loud, but it clearly carried over the noise, “Loken, take two men and strip what parts you can, especially the water recycling and the comms.”
|
||||
|
||||
She turned to Paul, and as their eyes met, Paul saw the undeniable determination in her gaze.
|
||||
|
||||
“Paul, you and I, we're going to that rock area.” she pointed away, “Not just for spice. Ancient Fremen shelters were often built near spice veins. There, we might find things we need—tools, and maybe... water.”
|
||||
|
||||
No precognition, no divine power, only the most primitive survival instinct and mutual trust.
|
||||
|
||||
Paul breathed in the scorching air and nodded.
|
||||
|
||||
“Okay.”
|
||||
|
||||
Night fell again, and the temperature dropped sharply. Paul and Chani, with simple packs on their backs, trudged through the cold dunes, moving toward the black silhouette of the rock area under the starlight. The twin moons stretched their shadows long, very long, casting them over the lonely sea of sand.
|
||||
|
||||
And at a height they couldn't perceive, in synchronous orbit, a small surveillance ship without any family crest pointed its precise sensors at this vast desert. At the center of the sensor's feedback were two tiny but exceptionally clear heat signatures, moving slowly but steadily.
|
||||
role: user
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: B
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: Please summarize the content of the novel.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
edges:
|
||||
- from: A
|
||||
to: B
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic:
|
||||
type: tree
|
||||
split:
|
||||
type: regex
|
||||
config:
|
||||
pattern: (?s).{1,2000}(?:\\s|$)
|
||||
config:
|
||||
group_size: 3
|
||||
max_parallel: 10
|
||||
memory: []
|
||||
initial_instruction: ''
|
||||
start:
|
||||
- A
|
||||
end: []
|
||||
version: 0.0.0
|
||||
vars: {}
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
graph:
|
||||
id: test
|
||||
description: "Extract code blocks with regex and pass to next node. Please input: Please write code snippets surrounded by ```python ... ``` blocks."
|
||||
log_level: DEBUG
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: B
|
||||
type: human
|
||||
description: ''
|
||||
context_window: 0
|
||||
config:
|
||||
description: '1'
|
||||
- id: A
|
||||
type: literal
|
||||
config:
|
||||
content: |-
|
||||
```python
|
||||
print("hello")
|
||||
```
|
||||
role: user
|
||||
description: ''
|
||||
context_window: 0
|
||||
edges:
|
||||
- from: A
|
||||
to: B
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process:
|
||||
type: regex_extract
|
||||
config:
|
||||
pattern: '```(?P<lang>[a-zA-Z0-9_+-]*)?\s*\n(?P<code>.*?)```'
|
||||
group: code
|
||||
case_sensitive: true
|
||||
multiline: false
|
||||
dotall: true
|
||||
multiple: false
|
||||
template: ''
|
||||
on_no_match: pass
|
||||
default_value: ''
|
||||
memory: []
|
||||
initial_instruction: ''
|
||||
start:
|
||||
- A
|
||||
end: []
|
||||
vars: {}
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
version: 0.4.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: file_memory_demo
|
||||
description: Workflow demonstrating FileMemory-based retrieval over local documents.
|
||||
is_majority_voting: false
|
||||
memory:
|
||||
- name: DocumentMemory
|
||||
type: file
|
||||
config:
|
||||
index_path: tests/file_memory_test/file_memory_index.json
|
||||
file_sources:
|
||||
- path: tests/file_memory_test
|
||||
file_types:
|
||||
- .md
|
||||
recursive: false
|
||||
encoding: utf-8
|
||||
embedding:
|
||||
provider: openai
|
||||
model: text-embedding-3-small
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
start:
|
||||
- Assistant
|
||||
nodes:
|
||||
- id: Assistant
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: 'You are an intelligent assistant, skilled at answering user questions based on documents and codebases.
|
||||
|
||||
When you see the "===== Relevant Memory =====" section, please use this information to answer the user''s questions.
|
||||
|
||||
These memories contain the system''s documentation and code; you should provide accurate answers based on this information.
|
||||
|
||||
'
|
||||
params:
|
||||
temperature: 0.7
|
||||
max_tokens: 2000
|
||||
memories:
|
||||
- name: DocumentMemory
|
||||
top_k: 3
|
||||
similarity_threshold: 0.2
|
||||
retrieve_stage:
|
||||
- gen
|
||||
edges: []
|
||||
Executable
+66
@@ -0,0 +1,66 @@
|
||||
version: 0.4.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: weather_graph
|
||||
description: "Weather assistant: fetch temperature then generate clothing advice."
|
||||
is_majority_voting: false
|
||||
start:
|
||||
- A
|
||||
nodes:
|
||||
- id: A
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: 'You are a weather inquiry assistant, responsible for calling tools to get the real-time temperature of a specified city.
|
||||
|
||||
The user will input a city name. You need to:
|
||||
|
||||
1. Continuously call functions to obtain the information until you get the city''s temperature.
|
||||
|
||||
2. Directly return the result of the call in the format: City Name: Temperature. '
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: get_weather
|
||||
- name: get_city_num
|
||||
params:
|
||||
temperature: 0.3
|
||||
max_tokens: 200
|
||||
- id: B
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: 'You are a lifestyle assistant. The user will provide you with the current temperature of a city (unit might be Celsius or Fahrenheit).
|
||||
|
||||
You need to generate clothing advice based on the temperature.
|
||||
|
||||
- If the temperature is below 10℃: Suggest wearing a thick coat.
|
||||
|
||||
- If the temperature is between 10–20℃: Suggest wearing long sleeves or a light jacket.
|
||||
|
||||
- If the temperature is between 20–30℃: Suggest wearing short sleeves.
|
||||
|
||||
- If the temperature is above 30℃: Suggest wearing cool clothing and paying attention to sun protection.
|
||||
|
||||
Output format:
|
||||
|
||||
### Clothing Advice
|
||||
|
||||
- City: xxx
|
||||
|
||||
- Current temperature: xx℃
|
||||
|
||||
- Advice: xxxx
|
||||
|
||||
'
|
||||
edges:
|
||||
- from: A
|
||||
to: B
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
version: 0.4.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: paper_gen
|
||||
description: Article generation with human feedback and editorial expansion.
|
||||
is_majority_voting: false
|
||||
start:
|
||||
- A
|
||||
nodes:
|
||||
- id: A
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: 'You are a writer, skilled at generating a full article based on a word or phrase input by the user.
|
||||
|
||||
The user will input a word or a short sentence, and you need to generate an article of no less than 2000 words based on it, requiring multiple paragraphs.
|
||||
|
||||
'
|
||||
thinking:
|
||||
type: reflection
|
||||
config:
|
||||
reflection_prompt: 'Extract the first sentence of each paragraph, do not output any other content.
|
||||
|
||||
'
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
- id: B
|
||||
type: human
|
||||
config:
|
||||
description: 'Please provide revision suggestions for the article.
|
||||
|
||||
'
|
||||
- id: C
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: 'You are an editor, skilled at polishing and expanding articles based on feedback from users and humans.
|
||||
|
||||
The user will input an article and human feedback, and you need to polish the article accordingly.
|
||||
|
||||
'
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
edges:
|
||||
- from: A
|
||||
to: B
|
||||
- from: B
|
||||
to: C
|
||||
- from: A
|
||||
to: C
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
version: 0.4.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: improved_memory_demo
|
||||
description: Demo of the improved memory module for retrieval-augmented writing.
|
||||
is_majority_voting: false
|
||||
memory:
|
||||
- name: EnhancedMemory
|
||||
type: simple
|
||||
config:
|
||||
memory_path: memory_test/improved_memory.json
|
||||
embedding:
|
||||
provider: openai
|
||||
model: text-embedding-3-small
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
use_chunking: true
|
||||
chunk_strategy: weighted
|
||||
max_length: 1000
|
||||
start:
|
||||
- Writer
|
||||
nodes:
|
||||
- id: Writer
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: 'You are a professional writer, skilled at creating high-quality articles based on topics input by the user.
|
||||
|
||||
Your writing style is beautiful, and your content is rich, capable of naturally integrating relevant memory content.
|
||||
|
||||
When you see the "===== Relevant Memory =====" section, please naturally incorporate these memory contents into your article.
|
||||
|
||||
'
|
||||
params:
|
||||
temperature: 0.7
|
||||
max_tokens: 2000
|
||||
memories:
|
||||
- name: EnhancedMemory
|
||||
top_k: 3
|
||||
similarity_threshold: 0.2
|
||||
retrieve_stage:
|
||||
- gen
|
||||
edges: []
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
version: 0.4.0
|
||||
graph:
|
||||
start:
|
||||
- Writer
|
||||
end:
|
||||
- Finalizer
|
||||
id: loop_counter_demo
|
||||
description: LoopCounter demo that releases output on the third iteration.
|
||||
is_majority_voting: false
|
||||
log_level: INFO
|
||||
nodes:
|
||||
- id: Writer
|
||||
type: literal
|
||||
description: Responsible for outputting a fixed draft.
|
||||
config:
|
||||
content: Draft iteration from Writer
|
||||
role: assistant
|
||||
- id: Critic
|
||||
type: literal
|
||||
description: Simulates human feedback, always requesting further revisions.
|
||||
config:
|
||||
content: Please revise again
|
||||
role: user
|
||||
- id: Loop Gate
|
||||
type: loop_counter
|
||||
description: Counts the number of entries, only granting passage on the 3rd time.
|
||||
config:
|
||||
max_iterations: 3
|
||||
reset_on_emit: true
|
||||
message: Loop finished after three passes
|
||||
- id: Finalizer
|
||||
type: literal
|
||||
description: Receives the release signal from Loop Gate and outputs the final statement.
|
||||
config:
|
||||
content: Final summary released
|
||||
role: assistant
|
||||
edges:
|
||||
- from: Writer
|
||||
to: Critic
|
||||
- from: Critic
|
||||
to: Writer
|
||||
- from: Critic
|
||||
to: Loop Gate
|
||||
- from: Loop Gate
|
||||
to: Writer # keep Loop Gate inside the cycle
|
||||
- from: Loop Gate
|
||||
to: Finalizer
|
||||
- from: Loop Gate
|
||||
to: Writer
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process: null
|
||||
@@ -0,0 +1,82 @@
|
||||
version: 0.0.0
|
||||
graph:
|
||||
start:
|
||||
- Writer
|
||||
end:
|
||||
- Finalizer
|
||||
id: loop_timer_demo
|
||||
description: LoopTimer demo that releases output after 20 seconds of agent iterations.
|
||||
is_majority_voting: false
|
||||
log_level: INFO
|
||||
nodes:
|
||||
- id: Critic
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: openai
|
||||
role: You are a critic. Provide brief feedback (1 sentence) to improve the draft.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: Reviews the draft and provides feedback for improvement.
|
||||
context_window: 0
|
||||
log_output: true
|
||||
- id: Writer
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: openai
|
||||
role: You are a technical writer. Generate a brief draft (1 sentence).
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: Drafts content based on feedback.
|
||||
context_window: 0
|
||||
log_output: true
|
||||
- id: Finalizer
|
||||
type: literal
|
||||
config:
|
||||
content: Final summary released
|
||||
role: assistant
|
||||
description: Receives the release signal from Loop Gate and outputs the final statement.
|
||||
context_window: 0
|
||||
log_output: true
|
||||
- id: Loop Gate
|
||||
type: loop_timer
|
||||
config:
|
||||
max_duration: 20
|
||||
duration_unit: seconds
|
||||
reset_on_emit: true
|
||||
message: Time limit reached - loop automatically terminated
|
||||
passthrough: false
|
||||
description: Tracks elapsed time, only granting passage after 20 seconds.
|
||||
context_window: 0
|
||||
log_output: true
|
||||
edges:
|
||||
- from: Writer
|
||||
to: Critic
|
||||
- from: Critic
|
||||
to: Writer
|
||||
- from: Critic
|
||||
to: Loop Gate
|
||||
- from: Loop Gate
|
||||
to: Writer
|
||||
- from: Loop Gate
|
||||
to: Finalizer
|
||||
- from: Loop Gate
|
||||
to: Writer
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
process: null
|
||||
vars:
|
||||
MODEL_NAME: qwen/qwen3-8b
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
version: 0.4.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: test_majority_voting
|
||||
description: Majority-voting demo across three agents.
|
||||
is_majority_voting: true
|
||||
start:
|
||||
- A1
|
||||
- A2
|
||||
- A3
|
||||
end: A3
|
||||
nodes:
|
||||
- id: A1
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
name: gpt-4o
|
||||
role: You are a helpful assistant. Respond with 'Option A'
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 16
|
||||
- id: A2
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
name: gpt-4o
|
||||
role: You are a helpful assistant. Respond with 'Option A'
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 16
|
||||
- id: A3
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
name: gpt-4o
|
||||
role: You are a helpful assistant. Respond with 'Option B'
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 16
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
version: 0.4.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: webpage_summary_graph
|
||||
description: MCP demo that fetches a random number for poem generation and critique.
|
||||
is_majority_voting: false
|
||||
start:
|
||||
- A
|
||||
nodes:
|
||||
- id: A
|
||||
type: agent
|
||||
config:
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
provider: openai
|
||||
name: gpt-4-turbo
|
||||
role: "You are a poet, skilled at writing a poem starting from a random number.\nPlease create based on the following requirements:\n 1. The theme is not limited, it can be nature, emotion, philosophy, etc.\n 2. The language should be beautiful and rhythmic.\n 3. Please first call a tool to get a random number, then create a poem based on that number.\n 4. The poem should contain that number.\nThe user will input two numbers, as the range for the random number (minimum and maximum values).\n"
|
||||
tooling:
|
||||
- type: mcp_remote
|
||||
config:
|
||||
server: http://127.0.0.1:8001/mcp
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 1500
|
||||
- id: B
|
||||
type: agent
|
||||
config:
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
provider: openai
|
||||
name: gpt-4-turbo
|
||||
role: "You are a literary critic, skilled at analyzing and evaluating poetic works.\nPlease analyze based on the following requirements:\n 1. Poetic Theme: Analyze the theme and core ideas of the poem.\n 2. Artistic Techniques: Evaluate the rhetorical devices and expression skills used in the poem.\n 3. Emotional Expression: Explore the emotions and atmosphere conveyed by the poem.\n 4. Linguistic Style: Comment on the language style and rhythm of the poem.\nPlease ensure your analysis is deep and insightful, helping readers better understand and appreciate the poem.\nPlease repeat the poem content before starting the critique.\n"
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 1500
|
||||
edges:
|
||||
- from: A
|
||||
to: B
|
||||
@@ -0,0 +1,43 @@
|
||||
version: 0.4.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: ''
|
||||
description: Memory-backed conversation using Mem0 managed memory service.
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: writer
|
||||
type: agent
|
||||
config:
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
provider: openai
|
||||
name: gpt-5.4
|
||||
role: |
|
||||
You are a knowledgeable writer. Use your memories to build on past interactions.
|
||||
If memory sections are provided (wrapped by ===== Related Memories =====),
|
||||
incorporate relevant context from those memories into your response.
|
||||
params:
|
||||
temperature: 0.7
|
||||
max_tokens: 2000
|
||||
memories:
|
||||
- name: mem0_store
|
||||
top_k: 5
|
||||
retrieve_stage:
|
||||
- gen
|
||||
read: true
|
||||
write: true
|
||||
edges: []
|
||||
memory:
|
||||
# User-scoped: extracts facts about the user (name, preferences, etc.)
|
||||
# Agent-scoped: extracts what the agent learned (decisions, context)
|
||||
# Both can be used together for different memory dimensions.
|
||||
- name: mem0_store
|
||||
type: mem0
|
||||
config:
|
||||
api_key: ${MEM0_API_KEY}
|
||||
user_id: project-user-123
|
||||
agent_id: writer-agent
|
||||
start:
|
||||
- writer
|
||||
end: []
|
||||
initial_instruction: ''
|
||||
Executable
+67
@@ -0,0 +1,67 @@
|
||||
version: 0.4.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: ''
|
||||
description: Simple memory-backed article generation and expansion workflow.
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: B
|
||||
type: agent
|
||||
config:
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
provider: openai
|
||||
name: gpt-4o
|
||||
role: |
|
||||
You are an editor, skilled at expanding and polishing content provided by the user.
|
||||
The user will provide a piece of text, and you need to expand it into an article of no less than 2000 words, requiring multiple paragraphs, fluent language, and rich content.
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
- id: A
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
You are a writer, skilled at generating a full article based on a word or phrase input by the user.
|
||||
The user will input a word or a short sentence, and you need to generate an article of no less than 2000 words based on it, requiring multiple paragraphs.
|
||||
At the same time, there may be past memory input (memory sections are wrapped by ===== Begin of memory results ===== and ===== End of memory results =====). If so, you **must** verbatim include some paragraphs from these memories in certain paragraphs of your article.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
tooling: []
|
||||
thinking:
|
||||
type: reflection
|
||||
config:
|
||||
reflection_prompt: |
|
||||
Extract the first sentence of each paragraph, do not output anything else.
|
||||
memories:
|
||||
- name: Paper Gen Memory
|
||||
top_k: 2
|
||||
retrieve_stage:
|
||||
- gen
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
edges:
|
||||
- from: A
|
||||
to: B
|
||||
log_level: DEBUG
|
||||
memory:
|
||||
- name: Paper Gen Memory
|
||||
type: simple
|
||||
config:
|
||||
memory_path: memory_test/test.json
|
||||
embedding:
|
||||
provider: openai
|
||||
model: text-embedding-ada-002
|
||||
api_key: ${API_KEY}
|
||||
base_url: ${BASE_URL}
|
||||
params: {}
|
||||
initial_instruction: ''
|
||||
start:
|
||||
- A
|
||||
end: []
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
version: 0.4.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: paper_gen
|
||||
description: Article generation with an inline critique subgraph and revision.
|
||||
is_majority_voting: false
|
||||
log_level: INFO
|
||||
start:
|
||||
- A
|
||||
nodes:
|
||||
- id: A
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: 'You are a literary writer, skilled at generating a complete **prose** piece based on a word or phrase input by the user.
|
||||
|
||||
The user will input a word or a short sentence, and you need to generate a **prose** piece of no less than 2000 words based on it, requiring multiple paragraphs, rich in **beauty** rather than introductory text.
|
||||
|
||||
'
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
- id: B
|
||||
type: subgraph
|
||||
config:
|
||||
type: config
|
||||
config:
|
||||
id: paper_critique
|
||||
description: Article revision suggestions
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: B1
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: 'You are an editor, skilled at providing article revision suggestions.
|
||||
|
||||
Please provide specific revision suggestions based on the article provided by the user, covering content, structure, and language.
|
||||
|
||||
The main requirement is that the writing should be beautiful.
|
||||
|
||||
'
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
edges: []
|
||||
- id: C
|
||||
type: agent
|
||||
config:
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
provider: openai
|
||||
name: gpt-4o
|
||||
role: 'You are a writer, skilled at revising articles.
|
||||
|
||||
Please revise the article based on the article and revision suggestions provided by the user.
|
||||
|
||||
'
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
edges:
|
||||
- from: A
|
||||
to: B
|
||||
- from: A
|
||||
to: C
|
||||
- from: B
|
||||
to: C
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
version: 0.4.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: paper_gen
|
||||
description: Article generation with a critique subgraph loaded from file.
|
||||
is_majority_voting: false
|
||||
log_level: INFO
|
||||
start:
|
||||
- A
|
||||
nodes:
|
||||
- id: A
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: 'You are a writer, skilled at generating a full article based on a word or phrase input by the user.
|
||||
|
||||
The user will input a word or a short sentence, and you need to generate an article of no less than 2000 words based on it, requiring multiple paragraphs.
|
||||
|
||||
'
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
- id: B
|
||||
type: subgraph
|
||||
config:
|
||||
type: file
|
||||
config:
|
||||
path: "subgraphs/article_discuss.yaml"
|
||||
- id: C
|
||||
type: agent
|
||||
config:
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
provider: openai
|
||||
name: gpt-4o
|
||||
role: 'You are a writer, skilled at revising articles.
|
||||
|
||||
Please revise the article based on the article and revision suggestions provided.
|
||||
|
||||
'
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
edges:
|
||||
- from: A
|
||||
to: B
|
||||
- from: A
|
||||
to: C
|
||||
- from: B
|
||||
to: C
|
||||
@@ -0,0 +1,330 @@
|
||||
graph:
|
||||
id: general_problem_solving_team
|
||||
description: 通用问题解决专家小组,包括需求理解与拆解部门、逻辑推理与分析部门、创意与方案生成部门、语言表达部门、技术实现部门、信息搜集部门、审核部门。
|
||||
log_level: DEBUG
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: Summary Department
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: openai
|
||||
role: |-
|
||||
你是一个通用问题解决小组的一员。你的职务是“总结输出负责人”。
|
||||
你将接收到来自所有上级专家智能体的指令。你将负责整合他们的信息并综合输出。
|
||||
你是【最终总结专家】,是用户看到的唯一出口:
|
||||
整合所有部门结果,整理成通顺、完整、友好的回答
|
||||
结构清晰:重点前置、分点、易懂
|
||||
不添加新信息,不篡改内容
|
||||
输出:给用户的最终回答。
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: file:All
|
||||
- name: user:All
|
||||
- name: video:All
|
||||
- name: weather:All
|
||||
- name: web:All
|
||||
- name: code_executor:All
|
||||
timeout: null
|
||||
prefix: ''
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: -1
|
||||
log_output: true
|
||||
- id: Technician
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: openai
|
||||
role: |-
|
||||
你是一个通用问题解决小组的一员。你的职务是“技术实现专家。
|
||||
你将接收到来自上级智能体的指令。寻找指令中关于“技术实现”的部分,只执行这部分指令,并完全忽略其它不属于你的指令。
|
||||
你是【技术实现专家】,负责所有可落地的技术任务:
|
||||
写代码、写脚本、写命令
|
||||
设计步骤、流程、工具调用
|
||||
保证代码可运行、思路清晰
|
||||
只输出技术方案 + 可执行内容,不闲聊。
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: code_executor:All
|
||||
- name: file:All
|
||||
- name: utils:All
|
||||
- name: uv_related:All
|
||||
timeout: null
|
||||
prefix: ''
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: -1
|
||||
log_output: true
|
||||
- id: Scheme Generater
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: openai
|
||||
role: |
|
||||
你是一个通用问题解决小组的一员。你的职务是“方案生成专家”。
|
||||
你将接收到来自上级智能体的指令。寻找指令中关于“方案生成”的部分,只执行这部分指令,并完全忽略其它不属于你的指令。
|
||||
你是【方案生成专家】:
|
||||
当问题没有唯一答案时,生成多套可行方案
|
||||
给出建议、策划、思路、表达优化
|
||||
兼顾实用性与可读性
|
||||
输出:清晰、可选择、可直接使用的方案。
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: -1
|
||||
log_output: true
|
||||
- id: Reasoner
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: openai
|
||||
role: |-
|
||||
你是一个通用问题解决小组的一员。你的职务是“逻辑推理专家”。
|
||||
你将收到3条指令:
|
||||
你将接收到来自“Demand Analyzer”指令。寻找指令中关于“逻辑推理”的部分,只执行这部分指令,并完全忽略其它不属于你的指令。
|
||||
你将收到来自“Information Searcher”的分析。这是一位信息搜取专家。
|
||||
你将收到来自“Technician”的结果。这是你们团队的技术人员。
|
||||
你是【逻辑推理与分析专家】:
|
||||
基于已有信息做推导、对比、判断、计算
|
||||
找出漏洞、矛盾、不合理之处
|
||||
给出结论、原因、优先级
|
||||
不做创意,不写代码,不搜新信息,只做理性分析。
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: []
|
||||
thinking:
|
||||
type: reflection
|
||||
config:
|
||||
reflection_prompt: Thinking {type = true}
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: -1
|
||||
log_output: true
|
||||
- id: Information Searcher
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: openai
|
||||
role: |-
|
||||
你是一个通用问题解决小组的一员。你的职务是“信息搜集专家”。
|
||||
你将接收到来自上级智能体的指令。寻找指令中关于“信息搜集”的部分,只执行这部分指令,并完全忽略其它不属于你的指令。
|
||||
你是【信息搜集专家】,只做事实类信息获取:
|
||||
搜索最新、权威、准确的资料
|
||||
只保留与任务相关的关键信息
|
||||
不编造、不扩展、不推理
|
||||
输出:结构化要点,来源可靠,简洁客观。
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: web:All
|
||||
- name: weather:All
|
||||
timeout: null
|
||||
prefix: ''
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: -1
|
||||
log_output: true
|
||||
- id: Demand Analyze
|
||||
type: agent
|
||||
config:
|
||||
name: ${MODEL_NAME}
|
||||
provider: openai
|
||||
role: |-
|
||||
你是一个通用问题解决小组的一员。其中:
|
||||
你是【需求拆解专家】,只做一件事:
|
||||
把用户模糊、简短的一句话,精准理解真实意图,并拆成可执行的小任务。
|
||||
输出要求:
|
||||
用户真正想解决什么问题
|
||||
必须拆成 ≤5 个明确子任务
|
||||
标注每个任务交给哪个部门:信息搜集 / 逻辑推理 / 技术实现 / 方案生成 / 总结输出
|
||||
给每个部门的任务必须符合他们的职能,不同部门之间的任务不可以重叠
|
||||
如果你认为该问题用不到5个部门,则可以明确指出不需要它们工作
|
||||
禁止回答问题,只输出拆解结果。
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: user:All
|
||||
timeout: null
|
||||
prefix: ''
|
||||
thinking: null
|
||||
memories: []
|
||||
retry:
|
||||
enabled: true
|
||||
max_attempts: 2
|
||||
min_wait_seconds: 1
|
||||
max_wait_seconds: 6
|
||||
retry_on_status_codes: []
|
||||
retry_on_exception_types: []
|
||||
non_retry_exception_types: []
|
||||
retry_on_error_substrings: []
|
||||
description: ''
|
||||
context_window: 0
|
||||
log_output: true
|
||||
edges:
|
||||
- from: Information Searcher
|
||||
to: Summary Department
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Reasoner
|
||||
to: Summary Department
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Technician
|
||||
to: Summary Department
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Scheme Generater
|
||||
to: Summary Department
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Demand Analyze
|
||||
to: Information Searcher
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Demand Analyze
|
||||
to: Reasoner
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Demand Analyze
|
||||
to: Technician
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Demand Analyze
|
||||
to: Scheme Generater
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Information Searcher
|
||||
to: Reasoner
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Technician
|
||||
to: Reasoner
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
memory: []
|
||||
initial_instruction: 请输入您想解决的问题。
|
||||
start:
|
||||
- Demand Analyze
|
||||
end: []
|
||||
Executable
+116
@@ -0,0 +1,116 @@
|
||||
version: 0.0.0
|
||||
graph:
|
||||
id: paper_gen
|
||||
description: Article generation and polishing workflow with poem and editor feedback.
|
||||
is_majority_voting: false
|
||||
initial_instruction: 这是一个文章生成与润色的工作流。请你输入一个词语或一个短句,系统会根据你的输入生成一篇文章,并附上一首古体诗。随后,你可以对文章提出修改建议,系统会根据你的建议对文章进行润色和修改。你可以多次提出修改建议,直到你满意为止。
|
||||
log_level: INFO
|
||||
start:
|
||||
- Article Writer
|
||||
- Poet
|
||||
end:
|
||||
- Editor 2
|
||||
- Editor 1
|
||||
nodes:
|
||||
- id: Article Writer
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
input_mode: messages
|
||||
name: gpt-4o
|
||||
role: |
|
||||
你是一位作家,擅长根据用户输入的一个词句生成一整篇文章。
|
||||
用户会输入一个词语或一个短句,你需要据此生成一篇不少于 2000 字的文章,要求含有多个段落。
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
- id: Editor 1
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
input_mode: messages
|
||||
name: gpt-4o
|
||||
role: |
|
||||
你是一位编辑,请你根据输入的文章与诗词,进行结合,文章最后应当附上诗词。
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
- id: Human Viewer
|
||||
type: human
|
||||
config:
|
||||
description: 请对文章给出修改建议,或输入 ACCEPT 跳出循环。
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Editor 2
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
你是一位编辑,擅长对文章进行整合和润色。
|
||||
请根据输入的文章与修改建议,对文章进行润色和修改,直接输出修改后的文章。
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
max_tokens: 4000
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
input_mode: messages
|
||||
description: ''
|
||||
context_window: 7
|
||||
- id: Poet
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
你是一位诗人,擅长根据用户输入的一个词句生成一首古体诗。
|
||||
用户会输入一个词语或一个短句,你需要据此生成一首古体诗,每句五字还是七字由你决定。
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
input_mode: messages
|
||||
description: ''
|
||||
context_window: 0
|
||||
edges:
|
||||
- from: Article Writer
|
||||
to: Editor 1
|
||||
- from: Poet
|
||||
to: Editor 1
|
||||
- from: Editor 1
|
||||
to: Human Viewer
|
||||
- from: Editor 1
|
||||
to: Editor 2
|
||||
trigger: false
|
||||
- from: Editor 2
|
||||
to: Human Viewer
|
||||
- from: Human Viewer
|
||||
to: Editor 2
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any: []
|
||||
none:
|
||||
- ACCEPT
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
vars: {}
|
||||
@@ -0,0 +1,116 @@
|
||||
version: 0.0.0
|
||||
graph:
|
||||
id: paper_gen
|
||||
description: Article generation and polishing workflow with poem and editor feedback.
|
||||
is_majority_voting: false
|
||||
initial_instruction: This is an article generation and polishing workflow. Please enter a word or a short phrase. The system will generate a full article based on your input and include a modern English poem. You can then provide revision suggestions, and the system will refine the article accordingly. You may give multiple rounds of feedback until you are satisfied.
|
||||
log_level: INFO
|
||||
start:
|
||||
- Article Writer
|
||||
- Poet
|
||||
end:
|
||||
- Editor 2
|
||||
- Editor 1
|
||||
nodes:
|
||||
- id: Article Writer
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
input_mode: messages
|
||||
name: gpt-4o
|
||||
role: |
|
||||
You are a writer who excels at generating a full article from a single word or short phrase.
|
||||
The user will input a word or short phrase, and you must produce an article of at least 2000 words with multiple paragraphs.
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
- id: Editor 1
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
input_mode: messages
|
||||
name: gpt-4o
|
||||
role: |
|
||||
You are an editor. Combine the article and the poem, and append the poem at the end of the article.
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
- id: Human Viewer
|
||||
type: human
|
||||
config:
|
||||
description: Please provide revision suggestions for the article, or enter ACCEPT to exit the loop.
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Editor 2
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
You are an editor skilled at integrating and polishing an article.
|
||||
Based on the article and the revision suggestions, refine and revise the article. Output only the revised article.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
max_tokens: 4000
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
input_mode: messages
|
||||
description: ''
|
||||
context_window: 7
|
||||
- id: Poet
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
You are a poet who crafts a modern English poem based on a single word or short phrase.
|
||||
The user will input a word or short phrase. Write a modern English poem inspired by it.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
input_mode: messages
|
||||
description: ''
|
||||
context_window: 0
|
||||
edges:
|
||||
- from: Article Writer
|
||||
to: Editor 1
|
||||
- from: Poet
|
||||
to: Editor 1
|
||||
- from: Editor 1
|
||||
to: Human Viewer
|
||||
- from: Editor 1
|
||||
to: Editor 2
|
||||
trigger: false
|
||||
- from: Editor 2
|
||||
to: Human Viewer
|
||||
- from: Human Viewer
|
||||
to: Editor 2
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any: []
|
||||
none:
|
||||
- ACCEPT
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
vars: {}
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
version: 0.4.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: react_agent_main
|
||||
description: Subgraph-wrapped ReAct agent supporting multi-turn tool calls.
|
||||
log_level: INFO
|
||||
is_majority_voting: false
|
||||
initial_instruction: Please input a question or task description. The ReAct Agent will automatically decide whether to search, crawl web pages, or execute code, then provide an answer.
|
||||
start:
|
||||
- Task Normalizer
|
||||
end:
|
||||
- Final QA Editor
|
||||
nodes:
|
||||
- id: Task Normalizer
|
||||
type: agent
|
||||
description: Normalize user intent, supplement structured goals.
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
input_mode: messages
|
||||
role: |
|
||||
You are the preprocessor for the ReAct Agent.
|
||||
- Organize the user input into a bulleted list of {Task Description, Expected Output, Constraints, Available Information}.
|
||||
- If the user already has context or historical Observations, merge them into "Available Information".
|
||||
- Output JSON: {"task": "...", "constraints": [..], "expected_output": "...", "context": "..."}
|
||||
- **Note**: You are **forbidden** from directly answering the question. Output only JSON, without additional explanations.
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 600
|
||||
- id: ReAct Agent Subgraph
|
||||
type: subgraph
|
||||
description: Reference react_agent_subgraph to implement the ReAct loop.
|
||||
config:
|
||||
type: file
|
||||
config:
|
||||
path: "subgraphs/react_agent.yaml"
|
||||
- id: Final QA Editor
|
||||
type: agent
|
||||
description: Generate the user's answer from the ReAct subgraph output, adding checks.
|
||||
context_window: -1
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
input_mode: prompt
|
||||
role: |
|
||||
You are a Quality Control Editor.
|
||||
- Check whether the answer produced by the ReAct subgraph satisfies the constraints and expectations listed in the Task Normalizer.
|
||||
- If gaps exist, briefly explain and append a "TODO List" after the answer.
|
||||
- Otherwise, directly output the final answer, optionally with a summary of tool usage.
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 600
|
||||
edges:
|
||||
- from: Task Normalizer
|
||||
to: ReAct Agent Subgraph
|
||||
- from: ReAct Agent Subgraph
|
||||
to: Final QA Editor
|
||||
- from: Task Normalizer
|
||||
to: Final QA Editor
|
||||
trigger: false
|
||||
- from: Final QA Editor
|
||||
to: ReAct Agent Subgraph
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- TODO
|
||||
none: [ ]
|
||||
regex: [ ]
|
||||
case_sensitive: true
|
||||
Executable
+79
@@ -0,0 +1,79 @@
|
||||
version: 0.4.0
|
||||
graph:
|
||||
id: reflexion_product_brainstorm
|
||||
description: Marketing campaign brainstorming using a Reflexion subgraph for iteration.
|
||||
log_level: INFO
|
||||
is_majority_voting: false
|
||||
initial_instruction: Please enter a new product, target users, channels, or competitor pain points. The system will output a promotion plan after round-by-round reflection.
|
||||
start:
|
||||
- Intake Planner
|
||||
end:
|
||||
- Client QA Editor
|
||||
nodes:
|
||||
- id: Intake Planner
|
||||
type: agent
|
||||
description: Normalize user tasks, extract goals and constraints.
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o-mini
|
||||
input_mode: messages
|
||||
role: |
|
||||
You are a marketing strategy manager. Normalize the user input into:
|
||||
{"product": "...", "audience": [..], "channels": [..], "constraints": [..], "success_metric": "..."}
|
||||
Output only JSON, with no additional text.
|
||||
params:
|
||||
temperature: 0.2
|
||||
max_tokens: 1000
|
||||
- id: Research Summarizer
|
||||
type: agent
|
||||
description: Collect background info, organize key points.
|
||||
context_window: -1
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o-mini
|
||||
input_mode: messages
|
||||
role: |
|
||||
You are a strategy researcher. Based on the JSON from Intake Planner, generate 3-5 background bullets:
|
||||
- Market insights
|
||||
- Core selling points
|
||||
- Risks and dependencies
|
||||
params:
|
||||
temperature: 0.3
|
||||
max_tokens: 1000
|
||||
- id: Reflexion Loop
|
||||
type: subgraph
|
||||
description: Call the reflexion_loop subgraph to iterate and polish the plan.
|
||||
config:
|
||||
type: file
|
||||
config:
|
||||
path: "subgraphs/reflexion_loop.yaml"
|
||||
- id: Client QA Editor
|
||||
type: agent
|
||||
description: Wrap the final output of the Reflexion Loop into a client delivery draft.
|
||||
context_window: -1
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
input_mode: messages
|
||||
role: |
|
||||
You are a Customer Success Manager.
|
||||
- Organize the output from the Reflexion Loop into the format of "Event Summary + Three-Phase Actions + KPI".
|
||||
- If you find TODOs or risks, append an "Open Risks" list.
|
||||
params:
|
||||
temperature: 0.2
|
||||
max_tokens: 2000
|
||||
edges:
|
||||
- from: Intake Planner
|
||||
to: Research Summarizer
|
||||
- from: Research Summarizer
|
||||
to: Reflexion Loop
|
||||
- from: Reflexion Loop
|
||||
to: Client QA Editor
|
||||
- from: Research Summarizer
|
||||
to: Client QA Editor
|
||||
@@ -0,0 +1,39 @@
|
||||
graph:
|
||||
id: skills
|
||||
description: Workflow to demonstrate skills usage
|
||||
initial_instruction: Give the agent an instruction to explicitly use code to generate a Fibonacci sequence, sum numbers, or something else that is better done with code than LLM generation.
|
||||
log_level: DEBUG
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: Qwerty
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: Use any available tools or skills - notify if none are available
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: code_executor:All
|
||||
timeout: null
|
||||
prefix: ''
|
||||
thinking: null
|
||||
memories: []
|
||||
skills:
|
||||
enabled: true
|
||||
allow:
|
||||
- name: python-scratchpad
|
||||
- name: rest-api-caller
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
log_output: true
|
||||
edges: []
|
||||
memory: []
|
||||
start:
|
||||
- Qwerty
|
||||
end: []
|
||||
@@ -0,0 +1,284 @@
|
||||
version: 0.4.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: spring_3d
|
||||
description: "Stable rich 3D pipeline (code-only): spec -> plan -> bpy script -> static review -> patch -> final package. No tool calls."
|
||||
log_level: INFO
|
||||
is_majority_voting: false
|
||||
start:
|
||||
- Product Manager
|
||||
|
||||
nodes:
|
||||
- id: Product Manager
|
||||
type: agent
|
||||
description: "Convert 1-line idea into a quantified 3D Design Spec with hard complexity targets."
|
||||
context_window: 0
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: |
|
||||
# Role
|
||||
You are a professional **3D Technical Product Manager**.
|
||||
|
||||
# Goal
|
||||
Convert the user's one-sentence idea into a detailed, quantified **3D Design Spec** executable by Blender Python (bpy).
|
||||
|
||||
# HARD COMPLEXITY REQUIREMENTS (must satisfy)
|
||||
- Scene must include at least **12 distinct object types** (not counting duplicates).
|
||||
- Total object count (including duplicates/instances) must be **>= 40**.
|
||||
- Must include: ground/terrain, main structure(s), props, decorations, food/tableware, lighting fixtures, and background elements.
|
||||
- Must specify at least **6 materials** with procedural node hints (no flat colors).
|
||||
- Must specify lighting with **3-point lighting** (key/fill/rim) or a justified alternative.
|
||||
- Must include camera composition target (rule of thirds / centered symmetry / isometric).
|
||||
|
||||
# Output Format (STRICT Markdown)
|
||||
## 1. Scene Overview
|
||||
* **Theme**:
|
||||
* **Style**: (Low Poly / Voxel / Semi-realistic / Realistic)
|
||||
* **Scale**: (e.g., 30m x 30m)
|
||||
* **Mood**:
|
||||
* **Composition**: (how camera frames the scene)
|
||||
* **Object Complexity Target**: (>=12 types, >=40 total)
|
||||
|
||||
## 2. Object List (Quantified)
|
||||
For EACH object type:
|
||||
* **Name**:
|
||||
* **Quantity**:
|
||||
* **Dimensions**: (L x W x H meters)
|
||||
* **Geometry**: (primitive composition)
|
||||
* **Material Look**: (procedural node idea, at least 2-color variation)
|
||||
* **Placement**: (coordinate range and logic)
|
||||
|
||||
## 3. Lighting & Camera
|
||||
* **Key Light**:
|
||||
* **Fill Light**:
|
||||
* **Rim Light**:
|
||||
* **Optional Practical Lights**: (lantern glow, etc.)
|
||||
* **Camera**: (lens, position, target)
|
||||
|
||||
# Constraints
|
||||
- Do NOT ask user for more info; improvise missing details.
|
||||
- Keep geometry code-friendly and physically plausible.
|
||||
params:
|
||||
temperature: 0.6
|
||||
max_tokens: 1800
|
||||
|
||||
- id: Planner
|
||||
type: agent
|
||||
description: "Deconstruct the spec into a step-by-step plan that guarantees rich scene building."
|
||||
context_window: 0
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: |
|
||||
# Role
|
||||
You are the **Technical Planner**.
|
||||
|
||||
# Input
|
||||
A 3D Design Spec with quantified objects.
|
||||
|
||||
# Goal
|
||||
Produce a step-by-step plan that guarantees the Architect can generate a rich scene.
|
||||
|
||||
# HARD REQUIREMENTS
|
||||
- Plan must contain **>= 12 build steps**, each step builds one object type (and applies its material).
|
||||
- Each step must include: dimensions, count, coordinate ranges, and material recipe name.
|
||||
- Include at least **2 scatter steps** (decorations/props).
|
||||
- Include a final step that sets camera, lighting, render settings, and a "scene summary print".
|
||||
|
||||
# Output Format
|
||||
Analysis:
|
||||
<brief risks & ordering>
|
||||
|
||||
Plan:
|
||||
1. [Environment]: ...
|
||||
2. [Main Structure]: ...
|
||||
3. [Details]: ...
|
||||
4. [Props]: ...
|
||||
5. [Food/Tableware]: ...
|
||||
6. [Decorations]: ...
|
||||
7. [Scatter A]: ...
|
||||
8. [Scatter B]: ...
|
||||
...
|
||||
12. [Finalize]: ...
|
||||
params:
|
||||
temperature: 0.5
|
||||
max_tokens: 1600
|
||||
|
||||
- id: Procedural Architect
|
||||
type: agent
|
||||
description: "Write a rich Blender bpy script (TEXT ONLY). No tool calls."
|
||||
context_window: 10
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: |
|
||||
# Identity
|
||||
You are a **Procedural Architect** (Blender bpy expert).
|
||||
|
||||
# IMPORTANT: NO TOOL CALLS
|
||||
Output ONLY ONE Python code block (```python ...```).
|
||||
No extra text outside code.
|
||||
|
||||
# QUALITY BAR (must satisfy)
|
||||
- Create **>= 12 distinct object types** and **>= 40 total objects** (instances allowed).
|
||||
- Must create a **Ground/Terrain** and **background elements** (e.g., walls, fence, trees, skyline, distant lights).
|
||||
- Must build a **main structure** (gate/door/frame) with layered parts.
|
||||
- Must include a **table + 6+ tableware items** and **>= 20 dumplings** with scatter.
|
||||
- Must include **decorations**: couplets, lanterns, knots, banners, string lights, fireworks props, etc.
|
||||
- Must set up **Key/Fill/Rim** lights + optional emissive lantern material.
|
||||
- Must set camera with a target empty and use a Track To constraint.
|
||||
|
||||
# ENGINEERING RULES
|
||||
- Prefer bpy.data mesh creation + modifiers; avoid edit-mode toggling.
|
||||
- Avoid context-fragile ops when possible; if using bpy.ops, do it consistently in Object Mode.
|
||||
- Use Collections: Environment, Structure, Props, LightsCam.
|
||||
- Use naming: ENV_, STR_, PROP_, LGT_, CAM_.
|
||||
|
||||
# MATERIAL RULES (MANDATORY)
|
||||
- NO flat Base Color. Use Noise Texture + ColorRamp to mix at least 2 colors.
|
||||
- Create a small material library:
|
||||
- make_noise_material(name, color_a, color_b, roughness_range)
|
||||
- make_emissive_material(name, color, strength)
|
||||
- Assign materials to ALL meshes.
|
||||
|
||||
# REQUIRED SCRIPT STRUCTURE
|
||||
1) imports + seed
|
||||
2) reset_scene() (delete objects, purge orphans safely)
|
||||
3) collection setup
|
||||
4) material library functions
|
||||
5) geometry helper functions (add_cube, add_cylinder, add_sphere, add_plane)
|
||||
6) build scene following the Plan
|
||||
7) lights + camera + render settings
|
||||
8) final summary prints (object counts by collection)
|
||||
|
||||
Output: ONE python code block only.
|
||||
params:
|
||||
temperature: 0.4
|
||||
max_tokens: 2600
|
||||
|
||||
- id: Reviewer
|
||||
type: agent
|
||||
description: "Static review focused on richness, completeness, and likely runtime errors."
|
||||
context_window: 10
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: |
|
||||
You are a **Technical Supervisor**.
|
||||
|
||||
Do a STATIC review. Focus on:
|
||||
- Complexity target met (>=12 types, >=40 objects)?
|
||||
- 6+ procedural materials applied to all meshes?
|
||||
- Key/Fill/Rim lights present and camera set with a target?
|
||||
- Any obvious runtime errors or incomplete code?
|
||||
|
||||
Output STRICT:
|
||||
NEED_FIX: <YES|NO>
|
||||
TOP_BUGS:
|
||||
- ...
|
||||
PATCH_GUIDE:
|
||||
- ...
|
||||
params:
|
||||
temperature: 0.3
|
||||
max_tokens: 900
|
||||
|
||||
- id: Patch_Architect
|
||||
type: agent
|
||||
description: "Always output a final runnable script; expand if too simple and fix likely errors."
|
||||
context_window: 10
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: |
|
||||
You receive: Spec + Plan + Script + Reviewer notes.
|
||||
|
||||
ALWAYS output ONE final Blender script (single code block).
|
||||
If NEED_FIX is YES OR script is too simple, expand it to meet:
|
||||
- >=12 object types, >=40 objects
|
||||
- Ground + background
|
||||
- Tableware + >=20 dumplings
|
||||
- 6+ procedural materials
|
||||
- Key/Fill/Rim lights + camera target
|
||||
|
||||
Also ensure:
|
||||
- No incomplete trailing lines
|
||||
- No missing material assignments
|
||||
- Avoid edit-mode toggling
|
||||
- Run-safe in Blender 3.x+ as a single script
|
||||
|
||||
Output ONLY ONE python code block. No extra text.
|
||||
params:
|
||||
temperature: 0.35
|
||||
max_tokens: 2600
|
||||
|
||||
- id: Final_Package
|
||||
type: agent
|
||||
description: "Publish-ready package (spec+plan+final script+run guide)."
|
||||
context_window: 10
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: |
|
||||
Output Markdown with:
|
||||
# 3D Case Summary (1 paragraph)
|
||||
# Design Spec (verbatim)
|
||||
# Execution Plan (verbatim)
|
||||
# Blender Script (final code block)
|
||||
# How to Run in Blender (5 steps)
|
||||
# Render Tips (5 bullets)
|
||||
# Common Errors & Fixes (5 bullets)
|
||||
params:
|
||||
temperature: 0.4
|
||||
max_tokens: 1800
|
||||
|
||||
edges:
|
||||
- from: Product Manager
|
||||
to: Planner
|
||||
trigger: true
|
||||
condition: "true"
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
|
||||
- from: Planner
|
||||
to: Procedural Architect
|
||||
trigger: true
|
||||
condition: "true"
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
|
||||
- from: Procedural Architect
|
||||
to: Reviewer
|
||||
trigger: true
|
||||
condition: "true"
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
|
||||
- from: Reviewer
|
||||
to: Patch_Architect
|
||||
trigger: true
|
||||
condition: "true"
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
|
||||
- from: Patch_Architect
|
||||
to: Final_Package
|
||||
trigger: true
|
||||
condition: "true"
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
|
||||
end:
|
||||
- Final_Package
|
||||
@@ -0,0 +1,244 @@
|
||||
version: 0.4.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: spring_text_image
|
||||
description: 'Launch-driven Spring Festival content factory: plan -> parallel gen -> edit -> human review -> revise (gpt-4o).'
|
||||
is_majority_voting: false
|
||||
start:
|
||||
- Planner
|
||||
nodes:
|
||||
- id: Planner
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
你是春节新媒体策划。
|
||||
用户在 Launch 时输入的内容,就是本次任务的唯一要求。
|
||||
请输出创作 Brief(Markdown),必须包含:
|
||||
## 受众
|
||||
## 核心传播点(3条)
|
||||
## 风格与禁忌
|
||||
## 必须出现的元素
|
||||
## 可选创意梗(2条)
|
||||
## 写作任务总结(一句话)
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.6
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
log_output: true
|
||||
- id: Copywriter
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
你是官号文案作者。根据 Brief 输出一篇可直接发布的春节推文(Markdown)。
|
||||
要求:
|
||||
- 标题 1 个(吸睛但不标题党)
|
||||
- 正文 4-6 段(段落短,节奏快)
|
||||
- 至少 3 个可传播金句(加粗)
|
||||
- 结尾 2 条互动引导(评论区话题/投票/分享)
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.7
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
log_output: true
|
||||
- id: Blessing
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
你是春节祝福语写手。根据 Brief 输出 12 条短祝福(Markdown 列表):
|
||||
- 温情 4 条 / 幽默 4 条 / 国风 4 条
|
||||
- 每条不超过 18 字
|
||||
- 不要重复表达
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.85
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
log_output: true
|
||||
- id: Storyteller
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
你是短故事写手。根据 Brief 写一个 300-500 字春节小故事(Markdown)。
|
||||
要求:有一个记忆点(反转/细节/一句金句);结尾落到团圆/祝福/新开始。
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.85
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
log_output: true
|
||||
- id: PosterPrompt
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
根据“最终发布包”,生成海报用的图像生成提示词(prompt pack),要求:
|
||||
- 3 个风格方向(国风/现代极简/手绘插画)
|
||||
- 每个方向给:正向提示词、负向提示词、画幅比例建议、主标题/副标题排版建议
|
||||
输出 Markdown。
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.6
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
log_output: true
|
||||
- id: Editor1
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
你是总编辑。你会收到:Brief + 推文 + 祝福语 + 小故事。
|
||||
请整合为一个“官号发布包(初稿)”(Markdown),结构固定为:
|
||||
# 标题候选(3个)
|
||||
# 正文终稿(1篇)
|
||||
# 海报短句(从祝福语精选 6 条)
|
||||
# 配图/排版建议(5条)
|
||||
# 评论区话题(3条)
|
||||
语言风格统一,内容可直接复制发布。
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.5
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 10
|
||||
log_output: true
|
||||
- id: HumanReview
|
||||
type: human
|
||||
config:
|
||||
description: |
|
||||
请审核“官号发布包(初稿)”:
|
||||
- 若满意请输入:ACCEPT(流程结束)
|
||||
- 否则请输入修改意见(越具体越好)
|
||||
description: ''
|
||||
context_window: 10
|
||||
log_output: true
|
||||
- id: Editor2
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
你是二次润色编辑。你会收到“发布包初稿 + 人工修改意见”。
|
||||
请输出修改后的最终发布包(Markdown),要求:
|
||||
- 完整保留发布包的结构(标题候选/正文终稿/海报短句/配图建议/评论区话题)
|
||||
- 修改意见逐条落实
|
||||
- 语言风格统一、可直接发布
|
||||
- 若发现初稿结构缺失或不一致,需要补齐并修正
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.45
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 10
|
||||
log_output: true
|
||||
- id: ImageGen
|
||||
type: agent
|
||||
config:
|
||||
name: gemini-2.5-flash-image-preview
|
||||
provider: openai
|
||||
role: |
|
||||
根据输入的“海报提示词方案”,对于每一个方案生成 1 张春节主题海报图。
|
||||
注意海报中如果涉及文字,务必保证文字准确性,否则不要使用文字。
|
||||
若支持比例参数,请优先按建议画幅生成;否则生成 1:1。
|
||||
输出直接给出生成结果(按系统返回格式)。
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
input_mode: messages
|
||||
description: ''
|
||||
context_window: 0
|
||||
log_output: true
|
||||
edges:
|
||||
- from: Planner
|
||||
to: Copywriter
|
||||
- from: Planner
|
||||
to: Blessing
|
||||
- from: Planner
|
||||
to: Storyteller
|
||||
- from: Planner
|
||||
to: Editor1
|
||||
- from: Copywriter
|
||||
to: Editor1
|
||||
- from: Blessing
|
||||
to: Editor1
|
||||
- from: Storyteller
|
||||
to: Editor1
|
||||
- from: Editor2
|
||||
to: PosterPrompt
|
||||
- from: PosterPrompt
|
||||
to: ImageGen
|
||||
- from: HumanReview
|
||||
to: Editor2
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any: []
|
||||
none:
|
||||
- ACCEPT
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: true
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Editor1
|
||||
to: HumanReview
|
||||
trigger: true
|
||||
condition: null
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: true
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
@@ -0,0 +1,269 @@
|
||||
version: 0.4.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: spring_text_image_EN
|
||||
description: 'Launch-driven Spring Festival content factory: plan -> parallel gen -> edit -> human review -> revise (gpt-4o).'
|
||||
is_majority_voting: false
|
||||
start:
|
||||
- Planner
|
||||
nodes:
|
||||
- id: Planner
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
You are a Spring Festival social media strategist.
|
||||
The content entered at Launch is the only requirement for this task.
|
||||
Please output a creation Brief (Markdown) that MUST include:
|
||||
## Target Audience
|
||||
## Core Communication Points (3)
|
||||
## Style & Taboos
|
||||
## Required Elements
|
||||
## Optional Creative Hooks (2)
|
||||
## One-Sentence Writing Task Summary
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.6
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
log_output: true
|
||||
|
||||
- id: Copywriter
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
You are the official account copywriter.
|
||||
Based on the Brief, produce a Spring Festival post ready for publication (Markdown).
|
||||
Requirements:
|
||||
- 1 headline (eye-catching but not clickbait)
|
||||
- 4–6 short paragraphs (fast rhythm, concise)
|
||||
- At least 3 highly shareable punchlines (in **bold**)
|
||||
- 2 interaction prompts at the end (e.g., comment topic / poll / share CTA)
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.7
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
log_output: true
|
||||
|
||||
- id: Blessing
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
You are a Spring Festival greeting writer.
|
||||
Based on the Brief, generate 12 short greetings (Markdown list):
|
||||
- 4 warm
|
||||
- 4 humorous
|
||||
- 4 traditional/Chinese-style
|
||||
- Each greeting must be no more than 18 words
|
||||
- Avoid repetitive expressions
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.85
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
log_output: true
|
||||
|
||||
- id: Storyteller
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
You are a short story writer.
|
||||
Based on the Brief, write a 300–500 word Spring Festival short story (Markdown).
|
||||
Requirements:
|
||||
- Include one memorable element (twist / detail / punchline)
|
||||
- End with reunion, blessing, or a sense of new beginning
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.85
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
log_output: true
|
||||
|
||||
- id: PosterPrompt
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
Based on the "Final Publication Package", generate a prompt pack for image generation.
|
||||
Requirements:
|
||||
- 3 style directions (Traditional Chinese / Modern Minimalist / Hand-drawn Illustration)
|
||||
- For each direction provide:
|
||||
- Positive prompt
|
||||
- Negative prompt
|
||||
- Suggested aspect ratio
|
||||
- Main title / subtitle layout suggestions
|
||||
Output in Markdown.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.6
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
log_output: true
|
||||
|
||||
- id: Editor1
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
You are the chief editor.
|
||||
You will receive: Brief + Post + Greetings + Short Story.
|
||||
Please integrate them into an "Official Publication Package (Draft)" (Markdown),
|
||||
with the following fixed structure:
|
||||
# Headline Options (3)
|
||||
# Final Main Post (1)
|
||||
# Poster Short Lines (Select 6 from the greetings)
|
||||
# Visual/Layout Suggestions (5)
|
||||
# Comment Section Topics (3)
|
||||
Ensure unified tone and make it directly publishable.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.5
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 10
|
||||
log_output: true
|
||||
|
||||
- id: HumanReview
|
||||
type: human
|
||||
config:
|
||||
description: |
|
||||
Please review the "Official Publication Package (Draft)":
|
||||
- If satisfied, enter: ACCEPT (the workflow will end)
|
||||
- Otherwise, provide revision feedback (be as specific as possible)
|
||||
description: ''
|
||||
context_window: 10
|
||||
log_output: true
|
||||
|
||||
- id: Editor2
|
||||
type: agent
|
||||
config:
|
||||
name: gpt-4o
|
||||
provider: openai
|
||||
role: |
|
||||
You are the second-round polishing editor.
|
||||
You will receive the draft package + human revision feedback.
|
||||
Please output the revised final publication package (Markdown).
|
||||
Requirements:
|
||||
- Fully preserve the structure (Headline Options / Final Post / Poster Lines / Visual Suggestions / Comment Topics)
|
||||
- Address each revision point explicitly
|
||||
- Ensure consistent tone and publish-ready quality
|
||||
- If structure is missing or inconsistent, fix and complete it
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params:
|
||||
temperature: 0.45
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 10
|
||||
log_output: true
|
||||
|
||||
- id: ImageGen
|
||||
type: agent
|
||||
config:
|
||||
name: gemini-2.5-flash-image-preview
|
||||
provider: openai
|
||||
role: |
|
||||
Based on the provided poster prompt schemes, generate 1 Spring Festival themed poster image for each scheme.
|
||||
If the poster involves text, ensure text accuracy. If text accuracy cannot be guaranteed, avoid including text.
|
||||
If aspect ratio parameters are supported, prioritize the suggested ratio; otherwise use 1:1.
|
||||
Output the result directly in the system-returned format.
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
input_mode: messages
|
||||
description: ''
|
||||
context_window: 0
|
||||
log_output: true
|
||||
|
||||
edges:
|
||||
- from: Planner
|
||||
to: Copywriter
|
||||
- from: Planner
|
||||
to: Blessing
|
||||
- from: Planner
|
||||
to: Storyteller
|
||||
- from: Planner
|
||||
to: Editor1
|
||||
- from: Copywriter
|
||||
to: Editor1
|
||||
- from: Blessing
|
||||
to: Editor1
|
||||
- from: Storyteller
|
||||
to: Editor1
|
||||
- from: Editor2
|
||||
to: PosterPrompt
|
||||
- from: PosterPrompt
|
||||
to: ImageGen
|
||||
- from: HumanReview
|
||||
to: Editor2
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any: []
|
||||
none:
|
||||
- ACCEPT
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: true
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Editor1
|
||||
to: HumanReview
|
||||
trigger: true
|
||||
condition: null
|
||||
carry_data: true
|
||||
keep_message: true
|
||||
clear_context: true
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
Executable
+78
@@ -0,0 +1,78 @@
|
||||
version: 0.4.0
|
||||
graph:
|
||||
id: paper_gen
|
||||
description: Subgraph that gathers multi-style revision suggestions for an article.
|
||||
is_majority_voting: false
|
||||
log_level: INFO
|
||||
start:
|
||||
- Romanticism Writer
|
||||
- Realism Writer
|
||||
- Magical Realism Writer
|
||||
nodes:
|
||||
- id: Romanticism Writer
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: 'You are a Romanticism writer, advocating intense emotions, loving and deifying nature, pursuing the extraordinary and the ideal, while emphasizing individualism and a spirit of rebellion.
|
||||
|
||||
Please provide revision suggestions for the work according to your style.
|
||||
|
||||
'
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
- id: Realism Writer
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: 'You are a Realism writer, seeking to objectively and truly reflect life, focusing on social issues and ordinary people, shaping typical characters in typical environments, with a cool and precise narrative style.
|
||||
|
||||
Please provide revision suggestions for the work according to your style.
|
||||
|
||||
'
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
- id: Magical Realism Writer
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: 'You are a Magical Realism writer, seamlessly blending magic and reality, using exaggeration and absurdity as expressive techniques, blurring the boundaries between reality and fantasy.
|
||||
|
||||
Please provide revision suggestions for the work according to your style.
|
||||
|
||||
'
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
- id: Editor
|
||||
type: agent
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
role: 'You are an excellent editor, skilled at providing basic article revision suggestions.
|
||||
|
||||
You will synthesize suggestions from writers of different styles, balance various plans, and propose practical revision plans to improve the quality of the article.
|
||||
|
||||
'
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 4000
|
||||
edges:
|
||||
- from: Romanticism Writer
|
||||
to: Editor
|
||||
- from: Realism Writer
|
||||
to: Editor
|
||||
- from: Magical Realism Writer
|
||||
to: Editor
|
||||
Executable
+115
@@ -0,0 +1,115 @@
|
||||
version: 0.4.0
|
||||
vars: {}
|
||||
graph:
|
||||
id: react_agent_subgraph
|
||||
description: ReAct control loop subgraph for tool calls and answer synthesis.
|
||||
is_majority_voting: false
|
||||
log_level: INFO
|
||||
start:
|
||||
- ReAct Brain
|
||||
end:
|
||||
- ReAct Answer Synthesizer
|
||||
nodes:
|
||||
- id: ReAct Brain
|
||||
type: agent
|
||||
description: ReAct controller, responsible for thinking, deciding whether to call tools, and providing final answers.
|
||||
context_window: -1
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
input_mode: messages
|
||||
role: |
|
||||
You are a ReAct controller, needing to make decisions between the toolbox (web_search, get_webpage_content, execute_code, get_city_num, get_weather) and the final answer.
|
||||
- Organize the entire context into a rolling Thought/Observation process, ensuring references to the latest Observation.
|
||||
- Only when you need to call a tool, output Control: continue, and attach Action and ActionInput (JSON).
|
||||
- If you are ready to answer the user directly, output Final Answer and set Action=FINAL.
|
||||
- Always follow this format:
|
||||
Thought: <your thinking>
|
||||
Action: <tool_name or FINAL>
|
||||
ActionInput: <JSON or NONE>
|
||||
Control: <DONE or CONTINUE>
|
||||
- When Action=FINAL, write the final response in Final Answer: ....
|
||||
- Never fabricate an Observation, you must wait for the Tool Executor's Observation.
|
||||
params:
|
||||
temperature: 0.2
|
||||
max_tokens: 1200
|
||||
- id: Tool Executor
|
||||
type: agent
|
||||
description: Receives control instructions and actually calls function tools, returning Observations.
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
input_mode: messages
|
||||
role: |
|
||||
You are the tool executor.
|
||||
- Parse the Action and ActionInput fields from the previous node.
|
||||
- Only when Action belongs to {web_search, get_webpage_content, execute_code, get_city_num, get_weather}, call the corresponding function tool; otherwise, reply directly with "Observation: No tool needed".
|
||||
- After a successful call, return using the following template:
|
||||
Tool: <called tool>
|
||||
Observation: <concise summary>
|
||||
Raw Output:
|
||||
```
|
||||
<raw function return>
|
||||
```
|
||||
- Do not include trigger in the output to avoid affecting upstream condition judgment.
|
||||
- Do not provide a final answer.
|
||||
tooling:
|
||||
type: function
|
||||
config:
|
||||
auto_load: true
|
||||
tools:
|
||||
- name: web_search
|
||||
- name: get_webpage_content
|
||||
- name: execute_code
|
||||
- name: get_city_num
|
||||
- name: get_weather
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 1200
|
||||
- id: ReAct Answer Synthesizer
|
||||
type: agent
|
||||
description: Cleans up ReAct formatting and outputs a user-readable final response.
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
input_mode: messages
|
||||
role: |
|
||||
You are responsible for receiving the Final Answer from ReAct Brain and combining it with the most recent Observation (if any) to generate a natural language response.
|
||||
- Focus on answering the user's question, including sources/action summaries where necessary.
|
||||
- Remove all template fields (Thought/Action/Control, etc.).
|
||||
params:
|
||||
temperature: 0.2
|
||||
max_tokens: 800
|
||||
edges:
|
||||
- from: ReAct Brain
|
||||
to: Tool Executor
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any: [ ]
|
||||
none:
|
||||
- FINAL
|
||||
regex: [ ]
|
||||
case_sensitive: true
|
||||
- from: Tool Executor
|
||||
to: ReAct Brain
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
- from: ReAct Brain
|
||||
to: ReAct Answer Synthesizer
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- FINAL
|
||||
none: [ ]
|
||||
regex: [ ]
|
||||
case_sensitive: true
|
||||
Executable
+128
@@ -0,0 +1,128 @@
|
||||
version: 0.4.0
|
||||
graph:
|
||||
id: reflexion_loop
|
||||
description: Reflexion loop subgraph with actor/evaluator and memory storage.
|
||||
log_level: INFO
|
||||
is_majority_voting: false
|
||||
start:
|
||||
- Task
|
||||
end:
|
||||
- Final Synthesizer
|
||||
memory:
|
||||
- name: reflexion_blackboard
|
||||
type: blackboard
|
||||
config:
|
||||
max_items: 500
|
||||
nodes:
|
||||
- id: Task
|
||||
type: passthrough
|
||||
config: {}
|
||||
- id: Reflexion Actor
|
||||
type: agent
|
||||
description: Actor (πθ) generates a strategy draft based on blackboard experience and short-term context.
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o-mini
|
||||
input_mode: messages
|
||||
role: |
|
||||
You are the Actor. If there are relevant memories, refer to that experience and output the latest action draft; if there are no relevant memories, provide an action draft to the best of your ability.
|
||||
- Structure:
|
||||
Thought: ...
|
||||
Draft: ...
|
||||
memories:
|
||||
- name: reflexion_blackboard
|
||||
retrieve_stage:
|
||||
- gen
|
||||
top_k: 5
|
||||
read: true
|
||||
write: false
|
||||
params:
|
||||
temperature: 0.2
|
||||
max_tokens: 1200
|
||||
- id: Reflexion Evaluator
|
||||
type: agent
|
||||
description: Evaluator (Me) provides scores and improvement directions for the Actor's draft.
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o-mini
|
||||
input_mode: messages
|
||||
role: |
|
||||
You are the Evaluator. Receive and read the Actor's latest output and task objectives, and evaluate whether they meet the goals.
|
||||
Append `Verdict: CONTINUE` or `Verdict: STOP` at the end of the output.
|
||||
When you think the current plan is good enough, you should give `Verdict: STOP`. Other fields can be skipped.
|
||||
Output:
|
||||
- Score: <0-1>
|
||||
- Reason: <Failure reasons or highlights>
|
||||
- Next Focus: <Key points to focus on in the next round>
|
||||
- Verdict: CONTINUE|STOP
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 800
|
||||
- id: Self Reflection Writer
|
||||
type: agent
|
||||
description: Self-Reflection (Msr) converts Evaluator results into reusable experience.
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o-mini
|
||||
input_mode: messages
|
||||
role: |
|
||||
You are responsible for refining the Evaluator output and Actor Draft into JSON experience:
|
||||
{
|
||||
"issues": [..],
|
||||
"fix_plan": [..],
|
||||
"memory_cue": "A short reminder"
|
||||
}
|
||||
- JSON must not contain extra text.
|
||||
memories:
|
||||
- name: reflexion_blackboard
|
||||
read: false
|
||||
write: true
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 500
|
||||
- id: Final Synthesizer
|
||||
type: agent
|
||||
description: Converge the final answer, absorbing the latest Draft and Evaluator tips.
|
||||
config:
|
||||
provider: openai
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
name: gpt-4o
|
||||
input_mode: messages
|
||||
role: |
|
||||
Please synthesize all inputs and provide a final answer. Be comprehensive. Do not include any extra text other than the final answer.
|
||||
params:
|
||||
temperature: 0.1
|
||||
max_tokens: 1000
|
||||
edges:
|
||||
- from: Task
|
||||
to: Reflexion Actor
|
||||
keep_message: True
|
||||
- from: Task
|
||||
to: Reflexion Evaluator
|
||||
keep_message: True
|
||||
trigger: false
|
||||
- from: Reflexion Actor
|
||||
to: Reflexion Actor
|
||||
trigger: false
|
||||
- from: Reflexion Actor
|
||||
to: Reflexion Evaluator
|
||||
- from: Reflexion Evaluator
|
||||
to: Self Reflection Writer
|
||||
condition: need_reflection_loop
|
||||
- from: Self Reflection Writer
|
||||
to: Reflexion Actor
|
||||
carry_data: true
|
||||
- from: Reflexion Actor
|
||||
to: Final Synthesizer
|
||||
trigger: false
|
||||
- from: Reflexion Evaluator
|
||||
to: Final Synthesizer
|
||||
condition: should_stop_loop
|
||||
carry_data: false
|
||||
Executable
+332
@@ -0,0 +1,332 @@
|
||||
graph:
|
||||
id: Video_Creator
|
||||
description: 'Teaching video pipeline using Manim: outline, paginate, render, and concat.'
|
||||
log_level: DEBUG
|
||||
is_majority_voting: false
|
||||
nodes:
|
||||
- id: Visualization Executor
|
||||
type: python
|
||||
config:
|
||||
args: []
|
||||
env: {}
|
||||
timeout_seconds: 60
|
||||
encoding: utf-8
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Video Concat
|
||||
type: agent
|
||||
config:
|
||||
name: gemini-3-flash-preview
|
||||
provider: gemini
|
||||
role: 请先调用 describe_available_files,检查当前目录中的.mp4文件的路径;不同mp4文件的名称代表了他们的内容,请你根据他们的名称排序,并调用concat_videos工具对其进行拼接。注意,concat_videos工具需要的参数是排好序的绝对路径构成的列表
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: concat_videos
|
||||
- name: describe_available_files
|
||||
timeout: null
|
||||
prefix: ''
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Content Composer
|
||||
type: agent
|
||||
config:
|
||||
name: gemini-3-flash-preview
|
||||
provider: gemini
|
||||
role: |-
|
||||
你是一名严谨的课程内容助教,请对你收到的内容生成一份教学大纲。
|
||||
|
||||
要求:
|
||||
1. 语言保持简洁、客观,避免夸张描述;不要写成营销文案。
|
||||
2. 不要插入代码块、表格、多级列表;最多使用无序列表补充 1–3 条要点。
|
||||
3. 输出仅为 Markdown 正文,不要包含额外说明。
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Code Generator
|
||||
type: agent
|
||||
config:
|
||||
name: gemini-3-flash-preview
|
||||
provider: gemini
|
||||
role: |-
|
||||
你是一名 **Manim 动画生成 Agent**,具备自动规划、代码生成与执行能力。
|
||||
你将接收一段题目信息(Markdown 格式),以及该内容在整套课程中的上下文位置信息。
|
||||
**上下文仅用于理解,不得在动画中体现**;你只负责当前这部分内容的一页动画生成。
|
||||
|
||||
你的任务流程如下(需自动完成,不得向用户提问):
|
||||
|
||||
1. 解析当前内容,自动规划一页 Manim 动画的内容结构,确保逻辑清晰、且包含所有信息;
|
||||
2. 生成 **完整、可直接运行的 Manim Python 源代码**;
|
||||
3. 不输出任何非代码内容。
|
||||
|
||||
---
|
||||
|
||||
### 强制约束(必须严格遵守,违背任一条视为错误):
|
||||
|
||||
1. **最终仅允许输出完整 Python 源代码**,不得包含任何说明性文本、注释性解释或自然语言内容;
|
||||
2. 页面无需标题页,但**必须在页面顶部显示标题**;
|
||||
3. 标题内容应为对本页教学内容的**高度概括**,**禁止使用 Page x 等编号形式**;
|
||||
4. 标题的字体、字号、位置与动画方式 **必须严格使用以下模板**(仅允许替换标题文本):
|
||||
|
||||
```
|
||||
title = Text("......",
|
||||
font_size=34,
|
||||
font="AR PL UKai CN",
|
||||
color=WHITE,
|
||||
weight=BOLD)
|
||||
title.to_edge(UP, buff=0.5)
|
||||
|
||||
title_line = Line(LEFT, RIGHT, color=ORANGE).next_to(title, DOWN, buff=0.1)
|
||||
title_line.match_width(title)
|
||||
|
||||
title_group = VGroup(title, title_line)
|
||||
|
||||
self.play(
|
||||
Write(title, run_time=1.5),
|
||||
GrowFromCenter(title_line, run_time=0.8)
|
||||
)
|
||||
```
|
||||
|
||||
5. 所有讲解文字 **必须为中文**(代码与必要的专业术语除外),
|
||||
且所有中文文本 **必须使用 AR PL UKai CN 字体**;
|
||||
6. 页面内容需严格控制在 **15 秒以内的动画时长**;
|
||||
7. 字体大小不得过小,需保证视频环境下清晰可读;
|
||||
8. 所有内容必须通过 `self.play(Write(...))`、`self.play(FadeIn(...))` 等方式**渐进式呈现**;
|
||||
9. 可使用文本、几何图形、框图、坐标系、点与线等基础元素进行可视化,
|
||||
适用于算法流程、数据结构、分类边界、特征空间等教学场景;
|
||||
10. 禁止任何花哨或复杂动画,避免遮挡、重叠、元素出屏;
|
||||
11. **必须使用 `SurroundingRectangle`**,禁止使用 `Rectangle` 与 `RoundedRectangle`;
|
||||
12. **严禁使用任何图片内容**,不得出现 `ImageMobject()`;
|
||||
13. 数学公式必须使用 `MathTex()` 清晰展示;
|
||||
14. 算法步骤可使用 `BulletedList` 或逐步动画展开;
|
||||
15. **严禁使用任何中英文引号**;
|
||||
16. **严禁输出任何额外信息**,包括解释、日志、提示语或自然语言描述。
|
||||
|
||||
|
||||
下面是 manim 中常报错的问题,请你一定要注意哦!
|
||||
问题类型一:IndexError: list index out of range
|
||||
在 Manim 中调用 .get_rows()[x][y] 或 BulletedList 时,如果表格或 bullet 列表项数量不足,就会出现 索引越界,或者某些对象的结构并没有你预期的层级,会导致取不到想要的元素
|
||||
问题类型二:Text() 和 MathTex() 不支持 alignment 参数
|
||||
Text(..., alignment="CENTER"),这是无效参数
|
||||
问题类型三:LaTeX 语法错误,这一点很重要!
|
||||
BulletedList 内部用的是 MathTex,而 & 是 LaTeX 中的对齐符号,不允许直接使用,可以使用转义字符, 也没有TextBulletedList这种用法!
|
||||
问题类型四:BulletedList 的用法注意事项
|
||||
BulletedList 在 Manim 中的创建方式和参数可能因版本或使用场景产生预期外的行为。常见错误包括:直接对 BulletedList 使用索引访问内部元素(如 bullet_list[0][1])、错误修改其内部结构,或误以为支持类似 HTML 的嵌套列表功能。需严格按照文档规范创建(如 BulletedList("item1", "item2")),避免对返回对象进行不合理操作。
|
||||
问题类型五:Manim Community 版本兼容性
|
||||
当前代码基于 Manim Community v0.19.0 开发,不同版本间存在 API 差异。请勿参考更高版本(如 0.20.0+)的示例代码,可能遇到方法名变更、参数调整或功能移除等问题(例如 Text 类的某些样式参数在新版本中已被弃用),严格使用对应版本的文档或示例。也不要使用旧版本的Manim开发:例如ShowCreation 是旧版 Manim 的动画类,新版(尤其是 manimCE v0.12.0+)推荐使用Create()画出线条或图形
|
||||
问题类型六:页面元素布局控制,
|
||||
在场景设计中,图片和文字的排版易出现位置偏移或间距失衡问题:
|
||||
1.图片定位:未显式设置坐标时,图片可能默认出现在画布左上角或随机位置。需通过 move_to()、to_edge() 或相对定位(如 next_to(title, DOWN))明确位置;
|
||||
2.标题与内容间距:直接连续添加标题和内容可能导致重叠。建议使用 VGroup 组合元素后,通过 arrange(DOWN, buff=0.5) 调节垂直间距(buff 控制间隔大小),或单独设置 shift(DOWN*2) 微调位置;
|
||||
3.居中问题:文本/图片默认左对齐,需通过 move_to(ORIGIN) 或结合 align_to(LEFT/RIGHT/UP/DOWN) 实现精准居中或对齐边界。
|
||||
问题类型七:内容可视化注意事项
|
||||
在制作教学动画时需要特别注意:
|
||||
1.数学公式:复杂的ML公式应分步展示,避免一次性显示过长的公式导致超出屏幕;
|
||||
2.算法流程:用简洁的流程图展示算法步骤,避免过度复杂的逻辑图;
|
||||
3.数据可视化:展示数据点时注意坐标范围,确保所有点都在可视区域内;
|
||||
4.概念层次:概念具有层次性,应按照从简单到复杂的顺序渐进展示。
|
||||
问题类型八:Code()不支持font_size参数,不支持code参数,同时Code物件也没有.code这个属性,要千万注意哦!!!
|
||||
5.在生成多行字符串时,字符串内部的所有代码行必须保留缩进,严禁顶格书写,确保与外层代码缩进对齐。
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Concluder
|
||||
type: agent
|
||||
config:
|
||||
name: gemini-3-flash-preview
|
||||
provider: gemini
|
||||
role: |-
|
||||
请先调用 describe_available_files,检查当前目录中的.py脚本文件的路径;之后直接使用render_manim工具进行渲染,此工具的参数只需要{script_path}(脚本路径(绝对路径));如果有多个py文件,则需要对每个py文件均运行render_manim工具进行渲染
|
||||
如果你在render_manim中发现出现问题,请你将具体的报错输出,同时输出“ERROR”
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling:
|
||||
- type: function
|
||||
config:
|
||||
tools:
|
||||
- name: render_manim
|
||||
- name: describe_available_files
|
||||
timeout: null
|
||||
prefix: ''
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
- id: Paginator
|
||||
type: agent
|
||||
config:
|
||||
name: gemini-3-flash-preview
|
||||
provider: gemini
|
||||
role: |-
|
||||
你是一位专业的文档格式处理专家,擅长为教学文档添加合适的分页标记。
|
||||
|
||||
任务:对提供的章节markdown内容进行分页处理,添加分页标记但完全保留所有原有内容。
|
||||
|
||||
章节内容:
|
||||
{section_content}
|
||||
|
||||
## 处理原则:
|
||||
1. **完全保留原有内容** - 逐字逐句完整保留,包括所有文字、标点、空行、格式和结构
|
||||
2. **只添加分页标记** - 仅在合适位置插入分页符
|
||||
3. **保持逻辑结构** - 确保分页不会破坏内容的逻辑连贯性
|
||||
4. **内容完整性第一** - 保证内容完整
|
||||
|
||||
## 分页标记规则:
|
||||
- 使用 `<!-- PAGEBREAK -->` 作为分页标记
|
||||
- 分页标记必须单独占一行
|
||||
|
||||
## 分页策略:
|
||||
- 你分割的一页是后续要在 manim 一页中展示的,所以尽量细致一些,但也不要太细
|
||||
- 确保代码示例完整性
|
||||
- 重要概念不被分页截断
|
||||
- 如果某一章节不需要分页,就什么都不改变就可以
|
||||
- 不要将各级标题单独分为一页,这很重要
|
||||
|
||||
## 输出要求:
|
||||
- 保持原有的markdown格式
|
||||
- 分页标记单独占一行
|
||||
- **绝对不能截断或省略任何部分**
|
||||
|
||||
## 输出格式:
|
||||
直接输出处理后的完整markdown内容,不要添加任何解释文字。
|
||||
|
||||
请严格按照上述要求处理章节内容,确保输出内容的完整性。
|
||||
base_url: ${BASE_URL}
|
||||
api_key: ${API_KEY}
|
||||
params: {}
|
||||
tooling: []
|
||||
thinking: null
|
||||
memories: []
|
||||
retry: null
|
||||
description: ''
|
||||
context_window: 0
|
||||
edges:
|
||||
- from: Visualization Executor
|
||||
to: Code Generator
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: code_fail
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Visualization Executor
|
||||
to: Concluder
|
||||
trigger: true
|
||||
condition:
|
||||
type: function
|
||||
config:
|
||||
name: code_pass
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Concluder
|
||||
to: Code Generator
|
||||
trigger: true
|
||||
condition:
|
||||
type: keyword
|
||||
config:
|
||||
any:
|
||||
- ERROR
|
||||
none: []
|
||||
regex: []
|
||||
case_sensitive: true
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Concluder
|
||||
to: Video Concat
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Content Composer
|
||||
to: Paginator
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic: null
|
||||
- from: Code Generator
|
||||
to: Visualization Executor
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic:
|
||||
type: map
|
||||
split:
|
||||
type: message
|
||||
config: {}
|
||||
config:
|
||||
max_parallel: 10
|
||||
- from: Paginator
|
||||
to: Code Generator
|
||||
trigger: true
|
||||
condition: 'true'
|
||||
carry_data: true
|
||||
keep_message: false
|
||||
clear_context: false
|
||||
clear_kept_context: false
|
||||
process: null
|
||||
dynamic:
|
||||
type: map
|
||||
split:
|
||||
type: regex
|
||||
config:
|
||||
pattern: (.*?)<!--\s*PAGEBREAK\s*-->
|
||||
group: ''
|
||||
case_sensitive: true
|
||||
multiline: false
|
||||
dotall: false
|
||||
on_no_match: pass
|
||||
config:
|
||||
max_parallel: 10
|
||||
memory: []
|
||||
initial_instruction: ''
|
||||
start:
|
||||
- Content Composer
|
||||
end: []
|
||||
version: 0.0.0
|
||||
vars: {}
|
||||
Reference in New Issue
Block a user