From b77ca1bb90b281c383a4448d11c7a326c20f4f56 Mon Sep 17 00:00:00 2001 From: mediumsizeworkingdog Date: Mon, 14 Oct 2024 13:39:26 +0800 Subject: [PATCH 1/8] chore: removed formatting from sci example --- commons/qa_examples.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commons/qa_examples.py b/commons/qa_examples.py index 924e41d..63e322f 100644 --- a/commons/qa_examples.py +++ b/commons/qa_examples.py @@ -535,7 +535,7 @@ def _get_science_answer_examples() -> str: }, { "filename": "index.html", - "content": "Golf Ball Trajectory Simulator




Current Distance: 0 m

Best Distance: 0 m

", + "content": "Golf Ball Trajectory Simulator




Current Distance: 0 m

Best Distance: 0 m

", "language": "html" } ] From 21465fe63864c48195410cccc39648d5ed5eacf7 Mon Sep 17 00:00:00 2001 From: mediumsizeworkingdog Date: Mon, 14 Oct 2024 13:42:37 +0800 Subject: [PATCH 2/8] Revert "Merge branch 'dev' into chore/improve-logger-messages" This reverts commit b9bcdd3c5baee306157200796498d48fa7457884, reversing changes made to b77ca1bb90b281c383a4448d11c7a326c20f4f56. --- Dockerfile | 2 +- commons/cache/redis.py | 13 +++--- commons/config.py | 8 ---- commons/synthetic.py | 93 +++++++++++++++++++++++------------------- pyproject.toml | 20 +++++++++ 5 files changed, 79 insertions(+), 57 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9eaccc2..d4b7d15 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,4 +25,4 @@ COPY . . EXPOSE 5003 -CMD ["python", "main.py", "--env_name", "prod"] +CMD ["python", "main.py"] diff --git a/commons/cache/redis.py b/commons/cache/redis.py index b5fde41..aeb0c56 100644 --- a/commons/cache/redis.py +++ b/commons/cache/redis.py @@ -9,7 +9,7 @@ from redis import asyncio as aioredis from redis.asyncio.client import Redis -from commons.config import RedisSettings, get_settings, parse_cli_args +from commons.config import RedisSettings, get_settings def build_redis_url() -> str: @@ -130,18 +130,17 @@ async def enqueue(self, data: Any) -> int: logger.debug(f"Writing persistent data into {hist_key}") # place into persistent key str_data = json.dumps(jsonable_encoder(data)).encode(self._encoding) - args = parse_cli_args() - if args.env_name and args.env_name == "prod": - # expire in 4 hours time - await self.redis.set(hist_key, str_data, ex=3600 * 4) # pyright: ignore[reportUnknownMemberType] - else: - await self.redis.set(hist_key, str_data) # pyright: ignore[reportUnknownMemberType] + await self.redis.set(hist_key, str_data) # pyright: ignore[reportUnknownMemberType] queue_key = self._build_key(self._queue_key) logger.debug(f"Writing queue data into {queue_key}") # fuck it and push the data into the queue as well, instead of it being a reference to the persistent data # this also simplifies dequeuing logic num_items: int = await self.redis.rpush(queue_key, str_data) # type: ignore + + # collect cids for each answer and log successful upload to DB + ids: list[str] = [response["cid"] for response in data["responses"]] + logger.success(f"📦 Pushed Task {ids} to DB") return num_items except Exception as exc: logger.opt(exception=True).error( diff --git a/commons/config.py b/commons/config.py index f025640..07cc17c 100644 --- a/commons/config.py +++ b/commons/config.py @@ -1,5 +1,4 @@ import argparse -import functools import os import sys @@ -87,7 +86,6 @@ def get_settings() -> Settings: return Settings() -@functools.lru_cache(maxsize=1) def parse_cli_args(): parser = argparse.ArgumentParser(description="CLI arguments for the application") parser.add_argument( @@ -96,12 +94,6 @@ def parse_cli_args(): parser.add_argument( "--trace", action="store_true", help="Enable TRACE logging level" ) - parser.add_argument( - "--env_name", - type=str, - choices=["dev", "prod"], - help="Specify the environment (dev or prod)", - ) args = parser.parse_args() if args.trace: diff --git a/commons/synthetic.py b/commons/synthetic.py index e089475..d1500a4 100644 --- a/commons/synthetic.py +++ b/commons/synthetic.py @@ -94,8 +94,6 @@ async def generate_question( _topic: Topics, persona: str, ) -> tuple[str | None, Dict | None]: - logger.info(f"Generating question with model: {model}") - MAX_RETRIES = 5 global used_objects global previous_coding_question @@ -146,8 +144,8 @@ async def generate_question( **kwargs_clone, }, ) - logger.success(f"Completed generating base question: {coding_question}") previous_coding_question = coding_question + logger.info("Base Question Generation Completed") return coding_question, kwargs except RetryError: logger.error( @@ -177,13 +175,14 @@ async def generate_answer( model: str, question: str, topic: Topics, + qa_id: str, err: str | None = None, code: str | None = None, ) -> Tuple[str, CodeAnswer | None]: """Generates a coding question answer for a given coding question.""" # import commons.config as config - logger.info(f"Generating code answer with model: {model}") + # logger.info(f"{qa_id} Generating code answer with model: {model}") if bool(err) != bool(code): raise ValueError("Both error and code must be provided or neither") @@ -243,11 +242,10 @@ async def generate_answer( }, ) # logger.warning(f"@@@@@ generate_answer(): {response_model} \n") + logger.info(f"{qa_id} Answer Generation Completed ") return model, response_model except RetryError: - logger.error( - f"Failed to generate answer after {MAX_RETRIES} attempts. Switching model." - ) + logger.error(f"{qa_id} Failed after {MAX_RETRIES} attempts. Switching model.") raise # used_models.add(model) # remaining_models = [m for m in config.ANSWER_MODELS if m not in used_models] @@ -258,7 +256,7 @@ async def generate_answer( # new_model = random.choice(remaining_models) # return await generate_answer(client, new_model, question, topic=topic) except Exception as e: - logger.error(f"Error occurred while generating code answer: {e}") + logger.error(f"Error occurred while generating {qa_id} answer: {e}") return model, None @@ -290,17 +288,18 @@ async def augment_question( question: str, augmentation_level: AugmentationLevel, topic: Topics, -) -> str: +) -> tuple[str, str]: """Augment the question with the given model and augmentation level.""" - logger.info( - f"Augmenting question with model and augmentation: {model}, {augmentation_level}" - ) + augmentation_prompt = "" preamble = """ You are an LLM specializing in modifying existing coding questions to create similar yet distinct versions. Ultimately the new edited questions that you generate will be implemented by a programming agent. As such, use your vast knowledge of UX and software engineering principles to make intelligent yet distinguishable modifications. """ + # create unique qa_id + qa_id = str(uuid.uuid4()) + if augmentation_level == AugmentationLevel.REMOVE_REQUIREMENTS: augmentation_prompt = f"You must remove any 1 requirement from the following question: {question}. Ensure that the requirement you remove will not break the functionality of the remaining requirements." elif augmentation_level == AugmentationLevel.ADD_REQUIREMENTS: @@ -319,7 +318,7 @@ async def augment_question( "augmentation_level": augmentation_level, } ) - return question + return question, qa_id kwargs = { "response_model": CodingQuestion, @@ -337,24 +336,28 @@ async def augment_question( if model.startswith("openai"): kwargs["seed"] = random.randint(0, int(1e9)) # needed for OpenAI - response_model = await client.chat.completions.create(**kwargs) - - kwargs_clone = kwargs.copy() - kwargs_clone["response_model"] = kwargs["response_model"].model_json_schema() - langfuse_context.update_current_observation( - input=kwargs_clone.pop("messages"), - model=model, - output=response_model.model_dump(), - # usage=log_llm_usage(response_model.usage), - metadata={ - "topic": topic, - "question": question, - "augmentation_level": augmentation_level, - **kwargs_clone, - }, - ) - logger.success(f"Completed generating augmentation {augmentation_level}") - return response_model.question + try: + response_model = await client.chat.completions.create(**kwargs) + + kwargs_clone = kwargs.copy() + kwargs_clone["response_model"] = kwargs["response_model"].model_json_schema() + langfuse_context.update_current_observation( + input=kwargs_clone.pop("messages"), + model=model, + output=response_model.model_dump(), + # usage=log_llm_usage(response_model.usage), + metadata={ + "topic": topic, + "question": question, + "augmentation_level": augmentation_level, + **kwargs_clone, + }, + ) + logger.info(f"{qa_id} {augmentation_level} Completed") + return response_model.question, qa_id + except Exception as e: + logger.error(f"{qa_id}: failed to augment question: {e}") + raise RuntimeError from (e) def build_single_index_html(ans: CodeAnswer) -> CodeAnswer: @@ -459,9 +462,12 @@ async def _generate_response( model: str, question: str, topic: Topics, + qa_id: str, level: AugmentationLevel | None = None, ): - model, result = await generate_answer(client, model, question, topic=topic) + model, result = await generate_answer( + client, model, question, topic=topic, qa_id=qa_id + ) if result is None: raise ValueError("generate_answer() returned none") # TODO remove after testing ensure single index.html file just for now @@ -492,7 +498,7 @@ async def _generate_response( else: raise ValueError("No index.html file found in the result") - return model, result, level + return model, result, level, qa_id # 1. get random persona from hugging face persona = get_random_persona() @@ -512,7 +518,11 @@ async def _generate_response( augmented_prompts = [] if response_strategy == ResponseStrategy.NO_AUGMENTATION: for model in answer_models: - tasks.append(_generate_response(model, question_prompt, selected_topic[0])) + tasks.append( + _generate_response( + model, question_prompt, selected_topic[0], qa_id="placeholder" + ) + ) elif response_strategy == ResponseStrategy.AUGMENTATION_DETERIORIATE: # 4. augment questions # if augmenting, use same model for both question and answer generation @@ -521,7 +531,7 @@ async def _generate_response( assert type(answer_models) is str for level in AugmentationLevel: - augmented_question = await augment_question( + augmented_question, qa_id = await augment_question( client, question_model, question_prompt, level, selected_topic[0] ) augmented_prompts.append( @@ -534,16 +544,17 @@ async def _generate_response( augmented_question, topic=selected_topic[0], level=level, + qa_id=qa_id, ) ) results: list[ - tuple[str, CodeAnswer | None, AugmentationLevel | None] + tuple[str, CodeAnswer | None, AugmentationLevel | None, str] ] = await asyncio.gather(*tasks) responses = [] synthetic_ground_truth: dict[str, int] = {} - for model, result, level in results: + for model, result, level, qa_id in results: if not result: raise RuntimeError("Error generating prompt-response pair") @@ -555,18 +566,18 @@ async def _generate_response( } for file in result.files ] - completion_id = str(uuid.uuid4()) + responses.append( { "model": model, "completion": {"files": formatted_files}, - "cid": completion_id, + "cid": qa_id, } ) if level: - logger.debug(f"{model=},{completion_id=}, {level=}") - synthetic_ground_truth[completion_id] = level.value + logger.debug(f"{model=},{qa_id=}, {level=}") + synthetic_ground_truth[qa_id] = level.value return { "prompt": question_prompt, diff --git a/pyproject.toml b/pyproject.toml index 63e3014..7c179f3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,6 +66,26 @@ Repository = "https://github.com/tensorplex-labs/dojo-synthetic-api" [tool.commitizen] name = "cz_conventional_commits" +[tool.pyright] +include = ["commons"] +exclude = [ + "**/node_modules", + "**/__pycache__", + "src/experimental", + "src/typestubs", + "*.js" +] +ignore = ["tests"] +defineConstant = {DEBUG = true} +typeCheckingMode = "standard" +reportUnreachable = true +reportUnusedParameter = true +reportPrivateLocalImportUsage = true +reportMissingImports = "error" +reportMissingTypeStubs = false +pythonVersion = "3.11" +pythonPlatform = "All" + [tool.ruff] # Exclude a variety of commonly ignored directories. exclude = [ From 5d90ccd7649577c26f0e7f814dbb8953c21ac7a4 Mon Sep 17 00:00:00 2001 From: mediumsizeworkingdog Date: Mon, 14 Oct 2024 18:12:31 +0800 Subject: [PATCH 3/8] fix: fixed generating more tasks than expected --- commons/routes/synthetic_gen.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/commons/routes/synthetic_gen.py b/commons/routes/synthetic_gen.py index ac1312b..649c926 100644 --- a/commons/routes/synthetic_gen.py +++ b/commons/routes/synthetic_gen.py @@ -2,7 +2,7 @@ import functools import json -from fastapi import APIRouter, BackgroundTasks +from fastapi import APIRouter from pydantic import BaseModel from commons.cache import RedisCache @@ -31,7 +31,7 @@ class SyntheticGenResponse(BaseModel): @synthetic_gen_router.get("/synthetic-gen") -async def generate_synthetic_data(background_tasks: BackgroundTasks): +async def generate_synthetic_data(): try: num_elems = await cache.get_queue_length() if num_elems == 0: @@ -51,8 +51,6 @@ async def generate_synthetic_data(background_tasks: BackgroundTasks): except json.JSONDecodeError: result = {} - background_tasks.add_task(worker.run) - return SyntheticGenResponse(success=True, body=result, error=None) except Exception as e: return SyntheticGenResponse(success=False, body={}, error=str(e)) From 033facbe4b2614c87aa766f3653a97a4461d5e15 Mon Sep 17 00:00:00 2001 From: mediumsizeworkingdog Date: Mon, 14 Oct 2024 18:41:02 +0800 Subject: [PATCH 4/8] chore: manual merge dev -> improve-logger-messages --- Dockerfile | 2 +- commons/cache/redis.py | 11 ++++++++--- commons/config.py | 8 ++++++++ pyproject.toml | 20 -------------------- 4 files changed, 17 insertions(+), 24 deletions(-) diff --git a/Dockerfile b/Dockerfile index d4b7d15..bee30dd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,4 +25,4 @@ COPY . . EXPOSE 5003 -CMD ["python", "main.py"] +CMD ["python", "main.py", "--env_name", "dev"] diff --git a/commons/cache/redis.py b/commons/cache/redis.py index aeb0c56..f747b7d 100644 --- a/commons/cache/redis.py +++ b/commons/cache/redis.py @@ -9,7 +9,7 @@ from redis import asyncio as aioredis from redis.asyncio.client import Redis -from commons.config import RedisSettings, get_settings +from commons.config import RedisSettings, get_settings, parse_cli_args def build_redis_url() -> str: @@ -130,7 +130,12 @@ async def enqueue(self, data: Any) -> int: logger.debug(f"Writing persistent data into {hist_key}") # place into persistent key str_data = json.dumps(jsonable_encoder(data)).encode(self._encoding) - await self.redis.set(hist_key, str_data) # pyright: ignore[reportUnknownMemberType] + args = parse_cli_args() + if args.env_name and args.env_name == "prod": + # expire in 4 hours time + await self.redis.set(hist_key, str_data, ex=3600 * 4) # pyright: ignore[reportUnknownMemberType] + else: + await self.redis.set(hist_key, str_data) # pyright: ignore[reportUnknownMemberType] queue_key = self._build_key(self._queue_key) logger.debug(f"Writing queue data into {queue_key}") @@ -140,7 +145,7 @@ async def enqueue(self, data: Any) -> int: # collect cids for each answer and log successful upload to DB ids: list[str] = [response["cid"] for response in data["responses"]] - logger.success(f"📦 Pushed Task {ids} to DB") + logger.success(f"Pushed Task {ids} to DB") return num_items except Exception as exc: logger.opt(exception=True).error( diff --git a/commons/config.py b/commons/config.py index 07cc17c..f025640 100644 --- a/commons/config.py +++ b/commons/config.py @@ -1,4 +1,5 @@ import argparse +import functools import os import sys @@ -86,6 +87,7 @@ def get_settings() -> Settings: return Settings() +@functools.lru_cache(maxsize=1) def parse_cli_args(): parser = argparse.ArgumentParser(description="CLI arguments for the application") parser.add_argument( @@ -94,6 +96,12 @@ def parse_cli_args(): parser.add_argument( "--trace", action="store_true", help="Enable TRACE logging level" ) + parser.add_argument( + "--env_name", + type=str, + choices=["dev", "prod"], + help="Specify the environment (dev or prod)", + ) args = parser.parse_args() if args.trace: diff --git a/pyproject.toml b/pyproject.toml index 7c179f3..63e3014 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,26 +66,6 @@ Repository = "https://github.com/tensorplex-labs/dojo-synthetic-api" [tool.commitizen] name = "cz_conventional_commits" -[tool.pyright] -include = ["commons"] -exclude = [ - "**/node_modules", - "**/__pycache__", - "src/experimental", - "src/typestubs", - "*.js" -] -ignore = ["tests"] -defineConstant = {DEBUG = true} -typeCheckingMode = "standard" -reportUnreachable = true -reportUnusedParameter = true -reportPrivateLocalImportUsage = true -reportMissingImports = "error" -reportMissingTypeStubs = false -pythonVersion = "3.11" -pythonPlatform = "All" - [tool.ruff] # Exclude a variety of commonly ignored directories. exclude = [ From ea63d3cf180cb7fd62dffc0a1653f018ccc2fdc4 Mon Sep 17 00:00:00 2001 From: mediumsizeworkingdog Date: Tue, 15 Oct 2024 00:20:47 +0800 Subject: [PATCH 5/8] chore: manual merge dev -> improve-logger-message attempt #2 --- Dockerfile | 2 +- commons/cache/redis.py | 11 ++++++++--- commons/config.py | 8 ++++++++ commons/routes/synthetic_gen.py | 6 ++---- pyproject.toml | 20 -------------------- 5 files changed, 19 insertions(+), 28 deletions(-) diff --git a/Dockerfile b/Dockerfile index d4b7d15..9eaccc2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,4 +25,4 @@ COPY . . EXPOSE 5003 -CMD ["python", "main.py"] +CMD ["python", "main.py", "--env_name", "prod"] diff --git a/commons/cache/redis.py b/commons/cache/redis.py index aeb0c56..f747b7d 100644 --- a/commons/cache/redis.py +++ b/commons/cache/redis.py @@ -9,7 +9,7 @@ from redis import asyncio as aioredis from redis.asyncio.client import Redis -from commons.config import RedisSettings, get_settings +from commons.config import RedisSettings, get_settings, parse_cli_args def build_redis_url() -> str: @@ -130,7 +130,12 @@ async def enqueue(self, data: Any) -> int: logger.debug(f"Writing persistent data into {hist_key}") # place into persistent key str_data = json.dumps(jsonable_encoder(data)).encode(self._encoding) - await self.redis.set(hist_key, str_data) # pyright: ignore[reportUnknownMemberType] + args = parse_cli_args() + if args.env_name and args.env_name == "prod": + # expire in 4 hours time + await self.redis.set(hist_key, str_data, ex=3600 * 4) # pyright: ignore[reportUnknownMemberType] + else: + await self.redis.set(hist_key, str_data) # pyright: ignore[reportUnknownMemberType] queue_key = self._build_key(self._queue_key) logger.debug(f"Writing queue data into {queue_key}") @@ -140,7 +145,7 @@ async def enqueue(self, data: Any) -> int: # collect cids for each answer and log successful upload to DB ids: list[str] = [response["cid"] for response in data["responses"]] - logger.success(f"📦 Pushed Task {ids} to DB") + logger.success(f"Pushed Task {ids} to DB") return num_items except Exception as exc: logger.opt(exception=True).error( diff --git a/commons/config.py b/commons/config.py index 07cc17c..f025640 100644 --- a/commons/config.py +++ b/commons/config.py @@ -1,4 +1,5 @@ import argparse +import functools import os import sys @@ -86,6 +87,7 @@ def get_settings() -> Settings: return Settings() +@functools.lru_cache(maxsize=1) def parse_cli_args(): parser = argparse.ArgumentParser(description="CLI arguments for the application") parser.add_argument( @@ -94,6 +96,12 @@ def parse_cli_args(): parser.add_argument( "--trace", action="store_true", help="Enable TRACE logging level" ) + parser.add_argument( + "--env_name", + type=str, + choices=["dev", "prod"], + help="Specify the environment (dev or prod)", + ) args = parser.parse_args() if args.trace: diff --git a/commons/routes/synthetic_gen.py b/commons/routes/synthetic_gen.py index ac1312b..649c926 100644 --- a/commons/routes/synthetic_gen.py +++ b/commons/routes/synthetic_gen.py @@ -2,7 +2,7 @@ import functools import json -from fastapi import APIRouter, BackgroundTasks +from fastapi import APIRouter from pydantic import BaseModel from commons.cache import RedisCache @@ -31,7 +31,7 @@ class SyntheticGenResponse(BaseModel): @synthetic_gen_router.get("/synthetic-gen") -async def generate_synthetic_data(background_tasks: BackgroundTasks): +async def generate_synthetic_data(): try: num_elems = await cache.get_queue_length() if num_elems == 0: @@ -51,8 +51,6 @@ async def generate_synthetic_data(background_tasks: BackgroundTasks): except json.JSONDecodeError: result = {} - background_tasks.add_task(worker.run) - return SyntheticGenResponse(success=True, body=result, error=None) except Exception as e: return SyntheticGenResponse(success=False, body={}, error=str(e)) diff --git a/pyproject.toml b/pyproject.toml index 7c179f3..63e3014 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,26 +66,6 @@ Repository = "https://github.com/tensorplex-labs/dojo-synthetic-api" [tool.commitizen] name = "cz_conventional_commits" -[tool.pyright] -include = ["commons"] -exclude = [ - "**/node_modules", - "**/__pycache__", - "src/experimental", - "src/typestubs", - "*.js" -] -ignore = ["tests"] -defineConstant = {DEBUG = true} -typeCheckingMode = "standard" -reportUnreachable = true -reportUnusedParameter = true -reportPrivateLocalImportUsage = true -reportMissingImports = "error" -reportMissingTypeStubs = false -pythonVersion = "3.11" -pythonPlatform = "All" - [tool.ruff] # Exclude a variety of commonly ignored directories. exclude = [ From d91ee905bfc97a1c35d3c4c7d09c62157a059abb Mon Sep 17 00:00:00 2001 From: mediumsizeworkingdog Date: Tue, 15 Oct 2024 14:20:13 +0800 Subject: [PATCH 6/8] test: test commit --- commons/synthetic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commons/synthetic.py b/commons/synthetic.py index d1500a4..f3384b0 100644 --- a/commons/synthetic.py +++ b/commons/synthetic.py @@ -99,7 +99,7 @@ async def generate_question( global previous_coding_question global used_models used_models = set() - + # test comment # try generating until max_retries, then switch models try: async for attempt in AsyncRetrying( From 7df5c2ab1c40c87906457feaf56e84f1aa5edd66 Mon Sep 17 00:00:00 2001 From: mediumsizeworkingdog Date: Tue, 15 Oct 2024 14:21:13 +0800 Subject: [PATCH 7/8] test: undo test commit --- commons/synthetic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commons/synthetic.py b/commons/synthetic.py index f3384b0..d1500a4 100644 --- a/commons/synthetic.py +++ b/commons/synthetic.py @@ -99,7 +99,7 @@ async def generate_question( global previous_coding_question global used_models used_models = set() - # test comment + # try generating until max_retries, then switch models try: async for attempt in AsyncRetrying( From 9ab0d0734c7c5b8c72f18e3ad5c7d060db1b26c8 Mon Sep 17 00:00:00 2001 From: mediumsizeworkingdog Date: Wed, 16 Oct 2024 14:23:26 +0800 Subject: [PATCH 8/8] chore: disabled instructor retries for being slow --- commons/synthetic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commons/synthetic.py b/commons/synthetic.py index d1500a4..8710906 100644 --- a/commons/synthetic.py +++ b/commons/synthetic.py @@ -94,7 +94,7 @@ async def generate_question( _topic: Topics, persona: str, ) -> tuple[str | None, Dict | None]: - MAX_RETRIES = 5 + MAX_RETRIES = 0 global used_objects global previous_coding_question global used_models @@ -215,7 +215,7 @@ async def generate_answer( if model.startswith("openai"): kwargs["seed"] = random.randint(0, cast(int, 1e9)) # needed for OpenAI - MAX_RETRIES = 2 + MAX_RETRIES = 0 # try generating until max retries, then switch models try: async for attempt in AsyncRetrying(