Spaces:
Running
Running
Commit ·
0aec89b
1
Parent(s): 76996d0
adding compaction
Browse files- agent/context_manager/manager.py +4 -1
- agent/core/agent_loop.py +33 -28
agent/context_manager/manager.py
CHANGED
|
@@ -78,7 +78,9 @@ class ContextManager:
|
|
| 78 |
"""Get all messages for sending to LLM"""
|
| 79 |
return self.items
|
| 80 |
|
| 81 |
-
async def compact(
|
|
|
|
|
|
|
| 82 |
"""Remove old messages to keep history under target size"""
|
| 83 |
if (self.context_length <= self.max_context) or not self.items:
|
| 84 |
return
|
|
@@ -112,6 +114,7 @@ class ContextManager:
|
|
| 112 |
model=model_name,
|
| 113 |
messages=messages_to_summarize,
|
| 114 |
max_completion_tokens=self.compact_size,
|
|
|
|
| 115 |
)
|
| 116 |
summarized_message = Message(
|
| 117 |
role="assistant", content=response.choices[0].message.content
|
|
|
|
| 78 |
"""Get all messages for sending to LLM"""
|
| 79 |
return self.items
|
| 80 |
|
| 81 |
+
async def compact(
|
| 82 |
+
self, model_name: str, tool_specs: list[dict] | None = None
|
| 83 |
+
) -> None:
|
| 84 |
"""Remove old messages to keep history under target size"""
|
| 85 |
if (self.context_length <= self.max_context) or not self.items:
|
| 86 |
return
|
|
|
|
| 114 |
model=model_name,
|
| 115 |
messages=messages_to_summarize,
|
| 116 |
max_completion_tokens=self.compact_size,
|
| 117 |
+
tools=tool_specs,
|
| 118 |
)
|
| 119 |
summarized_message = Message(
|
| 120 |
role="assistant", content=response.choices[0].message.content
|
agent/core/agent_loop.py
CHANGED
|
@@ -6,6 +6,7 @@ import asyncio
|
|
| 6 |
import json
|
| 7 |
|
| 8 |
from litellm import ChatCompletionMessageToolCall, Message, ModelResponse, acompletion
|
|
|
|
| 9 |
from lmnr import observe
|
| 10 |
|
| 11 |
from agent.config import Config
|
|
@@ -108,13 +109,31 @@ def _needs_approval(
|
|
| 108 |
return False
|
| 109 |
|
| 110 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
class Handlers:
|
| 112 |
"""Handler functions for each operation type"""
|
| 113 |
|
| 114 |
@staticmethod
|
| 115 |
@observe(name="run_agent")
|
| 116 |
async def run_agent(
|
| 117 |
-
session: Session, text: str, max_iterations: int =
|
| 118 |
) -> str | None:
|
| 119 |
"""
|
| 120 |
Handle user input (like user_input_or_turn in codex.rs:1291)
|
|
@@ -141,6 +160,9 @@ class Handlers:
|
|
| 141 |
final_response = None
|
| 142 |
|
| 143 |
while iteration < max_iterations:
|
|
|
|
|
|
|
|
|
|
| 144 |
messages = session.context_manager.get_messages()
|
| 145 |
tools = session.tool_router.get_tool_specs_for_llm()
|
| 146 |
|
|
@@ -277,6 +299,14 @@ class Handlers:
|
|
| 277 |
|
| 278 |
iteration += 1
|
| 279 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 280 |
except Exception as e:
|
| 281 |
import traceback
|
| 282 |
|
|
@@ -288,18 +318,6 @@ class Handlers:
|
|
| 288 |
)
|
| 289 |
break
|
| 290 |
|
| 291 |
-
old_length = session.context_manager.context_length
|
| 292 |
-
await session.context_manager.compact(model_name=session.config.model_name)
|
| 293 |
-
new_length = session.context_manager.context_length
|
| 294 |
-
|
| 295 |
-
if new_length != old_length:
|
| 296 |
-
await session.send_event(
|
| 297 |
-
Event(
|
| 298 |
-
event_type="compacted",
|
| 299 |
-
data={"old_tokens": old_length, "new_tokens": new_length},
|
| 300 |
-
)
|
| 301 |
-
)
|
| 302 |
-
|
| 303 |
await session.send_event(
|
| 304 |
Event(
|
| 305 |
event_type="turn_complete",
|
|
@@ -319,20 +337,6 @@ class Handlers:
|
|
| 319 |
session.interrupt()
|
| 320 |
await session.send_event(Event(event_type="interrupted"))
|
| 321 |
|
| 322 |
-
@staticmethod
|
| 323 |
-
async def compact(session: Session) -> None:
|
| 324 |
-
"""Handle compact (like compact in codex.rs:1317)"""
|
| 325 |
-
old_length = session.context_manager.context_length
|
| 326 |
-
await session.context_manager.compact(model_name=session.config.model_name)
|
| 327 |
-
new_length = session.context_manager.context_length
|
| 328 |
-
|
| 329 |
-
await session.send_event(
|
| 330 |
-
Event(
|
| 331 |
-
event_type="compacted",
|
| 332 |
-
data={"removed": old_length, "remaining": new_length},
|
| 333 |
-
)
|
| 334 |
-
)
|
| 335 |
-
|
| 336 |
@staticmethod
|
| 337 |
async def undo(session: Session) -> None:
|
| 338 |
"""Handle undo (like undo in codex.rs:1314)"""
|
|
@@ -505,7 +509,8 @@ async def process_submission(session: Session, submission) -> bool:
|
|
| 505 |
return True
|
| 506 |
|
| 507 |
if op.op_type == OpType.COMPACT:
|
| 508 |
-
|
|
|
|
| 509 |
return True
|
| 510 |
|
| 511 |
if op.op_type == OpType.UNDO:
|
|
|
|
| 6 |
import json
|
| 7 |
|
| 8 |
from litellm import ChatCompletionMessageToolCall, Message, ModelResponse, acompletion
|
| 9 |
+
from litellm.exceptions import ContextWindowExceededError
|
| 10 |
from lmnr import observe
|
| 11 |
|
| 12 |
from agent.config import Config
|
|
|
|
| 109 |
return False
|
| 110 |
|
| 111 |
|
| 112 |
+
async def _compact_and_notify(session: Session) -> None:
|
| 113 |
+
"""Run compaction and send event if context was reduced."""
|
| 114 |
+
old_length = session.context_manager.context_length
|
| 115 |
+
tool_specs = session.tool_router.get_tool_specs_for_llm()
|
| 116 |
+
await session.context_manager.compact(
|
| 117 |
+
model_name=session.config.model_name,
|
| 118 |
+
tool_specs=tool_specs,
|
| 119 |
+
)
|
| 120 |
+
new_length = session.context_manager.context_length
|
| 121 |
+
if new_length != old_length:
|
| 122 |
+
await session.send_event(
|
| 123 |
+
Event(
|
| 124 |
+
event_type="compacted",
|
| 125 |
+
data={"old_tokens": old_length, "new_tokens": new_length},
|
| 126 |
+
)
|
| 127 |
+
)
|
| 128 |
+
|
| 129 |
+
|
| 130 |
class Handlers:
|
| 131 |
"""Handler functions for each operation type"""
|
| 132 |
|
| 133 |
@staticmethod
|
| 134 |
@observe(name="run_agent")
|
| 135 |
async def run_agent(
|
| 136 |
+
session: Session, text: str, max_iterations: int = 300
|
| 137 |
) -> str | None:
|
| 138 |
"""
|
| 139 |
Handle user input (like user_input_or_turn in codex.rs:1291)
|
|
|
|
| 160 |
final_response = None
|
| 161 |
|
| 162 |
while iteration < max_iterations:
|
| 163 |
+
# Compact before calling the LLM if context is near the limit
|
| 164 |
+
await _compact_and_notify(session)
|
| 165 |
+
|
| 166 |
messages = session.context_manager.get_messages()
|
| 167 |
tools = session.tool_router.get_tool_specs_for_llm()
|
| 168 |
|
|
|
|
| 299 |
|
| 300 |
iteration += 1
|
| 301 |
|
| 302 |
+
except ContextWindowExceededError:
|
| 303 |
+
# Force compact and retry this iteration
|
| 304 |
+
session.context_manager.context_length = (
|
| 305 |
+
session.context_manager.max_context + 1
|
| 306 |
+
)
|
| 307 |
+
await _compact_and_notify(session)
|
| 308 |
+
continue
|
| 309 |
+
|
| 310 |
except Exception as e:
|
| 311 |
import traceback
|
| 312 |
|
|
|
|
| 318 |
)
|
| 319 |
break
|
| 320 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 321 |
await session.send_event(
|
| 322 |
Event(
|
| 323 |
event_type="turn_complete",
|
|
|
|
| 337 |
session.interrupt()
|
| 338 |
await session.send_event(Event(event_type="interrupted"))
|
| 339 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 340 |
@staticmethod
|
| 341 |
async def undo(session: Session) -> None:
|
| 342 |
"""Handle undo (like undo in codex.rs:1314)"""
|
|
|
|
| 509 |
return True
|
| 510 |
|
| 511 |
if op.op_type == OpType.COMPACT:
|
| 512 |
+
# compact from the frontend
|
| 513 |
+
await _compact_and_notify(session)
|
| 514 |
return True
|
| 515 |
|
| 516 |
if op.op_type == OpType.UNDO:
|