1
1
import openai
2
2
import os
3
- import requests
4
- import re
5
- from time import sleep
6
3
import time
4
+ import logging
5
+ import argparse
6
+ import streamlit as st
7
+
8
+ # Set up logging
9
+ logging .basicConfig (level = logging .INFO )
7
10
8
11
# Define a function to open a file and return its contents as a string
9
- def open_file (filepath ) :
10
- with open (filepath , 'r' , encoding = 'utf-8' ) as infile :
11
- return infile .read ()
12
+ def open_file (filepath ):
13
+ try :
14
+ with open (filepath , 'r' , encoding = 'utf-8' ) as infile :
15
+ return infile .read ()
16
+ except IOError as e :
17
+ logging .error (f'Error opening file { filepath } : { e } ' )
18
+ raise e
19
+
20
+ # Define a function to save content to a file
21
+ def save_file (filepath , content , mode = 'w' ):
22
+ try :
23
+ with open (filepath , mode , encoding = 'utf-8' ) as outfile :
24
+ outfile .write (content )
25
+ except IOError as e :
26
+ logging .error (f'Error writing to file { filepath } : { e } ' )
27
+
28
+ def save_debug (content ):
29
+ try :
30
+ save_file ('debug.txt' , content , 'a' )
31
+ except IOError as e :
32
+ logging .error (f'Error writing to file { filepath } : { e } ' )
12
33
13
- #Define a function to save content to a file
14
- def save_file (filepath , content ):
15
- with open (filepath , 'w' , encoding = 'utf-8' ) as outfile :
16
- outfile .write (content )
17
34
18
35
# Set the OpenAI API keys by reading them from files
19
- api_key = open_file ('openai apikey2.txt' )
36
+ api_key = open_file ('openai_apikey.md' )
37
+
38
+ page_title = '# Chain Prompt + Tree of Thoughts 🎈'
39
+
40
+ st .set_page_config (page_title = page_title , page_icon = None , layout = "wide" , initial_sidebar_state = "auto" , menu_items = None )
41
+
42
+ st .markdown (page_title )
43
+
44
+ col1 , col2 = st .columns ([1 , 4 ])
45
+ col1 .subheader ("Auto" )
46
+ col2 .subheader ("Result" )
47
+ bar = col2 .progress (0 )
20
48
21
49
class ScriptRunner :
22
- def __init__ (self ):
50
+ def __init__ (self , loop_count ):
23
51
self .current_progress = 0
52
+ self .loop_count = loop_count
53
+ self .conversation = []
54
+ self .problem = ""
55
+ self .evidea2 = ""
24
56
25
- def update progress (self , value );
57
+ def update_progress (self , value ):
26
58
self .current_progress = value
59
+ bar .progress (value )
27
60
28
- def get_solution (self ):
61
+ def get_solution (self ):
29
62
if self .conversation :
30
63
assistant_messages = ""
31
64
for msg in self .conversation :
32
- if msg ['role' ] = 'assistant' :
65
+ if msg ['role' ] = = 'assistant' :
33
66
assistant_messages += msg ['content' ] + "\n "
34
67
return assistant_messages .strip ()
35
68
return 'Solution not yet available.'
36
69
37
- def get_chain_results (self ):
70
+ def get_chain_results (self ):
38
71
chain_results = {}
39
- for i in range (1 , 8 ):
40
- if os . path .exists (f'chain{ i } .txt' );
41
- chain_results [f'chain{ i } ' ] = open_file (f'chain{ i } .txt ' )
42
- return chain_results
72
+ for i in range (1 , 8 ):
73
+ if os .path .exists (f'chain{ i } .md' ):
74
+ chain_results [f'chain{ i } ' ] = open_file (f'chain{ i } .md ' )
75
+ return chain_results
43
76
44
77
def get_chat_response (self ):
45
- eturn self .chat_response
78
+ return self .chat_response
46
79
47
80
def get_conversation_history (self ):
48
81
return "\n " .join ([f"{ message ['role' ].capitalize ()} : { message ['content' ]} " for message in self .conversation ])
49
82
83
+
50
84
def chatgpt (self , api_key , conversation , chatbot , user_input , temperature = 0.7 , frequency_penalty = 0.2 , presence_penalty = 0 , max_retry = 5 ):
51
85
# Set the API key
52
86
openai .api_key = api_key
@@ -62,6 +96,9 @@ def chatgpt(self, api_key, conversation, chatbot, user_input, temperature=0.7, f
62
96
retry = 0
63
97
while True :
64
98
try :
99
+ save_debug (f'retry: { retry } \n ' )
100
+ save_debug (f'messages_input: { messages_input } \n ' )
101
+
65
102
# Make an API call to the Chat Completion endpoint with the updated messages
66
103
completion = openai .ChatCompletion .create (
67
104
model = "gpt-4" ,
@@ -74,108 +111,159 @@ def chatgpt(self, api_key, conversation, chatbot, user_input, temperature=0.7, f
74
111
# Extract the assistant's message and add it to the conversation
75
112
message = completion ['choices' ][0 ]['message' ]['content' ]
76
113
conversation .append ({"role" : "assistant" , "content" : message })
114
+ save_debug (f'message: { message } \n ' )
115
+ save_debug ('----\n ' )
77
116
return message
78
- except openai .api_resources .completion .ChatCompletion .CreateError as e :
117
+
118
+ except openai .error .RateLimitError as e :
79
119
if e .error ['message' ] == 'Rate limit exceeded' and retry < max_retry :
80
- time .sleep (1 ) # Sleep for 1 second before retrying
120
+ retry_time = e .retry_after if hasattr (e , 'retry_after' ) else 3
121
+ print (f'Rate limit exceeded. Sleeping for { retry_time } seconds...' )
122
+ time .sleep (retry_time )
81
123
retry += 1
82
124
else :
83
125
raise e
84
- time .sleep (1 ) # Sleep for 1 second before retrying
126
+
127
+ except openai .error .ServiceUnavailableError as e :
128
+ retry_time = 10 # Adjust the retry time as needed
129
+ print (f'Service is unavailable. Retrying in { retry_time } seconds...' )
130
+ time .sleep (retry_time )
131
+ retry += 1
132
+
133
+ except openai .error .APIError as e :
134
+ retry_time = e .retry_after if hasattr (e , 'retry_after' ) else 10
135
+ print (f'API error occurred. Retrying in { retry_time } seconds...' )
136
+ time .sleep (retry_time )
137
+ retry += 1
138
+
139
+ except OSError as e :
140
+ retry_time = 5 # Adjust the retry time as needed
141
+ print (f'Connection error occurred: { e } . Retrying in { retry_time } seconds...' )
142
+ time .sleep (retry_time )
143
+ retry += 1
144
+
145
+ def chain_process (self , prompt_file , save_file_name , replacements , api_key , conversation , chatbot ):
146
+ prompt = open_file (prompt_file )
147
+ for placeholder , value in replacements .items ():
148
+ prompt = prompt .replace (placeholder , value )
149
+
150
+ col1 .markdown (f'- { prompt_file } ' )
151
+
152
+ result = self .chatgpt (api_key , conversation , chatbot , prompt )
153
+ save_file (save_file_name , result )
154
+
155
+ with col2 .expander (save_file_name ):
156
+ st .markdown (f'Prompt: { prompt_file } ' )
157
+ st .markdown (f'File: { save_file_name } ' )
158
+ st .markdown (result )
159
+
160
+ return result
85
161
86
162
def run_loop (self ):
87
- for i in range ( 3 ): # change the number here to adjust the number of iterations
163
+ for i in range ( self . loop_count ):
88
164
# Create a new conversation list for each iteration
89
165
conversation_iteration = []
90
-
166
+
91
167
# Summary Chain 3
92
- win1 = open_file ('prompt3.txt' ).replace ('<<WINNINGIDEA>>' , self .evidea2 )
93
- print (win1 )
94
- win2 = self .chatgpt (api_key , conversation_iteration , "Assistant" , win1 )
95
- save_file ('winning1_{}.txt' .format (i ), win2 )
96
- print (win2 )
168
+ replacements = {'<<WINNINGIDEA>>' : self .evidea2 }
169
+ win2 = self .chain_process ('prompts/discriminate.md' , f'results/loop_{ i } _discriminated.md' , replacements , api_key , conversation_iteration , "Assistant" )
97
170
self .update_progress (20 + 20 * i )
98
171
99
172
# Summary Chain 4
100
- loopidea = open_file ('prompt1-5.txt' ).replace ('<<PROBLEM>>' , self .problem ).replace ('<<WINNING2>>' , win2 )
101
- print (loopidea )
102
- loopidea2 = self .chatgpt (api_key , conversation_iteration , "Assistant" , loopidea )
103
- save_file ('winningloop_{}.txt' .format (i ), loopidea2 )
104
- print (loopidea2 )
173
+ replacements = {'<<PROBLEM>>' : self .problem , '<<WINNING2>>' : win2 }
174
+ loopidea2 = self .chain_process ('prompts/brainstorm.md' , f'results/loop_{ i } _brained.md' , replacements , api_key , conversation_iteration , "Assistant" )
105
175
self .update_progress (40 + 20 * i )
106
176
107
177
# Summary Chain 5
108
- loopidea3 = open_file ('prompt2-5.txt' ).replace ('<<WLOOP>>' , loopidea2 )
109
- print (loopidea3 )
110
- loopidea4 = self .chatgpt (api_key , conversation_iteration , "Assistant" , loopidea3 )
111
- save_file ('winningloop2_().txt' .format (i ), loopidea4 )
112
- print (loopidea4 )
178
+ replacements = {'<<WLOOP>>' : loopidea2 }
179
+ loopidea4 = self .chain_process ('prompts/evaluate.md' , f'results/loop_{ i } _evaluated.md' , replacements , api_key , conversation_iteration , "Assistant" )
113
180
self .update_progress (60 + 20 * i )
114
181
115
- def run_script (self ):
116
- self .conversation = []
117
- self .problem = open_file ('problems.txt' )
118
- # Create a new conversation list
119
- conversation = []
120
-
121
- # Summary Chain 1
122
- idea = open_file ('prompt1.txt' ).replace ('<<PROBLEM>>' , self .problem )
123
- print (idea )
124
- idea2 = self .chatgpt (api_key , conversation , "Assistant" , idea )
125
- save_file ('ideas1.txt' , idea2 )
126
- print (idea2 )
127
- self .update_progress (5 )
128
-
129
- # Summary Chain 2
130
- evidea = open_file ('prompt2.txt' ).replace ('<<3IDEAS>>' , idea2 )
131
- print (evidea )
132
- self .evidea2 = self .chatgpt (api_key , conversation , "Asaistant" , evidea )
133
- save_file ('evideas1.txt' , self .evidea2 )
134
- print (self .evidea2 )
135
- self .update_progress (10 )
136
-
137
- # Summary Chain 3
138
- win1 = open_file ('prompt3.txt' ).replace ('<<WINNINGIDEA>>' , self .evidea2 )
139
- print (win1 )
140
- win2 = self .chatgpt (api_key , conversation , "Assistant" , win1 )
141
- save_file ('winning1.txt' , win2 )
142
- print (win2 )
143
- self .update_progress (20 )
144
-
145
- # Summary Chain 4
146
- loopidea = open_file ('prompt1-5.txt' ).replace ('<<PROBLEM>>' , self .problem ).replace ('<<WINNING2>>' , win2 )
147
- print (loopidea )
148
- loopidea2 = self .chatgpt (api_key , conversation , "Assistant" , loopidea )
149
- save_file ('winningloop.txt' , loopidea2 )
150
- print (loopidea2 )
151
- self .update_progress (30 )
152
-
153
- # Summary Chain 5
154
- loopidea3 = open_file ('prompt2-5.txt' ).replace ('<<WLOOP>>' , loopidea2 )
155
- print (loopidea3 )
156
- loopidea4 = self .chatgpt (api_key , conversation , "Assistant" , loopidea3 )
157
- save_file ('winningloop2.txt' , loopidea4 )
158
- print (loopidea4 )
159
- self .run_loop ()
160
- self .update_progress (60 )
161
-
162
- # Summary Chain 6
163
- winner = open_file ('winning1_3.txt' )
164
- winner2 = open_file ('winnerprompt.txt' ).replace ('<<WINNER>>' , winner )
165
- print (winner2 )
166
- winner3 = self .chatgpt (api_key , conversation , "Assistant" , winner2 )
167
- save_file ('winnerdeep.txt' , winner3 )
168
- print (winner3 )
169
- self .update_progress (80 )
170
-
171
- # Summary Chain 7
172
- winner4 = open_file ('finalprompt.txt' ).replace ('<<WINNER2>>' , winner3 ) # 184 --
173
- print (winner4 )
174
- winner5 = self .chatgpt (api_key , conversation , "Assistant" , winner4 )
175
- save_file ('winnerfinal.txt' , winner5 )
176
- print (winner5 )
177
- self .update_progress (100 )
178
-
179
- # Print out the results of each chain
180
- for chain , result in self .get_chain_results ().items ():
181
- print (f"{ chain } : { result } " )
182
+ def run_script (self ):
183
+ self .problem = open_file ('problems.md' )
184
+
185
+ col2 .markdown ("Problems" )
186
+ col2 .markdown (self .problem )
187
+
188
+ conversation = []
189
+
190
+ # Summary Chain 1
191
+ replacements = {'<<PROBLEM>>' : self .problem }
192
+ idea2 = self .chain_process ('prompts/brainstorm-initial.md' , 'results/brainstormed.md' , replacements , api_key , conversation , "Assistant" )
193
+ self .update_progress (5 )
194
+
195
+ # Summary Chain 2
196
+ replacements = {'<<3IDEAS>>' : idea2 }
197
+ self .evidea2 = self .chain_process ('prompts/evaluate-initial.md' , 'results/evaluated.md' , replacements , api_key , conversation , "Assistant" )
198
+ self .update_progress (10 )
199
+
200
+ # Summary Chain 3
201
+ replacements = {'<<WINNINGIDEA>>' : self .evidea2 }
202
+ win2 = self .chain_process ('prompts/discriminate.md' , 'results/discriminated.md' , replacements , api_key , conversation , "Assistant" )
203
+ self .update_progress (20 )
204
+
205
+ # Summary Chain 4
206
+ replacements = {'<<PROBLEM>>' : self .problem , '<<WINNING2>>' : win2 }
207
+ loopidea2 = self .chain_process ('prompts/brainstorm.md' , 'results/brainstormed-2.md' , replacements , api_key , conversation , "Assistant" )
208
+ self .update_progress (30 )
209
+
210
+ # Summary Chain 5
211
+ replacements = {'<<WLOOP>>' : loopidea2 }
212
+ loopidea4 = self .chain_process ('prompts/evaluate.md' , 'results/evaluated-2.md' , replacements , api_key , conversation , "Assistant" )
213
+ self .update_progress (60 )
214
+
215
+ self .run_loop ()
216
+
217
+ # Summary Chain 6
218
+ winner = open_file (f'results/loop_{ self .loop_count - 1 } _evaluated.md' )
219
+ replacements = {'<<WINNER>>' : winner }
220
+ winner3 = self .chain_process ('prompts/deepen-win.md' , 'results/win-deepened.md' , replacements , api_key , conversation , "Assistant" )
221
+ self .update_progress (80 )
222
+
223
+ # Summary Chain 7
224
+ replacements = {'<<WINNER2>>' : winner3 }
225
+ winner5 = self .chain_process ('prompts/justify-win.md' , 'results/win-justified.md' , replacements , api_key , conversation , "Assistant" )
226
+ self .update_progress (95 )
227
+
228
+ # Create a solution.md
229
+ timestr = time .strftime ("%Y-%m-%d_%H-%M-%S" )
230
+ solution_file_name = f'solution_{ timestr } .md'
231
+ save_file (solution_file_name , '# SOLUTIONS\n \n ' , 'w' )
232
+ save_file (solution_file_name , '## Stated problems\n \n ' , 'a' )
233
+ save_file (solution_file_name , self .problem , 'a' )
234
+ save_file (solution_file_name , '\n \n ' , 'a' )
235
+ save_file (solution_file_name , '## Initial brainstorm\n \n ' , 'a' )
236
+ save_file (solution_file_name , self .evidea2 , 'a' )
237
+ save_file (solution_file_name , '\n \n ' , 'a' )
238
+ save_file (solution_file_name , '## Second brainstorm\n \n ' , 'a' )
239
+ save_file (solution_file_name , loopidea2 , 'a' )
240
+ save_file (solution_file_name , '\n \n ' , 'a' )
241
+ save_file (solution_file_name , '## Second brainstorm\n \n ' , 'a' )
242
+ save_file (solution_file_name , loopidea2 , 'a' )
243
+ save_file (solution_file_name , '\n \n ' , 'a' )
244
+ save_file (solution_file_name , f'## Solution\n ' , 'a' )
245
+ save_file (solution_file_name , f'After { self .loop_count } iterations, we deepened the thoughts on the solution.\n \n ' , 'a' )
246
+ save_file (solution_file_name , winner3 , 'a' )
247
+ save_file (solution_file_name , '\n \n ' , 'a' )
248
+ save_file (solution_file_name , f'## Final thoughts on the solution\n \n ' , 'a' )
249
+ save_file (solution_file_name , winner5 , 'a' )
250
+ self .update_progress (100 )
251
+
252
+ # Print out the results of each chain
253
+ for chain , result in self .get_chain_results ().items ():
254
+ logging .info (f'{ chain } : { result } ' )
255
+ with st .sidebar :
256
+ st .divider ()
257
+ st .markdown (chain )
258
+ st .divider ()
259
+ st .markdown (result )
260
+ st .divider ()
261
+
262
+
263
+ if __name__ == "__main__" :
264
+ parser = argparse .ArgumentParser (description = 'Run the script with a specific number of loops.' )
265
+ parser .add_argument ('--loops' , type = int , default = 3 , help = 'The number of loops to run.' )
266
+ args = parser .parse_args ()
267
+
268
+ runner = ScriptRunner (loop_count = args .loops )
269
+ runner .run_script ()
0 commit comments