| 1 | from agent import AgentContext, UserMessage |
| 2 | from helpers.api import ApiHandler, Input, Output, Request, Response |
| 3 | from helpers import guids, message_queue as mq |
| 4 | from helpers.persist_chat import remove_chat |
| 5 | from plugins._plugin_scan.helpers.prompt import build_prompt |
| 6 | |
| 7 | |
| 8 | class PluginScanRun(ApiHandler): |
| 9 | """ |
| 10 | POST /api/plugins/_plugin_scan/plugin_scan_run |
| 11 | Body: { "git_url": "https://github.com/...", "checks": [...] } # checks optional, defaults to all |
| 12 | Returns: { "ok": true, "verdict": "safe|caution|dangerous|unknown", "report": "<markdown>" } |
| 13 | |
| 14 | Combines plugin_scan_queue + plugin_scan_start into one synchronous call and awaits the result. |
| 15 | No server-side timeout - set an appropriate client-side timeout (repos can take 5+ min to scan). |
| 16 | """ |
| 17 | |
| 18 | async def process(self, input: Input, request: Request) -> Output: |
| 19 | git_url: str = input.get("git_url", "").strip() |
| 20 | if not git_url: |
| 21 | return Response("Missing 'git_url'.", 400) |
| 22 | |
| 23 | ctxid = guids.generate_id() |
| 24 | report = "" |
| 25 | try: |
| 26 | context = self.use_context(ctxid) |
| 27 | prompt = build_prompt(git_url, input.get("checks")) |
| 28 | mq.log_user_message(context, prompt, []) |
| 29 | task = context.communicate(UserMessage(prompt, [])) |
| 30 | report: str = await task.result() |
| 31 | except Exception as e: |
| 32 | return Response(f"Scan failed: {e}", 500) |
| 33 | finally: |
| 34 | try: |
| 35 | AgentContext.remove(ctxid) |
| 36 | remove_chat(ctxid) |
| 37 | except Exception: |
| 38 | pass |
| 39 | |
| 40 | return { |
| 41 | "ok": True, |
| 42 | "git_url": git_url, |
| 43 | "report": report or "", |
| 44 | } |