()
| 384 | chunk_responses = [] |
| 385 | |
| 386 | async def process_chunks(): |
| 387 | nonlocal memory_entries, all_passages, chunk_responses |
| 388 | |
| 389 | for i, chunk in enumerate(chunks): |
| 390 | chunk_start = time.time() |
| 391 | try: |
| 392 | # Send message to MIRIX for memory extraction |
| 393 | # MIRIX's MetaAgent will automatically route content to appropriate |
| 394 | # memory components (Episodic, Semantic, Procedural, etc.) |
| 395 | # NOTE: We don't pass user_id here - MIRIX uses the LocalClient's |
| 396 | # default user which was created during initialization. |
| 397 | response = await self._client.send_message( |
| 398 | agent_id=self._meta_agent.id, |
| 399 | role="user", |
| 400 | message=chunk, |
| 401 | ) |
| 402 | |
| 403 | chunk_latency = time.time() - chunk_start |
| 404 | |
| 405 | # Extract usage statistics from MirixResponse |
| 406 | if response and hasattr(response, 'usage') and response.usage: |
| 407 | self._record_mirix_usage(response.usage, chunk_latency) |
| 408 | |
| 409 | # Record passage info for logging |
| 410 | passage_info = { |
| 411 | "chunk_index": i, |
| 412 | "chunk_tokens": self.count_tokens(chunk), |
| 413 | "content_preview": chunk[:500] + "..." if len(chunk) > 500 else chunk, |
| 414 | "latency": round(chunk_latency, 3), |
| 415 | } |
| 416 | |
| 417 | # Extract response messages for logging |
| 418 | # MIRIX MirixResponse has messages as List[Union[ToolCallMessage, ToolReturnMessage, AssistantMessage, ...]] |
| 419 | # Each message has 'message_type' field to identify the type |
| 420 | # - ToolCallMessage: has tool_call.name, tool_call.arguments (JSON string) |
| 421 | # - ToolReturnMessage: has tool_return (string) |
| 422 | # - AssistantMessage: has content (string or list) |
| 423 | response_messages = [] |
| 424 | if response and hasattr(response, 'messages'): |
| 425 | logger.debug(f"[MIRIXAgent] Response has {len(response.messages)} messages") |
| 426 | for msg in response.messages: |
| 427 | msg_type = getattr(msg, 'message_type', None) |
| 428 | if hasattr(msg_type, 'value'): |
| 429 | msg_type = msg_type.value |
| 430 | |
| 431 | msg_content = "" |
| 432 | func_name = "" |
| 433 | func_args = {} |
| 434 | |
| 435 | if msg_type == 'tool_call_message': |
| 436 | # ToolCallMessage has tool_call with name and arguments |
| 437 | tool_call = getattr(msg, 'tool_call', None) |
| 438 | if tool_call: |
| 439 | func_name = getattr(tool_call, 'name', 'unknown') |
| 440 | args_str = getattr(tool_call, 'arguments', '{}') |
| 441 | try: |
| 442 | if isinstance(args_str, str): |
| 443 | func_args = json.loads(args_str) if args_str else {} |
nothing calls this directly
no test coverage detected