| 25 | return True # Require API key |
| 26 | |
| 27 | async def process(self, input: dict, request: Request) -> dict | Response: |
| 28 | # Extract parameters |
| 29 | context_id = input.get("context_id", "") |
| 30 | message = input.get("message", "") |
| 31 | attachments = input.get("attachments", []) |
| 32 | lifetime_hours = input.get("lifetime_hours", 24) # Default 24 hours |
| 33 | project_name = input.get("project_name", None) |
| 34 | agent_profile = input.get("agent_profile", None) |
| 35 | try: |
| 36 | lifetime_hours = float(lifetime_hours) |
| 37 | if lifetime_hours <= 0: |
| 38 | raise ValueError("lifetime_hours must be greater than 0") |
| 39 | except (TypeError, ValueError): |
| 40 | return Response( |
| 41 | '{"error": "lifetime_hours must be a positive number"}', |
| 42 | status=400, |
| 43 | mimetype="application/json", |
| 44 | ) |
| 45 | |
| 46 | # Set an agent if profile provided |
| 47 | override_settings = {} |
| 48 | if agent_profile: |
| 49 | override_settings["agent_profile"] = agent_profile |
| 50 | |
| 51 | if not message: |
| 52 | return Response('{"error": "Message is required"}', status=400, mimetype="application/json") |
| 53 | |
| 54 | # Handle attachments (base64 encoded) |
| 55 | attachment_paths = [] |
| 56 | if attachments: |
| 57 | upload_folder_int = "/a0/usr/uploads" |
| 58 | upload_folder_ext = files.get_abs_path("usr/uploads") |
| 59 | os.makedirs(upload_folder_ext, exist_ok=True) |
| 60 | |
| 61 | for attachment in attachments: |
| 62 | if not isinstance(attachment, dict) or "filename" not in attachment or "base64" not in attachment: |
| 63 | continue |
| 64 | |
| 65 | try: |
| 66 | filename = safe_filename(attachment["filename"]) |
| 67 | if not filename: |
| 68 | raise ValueError("Invalid filename") |
| 69 | |
| 70 | # Decode base64 content |
| 71 | file_content = base64.b64decode(attachment["base64"]) |
| 72 | |
| 73 | # Save to temp file |
| 74 | save_path = os.path.join(upload_folder_ext, filename) |
| 75 | with open(save_path, "wb") as f: |
| 76 | f.write(file_content) |
| 77 | |
| 78 | attachment_paths.append(os.path.join(upload_folder_int, filename)) |
| 79 | except Exception as e: |
| 80 | PrintStyle.error(f"Failed to process attachment {attachment.get('filename', 'unknown')}: {e}") |
| 81 | continue |
| 82 | |
| 83 | # Get or create context |
| 84 | if context_id: |