feat: add pitrader_script step type + image vision for pipeline triggers

Add pitrader_script executor for running PITrader scripts (pi-scan,
playbook, execute_trades) as pipeline steps with vault credential
injection and JSON output capture.

Extend claude_prompt step with vision support (image_b64 in trigger
context). Add image pipeline trigger to on_image_message handler.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Christian Gick
2026-03-19 13:45:36 +02:00
parent 18b88d490f
commit 0988f636d0
4 changed files with 159 additions and 3 deletions

16
bot.py
View File

@@ -2123,6 +2123,15 @@ class Bot:
if time.time() - server_ts > 30:
return
# Check for pipeline file_upload triggers (before DM/mention check)
source = event.source or {}
content = source.get("content", {})
info = content.get("info", {})
img_mime = info.get("mimetype", "image/png")
img_filename = content.get("body", "image.png")
if self.cron_scheduler:
await self._check_pipeline_file_trigger(room, event, img_filename, img_mime)
await self._load_room_settings(room.room_id)
# In DMs respond to all images; in groups only if bot was recently @mentioned
@@ -2280,13 +2289,17 @@ class Bot:
# Download file content for trigger data
mxc_url = event.url if hasattr(event, "url") else None
file_text = ""
image_b64 = ""
if mxc_url:
try:
resp = await self.client.download(mxc=mxc_url)
if hasattr(resp, "body"):
file_bytes = resp.body
ext = os.path.splitext(filename.lower())[1]
if ext == ".pdf":
if mime_type.startswith("image/"):
# Encode image as base64 for vision analysis in claude_prompt steps
image_b64 = base64.b64encode(file_bytes).decode("utf-8")
elif ext == ".pdf":
file_text = self._extract_pdf_text(file_bytes)
elif ext == ".docx":
file_text = self._extract_docx_text(file_bytes)
@@ -2301,6 +2314,7 @@ class Bot:
"filename": filename,
"mime_type": mime_type,
"file_content": file_text,
"image_b64": image_b64,
"sender": event.sender,
"room_id": room.room_id,
}