custom BaseCallbackHandler in STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION agent not calling on_tool_end
Labels: name: area: agent, name: auto:bug

### System Info

`langchain 0.0.235`

I wrote my own callback handler
`class ChatHandler(BaseCallbackHandler):`
which includes the function
   ```
def on_tool_end(self, output: str, observation_prefix: Optional[str] = None, llm_prefix: Optional[str] = None, **kwargs: Any) -> Any:
        """Run when tool ends running."""
        if observation_prefix is not None:
            print("OBSERVATION: "+str(output))
        if llm_prefix is not None:
            print("llm_prefix: "+str(output))
```
as inspired by the source of the file callback handler https://api.python.langchain.com/en/latest/_modules/langchain/callbacks/file.html#FileCallbackHandler .

I have a STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION agent. My goal is to capture the observation, it seems not to call the function. The handler works fine for other functions.

I attach the handler like this:
```
cHandler = chatHandler.ChatHandler()
cManager = manager.BaseCallbackManager(handlers=[cHandler])
initialize_agent(tools,llm, callback_manager=cManager, ...
```

Am I using the wrong callback manager?

### Who can help?

@agola11
@hwchase17

### Information

- [ ] The official example notebooks/scripts
- [X] My own modified scripts

### Related Components

- [X] LLMs/Chat Models
- [ ] Embedding Models
- [ ] Prompts / Prompt Templates / Prompt Selectors
- [ ] Output Parsers
- [ ] Document Loaders
- [ ] Vector Stores / Retrievers
- [ ] Memory
- [X] Agents / Agent Executors
- [ ] Tools / Toolkits
- [ ] Chains
- [X] Callbacks/Tracing
- [ ] Async

### Reproduction

```
import os
from langchain.agents import initialize_agent
from langchain.callbacks import manager
from langchain.chat_models import AzureChatOpenAI
from langchain.agents import AgentType
from langchain.callbacks.base import BaseCallbackHandler
from langchain.schema import AgentAction
from typing import Any, Dict, List, Optional

# ENVIRONMENT KEYS; OPENAI_API_KEY
import json
vals = json.load(open("../local.settings.json"))['Values']
for k in vals.keys():
    os.environ[k] = vals[k]

from langchain.agents import Tool
def a(b):
    print('tool used wow')
    return "frogimage.png"
t = Tool( 
        name="Search things online", #search location by vague name
        func=a,
        description="Use this tool to search and find things online.",
        return_direct=False
    )

BASE_URL = "https://XXX.openai.azure.com"
DEPLOYMENT_NAME = "gpt-35-turbo-16k"
model = AzureChatOpenAI(
    openai_api_base=BASE_URL,
    openai_api_version="2023-05-15",
    deployment_name=DEPLOYMENT_NAME,
    openai_api_key=os.environ["OPENAI_API_KEY"],
    openai_api_type="azure",
    temperature=0.0
)

class TestHandler(BaseCallbackHandler):
    def on_tool_end(self, output: str, observation_prefix: Optional[str] = None, llm_prefix: Optional[str] = None, **kwargs: Any) -> Any:
        """Run when tool ends running."""
        print("on_tool_end")

    def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any:
        """Run on agent action."""
        print("on_agent_action")

cHandler = TestHandler()
cManager = manager.BaseCallbackManager(handlers=[cHandler])

agent_chain = initialize_agent([t],model, callback_manager=cManager, agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, verbose=True)

agent_chain("search frog images online")
```
outputs:

> > Entering new AgentExecutor chain...
> on_agent_action
> Action:
> ```
> {
>   "action": "Search things online",
>   "action_input": "frog images"
> }
> ```tool used wow
> 
> Observation: frogimage.png
> Thought:I found an image of a frog. Here it is:
> Action:
> ```
> {
>   "action": "Final Answer",
>   "action_input": "frogimage.png"
> }
> ```
> 
> 
> > Finished chain.
> {'input': 'search frog images online', 'output': 'frogimage.png'}


### Expected behavior

The function on_tool_end is called when the agent has used a tool, printing on_tool_end, but only on_agent_action is printed.