main
py 68 lines 2.32 KB
Raw
1 """API handler for chat compaction."""
2 from helpers.api import ApiHandler, Input, Output, Request, Response
3 from agent import AgentContext
4 from plugins._chat_compaction.helpers.compactor import (
5 MIN_COMPACTION_TOKENS,
6 get_compaction_stats,
7 run_compaction,
8 )
9
10
11 class CompactChat(ApiHandler):
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):
58 """Wrapper to run compaction and handle errors."""
59 try:
60 await run_compaction(context, use_chat_model, preset_name)
61 except Exception as e:
62 context.log.log(
63 type="error",
64 heading="Compaction Failed",
65 content=str(e),
66 )
67 from helpers.state_monitor_integration import mark_dirty_all
68 mark_dirty_all(reason="plugins._chat_compaction.compact_chat_error")