class_docstr: (In preview) A class for generic conversable agents which can be configured as assistant or user proxy.
  
  After receiving each message, the agent will send a reply to the sender unless the msg is a termination msg.
  For example, AssistantAgent and UserProxyAgent are subclasses of this class,
  configured with different default settings.
  
  To modify auto reply, override `generate_reply` method.
  To disable/enable human response in every turn, set `human_input_mode` to "NEVER" or "ALWAYS".
  To modify the way to get human input, override `get_human_input` method.
  To modify the way to execute code blocks, single code block, or function call, override `execute_code_blocks`,
  `run_code`, and `execute_function` methods respectively.
  To customize the initial message when a conversation starts, override `generate_init_message` method.
class_docstr_tok: ["(","In","preview",")","A","class","for","generic","conversable","agents","which","can","be","configured","as","assistant","or","user","proxy",".","After","receiving","each","message",",","the","agent","will","send","a","reply","to","the","sender","unless","the","msg","is","a","termination","msg",".","For","example",",","AssistantAgent","and","UserProxyAgent","are","subclasses","of","this","class",",","configured","with","different","default","settings",".","To","modify","auto","reply",",","override","`","generate_reply","`","method",".","To","disable\/enable","human","response","in","every","turn",",","set","`","human_input_mode","`","to","``","NEVER","''","or","``","ALWAYS","''",".","To","modify","the","way","to","get","human","input",",","override","`","get_human_input","`","method",".","To","modify","the","way","to","execute","code","blocks",",","single","code","block",",","or","function","call",",","override","`","execute_code_blocks","`",",","`","run_code","`",",","and","`","execute_function","`","methods","respectively",".","To","customize","the","initial","message","when","a","conversation","starts",",","override","`","generate_init_message","`","method","."]
docstr: Calls any registered capability hooks to use and potentially modify the text of the last message,
  as long as the last message is not a function call or exit command.
docstr_tok: ["Calls","any","registered","capability","hooks","to","use","and","potentially","modify","the","text","of","the","last","message",",","as","long","as","the","last","message","is","not","a","function","call","or","exit","command","."]
code: def process_last_message(self, messages):
      """
      Calls any registered capability hooks to use and potentially modify the text of the last message,
      as long as the last message is not a function call or exit command.
      """
  
      # If any required condition is not met, return the original message list.
      hook_list = self.hook_lists[self.process_last_message]
      if len(hook_list) == 0:
          return messages  # No hooks registered.
      if messages is None:
          return None  # No message to process.
      if len(messages) == 0:
          return messages  # No message to process.
      last_message = messages[-1]
      if "function_call" in last_message:
          return messages  # Last message is a function call.
      if "context" in last_message:
          return messages  # Last message contains a context key.
      if "content" not in last_message:
          return messages  # Last message has no content.
      user_text = last_message["content"]
      if not isinstance(user_text, str):
          return messages  # Last message content is not a string. TODO: Multimodal agents will use a dict here.
      if user_text == "exit":
          return messages  # Last message is an exit command.
  
      # Call each hook (in order of registration) to process the user's message.
      processed_user_text = user_text
      for hook in hook_list:
          processed_user_text = hook(processed_user_text)
      if processed_user_text == user_text:
          return (
              messages  # No hooks actually modified the user's message.
          )
  
      # Replace the last user message with the expanded one.
      messages = messages.copy()
      messages[-1]["content"] = processed_user_text
      return messages
  
imports: import asyncio
  import copy
  import functools
  import inspect
  import json
  import logging
  import re
  from collections import defaultdict
  from typing import Any, Awaitable, Callable, Dict, List, Literal, Optional, Tuple, Type, TypeVar, Union
  from ..None import OpenAIWrapper
  from ..code_utils import DEFAULT_MODEL, UNKNOWN, content_str, execute_code, extract_code, infer_lang
  from ..function_utils import get_function_schema, load_basemodels_if_needed, serialize_to_str
  from .agent import Agent
  from .._pydantic import model_dump
label_desc: Use image node_id 48 for calling the ConversableAgent obj's underlying member method code with example usage: obj.process_last_message(messages) and returns: messages, messages, None, messages, messages, messages, messages, messages, messages, messages