(self, input: Input, request: Request)
| 12 | """Compact the current chat history into a summarized message.""" |
| 13 | |
| 14 | async def process(self, input: Input, request: Request) -> Output: |
| 15 | ctxid = input.get("context", "") |
| 16 | action = input.get("action", "compact") |
| 17 | |
| 18 | if not ctxid: |
| 19 | return Response("Missing context id", 400) |
| 20 | |
| 21 | context = AgentContext.get(ctxid) |
| 22 | if not context: |
| 23 | return Response("Context not found", 404) |
| 24 | |
| 25 | if context.is_running(): |
| 26 | return Response("Cannot compact while agent is running", 409) |
| 27 | |
| 28 | visible_count = len(context.log.logs) |
| 29 | if visible_count <= 1: |
| 30 | return Response("Not enough messages to compact", 400) |
| 31 | |
| 32 | # Gate both stats and compact — no point opening the modal for tiny chats |
| 33 | stats = await get_compaction_stats(context) |
| 34 | if stats["token_count"] < MIN_COMPACTION_TOKENS: |
| 35 | return { |
| 36 | "ok": False, |
| 37 | "message": f"Not enough content to compact (minimum {MIN_COMPACTION_TOKENS:,} tokens)", |
| 38 | } |
| 39 | |
| 40 | if action == "stats": |
| 41 | return {"ok": True, "stats": stats} |
| 42 | |
| 43 | elif action == "compact": |
| 44 | use_chat_model = input.get("use_chat_model", True) |
| 45 | preset_name = input.get("preset_name") or None |
| 46 | |
| 47 | context.run_task( |
| 48 | _run_compaction_task, context, use_chat_model, preset_name |
| 49 | ) |
| 50 | |
| 51 | return {"ok": True, "message": "Compaction started"} |
| 52 | |
| 53 | else: |
| 54 | return Response(f"Unknown action: {action}", 400) |
| 55 | |
| 56 | |
| 57 | async def _run_compaction_task(context, use_chat_model: bool, preset_name: str | None): |
nothing calls this directly
no test coverage detected