-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathllm.py
More file actions
208 lines (203 loc) · 9.79 KB
/
llm.py
File metadata and controls
208 lines (203 loc) · 9.79 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
import config
import requests
import os
import json
import logging
import time
written_files = dict()
used_names = set()
tools = []
input_token=0
output_token=0
def gen_tools(agent_name):
if config.share_file:
wf = []
for agent, files in written_files.items():
agent_files = [f for f in files if 'todo' not in f.lower() and 'status' not in f.lower()]
wf.extend(agent_files)
else:
if agent_name in written_files:
wf = [f for f in written_files[agent_name] if 'todo' not in f.lower() and 'status' not in f.lower()]
else:
wf = []
global tools
tools = [
{
"name": "exec_python_file",
"description": "Execute a Python file and get the result. Cannot detect bugs. Be sure to review the code or use write_file to write the file first. If the program requires user input, please use this function first, and then use 'input' function to pass your input.",
"parameters": {
"type": "object",
"properties": {
"filename": {
"type": "string",
"description": "The filename of the Python file to be executed."
}
}
}
},
{
"name": "input",
"description": "Input a string to the running Python code. Only available after exec_python_file is called.",
"parameters": {
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "The string to be input."
}
}
}
},
{
"name": "read_file",
"description": f"Read the content of a file. Return file content and file hash. To modify a file, please first read it, then write it(using the same hash).\nYou have created these files:{wf}\nYou can also read any files created by other agents.",
"parameters": {
"type": "object",
"properties": {
"filename": {
"type": "string",
"description": "The filename to be read."
}
}
},
"required": [
"filename"
]
},
{
"name": "write_file",
"description": f"Write raw content to a file. If the file exists, only overwrite when overwrite = True and hash value (get it from read_file) is correct. ",
"parameters": {
"type": "object",
"properties": {
"filename": {
"type": "string",
"description": "The filename to be written."
},
"content": {
"type": "string",
"description": r"The content to be written. Use \n instead of \\n for a new line."
},
"overwrite": {
"type": "boolean",
"description": "Optional. Whether to overwrite the file if it exists. Default is False. If True, base_commit_hash is required."
},
"base_commit_hash": {
"type": "string",
"description": "Optional. The hash value of the file to be modified(get it from read_file). Required when overwrite = True."
}
}
},
"required": [
"filename",
"content"
]
},
{"name": "change_task_status",
"description": "Change the content of your task status. It should include what you have done, and what you should do later, in case you would forget.",
"parameters": {
"type": "object",
"properties": {
"todo": {
"type": "string",
"description": "You TODO list. You must finish all the tasks and clear this list before calling the 'terminate' function."
},
"done": {
"type": "string",
"description": "The tasks you have done. You can write anything you want to remember."
}
}
},
"required": [
"content"
]
},
{
"name": "add_agent",
"description": "If your task is too complex, you can recruit agents to the conversation as your subordinates and help you. Return the real name. To add multiple agents, please call this function multiple times. After that, you MUST talk to them using function calls. You do not need to add your collaborators in the prompt, since they have been added by the CEO.",
"parameters": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The name of the agent to be added. Do not use space. Do not use the same name as any existing agent."
},
"description": {
"type": "string",
"description": "The description of the agent, for your reference."
},
"initial_prompt": {
"type": "string",
"description": '''
The initial prompt and memory of that agent. Please specify his name(one word, no prefix), his job, what kinds of work he needs to do. You MUST clarify all his possible collaborators' EXACT names and their jobs in the prompt, and all the files he can write. The format should be like (The example is for Alice in another novel writing project):
You are Alice, a novelist. Your job is to write a single chapter of a novel with 1000 words according to the outline (outline.txt) from Carol, the architect designer, and pass it to David (chapter_x.txt), the editor. Please only follow this routine. Your collarborators include Bob(the Boss), Carol(the architect designer) and David(the editor).
Please note that every agent is lazy, and will not care anything not mentioned by your prompt. To ensure the completion of the project, the work of each agent should be non-divisable, detailed in specific action(like what file to write) and limited to a simple and specific instruction(For instance, instead of "align with the overall national policies", please specify those policies).
'''
}
}
},
"required": [
"name",
"description",
"initial_prompt"
]
},
{
"name": "talk",
"description": "Leave a message to specific agents for feedback. They will reply you later on.",
"parameters":{
"type": "object",
"properties": {
"messages": {
"type": "string",
"description": "All the messages to be sent. The format must look like: <talk goal=\"Name\">TalkContent</talk><talk goal=\"Name\">TalkContent</talk>"
}
}
},
"required": [
"messages"
]
},
{
"name": "terminate",
"description": "End your current conversation. Please ensure all your tasks in your TODO list have been done and cleared.",
}
]
def _get_llm_response(messages, enable_tools=True, agent_name=''):
api_key = config.api_key
url = config.url
headers = {'Content-Type': 'application/json',
'Authorization':f'Bearer {api_key}'}
gen_tools(agent_name)
if enable_tools:
body = {
'model': config.model,
"messages": messages,
"functions": tools,
"temperature": 0,
}
else:
body = {
'model': config.model,
"messages": messages,
"temperature": 0,
}
try:
response = requests.post(url, headers=headers, json=body)
# print(response.content)
return response.json()
except Exception as e:
return {'error': e}
def get_llm_response(messages, enable_tools=True, agent_name=''):
response = _get_llm_response(messages, enable_tools, agent_name)
while 'choices' not in response:
logging.error(response)
# time.sleep(3)
response = _get_llm_response(messages, enable_tools, agent_name)
# if response['choices'][0]['message']['content']:
# logging.info(response['choices'][0]['message']['content'])
global input_token,output_token
input_token+=response['usage']['prompt_tokens']
output_token+=response['usage']['completion_tokens']
logging.info(f"Input token: {input_token}, Output token: {output_token}")
return response