AgentExecutor not working with MultiPromptChain
Labels: name: area: agent, name: auto:improvement

### System Info

Windows 10
Python 3.9.7
langchain 0.0.236

### Who can help?

@hwchase17 @agola11 I have problem to make work together MultiPromptChain and AgentExecutor. Problem actually is trivial MultiPromptChain.destination_chains has type of Mapping[str, LLMChain] and AgentExecutor did not fit in this definition. Second AgentExecutor has output_keys = ["output"] but MultiPromptChain expects ["text"]. My workaround is to make custom class
class CustomRouterChain(MultiRouteChain):
    @property
    def output_keys(self) -> List[str]:
        return ["output"]

But it would be more user friendly if these two classes could work together out of the box according to your tutorials. Thanks.

### Information

- [ ] The official example notebooks/scripts
- [X] My own modified scripts

### Related Components

- [ ] LLMs/Chat Models
- [ ] Embedding Models
- [ ] Prompts / Prompt Templates / Prompt Selectors
- [ ] Output Parsers
- [ ] Document Loaders
- [ ] Vector Stores / Retrievers
- [ ] Memory
- [X] Agents / Agent Executors
- [ ] Tools / Toolkits
- [X] Chains
- [ ] Callbacks/Tracing
- [ ] Async

### Reproduction

from langchain.chains.router import MultiPromptChain
from langchain.chains import ConversationChain
from langchain.chains.llm import LLMChain
from langchain.prompts import PromptTemplate
from langchain.agents import tool

from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.llms import OpenAI

physics_template = """You are a very smart physics professor. \
You are great at answering questions about physics in a concise and easy to understand manner. \
When you don't know the answer to a question you admit that you don't know.

Here is a question:
{input}"""


math_template = """You are a very good mathematician. You are great at answering math questions. \
You are so good because you are able to break down hard problems into their component parts, \
answer the component parts, and then put them together to answer the broader question.

Here is a question:
{input}"""

@tool
def text_length(input: str) -> int:
    """This tool returns exact text length. Use it when you need to measure text length.
    It inputs text string."""
    return len(input)

llm = OpenAI()
agent = initialize_agent([text_length], llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)

prompt_infos = [
    {
        "name": "physics",
        "description": "Good for answering questions about physics",
        "prompt_template": physics_template,
        "agent": None,
    },
    {
        "name": "math",
        "description": "Good for answering math questions",
        "prompt_template": math_template,
        "agent": None,
    },
    {
        "name": "text_length",
        "description": "Good for answering questions about text length",
        "prompt_template": "{input}",
        "agent": agent,
    },
]

destination_chains = {}
for p_info in prompt_infos:
    name = p_info["name"]
    prompt_template = p_info["prompt_template"]
    prompt = PromptTemplate(template=prompt_template, input_variables=["input"])
    chain = LLMChain(llm=llm, prompt=prompt)
    if p_info["agent"] is None:
        destination_chains[name] = chain
    else:
        destination_chains[name] = p_info["agent"]
default_chain = ConversationChain(llm=llm, output_key="text")

from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser
from langchain.chains.router.multi_prompt_prompt import MULTI_PROMPT_ROUTER_TEMPLATE

destinations = [f"{p['name']}: {p['description']}" for p in prompt_infos]
destinations_str = "\n".join(destinations)
router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(destinations=destinations_str)
router_prompt = PromptTemplate(
    template=router_template,
    input_variables=["input"],
    output_parser=RouterOutputParser(),
)
router_chain = LLMRouterChain.from_llm(llm, router_prompt)

chain = MultiPromptChain(
    router_chain=router_chain,
    destination_chains=destination_chains,
    default_chain=default_chain,
    verbose=True,
)

print(chain.run("What is black body radiation?"))
print(chain.run("What is the first prime number greater than 40 such that one plus the prime number is divisible by 3"))
print(chain.run("What length have following text: one, two, three, four"))

### Expected behavior

Runs without errors.