-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfunction_calling_lab.py
More file actions
212 lines (185 loc) · 6.5 KB
/
function_calling_lab.py
File metadata and controls
212 lines (185 loc) · 6.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
client = OpenAI()
model_to_use = "gpt-4-turbo"
import time
import json
# List out 20 assistants defined in OpenAI and delete all assistants with name starting with demo
assistants = client.beta.assistants.list(
order="desc",
limit="20",
)
# delete all assistants with name starting with demo
for i in range(len(assistants.data)):
print(assistants.data[i].name)
if assistants.data[i].name.startswith("demo"):
client.beta.assistants.delete(assistants.data[i].id)
custom_tools = [
{
"type":"function",
"function": {
"name":"redirect_assistant",
"description":"redirecting to a professional of a subject",
"parameters": {
"type":"object",
"properties": {
"assistant_name": {
"type":"string",
"description":"the professional name to redirect to. choices are 'math' or 'history'"
}
}
}
}
}
]
general_assistant = client.beta.assistants.create(
instructions = """
You are a general teacher that will give a short sentence as the answer.
However, if the question is about math or history, you should use the redirect tool
to redirect the topic to a professional for further answer.
""",
name="demoGeneralTeacher",
tools=custom_tools,
model=model_to_use
)
print("general_assistant_id:" + general_assistant.id)
#default assistant is general
current_assistant_id = general_assistant.id
history_assistant = client.beta.assistants.create(
instructions = """
You are a history professional, you will give detail answers to the student.
You will begin you answer with "Long Long Time Ago..."
""",
name="demoHistoryTeacher",
tools=[],
model=model_to_use
)
print("history_assistant id:" + history_assistant.id)
math_assistant = client.beta.assistants.create(
instructions = """
You are a math professional, you will give detail answers to the student.
You will begin you answer with "In The World Of Numbers..."
""",
name="demoMathTeacher",
tools=[],
model=model_to_use
)
print("math_assistant id:" + math_assistant.id)
thread = client.beta.threads.create()
message1 = client.beta.threads.messages.create(
thread.id,
role="user",
# content="What happened in world war 2?"
content="What is a prime number?"
)
print(thread)
print(message1)
run = client.beta.threads.runs.create(
thread_id = thread.id,
assistant_id = general_assistant.id
)
# python function to change assistant
def redirect_assistant(assistant_name):
global current_assistant_id
print("Redirecting to " + assistant_name)
if assistant_name in ["history", "math"]:
if assistant_name == 'math':
current_assistant_id = math_assistant.id
else:
current_assistant_id = history_assistant.id
print("changing assistant id to:" + current_assistant_id)
return "refering to " + assistant_name + " for further explanation"
else:
return "no specialist assistant here. Keep it general."
# wait for run to complete. For runs expecting to complete without function call
# def wait_for_run(run_to_wait):
# run_wait = client.beta.threads.runs.retrieve(
# thread_id=thread.id,
# run_id = run_to_wait.id
# )
# while not (run_wait.status == "completed"):
# run_wait = client.beta.threads.runs.retrieve(
# thread_id=thread.id,
# run_id = run_to_wait.id
# )
# print("Waiting to complete:" + run_wait.status)
# time.sleep(1)
def wait_for_run(run_to_wait):
while True:
run_wait = client.beta.threads.runs.retrieve(
thread_id=thread.id,
run_id = run_to_wait.id
)
if run_wait.status == "completed":
break
print("Waiting to complete:" + run_wait.status)
time.sleep(1)
# function to print the current messages in the thread
def print_messages(messages):
for i in range(len(messages)):
print(messages[i].content[0].text.value)
# submit function call result, so the flow can continue
def submit_tool_call_output(run_id, tool_call_id, function_name, function_parameters):
print("tool_call_id " + tool_call_id)
print("function_name " + function_name)
print("function_parameters " + function_parameters)
function_call_result = ""
if function_name == "redirect_assistant":
parameter_obj = json.loads(function_parameters)
print(parameter_obj)
function_call_result = redirect_assistant(parameter_obj['assistant_name'])
print("function call result:" + function_call_result)
run_tool_submit = client.beta.threads.runs.submit_tool_outputs(
thread_id=thread.id,
run_id=run_id,
tool_outputs=[
{
"tool_call_id": tool_call_id,
"output": function_call_result
}
]
)
wait_for_run(run_tool_submit)
# wait for 5s for the process to complete
for i in range(5):
run = client.beta.threads.runs.retrieve(
thread_id=thread.id,
run_id = run.id
)
# function call happened, requiring action from the server side (not open ai) to complete, and submit the result
if run.status == "requires_action":
# getting the first call, can have multiple actions
first_tool_call = run.required_action.submit_tool_outputs.tool_calls[0]
tool_call_id = first_tool_call.id
function_name = first_tool_call.function.name
function_parameters = first_tool_call.function.arguments
# first by calling the python function, and submit the result back to open ai
submit_tool_call_output(run.id, tool_call_id, function_name, function_parameters)
# after submitting the result of tool call, the run would continue, and finally reach completed
if run.status == "completed":
print(run)
messages = client.beta.threads.messages.list(
thread_id=thread.id
)
print(messages)
print_messages(messages.data)
break
# print(first_tool_call)
time.sleep(1)
# submit a message on behalf of user, and ask for more detail. The current assistant should now be either history or math, or still for general
message = client.beta.threads.messages.create(
thread.id,
role="user",
content="Please give me more details"
)
print("answering by current_assistant_id:" + current_assistant_id)
run = client.beta.threads.runs.create(
thread_id = thread.id,
assistant_id = current_assistant_id
)
wait_for_run(run)
messages = client.beta.threads.messages.list(
thread_id=thread.id
)
print_messages(messages.data)