Wendong-Fan commited on
Commit
fc5e352
·
2 Parent(s): f597cc4 a9217f2

Community contribution - cooking assistant (#375)

Browse files
community_usecase/cooking-assistant/README.md ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Personal Dietician
2
+
3
+ This code example searches for recipes on the internet based on the ingredients you have, refines the content based on a dieterary restriction and generates shopping lists.
4
+
5
+ ## How to use
6
+
7
+ 1. Set up the OPENAI api key in the .env file
8
+
9
+ ```bash
10
+ OPENAI_API_KEY = 'xxx'
11
+ ```
12
+
13
+ 2. Copy the python script to the owl/examples folder.
14
+
15
+ 3. Run the script
16
+
17
+ ```bash
18
+ python run_gpt4o.py
19
+ ```
20
+
21
+ 4. You can find the entire thought process of the agent within the log file.
22
+
23
+ 5. Demo Link - https://drive.google.com/drive/folders/10LnMEMf_xQGojHyTAS57vI7oOmjvuKPE?usp=sharing
community_usecase/cooking-assistant/run_gpt4o.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import logging
3
+ import json
4
+
5
+ from dotenv import load_dotenv
6
+ from camel.models import ModelFactory
7
+ from camel.types import ModelPlatformType
8
+
9
+ from camel.toolkits import (
10
+ SearchToolkit,
11
+ BrowserToolkit,
12
+ )
13
+ from camel.societies import RolePlaying
14
+ from camel.logger import set_log_level, get_logger
15
+
16
+
17
+ from owl.utils import run_society
18
+ import pathlib
19
+
20
+ base_dir = pathlib.Path(__file__).parent.parent
21
+ env_path = base_dir / "owl" / ".env"
22
+ load_dotenv(dotenv_path=str(env_path))
23
+
24
+ set_log_level(level="DEBUG")
25
+ logger = get_logger(__name__)
26
+ file_handler = logging.FileHandler("cooking_companion.log")
27
+ file_handler.setLevel(logging.DEBUG)
28
+ formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
29
+ file_handler.setFormatter(formatter)
30
+ logger.addHandler(file_handler)
31
+
32
+ root_logger = logging.getLogger()
33
+ root_logger.addHandler(file_handler)
34
+
35
+
36
+ def construct_cooking_society(task: str) -> RolePlaying:
37
+ """Construct a society of agents for the cooking companion.
38
+
39
+ Args:
40
+ task (str): The cooking-related task to be addressed.
41
+
42
+ Returns:
43
+ RolePlaying: A configured society of agents for the cooking companion.
44
+ """
45
+ models = {
46
+ "user": ModelFactory.create(
47
+ model_platform=ModelPlatformType.OPENAI_COMPATIBLE_MODEL,
48
+ model_type="gpt-4o",
49
+ api_key=os.getenv("OPENAI_API_KEY"),
50
+ model_config_dict={"temperature": 0.4},
51
+ ),
52
+ "assistant": ModelFactory.create(
53
+ model_platform=ModelPlatformType.OPENAI_COMPATIBLE_MODEL,
54
+ model_type="gpt-4o",
55
+ api_key=os.getenv("OPENAI_API_KEY"),
56
+ model_config_dict={"temperature": 0.4},
57
+ ),
58
+ "recipe_analyst": ModelFactory.create(
59
+ model_platform=ModelPlatformType.OPENAI_COMPATIBLE_MODEL,
60
+ model_type="gpt-4o",
61
+ api_key=os.getenv("OPENAI_API_KEY"),
62
+ model_config_dict={"temperature": 0.2},
63
+ ),
64
+ "planning": ModelFactory.create(
65
+ model_platform=ModelPlatformType.OPENAI_COMPATIBLE_MODEL,
66
+ model_type="gpt-4o",
67
+ api_key=os.getenv("OPENAI_API_KEY"),
68
+ model_config_dict={"temperature": 0.3},
69
+ ),
70
+ }
71
+
72
+ browser_toolkit = BrowserToolkit(
73
+ headless=False,
74
+ web_agent_model=models["recipe_analyst"],
75
+ planning_agent_model=models["planning"],
76
+ )
77
+
78
+ tools = [
79
+ *browser_toolkit.get_tools(),
80
+ SearchToolkit().search_duckduckgo,
81
+ ]
82
+
83
+ user_agent_kwargs = {"model": models["user"]}
84
+ assistant_agent_kwargs = {"model": models["assistant"], "tools": tools}
85
+
86
+ task_kwargs = {
87
+ "task_prompt": task,
88
+ "with_task_specify": False,
89
+ }
90
+
91
+ society = RolePlaying(
92
+ **task_kwargs,
93
+ user_role_name="user",
94
+ user_agent_kwargs=user_agent_kwargs,
95
+ assistant_role_name="cooking_assistant",
96
+ assistant_agent_kwargs=assistant_agent_kwargs,
97
+ )
98
+
99
+ return society
100
+
101
+
102
+ def analyze_chat_history(chat_history):
103
+ """Analyze chat history and extract tool call information."""
104
+ print("\n============ Tool Call Analysis ============")
105
+ logger.info("========== Starting tool call analysis ==========")
106
+
107
+ tool_calls = []
108
+ for i, message in enumerate(chat_history):
109
+ if message.get("role") == "assistant" and "tool_calls" in message:
110
+ for tool_call in message.get("tool_calls", []):
111
+ if tool_call.get("type") == "function":
112
+ function = tool_call.get("function", {})
113
+ tool_info = {
114
+ "call_id": tool_call.get("id"),
115
+ "name": function.get("name"),
116
+ "arguments": function.get("arguments"),
117
+ "message_index": i,
118
+ }
119
+ tool_calls.append(tool_info)
120
+ print(f"Tool Call: {function.get('name')} Args: {function.get('arguments')}")
121
+ logger.info(f"Tool Call: {function.get('name')} Args: {function.get('arguments')}")
122
+
123
+ elif message.get("role") == "tool" and "tool_call_id" in message:
124
+ for tool_call in tool_calls:
125
+ if tool_call.get("call_id") == message.get("tool_call_id"):
126
+ result = message.get("content", "")
127
+ result_summary = result[:100] + "..." if len(result) > 100 else result
128
+ print(f"Tool Result: {tool_call.get('name')} Return: {result_summary}")
129
+ logger.info(f"Tool Result: {tool_call.get('name')} Return: {result_summary}")
130
+
131
+ print(f"Total tool calls found: {len(tool_calls)}")
132
+ logger.info(f"Total tool calls found: {len(tool_calls)}")
133
+ logger.info("========== Finished tool call analysis ==========")
134
+
135
+ with open("cooking_chat_history.json", "w", encoding="utf-8") as f:
136
+ json.dump(chat_history, f, ensure_ascii=False, indent=2)
137
+
138
+ print("Records saved to cooking_chat_history.json")
139
+ print("============ Analysis Complete ============\n")
140
+
141
+
142
+ def run_cooking_companion():
143
+ task = "I have chicken breast, broccoli, garlic, and pasta. I'm looking for a quick dinner recipe that's healthy. I'm also trying to reduce my sodium intake. Search the internet for a recipe, modify it for low sodium, and create a shopping list for any additional ingredients I need?"
144
+ society = construct_cooking_society(task)
145
+ answer, chat_history, token_count = run_society(society)
146
+
147
+ # Record tool usage history
148
+ analyze_chat_history(chat_history)
149
+ print(f"\033[94mAnswer: {answer}\033[0m")
150
+
151
+
152
+ if __name__ == "__main__":
153
+ run_cooking_companion()