├── .env.sample ├── .gitignore ├── .vscode └── settings.json ├── README.md ├── imgs ├── mermaid_ai_agent.png └── setup.png ├── pyproject.toml ├── src └── mermaid_agent │ ├── __init__.py │ ├── examples.py │ ├── main.py │ ├── mermaid_agent.py │ ├── modules │ ├── __init__.py │ ├── chain.py │ ├── llm_module.py │ ├── mermaid.py │ ├── typings.py │ └── utils.py │ └── tests │ ├── __init__.py │ ├── chainable_test.py │ └── llm_test.py └── uv.lock /.env.sample: -------------------------------------------------------------------------------- 1 | ANTHROPIC_API_KEY= 2 | OPENAI_API_KEY= 3 | VERTEX_API_KEY= 4 | GROQ_API_KEY= -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/latest/usage/project/#working-with-version-control 110 | .pdm.toml 111 | .pdm-python 112 | .pdm-build/ 113 | 114 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 115 | __pypackages__/ 116 | 117 | # Celery stuff 118 | celerybeat-schedule 119 | celerybeat.pid 120 | 121 | # SageMath parsed files 122 | *.sage.py 123 | 124 | # Environments 125 | .env 126 | .venv 127 | env/ 128 | venv/ 129 | ENV/ 130 | env.bak/ 131 | venv.bak/ 132 | 133 | # Spyder project settings 134 | .spyderproject 135 | .spyproject 136 | 137 | # Rope project settings 138 | .ropeproject 139 | 140 | # mkdocs documentation 141 | /site 142 | 143 | # mypy 144 | .mypy_cache/ 145 | .dmypy.json 146 | dmypy.json 147 | 148 | # Pyre type checker 149 | .pyre/ 150 | 151 | # pytype static type analyzer 152 | .pytype/ 153 | 154 | # Cython debug symbols 155 | cython_debug/ 156 | 157 | # PyCharm 158 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 159 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 160 | # and can be added to the global gitignore or merged into this file. For a more nuclear 161 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 162 | #.idea/ 163 | 164 | ./*.png 165 | .aider* 166 | 167 | output/ -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "synthwave84.brightness": 0.8 3 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mermaid Diagram AI Agent 2 | > Communicate your work with diagrams in seconds with GenAI + Mermaid 3 | 4 | ![Command Diagram](./imgs/mermaid_ai_agent.png) 5 | 6 | ## Setup 7 | > Image generated WITH this tool! 8 | ![Setup](./imgs/setup.png) 9 | 10 | - Install [uv](https://docs.astral.sh/uv/getting-started/installation/) 11 | - Install dependencies `uv sync` 12 | - Set your OpenAI API key as an environment variable `export OPENAI_API_KEY=` 13 | - Optionally setup 14 | - Optionally set ANTHROPIC_API_KEY, VERTEX_API_KEY, GROQ_API_KEY as environment variables. See `.env.sample` for details. 15 | - Update your LLM in the `src/mermaid_agent/modules/llm_module.py: build_model()` function. 16 | - ✅ To run a single generation: 17 | - `uv run main mer -p "Flowchart of ##setup instructions" -o "setup_diagram.png" -i "./README.md"` 18 | - `uv run main mer -p "state diagram of process: build prompt, generate HQ examples, iterate, build dataset, fine-tune, test, iterate, prompt " -o "fine_tune_process.png"` 19 | - `uv run main mer -p "pie chart title: 'Time Spent on Project Tasks', 'Coding': 40, 'Testing': 20, 'Documentation': 20, 'Meetings': 15, 'Learn AI Coding w/IndyDevDan': 5" -o "project_time_allocation.png"` 20 | - ✅ To run an interactive generation: 21 | - `uv run main mer-iter -p "Flowchart of ##setup instructions" -o "setup_diagram.png" -i "./README.md"` 22 | - ✅ To run a bulk-version based iteration 23 | - `uv run main mer-bulk -p "Flowchart of ##setup instructions" -o "setup_diagram.png" -i "./README.md" -c 5` 24 | - `uv run main mer-bulk -p "pie chart title: 'Time Spent on Project Tasks', 'Coding', 'Testing', 'Documentation', 'Meetings', 'Learn AI Coding w/IndyDevDan'" -o "project_time_allocation.png" -c 5` 25 | 26 | ## Learn AI Coding 27 | - Watch us code the [mer-bulk command with AIDER](https://youtu.be/ag-KxYS8Vuw) 28 | 29 | ## Next 30 | - [] every output/ session id directory for image 31 | - [] log the mermaid chart text to a /output file 32 | - [] multiple input files for improved context 33 | - [] params for size and theme? 34 | - [] integration into idt? 35 | 36 | 37 | ## Resources 38 | - https://gist.github.com/disler/d51d7e37c3e5f8d277d8e0a71f4a1d2e 39 | - https://mermaid.ink/ 40 | - https://www.makotemplates.org/ 41 | - https://github.com/simonw/llm 42 | - https://pypi.org/project/Mako/ 43 | - https://docs.astral.sh/uv/getting-started/features/#python-versions 44 | - https://mermaid.js.org 45 | - https://mermaid.js.org/syntax/examples.html 46 | - https://ai.google.dev/api/models#models_list-shell -------------------------------------------------------------------------------- /imgs/mermaid_ai_agent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disler/mermaid-js-ai-agent/6c12451ad02b196754328d19a566017140e5651d/imgs/mermaid_ai_agent.png -------------------------------------------------------------------------------- /imgs/setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disler/mermaid-js-ai-agent/6c12451ad02b196754328d19a566017140e5651d/imgs/setup.png -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "mermaid-agent" 3 | version = "0.1.0" 4 | description = "Add your description here" 5 | readme = "README.md" 6 | requires-python = ">=3.10" 7 | dependencies = [ 8 | "openai>=1.42.0", 9 | "python-dotenv>=1.0.1", 10 | "pydantic>=2.8.2", 11 | "pillow>=10.4.0", 12 | "requests>=2.32.3", 13 | "llm>=0.15", 14 | "pytest>=8.3.2", 15 | "llm-gemini>=0.1a4", 16 | "typer>=0.12.5", 17 | "jinja2>=3.1.4", 18 | "llm-claude-3>=0.4", 19 | "mako>=1.3.5", 20 | ] 21 | 22 | [build-system] 23 | requires = ["hatchling"] 24 | build-backend = "hatchling.build" 25 | 26 | [project.scripts] 27 | main = "mermaid_agent.main:main" 28 | -------------------------------------------------------------------------------- /src/mermaid_agent/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disler/mermaid-js-ai-agent/6c12451ad02b196754328d19a566017140e5651d/src/mermaid_agent/__init__.py -------------------------------------------------------------------------------- /src/mermaid_agent/examples.py: -------------------------------------------------------------------------------- 1 | # This graph illustrates a simple relationship between nodes A, B, C, D, and E, showing how each node is connected to others. 2 | graph = """ 3 | graph LR; 4 | A--> B & C & D; 5 | B--> A & E; 6 | C--> A & E; 7 | D--> A & E; 8 | E--> B & C & D; 9 | """ 10 | 11 | # This pie chart illustrates sales by product, with Product A accounting for 40%, Product B for 30%, Product C for 20%, and Product D for 10%. 12 | pie_chart = """ 13 | pie 14 | title Sales by Product 15 | "Product A": 40 16 | "Product B": 30 17 | "Product C": 20 18 | "Product D": 10 19 | """ 20 | 21 | # This sequence diagram illustrates a conversation between Alice and Bob, with a loop for John's healthcheck. 22 | sequence_diagram = """ 23 | sequenceDiagram 24 | participant Alice 25 | participant Bob 26 | Alice->>John: Hello John, how are you? 27 | loop Healthcheck 28 | John->>John: Fight against hypochondria 29 | end 30 | Note right of John: Rational thoughts
prevail! 31 | John-->>Alice: Great! 32 | John->>Bob: How about you? 33 | Bob-->>John: Jolly good! 34 | """ 35 | 36 | # This Gantt chart illustrates a project schedule with two sections, showing the start date, duration, and completion status of tasks. 37 | gantt_chart = """ 38 | gantt 39 | title A Gantt Diagram 40 | dateFormat YYYY-MM-DD 41 | section Section 42 | A task :a1, 2014-01-01, 30d 43 | Another task :after a1 , 20d 44 | section Another 45 | Task in sec :2014-01-12 , 12d 46 | another task : 24d 47 | """ 48 | 49 | # This class diagram illustrates an Animal hierarchy with Duck, Fish, and Zebra subclasses, showing their attributes and methods. 50 | class_diagram = """ 51 | classDiagram 52 | Animal <|-- Duck 53 | Animal <|-- Fish 54 | Animal <|-- Zebra 55 | Animal : +int age 56 | Animal : +String gender 57 | Animal: +isMammal() 58 | Animal: +mate() 59 | class Duck{ 60 | +String beakColor 61 | +swim() 62 | +quack() 63 | } 64 | class Fish{ 65 | -int sizeInFeet 66 | -canEat() 67 | } 68 | class Zebra{ 69 | +bool is_wild 70 | +run() 71 | } 72 | """ 73 | 74 | # Prompt: Build a simple mermaid chart for a pie chart that shows the distribution of the top 3 fruits. Return the mermaid chart only. 75 | llm_pie = """ 76 | pie title Favorite Fruits 77 | "Apples" : 40 78 | "Bananas" : 35 79 | "Oranges" : 25 80 | """ 81 | -------------------------------------------------------------------------------- /src/mermaid_agent/main.py: -------------------------------------------------------------------------------- 1 | from mermaid_agent import mermaid_agent 2 | from mermaid_agent.modules import llm_module 3 | from mermaid_agent.modules import mermaid 4 | from mermaid_agent.modules import chain 5 | from mermaid_agent.modules.typings import ( 6 | OneShotMermaidParams, 7 | IterateMermaidParams, 8 | MermaidAgentResponse, 9 | BulkMermaidParams, 10 | BulkMermaidAgentResponse, 11 | ) 12 | 13 | import os 14 | import typer 15 | from jinja2 import Template 16 | from PIL import Image 17 | from mermaid_agent.modules.utils import build_file_path, current_date_time_str 18 | 19 | app = typer.Typer() 20 | 21 | # Constants for reusable options 22 | PROMPT_OPTION = typer.Option( 23 | ..., "--prompt", "-p", help="The prompt for generating the Mermaid chart" 24 | ) 25 | OUTPUT_FILE_OPTION = typer.Option( 26 | "mermaid.png", "--output", "-o", help="Output file name for the generated chart" 27 | ) 28 | INPUT_FILE_OPTION = typer.Option( 29 | None, "--input", "-i", help="Input file containing additional content" 30 | ) 31 | 32 | 33 | @app.command() 34 | def mer( 35 | prompt: str = PROMPT_OPTION, 36 | output_file: str = OUTPUT_FILE_OPTION, 37 | input_file: str = INPUT_FILE_OPTION, 38 | ) -> MermaidAgentResponse: 39 | """Generates a Mermaid chart in one shot.""" 40 | params = OneShotMermaidParams( 41 | prompt=prompt, output_file=output_file, input_file=input_file 42 | ) 43 | response: MermaidAgentResponse = mermaid_agent.one_shot_mermaid_agent(params) 44 | if response.img: 45 | mermaid.show_image(response.img) 46 | return response 47 | 48 | 49 | @app.command() 50 | def mer_iter( 51 | prompt: str = PROMPT_OPTION, 52 | output_file: str = OUTPUT_FILE_OPTION, 53 | input_file: str = INPUT_FILE_OPTION, 54 | ) -> MermaidAgentResponse: 55 | """Generates a Mermaid chart iteratively, allowing for user refinement.""" 56 | params = OneShotMermaidParams( 57 | prompt=prompt, output_file=output_file, input_file=input_file 58 | ) 59 | 60 | if not params.prompt.strip(): 61 | raise Exception("Prompt is required") 62 | 63 | print(f"Prompt: {params.prompt}") 64 | print(f"Output file: {params.output_file}") 65 | print(f"Input file: {params.input_file}") 66 | 67 | response: MermaidAgentResponse = mermaid_agent.one_shot_mermaid_agent(params) 68 | if response.img: 69 | mermaid.show_image(response.img) 70 | else: 71 | raise Exception("Failed to generate Mermaid chart") 72 | 73 | print(f"BUILT one shot mermaid chart: {response}") 74 | 75 | # Create a directory for this iteration session 76 | session_dir = build_file_path(f"iter_session_{current_date_time_str()}") 77 | os.makedirs(session_dir, exist_ok=True) 78 | 79 | # Save the initial chart 80 | iteration_count = 0 81 | initial_output_file = os.path.join( 82 | session_dir, f"iteration_{iteration_count}_{output_file}" 83 | ) 84 | response.img.save(initial_output_file) 85 | 86 | iterate_params = IterateMermaidParams( 87 | change_prompt="", 88 | base_prompt=prompt, 89 | current_mermaid_chart=response.mermaid, 90 | current_mermaid_img=response.img, 91 | output_file=output_file, 92 | input_file=input_file, 93 | ) 94 | 95 | while True: 96 | user_input = input( 97 | "Would you like to make any changes? (Enter change request or 'n'/'no'/'e' to exit): " 98 | ) 99 | if user_input.lower() in ["n", "no", "e"]: 100 | break 101 | 102 | iterate_params.change_prompt = user_input 103 | 104 | response = mermaid_agent.iterate_mermaid_agent(iterate_params) 105 | iterate_params.current_mermaid_chart = response.mermaid 106 | if response.img: 107 | iterate_params.current_mermaid_img = response.img 108 | mermaid.show_image(iterate_params.current_mermaid_img) 109 | 110 | iteration_count += 1 111 | iteration_output_file = os.path.join( 112 | session_dir, f"iteration_{iteration_count}_{output_file}" 113 | ) 114 | response.img.save(iteration_output_file) 115 | 116 | return response 117 | 118 | 119 | @app.command() 120 | def mer_bulk( 121 | prompt: str = PROMPT_OPTION, 122 | output_file: str = OUTPUT_FILE_OPTION, 123 | input_file: str = INPUT_FILE_OPTION, 124 | count: int = typer.Option(5, "--count", "-c", help="Number of diagrams to generate"), 125 | ) -> BulkMermaidAgentResponse: 126 | """Generates multiple Mermaid charts in one shot.""" 127 | params = BulkMermaidParams( 128 | prompt=prompt, output_file=output_file, input_file=input_file, count=count 129 | ) 130 | response: BulkMermaidAgentResponse = mermaid_agent.bulk_mermaid_agent(params) 131 | for i, res in enumerate(response.responses): 132 | if res.img: 133 | mermaid.show_image(res.img) 134 | print(f"Generated diagram {i+1}/{count}") 135 | return response 136 | 137 | 138 | def main(): 139 | """Entry point for the Mermaid agent CLI.""" 140 | app() 141 | -------------------------------------------------------------------------------- /src/mermaid_agent/mermaid_agent.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | from mermaid_agent.modules import llm_module, utils 3 | from mermaid_agent.modules import mermaid 4 | from mermaid_agent.modules import chain 5 | from mermaid_agent.modules.typings import ( 6 | OneShotMermaidParams, 7 | ResolutionMermaidParams, 8 | IterateMermaidParams, 9 | MermaidAgentResponse, 10 | BulkMermaidParams, 11 | BulkMermaidAgentResponse, 12 | ) 13 | from PIL import Image 14 | 15 | 16 | def build_model(): 17 | # see llm_module.py for model options 18 | # return llm_module.build_sonnet_3_5() 19 | return llm_module.build_latest_openai() 20 | # return llm_module.build_mini_model() 21 | 22 | 23 | def one_shot_mermaid_agent(params: OneShotMermaidParams) -> MermaidAgentResponse: 24 | 25 | model = build_model() 26 | 27 | base_prompt = params.prompt 28 | output_file = params.output_file 29 | input_file = params.input_file 30 | 31 | file_content = "" 32 | if input_file: 33 | with open(input_file, "r") as file: 34 | file_content = file.read() 35 | 36 | mermaid_prompt_1 = """You are a world-class expert at creating mermaid charts. 37 | 38 | You follow the instructions perfectly to generate mermaid charts. 39 | 40 | 41 | Based on the user-prompt, create the corresponding mermaid chart. 42 | Be very precise with the chart, every node and edge must be included. 43 | Use double quotes for text in the chart 44 | Respond with the mermaid chart only. 45 | Do not wrap the mermaid chart in markdown code blocks. Respond with the mermaid chart only. 46 | If you see a file-content section, use the content to help create the chart. 47 | Keep node labels short and concise. 48 | Avoid embedding links in the chart. 49 | 50 | 51 | % if file_content: 52 | 53 | ${file_content} 54 | 55 | % endif 56 | 57 | 58 | 59 | 60 | Create a flowchart that shows A flowing to E. At C, branch out to H and I. 61 | 62 | 63 | graph LR; 64 | A 65 | B 66 | C 67 | D 68 | E 69 | H 70 | I 71 | 72 | A --> B 73 | A --> C 74 | A --> D 75 | C --> H 76 | C --> I 77 | D --> E 78 | 79 | 80 | 81 | 82 | Build a pie chart that shows the distribution of Apples: 40, Bananas: 35, Oranges: 25. 83 | 84 | 85 | pie title Distribution of Fruits 86 | "Apples" : 40 87 | "Bananas" : 35 88 | "Oranges" : 25 89 | 90 | 91 | 92 | 93 | State diagram for a traffic light. Still, Moving, Crash. 94 | 95 | 96 | stateDiagram-v2 97 | [*] --> Still 98 | Still --> [*] 99 | 100 | Still --> Moving 101 | Moving --> Still 102 | Moving --> Crash 103 | Crash --> [*] 104 | 105 | 106 | 107 | 108 | Create a timeline of major social media platforms from 2002 to 2006. 109 | 110 | 111 | timeline 112 | title History of Social Media Platforms 113 | 2002 : LinkedIn 114 | 2004 : Facebook 115 | : Google 116 | 2005 : Youtube 117 | 2006 : Twitter 118 | 119 | 120 | 121 | 122 | 123 | {{user_prompt}} 124 | 125 | 126 | Your mermaid chart:""" 127 | 128 | mermaid_prompt_2 = """You are a world-class expert at creating mermaid charts. 129 | 130 | Your co-worker has just generated a mermaid chart. 131 | 132 | It's your job to review the chart to ensure it's correct. 133 | 134 | If you see any mistakes, be very precise in what the mistakes are. 135 | 136 | 137 | Review the chart to ensure it's correct. 138 | Be very precise in your correction. 139 | If you see any mistakes, correct them. 140 | Respond with the corrected mermaid chart. 141 | Do not wrap the mermaid chart in markdown code blocks. Respond with the mermaid chart only. 142 | If the chart is already correct, respond with the chart only. 143 | 144 | 145 | 146 | {{output[-1]}} 147 | 148 | 149 | Your correction of the mermaid chart if needed:""" 150 | 151 | context = {"user_prompt": base_prompt, "file_content": file_content} 152 | 153 | # Render the template with the context 154 | rendered_mermaid_prompt_1 = llm_module.conditional_render( 155 | mermaid_prompt_1, {"file_content": file_content} 156 | ) 157 | 158 | chain.MinimalChainable.to_delim_text_file( 159 | utils.build_file_path("rendered_mermaid_prompt_1"), [rendered_mermaid_prompt_1] 160 | ) 161 | 162 | prompt_response, ctx_filled_prompts = chain.MinimalChainable.run( 163 | context, 164 | model, 165 | llm_module.prompt, 166 | prompts=[rendered_mermaid_prompt_1, mermaid_prompt_2], 167 | ) 168 | 169 | chain.MinimalChainable.to_delim_text_file( 170 | utils.build_file_path("mermaid_prompt_1_results"), prompt_response 171 | ) 172 | 173 | chain.MinimalChainable.to_delim_text_file( 174 | utils.build_file_path("mermaid_prompt_1_ctx_filled_prompts"), ctx_filled_prompts 175 | ) 176 | 177 | res = llm_module.parse_markdown_backticks(prompt_response[-1]) 178 | 179 | img = mermaid.mm(res, output_file) 180 | 181 | for _ in range(2): 182 | if img is None: 183 | print("Failed to generate image - running resolution agent") 184 | 185 | resolution_params = ResolutionMermaidParams( 186 | error="Error: Failed to generate Mermaid diagram", 187 | damaged_mermaid_chart=res, 188 | base_prompt=base_prompt, 189 | output_file=output_file, 190 | input_file=input_file, 191 | ) 192 | 193 | resolution_response = resolution_mermaid_agent(resolution_params) 194 | img = resolution_response.img 195 | else: 196 | break 197 | 198 | return MermaidAgentResponse(img=img, mermaid=res) 199 | 200 | 201 | def resolution_mermaid_agent(params: ResolutionMermaidParams) -> MermaidAgentResponse: 202 | model = build_model() 203 | 204 | error = params.error 205 | damaged_mermaid_chart = params.damaged_mermaid_chart 206 | prompt = params.base_prompt 207 | output_file = params.output_file 208 | input_file = params.input_file 209 | 210 | file_content = "" 211 | if input_file: 212 | with open(input_file, "r") as file: 213 | file_content = file.read() 214 | 215 | correction_prompt = """You are a world-class expert at creating and fixing mermaid charts. 216 | 217 | You have been given a damaged mermaid chart and an error message. Your task is to fix the chart. 218 | 219 | 220 | Analyze the error message and the damaged mermaid chart. 221 | Identify the issue causing the error. 222 | Fix the mermaid chart to resolve the error. 223 | Ensure the fixed chart still fulfills the original prompt. 224 | Respond with the corrected mermaid chart only. 225 | Do not wrap the mermaid chart in markdown code blocks. 226 | 227 | 228 | 229 | {{error}} 230 | 231 | 232 | 233 | {{damaged_mermaid_chart}} 234 | 235 | 236 | 237 | {{prompt}} 238 | 239 | 240 | % if file_content: 241 | 242 | ${file_content} 243 | 244 | % endif 245 | 246 | Your corrected mermaid chart:""" 247 | 248 | context = { 249 | "error": error, 250 | "damaged_mermaid_chart": damaged_mermaid_chart, 251 | "prompt": prompt, 252 | "file_content": file_content, 253 | } 254 | 255 | # Render the template with the context 256 | rendered_correction_prompt = llm_module.conditional_render( 257 | correction_prompt, {"file_content": file_content} 258 | ) 259 | 260 | prompt_response, ctx_filled_prompts = chain.MinimalChainable.run( 261 | context, model, llm_module.prompt, prompts=[rendered_correction_prompt] 262 | ) 263 | 264 | chain.MinimalChainable.to_delim_text_file( 265 | utils.build_file_path("resolution_mermaid_results"), prompt_response 266 | ) 267 | 268 | chain.MinimalChainable.to_delim_text_file( 269 | utils.build_file_path("resolution_mermaid_ctx_filled_prompts"), 270 | ctx_filled_prompts, 271 | ) 272 | 273 | res = llm_module.parse_markdown_backticks(prompt_response[-1]) 274 | 275 | img = mermaid.mm(res, output_file) 276 | 277 | return MermaidAgentResponse(img=img, mermaid=res) 278 | 279 | 280 | def bulk_mermaid_agent(params: BulkMermaidParams) -> BulkMermaidAgentResponse: 281 | responses = [] 282 | for i in range(params.count): 283 | one_shot_params = OneShotMermaidParams( 284 | prompt=params.prompt, 285 | output_file=f"{i+1}_{params.output_file}", 286 | input_file=params.input_file, 287 | ) 288 | response = one_shot_mermaid_agent(one_shot_params) 289 | responses.append(response) 290 | 291 | return BulkMermaidAgentResponse(responses=responses) 292 | 293 | 294 | def iterate_mermaid_agent(params: IterateMermaidParams) -> MermaidAgentResponse: 295 | model = build_model() 296 | 297 | change_prompt = params.change_prompt 298 | base_prompt = params.base_prompt 299 | current_mermaid_chart = params.current_mermaid_chart 300 | current_mermaid_img = params.current_mermaid_img 301 | output_file = params.output_file 302 | input_file = params.input_file 303 | 304 | file_content = "" 305 | if input_file: 306 | with open(input_file, "r") as file: 307 | file_content = file.read() 308 | 309 | iteration_prompt_1 = """You are a world-class expert at creating and modifying mermaid charts. 310 | 311 | You have been given a current mermaid chart and a request for changes. Your task is to update the chart according to the requested changes. 312 | 313 | 314 | Analyze the current mermaid chart and the requested changes. 315 | Update the mermaid chart to incorporate the requested changes. 316 | Ensure the updated chart still fulfills the original base prompt. 317 | Respond with the updated mermaid chart only. 318 | Do not wrap the mermaid chart in markdown code blocks. 319 | 320 | 321 | 322 | {{current_mermaid_chart}} 323 | 324 | 325 | 326 | {{base_prompt}} 327 | 328 | 329 | 330 | {{change_prompt}} 331 | 332 | 333 | % if file_content: 334 | 335 | ${file_content} 336 | 337 | % endif 338 | 339 | Your updated mermaid chart:""" 340 | 341 | iteration_prompt_2 = """You are a world-class expert at creating and reviewing mermaid charts. 342 | 343 | Your co-worker has just updated a mermaid chart based on requested changes. Your task is to review the updated chart to ensure it's correct and incorporates the requested changes. 344 | 345 | 346 | Review the updated chart to ensure it's correct and incorporates the requested changes. 347 | Be very precise in your critique. 348 | If you see any mistakes or missing changes, correct them. 349 | Ensure the updated chart still fulfills the original base prompt. 350 | Respond with the final mermaid chart only. 351 | Do not wrap the mermaid chart in markdown code blocks. 352 | 353 | 354 | 355 | {{output[-1]}} 356 | 357 | 358 | 359 | {{base_prompt}} 360 | 361 | 362 | 363 | {{change_prompt}} 364 | 365 | 366 | Your final mermaid chart:""" 367 | 368 | context = { 369 | "current_mermaid_chart": current_mermaid_chart, 370 | "base_prompt": base_prompt, 371 | "change_prompt": change_prompt, 372 | "file_content": file_content, 373 | } 374 | 375 | # Render the templates with the context 376 | rendered_iteration_prompt_1 = llm_module.conditional_render( 377 | iteration_prompt_1, {"file_content": file_content} 378 | ) 379 | rendered_iteration_prompt_2 = iteration_prompt_2 380 | 381 | prompt_response, ctx_filled_prompts = chain.MinimalChainable.run( 382 | context, 383 | model, 384 | llm_module.prompt, 385 | prompts=[rendered_iteration_prompt_1, rendered_iteration_prompt_2], 386 | ) 387 | 388 | chain.MinimalChainable.to_delim_text_file( 389 | utils.build_file_path("iteration_mermaid_results"), prompt_response 390 | ) 391 | 392 | chain.MinimalChainable.to_delim_text_file( 393 | utils.build_file_path("iteration_mermaid_ctx_filled_prompts"), 394 | ctx_filled_prompts, 395 | ) 396 | 397 | res = llm_module.parse_markdown_backticks(prompt_response[-1]) 398 | 399 | img = mermaid.mm(res, output_file) 400 | 401 | return MermaidAgentResponse(img=img, mermaid=res) 402 | -------------------------------------------------------------------------------- /src/mermaid_agent/modules/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disler/mermaid-js-ai-agent/6c12451ad02b196754328d19a566017140e5651d/src/mermaid_agent/modules/__init__.py -------------------------------------------------------------------------------- /src/mermaid_agent/modules/chain.py: -------------------------------------------------------------------------------- 1 | import json 2 | import re 3 | from typing import List, Dict, Callable, Any, Tuple, Union 4 | from .typings import FusionChainResult 5 | import concurrent.futures 6 | 7 | 8 | class FusionChain: 9 | 10 | @staticmethod 11 | def run( 12 | context: Dict[str, Any], 13 | models: List[Any], 14 | callable: Callable, 15 | prompts: List[str], 16 | evaluator: Callable[[List[Any]], Tuple[Any, List[float]]], 17 | get_model_name: Callable[[Any], str], 18 | ) -> FusionChainResult: 19 | """ 20 | Run a competition between models on a list of prompts. 21 | 22 | Runs the MinimalChainable.run method for each model for each prompt and evaluates the results. 23 | 24 | The evaluator runs on the last output of each model at the end of the chain of prompts. 25 | 26 | The eval method returns a performance score for each model from 0 to 1, giving priority to models earlier in the list. 27 | 28 | Args: 29 | context (Dict[str, Any]): The context for the prompts. 30 | models (List[Any]): List of models to compete. 31 | callable (Callable): The function to call for each prompt. 32 | prompts (List[str]): List of prompts to process. 33 | evaluator (Callable[[List[str]], Tuple[Any, List[float]]]): Function to evaluate model outputs, returning the top response and the scores. 34 | get_model_name (Callable[[Any], str]): Function to get the name of a model. Defaults to str(model). 35 | 36 | Returns: 37 | FusionChainResult: A FusionChainResult object containing the top response, all outputs, all context-filled prompts, performance scores, and model names. 38 | """ 39 | all_outputs = [] 40 | all_context_filled_prompts = [] 41 | 42 | for model in models: 43 | outputs, context_filled_prompts = MinimalChainable.run( 44 | context, model, callable, prompts 45 | ) 46 | all_outputs.append(outputs) 47 | all_context_filled_prompts.append(context_filled_prompts) 48 | 49 | # Evaluate the last output of each model 50 | last_outputs = [outputs[-1] for outputs in all_outputs] 51 | top_response, performance_scores = evaluator(last_outputs) 52 | 53 | model_names = [get_model_name(model) for model in models] 54 | 55 | return FusionChainResult( 56 | top_response=top_response, 57 | all_prompt_responses=all_outputs, 58 | all_context_filled_prompts=all_context_filled_prompts, 59 | performance_scores=performance_scores, 60 | model_names=model_names, 61 | ) 62 | 63 | @staticmethod 64 | def run_parallel( 65 | context: Dict[str, Any], 66 | models: List[Any], 67 | callable: Callable, 68 | prompts: List[str], 69 | evaluator: Callable[[List[Any]], Tuple[Any, List[float]]], 70 | get_model_name: Callable[[Any], str], 71 | num_workers: int = 4, 72 | ) -> FusionChainResult: 73 | """ 74 | Run a competition between models on a list of prompts in parallel. 75 | 76 | This method is similar to the 'run' method but utilizes parallel processing 77 | to improve performance when dealing with multiple models. 78 | 79 | Args: 80 | context (Dict[str, Any]): The context for the prompts. 81 | models (List[Any]): List of models to compete. 82 | callable (Callable): The function to call for each prompt. 83 | prompts (List[str]): List of prompts to process. 84 | evaluator (Callable[[List[str]], Tuple[Any, List[float]]]): Function to evaluate model outputs, returning the top response and the scores. 85 | num_workers (int): Number of parallel workers to use. Defaults to 4. 86 | get_model_name (Callable[[Any], str]): Function to get the name of a model. Defaults to str(model). 87 | 88 | Returns: 89 | FusionChainResult: A FusionChainResult object containing the top response, all outputs, all context-filled prompts, performance scores, and model names. 90 | """ 91 | 92 | def process_model(model): 93 | outputs, context_filled_prompts = MinimalChainable.run( 94 | context, model, callable, prompts 95 | ) 96 | return outputs, context_filled_prompts 97 | 98 | all_outputs = [] 99 | all_context_filled_prompts = [] 100 | 101 | with concurrent.futures.ThreadPoolExecutor(max_workers=num_workers) as executor: 102 | future_to_model = { 103 | executor.submit(process_model, model): model for model in models 104 | } 105 | for future in concurrent.futures.as_completed(future_to_model): 106 | outputs, context_filled_prompts = future.result() 107 | all_outputs.append(outputs) 108 | all_context_filled_prompts.append(context_filled_prompts) 109 | 110 | # Evaluate the last output of each model 111 | last_outputs = [outputs[-1] for outputs in all_outputs] 112 | top_response, performance_scores = evaluator(last_outputs) 113 | 114 | model_names = [get_model_name(model) for model in models] 115 | 116 | return FusionChainResult( 117 | top_response=top_response, 118 | all_prompt_responses=all_outputs, 119 | all_context_filled_prompts=all_context_filled_prompts, 120 | performance_scores=performance_scores, 121 | model_names=model_names, 122 | ) 123 | 124 | 125 | class MinimalChainable: 126 | """ 127 | Sequential prompt chaining with context and output back-references. 128 | """ 129 | 130 | @staticmethod 131 | def run( 132 | context: Dict[str, Any], model: Any, callable: Callable, prompts: List[str] 133 | ) -> Tuple[List[Any], List[str]]: 134 | # Initialize an empty list to store the outputs 135 | output = [] 136 | context_filled_prompts = [] 137 | 138 | # Iterate over each prompt with its index 139 | for i, prompt in enumerate(prompts): 140 | # Iterate over each key-value pair in the context 141 | for key, value in context.items(): 142 | # Check if the key is in the prompt 143 | if "{{" + key + "}}" in prompt: 144 | # Replace the key with its value 145 | prompt = prompt.replace("{{" + key + "}}", str(value)) 146 | 147 | # Replace references to previous outputs 148 | # Iterate from the current index down to 1 149 | for j in range(i, 0, -1): 150 | # Get the previous output 151 | previous_output = output[i - j] 152 | 153 | # Handle JSON (dict) output references 154 | # Check if the previous output is a dictionary 155 | if isinstance(previous_output, dict): 156 | # Check if the reference is in the prompt 157 | if f"{{{{output[-{j}]}}}}" in prompt: 158 | # Replace the reference with the JSON string 159 | prompt = prompt.replace( 160 | f"{{{{output[-{j}]}}}}", json.dumps(previous_output) 161 | ) 162 | # Iterate over each key-value pair in the previous output 163 | for key, value in previous_output.items(): 164 | # Check if the key reference is in the prompt 165 | if f"{{{{output[-{j}].{key}}}}}" in prompt: 166 | # Replace the key reference with its value 167 | prompt = prompt.replace( 168 | f"{{{{output[-{j}].{key}}}}}", str(value) 169 | ) 170 | # If not a dict, use the original string 171 | else: 172 | # Check if the reference is in the prompt 173 | if f"{{{{output[-{j}]}}}}" in prompt: 174 | # Replace the reference with the previous output 175 | prompt = prompt.replace( 176 | f"{{{{output[-{j}]}}}}", str(previous_output) 177 | ) 178 | 179 | # Append the context filled prompt to the list 180 | context_filled_prompts.append(prompt) 181 | 182 | # Call the provided callable with the processed prompt 183 | # Get the result by calling the callable with the model and prompt 184 | result = callable(model, prompt) 185 | 186 | print("result", result) 187 | 188 | # Try to parse the result as JSON, handling markdown-wrapped JSON 189 | try: 190 | # First, attempt to extract JSON from markdown code blocks 191 | # Search for JSON in markdown code blocks 192 | json_match = re.search(r"```(?:json)?\s*([\s\S]*?)\s*```", result) 193 | # If a match is found 194 | if json_match: 195 | # Parse the JSON from the match 196 | result = json.loads(json_match.group(1)) 197 | else: 198 | # If no markdown block found, try parsing the entire result 199 | # Parse the entire result as JSON 200 | result = json.loads(result) 201 | except json.JSONDecodeError: 202 | # Not JSON, keep as is 203 | pass 204 | 205 | # Append the result to the output list 206 | output.append(result) 207 | 208 | # Return the list of outputs 209 | return output, context_filled_prompts 210 | 211 | @staticmethod 212 | def to_delim_text_file(name: str, content: List[Union[str, dict, list]]) -> str: 213 | result_string = "" 214 | with open(f"{name}.txt", "w") as outfile: 215 | for i, item in enumerate(content, 1): 216 | if isinstance(item, (dict, list)): 217 | item = json.dumps(item) 218 | elif not isinstance(item, str): 219 | item = str(item) 220 | chain_text_delim = ( 221 | f"{'🔗' * i} -------- Prompt Chain Result #{i} -------------\n\n" 222 | ) 223 | outfile.write(chain_text_delim) 224 | outfile.write(item) 225 | outfile.write("\n\n") 226 | 227 | result_string += chain_text_delim + item + "\n\n" 228 | 229 | return result_string 230 | -------------------------------------------------------------------------------- /src/mermaid_agent/modules/llm_module.py: -------------------------------------------------------------------------------- 1 | import llm 2 | from dotenv import load_dotenv 3 | import os 4 | from mako.template import Template 5 | 6 | # Load environment variables from .env file 7 | load_dotenv() 8 | 9 | 10 | def conditional_render(prompt, context, start_delim="% if", end_delim="% endif"): 11 | template = Template(prompt) 12 | return template.render(**context) 13 | 14 | 15 | def parse_markdown_backticks(str) -> str: 16 | if "```" not in str: 17 | return str.strip() 18 | # Remove opening backticks and language identifier 19 | str = str.split("```", 1)[-1].split("\n", 1)[-1] 20 | # Remove closing backticks 21 | str = str.rsplit("```", 1)[0] 22 | # Remove any leading or trailing whitespace 23 | return str.strip() 24 | 25 | 26 | def prompt(model: llm.Model, prompt: str): 27 | res = model.prompt(prompt) 28 | return res.text() 29 | 30 | 31 | def get_model_name(model: llm.Model): 32 | return model.model_id 33 | 34 | 35 | def build_sonnet_3_5(): 36 | ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY") 37 | 38 | sonnet_3_5_model: llm.Model = llm.get_model("claude-3.5-sonnet") 39 | sonnet_3_5_model.key = ANTHROPIC_API_KEY 40 | 41 | return sonnet_3_5_model 42 | 43 | 44 | def build_mini_model(): 45 | OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") 46 | gpt4_o_mini_model: llm.Model = llm.get_model("gpt-4o-mini") 47 | gpt4_o_mini_model.key = OPENAI_API_KEY 48 | return gpt4_o_mini_model 49 | 50 | 51 | def build_big_3_models(): 52 | ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY") 53 | OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") 54 | GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") 55 | 56 | sonnet_3_5_model: llm.Model = llm.get_model("claude-3.5-sonnet") 57 | sonnet_3_5_model.key = ANTHROPIC_API_KEY 58 | 59 | gpt4_o_model: llm.Model = llm.get_model("4o") 60 | gpt4_o_model.key = OPENAI_API_KEY 61 | 62 | gemini_1_5_pro_model: llm.Model = llm.get_model("gemini-1.5-pro-latest") 63 | gemini_1_5_pro_model.key = GEMINI_API_KEY 64 | 65 | return sonnet_3_5_model, gpt4_o_model, gemini_1_5_pro_model 66 | 67 | 68 | def build_latest_openai(): 69 | OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") 70 | 71 | # chatgpt_4o_latest_model: llm.Model = llm.get_model("chatgpt-4o-latest") - experimental 72 | chatgpt_4o_latest_model: llm.Model = llm.get_model("gpt-4o-2024-08-06") 73 | chatgpt_4o_latest_model.key = OPENAI_API_KEY 74 | return chatgpt_4o_latest_model 75 | 76 | 77 | def build_big_3_plus_mini_models(): 78 | 79 | ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY") 80 | OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") 81 | GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") 82 | 83 | sonnet_3_5_model: llm.Model = llm.get_model("claude-3.5-sonnet") 84 | sonnet_3_5_model.key = ANTHROPIC_API_KEY 85 | 86 | gpt4_o_model: llm.Model = llm.get_model("4o") 87 | gpt4_o_model.key = OPENAI_API_KEY 88 | 89 | gemini_1_5_pro_model: llm.Model = llm.get_model("gemini-1.5-pro-latest") 90 | gemini_1_5_pro_model.key = GEMINI_API_KEY 91 | 92 | gpt4_o_mini_model: llm.Model = llm.get_model("gpt-4o-mini") 93 | gpt4_o_mini_model.key = OPENAI_API_KEY 94 | 95 | chatgpt_4o_latest_model = build_latest_openai() 96 | 97 | return ( 98 | sonnet_3_5_model, 99 | gpt4_o_model, 100 | gemini_1_5_pro_model, 101 | gpt4_o_mini_model, 102 | ) 103 | 104 | 105 | def build_gemini_duo(): 106 | gemini_1_5_pro: llm.Model = llm.get_model("gemini-1.5-pro-latest") 107 | gemini_1_5_flash: llm.Model = llm.get_model("gemini-1.5-flash-latest") 108 | 109 | GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") 110 | 111 | gemini_1_5_pro.key = GEMINI_API_KEY 112 | gemini_1_5_flash.key = GEMINI_API_KEY 113 | 114 | return gemini_1_5_pro, gemini_1_5_flash 115 | -------------------------------------------------------------------------------- /src/mermaid_agent/modules/mermaid.py: -------------------------------------------------------------------------------- 1 | import base64 2 | from typing import Optional 3 | import requests 4 | from PIL import Image, UnidentifiedImageError 5 | import io 6 | from mermaid_agent.modules.utils import build_file_path 7 | 8 | 9 | def build_image(graph, filename): 10 | graphbytes = graph.encode("utf8") 11 | base64_bytes = base64.b64encode(graphbytes) 12 | base64_string = base64_bytes.decode("ascii") 13 | 14 | width = 500 15 | height = 500 16 | scale = 2 17 | theme = "dark" # Options: "default", "neutral", "dark", "forest", "base" 18 | 19 | url = ( 20 | "https://mermaid.ink/img/" 21 | + base64_string 22 | + f"?width={width}&height={height}&scale={scale}&theme={theme}&bgColor=2a303c" 23 | ) 24 | 25 | response = requests.get(url) 26 | try: 27 | return Image.open(io.BytesIO(response.content)) 28 | except UnidentifiedImageError: 29 | print( 30 | f"Error: Unable to identify the image. The Mermaid diagram might be invalid. '{filename}'" 31 | ) 32 | return None 33 | 34 | 35 | def save_image_locally(img, filename): 36 | img.save(filename) 37 | 38 | 39 | def show_image(img): 40 | if img: 41 | img.show() 42 | else: 43 | print("Error: No image to display") 44 | 45 | 46 | def mm(graph, filename) -> Optional[Image.Image]: 47 | img = build_image(graph, filename) 48 | if img: 49 | output_path = build_file_path(filename) 50 | save_image_locally(img, output_path) 51 | return img 52 | else: 53 | return None 54 | -------------------------------------------------------------------------------- /src/mermaid_agent/modules/typings.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, ConfigDict 2 | from typing import List, Dict, Optional, Union, Any 3 | from PIL import Image 4 | 5 | 6 | class FusionChainResult(BaseModel): 7 | top_response: Union[str, Dict[str, Any]] 8 | all_prompt_responses: List[List[Any]] 9 | all_context_filled_prompts: List[List[str]] 10 | performance_scores: List[float] 11 | model_names: List[str] 12 | 13 | 14 | class OneShotMermaidParams(BaseModel): 15 | prompt: str 16 | output_file: str 17 | input_file: Optional[str] = None 18 | 19 | 20 | class ResolutionMermaidParams(BaseModel): 21 | error: str 22 | damaged_mermaid_chart: str 23 | base_prompt: str 24 | output_file: str 25 | input_file: Optional[str] = None 26 | 27 | 28 | class IterateMermaidParams(BaseModel): 29 | change_prompt: str 30 | base_prompt: str 31 | current_mermaid_chart: str 32 | current_mermaid_img: Image.Image 33 | output_file: str 34 | input_file: Optional[str] = None 35 | 36 | model_config = ConfigDict(arbitrary_types_allowed=True) 37 | 38 | 39 | class BulkMermaidParams(BaseModel): 40 | prompt: str 41 | output_file: str 42 | input_file: Optional[str] = None 43 | count: int 44 | 45 | class MermaidAgentResponse(BaseModel): 46 | img: Optional[Image.Image] 47 | mermaid: Optional[str] 48 | 49 | model_config = ConfigDict(arbitrary_types_allowed=True) 50 | 51 | class BulkMermaidAgentResponse(BaseModel): 52 | responses: List[MermaidAgentResponse] 53 | -------------------------------------------------------------------------------- /src/mermaid_agent/modules/utils.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import json 3 | import os 4 | from typing import Union, Dict, List 5 | 6 | OUTPUT_DIR = "output" 7 | 8 | 9 | def build_file_path(name: str): 10 | session_dir = f"{OUTPUT_DIR}" 11 | os.makedirs(session_dir, exist_ok=True) 12 | return os.path.join(session_dir, f"{name}") 13 | 14 | 15 | def build_file_name_session(name: str, session_id: str): 16 | session_dir = f"{OUTPUT_DIR}/{session_id}" 17 | os.makedirs(session_dir, exist_ok=True) 18 | return os.path.join(session_dir, f"{name}") 19 | 20 | 21 | def to_json_file_pretty(name: str, content: Union[Dict, List]): 22 | def default_serializer(obj): 23 | if hasattr(obj, "model_dump"): 24 | return obj.model_dump() 25 | raise TypeError( 26 | f"Object of type {obj.__class__.__name__} is not JSON serializable" 27 | ) 28 | 29 | with open(f"{name}.json", "w") as outfile: 30 | json.dump(content, outfile, indent=2, default=default_serializer) 31 | 32 | 33 | def current_date_time_str() -> str: 34 | return datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") 35 | 36 | 37 | def current_date_str() -> str: 38 | return datetime.datetime.now().strftime("%Y-%m-%d") 39 | 40 | 41 | def dict_item_diff_by_set( 42 | previous_list: List[Dict], current_list: List[Dict], set_key: str 43 | ) -> List[str]: 44 | previous_set = {item[set_key] for item in previous_list} 45 | current_set = {item[set_key] for item in current_list} 46 | return list(current_set - previous_set) 47 | -------------------------------------------------------------------------------- /src/mermaid_agent/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disler/mermaid-js-ai-agent/6c12451ad02b196754328d19a566017140e5651d/src/mermaid_agent/tests/__init__.py -------------------------------------------------------------------------------- /src/mermaid_agent/tests/chainable_test.py: -------------------------------------------------------------------------------- 1 | from typing import Any, List, Tuple 2 | 3 | from pydantic import BaseModel 4 | from mermaid_agent.modules.chain import MinimalChainable, FusionChain 5 | from mermaid_agent.modules.llm_module import ( 6 | build_big_3_models, 7 | prompt as llm_prompt, 8 | get_model_name, 9 | ) 10 | from mermaid_agent.modules.typings import FusionChainResult 11 | 12 | 13 | def test_chainable_solo(): 14 | # Mock model and callable function 15 | class MockModel: 16 | pass 17 | 18 | def mock_callable_prompt(model, prompt): 19 | return f"Solo response: {prompt}" 20 | 21 | # Test context and single chain 22 | context = {"variable": "Test"} 23 | chains = ["Single prompt: {{variable}}"] 24 | 25 | # Run the Chainable 26 | result, _ = MinimalChainable.run(context, MockModel(), mock_callable_prompt, chains) 27 | 28 | # Assert the results 29 | assert len(result) == 1 30 | assert result[0] == "Solo response: Single prompt: Test" 31 | 32 | 33 | def test_chainable_run(): 34 | # Mock model and callable function 35 | class MockModel: 36 | pass 37 | 38 | def mock_callable_prompt(model, prompt): 39 | return f"Response to: {prompt}" 40 | 41 | # Test context and chains 42 | context = {"var1": "Hello", "var2": "World"} 43 | chains = ["First prompt: {{var1}}", "Second prompt: {{var2}} and {{var1}}"] 44 | 45 | # Run the Chainable 46 | result, _ = MinimalChainable.run(context, MockModel(), mock_callable_prompt, chains) 47 | 48 | # Assert the results 49 | assert len(result) == 2 50 | assert result[0] == "Response to: First prompt: Hello" 51 | assert result[1] == "Response to: Second prompt: World and Hello" 52 | 53 | 54 | def test_chainable_with_output(): 55 | # Mock model and callable function 56 | class MockModel: 57 | pass 58 | 59 | def mock_callable_prompt(model, prompt): 60 | return f"Response to: {prompt}" 61 | 62 | # Test context and chains 63 | context = {"var1": "Hello", "var2": "World"} 64 | chains = ["First prompt: {{var1}}", "Second prompt: {{var2}} and {{output[-1]}}"] 65 | 66 | # Run the Chainable 67 | result, _ = MinimalChainable.run(context, MockModel(), mock_callable_prompt, chains) 68 | 69 | # Assert the results 70 | assert len(result) == 2 71 | assert result[0] == "Response to: First prompt: Hello" 72 | assert ( 73 | result[1] 74 | == "Response to: Second prompt: World and Response to: First prompt: Hello" 75 | ) 76 | 77 | 78 | def test_chainable_json_output(): 79 | # Mock model and callable function 80 | class MockModel: 81 | pass 82 | 83 | def mock_callable_prompt(model, prompt): 84 | if "Output JSON" in prompt: 85 | return '{"key": "value"}' 86 | return prompt 87 | 88 | # Test context and chains 89 | context = {"test": "JSON"} 90 | chains = ["Output JSON: {{test}}", "Reference JSON: {{output[-1].key}}"] 91 | 92 | # Run the Chainable 93 | result, _ = MinimalChainable.run(context, MockModel(), mock_callable_prompt, chains) 94 | 95 | # Assert the results 96 | assert len(result) == 2 97 | assert isinstance(result[0], dict) 98 | print("result", result) 99 | assert result[0] == {"key": "value"} 100 | assert result[1] == "Reference JSON: value" # Remove quotes around "value" 101 | 102 | 103 | def test_chainable_reference_entire_json_output(): 104 | # Mock model and callable function 105 | class MockModel: 106 | pass 107 | 108 | def mock_callable_prompt(model, prompt): 109 | if "Output JSON" in prompt: 110 | return '{"key": "value"}' 111 | return prompt 112 | 113 | context = {"test": "JSON"} 114 | chains = ["Output JSON: {{test}}", "Reference JSON: {{output[-1]}}"] 115 | 116 | # Run the Chainable 117 | result, _ = MinimalChainable.run(context, MockModel(), mock_callable_prompt, chains) 118 | 119 | assert len(result) == 2 120 | assert isinstance(result[0], dict) 121 | assert result[0] == {"key": "value"} 122 | assert result[1] == 'Reference JSON: {"key": "value"}' 123 | 124 | 125 | def test_chainable_reference_long_output_value(): 126 | # Mock model and callable function 127 | class MockModel: 128 | pass 129 | 130 | def mock_callable_prompt(model, prompt): 131 | return prompt 132 | 133 | context = {"test": "JSON"} 134 | chains = [ 135 | "Output JSON: {{test}}", 136 | "1 Reference JSON: {{output[-1]}}", 137 | "2 Reference JSON: {{output[-2]}}", 138 | "3 Reference JSON: {{output[-1]}}", 139 | ] 140 | 141 | # Run the Chainable 142 | result, _ = MinimalChainable.run(context, MockModel(), mock_callable_prompt, chains) 143 | 144 | assert len(result) == 4 145 | assert result[0] == "Output JSON: JSON" 146 | assert result[1] == "1 Reference JSON: Output JSON: JSON" 147 | assert result[2] == "2 Reference JSON: Output JSON: JSON" 148 | assert result[3] == "3 Reference JSON: 2 Reference JSON: Output JSON: JSON" 149 | 150 | 151 | def test_chainable_empty_context(): 152 | # Mock model and callable function 153 | class MockModel: 154 | pass 155 | 156 | def mock_callable_prompt(model, prompt): 157 | return prompt 158 | 159 | # Test with empty context 160 | context = {} 161 | chains = ["Simple prompt"] 162 | 163 | # Run the Chainable 164 | result, _ = MinimalChainable.run(context, MockModel(), mock_callable_prompt, chains) 165 | 166 | # Assert the results 167 | assert len(result) == 1 168 | assert result[0] == "Simple prompt" 169 | 170 | 171 | def test_chainable_json_output_with_markdown(): 172 | # Mock model and callable function 173 | class MockModel: 174 | pass 175 | 176 | def mock_callable_prompt(model, prompt): 177 | return """ 178 | Here's a JSON response wrapped in markdown: 179 | ```json 180 | { 181 | "key": "value", 182 | "number": 42, 183 | "nested": { 184 | "inner": "content" 185 | } 186 | } 187 | ``` 188 | """ 189 | 190 | context = {} 191 | chains = ["Test JSON parsing"] 192 | 193 | # Run the Chainable 194 | result, _ = MinimalChainable.run(context, MockModel(), mock_callable_prompt, chains) 195 | 196 | # Assert the results 197 | assert len(result) == 1 198 | assert isinstance(result[0], dict) 199 | assert result[0] == {"key": "value", "number": 42, "nested": {"inner": "content"}} 200 | 201 | 202 | # ------------ CompetitionChainable.run 203 | 204 | import random 205 | 206 | 207 | def test_fusion_chain_run(): 208 | # Mock models 209 | class MockModel: 210 | def __init__(self, name): 211 | self.name = name 212 | 213 | # Mock callable function 214 | def mock_callable_prompt(model, prompt): 215 | return f"{model.name} response: {prompt}" 216 | 217 | # Mock evaluator function (random scores between 0 and 1) 218 | def mock_evaluator(outputs): 219 | top_response = random.choice(outputs) 220 | scores = [random.random() for _ in outputs] 221 | return top_response, scores 222 | 223 | # Test context and chains 224 | context = {"var1": "Hello", "var2": "World"} 225 | chains = ["First prompt: {{var1}}", "Second prompt: {{var2}} and {{output[-1]}}"] 226 | 227 | # Create mock models 228 | models = [MockModel(f"Model{i}") for i in range(3)] 229 | 230 | # Mock get_model_name function 231 | def mock_get_model_name(model): 232 | return model.name 233 | 234 | # Run the FusionChain 235 | result = FusionChain.run( 236 | context=context, 237 | models=models, 238 | callable=mock_callable_prompt, 239 | prompts=chains, 240 | evaluator=mock_evaluator, 241 | get_model_name=mock_get_model_name, 242 | ) 243 | 244 | # Assert the results 245 | assert isinstance(result, FusionChainResult) 246 | assert len(result.all_prompt_responses) == 3 247 | assert len(result.all_context_filled_prompts) == 3 248 | assert len(result.performance_scores) == 3 249 | assert len(result.model_names) == 3 250 | 251 | for i, (outputs, context_filled_prompts) in enumerate( 252 | zip(result.all_prompt_responses, result.all_context_filled_prompts) 253 | ): 254 | assert len(outputs) == 2 255 | assert len(context_filled_prompts) == 2 256 | 257 | assert outputs[0] == f"Model{i} response: First prompt: Hello" 258 | assert ( 259 | outputs[1] 260 | == f"Model{i} response: Second prompt: World and Model{i} response: First prompt: Hello" 261 | ) 262 | 263 | assert context_filled_prompts[0] == "First prompt: Hello" 264 | assert ( 265 | context_filled_prompts[1] 266 | == f"Second prompt: World and Model{i} response: First prompt: Hello" 267 | ) 268 | 269 | # Check that performance scores are between 0 and 1 270 | assert all(0 <= score <= 1 for score in result.performance_scores) 271 | 272 | # Check that the number of unique scores is likely more than 1 (random function) 273 | assert ( 274 | len(set(result.performance_scores)) > 1 275 | ), "All performance scores are the same, which is unlikely with a random evaluator" 276 | 277 | # Check that top_response is present and is either a string or a dict 278 | assert isinstance(result.top_response, (str, dict)) 279 | 280 | # Print the output of FusionChain.run 281 | print("All outputs:") 282 | for i, outputs in enumerate(result.all_prompt_responses): 283 | print(f"Model {i}:") 284 | for j, output in enumerate(outputs): 285 | print(f" Chain {j}: {output}") 286 | 287 | print("\nAll context filled prompts:") 288 | for i, prompts in enumerate(result.all_context_filled_prompts): 289 | print(f"Model {i}:") 290 | for j, prompt in enumerate(prompts): 291 | print(f" Chain {j}: {prompt}") 292 | 293 | print("\nPerformance scores:") 294 | for i, score in enumerate(result.performance_scores): 295 | print(f"Model {i}: {score}") 296 | 297 | print("\nTop response:") 298 | print(result.top_response) 299 | 300 | print("result.model_dump: ", result.model_dump()) 301 | print("result.model_dump_json: ", result.model_dump_json()) 302 | 303 | 304 | def test_real_fusion_chain_run(): 305 | 306 | sonnet_3_5_model, gpt4_o_model, gemini_1_5_pro_model = build_big_3_models() 307 | 308 | code_request = ( 309 | "Python code to Scrape the URL and return the content within the tag" 310 | ) 311 | 312 | context = { 313 | "code_request": code_request, 314 | } 315 | 316 | prompts = [ 317 | # Prompt 1 318 | """ 319 | Draft a high-level plan for code that will fulfill the CODE_REQUEST. Include the main steps and any libraries that might be useful. Be concise and short. 320 | 321 | ## CODE_REQUEST 322 | {{code_request}} 323 | 324 | ## Code Draft Plan""", 325 | # Prompt 2 326 | """ 327 | Write code to fulfill the CODE_REQUEST. Use appropriate libraries and error handling. 328 | 329 | ## CODE_REQUEST 330 | {{code_request}} 331 | 332 | ## Code Draft 333 | {{output[-1]}} 334 | 335 | ## Code""", 336 | # Prompt 3 337 | """ 338 | Review the code draft and code for fulfilling the CODE_REQUEST. Make improvements and produce concise, final, readable, and runnable production level code. 339 | 340 | ## CODE_REQUEST 341 | {{code_request}} 342 | 343 | ## Code Draft 344 | {{output[-2]}} 345 | 346 | ## Code 347 | ``` 348 | {{output[-1]}} 349 | ``` 350 | 351 | ## Production Code""", 352 | ] 353 | 354 | def evaluator(outputs: List[str]) -> Tuple[Any, List[float]]: 355 | 356 | outputs_as_str_md = "\n".join( 357 | [f"### Output {n+1}\n```{content}```" for n, content in enumerate(outputs)] 358 | ) 359 | 360 | eval_prompt = """# Given these outputs, evaluate them on a scale of 0.0 - 1.0, where the maximum rating is given to the most relevant and accurate output given the PROMPT_REQUEST. 361 | 362 | Respond in this JSON format {"ratings": [float, float, float, ...]} where each float is the rating for the corresponding output. 363 | Respond strictly in JSON format, do not include any other text in your response. 364 | 365 | ## PROMPT_REQUEST 366 | {{prompt_request}} 367 | 368 | ## Outputs 369 | {{outputs_as_str_md}} 370 | 371 | ## Your Rating In JSON:""" 372 | 373 | eval_prompt_responses, context_filled_prompts = MinimalChainable.run( 374 | context={ 375 | "prompt_request": code_request, 376 | "outputs_as_str_md": outputs_as_str_md, 377 | }, 378 | model=sonnet_3_5_model, 379 | callable=llm_prompt, 380 | prompts=[eval_prompt], 381 | ) 382 | 383 | class Parse(BaseModel): 384 | ratings: List[float] 385 | 386 | print("eval_prompt_responses", eval_prompt_responses) 387 | print("context_filled_prompts", context_filled_prompts) 388 | 389 | ratings = Parse.model_validate(eval_prompt_responses[-1]).ratings 390 | 391 | top_response = outputs[ratings.index(max(ratings))] 392 | 393 | return top_response, ratings 394 | 395 | models = [sonnet_3_5_model, gpt4_o_model, gemini_1_5_pro_model] 396 | # models = [sonnet_3_5_model, gpt4_o_model] 397 | 398 | result = FusionChain.run_parallel( 399 | context=context, 400 | models=models, 401 | callable=llm_prompt, 402 | prompts=prompts, 403 | evaluator=evaluator, 404 | get_model_name=get_model_name, 405 | ) 406 | 407 | # Assertions 408 | assert isinstance(result, FusionChainResult) 409 | assert len(result.all_prompt_responses) == 3, "Should have outputs for all 3 models" 410 | assert ( 411 | len(result.all_context_filled_prompts) == 3 412 | ), "Should have context-filled prompts for all 3 models" 413 | assert ( 414 | len(result.performance_scores) == 3 415 | ), "Should have performance scores for all 3 models" 416 | assert len(result.model_names) == 3, "Should have names for all 3 models" 417 | 418 | for model_outputs, model_prompts in zip( 419 | result.all_prompt_responses, result.all_context_filled_prompts 420 | ): 421 | assert ( 422 | len(model_outputs) == 3 423 | ), "Each model should have 3 outputs (one for each prompt)" 424 | assert ( 425 | len(model_prompts) == 3 426 | ), "Each model should have 3 context-filled prompts" 427 | 428 | # Check if the outputs contain Python code 429 | assert any( 430 | "def" in output or "import" in output for output in model_outputs 431 | ), "At least one output should contain Python code" 432 | 433 | # Check if the context is properly filled in the prompts 434 | assert all( 435 | "{{code_request}}" not in prompt for prompt in model_prompts 436 | ), "All placeholders should be replaced in the prompts" 437 | 438 | # Check if the performance scores are reasonable 439 | assert all( 440 | 0 <= score <= 1 for score in result.performance_scores 441 | ), "All performance scores should be between 0 and 1" 442 | 443 | # Check that top_response is present and is either a string or a dict 444 | assert isinstance( 445 | result.top_response, (str, dict) 446 | ), "Top response should be either a string or a dict" 447 | 448 | # Build up a string with results for manual inspection 449 | result_string = "" 450 | for i, (model_outputs, model_prompts, score) in enumerate( 451 | zip( 452 | result.all_prompt_responses, 453 | result.all_context_filled_prompts, 454 | result.performance_scores, 455 | ) 456 | ): 457 | result_string += f"\nModel {i + 1}:\n" 458 | result_string += f"Performance score: {score}\n" 459 | for j, (output, prompt) in enumerate(zip(model_outputs, model_prompts)): 460 | result_string += f"\nPrompt {j + 1}:\n" 461 | result_string += prompt 462 | result_string += "\n\nOutput:\n" 463 | result_string += output 464 | result_string += "\n" 465 | result_string += "\n" + "=" * 50 + "\n" 466 | 467 | # add eval summary 468 | eval_summary = "\n\nEvaluation Scores:\n" + "\n".join( 469 | [ 470 | f"Model {i+1} ({model.model_id}): {score:.2f}" 471 | for i, (model, score) in enumerate(zip(models, result.performance_scores)) 472 | ] 473 | ) 474 | 475 | result_string += "\nTest completed successfully!\n" 476 | 477 | # Write the result string to a file 478 | with open("./test_output.txt", "w") as f: 479 | f.write(result_string) 480 | 481 | print("Results have been written to test_output.txt") 482 | -------------------------------------------------------------------------------- /src/mermaid_agent/tests/llm_test.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from mermaid_agent.modules.llm_module import ( 3 | build_gemini_duo, 4 | build_sonnet_3_5, 5 | build_big_3_models, 6 | ) 7 | 8 | 9 | def test_sonnet_3_5_model(): 10 | # Build the models 11 | sonnet_3_5_model = build_sonnet_3_5() 12 | 13 | # Define a simple prompt 14 | test_prompt = "What is the capital of France?" 15 | 16 | # Test sonnet_3_5_model 17 | sonnet_result = sonnet_3_5_model.prompt(test_prompt, temperature=0.5).text() 18 | assert ( 19 | "Paris" in sonnet_result 20 | ), f"Unexpected response from sonnet_3_5_model: {sonnet_result}" 21 | print("Sonnet 3.5 response:", sonnet_result) 22 | 23 | 24 | def test_build_big3_models(): 25 | # Build the big 3 models 26 | sonnet_3_5_model, gpt4_o_model, gemini_1_5_pro_model = build_big_3_models() 27 | 28 | # Define a simple prompt 29 | test_prompt = "What is the capital of France?" 30 | 31 | # Test sonnet_3_5_model 32 | sonnet_result = sonnet_3_5_model.prompt(test_prompt, temperature=0.5).text() 33 | assert ( 34 | "Paris" in sonnet_result 35 | ), f"Unexpected response from sonnet_3_5_model: {sonnet_result}" 36 | print("Sonnet 3.5 response:", sonnet_result) 37 | 38 | # Test gpt4_o_model 39 | gpt4_result = gpt4_o_model.prompt(test_prompt, temperature=0.5).text() 40 | assert ( 41 | "Paris" in gpt4_result 42 | ), f"Unexpected response from gpt4_o_model: {gpt4_result}" 43 | print("GPT-4 response:", gpt4_result) 44 | 45 | # Test gemini_1_5_pro_model 46 | gemini_result = gemini_1_5_pro_model.prompt(test_prompt).text() 47 | assert ( 48 | "Paris" in gemini_result 49 | ), f"Unexpected response from gemini_1_5_pro_model: {gemini_result}" 50 | print("Gemini 1.5 Pro response:", gemini_result) 51 | 52 | 53 | def test_build_gemini_duo(): 54 | # Build the Gemini duo models 55 | gemini_1_5_pro, gemini_1_5_flash = build_gemini_duo() 56 | 57 | # Define a simple prompt 58 | test_prompt = "What is the capital of France?" 59 | 60 | # Test gemini_1_5_pro 61 | pro_result = gemini_1_5_pro.prompt(test_prompt).text() 62 | assert ( 63 | "Paris" in pro_result 64 | ), f"Unexpected response from gemini_1_5_pro: {pro_result}" 65 | print("Gemini 1.5 Pro response:", pro_result) 66 | 67 | # Test gemini_1_5_flash 68 | flash_result = gemini_1_5_flash.prompt(test_prompt).text() 69 | assert ( 70 | "Paris" in flash_result 71 | ), f"Unexpected response from gemini_1_5_flash: {flash_result}" 72 | print("Gemini 1.5 Flash response:", flash_result) 73 | -------------------------------------------------------------------------------- /uv.lock: -------------------------------------------------------------------------------- 1 | version = 1 2 | requires-python = ">=3.10" 3 | resolution-markers = [ 4 | "python_full_version < '3.13'", 5 | "python_full_version >= '3.13'", 6 | ] 7 | 8 | [[package]] 9 | name = "annotated-types" 10 | version = "0.7.0" 11 | source = { registry = "https://pypi.org/simple" } 12 | sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } 13 | wheels = [ 14 | { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, 15 | ] 16 | 17 | [[package]] 18 | name = "anthropic" 19 | version = "0.34.1" 20 | source = { registry = "https://pypi.org/simple" } 21 | dependencies = [ 22 | { name = "anyio" }, 23 | { name = "distro" }, 24 | { name = "httpx" }, 25 | { name = "jiter" }, 26 | { name = "pydantic" }, 27 | { name = "sniffio" }, 28 | { name = "tokenizers" }, 29 | { name = "typing-extensions" }, 30 | ] 31 | sdist = { url = "https://files.pythonhosted.org/packages/87/e2/98ff733ff75c1d371c029fb27eb9308f9c8e694749cea70382338a8e7e88/anthropic-0.34.1.tar.gz", hash = "sha256:69e822bd7a31ec11c2edb85f2147e8f0ee0cfd3288fea70b0ca8808b2f9bf91d", size = 901462 } 32 | wheels = [ 33 | { url = "https://files.pythonhosted.org/packages/a4/1c/1ce9edec76885badebacb4e31d42acffbdfd30dbaa839d5c378d57ac9aa9/anthropic-0.34.1-py3-none-any.whl", hash = "sha256:2fa26710809d0960d970f26cd0be3686437250a481edb95c33d837aa5fa24158", size = 891537 }, 34 | ] 35 | 36 | [[package]] 37 | name = "anyio" 38 | version = "4.4.0" 39 | source = { registry = "https://pypi.org/simple" } 40 | dependencies = [ 41 | { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, 42 | { name = "idna" }, 43 | { name = "sniffio" }, 44 | { name = "typing-extensions", marker = "python_full_version < '3.11'" }, 45 | ] 46 | sdist = { url = "https://files.pythonhosted.org/packages/e6/e3/c4c8d473d6780ef1853d630d581f70d655b4f8d7553c6997958c283039a2/anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94", size = 163930 } 47 | wheels = [ 48 | { url = "https://files.pythonhosted.org/packages/7b/a2/10639a79341f6c019dedc95bd48a4928eed9f1d1197f4c04f546fc7ae0ff/anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7", size = 86780 }, 49 | ] 50 | 51 | [[package]] 52 | name = "certifi" 53 | version = "2024.7.4" 54 | source = { registry = "https://pypi.org/simple" } 55 | sdist = { url = "https://files.pythonhosted.org/packages/c2/02/a95f2b11e207f68bc64d7aae9666fed2e2b3f307748d5123dffb72a1bbea/certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b", size = 164065 } 56 | wheels = [ 57 | { url = "https://files.pythonhosted.org/packages/1c/d5/c84e1a17bf61d4df64ca866a1c9a913874b4e9bdc131ec689a0ad013fb36/certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90", size = 162960 }, 58 | ] 59 | 60 | [[package]] 61 | name = "charset-normalizer" 62 | version = "3.3.2" 63 | source = { registry = "https://pypi.org/simple" } 64 | sdist = { url = "https://files.pythonhosted.org/packages/63/09/c1bc53dab74b1816a00d8d030de5bf98f724c52c1635e07681d312f20be8/charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", size = 104809 } 65 | wheels = [ 66 | { url = "https://files.pythonhosted.org/packages/2b/61/095a0aa1a84d1481998b534177c8566fdc50bb1233ea9a0478cd3cc075bd/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", size = 194219 }, 67 | { url = "https://files.pythonhosted.org/packages/cc/94/f7cf5e5134175de79ad2059edf2adce18e0685ebdb9227ff0139975d0e93/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", size = 122521 }, 68 | { url = "https://files.pythonhosted.org/packages/46/6a/d5c26c41c49b546860cc1acabdddf48b0b3fb2685f4f5617ac59261b44ae/charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", size = 120383 }, 69 | { url = "https://files.pythonhosted.org/packages/b8/60/e2f67915a51be59d4539ed189eb0a2b0d292bf79270410746becb32bc2c3/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", size = 138223 }, 70 | { url = "https://files.pythonhosted.org/packages/05/8c/eb854996d5fef5e4f33ad56927ad053d04dc820e4a3d39023f35cad72617/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", size = 148101 }, 71 | { url = "https://files.pythonhosted.org/packages/f6/93/bb6cbeec3bf9da9b2eba458c15966658d1daa8b982c642f81c93ad9b40e1/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", size = 140699 }, 72 | { url = "https://files.pythonhosted.org/packages/da/f1/3702ba2a7470666a62fd81c58a4c40be00670e5006a67f4d626e57f013ae/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", size = 142065 }, 73 | { url = "https://files.pythonhosted.org/packages/3f/ba/3f5e7be00b215fa10e13d64b1f6237eb6ebea66676a41b2bcdd09fe74323/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", size = 144505 }, 74 | { url = "https://files.pythonhosted.org/packages/33/c3/3b96a435c5109dd5b6adc8a59ba1d678b302a97938f032e3770cc84cd354/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", size = 139425 }, 75 | { url = "https://files.pythonhosted.org/packages/43/05/3bf613e719efe68fb3a77f9c536a389f35b95d75424b96b426a47a45ef1d/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", size = 145287 }, 76 | { url = "https://files.pythonhosted.org/packages/58/78/a0bc646900994df12e07b4ae5c713f2b3e5998f58b9d3720cce2aa45652f/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", size = 149929 }, 77 | { url = "https://files.pythonhosted.org/packages/eb/5c/97d97248af4920bc68687d9c3b3c0f47c910e21a8ff80af4565a576bd2f0/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", size = 141605 }, 78 | { url = "https://files.pythonhosted.org/packages/a8/31/47d018ef89f95b8aded95c589a77c072c55e94b50a41aa99c0a2008a45a4/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", size = 142646 }, 79 | { url = "https://files.pythonhosted.org/packages/ae/d5/4fecf1d58bedb1340a50f165ba1c7ddc0400252d6832ff619c4568b36cc0/charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", size = 92846 }, 80 | { url = "https://files.pythonhosted.org/packages/a2/a0/4af29e22cb5942488cf45630cbdd7cefd908768e69bdd90280842e4e8529/charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", size = 100343 }, 81 | { url = "https://files.pythonhosted.org/packages/68/77/02839016f6fbbf808e8b38601df6e0e66c17bbab76dff4613f7511413597/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", size = 191647 }, 82 | { url = "https://files.pythonhosted.org/packages/3e/33/21a875a61057165e92227466e54ee076b73af1e21fe1b31f1e292251aa1e/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", size = 121434 }, 83 | { url = "https://files.pythonhosted.org/packages/dd/51/68b61b90b24ca35495956b718f35a9756ef7d3dd4b3c1508056fa98d1a1b/charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", size = 118979 }, 84 | { url = "https://files.pythonhosted.org/packages/e4/a6/7ee57823d46331ddc37dd00749c95b0edec2c79b15fc0d6e6efb532e89ac/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", size = 136582 }, 85 | { url = "https://files.pythonhosted.org/packages/74/f1/0d9fe69ac441467b737ba7f48c68241487df2f4522dd7246d9426e7c690e/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", size = 146645 }, 86 | { url = "https://files.pythonhosted.org/packages/05/31/e1f51c76db7be1d4aef220d29fbfa5dbb4a99165d9833dcbf166753b6dc0/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", size = 139398 }, 87 | { url = "https://files.pythonhosted.org/packages/40/26/f35951c45070edc957ba40a5b1db3cf60a9dbb1b350c2d5bef03e01e61de/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", size = 140273 }, 88 | { url = "https://files.pythonhosted.org/packages/07/07/7e554f2bbce3295e191f7e653ff15d55309a9ca40d0362fcdab36f01063c/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", size = 142577 }, 89 | { url = "https://files.pythonhosted.org/packages/d8/b5/eb705c313100defa57da79277d9207dc8d8e45931035862fa64b625bfead/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", size = 137747 }, 90 | { url = "https://files.pythonhosted.org/packages/19/28/573147271fd041d351b438a5665be8223f1dd92f273713cb882ddafe214c/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", size = 143375 }, 91 | { url = "https://files.pythonhosted.org/packages/cf/7c/f3b682fa053cc21373c9a839e6beba7705857075686a05c72e0f8c4980ca/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", size = 148474 }, 92 | { url = "https://files.pythonhosted.org/packages/1e/49/7ab74d4ac537ece3bc3334ee08645e231f39f7d6df6347b29a74b0537103/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", size = 140232 }, 93 | { url = "https://files.pythonhosted.org/packages/2d/dc/9dacba68c9ac0ae781d40e1a0c0058e26302ea0660e574ddf6797a0347f7/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", size = 140859 }, 94 | { url = "https://files.pythonhosted.org/packages/6c/c2/4a583f800c0708dd22096298e49f887b49d9746d0e78bfc1d7e29816614c/charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", size = 92509 }, 95 | { url = "https://files.pythonhosted.org/packages/57/ec/80c8d48ac8b1741d5b963797b7c0c869335619e13d4744ca2f67fc11c6fc/charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", size = 99870 }, 96 | { url = "https://files.pythonhosted.org/packages/d1/b2/fcedc8255ec42afee97f9e6f0145c734bbe104aac28300214593eb326f1d/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", size = 192892 }, 97 | { url = "https://files.pythonhosted.org/packages/2e/7d/2259318c202f3d17f3fe6438149b3b9e706d1070fe3fcbb28049730bb25c/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", size = 122213 }, 98 | { url = "https://files.pythonhosted.org/packages/3a/52/9f9d17c3b54dc238de384c4cb5a2ef0e27985b42a0e5cc8e8a31d918d48d/charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", size = 119404 }, 99 | { url = "https://files.pythonhosted.org/packages/99/b0/9c365f6d79a9f0f3c379ddb40a256a67aa69c59609608fe7feb6235896e1/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", size = 137275 }, 100 | { url = "https://files.pythonhosted.org/packages/91/33/749df346e93d7a30cdcb90cbfdd41a06026317bfbfb62cd68307c1a3c543/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", size = 147518 }, 101 | { url = "https://files.pythonhosted.org/packages/72/1a/641d5c9f59e6af4c7b53da463d07600a695b9824e20849cb6eea8a627761/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", size = 140182 }, 102 | { url = "https://files.pythonhosted.org/packages/ee/fb/14d30eb4956408ee3ae09ad34299131fb383c47df355ddb428a7331cfa1e/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", size = 141869 }, 103 | { url = "https://files.pythonhosted.org/packages/df/3e/a06b18788ca2eb6695c9b22325b6fde7dde0f1d1838b1792a0076f58fe9d/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", size = 144042 }, 104 | { url = "https://files.pythonhosted.org/packages/45/59/3d27019d3b447a88fe7e7d004a1e04be220227760264cc41b405e863891b/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", size = 138275 }, 105 | { url = "https://files.pythonhosted.org/packages/7b/ef/5eb105530b4da8ae37d506ccfa25057961b7b63d581def6f99165ea89c7e/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", size = 144819 }, 106 | { url = "https://files.pythonhosted.org/packages/a2/51/e5023f937d7f307c948ed3e5c29c4b7a3e42ed2ee0b8cdf8f3a706089bf0/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", size = 149415 }, 107 | { url = "https://files.pythonhosted.org/packages/24/9d/2e3ef673dfd5be0154b20363c5cdcc5606f35666544381bee15af3778239/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", size = 141212 }, 108 | { url = "https://files.pythonhosted.org/packages/5b/ae/ce2c12fcac59cb3860b2e2d76dc405253a4475436b1861d95fe75bdea520/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", size = 142167 }, 109 | { url = "https://files.pythonhosted.org/packages/ed/3a/a448bf035dce5da359daf9ae8a16b8a39623cc395a2ffb1620aa1bce62b0/charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", size = 93041 }, 110 | { url = "https://files.pythonhosted.org/packages/b6/7c/8debebb4f90174074b827c63242c23851bdf00a532489fba57fef3416e40/charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", size = 100397 }, 111 | { url = "https://files.pythonhosted.org/packages/28/76/e6222113b83e3622caa4bb41032d0b1bf785250607392e1b778aca0b8a7d/charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", size = 48543 }, 112 | ] 113 | 114 | [[package]] 115 | name = "click" 116 | version = "8.1.7" 117 | source = { registry = "https://pypi.org/simple" } 118 | dependencies = [ 119 | { name = "colorama", marker = "platform_system == 'Windows'" }, 120 | ] 121 | sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } 122 | wheels = [ 123 | { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, 124 | ] 125 | 126 | [[package]] 127 | name = "click-default-group" 128 | version = "1.2.4" 129 | source = { registry = "https://pypi.org/simple" } 130 | dependencies = [ 131 | { name = "click" }, 132 | ] 133 | sdist = { url = "https://files.pythonhosted.org/packages/1d/ce/edb087fb53de63dad3b36408ca30368f438738098e668b78c87f93cd41df/click_default_group-1.2.4.tar.gz", hash = "sha256:eb3f3c99ec0d456ca6cd2a7f08f7d4e91771bef51b01bdd9580cc6450fe1251e", size = 3505 } 134 | wheels = [ 135 | { url = "https://files.pythonhosted.org/packages/2c/1a/aff8bb287a4b1400f69e09a53bd65de96aa5cee5691925b38731c67fc695/click_default_group-1.2.4-py2.py3-none-any.whl", hash = "sha256:9b60486923720e7fc61731bdb32b617039aba820e22e1c88766b1125592eaa5f", size = 4123 }, 136 | ] 137 | 138 | [[package]] 139 | name = "colorama" 140 | version = "0.4.6" 141 | source = { registry = "https://pypi.org/simple" } 142 | sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } 143 | wheels = [ 144 | { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, 145 | ] 146 | 147 | [[package]] 148 | name = "distro" 149 | version = "1.9.0" 150 | source = { registry = "https://pypi.org/simple" } 151 | sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722 } 152 | wheels = [ 153 | { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277 }, 154 | ] 155 | 156 | [[package]] 157 | name = "exceptiongroup" 158 | version = "1.2.2" 159 | source = { registry = "https://pypi.org/simple" } 160 | sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } 161 | wheels = [ 162 | { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, 163 | ] 164 | 165 | [[package]] 166 | name = "filelock" 167 | version = "3.15.4" 168 | source = { registry = "https://pypi.org/simple" } 169 | sdist = { url = "https://files.pythonhosted.org/packages/08/dd/49e06f09b6645156550fb9aee9cc1e59aba7efbc972d665a1bd6ae0435d4/filelock-3.15.4.tar.gz", hash = "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb", size = 18007 } 170 | wheels = [ 171 | { url = "https://files.pythonhosted.org/packages/ae/f0/48285f0262fe47103a4a45972ed2f9b93e4c80b8fd609fa98da78b2a5706/filelock-3.15.4-py3-none-any.whl", hash = "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7", size = 16159 }, 172 | ] 173 | 174 | [[package]] 175 | name = "fsspec" 176 | version = "2024.6.1" 177 | source = { registry = "https://pypi.org/simple" } 178 | sdist = { url = "https://files.pythonhosted.org/packages/90/b6/eba5024a9889fcfff396db543a34bef0ab9d002278f163129f9f01005960/fsspec-2024.6.1.tar.gz", hash = "sha256:fad7d7e209dd4c1208e3bbfda706620e0da5142bebbd9c384afb95b07e798e49", size = 284584 } 179 | wheels = [ 180 | { url = "https://files.pythonhosted.org/packages/5e/44/73bea497ac69bafde2ee4269292fa3b41f1198f4bb7bbaaabde30ad29d4a/fsspec-2024.6.1-py3-none-any.whl", hash = "sha256:3cb443f8bcd2efb31295a5b9fdb02aee81d8452c80d28f97a6d0959e6cee101e", size = 177561 }, 181 | ] 182 | 183 | [[package]] 184 | name = "h11" 185 | version = "0.14.0" 186 | source = { registry = "https://pypi.org/simple" } 187 | sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } 188 | wheels = [ 189 | { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, 190 | ] 191 | 192 | [[package]] 193 | name = "httpcore" 194 | version = "1.0.5" 195 | source = { registry = "https://pypi.org/simple" } 196 | dependencies = [ 197 | { name = "certifi" }, 198 | { name = "h11" }, 199 | ] 200 | sdist = { url = "https://files.pythonhosted.org/packages/17/b0/5e8b8674f8d203335a62fdfcfa0d11ebe09e23613c3391033cbba35f7926/httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61", size = 83234 } 201 | wheels = [ 202 | { url = "https://files.pythonhosted.org/packages/78/d4/e5d7e4f2174f8a4d63c8897d79eb8fe2503f7ecc03282fee1fa2719c2704/httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5", size = 77926 }, 203 | ] 204 | 205 | [[package]] 206 | name = "httpx" 207 | version = "0.27.2" 208 | source = { registry = "https://pypi.org/simple" } 209 | dependencies = [ 210 | { name = "anyio" }, 211 | { name = "certifi" }, 212 | { name = "httpcore" }, 213 | { name = "idna" }, 214 | { name = "sniffio" }, 215 | ] 216 | sdist = { url = "https://files.pythonhosted.org/packages/78/82/08f8c936781f67d9e6b9eeb8a0c8b4e406136ea4c3d1f89a5db71d42e0e6/httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2", size = 144189 } 217 | wheels = [ 218 | { url = "https://files.pythonhosted.org/packages/56/95/9377bcb415797e44274b51d46e3249eba641711cf3348050f76ee7b15ffc/httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0", size = 76395 }, 219 | ] 220 | 221 | [[package]] 222 | name = "huggingface-hub" 223 | version = "0.24.6" 224 | source = { registry = "https://pypi.org/simple" } 225 | dependencies = [ 226 | { name = "filelock" }, 227 | { name = "fsspec" }, 228 | { name = "packaging" }, 229 | { name = "pyyaml" }, 230 | { name = "requests" }, 231 | { name = "tqdm" }, 232 | { name = "typing-extensions" }, 233 | ] 234 | sdist = { url = "https://files.pythonhosted.org/packages/65/24/b98fce967b7d63700e5805b915012ba25bb538a81fcf11e97f3cc3f4f012/huggingface_hub-0.24.6.tar.gz", hash = "sha256:cc2579e761d070713eaa9c323e3debe39d5b464ae3a7261c39a9195b27bb8000", size = 349200 } 235 | wheels = [ 236 | { url = "https://files.pythonhosted.org/packages/b9/8f/d6718641c14d98a5848c6a24d2376028d292074ffade0702940a4b1dde76/huggingface_hub-0.24.6-py3-none-any.whl", hash = "sha256:a990f3232aa985fe749bc9474060cbad75e8b2f115f6665a9fda5b9c97818970", size = 417509 }, 237 | ] 238 | 239 | [[package]] 240 | name = "idna" 241 | version = "3.8" 242 | source = { registry = "https://pypi.org/simple" } 243 | sdist = { url = "https://files.pythonhosted.org/packages/e8/ac/e349c5e6d4543326c6883ee9491e3921e0d07b55fdf3cce184b40d63e72a/idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603", size = 189467 } 244 | wheels = [ 245 | { url = "https://files.pythonhosted.org/packages/22/7e/d71db821f177828df9dea8c42ac46473366f191be53080e552e628aad991/idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac", size = 66894 }, 246 | ] 247 | 248 | [[package]] 249 | name = "ijson" 250 | version = "3.3.0" 251 | source = { registry = "https://pypi.org/simple" } 252 | sdist = { url = "https://files.pythonhosted.org/packages/6c/83/28e9e93a3a61913e334e3a2e78ea9924bb9f9b1ac45898977f9d9dd6133f/ijson-3.3.0.tar.gz", hash = "sha256:7f172e6ba1bee0d4c8f8ebd639577bfe429dee0f3f96775a067b8bae4492d8a0", size = 60079 } 253 | wheels = [ 254 | { url = "https://files.pythonhosted.org/packages/ad/89/96e3608499b4a500b9bc27aa8242704e675849dd65bdfa8682b00a92477e/ijson-3.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7f7a5250599c366369fbf3bc4e176f5daa28eb6bc7d6130d02462ed335361675", size = 85009 }, 255 | { url = "https://files.pythonhosted.org/packages/e4/7e/1098503500f5316c5f7912a51c91aca5cbc609c09ce4ecd9c4809983c560/ijson-3.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f87a7e52f79059f9c58f6886c262061065eb6f7554a587be7ed3aa63e6b71b34", size = 57796 }, 256 | { url = "https://files.pythonhosted.org/packages/78/f7/27b8c27a285628719ff55b68507581c86b551eb162ce810fe51e3e1a25f2/ijson-3.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b73b493af9e947caed75d329676b1b801d673b17481962823a3e55fe529c8b8b", size = 57218 }, 257 | { url = "https://files.pythonhosted.org/packages/0c/c5/1698094cb6a336a223c30e1167cc1b15cdb4bfa75399c1a2eb82fa76cc3c/ijson-3.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5576415f3d76290b160aa093ff968f8bf6de7d681e16e463a0134106b506f49", size = 117153 }, 258 | { url = "https://files.pythonhosted.org/packages/4b/21/c206dda0945bd832cc9b0894596b0efc2cb1819a0ac61d8be1429ac09494/ijson-3.3.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e9ffe358d5fdd6b878a8a364e96e15ca7ca57b92a48f588378cef315a8b019e", size = 110781 }, 259 | { url = "https://files.pythonhosted.org/packages/f4/f5/2d733e64577109a9b255d14d031e44a801fa20df9ccc58b54a31e8ecf9e6/ijson-3.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8643c255a25824ddd0895c59f2319c019e13e949dc37162f876c41a283361527", size = 114527 }, 260 | { url = "https://files.pythonhosted.org/packages/8d/a8/78bfee312aa23417b86189a65f30b0edbceaee96dc6a616cc15f611187d1/ijson-3.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:df3ab5e078cab19f7eaeef1d5f063103e1ebf8c26d059767b26a6a0ad8b250a3", size = 116824 }, 261 | { url = "https://files.pythonhosted.org/packages/5d/a4/aff410f7d6aa1a77ee2ab2d6a2d2758422726270cb149c908a9baf33cf58/ijson-3.3.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3dc1fb02c6ed0bae1b4bf96971258bf88aea72051b6e4cebae97cff7090c0607", size = 112647 }, 262 | { url = "https://files.pythonhosted.org/packages/77/ee/2b5122dc4713f5a954267147da36e7156240ca21b04ed5295bc0cabf0fbe/ijson-3.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e9afd97339fc5a20f0542c971f90f3ca97e73d3050cdc488d540b63fae45329a", size = 114156 }, 263 | { url = "https://files.pythonhosted.org/packages/b3/d7/ad3b266490b60c6939e8a07fd8e4b7e2002aea08eaa9572a016c3e3a9129/ijson-3.3.0-cp310-cp310-win32.whl", hash = "sha256:844c0d1c04c40fd1b60f148dc829d3f69b2de789d0ba239c35136efe9a386529", size = 48931 }, 264 | { url = "https://files.pythonhosted.org/packages/0b/68/b9e1c743274c8a23dddb12d2ed13b5f021f6d21669d51ff7fa2e9e6c19df/ijson-3.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:d654d045adafdcc6c100e8e911508a2eedbd2a1b5f93f930ba13ea67d7704ee9", size = 50965 }, 265 | { url = "https://files.pythonhosted.org/packages/fd/df/565ba72a6f4b2c833d051af8e2228cfa0b1fef17bb44995c00ad27470c52/ijson-3.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:501dce8eaa537e728aa35810656aa00460a2547dcb60937c8139f36ec344d7fc", size = 85041 }, 266 | { url = "https://files.pythonhosted.org/packages/f0/42/1361eaa57ece921d0239881bae6a5e102333be5b6e0102a05ec3caadbd5a/ijson-3.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:658ba9cad0374d37b38c9893f4864f284cdcc7d32041f9808fba8c7bcaadf134", size = 57829 }, 267 | { url = "https://files.pythonhosted.org/packages/f5/b0/143dbfe12e1d1303ea8d8cd6f40e95cea8f03bcad5b79708614a7856c22e/ijson-3.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2636cb8c0f1023ef16173f4b9a233bcdb1df11c400c603d5f299fac143ca8d70", size = 57217 }, 268 | { url = "https://files.pythonhosted.org/packages/0d/80/b3b60c5e5be2839365b03b915718ca462c544fdc71e7a79b7262837995ef/ijson-3.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd174b90db68c3bcca273e9391934a25d76929d727dc75224bf244446b28b03b", size = 121878 }, 269 | { url = "https://files.pythonhosted.org/packages/8d/eb/7560fafa4d40412efddf690cb65a9bf2d3429d6035e544103acbf5561dc4/ijson-3.3.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:97a9aea46e2a8371c4cf5386d881de833ed782901ac9f67ebcb63bb3b7d115af", size = 115620 }, 270 | { url = "https://files.pythonhosted.org/packages/51/2b/5a34c7841388dce161966e5286931518de832067cd83e6f003d93271e324/ijson-3.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c594c0abe69d9d6099f4ece17763d53072f65ba60b372d8ba6de8695ce6ee39e", size = 119200 }, 271 | { url = "https://files.pythonhosted.org/packages/3e/b7/1d64fbec0d0a7b0c02e9ad988a89614532028ead8bb52a2456c92e6ee35a/ijson-3.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8e0ff16c224d9bfe4e9e6bd0395826096cda4a3ef51e6c301e1b61007ee2bd24", size = 121107 }, 272 | { url = "https://files.pythonhosted.org/packages/d4/b9/01044f09850bc545ffc85b35aaec473d4f4ca2b6667299033d252c1b60dd/ijson-3.3.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0015354011303175eae7e2ef5136414e91de2298e5a2e9580ed100b728c07e51", size = 116658 }, 273 | { url = "https://files.pythonhosted.org/packages/fb/0d/53856b61f3d952d299d1695c487e8e28058d01fa2adfba3d6d4b4660c242/ijson-3.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:034642558afa57351a0ffe6de89e63907c4cf6849070cc10a3b2542dccda1afe", size = 118186 }, 274 | { url = "https://files.pythonhosted.org/packages/95/2d/5bd86e2307dd594840ee51c4e32de953fee837f028acf0f6afb08914cd06/ijson-3.3.0-cp311-cp311-win32.whl", hash = "sha256:192e4b65495978b0bce0c78e859d14772e841724d3269fc1667dc6d2f53cc0ea", size = 48938 }, 275 | { url = "https://files.pythonhosted.org/packages/55/e1/4ba2b65b87f67fb19d698984d92635e46d9ce9dd748ce7d009441a586710/ijson-3.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:72e3488453754bdb45c878e31ce557ea87e1eb0f8b4fc610373da35e8074ce42", size = 50972 }, 276 | { url = "https://files.pythonhosted.org/packages/8a/4d/3992f7383e26a950e02dc704bc6c5786a080d5c25fe0fc5543ef477c1883/ijson-3.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:988e959f2f3d59ebd9c2962ae71b97c0df58323910d0b368cc190ad07429d1bb", size = 84550 }, 277 | { url = "https://files.pythonhosted.org/packages/1b/cc/3d4372e0d0b02a821b982f1fdf10385512dae9b9443c1597719dd37769a9/ijson-3.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b2f73f0d0fce5300f23a1383d19b44d103bb113b57a69c36fd95b7c03099b181", size = 57572 }, 278 | { url = "https://files.pythonhosted.org/packages/02/de/970d48b1ff9da5d9513c86fdd2acef5cb3415541c8069e0d92a151b84adb/ijson-3.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0ee57a28c6bf523d7cb0513096e4eb4dac16cd935695049de7608ec110c2b751", size = 56902 }, 279 | { url = "https://files.pythonhosted.org/packages/5e/a0/4537722c8b3b05e82c23dfe09a3a64dd1e44a013a5ca58b1e77dfe48b2f1/ijson-3.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0155a8f079c688c2ccaea05de1ad69877995c547ba3d3612c1c336edc12a3a5", size = 127400 }, 280 | { url = "https://files.pythonhosted.org/packages/b2/96/54956062a99cf49f7a7064b573dcd756da0563ce57910dc34e27a473d9b9/ijson-3.3.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ab00721304af1ae1afa4313ecfa1bf16b07f55ef91e4a5b93aeaa3e2bd7917c", size = 118786 }, 281 | { url = "https://files.pythonhosted.org/packages/07/74/795319531c5b5504508f595e631d592957f24bed7ff51a15bc4c61e7b24c/ijson-3.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40ee3821ee90be0f0e95dcf9862d786a7439bd1113e370736bfdf197e9765bfb", size = 126288 }, 282 | { url = "https://files.pythonhosted.org/packages/69/6a/e0cec06fbd98851d5d233b59058c1dc2ea767c9bb6feca41aa9164fff769/ijson-3.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:da3b6987a0bc3e6d0f721b42c7a0198ef897ae50579547b0345f7f02486898f5", size = 129569 }, 283 | { url = "https://files.pythonhosted.org/packages/2a/4f/82c0d896d8dcb175f99ced7d87705057bcd13523998b48a629b90139a0dc/ijson-3.3.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:63afea5f2d50d931feb20dcc50954e23cef4127606cc0ecf7a27128ed9f9a9e6", size = 121508 }, 284 | { url = "https://files.pythonhosted.org/packages/2b/b6/8973474eba4a917885e289d9e138267d3d1f052c2d93b8c968755661a42d/ijson-3.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b5c3e285e0735fd8c5a26d177eca8b52512cdd8687ca86ec77a0c66e9c510182", size = 127896 }, 285 | { url = "https://files.pythonhosted.org/packages/94/25/00e66af887adbbe70002e0479c3c2340bdfa17a168e25d4ab5a27b53582d/ijson-3.3.0-cp312-cp312-win32.whl", hash = "sha256:907f3a8674e489abdcb0206723e5560a5cb1fa42470dcc637942d7b10f28b695", size = 49272 }, 286 | { url = "https://files.pythonhosted.org/packages/25/a2/e187beee237808b2c417109ae0f4f7ee7c81ecbe9706305d6ac2a509cc45/ijson-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:8f890d04ad33262d0c77ead53c85f13abfb82f2c8f078dfbf24b78f59534dfdd", size = 51272 }, 287 | { url = "https://files.pythonhosted.org/packages/c3/28/2e1cf00abe5d97aef074e7835b86a94c9a06be4629a0e2c12600792b51ba/ijson-3.3.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2af323a8aec8a50fa9effa6d640691a30a9f8c4925bd5364a1ca97f1ac6b9b5c", size = 54308 }, 288 | { url = "https://files.pythonhosted.org/packages/04/d2/8c541c28da4f931bac8177e251efe2b6902f7c486d2d4bdd669eed4ff5c0/ijson-3.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f64f01795119880023ba3ce43072283a393f0b90f52b66cc0ea1a89aa64a9ccb", size = 66010 }, 289 | { url = "https://files.pythonhosted.org/packages/d0/02/8fec0b9037a368811dba7901035e8e0973ebda308f57f30c42101a16a5f7/ijson-3.3.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a716e05547a39b788deaf22725490855337fc36613288aa8ae1601dc8c525553", size = 66770 }, 290 | { url = "https://files.pythonhosted.org/packages/47/23/90c61f978c83647112460047ea0137bde9c7fe26600ce255bb3e17ea7a21/ijson-3.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:473f5d921fadc135d1ad698e2697025045cd8ed7e5e842258295012d8a3bc702", size = 64159 }, 291 | { url = "https://files.pythonhosted.org/packages/20/af/aab1a36072590af62d848f03981f1c587ca40a391fc61e418e388d8b0d46/ijson-3.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd26b396bc3a1e85f4acebeadbf627fa6117b97f4c10b177d5779577c6607744", size = 51095 }, 292 | ] 293 | 294 | [[package]] 295 | name = "iniconfig" 296 | version = "2.0.0" 297 | source = { registry = "https://pypi.org/simple" } 298 | sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } 299 | wheels = [ 300 | { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, 301 | ] 302 | 303 | [[package]] 304 | name = "jinja2" 305 | version = "3.1.4" 306 | source = { registry = "https://pypi.org/simple" } 307 | dependencies = [ 308 | { name = "markupsafe" }, 309 | ] 310 | sdist = { url = "https://files.pythonhosted.org/packages/ed/55/39036716d19cab0747a5020fc7e907f362fbf48c984b14e62127f7e68e5d/jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", size = 240245 } 311 | wheels = [ 312 | { url = "https://files.pythonhosted.org/packages/31/80/3a54838c3fb461f6fec263ebf3a3a41771bd05190238de3486aae8540c36/jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d", size = 133271 }, 313 | ] 314 | 315 | [[package]] 316 | name = "jiter" 317 | version = "0.5.0" 318 | source = { registry = "https://pypi.org/simple" } 319 | sdist = { url = "https://files.pythonhosted.org/packages/d7/1a/aa64be757afc614484b370a4d9fc1747dc9237b37ce464f7f9d9ca2a3d38/jiter-0.5.0.tar.gz", hash = "sha256:1d916ba875bcab5c5f7d927df998c4cb694d27dceddf3392e58beaf10563368a", size = 158300 } 320 | wheels = [ 321 | { url = "https://files.pythonhosted.org/packages/af/09/f659fc67d6aaa82c56432c4a7cc8365fff763acbf1c8f24121076617f207/jiter-0.5.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b599f4e89b3def9a94091e6ee52e1d7ad7bc33e238ebb9c4c63f211d74822c3f", size = 284126 }, 322 | { url = "https://files.pythonhosted.org/packages/07/2d/5bdaddfefc44f91af0f3340e75ef327950d790c9f86490757ac8b395c074/jiter-0.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a063f71c4b06225543dddadbe09d203dc0c95ba352d8b85f1221173480a71d5", size = 299265 }, 323 | { url = "https://files.pythonhosted.org/packages/74/bd/964485231deaec8caa6599f3f27c8787a54e9f9373ae80dcfbda2ad79c02/jiter-0.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:acc0d5b8b3dd12e91dd184b87273f864b363dfabc90ef29a1092d269f18c7e28", size = 332178 }, 324 | { url = "https://files.pythonhosted.org/packages/cf/4f/6353179174db10254549bbf2eb2c7ea102e59e0460ee374adb12071c274d/jiter-0.5.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c22541f0b672f4d741382a97c65609332a783501551445ab2df137ada01e019e", size = 342533 }, 325 | { url = "https://files.pythonhosted.org/packages/76/6f/21576071b8b056ef743129b9dacf9da65e328b58766f3d1ea265e966f000/jiter-0.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:63314832e302cc10d8dfbda0333a384bf4bcfce80d65fe99b0f3c0da8945a91a", size = 363469 }, 326 | { url = "https://files.pythonhosted.org/packages/73/a1/9ef99a279c72a031dbe8a4085db41e3521ae01ab0058651d6ccc809a5e93/jiter-0.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a25fbd8a5a58061e433d6fae6d5298777c0814a8bcefa1e5ecfff20c594bd749", size = 379078 }, 327 | { url = "https://files.pythonhosted.org/packages/41/6a/c038077509d67fe876c724bfe9ad15334593851a7def0d84518172bdd44a/jiter-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:503b2c27d87dfff5ab717a8200fbbcf4714516c9d85558048b1fc14d2de7d8dc", size = 318943 }, 328 | { url = "https://files.pythonhosted.org/packages/67/0d/d82673814eb38c208b7881581df596e680f8c2c003e2b80c25ca58975ee4/jiter-0.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6d1f3d27cce923713933a844872d213d244e09b53ec99b7a7fdf73d543529d6d", size = 357394 }, 329 | { url = "https://files.pythonhosted.org/packages/56/9e/cbd8f6612346c38cc42e41e35cda19ce78f5b12e4106d1186e8e95ee839b/jiter-0.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c95980207b3998f2c3b3098f357994d3fd7661121f30669ca7cb945f09510a87", size = 511080 }, 330 | { url = "https://files.pythonhosted.org/packages/ff/33/135c0c33565b6d5c3010d047710837427dd24c9adbc9ca090f3f92df446e/jiter-0.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:afa66939d834b0ce063f57d9895e8036ffc41c4bd90e4a99631e5f261d9b518e", size = 492827 }, 331 | { url = "https://files.pythonhosted.org/packages/68/c1/491a8ef682508edbaf2a32e41c1b1e34064078b369b0c2d141170999d1c9/jiter-0.5.0-cp310-none-win32.whl", hash = "sha256:f16ca8f10e62f25fd81d5310e852df6649af17824146ca74647a018424ddeccf", size = 195081 }, 332 | { url = "https://files.pythonhosted.org/packages/31/20/8cda4faa9571affea6130b150289522a22329778bdfa45a7aab4e7edff95/jiter-0.5.0-cp310-none-win_amd64.whl", hash = "sha256:b2950e4798e82dd9176935ef6a55cf6a448b5c71515a556da3f6b811a7844f1e", size = 190977 }, 333 | { url = "https://files.pythonhosted.org/packages/94/5f/3ac960ed598726aae46edea916e6df4df7ff6fe084bc60774b95cf3154e6/jiter-0.5.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d4c8e1ed0ef31ad29cae5ea16b9e41529eb50a7fba70600008e9f8de6376d553", size = 284131 }, 334 | { url = "https://files.pythonhosted.org/packages/03/eb/2308fa5f5c14c97c4c7720fef9465f1fa0771826cddb4eec9866bdd88846/jiter-0.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c6f16e21276074a12d8421692515b3fd6d2ea9c94fd0734c39a12960a20e85f3", size = 299310 }, 335 | { url = "https://files.pythonhosted.org/packages/3c/f6/dba34ca10b44715fa5302b8e8d2113f72eb00a9297ddf3fa0ae4fd22d1d1/jiter-0.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5280e68e7740c8c128d3ae5ab63335ce6d1fb6603d3b809637b11713487af9e6", size = 332282 }, 336 | { url = "https://files.pythonhosted.org/packages/69/f7/64e0a7439790ec47f7681adb3871c9d9c45fff771102490bbee5e92c00b7/jiter-0.5.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:583c57fc30cc1fec360e66323aadd7fc3edeec01289bfafc35d3b9dcb29495e4", size = 342370 }, 337 | { url = "https://files.pythonhosted.org/packages/55/31/1efbfff2ae8e4d919144c53db19b828049ad0622a670be3bbea94a86282c/jiter-0.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:26351cc14507bdf466b5f99aba3df3143a59da75799bf64a53a3ad3155ecded9", size = 363591 }, 338 | { url = "https://files.pythonhosted.org/packages/30/c3/7ab2ca2276426a7398c6dfb651e38dbc81954c79a3bfbc36c514d8599499/jiter-0.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829df14d656b3fb87e50ae8b48253a8851c707da9f30d45aacab2aa2ba2d614", size = 378551 }, 339 | { url = "https://files.pythonhosted.org/packages/47/e7/5d88031cd743c62199b125181a591b1671df3ff2f6e102df85c58d8f7d31/jiter-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42a4bdcf7307b86cb863b2fb9bb55029b422d8f86276a50487982d99eed7c6e", size = 319152 }, 340 | { url = "https://files.pythonhosted.org/packages/4c/2d/09ea58e1adca9f0359f3d41ef44a1a18e59518d7c43a21f4ece9e72e28c0/jiter-0.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04d461ad0aebf696f8da13c99bc1b3e06f66ecf6cfd56254cc402f6385231c06", size = 357377 }, 341 | { url = "https://files.pythonhosted.org/packages/7d/2f/83ff1058cb56fc3ff73e0d3c6440703ddc9cdb7f759b00cfbde8228fc435/jiter-0.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e6375923c5f19888c9226582a124b77b622f8fd0018b843c45eeb19d9701c403", size = 511091 }, 342 | { url = "https://files.pythonhosted.org/packages/ae/c9/4f85f97c9894382ab457382337aea0012711baaa17f2ed55c0ff25f3668a/jiter-0.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cec323a853c24fd0472517113768c92ae0be8f8c384ef4441d3632da8baa646", size = 492948 }, 343 | { url = "https://files.pythonhosted.org/packages/4d/f2/2e987e0eb465e064c5f52c2f29c8d955452e3b316746e326269263bfb1b7/jiter-0.5.0-cp311-none-win32.whl", hash = "sha256:aa1db0967130b5cab63dfe4d6ff547c88b2a394c3410db64744d491df7f069bb", size = 195183 }, 344 | { url = "https://files.pythonhosted.org/packages/ab/59/05d1c3203c349b37c4dd28b02b9b4e5915a7bcbd9319173b4548a67d2e93/jiter-0.5.0-cp311-none-win_amd64.whl", hash = "sha256:aa9d2b85b2ed7dc7697597dcfaac66e63c1b3028652f751c81c65a9f220899ae", size = 191032 }, 345 | { url = "https://files.pythonhosted.org/packages/aa/bd/c3950e2c478161e131bed8cb67c36aed418190e2a961a1c981e69954e54b/jiter-0.5.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9f664e7351604f91dcdd557603c57fc0d551bc65cc0a732fdacbf73ad335049a", size = 283511 }, 346 | { url = "https://files.pythonhosted.org/packages/80/1c/8ce58d8c37a589eeaaa5d07d131fd31043886f5e77ab50c00a66d869a361/jiter-0.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:044f2f1148b5248ad2c8c3afb43430dccf676c5a5834d2f5089a4e6c5bbd64df", size = 296974 }, 347 | { url = "https://files.pythonhosted.org/packages/4d/b8/6faeff9eed8952bed93a77ea1cffae7b946795b88eafd1a60e87a67b09e0/jiter-0.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:702e3520384c88b6e270c55c772d4bd6d7b150608dcc94dea87ceba1b6391248", size = 331897 }, 348 | { url = "https://files.pythonhosted.org/packages/4f/54/1d9a2209b46d39ce6f0cef3ad87c462f9c50312ab84585e6bd5541292b35/jiter-0.5.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:528d742dcde73fad9d63e8242c036ab4a84389a56e04efd854062b660f559544", size = 342962 }, 349 | { url = "https://files.pythonhosted.org/packages/2a/de/90360be7fc54b2b4c2dfe79eb4ed1f659fce9c96682e6a0be4bbe71371f7/jiter-0.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8cf80e5fe6ab582c82f0c3331df27a7e1565e2dcf06265afd5173d809cdbf9ba", size = 363844 }, 350 | { url = "https://files.pythonhosted.org/packages/ba/ad/ef32b173191b7a53ea8a6757b80723cba321f8469834825e8c71c96bde17/jiter-0.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:44dfc9ddfb9b51a5626568ef4e55ada462b7328996294fe4d36de02fce42721f", size = 378709 }, 351 | { url = "https://files.pythonhosted.org/packages/07/de/353ce53743c0defbbbd652e89c106a97dbbac4eb42c95920b74b5056b93a/jiter-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c451f7922992751a936b96c5f5b9bb9312243d9b754c34b33d0cb72c84669f4e", size = 319038 }, 352 | { url = "https://files.pythonhosted.org/packages/3f/92/42d47310bf9530b9dece9e2d7c6d51cf419af5586ededaf5e66622d160e2/jiter-0.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:308fce789a2f093dca1ff91ac391f11a9f99c35369117ad5a5c6c4903e1b3e3a", size = 357763 }, 353 | { url = "https://files.pythonhosted.org/packages/bd/8c/2bb76a9a84474d48fdd133d3445db8a4413da4e87c23879d917e000a9d87/jiter-0.5.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7f5ad4a7c6b0d90776fdefa294f662e8a86871e601309643de30bf94bb93a64e", size = 511031 }, 354 | { url = "https://files.pythonhosted.org/packages/33/4f/9f23d79c0795e0a8e56e7988e8785c2dcda27e0ed37977256d50c77c6a19/jiter-0.5.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ea189db75f8eca08807d02ae27929e890c7d47599ce3d0a6a5d41f2419ecf338", size = 493042 }, 355 | { url = "https://files.pythonhosted.org/packages/df/67/8a4f975aa834b8aecdb6b131422390173928fd47f42f269dcc32034ab432/jiter-0.5.0-cp312-none-win32.whl", hash = "sha256:e3bbe3910c724b877846186c25fe3c802e105a2c1fc2b57d6688b9f8772026e4", size = 195405 }, 356 | { url = "https://files.pythonhosted.org/packages/15/81/296b1e25c43db67848728cdab34ac3eb5c5cbb4955ceb3f51ae60d4a5e3d/jiter-0.5.0-cp312-none-win_amd64.whl", hash = "sha256:a586832f70c3f1481732919215f36d41c59ca080fa27a65cf23d9490e75b2ef5", size = 189720 }, 357 | ] 358 | 359 | [[package]] 360 | name = "llm" 361 | version = "0.15" 362 | source = { registry = "https://pypi.org/simple" } 363 | dependencies = [ 364 | { name = "click" }, 365 | { name = "click-default-group" }, 366 | { name = "openai" }, 367 | { name = "pip" }, 368 | { name = "pluggy" }, 369 | { name = "pydantic" }, 370 | { name = "pyreadline3", marker = "sys_platform == 'win32'" }, 371 | { name = "python-ulid" }, 372 | { name = "pyyaml" }, 373 | { name = "setuptools" }, 374 | { name = "sqlite-migrate" }, 375 | { name = "sqlite-utils" }, 376 | ] 377 | sdist = { url = "https://files.pythonhosted.org/packages/88/06/437d8ffaf329a05fedbccc994e0a9f57c1ea7c23a1c07e113b813a6652a6/llm-0.15.tar.gz", hash = "sha256:9da5c195b514d446f81e63aa48fc2c208a44e791eb16c3529c48ae8d6021e339", size = 36692 } 378 | wheels = [ 379 | { url = "https://files.pythonhosted.org/packages/51/17/1ab18b7dfabb4747992ccc766dd6aa4bad28c56461e4f70efd85ec6cb71d/llm-0.15-py3-none-any.whl", hash = "sha256:a0f028b46fdc3cd8fd2dcbf52a0784a21a2f8d09f9d70d195dc620d253a972d0", size = 38239 }, 380 | ] 381 | 382 | [[package]] 383 | name = "llm-claude-3" 384 | version = "0.4" 385 | source = { registry = "https://pypi.org/simple" } 386 | dependencies = [ 387 | { name = "anthropic" }, 388 | { name = "llm" }, 389 | ] 390 | sdist = { url = "https://files.pythonhosted.org/packages/73/3b/ab00dcae633b9542abd3a249319a39024453d1763f9c474190a195b44f00/llm_claude_3-0.4.tar.gz", hash = "sha256:775d84705259230591346de595194a58b076bc106737fffbf86628ded148ddd9", size = 7937 } 391 | wheels = [ 392 | { url = "https://files.pythonhosted.org/packages/e9/54/a48147c0fa1f53b63d359abcc793d510391ef6e814f365ee10482aeaf254/llm_claude_3-0.4-py3-none-any.whl", hash = "sha256:b2162a83405afd67bf04d2f04e172cf4e78a57f51067fbe15d0972d5bd8ff092", size = 8055 }, 393 | ] 394 | 395 | [[package]] 396 | name = "llm-gemini" 397 | version = "0.1a4" 398 | source = { registry = "https://pypi.org/simple" } 399 | dependencies = [ 400 | { name = "httpx" }, 401 | { name = "ijson" }, 402 | { name = "llm" }, 403 | ] 404 | sdist = { url = "https://files.pythonhosted.org/packages/f9/59/75cd412222572f974ec28360f3e9325e5bd1e965f5c4ba6b02ab4e43b6d1/llm_gemini-0.1a4.tar.gz", hash = "sha256:c3675a8d55f4bca425f32f1f243f1613dace95fa93083902bf3ddba28e8a826b", size = 7803 } 405 | wheels = [ 406 | { url = "https://files.pythonhosted.org/packages/17/b9/87f783f94a1a79aa7af69f895b6c26b0635e5139c48255453217d36b9910/llm_gemini-0.1a4-py3-none-any.whl", hash = "sha256:b4f0ef4c67e2b486268a19734e99e576114a9d31188fc0dac276978a56ec2b29", size = 8130 }, 407 | ] 408 | 409 | [[package]] 410 | name = "mako" 411 | version = "1.3.5" 412 | source = { registry = "https://pypi.org/simple" } 413 | dependencies = [ 414 | { name = "markupsafe" }, 415 | ] 416 | sdist = { url = "https://files.pythonhosted.org/packages/67/03/fb5ba97ff65ce64f6d35b582aacffc26b693a98053fa831ab43a437cbddb/Mako-1.3.5.tar.gz", hash = "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc", size = 392738 } 417 | wheels = [ 418 | { url = "https://files.pythonhosted.org/packages/03/62/70f5a0c2dd208f9f3f2f9afd103aec42ee4d9ad2401d78342f75e9b8da36/Mako-1.3.5-py3-none-any.whl", hash = "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a", size = 78565 }, 419 | ] 420 | 421 | [[package]] 422 | name = "markdown-it-py" 423 | version = "3.0.0" 424 | source = { registry = "https://pypi.org/simple" } 425 | dependencies = [ 426 | { name = "mdurl" }, 427 | ] 428 | sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 } 429 | wheels = [ 430 | { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, 431 | ] 432 | 433 | [[package]] 434 | name = "markupsafe" 435 | version = "2.1.5" 436 | source = { registry = "https://pypi.org/simple" } 437 | sdist = { url = "https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", size = 19384 } 438 | wheels = [ 439 | { url = "https://files.pythonhosted.org/packages/e4/54/ad5eb37bf9d51800010a74e4665425831a9db4e7c4e0fde4352e391e808e/MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", size = 18206 }, 440 | { url = "https://files.pythonhosted.org/packages/6a/4a/a4d49415e600bacae038c67f9fecc1d5433b9d3c71a4de6f33537b89654c/MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", size = 14079 }, 441 | { url = "https://files.pythonhosted.org/packages/0a/7b/85681ae3c33c385b10ac0f8dd025c30af83c78cec1c37a6aa3b55e67f5ec/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", size = 26620 }, 442 | { url = "https://files.pythonhosted.org/packages/7c/52/2b1b570f6b8b803cef5ac28fdf78c0da318916c7d2fe9402a84d591b394c/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", size = 25818 }, 443 | { url = "https://files.pythonhosted.org/packages/29/fe/a36ba8c7ca55621620b2d7c585313efd10729e63ef81e4e61f52330da781/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", size = 25493 }, 444 | { url = "https://files.pythonhosted.org/packages/60/ae/9c60231cdfda003434e8bd27282b1f4e197ad5a710c14bee8bea8a9ca4f0/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", size = 30630 }, 445 | { url = "https://files.pythonhosted.org/packages/65/dc/1510be4d179869f5dafe071aecb3f1f41b45d37c02329dfba01ff59e5ac5/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", size = 29745 }, 446 | { url = "https://files.pythonhosted.org/packages/30/39/8d845dd7d0b0613d86e0ef89549bfb5f61ed781f59af45fc96496e897f3a/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", size = 30021 }, 447 | { url = "https://files.pythonhosted.org/packages/c7/5c/356a6f62e4f3c5fbf2602b4771376af22a3b16efa74eb8716fb4e328e01e/MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", size = 16659 }, 448 | { url = "https://files.pythonhosted.org/packages/69/48/acbf292615c65f0604a0c6fc402ce6d8c991276e16c80c46a8f758fbd30c/MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", size = 17213 }, 449 | { url = "https://files.pythonhosted.org/packages/11/e7/291e55127bb2ae67c64d66cef01432b5933859dfb7d6949daa721b89d0b3/MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", size = 18219 }, 450 | { url = "https://files.pythonhosted.org/packages/6b/cb/aed7a284c00dfa7c0682d14df85ad4955a350a21d2e3b06d8240497359bf/MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", size = 14098 }, 451 | { url = "https://files.pythonhosted.org/packages/1c/cf/35fe557e53709e93feb65575c93927942087e9b97213eabc3fe9d5b25a55/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", size = 29014 }, 452 | { url = "https://files.pythonhosted.org/packages/97/18/c30da5e7a0e7f4603abfc6780574131221d9148f323752c2755d48abad30/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", size = 28220 }, 453 | { url = "https://files.pythonhosted.org/packages/0c/40/2e73e7d532d030b1e41180807a80d564eda53babaf04d65e15c1cf897e40/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", size = 27756 }, 454 | { url = "https://files.pythonhosted.org/packages/18/46/5dca760547e8c59c5311b332f70605d24c99d1303dd9a6e1fc3ed0d73561/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", size = 33988 }, 455 | { url = "https://files.pythonhosted.org/packages/6d/c5/27febe918ac36397919cd4a67d5579cbbfa8da027fa1238af6285bb368ea/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", size = 32718 }, 456 | { url = "https://files.pythonhosted.org/packages/f8/81/56e567126a2c2bc2684d6391332e357589a96a76cb9f8e5052d85cb0ead8/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", size = 33317 }, 457 | { url = "https://files.pythonhosted.org/packages/00/0b/23f4b2470accb53285c613a3ab9ec19dc944eaf53592cb6d9e2af8aa24cc/MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", size = 16670 }, 458 | { url = "https://files.pythonhosted.org/packages/b7/a2/c78a06a9ec6d04b3445a949615c4c7ed86a0b2eb68e44e7541b9d57067cc/MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", size = 17224 }, 459 | { url = "https://files.pythonhosted.org/packages/53/bd/583bf3e4c8d6a321938c13f49d44024dbe5ed63e0a7ba127e454a66da974/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", size = 18215 }, 460 | { url = "https://files.pythonhosted.org/packages/48/d6/e7cd795fc710292c3af3a06d80868ce4b02bfbbf370b7cee11d282815a2a/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", size = 14069 }, 461 | { url = "https://files.pythonhosted.org/packages/51/b5/5d8ec796e2a08fc814a2c7d2584b55f889a55cf17dd1a90f2beb70744e5c/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", size = 29452 }, 462 | { url = "https://files.pythonhosted.org/packages/0a/0d/2454f072fae3b5a137c119abf15465d1771319dfe9e4acbb31722a0fff91/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", size = 28462 }, 463 | { url = "https://files.pythonhosted.org/packages/2d/75/fd6cb2e68780f72d47e6671840ca517bda5ef663d30ada7616b0462ad1e3/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", size = 27869 }, 464 | { url = "https://files.pythonhosted.org/packages/b0/81/147c477391c2750e8fc7705829f7351cf1cd3be64406edcf900dc633feb2/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", size = 33906 }, 465 | { url = "https://files.pythonhosted.org/packages/8b/ff/9a52b71839d7a256b563e85d11050e307121000dcebc97df120176b3ad93/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", size = 32296 }, 466 | { url = "https://files.pythonhosted.org/packages/88/07/2dc76aa51b481eb96a4c3198894f38b480490e834479611a4053fbf08623/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", size = 33038 }, 467 | { url = "https://files.pythonhosted.org/packages/96/0c/620c1fb3661858c0e37eb3cbffd8c6f732a67cd97296f725789679801b31/MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", size = 16572 }, 468 | { url = "https://files.pythonhosted.org/packages/3f/14/c3554d512d5f9100a95e737502f4a2323a1959f6d0d01e0d0997b35f7b10/MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", size = 17127 }, 469 | ] 470 | 471 | [[package]] 472 | name = "mdurl" 473 | version = "0.1.2" 474 | source = { registry = "https://pypi.org/simple" } 475 | sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } 476 | wheels = [ 477 | { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, 478 | ] 479 | 480 | [[package]] 481 | name = "mermaid-agent" 482 | version = "0.1.0" 483 | source = { editable = "." } 484 | dependencies = [ 485 | { name = "jinja2" }, 486 | { name = "llm" }, 487 | { name = "llm-claude-3" }, 488 | { name = "llm-gemini" }, 489 | { name = "mako" }, 490 | { name = "openai" }, 491 | { name = "pillow" }, 492 | { name = "pydantic" }, 493 | { name = "pytest" }, 494 | { name = "python-dotenv" }, 495 | { name = "requests" }, 496 | { name = "typer" }, 497 | ] 498 | 499 | [package.metadata] 500 | requires-dist = [ 501 | { name = "jinja2", specifier = ">=3.1.4" }, 502 | { name = "llm", specifier = ">=0.15" }, 503 | { name = "llm-claude-3", specifier = ">=0.4" }, 504 | { name = "llm-gemini", specifier = ">=0.1a4" }, 505 | { name = "mako", specifier = ">=1.3.5" }, 506 | { name = "openai", specifier = ">=1.42.0" }, 507 | { name = "pillow", specifier = ">=10.4.0" }, 508 | { name = "pydantic", specifier = ">=2.8.2" }, 509 | { name = "pytest", specifier = ">=8.3.2" }, 510 | { name = "python-dotenv", specifier = ">=1.0.1" }, 511 | { name = "requests", specifier = ">=2.32.3" }, 512 | { name = "typer", specifier = ">=0.12.5" }, 513 | ] 514 | 515 | [[package]] 516 | name = "openai" 517 | version = "1.42.0" 518 | source = { registry = "https://pypi.org/simple" } 519 | dependencies = [ 520 | { name = "anyio" }, 521 | { name = "distro" }, 522 | { name = "httpx" }, 523 | { name = "jiter" }, 524 | { name = "pydantic" }, 525 | { name = "sniffio" }, 526 | { name = "tqdm" }, 527 | { name = "typing-extensions" }, 528 | ] 529 | sdist = { url = "https://files.pythonhosted.org/packages/8c/1f/310b0b5efb6178ad9f9ca4a80b2ead3cb7cbc16a1b843941bcf1c52dd884/openai-1.42.0.tar.gz", hash = "sha256:c9d31853b4e0bc2dc8bd08003b462a006035655a701471695d0bfdc08529cde3", size = 290549 } 530 | wheels = [ 531 | { url = "https://files.pythonhosted.org/packages/cf/9e/d77569d06e365f093977d94f305a395b7ac5ccd746016a2e8dd34c4e20c1/openai-1.42.0-py3-none-any.whl", hash = "sha256:dc91e0307033a4f94931e5d03cc3b29b9717014ad5e73f9f2051b6cb5eda4d80", size = 362858 }, 532 | ] 533 | 534 | [[package]] 535 | name = "packaging" 536 | version = "24.1" 537 | source = { registry = "https://pypi.org/simple" } 538 | sdist = { url = "https://files.pythonhosted.org/packages/51/65/50db4dda066951078f0a96cf12f4b9ada6e4b811516bf0262c0f4f7064d4/packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", size = 148788 } 539 | wheels = [ 540 | { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985 }, 541 | ] 542 | 543 | [[package]] 544 | name = "pillow" 545 | version = "10.4.0" 546 | source = { registry = "https://pypi.org/simple" } 547 | sdist = { url = "https://files.pythonhosted.org/packages/cd/74/ad3d526f3bf7b6d3f408b73fde271ec69dfac8b81341a318ce825f2b3812/pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06", size = 46555059 } 548 | wheels = [ 549 | { url = "https://files.pythonhosted.org/packages/0e/69/a31cccd538ca0b5272be2a38347f8839b97a14be104ea08b0db92f749c74/pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e", size = 3509271 }, 550 | { url = "https://files.pythonhosted.org/packages/9a/9e/4143b907be8ea0bce215f2ae4f7480027473f8b61fcedfda9d851082a5d2/pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d", size = 3375658 }, 551 | { url = "https://files.pythonhosted.org/packages/8a/25/1fc45761955f9359b1169aa75e241551e74ac01a09f487adaaf4c3472d11/pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856", size = 4332075 }, 552 | { url = "https://files.pythonhosted.org/packages/5e/dd/425b95d0151e1d6c951f45051112394f130df3da67363b6bc75dc4c27aba/pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f", size = 4444808 }, 553 | { url = "https://files.pythonhosted.org/packages/b1/84/9a15cc5726cbbfe7f9f90bfb11f5d028586595907cd093815ca6644932e3/pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b", size = 4356290 }, 554 | { url = "https://files.pythonhosted.org/packages/b5/5b/6651c288b08df3b8c1e2f8c1152201e0b25d240e22ddade0f1e242fc9fa0/pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc", size = 4525163 }, 555 | { url = "https://files.pythonhosted.org/packages/07/8b/34854bf11a83c248505c8cb0fcf8d3d0b459a2246c8809b967963b6b12ae/pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e", size = 4463100 }, 556 | { url = "https://files.pythonhosted.org/packages/78/63/0632aee4e82476d9cbe5200c0cdf9ba41ee04ed77887432845264d81116d/pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46", size = 4592880 }, 557 | { url = "https://files.pythonhosted.org/packages/df/56/b8663d7520671b4398b9d97e1ed9f583d4afcbefbda3c6188325e8c297bd/pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984", size = 2235218 }, 558 | { url = "https://files.pythonhosted.org/packages/f4/72/0203e94a91ddb4a9d5238434ae6c1ca10e610e8487036132ea9bf806ca2a/pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141", size = 2554487 }, 559 | { url = "https://files.pythonhosted.org/packages/bd/52/7e7e93d7a6e4290543f17dc6f7d3af4bd0b3dd9926e2e8a35ac2282bc5f4/pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1", size = 2243219 }, 560 | { url = "https://files.pythonhosted.org/packages/a7/62/c9449f9c3043c37f73e7487ec4ef0c03eb9c9afc91a92b977a67b3c0bbc5/pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c", size = 3509265 }, 561 | { url = "https://files.pythonhosted.org/packages/f4/5f/491dafc7bbf5a3cc1845dc0430872e8096eb9e2b6f8161509d124594ec2d/pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be", size = 3375655 }, 562 | { url = "https://files.pythonhosted.org/packages/73/d5/c4011a76f4207a3c151134cd22a1415741e42fa5ddecec7c0182887deb3d/pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3", size = 4340304 }, 563 | { url = "https://files.pythonhosted.org/packages/ac/10/c67e20445a707f7a610699bba4fe050583b688d8cd2d202572b257f46600/pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6", size = 4452804 }, 564 | { url = "https://files.pythonhosted.org/packages/a9/83/6523837906d1da2b269dee787e31df3b0acb12e3d08f024965a3e7f64665/pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe", size = 4365126 }, 565 | { url = "https://files.pythonhosted.org/packages/ba/e5/8c68ff608a4203085158cff5cc2a3c534ec384536d9438c405ed6370d080/pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319", size = 4533541 }, 566 | { url = "https://files.pythonhosted.org/packages/f4/7c/01b8dbdca5bc6785573f4cee96e2358b0918b7b2c7b60d8b6f3abf87a070/pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d", size = 4471616 }, 567 | { url = "https://files.pythonhosted.org/packages/c8/57/2899b82394a35a0fbfd352e290945440e3b3785655a03365c0ca8279f351/pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696", size = 4600802 }, 568 | { url = "https://files.pythonhosted.org/packages/4d/d7/a44f193d4c26e58ee5d2d9db3d4854b2cfb5b5e08d360a5e03fe987c0086/pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496", size = 2235213 }, 569 | { url = "https://files.pythonhosted.org/packages/c1/d0/5866318eec2b801cdb8c82abf190c8343d8a1cd8bf5a0c17444a6f268291/pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91", size = 2554498 }, 570 | { url = "https://files.pythonhosted.org/packages/d4/c8/310ac16ac2b97e902d9eb438688de0d961660a87703ad1561fd3dfbd2aa0/pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22", size = 2243219 }, 571 | { url = "https://files.pythonhosted.org/packages/05/cb/0353013dc30c02a8be34eb91d25e4e4cf594b59e5a55ea1128fde1e5f8ea/pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94", size = 3509350 }, 572 | { url = "https://files.pythonhosted.org/packages/e7/cf/5c558a0f247e0bf9cec92bff9b46ae6474dd736f6d906315e60e4075f737/pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597", size = 3374980 }, 573 | { url = "https://files.pythonhosted.org/packages/84/48/6e394b86369a4eb68b8a1382c78dc092245af517385c086c5094e3b34428/pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80", size = 4343799 }, 574 | { url = "https://files.pythonhosted.org/packages/3b/f3/a8c6c11fa84b59b9df0cd5694492da8c039a24cd159f0f6918690105c3be/pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca", size = 4459973 }, 575 | { url = "https://files.pythonhosted.org/packages/7d/1b/c14b4197b80150fb64453585247e6fb2e1d93761fa0fa9cf63b102fde822/pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef", size = 4370054 }, 576 | { url = "https://files.pythonhosted.org/packages/55/77/40daddf677897a923d5d33329acd52a2144d54a9644f2a5422c028c6bf2d/pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a", size = 4539484 }, 577 | { url = "https://files.pythonhosted.org/packages/40/54/90de3e4256b1207300fb2b1d7168dd912a2fb4b2401e439ba23c2b2cabde/pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b", size = 4477375 }, 578 | { url = "https://files.pythonhosted.org/packages/13/24/1bfba52f44193860918ff7c93d03d95e3f8748ca1de3ceaf11157a14cf16/pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9", size = 4608773 }, 579 | { url = "https://files.pythonhosted.org/packages/55/04/5e6de6e6120451ec0c24516c41dbaf80cce1b6451f96561235ef2429da2e/pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42", size = 2235690 }, 580 | { url = "https://files.pythonhosted.org/packages/74/0a/d4ce3c44bca8635bd29a2eab5aa181b654a734a29b263ca8efe013beea98/pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a", size = 2554951 }, 581 | { url = "https://files.pythonhosted.org/packages/b5/ca/184349ee40f2e92439be9b3502ae6cfc43ac4b50bc4fc6b3de7957563894/pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9", size = 2243427 }, 582 | { url = "https://files.pythonhosted.org/packages/c3/00/706cebe7c2c12a6318aabe5d354836f54adff7156fd9e1bd6c89f4ba0e98/pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3", size = 3525685 }, 583 | { url = "https://files.pythonhosted.org/packages/cf/76/f658cbfa49405e5ecbfb9ba42d07074ad9792031267e782d409fd8fe7c69/pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb", size = 3374883 }, 584 | { url = "https://files.pythonhosted.org/packages/46/2b/99c28c4379a85e65378211971c0b430d9c7234b1ec4d59b2668f6299e011/pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70", size = 4339837 }, 585 | { url = "https://files.pythonhosted.org/packages/f1/74/b1ec314f624c0c43711fdf0d8076f82d9d802afd58f1d62c2a86878e8615/pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be", size = 4455562 }, 586 | { url = "https://files.pythonhosted.org/packages/4a/2a/4b04157cb7b9c74372fa867096a1607e6fedad93a44deeff553ccd307868/pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0", size = 4366761 }, 587 | { url = "https://files.pythonhosted.org/packages/ac/7b/8f1d815c1a6a268fe90481232c98dd0e5fa8c75e341a75f060037bd5ceae/pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc", size = 4536767 }, 588 | { url = "https://files.pythonhosted.org/packages/e5/77/05fa64d1f45d12c22c314e7b97398ffb28ef2813a485465017b7978b3ce7/pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a", size = 4477989 }, 589 | { url = "https://files.pythonhosted.org/packages/12/63/b0397cfc2caae05c3fb2f4ed1b4fc4fc878f0243510a7a6034ca59726494/pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309", size = 4610255 }, 590 | { url = "https://files.pythonhosted.org/packages/7b/f9/cfaa5082ca9bc4a6de66ffe1c12c2d90bf09c309a5f52b27759a596900e7/pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060", size = 2235603 }, 591 | { url = "https://files.pythonhosted.org/packages/01/6a/30ff0eef6e0c0e71e55ded56a38d4859bf9d3634a94a88743897b5f96936/pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea", size = 2554972 }, 592 | { url = "https://files.pythonhosted.org/packages/48/2c/2e0a52890f269435eee38b21c8218e102c621fe8d8df8b9dd06fabf879ba/pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d", size = 2243375 }, 593 | { url = "https://files.pythonhosted.org/packages/38/30/095d4f55f3a053392f75e2eae45eba3228452783bab3d9a920b951ac495c/pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4", size = 3493889 }, 594 | { url = "https://files.pythonhosted.org/packages/f3/e8/4ff79788803a5fcd5dc35efdc9386af153569853767bff74540725b45863/pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da", size = 3346160 }, 595 | { url = "https://files.pythonhosted.org/packages/d7/ac/4184edd511b14f760c73f5bb8a5d6fd85c591c8aff7c2229677a355c4179/pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026", size = 3435020 }, 596 | { url = "https://files.pythonhosted.org/packages/da/21/1749cd09160149c0a246a81d646e05f35041619ce76f6493d6a96e8d1103/pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e", size = 3490539 }, 597 | { url = "https://files.pythonhosted.org/packages/b6/f5/f71fe1888b96083b3f6dfa0709101f61fc9e972c0c8d04e9d93ccef2a045/pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5", size = 3476125 }, 598 | { url = "https://files.pythonhosted.org/packages/96/b9/c0362c54290a31866c3526848583a2f45a535aa9d725fd31e25d318c805f/pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885", size = 3579373 }, 599 | { url = "https://files.pythonhosted.org/packages/52/3b/ce7a01026a7cf46e5452afa86f97a5e88ca97f562cafa76570178ab56d8d/pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5", size = 2554661 }, 600 | ] 601 | 602 | [[package]] 603 | name = "pip" 604 | version = "24.2" 605 | source = { registry = "https://pypi.org/simple" } 606 | sdist = { url = "https://files.pythonhosted.org/packages/4d/87/fb90046e096a03aeab235e139436b3fe804cdd447ed2093b0d70eba3f7f8/pip-24.2.tar.gz", hash = "sha256:5b5e490b5e9cb275c879595064adce9ebd31b854e3e803740b72f9ccf34a45b8", size = 1922041 } 607 | wheels = [ 608 | { url = "https://files.pythonhosted.org/packages/d4/55/90db48d85f7689ec6f81c0db0622d704306c5284850383c090e6c7195a5c/pip-24.2-py3-none-any.whl", hash = "sha256:2cd581cf58ab7fcfca4ce8efa6dcacd0de5bf8d0a3eb9ec927e07405f4d9e2a2", size = 1815170 }, 609 | ] 610 | 611 | [[package]] 612 | name = "pluggy" 613 | version = "1.5.0" 614 | source = { registry = "https://pypi.org/simple" } 615 | sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } 616 | wheels = [ 617 | { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, 618 | ] 619 | 620 | [[package]] 621 | name = "pydantic" 622 | version = "2.8.2" 623 | source = { registry = "https://pypi.org/simple" } 624 | dependencies = [ 625 | { name = "annotated-types" }, 626 | { name = "pydantic-core" }, 627 | { name = "typing-extensions" }, 628 | ] 629 | sdist = { url = "https://files.pythonhosted.org/packages/8c/99/d0a5dca411e0a017762258013ba9905cd6e7baa9a3fd1fe8b6529472902e/pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a", size = 739834 } 630 | wheels = [ 631 | { url = "https://files.pythonhosted.org/packages/1f/fa/b7f815b8c9ad021c07f88875b601222ef5e70619391ade4a49234d12d278/pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8", size = 423875 }, 632 | ] 633 | 634 | [[package]] 635 | name = "pydantic-core" 636 | version = "2.20.1" 637 | source = { registry = "https://pypi.org/simple" } 638 | dependencies = [ 639 | { name = "typing-extensions" }, 640 | ] 641 | sdist = { url = "https://files.pythonhosted.org/packages/12/e3/0d5ad91211dba310f7ded335f4dad871172b9cc9ce204f5a56d76ccd6247/pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4", size = 388371 } 642 | wheels = [ 643 | { url = "https://files.pythonhosted.org/packages/6b/9d/f30f080f745682e762512f3eef1f6e392c7d74a102e6e96de8a013a5db84/pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3", size = 1837257 }, 644 | { url = "https://files.pythonhosted.org/packages/f2/89/77e7aebdd4a235497ac1e07f0a99e9f40e47f6e0f6783fe30500df08fc42/pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6", size = 1776715 }, 645 | { url = "https://files.pythonhosted.org/packages/18/50/5a4e9120b395108c2a0441a425356c0d26a655d7c617288bec1c28b854ac/pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a", size = 1789023 }, 646 | { url = "https://files.pythonhosted.org/packages/c7/e5/f19e13ba86b968d024b56aa53f40b24828652ac026e5addd0ae49eeada02/pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3", size = 1775598 }, 647 | { url = "https://files.pythonhosted.org/packages/c9/c7/f3c29bed28bd022c783baba5bf9946c4f694cb837a687e62f453c81eb5c6/pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1", size = 1977691 }, 648 | { url = "https://files.pythonhosted.org/packages/41/3e/f62c2a05c554fff34570f6788617e9670c83ed7bc07d62a55cccd1bc0be6/pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953", size = 2693214 }, 649 | { url = "https://files.pythonhosted.org/packages/ae/49/8a6fe79d35e2f3bea566d8ea0e4e6f436d4f749d7838c8e8c4c5148ae706/pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98", size = 2061047 }, 650 | { url = "https://files.pythonhosted.org/packages/51/c6/585355c7c8561e11197dbf6333c57dd32f9f62165d48589b57ced2373d97/pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a", size = 1895106 }, 651 | { url = "https://files.pythonhosted.org/packages/ce/23/829f6b87de0775919e82f8addef8b487ace1c77bb4cb754b217f7b1301b6/pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a", size = 1968506 }, 652 | { url = "https://files.pythonhosted.org/packages/ca/2f/f8ca8f0c40b3ee0a4d8730a51851adb14c5eda986ec09f8d754b2fba784e/pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840", size = 2110217 }, 653 | { url = "https://files.pythonhosted.org/packages/bb/a0/1876656c7b17eb69cc683452cce6bb890dd722222a71b3de57ddb512f561/pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250", size = 1709669 }, 654 | { url = "https://files.pythonhosted.org/packages/be/4a/576524eefa9b301c088c4818dc50ff1c51a88fe29efd87ab75748ae15fd7/pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c", size = 1902386 }, 655 | { url = "https://files.pythonhosted.org/packages/61/db/f6a724db226d990a329910727cfac43539ff6969edc217286dd05cda3ef6/pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312", size = 1834507 }, 656 | { url = "https://files.pythonhosted.org/packages/9b/83/6f2bfe75209d557ae1c3550c1252684fc1827b8b12fbed84c3b4439e135d/pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88", size = 1773527 }, 657 | { url = "https://files.pythonhosted.org/packages/93/ef/513ea76d7ca81f2354bb9c8d7839fc1157673e652613f7e1aff17d8ce05d/pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc", size = 1787879 }, 658 | { url = "https://files.pythonhosted.org/packages/31/0a/ac294caecf235f0cc651de6232f1642bb793af448d1cfc541b0dc1fd72b8/pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43", size = 1774694 }, 659 | { url = "https://files.pythonhosted.org/packages/46/a4/08f12b5512f095963550a7cb49ae010e3f8f3f22b45e508c2cb4d7744fce/pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6", size = 1976369 }, 660 | { url = "https://files.pythonhosted.org/packages/15/59/b2495be4410462aedb399071c71884042a2c6443319cbf62d00b4a7ed7a5/pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121", size = 2691250 }, 661 | { url = "https://files.pythonhosted.org/packages/3c/ae/fc99ce1ba791c9e9d1dee04ce80eef1dae5b25b27e3fc8e19f4e3f1348bf/pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1", size = 2061462 }, 662 | { url = "https://files.pythonhosted.org/packages/44/bb/eb07cbe47cfd638603ce3cb8c220f1a054b821e666509e535f27ba07ca5f/pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b", size = 1893923 }, 663 | { url = "https://files.pythonhosted.org/packages/ce/ef/5a52400553b8faa0e7f11fd7a2ba11e8d2feb50b540f9e7973c49b97eac0/pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27", size = 1966779 }, 664 | { url = "https://files.pythonhosted.org/packages/4c/5b/fb37fe341344d9651f5c5f579639cd97d50a457dc53901aa8f7e9f28beb9/pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b", size = 2109044 }, 665 | { url = "https://files.pythonhosted.org/packages/70/1a/6f7278802dbc66716661618807ab0dfa4fc32b09d1235923bbbe8b3a5757/pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a", size = 1708265 }, 666 | { url = "https://files.pythonhosted.org/packages/35/7f/58758c42c61b0bdd585158586fecea295523d49933cb33664ea888162daf/pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2", size = 1901750 }, 667 | { url = "https://files.pythonhosted.org/packages/6f/47/ef0d60ae23c41aced42921728650460dc831a0adf604bfa66b76028cb4d0/pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231", size = 1839225 }, 668 | { url = "https://files.pythonhosted.org/packages/6a/23/430f2878c9cd977a61bb39f71751d9310ec55cee36b3d5bf1752c6341fd0/pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9", size = 1768604 }, 669 | { url = "https://files.pythonhosted.org/packages/9e/2b/ec4e7225dee79e0dc80ccc3c35ab33cc2c4bbb8a1a7ecf060e5e453651ec/pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f", size = 1789767 }, 670 | { url = "https://files.pythonhosted.org/packages/64/b0/38b24a1fa6d2f96af3148362e10737ec073768cd44d3ec21dca3be40a519/pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52", size = 1772061 }, 671 | { url = "https://files.pythonhosted.org/packages/5e/da/bb73274c42cb60decfa61e9eb0c9029da78b3b9af0a9de0309dbc8ff87b6/pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237", size = 1974573 }, 672 | { url = "https://files.pythonhosted.org/packages/c8/65/41693110fb3552556180460daffdb8bbeefb87fc026fd9aa4b849374015c/pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe", size = 2625596 }, 673 | { url = "https://files.pythonhosted.org/packages/09/b3/a5a54b47cccd1ab661ed5775235c5e06924753c2d4817737c5667bfa19a8/pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e", size = 2099064 }, 674 | { url = "https://files.pythonhosted.org/packages/52/fa/443a7a6ea54beaba45ff3a59f3d3e6e3004b7460bcfb0be77bcf98719d3b/pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24", size = 1900345 }, 675 | { url = "https://files.pythonhosted.org/packages/8e/e6/9aca9ffae60f9cdf0183069de3e271889b628d0fb175913fcb3db5618fb1/pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1", size = 1968252 }, 676 | { url = "https://files.pythonhosted.org/packages/46/5e/6c716810ea20a6419188992973a73c2fb4eb99cd382368d0637ddb6d3c99/pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd", size = 2119191 }, 677 | { url = "https://files.pythonhosted.org/packages/06/fc/6123b00a9240fbb9ae0babad7a005d51103d9a5d39c957a986f5cdd0c271/pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688", size = 1717788 }, 678 | { url = "https://files.pythonhosted.org/packages/d5/36/e61ad5a46607a469e2786f398cd671ebafcd9fb17f09a2359985c7228df5/pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d", size = 1898188 }, 679 | { url = "https://files.pythonhosted.org/packages/49/75/40b0e98b658fdba02a693b3bacb4c875a28bba87796c7b13975976597d8c/pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686", size = 1838688 }, 680 | { url = "https://files.pythonhosted.org/packages/75/02/d8ba2d4a266591a6a623c68b331b96523d4b62ab82a951794e3ed8907390/pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a", size = 1768409 }, 681 | { url = "https://files.pythonhosted.org/packages/91/ae/25ecd9bc4ce4993e99a1a3c9ab111c082630c914260e129572fafed4ecc2/pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b", size = 1789317 }, 682 | { url = "https://files.pythonhosted.org/packages/7a/80/72057580681cdbe55699c367963d9c661b569a1d39338b4f6239faf36cdc/pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19", size = 1771949 }, 683 | { url = "https://files.pythonhosted.org/packages/a2/be/d9bbabc55b05019013180f141fcaf3b14dbe15ca7da550e95b60c321009a/pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac", size = 1974392 }, 684 | { url = "https://files.pythonhosted.org/packages/79/2d/7bcd938c6afb0f40293283f5f09988b61fb0a4f1d180abe7c23a2f665f8e/pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703", size = 2625565 }, 685 | { url = "https://files.pythonhosted.org/packages/ac/88/ca758e979457096008a4b16a064509028e3e092a1e85a5ed6c18ced8da88/pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c", size = 2098784 }, 686 | { url = "https://files.pythonhosted.org/packages/eb/de/2fad6d63c3c42e472e985acb12ec45b7f56e42e6f4cd6dfbc5e87ee8678c/pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83", size = 1900198 }, 687 | { url = "https://files.pythonhosted.org/packages/fe/50/077c7f35b6488dc369a6d22993af3a37901e198630f38ac43391ca730f5b/pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203", size = 1968005 }, 688 | { url = "https://files.pythonhosted.org/packages/5d/1f/f378631574ead46d636b9a04a80ff878b9365d4b361b1905ef1667d4182a/pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0", size = 2118920 }, 689 | { url = "https://files.pythonhosted.org/packages/7a/ea/e4943f17df7a3031d709481fe4363d4624ae875a6409aec34c28c9e6cf59/pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e", size = 1717397 }, 690 | { url = "https://files.pythonhosted.org/packages/13/63/b95781763e8d84207025071c0cec16d921c0163c7a9033ae4b9a0e020dc7/pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20", size = 1898013 }, 691 | { url = "https://files.pythonhosted.org/packages/73/73/0c7265903f66cce39ed7ca939684fba344210cefc91ccc999cfd5b113fd3/pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906", size = 1828190 }, 692 | { url = "https://files.pythonhosted.org/packages/27/55/60b8b0e58b49ee3ed36a18562dd7c6bc06a551c390e387af5872a238f2ec/pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94", size = 1715252 }, 693 | { url = "https://files.pythonhosted.org/packages/28/3d/d66314bad6bb777a36559195a007b31e916bd9e2c198f7bb8f4ccdceb4fa/pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f", size = 1782641 }, 694 | { url = "https://files.pythonhosted.org/packages/9e/f5/f178f4354d0d6c1431a8f9ede71f3c4269ac4dc55d314fdb7555814276dc/pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482", size = 1928788 }, 695 | { url = "https://files.pythonhosted.org/packages/9c/51/1f5e27bb194df79e30b593b608c66e881ed481241e2b9ed5bdf86d165480/pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6", size = 1886116 }, 696 | { url = "https://files.pythonhosted.org/packages/ac/76/450d9258c58dc7c70b9e3aadf6bebe23ddd99e459c365e2adbde80e238da/pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc", size = 1960125 }, 697 | { url = "https://files.pythonhosted.org/packages/dd/9e/0309a7a4bea51771729515e413b3987be0789837de99087f7415e0db1f9b/pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99", size = 2100407 }, 698 | { url = "https://files.pythonhosted.org/packages/af/93/06d44e08277b3b818b75bd5f25e879d7693e4b7dd3505fde89916fcc9ca2/pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6", size = 1914966 }, 699 | ] 700 | 701 | [[package]] 702 | name = "pygments" 703 | version = "2.18.0" 704 | source = { registry = "https://pypi.org/simple" } 705 | sdist = { url = "https://files.pythonhosted.org/packages/8e/62/8336eff65bcbc8e4cb5d05b55faf041285951b6e80f33e2bff2024788f31/pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", size = 4891905 } 706 | wheels = [ 707 | { url = "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", size = 1205513 }, 708 | ] 709 | 710 | [[package]] 711 | name = "pyreadline3" 712 | version = "3.4.1" 713 | source = { registry = "https://pypi.org/simple" } 714 | sdist = { url = "https://files.pythonhosted.org/packages/d7/86/3d61a61f36a0067874a00cb4dceb9028d34b6060e47828f7fc86fb9f7ee9/pyreadline3-3.4.1.tar.gz", hash = "sha256:6f3d1f7b8a31ba32b73917cefc1f28cc660562f39aea8646d30bd6eff21f7bae", size = 86465 } 715 | wheels = [ 716 | { url = "https://files.pythonhosted.org/packages/56/fc/a3c13ded7b3057680c8ae95a9b6cc83e63657c38e0005c400a5d018a33a7/pyreadline3-3.4.1-py3-none-any.whl", hash = "sha256:b0efb6516fd4fb07b45949053826a62fa4cb353db5be2bbb4a7aa1fdd1e345fb", size = 95203 }, 717 | ] 718 | 719 | [[package]] 720 | name = "pytest" 721 | version = "8.3.2" 722 | source = { registry = "https://pypi.org/simple" } 723 | dependencies = [ 724 | { name = "colorama", marker = "sys_platform == 'win32'" }, 725 | { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, 726 | { name = "iniconfig" }, 727 | { name = "packaging" }, 728 | { name = "pluggy" }, 729 | { name = "tomli", marker = "python_full_version < '3.11'" }, 730 | ] 731 | sdist = { url = "https://files.pythonhosted.org/packages/b4/8c/9862305bdcd6020bc7b45b1b5e7397a6caf1a33d3025b9a003b39075ffb2/pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce", size = 1439314 } 732 | wheels = [ 733 | { url = "https://files.pythonhosted.org/packages/0f/f9/cf155cf32ca7d6fa3601bc4c5dd19086af4b320b706919d48a4c79081cf9/pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5", size = 341802 }, 734 | ] 735 | 736 | [[package]] 737 | name = "python-dateutil" 738 | version = "2.9.0.post0" 739 | source = { registry = "https://pypi.org/simple" } 740 | dependencies = [ 741 | { name = "six" }, 742 | ] 743 | sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } 744 | wheels = [ 745 | { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, 746 | ] 747 | 748 | [[package]] 749 | name = "python-dotenv" 750 | version = "1.0.1" 751 | source = { registry = "https://pypi.org/simple" } 752 | sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 } 753 | wheels = [ 754 | { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 }, 755 | ] 756 | 757 | [[package]] 758 | name = "python-ulid" 759 | version = "2.7.0" 760 | source = { registry = "https://pypi.org/simple" } 761 | sdist = { url = "https://files.pythonhosted.org/packages/a9/c5/03acac11f80d718da98201dadf6fdcf5aa4001e83bb61a65b6b91baa489c/python_ulid-2.7.0.tar.gz", hash = "sha256:18eb595885140851a490a95b0da4447911ff69fa9f434732067b97f6956f9fe9", size = 25010 } 762 | wheels = [ 763 | { url = "https://files.pythonhosted.org/packages/e2/48/90be1411fdbd38d291fa9e97621a60b5576d9122449bce4505ddfcfc9328/python_ulid-2.7.0-py3-none-any.whl", hash = "sha256:c81658e382f69bad8c6d365155c4ae21843ae4226b94f72c12d7adcbb545a251", size = 10788 }, 764 | ] 765 | 766 | [[package]] 767 | name = "pyyaml" 768 | version = "6.0.2" 769 | source = { registry = "https://pypi.org/simple" } 770 | sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } 771 | wheels = [ 772 | { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199 }, 773 | { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758 }, 774 | { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463 }, 775 | { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280 }, 776 | { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239 }, 777 | { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802 }, 778 | { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527 }, 779 | { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052 }, 780 | { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774 }, 781 | { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612 }, 782 | { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040 }, 783 | { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829 }, 784 | { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167 }, 785 | { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952 }, 786 | { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301 }, 787 | { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638 }, 788 | { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850 }, 789 | { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980 }, 790 | { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, 791 | { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, 792 | { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, 793 | { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, 794 | { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, 795 | { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, 796 | { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, 797 | { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, 798 | { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, 799 | { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, 800 | { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, 801 | { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, 802 | { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, 803 | { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, 804 | { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, 805 | { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, 806 | { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, 807 | { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, 808 | ] 809 | 810 | [[package]] 811 | name = "requests" 812 | version = "2.32.3" 813 | source = { registry = "https://pypi.org/simple" } 814 | dependencies = [ 815 | { name = "certifi" }, 816 | { name = "charset-normalizer" }, 817 | { name = "idna" }, 818 | { name = "urllib3" }, 819 | ] 820 | sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } 821 | wheels = [ 822 | { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, 823 | ] 824 | 825 | [[package]] 826 | name = "rich" 827 | version = "13.8.0" 828 | source = { registry = "https://pypi.org/simple" } 829 | dependencies = [ 830 | { name = "markdown-it-py" }, 831 | { name = "pygments" }, 832 | ] 833 | sdist = { url = "https://files.pythonhosted.org/packages/cf/60/5959113cae0ce512cf246a6871c623117330105a0d5f59b4e26138f2c9cc/rich-13.8.0.tar.gz", hash = "sha256:a5ac1f1cd448ade0d59cc3356f7db7a7ccda2c8cbae9c7a90c28ff463d3e91f4", size = 222072 } 834 | wheels = [ 835 | { url = "https://files.pythonhosted.org/packages/c7/d9/c2a126eeae791e90ea099d05cb0515feea3688474b978343f3cdcfe04523/rich-13.8.0-py3-none-any.whl", hash = "sha256:2e85306a063b9492dffc86278197a60cbece75bcb766022f3436f567cae11bdc", size = 241597 }, 836 | ] 837 | 838 | [[package]] 839 | name = "setuptools" 840 | version = "74.0.0" 841 | source = { registry = "https://pypi.org/simple" } 842 | sdist = { url = "https://files.pythonhosted.org/packages/6a/21/8fd457d5a979109603e0e460c73177c3a9b6b7abcd136d0146156da95895/setuptools-74.0.0.tar.gz", hash = "sha256:a85e96b8be2b906f3e3e789adec6a9323abf79758ecfa3065bd740d81158b11e", size = 1389536 } 843 | wheels = [ 844 | { url = "https://files.pythonhosted.org/packages/df/b5/168cec9a10bf93b60b8f9af7f4e61d526e31e1aad8b9be0e30837746d700/setuptools-74.0.0-py3-none-any.whl", hash = "sha256:0274581a0037b638b9fc1c6883cc71c0210865aaa76073f7882376b641b84e8f", size = 1301729 }, 845 | ] 846 | 847 | [[package]] 848 | name = "shellingham" 849 | version = "1.5.4" 850 | source = { registry = "https://pypi.org/simple" } 851 | sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310 } 852 | wheels = [ 853 | { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 }, 854 | ] 855 | 856 | [[package]] 857 | name = "six" 858 | version = "1.16.0" 859 | source = { registry = "https://pypi.org/simple" } 860 | sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 } 861 | wheels = [ 862 | { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 }, 863 | ] 864 | 865 | [[package]] 866 | name = "sniffio" 867 | version = "1.3.1" 868 | source = { registry = "https://pypi.org/simple" } 869 | sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } 870 | wheels = [ 871 | { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, 872 | ] 873 | 874 | [[package]] 875 | name = "sqlite-fts4" 876 | version = "1.0.3" 877 | source = { registry = "https://pypi.org/simple" } 878 | sdist = { url = "https://files.pythonhosted.org/packages/c2/6d/9dad6c3b433ab8912ace969c66abd595f8e0a2ccccdb73602b1291dbda29/sqlite-fts4-1.0.3.tar.gz", hash = "sha256:78b05eeaf6680e9dbed8986bde011e9c086a06cb0c931b3cf7da94c214e8930c", size = 9718 } 879 | wheels = [ 880 | { url = "https://files.pythonhosted.org/packages/51/29/0096e8b1811aaa78cfb296996f621f41120c21c2f5cd448ae1d54979d9fc/sqlite_fts4-1.0.3-py3-none-any.whl", hash = "sha256:0359edd8dea6fd73c848989e1e2b1f31a50fe5f9d7272299ff0e8dbaa62d035f", size = 9972 }, 881 | ] 882 | 883 | [[package]] 884 | name = "sqlite-migrate" 885 | version = "0.1b0" 886 | source = { registry = "https://pypi.org/simple" } 887 | dependencies = [ 888 | { name = "sqlite-utils" }, 889 | ] 890 | sdist = { url = "https://files.pythonhosted.org/packages/13/86/1463a00d3c4bdb707c0ed4077d17687465a0aa9444593f66f6c4b49e39b5/sqlite-migrate-0.1b0.tar.gz", hash = "sha256:8d502b3ca4b9c45e56012bd35c03d23235f0823c976d4ce940cbb40e33087ded", size = 10736 } 891 | wheels = [ 892 | { url = "https://files.pythonhosted.org/packages/df/92/994545b912e6d6feb40323047f02ca039321e690aa2c27afcd5c4105e37b/sqlite_migrate-0.1b0-py3-none-any.whl", hash = "sha256:a4125e35e1de3dc56b6b6ec60e9833ce0ce20192b929ddcb2d4246c5098859c6", size = 9986 }, 893 | ] 894 | 895 | [[package]] 896 | name = "sqlite-utils" 897 | version = "3.37" 898 | source = { registry = "https://pypi.org/simple" } 899 | dependencies = [ 900 | { name = "click" }, 901 | { name = "click-default-group" }, 902 | { name = "pluggy" }, 903 | { name = "python-dateutil" }, 904 | { name = "sqlite-fts4" }, 905 | { name = "tabulate" }, 906 | ] 907 | sdist = { url = "https://files.pythonhosted.org/packages/65/c5/a16a5d3f5f64e700a77de3df427ce1fcf5029e38db3352e12a0696448569/sqlite_utils-3.37.tar.gz", hash = "sha256:542a71033d4e7936fe909230ac9794d3e200021838ab63dbaf3ce8f5bc2273a4", size = 211980 } 908 | wheels = [ 909 | { url = "https://files.pythonhosted.org/packages/b5/37/2566f7952b512c7bc54859be73b29270791c6893ce0ef97dcf91cba3c775/sqlite_utils-3.37-py3-none-any.whl", hash = "sha256:4fb0dc9e61b1f9226a14eb1f072e984cf3cb69058dc2838887600a0771e9624f", size = 67704 }, 910 | ] 911 | 912 | [[package]] 913 | name = "tabulate" 914 | version = "0.9.0" 915 | source = { registry = "https://pypi.org/simple" } 916 | sdist = { url = "https://files.pythonhosted.org/packages/ec/fe/802052aecb21e3797b8f7902564ab6ea0d60ff8ca23952079064155d1ae1/tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c", size = 81090 } 917 | wheels = [ 918 | { url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252 }, 919 | ] 920 | 921 | [[package]] 922 | name = "tokenizers" 923 | version = "0.20.0" 924 | source = { registry = "https://pypi.org/simple" } 925 | dependencies = [ 926 | { name = "huggingface-hub" }, 927 | ] 928 | sdist = { url = "https://files.pythonhosted.org/packages/02/3a/508a4875f69e12b08fb3dabfc746039fe763838ff45d6e42229ed09a41c2/tokenizers-0.20.0.tar.gz", hash = "sha256:39d7acc43f564c274085cafcd1dae9d36f332456de1a31970296a6b8da4eac8d", size = 337421 } 929 | wheels = [ 930 | { url = "https://files.pythonhosted.org/packages/0d/47/88f92fb433fe2fb59b35bbce28455095bcb7b40fff385223b1e7818cec38/tokenizers-0.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:6cff5c5e37c41bc5faa519d6f3df0679e4b37da54ea1f42121719c5e2b4905c0", size = 2624575 }, 931 | { url = "https://files.pythonhosted.org/packages/fc/e5/74c6ab076de7d2d4d347e8781086117889d202628dfd5f5fba8ebefb1ea2/tokenizers-0.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:62a56bf75c27443432456f4ca5ca055befa95e25be8a28141cc495cac8ae4d6d", size = 2515759 }, 932 | { url = "https://files.pythonhosted.org/packages/4e/f5/1087cb5100e704dce9a1419d6f3e8ac843c98efa11579c3287ddb036b476/tokenizers-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68cc7de6a63f09c4a86909c2597b995aa66e19df852a23aea894929c74369929", size = 2892020 }, 933 | { url = "https://files.pythonhosted.org/packages/35/07/7004003098e3d442bba9b9821b78f34043248bdf6a78433846944b7d9a61/tokenizers-0.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:053c37ecee482cc958fdee53af3c6534286a86f5d35aac476f7c246830e53ae5", size = 2754734 }, 934 | { url = "https://files.pythonhosted.org/packages/d0/61/9f3def0db2db72d8da6c4c318481a35c5c71172dad54ff3813f765ab2a45/tokenizers-0.20.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3d7074aaabc151a6363fa03db5493fc95b423b2a1874456783989e96d541c7b6", size = 3009897 }, 935 | { url = "https://files.pythonhosted.org/packages/c1/98/f4a9a18a4e2e254c6ed253b3e5344d8f48760d3af6813df4415446db1b4c/tokenizers-0.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a11435780f2acd89e8fefe5e81cecf01776f6edb9b3ac95bcb76baee76b30b90", size = 3032295 }, 936 | { url = "https://files.pythonhosted.org/packages/87/43/52b096d5aacb3eb698f1b791e8a6c1b7ecd39b17724c38312804b79429fa/tokenizers-0.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9a81cd2712973b007d84268d45fc3f6f90a79c31dfe7f1925e6732f8d2959987", size = 3328639 }, 937 | { url = "https://files.pythonhosted.org/packages/fc/7e/794850f99752d1811952722c18652a5c0125b0ef595d9ed069d00da9a5db/tokenizers-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7dfd796ab9d909f76fb93080e1c7c8309f196ecb316eb130718cd5e34231c69", size = 2936169 }, 938 | { url = "https://files.pythonhosted.org/packages/ea/3d/d573173b0cd78cd64e95b5c8f268f3a619877bc6a484b649d98af4de24bf/tokenizers-0.20.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8029ad2aa8cb00605c9374566034c1cc1b15130713e0eb5afcef6cface8255c9", size = 8965441 }, 939 | { url = "https://files.pythonhosted.org/packages/27/cb/76636123a5bc550c48aa8048def1ae3d86421723be2cca8f195f464c20f6/tokenizers-0.20.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ca4d54260ebe97d59dfa9a30baa20d0c4dd9137d99a8801700055c561145c24e", size = 9284485 }, 940 | { url = "https://files.pythonhosted.org/packages/32/16/5eaa1405e15ca91a9e0f6c07963cd91f48daf8f999ff731b589078a4caa1/tokenizers-0.20.0-cp310-none-win32.whl", hash = "sha256:95ee16b57cec11b86a7940174ec5197d506439b0f415ab3859f254b1dffe9df0", size = 2125655 }, 941 | { url = "https://files.pythonhosted.org/packages/63/90/84534f81ff1453a1bcc049b03ea6820ca7ab497519b79b129d7297bb4e60/tokenizers-0.20.0-cp310-none-win_amd64.whl", hash = "sha256:0a61a11e93eeadbf02aea082ffc75241c4198e0608bbbac4f65a9026851dcf37", size = 2326217 }, 942 | { url = "https://files.pythonhosted.org/packages/a4/f6/ae042eeae413bae9af5adceed7fe6f30fb0abc9868a55916d4e07c8ea1fb/tokenizers-0.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6636b798b3c4d6c9b1af1a918bd07c867808e5a21c64324e95318a237e6366c3", size = 2625296 }, 943 | { url = "https://files.pythonhosted.org/packages/62/8b/dab4d716e9a00c1581443213283c9fdfdb982cdad6ecc046bae9c7e42fc8/tokenizers-0.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ec603e42eaf499ffd58b9258162add948717cf21372458132f14e13a6bc7172", size = 2516726 }, 944 | { url = "https://files.pythonhosted.org/packages/95/1e/800e0896ea43ab86d70cfc6ed6a30d6aefcab498eff49db79cc92e08e1fe/tokenizers-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cce124264903a8ea6f8f48e1cc7669e5ef638c18bd4ab0a88769d5f92debdf7f", size = 2891801 }, 945 | { url = "https://files.pythonhosted.org/packages/02/80/22ceab06d120df5b589f993248bceef177a932024ae8ee033ec3da5cc87f/tokenizers-0.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07bbeba0231cf8de07aa6b9e33e9779ff103d47042eeeb859a8c432e3292fb98", size = 2753762 }, 946 | { url = "https://files.pythonhosted.org/packages/22/7c/02431f0711162ab3994e4099b9ece4b6a00755e3180bf5dfe70da0c13836/tokenizers-0.20.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:06c0ca8397b35d38b83a44a9c6929790c1692957d88541df061cb34d82ebbf08", size = 3010928 }, 947 | { url = "https://files.pythonhosted.org/packages/bc/14/193b7e58017e9592799498686df718c5f68bfb72205d3075ce9cdd441db7/tokenizers-0.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ca6557ac3b83d912dfbb1f70ab56bd4b0594043916688e906ede09f42e192401", size = 3032435 }, 948 | { url = "https://files.pythonhosted.org/packages/71/ae/c7fc7a614ce78cab7b8f82f7a24a074837cbc7e0086960cbe4801b2b3c83/tokenizers-0.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a5ad94c9e80ac6098328bee2e3264dbced4c6faa34429994d473f795ec58ef4", size = 3328437 }, 949 | { url = "https://files.pythonhosted.org/packages/a5/0e/e4421e6b8c8b3ae093bef22faa28c50d7dbd654f661edc5f5880a93dbf10/tokenizers-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b5c7f906ee6bec30a9dc20268a8b80f3b9584de1c9f051671cb057dc6ce28f6", size = 2936532 }, 950 | { url = "https://files.pythonhosted.org/packages/b9/08/ac9c8fe9c1f5b4ef89bcbf543cda890e76c2ea1c2e957bf77fd5fcf72b6c/tokenizers-0.20.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:31e087e9ee1b8f075b002bfee257e858dc695f955b43903e1bb4aa9f170e37fe", size = 8965273 }, 951 | { url = "https://files.pythonhosted.org/packages/fb/71/b9626f9f5a33dd1d80bb6d3721f0a4b0b48ced0c702e65aad5c8c7c1ae7e/tokenizers-0.20.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c3124fb6f3346cb3d8d775375d3b429bf4dcfc24f739822702009d20a4297990", size = 9283768 }, 952 | { url = "https://files.pythonhosted.org/packages/ba/78/70f79f939385579bb25f14cb14ab0eaa49e46a7d099577c2e08e3c3597d8/tokenizers-0.20.0-cp311-none-win32.whl", hash = "sha256:a4bb8b40ba9eefa621fdcabf04a74aa6038ae3be0c614c6458bd91a4697a452f", size = 2126085 }, 953 | { url = "https://files.pythonhosted.org/packages/c0/3c/9228601e180b177755fd9f35cbb229c13f1919a55f07a602b1bd7d716470/tokenizers-0.20.0-cp311-none-win_amd64.whl", hash = "sha256:2b709d371f1fe60a28ef0c5c67815952d455ca7f34dbe7197eaaed3cc54b658e", size = 2327670 }, 954 | { url = "https://files.pythonhosted.org/packages/ce/d4/152f9964cee16b43b9147212e925793df1a469324b29b4c7a6cb60280c99/tokenizers-0.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:15c81a17d0d66f4987c6ca16f4bea7ec253b8c7ed1bb00fdc5d038b1bb56e714", size = 2613552 }, 955 | { url = "https://files.pythonhosted.org/packages/6e/99/594b518d44ba2b099753816a9c0c33dbdcf77cc3ec5b256690f70d7431c2/tokenizers-0.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6a531cdf1fb6dc41c984c785a3b299cb0586de0b35683842a3afbb1e5207f910", size = 2513918 }, 956 | { url = "https://files.pythonhosted.org/packages/24/fa/77f0cf9b3c662b4de18953fb06126c424059f4b09ca2d1b720beabc6afde/tokenizers-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06caabeb4587f8404e0cd9d40f458e9cba3e815c8155a38e579a74ff3e2a4301", size = 2892465 }, 957 | { url = "https://files.pythonhosted.org/packages/2d/e6/59abfc09f1dc23a47fd03dd8e3bf3fce67d9be2b8ba15a73c9a86b5a646c/tokenizers-0.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8768f964f23f5b9f50546c0369c75ab3262de926983888bbe8b98be05392a79c", size = 2750862 }, 958 | { url = "https://files.pythonhosted.org/packages/0f/b2/f212ca05c1b246b9429905c18a4d68abacf2a35214eceedb1d65c6c37831/tokenizers-0.20.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:626403860152c816f97b649fd279bd622c3d417678c93b4b1a8909b6380b69a8", size = 3012971 }, 959 | { url = "https://files.pythonhosted.org/packages/16/0b/099f5e5b97e8323837a5828f6d21f4bb2a3b529507dc19bd274e48e15825/tokenizers-0.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c1b88fa9e5ff062326f4bf82681da5a96fca7104d921a6bd7b1e6fcf224af26", size = 3038445 }, 960 | { url = "https://files.pythonhosted.org/packages/62/7c/4e3cb25dc1c5eea6053752f55007071da6b33a96021e0cea4b45b6ef0908/tokenizers-0.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d7e559436a07dc547f22ce1101f26d8b2fad387e28ec8e7e1e3b11695d681d8", size = 3329352 }, 961 | { url = "https://files.pythonhosted.org/packages/32/20/a8fe63317d4f3c015cbd5b6dec0ce08e2722685ca836ad4a44dec53d000f/tokenizers-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e48afb75e50449848964e4a67b0da01261dd3aa8df8daecf10db8fd7f5b076eb", size = 2938786 }, 962 | { url = "https://files.pythonhosted.org/packages/06/e8/78f1c0f356d0a6e4e4e450e2419ace1918bfab875100c3047021a8261ba0/tokenizers-0.20.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:baf5d0e1ff44710a95eefc196dd87666ffc609fd447c5e5b68272a7c3d342a1d", size = 8967350 }, 963 | { url = "https://files.pythonhosted.org/packages/e6/eb/3a1edfc1ffb876ffc1f668c8fa2b2ffb57edf8e9188af49218cf41f9cd9f/tokenizers-0.20.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e5e56df0e8ed23ba60ae3848c3f069a0710c4b197218fe4f89e27eba38510768", size = 9284785 }, 964 | { url = "https://files.pythonhosted.org/packages/00/75/426a93399ba5e6e879215e1abb696adb83b1e2a98d65b47b8ba4262b3d17/tokenizers-0.20.0-cp312-none-win32.whl", hash = "sha256:ec53e5ecc142a82432f9c6c677dbbe5a2bfee92b8abf409a9ecb0d425ee0ce75", size = 2125012 }, 965 | { url = "https://files.pythonhosted.org/packages/a5/45/9c19187645401ec30884379ada74aa6e71fb5eaf20485a82ea37a0fd3659/tokenizers-0.20.0-cp312-none-win_amd64.whl", hash = "sha256:f18661ece72e39c0dfaa174d6223248a15b457dbd4b0fc07809b8e6d3ca1a234", size = 2314154 }, 966 | { url = "https://files.pythonhosted.org/packages/cd/99/dba2f18ba180aefddb65852d2cea69de607232f4cf1d999e789899d56c19/tokenizers-0.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d68e15f1815357b059ec266062340c343ea7f98f7f330602df81ffa3474b6122", size = 2626438 }, 967 | { url = "https://files.pythonhosted.org/packages/79/e6/eb28c3c7d23f3feaa9fb6ae16ff313210474b3c9f81689afe6d132915da0/tokenizers-0.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:23f9ecec637b9bc80da5f703808d29ed5329e56b5aa8d791d1088014f48afadc", size = 2517016 }, 968 | { url = "https://files.pythonhosted.org/packages/18/2f/35f7fdbf1ae6fa3d0348531596a63651fdb117ff367e3dfe8a6be5f31f5a/tokenizers-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f830b318ee599e3d0665b3e325f85bc75ee2d2ca6285f52e439dc22b64691580", size = 2890784 }, 969 | { url = "https://files.pythonhosted.org/packages/97/10/7b74d7e5663f886d058df470f14fd492078533a5aee52bf1553eed83a49d/tokenizers-0.20.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3dc750def789cb1de1b5a37657919545e1d9ffa667658b3fa9cb7862407a1b8", size = 3007139 }, 970 | { url = "https://files.pythonhosted.org/packages/77/5a/a59c9f97000fce432e3728fbe32c23cf3dd9933255d76166101c2b12a916/tokenizers-0.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e26e6c755ae884c2ea6135cd215bdd0fccafe4ee62405014b8c3cd19954e3ab9", size = 2933499 }, 971 | { url = "https://files.pythonhosted.org/packages/bd/7a/fde367e46596855e172c466655fc416d98be6c7ae792afdb5315ca38bed0/tokenizers-0.20.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:a1158c7174f427182e08baa2a8ded2940f2b4a3e94969a85cc9cfd16004cbcea", size = 8964991 }, 972 | { url = "https://files.pythonhosted.org/packages/9f/fa/075959c7d901a55b2a3198d0ecfbc624c553f5ff8027bc4fac0aa6bab70a/tokenizers-0.20.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:6324826287a3fc198898d3dcf758fe4a8479e42d6039f4c59e2cedd3cf92f64e", size = 9284502 }, 973 | ] 974 | 975 | [[package]] 976 | name = "tomli" 977 | version = "2.0.1" 978 | source = { registry = "https://pypi.org/simple" } 979 | sdist = { url = "https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f", size = 15164 } 980 | wheels = [ 981 | { url = "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", size = 12757 }, 982 | ] 983 | 984 | [[package]] 985 | name = "tqdm" 986 | version = "4.66.5" 987 | source = { registry = "https://pypi.org/simple" } 988 | dependencies = [ 989 | { name = "colorama", marker = "platform_system == 'Windows'" }, 990 | ] 991 | sdist = { url = "https://files.pythonhosted.org/packages/58/83/6ba9844a41128c62e810fddddd72473201f3eacde02046066142a2d96cc5/tqdm-4.66.5.tar.gz", hash = "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad", size = 169504 } 992 | wheels = [ 993 | { url = "https://files.pythonhosted.org/packages/48/5d/acf5905c36149bbaec41ccf7f2b68814647347b72075ac0b1fe3022fdc73/tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd", size = 78351 }, 994 | ] 995 | 996 | [[package]] 997 | name = "typer" 998 | version = "0.12.5" 999 | source = { registry = "https://pypi.org/simple" } 1000 | dependencies = [ 1001 | { name = "click" }, 1002 | { name = "rich" }, 1003 | { name = "shellingham" }, 1004 | { name = "typing-extensions" }, 1005 | ] 1006 | sdist = { url = "https://files.pythonhosted.org/packages/c5/58/a79003b91ac2c6890fc5d90145c662fd5771c6f11447f116b63300436bc9/typer-0.12.5.tar.gz", hash = "sha256:f592f089bedcc8ec1b974125d64851029c3b1af145f04aca64d69410f0c9b722", size = 98953 } 1007 | wheels = [ 1008 | { url = "https://files.pythonhosted.org/packages/a8/2b/886d13e742e514f704c33c4caa7df0f3b89e5a25ef8db02aa9ca3d9535d5/typer-0.12.5-py3-none-any.whl", hash = "sha256:62fe4e471711b147e3365034133904df3e235698399bc4de2b36c8579298d52b", size = 47288 }, 1009 | ] 1010 | 1011 | [[package]] 1012 | name = "typing-extensions" 1013 | version = "4.12.2" 1014 | source = { registry = "https://pypi.org/simple" } 1015 | sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } 1016 | wheels = [ 1017 | { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, 1018 | ] 1019 | 1020 | [[package]] 1021 | name = "urllib3" 1022 | version = "2.2.2" 1023 | source = { registry = "https://pypi.org/simple" } 1024 | sdist = { url = "https://files.pythonhosted.org/packages/43/6d/fa469ae21497ddc8bc93e5877702dca7cb8f911e337aca7452b5724f1bb6/urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168", size = 292266 } 1025 | wheels = [ 1026 | { url = "https://files.pythonhosted.org/packages/ca/1c/89ffc63a9605b583d5df2be791a27bc1a42b7c32bab68d3c8f2f73a98cd4/urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472", size = 121444 }, 1027 | ] 1028 | --------------------------------------------------------------------------------