Evan Lesmez commited on
Commit
63ae673
1 Parent(s): b8c2636

Update prompting to direct towards edamam tool

Browse files

Current state of app is broken.
Prompts now instruct generatinga a recipe keyword query to be extracted
by a LangChain Agent that dynamically calls a custom Edamam Recipe
Search tool.
Functioning for recipes with compatible ingredients but fails when too
many are included or if there is too much diversity.

_proc/00_engineer_prompt.ipynb CHANGED
@@ -75,14 +75,6 @@
75
  "language": "python"
76
  },
77
  "outputs": [
78
- {
79
- "name": "stderr",
80
- "output_type": "stream",
81
- "text": [
82
- "Anthropic module not found. Install with `pip install anthropic`.\n",
83
- "WARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\n"
84
- ]
85
- },
86
  {
87
  "name": "stdout",
88
  "output_type": "stream",
@@ -92,101 +84,58 @@
92
  "> Entering new ConversationChain chain...\n",
93
  "Prompt after formatting:\n",
94
  "System: The following is a conversation between a human and a friendly AI chef. \n",
95
- "The AI is compassionate to animals and only recommends vegan recipes based on the ingredients, allergies, and other preferences the human has.\n",
96
- "\n",
97
- "Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey \n",
98
  "\n",
99
  "Let's think step by step.\n",
100
- "If the human messages are unrelated to vegan recipes, remind them of your purpose to recommend vegan recipes.\n",
 
101
  "AI: What ingredients do you wish to cook with?\n",
102
  "Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\n",
103
  "AI: Do you have any allergies I should be aware of?\n",
104
  "Human: Allergies: \n",
105
  "AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\n",
106
- "Human: Give me a vegan recipe that includes at least a few of the ingredients provided (if any).\n",
107
- "Respect the human's allergies (if any).\n",
108
- "Follow these other preferences as closely as possible if they are inline with your purpose of recommending vegan recipes:\n",
109
  "\n",
110
  "###\n",
111
  "Preferences: The preparation time should be less than 30 minutes. I really love Thai food!\n",
112
  "###\n",
 
 
113
  "\n",
114
- "Output format:\n",
115
- "\n",
116
- "**Vegan recipe name**\n",
117
- "Preparation time (humanized)\n",
118
- "\n",
119
- "Ingredients (List of ingredients with quantities):\n",
120
- "- <quantity and unit> <ingredient>\n",
121
  "\n",
122
- "Steps (detailed):\n",
123
- "1.\n",
124
- "2.\n",
125
- "3.\n",
126
- "...\n",
127
- "AI: Here is a Thai-inspired vegan recipe for you:\n",
128
  "\n",
129
- "**Thai Tofu Lettuce Wraps**\n",
130
- "Preparation time: Less than 30 minutes\n",
 
 
 
 
131
  "\n",
132
- "Ingredients:\n",
133
- "- 1/2 block of firm tofu, crumbled\n",
134
- "- 1/4 cup pickles, chopped\n",
135
- "- 1/4 cup olives, sliced\n",
136
- "- 1/2 bell pepper, sliced\n",
137
- "- 1/2 carrot, finely chopped\n",
138
- "- 4-6 lettuce leaves\n",
139
- "- 2 tablespoons soy sauce\n",
140
- "- 1 tablespoon rice vinegar\n",
141
- "- 1 tablespoon agave nectar\n",
142
- "- 1/2 tablespoon garlic powder\n",
143
- "- 1/2 tablespoon onion powder\n",
144
- "- 1/2 teaspoon dried basil\n",
145
- "- 1/2 teaspoon dried oregano\n",
146
- "- 1/2 teaspoon salt\n",
147
- "- 1/4 teaspoon black pepper\n",
148
- "- 4-6 slices of bread, toasted\n",
149
  "\n",
150
- "Steps:\n",
151
- "1. In a large bowl, combine crumbled tofu, pickles, olives, bell pepper, and carrot.\n",
152
- "2. In a small bowl, whisk together soy sauce, rice vinegar, agave nectar, garlic powder, onion powder, basil, oregano, salt, and black pepper.\n",
153
- "3. Pour the dressing over the tofu mixture, and stir until everything is coated.\n",
154
- "4. Place a spoonful of the tofu mixture into each lettuce leaf, and serve with a slice of toasted bread.\n",
155
  "Human: Recommend a different recipe please.\n",
 
 
156
  "\n",
157
  "> Finished chain.\n",
158
- "Sure, how about this recipe that incorporates more of the ingredients you provided?\n",
159
- "\n",
160
- "**Vegan Mediterranean Tofu Sandwich**\n",
161
- "Preparation time: Less than 30 minutes\n",
162
- "\n",
163
- "Ingredients:\n",
164
- "- 1/2 block of firm tofu, sliced\n",
165
- "- 2 teaspoons olive oil\n",
166
- "- 1/2 teaspoon dried oregano\n",
167
- "- 1/2 teaspoon dried basil\n",
168
- "- Salt and pepper to taste\n",
169
- "- 2 slices of bread\n",
170
- "- 1/4 cup hummus\n",
171
- "- 2-3 lettuce leaves\n",
172
- "- 1/4 cup sliced tomatoes\n",
173
- "- 1/4 cup sliced bell peppers\n",
174
- "- 1/4 cup grated carrot\n",
175
- "\n",
176
- "Steps:\n",
177
- "1. Preheat the oven to 375°F.\n",
178
- "2. In a small bowl, mix olive oil, oregano, basil, salt, and pepper, and place tofu slices on a baking sheet. Brush tofu with the olive oil mixture, covering both sides.\n",
179
- "3. Place the baking sheet in the oven and bake the tofu for 15 minutes, flipping the slices halfway through.\n",
180
- "4. Toast the bread slices.\n",
181
- "5. Spread the hummus on one slice of bread, and layer lettuce, tomatoes, bell peppers, grated carrot, and baked tofu on top. Top with the other slice of bread.\n",
182
- "6. Slice the sandwich in half, and enjoy!\n"
183
- ]
184
- },
185
- {
186
- "name": "stderr",
187
- "output_type": "stream",
188
- "text": [
189
- "WARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\n"
190
  ]
191
  }
192
  ],
@@ -194,7 +143,7 @@
194
  "#| eval: false\n",
195
  "chat = PromptLayerChatOpenAI(temperature=1, pl_tags=[\"langchain\"], return_pl_id=True)\n",
196
  "memory = ConversationBufferMemory(return_messages=True)\n",
197
- "chat_msgs = init_prompt.format_prompt(\n",
198
  " ingredients=\"tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\",\n",
199
  " allergies=\"\",\n",
200
  " recipe_freeform_input=\"The preparation time should be less than 30 minutes. I really love Thai food!\",\n",
@@ -215,6 +164,7 @@
215
  ")\n",
216
  "\n",
217
  "result = conversation.predict(input=\"Recommend a different recipe please.\")\n",
 
218
  "print(result)"
219
  ]
220
  }
 
75
  "language": "python"
76
  },
77
  "outputs": [
 
 
 
 
 
 
 
 
78
  {
79
  "name": "stdout",
80
  "output_type": "stream",
 
84
  "> Entering new ConversationChain chain...\n",
85
  "Prompt after formatting:\n",
86
  "System: The following is a conversation between a human and a friendly AI chef. \n",
87
+ "The AI is compassionate to animals.\n",
88
+ "The AI generates a simple concise keyword query for a vegan recipe, based on the ingredients, allergies, and other preferences the human has, to use in recipe APIs.\n",
89
+ "Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\n",
90
  "\n",
91
  "Let's think step by step.\n",
92
+ "If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\n",
93
+ "Only generate keyword queries as other tools should be used to fetch full recipes.\n",
94
  "AI: What ingredients do you wish to cook with?\n",
95
  "Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\n",
96
  "AI: Do you have any allergies I should be aware of?\n",
97
  "Human: Allergies: \n",
98
  "AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\n",
99
+ "Human: Generate a vegan recipe keyword query that is aligned with the user's allergies and contains at least a few of the ingredients provided (if any).\n",
100
+ "Draw some inspiration from the user's preferences delimited below if any are specified.\n",
 
101
  "\n",
102
  "###\n",
103
  "Preferences: The preparation time should be less than 30 minutes. I really love Thai food!\n",
104
  "###\n",
105
+ "AI: Based on your preferences, allergies, and ingredients, a concise vegan recipe keyword query could be: \"vegan Thai tofu sandwich with pickles, olives, tomatoes, lettuce, bell peppers, and carrots\". This should help you find a suitable recipe using recipe APIs or other recipe platforms.\n",
106
+ "Human: Recommend a different recipe please.\n",
107
  "\n",
108
+ "> Finished chain.\n",
 
 
 
 
 
 
109
  "\n",
 
 
 
 
 
 
110
  "\n",
111
+ "> Entering new ConversationChain chain...\n",
112
+ "Prompt after formatting:\n",
113
+ "System: The following is a conversation between a human and a friendly AI chef. \n",
114
+ "The AI is compassionate to animals.\n",
115
+ "The AI generates a simple concise keyword query for a vegan recipe, based on the ingredients, allergies, and other preferences the human has, to use in recipe APIs.\n",
116
+ "Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\n",
117
  "\n",
118
+ "Let's think step by step.\n",
119
+ "If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\n",
120
+ "Only generate keyword queries as other tools should be used to fetch full recipes.\n",
121
+ "AI: What ingredients do you wish to cook with?\n",
122
+ "Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\n",
123
+ "AI: Do you have any allergies I should be aware of?\n",
124
+ "Human: Allergies: \n",
125
+ "AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\n",
126
+ "Human: Generate a vegan recipe keyword query that is aligned with the user's allergies and contains at least a few of the ingredients provided (if any).\n",
127
+ "Draw some inspiration from the user's preferences delimited below if any are specified.\n",
 
 
 
 
 
 
 
128
  "\n",
129
+ "###\n",
130
+ "Preferences: The preparation time should be less than 30 minutes. I really love Thai food!\n",
131
+ "###\n",
132
+ "AI: Based on your preferences, allergies, and ingredients, a concise vegan recipe keyword query could be: \"vegan Thai tofu sandwich with pickles, olives, tomatoes, lettuce, bell peppers, and carrots\". This should help you find a suitable recipe using recipe APIs or other recipe platforms.\n",
 
133
  "Human: Recommend a different recipe please.\n",
134
+ "AI: Certainly! How about a vegan Thai peanut tofu stir-fry? It's a delicious and easy-to-make dish that incorporates some of the ingredients you mentioned. Here's a concise vegan recipe keyword query for it: \"vegan Thai peanut tofu stir-fry with tofu, bell peppers, carrots, and peanuts\". This should give you some great recipe options to explore!\n",
135
+ "Human: Aactually how about italian instead?\n",
136
  "\n",
137
  "> Finished chain.\n",
138
+ "Of course! If you prefer an Italian-inspired vegan recipe, how about a vegan Caprese salad with marinated tofu? It's a refreshing and flavorful dish that combines tomatoes, tofu, and basil. Here's a concise vegan recipe keyword query for it: \"vegan Caprese salad with marinated tofu, tomatoes, and basil\". This should help you find some delicious Italian vegan recipes to try out!\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  ]
140
  }
141
  ],
 
143
  "#| eval: false\n",
144
  "chat = PromptLayerChatOpenAI(temperature=1, pl_tags=[\"langchain\"], return_pl_id=True)\n",
145
  "memory = ConversationBufferMemory(return_messages=True)\n",
146
+ "chat_msgs = INIT_PROMPT.format_prompt(\n",
147
  " ingredients=\"tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\",\n",
148
  " allergies=\"\",\n",
149
  " recipe_freeform_input=\"The preparation time should be less than 30 minutes. I really love Thai food!\",\n",
 
164
  ")\n",
165
  "\n",
166
  "result = conversation.predict(input=\"Recommend a different recipe please.\")\n",
167
+ "result = conversation.predict(input=\"Aactually how about italian instead?\")\n",
168
  "print(result)"
169
  ]
170
  }
_proc/01_app.ipynb CHANGED
@@ -22,35 +22,135 @@
22
  },
23
  {
24
  "cell_type": "code",
25
- "execution_count": 1,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  "metadata": {},
 
 
 
 
 
 
 
 
 
 
27
  "outputs": [
28
  {
29
  "data": {
30
  "text/markdown": [
31
  "---\n",
32
  "\n",
33
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#L32){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
34
  "\n",
35
- "### ConversationBot\n",
 
 
 
 
 
 
 
36
  "\n",
37
- "> ConversationBot (verbose=True)\n",
 
 
 
38
  "\n",
39
- "Initialize self. See help(type(self)) for accurate signature."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  ],
41
  "text/plain": [
42
  "---\n",
43
  "\n",
44
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#L32){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
45
  "\n",
46
- "### ConversationBot\n",
 
 
47
  "\n",
48
- "> ConversationBot (verbose=True)\n",
49
  "\n",
50
- "Initialize self. See help(type(self)) for accurate signature."
51
  ]
52
  },
53
- "execution_count": 1,
54
  "metadata": {},
55
  "output_type": "execute_result"
56
  }
@@ -58,7 +158,148 @@
58
  "source": [
59
  "#| echo: false\n",
60
  "#| output: asis\n",
61
- "show_doc(ConversationBot)"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  ]
63
  },
64
  {
@@ -71,7 +312,14 @@
71
  {
72
  "data": {
73
  "text/plain": [
74
- "Path('/home/evylz/AnimalEquality/lv-recipe-chatbot/assets/images/vegan_ingredients')"
 
 
 
 
 
 
 
75
  ]
76
  },
77
  "execution_count": null,
@@ -80,8 +328,8 @@
80
  }
81
  ],
82
  "source": [
83
- "os.listdir(SAMPLE_IMG_DIR)\n",
84
- "SAMPLE_IMG_DIR"
85
  ]
86
  },
87
  {
@@ -90,9 +338,66 @@
90
  "metadata": {
91
  "language": "python"
92
  },
93
- "outputs": [],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  "source": [
95
- "from dotenv import load_dotenv"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  ]
97
  },
98
  {
@@ -105,7 +410,7 @@
105
  {
106
  "data": {
107
  "text/plain": [
108
- "True"
109
  ]
110
  },
111
  "execution_count": null,
@@ -114,8 +419,8 @@
114
  }
115
  ],
116
  "source": [
117
- "#: eval: false\n",
118
- "load_dotenv()"
119
  ]
120
  },
121
  {
@@ -170,7 +475,7 @@
170
  },
171
  {
172
  "cell_type": "code",
173
- "execution_count": 2,
174
  "metadata": {},
175
  "outputs": [
176
  {
@@ -178,7 +483,7 @@
178
  "text/markdown": [
179
  "---\n",
180
  "\n",
181
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#L116){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
182
  "\n",
183
  "### create_demo\n",
184
  "\n",
@@ -187,14 +492,14 @@
187
  "text/plain": [
188
  "---\n",
189
  "\n",
190
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#L116){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
191
  "\n",
192
  "### create_demo\n",
193
  "\n",
194
  "> create_demo (bot=<class '__main__.ConversationBot'>)"
195
  ]
196
  },
197
- "execution_count": 2,
198
  "metadata": {},
199
  "output_type": "execute_result"
200
  }
 
22
  },
23
  {
24
  "cell_type": "code",
25
+ "execution_count": null,
26
+ "metadata": {
27
+ "language": "python"
28
+ },
29
+ "outputs": [],
30
+ "source": [
31
+ "from dotenv import load_dotenv"
32
+ ]
33
+ },
34
+ {
35
+ "cell_type": "code",
36
+ "execution_count": null,
37
+ "metadata": {
38
+ "language": "python"
39
+ },
40
+ "outputs": [
41
+ {
42
+ "data": {
43
+ "text/plain": [
44
+ "True"
45
+ ]
46
+ },
47
+ "execution_count": null,
48
+ "metadata": {},
49
+ "output_type": "execute_result"
50
+ }
51
+ ],
52
+ "source": [
53
+ "#: eval: false\n",
54
+ "load_dotenv()"
55
+ ]
56
+ },
57
+ {
58
+ "cell_type": "markdown",
59
  "metadata": {},
60
+ "source": [
61
+ "## Put the chat backend pieces together"
62
+ ]
63
+ },
64
+ {
65
+ "cell_type": "code",
66
+ "execution_count": 1,
67
+ "metadata": {
68
+ "language": "python"
69
+ },
70
  "outputs": [
71
  {
72
  "data": {
73
  "text/markdown": [
74
  "---\n",
75
  "\n",
76
+ "### ConversationBufferMemory\n",
77
  "\n",
78
+ "> ConversationBufferMemory\n",
79
+ "> (chat_memory:langchain.schema.memory.BaseChatMe\n",
80
+ "> ssageHistory=None,\n",
81
+ "> output_key:Optional[str]=None,\n",
82
+ "> input_key:Optional[str]=None,\n",
83
+ "> return_messages:bool=False,\n",
84
+ "> human_prefix:str='Human', ai_prefix:str='AI',\n",
85
+ "> memory_key:str='history')\n",
86
  "\n",
87
+ "Buffer for storing conversation memory."
88
+ ],
89
+ "text/plain": [
90
+ "---\n",
91
  "\n",
92
+ "### ConversationBufferMemory\n",
93
+ "\n",
94
+ "> ConversationBufferMemory\n",
95
+ "> (chat_memory:langchain.schema.memory.BaseChatMe\n",
96
+ "> ssageHistory=None,\n",
97
+ "> output_key:Optional[str]=None,\n",
98
+ "> input_key:Optional[str]=None,\n",
99
+ "> return_messages:bool=False,\n",
100
+ "> human_prefix:str='Human', ai_prefix:str='AI',\n",
101
+ "> memory_key:str='history')\n",
102
+ "\n",
103
+ "Buffer for storing conversation memory."
104
+ ]
105
+ },
106
+ "execution_count": 1,
107
+ "metadata": {},
108
+ "output_type": "execute_result"
109
+ }
110
+ ],
111
+ "source": [
112
+ "#| echo: false\n",
113
+ "#| output: asis\n",
114
+ "show_doc(ConversationBufferMemory)"
115
+ ]
116
+ },
117
+ {
118
+ "cell_type": "code",
119
+ "execution_count": 2,
120
+ "metadata": {
121
+ "language": "python"
122
+ },
123
+ "outputs": [
124
+ {
125
+ "data": {
126
+ "text/markdown": [
127
+ "---\n",
128
+ "\n",
129
+ "### ChatMessageHistory\n",
130
+ "\n",
131
+ "> ChatMessageHistory\n",
132
+ "> (messages:List[langchain.schema.messages.BaseMessage]\n",
133
+ "> =[])\n",
134
+ "\n",
135
+ "In memory implementation of chat message history.\n",
136
+ "\n",
137
+ "Stores messages in an in memory list."
138
  ],
139
  "text/plain": [
140
  "---\n",
141
  "\n",
142
+ "### ChatMessageHistory\n",
143
  "\n",
144
+ "> ChatMessageHistory\n",
145
+ "> (messages:List[langchain.schema.messages.BaseMessage]\n",
146
+ "> =[])\n",
147
  "\n",
148
+ "In memory implementation of chat message history.\n",
149
  "\n",
150
+ "Stores messages in an in memory list."
151
  ]
152
  },
153
+ "execution_count": 2,
154
  "metadata": {},
155
  "output_type": "execute_result"
156
  }
 
158
  "source": [
159
  "#| echo: false\n",
160
  "#| output: asis\n",
161
+ "show_doc(ChatMessageHistory)"
162
+ ]
163
+ },
164
+ {
165
+ "cell_type": "code",
166
+ "execution_count": 3,
167
+ "metadata": {
168
+ "language": "python"
169
+ },
170
+ "outputs": [
171
+ {
172
+ "data": {
173
+ "text/markdown": [
174
+ "---\n",
175
+ "\n",
176
+ "### ChatOpenAI\n",
177
+ "\n",
178
+ "> ChatOpenAI (cache:Optional[bool]=None, verbose:bool=None, callbacks:Union\n",
179
+ "> [List[langchain.callbacks.base.BaseCallbackHandler],langchain\n",
180
+ "> .callbacks.base.BaseCallbackManager,NoneType]=None, callback_\n",
181
+ "> manager:Optional[langchain.callbacks.base.BaseCallbackManager\n",
182
+ "> ]=None, tags:Optional[List[str]]=None,\n",
183
+ "> metadata:Optional[Dict[str,Any]]=None, client:Any=None,\n",
184
+ "> model:str='gpt-3.5-turbo', temperature:float=0.7,\n",
185
+ "> model_kwargs:Dict[str,Any]=None,\n",
186
+ "> openai_api_key:Optional[str]=None,\n",
187
+ "> openai_api_base:Optional[str]=None,\n",
188
+ "> openai_organization:Optional[str]=None,\n",
189
+ "> openai_proxy:Optional[str]=None, request_timeout:Union[float,\n",
190
+ "> Tuple[float,float],NoneType]=None, max_retries:int=6,\n",
191
+ "> streaming:bool=False, n:int=1, max_tokens:Optional[int]=None,\n",
192
+ "> tiktoken_model_name:Optional[str]=None)\n",
193
+ "\n",
194
+ "Wrapper around OpenAI Chat large language models.\n",
195
+ "\n",
196
+ "To use, you should have the ``openai`` python package installed, and the\n",
197
+ "environment variable ``OPENAI_API_KEY`` set with your API key.\n",
198
+ "\n",
199
+ "Any parameters that are valid to be passed to the openai.create call can be passed\n",
200
+ "in, even if not explicitly saved on this class.\n",
201
+ "\n",
202
+ "Example:\n",
203
+ " .. code-block:: python\n",
204
+ "\n",
205
+ " from langchain.chat_models import ChatOpenAI\n",
206
+ " openai = ChatOpenAI(model_name=\"gpt-3.5-turbo\")"
207
+ ],
208
+ "text/plain": [
209
+ "---\n",
210
+ "\n",
211
+ "### ChatOpenAI\n",
212
+ "\n",
213
+ "> ChatOpenAI (cache:Optional[bool]=None, verbose:bool=None, callbacks:Union\n",
214
+ "> [List[langchain.callbacks.base.BaseCallbackHandler],langchain\n",
215
+ "> .callbacks.base.BaseCallbackManager,NoneType]=None, callback_\n",
216
+ "> manager:Optional[langchain.callbacks.base.BaseCallbackManager\n",
217
+ "> ]=None, tags:Optional[List[str]]=None,\n",
218
+ "> metadata:Optional[Dict[str,Any]]=None, client:Any=None,\n",
219
+ "> model:str='gpt-3.5-turbo', temperature:float=0.7,\n",
220
+ "> model_kwargs:Dict[str,Any]=None,\n",
221
+ "> openai_api_key:Optional[str]=None,\n",
222
+ "> openai_api_base:Optional[str]=None,\n",
223
+ "> openai_organization:Optional[str]=None,\n",
224
+ "> openai_proxy:Optional[str]=None, request_timeout:Union[float,\n",
225
+ "> Tuple[float,float],NoneType]=None, max_retries:int=6,\n",
226
+ "> streaming:bool=False, n:int=1, max_tokens:Optional[int]=None,\n",
227
+ "> tiktoken_model_name:Optional[str]=None)\n",
228
+ "\n",
229
+ "Wrapper around OpenAI Chat large language models.\n",
230
+ "\n",
231
+ "To use, you should have the ``openai`` python package installed, and the\n",
232
+ "environment variable ``OPENAI_API_KEY`` set with your API key.\n",
233
+ "\n",
234
+ "Any parameters that are valid to be passed to the openai.create call can be passed\n",
235
+ "in, even if not explicitly saved on this class.\n",
236
+ "\n",
237
+ "Example:\n",
238
+ " .. code-block:: python\n",
239
+ "\n",
240
+ " from langchain.chat_models import ChatOpenAI\n",
241
+ " openai = ChatOpenAI(model_name=\"gpt-3.5-turbo\")"
242
+ ]
243
+ },
244
+ "execution_count": 3,
245
+ "metadata": {},
246
+ "output_type": "execute_result"
247
+ }
248
+ ],
249
+ "source": [
250
+ "#| echo: false\n",
251
+ "#| output: asis\n",
252
+ "show_doc(ChatOpenAI)"
253
+ ]
254
+ },
255
+ {
256
+ "cell_type": "code",
257
+ "execution_count": null,
258
+ "metadata": {
259
+ "language": "python"
260
+ },
261
+ "outputs": [],
262
+ "source": [
263
+ "#| eval: false\n",
264
+ "llm = ChatOpenAI(temperature=1)\n",
265
+ "MEMORY_KEY = \"chat_history\"\n",
266
+ "chat_msgs = INIT_PROMPT.format_prompt(\n",
267
+ " ingredients=\"tofu, brocolli\",\n",
268
+ " allergies=\"\",\n",
269
+ " recipe_freeform_input=\"The preparation time should be less than 30 minutes. I really love Thai food!\",\n",
270
+ ")\n",
271
+ "chat_msgs = chat_msgs.to_messages()\n",
272
+ "results = llm.generate([chat_msgs])\n",
273
+ "\n",
274
+ "chat_msgs.append(results.generations[0][0].message)\n",
275
+ "tools = [vegan_recipe_edamam_search]\n",
276
+ "prompt = OpenAIFunctionsAgent.create_prompt(\n",
277
+ " system_message=INIT_PROMPT.messages[0],\n",
278
+ " extra_prompt_messages=chat_msgs + [MessagesPlaceholder(variable_name=MEMORY_KEY)],\n",
279
+ ")\n",
280
+ "memory = ConversationBufferMemory(\n",
281
+ " chat_memory=ChatMessageHistory(messages=chat_msgs),\n",
282
+ " return_messages=True,\n",
283
+ " memory_key=MEMORY_KEY,\n",
284
+ ")\n",
285
+ "agent_executor = AgentExecutor(\n",
286
+ " agent=OpenAIFunctionsAgent(llm=llm, tools=tools, prompt=prompt),\n",
287
+ " tools=tools,\n",
288
+ " memory=memory,\n",
289
+ " verbose=True,\n",
290
+ ")"
291
+ ]
292
+ },
293
+ {
294
+ "cell_type": "code",
295
+ "execution_count": null,
296
+ "metadata": {
297
+ "language": "python"
298
+ },
299
+ "outputs": [],
300
+ "source": [
301
+ "# Fails for a weird query\n",
302
+ "# \"tofu, pickles, mustard, olives, tomatoes, lettuce, bell peppers, carrots, bread\""
303
  ]
304
  },
305
  {
 
312
  {
313
  "data": {
314
  "text/plain": [
315
+ "[SystemMessage(content=\"The following is a conversation between a human and a friendly AI chef. \\nThe AI is compassionate to animals.\\nThe AI generates a simple concise keyword query for a vegan recipe, based on the ingredients, allergies, and other preferences the human has, to use in recipe APIs.\\nKnowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\\n\\nLet's think step by step.\\nIf the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\\nOnly generate keyword queries as other tools should be used to fetch full recipes.\", additional_kwargs={}),\n",
316
+ " AIMessage(content='What ingredients do you wish to cook with?', additional_kwargs={}, example=False),\n",
317
+ " HumanMessage(content='Ingredients: tofu, brocolli', additional_kwargs={}, example=False),\n",
318
+ " AIMessage(content='Do you have any allergies I should be aware of?', additional_kwargs={}, example=False),\n",
319
+ " HumanMessage(content='Allergies: ', additional_kwargs={}, example=False),\n",
320
+ " AIMessage(content='Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?', additional_kwargs={}, example=False),\n",
321
+ " HumanMessage(content=\"Generate a vegan recipe keyword query that is aligned with the user's allergies and contains at least a few of the ingredients provided (if any).\\nDraw some inspiration from the user's preferences delimited below if any are specified.\\n\\n###\\nPreferences: The preparation time should be less than 30 minutes. I really love Thai food!\\n###\", additional_kwargs={}, example=False),\n",
322
+ " AIMessage(content='Based on the ingredients, allergies, and preferences you provided, here is a vegan recipe keyword query suggestion: \"vegan Thai tofu broccoli stir fry recipe\"', additional_kwargs={}, example=False)]"
323
  ]
324
  },
325
  "execution_count": null,
 
328
  }
329
  ],
330
  "source": [
331
+ "#| eval: false\n",
332
+ "memory.chat_memory.messages"
333
  ]
334
  },
335
  {
 
338
  "metadata": {
339
  "language": "python"
340
  },
341
+ "outputs": [
342
+ {
343
+ "name": "stdout",
344
+ "output_type": "stream",
345
+ "text": [
346
+ "\n",
347
+ "\n",
348
+ "> Entering new AgentExecutor chain...\n",
349
+ "\n",
350
+ "Invoking: `vegan_recipe_edamam_search` with `{'query': 'vegan tofu broccoli'}`\n",
351
+ "\n",
352
+ "\n",
353
+ "[{'label': 'Vegan BBQ teriyaki tofu', 'url': 'https://www.bbcgoodfood.com/recipes/teriyaki-tofu-vegan-barbecue', 'ingredientLines': ['4 tbsp low-salt soy sauce', '2 tbsp soft brown sugar', 'pinch ground ginger', '2 tbsp mirin', '3 tsp sesame oil', '350g block very firm tofu (see tip below) cut into thick slices', '½ tbsp rapeseed oil', '2 courgettes, sliced horizontally into strips', '200g Tenderstem broccoli', 'black and white sesame seeds, to serve'], 'totalTime': 25.0}, {'label': 'Vegan Crispy Stir-Fried Tofu With Broccoli Recipe', 'url': 'http://www.seriouseats.com/recipes/2014/02/vegan-experience-crispy-tofu-broccoli-stir-fry.html', 'ingredientLines': ['1 1/2 quarts vegetable or peanut oil', '1/2 cup plus 2 teaspoons cornstarch, divided', '1/2 cup all-purpose flour', '1/2 teaspoon baking powder', 'Kosher salt', '1/2 cup cold water', '1/2 cup vodka', '1 pound extra-firm tofu, cut into 1/2- by 2- by 1-inch slabs, carefully dried (see note above)', '1 pound broccoli, cut into 1-inch florets', '1/4 cup Xiaoshing wine or dry sherry', '1/4 cup homemade or store-bought low-sodium vegetable stock', '2 tablespoons soy sauce', '1 tablespoon fermented black bean sauce', '2 tablespoons sugar', '1 tablespoon toasted sesame oil', '2 (1-inch) segments lemon peel, plus 2 teaspoons lemon juice', '4 cloves garlic, minced (about 4 teaspoons)', '1 tablespoon minced or grated fresh ginger', '6 scallions, white and light green parts only, finely chopped', '2 tablespoons toasted sesame seeds, divided'], 'totalTime': 30.0}, {'label': 'Thai-Style Chopped Salad with Sriracha Tofu', 'url': 'http://www.eatingwell.com/recipe/276172/thai-style-chopped-salad-with-sriracha-tofu/', 'ingredientLines': ['1 (10 ounce) package kale, Brussels sprout, broccoli and cabbage salad mix', '1 (12 ounce) package frozen shelled edamame, thawed', '2 (7 ounce) packages Sriracha-flavored baked tofu, cubed', '1/2 cup spicy peanut vinaigrette'], 'totalTime': 10.0}]"
354
+ ]
355
+ }
356
+ ],
357
  "source": [
358
+ "#| eval: false\n",
359
+ "agent_executor.run(\"Search for vegan recipe\")"
360
+ ]
361
+ },
362
+ {
363
+ "cell_type": "code",
364
+ "execution_count": 4,
365
+ "metadata": {},
366
+ "outputs": [
367
+ {
368
+ "data": {
369
+ "text/markdown": [
370
+ "---\n",
371
+ "\n",
372
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#L42){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
373
+ "\n",
374
+ "### ConversationBot\n",
375
+ "\n",
376
+ "> ConversationBot (verbose=True)\n",
377
+ "\n",
378
+ "Initialize self. See help(type(self)) for accurate signature."
379
+ ],
380
+ "text/plain": [
381
+ "---\n",
382
+ "\n",
383
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#L42){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
384
+ "\n",
385
+ "### ConversationBot\n",
386
+ "\n",
387
+ "> ConversationBot (verbose=True)\n",
388
+ "\n",
389
+ "Initialize self. See help(type(self)) for accurate signature."
390
+ ]
391
+ },
392
+ "execution_count": 4,
393
+ "metadata": {},
394
+ "output_type": "execute_result"
395
+ }
396
+ ],
397
+ "source": [
398
+ "#| echo: false\n",
399
+ "#| output: asis\n",
400
+ "show_doc(ConversationBot)"
401
  ]
402
  },
403
  {
 
410
  {
411
  "data": {
412
  "text/plain": [
413
+ "Path('/home/evylz/AnimalEquality/lv-recipe-chatbot/assets/images/vegan_ingredients')"
414
  ]
415
  },
416
  "execution_count": null,
 
419
  }
420
  ],
421
  "source": [
422
+ "os.listdir(SAMPLE_IMG_DIR)\n",
423
+ "SAMPLE_IMG_DIR"
424
  ]
425
  },
426
  {
 
475
  },
476
  {
477
  "cell_type": "code",
478
+ "execution_count": 5,
479
  "metadata": {},
480
  "outputs": [
481
  {
 
483
  "text/markdown": [
484
  "---\n",
485
  "\n",
486
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#L126){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
487
  "\n",
488
  "### create_demo\n",
489
  "\n",
 
492
  "text/plain": [
493
  "---\n",
494
  "\n",
495
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#L126){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
496
  "\n",
497
  "### create_demo\n",
498
  "\n",
499
  "> create_demo (bot=<class '__main__.ConversationBot'>)"
500
  ]
501
  },
502
+ "execution_count": 5,
503
  "metadata": {},
504
  "output_type": "execute_result"
505
  }
_proc/02_vegan_recipe_tools.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
_proc/03_ingredient_vision.ipynb CHANGED
@@ -37,7 +37,7 @@
37
  "text/markdown": [
38
  "---\n",
39
  "\n",
40
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L24){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
41
  "\n",
42
  "### format_image\n",
43
  "\n",
@@ -50,7 +50,7 @@
50
  "text/plain": [
51
  "---\n",
52
  "\n",
53
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L24){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
54
  "\n",
55
  "### format_image\n",
56
  "\n",
@@ -82,7 +82,7 @@
82
  "text/markdown": [
83
  "---\n",
84
  "\n",
85
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L36){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
86
  "\n",
87
  "### BlipImageCaptioning\n",
88
  "\n",
@@ -93,7 +93,7 @@
93
  "text/plain": [
94
  "---\n",
95
  "\n",
96
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L36){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
97
  "\n",
98
  "### BlipImageCaptioning\n",
99
  "\n",
@@ -125,7 +125,7 @@
125
  "text/markdown": [
126
  "---\n",
127
  "\n",
128
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L51){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
129
  "\n",
130
  "### BlipImageCaptioning.inference\n",
131
  "\n",
@@ -143,7 +143,7 @@
143
  "text/plain": [
144
  "---\n",
145
  "\n",
146
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L51){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
147
  "\n",
148
  "### BlipImageCaptioning.inference\n",
149
  "\n",
@@ -180,7 +180,7 @@
180
  "text/markdown": [
181
  "---\n",
182
  "\n",
183
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L60){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
184
  "\n",
185
  "### BlipVQA\n",
186
  "\n",
@@ -194,7 +194,7 @@
194
  "text/plain": [
195
  "---\n",
196
  "\n",
197
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L60){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
198
  "\n",
199
  "### BlipVQA\n",
200
  "\n",
@@ -229,7 +229,7 @@
229
  "text/markdown": [
230
  "---\n",
231
  "\n",
232
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L76){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
233
  "\n",
234
  "### BlipVQA.inference\n",
235
  "\n",
@@ -247,7 +247,7 @@
247
  "text/plain": [
248
  "---\n",
249
  "\n",
250
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L76){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
251
  "\n",
252
  "### BlipVQA.inference\n",
253
  "\n",
@@ -753,7 +753,7 @@
753
  "text/markdown": [
754
  "---\n",
755
  "\n",
756
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L89){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
757
  "\n",
758
  "### VeganIngredientFinder\n",
759
  "\n",
@@ -764,7 +764,7 @@
764
  "text/plain": [
765
  "---\n",
766
  "\n",
767
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L89){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
768
  "\n",
769
  "### VeganIngredientFinder\n",
770
  "\n",
@@ -796,7 +796,7 @@
796
  "text/markdown": [
797
  "---\n",
798
  "\n",
799
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L93){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
800
  "\n",
801
  "### VeganIngredientFinder.list_ingredients\n",
802
  "\n",
@@ -810,7 +810,7 @@
810
  "text/plain": [
811
  "---\n",
812
  "\n",
813
- "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L93){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
814
  "\n",
815
  "### VeganIngredientFinder.list_ingredients\n",
816
  "\n",
 
37
  "text/markdown": [
38
  "---\n",
39
  "\n",
40
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L26){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
41
  "\n",
42
  "### format_image\n",
43
  "\n",
 
50
  "text/plain": [
51
  "---\n",
52
  "\n",
53
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L26){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
54
  "\n",
55
  "### format_image\n",
56
  "\n",
 
82
  "text/markdown": [
83
  "---\n",
84
  "\n",
85
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L41){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
86
  "\n",
87
  "### BlipImageCaptioning\n",
88
  "\n",
 
93
  "text/plain": [
94
  "---\n",
95
  "\n",
96
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L41){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
97
  "\n",
98
  "### BlipImageCaptioning\n",
99
  "\n",
 
125
  "text/markdown": [
126
  "---\n",
127
  "\n",
128
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L60){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
129
  "\n",
130
  "### BlipImageCaptioning.inference\n",
131
  "\n",
 
143
  "text/plain": [
144
  "---\n",
145
  "\n",
146
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L60){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
147
  "\n",
148
  "### BlipImageCaptioning.inference\n",
149
  "\n",
 
180
  "text/markdown": [
181
  "---\n",
182
  "\n",
183
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L71){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
184
  "\n",
185
  "### BlipVQA\n",
186
  "\n",
 
194
  "text/plain": [
195
  "---\n",
196
  "\n",
197
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L71){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
198
  "\n",
199
  "### BlipVQA\n",
200
  "\n",
 
229
  "text/markdown": [
230
  "---\n",
231
  "\n",
232
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L89){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
233
  "\n",
234
  "### BlipVQA.inference\n",
235
  "\n",
 
247
  "text/plain": [
248
  "---\n",
249
  "\n",
250
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L89){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
251
  "\n",
252
  "### BlipVQA.inference\n",
253
  "\n",
 
753
  "text/markdown": [
754
  "---\n",
755
  "\n",
756
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L106){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
757
  "\n",
758
  "### VeganIngredientFinder\n",
759
  "\n",
 
764
  "text/plain": [
765
  "---\n",
766
  "\n",
767
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L106){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
768
  "\n",
769
  "### VeganIngredientFinder\n",
770
  "\n",
 
796
  "text/markdown": [
797
  "---\n",
798
  "\n",
799
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L111){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
800
  "\n",
801
  "### VeganIngredientFinder.list_ingredients\n",
802
  "\n",
 
810
  "text/plain": [
811
  "---\n",
812
  "\n",
813
+ "[source](https://gitlab.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/ingredient_vision.py#L111){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n",
814
  "\n",
815
  "### VeganIngredientFinder.list_ingredients\n",
816
  "\n",
_proc/_docs/engineer_prompt.html CHANGED
@@ -126,7 +126,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
126
  <button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
127
  <i class="bi bi-layout-text-sidebar-reverse"></i>
128
  </button>
129
- <nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="./engineer_prompt.html">engineer_prompt</a></li></ol></nav>
130
  <a class="flex-grow-1" role="button" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
131
  </a>
132
  </div>
@@ -136,46 +136,6 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
136
  <div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
137
  <!-- sidebar -->
138
  <nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal sidebar-navigation floating overflow-auto">
139
- <div class="sidebar-menu-container">
140
- <ul class="list-unstyled mt-1">
141
- <li class="sidebar-item">
142
- <div class="sidebar-item-container">
143
- <a href="./index.html" class="sidebar-item-text sidebar-link">
144
- <span class="menu-text">lv-recipe-chatbot</span></a>
145
- </div>
146
- </li>
147
- <li class="sidebar-item">
148
- <div class="sidebar-item-container">
149
- <a href="./engineer_prompt.html" class="sidebar-item-text sidebar-link active">
150
- <span class="menu-text">engineer_prompt</span></a>
151
- </div>
152
- </li>
153
- <li class="sidebar-item">
154
- <div class="sidebar-item-container">
155
- <a href="./app.html" class="sidebar-item-text sidebar-link">
156
- <span class="menu-text">app</span></a>
157
- </div>
158
- </li>
159
- <li class="sidebar-item">
160
- <div class="sidebar-item-container">
161
- <a href="./lchain_tool.html" class="sidebar-item-text sidebar-link">
162
- <span class="menu-text">lchain_tool</span></a>
163
- </div>
164
- </li>
165
- <li class="sidebar-item">
166
- <div class="sidebar-item-container">
167
- <a href="./ingredient_vision.html" class="sidebar-item-text sidebar-link">
168
- <span class="menu-text">ingredient_vision</span></a>
169
- </div>
170
- </li>
171
- <li class="sidebar-item">
172
- <div class="sidebar-item-container">
173
- <a href="./edamam_api.html" class="sidebar-item-text sidebar-link">
174
- <span class="menu-text">edamam_api</span></a>
175
- </div>
176
- </li>
177
- </ul>
178
- </div>
179
  </nav>
180
  <div id="quarto-sidebar-glass" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass"></div>
181
  <!-- margin-sidebar -->
@@ -345,6 +305,9 @@ Steps:
345
  6. Slice the sandwich in half, and enjoy!</code></pre>
346
  </div>
347
  </div>
 
 
 
348
 
349
 
350
 
@@ -586,4 +549,4 @@ window.document.addEventListener("DOMContentLoaded", function (event) {
586
 
587
 
588
 
589
- <footer class="footer"><div class="nav-footer"><div class="nav-footer-center"><div class="toc-actions"><div><i class="bi bi-git"></i></div><div class="action-links"><p><a href="https://gitlab.com/animalequality/lv-recipe-chatbot/issues/new" class="toc-action">Report an issue</a></p></div></div></div></div></footer></body></html>
 
126
  <button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
127
  <i class="bi bi-layout-text-sidebar-reverse"></i>
128
  </button>
129
+ <nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item">engineer_prompt</li></ol></nav>
130
  <a class="flex-grow-1" role="button" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
131
  </a>
132
  </div>
 
136
  <div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
137
  <!-- sidebar -->
138
  <nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal sidebar-navigation floating overflow-auto">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  </nav>
140
  <div id="quarto-sidebar-glass" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar,#quarto-sidebar-glass"></div>
141
  <!-- margin-sidebar -->
 
305
  6. Slice the sandwich in half, and enjoy!</code></pre>
306
  </div>
307
  </div>
308
+ <div class="cell">
309
+ <div class="sourceCode cell-code" id="cb7"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>test_temp <span class="op">=</span> HumanMessagePromptTemplate.from_template(<span class="st">"Ingredients: </span><span class="sc">{ingredients}</span><span class="st">"</span>)</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
310
+ </div>
311
 
312
 
313
 
 
549
 
550
 
551
 
552
+ <footer class="footer"><div class="nav-footer"><div class="nav-footer-center"><div class="toc-actions"><div><i class="bi bi-github"></i></div><div class="action-links"><p><a href="https://github.com/animalequality/lv-recipe-chatbot/issues/new" class="toc-action">Report an issue</a></p></div></div></div></div></footer></body></html>
_proc/_docs/search.json CHANGED
@@ -74,7 +74,7 @@
74
  "href": "engineer_prompt.html",
75
  "title": "engineer_prompt",
76
  "section": "",
77
- "text": "Setup env\n\nfrom dotenv import load_dotenv\n\n\nload_dotenv()\n\nTrue\n\n\nEvaluate chat backend\n\nchat = PromptLayerChatOpenAI(temperature=1, pl_tags=[\"langchain\"], return_pl_id=True)\nmemory = ConversationBufferMemory(return_messages=True)\nchat_msgs = init_prompt.format_prompt(\n ingredients=\"tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\",\n allergies=\"\",\n recipe_freeform_input=\"The preparation time should be less than 30 minutes. I really love Thai food!\",\n)\n\nchat_msgs = chat_msgs.to_messages()\nresults = chat.generate([chat_msgs])\nchat_msgs.extend(\n [\n results.generations[0][0].message,\n MessagesPlaceholder(variable_name=\"history\"),\n HumanMessagePromptTemplate.from_template(\"{input}\"),\n ]\n)\nopen_prompt = ChatPromptTemplate.from_messages(chat_msgs)\nconversation = ConversationChain(\n llm=chat, verbose=True, memory=memory, prompt=open_prompt\n)\n\nresult = conversation.predict(input=\"Recommend a different recipe please.\")\nprint(result)\n\nAnthropic module not found. Install with `pip install anthropic`.\nWARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\nWARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\n\n\n\n\n&gt; Entering new ConversationChain chain...\nPrompt after formatting:\nSystem: The following is a conversation between a human and a friendly AI chef. \nThe AI is compassionate to animals and only recommends vegan recipes based on the ingredients, allergies, and other preferences the human has.\n\nKnowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey \n\nLet's think step by step.\nIf the human messages are unrelated to vegan recipes, remind them of your purpose to recommend vegan recipes.\nAI: What ingredients do you wish to cook with?\nHuman: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\nAI: Do you have any allergies I should be aware of?\nHuman: Allergies: \nAI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\nHuman: Give me a vegan recipe that includes at least a few of the ingredients provided (if any).\nRespect the human's allergies (if any).\nFollow these other preferences as closely as possible if they are inline with your purpose of recommending vegan recipes:\n\n###\nPreferences: The preparation time should be less than 30 minutes. I really love Thai food!\n###\n\nOutput format:\n\n**Vegan recipe name**\nPreparation time (humanized)\n\nIngredients (List of ingredients with quantities):\n- &lt;quantity and unit&gt; &lt;ingredient&gt;\n\nSteps (detailed):\n1.\n2.\n3.\n...\nAI: Here is a Thai-inspired vegan recipe for you:\n\n**Thai Tofu Lettuce Wraps**\nPreparation time: Less than 30 minutes\n\nIngredients:\n- 1/2 block of firm tofu, crumbled\n- 1/4 cup pickles, chopped\n- 1/4 cup olives, sliced\n- 1/2 bell pepper, sliced\n- 1/2 carrot, finely chopped\n- 4-6 lettuce leaves\n- 2 tablespoons soy sauce\n- 1 tablespoon rice vinegar\n- 1 tablespoon agave nectar\n- 1/2 tablespoon garlic powder\n- 1/2 tablespoon onion powder\n- 1/2 teaspoon dried basil\n- 1/2 teaspoon dried oregano\n- 1/2 teaspoon salt\n- 1/4 teaspoon black pepper\n- 4-6 slices of bread, toasted\n\nSteps:\n1. In a large bowl, combine crumbled tofu, pickles, olives, bell pepper, and carrot.\n2. In a small bowl, whisk together soy sauce, rice vinegar, agave nectar, garlic powder, onion powder, basil, oregano, salt, and black pepper.\n3. Pour the dressing over the tofu mixture, and stir until everything is coated.\n4. Place a spoonful of the tofu mixture into each lettuce leaf, and serve with a slice of toasted bread.\nHuman: Recommend a different recipe please.\n\n&gt; Finished chain.\nSure, how about this recipe that incorporates more of the ingredients you provided?\n\n**Vegan Mediterranean Tofu Sandwich**\nPreparation time: Less than 30 minutes\n\nIngredients:\n- 1/2 block of firm tofu, sliced\n- 2 teaspoons olive oil\n- 1/2 teaspoon dried oregano\n- 1/2 teaspoon dried basil\n- Salt and pepper to taste\n- 2 slices of bread\n- 1/4 cup hummus\n- 2-3 lettuce leaves\n- 1/4 cup sliced tomatoes\n- 1/4 cup sliced bell peppers\n- 1/4 cup grated carrot\n\nSteps:\n1. Preheat the oven to 375°F.\n2. In a small bowl, mix olive oil, oregano, basil, salt, and pepper, and place tofu slices on a baking sheet. Brush tofu with the olive oil mixture, covering both sides.\n3. Place the baking sheet in the oven and bake the tofu for 15 minutes, flipping the slices halfway through.\n4. Toast the bread slices.\n5. Spread the hummus on one slice of bread, and layer lettuce, tomatoes, bell peppers, grated carrot, and baked tofu on top. Top with the other slice of bread.\n6. Slice the sandwich in half, and enjoy!"
78
  },
79
  {
80
  "objectID": "edamam_api.html",
 
74
  "href": "engineer_prompt.html",
75
  "title": "engineer_prompt",
76
  "section": "",
77
+ "text": "Setup env\n\nfrom dotenv import load_dotenv\n\n\nload_dotenv()\n\nTrue\n\n\nEvaluate chat backend\n\nchat = PromptLayerChatOpenAI(temperature=1, pl_tags=[\"langchain\"], return_pl_id=True)\nmemory = ConversationBufferMemory(return_messages=True)\nchat_msgs = init_prompt.format_prompt(\n ingredients=\"tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\",\n allergies=\"\",\n recipe_freeform_input=\"The preparation time should be less than 30 minutes. I really love Thai food!\",\n)\n\nchat_msgs = chat_msgs.to_messages()\nresults = chat.generate([chat_msgs])\nchat_msgs.extend(\n [\n results.generations[0][0].message,\n MessagesPlaceholder(variable_name=\"history\"),\n HumanMessagePromptTemplate.from_template(\"{input}\"),\n ]\n)\nopen_prompt = ChatPromptTemplate.from_messages(chat_msgs)\nconversation = ConversationChain(\n llm=chat, verbose=True, memory=memory, prompt=open_prompt\n)\n\nresult = conversation.predict(input=\"Recommend a different recipe please.\")\nprint(result)\n\nAnthropic module not found. Install with `pip install anthropic`.\nWARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\nWARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\n\n\n\n\n&gt; Entering new ConversationChain chain...\nPrompt after formatting:\nSystem: The following is a conversation between a human and a friendly AI chef. \nThe AI is compassionate to animals and only recommends vegan recipes based on the ingredients, allergies, and other preferences the human has.\n\nKnowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey \n\nLet's think step by step.\nIf the human messages are unrelated to vegan recipes, remind them of your purpose to recommend vegan recipes.\nAI: What ingredients do you wish to cook with?\nHuman: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\nAI: Do you have any allergies I should be aware of?\nHuman: Allergies: \nAI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\nHuman: Give me a vegan recipe that includes at least a few of the ingredients provided (if any).\nRespect the human's allergies (if any).\nFollow these other preferences as closely as possible if they are inline with your purpose of recommending vegan recipes:\n\n###\nPreferences: The preparation time should be less than 30 minutes. I really love Thai food!\n###\n\nOutput format:\n\n**Vegan recipe name**\nPreparation time (humanized)\n\nIngredients (List of ingredients with quantities):\n- &lt;quantity and unit&gt; &lt;ingredient&gt;\n\nSteps (detailed):\n1.\n2.\n3.\n...\nAI: Here is a Thai-inspired vegan recipe for you:\n\n**Thai Tofu Lettuce Wraps**\nPreparation time: Less than 30 minutes\n\nIngredients:\n- 1/2 block of firm tofu, crumbled\n- 1/4 cup pickles, chopped\n- 1/4 cup olives, sliced\n- 1/2 bell pepper, sliced\n- 1/2 carrot, finely chopped\n- 4-6 lettuce leaves\n- 2 tablespoons soy sauce\n- 1 tablespoon rice vinegar\n- 1 tablespoon agave nectar\n- 1/2 tablespoon garlic powder\n- 1/2 tablespoon onion powder\n- 1/2 teaspoon dried basil\n- 1/2 teaspoon dried oregano\n- 1/2 teaspoon salt\n- 1/4 teaspoon black pepper\n- 4-6 slices of bread, toasted\n\nSteps:\n1. In a large bowl, combine crumbled tofu, pickles, olives, bell pepper, and carrot.\n2. In a small bowl, whisk together soy sauce, rice vinegar, agave nectar, garlic powder, onion powder, basil, oregano, salt, and black pepper.\n3. Pour the dressing over the tofu mixture, and stir until everything is coated.\n4. Place a spoonful of the tofu mixture into each lettuce leaf, and serve with a slice of toasted bread.\nHuman: Recommend a different recipe please.\n\n&gt; Finished chain.\nSure, how about this recipe that incorporates more of the ingredients you provided?\n\n**Vegan Mediterranean Tofu Sandwich**\nPreparation time: Less than 30 minutes\n\nIngredients:\n- 1/2 block of firm tofu, sliced\n- 2 teaspoons olive oil\n- 1/2 teaspoon dried oregano\n- 1/2 teaspoon dried basil\n- Salt and pepper to taste\n- 2 slices of bread\n- 1/4 cup hummus\n- 2-3 lettuce leaves\n- 1/4 cup sliced tomatoes\n- 1/4 cup sliced bell peppers\n- 1/4 cup grated carrot\n\nSteps:\n1. Preheat the oven to 375°F.\n2. In a small bowl, mix olive oil, oregano, basil, salt, and pepper, and place tofu slices on a baking sheet. Brush tofu with the olive oil mixture, covering both sides.\n3. Place the baking sheet in the oven and bake the tofu for 15 minutes, flipping the slices halfway through.\n4. Toast the bread slices.\n5. Spread the hummus on one slice of bread, and layer lettuce, tomatoes, bell peppers, grated carrot, and baked tofu on top. Top with the other slice of bread.\n6. Slice the sandwich in half, and enjoy!\n\n\n\ntest_temp = HumanMessagePromptTemplate.from_template(\"Ingredients: {ingredients}\")"
78
  },
79
  {
80
  "objectID": "edamam_api.html",
_proc/_docs/sitemap.xml CHANGED
@@ -2,11 +2,11 @@
2
  <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
3
  <url>
4
  <loc>https://animalequality.github.io/lv-recipe-chatbot/ingredient_vision.html</loc>
5
- <lastmod>2023-06-12T18:18:15.258Z</lastmod>
6
  </url>
7
  <url>
8
  <loc>https://animalequality.github.io/lv-recipe-chatbot/app.html</loc>
9
- <lastmod>2023-06-12T18:13:05.828Z</lastmod>
10
  </url>
11
  <url>
12
  <loc>https://animalequality.github.io/lv-recipe-chatbot/index.html</loc>
@@ -14,11 +14,11 @@
14
  </url>
15
  <url>
16
  <loc>https://animalequality.github.io/lv-recipe-chatbot/lchain_tool.html</loc>
17
- <lastmod>2023-06-12T18:08:38.475Z</lastmod>
18
  </url>
19
  <url>
20
  <loc>https://animalequality.github.io/lv-recipe-chatbot/engineer_prompt.html</loc>
21
- <lastmod>2023-06-12T18:14:11.620Z</lastmod>
22
  </url>
23
  <url>
24
  <loc>https://animalequality.github.io/lv-recipe-chatbot/edamam_api.html</loc>
 
2
  <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
3
  <url>
4
  <loc>https://animalequality.github.io/lv-recipe-chatbot/ingredient_vision.html</loc>
5
+ <lastmod>2023-06-12T19:02:21.982Z</lastmod>
6
  </url>
7
  <url>
8
  <loc>https://animalequality.github.io/lv-recipe-chatbot/app.html</loc>
9
+ <lastmod>2023-06-12T19:02:20.886Z</lastmod>
10
  </url>
11
  <url>
12
  <loc>https://animalequality.github.io/lv-recipe-chatbot/index.html</loc>
 
14
  </url>
15
  <url>
16
  <loc>https://animalequality.github.io/lv-recipe-chatbot/lchain_tool.html</loc>
17
+ <lastmod>2023-06-12T19:02:21.258Z</lastmod>
18
  </url>
19
  <url>
20
  <loc>https://animalequality.github.io/lv-recipe-chatbot/engineer_prompt.html</loc>
21
+ <lastmod>2023-06-12T19:02:20.550Z</lastmod>
22
  </url>
23
  <url>
24
  <loc>https://animalequality.github.io/lv-recipe-chatbot/edamam_api.html</loc>
lv_recipe_chatbot/_modidx.py CHANGED
@@ -44,7 +44,19 @@ d = { 'settings': { 'branch': 'main',
44
  'lv_recipe_chatbot/ingredient_vision.py'),
45
  'lv_recipe_chatbot.ingredient_vision.format_image': ( 'ingredient_vision.html#format_image',
46
  'lv_recipe_chatbot/ingredient_vision.py')},
47
- 'lv_recipe_chatbot.lchain_tool': { 'lv_recipe_chatbot.lchain_tool.RecipeSerpAPIWrapper': ( 'lchain_tool.html#recipeserpapiwrapper',
48
  'lv_recipe_chatbot/lchain_tool.py'),
49
- 'lv_recipe_chatbot.lchain_tool.RecipeSerpAPIWrapper._process_response': ( 'lchain_tool.html#recipeserpapiwrapper._process_response',
50
- 'lv_recipe_chatbot/lchain_tool.py')}}}
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  'lv_recipe_chatbot/ingredient_vision.py'),
45
  'lv_recipe_chatbot.ingredient_vision.format_image': ( 'ingredient_vision.html#format_image',
46
  'lv_recipe_chatbot/ingredient_vision.py')},
47
+ 'lv_recipe_chatbot.lchain_tool': { 'lv_recipe_chatbot.lchain_tool.RecipeSerpAPIWrapper': ( 'vegan_recipe_tools.html#recipeserpapiwrapper',
48
  'lv_recipe_chatbot/lchain_tool.py'),
49
+ 'lv_recipe_chatbot.lchain_tool.RecipeSerpAPIWrapper._process_response': ( 'vegan_recipe_tools.html#recipeserpapiwrapper._process_response',
50
+ 'lv_recipe_chatbot/lchain_tool.py'),
51
+ 'lv_recipe_chatbot.lchain_tool.get_vegan_recipes_edamam_api': ( 'vegan_recipe_tools.html#get_vegan_recipes_edamam_api',
52
+ 'lv_recipe_chatbot/lchain_tool.py'),
53
+ 'lv_recipe_chatbot.lchain_tool.vegan_recipe_edamam_search': ( 'vegan_recipe_tools.html#vegan_recipe_edamam_search',
54
+ 'lv_recipe_chatbot/lchain_tool.py')},
55
+ 'lv_recipe_chatbot.vegan_recipe_tools': { 'lv_recipe_chatbot.vegan_recipe_tools.RecipeSerpAPIWrapper': ( 'vegan_recipe_tools.html#recipeserpapiwrapper',
56
+ 'lv_recipe_chatbot/vegan_recipe_tools.py'),
57
+ 'lv_recipe_chatbot.vegan_recipe_tools.RecipeSerpAPIWrapper._process_response': ( 'vegan_recipe_tools.html#recipeserpapiwrapper._process_response',
58
+ 'lv_recipe_chatbot/vegan_recipe_tools.py'),
59
+ 'lv_recipe_chatbot.vegan_recipe_tools.get_vegan_recipes_edamam_api': ( 'vegan_recipe_tools.html#get_vegan_recipes_edamam_api',
60
+ 'lv_recipe_chatbot/vegan_recipe_tools.py'),
61
+ 'lv_recipe_chatbot.vegan_recipe_tools.vegan_recipe_edamam_search': ( 'vegan_recipe_tools.html#vegan_recipe_edamam_search',
62
+ 'lv_recipe_chatbot/vegan_recipe_tools.py')}}}
lv_recipe_chatbot/app.py CHANGED
@@ -9,9 +9,18 @@ import os
9
 
10
  import gradio as gr
11
  from fastcore.utils import in_jupyter
 
 
 
 
 
 
 
 
 
12
  from langchain.chains import ConversationChain
13
  from langchain.chat_models import ChatOpenAI
14
- from langchain.memory import ConversationBufferMemory
15
  from langchain.prompts.chat import (
16
  ChatPromptTemplate,
17
  HumanMessagePromptTemplate,
@@ -27,8 +36,9 @@ from lv_recipe_chatbot.ingredient_vision import (
27
  VeganIngredientFinder,
28
  format_image,
29
  )
 
30
 
31
- # %% ../nbs/01_app.ipynb 4
32
  class ConversationBot:
33
  def __init__(self, verbose=True):
34
  self.chat = ChatOpenAI(temperature=1, verbose=True)
@@ -112,7 +122,7 @@ The extracted ingredients are:
112
  def __del__(self):
113
  del self.vegan_ingred_finder
114
 
115
- # %% ../nbs/01_app.ipynb 10
116
  def create_demo(bot=ConversationBot):
117
  sample_images = []
118
  all_imgs = [f"{SAMPLE_IMG_DIR}/{img}" for img in os.listdir(SAMPLE_IMG_DIR)]
 
9
 
10
  import gradio as gr
11
  from fastcore.utils import in_jupyter
12
+ from langchain import LLMChain, OpenAI, PromptTemplate
13
+ from langchain.agents import (
14
+ AgentExecutor,
15
+ AgentType,
16
+ OpenAIFunctionsAgent,
17
+ Tool,
18
+ initialize_agent,
19
+ load_tools,
20
+ )
21
  from langchain.chains import ConversationChain
22
  from langchain.chat_models import ChatOpenAI
23
+ from langchain.memory import ChatMessageHistory, ConversationBufferMemory
24
  from langchain.prompts.chat import (
25
  ChatPromptTemplate,
26
  HumanMessagePromptTemplate,
 
36
  VeganIngredientFinder,
37
  format_image,
38
  )
39
+ from .vegan_recipe_tools import vegan_recipe_edamam_search
40
 
41
+ # %% ../nbs/01_app.ipynb 14
42
  class ConversationBot:
43
  def __init__(self, verbose=True):
44
  self.chat = ChatOpenAI(temperature=1, verbose=True)
 
122
  def __del__(self):
123
  del self.vegan_ingred_finder
124
 
125
+ # %% ../nbs/01_app.ipynb 18
126
  def create_demo(bot=ConversationBot):
127
  sample_images = []
128
  all_imgs = [f"{SAMPLE_IMG_DIR}/{img}" for img in os.listdir(SAMPLE_IMG_DIR)]
lv_recipe_chatbot/engineer_prompt.py CHANGED
@@ -21,15 +21,14 @@ from langchain.schema import AIMessage, HumanMessage, SystemMessage
21
  INIT_PROMPT = ChatPromptTemplate.from_messages(
22
  [
23
  SystemMessagePromptTemplate.from_template(
24
- """
25
- The following is a conversation between a human and a friendly AI chef.
26
- The AI is compassionate to animals and only recommends vegan recipes based on the ingredients, allergies, and other preferences the human has.
27
-
28
- Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey
29
 
30
  Let's think step by step.
31
- If the human messages are unrelated to vegan recipes, remind them of your purpose to recommend vegan recipes.
32
- """.strip()
33
  ),
34
  AIMessagePromptTemplate.from_template(
35
  "What ingredients do you wish to cook with?"
@@ -43,30 +42,12 @@ If the human messages are unrelated to vegan recipes, remind them of your purpos
43
  "Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?"
44
  ),
45
  HumanMessagePromptTemplate.from_template(
46
- """
47
- Give me a vegan recipe that includes at least a few of the ingredients provided (if any).
48
- If there are only a few ingredients, please add more as necessary to provide a known tastier vegan recipe.
49
- Respect the user's allergies (if any).
50
- Follow these other preferences as closely as possible if they are inline with your purpose of recommending vegan recipes:
51
 
52
  ###
53
  Preferences: {recipe_freeform_input}
54
- ###
55
-
56
- Output format:
57
-
58
- **Vegan recipe name**
59
- Preparation time (humanized)
60
-
61
- Ingredients (List of ingredients with quantities):
62
- - <quantity and unit> <ingredient>
63
-
64
- Steps (detailed):
65
- 1.
66
- 2.
67
- 3.
68
- ...
69
- """.strip()
70
  ),
71
  ]
72
  )
 
21
  INIT_PROMPT = ChatPromptTemplate.from_messages(
22
  [
23
  SystemMessagePromptTemplate.from_template(
24
+ """The following is a conversation between a human and a friendly AI chef.
25
+ The AI is compassionate to animals.
26
+ The AI generates a simple concise keyword query for a vegan recipe, based on the ingredients, allergies, and other preferences the human has, to use in recipe APIs.
27
+ Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.
 
28
 
29
  Let's think step by step.
30
+ If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.
31
+ Only generate keyword queries as other tools should be used to fetch full recipes."""
32
  ),
33
  AIMessagePromptTemplate.from_template(
34
  "What ingredients do you wish to cook with?"
 
42
  "Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?"
43
  ),
44
  HumanMessagePromptTemplate.from_template(
45
+ """Generate a vegan recipe keyword query that is aligned with the user's allergies and contains at least a few of the ingredients provided (if any).
46
+ Draw some inspiration from the user's preferences delimited below if any are specified.
 
 
 
47
 
48
  ###
49
  Preferences: {recipe_freeform_input}
50
+ ###"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  ),
52
  ]
53
  )
lv_recipe_chatbot/lchain_tool.py CHANGED
@@ -1,21 +1,34 @@
1
- # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/02_lchain_tool.ipynb.
2
 
3
  # %% auto 0
4
- __all__ = ['RecipeSerpAPIWrapper']
5
 
6
- # %% ../nbs/02_lchain_tool.ipynb 3
7
  import os
 
8
 
9
- from IPython.display import Image
10
- from langchain.agents import AgentType, Tool, initialize_agent, load_tools, tool
 
 
 
 
 
 
 
 
11
  from langchain.agents.agent_toolkits import create_python_agent
12
  from langchain.chat_models import ChatOpenAI
 
 
13
  from langchain.python import PythonREPL
 
 
14
  from langchain.tools.python.tool import PythonREPLTool
15
  from langchain.utilities import GoogleSerperAPIWrapper, SerpAPIWrapper
16
  from serpapi import GoogleSearch
17
 
18
- # %% ../nbs/02_lchain_tool.ipynb 12
19
  class RecipeSerpAPIWrapper(SerpAPIWrapper):
20
  @staticmethod
21
  def _process_response(res: dict) -> str:
@@ -24,3 +37,43 @@ class RecipeSerpAPIWrapper(SerpAPIWrapper):
24
  raise ValueError(f"Got error from SerpAPI: {res['error']}")
25
  if "recipes_results" in res.keys():
26
  return res["recipes_results"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/02_vegan_recipe_tools.ipynb.
2
 
3
  # %% auto 0
4
+ __all__ = ['RecipeSerpAPIWrapper', 'get_vegan_recipes_edamam_api', 'vegan_recipe_edamam_search']
5
 
6
+ # %% ../nbs/02_vegan_recipe_tools.ipynb 3
7
  import os
8
+ from typing import Dict
9
 
10
+ import requests
11
+ from IPython.display import Image, Markdown, display
12
+ from langchain.agents import (
13
+ AgentExecutor,
14
+ AgentType,
15
+ OpenAIFunctionsAgent,
16
+ Tool,
17
+ initialize_agent,
18
+ load_tools,
19
+ )
20
  from langchain.agents.agent_toolkits import create_python_agent
21
  from langchain.chat_models import ChatOpenAI
22
+ from langchain.memory import ConversationBufferMemory
23
+ from langchain.prompts import MessagesPlaceholder
24
  from langchain.python import PythonREPL
25
+ from langchain.schema import SystemMessage
26
+ from langchain.tools import tool
27
  from langchain.tools.python.tool import PythonREPLTool
28
  from langchain.utilities import GoogleSerperAPIWrapper, SerpAPIWrapper
29
  from serpapi import GoogleSearch
30
 
31
+ # %% ../nbs/02_vegan_recipe_tools.ipynb 21
32
  class RecipeSerpAPIWrapper(SerpAPIWrapper):
33
  @staticmethod
34
  def _process_response(res: dict) -> str:
 
37
  raise ValueError(f"Got error from SerpAPI: {res['error']}")
38
  if "recipes_results" in res.keys():
39
  return res["recipes_results"]
40
+
41
+ # %% ../nbs/02_vegan_recipe_tools.ipynb 48
42
+ def get_vegan_recipes_edamam_api(params: Dict) -> requests.Response:
43
+ """
44
+ type is required and can be "any", "public", "user"
45
+ """
46
+ if "health" in params:
47
+ params["health"].append("vegan")
48
+ else:
49
+ params["health"] = ["vegan"]
50
+ params["app_id"] = os.environ["EDAMAM_APP_ID"]
51
+ params["app_key"] = os.environ["EDAMAM_APP_KEY"]
52
+ params["type"] = "public"
53
+ return requests.get("https://api.edamam.com/api/recipes/v2", params=params)
54
+
55
+ # %% ../nbs/02_vegan_recipe_tools.ipynb 55
56
+ @tool
57
+ def vegan_recipe_edamam_search(query: str) -> str:
58
+ """
59
+ Searches for vegan recipes based on a query.
60
+ If the query is not vegan friendly, adapt it to be.
61
+ If the request fails an explanation message will be returned instead of the recipe JSON.
62
+ """
63
+ # Veganize the query more
64
+ if "vegan" not in query.lower():
65
+ query = "vegan " + query
66
+
67
+ # TODO integrate additional params like totalTime range, cuisineType choice, nutrients[PROCNT] range of protein, health additional health params like gluten-free
68
+
69
+ params = {
70
+ "q": query,
71
+ "field": ["label", "url", "totalTime", "ingredientLines"]
72
+ # todo figure out how to include "image", "totalNutrients", "ingredientLines" without going over token limits immediately.
73
+ }
74
+
75
+ response = get_vegan_recipes_edamam_api(params)
76
+ if not response.ok:
77
+ return f"Received an error from Edamam API: {response.status_code} {response.text }"
78
+
79
+ return str([r["recipe"] for r in response.json()["hits"][0:3]])
lv_recipe_chatbot/vegan_recipe_tools.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/02_vegan_recipe_tools.ipynb.
2
+
3
+ # %% auto 0
4
+ __all__ = ['RecipeSerpAPIWrapper', 'get_vegan_recipes_edamam_api', 'vegan_recipe_edamam_search']
5
+
6
+ # %% ../nbs/02_vegan_recipe_tools.ipynb 3
7
+ import os
8
+ from typing import Dict
9
+
10
+ import requests
11
+ from IPython.display import Image, Markdown, display
12
+ from langchain.agents import (
13
+ AgentExecutor,
14
+ AgentType,
15
+ OpenAIFunctionsAgent,
16
+ Tool,
17
+ initialize_agent,
18
+ load_tools,
19
+ )
20
+ from langchain.agents.agent_toolkits import create_python_agent
21
+ from langchain.chat_models import ChatOpenAI
22
+ from langchain.memory import ConversationBufferMemory
23
+ from langchain.prompts import MessagesPlaceholder
24
+ from langchain.python import PythonREPL
25
+ from langchain.schema import SystemMessage
26
+ from langchain.tools import tool
27
+ from langchain.tools.python.tool import PythonREPLTool
28
+ from langchain.utilities import GoogleSerperAPIWrapper, SerpAPIWrapper
29
+ from serpapi import GoogleSearch
30
+
31
+ # %% ../nbs/02_vegan_recipe_tools.ipynb 21
32
+ class RecipeSerpAPIWrapper(SerpAPIWrapper):
33
+ @staticmethod
34
+ def _process_response(res: dict) -> str:
35
+ """Process response from SerpAPI."""
36
+ if "error" in res.keys():
37
+ raise ValueError(f"Got error from SerpAPI: {res['error']}")
38
+ if "recipes_results" in res.keys():
39
+ return res["recipes_results"]
40
+
41
+ # %% ../nbs/02_vegan_recipe_tools.ipynb 48
42
+ def get_vegan_recipes_edamam_api(params: Dict) -> requests.Response:
43
+ """
44
+ type is required and can be "any", "public", "user"
45
+ """
46
+ if "health" in params:
47
+ params["health"].append("vegan")
48
+ else:
49
+ params["health"] = ["vegan"]
50
+ params["app_id"] = os.environ["EDAMAM_APP_ID"]
51
+ params["app_key"] = os.environ["EDAMAM_APP_KEY"]
52
+ params["type"] = "public"
53
+ return requests.get("https://api.edamam.com/api/recipes/v2", params=params)
54
+
55
+ # %% ../nbs/02_vegan_recipe_tools.ipynb 55
56
+ @tool
57
+ def vegan_recipe_edamam_search(query: str) -> str:
58
+ """
59
+ Searches for vegan recipes based on a query.
60
+ If the query is not vegan friendly, adapt it to be.
61
+ If the request fails an explanation message will be returned instead of the recipe JSON.
62
+ """
63
+ # Veganize the query more
64
+ if "vegan" not in query.lower():
65
+ query = "vegan " + query
66
+
67
+ # TODO integrate additional params like totalTime range, cuisineType choice, nutrients[PROCNT] range of protein, health additional health params like gluten-free
68
+
69
+ params = {
70
+ "q": query,
71
+ "field": ["label", "url", "totalTime", "ingredientLines"]
72
+ # todo figure out how to include "image", "totalNutrients", "ingredientLines" without going over token limits immediately.
73
+ }
74
+
75
+ response = get_vegan_recipes_edamam_api(params)
76
+ if not response.ok:
77
+ return f"Received an error from Edamam API: {response.status_code} {response.text }"
78
+
79
+ return str([r["recipe"] for r in response.json()["hits"][0:3]])
nbs/.last_checked ADDED
File without changes
nbs/00_engineer_prompt.ipynb CHANGED
@@ -98,12 +98,12 @@
98
  " SystemMessagePromptTemplate.from_template(\n",
99
  " \"\"\"The following is a conversation between a human and a friendly AI chef. \n",
100
  "The AI is compassionate to animals.\n",
101
- "The AI generates a vegan recipe name, based on the ingredients, allergies, and other preferences the human has, to query recipe APIs.\n",
102
  "Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\n",
103
  "\n",
104
  "Let's think step by step.\n",
105
  "If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\n",
106
- "Only generate names as tools should be used to fetch full recipes.\"\"\"\n",
107
  " ),\n",
108
  " AIMessagePromptTemplate.from_template(\n",
109
  " \"What ingredients do you wish to cook with?\"\n",
@@ -117,14 +117,12 @@
117
  " \"Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\"\n",
118
  " ),\n",
119
  " HumanMessagePromptTemplate.from_template(\n",
120
- " \"\"\"Come up with a vegan recipe name to use the user's allergies and contains at least a few of the ingredients provided (if any).\n",
121
- "Try to follow the user's preferences delimited below if any are specified.\n",
122
  "\n",
123
  "###\n",
124
  "Preferences: {recipe_freeform_input}\n",
125
- "###\n",
126
- "\n",
127
- "\"\"\"\n",
128
  " ),\n",
129
  " ]\n",
130
  ")"
@@ -152,26 +150,24 @@
152
  "Prompt after formatting:\n",
153
  "\u001b[32;1m\u001b[1;3mSystem: The following is a conversation between a human and a friendly AI chef. \n",
154
  "The AI is compassionate to animals.\n",
155
- "The AI generates a vegan recipe name, based on the ingredients, allergies, and other preferences the human has, to query recipe APIs.\n",
156
  "Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\n",
157
  "\n",
158
  "Let's think step by step.\n",
159
  "If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\n",
160
- "Only generate names as tools should be used to fetch full recipes.\n",
161
  "AI: What ingredients do you wish to cook with?\n",
162
  "Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\n",
163
  "AI: Do you have any allergies I should be aware of?\n",
164
  "Human: Allergies: \n",
165
  "AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\n",
166
- "Human: Come up with a vegan recipe name to use the user's allergies and contains at least a few of the ingredients provided (if any).\n",
167
- "Try to follow the user's preferences delimited below if any are specified.\n",
168
  "\n",
169
  "###\n",
170
  "Preferences: The preparation time should be less than 30 minutes. I really love Thai food!\n",
171
  "###\n",
172
- "\n",
173
- "\n",
174
- "AI: Based on your preferences and the provided ingredients, I have come up with a vegan recipe name: \"Thai-inspired Tofu Banh Mi\". This recipe combines the flavors of Thai cuisine with the ingredients you mentioned, including tofu, pickles, tomatoes, and bread. It's a delicious and quick vegan sandwich that can be prepared in less than 30 minutes. Enjoy!\n",
175
  "Human: Recommend a different recipe please.\u001b[0m\n",
176
  "\n",
177
  "\u001b[1m> Finished chain.\u001b[0m\n",
@@ -181,32 +177,30 @@
181
  "Prompt after formatting:\n",
182
  "\u001b[32;1m\u001b[1;3mSystem: The following is a conversation between a human and a friendly AI chef. \n",
183
  "The AI is compassionate to animals.\n",
184
- "The AI generates a vegan recipe name, based on the ingredients, allergies, and other preferences the human has, to query recipe APIs.\n",
185
  "Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\n",
186
  "\n",
187
  "Let's think step by step.\n",
188
  "If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\n",
189
- "Only generate names as tools should be used to fetch full recipes.\n",
190
  "AI: What ingredients do you wish to cook with?\n",
191
  "Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\n",
192
  "AI: Do you have any allergies I should be aware of?\n",
193
  "Human: Allergies: \n",
194
  "AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\n",
195
- "Human: Come up with a vegan recipe name to use the user's allergies and contains at least a few of the ingredients provided (if any).\n",
196
- "Try to follow the user's preferences delimited below if any are specified.\n",
197
  "\n",
198
  "###\n",
199
  "Preferences: The preparation time should be less than 30 minutes. I really love Thai food!\n",
200
  "###\n",
201
- "\n",
202
- "\n",
203
- "AI: Based on your preferences and the provided ingredients, I have come up with a vegan recipe name: \"Thai-inspired Tofu Banh Mi\". This recipe combines the flavors of Thai cuisine with the ingredients you mentioned, including tofu, pickles, tomatoes, and bread. It's a delicious and quick vegan sandwich that can be prepared in less than 30 minutes. Enjoy!\n",
204
  "Human: Recommend a different recipe please.\n",
205
- "AI: Based on your preferences and the provided ingredients, another vegan recipe name I suggest is \"Mediterranean Tofu Salad with Tangy Pickle Dressing\". This recipe combines the freshness of Mediterranean flavors with the ingredients you mentioned, including tofu, pickles, olives, tomatoes, lettuce, and bell peppers. The tangy pickle dressing adds a delicious twist to the salad. It's a light and flavorful option that can be prepared in less than 30 minutes. Enjoy!\n",
206
  "Human: Aactually how about italian instead?\u001b[0m\n",
207
  "\n",
208
  "\u001b[1m> Finished chain.\u001b[0m\n",
209
- "Absolutely! How about the recipe name \"Italian Tofu Caprese Sandwich\"? This recipe combines the Italian flavors with tofu and some of the ingredients you mentioned, including tomatoes and bread. It's a vegan twist on the classic Caprese sandwich, featuring fresh tomatoes, tofu, and a drizzle of balsamic glaze. With its vibrant colors and delicious flavors, this Italian-inspired sandwich is sure to satisfy your taste buds. Enjoy!\n"
210
  ]
211
  }
212
  ],
 
98
  " SystemMessagePromptTemplate.from_template(\n",
99
  " \"\"\"The following is a conversation between a human and a friendly AI chef. \n",
100
  "The AI is compassionate to animals.\n",
101
+ "The AI generates a simple concise keyword query for a vegan recipe, based on the ingredients, allergies, and other preferences the human has, to use in recipe APIs.\n",
102
  "Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\n",
103
  "\n",
104
  "Let's think step by step.\n",
105
  "If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\n",
106
+ "Only generate keyword queries as other tools should be used to fetch full recipes.\"\"\"\n",
107
  " ),\n",
108
  " AIMessagePromptTemplate.from_template(\n",
109
  " \"What ingredients do you wish to cook with?\"\n",
 
117
  " \"Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\"\n",
118
  " ),\n",
119
  " HumanMessagePromptTemplate.from_template(\n",
120
+ " \"\"\"Generate a vegan recipe keyword query that is aligned with the user's allergies and contains at least a few of the ingredients provided (if any).\n",
121
+ "Draw some inspiration from the user's preferences delimited below if any are specified.\n",
122
  "\n",
123
  "###\n",
124
  "Preferences: {recipe_freeform_input}\n",
125
+ "###\"\"\"\n",
 
 
126
  " ),\n",
127
  " ]\n",
128
  ")"
 
150
  "Prompt after formatting:\n",
151
  "\u001b[32;1m\u001b[1;3mSystem: The following is a conversation between a human and a friendly AI chef. \n",
152
  "The AI is compassionate to animals.\n",
153
+ "The AI generates a simple concise keyword query for a vegan recipe, based on the ingredients, allergies, and other preferences the human has, to use in recipe APIs.\n",
154
  "Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\n",
155
  "\n",
156
  "Let's think step by step.\n",
157
  "If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\n",
158
+ "Only generate keyword queries as other tools should be used to fetch full recipes.\n",
159
  "AI: What ingredients do you wish to cook with?\n",
160
  "Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\n",
161
  "AI: Do you have any allergies I should be aware of?\n",
162
  "Human: Allergies: \n",
163
  "AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\n",
164
+ "Human: Generate a vegan recipe keyword query that is aligned with the user's allergies and contains at least a few of the ingredients provided (if any).\n",
165
+ "Draw some inspiration from the user's preferences delimited below if any are specified.\n",
166
  "\n",
167
  "###\n",
168
  "Preferences: The preparation time should be less than 30 minutes. I really love Thai food!\n",
169
  "###\n",
170
+ "AI: Based on your preferences, allergies, and ingredients, a concise vegan recipe keyword query could be: \"vegan Thai tofu sandwich with pickles, olives, tomatoes, lettuce, bell peppers, and carrots\". This should help you find a suitable recipe using recipe APIs or other recipe platforms.\n",
 
 
171
  "Human: Recommend a different recipe please.\u001b[0m\n",
172
  "\n",
173
  "\u001b[1m> Finished chain.\u001b[0m\n",
 
177
  "Prompt after formatting:\n",
178
  "\u001b[32;1m\u001b[1;3mSystem: The following is a conversation between a human and a friendly AI chef. \n",
179
  "The AI is compassionate to animals.\n",
180
+ "The AI generates a simple concise keyword query for a vegan recipe, based on the ingredients, allergies, and other preferences the human has, to use in recipe APIs.\n",
181
  "Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\n",
182
  "\n",
183
  "Let's think step by step.\n",
184
  "If the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\n",
185
+ "Only generate keyword queries as other tools should be used to fetch full recipes.\n",
186
  "AI: What ingredients do you wish to cook with?\n",
187
  "Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\n",
188
  "AI: Do you have any allergies I should be aware of?\n",
189
  "Human: Allergies: \n",
190
  "AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\n",
191
+ "Human: Generate a vegan recipe keyword query that is aligned with the user's allergies and contains at least a few of the ingredients provided (if any).\n",
192
+ "Draw some inspiration from the user's preferences delimited below if any are specified.\n",
193
  "\n",
194
  "###\n",
195
  "Preferences: The preparation time should be less than 30 minutes. I really love Thai food!\n",
196
  "###\n",
197
+ "AI: Based on your preferences, allergies, and ingredients, a concise vegan recipe keyword query could be: \"vegan Thai tofu sandwich with pickles, olives, tomatoes, lettuce, bell peppers, and carrots\". This should help you find a suitable recipe using recipe APIs or other recipe platforms.\n",
 
 
198
  "Human: Recommend a different recipe please.\n",
199
+ "AI: Certainly! How about a vegan Thai peanut tofu stir-fry? It's a delicious and easy-to-make dish that incorporates some of the ingredients you mentioned. Here's a concise vegan recipe keyword query for it: \"vegan Thai peanut tofu stir-fry with tofu, bell peppers, carrots, and peanuts\". This should give you some great recipe options to explore!\n",
200
  "Human: Aactually how about italian instead?\u001b[0m\n",
201
  "\n",
202
  "\u001b[1m> Finished chain.\u001b[0m\n",
203
+ "Of course! If you prefer an Italian-inspired vegan recipe, how about a vegan Caprese salad with marinated tofu? It's a refreshing and flavorful dish that combines tomatoes, tofu, and basil. Here's a concise vegan recipe keyword query for it: \"vegan Caprese salad with marinated tofu, tomatoes, and basil\". This should help you find some delicious Italian vegan recipes to try out!\n"
204
  ]
205
  }
206
  ],
nbs/01_app.ipynb CHANGED
@@ -40,9 +40,18 @@
40
  "\n",
41
  "import gradio as gr\n",
42
  "from fastcore.utils import in_jupyter\n",
 
 
 
 
 
 
 
 
 
43
  "from langchain.chains import ConversationChain\n",
44
  "from langchain.chat_models import ChatOpenAI\n",
45
- "from langchain.memory import ConversationBufferMemory\n",
46
  "from langchain.prompts.chat import (\n",
47
  " ChatPromptTemplate,\n",
48
  " HumanMessagePromptTemplate,\n",
@@ -57,9 +66,325 @@
57
  " BlipImageCaptioning,\n",
58
  " VeganIngredientFinder,\n",
59
  " format_image,\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  ")"
61
  ]
62
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  {
64
  "cell_type": "code",
65
  "execution_count": null,
@@ -174,36 +499,6 @@
174
  "SAMPLE_IMG_DIR"
175
  ]
176
  },
177
- {
178
- "cell_type": "code",
179
- "execution_count": null,
180
- "metadata": {},
181
- "outputs": [],
182
- "source": [
183
- "from dotenv import load_dotenv"
184
- ]
185
- },
186
- {
187
- "cell_type": "code",
188
- "execution_count": null,
189
- "metadata": {},
190
- "outputs": [
191
- {
192
- "data": {
193
- "text/plain": [
194
- "True"
195
- ]
196
- },
197
- "execution_count": null,
198
- "metadata": {},
199
- "output_type": "execute_result"
200
- }
201
- ],
202
- "source": [
203
- "#: eval: false\n",
204
- "load_dotenv()"
205
- ]
206
- },
207
  {
208
  "cell_type": "code",
209
  "execution_count": null,
 
40
  "\n",
41
  "import gradio as gr\n",
42
  "from fastcore.utils import in_jupyter\n",
43
+ "from langchain import LLMChain, OpenAI, PromptTemplate\n",
44
+ "from langchain.agents import (\n",
45
+ " AgentExecutor,\n",
46
+ " AgentType,\n",
47
+ " OpenAIFunctionsAgent,\n",
48
+ " Tool,\n",
49
+ " initialize_agent,\n",
50
+ " load_tools,\n",
51
+ ")\n",
52
  "from langchain.chains import ConversationChain\n",
53
  "from langchain.chat_models import ChatOpenAI\n",
54
+ "from langchain.memory import ChatMessageHistory, ConversationBufferMemory\n",
55
  "from langchain.prompts.chat import (\n",
56
  " ChatPromptTemplate,\n",
57
  " HumanMessagePromptTemplate,\n",
 
66
  " BlipImageCaptioning,\n",
67
  " VeganIngredientFinder,\n",
68
  " format_image,\n",
69
+ ")\n",
70
+ "from lv_recipe_chatbot.vegan_recipe_tools import vegan_recipe_edamam_search"
71
+ ]
72
+ },
73
+ {
74
+ "cell_type": "code",
75
+ "execution_count": null,
76
+ "metadata": {},
77
+ "outputs": [],
78
+ "source": [
79
+ "from dotenv import load_dotenv"
80
+ ]
81
+ },
82
+ {
83
+ "cell_type": "code",
84
+ "execution_count": null,
85
+ "metadata": {},
86
+ "outputs": [
87
+ {
88
+ "data": {
89
+ "text/plain": [
90
+ "True"
91
+ ]
92
+ },
93
+ "execution_count": null,
94
+ "metadata": {},
95
+ "output_type": "execute_result"
96
+ }
97
+ ],
98
+ "source": [
99
+ "#: eval: false\n",
100
+ "load_dotenv()"
101
+ ]
102
+ },
103
+ {
104
+ "cell_type": "markdown",
105
+ "metadata": {},
106
+ "source": [
107
+ "## Put the chat backend pieces together"
108
+ ]
109
+ },
110
+ {
111
+ "cell_type": "code",
112
+ "execution_count": null,
113
+ "metadata": {},
114
+ "outputs": [
115
+ {
116
+ "data": {
117
+ "text/markdown": [
118
+ "---\n",
119
+ "\n",
120
+ "### ConversationBufferMemory\n",
121
+ "\n",
122
+ "> ConversationBufferMemory\n",
123
+ "> (chat_memory:langchain.schema.memory.BaseChatMe\n",
124
+ "> ssageHistory=None,\n",
125
+ "> output_key:Optional[str]=None,\n",
126
+ "> input_key:Optional[str]=None,\n",
127
+ "> return_messages:bool=False,\n",
128
+ "> human_prefix:str='Human', ai_prefix:str='AI',\n",
129
+ "> memory_key:str='history')\n",
130
+ "\n",
131
+ "Buffer for storing conversation memory."
132
+ ],
133
+ "text/plain": [
134
+ "---\n",
135
+ "\n",
136
+ "### ConversationBufferMemory\n",
137
+ "\n",
138
+ "> ConversationBufferMemory\n",
139
+ "> (chat_memory:langchain.schema.memory.BaseChatMe\n",
140
+ "> ssageHistory=None,\n",
141
+ "> output_key:Optional[str]=None,\n",
142
+ "> input_key:Optional[str]=None,\n",
143
+ "> return_messages:bool=False,\n",
144
+ "> human_prefix:str='Human', ai_prefix:str='AI',\n",
145
+ "> memory_key:str='history')\n",
146
+ "\n",
147
+ "Buffer for storing conversation memory."
148
+ ]
149
+ },
150
+ "execution_count": null,
151
+ "metadata": {},
152
+ "output_type": "execute_result"
153
+ }
154
+ ],
155
+ "source": [
156
+ "show_doc(ConversationBufferMemory)"
157
+ ]
158
+ },
159
+ {
160
+ "cell_type": "code",
161
+ "execution_count": null,
162
+ "metadata": {},
163
+ "outputs": [
164
+ {
165
+ "data": {
166
+ "text/markdown": [
167
+ "---\n",
168
+ "\n",
169
+ "### ChatMessageHistory\n",
170
+ "\n",
171
+ "> ChatMessageHistory\n",
172
+ "> (messages:List[langchain.schema.messages.BaseMessage]\n",
173
+ "> =[])\n",
174
+ "\n",
175
+ "In memory implementation of chat message history.\n",
176
+ "\n",
177
+ "Stores messages in an in memory list."
178
+ ],
179
+ "text/plain": [
180
+ "---\n",
181
+ "\n",
182
+ "### ChatMessageHistory\n",
183
+ "\n",
184
+ "> ChatMessageHistory\n",
185
+ "> (messages:List[langchain.schema.messages.BaseMessage]\n",
186
+ "> =[])\n",
187
+ "\n",
188
+ "In memory implementation of chat message history.\n",
189
+ "\n",
190
+ "Stores messages in an in memory list."
191
+ ]
192
+ },
193
+ "execution_count": null,
194
+ "metadata": {},
195
+ "output_type": "execute_result"
196
+ }
197
+ ],
198
+ "source": [
199
+ "show_doc(ChatMessageHistory)"
200
+ ]
201
+ },
202
+ {
203
+ "cell_type": "code",
204
+ "execution_count": null,
205
+ "metadata": {},
206
+ "outputs": [
207
+ {
208
+ "data": {
209
+ "text/markdown": [
210
+ "---\n",
211
+ "\n",
212
+ "### ChatOpenAI\n",
213
+ "\n",
214
+ "> ChatOpenAI (cache:Optional[bool]=None, verbose:bool=None, callbacks:Union\n",
215
+ "> [List[langchain.callbacks.base.BaseCallbackHandler],langchain\n",
216
+ "> .callbacks.base.BaseCallbackManager,NoneType]=None, callback_\n",
217
+ "> manager:Optional[langchain.callbacks.base.BaseCallbackManager\n",
218
+ "> ]=None, tags:Optional[List[str]]=None,\n",
219
+ "> metadata:Optional[Dict[str,Any]]=None, client:Any=None,\n",
220
+ "> model:str='gpt-3.5-turbo', temperature:float=0.7,\n",
221
+ "> model_kwargs:Dict[str,Any]=None,\n",
222
+ "> openai_api_key:Optional[str]=None,\n",
223
+ "> openai_api_base:Optional[str]=None,\n",
224
+ "> openai_organization:Optional[str]=None,\n",
225
+ "> openai_proxy:Optional[str]=None, request_timeout:Union[float,\n",
226
+ "> Tuple[float,float],NoneType]=None, max_retries:int=6,\n",
227
+ "> streaming:bool=False, n:int=1, max_tokens:Optional[int]=None,\n",
228
+ "> tiktoken_model_name:Optional[str]=None)\n",
229
+ "\n",
230
+ "Wrapper around OpenAI Chat large language models.\n",
231
+ "\n",
232
+ "To use, you should have the ``openai`` python package installed, and the\n",
233
+ "environment variable ``OPENAI_API_KEY`` set with your API key.\n",
234
+ "\n",
235
+ "Any parameters that are valid to be passed to the openai.create call can be passed\n",
236
+ "in, even if not explicitly saved on this class.\n",
237
+ "\n",
238
+ "Example:\n",
239
+ " .. code-block:: python\n",
240
+ "\n",
241
+ " from langchain.chat_models import ChatOpenAI\n",
242
+ " openai = ChatOpenAI(model_name=\"gpt-3.5-turbo\")"
243
+ ],
244
+ "text/plain": [
245
+ "---\n",
246
+ "\n",
247
+ "### ChatOpenAI\n",
248
+ "\n",
249
+ "> ChatOpenAI (cache:Optional[bool]=None, verbose:bool=None, callbacks:Union\n",
250
+ "> [List[langchain.callbacks.base.BaseCallbackHandler],langchain\n",
251
+ "> .callbacks.base.BaseCallbackManager,NoneType]=None, callback_\n",
252
+ "> manager:Optional[langchain.callbacks.base.BaseCallbackManager\n",
253
+ "> ]=None, tags:Optional[List[str]]=None,\n",
254
+ "> metadata:Optional[Dict[str,Any]]=None, client:Any=None,\n",
255
+ "> model:str='gpt-3.5-turbo', temperature:float=0.7,\n",
256
+ "> model_kwargs:Dict[str,Any]=None,\n",
257
+ "> openai_api_key:Optional[str]=None,\n",
258
+ "> openai_api_base:Optional[str]=None,\n",
259
+ "> openai_organization:Optional[str]=None,\n",
260
+ "> openai_proxy:Optional[str]=None, request_timeout:Union[float,\n",
261
+ "> Tuple[float,float],NoneType]=None, max_retries:int=6,\n",
262
+ "> streaming:bool=False, n:int=1, max_tokens:Optional[int]=None,\n",
263
+ "> tiktoken_model_name:Optional[str]=None)\n",
264
+ "\n",
265
+ "Wrapper around OpenAI Chat large language models.\n",
266
+ "\n",
267
+ "To use, you should have the ``openai`` python package installed, and the\n",
268
+ "environment variable ``OPENAI_API_KEY`` set with your API key.\n",
269
+ "\n",
270
+ "Any parameters that are valid to be passed to the openai.create call can be passed\n",
271
+ "in, even if not explicitly saved on this class.\n",
272
+ "\n",
273
+ "Example:\n",
274
+ " .. code-block:: python\n",
275
+ "\n",
276
+ " from langchain.chat_models import ChatOpenAI\n",
277
+ " openai = ChatOpenAI(model_name=\"gpt-3.5-turbo\")"
278
+ ]
279
+ },
280
+ "execution_count": null,
281
+ "metadata": {},
282
+ "output_type": "execute_result"
283
+ }
284
+ ],
285
+ "source": [
286
+ "show_doc(ChatOpenAI)"
287
+ ]
288
+ },
289
+ {
290
+ "cell_type": "code",
291
+ "execution_count": null,
292
+ "metadata": {},
293
+ "outputs": [],
294
+ "source": [
295
+ "#| eval: false\n",
296
+ "llm = ChatOpenAI(temperature=1)\n",
297
+ "MEMORY_KEY = \"chat_history\"\n",
298
+ "chat_msgs = INIT_PROMPT.format_prompt(\n",
299
+ " ingredients=\"tofu, brocolli\",\n",
300
+ " allergies=\"\",\n",
301
+ " recipe_freeform_input=\"The preparation time should be less than 30 minutes. I really love Thai food!\",\n",
302
+ ")\n",
303
+ "chat_msgs = chat_msgs.to_messages()\n",
304
+ "results = llm.generate([chat_msgs])\n",
305
+ "\n",
306
+ "chat_msgs.append(results.generations[0][0].message)\n",
307
+ "tools = [vegan_recipe_edamam_search]\n",
308
+ "prompt = OpenAIFunctionsAgent.create_prompt(\n",
309
+ " system_message=INIT_PROMPT.messages[0],\n",
310
+ " extra_prompt_messages=chat_msgs + [MessagesPlaceholder(variable_name=MEMORY_KEY)],\n",
311
+ ")\n",
312
+ "memory = ConversationBufferMemory(\n",
313
+ " chat_memory=ChatMessageHistory(messages=chat_msgs),\n",
314
+ " return_messages=True,\n",
315
+ " memory_key=MEMORY_KEY,\n",
316
+ ")\n",
317
+ "agent_executor = AgentExecutor(\n",
318
+ " agent=OpenAIFunctionsAgent(llm=llm, tools=tools, prompt=prompt),\n",
319
+ " tools=tools,\n",
320
+ " memory=memory,\n",
321
+ " verbose=True,\n",
322
  ")"
323
  ]
324
  },
325
+ {
326
+ "cell_type": "code",
327
+ "execution_count": null,
328
+ "metadata": {},
329
+ "outputs": [],
330
+ "source": [
331
+ "# Fails for a weird query\n",
332
+ "# \"tofu, pickles, mustard, olives, tomatoes, lettuce, bell peppers, carrots, bread\""
333
+ ]
334
+ },
335
+ {
336
+ "cell_type": "code",
337
+ "execution_count": null,
338
+ "metadata": {},
339
+ "outputs": [
340
+ {
341
+ "data": {
342
+ "text/plain": [
343
+ "[SystemMessage(content=\"The following is a conversation between a human and a friendly AI chef. \\nThe AI is compassionate to animals.\\nThe AI generates a simple concise keyword query for a vegan recipe, based on the ingredients, allergies, and other preferences the human has, to use in recipe APIs.\\nKnowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey.\\n\\nLet's think step by step.\\nIf the human messages are unrelated to vegan recipes, remind them of your purpose to recipes.\\nOnly generate keyword queries as other tools should be used to fetch full recipes.\", additional_kwargs={}),\n",
344
+ " AIMessage(content='What ingredients do you wish to cook with?', additional_kwargs={}, example=False),\n",
345
+ " HumanMessage(content='Ingredients: tofu, brocolli', additional_kwargs={}, example=False),\n",
346
+ " AIMessage(content='Do you have any allergies I should be aware of?', additional_kwargs={}, example=False),\n",
347
+ " HumanMessage(content='Allergies: ', additional_kwargs={}, example=False),\n",
348
+ " AIMessage(content='Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?', additional_kwargs={}, example=False),\n",
349
+ " HumanMessage(content=\"Generate a vegan recipe keyword query that is aligned with the user's allergies and contains at least a few of the ingredients provided (if any).\\nDraw some inspiration from the user's preferences delimited below if any are specified.\\n\\n###\\nPreferences: The preparation time should be less than 30 minutes. I really love Thai food!\\n###\", additional_kwargs={}, example=False),\n",
350
+ " AIMessage(content='Based on the ingredients, allergies, and preferences you provided, here is a vegan recipe keyword query suggestion: \"vegan Thai tofu broccoli stir fry recipe\"', additional_kwargs={}, example=False)]"
351
+ ]
352
+ },
353
+ "execution_count": null,
354
+ "metadata": {},
355
+ "output_type": "execute_result"
356
+ }
357
+ ],
358
+ "source": [
359
+ "#| eval: false\n",
360
+ "memory.chat_memory.messages"
361
+ ]
362
+ },
363
+ {
364
+ "cell_type": "code",
365
+ "execution_count": null,
366
+ "metadata": {},
367
+ "outputs": [
368
+ {
369
+ "name": "stdout",
370
+ "output_type": "stream",
371
+ "text": [
372
+ "\n",
373
+ "\n",
374
+ "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
375
+ "\u001b[32;1m\u001b[1;3m\n",
376
+ "Invoking: `vegan_recipe_edamam_search` with `{'query': 'vegan tofu broccoli'}`\n",
377
+ "\n",
378
+ "\n",
379
+ "\u001b[0m\u001b[36;1m\u001b[1;3m[{'label': 'Vegan BBQ teriyaki tofu', 'url': 'https://www.bbcgoodfood.com/recipes/teriyaki-tofu-vegan-barbecue', 'ingredientLines': ['4 tbsp low-salt soy sauce', '2 tbsp soft brown sugar', 'pinch ground ginger', '2 tbsp mirin', '3 tsp sesame oil', '350g block very firm tofu (see tip below) cut into thick slices', '½ tbsp rapeseed oil', '2 courgettes, sliced horizontally into strips', '200g Tenderstem broccoli', 'black and white sesame seeds, to serve'], 'totalTime': 25.0}, {'label': 'Vegan Crispy Stir-Fried Tofu With Broccoli Recipe', 'url': 'http://www.seriouseats.com/recipes/2014/02/vegan-experience-crispy-tofu-broccoli-stir-fry.html', 'ingredientLines': ['1 1/2 quarts vegetable or peanut oil', '1/2 cup plus 2 teaspoons cornstarch, divided', '1/2 cup all-purpose flour', '1/2 teaspoon baking powder', 'Kosher salt', '1/2 cup cold water', '1/2 cup vodka', '1 pound extra-firm tofu, cut into 1/2- by 2- by 1-inch slabs, carefully dried (see note above)', '1 pound broccoli, cut into 1-inch florets', '1/4 cup Xiaoshing wine or dry sherry', '1/4 cup homemade or store-bought low-sodium vegetable stock', '2 tablespoons soy sauce', '1 tablespoon fermented black bean sauce', '2 tablespoons sugar', '1 tablespoon toasted sesame oil', '2 (1-inch) segments lemon peel, plus 2 teaspoons lemon juice', '4 cloves garlic, minced (about 4 teaspoons)', '1 tablespoon minced or grated fresh ginger', '6 scallions, white and light green parts only, finely chopped', '2 tablespoons toasted sesame seeds, divided'], 'totalTime': 30.0}, {'label': 'Thai-Style Chopped Salad with Sriracha Tofu', 'url': 'http://www.eatingwell.com/recipe/276172/thai-style-chopped-salad-with-sriracha-tofu/', 'ingredientLines': ['1 (10 ounce) package kale, Brussels sprout, broccoli and cabbage salad mix', '1 (12 ounce) package frozen shelled edamame, thawed', '2 (7 ounce) packages Sriracha-flavored baked tofu, cubed', '1/2 cup spicy peanut vinaigrette'], 'totalTime': 10.0}]\u001b[0m"
380
+ ]
381
+ }
382
+ ],
383
+ "source": [
384
+ "#| eval: false\n",
385
+ "agent_executor.run(\"Search for vegan recipe\")"
386
+ ]
387
+ },
388
  {
389
  "cell_type": "code",
390
  "execution_count": null,
 
499
  "SAMPLE_IMG_DIR"
500
  ]
501
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
502
  {
503
  "cell_type": "code",
504
  "execution_count": null,
nbs/02_lchain_tool.ipynb DELETED
@@ -1,962 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "markdown",
5
- "metadata": {},
6
- "source": [
7
- "# lchain_tool\n",
8
- "\n",
9
- "> Exploring Langchain Tool capabilities"
10
- ]
11
- },
12
- {
13
- "cell_type": "code",
14
- "execution_count": null,
15
- "metadata": {},
16
- "outputs": [],
17
- "source": [
18
- "#| default_exp lchain_tool"
19
- ]
20
- },
21
- {
22
- "cell_type": "code",
23
- "execution_count": null,
24
- "metadata": {},
25
- "outputs": [],
26
- "source": [
27
- "#| hide\n",
28
- "from nbdev.showdoc import *"
29
- ]
30
- },
31
- {
32
- "cell_type": "code",
33
- "execution_count": null,
34
- "metadata": {},
35
- "outputs": [],
36
- "source": [
37
- "#| export\n",
38
- "import os\n",
39
- "\n",
40
- "from IPython.display import Image\n",
41
- "from langchain.agents import AgentType, Tool, initialize_agent, load_tools, tool\n",
42
- "from langchain.agents.agent_toolkits import create_python_agent\n",
43
- "from langchain.chat_models import ChatOpenAI\n",
44
- "from langchain.python import PythonREPL\n",
45
- "from langchain.tools.python.tool import PythonREPLTool\n",
46
- "from langchain.utilities import GoogleSerperAPIWrapper, SerpAPIWrapper\n",
47
- "from serpapi import GoogleSearch"
48
- ]
49
- },
50
- {
51
- "cell_type": "code",
52
- "execution_count": null,
53
- "metadata": {},
54
- "outputs": [],
55
- "source": [
56
- "from dotenv import load_dotenv"
57
- ]
58
- },
59
- {
60
- "cell_type": "code",
61
- "execution_count": null,
62
- "metadata": {},
63
- "outputs": [
64
- {
65
- "data": {
66
- "text/plain": [
67
- "True"
68
- ]
69
- },
70
- "execution_count": null,
71
- "metadata": {},
72
- "output_type": "execute_result"
73
- }
74
- ],
75
- "source": [
76
- "load_dotenv()"
77
- ]
78
- },
79
- {
80
- "cell_type": "code",
81
- "execution_count": null,
82
- "metadata": {},
83
- "outputs": [],
84
- "source": [
85
- "llm = ChatOpenAI(temperature=0)"
86
- ]
87
- },
88
- {
89
- "cell_type": "code",
90
- "execution_count": null,
91
- "metadata": {},
92
- "outputs": [],
93
- "source": [
94
- "tools = load_tools([\"llm-math\"], llm=llm)\n",
95
- "agent = initialize_agent(\n",
96
- " tools,\n",
97
- " llm,\n",
98
- " agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n",
99
- " handle_parsing_errors=True,\n",
100
- " verbose=True,\n",
101
- ")"
102
- ]
103
- },
104
- {
105
- "cell_type": "code",
106
- "execution_count": null,
107
- "metadata": {},
108
- "outputs": [
109
- {
110
- "name": "stdout",
111
- "output_type": "stream",
112
- "text": [
113
- "\n",
114
- "\n",
115
- "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
116
- "\u001b[32;1m\u001b[1;3mWe can calculate this using the Calculator tool.\n",
117
- "\n",
118
- "Action:\n",
119
- "```\n",
120
- "{\n",
121
- " \"action\": \"Calculator\",\n",
122
- " \"action_input\": \"0.03 * 300 * 30\"\n",
123
- "}\n",
124
- "```\n",
125
- "\n",
126
- "\u001b[0m\n",
127
- "Observation: \u001b[36;1m\u001b[1;3mAnswer: 270.0\u001b[0m\n",
128
- "Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: This is the correct answer to the question.\u001b[0m\n",
129
- "Observation: Invalid or incomplete response\n",
130
- "Thought:\u001b[32;1m\u001b[1;3mLet me try the same action again.\n",
131
- "\n",
132
- "Action:\n",
133
- "```\n",
134
- "{\n",
135
- " \"action\": \"Calculator\",\n",
136
- " \"action_input\": \"0.03 * 300 * 30\"\n",
137
- "}\n",
138
- "```\n",
139
- "\n",
140
- "\u001b[0m\n",
141
- "Observation: \u001b[36;1m\u001b[1;3mAnswer: 270.0\u001b[0m\n",
142
- "Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: The tool gave the same answer, so I can be confident that it is correct.\n",
143
- "\u001b[0m\n",
144
- "Observation: Invalid or incomplete response\n",
145
- "Thought:\u001b[32;1m\u001b[1;3mThere seems to be an issue with the LLM response. Let me try a different way to calculate the answer.\n",
146
- "\n",
147
- "Action:\n",
148
- "```\n",
149
- "{\n",
150
- " \"action\": \"Calculator\",\n",
151
- " \"action_input\": \"300 * 30 * 0.03\"\n",
152
- "}\n",
153
- "```\n",
154
- "\n",
155
- "\u001b[0m\n",
156
- "Observation: \u001b[36;1m\u001b[1;3mAnswer: 270.0\u001b[0m\n",
157
- "Thought:\u001b[32;1m\u001b[1;3mI have successfully calculated the answer to the question using the calculator tool.\n",
158
- "\n",
159
- "Final Answer: 270.0\u001b[0m\n",
160
- "\n",
161
- "\u001b[1m> Finished chain.\u001b[0m\n"
162
- ]
163
- },
164
- {
165
- "data": {
166
- "text/plain": [
167
- "{'input': 'What is the 3% of of 300 * 30?', 'output': '270.0'}"
168
- ]
169
- },
170
- "execution_count": null,
171
- "metadata": {},
172
- "output_type": "execute_result"
173
- }
174
- ],
175
- "source": [
176
- "#| eval:false\n",
177
- "agent(\"What is the 3% of of 300 * 30?\")"
178
- ]
179
- },
180
- {
181
- "cell_type": "markdown",
182
- "metadata": {},
183
- "source": [
184
- "[SerpAPI Google Images](https://python.langchain.com/en/latest/modules/agents/tools/examples/google_serper.html#searching-for-google-images)"
185
- ]
186
- },
187
- {
188
- "cell_type": "code",
189
- "execution_count": null,
190
- "metadata": {},
191
- "outputs": [
192
- {
193
- "data": {
194
- "text/plain": [
195
- "[{'title': 'Easy Tofu Pad Thai',\n",
196
- " 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',\n",
197
- " 'source': 'Minimalist Baker',\n",
198
- " 'rating': 4.9,\n",
199
- " 'reviews': 117,\n",
200
- " 'total_time': '30 min',\n",
201
- " 'ingredients': ['Pad thai rice',\n",
202
- " 'peanut sauce',\n",
203
- " 'thai red',\n",
204
- " 'soy sauce',\n",
205
- " 'bean sprouts']},\n",
206
- " {'title': 'Vegan Pad Thai',\n",
207
- " 'link': 'https://www.noracooks.com/vegan-pad-thai/',\n",
208
- " 'source': 'Nora Cooks',\n",
209
- " 'rating': 5.0,\n",
210
- " 'reviews': 53,\n",
211
- " 'total_time': '30 min',\n",
212
- " 'ingredients': ['Stir fry rice',\n",
213
- " 'mung bean sprouts',\n",
214
- " 'soy sauce',\n",
215
- " 'maple syrup',\n",
216
- " 'sriracha hot sauce']},\n",
217
- " {'title': 'Vegan Pad Thai',\n",
218
- " 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116',\n",
219
- " 'source': 'Pick Up Limes',\n",
220
- " 'rating': 5.0,\n",
221
- " 'reviews': 34,\n",
222
- " 'total_time': '30 min',\n",
223
- " 'ingredients': ['Brown rice noodles',\n",
224
- " 'red hot',\n",
225
- " 'soy sauce',\n",
226
- " 'bean sprouts',\n",
227
- " 'sriracha hot sauce']}]"
228
- ]
229
- },
230
- "execution_count": null,
231
- "metadata": {},
232
- "output_type": "execute_result"
233
- }
234
- ],
235
- "source": [
236
- "#| eval: false\n",
237
- "params = {\n",
238
- " \"q\": \"Vegan pad thai recipes\",\n",
239
- " \"location\": \"United States\",\n",
240
- " \"hl\": \"en\",\n",
241
- " \"gl\": \"us\",\n",
242
- " \"api_key\": os.environ[\"SERPAPI_API_KEY\"],\n",
243
- "}\n",
244
- "\n",
245
- "search = GoogleSearch(params)\n",
246
- "results = search.get_dict()\n",
247
- "recipes_results = results[\"recipes_results\"]\n",
248
- "recipes_results"
249
- ]
250
- },
251
- {
252
- "cell_type": "code",
253
- "execution_count": null,
254
- "metadata": {},
255
- "outputs": [
256
- {
257
- "data": {
258
- "text/markdown": [
259
- "---\n",
260
- "\n",
261
- "### SerpAPIWrapper\n",
262
- "\n",
263
- "> SerpAPIWrapper (search_engine:Any=None, params:dict={'engine': 'google',\n",
264
- "> 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'},\n",
265
- "> serpapi_api_key:Optional[str]=None,\n",
266
- "> aiosession:Optional[aiohttp.client.ClientSession]=None)\n",
267
- "\n",
268
- "Wrapper around SerpAPI.\n",
269
- "\n",
270
- "To use, you should have the ``google-search-results`` python package installed,\n",
271
- "and the environment variable ``SERPAPI_API_KEY`` set with your API key, or pass\n",
272
- "`serpapi_api_key` as a named parameter to the constructor.\n",
273
- "\n",
274
- "Example:\n",
275
- " .. code-block:: python\n",
276
- "\n",
277
- " from langchain import SerpAPIWrapper\n",
278
- " serpapi = SerpAPIWrapper()"
279
- ],
280
- "text/plain": [
281
- "---\n",
282
- "\n",
283
- "### SerpAPIWrapper\n",
284
- "\n",
285
- "> SerpAPIWrapper (search_engine:Any=None, params:dict={'engine': 'google',\n",
286
- "> 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'},\n",
287
- "> serpapi_api_key:Optional[str]=None,\n",
288
- "> aiosession:Optional[aiohttp.client.ClientSession]=None)\n",
289
- "\n",
290
- "Wrapper around SerpAPI.\n",
291
- "\n",
292
- "To use, you should have the ``google-search-results`` python package installed,\n",
293
- "and the environment variable ``SERPAPI_API_KEY`` set with your API key, or pass\n",
294
- "`serpapi_api_key` as a named parameter to the constructor.\n",
295
- "\n",
296
- "Example:\n",
297
- " .. code-block:: python\n",
298
- "\n",
299
- " from langchain import SerpAPIWrapper\n",
300
- " serpapi = SerpAPIWrapper()"
301
- ]
302
- },
303
- "execution_count": null,
304
- "metadata": {},
305
- "output_type": "execute_result"
306
- }
307
- ],
308
- "source": [
309
- "show_doc(SerpAPIWrapper)"
310
- ]
311
- },
312
- {
313
- "cell_type": "code",
314
- "execution_count": null,
315
- "metadata": {},
316
- "outputs": [],
317
- "source": [
318
- "#| export\n",
319
- "class RecipeSerpAPIWrapper(SerpAPIWrapper):\n",
320
- " @staticmethod\n",
321
- " def _process_response(res: dict) -> str:\n",
322
- " \"\"\"Process response from SerpAPI.\"\"\"\n",
323
- " if \"error\" in res.keys():\n",
324
- " raise ValueError(f\"Got error from SerpAPI: {res['error']}\")\n",
325
- " if \"recipes_results\" in res.keys():\n",
326
- " return res[\"recipes_results\"]"
327
- ]
328
- },
329
- {
330
- "cell_type": "code",
331
- "execution_count": null,
332
- "metadata": {},
333
- "outputs": [],
334
- "source": [
335
- "#| eval: false\n",
336
- "params = {\n",
337
- " \"location\": \"United States\",\n",
338
- " \"hl\": \"en\",\n",
339
- " \"gl\": \"us\",\n",
340
- "}\n",
341
- "search = RecipeSerpAPIWrapper(params=params)"
342
- ]
343
- },
344
- {
345
- "cell_type": "code",
346
- "execution_count": null,
347
- "metadata": {},
348
- "outputs": [
349
- {
350
- "data": {
351
- "text/plain": [
352
- "[{'title': 'Easy Vegan Fried Rice',\n",
353
- " 'link': 'https://minimalistbaker.com/easy-vegan-fried-rice/',\n",
354
- " 'source': 'Minimalist Baker',\n",
355
- " 'rating': 4.8,\n",
356
- " 'reviews': 457,\n",
357
- " 'total_time': '1 hr 15 min',\n",
358
- " 'ingredients': ['Peanut butter',\n",
359
- " 'grain brown rice',\n",
360
- " 'soy sauce',\n",
361
- " 'maple syrup',\n",
362
- " 'chili garlic sauce']},\n",
363
- " {'title': 'The Best Vegan Fried Rice',\n",
364
- " 'link': 'https://shortgirltallorder.com/best-vegan-fried-rice',\n",
365
- " 'source': 'Short Girl Tall Order',\n",
366
- " 'rating': 4.8,\n",
367
- " 'reviews': 65,\n",
368
- " 'total_time': '28 min',\n",
369
- " 'ingredients': ['Soy sauce',\n",
370
- " 'white rice',\n",
371
- " 'rice wine vinegar',\n",
372
- " 'sugar',\n",
373
- " 'fresh peas']},\n",
374
- " {'title': 'Vegan Fried Rice',\n",
375
- " 'link': 'https://www.noracooks.com/vegan-fried-rice/',\n",
376
- " 'source': 'Nora Cooks',\n",
377
- " 'rating': 5.0,\n",
378
- " 'reviews': 15,\n",
379
- " 'total_time': '20 min',\n",
380
- " 'ingredients': ['Gluten free',\n",
381
- " 'nutritional yeast',\n",
382
- " 'toasted sesame oil',\n",
383
- " 'carrots',\n",
384
- " 'olive oil']}]"
385
- ]
386
- },
387
- "execution_count": null,
388
- "metadata": {},
389
- "output_type": "execute_result"
390
- }
391
- ],
392
- "source": [
393
- "#| eval: false\n",
394
- "vegan_recipes = search.run(\"Vegan fried rice recipes\")\n",
395
- "vegan_recipes[0:3]"
396
- ]
397
- },
398
- {
399
- "cell_type": "code",
400
- "execution_count": null,
401
- "metadata": {},
402
- "outputs": [],
403
- "source": [
404
- "#| eval: false\n",
405
- "params = {\n",
406
- " \"engine\": \"google_images\",\n",
407
- " \"q\": \"Vegan pad thai recipes\",\n",
408
- " \"location\": \"United States\",\n",
409
- " \"api_key\": os.environ[\"SERPAPI_API_KEY\"],\n",
410
- "}\n",
411
- "\n",
412
- "search = GoogleSearch(params)\n",
413
- "results = search.get_dict()"
414
- ]
415
- },
416
- {
417
- "cell_type": "code",
418
- "execution_count": null,
419
- "metadata": {},
420
- "outputs": [
421
- {
422
- "data": {
423
- "text/plain": [
424
- "'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes'"
425
- ]
426
- },
427
- "metadata": {},
428
- "output_type": "display_data"
429
- },
430
- {
431
- "data": {
432
- "text/plain": [
433
- "'https://minimalistbaker.com/easy-tofu-pad-thai/'"
434
- ]
435
- },
436
- "metadata": {},
437
- "output_type": "display_data"
438
- },
439
- {
440
- "data": {
441
- "text/html": [
442
- "<img src=\"https://serpapi.com/searches/6480db18c56d93170a8e715f/images/6f34b4708ae4dd36a28ca4ca4a3abf6af168f575eef7bd2e8f81a12e175fcf53.jpeg\"/>"
443
- ],
444
- "text/plain": [
445
- "<IPython.core.display.Image object>"
446
- ]
447
- },
448
- "metadata": {},
449
- "output_type": "display_data"
450
- },
451
- {
452
- "data": {
453
- "text/plain": [
454
- "'Healthier vegan pad thai - Lazy Cat Kitchen'"
455
- ]
456
- },
457
- "metadata": {},
458
- "output_type": "display_data"
459
- },
460
- {
461
- "data": {
462
- "text/plain": [
463
- "'https://www.lazycatkitchen.com/healthier-vegan-pad-thai/'"
464
- ]
465
- },
466
- "metadata": {},
467
- "output_type": "display_data"
468
- },
469
- {
470
- "data": {
471
- "text/html": [
472
- "<img src=\"https://serpapi.com/searches/6480db18c56d93170a8e715f/images/6f34b4708ae4dd36dee6fed89369c822a79ad529f726d1a65fdd09459c0a0b6a.jpeg\"/>"
473
- ],
474
- "text/plain": [
475
- "<IPython.core.display.Image object>"
476
- ]
477
- },
478
- "metadata": {},
479
- "output_type": "display_data"
480
- },
481
- {
482
- "data": {
483
- "text/plain": [
484
- "'The Best Vegan Pad Thai - Full of Plants'"
485
- ]
486
- },
487
- "metadata": {},
488
- "output_type": "display_data"
489
- },
490
- {
491
- "data": {
492
- "text/plain": [
493
- "'https://fullofplants.com/the-best-vegan-pad-thai/'"
494
- ]
495
- },
496
- "metadata": {},
497
- "output_type": "display_data"
498
- },
499
- {
500
- "data": {
501
- "text/html": [
502
- "<img src=\"https://serpapi.com/searches/6480db18c56d93170a8e715f/images/6f34b4708ae4dd3695828a207980e4280bb4e14cdccb84ebf5350f19237416f8.jpeg\"/>"
503
- ],
504
- "text/plain": [
505
- "<IPython.core.display.Image object>"
506
- ]
507
- },
508
- "metadata": {},
509
- "output_type": "display_data"
510
- },
511
- {
512
- "data": {
513
- "text/plain": [
514
- "'Easy Vegan Pad Thai - Oh My Veggies'"
515
- ]
516
- },
517
- "metadata": {},
518
- "output_type": "display_data"
519
- },
520
- {
521
- "data": {
522
- "text/plain": [
523
- "'https://ohmyveggies.com/easy-vegan-pad-thai/'"
524
- ]
525
- },
526
- "metadata": {},
527
- "output_type": "display_data"
528
- },
529
- {
530
- "data": {
531
- "text/html": [
532
- "<img src=\"https://serpapi.com/searches/6480db18c56d93170a8e715f/images/6f34b4708ae4dd36885ca51553e15b434e41039ef307ecbb4869522eeeefcfa5.jpeg\"/>"
533
- ],
534
- "text/plain": [
535
- "<IPython.core.display.Image object>"
536
- ]
537
- },
538
- "metadata": {},
539
- "output_type": "display_data"
540
- },
541
- {
542
- "data": {
543
- "text/plain": [
544
- "'Easy Vegan Pad Thai - My Darling Vegan'"
545
- ]
546
- },
547
- "metadata": {},
548
- "output_type": "display_data"
549
- },
550
- {
551
- "data": {
552
- "text/plain": [
553
- "'https://www.mydarlingvegan.com/vegan-pad-thai/'"
554
- ]
555
- },
556
- "metadata": {},
557
- "output_type": "display_data"
558
- },
559
- {
560
- "data": {
561
- "text/html": [
562
- "<img src=\"https://serpapi.com/searches/6480db18c56d93170a8e715f/images/6f34b4708ae4dd36a554bfded8055a9df50470d25fe62e19b9de5f16e262497f.jpeg\"/>"
563
- ],
564
- "text/plain": [
565
- "<IPython.core.display.Image object>"
566
- ]
567
- },
568
- "metadata": {},
569
- "output_type": "display_data"
570
- }
571
- ],
572
- "source": [
573
- "#| eval: false\n",
574
- "\n",
575
- "for r in results[\"images_results\"][0:5]:\n",
576
- " display(r[\"title\"], r[\"link\"], Image(url=r[\"thumbnail\"]))"
577
- ]
578
- },
579
- {
580
- "cell_type": "code",
581
- "execution_count": null,
582
- "metadata": {},
583
- "outputs": [
584
- {
585
- "data": {
586
- "text/markdown": [
587
- "---\n",
588
- "\n",
589
- "### load_tools\n",
590
- "\n",
591
- "> load_tools (tool_names:List[str],\n",
592
- "> llm:Optional[langchain.base_language.BaseLanguageModel]=None,\n",
593
- "> callbacks:Union[List[langchain.callbacks.base.BaseCallbackHan\n",
594
- "> dler],langchain.callbacks.base.BaseCallbackManager,NoneType]=\n",
595
- "> None, **kwargs:Any)\n",
596
- "\n",
597
- "Load tools based on their name.\n",
598
- "\n",
599
- "Args:\n",
600
- " tool_names: name of tools to load.\n",
601
- " llm: Optional language model, may be needed to initialize certain tools.\n",
602
- " callbacks: Optional callback manager or list of callback handlers.\n",
603
- " If not provided, default global callback manager will be used.\n",
604
- "\n",
605
- "Returns:\n",
606
- " List of tools."
607
- ],
608
- "text/plain": [
609
- "---\n",
610
- "\n",
611
- "### load_tools\n",
612
- "\n",
613
- "> load_tools (tool_names:List[str],\n",
614
- "> llm:Optional[langchain.base_language.BaseLanguageModel]=None,\n",
615
- "> callbacks:Union[List[langchain.callbacks.base.BaseCallbackHan\n",
616
- "> dler],langchain.callbacks.base.BaseCallbackManager,NoneType]=\n",
617
- "> None, **kwargs:Any)\n",
618
- "\n",
619
- "Load tools based on their name.\n",
620
- "\n",
621
- "Args:\n",
622
- " tool_names: name of tools to load.\n",
623
- " llm: Optional language model, may be needed to initialize certain tools.\n",
624
- " callbacks: Optional callback manager or list of callback handlers.\n",
625
- " If not provided, default global callback manager will be used.\n",
626
- "\n",
627
- "Returns:\n",
628
- " List of tools."
629
- ]
630
- },
631
- "execution_count": null,
632
- "metadata": {},
633
- "output_type": "execute_result"
634
- }
635
- ],
636
- "source": [
637
- "show_doc(load_tools)"
638
- ]
639
- },
640
- {
641
- "cell_type": "markdown",
642
- "metadata": {},
643
- "source": [
644
- "Here is the SerpAPIWrapper tool implementation"
645
- ]
646
- },
647
- {
648
- "cell_type": "code",
649
- "execution_count": null,
650
- "metadata": {},
651
- "outputs": [],
652
- "source": [
653
- "from langchain.agents.load_tools import _get_serpapi"
654
- ]
655
- },
656
- {
657
- "cell_type": "code",
658
- "execution_count": null,
659
- "metadata": {},
660
- "outputs": [
661
- {
662
- "data": {
663
- "text/plain": [
664
- "\u001b[0;31mSignature:\u001b[0m \u001b[0m_get_serpapi\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mAny\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mlangchain\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtools\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbase\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mBaseTool\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
665
- "\u001b[0;31mDocstring:\u001b[0m <no docstring>\n",
666
- "\u001b[0;31mSource:\u001b[0m \n",
667
- "\u001b[0;32mdef\u001b[0m \u001b[0m_get_serpapi\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mAny\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mBaseTool\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n",
668
- "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mTool\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\u001b[0m\n",
669
- "\u001b[0;34m\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"Search\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
670
- "\u001b[0;34m\u001b[0m \u001b[0mdescription\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"A search engine. Useful for when you need to answer questions about current events. Input should be a search query.\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
671
- "\u001b[0;34m\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mSerpAPIWrapper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
672
- "\u001b[0;34m\u001b[0m \u001b[0mcoroutine\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mSerpAPIWrapper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marun\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n",
673
- "\u001b[0;34m\u001b[0m \u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
674
- "\u001b[0;31mFile:\u001b[0m ~/AnimalEquality/lv-recipe-chatbot/env/lib/python3.10/site-packages/langchain/agents/load_tools.py\n",
675
- "\u001b[0;31mType:\u001b[0m function"
676
- ]
677
- },
678
- "metadata": {},
679
- "output_type": "display_data"
680
- }
681
- ],
682
- "source": [
683
- "??_get_serpapi"
684
- ]
685
- },
686
- {
687
- "cell_type": "markdown",
688
- "metadata": {},
689
- "source": [
690
- "Let's use that for inspiration for our recipe version of the tool"
691
- ]
692
- },
693
- {
694
- "cell_type": "code",
695
- "execution_count": null,
696
- "metadata": {},
697
- "outputs": [],
698
- "source": [
699
- "params = {\n",
700
- " \"location\": \"United States\",\n",
701
- " \"hl\": \"en\",\n",
702
- " \"gl\": \"us\",\n",
703
- "}\n",
704
- "search = RecipeSerpAPIWrapper(params=params)\n",
705
- "serpapi_recipe_tool = Tool(\n",
706
- " name=\"Vegan Recipe Search\",\n",
707
- " description=\"A search engine. Useful for when you need to fetch existing vetted vegan recipes. Input should be a vegan recipe search query.\",\n",
708
- " func=search.run,\n",
709
- ")"
710
- ]
711
- },
712
- {
713
- "cell_type": "code",
714
- "execution_count": null,
715
- "metadata": {},
716
- "outputs": [],
717
- "source": [
718
- "@tool\n",
719
- "def time(text: str) -> str:\n",
720
- " \"\"\"Returns todays date, use this for any\n",
721
- " questions related to knowing todays date.\n",
722
- " The input should always be an empty string,\n",
723
- " and this function will always return todays\n",
724
- " date - any date mathmatics should occur\n",
725
- " outside this function.\"\"\"\n",
726
- " return str(date.today())"
727
- ]
728
- },
729
- {
730
- "cell_type": "code",
731
- "execution_count": null,
732
- "metadata": {},
733
- "outputs": [],
734
- "source": [
735
- "agent = initialize_agent(\n",
736
- " [time],\n",
737
- " llm,\n",
738
- " agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n",
739
- " handle_parsing_errors=True,\n",
740
- " verbose=True,\n",
741
- ")"
742
- ]
743
- },
744
- {
745
- "cell_type": "code",
746
- "execution_count": null,
747
- "metadata": {},
748
- "outputs": [],
749
- "source": [
750
- "@tool\n",
751
- "def vegan_recipe_serpapi_search(text: str) -> str:\n",
752
- " \"\"\"Returns a JSON/Python list of dictionaries of recipe data with keys in format:\n",
753
- " ```\n",
754
- " 'title': str,\n",
755
- " 'link': str,\n",
756
- " 'source': str,\n",
757
- " 'rating': int,\n",
758
- " 'reviews': int,\n",
759
- " 'total_time': str,\n",
760
- " 'ingredients': [\n",
761
- " str,\n",
762
- " str,\n",
763
- " ```\n",
764
- " The input must be the name of a vegan recipe \\\n",
765
- " or query parameters such as ingredients to include, prep time, cuisine region. \\\n",
766
- " Only execute the search for vegan recipes and ingredients. \\\n",
767
- " If the SerpAPI request errors or recipes are not found, \\\n",
768
- " an explanation message will be returned instead of the recipe JSON.\"\"\"\n",
769
- " params = {\n",
770
- " \"q\": text,\n",
771
- " \"location\": \"United States\",\n",
772
- " \"hl\": \"en\",\n",
773
- " \"gl\": \"us\",\n",
774
- " \"api_key\": os.environ[\"SERPAPI_API_KEY\"],\n",
775
- " }\n",
776
- "\n",
777
- " search = GoogleSearch(params)\n",
778
- " results = search.get_dict()\n",
779
- " if \"error\" in results.keys():\n",
780
- " return f\"Received an error from SerpAPI: {results['error']}\\n Query: {text}\"\n",
781
- "\n",
782
- " if \"recipes_results\" in results.keys():\n",
783
- " return str(results[\"recipes_results\"])\n",
784
- "\n",
785
- " return \"No recipes found for that query\""
786
- ]
787
- },
788
- {
789
- "cell_type": "markdown",
790
- "metadata": {},
791
- "source": [
792
- "Create an agent with the tool"
793
- ]
794
- },
795
- {
796
- "cell_type": "code",
797
- "execution_count": null,
798
- "metadata": {},
799
- "outputs": [],
800
- "source": [
801
- "agent = initialize_agent(\n",
802
- " tools=[vegan_recipe_serpapi_search],\n",
803
- " llm=llm,\n",
804
- " agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n",
805
- " handle_parsing_errors=True,\n",
806
- " verbose=True,\n",
807
- ")"
808
- ]
809
- },
810
- {
811
- "cell_type": "code",
812
- "execution_count": null,
813
- "metadata": {},
814
- "outputs": [
815
- {
816
- "name": "stdout",
817
- "output_type": "stream",
818
- "text": [
819
- "\n",
820
- "\n",
821
- "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
822
- "\u001b[32;1m\u001b[1;3mThought: I can use the `vegan_recipe_serpapi_search` tool to search for vegan pad thai recipes.\n",
823
- "\n",
824
- "Action:\n",
825
- "```\n",
826
- "{\n",
827
- " \"action\": \"vegan_recipe_serpapi_search\",\n",
828
- " \"action_input\": \"vegan pad thai\"\n",
829
- "}\n",
830
- "```\n",
831
- "\n",
832
- "\u001b[0m\n",
833
- "Observation: \u001b[36;1m\u001b[1;3m[{'title': 'Vegan Pad Thai', 'link': 'https://www.noracooks.com/vegan-pad-thai/', 'source': 'Nora Cooks', 'rating': 5.0, 'reviews': 53, 'total_time': '30 min', 'ingredients': ['Stir fry rice', 'mung bean sprouts', 'soy sauce', 'maple syrup', 'sriracha hot sauce']}, {'title': 'Easy Tofu Pad Thai', 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/', 'source': 'Minimalist Baker', 'rating': 4.9, 'reviews': 117, 'total_time': '30 min', 'ingredients': ['Pad thai rice', 'peanut sauce', 'thai red', 'soy sauce', 'bean sprouts']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116', 'source': 'Pick Up Limes', 'rating': 5.0, 'reviews': 34, 'total_time': '30 min', 'ingredients': ['Brown rice noodles', 'red hot', 'soy sauce', 'bean sprouts', 'sriracha hot sauce']}]\u001b[0m\n",
834
- "Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: The `vegan_recipe_serpapi_search` tool returned a list of three vegan pad thai recipes with their titles, links, sources, ratings, reviews, total time, and ingredients.\u001b[0m\n",
835
- "Observation: Invalid or incomplete response\n",
836
- "Thought:\u001b[32;1m\u001b[1;3mI will try running the `vegan_recipe_serpapi_search` tool again with the input \"vegan pad thai\".\n",
837
- "\n",
838
- "Action:\n",
839
- "```\n",
840
- "{\n",
841
- " \"action\": \"vegan_recipe_serpapi_search\",\n",
842
- " \"action_input\": \"vegan pad thai\"\n",
843
- "}\n",
844
- "```\n",
845
- "\n",
846
- "\n",
847
- "\u001b[0m\n",
848
- "Observation: \u001b[36;1m\u001b[1;3m[{'title': 'Vegan Pad Thai', 'link': 'https://www.noracooks.com/vegan-pad-thai/', 'source': 'Nora Cooks', 'rating': 5.0, 'reviews': 53, 'total_time': '30 min', 'ingredients': ['Stir fry rice', 'mung bean sprouts', 'soy sauce', 'maple syrup', 'sriracha hot sauce']}, {'title': 'Easy Tofu Pad Thai', 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/', 'source': 'Minimalist Baker', 'rating': 4.9, 'reviews': 117, 'total_time': '30 min', 'ingredients': ['Pad thai rice', 'peanut sauce', 'thai red', 'soy sauce', 'bean sprouts']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116', 'source': 'Pick Up Limes', 'rating': 5.0, 'reviews': 34, 'total_time': '30 min', 'ingredients': ['Brown rice noodles', 'red hot', 'soy sauce', 'bean sprouts', 'sriracha hot sauce']}]\u001b[0m\n",
849
- "Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: The `vegan_recipe_serpapi_search` tool returned a list of three vegan pad thai recipes with their titles, links, sources, ratings, reviews, total time, and ingredients.\n",
850
- "\u001b[0m\n",
851
- "Observation: Invalid or incomplete response\n",
852
- "Thought:\u001b[32;1m\u001b[1;3mI will try running the `vegan_recipe_serpapi_search` tool again with the input \"vegan pad thai recipes\".\n",
853
- "\n",
854
- "Action:\n",
855
- "```\n",
856
- "{\n",
857
- " \"action\": \"vegan_recipe_serpapi_search\",\n",
858
- " \"action_input\": \"vegan pad thai recipes\"\n",
859
- "}\n",
860
- "```\n",
861
- "\n",
862
- "\n",
863
- "\u001b[0m\n",
864
- "Observation: \u001b[36;1m\u001b[1;3m[{'title': 'Easy Tofu Pad Thai', 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/', 'source': 'Minimalist Baker', 'rating': 4.9, 'reviews': 117, 'total_time': '30 min', 'ingredients': ['Pad thai rice', 'peanut sauce', 'thai red', 'soy sauce', 'bean sprouts']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.noracooks.com/vegan-pad-thai/', 'source': 'Nora Cooks', 'rating': 5.0, 'reviews': 53, 'total_time': '30 min', 'ingredients': ['Stir fry rice', 'mung bean sprouts', 'soy sauce', 'maple syrup', 'sriracha hot sauce']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116', 'source': 'Pick Up Limes', 'rating': 5.0, 'reviews': 34, 'total_time': '30 min', 'ingredients': ['Brown rice noodles', 'red hot', 'soy sauce', 'bean sprouts', 'sriracha hot sauce']}]\u001b[0m\n",
865
- "Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: I have successfully used the `vegan_recipe_serpapi_search` tool to search for vegan pad thai recipes. The tool returned a list of three vegan pad thai recipes with their titles, links, sources, ratings, reviews, total time, and ingredients.\n",
866
- "\n",
867
- "\u001b[0m\n",
868
- "Observation: Invalid or incomplete response\n",
869
- "Thought:\u001b[32;1m\u001b[1;3mI will try running the `vegan_recipe_serpapi_search` tool again with the input \"vegan pad thai recipe\".\n",
870
- "\n",
871
- "Action:\n",
872
- "```\n",
873
- "{\n",
874
- " \"action\": \"vegan_recipe_serpapi_search\",\n",
875
- " \"action_input\": \"vegan pad thai recipe\"\n",
876
- "}\n",
877
- "```\n",
878
- "\n",
879
- "\n",
880
- "\u001b[0m\n",
881
- "Observation: \u001b[36;1m\u001b[1;3m[{'title': 'Easy Tofu Pad Thai', 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/', 'source': 'Minimalist Baker', 'rating': 4.9, 'reviews': 117, 'total_time': '30 min', 'ingredients': ['Pad thai rice', 'peanut sauce', 'thai red', 'soy sauce', 'bean sprouts']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.noracooks.com/vegan-pad-thai/', 'source': 'Nora Cooks', 'rating': 5.0, 'reviews': 53, 'total_time': '30 min', 'ingredients': ['Stir fry rice', 'mung bean sprouts', 'soy sauce', 'maple syrup', 'sriracha hot sauce']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116', 'source': 'Pick Up Limes', 'rating': 5.0, 'reviews': 34, 'total_time': '30 min', 'ingredients': ['Brown rice noodles', 'red hot', 'soy sauce', 'bean sprouts', 'sriracha hot sauce']}]\u001b[0m\n",
882
- "Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: I have successfully used the `vegan_recipe_serpapi_search` tool to search for vegan pad thai recipes. The tool returned a list of three vegan pad thai recipes with their titles, links, sources, ratings, reviews, total time, and ingredients. \n",
883
- "\n",
884
- "Final Answer: Here are three vegan pad thai recipes: \n",
885
- "1. Easy Tofu Pad Thai from Minimalist Baker\n",
886
- "2. Vegan Pad Thai from Nora Cooks\n",
887
- "3. Vegan Pad Thai from Pick Up Limes.\u001b[0m\n",
888
- "\n",
889
- "\u001b[1m> Finished chain.\u001b[0m\n"
890
- ]
891
- },
892
- {
893
- "data": {
894
- "text/plain": [
895
- "'Here are three vegan pad thai recipes: \\n1. Easy Tofu Pad Thai from Minimalist Baker\\n2. Vegan Pad Thai from Nora Cooks\\n3. Vegan Pad Thai from Pick Up Limes.'"
896
- ]
897
- },
898
- "execution_count": null,
899
- "metadata": {},
900
- "output_type": "execute_result"
901
- }
902
- ],
903
- "source": [
904
- "#| eval: false\n",
905
- "agent.run(\"Search vegan pad thai recipes\")"
906
- ]
907
- },
908
- {
909
- "cell_type": "markdown",
910
- "metadata": {},
911
- "source": [
912
- "This doc should be corrected [LangChain serpapi doc could be updated](https://python.langchain.com/en/latest/modules/agents/tools/examples/serpapi.html)"
913
- ]
914
- },
915
- {
916
- "cell_type": "code",
917
- "execution_count": null,
918
- "metadata": {},
919
- "outputs": [],
920
- "source": [
921
- "#| eval: false\n",
922
- "search = GoogleSerperAPIWrapper(type=\"search\")\n",
923
- "results = search.results(\"Lion\")"
924
- ]
925
- },
926
- {
927
- "cell_type": "markdown",
928
- "metadata": {},
929
- "source": [
930
- "[edamam](https://www.edamam.com/)"
931
- ]
932
- },
933
- {
934
- "cell_type": "code",
935
- "execution_count": null,
936
- "metadata": {},
937
- "outputs": [],
938
- "source": [
939
- "#| hide\n",
940
- "import nbdev\n",
941
- "\n",
942
- "nbdev.nbdev_export()"
943
- ]
944
- },
945
- {
946
- "cell_type": "code",
947
- "execution_count": null,
948
- "metadata": {},
949
- "outputs": [],
950
- "source": []
951
- }
952
- ],
953
- "metadata": {
954
- "kernelspec": {
955
- "display_name": "python3",
956
- "language": "python",
957
- "name": "python3"
958
- }
959
- },
960
- "nbformat": 4,
961
- "nbformat_minor": 4
962
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
nbs/02_vegan_recipe_tools.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
nbs/04_edamam_api.ipynb DELETED
@@ -1,71 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "markdown",
5
- "metadata": {},
6
- "source": [
7
- "# edamam_api\n",
8
- "\n",
9
- "> Tinkering with the [](Edamam API)"
10
- ]
11
- },
12
- {
13
- "cell_type": "code",
14
- "execution_count": null,
15
- "metadata": {},
16
- "outputs": [],
17
- "source": [
18
- "#| default_exp edamam_api"
19
- ]
20
- },
21
- {
22
- "cell_type": "code",
23
- "execution_count": null,
24
- "metadata": {},
25
- "outputs": [],
26
- "source": [
27
- "#| hide\n",
28
- "from nbdev.showdoc import *"
29
- ]
30
- },
31
- {
32
- "cell_type": "code",
33
- "execution_count": null,
34
- "metadata": {},
35
- "outputs": [],
36
- "source": [
37
- "#| export\n",
38
- "def foo():\n",
39
- " pass"
40
- ]
41
- },
42
- {
43
- "cell_type": "code",
44
- "execution_count": null,
45
- "metadata": {},
46
- "outputs": [],
47
- "source": [
48
- "#| hide\n",
49
- "import nbdev\n",
50
- "\n",
51
- "nbdev.nbdev_export()"
52
- ]
53
- },
54
- {
55
- "cell_type": "code",
56
- "execution_count": null,
57
- "metadata": {},
58
- "outputs": [],
59
- "source": []
60
- }
61
- ],
62
- "metadata": {
63
- "kernelspec": {
64
- "display_name": "python3",
65
- "language": "python",
66
- "name": "python3"
67
- }
68
- },
69
- "nbformat": 4,
70
- "nbformat_minor": 4
71
- }