Actions of Stateful Agent
Developers also could create a class and enhance its functionality using ActionWeaver’s action decorators.
[1]:
import os
import openai
from openai import OpenAI
from actionweaver.llms import wrap
from actionweaver import action
from typing import List
openai.api_key = os.getenv("OPENAI_API_KEY")
[2]:
class AgentV0:
def __init__(self):
self.llm = wrap(OpenAI())
self.messages = []
self.times = []
def __call__(self, text):
self.messages += [{"role": "user", "content":text}]
return self.llm.create(model="gpt-3.5-turbo", messages=self.messages, actions = [self.get_current_time])
@action(name="GetCurrentTime")
def get_current_time(self) -> str:
"""
Use this for getting the current time in the specified time zone.
:return: A string representing the current time in the specified time zone.
"""
import datetime
current_time = datetime.datetime.now()
self.times += [str(current_time)]
return f"The current time is {current_time}"
agent = AgentV0()
[3]:
# You can invoke actions just like regular instance methods
agent.get_current_time() # Output: 'The current time is 20:34.'
agent("what time is it")
[3]:
ChatCompletion(id='chatcmpl-8e9w3bflg5iwHCenO7WGjSVZVSyvT', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='The current time is 2024-01-06 18:00:02.', role='assistant', function_call=None, tool_calls=None))], created=1704582003, model='gpt-3.5-turbo-0613', object='chat.completion', system_fingerprint=None, usage=CompletionUsage(completion_tokens=19, prompt_tokens=100, total_tokens=119))
Grouping and Extending Actions Through Inheritance
[5]:
class LangChainTools:
def __init__(self):
from langchain_community.tools.google_search.tool import GoogleSearchRun
from langchain_community.utilities.google_search import GoogleSearchAPIWrapper
self.google_search_api = GoogleSearchRun(api_wrapper=GoogleSearchAPIWrapper())
@action(name="GoogleSearch")
def google_search(self, query: str) -> str:
"""
Perform a Google search using the provided query.
:param query: The search query to be used for the Google search.
:return: The search results as a string.
"""
return self.google_search_api(query)
class AgentV1(AgentV0, LangChainTools):
def __init__(self):
AgentV0.__init__(self)
LangChainTools.__init__(self)
def __call__(self, text):
self.messages += [{"role": "user", "content":text}]
return self.llm.chat.completions.create(model="gpt-3.5-turbo", messages=self.messages, actions = [self.google_search])
agent = AgentV1()
agent("what happened today")
[5]:
ChatCompletion(id='chatcmpl-8e9wfhRvZ56jZc2PxU4Fd6d7Vy6jM', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content="Today's events include:\n\n1. Perugino: Adoration of the Magi - A featured event celebrating Epiphany, a major feast, held annually on this day.\n\n2. Legislative proceedings - Various legislative sessions and motions are taking place today in the Assembly and Senate.\n\n3. New York State Fair - There are numerous fun activities and events happening at the New York State Fair. You can plan your itinerary by selecting the events you are interested in.\n\n4. Senate events - You can watch or listen to today's Senate events, as well as access the TV schedule, media archive, and more.\n\n5. Campus Recreation - There is a Judo Club meeting at the UNL Coliseum in Temporary Conference Room 306.\n\n6. Apple Shortcut - There is a suggestion to use an Apple Shortcut to get a list of today's Calendar Events and put them into a Keyboard.\n\nPlease note that these are just a few highlights, and there may be additional events happening today.", role='assistant', function_call=None, tool_calls=None))], created=1704582041, model='gpt-3.5-turbo-0613', object='chat.completion', system_fingerprint=None, usage=CompletionUsage(completion_tokens=197, prompt_tokens=428, total_tokens=625))
We could use parameter orch when calling the chat completion API. This feature will allow us for more precise control over the specific set of tools available to the LLM during each interaction.
Example:
client.chat.completions.create(
messages = ...
actions=[a1, a2, a3], # First, LLM respond with either a1, a2 or a3, or text without action
# Define the orchestration logic for actions:
orch={
a1.name: [a2, a3], # If a1 is invoked, the next response will be either a2, a3 or a text response.
a2.name: a3, # If a2 is invoked, the next action will be a3
a3.name: [a4] # If a3 is invoked, the next response will be a4 or a text response.
a4.name: None # If a4 is invoked, the next response will guarantee to be a text message
}
)
For details please take a look at here
[5]:
class FileAgent(AgentV0):
@action(name="FileHandler")
def handle_file(self, instruction: str) -> str:
"""
Handles ALL user instructions related to file operations.
Args:
instruction (str): The user's instruction about file handling.
Returns:
str: The response to the user's question.
"""
print (f"Handling {instruction}")
return instruction
@action(name="ListFiles")
def list_all_files_in_repo(self, repo_path: str ='.') -> List:
"""
Lists all the files in the given repository.
:param repo_path: Path to the repository. Defaults to the current directory.
:return: List of file paths.
"""
print(f"list_all_files_in_repo: {repo_path}")
file_list = []
for root, _, files in os.walk(repo_path):
for file in files:
file_list.append(os.path.join(root, file))
break
return file_list
@action(name="ReadFile")
def read_from_file(self, file_path: str) -> str:
"""
Reads the content of a file and returns it as a string.
:param file_path: The path to the file that needs to be read.
:return: A string containing the content of the file.
"""
print(f"read_from_file: {file_path}")
with open(file_path, 'r') as file:
content = file.read()
return f"The file content: \n{content}"
def __call__(self, text):
self.messages += [{"role": "user", "content":text}]
return self.llm.create(model="gpt-3.5-turbo", messages=self.messages, actions = [self.handle_file], orch = {self.handle_file.name: [self.list_all_files_in_repo, self.read_from_file]})
[9]:
agent = FileAgent()
[10]:
agent("Take file action of [list all files in current repository]")
Handling list all files
list_all_files_in_repo: .
[10]:
ChatCompletion(id='chatcmpl-8cihLJHsfQZz3hPPHAyamQ7HVPm85', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content="Here are all the files in the current repository:\n\n1. langsmith.ipynb\n2. azure_tutorial-Copy1.ipynb\n3. parallel_tools.log\n4. untitled.md\n5. parallel_tools.ipynb\n6. network.html\n7. stateful_agent.ipynb\n8. huggingface.ipynb\n9. anyscale.ipynb\n10. ReAct.ipynb\n11. tracing.log\n12. structured_extraction.log\n13. quickstart.ipynb\n14. structured_extraction.ipynb\n15. azure_tutorial.ipynb\n16. litellm.ipynb\n17. cookbook.ipynb\n18. logging.ipynb\n19. nx.html\n20. agent.log\n21. logging-Copy1.ipynb\n22. orchestration.ipynb\n\nLet me know if there's anything else I can help with!", role='assistant', function_call=None, tool_calls=None))], created=1704238975, model='gpt-3.5-turbo-0613', object='chat.completion', system_fingerprint=None, usage=CompletionUsage(completion_tokens=190, prompt_tokens=306, total_tokens=496))