mirror of
https://github.com/Mintplex-Labs/langchain-python.git
synced 2026-07-19 13:26:32 -04:00
f23b3ceb49
consolidating logic for when a chain is able to run with single input text, single output text open to feedback on naming, logic, usefulness
95 lines
2.8 KiB
Python
95 lines
2.8 KiB
Python
"""Implement an LLM driven browser."""
|
|
from typing import Dict, List
|
|
|
|
from pydantic import BaseModel, Extra
|
|
|
|
from langchain.chains.base import Chain
|
|
from langchain.chains.llm import LLMChain
|
|
from langchain.chains.natbot.prompt import PROMPT
|
|
from langchain.llms.base import LLM
|
|
from langchain.llms.openai import OpenAI
|
|
|
|
|
|
class NatBotChain(Chain, BaseModel):
|
|
"""Implement an LLM driven browser.
|
|
|
|
Example:
|
|
.. code-block:: python
|
|
|
|
from langchain import NatBotChain, OpenAI
|
|
natbot = NatBotChain(llm=OpenAI(), objective="Buy me a new hat.")
|
|
"""
|
|
|
|
llm: LLM
|
|
"""LLM wrapper to use."""
|
|
objective: str
|
|
"""Objective that NatBot is tasked with completing."""
|
|
input_url_key: str = "url" #: :meta private:
|
|
input_browser_content_key: str = "browser_content" #: :meta private:
|
|
previous_command: str = "" #: :meta private:
|
|
output_key: str = "command" #: :meta private:
|
|
|
|
class Config:
|
|
"""Configuration for this pydantic object."""
|
|
|
|
extra = Extra.forbid
|
|
arbitrary_types_allowed = True
|
|
|
|
@classmethod
|
|
def from_default(cls, objective: str) -> "NatBotChain":
|
|
"""Load with default LLM."""
|
|
llm = OpenAI(temperature=0.5, best_of=10, n=3, max_tokens=50)
|
|
return cls(llm=llm, objective=objective)
|
|
|
|
@property
|
|
def input_keys(self) -> List[str]:
|
|
"""Expect url and browser content.
|
|
|
|
:meta private:
|
|
"""
|
|
return [self.input_url_key, self.input_browser_content_key]
|
|
|
|
@property
|
|
def output_keys(self) -> List[str]:
|
|
"""Return command.
|
|
|
|
:meta private:
|
|
"""
|
|
return [self.output_key]
|
|
|
|
def _call(self, inputs: Dict[str, str]) -> Dict[str, str]:
|
|
llm_executor = LLMChain(prompt=PROMPT, llm=self.llm)
|
|
url = inputs[self.input_url_key]
|
|
browser_content = inputs[self.input_browser_content_key]
|
|
llm_cmd = llm_executor.predict(
|
|
objective=self.objective,
|
|
url=url[:100],
|
|
previous_command=self.previous_command,
|
|
browser_content=browser_content[:4500],
|
|
)
|
|
llm_cmd = llm_cmd.strip()
|
|
self.previous_command = llm_cmd
|
|
return {self.output_key: llm_cmd}
|
|
|
|
def execute(self, url: str, browser_content: str) -> str:
|
|
"""Figure out next browser command to run.
|
|
|
|
Args:
|
|
url: URL of the site currently on.
|
|
browser_content: Content of the page as currently displayed by the browser.
|
|
|
|
Returns:
|
|
Next browser command to run.
|
|
|
|
Example:
|
|
.. code-block:: python
|
|
|
|
browser_content = "...."
|
|
llm_command = natbot.run("www.google.com", browser_content)
|
|
"""
|
|
_inputs = {
|
|
self.input_url_key: url,
|
|
self.input_browser_content_key: browser_content,
|
|
}
|
|
return self(_inputs)[self.output_key]
|