Process a single inbound message. Args: msg: The inbound message to process. Returns: The response message, or None if no response needed.
(self, msg: InboundMessage)
| 159 | logger.info("Agent loop stopping") |
| 160 | |
| 161 | async def _process_message(self, msg: InboundMessage) -> OutboundMessage | None: |
| 162 | """ |
| 163 | Process a single inbound message. |
| 164 | |
| 165 | Args: |
| 166 | msg: The inbound message to process. |
| 167 | |
| 168 | Returns: |
| 169 | The response message, or None if no response needed. |
| 170 | """ |
| 171 | # Handle system messages (subagent announces) |
| 172 | # The chat_id contains the original "channel:chat_id" to route back to |
| 173 | if msg.channel == "system": |
| 174 | return await self._process_system_message(msg) |
| 175 | |
| 176 | preview = msg.content[:80] + "..." if len(msg.content) > 80 else msg.content |
| 177 | logger.info(f"Processing message from {msg.channel}:{msg.sender_id}: {preview}") |
| 178 | |
| 179 | # Get or create session |
| 180 | session = self.sessions.get_or_create(msg.session_key) |
| 181 | |
| 182 | # Update tool contexts |
| 183 | message_tool = self.tools.get("message") |
| 184 | if isinstance(message_tool, MessageTool): |
| 185 | message_tool.set_context(msg.channel, msg.chat_id) |
| 186 | |
| 187 | spawn_tool = self.tools.get("spawn") |
| 188 | if isinstance(spawn_tool, SpawnTool): |
| 189 | spawn_tool.set_context(msg.channel, msg.chat_id) |
| 190 | |
| 191 | cron_tool = self.tools.get("cron") |
| 192 | if isinstance(cron_tool, CronTool): |
| 193 | cron_tool.set_context(msg.channel, msg.chat_id) |
| 194 | |
| 195 | # Build initial messages (use get_history for LLM-formatted messages) |
| 196 | messages = self.context.build_messages( |
| 197 | history=session.get_history(), |
| 198 | current_message=msg.content, |
| 199 | media=msg.media if msg.media else None, |
| 200 | channel=msg.channel, |
| 201 | chat_id=msg.chat_id, |
| 202 | ) |
| 203 | |
| 204 | # Agent loop |
| 205 | iteration = 0 |
| 206 | final_content = None |
| 207 | |
| 208 | while iteration < self.max_iterations: |
| 209 | iteration += 1 |
| 210 | |
| 211 | # Call LLM |
| 212 | response = await self.provider.chat( |
| 213 | messages=messages, tools=self.tools.get_definitions(), model=self.model |
| 214 | ) |
| 215 | |
| 216 | # Handle tool calls |
| 217 | if response.has_tool_calls: |
| 218 | # Add assistant message with tool calls |
no test coverage detected