From bcb5e94435c1d15dc212ec736e581a320ece2414 Mon Sep 17 00:00:00 2001 From: = Enea_Gore Date: Fri, 4 Apr 2025 20:01:44 +0200 Subject: [PATCH 1/6] setup weviate, update pydantic, create schema, create approach, initial commit --- .../endpoints/health_endpoint.py | 4 +- athena/athena/athena/endpoints.py | 2 +- athena/athena/athena/schemas/exercise.py | 2 +- athena/athena/athena/schemas/feedback.py | 2 +- .../athena/schemas/modeling_exercise.py | 4 +- .../athena/schemas/programming_exercise.py | 4 +- athena/athena/athena/schemas/schema.py | 2 +- athena/athena/athena/schemas/submission.py | 2 +- athena/athena/athena/schemas/text_exercise.py | 4 +- athena/athena/poetry.lock | 25 +- athena/athena/pyproject.toml | 2 +- .../module_text_llm/__main__.py | 7 +- .../module_text_llm/module_text_llm/config.py | 3 +- .../in_context_learning/__init__.py | 13 + .../in_context_learning/agent.py | 68 +++ .../in_context_learning/docker-compose.yml | 32 + .../feedback_icl/generate_embeddings.py | 7 + .../feedback_icl/retrieve_rag_context_icl.py | 59 ++ .../feedback_icl/store_feedback_icl.py | 101 +++ .../feedback_icl/store_indices_icl.py | 47 ++ .../generate_suggestions.py | 164 +++++ .../in_context_learning/ollama_prompt.py | 82 +++ .../prompt_generate_suggestions.py | 54 ++ .../modules/text/module_text_llm/poetry.lock | 577 ++++++++++++++++-- .../text/module_text_llm/pyproject.toml | 3 +- 25 files changed, 1178 insertions(+), 92 deletions(-) create mode 100644 athena/modules/text/module_text_llm/module_text_llm/in_context_learning/__init__.py create mode 100644 athena/modules/text/module_text_llm/module_text_llm/in_context_learning/agent.py create mode 100644 athena/modules/text/module_text_llm/module_text_llm/in_context_learning/docker-compose.yml create mode 100644 athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/generate_embeddings.py create mode 100644 athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context_icl.py create mode 100644 athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback_icl.py create mode 100644 athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_indices_icl.py create mode 100644 athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py create mode 100644 athena/modules/text/module_text_llm/module_text_llm/in_context_learning/ollama_prompt.py create mode 100644 athena/modules/text/module_text_llm/module_text_llm/in_context_learning/prompt_generate_suggestions.py diff --git a/athena/assessment_module_manager/assessment_module_manager/endpoints/health_endpoint.py b/athena/assessment_module_manager/assessment_module_manager/endpoints/health_endpoint.py index effdf926..9ee9f70a 100644 --- a/athena/assessment_module_manager/assessment_module_manager/endpoints/health_endpoint.py +++ b/athena/assessment_module_manager/assessment_module_manager/endpoints/health_endpoint.py @@ -1,6 +1,6 @@ import httpx from pydantic import BaseModel, Field - +from typing import Literal from .modules_endpoint import get_modules from assessment_module_manager.app import app from assessment_module_manager.logger import logger @@ -29,7 +29,7 @@ class HealthResponse(BaseModel): and whether all the modules are healthy (i.e. reachable). Additional information about the modules is also provided. """ - status: str = Field(const=True, default="ok", example="ok") + status: str = Field(Literal=True, default="ok", example="ok") modules: dict = Field( example=[ { diff --git a/athena/athena/athena/endpoints.py b/athena/athena/athena/endpoints.py index 6d259a2a..a3014050 100644 --- a/athena/athena/athena/endpoints.py +++ b/athena/athena/athena/endpoints.py @@ -156,7 +156,7 @@ class SubmissionSelectorRequest(BaseModel): class Config: # Allow camelCase field names in the API (converted to snake_case) alias_generator = to_camel - allow_population_by_field_name = True + populate_by_name = True @app.post("/select_submission", responses=module_responses) @authenticated diff --git a/athena/athena/athena/schemas/exercise.py b/athena/athena/athena/schemas/exercise.py index 1f173e2e..ee85e05a 100644 --- a/athena/athena/athena/schemas/exercise.py +++ b/athena/athena/athena/schemas/exercise.py @@ -29,4 +29,4 @@ class Exercise(Schema, ABC): meta: dict = Field({}, example={"internal_id": "5"}) class Config: - orm_mode = True + from_attributes = True diff --git a/athena/athena/athena/schemas/feedback.py b/athena/athena/athena/schemas/feedback.py index 4cf9c6a2..24af4941 100644 --- a/athena/athena/athena/schemas/feedback.py +++ b/athena/athena/athena/schemas/feedback.py @@ -33,4 +33,4 @@ def to_model(self, is_suggestion: bool = False, lms_id: Optional[int] = None, lm return type(self).get_model_class()(**self.dict(), is_suggestion=is_suggestion, lms_id=lms_id, lms_url=lms_url) class Config: - orm_mode = True + from_attributes = True diff --git a/athena/athena/athena/schemas/modeling_exercise.py b/athena/athena/athena/schemas/modeling_exercise.py index 70452f83..69cdeb5f 100644 --- a/athena/athena/athena/schemas/modeling_exercise.py +++ b/athena/athena/athena/schemas/modeling_exercise.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import Optional, Literal from pydantic import Field from .exercise_type import ExerciseType @@ -8,6 +8,6 @@ class ModelingExercise(Exercise): """A modeling exercise that can be solved by students, enhanced with metadata.""" - type: ExerciseType = Field(ExerciseType.modeling, const=True) + type: ExerciseType = Field(ExerciseType.modeling, Literal=True) example_solution: Optional[str] = Field(None, description="An example solution to the exercise.") diff --git a/athena/athena/athena/schemas/programming_exercise.py b/athena/athena/athena/schemas/programming_exercise.py index ac875b05..5d554236 100644 --- a/athena/athena/athena/schemas/programming_exercise.py +++ b/athena/athena/athena/schemas/programming_exercise.py @@ -5,12 +5,12 @@ from athena.helpers.programming.code_repository import get_repository_zip, get_repository from .exercise_type import ExerciseType from .exercise import Exercise - +from typing import Literal class ProgrammingExercise(Exercise): """A programming exercise that can be solved by students, enhanced with metadata.""" - type: ExerciseType = Field(ExerciseType.programming, const=True) + type: ExerciseType = Field(ExerciseType.programming, Literal=True) programming_language: str = Field(description="The programming language that is used for this exercise.", example="java") solution_repository_uri: AnyUrl = Field(description="URL to the solution git repository, which contains the " diff --git a/athena/athena/athena/schemas/schema.py b/athena/athena/athena/schemas/schema.py index 67e146ad..b0e7e6b7 100644 --- a/athena/athena/athena/schemas/schema.py +++ b/athena/athena/athena/schemas/schema.py @@ -32,4 +32,4 @@ def to_model(self): class Config: # Allow camelCase field names in the API (converted to snake_case) alias_generator = to_camel - allow_population_by_field_name = True \ No newline at end of file + populate_by_name = True \ No newline at end of file diff --git a/athena/athena/athena/schemas/submission.py b/athena/athena/athena/schemas/submission.py index f9e39c37..0bf684bd 100644 --- a/athena/athena/athena/schemas/submission.py +++ b/athena/athena/athena/schemas/submission.py @@ -12,4 +12,4 @@ class Submission(Schema, ABC): meta: dict = Field({}, example={}) class Config: - orm_mode = True + from_attributes = True diff --git a/athena/athena/athena/schemas/text_exercise.py b/athena/athena/athena/schemas/text_exercise.py index 6c836766..09ea6512 100644 --- a/athena/athena/athena/schemas/text_exercise.py +++ b/athena/athena/athena/schemas/text_exercise.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import Optional, Literal from pydantic import Field from .exercise_type import ExerciseType @@ -8,6 +8,6 @@ class TextExercise(Exercise): """A text exercise that can be solved by students, enhanced with metadata.""" - type: ExerciseType = Field(ExerciseType.text, const=True) + type: ExerciseType = Field(ExerciseType.text, Literal=True) example_solution: Optional[str] = Field(None, description="An example solution to the exercise.") diff --git a/athena/athena/poetry.lock b/athena/athena/poetry.lock index a9d17180..181221bc 100644 --- a/athena/athena/poetry.lock +++ b/athena/athena/poetry.lock @@ -262,39 +262,40 @@ files = [ [[package]] name = "httpcore" -version = "0.17.3" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "httpcore-0.17.3-py3-none-any.whl", hash = "sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87"}, - {file = "httpcore-0.17.3.tar.gz", hash = "sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] -anyio = ">=3.0,<5.0" certifi = "*" h11 = ">=0.13,<0.15" -sniffio = "==1.*" [package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.24.1" +version = "0.26.0" description = "The next generation HTTP client." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "httpx-0.24.1-py3-none-any.whl", hash = "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd"}, - {file = "httpx-0.24.1.tar.gz", hash = "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd"}, + {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"}, + {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"}, ] [package.dependencies] +anyio = "*" certifi = "*" -httpcore = ">=0.15.0,<0.18.0" +httpcore = "==1.*" idna = "*" sniffio = "*" @@ -1134,4 +1135,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "3.11.*" -content-hash = "0c115e830083d14aa96e0f88f102dfcac65ac31bc522fb8c3bc68337adbeaccc" +content-hash = "c12b8f645a94ce769948ada5c243b2bcbc2cf10b20c0323a30cb70d13eadec37" diff --git a/athena/athena/pyproject.toml b/athena/athena/pyproject.toml index 98d83e5d..d76ab52e 100644 --- a/athena/athena/pyproject.toml +++ b/athena/athena/pyproject.toml @@ -9,7 +9,7 @@ license = "MIT" python = "3.11.*" fastapi = "^0.109.1" uvicorn = "^0.23.0" -httpx = "^0.24.1" +httpx = "^0.26.0" gitpython = "^3.1.41" sqlalchemy = {extras = ["mypy"], version = "^2.0.21"} psycopg2 = "^2.9.9" diff --git a/athena/modules/text/module_text_llm/module_text_llm/__main__.py b/athena/modules/text/module_text_llm/module_text_llm/__main__.py index 0bfc6e41..647d8b7f 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/__main__.py +++ b/athena/modules/text/module_text_llm/module_text_llm/__main__.py @@ -11,7 +11,8 @@ from module_text_llm.evaluation import get_feedback_statistics, get_llm_statistics from module_text_llm.generate_evaluation import generate_evaluation from module_text_llm.approach_controller import generate_suggestions - +from module_text_llm.RandomMessage import write_random_message,query_messages,create_minimal_schema +from module_text_llm.in_context_learning.feedback_icl.store_feedback_icl import store_feedback_icl @submissions_consumer def receive_submissions(exercise: Exercise, submissions: List[Submission]): logger.info("receive_submissions: Received %d submissions for exercise %d", len(submissions), exercise.id) @@ -25,8 +26,10 @@ def select_submission(exercise: Exercise, submissions: List[Submission]) -> Subm @feedback_consumer def process_incoming_feedback(exercise: Exercise, submission: Submission, feedbacks: List[Feedback]): + logger.info("Will try to create Schema") logger.info("process_feedback: Received %d feedbacks for submission %d of exercise %d.", len(feedbacks), submission.id, exercise.id) - + store_feedback_icl(submission, exercise, feedbacks) + @feedback_provider async def suggest_feedback(exercise: Exercise, submission: Submission, is_graded: bool, module_config: Configuration) -> List[Feedback]: logger.info("suggest_feedback: %s suggestions for submission %d of exercise %d were requested, with approach: %s", diff --git a/athena/modules/text/module_text_llm/module_text_llm/config.py b/athena/modules/text/module_text_llm/module_text_llm/config.py index 7d904eae..c1b65d00 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/config.py +++ b/athena/modules/text/module_text_llm/module_text_llm/config.py @@ -1,3 +1,4 @@ +from module_text_llm.in_context_learning import InContextLearningConfig from module_text_llm.self_consistency import SelfConsistencyConfig from pydantic import BaseModel, Field from typing import Union @@ -7,7 +8,7 @@ from module_text_llm.basic_approach import BasicApproachConfig from module_text_llm.divide_and_conquer import DivideAndConquerConfig -ApproachConfigUnion = Union[BasicApproachConfig, ChainOfThoughtConfig, DivideAndConquerConfig, SelfConsistencyConfig] +ApproachConfigUnion = Union[BasicApproachConfig, ChainOfThoughtConfig, DivideAndConquerConfig, SelfConsistencyConfig, InContextLearningConfig] @config_schema_provider class Configuration(BaseModel): diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/__init__.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/__init__.py new file mode 100644 index 00000000..b3e6d6a0 --- /dev/null +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/__init__.py @@ -0,0 +1,13 @@ +from module_text_llm.approach_config import ApproachConfig +from pydantic import Field +from typing import Literal +from athena.text import Exercise, Submission +from module_text_llm.in_context_learning.generate_suggestions import generate_suggestions +from module_text_llm.in_context_learning.prompt_generate_suggestions import GenerateSuggestionsPrompt + +class InContextLearningConfig(ApproachConfig): + type: Literal['in_context_learning'] = 'in_context_learning' + generate_suggestions_prompt: GenerateSuggestionsPrompt = Field(default=GenerateSuggestionsPrompt()) + + async def generate_suggestions(self, exercise: Exercise, submission: Submission, config,*, debug: bool, is_graded: bool): + return await generate_suggestions(exercise, submission, config, debug, is_graded) \ No newline at end of file diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/agent.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/agent.py new file mode 100644 index 00000000..359504a3 --- /dev/null +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/agent.py @@ -0,0 +1,68 @@ +# from langchain_openai import ChatOpenAI +# from langchain_core.prompts import ChatPromptTemplate +# from langchain.agents import AgentExecutor, create_tool_calling_agent +# from pydantic import BaseModel, Field +# from langchain_core.tools import tool +# from module_text_llm.in_context_learning.feedback_icl.retrieve_rag_context_icl import retrieve_rag_context_icl +# from module_text_llm.in_context_learning.prompt_generate_suggestions import FeedbackModel +# from typing import List + +# # @tool +# # def retrieve_rag_context(submission_segment: str ,exercise_id: int) -> str: +# # """ +# # This method takes a segment from a submission and for a given exercise id, +# # returns feedback that has been given for similar texts. + +# # Args: +# # submission_segment: A segment of the submission. +# # exercise_id: The id of the exercise. + +# # Returns: +# # str: A formatted string of feedbacks which reference text similar to the submission_segment. +# # """ +# # return retrieve_rag_context_icl(submission_segment,exercise_id) + +# @tool +# class AssessmentModel(BaseModel): +# """Collection of feedbacks making up an assessment""" + +# feedbacks: List[FeedbackModel] = Field(description="Assessment feedbacks") + +# class AssessmentModelParse(BaseModel): +# """Collection of feedbacks making up an assessment""" + +# feedbacks: List[FeedbackModel] = Field(description="Assessment feedbacks") + +# class TutorAgent: +# def __init__(self,config): +# self.model = config.model.get_model() +# self.outputModel = ChatOpenAI(model="gpt-4o-mini") +# self.approach_config = None +# self.openai_tools = [retrieve_rag_context] +# self.setConfig(config) + + +# def setConfig(self,approach_config): +# self.approach_config = approach_config +# self.prompt = ChatPromptTemplate.from_messages( +# [ +# ("system", self.approach_config.generate_suggestions_prompt.system_message), +# ("human", "{submission}"), +# ("placeholder", "{agent_scratchpad}"), +# ]) + +# self.agent = create_tool_calling_agent(self.model, self.openai_tools , self.prompt) +# self.agent_executor = AgentExecutor(agent=self.agent, tools=self.openai_tools) +# self.config = {"configurable": {"session_id": "test-session"}} + +# def call_agent(self, prompt): +# """Calls the agent with a prompt and returns the response output.""" + +# response = self.agent_executor.invoke( +# input = prompt +# ) + +# res = self.model.with_structured_output(AssessmentModelParse).invoke(f"Format the following output {response}") +# return res + + \ No newline at end of file diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/docker-compose.yml b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/docker-compose.yml new file mode 100644 index 00000000..4448f410 --- /dev/null +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/docker-compose.yml @@ -0,0 +1,32 @@ +--- +services: + weaviate: + command: + - --host + - 0.0.0.0 + - --port + - '8080' + - --scheme + - http + image: cr.weaviate.io/semitechnologies/weaviate:1.30.0 + ports: + - 8080:8080 + - 50051:50051 + volumes: + - weaviate_data:/var/lib/weaviate + restart: on-failure:0 + environment: + CLIP_INFERENCE_API: 'http://multi2vec-clip:8080' + QUERY_DEFAULTS_LIMIT: 25 + AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true' + PERSISTENCE_DATA_PATH: '/var/lib/weaviate' + ENABLE_MODULES: 'multi2vec-clip' + ENABLE_API_BASED_MODULES: 'true' + CLUSTER_HOSTNAME: 'node1' + multi2vec-clip: + image: cr.weaviate.io/semitechnologies/multi2vec-clip:sentence-transformers-clip-ViT-B-32-multilingual-v1 + environment: + ENABLE_CUDA: '0' +volumes: + weaviate_data: +... diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/generate_embeddings.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/generate_embeddings.py new file mode 100644 index 00000000..681e8e95 --- /dev/null +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/generate_embeddings.py @@ -0,0 +1,7 @@ +from langchain_openai import OpenAIEmbeddings + +def embed_text(text): + embeddings = OpenAIEmbeddings(model="text-embedding-3-large") + query_result = embeddings.embed_query(text) + return query_result + # return np.array(query_result, dtype=np.float32) only relevant for numpy operations diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context_icl.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context_icl.py new file mode 100644 index 00000000..35091fca --- /dev/null +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context_icl.py @@ -0,0 +1,59 @@ +from athena.logger import logger +from module_text_llm.in_context_learning.feedback_icl.store_indices_icl import retrieve_embedding_index, retrieve_feedback +from module_text_llm.in_context_learning.feedback_icl.store_feedback_icl import query_embedding +from module_text_llm.in_context_learning.feedback_icl.generate_embeddings import embed_text + +def retrieve_rag_context_icl(submission_segment: str ,exercise_id: int) -> str: + """ + This method takes a segment from a submission and for a given exercise id, + returns feedback that has been given for similar texts. + + Args: + submission_segment: A segment of the submission. + exercise_id: The id of the exercise. + + Returns: + str: A formatted string of feedbacks which reference text similar to the submission_segment. + """ + # query_submission= embed_text(submission_segment) + + rag_context = [] + + rresult_objects = query_embedding(submission_segment,exercise_id) + print(rresult_objects) + return " " + # for result in rresult_objects: + # print("result",result) + # print(type(result)) + + # if list_of_indices is not None: + # for index in list_of_indices[0]: + # if index != -1: + # stored_feedback = retrieve_feedback(index,exercise_id) + # print("Stored feedback",stored_feedback) + # rag_context.append({"submission_chunk": submission_segment, "feedback": stored_feedback}) + # formatted_rag_context = format_rag_context(rag_context) + # else: + # formatted_rag_context = "There are no submission at the moment" + # return formatted_rag_context + +def format_rag_context(rag_context): + formatted_string = "" + + for context_item in rag_context: + submission_text = context_item["submission_chunk"] + feedback = context_item["feedback"] + if feedback is not None: + formatted_string += "**Tutor provided Feedback from previous submissions of this same exercise:**\n" + feedback["text_reference"] = get_reference(feedback, submission_text) + clean_feedback = {key: value for key, value in feedback.items() if key not in ["id","index_start","index_end","is_graded","meta"]} + + formatted_string += f"{clean_feedback}\n" + formatted_string += "\n" + "-"*40 + "\n" + + return formatted_string + +def get_reference(feedback, submission_text): + if (feedback["index_start"] is not None) and (feedback["index_end"] is not None): + return submission_text[feedback["index_start"]:feedback["index_end"]] + return submission_text diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback_icl.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback_icl.py new file mode 100644 index 00000000..bfffccbe --- /dev/null +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback_icl.py @@ -0,0 +1,101 @@ +import numpy as np +import os +from athena.text import Submission, Exercise, Feedback +from typing import List +from athena.logger import logger +from module_text_llm.in_context_learning.feedback_icl.generate_embeddings import embed_text +import weaviate +import weaviate.classes as wvc + + +def create_schema(client): + """ + Create a schema with two classes: Question and Answer. + Each class has properties for storing relevant information. + """ + + # Define the Question class + questions = client.collections.create( + name="Feedback", + vectorizer_config=wvc.config.Configure.Vectorizer.none(), + properties=[ + wvc.config.Property(name="exercise_id", data_type=wvc.config.DataType.NUMBER), + wvc.config.Property(name="submission_id", data_type=wvc.config.DataType.NUMBER), + wvc.config.Property(name="title", data_type=wvc.config.DataType.TEXT), + wvc.config.Property(name="description", data_type=wvc.config.DataType.TEXT), + wvc.config.Property(name="credits", data_type=wvc.config.DataType.NUMBER), + wvc.config.Property(name="grading_id", data_type=wvc.config.DataType.UUID), + ] + ) + + print("Schema ICL created.") + print(questions.config.get(simple=False)) + +def store_feedback_icl(submission: Submission, exercise: Exercise, feedbacks: List[Feedback]): + client = weaviate.connect_to_local() + try: + create_schema(client) + finally: + logger.info("Storing feedback for submission %d of exercise %d.", submission.id, exercise.id) + + for feedback in feedbacks: + print("doing feedback") + chunk = get_reference(feedback, submission.text) + embedding = embed_text(chunk) + store_feedback(embedding, exercise.id, submission.id, feedback, client) + # save_embedding(embedding, exercise.id) + # store_embedding_index(exercise.id, submission.id, feedback) + client.close() +def store_feedback(embedding, exercise_id, submission_id, feedback, client): + """ + Store feedback in the Weaviate database. + """ + print("storing feedback") + questions = client.collections.get("Feedback") + uuid = questions.data.insert( + properties={ + "exercise_id": exercise_id, + "submission_id": submission_id, + "title": feedback.title, + "description": feedback.description, + "credits": feedback.credits, + "grading_id": feedback.structured_grading_instruction_id + }, + vector=embedding, + ) + print(uuid) + print("Feedback stored successfully.") + return uuid + + +# Here is the usage of the function: +# list_of_indices = query_embedding(query_submission,exercise_id) +#TODO implement a filter for the exercise id. Use the certainity limit to filter the results. +def query_embedding (query,exercise_id,results_limit=1, threshold=0.5): + logger.info("Querying") + client = weaviate.connect_to_local() + feedbacks = client.collections.get("Feedback") + embedded_query = embed_text(query) + # print("embedded query",embedded_query) + + results = feedbacks.query.near_vector( + near_vector=embedded_query, + limit = results_limit, + return_metadata=wvc.query.MetadataQuery(certainty=True) + ) + + print(results) + client.close() + return results + # return "test" + +def get_reference(feedback, submission_text): + if (feedback.index_start is not None) and (feedback.index_end is not None): + return submission_text[feedback.index_start:feedback.index_end ] + return submission_text + +def check_if_embedding_exists(exercise_id): + """ + Check if the embedding index file exists for the given exercise ID. + """ + return True \ No newline at end of file diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_indices_icl.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_indices_icl.py new file mode 100644 index 00000000..a2d5eb7a --- /dev/null +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_indices_icl.py @@ -0,0 +1,47 @@ +import os +import json + +def load_indices(index_file): + """ Load the indices from the file or return an empty dictionary if the file does not exist. """ + if os.path.exists(index_file): + with open(index_file, 'r', encoding="utf-8") as f: + return json.load(f) + else: + return {} + +def store_embedding_index(exercise_id, submission_id,feedback): + """ Store a new submission and exercise ID with an auto-incrementing index. """ + index_file = f"indices_{exercise_id}.json" + indices = load_indices(index_file) + next_index = len(indices) + print(feedback) + indices[next_index] = { + "exercise_id": exercise_id, + "submission_id": submission_id, + "feedback": feedback.dict() + } + + with open(index_file, 'w', encoding="utf-8") as f: + json.dump(indices, f, indent=4) + + print(f"Stored new entry: Exercise ID {exercise_id}, Submission ID {submission_id} at index {next_index}") + +def retrieve_embedding_index(index,exercise_id): + index_file = f"indices_{exercise_id}.json" + index = str(index) + indices = load_indices(index_file) + + if index in indices: + return indices[index]["exercise_id"], indices[index]["submission_id"] + + return None, None + +def retrieve_feedback(index,exercise_id): + index_file = f"indices_{exercise_id}.json" + index = str(index) + indices = load_indices(index_file) + + if index in indices: + return indices[index]["feedback"] + + return None \ No newline at end of file diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py new file mode 100644 index 00000000..d6e39d56 --- /dev/null +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py @@ -0,0 +1,164 @@ +from typing import List +from module_text_llm.approach_config import ApproachConfig +from athena import emit_meta +from athena.text import Exercise, Submission, Feedback +from athena.logger import logger +from llm_core.utils.llm_utils import ( + get_chat_prompt_with_formatting_instructions, + check_prompt_length_and_omit_features_if_necessary, + num_tokens_from_prompt, +) +from langchain_community.chat_models import ChatOllama # type: ignore + +from llm_core.utils.predict_and_parse import predict_and_parse +from module_text_llm.helpers.utils import add_sentence_numbers, get_index_range_from_line_range, format_grading_instructions +from module_text_llm.in_context_learning.prompt_generate_suggestions import AssessmentModel +# from module_text_llm.in_context_learning.agent import TutorAgent +from module_text_llm.in_context_learning.ollama_prompt import system_message_segment, human_message_segment, Segmentation, system_message, human_message + +from module_text_llm.in_context_learning.feedback_icl.store_feedback_icl import check_if_embedding_exists +from module_text_llm.in_context_learning.feedback_icl.retrieve_rag_context_icl import retrieve_rag_context_icl + + +async def generate_suggestions(exercise: Exercise, submission: Submission, config:ApproachConfig, debug: bool, is_graded :bool) -> List[Feedback]: + model = config.model.get_model() # type: ignore[attr-defined] + isOllama = isinstance(model, ChatOllama) + + formatted_rag_context = "" + prompt_input = { + "max_points": exercise.max_points, + "bonus_points": exercise.bonus_points, + "grading_instructions": format_grading_instructions(exercise.grading_instructions, exercise.grading_criteria), + "problem_statement": exercise.problem_statement or "No problem statement.", + "example_solution": exercise.example_solution, + "rag_context": formatted_rag_context, + "submission": add_sentence_numbers(submission.text), + "exercise_id": exercise.id, + } + + chat_prompt = get_chat_prompt_with_formatting_instructions( + model=model, + system_message=config.generate_suggestions_prompt.system_message, + human_message=config.generate_suggestions_prompt.human_message, + pydantic_object=AssessmentModel + ) + + # Check if the prompt is too long and omit features if necessary (in order of importance) + omittable_features = ["example_solution", "problem_statement", "grading_instructions"] + prompt_input, should_run = check_prompt_length_and_omit_features_if_necessary( + prompt=chat_prompt, + prompt_input= prompt_input, + max_input_tokens=config.max_input_tokens+7000, + omittable_features=omittable_features, + debug=debug + ) + + # Skip if the prompt is too long + if not should_run: + logger.warning("Input too long. Skipping.") + if debug: + emit_meta("prompt", chat_prompt.format(**prompt_input)) + emit_meta("error", f"Input too long {num_tokens_from_prompt(chat_prompt, prompt_input)} > {config.max_input_tokens}") + return [] + + if (isOllama): + embeddings_exist = check_if_embedding_exists(exercise.id) + + if embeddings_exist: + segmentation_prompt = get_chat_prompt_with_formatting_instructions( + model=model, + system_message=system_message_segment, + human_message=human_message_segment, + pydantic_object=Segmentation + ) + segmentation_prompt_input = { + "grading_instructions": format_grading_instructions(exercise.grading_instructions, exercise.grading_criteria), + "submission": submission.text, + "problem_statement": exercise.problem_statement or "No problem statement.", + } + chain = segmentation_prompt | model + segments = chain.invoke( segmentation_prompt_input) + + for segment in segments: + formatted_rag_context += retrieve_rag_context_icl(segment[0],exercise.id) + prompt_input["rag_context"] = formatted_rag_context + else: + prompt_input["rag_context"] = "There are no submission at the moment" + + result = await predict_and_parse( + model=model, + chat_prompt=chat_prompt, + prompt_input=prompt_input, + pydantic_object=AssessmentModel, + tags=[ + f"exercise-{exercise.id}", + f"submission-{submission.id}", + ], + ) + else : + embeddings_exist = check_if_embedding_exists(exercise.id) + + if embeddings_exist: + segmentation_prompt = get_chat_prompt_with_formatting_instructions( + model=model, + system_message=system_message_segment, + human_message=human_message_segment, + pydantic_object=Segmentation + ) + segmentation_prompt_input = { + "grading_instructions": format_grading_instructions(exercise.grading_instructions, exercise.grading_criteria), + "submission": submission.text, + "problem_statement": exercise.problem_statement or "No problem statement.", + } + chain = segmentation_prompt | model + segments = chain.invoke( segmentation_prompt_input) + # print("segments ",segments) + for segment in segments: + formatted_rag_context += retrieve_rag_context_icl(segment[0],exercise.id) + prompt_input["rag_context"] = formatted_rag_context + else: + prompt_input["rag_context"] = "There are no submission at the moment" + + result = await predict_and_parse( + model=model, + chat_prompt=chat_prompt, + prompt_input=prompt_input, + pydantic_object=AssessmentModel, + use_function_calling=True, + tags=[ + f"exercise-{exercise.id}", + f"submission-{submission.id}", + ], + ) + if debug: + emit_meta("generate_suggestions", { + "prompt": chat_prompt.format(**prompt_input), + "result": result.dict() if result is not None else None + }) + + if result is None: + return [] + + grading_instruction_ids = set( + grading_instruction.id + for criterion in exercise.grading_criteria or [] + for grading_instruction in criterion.structured_grading_instructions + ) + feedbacks = [] + for feedback in result.feedbacks: + index_start, index_end = get_index_range_from_line_range(feedback.line_start, feedback.line_end, submission.text) + grading_instruction_id = feedback.grading_instruction_id if feedback.grading_instruction_id in grading_instruction_ids else None + feedbacks.append(Feedback( + exercise_id=exercise.id, + submission_id=submission.id, + title=feedback.title, + description=feedback.description, + index_start=index_start, + index_end=index_end, + credits=feedback.credits, + is_graded=is_graded, + structured_grading_instruction_id=grading_instruction_id, + meta={} + )) + + return feedbacks diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/ollama_prompt.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/ollama_prompt.py new file mode 100644 index 00000000..9641a380 --- /dev/null +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/ollama_prompt.py @@ -0,0 +1,82 @@ +from pydantic import Field, BaseModel +from typing import List, Optional + +class Segment(BaseModel): + segment: str = Field(description="Segment of the text") + title: str = Field(description="Title of the criterion that this text adresses") + + +class Segmentation(BaseModel): + segments: List[Segment] = Field(description="List of segments") + + +system_message_segment = """ +You are an AI asisstnat for text assessment at a prestigious university. +You are tasked with segmenting the following text into parts that address different parts of the problem statement. +You can use the criteria from provided grading instructions to help in regards to the semantic segmentation of the text. +# Problem Statement +{problem_statement} + +# Grading Instructions +{grading_instructions} + +Return a valid json response, which contains a list. +Each element of the list should be a Segment which contains the segment text and the criterion title which it adresses. +Keep in mind that not all criterion might be adressed in the text. +""" + +human_message_segment = """ +# Submission +# {submission} +""" +system_message = """You are an AI tutor for text assessment at a prestigious university. + +# Task +Create graded feedback suggestions for a student's text submission that a human tutor would accept. Meaning, the feedback you provide should be applicable to the submission with little to no modification. + +# Problem statement +{problem_statement} + +# Example solution +{example_solution} + +# Grading instructions +{grading_instructions} +Max points: {max_points}, bonus points: {bonus_points} +The exercise id is: {exercise_id} +-------------------------- + +You have access to the following tutor feedback on similar texts: +{rag_context} +Respond in json. +""" + +human_message = """Student's submission to grade (with sentence numbers : ): + +{submission} +""" + +# Input Prompt +class GenerateSuggestionsPrompt(BaseModel): + """Features available: **{problem_statement}**, **{example_solution}**, **{grading_instructions}**, **{max_points}**, **{bonus_points}**, **{submission}** + +_Note: **{problem_statement}**, **{example_solution}**, or **{grading_instructions}** might be omitted if the input is too long._""" + system_message: str = Field(default=system_message, + description="Message for priming AI behavior and instructing it what to do.") + human_message: str = Field(default=human_message, + description="Message from a human. The input on which the AI is supposed to act.") + +# Output Object +class FeedbackModel(BaseModel): + title: str = Field(description="Very short title, i.e. feedback category or similar", example="Logic Error") + description: str = Field(description="Feedback description") + line_start: Optional[int] = Field(description="Referenced line number start, or empty if unreferenced") + line_end: Optional[int] = Field(description="Referenced line number end, or empty if unreferenced") + credits: float = Field(0.0, description="Number of points received/deducted") + grading_instruction_id: Optional[int] = Field( + description="ID of the grading instruction that was used to generate this feedback, or empty if no grading instruction was used" + ) + +class AssessmentModel(BaseModel): + """Collection of feedbacks making up an assessment""" + feedbacks: List[FeedbackModel] = Field(description="Assessment feedbacks") \ No newline at end of file diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/prompt_generate_suggestions.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/prompt_generate_suggestions.py new file mode 100644 index 00000000..ebae5378 --- /dev/null +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/prompt_generate_suggestions.py @@ -0,0 +1,54 @@ +from pydantic import Field, BaseModel +from typing import List, Optional + +system_message = """You are an AI tutor for text assessment at a prestigious university. + +# Task +Create graded feedback suggestions for a student's text submission that a human tutor would accept. Meaning, the feedback you provide should be applicable to the submission with little to no modification. + +# Problem statement +{problem_statement} + +# Example solution +{example_solution} + +# Grading instructions +{grading_instructions} +Max points: {max_points}, bonus points: {bonus_points} +The exercise id is: {exercise_id} +-------------------------- +You have access to a tool which gives you example feedback from professional tutors. You can use these to think about what kind of feedback would be appropriate for the student's submission. +You do not need to write the exact same feedback as the examples, but you can use them as inspiration. +When providing line references, they should never overlap. +Your response must include a title, description, credits, line_start and line end for each feedback and the grading isntruction id. Line start and end can be left out if it does not apply to a specific part of the submission but its a general feedback. +""" + +human_message = """Student's submission to grade (with sentence numbers : ): + +{submission} +""" + +# Input Prompt +class GenerateSuggestionsPrompt(BaseModel): + """Features available: **{problem_statement}**, **{example_solution}**, **{grading_instructions}**, **{max_points}**, **{bonus_points}**, **{submission}** + +_Note: **{problem_statement}**, **{example_solution}**, or **{grading_instructions}** might be omitted if the input is too long._""" + system_message: str = Field(default=system_message, + description="Message for priming AI behavior and instructing it what to do.") + human_message: str = Field(default=human_message, + description="Message from a human. The input on which the AI is supposed to act.") + +# Output Object +class FeedbackModel(BaseModel): + title: str = Field(description="Very short title, i.e. feedback category or similar", example="Logic Error") + description: str = Field(description="Feedback description") + line_start: Optional[int] = Field(description="Referenced line number start, or empty if unreferenced") + line_end: Optional[int] = Field(description="Referenced line number end, or empty if unreferenced") + credits: float = Field(0.0, description="Number of points received/deducted") + grading_instruction_id: Optional[int] = Field( + description="ID of the grading instruction that was used to generate this feedback, or empty if no grading instruction was used" + ) + +class AssessmentModel(BaseModel): + """Collection of feedbacks making up an assessment""" + feedbacks: List[FeedbackModel] = Field(description="Assessment feedbacks") \ No newline at end of file diff --git a/athena/modules/text/module_text_llm/poetry.lock b/athena/modules/text/module_text_llm/poetry.lock index 9f12b92d..e6911d50 100644 --- a/athena/modules/text/module_text_llm/poetry.lock +++ b/athena/modules/text/module_text_llm/poetry.lock @@ -122,6 +122,17 @@ files = [ [package.dependencies] frozenlist = ">=1.1.0" +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + [[package]] name = "anyio" version = "4.7.0" @@ -166,7 +177,7 @@ develop = true [package.dependencies] fastapi = "^0.109.1" gitpython = "^3.1.41" -httpx = "^0.24.1" +httpx = "^0.26.0" psycopg2 = "^2.9.9" sqlalchemy = {version = "^2.0.21", extras = ["mypy"]} uvicorn = "^0.23.0" @@ -194,6 +205,20 @@ docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphi tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] +[[package]] +name = "authlib" +version = "1.3.1" +description = "The ultimate Python library in building OAuth and OpenID Connect servers and clients." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Authlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:d35800b973099bbadc49b42b256ecb80041ad56b7fe1216a362c7943c088f377"}, + {file = "authlib-1.3.1.tar.gz", hash = "sha256:7ae843f03c06c5c0debd63c9db91f9fda64fa62a42a77419fa15fbb7e7a58917"}, +] + +[package.dependencies] +cryptography = "*" + [[package]] name = "certifi" version = "2024.12.14" @@ -205,6 +230,85 @@ files = [ {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] +[[package]] +name = "cffi" +version = "1.17.1" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, + {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, + {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, + {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, + {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, +] + +[package.dependencies] +pycparser = "*" + [[package]] name = "charset-normalizer" version = "3.4.1" @@ -331,6 +435,63 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "cryptography" +version = "44.0.2" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = "!=3.9.0,!=3.9.1,>=3.7" +files = [ + {file = "cryptography-44.0.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308"}, + {file = "cryptography-44.0.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688"}, + {file = "cryptography-44.0.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7"}, + {file = "cryptography-44.0.2-cp37-abi3-win32.whl", hash = "sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79"}, + {file = "cryptography-44.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa"}, + {file = "cryptography-44.0.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23"}, + {file = "cryptography-44.0.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922"}, + {file = "cryptography-44.0.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4"}, + {file = "cryptography-44.0.2-cp39-abi3-win32.whl", hash = "sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5"}, + {file = "cryptography-44.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:af4ff3e388f2fa7bff9f7f2b31b87d5651c45731d3e8cfa0944be43dff5cfbdb"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:0529b1d5a0105dd3731fa65680b45ce49da4d8115ea76e9da77a875396727b41"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:7ca25849404be2f8e4b3c59483d9d3c51298a22c1c61a0e84415104dacaf5562"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:268e4e9b177c76d569e8a145a6939eca9a5fec658c932348598818acf31ae9a5"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:9eb9d22b0a5d8fd9925a7764a054dca914000607dff201a24c791ff5c799e1fa"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2bf7bf75f7df9715f810d1b038870309342bff3069c5bd8c6b96128cb158668d"}, + {file = "cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:909c97ab43a9c0c0b0ada7a1281430e4e5ec0458e6d9244c0e821bbf152f061d"}, + {file = "cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:96e7a5e9d6e71f9f4fca8eebfd603f8e86c5225bb18eb621b2c1e50b290a9471"}, + {file = "cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d1b3031093a366ac767b3feb8bcddb596671b3aaff82d4050f984da0c248b615"}, + {file = "cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:04abd71114848aa25edb28e225ab5f268096f44cf0127f3d36975bdf1bdf3390"}, + {file = "cryptography-44.0.2.tar.gz", hash = "sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0"}, +] + +[package.dependencies] +cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0)"] +docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] +nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2)"] +pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] +sdist = ["build (>=1.0.0)"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi (>=2024)", "cryptography-vectors (==44.0.2)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] +test-randomorder = ["pytest-randomly"] + [[package]] name = "dataclasses-json" version = "0.6.7" @@ -650,6 +811,149 @@ files = [ docs = ["Sphinx", "furo"] test = ["objgraph", "psutil"] +[[package]] +name = "grpcio" +version = "1.71.0" +description = "HTTP/2-based RPC framework" +optional = false +python-versions = ">=3.9" +files = [ + {file = "grpcio-1.71.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:c200cb6f2393468142eb50ab19613229dcc7829b5ccee8b658a36005f6669fdd"}, + {file = "grpcio-1.71.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:b2266862c5ad664a380fbbcdbdb8289d71464c42a8c29053820ee78ba0119e5d"}, + {file = "grpcio-1.71.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:0ab8b2864396663a5b0b0d6d79495657ae85fa37dcb6498a2669d067c65c11ea"}, + {file = "grpcio-1.71.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c30f393f9d5ff00a71bb56de4aa75b8fe91b161aeb61d39528db6b768d7eac69"}, + {file = "grpcio-1.71.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f250ff44843d9a0615e350c77f890082102a0318d66a99540f54769c8766ab73"}, + {file = "grpcio-1.71.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e6d8de076528f7c43a2f576bc311799f89d795aa6c9b637377cc2b1616473804"}, + {file = "grpcio-1.71.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9b91879d6da1605811ebc60d21ab6a7e4bae6c35f6b63a061d61eb818c8168f6"}, + {file = "grpcio-1.71.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f71574afdf944e6652203cd1badcda195b2a27d9c83e6d88dc1ce3cfb73b31a5"}, + {file = "grpcio-1.71.0-cp310-cp310-win32.whl", hash = "sha256:8997d6785e93308f277884ee6899ba63baafa0dfb4729748200fcc537858a509"}, + {file = "grpcio-1.71.0-cp310-cp310-win_amd64.whl", hash = "sha256:7d6ac9481d9d0d129224f6d5934d5832c4b1cddb96b59e7eba8416868909786a"}, + {file = "grpcio-1.71.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:d6aa986318c36508dc1d5001a3ff169a15b99b9f96ef5e98e13522c506b37eef"}, + {file = "grpcio-1.71.0-cp311-cp311-macosx_10_14_universal2.whl", hash = "sha256:d2c170247315f2d7e5798a22358e982ad6eeb68fa20cf7a820bb74c11f0736e7"}, + {file = "grpcio-1.71.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:e6f83a583ed0a5b08c5bc7a3fe860bb3c2eac1f03f1f63e0bc2091325605d2b7"}, + {file = "grpcio-1.71.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4be74ddeeb92cc87190e0e376dbc8fc7736dbb6d3d454f2fa1f5be1dee26b9d7"}, + {file = "grpcio-1.71.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dd0dfbe4d5eb1fcfec9490ca13f82b089a309dc3678e2edabc144051270a66e"}, + {file = "grpcio-1.71.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a2242d6950dc892afdf9e951ed7ff89473aaf744b7d5727ad56bdaace363722b"}, + {file = "grpcio-1.71.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0fa05ee31a20456b13ae49ad2e5d585265f71dd19fbd9ef983c28f926d45d0a7"}, + {file = "grpcio-1.71.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3d081e859fb1ebe176de33fc3adb26c7d46b8812f906042705346b314bde32c3"}, + {file = "grpcio-1.71.0-cp311-cp311-win32.whl", hash = "sha256:d6de81c9c00c8a23047136b11794b3584cdc1460ed7cbc10eada50614baa1444"}, + {file = "grpcio-1.71.0-cp311-cp311-win_amd64.whl", hash = "sha256:24e867651fc67717b6f896d5f0cac0ec863a8b5fb7d6441c2ab428f52c651c6b"}, + {file = "grpcio-1.71.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:0ff35c8d807c1c7531d3002be03221ff9ae15712b53ab46e2a0b4bb271f38537"}, + {file = "grpcio-1.71.0-cp312-cp312-macosx_10_14_universal2.whl", hash = "sha256:b78a99cd1ece4be92ab7c07765a0b038194ded2e0a26fd654591ee136088d8d7"}, + {file = "grpcio-1.71.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:dc1a1231ed23caac1de9f943d031f1bc38d0f69d2a3b243ea0d664fc1fbd7fec"}, + {file = "grpcio-1.71.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e6beeea5566092c5e3c4896c6d1d307fb46b1d4bdf3e70c8340b190a69198594"}, + {file = "grpcio-1.71.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5170929109450a2c031cfe87d6716f2fae39695ad5335d9106ae88cc32dc84c"}, + {file = "grpcio-1.71.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5b08d03ace7aca7b2fadd4baf291139b4a5f058805a8327bfe9aece7253b6d67"}, + {file = "grpcio-1.71.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f903017db76bf9cc2b2d8bdd37bf04b505bbccad6be8a81e1542206875d0e9db"}, + {file = "grpcio-1.71.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:469f42a0b410883185eab4689060a20488a1a0a00f8bbb3cbc1061197b4c5a79"}, + {file = "grpcio-1.71.0-cp312-cp312-win32.whl", hash = "sha256:ad9f30838550695b5eb302add33f21f7301b882937460dd24f24b3cc5a95067a"}, + {file = "grpcio-1.71.0-cp312-cp312-win_amd64.whl", hash = "sha256:652350609332de6dac4ece254e5d7e1ff834e203d6afb769601f286886f6f3a8"}, + {file = "grpcio-1.71.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:cebc1b34ba40a312ab480ccdb396ff3c529377a2fce72c45a741f7215bfe8379"}, + {file = "grpcio-1.71.0-cp313-cp313-macosx_10_14_universal2.whl", hash = "sha256:85da336e3649a3d2171e82f696b5cad2c6231fdd5bad52616476235681bee5b3"}, + {file = "grpcio-1.71.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:f9a412f55bb6e8f3bb000e020dbc1e709627dcb3a56f6431fa7076b4c1aab0db"}, + {file = "grpcio-1.71.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47be9584729534660416f6d2a3108aaeac1122f6b5bdbf9fd823e11fe6fbaa29"}, + {file = "grpcio-1.71.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c9c80ac6091c916db81131d50926a93ab162a7e97e4428ffc186b6e80d6dda4"}, + {file = "grpcio-1.71.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:789d5e2a3a15419374b7b45cd680b1e83bbc1e52b9086e49308e2c0b5bbae6e3"}, + {file = "grpcio-1.71.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:1be857615e26a86d7363e8a163fade914595c81fec962b3d514a4b1e8760467b"}, + {file = "grpcio-1.71.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:a76d39b5fafd79ed604c4be0a869ec3581a172a707e2a8d7a4858cb05a5a7637"}, + {file = "grpcio-1.71.0-cp313-cp313-win32.whl", hash = "sha256:74258dce215cb1995083daa17b379a1a5a87d275387b7ffe137f1d5131e2cfbb"}, + {file = "grpcio-1.71.0-cp313-cp313-win_amd64.whl", hash = "sha256:22c3bc8d488c039a199f7a003a38cb7635db6656fa96437a8accde8322ce2366"}, + {file = "grpcio-1.71.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:c6a0a28450c16809f94e0b5bfe52cabff63e7e4b97b44123ebf77f448534d07d"}, + {file = "grpcio-1.71.0-cp39-cp39-macosx_10_14_universal2.whl", hash = "sha256:a371e6b6a5379d3692cc4ea1cb92754d2a47bdddeee755d3203d1f84ae08e03e"}, + {file = "grpcio-1.71.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:39983a9245d37394fd59de71e88c4b295eb510a3555e0a847d9965088cdbd033"}, + {file = "grpcio-1.71.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9182e0063112e55e74ee7584769ec5a0b4f18252c35787f48738627e23a62b97"}, + {file = "grpcio-1.71.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693bc706c031aeb848849b9d1c6b63ae6bcc64057984bb91a542332b75aa4c3d"}, + {file = "grpcio-1.71.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:20e8f653abd5ec606be69540f57289274c9ca503ed38388481e98fa396ed0b41"}, + {file = "grpcio-1.71.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8700a2a57771cc43ea295296330daaddc0d93c088f0a35cc969292b6db959bf3"}, + {file = "grpcio-1.71.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d35a95f05a8a2cbe8e02be137740138b3b2ea5f80bd004444e4f9a1ffc511e32"}, + {file = "grpcio-1.71.0-cp39-cp39-win32.whl", hash = "sha256:f9c30c464cb2ddfbc2ddf9400287701270fdc0f14be5f08a1e3939f1e749b455"}, + {file = "grpcio-1.71.0-cp39-cp39-win_amd64.whl", hash = "sha256:63e41b91032f298b3e973b3fa4093cbbc620c875e2da7b93e249d4728b54559a"}, + {file = "grpcio-1.71.0.tar.gz", hash = "sha256:2b85f7820475ad3edec209d3d89a7909ada16caab05d3f2e08a7e8ae3200a55c"}, +] + +[package.extras] +protobuf = ["grpcio-tools (>=1.71.0)"] + +[[package]] +name = "grpcio-health-checking" +version = "1.71.0" +description = "Standard Health Checking Service for gRPC" +optional = false +python-versions = ">=3.9" +files = [ + {file = "grpcio_health_checking-1.71.0-py3-none-any.whl", hash = "sha256:b7d9b7a7606ab4cd02d23bd1d3943843f784ffc987c9bfec14c9d058d9e279db"}, + {file = "grpcio_health_checking-1.71.0.tar.gz", hash = "sha256:ff9bd55beb97ce3322fda2ae58781c9d6c6fcca6a35ca3b712975d9f75dd30af"}, +] + +[package.dependencies] +grpcio = ">=1.71.0" +protobuf = ">=5.26.1,<6.0dev" + +[[package]] +name = "grpcio-tools" +version = "1.71.0" +description = "Protobuf code generator for gRPC" +optional = false +python-versions = ">=3.9" +files = [ + {file = "grpcio_tools-1.71.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:f4ad7f0d756546902597053d70b3af2606fbd70d7972876cd75c1e241d22ae00"}, + {file = "grpcio_tools-1.71.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:64bdb291df61cf570b5256777ad5fe2b1db6d67bc46e55dc56a0a862722ae329"}, + {file = "grpcio_tools-1.71.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:8dd9795e982d77a4b496f7278b943c2563d9afde2069cdee78c111a40cc4d675"}, + {file = "grpcio_tools-1.71.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1b5860c41a36b26fec4f52998f1a451d0525a5c9a4fb06b6ea3e9211abdb925"}, + {file = "grpcio_tools-1.71.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3059c14035e5dc03d462f261e5900b9a077fd1a36976c3865b8507474520bad4"}, + {file = "grpcio_tools-1.71.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f360981b215b1d5aff9235b37e7e1826246e35bbac32a53e41d4e990a37b8f4c"}, + {file = "grpcio_tools-1.71.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bfe3888c3bbe16a5aa39409bc38744a31c0c3d2daa2b0095978c56e106c85b42"}, + {file = "grpcio_tools-1.71.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:145985c0bf12131f0a1503e65763e0f060473f7f3928ed1ff3fb0e8aad5bc8ac"}, + {file = "grpcio_tools-1.71.0-cp310-cp310-win32.whl", hash = "sha256:82c430edd939bb863550ee0fecf067d78feff828908a1b529bbe33cc57f2419c"}, + {file = "grpcio_tools-1.71.0-cp310-cp310-win_amd64.whl", hash = "sha256:83e90724e3f02415c628e4ead1d6ffe063820aaaa078d9a39176793df958cd5a"}, + {file = "grpcio_tools-1.71.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:1f19b16b49afa5d21473f49c0966dd430c88d089cd52ac02404d8cef67134efb"}, + {file = "grpcio_tools-1.71.0-cp311-cp311-macosx_10_14_universal2.whl", hash = "sha256:459c8f5e00e390aecd5b89de67deb3ec7188a274bc6cb50e43cef35ab3a3f45d"}, + {file = "grpcio_tools-1.71.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:edab7e6518de01196be37f96cb1e138c3819986bf5e2a6c9e1519b4d716b2f5a"}, + {file = "grpcio_tools-1.71.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8b93b9f6adc7491d4c10144c0643409db298e5e63c997106a804f6f0248dbaf4"}, + {file = "grpcio_tools-1.71.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ae5f2efa9e644c10bf1021600bfc099dfbd8e02b184d2d25dc31fcd6c2bc59e"}, + {file = "grpcio_tools-1.71.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:65aa082f4435571d65d5ce07fc444f23c3eff4f3e34abef599ef8c9e1f6f360f"}, + {file = "grpcio_tools-1.71.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1331e726e08b7bdcbf2075fcf4b47dff07842b04845e6e220a08a4663e232d7f"}, + {file = "grpcio_tools-1.71.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6693a7d3ba138b0e693b3d1f687cdd9db9e68976c3fa2b951c17a072fea8b583"}, + {file = "grpcio_tools-1.71.0-cp311-cp311-win32.whl", hash = "sha256:6d11ed3ff7b6023b5c72a8654975324bb98c1092426ba5b481af406ff559df00"}, + {file = "grpcio_tools-1.71.0-cp311-cp311-win_amd64.whl", hash = "sha256:072b2a5805ac97e4623b3aa8f7818275f3fb087f4aa131b0fce00471065f6eaa"}, + {file = "grpcio_tools-1.71.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:61c0409d5bdac57a7bd0ce0ab01c1c916728fe4c8a03d77a25135ad481eb505c"}, + {file = "grpcio_tools-1.71.0-cp312-cp312-macosx_10_14_universal2.whl", hash = "sha256:28784f39921d061d2164a9dcda5164a69d07bf29f91f0ea50b505958292312c9"}, + {file = "grpcio_tools-1.71.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:192808cf553cedca73f0479cc61d5684ad61f24db7a5f3c4dfe1500342425866"}, + {file = "grpcio_tools-1.71.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:989ee9da61098230d3d4c8f8f8e27c2de796f1ff21b1c90110e636d9acd9432b"}, + {file = "grpcio_tools-1.71.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:541a756276c8a55dec991f6c0106ae20c8c8f5ce8d0bdbfcb01e2338d1a8192b"}, + {file = "grpcio_tools-1.71.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:870c0097700d13c403e5517cb7750ab5b4a791ce3e71791c411a38c5468b64bd"}, + {file = "grpcio_tools-1.71.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:abd57f615e88bf93c3c6fd31f923106e3beb12f8cd2df95b0d256fa07a7a0a57"}, + {file = "grpcio_tools-1.71.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:753270e2d06d37e6d7af8967d1d059ec635ad215882041a36294f4e2fd502b2e"}, + {file = "grpcio_tools-1.71.0-cp312-cp312-win32.whl", hash = "sha256:0e647794bd7138b8c215e86277a9711a95cf6a03ff6f9e555d54fdf7378b9f9d"}, + {file = "grpcio_tools-1.71.0-cp312-cp312-win_amd64.whl", hash = "sha256:48debc879570972d28bfe98e4970eff25bb26da3f383e0e49829b2d2cd35ad87"}, + {file = "grpcio_tools-1.71.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:9a78d07d6c301a25ef5ede962920a522556a1dfee1ccc05795994ceb867f766c"}, + {file = "grpcio_tools-1.71.0-cp313-cp313-macosx_10_14_universal2.whl", hash = "sha256:580ac88141c9815557e63c9c04f5b1cdb19b4db8d0cb792b573354bde1ee8b12"}, + {file = "grpcio_tools-1.71.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:f7c678e68ece0ae908ecae1c4314a0c2c7f83e26e281738b9609860cc2c82d96"}, + {file = "grpcio_tools-1.71.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56ecd6cc89b5e5eed1de5eb9cafce86c9c9043ee3840888cc464d16200290b53"}, + {file = "grpcio_tools-1.71.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e52a041afc20ab2431d756b6295d727bd7adee813b21b06a3483f4a7a15ea15f"}, + {file = "grpcio_tools-1.71.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:2a1712f12102b60c8d92779b89d0504e0d6f3a59f2b933e5622b8583f5c02992"}, + {file = "grpcio_tools-1.71.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:41878cb7a75477e62fdd45e7e9155b3af1b7a5332844021e2511deaf99ac9e6c"}, + {file = "grpcio_tools-1.71.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:682e958b476049ccc14c71bedf3f979bced01f6e0c04852efc5887841a32ad6b"}, + {file = "grpcio_tools-1.71.0-cp313-cp313-win32.whl", hash = "sha256:0ccfb837152b7b858b9f26bb110b3ae8c46675d56130f6c2f03605c4f129be13"}, + {file = "grpcio_tools-1.71.0-cp313-cp313-win_amd64.whl", hash = "sha256:ffff9bc5eacb34dd26b487194f7d44a3e64e752fc2cf049d798021bf25053b87"}, + {file = "grpcio_tools-1.71.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:834959b6eceb85de5217a411aba1643b5f782798680c122202d6a06177226644"}, + {file = "grpcio_tools-1.71.0-cp39-cp39-macosx_10_14_universal2.whl", hash = "sha256:e3ae9556e2a1cd70e7d7b0e0459c35af71d51a7dae4cf36075068011a69f13ec"}, + {file = "grpcio_tools-1.71.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:77fe6db1334e0ce318b2cb4e70afa94e0c173ed1a533d37aea69ad9f61ae8ea9"}, + {file = "grpcio_tools-1.71.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57e3e2544c306b60ef2d76570bac4e977be1ad548641c9eec130c3bc47e80141"}, + {file = "grpcio_tools-1.71.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af39e245fa56f7f5c2fe86b7d6c1b78f395c07e54d5613cbdbb3c24769a92b6e"}, + {file = "grpcio_tools-1.71.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8f987d0053351217954543b174b0bddbf51d45b3cfcf8d6de97b0a43d264d753"}, + {file = "grpcio_tools-1.71.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8e6cdbba4dae7b37b0d25d074614be9936fb720144420f03d9f142a80be69ba2"}, + {file = "grpcio_tools-1.71.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d3adc8b229e60c77bab5a5d62b415667133bd5ced7d59b5f71d6317c9143631e"}, + {file = "grpcio_tools-1.71.0-cp39-cp39-win32.whl", hash = "sha256:f68334d28a267fabec6e70cb5986e9999cfbfd14db654094ddf9aedd804a293a"}, + {file = "grpcio_tools-1.71.0-cp39-cp39-win_amd64.whl", hash = "sha256:1291a6136c07a86c3bb09f6c33f5cf227cc14956edd1b85cb572327a36e0aef8"}, + {file = "grpcio_tools-1.71.0.tar.gz", hash = "sha256:38dba8e0d5e0fb23a034e09644fdc6ed862be2371887eee54901999e8f6792a8"}, +] + +[package.dependencies] +grpcio = ">=1.71.0" +protobuf = ">=5.26.1,<6.0dev" +setuptools = "*" + [[package]] name = "h11" version = "0.14.0" @@ -663,39 +967,40 @@ files = [ [[package]] name = "httpcore" -version = "0.17.3" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "httpcore-0.17.3-py3-none-any.whl", hash = "sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87"}, - {file = "httpcore-0.17.3.tar.gz", hash = "sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] -anyio = ">=3.0,<5.0" certifi = "*" h11 = ">=0.13,<0.15" -sniffio = "==1.*" [package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.24.1" +version = "0.26.0" description = "The next generation HTTP client." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "httpx-0.24.1-py3-none-any.whl", hash = "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd"}, - {file = "httpx-0.24.1.tar.gz", hash = "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd"}, + {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"}, + {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"}, ] [package.dependencies] +anyio = "*" certifi = "*" -httpcore = ">=0.15.0,<0.18.0" +httpcore = "==1.*" idna = "*" sniffio = "*" @@ -1544,6 +1849,26 @@ with-pyroma = ["pyroma (>=2.4)"] with-ruff = ["ruff"] with-vulture = ["vulture (>=1.5)"] +[[package]] +name = "protobuf" +version = "5.29.4" +description = "" +optional = false +python-versions = ">=3.8" +files = [ + {file = "protobuf-5.29.4-cp310-abi3-win32.whl", hash = "sha256:13eb236f8eb9ec34e63fc8b1d6efd2777d062fa6aaa68268fb67cf77f6839ad7"}, + {file = "protobuf-5.29.4-cp310-abi3-win_amd64.whl", hash = "sha256:bcefcdf3976233f8a502d265eb65ea740c989bacc6c30a58290ed0e519eb4b8d"}, + {file = "protobuf-5.29.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:307ecba1d852ec237e9ba668e087326a67564ef83e45a0189a772ede9e854dd0"}, + {file = "protobuf-5.29.4-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:aec4962f9ea93c431d5714ed1be1c93f13e1a8618e70035ba2b0564d9e633f2e"}, + {file = "protobuf-5.29.4-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:d7d3f7d1d5a66ed4942d4fefb12ac4b14a29028b209d4bfb25c68ae172059922"}, + {file = "protobuf-5.29.4-cp38-cp38-win32.whl", hash = "sha256:1832f0515b62d12d8e6ffc078d7e9eb06969aa6dc13c13e1036e39d73bebc2de"}, + {file = "protobuf-5.29.4-cp38-cp38-win_amd64.whl", hash = "sha256:476cb7b14914c780605a8cf62e38c2a85f8caff2e28a6a0bad827ec7d6c85d68"}, + {file = "protobuf-5.29.4-cp39-cp39-win32.whl", hash = "sha256:fd32223020cb25a2cc100366f1dedc904e2d71d9322403224cdde5fdced0dabe"}, + {file = "protobuf-5.29.4-cp39-cp39-win_amd64.whl", hash = "sha256:678974e1e3a9b975b8bc2447fca458db5f93a2fb6b0c8db46b6675b5b5346812"}, + {file = "protobuf-5.29.4-py3-none-any.whl", hash = "sha256:3fde11b505e1597f71b875ef2fc52062b6a9740e5f7c8997ce878b6009145862"}, + {file = "protobuf-5.29.4.tar.gz", hash = "sha256:4f1dfcd7997b31ef8f53ec82781ff434a28bf71d9102ddde14d076adcfc78c99"}, +] + [[package]] name = "psycopg2" version = "2.9.10" @@ -1573,64 +1898,135 @@ files = [ {file = "pycodestyle-2.12.1.tar.gz", hash = "sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521"}, ] +[[package]] +name = "pycparser" +version = "2.22" +description = "C parser in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + [[package]] name = "pydantic" -version = "1.10.17" -description = "Data validation and settings management using python type hints" +version = "2.8.0" +description = "Data validation using Python type hints" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic-1.10.17-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fa51175313cc30097660b10eec8ca55ed08bfa07acbfe02f7a42f6c242e9a4b"}, - {file = "pydantic-1.10.17-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7e8988bb16988890c985bd2093df9dd731bfb9d5e0860db054c23034fab8f7a"}, - {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:371dcf1831f87c9e217e2b6a0c66842879a14873114ebb9d0861ab22e3b5bb1e"}, - {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4866a1579c0c3ca2c40575398a24d805d4db6cb353ee74df75ddeee3c657f9a7"}, - {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:543da3c6914795b37785703ffc74ba4d660418620cc273490d42c53949eeeca6"}, - {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7623b59876f49e61c2e283551cc3647616d2fbdc0b4d36d3d638aae8547ea681"}, - {file = "pydantic-1.10.17-cp310-cp310-win_amd64.whl", hash = "sha256:409b2b36d7d7d19cd8310b97a4ce6b1755ef8bd45b9a2ec5ec2b124db0a0d8f3"}, - {file = "pydantic-1.10.17-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fa43f362b46741df8f201bf3e7dff3569fa92069bcc7b4a740dea3602e27ab7a"}, - {file = "pydantic-1.10.17-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2a72d2a5ff86a3075ed81ca031eac86923d44bc5d42e719d585a8eb547bf0c9b"}, - {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4ad32aed3bf5eea5ca5decc3d1bbc3d0ec5d4fbcd72a03cdad849458decbc63"}, - {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb4e741782e236ee7dc1fb11ad94dc56aabaf02d21df0e79e0c21fe07c95741"}, - {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d2f89a719411cb234105735a520b7c077158a81e0fe1cb05a79c01fc5eb59d3c"}, - {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db3b48d9283d80a314f7a682f7acae8422386de659fffaba454b77a083c3937d"}, - {file = "pydantic-1.10.17-cp311-cp311-win_amd64.whl", hash = "sha256:9c803a5113cfab7bbb912f75faa4fc1e4acff43e452c82560349fff64f852e1b"}, - {file = "pydantic-1.10.17-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:820ae12a390c9cbb26bb44913c87fa2ff431a029a785642c1ff11fed0a095fcb"}, - {file = "pydantic-1.10.17-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c1e51d1af306641b7d1574d6d3307eaa10a4991542ca324f0feb134fee259815"}, - {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e53fb834aae96e7b0dadd6e92c66e7dd9cdf08965340ed04c16813102a47fab"}, - {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e2495309b1266e81d259a570dd199916ff34f7f51f1b549a0d37a6d9b17b4dc"}, - {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:098ad8de840c92ea586bf8efd9e2e90c6339d33ab5c1cfbb85be66e4ecf8213f"}, - {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:525bbef620dac93c430d5d6bdbc91bdb5521698d434adf4434a7ef6ffd5c4b7f"}, - {file = "pydantic-1.10.17-cp312-cp312-win_amd64.whl", hash = "sha256:6654028d1144df451e1da69a670083c27117d493f16cf83da81e1e50edce72ad"}, - {file = "pydantic-1.10.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c87cedb4680d1614f1d59d13fea353faf3afd41ba5c906a266f3f2e8c245d655"}, - {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11289fa895bcbc8f18704efa1d8020bb9a86314da435348f59745473eb042e6b"}, - {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94833612d6fd18b57c359a127cbfd932d9150c1b72fea7c86ab58c2a77edd7c7"}, - {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d4ecb515fa7cb0e46e163ecd9d52f9147ba57bc3633dca0e586cdb7a232db9e3"}, - {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7017971ffa7fd7808146880aa41b266e06c1e6e12261768a28b8b41ba55c8076"}, - {file = "pydantic-1.10.17-cp37-cp37m-win_amd64.whl", hash = "sha256:e840e6b2026920fc3f250ea8ebfdedf6ea7a25b77bf04c6576178e681942ae0f"}, - {file = "pydantic-1.10.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bfbb18b616abc4df70591b8c1ff1b3eabd234ddcddb86b7cac82657ab9017e33"}, - {file = "pydantic-1.10.17-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebb249096d873593e014535ab07145498957091aa6ae92759a32d40cb9998e2e"}, - {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8c209af63ccd7b22fba94b9024e8b7fd07feffee0001efae50dd99316b27768"}, - {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b40c9e13a0b61583e5599e7950490c700297b4a375b55b2b592774332798b7"}, - {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c31d281c7485223caf6474fc2b7cf21456289dbaa31401844069b77160cab9c7"}, - {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae5184e99a060a5c80010a2d53c99aee76a3b0ad683d493e5f0620b5d86eeb75"}, - {file = "pydantic-1.10.17-cp38-cp38-win_amd64.whl", hash = "sha256:ad1e33dc6b9787a6f0f3fd132859aa75626528b49cc1f9e429cdacb2608ad5f0"}, - {file = "pydantic-1.10.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7e17c0ee7192e54a10943f245dc79e36d9fe282418ea05b886e1c666063a7b54"}, - {file = "pydantic-1.10.17-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cafb9c938f61d1b182dfc7d44a7021326547b7b9cf695db5b68ec7b590214773"}, - {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95ef534e3c22e5abbdbdd6f66b6ea9dac3ca3e34c5c632894f8625d13d084cbe"}, - {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d96b8799ae3d782df7ec9615cb59fc32c32e1ed6afa1b231b0595f6516e8ab"}, - {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ab2f976336808fd5d539fdc26eb51f9aafc1f4b638e212ef6b6f05e753c8011d"}, - {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8ad363330557beac73159acfbeed220d5f1bfcd6b930302a987a375e02f74fd"}, - {file = "pydantic-1.10.17-cp39-cp39-win_amd64.whl", hash = "sha256:48db882e48575ce4b39659558b2f9f37c25b8d348e37a2b4e32971dd5a7d6227"}, - {file = "pydantic-1.10.17-py3-none-any.whl", hash = "sha256:e41b5b973e5c64f674b3b4720286ded184dcc26a691dd55f34391c62c6934688"}, - {file = "pydantic-1.10.17.tar.gz", hash = "sha256:f434160fb14b353caf634149baaf847206406471ba70e64657c1e8330277a991"}, + {file = "pydantic-2.8.0-py3-none-any.whl", hash = "sha256:ead4f3a1e92386a734ca1411cb25d94147cf8778ed5be6b56749047676d6364e"}, + {file = "pydantic-2.8.0.tar.gz", hash = "sha256:d970ffb9d030b710795878940bd0489842c638e7252fc4a19c3ae2f7da4d6141"}, ] [package.dependencies] -typing-extensions = ">=4.2.0" +annotated-types = ">=0.4.0" +pydantic-core = "2.20.0" +typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} [package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.20.0" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:e9dcd7fb34f7bfb239b5fa420033642fff0ad676b765559c3737b91f664d4fa9"}, + {file = "pydantic_core-2.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:649a764d9b0da29816889424697b2a3746963ad36d3e0968784ceed6e40c6355"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7701df088d0b05f3460f7ba15aec81ac8b0fb5690367dfd072a6c38cf5b7fdb5"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ab760f17c3e792225cdaef31ca23c0aea45c14ce80d8eff62503f86a5ab76bff"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb1ad5b4d73cde784cf64580166568074f5ccd2548d765e690546cff3d80937d"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b81ec2efc04fc1dbf400647d4357d64fb25543bae38d2d19787d69360aad21c9"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4a9732a5cad764ba37f3aa873dccb41b584f69c347a57323eda0930deec8e10"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6dc85b9e10cc21d9c1055f15684f76fa4facadddcb6cd63abab702eb93c98943"}, + {file = "pydantic_core-2.20.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:21d9f7e24f63fdc7118e6cc49defaab8c1d27570782f7e5256169d77498cf7c7"}, + {file = "pydantic_core-2.20.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b315685832ab9287e6124b5d74fc12dda31e6421d7f6b08525791452844bc2d"}, + {file = "pydantic_core-2.20.0-cp310-none-win32.whl", hash = "sha256:c3dc8ec8b87c7ad534c75b8855168a08a7036fdb9deeeed5705ba9410721c84d"}, + {file = "pydantic_core-2.20.0-cp310-none-win_amd64.whl", hash = "sha256:85770b4b37bb36ef93a6122601795231225641003e0318d23c6233c59b424279"}, + {file = "pydantic_core-2.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:58e251bb5a5998f7226dc90b0b753eeffa720bd66664eba51927c2a7a2d5f32c"}, + {file = "pydantic_core-2.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:78d584caac52c24240ef9ecd75de64c760bbd0e20dbf6973631815e3ef16ef8b"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5084ec9721f82bef5ff7c4d1ee65e1626783abb585f8c0993833490b63fe1792"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6d0f52684868db7c218437d260e14d37948b094493f2646f22d3dda7229bbe3f"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1def125d59a87fe451212a72ab9ed34c118ff771e5473fef4f2f95d8ede26d75"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b34480fd6778ab356abf1e9086a4ced95002a1e195e8d2fd182b0def9d944d11"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d42669d319db366cb567c3b444f43caa7ffb779bf9530692c6f244fc635a41eb"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:53b06aea7a48919a254b32107647be9128c066aaa6ee6d5d08222325f25ef175"}, + {file = "pydantic_core-2.20.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1f038156b696a1c39d763b2080aeefa87ddb4162c10aa9fabfefffc3dd8180fa"}, + {file = "pydantic_core-2.20.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3f0f3a4a23717280a5ee3ac4fb1f81d6fde604c9ec5100f7f6f987716bb8c137"}, + {file = "pydantic_core-2.20.0-cp311-none-win32.whl", hash = "sha256:316fe7c3fec017affd916a0c83d6f1ec697cbbbdf1124769fa73328e7907cc2e"}, + {file = "pydantic_core-2.20.0-cp311-none-win_amd64.whl", hash = "sha256:2d06a7fa437f93782e3f32d739c3ec189f82fca74336c08255f9e20cea1ed378"}, + {file = "pydantic_core-2.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:d6f8c49657f3eb7720ed4c9b26624063da14937fc94d1812f1e04a2204db3e17"}, + {file = "pydantic_core-2.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad1bd2f377f56fec11d5cfd0977c30061cd19f4fa199bf138b200ec0d5e27eeb"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed741183719a5271f97d93bbcc45ed64619fa38068aaa6e90027d1d17e30dc8d"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d82e5ed3a05f2dcb89c6ead2fd0dbff7ac09bc02c1b4028ece2d3a3854d049ce"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2ba34a099576234671f2e4274e5bc6813b22e28778c216d680eabd0db3f7dad"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:879ae6bb08a063b3e1b7ac8c860096d8fd6b48dd9b2690b7f2738b8c835e744b"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b0eefc7633a04c0694340aad91fbfd1986fe1a1e0c63a22793ba40a18fcbdc8"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73deadd6fd8a23e2f40b412b3ac617a112143c8989a4fe265050fd91ba5c0608"}, + {file = "pydantic_core-2.20.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:35681445dc85446fb105943d81ae7569aa7e89de80d1ca4ac3229e05c311bdb1"}, + {file = "pydantic_core-2.20.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0f6dd3612a3b9f91f2e63924ea18a4476656c6d01843ca20a4c09e00422195af"}, + {file = "pydantic_core-2.20.0-cp312-none-win32.whl", hash = "sha256:7e37b6bb6e90c2b8412b06373c6978d9d81e7199a40e24a6ef480e8acdeaf918"}, + {file = "pydantic_core-2.20.0-cp312-none-win_amd64.whl", hash = "sha256:7d4df13d1c55e84351fab51383520b84f490740a9f1fec905362aa64590b7a5d"}, + {file = "pydantic_core-2.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:d43e7ab3b65e4dc35a7612cfff7b0fd62dce5bc11a7cd198310b57f39847fd6c"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b6a24d7b5893392f2b8e3b7a0031ae3b14c6c1942a4615f0d8794fdeeefb08b"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b2f13c3e955a087c3ec86f97661d9f72a76e221281b2262956af381224cfc243"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:72432fd6e868c8d0a6849869e004b8bcae233a3c56383954c228316694920b38"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d70a8ff2d4953afb4cbe6211f17268ad29c0b47e73d3372f40e7775904bc28fc"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e49524917b8d3c2f42cd0d2df61178e08e50f5f029f9af1f402b3ee64574392"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4f0f71653b1c1bad0350bc0b4cc057ab87b438ff18fa6392533811ebd01439c"}, + {file = "pydantic_core-2.20.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:16197e6f4fdecb9892ed2436e507e44f0a1aa2cff3b9306d1c879ea2f9200997"}, + {file = "pydantic_core-2.20.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:763602504bf640b3ded3bba3f8ed8a1cc2fc6a87b8d55c1c5689f428c49c947e"}, + {file = "pydantic_core-2.20.0-cp313-none-win32.whl", hash = "sha256:a3f243f318bd9523277fa123b3163f4c005a3e8619d4b867064de02f287a564d"}, + {file = "pydantic_core-2.20.0-cp313-none-win_amd64.whl", hash = "sha256:03aceaf6a5adaad3bec2233edc5a7905026553916615888e53154807e404545c"}, + {file = "pydantic_core-2.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d6f2d8b8da1f03f577243b07bbdd3412eee3d37d1f2fd71d1513cbc76a8c1239"}, + {file = "pydantic_core-2.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a272785a226869416c6b3c1b7e450506152d3844207331f02f27173562c917e0"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efbb412d55a4ffe73963fed95c09ccb83647ec63b711c4b3752be10a56f0090b"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1e4f46189d8740561b43655263a41aac75ff0388febcb2c9ec4f1b60a0ec12f3"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87d3df115f4a3c8c5e4d5acf067d399c6466d7e604fc9ee9acbe6f0c88a0c3cf"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a340d2bdebe819d08f605e9705ed551c3feb97e4fd71822d7147c1e4bdbb9508"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:616b9c2f882393d422ba11b40e72382fe975e806ad693095e9a3b67c59ea6150"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:25c46bb2ff6084859bbcfdf4f1a63004b98e88b6d04053e8bf324e115398e9e7"}, + {file = "pydantic_core-2.20.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:23425eccef8f2c342f78d3a238c824623836c6c874d93c726673dbf7e56c78c0"}, + {file = "pydantic_core-2.20.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:52527e8f223ba29608d999d65b204676398009725007c9336651c2ec2d93cffc"}, + {file = "pydantic_core-2.20.0-cp38-none-win32.whl", hash = "sha256:1c3c5b7f70dd19a6845292b0775295ea81c61540f68671ae06bfe4421b3222c2"}, + {file = "pydantic_core-2.20.0-cp38-none-win_amd64.whl", hash = "sha256:8093473d7b9e908af1cef30025609afc8f5fd2a16ff07f97440fd911421e4432"}, + {file = "pydantic_core-2.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ee7785938e407418795e4399b2bf5b5f3cf6cf728077a7f26973220d58d885cf"}, + {file = "pydantic_core-2.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0e75794883d635071cf6b4ed2a5d7a1e50672ab7a051454c76446ef1ebcdcc91"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:344e352c96e53b4f56b53d24728217c69399b8129c16789f70236083c6ceb2ac"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:978d4123ad1e605daf1ba5e01d4f235bcf7b6e340ef07e7122e8e9cfe3eb61ab"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c05eaf6c863781eb834ab41f5963604ab92855822a2062897958089d1335dad"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bc7e43b4a528ffca8c9151b6a2ca34482c2fdc05e6aa24a84b7f475c896fc51d"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:658287a29351166510ebbe0a75c373600cc4367a3d9337b964dada8d38bcc0f4"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1dacf660d6de692fe351e8c806e7efccf09ee5184865893afbe8e59be4920b4a"}, + {file = "pydantic_core-2.20.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3e147fc6e27b9a487320d78515c5f29798b539179f7777018cedf51b7749e4f4"}, + {file = "pydantic_core-2.20.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c867230d715a3dd1d962c8d9bef0d3168994ed663e21bf748b6e3a529a129aab"}, + {file = "pydantic_core-2.20.0-cp39-none-win32.whl", hash = "sha256:22b813baf0dbf612752d8143a2dbf8e33ccb850656b7850e009bad2e101fc377"}, + {file = "pydantic_core-2.20.0-cp39-none-win_amd64.whl", hash = "sha256:3a7235b46c1bbe201f09b6f0f5e6c36b16bad3d0532a10493742f91fbdc8035f"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cafde15a6f7feaec2f570646e2ffc5b73412295d29134a29067e70740ec6ee20"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2aec8eeea0b08fd6bc2213d8e86811a07491849fd3d79955b62d83e32fa2ad5f"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:840200827984f1c4e114008abc2f5ede362d6e11ed0b5931681884dd41852ff1"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8ea1d8b7df522e5ced34993c423c3bf3735c53df8b2a15688a2f03a7d678800"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d5b8376a867047bf08910573deb95d3c8dfb976eb014ee24f3b5a61ccc5bee1b"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d08264b4460326cefacc179fc1411304d5af388a79910832835e6f641512358b"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:7a3639011c2e8a9628466f616ed7fb413f30032b891898e10895a0a8b5857d6c"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:05e83ce2f7eba29e627dd8066aa6c4c0269b2d4f889c0eba157233a353053cea"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:603a843fea76a595c8f661cd4da4d2281dff1e38c4a836a928eac1a2f8fe88e4"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ac76f30d5d3454f4c28826d891fe74d25121a346c69523c9810ebba43f3b1cec"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e3b1d4b1b3f6082849f9b28427ef147a5b46a6132a3dbaf9ca1baa40c88609"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2761f71faed820e25ec62eacba670d1b5c2709bb131a19fcdbfbb09884593e5a"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a0586cddbf4380e24569b8a05f234e7305717cc8323f50114dfb2051fcbce2a3"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:b8c46a8cf53e849eea7090f331ae2202cd0f1ceb090b00f5902c423bd1e11805"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b4a085bd04af7245e140d1b95619fe8abb445a3d7fdf219b3f80c940853268ef"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:116b326ac82c8b315e7348390f6d30bcfe6e688a7d3f1de50ff7bcc2042a23c2"}, + {file = "pydantic_core-2.20.0.tar.gz", hash = "sha256:366be8e64e0cb63d87cf79b4e1765c0703dd6313c729b22e7b9e378db6b96877"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydocstyle" @@ -1999,6 +2395,26 @@ files = [ [package.extras] yaml = ["pyyaml"] +[[package]] +name = "setuptools" +version = "78.1.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.9" +files = [ + {file = "setuptools-78.1.0-py3-none-any.whl", hash = "sha256:3e386e96793c8702ae83d17b853fb93d3e09ef82ec62722e61da5cd22376dcd8"}, + {file = "setuptools-78.1.0.tar.gz", hash = "sha256:18fd474d4a82a5f83dac888df697af65afa82dec7323d09c3e37d1f14288da54"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.8.0)"] +core = ["importlib_metadata (>=6)", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.14.*)", "pytest-mypy"] + [[package]] name = "smmap" version = "5.0.1" @@ -2330,6 +2746,43 @@ h11 = ">=0.8" [package.extras] standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] +[[package]] +name = "validators" +version = "0.34.0" +description = "Python Data Validation for Humansâ„¢" +optional = false +python-versions = ">=3.8" +files = [ + {file = "validators-0.34.0-py3-none-any.whl", hash = "sha256:c804b476e3e6d3786fa07a30073a4ef694e617805eb1946ceee3fe5a9b8b1321"}, + {file = "validators-0.34.0.tar.gz", hash = "sha256:647fe407b45af9a74d245b943b18e6a816acf4926974278f6dd617778e1e781f"}, +] + +[package.extras] +crypto-eth-addresses = ["eth-hash[pycryptodome] (>=0.7.0)"] + +[[package]] +name = "weaviate-client" +version = "4.12.0" +description = "A python native Weaviate client" +optional = false +python-versions = ">=3.9" +files = [ + {file = "weaviate_client-4.12.0-py3-none-any.whl", hash = "sha256:72299b18edca40a97d44917ecf1a488949e71a82cab6e19e93d2408bcdcb1eea"}, + {file = "weaviate_client-4.12.0.tar.gz", hash = "sha256:4bbccecd87a17d612a52394825fea696569def2faf37d1e268b4a23c4f91748a"}, +] + +[package.dependencies] +authlib = ">=1.2.1,<1.3.2" +grpcio = ">=1.66.2,<2.0.0" +grpcio-health-checking = ">=1.66.2,<2.0.0" +grpcio-tools = ">=1.66.2,<2.0.0" +httpx = ">=0.26.0,<0.29.0" +pydantic = ">=2.8.0,<3.0.0" +validators = "0.34.0" + +[package.extras] +agents = ["weaviate-agents (>=0.3.0,<1.0.0)"] + [[package]] name = "yarl" version = "1.18.3" @@ -2429,4 +2882,4 @@ propcache = ">=0.2.0" [metadata] lock-version = "2.0" python-versions = "3.11.*" -content-hash = "a2ec0f8a34c58ac18bbbf07c9fd4bd855c80b9fadd8ba3b4048e8e51027e1ef6" +content-hash = "7f59b73be7b36388c57d1087778aafb12e881074763cd06718adb0ed7731244c" diff --git a/athena/modules/text/module_text_llm/pyproject.toml b/athena/modules/text/module_text_llm/pyproject.toml index bf03e028..9f21768c 100644 --- a/athena/modules/text/module_text_llm/pyproject.toml +++ b/athena/modules/text/module_text_llm/pyproject.toml @@ -15,9 +15,10 @@ gitpython = "3.1.41" nltk = "3.9.1" python-dotenv = "1.0.0" tiktoken = "0.7.0" +weaviate-client = "4.12.0" [tool.poetry.dev-dependencies] -pydantic = "1.10.17" +pydantic = "2.8.0" prospector = "^1.10.2" [tool.poetry.scripts] From 85981752277a246cc63ae1c8c067bab9d84d8a25 Mon Sep 17 00:00:00 2001 From: = Enea_Gore Date: Mon, 14 Apr 2025 15:52:07 +0200 Subject: [PATCH 2/6] Clean up code, improve prompt format, filter by exercise id --- athena/athena/edutelligence | 1 + .../module_text_llm/__main__.py | 1 - .../in_context_learning/__init__.py | 3 +- .../in_context_learning/agent.py | 68 ------------------ .../feedback_icl/generate_embeddings.py | 1 - .../feedback_icl/retrieve_rag_context_icl.py | 58 +++++++-------- .../feedback_icl/store_feedback_icl.py | 72 +++++++------------ .../feedback_icl/store_indices_icl.py | 47 ------------ .../generate_suggestions.py | 6 +- .../prompt_generate_suggestions.py | 8 +-- 10 files changed, 61 insertions(+), 204 deletions(-) create mode 160000 athena/athena/edutelligence delete mode 100644 athena/modules/text/module_text_llm/module_text_llm/in_context_learning/agent.py delete mode 100644 athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_indices_icl.py diff --git a/athena/athena/edutelligence b/athena/athena/edutelligence new file mode 160000 index 00000000..30e32d6d --- /dev/null +++ b/athena/athena/edutelligence @@ -0,0 +1 @@ +Subproject commit 30e32d6d6cb5df41b8dd76ff4061f97c5f4461eb diff --git a/athena/modules/text/module_text_llm/module_text_llm/__main__.py b/athena/modules/text/module_text_llm/module_text_llm/__main__.py index 647d8b7f..e705b974 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/__main__.py +++ b/athena/modules/text/module_text_llm/module_text_llm/__main__.py @@ -11,7 +11,6 @@ from module_text_llm.evaluation import get_feedback_statistics, get_llm_statistics from module_text_llm.generate_evaluation import generate_evaluation from module_text_llm.approach_controller import generate_suggestions -from module_text_llm.RandomMessage import write_random_message,query_messages,create_minimal_schema from module_text_llm.in_context_learning.feedback_icl.store_feedback_icl import store_feedback_icl @submissions_consumer def receive_submissions(exercise: Exercise, submissions: List[Submission]): diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/__init__.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/__init__.py index b3e6d6a0..75a81b5f 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/__init__.py +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/__init__.py @@ -10,4 +10,5 @@ class InContextLearningConfig(ApproachConfig): generate_suggestions_prompt: GenerateSuggestionsPrompt = Field(default=GenerateSuggestionsPrompt()) async def generate_suggestions(self, exercise: Exercise, submission: Submission, config,*, debug: bool, is_graded: bool): - return await generate_suggestions(exercise, submission, config, debug, is_graded) \ No newline at end of file + return await generate_suggestions(exercise, submission, config, debug, is_graded) + \ No newline at end of file diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/agent.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/agent.py deleted file mode 100644 index 359504a3..00000000 --- a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/agent.py +++ /dev/null @@ -1,68 +0,0 @@ -# from langchain_openai import ChatOpenAI -# from langchain_core.prompts import ChatPromptTemplate -# from langchain.agents import AgentExecutor, create_tool_calling_agent -# from pydantic import BaseModel, Field -# from langchain_core.tools import tool -# from module_text_llm.in_context_learning.feedback_icl.retrieve_rag_context_icl import retrieve_rag_context_icl -# from module_text_llm.in_context_learning.prompt_generate_suggestions import FeedbackModel -# from typing import List - -# # @tool -# # def retrieve_rag_context(submission_segment: str ,exercise_id: int) -> str: -# # """ -# # This method takes a segment from a submission and for a given exercise id, -# # returns feedback that has been given for similar texts. - -# # Args: -# # submission_segment: A segment of the submission. -# # exercise_id: The id of the exercise. - -# # Returns: -# # str: A formatted string of feedbacks which reference text similar to the submission_segment. -# # """ -# # return retrieve_rag_context_icl(submission_segment,exercise_id) - -# @tool -# class AssessmentModel(BaseModel): -# """Collection of feedbacks making up an assessment""" - -# feedbacks: List[FeedbackModel] = Field(description="Assessment feedbacks") - -# class AssessmentModelParse(BaseModel): -# """Collection of feedbacks making up an assessment""" - -# feedbacks: List[FeedbackModel] = Field(description="Assessment feedbacks") - -# class TutorAgent: -# def __init__(self,config): -# self.model = config.model.get_model() -# self.outputModel = ChatOpenAI(model="gpt-4o-mini") -# self.approach_config = None -# self.openai_tools = [retrieve_rag_context] -# self.setConfig(config) - - -# def setConfig(self,approach_config): -# self.approach_config = approach_config -# self.prompt = ChatPromptTemplate.from_messages( -# [ -# ("system", self.approach_config.generate_suggestions_prompt.system_message), -# ("human", "{submission}"), -# ("placeholder", "{agent_scratchpad}"), -# ]) - -# self.agent = create_tool_calling_agent(self.model, self.openai_tools , self.prompt) -# self.agent_executor = AgentExecutor(agent=self.agent, tools=self.openai_tools) -# self.config = {"configurable": {"session_id": "test-session"}} - -# def call_agent(self, prompt): -# """Calls the agent with a prompt and returns the response output.""" - -# response = self.agent_executor.invoke( -# input = prompt -# ) - -# res = self.model.with_structured_output(AssessmentModelParse).invoke(f"Format the following output {response}") -# return res - - \ No newline at end of file diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/generate_embeddings.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/generate_embeddings.py index 681e8e95..c9ad3ad6 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/generate_embeddings.py +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/generate_embeddings.py @@ -4,4 +4,3 @@ def embed_text(text): embeddings = OpenAIEmbeddings(model="text-embedding-3-large") query_result = embeddings.embed_query(text) return query_result - # return np.array(query_result, dtype=np.float32) only relevant for numpy operations diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context_icl.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context_icl.py index 35091fca..a673edae 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context_icl.py +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context_icl.py @@ -1,7 +1,4 @@ -from athena.logger import logger -from module_text_llm.in_context_learning.feedback_icl.store_indices_icl import retrieve_embedding_index, retrieve_feedback from module_text_llm.in_context_learning.feedback_icl.store_feedback_icl import query_embedding -from module_text_llm.in_context_learning.feedback_icl.generate_embeddings import embed_text def retrieve_rag_context_icl(submission_segment: str ,exercise_id: int) -> str: """ @@ -15,40 +12,39 @@ def retrieve_rag_context_icl(submission_segment: str ,exercise_id: int) -> str: Returns: str: A formatted string of feedbacks which reference text similar to the submission_segment. """ - # query_submission= embed_text(submission_segment) rag_context = [] - rresult_objects = query_embedding(submission_segment,exercise_id) - print(rresult_objects) - return " " - # for result in rresult_objects: - # print("result",result) - # print(type(result)) - - # if list_of_indices is not None: - # for index in list_of_indices[0]: - # if index != -1: - # stored_feedback = retrieve_feedback(index,exercise_id) - # print("Stored feedback",stored_feedback) - # rag_context.append({"submission_chunk": submission_segment, "feedback": stored_feedback}) - # formatted_rag_context = format_rag_context(rag_context) - # else: - # formatted_rag_context = "There are no submission at the moment" - # return formatted_rag_context + result_objects = query_embedding(submission_segment,exercise_id) + for result in result_objects.objects: + title = result.properties.get("title") + description = result.properties.get("description") + credits = result.properties.get("credits") + reference = result.properties.get("reference") + rag_context.append(format_context(title,description,credits,reference)) + return format_rag_context(rag_context) -def format_rag_context(rag_context): +def format_context(title,description,credits,reference): formatted_string = "" - + formatted_string += f""" + For the reference text in the submission: {reference}**\n + The tutor provided the following feedback:\n + **Title**: {title}\n + **Description**: {description}\n + **Credits**: {credits}\n + **Reference text**: {reference}**\n + **\n""" + return formatted_string + +def format_rag_context(rag_context): + formatted_string = """ **Tutor provided Feedback from previous submissions of this same exercise. + This are possible examples that could help with the grading of the current submission. However they are not identical + so please be careful when using them. You must carefully decide whether this references are relevant.**\n + **\n""" + formatted_string += "\n" + "-"*40 + "\n" + for context_item in rag_context: - submission_text = context_item["submission_chunk"] - feedback = context_item["feedback"] - if feedback is not None: - formatted_string += "**Tutor provided Feedback from previous submissions of this same exercise:**\n" - feedback["text_reference"] = get_reference(feedback, submission_text) - clean_feedback = {key: value for key, value in feedback.items() if key not in ["id","index_start","index_end","is_graded","meta"]} - - formatted_string += f"{clean_feedback}\n" + formatted_string += f"{context_item}\n" formatted_string += "\n" + "-"*40 + "\n" return formatted_string diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback_icl.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback_icl.py index bfffccbe..1a72a58e 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback_icl.py +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback_icl.py @@ -6,30 +6,24 @@ from module_text_llm.in_context_learning.feedback_icl.generate_embeddings import embed_text import weaviate import weaviate.classes as wvc - +from weaviate.classes.query import Filter def create_schema(client): """ - Create a schema with two classes: Question and Answer. - Each class has properties for storing relevant information. + Creates a schema with the information needed for ICL. """ - - # Define the Question class - questions = client.collections.create( - name="Feedback", - vectorizer_config=wvc.config.Configure.Vectorizer.none(), - properties=[ - wvc.config.Property(name="exercise_id", data_type=wvc.config.DataType.NUMBER), - wvc.config.Property(name="submission_id", data_type=wvc.config.DataType.NUMBER), - wvc.config.Property(name="title", data_type=wvc.config.DataType.TEXT), - wvc.config.Property(name="description", data_type=wvc.config.DataType.TEXT), - wvc.config.Property(name="credits", data_type=wvc.config.DataType.NUMBER), - wvc.config.Property(name="grading_id", data_type=wvc.config.DataType.UUID), - ] - ) - - print("Schema ICL created.") - print(questions.config.get(simple=False)) + feedback_collection = client.collections.create( + name="Feedback", + vectorizer_config=wvc.config.Configure.Vectorizer.none(), + properties=[ + wvc.config.Property(name="exercise_id", data_type=wvc.config.DataType.NUMBER), + wvc.config.Property(name="submission_id", data_type=wvc.config.DataType.NUMBER), + wvc.config.Property(name="title", data_type=wvc.config.DataType.TEXT), + wvc.config.Property(name="description", data_type=wvc.config.DataType.TEXT), + wvc.config.Property(name="credits", data_type=wvc.config.DataType.NUMBER), + wvc.config.Property(name="grading_id", data_type=wvc.config.DataType.NUMBER), + ] +) def store_feedback_icl(submission: Submission, exercise: Exercise, feedbacks: List[Feedback]): client = weaviate.connect_to_local() @@ -37,29 +31,26 @@ def store_feedback_icl(submission: Submission, exercise: Exercise, feedbacks: Li create_schema(client) finally: logger.info("Storing feedback for submission %d of exercise %d.", submission.id, exercise.id) - for feedback in feedbacks: - print("doing feedback") chunk = get_reference(feedback, submission.text) embedding = embed_text(chunk) - store_feedback(embedding, exercise.id, submission.id, feedback, client) - # save_embedding(embedding, exercise.id) - # store_embedding_index(exercise.id, submission.id, feedback) + store_feedback(embedding, exercise.id, submission.id, feedback,chunk, client) client.close() -def store_feedback(embedding, exercise_id, submission_id, feedback, client): + +def store_feedback(embedding, exercise_id, submission_id, feedback,chunk, client): """ Store feedback in the Weaviate database. """ - print("storing feedback") - questions = client.collections.get("Feedback") - uuid = questions.data.insert( + feedback_collection = client.collections.get("Feedback") + uuid = feedback_collection.data.insert( properties={ "exercise_id": exercise_id, "submission_id": submission_id, "title": feedback.title, "description": feedback.description, "credits": feedback.credits, - "grading_id": feedback.structured_grading_instruction_id + "grading_id": feedback.structured_grading_instruction_id, + "reference": chunk }, vector=embedding, ) @@ -67,35 +58,22 @@ def store_feedback(embedding, exercise_id, submission_id, feedback, client): print("Feedback stored successfully.") return uuid - -# Here is the usage of the function: -# list_of_indices = query_embedding(query_submission,exercise_id) -#TODO implement a filter for the exercise id. Use the certainity limit to filter the results. -def query_embedding (query,exercise_id,results_limit=1, threshold=0.5): - logger.info("Querying") +def query_embedding (query,exercise_id,results_limit=1): + logger.info("Querying weaviate database") client = weaviate.connect_to_local() feedbacks = client.collections.get("Feedback") embedded_query = embed_text(query) - # print("embedded query",embedded_query) results = feedbacks.query.near_vector( near_vector=embedded_query, limit = results_limit, + filters=Filter.by_property("exercise_id").equal(exercise_id), return_metadata=wvc.query.MetadataQuery(certainty=True) ) - - print(results) client.close() return results - # return "test" - + def get_reference(feedback, submission_text): if (feedback.index_start is not None) and (feedback.index_end is not None): return submission_text[feedback.index_start:feedback.index_end ] return submission_text - -def check_if_embedding_exists(exercise_id): - """ - Check if the embedding index file exists for the given exercise ID. - """ - return True \ No newline at end of file diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_indices_icl.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_indices_icl.py deleted file mode 100644 index a2d5eb7a..00000000 --- a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_indices_icl.py +++ /dev/null @@ -1,47 +0,0 @@ -import os -import json - -def load_indices(index_file): - """ Load the indices from the file or return an empty dictionary if the file does not exist. """ - if os.path.exists(index_file): - with open(index_file, 'r', encoding="utf-8") as f: - return json.load(f) - else: - return {} - -def store_embedding_index(exercise_id, submission_id,feedback): - """ Store a new submission and exercise ID with an auto-incrementing index. """ - index_file = f"indices_{exercise_id}.json" - indices = load_indices(index_file) - next_index = len(indices) - print(feedback) - indices[next_index] = { - "exercise_id": exercise_id, - "submission_id": submission_id, - "feedback": feedback.dict() - } - - with open(index_file, 'w', encoding="utf-8") as f: - json.dump(indices, f, indent=4) - - print(f"Stored new entry: Exercise ID {exercise_id}, Submission ID {submission_id} at index {next_index}") - -def retrieve_embedding_index(index,exercise_id): - index_file = f"indices_{exercise_id}.json" - index = str(index) - indices = load_indices(index_file) - - if index in indices: - return indices[index]["exercise_id"], indices[index]["submission_id"] - - return None, None - -def retrieve_feedback(index,exercise_id): - index_file = f"indices_{exercise_id}.json" - index = str(index) - indices = load_indices(index_file) - - if index in indices: - return indices[index]["feedback"] - - return None \ No newline at end of file diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py index d6e39d56..bef8811f 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py @@ -16,7 +16,6 @@ # from module_text_llm.in_context_learning.agent import TutorAgent from module_text_llm.in_context_learning.ollama_prompt import system_message_segment, human_message_segment, Segmentation, system_message, human_message -from module_text_llm.in_context_learning.feedback_icl.store_feedback_icl import check_if_embedding_exists from module_text_llm.in_context_learning.feedback_icl.retrieve_rag_context_icl import retrieve_rag_context_icl @@ -62,7 +61,7 @@ async def generate_suggestions(exercise: Exercise, submission: Submission, confi return [] if (isOllama): - embeddings_exist = check_if_embedding_exists(exercise.id) + embeddings_exist = True if embeddings_exist: segmentation_prompt = get_chat_prompt_with_formatting_instructions( @@ -96,7 +95,7 @@ async def generate_suggestions(exercise: Exercise, submission: Submission, confi ], ) else : - embeddings_exist = check_if_embedding_exists(exercise.id) + embeddings_exist = True if embeddings_exist: segmentation_prompt = get_chat_prompt_with_formatting_instructions( @@ -112,7 +111,6 @@ async def generate_suggestions(exercise: Exercise, submission: Submission, confi } chain = segmentation_prompt | model segments = chain.invoke( segmentation_prompt_input) - # print("segments ",segments) for segment in segments: formatted_rag_context += retrieve_rag_context_icl(segment[0],exercise.id) prompt_input["rag_context"] = formatted_rag_context diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/prompt_generate_suggestions.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/prompt_generate_suggestions.py index ebae5378..48d317f5 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/prompt_generate_suggestions.py +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/prompt_generate_suggestions.py @@ -17,10 +17,10 @@ Max points: {max_points}, bonus points: {bonus_points} The exercise id is: {exercise_id} -------------------------- -You have access to a tool which gives you example feedback from professional tutors. You can use these to think about what kind of feedback would be appropriate for the student's submission. -You do not need to write the exact same feedback as the examples, but you can use them as inspiration. -When providing line references, they should never overlap. -Your response must include a title, description, credits, line_start and line end for each feedback and the grading isntruction id. Line start and end can be left out if it does not apply to a specific part of the submission but its a general feedback. +You have access to the following tutor feedback on similar texts, Keep in mind what the reference text is +and that it may not be relevant to the current submission. You must carefully decide whether this references are relevant: +{rag_context} +Respond in json. """ human_message = """Student's submission to grade (with sentence numbers : ): From 7670363988566b9276f527b727e427ea14ca43e6 Mon Sep 17 00:00:00 2001 From: = Enea_Gore Date: Mon, 21 Apr 2025 17:57:23 +0200 Subject: [PATCH 3/6] linting and code quality --- .../feedback_icl/retrieve_rag_context_icl.py | 6 +- .../feedback_icl/store_feedback_icl.py | 8 +- .../generate_suggestions.py | 95 ++++++------------- 3 files changed, 33 insertions(+), 76 deletions(-) diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context_icl.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context_icl.py index a673edae..0f1fa89f 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context_icl.py +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context_icl.py @@ -44,9 +44,9 @@ def format_rag_context(rag_context): formatted_string += "\n" + "-"*40 + "\n" for context_item in rag_context: - formatted_string += f"{context_item}\n" - formatted_string += "\n" + "-"*40 + "\n" - + formatted_string += f"{context_item}\n" + formatted_string += "\n" + "-"*40 + "\n" + return formatted_string def get_reference(feedback, submission_text): diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback_icl.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback_icl.py index 1a72a58e..c97af474 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback_icl.py +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback_icl.py @@ -33,14 +33,14 @@ def store_feedback_icl(submission: Submission, exercise: Exercise, feedbacks: Li logger.info("Storing feedback for submission %d of exercise %d.", submission.id, exercise.id) for feedback in feedbacks: chunk = get_reference(feedback, submission.text) - embedding = embed_text(chunk) - store_feedback(embedding, exercise.id, submission.id, feedback,chunk, client) + store_feedback(exercise.id, submission.id, feedback,chunk, client) client.close() -def store_feedback(embedding, exercise_id, submission_id, feedback,chunk, client): +def store_feedback(exercise_id, submission_id, feedback, chunk, client): """ Store feedback in the Weaviate database. """ + embedding = embed_text(chunk) feedback_collection = client.collections.get("Feedback") uuid = feedback_collection.data.insert( properties={ @@ -54,8 +54,6 @@ def store_feedback(embedding, exercise_id, submission_id, feedback,chunk, client }, vector=embedding, ) - print(uuid) - print("Feedback stored successfully.") return uuid def query_embedding (query,exercise_id,results_limit=1): diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py index bef8811f..990fa931 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py @@ -21,7 +21,6 @@ async def generate_suggestions(exercise: Exercise, submission: Submission, config:ApproachConfig, debug: bool, is_graded :bool) -> List[Feedback]: model = config.model.get_model() # type: ignore[attr-defined] - isOllama = isinstance(model, ChatOllama) formatted_rag_context = "" prompt_input = { @@ -60,74 +59,34 @@ async def generate_suggestions(exercise: Exercise, submission: Submission, confi emit_meta("error", f"Input too long {num_tokens_from_prompt(chat_prompt, prompt_input)} > {config.max_input_tokens}") return [] - if (isOllama): - embeddings_exist = True - - if embeddings_exist: - segmentation_prompt = get_chat_prompt_with_formatting_instructions( - model=model, - system_message=system_message_segment, - human_message=human_message_segment, - pydantic_object=Segmentation - ) - segmentation_prompt_input = { - "grading_instructions": format_grading_instructions(exercise.grading_instructions, exercise.grading_criteria), - "submission": submission.text, - "problem_statement": exercise.problem_statement or "No problem statement.", - } - chain = segmentation_prompt | model - segments = chain.invoke( segmentation_prompt_input) + + segmentation_prompt = get_chat_prompt_with_formatting_instructions( + model=model, + system_message=system_message_segment, + human_message=human_message_segment, + pydantic_object=Segmentation + ) + segmentation_prompt_input = { + "grading_instructions": format_grading_instructions(exercise.grading_instructions, exercise.grading_criteria), + "submission": submission.text, + "problem_statement": exercise.problem_statement or "No problem statement.", + } + chain = segmentation_prompt | model + segments = chain.invoke( segmentation_prompt_input) + for segment in segments: + formatted_rag_context += retrieve_rag_context_icl(segment[0],exercise.id) + prompt_input["rag_context"] = formatted_rag_context - for segment in segments: - formatted_rag_context += retrieve_rag_context_icl(segment[0],exercise.id) - prompt_input["rag_context"] = formatted_rag_context - else: - prompt_input["rag_context"] = "There are no submission at the moment" - - result = await predict_and_parse( - model=model, - chat_prompt=chat_prompt, - prompt_input=prompt_input, - pydantic_object=AssessmentModel, - tags=[ - f"exercise-{exercise.id}", - f"submission-{submission.id}", - ], - ) - else : - embeddings_exist = True - - if embeddings_exist: - segmentation_prompt = get_chat_prompt_with_formatting_instructions( - model=model, - system_message=system_message_segment, - human_message=human_message_segment, - pydantic_object=Segmentation - ) - segmentation_prompt_input = { - "grading_instructions": format_grading_instructions(exercise.grading_instructions, exercise.grading_criteria), - "submission": submission.text, - "problem_statement": exercise.problem_statement or "No problem statement.", - } - chain = segmentation_prompt | model - segments = chain.invoke( segmentation_prompt_input) - for segment in segments: - formatted_rag_context += retrieve_rag_context_icl(segment[0],exercise.id) - prompt_input["rag_context"] = formatted_rag_context - else: - prompt_input["rag_context"] = "There are no submission at the moment" - - result = await predict_and_parse( - model=model, - chat_prompt=chat_prompt, - prompt_input=prompt_input, - pydantic_object=AssessmentModel, - use_function_calling=True, - tags=[ - f"exercise-{exercise.id}", - f"submission-{submission.id}", - ], - ) + result = await predict_and_parse( + model=model, + chat_prompt=chat_prompt, + prompt_input=prompt_input, + pydantic_object=AssessmentModel, + use_function_calling=True, + tags=[ + f"exercise-{exercise.id}", + f"submission-{submission.id}", + ],) if debug: emit_meta("generate_suggestions", { "prompt": chat_prompt.format(**prompt_input), From 059d6c80e134ff83aaeeebcaa94428651f4581b0 Mon Sep 17 00:00:00 2001 From: = Enea_Gore Date: Thu, 24 Apr 2025 20:12:29 +0200 Subject: [PATCH 4/6] change request and fix pydantic 2.8 for all llm modules --- athena/athena/edutelligence | 1 - .../modeling/module_modeling_llm/poetry.lock | 196 +++++++++++------ .../module_modeling_llm/pyproject.toml | 2 +- .../module_programming_llm/poetry.lock | 207 ++++++++++++------ .../module_programming_llm/pyproject.toml | 2 +- .../module_text_llm/__main__.py | 5 +- ...context_icl.py => retrieve_rag_context.py} | 6 +- ...tore_feedback_icl.py => store_feedback.py} | 8 +- .../generate_suggestions.py | 17 +- 9 files changed, 295 insertions(+), 149 deletions(-) delete mode 160000 athena/athena/edutelligence rename athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/{retrieve_rag_context_icl.py => retrieve_rag_context.py} (93%) rename athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/{store_feedback_icl.py => store_feedback.py} (89%) diff --git a/athena/athena/edutelligence b/athena/athena/edutelligence deleted file mode 160000 index 30e32d6d..00000000 --- a/athena/athena/edutelligence +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 30e32d6d6cb5df41b8dd76ff4061f97c5f4461eb diff --git a/athena/modules/modeling/module_modeling_llm/poetry.lock b/athena/modules/modeling/module_modeling_llm/poetry.lock index ef71273f..5fc2d964 100644 --- a/athena/modules/modeling/module_modeling_llm/poetry.lock +++ b/athena/modules/modeling/module_modeling_llm/poetry.lock @@ -122,6 +122,17 @@ files = [ [package.dependencies] frozenlist = ">=1.1.0" +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + [[package]] name = "anyio" version = "4.7.0" @@ -166,7 +177,7 @@ develop = true [package.dependencies] fastapi = "^0.109.1" gitpython = "^3.1.41" -httpx = "^0.24.1" +httpx = "^0.26.0" psycopg2 = "^2.9.9" sqlalchemy = {version = "^2.0.21", extras = ["mypy"]} uvicorn = "^0.23.0" @@ -676,39 +687,40 @@ files = [ [[package]] name = "httpcore" -version = "0.17.3" +version = "1.0.8" description = "A minimal low-level HTTP client." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "httpcore-0.17.3-py3-none-any.whl", hash = "sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87"}, - {file = "httpcore-0.17.3.tar.gz", hash = "sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888"}, + {file = "httpcore-1.0.8-py3-none-any.whl", hash = "sha256:5254cf149bcb5f75e9d1b2b9f729ea4a4b883d1ad7379fc632b727cec23674be"}, + {file = "httpcore-1.0.8.tar.gz", hash = "sha256:86e94505ed24ea06514883fd44d2bc02d90e77e7979c8eb71b90f41d364a1bad"}, ] [package.dependencies] -anyio = ">=3.0,<5.0" certifi = "*" h11 = ">=0.13,<0.15" -sniffio = "==1.*" [package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.24.1" +version = "0.26.0" description = "The next generation HTTP client." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "httpx-0.24.1-py3-none-any.whl", hash = "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd"}, - {file = "httpx-0.24.1.tar.gz", hash = "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd"}, + {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"}, + {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"}, ] [package.dependencies] +anyio = "*" certifi = "*" -httpcore = ">=0.15.0,<0.18.0" +httpcore = "==1.*" idna = "*" sniffio = "*" @@ -1577,62 +1589,122 @@ files = [ [[package]] name = "pydantic" -version = "1.10.17" -description = "Data validation and settings management using python type hints" +version = "2.8.0" +description = "Data validation using Python type hints" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic-1.10.17-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fa51175313cc30097660b10eec8ca55ed08bfa07acbfe02f7a42f6c242e9a4b"}, - {file = "pydantic-1.10.17-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7e8988bb16988890c985bd2093df9dd731bfb9d5e0860db054c23034fab8f7a"}, - {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:371dcf1831f87c9e217e2b6a0c66842879a14873114ebb9d0861ab22e3b5bb1e"}, - {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4866a1579c0c3ca2c40575398a24d805d4db6cb353ee74df75ddeee3c657f9a7"}, - {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:543da3c6914795b37785703ffc74ba4d660418620cc273490d42c53949eeeca6"}, - {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7623b59876f49e61c2e283551cc3647616d2fbdc0b4d36d3d638aae8547ea681"}, - {file = "pydantic-1.10.17-cp310-cp310-win_amd64.whl", hash = "sha256:409b2b36d7d7d19cd8310b97a4ce6b1755ef8bd45b9a2ec5ec2b124db0a0d8f3"}, - {file = "pydantic-1.10.17-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fa43f362b46741df8f201bf3e7dff3569fa92069bcc7b4a740dea3602e27ab7a"}, - {file = "pydantic-1.10.17-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2a72d2a5ff86a3075ed81ca031eac86923d44bc5d42e719d585a8eb547bf0c9b"}, - {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4ad32aed3bf5eea5ca5decc3d1bbc3d0ec5d4fbcd72a03cdad849458decbc63"}, - {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb4e741782e236ee7dc1fb11ad94dc56aabaf02d21df0e79e0c21fe07c95741"}, - {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d2f89a719411cb234105735a520b7c077158a81e0fe1cb05a79c01fc5eb59d3c"}, - {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db3b48d9283d80a314f7a682f7acae8422386de659fffaba454b77a083c3937d"}, - {file = "pydantic-1.10.17-cp311-cp311-win_amd64.whl", hash = "sha256:9c803a5113cfab7bbb912f75faa4fc1e4acff43e452c82560349fff64f852e1b"}, - {file = "pydantic-1.10.17-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:820ae12a390c9cbb26bb44913c87fa2ff431a029a785642c1ff11fed0a095fcb"}, - {file = "pydantic-1.10.17-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c1e51d1af306641b7d1574d6d3307eaa10a4991542ca324f0feb134fee259815"}, - {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e53fb834aae96e7b0dadd6e92c66e7dd9cdf08965340ed04c16813102a47fab"}, - {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e2495309b1266e81d259a570dd199916ff34f7f51f1b549a0d37a6d9b17b4dc"}, - {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:098ad8de840c92ea586bf8efd9e2e90c6339d33ab5c1cfbb85be66e4ecf8213f"}, - {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:525bbef620dac93c430d5d6bdbc91bdb5521698d434adf4434a7ef6ffd5c4b7f"}, - {file = "pydantic-1.10.17-cp312-cp312-win_amd64.whl", hash = "sha256:6654028d1144df451e1da69a670083c27117d493f16cf83da81e1e50edce72ad"}, - {file = "pydantic-1.10.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c87cedb4680d1614f1d59d13fea353faf3afd41ba5c906a266f3f2e8c245d655"}, - {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11289fa895bcbc8f18704efa1d8020bb9a86314da435348f59745473eb042e6b"}, - {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94833612d6fd18b57c359a127cbfd932d9150c1b72fea7c86ab58c2a77edd7c7"}, - {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d4ecb515fa7cb0e46e163ecd9d52f9147ba57bc3633dca0e586cdb7a232db9e3"}, - {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7017971ffa7fd7808146880aa41b266e06c1e6e12261768a28b8b41ba55c8076"}, - {file = "pydantic-1.10.17-cp37-cp37m-win_amd64.whl", hash = "sha256:e840e6b2026920fc3f250ea8ebfdedf6ea7a25b77bf04c6576178e681942ae0f"}, - {file = "pydantic-1.10.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bfbb18b616abc4df70591b8c1ff1b3eabd234ddcddb86b7cac82657ab9017e33"}, - {file = "pydantic-1.10.17-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebb249096d873593e014535ab07145498957091aa6ae92759a32d40cb9998e2e"}, - {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8c209af63ccd7b22fba94b9024e8b7fd07feffee0001efae50dd99316b27768"}, - {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b40c9e13a0b61583e5599e7950490c700297b4a375b55b2b592774332798b7"}, - {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c31d281c7485223caf6474fc2b7cf21456289dbaa31401844069b77160cab9c7"}, - {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae5184e99a060a5c80010a2d53c99aee76a3b0ad683d493e5f0620b5d86eeb75"}, - {file = "pydantic-1.10.17-cp38-cp38-win_amd64.whl", hash = "sha256:ad1e33dc6b9787a6f0f3fd132859aa75626528b49cc1f9e429cdacb2608ad5f0"}, - {file = "pydantic-1.10.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7e17c0ee7192e54a10943f245dc79e36d9fe282418ea05b886e1c666063a7b54"}, - {file = "pydantic-1.10.17-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cafb9c938f61d1b182dfc7d44a7021326547b7b9cf695db5b68ec7b590214773"}, - {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95ef534e3c22e5abbdbdd6f66b6ea9dac3ca3e34c5c632894f8625d13d084cbe"}, - {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d96b8799ae3d782df7ec9615cb59fc32c32e1ed6afa1b231b0595f6516e8ab"}, - {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ab2f976336808fd5d539fdc26eb51f9aafc1f4b638e212ef6b6f05e753c8011d"}, - {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8ad363330557beac73159acfbeed220d5f1bfcd6b930302a987a375e02f74fd"}, - {file = "pydantic-1.10.17-cp39-cp39-win_amd64.whl", hash = "sha256:48db882e48575ce4b39659558b2f9f37c25b8d348e37a2b4e32971dd5a7d6227"}, - {file = "pydantic-1.10.17-py3-none-any.whl", hash = "sha256:e41b5b973e5c64f674b3b4720286ded184dcc26a691dd55f34391c62c6934688"}, - {file = "pydantic-1.10.17.tar.gz", hash = "sha256:f434160fb14b353caf634149baaf847206406471ba70e64657c1e8330277a991"}, + {file = "pydantic-2.8.0-py3-none-any.whl", hash = "sha256:ead4f3a1e92386a734ca1411cb25d94147cf8778ed5be6b56749047676d6364e"}, + {file = "pydantic-2.8.0.tar.gz", hash = "sha256:d970ffb9d030b710795878940bd0489842c638e7252fc4a19c3ae2f7da4d6141"}, ] [package.dependencies] -typing-extensions = ">=4.2.0" +annotated-types = ">=0.4.0" +pydantic-core = "2.20.0" +typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} [package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.20.0" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:e9dcd7fb34f7bfb239b5fa420033642fff0ad676b765559c3737b91f664d4fa9"}, + {file = "pydantic_core-2.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:649a764d9b0da29816889424697b2a3746963ad36d3e0968784ceed6e40c6355"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7701df088d0b05f3460f7ba15aec81ac8b0fb5690367dfd072a6c38cf5b7fdb5"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ab760f17c3e792225cdaef31ca23c0aea45c14ce80d8eff62503f86a5ab76bff"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb1ad5b4d73cde784cf64580166568074f5ccd2548d765e690546cff3d80937d"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b81ec2efc04fc1dbf400647d4357d64fb25543bae38d2d19787d69360aad21c9"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4a9732a5cad764ba37f3aa873dccb41b584f69c347a57323eda0930deec8e10"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6dc85b9e10cc21d9c1055f15684f76fa4facadddcb6cd63abab702eb93c98943"}, + {file = "pydantic_core-2.20.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:21d9f7e24f63fdc7118e6cc49defaab8c1d27570782f7e5256169d77498cf7c7"}, + {file = "pydantic_core-2.20.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b315685832ab9287e6124b5d74fc12dda31e6421d7f6b08525791452844bc2d"}, + {file = "pydantic_core-2.20.0-cp310-none-win32.whl", hash = "sha256:c3dc8ec8b87c7ad534c75b8855168a08a7036fdb9deeeed5705ba9410721c84d"}, + {file = "pydantic_core-2.20.0-cp310-none-win_amd64.whl", hash = "sha256:85770b4b37bb36ef93a6122601795231225641003e0318d23c6233c59b424279"}, + {file = "pydantic_core-2.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:58e251bb5a5998f7226dc90b0b753eeffa720bd66664eba51927c2a7a2d5f32c"}, + {file = "pydantic_core-2.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:78d584caac52c24240ef9ecd75de64c760bbd0e20dbf6973631815e3ef16ef8b"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5084ec9721f82bef5ff7c4d1ee65e1626783abb585f8c0993833490b63fe1792"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6d0f52684868db7c218437d260e14d37948b094493f2646f22d3dda7229bbe3f"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1def125d59a87fe451212a72ab9ed34c118ff771e5473fef4f2f95d8ede26d75"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b34480fd6778ab356abf1e9086a4ced95002a1e195e8d2fd182b0def9d944d11"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d42669d319db366cb567c3b444f43caa7ffb779bf9530692c6f244fc635a41eb"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:53b06aea7a48919a254b32107647be9128c066aaa6ee6d5d08222325f25ef175"}, + {file = "pydantic_core-2.20.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1f038156b696a1c39d763b2080aeefa87ddb4162c10aa9fabfefffc3dd8180fa"}, + {file = "pydantic_core-2.20.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3f0f3a4a23717280a5ee3ac4fb1f81d6fde604c9ec5100f7f6f987716bb8c137"}, + {file = "pydantic_core-2.20.0-cp311-none-win32.whl", hash = "sha256:316fe7c3fec017affd916a0c83d6f1ec697cbbbdf1124769fa73328e7907cc2e"}, + {file = "pydantic_core-2.20.0-cp311-none-win_amd64.whl", hash = "sha256:2d06a7fa437f93782e3f32d739c3ec189f82fca74336c08255f9e20cea1ed378"}, + {file = "pydantic_core-2.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:d6f8c49657f3eb7720ed4c9b26624063da14937fc94d1812f1e04a2204db3e17"}, + {file = "pydantic_core-2.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad1bd2f377f56fec11d5cfd0977c30061cd19f4fa199bf138b200ec0d5e27eeb"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed741183719a5271f97d93bbcc45ed64619fa38068aaa6e90027d1d17e30dc8d"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d82e5ed3a05f2dcb89c6ead2fd0dbff7ac09bc02c1b4028ece2d3a3854d049ce"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2ba34a099576234671f2e4274e5bc6813b22e28778c216d680eabd0db3f7dad"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:879ae6bb08a063b3e1b7ac8c860096d8fd6b48dd9b2690b7f2738b8c835e744b"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b0eefc7633a04c0694340aad91fbfd1986fe1a1e0c63a22793ba40a18fcbdc8"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73deadd6fd8a23e2f40b412b3ac617a112143c8989a4fe265050fd91ba5c0608"}, + {file = "pydantic_core-2.20.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:35681445dc85446fb105943d81ae7569aa7e89de80d1ca4ac3229e05c311bdb1"}, + {file = "pydantic_core-2.20.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0f6dd3612a3b9f91f2e63924ea18a4476656c6d01843ca20a4c09e00422195af"}, + {file = "pydantic_core-2.20.0-cp312-none-win32.whl", hash = "sha256:7e37b6bb6e90c2b8412b06373c6978d9d81e7199a40e24a6ef480e8acdeaf918"}, + {file = "pydantic_core-2.20.0-cp312-none-win_amd64.whl", hash = "sha256:7d4df13d1c55e84351fab51383520b84f490740a9f1fec905362aa64590b7a5d"}, + {file = "pydantic_core-2.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:d43e7ab3b65e4dc35a7612cfff7b0fd62dce5bc11a7cd198310b57f39847fd6c"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b6a24d7b5893392f2b8e3b7a0031ae3b14c6c1942a4615f0d8794fdeeefb08b"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b2f13c3e955a087c3ec86f97661d9f72a76e221281b2262956af381224cfc243"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:72432fd6e868c8d0a6849869e004b8bcae233a3c56383954c228316694920b38"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d70a8ff2d4953afb4cbe6211f17268ad29c0b47e73d3372f40e7775904bc28fc"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e49524917b8d3c2f42cd0d2df61178e08e50f5f029f9af1f402b3ee64574392"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4f0f71653b1c1bad0350bc0b4cc057ab87b438ff18fa6392533811ebd01439c"}, + {file = "pydantic_core-2.20.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:16197e6f4fdecb9892ed2436e507e44f0a1aa2cff3b9306d1c879ea2f9200997"}, + {file = "pydantic_core-2.20.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:763602504bf640b3ded3bba3f8ed8a1cc2fc6a87b8d55c1c5689f428c49c947e"}, + {file = "pydantic_core-2.20.0-cp313-none-win32.whl", hash = "sha256:a3f243f318bd9523277fa123b3163f4c005a3e8619d4b867064de02f287a564d"}, + {file = "pydantic_core-2.20.0-cp313-none-win_amd64.whl", hash = "sha256:03aceaf6a5adaad3bec2233edc5a7905026553916615888e53154807e404545c"}, + {file = "pydantic_core-2.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d6f2d8b8da1f03f577243b07bbdd3412eee3d37d1f2fd71d1513cbc76a8c1239"}, + {file = "pydantic_core-2.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a272785a226869416c6b3c1b7e450506152d3844207331f02f27173562c917e0"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efbb412d55a4ffe73963fed95c09ccb83647ec63b711c4b3752be10a56f0090b"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1e4f46189d8740561b43655263a41aac75ff0388febcb2c9ec4f1b60a0ec12f3"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87d3df115f4a3c8c5e4d5acf067d399c6466d7e604fc9ee9acbe6f0c88a0c3cf"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a340d2bdebe819d08f605e9705ed551c3feb97e4fd71822d7147c1e4bdbb9508"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:616b9c2f882393d422ba11b40e72382fe975e806ad693095e9a3b67c59ea6150"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:25c46bb2ff6084859bbcfdf4f1a63004b98e88b6d04053e8bf324e115398e9e7"}, + {file = "pydantic_core-2.20.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:23425eccef8f2c342f78d3a238c824623836c6c874d93c726673dbf7e56c78c0"}, + {file = "pydantic_core-2.20.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:52527e8f223ba29608d999d65b204676398009725007c9336651c2ec2d93cffc"}, + {file = "pydantic_core-2.20.0-cp38-none-win32.whl", hash = "sha256:1c3c5b7f70dd19a6845292b0775295ea81c61540f68671ae06bfe4421b3222c2"}, + {file = "pydantic_core-2.20.0-cp38-none-win_amd64.whl", hash = "sha256:8093473d7b9e908af1cef30025609afc8f5fd2a16ff07f97440fd911421e4432"}, + {file = "pydantic_core-2.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ee7785938e407418795e4399b2bf5b5f3cf6cf728077a7f26973220d58d885cf"}, + {file = "pydantic_core-2.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0e75794883d635071cf6b4ed2a5d7a1e50672ab7a051454c76446ef1ebcdcc91"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:344e352c96e53b4f56b53d24728217c69399b8129c16789f70236083c6ceb2ac"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:978d4123ad1e605daf1ba5e01d4f235bcf7b6e340ef07e7122e8e9cfe3eb61ab"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c05eaf6c863781eb834ab41f5963604ab92855822a2062897958089d1335dad"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bc7e43b4a528ffca8c9151b6a2ca34482c2fdc05e6aa24a84b7f475c896fc51d"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:658287a29351166510ebbe0a75c373600cc4367a3d9337b964dada8d38bcc0f4"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1dacf660d6de692fe351e8c806e7efccf09ee5184865893afbe8e59be4920b4a"}, + {file = "pydantic_core-2.20.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3e147fc6e27b9a487320d78515c5f29798b539179f7777018cedf51b7749e4f4"}, + {file = "pydantic_core-2.20.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c867230d715a3dd1d962c8d9bef0d3168994ed663e21bf748b6e3a529a129aab"}, + {file = "pydantic_core-2.20.0-cp39-none-win32.whl", hash = "sha256:22b813baf0dbf612752d8143a2dbf8e33ccb850656b7850e009bad2e101fc377"}, + {file = "pydantic_core-2.20.0-cp39-none-win_amd64.whl", hash = "sha256:3a7235b46c1bbe201f09b6f0f5e6c36b16bad3d0532a10493742f91fbdc8035f"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cafde15a6f7feaec2f570646e2ffc5b73412295d29134a29067e70740ec6ee20"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2aec8eeea0b08fd6bc2213d8e86811a07491849fd3d79955b62d83e32fa2ad5f"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:840200827984f1c4e114008abc2f5ede362d6e11ed0b5931681884dd41852ff1"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8ea1d8b7df522e5ced34993c423c3bf3735c53df8b2a15688a2f03a7d678800"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d5b8376a867047bf08910573deb95d3c8dfb976eb014ee24f3b5a61ccc5bee1b"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d08264b4460326cefacc179fc1411304d5af388a79910832835e6f641512358b"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:7a3639011c2e8a9628466f616ed7fb413f30032b891898e10895a0a8b5857d6c"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:05e83ce2f7eba29e627dd8066aa6c4c0269b2d4f889c0eba157233a353053cea"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:603a843fea76a595c8f661cd4da4d2281dff1e38c4a836a928eac1a2f8fe88e4"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ac76f30d5d3454f4c28826d891fe74d25121a346c69523c9810ebba43f3b1cec"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e3b1d4b1b3f6082849f9b28427ef147a5b46a6132a3dbaf9ca1baa40c88609"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2761f71faed820e25ec62eacba670d1b5c2709bb131a19fcdbfbb09884593e5a"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a0586cddbf4380e24569b8a05f234e7305717cc8323f50114dfb2051fcbce2a3"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:b8c46a8cf53e849eea7090f331ae2202cd0f1ceb090b00f5902c423bd1e11805"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b4a085bd04af7245e140d1b95619fe8abb445a3d7fdf219b3f80c940853268ef"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:116b326ac82c8b315e7348390f6d30bcfe6e688a7d3f1de50ff7bcc2042a23c2"}, + {file = "pydantic_core-2.20.0.tar.gz", hash = "sha256:366be8e64e0cb63d87cf79b4e1765c0703dd6313c729b22e7b9e378db6b96877"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydocstyle" @@ -2417,4 +2489,4 @@ propcache = ">=0.2.0" [metadata] lock-version = "2.0" python-versions = "3.11.*" -content-hash = "275bcd923db6c350fdd8e830f4508c45073e49fb19ef1a9af0c8eb904d2af7d7" +content-hash = "fc56a6502e0f26316b3c6d1e96fd0845bdd661c8c3f5416efe0587b7dc0f5c92" diff --git a/athena/modules/modeling/module_modeling_llm/pyproject.toml b/athena/modules/modeling/module_modeling_llm/pyproject.toml index fdc2f28b..f5ea1037 100644 --- a/athena/modules/modeling/module_modeling_llm/pyproject.toml +++ b/athena/modules/modeling/module_modeling_llm/pyproject.toml @@ -17,7 +17,7 @@ tiktoken = "0.7.0" langsmith = "0.1.106" [tool.poetry.group.dev.dependencies] -pydantic = "1.10.17" +pydantic = "2.8.0" prospector = "^1.10.2" types-requests = "2.31.0.8" diff --git a/athena/modules/programming/module_programming_llm/poetry.lock b/athena/modules/programming/module_programming_llm/poetry.lock index 318c0e68..e682ac5b 100644 --- a/athena/modules/programming/module_programming_llm/poetry.lock +++ b/athena/modules/programming/module_programming_llm/poetry.lock @@ -122,6 +122,17 @@ files = [ [package.dependencies] frozenlist = ">=1.1.0" +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + [[package]] name = "anyio" version = "4.7.0" @@ -166,7 +177,7 @@ develop = true [package.dependencies] fastapi = "^0.109.1" gitpython = "^3.1.41" -httpx = "^0.24.1" +httpx = "^0.26.0" psycopg2 = "^2.9.9" sqlalchemy = {version = "^2.0.21", extras = ["mypy"]} uvicorn = "^0.23.0" @@ -676,39 +687,40 @@ files = [ [[package]] name = "httpcore" -version = "0.17.3" +version = "1.0.8" description = "A minimal low-level HTTP client." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "httpcore-0.17.3-py3-none-any.whl", hash = "sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87"}, - {file = "httpcore-0.17.3.tar.gz", hash = "sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888"}, + {file = "httpcore-1.0.8-py3-none-any.whl", hash = "sha256:5254cf149bcb5f75e9d1b2b9f729ea4a4b883d1ad7379fc632b727cec23674be"}, + {file = "httpcore-1.0.8.tar.gz", hash = "sha256:86e94505ed24ea06514883fd44d2bc02d90e77e7979c8eb71b90f41d364a1bad"}, ] [package.dependencies] -anyio = ">=3.0,<5.0" certifi = "*" h11 = ">=0.13,<0.15" -sniffio = "==1.*" [package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.24.1" +version = "0.26.0" description = "The next generation HTTP client." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "httpx-0.24.1-py3-none-any.whl", hash = "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd"}, - {file = "httpx-0.24.1.tar.gz", hash = "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd"}, + {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"}, + {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"}, ] [package.dependencies] +anyio = "*" certifi = "*" -httpcore = ">=0.15.0,<0.18.0" +httpcore = "==1.*" idna = "*" sniffio = "*" @@ -1423,18 +1435,17 @@ type = ["mypy (>=1.11.2)"] [[package]] name = "promptlayer" -version = "0.1.99" +version = "0.1.96" description = "PromptLayer is a package to keep track of your GPT models training" optional = false -python-versions = ">=3.8.1,<4.0" +python-versions = "*" files = [ - {file = "promptlayer-0.1.99-py3-none-any.whl", hash = "sha256:8cfdb67adfa9ad2508e35a67dd0d1f42aa80afe6e43fbf74e0b5c9ab3f9e7b32"}, - {file = "promptlayer-0.1.99.tar.gz", hash = "sha256:7bf839c50a921d2c7244ebf48c88ccb761df3d05c0dd18978d1be3c792287688"}, + {file = "promptlayer-0.1.96-py3-none-any.whl", hash = "sha256:ad2f214c3814ec86950e9f6dc76e34903e4839c25e844a9ea27c33bc18cb5af3"}, + {file = "promptlayer-0.1.96.tar.gz", hash = "sha256:ccd8d839955e97ae1dc25e8c7d29dd647622772313962539f200d245c32b8037"}, ] [package.dependencies] -pydantic = ">=1,<2" -requests = ">=2.31.0,<3.0.0" +requests = "*" [[package]] name = "propcache" @@ -1596,62 +1607,122 @@ files = [ [[package]] name = "pydantic" -version = "1.10.17" -description = "Data validation and settings management using python type hints" +version = "2.8.0" +description = "Data validation using Python type hints" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic-1.10.17-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fa51175313cc30097660b10eec8ca55ed08bfa07acbfe02f7a42f6c242e9a4b"}, - {file = "pydantic-1.10.17-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7e8988bb16988890c985bd2093df9dd731bfb9d5e0860db054c23034fab8f7a"}, - {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:371dcf1831f87c9e217e2b6a0c66842879a14873114ebb9d0861ab22e3b5bb1e"}, - {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4866a1579c0c3ca2c40575398a24d805d4db6cb353ee74df75ddeee3c657f9a7"}, - {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:543da3c6914795b37785703ffc74ba4d660418620cc273490d42c53949eeeca6"}, - {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7623b59876f49e61c2e283551cc3647616d2fbdc0b4d36d3d638aae8547ea681"}, - {file = "pydantic-1.10.17-cp310-cp310-win_amd64.whl", hash = "sha256:409b2b36d7d7d19cd8310b97a4ce6b1755ef8bd45b9a2ec5ec2b124db0a0d8f3"}, - {file = "pydantic-1.10.17-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fa43f362b46741df8f201bf3e7dff3569fa92069bcc7b4a740dea3602e27ab7a"}, - {file = "pydantic-1.10.17-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2a72d2a5ff86a3075ed81ca031eac86923d44bc5d42e719d585a8eb547bf0c9b"}, - {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4ad32aed3bf5eea5ca5decc3d1bbc3d0ec5d4fbcd72a03cdad849458decbc63"}, - {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb4e741782e236ee7dc1fb11ad94dc56aabaf02d21df0e79e0c21fe07c95741"}, - {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d2f89a719411cb234105735a520b7c077158a81e0fe1cb05a79c01fc5eb59d3c"}, - {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db3b48d9283d80a314f7a682f7acae8422386de659fffaba454b77a083c3937d"}, - {file = "pydantic-1.10.17-cp311-cp311-win_amd64.whl", hash = "sha256:9c803a5113cfab7bbb912f75faa4fc1e4acff43e452c82560349fff64f852e1b"}, - {file = "pydantic-1.10.17-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:820ae12a390c9cbb26bb44913c87fa2ff431a029a785642c1ff11fed0a095fcb"}, - {file = "pydantic-1.10.17-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c1e51d1af306641b7d1574d6d3307eaa10a4991542ca324f0feb134fee259815"}, - {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e53fb834aae96e7b0dadd6e92c66e7dd9cdf08965340ed04c16813102a47fab"}, - {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e2495309b1266e81d259a570dd199916ff34f7f51f1b549a0d37a6d9b17b4dc"}, - {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:098ad8de840c92ea586bf8efd9e2e90c6339d33ab5c1cfbb85be66e4ecf8213f"}, - {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:525bbef620dac93c430d5d6bdbc91bdb5521698d434adf4434a7ef6ffd5c4b7f"}, - {file = "pydantic-1.10.17-cp312-cp312-win_amd64.whl", hash = "sha256:6654028d1144df451e1da69a670083c27117d493f16cf83da81e1e50edce72ad"}, - {file = "pydantic-1.10.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c87cedb4680d1614f1d59d13fea353faf3afd41ba5c906a266f3f2e8c245d655"}, - {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11289fa895bcbc8f18704efa1d8020bb9a86314da435348f59745473eb042e6b"}, - {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94833612d6fd18b57c359a127cbfd932d9150c1b72fea7c86ab58c2a77edd7c7"}, - {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d4ecb515fa7cb0e46e163ecd9d52f9147ba57bc3633dca0e586cdb7a232db9e3"}, - {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7017971ffa7fd7808146880aa41b266e06c1e6e12261768a28b8b41ba55c8076"}, - {file = "pydantic-1.10.17-cp37-cp37m-win_amd64.whl", hash = "sha256:e840e6b2026920fc3f250ea8ebfdedf6ea7a25b77bf04c6576178e681942ae0f"}, - {file = "pydantic-1.10.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bfbb18b616abc4df70591b8c1ff1b3eabd234ddcddb86b7cac82657ab9017e33"}, - {file = "pydantic-1.10.17-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebb249096d873593e014535ab07145498957091aa6ae92759a32d40cb9998e2e"}, - {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8c209af63ccd7b22fba94b9024e8b7fd07feffee0001efae50dd99316b27768"}, - {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b40c9e13a0b61583e5599e7950490c700297b4a375b55b2b592774332798b7"}, - {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c31d281c7485223caf6474fc2b7cf21456289dbaa31401844069b77160cab9c7"}, - {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae5184e99a060a5c80010a2d53c99aee76a3b0ad683d493e5f0620b5d86eeb75"}, - {file = "pydantic-1.10.17-cp38-cp38-win_amd64.whl", hash = "sha256:ad1e33dc6b9787a6f0f3fd132859aa75626528b49cc1f9e429cdacb2608ad5f0"}, - {file = "pydantic-1.10.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7e17c0ee7192e54a10943f245dc79e36d9fe282418ea05b886e1c666063a7b54"}, - {file = "pydantic-1.10.17-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cafb9c938f61d1b182dfc7d44a7021326547b7b9cf695db5b68ec7b590214773"}, - {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95ef534e3c22e5abbdbdd6f66b6ea9dac3ca3e34c5c632894f8625d13d084cbe"}, - {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d96b8799ae3d782df7ec9615cb59fc32c32e1ed6afa1b231b0595f6516e8ab"}, - {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ab2f976336808fd5d539fdc26eb51f9aafc1f4b638e212ef6b6f05e753c8011d"}, - {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8ad363330557beac73159acfbeed220d5f1bfcd6b930302a987a375e02f74fd"}, - {file = "pydantic-1.10.17-cp39-cp39-win_amd64.whl", hash = "sha256:48db882e48575ce4b39659558b2f9f37c25b8d348e37a2b4e32971dd5a7d6227"}, - {file = "pydantic-1.10.17-py3-none-any.whl", hash = "sha256:e41b5b973e5c64f674b3b4720286ded184dcc26a691dd55f34391c62c6934688"}, - {file = "pydantic-1.10.17.tar.gz", hash = "sha256:f434160fb14b353caf634149baaf847206406471ba70e64657c1e8330277a991"}, + {file = "pydantic-2.8.0-py3-none-any.whl", hash = "sha256:ead4f3a1e92386a734ca1411cb25d94147cf8778ed5be6b56749047676d6364e"}, + {file = "pydantic-2.8.0.tar.gz", hash = "sha256:d970ffb9d030b710795878940bd0489842c638e7252fc4a19c3ae2f7da4d6141"}, ] [package.dependencies] -typing-extensions = ">=4.2.0" +annotated-types = ">=0.4.0" +pydantic-core = "2.20.0" +typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} [package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.20.0" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:e9dcd7fb34f7bfb239b5fa420033642fff0ad676b765559c3737b91f664d4fa9"}, + {file = "pydantic_core-2.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:649a764d9b0da29816889424697b2a3746963ad36d3e0968784ceed6e40c6355"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7701df088d0b05f3460f7ba15aec81ac8b0fb5690367dfd072a6c38cf5b7fdb5"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ab760f17c3e792225cdaef31ca23c0aea45c14ce80d8eff62503f86a5ab76bff"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb1ad5b4d73cde784cf64580166568074f5ccd2548d765e690546cff3d80937d"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b81ec2efc04fc1dbf400647d4357d64fb25543bae38d2d19787d69360aad21c9"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4a9732a5cad764ba37f3aa873dccb41b584f69c347a57323eda0930deec8e10"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6dc85b9e10cc21d9c1055f15684f76fa4facadddcb6cd63abab702eb93c98943"}, + {file = "pydantic_core-2.20.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:21d9f7e24f63fdc7118e6cc49defaab8c1d27570782f7e5256169d77498cf7c7"}, + {file = "pydantic_core-2.20.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b315685832ab9287e6124b5d74fc12dda31e6421d7f6b08525791452844bc2d"}, + {file = "pydantic_core-2.20.0-cp310-none-win32.whl", hash = "sha256:c3dc8ec8b87c7ad534c75b8855168a08a7036fdb9deeeed5705ba9410721c84d"}, + {file = "pydantic_core-2.20.0-cp310-none-win_amd64.whl", hash = "sha256:85770b4b37bb36ef93a6122601795231225641003e0318d23c6233c59b424279"}, + {file = "pydantic_core-2.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:58e251bb5a5998f7226dc90b0b753eeffa720bd66664eba51927c2a7a2d5f32c"}, + {file = "pydantic_core-2.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:78d584caac52c24240ef9ecd75de64c760bbd0e20dbf6973631815e3ef16ef8b"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5084ec9721f82bef5ff7c4d1ee65e1626783abb585f8c0993833490b63fe1792"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6d0f52684868db7c218437d260e14d37948b094493f2646f22d3dda7229bbe3f"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1def125d59a87fe451212a72ab9ed34c118ff771e5473fef4f2f95d8ede26d75"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b34480fd6778ab356abf1e9086a4ced95002a1e195e8d2fd182b0def9d944d11"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d42669d319db366cb567c3b444f43caa7ffb779bf9530692c6f244fc635a41eb"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:53b06aea7a48919a254b32107647be9128c066aaa6ee6d5d08222325f25ef175"}, + {file = "pydantic_core-2.20.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1f038156b696a1c39d763b2080aeefa87ddb4162c10aa9fabfefffc3dd8180fa"}, + {file = "pydantic_core-2.20.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3f0f3a4a23717280a5ee3ac4fb1f81d6fde604c9ec5100f7f6f987716bb8c137"}, + {file = "pydantic_core-2.20.0-cp311-none-win32.whl", hash = "sha256:316fe7c3fec017affd916a0c83d6f1ec697cbbbdf1124769fa73328e7907cc2e"}, + {file = "pydantic_core-2.20.0-cp311-none-win_amd64.whl", hash = "sha256:2d06a7fa437f93782e3f32d739c3ec189f82fca74336c08255f9e20cea1ed378"}, + {file = "pydantic_core-2.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:d6f8c49657f3eb7720ed4c9b26624063da14937fc94d1812f1e04a2204db3e17"}, + {file = "pydantic_core-2.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad1bd2f377f56fec11d5cfd0977c30061cd19f4fa199bf138b200ec0d5e27eeb"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed741183719a5271f97d93bbcc45ed64619fa38068aaa6e90027d1d17e30dc8d"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d82e5ed3a05f2dcb89c6ead2fd0dbff7ac09bc02c1b4028ece2d3a3854d049ce"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2ba34a099576234671f2e4274e5bc6813b22e28778c216d680eabd0db3f7dad"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:879ae6bb08a063b3e1b7ac8c860096d8fd6b48dd9b2690b7f2738b8c835e744b"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b0eefc7633a04c0694340aad91fbfd1986fe1a1e0c63a22793ba40a18fcbdc8"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73deadd6fd8a23e2f40b412b3ac617a112143c8989a4fe265050fd91ba5c0608"}, + {file = "pydantic_core-2.20.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:35681445dc85446fb105943d81ae7569aa7e89de80d1ca4ac3229e05c311bdb1"}, + {file = "pydantic_core-2.20.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0f6dd3612a3b9f91f2e63924ea18a4476656c6d01843ca20a4c09e00422195af"}, + {file = "pydantic_core-2.20.0-cp312-none-win32.whl", hash = "sha256:7e37b6bb6e90c2b8412b06373c6978d9d81e7199a40e24a6ef480e8acdeaf918"}, + {file = "pydantic_core-2.20.0-cp312-none-win_amd64.whl", hash = "sha256:7d4df13d1c55e84351fab51383520b84f490740a9f1fec905362aa64590b7a5d"}, + {file = "pydantic_core-2.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:d43e7ab3b65e4dc35a7612cfff7b0fd62dce5bc11a7cd198310b57f39847fd6c"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b6a24d7b5893392f2b8e3b7a0031ae3b14c6c1942a4615f0d8794fdeeefb08b"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b2f13c3e955a087c3ec86f97661d9f72a76e221281b2262956af381224cfc243"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:72432fd6e868c8d0a6849869e004b8bcae233a3c56383954c228316694920b38"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d70a8ff2d4953afb4cbe6211f17268ad29c0b47e73d3372f40e7775904bc28fc"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e49524917b8d3c2f42cd0d2df61178e08e50f5f029f9af1f402b3ee64574392"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4f0f71653b1c1bad0350bc0b4cc057ab87b438ff18fa6392533811ebd01439c"}, + {file = "pydantic_core-2.20.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:16197e6f4fdecb9892ed2436e507e44f0a1aa2cff3b9306d1c879ea2f9200997"}, + {file = "pydantic_core-2.20.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:763602504bf640b3ded3bba3f8ed8a1cc2fc6a87b8d55c1c5689f428c49c947e"}, + {file = "pydantic_core-2.20.0-cp313-none-win32.whl", hash = "sha256:a3f243f318bd9523277fa123b3163f4c005a3e8619d4b867064de02f287a564d"}, + {file = "pydantic_core-2.20.0-cp313-none-win_amd64.whl", hash = "sha256:03aceaf6a5adaad3bec2233edc5a7905026553916615888e53154807e404545c"}, + {file = "pydantic_core-2.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d6f2d8b8da1f03f577243b07bbdd3412eee3d37d1f2fd71d1513cbc76a8c1239"}, + {file = "pydantic_core-2.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a272785a226869416c6b3c1b7e450506152d3844207331f02f27173562c917e0"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efbb412d55a4ffe73963fed95c09ccb83647ec63b711c4b3752be10a56f0090b"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1e4f46189d8740561b43655263a41aac75ff0388febcb2c9ec4f1b60a0ec12f3"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87d3df115f4a3c8c5e4d5acf067d399c6466d7e604fc9ee9acbe6f0c88a0c3cf"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a340d2bdebe819d08f605e9705ed551c3feb97e4fd71822d7147c1e4bdbb9508"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:616b9c2f882393d422ba11b40e72382fe975e806ad693095e9a3b67c59ea6150"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:25c46bb2ff6084859bbcfdf4f1a63004b98e88b6d04053e8bf324e115398e9e7"}, + {file = "pydantic_core-2.20.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:23425eccef8f2c342f78d3a238c824623836c6c874d93c726673dbf7e56c78c0"}, + {file = "pydantic_core-2.20.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:52527e8f223ba29608d999d65b204676398009725007c9336651c2ec2d93cffc"}, + {file = "pydantic_core-2.20.0-cp38-none-win32.whl", hash = "sha256:1c3c5b7f70dd19a6845292b0775295ea81c61540f68671ae06bfe4421b3222c2"}, + {file = "pydantic_core-2.20.0-cp38-none-win_amd64.whl", hash = "sha256:8093473d7b9e908af1cef30025609afc8f5fd2a16ff07f97440fd911421e4432"}, + {file = "pydantic_core-2.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ee7785938e407418795e4399b2bf5b5f3cf6cf728077a7f26973220d58d885cf"}, + {file = "pydantic_core-2.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0e75794883d635071cf6b4ed2a5d7a1e50672ab7a051454c76446ef1ebcdcc91"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:344e352c96e53b4f56b53d24728217c69399b8129c16789f70236083c6ceb2ac"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:978d4123ad1e605daf1ba5e01d4f235bcf7b6e340ef07e7122e8e9cfe3eb61ab"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c05eaf6c863781eb834ab41f5963604ab92855822a2062897958089d1335dad"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bc7e43b4a528ffca8c9151b6a2ca34482c2fdc05e6aa24a84b7f475c896fc51d"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:658287a29351166510ebbe0a75c373600cc4367a3d9337b964dada8d38bcc0f4"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1dacf660d6de692fe351e8c806e7efccf09ee5184865893afbe8e59be4920b4a"}, + {file = "pydantic_core-2.20.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3e147fc6e27b9a487320d78515c5f29798b539179f7777018cedf51b7749e4f4"}, + {file = "pydantic_core-2.20.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c867230d715a3dd1d962c8d9bef0d3168994ed663e21bf748b6e3a529a129aab"}, + {file = "pydantic_core-2.20.0-cp39-none-win32.whl", hash = "sha256:22b813baf0dbf612752d8143a2dbf8e33ccb850656b7850e009bad2e101fc377"}, + {file = "pydantic_core-2.20.0-cp39-none-win_amd64.whl", hash = "sha256:3a7235b46c1bbe201f09b6f0f5e6c36b16bad3d0532a10493742f91fbdc8035f"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cafde15a6f7feaec2f570646e2ffc5b73412295d29134a29067e70740ec6ee20"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2aec8eeea0b08fd6bc2213d8e86811a07491849fd3d79955b62d83e32fa2ad5f"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:840200827984f1c4e114008abc2f5ede362d6e11ed0b5931681884dd41852ff1"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8ea1d8b7df522e5ced34993c423c3bf3735c53df8b2a15688a2f03a7d678800"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d5b8376a867047bf08910573deb95d3c8dfb976eb014ee24f3b5a61ccc5bee1b"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d08264b4460326cefacc179fc1411304d5af388a79910832835e6f641512358b"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:7a3639011c2e8a9628466f616ed7fb413f30032b891898e10895a0a8b5857d6c"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:05e83ce2f7eba29e627dd8066aa6c4c0269b2d4f889c0eba157233a353053cea"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:603a843fea76a595c8f661cd4da4d2281dff1e38c4a836a928eac1a2f8fe88e4"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ac76f30d5d3454f4c28826d891fe74d25121a346c69523c9810ebba43f3b1cec"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e3b1d4b1b3f6082849f9b28427ef147a5b46a6132a3dbaf9ca1baa40c88609"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2761f71faed820e25ec62eacba670d1b5c2709bb131a19fcdbfbb09884593e5a"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a0586cddbf4380e24569b8a05f234e7305717cc8323f50114dfb2051fcbce2a3"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:b8c46a8cf53e849eea7090f331ae2202cd0f1ceb090b00f5902c423bd1e11805"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b4a085bd04af7245e140d1b95619fe8abb445a3d7fdf219b3f80c940853268ef"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:116b326ac82c8b315e7348390f6d30bcfe6e688a7d3f1de50ff7bcc2042a23c2"}, + {file = "pydantic_core-2.20.0.tar.gz", hash = "sha256:366be8e64e0cb63d87cf79b4e1765c0703dd6313c729b22e7b9e378db6b96877"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydocstyle" @@ -2450,4 +2521,4 @@ propcache = ">=0.2.0" [metadata] lock-version = "2.0" python-versions = "3.11.*" -content-hash = "08300b16bb143b2f1440bddacd397dbb006b2274fc5674e55c9b3b11bde3a4a3" +content-hash = "8801f7a9556b54d86eed08f4e967d63a0e2bbf8bc9803f2a2507aa7ff122c56a" diff --git a/athena/modules/programming/module_programming_llm/pyproject.toml b/athena/modules/programming/module_programming_llm/pyproject.toml index e02e1117..91925cad 100644 --- a/athena/modules/programming/module_programming_llm/pyproject.toml +++ b/athena/modules/programming/module_programming_llm/pyproject.toml @@ -20,7 +20,7 @@ nltk = "3.9.1" [tool.poetry.group.dev.dependencies] types-requests = "^2.31.0.8" -pydantic = "1.10.17" +pydantic = "2.8.0" prospector = "^1.10.2" [tool.poetry.scripts] diff --git a/athena/modules/text/module_text_llm/module_text_llm/__main__.py b/athena/modules/text/module_text_llm/module_text_llm/__main__.py index e705b974..8fae22ba 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/__main__.py +++ b/athena/modules/text/module_text_llm/module_text_llm/__main__.py @@ -11,7 +11,8 @@ from module_text_llm.evaluation import get_feedback_statistics, get_llm_statistics from module_text_llm.generate_evaluation import generate_evaluation from module_text_llm.approach_controller import generate_suggestions -from module_text_llm.in_context_learning.feedback_icl.store_feedback_icl import store_feedback_icl +from module_text_llm.in_context_learning.feedback_icl.store_feedback import store_feedback + @submissions_consumer def receive_submissions(exercise: Exercise, submissions: List[Submission]): logger.info("receive_submissions: Received %d submissions for exercise %d", len(submissions), exercise.id) @@ -27,7 +28,7 @@ def select_submission(exercise: Exercise, submissions: List[Submission]) -> Subm def process_incoming_feedback(exercise: Exercise, submission: Submission, feedbacks: List[Feedback]): logger.info("Will try to create Schema") logger.info("process_feedback: Received %d feedbacks for submission %d of exercise %d.", len(feedbacks), submission.id, exercise.id) - store_feedback_icl(submission, exercise, feedbacks) + store_feedback(submission, exercise, feedbacks) @feedback_provider async def suggest_feedback(exercise: Exercise, submission: Submission, is_graded: bool, module_config: Configuration) -> List[Feedback]: diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context_icl.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context.py similarity index 93% rename from athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context_icl.py rename to athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context.py index 0f1fa89f..599ff04b 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context_icl.py +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/retrieve_rag_context.py @@ -1,6 +1,6 @@ -from module_text_llm.in_context_learning.feedback_icl.store_feedback_icl import query_embedding +from module_text_llm.in_context_learning.feedback_icl.store_feedback import query_embedding -def retrieve_rag_context_icl(submission_segment: str ,exercise_id: int) -> str: +def retrieve_rag_context(submission_segment: str ,exercise_id: int) -> str: """ This method takes a segment from a submission and for a given exercise id, returns feedback that has been given for similar texts. @@ -39,7 +39,7 @@ def format_context(title,description,credits,reference): def format_rag_context(rag_context): formatted_string = """ **Tutor provided Feedback from previous submissions of this same exercise. This are possible examples that could help with the grading of the current submission. However they are not identical - so please be careful when using them. You must carefully decide whether this references are relevant.**\n + so please be careful when using them. You must carefully decide whether these references are relevant.**\n **\n""" formatted_string += "\n" + "-"*40 + "\n" diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback_icl.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback.py similarity index 89% rename from athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback_icl.py rename to athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback.py index c97af474..dc6feefd 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback_icl.py +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/feedback_icl/store_feedback.py @@ -25,7 +25,7 @@ def create_schema(client): ] ) -def store_feedback_icl(submission: Submission, exercise: Exercise, feedbacks: List[Feedback]): +def store_feedback(submission: Submission, exercise: Exercise, feedbacks: List[Feedback]): client = weaviate.connect_to_local() try: create_schema(client) @@ -33,10 +33,10 @@ def store_feedback_icl(submission: Submission, exercise: Exercise, feedbacks: Li logger.info("Storing feedback for submission %d of exercise %d.", submission.id, exercise.id) for feedback in feedbacks: chunk = get_reference(feedback, submission.text) - store_feedback(exercise.id, submission.id, feedback,chunk, client) + store_single_feedback(exercise.id, submission.id, feedback,chunk, client) client.close() -def store_feedback(exercise_id, submission_id, feedback, chunk, client): +def store_single_feedback(exercise_id, submission_id, feedback, chunk, client): """ Store feedback in the Weaviate database. """ @@ -56,7 +56,7 @@ def store_feedback(exercise_id, submission_id, feedback, chunk, client): ) return uuid -def query_embedding (query,exercise_id,results_limit=1): +def query_embedding(query,exercise_id,results_limit=1): logger.info("Querying weaviate database") client = weaviate.connect_to_local() feedbacks = client.collections.get("Feedback") diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py index 990fa931..0af7d28a 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py @@ -13,10 +13,9 @@ from llm_core.utils.predict_and_parse import predict_and_parse from module_text_llm.helpers.utils import add_sentence_numbers, get_index_range_from_line_range, format_grading_instructions from module_text_llm.in_context_learning.prompt_generate_suggestions import AssessmentModel -# from module_text_llm.in_context_learning.agent import TutorAgent from module_text_llm.in_context_learning.ollama_prompt import system_message_segment, human_message_segment, Segmentation, system_message, human_message -from module_text_llm.in_context_learning.feedback_icl.retrieve_rag_context_icl import retrieve_rag_context_icl +from module_text_llm.in_context_learning.feedback_icl.retrieve_rag_context import retrieve_rag_context async def generate_suggestions(exercise: Exercise, submission: Submission, config:ApproachConfig, debug: bool, is_graded :bool) -> List[Feedback]: @@ -64,19 +63,22 @@ async def generate_suggestions(exercise: Exercise, submission: Submission, confi model=model, system_message=system_message_segment, human_message=human_message_segment, - pydantic_object=Segmentation - ) + pydantic_object=Segmentation) + segmentation_prompt_input = { "grading_instructions": format_grading_instructions(exercise.grading_instructions, exercise.grading_criteria), "submission": submission.text, "problem_statement": exercise.problem_statement or "No problem statement.", } + chain = segmentation_prompt | model segments = chain.invoke( segmentation_prompt_input) + for segment in segments: - formatted_rag_context += retrieve_rag_context_icl(segment[0],exercise.id) - prompt_input["rag_context"] = formatted_rag_context - + formatted_rag_context += retrieve_rag_context(segment[0],exercise.id) + + prompt_input["rag_context"] = formatted_rag_context + result = await predict_and_parse( model=model, chat_prompt=chat_prompt, @@ -87,6 +89,7 @@ async def generate_suggestions(exercise: Exercise, submission: Submission, confi f"exercise-{exercise.id}", f"submission-{submission.id}", ],) + if debug: emit_meta("generate_suggestions", { "prompt": chat_prompt.format(**prompt_input), From 3ed001f89983cf4b0f0ea94548386fe9c0dcd9a0 Mon Sep 17 00:00:00 2001 From: = Enea_Gore Date: Thu, 24 Apr 2025 20:16:25 +0200 Subject: [PATCH 5/6] rename segmentation prompt --- .../in_context_learning/generate_suggestions.py | 4 +--- .../{ollama_prompt.py => segmentation_prompt.py} | 0 2 files changed, 1 insertion(+), 3 deletions(-) rename athena/modules/text/module_text_llm/module_text_llm/in_context_learning/{ollama_prompt.py => segmentation_prompt.py} (100%) diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py index 0af7d28a..6a7e5392 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/generate_suggestions.py @@ -8,13 +8,11 @@ check_prompt_length_and_omit_features_if_necessary, num_tokens_from_prompt, ) -from langchain_community.chat_models import ChatOllama # type: ignore from llm_core.utils.predict_and_parse import predict_and_parse from module_text_llm.helpers.utils import add_sentence_numbers, get_index_range_from_line_range, format_grading_instructions +from module_text_llm.in_context_learning.segmentation_prompt import system_message_segment, human_message_segment, Segmentation from module_text_llm.in_context_learning.prompt_generate_suggestions import AssessmentModel -from module_text_llm.in_context_learning.ollama_prompt import system_message_segment, human_message_segment, Segmentation, system_message, human_message - from module_text_llm.in_context_learning.feedback_icl.retrieve_rag_context import retrieve_rag_context diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/ollama_prompt.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/segmentation_prompt.py similarity index 100% rename from athena/modules/text/module_text_llm/module_text_llm/in_context_learning/ollama_prompt.py rename to athena/modules/text/module_text_llm/module_text_llm/in_context_learning/segmentation_prompt.py From fc7aea28c71a8c427bec7fa5c194906eb46b22a6 Mon Sep 17 00:00:00 2001 From: = Enea_Gore Date: Thu, 24 Apr 2025 20:20:01 +0200 Subject: [PATCH 6/6] simplify segmentation prompt --- .../segmentation_prompt.py | 53 +------------------ 1 file changed, 1 insertion(+), 52 deletions(-) diff --git a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/segmentation_prompt.py b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/segmentation_prompt.py index 9641a380..b824c297 100644 --- a/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/segmentation_prompt.py +++ b/athena/modules/text/module_text_llm/module_text_llm/in_context_learning/segmentation_prompt.py @@ -28,55 +28,4 @@ class Segmentation(BaseModel): human_message_segment = """ # Submission # {submission} -""" -system_message = """You are an AI tutor for text assessment at a prestigious university. - -# Task -Create graded feedback suggestions for a student's text submission that a human tutor would accept. Meaning, the feedback you provide should be applicable to the submission with little to no modification. - -# Problem statement -{problem_statement} - -# Example solution -{example_solution} - -# Grading instructions -{grading_instructions} -Max points: {max_points}, bonus points: {bonus_points} -The exercise id is: {exercise_id} --------------------------- - -You have access to the following tutor feedback on similar texts: -{rag_context} -Respond in json. -""" - -human_message = """Student's submission to grade (with sentence numbers : ): - -{submission} -""" - -# Input Prompt -class GenerateSuggestionsPrompt(BaseModel): - """Features available: **{problem_statement}**, **{example_solution}**, **{grading_instructions}**, **{max_points}**, **{bonus_points}**, **{submission}** - -_Note: **{problem_statement}**, **{example_solution}**, or **{grading_instructions}** might be omitted if the input is too long._""" - system_message: str = Field(default=system_message, - description="Message for priming AI behavior and instructing it what to do.") - human_message: str = Field(default=human_message, - description="Message from a human. The input on which the AI is supposed to act.") - -# Output Object -class FeedbackModel(BaseModel): - title: str = Field(description="Very short title, i.e. feedback category or similar", example="Logic Error") - description: str = Field(description="Feedback description") - line_start: Optional[int] = Field(description="Referenced line number start, or empty if unreferenced") - line_end: Optional[int] = Field(description="Referenced line number end, or empty if unreferenced") - credits: float = Field(0.0, description="Number of points received/deducted") - grading_instruction_id: Optional[int] = Field( - description="ID of the grading instruction that was used to generate this feedback, or empty if no grading instruction was used" - ) - -class AssessmentModel(BaseModel): - """Collection of feedbacks making up an assessment""" - feedbacks: List[FeedbackModel] = Field(description="Assessment feedbacks") \ No newline at end of file +""" \ No newline at end of file