start with adapting example, and seperating out tooling into file
This commit is contained in:
parent
4fb6ada4e2
commit
bbd62ce4fc
11
hw2/.requirements.txt
Normal file
11
hw2/.requirements.txt
Normal file
@ -0,0 +1,11 @@
|
||||
langchain-community
|
||||
langchain
|
||||
langchain_openai
|
||||
python-dotenv
|
||||
firecrawl-py
|
||||
chromadb
|
||||
langchainhub
|
||||
dnspython
|
||||
validators
|
||||
google-search-results
|
||||
langchain-experimental
|
24
hw2/README.md
Normal file
24
hw2/README.md
Normal file
@ -0,0 +1,24 @@
|
||||
## HW2 for gensec
|
||||
|
||||
|
||||
### Enviornment
|
||||
Install python3, then run the following:
|
||||
```
|
||||
pip install -r requirements.txt
|
||||
cp .env.example .env
|
||||
```
|
||||
After, populate .env with your OPENAI_API_KEY and FIREWALL_API_KEY
|
||||
|
||||
|
||||
### Running
|
||||
```
|
||||
python3 app.py
|
||||
```
|
||||
|
||||
### Example Queries
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
|
||||
Enjoy!
|
42
hw2/app.py
42
hw2/app.py
@ -0,0 +1,42 @@
|
||||
from langchain import hub
|
||||
from langchain.agents import AgentExecutor, create_react_agent, load_tools
|
||||
from langchain.tools import tool
|
||||
from langchain_openai import ChatOpenAI
|
||||
from dotenv import load_dotenv
|
||||
from tools import lookup_ip, lookup_name
|
||||
from langsmith import Client
|
||||
|
||||
"""
|
||||
This is the main runner of the custom agent. Agent tools are defined seperatly and imported from tools.py
|
||||
|
||||
So far, wholly adapted from https://github.com/wu4f/cs410g-src/blob/main/04_Agents/07_tools_custom_agent.py
|
||||
|
||||
"""
|
||||
|
||||
load_dotenv()
|
||||
#os.environ["LANGCHAIN_TRACING_V2"] = "true"
|
||||
#os.environ["LANGCHAIN_PROJECT"] = f"LangSmith Introduction"
|
||||
#os.environ["LANGCHAIN_ENDPOINT"] = "https://api.smith.langchain.com"
|
||||
#client = Client()
|
||||
llm = ChatOpenAI(model_name="gpt-4-turbo", temperature=0)
|
||||
|
||||
tools = load_tools(["serpapi", "terminal"], allow_dangerous_tools=True)
|
||||
tools.extend([lookup_name, lookup_ip])
|
||||
|
||||
base_prompt = hub.pull("langchain-ai/react-agent-template")
|
||||
prompt = base_prompt.partial(instructions="Answer the user's request utilizing at most 8 tool calls")
|
||||
agent = create_react_agent(llm,tools,prompt)
|
||||
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
|
||||
print("Welcome to my application. I am configured with these tools:")
|
||||
for tool in agent_executor.tools:
|
||||
print(f' Tool: {tool.name} = {tool.description}')
|
||||
while True:
|
||||
line = input("llm>> ")
|
||||
try:
|
||||
if line:
|
||||
result = agent_executor.invoke({"input":line})
|
||||
print(result)
|
||||
else:
|
||||
break
|
||||
except Exception as e:
|
||||
print(e)
|
8
hw2/requirements.txt
Normal file
8
hw2/requirements.txt
Normal file
@ -0,0 +1,8 @@
|
||||
langchain
|
||||
langchain_openai
|
||||
langchain-experimental
|
||||
langchainhub
|
||||
python-dotenv
|
||||
dnspython
|
||||
validators
|
||||
google-search-results
|
44
hw2/tools.py
Normal file
44
hw2/tools.py
Normal file
@ -0,0 +1,44 @@
|
||||
from langchain_core.pydantic_v1 import BaseModel, Field, root_validator
|
||||
from langchain.tools import tool
|
||||
import dns.resolver, dns.reversename
|
||||
import validators
|
||||
import validators
|
||||
|
||||
"""
|
||||
Tools to be run by my custom agent.
|
||||
|
||||
So far, these are the same tooling provided by the example in https://github.com/wu4f/cs410g-src/blob/main/04_Agents/07_tools_custom_agent.py,
|
||||
But I will be updating this to build my own tooling
|
||||
"""
|
||||
|
||||
class LookupNameInput(BaseModel):
|
||||
hostname: str = Field(description="Should be a hostname such as www.google.com")
|
||||
@root_validator
|
||||
def is_dns_address(cls, values: dict[str,any]) -> str:
|
||||
if validators.domain(values.get("hostname")):
|
||||
return values
|
||||
raise ValueError("Malformed hostname")
|
||||
class LookupIPInput(BaseModel):
|
||||
address: str = Field(description="Should be an IP address such as 208.91.197.27 or 143.95.239.83")
|
||||
@root_validator
|
||||
def is_ip_address(cls, values: dict[str,any]) -> str:
|
||||
if validators.ip_address.ipv4(values.get("address")):
|
||||
return values
|
||||
raise ValueError("Malformed IP address")
|
||||
|
||||
|
||||
@tool("lookup_name",args_schema=LookupNameInput, return_direct=False)
|
||||
def lookup_name(hostname):
|
||||
"""Given a DNS hostname, it will return its IPv4 addresses"""
|
||||
result = dns.resolver.resolve(hostname, 'A')
|
||||
res = [ r.to_text() for r in result ]
|
||||
return res[0]
|
||||
|
||||
|
||||
@tool("lookup_ip", args_schema=LookupIPInput, return_direct=False)
|
||||
def lookup_ip(address):
|
||||
"""Given an IP address, returns names associated with it"""
|
||||
n = dns.reversename.from_address(address)
|
||||
result = dns.resolver.resolve(n, 'PTR')
|
||||
res = [ r.to_text() for r in result ]
|
||||
return res[0]
|
Reference in New Issue
Block a user