@@ -114,53 +114,62 @@ def prepare_env():
114114 with open (config_path ) as f :
115115 config = toml .load (f )
116116
117- if "generatedfiles_root" not in config :
118- config ["generatedfiles_root" ] = "./generatedfiles"
119-
120- if "use_remote_job_queue" not in config :
121- config ["use_remote_job_queue" ] = True
122-
123- if "llmstack-runner" not in config :
124- config ["llmstack-runner" ] = {}
117+ with open (config_path , "w" ) as f :
118+ toml .dump (config , f )
125119
126- if "host" not in config ["llmstack-runner" ]:
127- config ["llmstack-runner" ]["host" ] = "localhost"
120+ return config_path
128121
129- if "port" not in config ["llmstack-runner" ]:
130- config ["llmstack-runner" ]["port" ] = 50051
131122
132- if "wss_port" not in config ["llmstack-runner" ]:
133- config ["llmstack-runner" ]["wss_port" ] = 50052
123+ def pull_redis_image ():
124+ """Pull Redis image"""
125+ client = docker .from_env ()
126+ image_name = "redis"
127+ image_tag = "latest"
134128
135- if "playwright_port" not in config ["llmstack-runner" ]:
136- config ["llmstack-runner" ]["playwright_port" ] = 50053
129+ # Pull image if it is not locally available
130+ if not any (f"{ image_name } :{ image_tag } " in image .tags for image in client .images .list ()):
131+ print (f"[Redis] Pulling { image_name } :{ image_tag } " )
137132
138- if "rq_redis_port" not in config ["llmstack-runner" ]:
139- config ["llmstack-runner" ]["rq_redis_port" ] = 50379
133+ layers_status = defaultdict (dict )
134+ response = client .api .pull (
135+ image_name ,
136+ tag = image_tag ,
137+ stream = True ,
138+ decode = True ,
139+ )
140+ for line in response :
141+ if "id" in line :
142+ layer_id = line ["id" ]
143+ # Update the status of this layer
144+ layers_status [layer_id ].update (line )
140145
141- if "rq_redis_host" not in config ["llmstack-runner" ]:
142- config ["llmstack-runner" ]["rq_redis_host" ] = "localhost"
146+ # Print the current status of all layers
147+ for layer , status in layers_status .items ():
148+ print (
149+ f"[Redis] Layer { layer } : { status .get ('status' , '' )} { status .get ('progress' , '' )} " ,
150+ )
151+ print () # Add a blank line for better readability
143152
144- with open (config_path , "w" ) as f :
145- toml .dump (config , f )
153+ elif "status" in line and "id" not in line :
154+ # Global status messages without a specific layer ID
155+ print (line ["status" ])
146156
147- return config_path
157+ elif "error" in line :
158+ print (f"Error: { line ['error' ]} " )
159+ break
148160
149161
150- def start_runner (environment ):
151- """Start llmstack-runner container"""
152- print ("[llmstack-runner ] Starting LLMStack Runner " )
162+ def start_redis (environment ):
163+ """Start Redis container"""
164+ print ("[Redis ] Starting Redis " )
153165 client = docker .from_env ()
154- runner_container = None
155- image_name = environment .get (
156- "RUNNER_IMAGE_NAME" ,
157- "ghcr.io/trypromptly/llmstack-runner" ,
158- )
159- image_tag = environment .get ("RUNNER_IMAGE_TAG" , "main" )
166+ redis_container = None
167+ image_name = environment .get ("REDIS_IMAGE_NAME" , "redis" )
168+ image_tag = environment .get ("REDIS_IMAGE_TAG" , "latest" )
160169
161170 # Pull image if it is not locally available
162171 if not any (f"{ image_name } :{ image_tag } " in image .tags for image in client .images .list ()):
163- print (f"[llmstack-runner ] Pulling { image_name } :{ image_tag } " )
172+ print (f"[Redis ] Pulling { image_name } :{ image_tag } " )
164173
165174 layers_status = defaultdict (dict )
166175 response = client .api .pull (
@@ -178,7 +187,7 @@ def start_runner(environment):
178187 # Print the current status of all layers
179188 for layer , status in layers_status .items ():
180189 print (
181- f"[llmstack-runner ] Layer { layer } : { status .get ('status' , '' )} { status .get ('progress' , '' )} " ,
190+ f"[Redis ] Layer { layer } : { status .get ('status' , '' )} { status .get ('progress' , '' )} " ,
182191 )
183192 print () # Add a blank line for better readability
184193
@@ -191,44 +200,41 @@ def start_runner(environment):
191200 break
192201
193202 try :
194- runner_container = client .containers .get ("llmstack-runner " )
203+ redis_container = client .containers .get ("llmstack-redis " )
195204 except docker .errors .NotFound :
196- runner_container = client .containers .run (
205+ redis_container = client .containers .run (
197206 f"{ image_name } :{ image_tag } " ,
198- name = "llmstack-runner " ,
207+ name = "llmstack-redis " ,
199208 ports = {
200- "50051/tcp" : os .environ ["RUNNER_PORT" ],
201- "50052/tcp" : os .environ ["RUNNER_WSS_PORT" ],
202- "50053/tcp" : os .environ ["RUNNER_PLAYWRIGHT_PORT" ],
203- "6379/tcp" : os .environ ["RUNNER_RQ_REDIS_PORT" ],
209+ "6379/tcp" : os .environ ["REDIS_PORT" ],
204210 },
205211 detach = True ,
206212 remove = True ,
207213 environment = environment ,
208214 )
209215
210- # Start runner container if not already running
211- print ("[llmstack-runner ] Started LLMStack Runner " )
212- if runner_container .status != "running" :
213- runner_container .start ()
216+ # Start Redis container if not already running
217+ print ("[Redis ] Started Redis " )
218+ if redis_container .status != "running" :
219+ redis_container .start ()
214220
215221 # Stream logs starting from the end to stdout
216- for line in runner_container .logs (stream = True , follow = True ):
217- print (f'[llmstack-runner ] { line .decode ("utf-8" ).strip ()} ' )
222+ for line in redis_container .logs (stream = True , follow = True ):
223+ print (f'[Redis ] { line .decode ("utf-8" ).strip ()} ' )
218224
219225
220- def stop_runner ():
221- """Stop llmstack-runner container"""
222- print ("\n Stopping LLMStack Runner \n " )
226+ def stop_redis ():
227+ """Stop Redis container"""
228+ print ("\n Stopping Redis \n " )
223229 client = docker .from_env ()
224- runner_container = None
230+ redis_container = None
225231 try :
226- runner_container = client .containers .get ("llmstack-runner " )
232+ redis_container = client .containers .get ("llmstack-redis " )
227233 except docker .errors .NotFound :
228234 pass
229235
230- if runner_container :
231- runner_container .stop ()
236+ if redis_container :
237+ redis_container .stop ()
232238
233239 client .close ()
234240
@@ -237,12 +243,14 @@ def main():
237243 """Main entry point for the application script"""
238244
239245 def signal_handler (sig , frame ):
240- stop_runner ()
241- if runner_thread .is_alive ():
242- runner_thread .join ()
243246 if server_process .poll () is None : # Check if the process is still running
244247 server_process .terminate ()
245248 server_process .wait ()
249+
250+ stop_redis ()
251+ if redis_thread .is_alive ():
252+ redis_thread .join ()
253+
246254 sys .exit (0 )
247255
248256 # Get config file path
@@ -266,19 +274,18 @@ def signal_handler(sig, frame):
266274
267275 # Load environment variables from config under [llmstack] section
268276 llmstack_environment = {}
269- runner_environment = {}
277+ redis_environment = {}
270278 with open (env_path ) as f :
271279 config = toml .load (f )
272280 for key in config ["llmstack" ]:
273281 os .environ [key .upper ()] = str (config ["llmstack" ][key ])
274282 llmstack_environment [key .upper ()] = str (config ["llmstack" ][key ])
275- for key in config ["llmstack-runner" ]:
276- os .environ [f"RUNNER_{ key .upper ()} " ] = str (
277- config ["llmstack-runner" ][key ],
278- )
279- runner_environment [f"RUNNER_{ key .upper ()} " ] = str (
280- config ["llmstack-runner" ][key ],
281- )
283+
284+ redis_environment ["REDIS_PORT" ] = (
285+ llmstack_environment ["REDIS_PORT" ] if "REDIS_PORT" in llmstack_environment else "50379"
286+ )
287+
288+ os .environ ["REDIS_PORT" ] = redis_environment ["REDIS_PORT" ]
282289
283290 # Load CLI args
284291 args = parser .parse_args ()
@@ -305,6 +312,7 @@ def signal_handler(sig, frame):
305312 run_django_command (sys .argv [1 :])
306313 sys .exit (0 )
307314
315+ run_django_command (["manage.py" , "migrate" , "--fake" ])
308316 run_django_command (["manage.py" , "migrate" , "--noinput" ])
309317 run_django_command (
310318 [
@@ -322,14 +330,17 @@ def signal_handler(sig, frame):
322330 # Install default playwright browsers
323331 subprocess .run (["playwright" , "install" , "chromium" ])
324332
325- # Start llmstack-runner container in a separate thread
333+ # Pull redis before starting
334+ pull_redis_image ()
335+
336+ # Start llmstack-redis container in a separate thread
326337 import threading
327338
328- runner_thread = threading .Thread (
329- target = start_runner ,
330- args = ([runner_environment ]),
339+ redis_thread = threading .Thread (
340+ target = start_redis ,
341+ args = ([redis_environment ]),
331342 )
332- runner_thread .start ()
343+ redis_thread .start ()
333344
334345 # Run llmstack runserver in a separate process
335346 server_process = subprocess .Popen (["llmstack" , "runserver" ])
@@ -372,10 +383,6 @@ def signal_handler(sig, frame):
372383 else :
373384 signal .pause ()
374385
375- # Stop runner container
376- stop_runner ()
377- runner_thread .join ()
378-
379386 # Stop server process
380387 server_process .terminate ()
381388 server_process .wait ()
@@ -384,6 +391,10 @@ def signal_handler(sig, frame):
384391 rqworker_process .terminate ()
385392 rqworker_process .wait ()
386393
394+ # Stop redis container
395+ stop_redis ()
396+ redis_thread .join ()
397+
387398
388399if __name__ == "__main__" :
389400 main ()
0 commit comments