Resilient PowerPoint generation with shell_agent primary path and python-pptx fallback
Use this workflow when:
This workflow provides two paths:
Both paths include automatic error capture and file location verification.
Use shell_agent to create a PowerPoint presentation with:
- Specify exact number of slides needed
- Define content/topic for each slide
- Request file saved with clear filename (e.g., presentation.pptx)
- Ask agent to confirm the full file path after creation
- Request agent report any errors with full outputExample task description:
Create a PowerPoint presentation with 10 slides covering [topic]. Each slide should have a title and bullet points. Save it as presentation.pptx in the current working directory and report the full file path. If you encounter any errors, show the complete error message.Check if shell_agent completed successfully:
If any check fails, proceed to Path 2 (Fallback).
First, write the PowerPoint generation script to a .py file (do NOT use inline execution):
# save as: generate_presentation.py
from pptx import Presentation
from pptx.util import Inches, Pt
import os
# CRITICAL: Explicitly set and verify working directory
working_dir = os.getcwd()
print(f"Working directory: {working_dir}")
# Create presentation
prs = Presentation()
# Example: Add slides with content
slides_content = [
{"title": "Slide 1 Title", "content": ["Bullet 1", "Bullet 2"]},
{"title": "Slide 2 Title", "content": ["Point A", "Point B", "Point C"]},
# Add more slides as needed
]
for slide_data in slides_content:
slide_layout = prs.slide_layouts[1] # Title and Content layout
slide = prs.slides.add_slide(slide_layout)
# Set title
title = slide.shapes.title
title.text = slide_data["title"]
# Set content
content = slide.placeholders[1]
tf = content.text_frame
tf.clear() # Clear existing content
for i, point in enumerate(slide_data["content"]):
if i == 0:
p = tf.paragraphs[0]
else:
p = tf.add_paragraph()
p.text = point
p.font.size = Pt(18)
# Save to current working directory with explicit path
output_filename = "presentation.pptx"
output_path = os.path.join(working_dir, output_filename)
prs.save(output_path)
print(f"Presentation saved to: {output_path}")
print(f"File exists: {os.path.exists(output_path)}")
print(f"File size: {os.path.getsize(output_path)} bytes")CRITICAL: Always redirect stderr to stdout to capture actual error messages:
# Execute the script with full error output
python generate_presentation.py 2>&1
# Or if using run_shell tool, ensure 2>&1 is includedWhy this matters: Without 2>&1, Python exceptions are sent to stderr and you only see "unknown error" instead of the actual exception message.
If execution fails, add these debugging commands:
# Check if python-pptx is installed
python -c "import pptx; print(pptx.__version__)" 2>&1
# Check working directory
pwd
ls -la
# Check Python version
python --version
# Run with verbose error output
python -u generate_presentation.py 2>&1 | tee execution_log.txtPowerPoint files may be in nested workspace directories. Always verify location:
# Find all .pptx files in workspace
find . -name "*.pptx" -type f 2>&1
# Or search for specific filename
find . -name "presentation.pptx" -type f 2>&1
# If not found locally, search broader (last resort)
find /workspace -name "*.pptx" -type f 2>/dev/nullOnce located, copy the file to your working directory:
# Get the full path from find output
FILE_PATH=$(find . -name "presentation.pptx" -type f | head -1)
# Copy to current directory
cp "$FILE_PATH" . 2>&1
# Or move it
mv "$FILE_PATH" . 2>&1Confirm the file exists and is valid:
# List file with details
ls -la presentation.pptx
# Check file size (should NOT be 0 bytes)
file presentation.pptx
stat presentation.pptx | grep Size
# Verify it's a valid PowerPoint file
python -c "from pptx import Presentation; prs = Presentation('presentation.pptx'); print(f'Slides: {len(prs.slides)}')" 2>&1| Problem | Solution |
|---|---|
| shell_agent returns "unknown error" | Switch to Path 2 (direct Python) immediately |
| Python script fails silently | Add 2>&1 to capture stderr; use python -u for unbuffered output |
| File not found after generation | Use find . -name "*.pptx" - don't assume current directory |
| File is 0 bytes | Re-run generation; check for exceptions in error output |
| Working directory confusion | Always print(os.getcwd()) in Python scripts; use absolute paths |
| Module not found (pptx) | Install with pip install python-pptx or use alternative environment |
| Permission denied | Check directory permissions: ls -la on parent dirs; use /workspace/ prefix |
Start
│
└─→ Try shell_agent with clear specs
│
├─→ Success + File path reported? ──→ Verify file → Done
│
└─→ Failed or opaque error?
│
└─→ Switch to direct Python (Path 2)
│
├─→ Write script to .py file
├─→ Execute with 2>&1 redirect
├─→ Capture and analyze errors
├─→ Fix and retry (max 3 attempts)
│
└─→ Success? → Locate → Copy → Verify → Done
└─→ Still failing? → Report actual error messages# Attempt 1: shell_agent (via task delegation)
# [Agent creates presentation, reports path or error]
# If shell_agent failed, proceed to Path 2:
# Step 1: Write Python script
cat > generate_presentation.py << 'EOF'
from pptx import Presentation
import os
print(f"Working directory: {os.getcwd()}")
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[0])
slide.shapes.title.text = "Title Slide"
prs.save("presentation.pptx")
print(f"Saved: presentation.pptx")
EOF
# Step 2: Execute with error capture
python generate_presentation.py 2>&1
# Output: Working directory: /workspace/task_123
# Saved: presentation.pptx
# Step 3: Locate (in case it's nested)
find . -name "presentation.pptx" -type f
# Output: ./presentation.pptx
# Step 4: Verify
ls -la presentation.pptx
# Output: -rw-r--r-- 1 user user 45632 Jan 15 10:30 presentation.pptx
python -c "from pptx import Presentation; print(len(Presentation('presentation.pptx').slides))"
# Output: 1# This is NOT helpful - stderr is hidden
python script.py
# This CAPTURES the actual error
python script.py 2>&1
# This CAPTURES and LOGS for analysis
python script.py 2>&1 | tee error_log.txt# Always include this at script start
import os
print(f"CWD: {os.getcwd()}")
print(f"Files in CWD: {os.listdir('.')}")
# Use absolute paths for output
output_path = os.path.join(os.getcwd(), "presentation.pptx")# Find most recently created
find . -name "*.pptx" -type f -printf '%T@ %p\n' | sort -n | tail -1
# Or find by name pattern
find . -name "*presentation*.pptx" -type f2>&1 to capture Python exceptionspython -u for unbuffered output (real-time error display)| tee logfile.txt to preserve error output for analysisA successful PowerPoint generation workflow:
c5a9c4b
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.