bearly tool (#11812)

pull/10532/head^2
Harrison Chase 9 months ago committed by GitHub
parent 4a2f0c51a1
commit a506302772
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,399 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "7d143c73",
"metadata": {},
"source": [
"# Bearly Code Interpreter\n",
"\n",
"> Bearly Code Interpreter allows for remote execution of code. This makes it perfect for a code sandbox for agents, to allow for safe implementation of things like Code Interpreter"
]
},
{
"cell_type": "markdown",
"id": "3f99f7c9",
"metadata": {},
"source": [
"In this notebook, we will create an example of an agent that uses Bearly to interact with data"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "cd5b952e",
"metadata": {},
"outputs": [],
"source": [
"from langchain.chat_models import ChatOpenAI\n",
"from langchain.tools import BearlyInterpreterTool\n",
"from langchain.agents import initialize_agent, AgentType"
]
},
{
"cell_type": "markdown",
"id": "7bd0b610",
"metadata": {},
"source": [
"Initialize the interpreter"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "32f1543f",
"metadata": {},
"outputs": [],
"source": [
"bearly_tool = BearlyInterpreterTool(api_key=\"...\")"
]
},
{
"cell_type": "markdown",
"id": "ac5c88ce",
"metadata": {},
"source": [
"Let's add some files to the the sandbox"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "b5586858",
"metadata": {},
"outputs": [],
"source": [
"bearly_tool.add_file(\n",
" source_path=\"sample_data/Bristol.pdf\", \n",
" target_path=\"Bristol.pdf\", \n",
" description=\"\"\n",
")\n",
"bearly_tool.add_file(\n",
" source_path=\"sample_data/US_GDP.csv\", \n",
" target_path=\"US_GDP.csv\", \n",
" description=\"\"\n",
")"
]
},
{
"cell_type": "markdown",
"id": "b5720471",
"metadata": {},
"source": [
"Create a `Tool` object now. This is necessary, because we added the files, and we want the tool description to reflect that"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "557a073c",
"metadata": {},
"outputs": [],
"source": [
"tools = [bearly_tool.as_tool()]"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "58e61295",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'bearly_interpreter'"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tools[0].name"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "483569b6",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Evaluates python code in a sandbox environment. The environment resets on every execution. You must send the whole script every time and print your outputs. Script should be pure python code that can be evaluated. It should be in python format NOT markdown. The code should NOT be wrapped in backticks. All python packages including requests, matplotlib, scipy, numpy, pandas, etc are available. If you have any files outputted write them to \"output/\" relative to the execution \n",
"path. Output can only be read from the directory, stdout, and stdin. Do not use things like plot.show() as it will \n",
"not work instead write them out `output/` and a link to the file will be returned. print() any output and results so you can capture the output.\n",
"\n",
"The following files available in the evaluation environment:\n",
"- path: `Bristol.pdf` \n",
" first four lines: [] \n",
" description: ``\n",
"- path: `US_GDP.csv` \n",
" first four lines: ['DATE,GDP\\n', '1947-01-01,243.164\\n', '1947-04-01,245.968\\n', '1947-07-01,249.585\\n'] \n",
" description: ``\n"
]
}
],
"source": [
"print(tools[0].description)"
]
},
{
"cell_type": "markdown",
"id": "24f952d5",
"metadata": {},
"source": [
"Initialize an agent"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "71831ea8",
"metadata": {},
"outputs": [],
"source": [
"llm = ChatOpenAI(model=\"gpt-4\", temperature=0)\n",
"agent = initialize_agent(\n",
" tools, llm, agent=AgentType.OPENAI_FUNCTIONS, verbose=True, handle_parsing_errors=True\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "b4f98540",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
"\u001b[32;1m\u001b[1;3m\n",
"Invoking: `bearly_interpreter` with `{'python_code': \"import PyPDF2\\n\\n# Open the PDF file in read-binary mode\\npdf_file = open('Bristol.pdf', 'rb')\\n\\n# Create a PDF file reader object\\npdf_reader = PyPDF2.PdfFileReader(pdf_file)\\n\\n# Get the text from page 3\\npage_obj = pdf_reader.getPage(2)\\npage_text = page_obj.extractText()\\n\\n# Close the PDF file\\npdf_file.close()\\n\\nprint(page_text)\"}`\n",
"\n",
"\n",
"\u001b[0m\u001b[36;1m\u001b[1;3m{'stdout': '', 'stderr': 'Traceback (most recent call last):\\n File \"/tmp/project/main.py\", line 7, in <module>\\n pdf_reader = PyPDF2.PdfFileReader(pdf_file)\\n File \"/venv/lib/python3.10/site-packages/PyPDF2/_reader.py\", line 1974, in __init__\\n deprecation_with_replacement(\"PdfFileReader\", \"PdfReader\", \"3.0.0\")\\n File \"/venv/lib/python3.10/site-packages/PyPDF2/_utils.py\", line 369, in deprecation_with_replacement\\n deprecation(DEPR_MSG_HAPPENED.format(old_name, removed_in, new_name))\\n File \"/venv/lib/python3.10/site-packages/PyPDF2/_utils.py\", line 351, in deprecation\\n raise DeprecationError(msg)\\nPyPDF2.errors.DeprecationError: PdfFileReader is deprecated and was removed in PyPDF2 3.0.0. Use PdfReader instead.\\n', 'fileLinks': [], 'exitCode': 1}\u001b[0m\u001b[32;1m\u001b[1;3m\n",
"Invoking: `bearly_interpreter` with `{'python_code': \"from PyPDF2 import PdfReader\\n\\n# Open the PDF file\\npdf = PdfReader('Bristol.pdf')\\n\\n# Get the text from page 3\\npage = pdf.pages[2]\\npage_text = page.extract_text()\\n\\nprint(page_text)\"}`\n",
"\n",
"\n",
"\u001b[0m\u001b[36;1m\u001b[1;3m{'stdout': '1 COVID-19 at Work: \\nExposing h ow risk is assessed and its consequences in England and Sweden \\nPeter Andersson and Tonia Novitz* \\n1.Introduction\\nT\\nhe crisis which arose suddenly at the beginning of 2020 relating to coronavirus was immediately \\ncentred on risk. Predictions ha d to be made swiftly regarding how it would spread, who it might \\naffect and what measures could be taken to prevent exposure in everyday so cial interaction, \\nincluding in the workplace. This was in no way a straightforward assessment, because initially so \\nmuch was unknown. Those gaps in our knowledge have since, partially, been ameliorated. It is \\nevident that not all those exposed to COVID-19 become ill, and many who contract the virus remain \\nasymptomatic, so that the odds on becoming seriously ill may seem small. But those odds are also stacked against certain segments of the population. The likelihood of mortality and morbidity are associated with age and ethnicity as well as pre -existing medical conditions (such as diabetes), but \\nalso with poverty which correlates to the extent of exposure in certain occupations.\\n1 Some risks \\narise which remain less predictable, as previously healthy people with no signs of particular \\nvulnerability can experience serious long term illness as well and in rare cases will even die.2 \\nPerceptions of risk in different countries have led to particular measures taken, ranging from handwashing to social distancing, use of personal protective equipment (PPE) such as face coverings, and even lockdowns which have taken various forms.\\n3 Use of testing and vaccines \\nalso bec ame part of the remedial landscape, with their availability and administration being \\n*This paper is part of the project An i nclusive and sustainable Swedish labour law the way\\nahead, dnr. 2017-03134 financed by the Swedish research council led by Petra Herzfeld Olssonat Stockholm University. The authors would like to thank her and other participants, Niklas\\nBruun and Erik Sjödin for their helpful comments on earlier drafts. A much shorter article titled\\nRisk Assessment and COVID -19: Systems at work (or not) in England and Sweden is published\\nin the (2021) Comparative Labour and Social Security Review /\\n Revue de droit comparé du\\ntravail et de la sécurité sociale.\\n1 Public Health England, Disparities in the risk and outcomes of COVID-19 (2 June 2020 -\\nhttps://assets.publishing.service.gov.uk/government/uploads/ system /uploads/attachment_data/file\\n/890258/disparities_review.pdf.\\n2 Nisreen A. Alwan, Track COVID- 19 sickness, not just positive tests and deaths ( 2020)\\n584.7820 Nature 170- 171; Elisabeth Mahase, Covid-19: What do we know about “long covid”?\\n(2020) BMJ 370.\\n3 Sarah Dryhurst, Claudia R. Schneider, John Kerr, Alexandra LJ Freeman, Gabriel Recchia,\\nAnne Marthe Van Der Bles, David Spiegelhalter, and Sander van der Linden, Risk perceptionsof COVID-19 around the world (2020) 23(7- 8) Journal of Risk Research 994; Wändi Bruine de\\nBruin, and Daniel Bennett, Relationships between initial COVID -19 risk perceptions and\\nprotective health behaviors: A national survey (2020) 59(2) American Journal of Prev entive\\nMedicine 157; and Simon Deakin and Gaofeng Meng, The Governance of Covid- 19:\\nAnthropogenic Risk, Evolutionary Learning, and the Future of the Social State (2020)49(4) Industrial Law Journal 539.\\n', 'stderr': '', 'fileLinks': [], 'exitCode': 0}\u001b[0m\u001b[32;1m\u001b[1;3mThe text on page 3 of the PDF is:\n",
"\n",
"\"1 COVID-19 at Work: \n",
"Exposing how risk is assessed and its consequences in England and Sweden \n",
"Peter Andersson and Tonia Novitz* \n",
"1.Introduction\n",
"The crisis which arose suddenly at the beginning of 2020 relating to coronavirus was immediately \n",
"centred on risk. Predictions had to be made swiftly regarding how it would spread, who it might \n",
"affect and what measures could be taken to prevent exposure in everyday social interaction, \n",
"including in the workplace. This was in no way a straightforward assessment, because initially so \n",
"much was unknown. Those gaps in our knowledge have since, partially, been ameliorated. It is \n",
"evident that not all those exposed to COVID-19 become ill, and many who contract the virus remain \n",
"asymptomatic, so that the odds on becoming seriously ill may seem small. But those odds are also stacked against certain segments of the population. The likelihood of mortality and morbidity are associated with age and ethnicity as well as pre-existing medical conditions (such as diabetes), but \n",
"also with poverty which correlates to the extent of exposure in certain occupations.\n",
"1 Some risks \n",
"arise which remain less predictable, as previously healthy people with no signs of particular \n",
"vulnerability can experience serious long term illness as well and in rare cases will even die.2 \n",
"Perceptions of risk in different countries have led to particular measures taken, ranging from handwashing to social distancing, use of personal protective equipment (PPE) such as face coverings, and even lockdowns which have taken various forms.\n",
"3 Use of testing and vaccines \n",
"also became part of the remedial landscape, with their availability and administration being \n",
"*This paper is part of the project An inclusive and sustainable Swedish labour law the way\n",
"ahead, dnr. 2017-03134 financed by the Swedish research council led by Petra Herzfeld Olssonat Stockholm University. The authors would like to thank her and other participants, Niklas\n",
"Bruun and Erik Sjödin for their helpful comments on earlier drafts. A much shorter article titled\n",
"Risk Assessment and COVID -19: Systems at work (or not) in England and Sweden is published\n",
"in the (2021) Comparative Labour and Social Security Review /\n",
" Revue de droit comparé du\n",
"travail et de la sécurité sociale.\n",
"1 Public Health England, Disparities in the risk and outcomes of COVID-19 (2 June 2020 -\n",
"https://assets.publishing.service.gov.uk/government/uploads/ system /uploads/attachment_data/file\n",
"/890258/disparities_review.pdf.\n",
"2 Nisreen A. Alwan, Track COVID- 19 sickness, not just positive tests and deaths ( 2020)\n",
"584.7820 Nature 170- 171; Elisabeth Mahase, Covid-19: What do we know about “long covid”?\n",
"(2020) BMJ 370.\n",
"3 Sarah Dryhurst, Claudia R. Schneider, John Kerr, Alexandra LJ Freeman, Gabriel Recchia,\n",
"Anne Marthe Van Der Bles, David Spiegelhalter, and Sander van der Linden, Risk perceptionsof COVID-19 around the world (2020) 23(7- 8) Journal of Risk Research 994; Wändi Bruine de\n",
"Bruin, and Daniel Bennett, Relationships between initial COVID -19 risk perceptions and\n",
"protective health behaviors: A national survey (2020) 59(2) American Journal of Preventive\n",
"Medicine 157; and Simon Deakin and Gaofeng Meng, The Governance of Covid- 19:\n",
"Anthropogenic Risk, Evolutionary Learning, and the Future of the Social State (2020)49(4) Industrial Law Journal 539.\"\u001b[0m\n",
"\n",
"\u001b[1m> Finished chain.\u001b[0m\n"
]
},
{
"data": {
"text/plain": [
"'The text on page 3 of the PDF is:\\n\\n\"1 COVID-19 at Work: \\nExposing how risk is assessed and its consequences in England and Sweden \\nPeter Andersson and Tonia Novitz* \\n1.Introduction\\nThe crisis which arose suddenly at the beginning of 2020 relating to coronavirus was immediately \\ncentred on risk. Predictions had to be made swiftly regarding how it would spread, who it might \\naffect and what measures could be taken to prevent exposure in everyday social interaction, \\nincluding in the workplace. This was in no way a straightforward assessment, because initially so \\nmuch was unknown. Those gaps in our knowledge have since, partially, been ameliorated. It is \\nevident that not all those exposed to COVID-19 become ill, and many who contract the virus remain \\nasymptomatic, so that the odds on becoming seriously ill may seem small. But those odds are also stacked against certain segments of the population. The likelihood of mortality and morbidity are associated with age and ethnicity as well as pre-existing medical conditions (such as diabetes), but \\nalso with poverty which correlates to the extent of exposure in certain occupations.\\n1 Some risks \\narise which remain less predictable, as previously healthy people with no signs of particular \\nvulnerability can experience serious long term illness as well and in rare cases will even die.2 \\nPerceptions of risk in different countries have led to particular measures taken, ranging from handwashing to social distancing, use of personal protective equipment (PPE) such as face coverings, and even lockdowns which have taken various forms.\\n3 Use of testing and vaccines \\nalso became part of the remedial landscape, with their availability and administration being \\n*This paper is part of the project An inclusive and sustainable Swedish labour law the way\\nahead, dnr. 2017-03134 financed by the Swedish research council led by Petra Herzfeld Olssonat Stockholm University. The authors would like to thank her and other participants, Niklas\\nBruun and Erik Sjödin for their helpful comments on earlier drafts. A much shorter article titled\\nRisk Assessment and COVID -19: Systems at work (or not) in England and Sweden is published\\nin the (2021) Comparative Labour and Social Security Review /\\n Revue de droit comparé du\\ntravail et de la sécurité sociale.\\n1 Public Health England, Disparities in the risk and outcomes of COVID-19 (2 June 2020 -\\nhttps://assets.publishing.service.gov.uk/government/uploads/ system /uploads/attachment_data/file\\n/890258/disparities_review.pdf.\\n2 Nisreen A. Alwan, Track COVID- 19 sickness, not just positive tests and deaths ( 2020)\\n584.7820 Nature 170- 171; Elisabeth Mahase, Covid-19: What do we know about “long covid”?\\n(2020) BMJ 370.\\n3 Sarah Dryhurst, Claudia R. Schneider, John Kerr, Alexandra LJ Freeman, Gabriel Recchia,\\nAnne Marthe Van Der Bles, David Spiegelhalter, and Sander van der Linden, Risk perceptionsof COVID-19 around the world (2020) 23(7- 8) Journal of Risk Research 994; Wändi Bruine de\\nBruin, and Daniel Bennett, Relationships between initial COVID -19 risk perceptions and\\nprotective health behaviors: A national survey (2020) 59(2) American Journal of Preventive\\nMedicine 157; and Simon Deakin and Gaofeng Meng, The Governance of Covid- 19:\\nAnthropogenic Risk, Evolutionary Learning, and the Future of the Social State (2020)49(4) Industrial Law Journal 539.\"'"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Extract pdf content\n",
"agent.run(\"What is the text on page 3 of the pdf?\")"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "451e6049",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
"\u001b[32;1m\u001b[1;3m\n",
"Invoking: `bearly_interpreter` with `{'python_code': \"import pandas as pd\\n\\n# Load the data\\nus_gdp = pd.read_csv('US_GDP.csv')\\n\\n# Convert the 'DATE' column to datetime\\nus_gdp['DATE'] = pd.to_datetime(us_gdp['DATE'])\\n\\n# Filter the data for the year 2019\\nus_gdp_2019 = us_gdp[us_gdp['DATE'].dt.year == 2019]\\n\\n# Print the GDP for 2019\\nprint(us_gdp_2019['GDP'].values)\"}`\n",
"\n",
"\n",
"\u001b[0m\u001b[36;1m\u001b[1;3m{'stdout': '[21104.133 21384.775 21694.282 21902.39 ]\\n', 'stderr': '', 'fileLinks': [], 'exitCode': 0}\u001b[0m\u001b[32;1m\u001b[1;3mThe US GDP for each quarter in 2019 was as follows:\n",
"\n",
"- Q1: 21104.133 billion dollars\n",
"- Q2: 21384.775 billion dollars\n",
"- Q3: 21694.282 billion dollars\n",
"- Q4: 21902.39 billion dollars\u001b[0m\n",
"\n",
"\u001b[1m> Finished chain.\u001b[0m\n"
]
},
{
"data": {
"text/plain": [
"'The US GDP for each quarter in 2019 was as follows:\\n\\n- Q1: 21104.133 billion dollars\\n- Q2: 21384.775 billion dollars\\n- Q3: 21694.282 billion dollars\\n- Q4: 21902.39 billion dollars'"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Simple Queries\n",
"agent.run(\"What was the US GDP in 2019?\")"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "fa48e793",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
"\u001b[32;1m\u001b[1;3m\n",
"Invoking: `bearly_interpreter` with `{'python_code': \"import pandas as pd\\n\\n# Load the data\\nus_gdp = pd.read_csv('US_GDP.csv')\\n\\n# Get the latest GDP\\nlatest_gdp = us_gdp['GDP'].iloc[-1]\\n\\n# Calculate the GDP in 2030 if the latest GDP number grew by 50%\\ngdp_2030 = latest_gdp * 1.5\\nprint(gdp_2030)\"}`\n",
"\n",
"\n",
"\u001b[0m\u001b[36;1m\u001b[1;3m{'stdout': '40594.518\\n', 'stderr': '', 'fileLinks': [], 'exitCode': 0}\u001b[0m\u001b[32;1m\u001b[1;3mIf the latest GDP number grew by 50%, the GDP in 2030 would be approximately 40,594.518 billion dollars.\u001b[0m\n",
"\n",
"\u001b[1m> Finished chain.\u001b[0m\n"
]
},
{
"data": {
"text/plain": [
"'If the latest GDP number grew by 50%, the GDP in 2030 would be approximately 40,594.518 billion dollars.'"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Calculations\n",
"agent.run(\"What would the GDP be in 2030 if the latest GDP number grew by 50%?\")"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "a49efca7",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
"\u001b[32;1m\u001b[1;3mCould not parse tool input: {'name': 'bearly_interpreter', 'arguments': '{\\n \"python_code\": \"\\nimport pandas as pd\\nimport matplotlib.pyplot as plt\\n\\n# Load the data\\ndf = pd.read_csv(\\'US_GDP.csv\\')\\n\\n# Convert the \\'DATE\\' column to datetime format\\ndf[\\'DATE\\'] = pd.to_datetime(df[\\'DATE\\'])\\n\\n# Plot the data\\nplt.figure(figsize=(10,6))\\nplt.plot(df[\\'DATE\\'], df[\\'GDP\\'], label=\\'US GDP\\')\\nplt.xlabel(\\'Year\\')\\nplt.ylabel(\\'GDP (in billions)\\')\\nplt.title(\\'US GDP Over Time\\')\\nplt.legend()\\nplt.grid(True)\\nplt.savefig(\\'output/US_GDP.png\\')\\n\"\\n}'} because the `arguments` is not valid JSON.\u001b[0mInvalid or incomplete response\u001b[32;1m\u001b[1;3m\n",
"Invoking: `bearly_interpreter` with `{'python_code': \"\\nimport pandas as pd\\nimport matplotlib.pyplot as plt\\n\\n# Load the data\\ndf = pd.read_csv('US_GDP.csv')\\n\\n# Convert the 'DATE' column to datetime format\\ndf['DATE'] = pd.to_datetime(df['DATE'])\\n\\n# Plot the data\\nplt.figure(figsize=(10,6))\\nplt.plot(df['DATE'], df['GDP'], label='US GDP')\\nplt.xlabel('Year')\\nplt.ylabel('GDP (in billions)')\\nplt.title('US GDP Over Time')\\nplt.legend()\\nplt.grid(True)\\nplt.savefig('output/US_GDP.png')\\n\"}`\n",
"\n",
"\n",
"\u001b[0m\u001b[36;1m\u001b[1;3m{'stdout': '', 'stderr': '', 'fileLinks': [{'pathname': 'US_GDP.png', 'tempLink': 'https://bearly-cubby.c559ae877a0a39985f534614a037d899.r2.cloudflarestorage.com/prod/bearly-cubby/temp/interpreter/2023_10/089daf37e9e343ba5ff21afaaa78b967c3466a550b3b11bd5c710c052b559e97/sxhM8gop2AYP88n5uHCsOJ6yTYNQm-HimZ70DcwQ4VI.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=c058d02de50a3cf0bb7e21c8e2d062c5%2F20231010%2F%2Fs3%2Faws4_request&X-Amz-Date=20231010T000000Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=104dc0d4a4b71eeea1030dda1830059920cb0f354fa00197b439eb8565bf141a', 'size': 34275}], 'exitCode': 0}\u001b[0m\u001b[32;1m\u001b[1;3mHere is the chart of the US GDP growth over time:\n",
"\n",
"![US GDP Over Time](https://bearly-cubby.c559ae877a0a39985f534614a037d899.r2.cloudflarestorage.com/prod/bearly-cubby/temp/interpreter/2023_10/089daf37e9e343ba5ff21afaaa78b967c3466a550b3b11bd5c710c052b559e97/sxhM8gop2AYP88n5uHCsOJ6yTYNQm-HimZ70DcwQ4VI.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=c058d02de50a3cf0bb7e21c8e2d062c5%2F20231010%2F%2Fs3%2Faws4_request&X-Amz-Date=20231010T000000Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=104dc0d4a4b71eeea1030dda1830059920cb0f354fa00197b439eb8565bf141a)\n",
"\n",
"The x-axis represents the year and the y-axis represents the GDP in billions. The line plot shows the growth of the US GDP over time.\u001b[0m\n",
"\n",
"\u001b[1m> Finished chain.\u001b[0m\n"
]
},
{
"data": {
"text/plain": [
"'Here is the chart of the US GDP growth over time:\\n\\n![US GDP Over Time](https://bearly-cubby.c559ae877a0a39985f534614a037d899.r2.cloudflarestorage.com/prod/bearly-cubby/temp/interpreter/2023_10/089daf37e9e343ba5ff21afaaa78b967c3466a550b3b11bd5c710c052b559e97/sxhM8gop2AYP88n5uHCsOJ6yTYNQm-HimZ70DcwQ4VI.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=c058d02de50a3cf0bb7e21c8e2d062c5%2F20231010%2F%2Fs3%2Faws4_request&X-Amz-Date=20231010T000000Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=104dc0d4a4b71eeea1030dda1830059920cb0f354fa00197b439eb8565bf141a)\\n\\nThe x-axis represents the year and the y-axis represents the GDP in billions. The line plot shows the growth of the US GDP over time.'"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Chart output\n",
"agent.run(\"Create a nice and labeled chart of the GDP growth over time\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4e78f28e",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.1"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -633,6 +633,12 @@ def _import_zapier_tool_ZapierNLARunAction() -> Any:
return ZapierNLARunAction
def _import_bearly_tool() -> Any:
from langchain.tools.bearly.tool import BearlyInterpreterTool
return BearlyInterpreterTool
def __getattr__(name: str) -> Any:
if name == "AINAppOps":
return _import_ainetwork_app()
@ -838,6 +844,8 @@ def __getattr__(name: str) -> Any:
return _import_zapier_tool_ZapierNLAListActions()
elif name == "ZapierNLARunAction":
return _import_zapier_tool_ZapierNLARunAction()
elif name == "BearlyInterpreterTool":
return _import_bearly_tool()
else:
raise AttributeError(f"Could not find: {name}")
@ -949,4 +957,5 @@ __all__ = [
"ZapierNLARunAction",
"tool",
"format_tool_to_openai_function",
"BearlyInterpreterTool",
]

@ -0,0 +1,153 @@
import base64
import itertools
import json
import re
from pathlib import Path
from typing import Dict, List, Type
import requests
from langchain.pydantic_v1 import BaseModel, Field
from langchain.tools import Tool
def strip_markdown_code(md_string: str) -> str:
stripped_string = re.sub(r"^`{1,3}.*?\n", "", md_string, flags=re.DOTALL)
stripped_string = re.sub(r"`{1,3}$", "", stripped_string)
return stripped_string
def head_file(path: str, n: int) -> List[str]:
try:
with open(path, "r") as f:
return [str(line) for line in itertools.islice(f, n)]
except Exception:
return []
def file_to_base64(path: str) -> str:
with open(path, "rb") as f:
return base64.b64encode(f.read()).decode()
class BearlyInterpreterToolArguments(BaseModel):
python_code: str = Field(
...,
example="print('Hello World')",
description=(
"The pure python script to be evaluated. "
"The contents will be in main.py. "
"It should not be in markdown format."
),
)
base_description = """Evaluates python code in a sandbox environment. \
The environment resets on every execution. \
You must send the whole script every time and print your outputs. \
Script should be pure python code that can be evaluated. \
It should be in python format NOT markdown. \
The code should NOT be wrapped in backticks. \
All python packages including requests, matplotlib, scipy, numpy, pandas, \
etc are available. \
If you have any files outputted write them to "output/" relative to the execution \
path. Output can only be read from the directory, stdout, and stdin. \
Do not use things like plot.show() as it will \
not work instead write them out `output/` and a link to the file will be returned. \
print() any output and results so you can capture the output."""
class FileInfo(BaseModel):
source_path: str
description: str
target_path: str
class BearlyInterpreterTool:
api_key: str
endpoint = "https://exec.bearly.ai/v1/interpreter"
name = "bearly_interpreter"
args_schema: Type[BaseModel] = BearlyInterpreterToolArguments
files: Dict[str, FileInfo] = {}
def __init__(self, api_key: str):
self.api_key = api_key
@property
def file_description(self) -> str:
if len(self.files) == 0:
return ""
lines = ["The following files available in the evaluation environment:"]
for target_path, file_info in self.files.items():
peek_content = head_file(file_info.source_path, 4)
lines.append(
f"- path: `{target_path}` \n first four lines: {peek_content}"
f" \n description: `{file_info.description}`"
)
return "\n".join(lines)
@property
def description(self) -> str:
return (base_description + "\n\n" + self.file_description).strip()
def make_input_files(self) -> List[dict]:
files = []
for target_path, file_info in self.files.items():
files.append(
{
"pathname": target_path,
"contentsBasesixtyfour": file_to_base64(file_info.source_path),
}
)
return files
def _run(self, python_code: str) -> dict:
script = strip_markdown_code(python_code)
resp = requests.post(
"https://exec.bearly.ai/v1/interpreter",
data=json.dumps(
{
"fileContents": script,
"inputFiles": self.make_input_files(),
"outputDir": "output/",
"outputAsLinks": True,
}
),
headers={"Authorization": self.api_key},
).json()
return {
"stdout": base64.b64decode(resp["stdoutBasesixtyfour"]).decode()
if resp["stdoutBasesixtyfour"]
else "",
"stderr": base64.b64decode(resp["stderrBasesixtyfour"]).decode()
if resp["stderrBasesixtyfour"]
else "",
"fileLinks": resp["fileLinks"],
"exitCode": resp["exitCode"],
}
async def _arun(self, query: str) -> str:
"""Use the tool asynchronously."""
raise NotImplementedError("custom_search does not support async")
def add_file(self, source_path: str, target_path: str, description: str) -> None:
if target_path in self.files:
raise ValueError("target_path already exists")
if not Path(source_path).exists():
raise ValueError("source_path does not exist")
self.files[target_path] = FileInfo(
target_path=target_path, source_path=source_path, description=description
)
def clear_files(self) -> None:
self.files = {}
# TODO: this is because we can't have a dynamic description
# because of the base pydantic class
def as_tool(self) -> Tool:
return Tool.from_function(
func=self._run,
name=self.name,
description=self.description,
args_schema=self.args_schema,
)

@ -108,6 +108,7 @@ _EXPECTED = [
"ZapierNLARunAction",
"format_tool_to_openai_function",
"tool",
"BearlyInterpreterTool",
]

Loading…
Cancel
Save