class_docstr: Encapsulates the Streamlit UI for a single LLM 'thought' during a LangChain Agent
  run. Each tool usage gets its own thought; and runs also generally having a
  concluding thought where the Agent determines that it has an answer to the prompt.
  
  Each thought gets its own expander UI.
class_docstr_tok: ["Encapsulates","the","Streamlit","UI","for","a","single","LLM","'thought","'","during","a","LangChain","Agent","run",".","Each","tool","usage","gets","its","own","thought",";","and","runs","also","generally","having","a","concluding","thought","where","the","Agent","determines","that","it","has","an","answer","to","the","prompt",".","Each","thought","gets","its","own","expander","UI","."]
code: def on_tool_start(
      self, serialized: Dict[str, Any], input_str: str, **kwargs: Any
  ) -> None:
      # Called with the name of the tool we're about to run (in `serialized[name]`),
      # and its input. We change our container's label to be the tool name.
      self._state = LLMThoughtState.RUNNING_TOOL
      tool_name = serialized["name"]
      self._last_tool = ToolRecord(name=tool_name, input_str=input_str)
      self._container.update(
          label=self._labeler.get_tool_label(
              self._last_tool, is_complete=False
          ),
          state="running",
      )
      if len(input_str) > MAX_TOOL_INPUT_STR_LENGTH:
          # output is printed later in on_tool_end
          self._container.markdown(
              f"**Input:**\n\n{input_str}\n\n**Output:**"
          )
  
imports: from __future__ import annotations
  import time
  from enum import Enum
  from typing import TYPE_CHECKING, Any, Dict, List, NamedTuple, Optional
  from langchain.callbacks.base import BaseCallbackHandler
  from langchain.schema import AgentAction, AgentFinish, LLMResult
  from streamlit.runtime.metrics_util import gather_metrics
label_desc: Use image node_id 9 for calling the LLMThought obj's underlying member method code with example usage: obj.on_tool_start(serialized, input_str) without return types