(messages: list)
| 652 | |
| 653 | # === SECTION: agent_loop === |
| 654 | def agent_loop(messages: list): |
| 655 | rounds_without_todo = 0 |
| 656 | while True: |
| 657 | # s06: compression pipeline |
| 658 | microcompact(messages) |
| 659 | if estimate_tokens(messages) > TOKEN_THRESHOLD: |
| 660 | print("[auto-compact triggered]") |
| 661 | messages[:] = auto_compact(messages) |
| 662 | # s08: drain background notifications |
| 663 | notifs = BG.drain() |
| 664 | if notifs: |
| 665 | txt = "\n".join(f"[bg:{n['task_id']}] {n['status']}: {n['result']}" for n in notifs) |
| 666 | messages.append({"role": "user", "content": f"<background-results>\n{txt}\n</background-results>"}) |
| 667 | # s10: check lead inbox |
| 668 | inbox = BUS.read_inbox("lead") |
| 669 | if inbox: |
| 670 | messages.append({"role": "user", "content": f"<inbox>{json.dumps(inbox, indent=2)}</inbox>"}) |
| 671 | # LLM call |
| 672 | response = client.messages.create( |
| 673 | model=MODEL, system=SYSTEM, messages=messages, |
| 674 | tools=TOOLS, max_tokens=8000, |
| 675 | ) |
| 676 | messages.append({"role": "assistant", "content": response.content}) |
| 677 | if response.stop_reason != "tool_use": |
| 678 | return |
| 679 | # Tool execution |
| 680 | results = [] |
| 681 | used_todo = False |
| 682 | manual_compress = False |
| 683 | for block in response.content: |
| 684 | if block.type == "tool_use": |
| 685 | if block.name == "compress": |
| 686 | manual_compress = True |
| 687 | handler = TOOL_HANDLERS.get(block.name) |
| 688 | try: |
| 689 | output = handler(**block.input) if handler else f"Unknown tool: {block.name}" |
| 690 | except Exception as e: |
| 691 | output = f"Error: {e}" |
| 692 | print(f"> {block.name}:") |
| 693 | print(str(output)[:200]) |
| 694 | results.append({"type": "tool_result", "tool_use_id": block.id, "content": str(output)}) |
| 695 | if block.name == "TodoWrite": |
| 696 | used_todo = True |
| 697 | # s03: nag reminder (only when todo workflow is active) |
| 698 | rounds_without_todo = 0 if used_todo else rounds_without_todo + 1 |
| 699 | if TODO.has_open_items() and rounds_without_todo >= 3: |
| 700 | results.append({"type": "text", "text": "<reminder>Update your todos.</reminder>"}) |
| 701 | messages.append({"role": "user", "content": results}) |
| 702 | # s06: manual compress |
| 703 | if manual_compress: |
| 704 | print("[manual compact]") |
| 705 | messages[:] = auto_compact(messages) |
| 706 | return |
| 707 | |
| 708 | |
| 709 | # === SECTION: repl === |
no test coverage detected