diff --git a/.gitignore b/.gitignore index aff56a9..0703f21 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,7 @@ data/ !src/data/ blob/ -models/ +./models/ outputs/ unsloth_compiled_cache/ grpo_trainer_lora_model/ diff --git a/README.md b/README.md index 5fb8d78..e5ff7dc 100644 --- a/README.md +++ b/README.md @@ -194,6 +194,98 @@ uv run pytest tests/test_search_replace_diff.py uv run pytest tests/test_search_replace_diff.py::test_specific_function ``` +## Trajectory Analyzer + +The trajectory analyzer toolkit loads agent trajectories from multiple formats, extracts metrics, and generates comparative visualizations. It's useful for analyzing tool usage patterns, comparing models across scaffolds, and studying transfer learning effects. + +### Supported Formats + +- **nano-agent**: `detailed_predictions.jsonl` with OpenAI chat format +- **R2E-Gym**: JSONL with `trajectory_steps` using XML function calls +- **SWE-agent**: Log files with `🎬 ACTION` markers + +### Quick Start + +```bash +# Run with the example config (adjust paths in the config file first) +uv run python -m src.trajectory_analyzer --config-name example_config + +# Generate specific plots +uv run python -m src.trajectory_analyzer --config-name example_config \ + 'plots=[tool_distribution,comparison,transfer_analysis]' \ + output_dir=./my_plots +``` + +### Configuration + +Create a YAML config file (see `src/trajectory_analyzer/conf/example_config.yaml`): + +```yaml +output_dir: "./plots" + +plots: + - tool_distribution # Bar chart of tool usage per run + - shell_command_distribution # Bar chart of shell commands + - success_rates # Resolution rates and tool success + - token_analysis # Token usage by success + - comparison # Multi-run comparison grid + - transfer_analysis # Cross-scaffold transfer analysis + +# For transfer learning analysis: map models to their training scaffold +model_to_trained_scaffold: + "agentica-org/DeepSWE-Preview": "r2e-gym" + +runs: + - name: "deepswe-nano-agent" + format: "nano_agent" + trajectories: "/path/to/detailed_predictions.jsonl" + results: "/path/to/swebench_results.json" # optional + base_model: "agentica-org/DeepSWE-Preview" + scaffold: "nano-agent" + lora_adapter: null + + - name: "deepswe-r2e-gym" + format: "r2e_gym" + trajectories: "/path/to/trajectories.jsonl" + results: null # uses reward field from trajectory + base_model: "agentica-org/DeepSWE-Preview" + scaffold: "r2e-gym" + lora_adapter: null +``` + +### Programmatic Usage + +```python +from src.trajectory_analyzer.loaders import NanoAgentLoader, R2EGymLoader +from src.trajectory_analyzer.analysis import MetricsExtractor, RunComparator +from src.trajectory_analyzer.plotting import TrajectoryPlotter + +# Load trajectories +loader = NanoAgentLoader() +run = loader.load_run( + name="my-run", + scaffold="nano-agent", + base_model="Qwen/Qwen3-32B", + trajectories_path="path/to/detailed_predictions.jsonl", + results_path="path/to/results.json", # optional +) + +# Extract metrics +extractor = MetricsExtractor() +metrics = extractor.extract_run_metrics(run) +print(f"Resolved: {metrics.resolved_instances}/{metrics.total_instances}") +print(f"Avg tool calls: {metrics.avg_tool_calls:.1f}") + +# Compare runs +comparator = RunComparator() +transfer = comparator.analyze_transfer(source_run, target_run, "r2e-gym") +print(f"Transfer delta: {transfer.transfer_delta:+.1%}") + +# Generate plots +plotter = TrajectoryPlotter(output_dir="./plots") +plotter.plot_all([run1, run2], plots=["comparison", "tool_distribution"]) +``` + ## Documentation Structure This repository uses several Markdown files to organize information: diff --git a/benchmarks/benchmark_container.def b/benchmarks/benchmark_container.def deleted file mode 100644 index 8c6a616..0000000 --- a/benchmarks/benchmark_container.def +++ /dev/null @@ -1,31 +0,0 @@ -Bootstrap: docker -From: vllm/vllm-openai:v0.10.0 - -%environment - export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt - export PYTHONNOUSERSITE=1 - export VLLM_ALLOW_INSECURE_SERIALIZATION=1 - -%post - apt-get update && \ - apt-get install -y --no-install-recommends git curl ca-certificates ripgrep - - pip install --upgrade pip - - # Same torch/flash-attn setup as training container - pip install torch==2.7.1+cu128 --index-url https://download.pytorch.org/whl/cu128 - pip install --no-build-isolation --prefer-binary flash-attn==2.8.0.post2 - pip install --no-build-isolation flashinfer-python - - # Benchmark packages - git clone https://github.com/sierra-research/tau-bench /tmp/tau-bench && \ - cd /tmp/tau-bench && pip install -e . && cd / - - # Nano - pip install nano-agent gitpython - # Mini-Swe-Agent and SWE Bench - pip install mini-swe-agent - # Aider - pip install aider-install aider-chat - # Misc - pip install openai anthropic requests jsonlines datasets \ No newline at end of file diff --git a/benchmarks/swe_bench/run_harness_eval.sh b/benchmarks/swe_bench/run_harness_eval.sh index d3bddb1..92d9a9e 100755 --- a/benchmarks/swe_bench/run_harness_eval.sh +++ b/benchmarks/swe_bench/run_harness_eval.sh @@ -9,6 +9,8 @@ set -euo pipefail # --run-id my_run \ # [--max-workers 8] # +# Note: --run-id is required +# # Requirements (on this CPU server): # pip install swebench # Docker installed and running @@ -16,7 +18,7 @@ set -euo pipefail subset="verified" split="test" preds="" -run_id="swebench_local_run" +run_id="" max_workers="8" while [[ $# -gt 0 ]]; do @@ -41,6 +43,11 @@ if [[ -z "$preds" ]]; then exit 1 fi +if [[ -z "$run_id" ]]; then + echo "ERROR: --run-id is required" >&2 + exit 1 +fi + case "$subset" in verified|Verified) dataset_name="princeton-nlp/SWE-bench_Verified";; @@ -69,4 +76,9 @@ python -m swebench.harness.run_evaluation \ --cache_level "instance" \ --timeout 3600 +# Clean up logs directory +if [[ -d "logs/run_evaluation/$run_id" ]]; then + echo "Cleaning up logs directory: logs/run_evaluation/$run_id" + rm -rf "logs/run_evaluation/$run_id" +fi diff --git a/benchmarks/swe_bench/run_nano_eval.py b/benchmarks/swe_bench/run_nano_eval.py index a09b5df..6a6705d 100755 --- a/benchmarks/swe_bench/run_nano_eval.py +++ b/benchmarks/swe_bench/run_nano_eval.py @@ -19,7 +19,7 @@ from datasets import load_dataset -def run_evaluation(endpoint: str, model_name: str, subset: str, split: str, slice_spec: str, output_dir: Path): +def run_evaluation(endpoint: str, model_name: str, subset: str, split: str, slice_spec: str, output_dir: Path, backend: str = "local"): """Run nano_agent on SWE-bench tasks and save predictions using a process pool.""" # Load SWE-bench dataset @@ -49,10 +49,11 @@ def run_evaluation(endpoint: str, model_name: str, subset: str, split: str, slic config = NanoConfig( api_base=endpoint, model=model_name, # e.g., "nano" for LoRA - token_limit=16384, - time_limit=40, - tool_limit=30, - temperature=0.2, + token_limit=65536, + time_limit=600, + tool_limit=500, + temperature=1.0, + backend=backend, ) # Prepare inputs for workers @@ -70,7 +71,7 @@ def run_evaluation(endpoint: str, model_name: str, subset: str, split: str, slic detailed_predictions: dict[str, dict] = {} # Run with a process pool of up to 8 workers - max_workers = min(8, len(inputs)) if inputs else 0 + max_workers = min(48, len(inputs)) if inputs else 0 if max_workers == 0: print("No instances to process.") return @@ -156,11 +157,13 @@ def main(): help="Dataset split") parser.add_argument("--slice", default=":25", help="Slice to run. Forms: :N (first N) or start:end (half-open)") + parser.add_argument("--backend", choices=["local", "apptainer"], default="local", + help="Execution backend (local or apptainer)") args = parser.parse_args() output_dir = Path(args.output_dir) - run_evaluation(args.endpoint, args.model_name, args.subset, args.split, args.slice, output_dir) + run_evaluation(args.endpoint, args.model_name, args.subset, args.split, args.slice, output_dir, args.backend) if __name__ == "__main__": diff --git a/benchmarks/swe_bench_mini_infer_job.sh b/benchmarks/swe_bench_mini_infer_job.sh deleted file mode 100644 index 8ba905a..0000000 --- a/benchmarks/swe_bench_mini_infer_job.sh +++ /dev/null @@ -1,177 +0,0 @@ -#!/bin/bash -#SBATCH --job-name=crrl-swe-mini -#SBATCH --output=logs/swe_mini_%A_%a.out -#SBATCH --error=logs/swe_mini_%A_%a.err -#SBATCH --nodes=1 -#SBATCH --gpus 1 -#SBATCH --time=00:30:00 -#SBATCH -C "fat" -#SBATCH --array=0-9 - -set -euo pipefail - -# Use common Apptainer runtime config (requires CRRL_WORKDIR in env) -source scripts/appt_common.sh - -# Defaults -BASE_MODEL="Qwen/Qwen3-8B" # HF model to serve with vLLM -LORA_PATH="" # Optional LoRA path; adapter name auto-derived from basename if set -MODEL_NAME="" # Model name passed to the agent; auto-derived if empty -SCAFFOLD="mini-swe-agent" # Scaffold identifier for run tagging -OUTPUT_BASE_DIR="swe_bench/results" -SUBSET="verified" -SPLIT="test" -SLICE="" -PORT=8000 -SIF="benchmarks/benchmark_container.sif" -START_SERVER=1 - -while [[ $# -gt 0 ]]; do - case "$1" in - --base-model) - BASE_MODEL="${2:?}"; shift 2;; - --lora-path) - LORA_PATH="${2:?}"; shift 2;; - --model-name) - MODEL_NAME="${2:?}"; shift 2;; - --output-dir) - OUTPUT_BASE_DIR="${2:?}"; shift 2;; - --subset) - SUBSET="${2:?}"; shift 2;; - --split) - SPLIT="${2:?}"; shift 2;; - --slice) - SLICE="${2:?}"; shift 2;; - --scaffold) - SCAFFOLD="${2:?}"; shift 2;; - --port) - PORT="${2:?}"; shift 2;; - --no-server) - START_SERVER=0; shift;; - *) - echo "Unknown arg: $1"; exit 1;; - esac -done - -# Derive slice and per-task settings when running as a SLURM array -TASK_ID=${SLURM_ARRAY_TASK_ID:-0} -SHARD_SIZE=50 - -# Auto-compute slice if not explicitly provided -if [[ -z "$SLICE" ]]; then - START=$(( TASK_ID * SHARD_SIZE )) - END=$(( START + SHARD_SIZE )) - SLICE="${START}:${END}" -fi - -# Offset port to avoid conflicts if multiple tasks land on the same node -if [[ $START_SERVER -eq 1 ]]; then - PORT=$(( PORT + TASK_ID )) -fi - -ENDPOINT="http://localhost:${PORT}/v1" - -# Derive MODEL_NAME and LoRA adapter name if not explicitly provided -LORA_ADAPTER_NAME="" -if [[ -n "$LORA_PATH" ]]; then - if [[ -z "$MODEL_NAME" ]]; then - ADAPTER_BASENAME="$(basename "$LORA_PATH")" - LORA_ADAPTER_NAME=$(printf '%s' "$ADAPTER_BASENAME" | sed -E 's/[^A-Za-z0-9._-]+/_/g; s/_+/_/g; s/^_+|_+$//g') - MODEL_NAME="$LORA_ADAPTER_NAME" - else - LORA_ADAPTER_NAME="$MODEL_NAME" - fi -else - if [[ -z "$MODEL_NAME" ]]; then - MODEL_NAME="$BASE_MODEL" - fi -fi - -sanitize_tag() { - local s="$1" - s="${s//\//__}" - s="${s// /_}" - s=$(printf '%s' "$s" | sed -E 's/[^A-Za-z0-9._-]+/_/g; s/_+/_/g; s/^_+|_+$//g') - printf '%s' "$s" -} - -if [[ -n "$LORA_PATH" ]]; then - BASE_TAG=$(sanitize_tag "$BASE_MODEL") - ADAPTER_TAG=$(sanitize_tag "$(basename "$LORA_PATH")") - MODEL_TAG="${BASE_TAG}__lora__${ADAPTER_TAG}" -else - MODEL_TAG=$(sanitize_tag "$MODEL_NAME") -fi - -RUN_TAG="${SCAFFOLD}-${MODEL_TAG}" -OUTPUT_DIR="${OUTPUT_BASE_DIR}/${RUN_TAG}/shard_${TASK_ID}" - -mkdir -p "$(dirname "logs/.keep")" "$OUTPUT_DIR" - -wait_for_vllm() { - local url="$1"; local -i tries=180 - while (( tries-- > 0 )); do - code=$(curl -s -o /dev/null -w "%{http_code}" "$url/models" || true) - if [[ "$code" == "200" ]]; then return 0; fi - sleep 2 - done - return 1 -} - -# Parser/template selection (mostly no-op for mini but harmless) -RP=""; TP=""; CT="" -case "${BASE_MODEL,,}" in - *qwen*) RP="--reasoning-parser qwen3"; TP="--tool-call-parser hermes";; - *nemotron*) TP="--tool-call-parser llama3_json"; CT="--chat-template src/chat_templates/tool_chat_template_llama3.1_json.jinja";; - *llama*) TP="--tool-call-parser llama3_json"; CT="--chat-template src/chat_templates/tool_chat_template_llama3.1_json.jinja";; - *mistral*) TP="--tool-call-parser mistral"; CT="--chat-template src/chat_templates/tool_chat_template_mistral.jinja";; - *) TP="--tool-call-parser hermes";; -esac - -VLLM_PID="" -if [[ $START_SERVER -eq 1 ]]; then - echo "Starting vLLM server on port $PORT for base model '$BASE_MODEL'..." - CMD=(apptainer exec $APPT_COMMON --env CUDA_VISIBLE_DEVICES=0 "$SIF" vllm serve "$BASE_MODEL" \ - --port "$PORT" \ - --enable-auto-tool-choice \ - --max-model-len 16384 \ - $CT \ - $RP $TP) - - if [[ -n "$LORA_PATH" ]]; then - CMD+=(--max-lora-rank 32 --enable-lora --lora-modules "$LORA_ADAPTER_NAME=$LORA_PATH") - fi - - "${CMD[@]}" > "logs/vllm_${SLURM_JOB_ID:-$$}.log" 2>&1 & - VLLM_PID=$! - trap 'if [[ -n "$VLLM_PID" ]]; then kill "$VLLM_PID" 2>/dev/null || true; fi' EXIT - - echo "Waiting for vLLM to become ready at $ENDPOINT ..." - if ! wait_for_vllm "$ENDPOINT"; then - echo "vLLM did not become ready in time" >&2 - exit 1 - fi -fi - -echo "Running mini-swe-agent evaluation with model '$MODEL_NAME'..." -apptainer exec $APPT_COMMON \ - --env OPENAI_API_BASE="$ENDPOINT" \ - --env OPENAI_API_KEY="dummy" \ - "$SIF" python3 benchmarks/swe_bench/run_mini_eval.py \ - --endpoint "$ENDPOINT" \ - --model-name "$MODEL_NAME" \ - --output-dir "$OUTPUT_DIR" \ - --subset "$SUBSET" \ - --split "$SPLIT" \ - --slice "$SLICE" - -echo "Predictions saved to $OUTPUT_DIR/preds.jsonl" - -# Stop vLLM if we started it -if [[ -n "$VLLM_PID" ]]; then - kill "$VLLM_PID" 2>/dev/null || true - wait "$VLLM_PID" 2>/dev/null || true -fi - - - diff --git a/benchmarks/swe_bench_nano_infer_job.sh b/benchmarks/swe_bench_nano_infer_job.sh index e013865..3d7ebce 100644 --- a/benchmarks/swe_bench_nano_infer_job.sh +++ b/benchmarks/swe_bench_nano_infer_job.sh @@ -3,28 +3,26 @@ #SBATCH --output=logs/swe_nano_%A_%a.out #SBATCH --error=logs/swe_nano_%A_%a.err #SBATCH --nodes=1 -#SBATCH --gpus 1 -#SBATCH --time=00:30:00 +#SBATCH --gpus 8 +#SBATCH --time=12:00:00 #SBATCH -C "fat" -#SBATCH --array=0-9 +#SBATCH --array=0 set -euo pipefail -# Use common Apptainer runtime config (requires CRRL_WORKDIR in env) -source scripts/appt_common.sh - # Defaults BASE_MODEL="Qwen/Qwen3-8B" # HF model to serve with vLLM LORA_PATH="" # Optional LoRA path; adapter name auto-derived from basename if set MODEL_NAME="" # Model name passed to the agent; auto-derived if empty SCAFFOLD="nano-agent" # Scaffold identifier for run tagging -OUTPUT_BASE_DIR="swe_bench/results" +OUTPUT_BASE_DIR="swe_bench/" SUBSET="verified" SPLIT="test" SLICE="" PORT=8000 SIF="benchmarks/benchmark_container.sif" START_SERVER=1 +WANDB_API_KEY="" while [[ $# -gt 0 ]]; do case "$1" in @@ -55,7 +53,7 @@ done # Derive slice and per-task settings when running as a SLURM array TASK_ID=${SLURM_ARRAY_TASK_ID:-0} -SHARD_SIZE=50 +SHARD_SIZE=500 # Auto-compute slice if not explicitly provided if [[ -z "$SLICE" ]]; then @@ -117,7 +115,7 @@ wait_for_vllm() { while (( tries-- > 0 )); do code=$(curl -s -o /dev/null -w "%{http_code}" "$url/models" || true) if [[ "$code" == "200" ]]; then return 0; fi - sleep 2 + sleep 10 done return 1 } @@ -133,12 +131,17 @@ case "${BASE_MODEL,,}" in esac VLLM_PID="" +export MAX_CONTEXT_LEN=65536 +export VLLM_ALLOW_LONG_MAX_MODEL_LEN=1 if [[ $START_SERVER -eq 1 ]]; then echo "Starting vLLM server on port $PORT for base model '$BASE_MODEL'..." - CMD=(apptainer exec $APPT_COMMON --env CUDA_VISIBLE_DEVICES=0 "$SIF" vllm serve "$BASE_MODEL" \ + CMD=(uv run vllm serve $BASE_MODEL \ --port "$PORT" \ --enable-auto-tool-choice \ - --max-model-len 16384 \ + --tensor-parallel-size 8 \ + --max-model-len $MAX_CONTEXT_LEN \ + --hf-overrides '{"max_position_embeddings": '$MAX_CONTEXT_LEN'}' \ + --enable_prefix_caching \ $CT \ $RP $TP) @@ -147,7 +150,7 @@ if [[ $START_SERVER -eq 1 ]]; then fi # Start server in background and capture PID - "${CMD[@]}" > "logs/vllm_${SLURM_JOB_ID:-$$}.log" 2>&1 & + (exec "${CMD[@]}") > "logs/vllm_${SLURM_JOB_ID:-$$}.log" 2>&1 & VLLM_PID=$! trap 'if [[ -n "$VLLM_PID" ]]; then kill "$VLLM_PID" 2>/dev/null || true; fi' EXIT @@ -159,16 +162,16 @@ if [[ $START_SERVER -eq 1 ]]; then fi echo "Running nano_agent evaluation with model '$MODEL_NAME'..." -apptainer exec $APPT_COMMON \ - --env OPENAI_API_BASE="$ENDPOINT" \ - --env OPENAI_API_KEY="dummy" \ - "$SIF" python3 benchmarks/swe_bench/run_nano_eval.py \ - --endpoint "$ENDPOINT" \ - --model-name "hosted_vllm/$MODEL_NAME" \ - --output-dir "$OUTPUT_DIR" \ - --subset "$SUBSET" \ - --split "$SPLIT" \ - --slice "$SLICE" +OPENAI_API_BASE="$ENDPOINT" \ +OPENAI_API_KEY="dummy" \ +uv run python benchmarks/swe_bench/run_nano_eval.py \ + --endpoint "$ENDPOINT" \ + --model-name "hosted_vllm/$MODEL_NAME" \ + --output-dir "$OUTPUT_DIR" \ + --subset "$SUBSET" \ + --split "$SPLIT" \ + --slice "$SLICE" \ + --backend "apptainer" echo "Predictions saved to $OUTPUT_DIR/preds.jsonl" diff --git a/benchmarks/tau_bench/tau_job.sh b/benchmarks/tau_bench/tau_job.sh deleted file mode 100755 index 825d01c..0000000 --- a/benchmarks/tau_bench/tau_job.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash -set -euo pipefail -# Tau Bench evaluation. -# Assumes vLLM is running on http://localhost:8000/v1 (see benchmarks/vllm.sh). - -mkdir -p tau_bench/results - -echo "Running baseline evaluation..." -apptainer exec benchmarks/benchmark_container.sif python -m tau_bench.run \ - --agent-strategy tool-calling \ - --env retail \ - --model gpt-4o --model-provider openai \ - --user-model gpt-4o --user-model-provider openai \ - --user-strategy llm \ - --max-concurrency 4 \ - --output-dir tau_bench/results/before - -echo "Running LoRA model evaluation..." -export OPENAI_API_BASE="http://localhost:8000/v1" -export OPENAI_API_KEY="dummy" -apptainer exec benchmarks/benchmark_container.sif python -m tau_bench.run \ - --agent-strategy tool-calling \ - --env retail \ - --model nano --model-provider openai \ - --user-model gpt-4o --user-model-provider openai \ - --user-strategy llm \ - --max-concurrency 4 \ - --output-dir tau_bench/results/after - -echo "=== Tau Bench Results ===" -echo "Before:" -cat tau_bench/results/before/metrics.json | grep success_rate || echo "No baseline metrics found" -echo "After:" -cat tau_bench/results/after/metrics.json | grep success_rate || echo "No LoRA metrics found" \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index d06e46c..c07ba32 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,22 +9,22 @@ dependencies = [ "trl @ git+https://github.com/ASSERT-KTH/trl.git@dev", # The agent we use for rollout generation, "nano-agent @ git+https://github.com/ASSERT-KTH/nano-agent.git", - "mini-swe-agent>=1.13.0", + "mini-swe-agent>=1.17.0", # Optimized loss kernels, forked to support GSPO "liger-kernel @ git+https://github.com/BjarniHaukur/liger-kernel.git", # Other HF stuff "accelerate>=1.8.0", "transformers", "huggingface-hub", - "datasets>=3.3.0", + "datasets>=4.4.1", "peft>=0.15.0", "bitsandbytes>=0.44.1; platform_system != 'Darwin'", # Logging - "wandb>=0.19.6", + "wandb>=0.23.0", # Config "hydra-core>=1.3.2", # Needed for SWE-Gym, to clone the repos - "gitpython>=3.1.44", + "gitpython>=3.1.45", # Is required BEFORE the package manager considers vLLM flash-attn "setuptools>=75.8.0", # efficient training of LLMs diff --git a/scripts/pull_swe_images.py b/scripts/pull_swe_images.py new file mode 100644 index 0000000..0f04edb --- /dev/null +++ b/scripts/pull_swe_images.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 +""" +Script to pull all SWE-bench images using apptainer pull to populate the cache. +Usage: python3 scripts/pull_swe_images.py --subset verified --shard-id 0 --num-shards 10 +""" + +import argparse +import subprocess +import sys +import os +from datasets import load_dataset + +def main(): + parser = argparse.ArgumentParser(description="Pull SWE-bench images for Apptainer cache") + parser.add_argument("--subset", default="verified", help="SWE-bench subset (verified, lite, full)") + parser.add_argument("--split", default="test", help="Dataset split") + parser.add_argument("--temp-sif", default="/proj/berzelius-2024-336/users/x_andaf/CodeRepairRL/temp.sif", help="Temporary SIF file path") + parser.add_argument("--shard-id", type=int, default=0, help="Shard ID for distributed pulling") + parser.add_argument("--num-shards", type=int, default=1, help="Total number of shards") + args = parser.parse_args() + + print(f"Loading dataset princeton-nlp/SWE-bench_{args.subset} split {args.split}...") + try: + dataset = load_dataset(f"princeton-nlp/SWE-bench_{args.subset}", split=args.split) + except Exception as e: + print(f"Error loading dataset: {e}") + sys.exit(1) + + # Sharding logic + if args.num_shards > 1: + dataset = dataset.shard(num_shards=args.num_shards, index=args.shard_id) + print(f"Processing shard {args.shard_id}/{args.num_shards} with {len(dataset)} instances.") + else: + print(f"Found {len(dataset)} instances.") + + temp_sif = args.temp_sif + + # Ensure directory for temp file exists + os.makedirs(os.path.dirname(temp_sif), exist_ok=True) + + for i, instance in enumerate(dataset): + instance_id = instance["instance_id"] + # Image naming convention: replace double underscore with _1776_ + # image_name_tag = instance_id.replace("__", "_1776_") + # image_uri = f"docker://docker.io/swebench/sweb.eval.x86_64.{image_name_tag}:latest" + image_uri = f"docker://slimshetty/swebench-verified:sweb.eval.x86_64.{instance_id}" + + print(f"[{i+1}/{len(dataset)}] Pulling {image_uri}...") + try: + # Pull to a temporary file to populate the cache + # We can overwrite the same file since we are running sequentially + subprocess.run(["apptainer", "pull", "--force", temp_sif, image_uri], check=True) + except subprocess.CalledProcessError as e: + print(f"Failed to pull {image_uri}: {e}", file=sys.stderr) + except KeyboardInterrupt: + print("\nInterrupted by user.") + break + + # Cleanup + if os.path.exists(temp_sif): + try: + os.remove(temp_sif) + except OSError: + pass + + print("Done.") + +if __name__ == "__main__": + main() diff --git a/scripts/pull_swe_images_job.sh b/scripts/pull_swe_images_job.sh new file mode 100644 index 0000000..199ba12 --- /dev/null +++ b/scripts/pull_swe_images_job.sh @@ -0,0 +1,45 @@ +#!/bin/bash +#SBATCH --job-name=pull-swe-images +#SBATCH --output=logs/pull_swe_%A_%a.out +#SBATCH --error=logs/pull_swe_%A_%a.err +#SBATCH --nodes=1 +#SBATCH -C "thin" +#SBATCH --gpus 1 +#SBATCH --time=06:00:00 +#SBATCH --array=0-19 + +set -euo pipefail + +# Configuration +SUBSET="verified" +SPLIT="test" +TOTAL_WORKERS=20 +WORKER_ID=${SLURM_ARRAY_TASK_ID:-0} + +echo "Starting worker ${WORKER_ID}/${TOTAL_WORKERS} for SWE-bench ${SUBSET}..." + +# Use a unique temp file for this job to avoid conflicts +TEMP_SIF="/proj/berzelius-2024-336/users/x_andaf/CodeRepairRL/temp_pull_${SLURM_JOB_ID}_${WORKER_ID}.sif" + +# Calculate slice for this worker +# Note: datasets.load_dataset doesn't support stride slicing directly in the load, +# but we can use Python to select the subset. +# Alternatively, we can update the python script to accept --shard-id and --num-shards. + +# Let's update the python command to handle sharding if we modify the script, +# or use the python script's slice logic if we add it. +# Since the current python script iterates all, we should modify it or use a wrapper. +# The easiest way without modifying python script further is to pass a slice argument. + +# Let's modify the python script to accept start/end or shard info. +# But first, I will write this job script assuming I'll add sharding support to the python script next. + +uv run scripts/pull_swe_images.py \ + --subset "$SUBSET" \ + --split "$SPLIT" \ + --temp-sif "$TEMP_SIF" \ + --shard-id "$WORKER_ID" \ + --num-shards "$TOTAL_WORKERS" + +echo "Worker ${WORKER_ID} finished." + diff --git a/src/agents/nano_agent.py b/src/agents/nano_agent.py index b6b9111..1e38cbc 100644 --- a/src/agents/nano_agent.py +++ b/src/agents/nano_agent.py @@ -6,12 +6,71 @@ from concurrent.futures import ThreadPoolExecutor from nano import Agent +from nano.env import Environment, ApptainerEnvironment from src.utils.git import handle_to_url, clone_repo_at_commit, clean_repo_dir logger = logging.getLogger(__name__) +def setup_env_swebench(env: Environment): + """ + Mimics the R2E-Gym setup function with both swebench and non-swebench paths. + Detects which type of image we're using and applies the appropriate setup. + """ + repo_path = "/testbed" + alt_path = "/root" + + # Set the PATH for all subsequent commands + DOCKER_PATH = "/root/.venv/bin:/root/.local/bin:/root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + env.path = DOCKER_PATH + + # === setup_env_swebench path === + # Make run_tests.sh executable (if present) + # We will not use this script in nano-agent + # env.run_shell("chmod +x /run_tests.sh 2>/dev/null || true") + + # Create symlink of conda env to /root/.venv + env.run_shell("ln -sf /opt/miniconda3/envs/testbed /root/.venv") + + # Install required packages + env.run_shell("python -m pip install chardet -q") + + # === setup_env (non-swebench R2E-Gym) path === + # Create local bin directory if needed + env.run_shell(f"mkdir -p {alt_path}/.local/bin") + + # Symlink python executables + env.run_shell(f"ln -sf {repo_path}/.venv/bin/python {alt_path}/.local/bin/python") + env.run_shell(f"ln -sf {repo_path}/.venv/bin/python {alt_path}/.local/bin/python3") + + # Symlink all executables from venv bin + env.run_shell(f"find {repo_path}/.venv/bin -type f -executable -exec ln -sf {{}} {alt_path}/.local/bin/ \\;") + + # Clean up pycache files + env.run_shell("find . -name '*.pyc' -delete 2>/dev/null || true") + env.run_shell("find . -name '__pycache__' -exec rm -rf {} + 2>/dev/null || true") + + # Clean up pycache from r2e_tests (if present) + env.run_shell("find /r2e_tests -name '*.pyc' -delete 2>/dev/null || true") + env.run_shell("find /r2e_tests -name '__pycache__' -exec rm -rf {} + 2>/dev/null || true") + + # Move r2e_tests to /root (if present) + # We will not use this script in nano-agent + # env.run_shell(f"mv /r2e_tests {alt_path}/r2e_tests 2>/dev/null || true") + + # Create symlink for r2e_tests in repo + # We will not use this script in nano-agent + # env.run_shell(f"ln -sf {alt_path}/r2e_tests {repo_path}/r2e_tests 2>/dev/null || true") + + # Install ripgrep + env.run_shell("apt-get update && apt-get install -y ripgrep 2>/dev/null || true") + + # Commit all changes to ensure we have a clean state + env.run_shell("git config --global user.email 'you@example.com'") + env.run_shell("git config --global user.name 'Your Name'") + env.run_shell("git add . && git commit -m 'add changes'") + @dataclass class NanoConfig: agent_kind: str = "nano" @@ -27,6 +86,8 @@ class NanoConfig: top_k: Optional[int] = None verbose: bool = False log: bool = False + backend: str = "local" + env: Optional[Any] = None def _process_one(data: dict[str, Any], config: NanoConfig) -> dict[str, Any]: @@ -37,36 +98,61 @@ def _process_one(data: dict[str, Any], config: NanoConfig) -> dict[str, Any]: agent_kwargs = asdict(config) agent_kwargs.pop("agent_kind", None) + + # Handle backend and environment setup + backend = agent_kwargs.pop("backend", "local") + env = agent_kwargs.pop("env", None) + + # Initialize agent with appropriate environment + if backend == "apptainer" and env is None: + # If using Apptainer backend but env not provided in config, we need to construct it + # This logic might belong better in the caller, but we can handle it here or + # expect the caller to pass the fully constructed environment in `config.env`. + # Based on the reference, the caller (run_nano_eval) should likely construct the environment. + # However, `_process_one` is called per instance, and the environment depends on the instance ID. + instance_id = data.get("instance_id") + image_name = f"docker.io/slimshetty/swebench-verified:sweb.eval.x86_64.{instance_id}" + workdir = "/testbed" + env = ApptainerEnvironment(image=f"docker://{image_name}", workdir=workdir, setup_fn=setup_env_swebench) + agent_kwargs["env"] = env + elif env: + agent_kwargs["env"] = env + agent = Agent(**agent_kwargs) diff = "" temp_folder = None - try: - repo_url = handle_to_url(data["repo"]) - temp_folder = clone_repo_at_commit(repo_url, data["base_commit"]) - except Exception as e: - agent._reset() - agent._append({"role": "user", "content": data["problem_statement"]}) - agent._append({"role": "assistant", "content": ""}) # this should be incredibly rare, only encountered this once in 20+ runs - logger.error(f"Error with git in _process_one: {type(e).__name__}: {e}") - if temp_folder: clean_repo_dir(temp_folder) - return dict( - prompt=agent.messages[:2], - completion=agent.messages[2:], - tools=agent.tools, - generated_diff="", - token_usage=agent.token_usage, - tool_usage=agent.tool_usage, - **agent.tool_stats - ) - + + if backend == "local": + try: + repo_url = handle_to_url(data["repo"]) + temp_folder = clone_repo_at_commit(repo_url, data["base_commit"]) + except Exception as e: + agent._reset() + agent._append({"role": "user", "content": data["problem_statement"]}) + agent._append({"role": "assistant", "content": ""}) + logger.error(f"Error with git in _process_one: {type(e).__name__}: {e}") + if temp_folder: clean_repo_dir(temp_folder) + return dict( + prompt=agent.messages[:2], + completion=agent.messages[2:], + tools=agent.tools, + generated_diff="", + token_usage=agent.token_usage, + tool_usage=agent.tool_usage, + **agent.tool_stats + ) + else: + # For container backends, the repo is already in the container image at workdir + temp_folder = "/testbed" # default workdir for SWE-bench containers + try: diff = agent.run(task=data["problem_statement"], repo_root=temp_folder) except Exception as e: logger.error(f"Error in _process_one: {type(e).__name__}: {e}") diff = "" finally: - if temp_folder: clean_repo_dir(temp_folder) + if backend == "local" and temp_folder: clean_repo_dir(temp_folder) token_usage = agent.token_usage tool_usage = agent.tool_usage diff --git a/src/trajectory_analyzer/__init__.py b/src/trajectory_analyzer/__init__.py new file mode 100644 index 0000000..524fc31 --- /dev/null +++ b/src/trajectory_analyzer/__init__.py @@ -0,0 +1,4 @@ +"""Trajectory Analyzer Toolkit for analyzing agent trajectories from multiple formats.""" + +__version__ = "0.1.0" + diff --git a/src/trajectory_analyzer/__main__.py b/src/trajectory_analyzer/__main__.py new file mode 100644 index 0000000..710595b --- /dev/null +++ b/src/trajectory_analyzer/__main__.py @@ -0,0 +1,7 @@ +"""Allow running as: python -m src.trajectory_analyzer""" + +from .cli import main + +if __name__ == "__main__": + main() + diff --git a/src/trajectory_analyzer/analysis/__init__.py b/src/trajectory_analyzer/analysis/__init__.py new file mode 100644 index 0000000..aa1351c --- /dev/null +++ b/src/trajectory_analyzer/analysis/__init__.py @@ -0,0 +1,25 @@ +"""Analysis modules for trajectory analysis.""" + +from .metrics import MetricsExtractor, RunMetrics +from .comparator import RunComparator +from .transfer import ( + TransferAnalyzer, + DeepTransferAnalysis, + McNemarResult, + ErrorModeAnalysis, + ToolVocabularyAnalysis, + ErrorCategory, +) + +__all__ = [ + "MetricsExtractor", + "RunMetrics", + "RunComparator", + "TransferAnalyzer", + "DeepTransferAnalysis", + "McNemarResult", + "ErrorModeAnalysis", + "ToolVocabularyAnalysis", + "ErrorCategory", +] + diff --git a/src/trajectory_analyzer/analysis/comparator.py b/src/trajectory_analyzer/analysis/comparator.py new file mode 100644 index 0000000..da7f736 --- /dev/null +++ b/src/trajectory_analyzer/analysis/comparator.py @@ -0,0 +1,321 @@ +"""Cross-run comparison and transfer learning analysis.""" + +from dataclasses import dataclass, field +from collections import defaultdict +from typing import Any + +from ..models import Run +from .metrics import MetricsExtractor, RunMetrics + + +@dataclass +class TransferAnalysis: + """Analysis of transfer learning between scaffolds.""" + + base_model: str + """Base model being compared.""" + + source_scaffold: str + """Scaffold the model was trained on.""" + + target_scaffold: str + """Scaffold the model is evaluated on.""" + + source_run: str + """Run name for source scaffold.""" + + target_run: str + """Run name for target scaffold.""" + + # Performance metrics + source_resolve_rate: float = 0.0 + target_resolve_rate: float = 0.0 + transfer_delta: float = 0.0 # target - source (negative = degradation) + + # Tool usage comparison + source_avg_tool_calls: float = 0.0 + target_avg_tool_calls: float = 0.0 + tool_usage_delta: float = 0.0 + + # Tool distribution similarity (Jaccard index of top tools) + tool_overlap: float = 0.0 + + @property + def transfer_successful(self) -> bool: + """Whether transfer maintained or improved performance.""" + return self.transfer_delta >= 0 + + def to_dict(self) -> dict[str, Any]: + """Convert to dictionary.""" + return { + 'base_model': self.base_model, + 'source_scaffold': self.source_scaffold, + 'target_scaffold': self.target_scaffold, + 'source_run': self.source_run, + 'target_run': self.target_run, + 'source_resolve_rate': self.source_resolve_rate, + 'target_resolve_rate': self.target_resolve_rate, + 'transfer_delta': self.transfer_delta, + 'source_avg_tool_calls': self.source_avg_tool_calls, + 'target_avg_tool_calls': self.target_avg_tool_calls, + 'tool_usage_delta': self.tool_usage_delta, + 'tool_overlap': self.tool_overlap, + 'transfer_successful': self.transfer_successful, + } + + +@dataclass +class FinetuningAnalysis: + """Analysis of fine-tuning impact.""" + + base_model: str + scaffold: str + lora_adapter: str + + base_run: str + finetuned_run: str + + # Performance comparison + base_resolve_rate: float = 0.0 + finetuned_resolve_rate: float = 0.0 + improvement: float = 0.0 # finetuned - base + + # Tool usage comparison + base_avg_tool_calls: float = 0.0 + finetuned_avg_tool_calls: float = 0.0 + + # Changes in tool distribution + new_tools: list[str] = field(default_factory=list) # Tools used only after finetuning + dropped_tools: list[str] = field(default_factory=list) # Tools no longer used + + def to_dict(self) -> dict[str, Any]: + """Convert to dictionary.""" + return { + 'base_model': self.base_model, + 'scaffold': self.scaffold, + 'lora_adapter': self.lora_adapter, + 'base_run': self.base_run, + 'finetuned_run': self.finetuned_run, + 'base_resolve_rate': self.base_resolve_rate, + 'finetuned_resolve_rate': self.finetuned_resolve_rate, + 'improvement': self.improvement, + 'base_avg_tool_calls': self.base_avg_tool_calls, + 'finetuned_avg_tool_calls': self.finetuned_avg_tool_calls, + 'new_tools': self.new_tools, + 'dropped_tools': self.dropped_tools, + } + + +class RunComparator: + """Compare runs for transfer learning and fine-tuning analysis.""" + + def __init__(self): + self.metrics_extractor = MetricsExtractor() + + def compare_runs(self, runs: list[Run]) -> dict[str, RunMetrics]: + """Extract and compare metrics across multiple runs. + + Args: + runs: List of runs to compare + + Returns: + Dictionary mapping run names to their metrics + """ + return { + run.name: self.metrics_extractor.extract_run_metrics(run) + for run in runs + } + + def analyze_transfer( + self, + source_run: Run, + target_run: Run, + source_scaffold: str, + ) -> TransferAnalysis: + """Analyze transfer learning from one scaffold to another. + + Args: + source_run: Run on the scaffold the model was trained for + target_run: Run on a different scaffold + source_scaffold: Name of the source scaffold + + Returns: + TransferAnalysis with comparison results + """ + source_metrics = self.metrics_extractor.extract_run_metrics(source_run) + target_metrics = self.metrics_extractor.extract_run_metrics(target_run) + + # Compute tool overlap (Jaccard index) + source_tools = set(source_metrics.tool_counts.keys()) + target_tools = set(target_metrics.tool_counts.keys()) + + if source_tools or target_tools: + intersection = len(source_tools & target_tools) + union = len(source_tools | target_tools) + tool_overlap = intersection / union if union > 0 else 0.0 + else: + tool_overlap = 0.0 + + return TransferAnalysis( + base_model=source_run.base_model, + source_scaffold=source_scaffold, + target_scaffold=target_run.scaffold, + source_run=source_run.name, + target_run=target_run.name, + source_resolve_rate=source_metrics.resolve_rate, + target_resolve_rate=target_metrics.resolve_rate, + transfer_delta=target_metrics.resolve_rate - source_metrics.resolve_rate, + source_avg_tool_calls=source_metrics.avg_tool_calls, + target_avg_tool_calls=target_metrics.avg_tool_calls, + tool_usage_delta=target_metrics.avg_tool_calls - source_metrics.avg_tool_calls, + tool_overlap=tool_overlap, + ) + + def analyze_finetuning( + self, + base_run: Run, + finetuned_run: Run, + ) -> FinetuningAnalysis: + """Analyze impact of fine-tuning. + + Args: + base_run: Run with base model + finetuned_run: Run with fine-tuned model + + Returns: + FinetuningAnalysis with comparison results + """ + base_metrics = self.metrics_extractor.extract_run_metrics(base_run) + ft_metrics = self.metrics_extractor.extract_run_metrics(finetuned_run) + + # Find tool changes + base_tools = set(base_metrics.tool_counts.keys()) + ft_tools = set(ft_metrics.tool_counts.keys()) + + new_tools = list(ft_tools - base_tools) + dropped_tools = list(base_tools - ft_tools) + + return FinetuningAnalysis( + base_model=base_run.base_model, + scaffold=base_run.scaffold, + lora_adapter=finetuned_run.lora_adapter or "unknown", + base_run=base_run.name, + finetuned_run=finetuned_run.name, + base_resolve_rate=base_metrics.resolve_rate, + finetuned_resolve_rate=ft_metrics.resolve_rate, + improvement=ft_metrics.resolve_rate - base_metrics.resolve_rate, + base_avg_tool_calls=base_metrics.avg_tool_calls, + finetuned_avg_tool_calls=ft_metrics.avg_tool_calls, + new_tools=new_tools, + dropped_tools=dropped_tools, + ) + + def find_transfer_pairs( + self, + runs: list[Run], + model_to_trained_scaffold: dict[str, str], + ) -> list[TransferAnalysis]: + """Find and analyze all transfer learning pairs. + + Args: + runs: All available runs + model_to_trained_scaffold: Mapping of base models to their training scaffold + e.g., {"agentica-org/DeepSWE-Preview": "r2e-gym"} + + Returns: + List of TransferAnalysis for each pair + """ + analyses = [] + + # Group runs by base model + runs_by_model: dict[str, list[Run]] = defaultdict(list) + for run in runs: + runs_by_model[run.base_model].append(run) + + # For each model, compare training scaffold to other scaffolds + for model, model_runs in runs_by_model.items(): + trained_scaffold = model_to_trained_scaffold.get(model) + if not trained_scaffold: + continue + + # Find source run (on training scaffold) + source_runs = [r for r in model_runs if r.scaffold == trained_scaffold] + if not source_runs: + continue + + source_run = source_runs[0] # Take first if multiple + + # Compare to runs on other scaffolds + for target_run in model_runs: + if target_run.scaffold != trained_scaffold: + analysis = self.analyze_transfer( + source_run, target_run, trained_scaffold + ) + analyses.append(analysis) + + return analyses + + def find_finetuning_pairs(self, runs: list[Run]) -> list[FinetuningAnalysis]: + """Find and analyze all base vs fine-tuned pairs. + + Args: + runs: All available runs + + Returns: + List of FinetuningAnalysis for each pair + """ + analyses = [] + + # Group runs by (base_model, scaffold) + runs_by_key: dict[tuple[str, str], list[Run]] = defaultdict(list) + for run in runs: + key = (run.base_model, run.scaffold) + runs_by_key[key].append(run) + + # For each group, compare base to fine-tuned versions + for (model, scaffold), group_runs in runs_by_key.items(): + base_runs = [r for r in group_runs if not r.is_finetuned] + ft_runs = [r for r in group_runs if r.is_finetuned] + + if not base_runs: + continue + + base_run = base_runs[0] # Take first if multiple + + for ft_run in ft_runs: + analysis = self.analyze_finetuning(base_run, ft_run) + analyses.append(analysis) + + return analyses + + def get_comparison_summary( + self, + runs: list[Run], + ) -> dict[str, Any]: + """Get a summary of all run comparisons. + + Args: + runs: All available runs + + Returns: + Summary dictionary with metrics and comparisons + """ + metrics = self.compare_runs(runs) + + # Sort by resolve rate + sorted_runs = sorted( + metrics.items(), + key=lambda x: x[1].resolve_rate, + reverse=True + ) + + return { + 'runs': {name: m.to_dict() for name, m in sorted_runs}, + 'best_run': sorted_runs[0][0] if sorted_runs else None, + 'worst_run': sorted_runs[-1][0] if sorted_runs else None, + 'avg_resolve_rate': ( + sum(m.resolve_rate for m in metrics.values()) / len(metrics) + if metrics else 0.0 + ), + } + diff --git a/src/trajectory_analyzer/analysis/metrics.py b/src/trajectory_analyzer/analysis/metrics.py new file mode 100644 index 0000000..0cb6992 --- /dev/null +++ b/src/trajectory_analyzer/analysis/metrics.py @@ -0,0 +1,261 @@ +"""Metrics extraction from trajectories and runs.""" + +from dataclasses import dataclass, field +from collections import defaultdict +from typing import Any +import statistics + +from ..models import Run, Trajectory + + +@dataclass +class RunMetrics: + """Aggregated metrics for a single run.""" + + run_name: str + scaffold: str + base_model: str + lora_adapter: str | None + + # Instance counts + total_instances: int = 0 + resolved_instances: int = 0 + instances_with_patch: int = 0 + + # Rates + resolve_rate: float = 0.0 + patch_rate: float = 0.0 + + # Tool usage + tool_counts: dict[str, int] = field(default_factory=dict) + shell_command_counts: dict[str, int] = field(default_factory=dict) + + # Per-trajectory distributions + tool_calls_per_traj: list[int] = field(default_factory=list) + tokens_per_traj: list[int] = field(default_factory=list) + steps_per_traj: list[int] = field(default_factory=list) + + # Success rate by tool + tool_success_rates: dict[str, float] = field(default_factory=dict) + + # Resolved vs unresolved comparison + resolved_avg_tool_calls: float = 0.0 + unresolved_avg_tool_calls: float = 0.0 + resolved_avg_tokens: float = 0.0 + unresolved_avg_tokens: float = 0.0 + + @property + def avg_tool_calls(self) -> float: + """Average tool calls per trajectory.""" + if not self.tool_calls_per_traj: + return 0.0 + return statistics.mean(self.tool_calls_per_traj) + + @property + def median_tool_calls(self) -> float: + """Median tool calls per trajectory.""" + if not self.tool_calls_per_traj: + return 0.0 + return statistics.median(self.tool_calls_per_traj) + + @property + def avg_tokens(self) -> float: + """Average tokens per trajectory.""" + if not self.tokens_per_traj: + return 0.0 + return statistics.mean(self.tokens_per_traj) + + @property + def avg_steps(self) -> float: + """Average steps per trajectory.""" + if not self.steps_per_traj: + return 0.0 + return statistics.mean(self.steps_per_traj) + + @property + def total_tool_calls(self) -> int: + """Total tool calls across all trajectories.""" + return sum(self.tool_counts.values()) + + def to_dict(self) -> dict[str, Any]: + """Convert to dictionary for serialization.""" + return { + 'run_name': self.run_name, + 'scaffold': self.scaffold, + 'base_model': self.base_model, + 'lora_adapter': self.lora_adapter, + 'total_instances': self.total_instances, + 'resolved_instances': self.resolved_instances, + 'instances_with_patch': self.instances_with_patch, + 'resolve_rate': self.resolve_rate, + 'patch_rate': self.patch_rate, + 'avg_tool_calls': self.avg_tool_calls, + 'median_tool_calls': self.median_tool_calls, + 'avg_tokens': self.avg_tokens, + 'avg_steps': self.avg_steps, + 'total_tool_calls': self.total_tool_calls, + 'tool_counts': self.tool_counts, + 'shell_command_counts': self.shell_command_counts, + 'tool_success_rates': self.tool_success_rates, + 'resolved_avg_tool_calls': self.resolved_avg_tool_calls, + 'unresolved_avg_tool_calls': self.unresolved_avg_tool_calls, + 'resolved_avg_tokens': self.resolved_avg_tokens, + 'unresolved_avg_tokens': self.unresolved_avg_tokens, + } + + +class MetricsExtractor: + """Extract metrics from runs and trajectories.""" + + def extract_run_metrics(self, run: Run) -> RunMetrics: + """Extract comprehensive metrics from a run. + + Args: + run: Run to analyze + + Returns: + RunMetrics with aggregated statistics + """ + metrics = RunMetrics( + run_name=run.name, + scaffold=run.scaffold, + base_model=run.base_model, + lora_adapter=run.lora_adapter, + ) + + # Basic counts + metrics.total_instances = len(run.trajectories) + metrics.resolved_instances = run.num_resolved + metrics.instances_with_patch = run.num_with_patch + + # Rates + metrics.resolve_rate = run.resolve_rate + metrics.patch_rate = run.patch_rate + + # Aggregate tool counts + tool_counts: dict[str, int] = defaultdict(int) + shell_counts: dict[str, int] = defaultdict(int) + tool_successes: dict[str, int] = defaultdict(int) + tool_totals: dict[str, int] = defaultdict(int) + + for traj in run.trajectories: + # Per-trajectory metrics + metrics.tool_calls_per_traj.append(traj.total_tool_calls) + metrics.tokens_per_traj.append(traj.total_tokens) + metrics.steps_per_traj.append(traj.num_steps) + + # Tool counts + for tool, count in traj.get_tool_counts().items(): + tool_counts[tool] += count + + for cmd, count in traj.get_shell_command_counts().items(): + shell_counts[cmd] += count + + # Track success/failure for each tool + for tc in traj.get_tool_calls(): + tool_totals[tc.name] += 1 + if tc.success: + tool_successes[tc.name] += 1 + + metrics.tool_counts = dict(tool_counts) + metrics.shell_command_counts = dict(shell_counts) + + # Compute tool success rates + metrics.tool_success_rates = { + tool: tool_successes[tool] / total + for tool, total in tool_totals.items() + if total > 0 + } + + # Resolved vs unresolved comparison + resolved_trajs = run.get_resolved_trajectories() + unresolved_trajs = run.get_unresolved_trajectories() + + if resolved_trajs: + metrics.resolved_avg_tool_calls = statistics.mean( + t.total_tool_calls for t in resolved_trajs + ) + metrics.resolved_avg_tokens = statistics.mean( + t.total_tokens for t in resolved_trajs + ) + + if unresolved_trajs: + metrics.unresolved_avg_tool_calls = statistics.mean( + t.total_tool_calls for t in unresolved_trajs + ) + metrics.unresolved_avg_tokens = statistics.mean( + t.total_tokens for t in unresolved_trajs + ) + + return metrics + + def extract_trajectory_metrics(self, traj: Trajectory) -> dict[str, Any]: + """Extract metrics from a single trajectory. + + Args: + traj: Trajectory to analyze + + Returns: + Dictionary of metrics + """ + return { + 'instance_id': traj.instance_id, + 'num_steps': traj.num_steps, + 'total_tool_calls': traj.total_tool_calls, + 'total_tokens': traj.total_tokens, + 'has_patch': traj.has_patch, + 'resolved': traj.resolved, + 'exit_reason': traj.exit_reason, + 'tool_counts': traj.get_tool_counts(), + 'shell_command_counts': traj.get_shell_command_counts(), + 'overall_success_rate': traj.get_tool_success_rate(), + } + + def get_tool_distribution(self, run: Run) -> dict[str, int]: + """Get tool call distribution for a run. + + Args: + run: Run to analyze + + Returns: + Dictionary mapping tool names to counts, sorted by count + """ + counts = run.get_total_tool_counts() + return dict(sorted(counts.items(), key=lambda x: x[1], reverse=True)) + + def get_shell_command_distribution(self, run: Run) -> dict[str, int]: + """Get shell command distribution for a run. + + Args: + run: Run to analyze + + Returns: + Dictionary mapping shell commands to counts, sorted by count + """ + counts = run.get_total_shell_command_counts() + return dict(sorted(counts.items(), key=lambda x: x[1], reverse=True)) + + def get_success_correlation( + self, + run: Run + ) -> tuple[list[int], list[bool], list[int]]: + """Get data for tool calls vs success correlation. + + Args: + run: Run to analyze + + Returns: + Tuple of (tool_calls, resolved, tokens) lists + """ + tool_calls = [] + resolved = [] + tokens = [] + + for traj in run.trajectories: + if traj.resolved is not None: + tool_calls.append(traj.total_tool_calls) + resolved.append(traj.resolved) + tokens.append(traj.total_tokens) + + return tool_calls, resolved, tokens + diff --git a/src/trajectory_analyzer/analysis/transfer.py b/src/trajectory_analyzer/analysis/transfer.py new file mode 100644 index 0000000..40840b4 --- /dev/null +++ b/src/trajectory_analyzer/analysis/transfer.py @@ -0,0 +1,702 @@ +"""Deep transfer learning analysis. + +Provides detailed analysis of transfer learning between scaffolds: +1. Instance-level correlation with McNemar's test +2. Error mode analysis and categorization +3. Tool vocabulary alignment analysis +""" + +from dataclasses import dataclass, field +from collections import defaultdict +from typing import Any +from enum import Enum +import math + +from ..models import Run, Trajectory, ToolCall +import re + + +# Common error patterns to look for in tool results +ERROR_PATTERNS = [ + (r'command failed with exit code (\d+)', 'exit_code_{0}'), + (r'No such file or directory', 'file_not_found'), + (r'Permission denied', 'permission_denied'), + (r'command not found', 'command_not_found'), + (r'FileNotFoundError', 'file_not_found'), + (r'ModuleNotFoundError', 'module_not_found'), + (r'ImportError', 'import_error'), + (r'SyntaxError', 'syntax_error'), + (r'IndentationError', 'indentation_error'), + (r'NameError', 'name_error'), + (r'TypeError', 'type_error'), + (r'ValueError', 'value_error'), + (r'AttributeError', 'attribute_error'), + (r'KeyError', 'key_error'), + (r'IndexError', 'index_error'), + (r'RuntimeError', 'runtime_error'), + (r'AssertionError', 'assertion_error'), + (r'OSError', 'os_error'), + (r'IOError', 'io_error'), + (r'Traceback \(most recent call last\)', 'python_traceback'), + (r'FAILED', 'test_failed'), + (r'ERROR', 'generic_error'), + (r'fatal:', 'git_fatal'), + (r'error:', 'generic_error'), + (r'not found', 'not_found'), + (r'does not exist', 'does_not_exist'), + (r'invalid', 'invalid_input'), + (r'timeout', 'timeout'), + (r'connection refused', 'connection_refused'), + (r'patch.*failed', 'patch_failed'), + (r'could not apply', 'patch_failed'), + (r'SEARCH.*not found', 'search_text_not_found'), + (r'multiple matches', 'multiple_matches'), + (r'No changes made', 'no_changes'), +] + + +def extract_error_pattern(result: str, mode: str = "categorized") -> str: + """Extract error pattern from a tool result string. + + Args: + result: The tool result/output string + mode: "categorized" for predefined patterns, "raw" for first N words + + Returns: + Identified error pattern or 'unknown_error' + """ + if not result: + return 'empty_result' + + if mode == "raw": + return extract_raw_error_prefix(result) + + result_lower = result.lower() + + for pattern, label in ERROR_PATTERNS: + match = re.search(pattern, result, re.IGNORECASE) + if match: + # Handle patterns with capture groups + if '{0}' in label and match.groups(): + return label.format(match.group(1)) + return label + + # If no pattern matched but marked as error, classify by length + if len(result) < 50: + return f'short_error: {result[:30]}' + + return 'unknown_error' + + +def extract_raw_error_prefix(result: str, num_words: int = 5) -> str: + """Extract first N words from error result as category. + + Args: + result: The tool result/output string + num_words: Number of words to extract + + Returns: + First N words of the error, cleaned up + """ + if not result: + return 'empty_result' + + # Clean up the result - remove newlines, extra spaces + cleaned = ' '.join(result.split()) + + # Get first N words + words = cleaned.split()[:num_words] + + if not words: + return 'empty_result' + + # Join and truncate if too long + prefix = ' '.join(words) + if len(prefix) > 60: + prefix = prefix[:57] + '...' + + return prefix + + +def format_tool_call_signature(tool_name: str, arguments: dict, max_len: int = 80) -> str: + """Format a tool call with its arguments into a readable signature. + + Args: + tool_name: Name of the tool + arguments: Tool arguments dictionary + max_len: Maximum length of the signature + + Returns: + Formatted signature like "shell(cmd='grep -r ...')" + """ + if not arguments: + return f"{tool_name}()" + + # Format key arguments + arg_parts = [] + for key, value in arguments.items(): + if value is None: + continue + + # Convert value to string and truncate if needed + str_val = str(value) + if len(str_val) > 30: + str_val = str_val[:27] + '...' + + # Clean up whitespace + str_val = ' '.join(str_val.split()) + + arg_parts.append(f"{key}='{str_val}'") + + if not arg_parts: + return f"{tool_name}()" + + # Join arguments + args_str = ', '.join(arg_parts) + signature = f"{tool_name}({args_str})" + + # Truncate if too long + if len(signature) > max_len: + signature = signature[:max_len-3] + '...' + + return signature + + +class ErrorCategory(Enum): + """Categories of errors in agent trajectories.""" + + # Tool-level errors + TOOL_NOT_FOUND = "tool_not_found" # Called a tool that doesn't exist + TOOL_PARSE_ERROR = "tool_parse_error" # Tool call couldn't be parsed + TOOL_WRONG_ARGS = "tool_wrong_args" # Correct tool, but arguments failed + TOOL_EXECUTION_ERROR = "tool_execution_error" # Tool ran but returned error + + # Strategy-level errors + NO_PATCH_GENERATED = "no_patch_generated" # Never produced a patch + PATCH_FAILED = "patch_failed" # Patch didn't apply or was wrong + MAX_STEPS_REACHED = "max_steps_reached" # Hit step limit + + # Other + UNKNOWN = "unknown" + + +@dataclass +class InstanceTransferResult: + """Result of transfer for a single instance.""" + + instance_id: str + source_resolved: bool + target_resolved: bool + + @property + def transfer_category(self) -> str: + """Categorize the transfer outcome.""" + if self.source_resolved and self.target_resolved: + return "both_success" + elif self.source_resolved and not self.target_resolved: + return "transfer_loss" # Worked on source, failed on target + elif not self.source_resolved and self.target_resolved: + return "transfer_gain" # Failed on source, worked on target + else: + return "both_failure" + + +@dataclass +class McNemarResult: + """Result of McNemar's test for paired binary outcomes.""" + + # Contingency table counts + both_success: int = 0 # Resolved on both scaffolds + both_failure: int = 0 # Failed on both scaffolds + source_only: int = 0 # Resolved only on source (transfer loss) + target_only: int = 0 # Resolved only on target (transfer gain) + + # Test statistics + chi_squared: float = 0.0 + p_value: float = 0.0 + + @property + def total_instances(self) -> int: + return self.both_success + self.both_failure + self.source_only + self.target_only + + @property + def source_resolve_rate(self) -> float: + total = self.total_instances + if total == 0: + return 0.0 + return (self.both_success + self.source_only) / total + + @property + def target_resolve_rate(self) -> float: + total = self.total_instances + if total == 0: + return 0.0 + return (self.both_success + self.target_only) / total + + @property + def is_significant(self) -> bool: + """Whether the difference is statistically significant (p < 0.05).""" + return self.p_value < 0.05 + + @property + def transfer_direction(self) -> str: + """Direction of transfer effect.""" + if self.source_only > self.target_only: + return "degradation" + elif self.target_only > self.source_only: + return "improvement" + else: + return "neutral" + + def to_dict(self) -> dict[str, Any]: + return { + 'both_success': self.both_success, + 'both_failure': self.both_failure, + 'source_only': self.source_only, + 'target_only': self.target_only, + 'total_instances': self.total_instances, + 'source_resolve_rate': self.source_resolve_rate, + 'target_resolve_rate': self.target_resolve_rate, + 'chi_squared': self.chi_squared, + 'p_value': self.p_value, + 'is_significant': self.is_significant, + 'transfer_direction': self.transfer_direction, + } + + +@dataclass +class ErrorModeAnalysis: + """Analysis of error modes in a run.""" + + run_name: str + scaffold: str + + # Error counts by category + error_counts: dict[str, int] = field(default_factory=dict) + + # Tool-specific error rates + tool_error_rates: dict[str, float] = field(default_factory=dict) + + # Most common error-causing tools + error_prone_tools: list[tuple[str, int]] = field(default_factory=list) + + # Sample error messages by category + error_samples: dict[str, list[str]] = field(default_factory=dict) + + # Detailed error pattern counts (e.g., "file_not_found", "syntax_error") + error_pattern_counts: dict[str, int] = field(default_factory=dict) + + # Error patterns by tool + tool_error_patterns: dict[str, dict[str, int]] = field(default_factory=dict) + + @property + def total_errors(self) -> int: + return sum(self.error_counts.values()) + + @property + def top_error_patterns(self) -> list[tuple[str, int]]: + """Get top error patterns sorted by frequency.""" + return sorted(self.error_pattern_counts.items(), key=lambda x: x[1], reverse=True) + + def to_dict(self) -> dict[str, Any]: + return { + 'run_name': self.run_name, + 'scaffold': self.scaffold, + 'error_counts': self.error_counts, + 'total_errors': self.total_errors, + 'tool_error_rates': self.tool_error_rates, + 'error_prone_tools': self.error_prone_tools, + 'error_samples': self.error_samples, + 'error_pattern_counts': self.error_pattern_counts, + 'tool_error_patterns': self.tool_error_patterns, + } + + +@dataclass +class ToolVocabularyAnalysis: + """Analysis of tool vocabulary alignment between scaffolds.""" + + source_scaffold: str + target_scaffold: str + + # Tool vocabularies + source_tools: set[str] = field(default_factory=set) + target_tools: set[str] = field(default_factory=set) + + # Overlap analysis + shared_tools: set[str] = field(default_factory=set) + source_only_tools: set[str] = field(default_factory=set) + target_only_tools: set[str] = field(default_factory=set) + + # Tool usage counts + source_tool_counts: dict[str, int] = field(default_factory=dict) + target_tool_counts: dict[str, int] = field(default_factory=dict) + + # "Hallucinated" tools: tools called on target that don't exist there + # (model trying to use source scaffold's tools) + hallucinated_tools: dict[str, int] = field(default_factory=dict) + + # Potential tool mappings (source tool -> likely target equivalent) + tool_mappings: dict[str, str] = field(default_factory=dict) + + @property + def jaccard_index(self) -> float: + """Jaccard similarity of tool vocabularies.""" + union = self.source_tools | self.target_tools + if not union: + return 0.0 + return len(self.shared_tools) / len(union) + + @property + def hallucination_rate(self) -> float: + """Rate of hallucinated tool calls on target scaffold.""" + total_hallucinated = sum(self.hallucinated_tools.values()) + total_target_calls = sum(self.target_tool_counts.values()) + if total_target_calls == 0: + return 0.0 + return total_hallucinated / total_target_calls + + def to_dict(self) -> dict[str, Any]: + return { + 'source_scaffold': self.source_scaffold, + 'target_scaffold': self.target_scaffold, + 'source_tools': list(self.source_tools), + 'target_tools': list(self.target_tools), + 'shared_tools': list(self.shared_tools), + 'source_only_tools': list(self.source_only_tools), + 'target_only_tools': list(self.target_only_tools), + 'jaccard_index': self.jaccard_index, + 'hallucinated_tools': self.hallucinated_tools, + 'hallucination_rate': self.hallucination_rate, + 'tool_mappings': self.tool_mappings, + } + + +@dataclass +class DeepTransferAnalysis: + """Comprehensive transfer learning analysis.""" + + source_run_name: str + target_run_name: str + base_model: str + source_scaffold: str + target_scaffold: str + + # McNemar's test results + mcnemar: McNemarResult = field(default_factory=McNemarResult) + + # Per-instance results + instance_results: list[InstanceTransferResult] = field(default_factory=list) + + # Error mode comparison + source_errors: ErrorModeAnalysis | None = None + target_errors: ErrorModeAnalysis | None = None + + # Tool vocabulary analysis + vocabulary: ToolVocabularyAnalysis | None = None + + def to_dict(self) -> dict[str, Any]: + return { + 'source_run_name': self.source_run_name, + 'target_run_name': self.target_run_name, + 'base_model': self.base_model, + 'source_scaffold': self.source_scaffold, + 'target_scaffold': self.target_scaffold, + 'mcnemar': self.mcnemar.to_dict(), + 'instance_results_summary': { + 'both_success': self.mcnemar.both_success, + 'both_failure': self.mcnemar.both_failure, + 'transfer_loss': self.mcnemar.source_only, + 'transfer_gain': self.mcnemar.target_only, + }, + 'source_errors': self.source_errors.to_dict() if self.source_errors else None, + 'target_errors': self.target_errors.to_dict() if self.target_errors else None, + 'vocabulary': self.vocabulary.to_dict() if self.vocabulary else None, + } + + +class TransferAnalyzer: + """Perform deep transfer learning analysis.""" + + # Known tool mappings between scaffolds + TOOL_MAPPINGS = { + # R2E-Gym -> nano-agent potential mappings + ('r2e-gym', 'nano-agent'): { + 'file_editor': 'apply_patch', + 'execute_bash': 'shell', + 'search': 'shell', # grep/rg via shell + }, + # nano-agent -> R2E-Gym potential mappings + ('nano-agent', 'r2e-gym'): { + 'shell': 'execute_bash', + 'apply_patch': 'file_editor', + }, + } + + # Known valid tools per scaffold + SCAFFOLD_TOOLS = { + 'nano-agent': {'shell', 'apply_patch'}, + 'r2e-gym': {'file_editor', 'execute_bash', 'search', 'finish', 'str_replace'}, + 'swe-agent': {'edit', 'view', 'create', 'submit', 'search_file', 'search_dir', 'find_file'}, + } + + def analyze_transfer( + self, + source_run: Run, + target_run: Run, + ) -> DeepTransferAnalysis: + """Perform comprehensive transfer analysis. + + Args: + source_run: Run on the source (training) scaffold + target_run: Run on the target scaffold + + Returns: + DeepTransferAnalysis with all metrics + """ + analysis = DeepTransferAnalysis( + source_run_name=source_run.name, + target_run_name=target_run.name, + base_model=source_run.base_model, + source_scaffold=source_run.scaffold, + target_scaffold=target_run.scaffold, + ) + + # 1. Instance-level correlation with McNemar's test + analysis.mcnemar, analysis.instance_results = self._compute_mcnemar( + source_run, target_run + ) + + # 2. Error mode analysis + analysis.source_errors = self._analyze_errors(source_run) + analysis.target_errors = self._analyze_errors(target_run) + + # 3. Tool vocabulary alignment + analysis.vocabulary = self._analyze_vocabulary(source_run, target_run) + + return analysis + + def _compute_mcnemar( + self, + source_run: Run, + target_run: Run, + ) -> tuple[McNemarResult, list[InstanceTransferResult]]: + """Compute McNemar's test for paired binary outcomes. + + McNemar's test compares paired proportions. The null hypothesis is that + the probability of success is the same on both scaffolds. + + Uses the chi-squared approximation: χ² = (b - c)² / (b + c) + where b = source_only, c = target_only (discordant pairs) + """ + # Build lookup for target run + target_by_id = {t.instance_id: t for t in target_run.trajectories} + + result = McNemarResult() + instance_results = [] + + for source_traj in source_run.trajectories: + target_traj = target_by_id.get(source_traj.instance_id) + if target_traj is None: + continue # Instance not in both runs + + source_resolved = source_traj.resolved or False + target_resolved = target_traj.resolved or False + + instance_results.append(InstanceTransferResult( + instance_id=source_traj.instance_id, + source_resolved=source_resolved, + target_resolved=target_resolved, + )) + + if source_resolved and target_resolved: + result.both_success += 1 + elif source_resolved and not target_resolved: + result.source_only += 1 + elif not source_resolved and target_resolved: + result.target_only += 1 + else: + result.both_failure += 1 + + # Compute McNemar's chi-squared statistic + b = result.source_only + c = result.target_only + + if b + c > 0: + # Standard McNemar's test (with continuity correction for small samples) + result.chi_squared = (abs(b - c) - 1) ** 2 / (b + c) if b + c >= 25 else (b - c) ** 2 / (b + c) + + # Compute p-value from chi-squared distribution (1 df) + result.p_value = self._chi2_p_value(result.chi_squared, df=1) + else: + result.chi_squared = 0.0 + result.p_value = 1.0 + + return result, instance_results + + def _chi2_p_value(self, chi2: float, df: int = 1) -> float: + """Compute p-value from chi-squared statistic. + + Uses the regularized incomplete gamma function approximation. + For df=1, this simplifies to 1 - erf(sqrt(chi2/2)). + """ + if chi2 <= 0: + return 1.0 + + # For df=1, use complementary error function approximation + x = math.sqrt(chi2 / 2) + + # Approximation of erfc(x) = 1 - erf(x) + # Using Abramowitz and Stegun approximation + t = 1.0 / (1.0 + 0.3275911 * x) + coeffs = [0.254829592, -0.284496736, 1.421413741, -1.453152027, 1.061405429] + poly = sum(c * t ** (i + 1) for i, c in enumerate(coeffs)) + erfc = poly * math.exp(-x * x) + + return erfc + + def _analyze_errors(self, run: Run) -> ErrorModeAnalysis: + """Analyze error modes in a run.""" + analysis = ErrorModeAnalysis( + run_name=run.name, + scaffold=run.scaffold, + ) + + error_counts: dict[str, int] = defaultdict(int) + tool_errors: dict[str, int] = defaultdict(int) + tool_totals: dict[str, int] = defaultdict(int) + error_samples: dict[str, list[str]] = defaultdict(list) + error_pattern_counts: dict[str, int] = defaultdict(int) + tool_error_patterns: dict[str, dict[str, int]] = defaultdict(lambda: defaultdict(int)) + + valid_tools = self.SCAFFOLD_TOOLS.get(run.scaffold, set()) + + for traj in run.trajectories: + # Check trajectory-level errors + if not traj.has_patch: + error_counts[ErrorCategory.NO_PATCH_GENERATED.value] += 1 + elif traj.resolved is False: + error_counts[ErrorCategory.PATCH_FAILED.value] += 1 + + if traj.exit_reason == 'max_steps': + error_counts[ErrorCategory.MAX_STEPS_REACHED.value] += 1 + + # Check tool-level errors + for tc in traj.get_tool_calls(): + tool_totals[tc.name] += 1 + + # Check for hallucinated tools + if valid_tools and tc.name not in valid_tools: + error_counts[ErrorCategory.TOOL_NOT_FOUND.value] += 1 + tool_errors[tc.name] += 1 + if len(error_samples[ErrorCategory.TOOL_NOT_FOUND.value]) < 5: + error_samples[ErrorCategory.TOOL_NOT_FOUND.value].append( + f"Called '{tc.name}' (not in {run.scaffold})" + ) + + # Check for execution errors + elif not tc.success: + error_counts[ErrorCategory.TOOL_EXECUTION_ERROR.value] += 1 + tool_errors[tc.name] += 1 + + # Extract error pattern from result (use raw mode for more detail) + error_pattern = extract_error_pattern(tc.result or "", mode="raw") + error_pattern_counts[error_pattern] += 1 + tool_error_patterns[tc.name][error_pattern] += 1 + + if len(error_samples[ErrorCategory.TOOL_EXECUTION_ERROR.value]) < 5: + result_preview = (tc.result or "")[:100] + error_samples[ErrorCategory.TOOL_EXECUTION_ERROR.value].append( + f"{tc.name}: {result_preview}..." + ) + + analysis.error_counts = dict(error_counts) + analysis.error_samples = dict(error_samples) + analysis.error_pattern_counts = dict(error_pattern_counts) + analysis.tool_error_patterns = { + tool: dict(patterns) for tool, patterns in tool_error_patterns.items() + } + + # Compute tool error rates + analysis.tool_error_rates = { + tool: tool_errors.get(tool, 0) / total + for tool, total in tool_totals.items() + if total > 0 + } + + # Find most error-prone tools + analysis.error_prone_tools = sorted( + [(tool, count) for tool, count in tool_errors.items()], + key=lambda x: x[1], + reverse=True + )[:10] + + return analysis + + def _analyze_vocabulary( + self, + source_run: Run, + target_run: Run, + ) -> ToolVocabularyAnalysis: + """Analyze tool vocabulary alignment.""" + analysis = ToolVocabularyAnalysis( + source_scaffold=source_run.scaffold, + target_scaffold=target_run.scaffold, + ) + + # Collect tool usage from source + source_counts: dict[str, int] = defaultdict(int) + for traj in source_run.trajectories: + for tc in traj.get_tool_calls(): + source_counts[tc.name] += 1 + + # Collect tool usage from target + target_counts: dict[str, int] = defaultdict(int) + for traj in target_run.trajectories: + for tc in traj.get_tool_calls(): + target_counts[tc.name] += 1 + + analysis.source_tools = set(source_counts.keys()) + analysis.target_tools = set(target_counts.keys()) + analysis.source_tool_counts = dict(source_counts) + analysis.target_tool_counts = dict(target_counts) + + # Compute overlaps + analysis.shared_tools = analysis.source_tools & analysis.target_tools + analysis.source_only_tools = analysis.source_tools - analysis.target_tools + analysis.target_only_tools = analysis.target_tools - analysis.source_tools + + # Check for hallucinated tools on target + # (tools that exist on source but not on target scaffold's valid set) + valid_target_tools = self.SCAFFOLD_TOOLS.get(target_run.scaffold, set()) + if valid_target_tools: + for tool, count in target_counts.items(): + if tool not in valid_target_tools: + analysis.hallucinated_tools[tool] = count + + # Set known tool mappings + mapping_key = (source_run.scaffold, target_run.scaffold) + analysis.tool_mappings = self.TOOL_MAPPINGS.get(mapping_key, {}) + + return analysis + + def get_transfer_loss_instances( + self, + analysis: DeepTransferAnalysis, + ) -> list[str]: + """Get instance IDs that succeeded on source but failed on target.""" + return [ + r.instance_id for r in analysis.instance_results + if r.transfer_category == "transfer_loss" + ] + + def get_transfer_gain_instances( + self, + analysis: DeepTransferAnalysis, + ) -> list[str]: + """Get instance IDs that failed on source but succeeded on target.""" + return [ + r.instance_id for r in analysis.instance_results + if r.transfer_category == "transfer_gain" + ] + diff --git a/src/trajectory_analyzer/cli.py b/src/trajectory_analyzer/cli.py new file mode 100644 index 0000000..15401bc --- /dev/null +++ b/src/trajectory_analyzer/cli.py @@ -0,0 +1,157 @@ +"""Hydra CLI entry point for trajectory analyzer.""" + +import logging +from pathlib import Path +from typing import Any + +import hydra +from omegaconf import DictConfig, OmegaConf + +from .loaders import ClaudeCodeLoader, NanoAgentLoader, R2EGymLoader, SWEAgentLoader, TrajectoryLoader +from .models import Run +from .analysis import MetricsExtractor, RunComparator +from .plotting import TrajectoryPlotter + +logger = logging.getLogger(__name__) + + +def get_loader(format: str) -> TrajectoryLoader: + """Get the appropriate loader for the format. + + Args: + format: One of 'claude_code', 'nano_agent', 'r2e_gym', 'swe_agent' + + Returns: + TrajectoryLoader instance + """ + loaders = { + 'claude_code': ClaudeCodeLoader, + 'nano_agent': NanoAgentLoader, + 'r2e_gym': R2EGymLoader, + 'swe_agent': SWEAgentLoader, + } + + if format not in loaders: + raise ValueError(f"Unknown format: {format}. Choose from {list(loaders.keys())}") + + return loaders[format]() + + +def load_run_from_config(run_config: DictConfig) -> Run: + """Load a run from configuration. + + Args: + run_config: Run configuration + + Returns: + Run object with loaded trajectories + """ + loader = get_loader(run_config.format) + + return loader.load_run( + name=run_config.name, + scaffold=run_config.scaffold, + base_model=run_config.base_model, + trajectories_path=run_config.trajectories, + results_path=run_config.get('results'), + lora_adapter=run_config.get('lora_adapter'), + ) + + +def print_summary(runs: list[Run], comparator: RunComparator) -> None: + """Print summary statistics for all runs.""" + print("\n" + "=" * 70) + print("TRAJECTORY ANALYSIS SUMMARY") + print("=" * 70) + + for run in runs: + print(f"\n{run.name}") + print("-" * len(run.name)) + print(f" Scaffold: {run.scaffold}") + print(f" Base Model: {run.base_model}") + if run.lora_adapter: + print(f" LoRA Adapter: {run.lora_adapter}") + print(f" Instances: {run.num_instances}") + print(f" Resolved: {run.num_resolved} ({run.resolve_rate:.1%})") + print(f" With Patch: {run.num_with_patch} ({run.patch_rate:.1%})") + print(f" Avg Tool Calls: {run.get_avg_tool_calls():.1f}") + print(f" Avg Tokens: {run.get_avg_tokens():.0f}") + print(f" Avg Steps: {run.get_avg_steps():.1f}") + + # Top tools + tool_counts = run.get_total_tool_counts() + if tool_counts: + sorted_tools = sorted(tool_counts.items(), key=lambda x: x[1], reverse=True)[:5] + print(f" Top Tools: {', '.join(f'{t}({c})' for t, c in sorted_tools)}") + + if len(runs) > 1: + summary = comparator.get_comparison_summary(runs) + print("\n" + "=" * 70) + print("COMPARISON SUMMARY") + print("=" * 70) + print(f" Best Run: {summary['best_run']}") + print(f" Worst Run: {summary['worst_run']}") + print(f" Average Resolution Rate: {summary['avg_resolve_rate']:.1%}") + + print() + + +@hydra.main(version_base=None, config_path="conf", config_name="analyzer_config") +def main(cfg: DictConfig) -> None: + """Main entry point for trajectory analyzer. + + Args: + cfg: Hydra configuration + """ + # Setup logging + logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' + ) + + logger.info("Trajectory Analyzer starting...") + logger.info(f"Configuration:\n{OmegaConf.to_yaml(cfg)}") + + # Load runs + runs: list[Run] = [] + for run_config in cfg.runs: + try: + run = load_run_from_config(run_config) + runs.append(run) + logger.info(f"Loaded run '{run.name}' with {len(run)} trajectories") + except Exception as e: + logger.error(f"Failed to load run '{run_config.name}': {e}") + + if not runs: + logger.error("No runs loaded. Check your configuration.") + return + + # Initialize analysis components + metrics_extractor = MetricsExtractor() + comparator = RunComparator() + plotter = TrajectoryPlotter(output_dir=cfg.output_dir) + + # Print summary + print_summary(runs, comparator) + + # Generate plots + plots_to_generate = list(cfg.plots) if cfg.plots else None + + logger.info(f"Generating plots: {plots_to_generate or 'all'}") + + # Set model to trained scaffold mapping for transfer analysis + model_to_scaffold = dict(cfg.get('model_to_trained_scaffold', {})) + + generated_plots = plotter.plot_all( + runs, + plots_to_generate, + model_to_trained_scaffold=model_to_scaffold, + ) + + logger.info(f"Generated {len(generated_plots)} plots in {cfg.output_dir}") + print(f"\nGenerated {len(generated_plots)} plots in {cfg.output_dir}") + + +if __name__ == "__main__": + main() + diff --git a/src/trajectory_analyzer/conf/__init__.py b/src/trajectory_analyzer/conf/__init__.py new file mode 100644 index 0000000..95787a8 --- /dev/null +++ b/src/trajectory_analyzer/conf/__init__.py @@ -0,0 +1,2 @@ +"""Trajectory analyzer configuration package.""" + diff --git a/src/trajectory_analyzer/conf/analyzer_config.yaml b/src/trajectory_analyzer/conf/analyzer_config.yaml new file mode 100644 index 0000000..893a004 --- /dev/null +++ b/src/trajectory_analyzer/conf/analyzer_config.yaml @@ -0,0 +1,72 @@ +# Trajectory Analyzer Configuration +# +# Usage: +# uv run python -m src.trajectory_analyzer --config-path conf --config-name analyzer_config +# uv run python -m src.trajectory_analyzer output_dir=./my_plots 'plots=[tool_distribution,comparison]' + +# Output settings +output_dir: "./plots" + +# Plots to generate +# Options: tool_distribution, shell_command_distribution, success_rates, +# token_analysis, error_patterns, failed_tool_calls, error_analysis, +# comparison, transfer_analysis +plots: + - tool_distribution + - shell_command_distribution + - success_rates + - token_analysis + - error_patterns + - failed_tool_calls + - error_analysis + - comparison + - transfer_analysis + +# Model to trained scaffold mapping (for transfer analysis) +# Maps base model names to the scaffold they were trained on +model_to_trained_scaffold: + "agentica-org/DeepSWE-Preview": "r2e-gym" + "mistralai/devstral-2512:free": "mistral-vibe-cli" + "anthropic/claude-3-5-haiku-20241022": "claude-code" + +# Runs to analyze +# Each run specifies: +# - name: Identifier for the run +# - format: nano_agent | r2e_gym | swe_agent +# - trajectories: Path to trajectory file(s) (supports glob patterns for r2e_gym) +# - results: Optional path to SWE-bench results JSON +# - base_model: Base model identifier +# - scaffold: Agent scaffold type +# - lora_adapter: Optional LoRA adapter name +runs: [] + +# Example runs configuration (uncomment and modify as needed): +# runs: +# - name: "deepswe-nano-agent" +# format: "nano_agent" +# trajectories: "/path/to/detailed_predictions.jsonl" +# results: "/path/to/results.json" +# base_model: "agentica-org/DeepSWE-Preview" +# scaffold: "nano-agent" +# lora_adapter: null +# +# - name: "deepswe-r2e-gym" +# format: "r2e_gym" +# trajectories: "/path/to/deepswe_32b_agent_*.jsonl" +# results: null +# base_model: "agentica-org/DeepSWE-Preview" +# scaffold: "r2e-gym" +# lora_adapter: null +# +# - name: "qwen-nano-agent-finetuned" +# format: "nano_agent" +# trajectories: "/path/to/detailed_predictions.jsonl" +# results: "/path/to/results.json" +# base_model: "Qwen/Qwen3-32B" +# scaffold: "nano-agent" +# lora_adapter: "GSPO-Final-lora-step-460" + +hydra: + job: + chdir: false + diff --git a/src/trajectory_analyzer/conf/example_config.yaml b/src/trajectory_analyzer/conf/example_config.yaml new file mode 100644 index 0000000..d634ed9 --- /dev/null +++ b/src/trajectory_analyzer/conf/example_config.yaml @@ -0,0 +1,73 @@ +# Example Trajectory Analyzer Configuration +# +# This example uses paths from the CodeRepairRL-results and R2E-Gym repositories. +# Adjust paths as needed for your setup. +# +# Usage: +# uv run python -m src.trajectory_analyzer --config-path conf --config-name example_config + +output_dir: "./plots/trajectory_analysis" + +plots: + # Per-run plots (generated for each run): + - tool_distribution # Bar chart of tool usage counts + - shell_command_distribution # Bar chart of shell commands (grep, cat, etc.) + - success_rates # Resolution rates, tool success rates + - token_analysis # Token usage analysis + - error_patterns # Top error messages (raw first 5 words) + - failed_tool_calls # Most common failing tool calls with arguments + - error_analysis # Comprehensive error analysis (categories, rates, tools) + # Multi-run plots (when 2+ runs): + - comparison # Cross-run comparison grid + - transfer_analysis # Transfer learning impact (basic summary) + - transfer_mcnemar # Instance-level transfer (McNemar contingency + stats) + - transfer_error_modes # Error mode comparison between scaffolds + - transfer_vocabulary # Tool vocabulary alignment and hallucinations + - transfer_error_patterns # Raw error message pattern changes + +# Model to trained scaffold mapping +# DeepSWE was trained on R2E-Gym scaffold +model_to_trained_scaffold: + "agentica-org/DeepSWE-Preview": "r2e-gym" + +runs: + # DeepSWE on nano-agent scaffold + - name: "deepswe-nano-agent" + format: "nano_agent" + trajectories: "/home/andre/Repos/CodeRepairRL-results/nano-agent-agentica-org_DeepSWE-Preview/detailed_predictions.jsonl" + results: "/home/andre/Repos/CodeRepairRL-results/nano-agent-agentica-org_DeepSWE-Preview/nano-agent-hosted_vllm__agentica-org__DeepSWE-Preview.deepswe_32b__nano__500_tool_cals.json" + base_model: "agentica-org/DeepSWE-Preview" + scaffold: "nano-agent" + lora_adapter: null + + # DeepSWE on R2E-Gym scaffold (its training scaffold) + - name: "deepswe-r2e-gym" + format: "r2e_gym" + trajectories: "/home/andre/Repos/CodeRepairRL-results/traj_deepswe32b/deepswe_32b_agent_swebv_eval_temp_1_run_3.jsonl" + results: "/home/andre/Repos/CodeRepairRL-results/traj_deepswe32b/deepswe_32b_agent_swebv_eval_temp_1_run_3.deepswe_32b__r2egym__run3.json" + base_model: "agentica-org/DeepSWE-Preview" + scaffold: "r2e-gym" + lora_adapter: null + + # Qwen base model on nano-agent + - name: "qwen32b-nano-agent" + format: "nano_agent" + trajectories: "/home/andre/Repos/CodeRepairRL-results/nano-agent-Qwen_Qwen3-32B/detailed_predictions.jsonl" + results: "/home/andre/Repos/CodeRepairRL-results/nano-agent-Qwen_Qwen3-32B/nano-agent-hosted_vllm__Qwen__Qwen3-32B.qwen_32b__nano__500_tool_calls.json" + base_model: "Qwen/Qwen3-32B" + scaffold: "nano-agent" + lora_adapter: null + + # Qwen base model on R2E-Gym scaffold + - name: "qwen32b-r2e-gym" + format: "r2e_gym" + trajectories: "/home/andre/Repos/CodeRepairRL-results/traj_qwen32b/qwen3_32b_agent_swebv_eval_temp_1_run_3.jsonl" + results: "/home/andre/Repos/CodeRepairRL-results/traj_qwen32b/qwen3_32b_agent_swebv_eval_temp_1_run_3.qwen_32b__r2egym__run3.json" + base_model: "Qwen/Qwen3-32B" + scaffold: "r2e-gym" + lora_adapter: null + +hydra: + job: + chdir: false + diff --git a/src/trajectory_analyzer/loaders/__init__.py b/src/trajectory_analyzer/loaders/__init__.py new file mode 100644 index 0000000..1db1dcd --- /dev/null +++ b/src/trajectory_analyzer/loaders/__init__.py @@ -0,0 +1,16 @@ +"""Trajectory loaders for different agent formats.""" + +from .base import TrajectoryLoader +from .claude_code import ClaudeCodeLoader +from .nano_agent import NanoAgentLoader +from .r2e_gym import R2EGymLoader +from .swe_agent import SWEAgentLoader + +__all__ = [ + "TrajectoryLoader", + "ClaudeCodeLoader", + "NanoAgentLoader", + "R2EGymLoader", + "SWEAgentLoader", +] + diff --git a/src/trajectory_analyzer/loaders/base.py b/src/trajectory_analyzer/loaders/base.py new file mode 100644 index 0000000..f175821 --- /dev/null +++ b/src/trajectory_analyzer/loaders/base.py @@ -0,0 +1,143 @@ +"""Abstract base class for trajectory loaders.""" + +import json +import logging +from abc import ABC, abstractmethod +from pathlib import Path +from typing import Any + +from ..models import Run, Trajectory + +logger = logging.getLogger(__name__) + + +class TrajectoryLoader(ABC): + """Abstract base class for loading trajectories from different formats.""" + + @abstractmethod + def load_trajectories(self, path: Path | str) -> list[Trajectory]: + """Load trajectories from a file or directory. + + Args: + path: Path to trajectory file(s) + + Returns: + List of Trajectory objects + """ + pass + + def load_run( + self, + name: str, + scaffold: str, + base_model: str, + trajectories_path: Path | str, + results_path: Path | str | None = None, + lora_adapter: str | None = None, + ) -> Run: + """Load a complete run with trajectories and optional results. + + Args: + name: Run identifier + scaffold: Agent scaffold type + base_model: Base model identifier + trajectories_path: Path to trajectory file(s) + results_path: Optional path to SWE-bench results JSON + lora_adapter: Optional LoRA adapter name + + Returns: + Run object with loaded trajectories + """ + trajectories = self.load_trajectories(trajectories_path) + + resolved_ids: set[str] = set() + if results_path: + resolved_ids = self.load_results(results_path) + + run = Run( + name=name, + scaffold=scaffold, + base_model=base_model, + trajectories=trajectories, + resolved_ids=resolved_ids, + lora_adapter=lora_adapter, + ) + + logger.info( + f"Loaded run '{name}': {len(trajectories)} trajectories, " + f"{len(resolved_ids)} resolved" + ) + + return run + + @staticmethod + def load_results(results_path: Path | str) -> set[str]: + """Load resolved instance IDs from SWE-bench results JSON. + + Args: + results_path: Path to results JSON file + + Returns: + Set of resolved instance IDs + """ + path = Path(results_path) + if not path.exists(): + logger.warning(f"Results file not found: {path}") + return set() + + try: + with open(path, 'r') as f: + data = json.load(f) + + # Handle different result formats + if "resolved_ids" in data: + return set(data["resolved_ids"]) + elif "resolved" in data: + return set(data["resolved"]) + else: + logger.warning(f"No resolved_ids found in {path}") + return set() + except Exception as e: + logger.error(f"Error loading results from {path}: {e}") + return set() + + @staticmethod + def load_jsonl(path: Path | str) -> list[dict[str, Any]]: + """Load records from a JSONL file. + + Args: + path: Path to JSONL file + + Returns: + List of parsed JSON records + """ + path = Path(path) + records = [] + + with open(path, 'r') as f: + for line_num, line in enumerate(f, 1): + line = line.strip() + if not line: + continue + try: + records.append(json.loads(line)) + except json.JSONDecodeError as e: + logger.warning(f"Failed to parse line {line_num} in {path}: {e}") + + return records + + @staticmethod + def detect_shell_command(cmd: str) -> str | None: + """Extract the base shell command from a command string. + + Args: + cmd: Full command string + + Returns: + Base command (first word) or None + """ + if not cmd: + return None + parts = cmd.strip().split() + return parts[0] if parts else None + diff --git a/src/trajectory_analyzer/loaders/nano_agent.py b/src/trajectory_analyzer/loaders/nano_agent.py new file mode 100644 index 0000000..90df360 --- /dev/null +++ b/src/trajectory_analyzer/loaders/nano_agent.py @@ -0,0 +1,219 @@ +"""Loader for nano-agent trajectory format.""" + +import logging +from pathlib import Path +from typing import Any + +from .base import TrajectoryLoader +from ..models import Trajectory, Step, ToolCall + +logger = logging.getLogger(__name__) + + +class NanoAgentLoader(TrajectoryLoader): + """Loader for nano-agent detailed_predictions.jsonl format. + + Expected format: + - JSONL file with one record per instance + - Each record has 'instance_id' and 'detailed_predictions' fields + - detailed_predictions contains: + - completion: list of chat messages (OpenAI format) + - generated_diff: the patch output + - token_usage: total tokens used + - tool_usage: total tool calls + - tool_calls_shell: number of shell tool calls + - tool_calls_apply_patch: number of apply_patch tool calls + - tool_success_rate_shell: success rate for shell + - tool_success_rate_apply_patch: success rate for apply_patch + - shell_cmd_*: counts for individual shell commands + """ + + def load_trajectories(self, path: Path | str) -> list[Trajectory]: + """Load trajectories from a nano-agent JSONL file. + + Args: + path: Path to detailed_predictions.jsonl + + Returns: + List of Trajectory objects + """ + path = Path(path) + records = self.load_jsonl(path) + + trajectories = [] + for record in records: + try: + traj = self._parse_record(record) + trajectories.append(traj) + except Exception as e: + instance_id = record.get('instance_id', 'unknown') + logger.warning(f"Failed to parse trajectory for {instance_id}: {e}") + + logger.info(f"Loaded {len(trajectories)} trajectories from {path}") + return trajectories + + def _parse_record(self, record: dict[str, Any]) -> Trajectory: + """Parse a single nano-agent record into a Trajectory.""" + instance_id = record.get('instance_id', 'unknown') + det = record.get('detailed_predictions', {}) + + # Parse chat completion into steps + completion = det.get('completion', []) + steps = self._parse_completion(completion, det) + + return Trajectory( + instance_id=instance_id, + steps=steps, + generated_patch=det.get('generated_diff'), + exit_reason=det.get('exit_reason'), + ) + + def _parse_completion( + self, + completion: list[dict[str, Any]] | None, + det: dict[str, Any] + ) -> list[Step]: + """Parse OpenAI chat completion format into Steps. + + The completion is a list of alternating assistant/tool messages. + Each assistant message with tool_calls forms a step. + """ + steps: list[Step] = [] + step_index = 0 + + if not completion: + return steps + + i = 0 + while i < len(completion): + msg = completion[i] + role = msg.get('role') + + if role == 'assistant': + # Parse assistant message as a step + tool_calls_data = msg.get('tool_calls') or [] + content = msg.get('content') or '' + + # Collect tool results from subsequent tool messages + tool_results: dict[str, str] = {} + j = i + 1 + while j < len(completion) and completion[j].get('role') == 'tool': + tool_msg = completion[j] + tool_call_id = tool_msg.get('tool_call_id', '') + tool_result = tool_msg.get('content', '') + tool_results[tool_call_id] = tool_result + j += 1 + + # Parse tool calls + tool_calls = self._parse_tool_calls(tool_calls_data, tool_results, det) + + if tool_calls or content: # Only add step if there's content + steps.append(Step( + index=step_index, + thought=content if content else None, + tool_calls=tool_calls, + token_usage=0, # Token usage is aggregated in nano-agent format + )) + step_index += 1 + + # Skip to after the tool messages + i = j + else: + i += 1 + + # Distribute total token usage across steps if available + total_tokens = det.get('token_usage', 0) + if steps and total_tokens > 0: + tokens_per_step = total_tokens // len(steps) + for step in steps: + step.token_usage = tokens_per_step + # Add remainder to last step + steps[-1].token_usage += total_tokens % len(steps) + + return steps + + def _parse_tool_calls( + self, + tool_calls_data: list[dict[str, Any]], + tool_results: dict[str, str], + det: dict[str, Any], + ) -> list[ToolCall]: + """Parse tool calls from OpenAI format.""" + tool_calls = [] + + # Get success rates for determining tool success + shell_success_rate = det.get('tool_success_rate_shell', 1.0) + apply_patch_success_rate = det.get('tool_success_rate_apply_patch', 1.0) + + for tc_data in tool_calls_data: + func_data = tc_data.get('function', {}) + tool_name = func_data.get('name', 'unknown') + + # Parse arguments + args_str = func_data.get('arguments', '{}') + try: + import json + arguments = json.loads(args_str) if isinstance(args_str, str) else args_str + except json.JSONDecodeError: + arguments = {'raw': args_str} + + # Get result from tool_results mapping + tool_call_id = tc_data.get('id', '') + result = tool_results.get(tool_call_id) + + # Determine success based on result content + success = self._determine_success(tool_name, result, arguments) + + # Extract shell command if applicable + shell_command = None + if tool_name in ('shell', 'execute_bash', 'bash'): + cmd = arguments.get('cmd') or arguments.get('command', '') + shell_command = self.detect_shell_command(cmd) + + tool_calls.append(ToolCall( + name=tool_name, + arguments=arguments, + result=result, + success=success, + shell_command=shell_command, + )) + + return tool_calls + + def _determine_success( + self, + tool_name: str, + result: str | None, + arguments: dict[str, Any], + ) -> bool: + """Determine if a tool call was successful based on its result.""" + if result is None: + return False + + result_lower = result.lower() + + # Check for common error patterns + error_patterns = [ + 'error:', + 'failed', + 'no such file', + 'not found', + 'command not found', + 'permission denied', + 'traceback', + 'exception', + ] + + for pattern in error_patterns: + if pattern in result_lower: + return False + + # For apply_patch, check for specific failure indicators + if tool_name == 'apply_patch': + if 'patch failed' in result_lower or 'could not apply' in result_lower: + return False + if 'not unique' in result_lower or 'multiple matches' in result_lower: + return False + + return True + diff --git a/src/trajectory_analyzer/loaders/r2e_gym.py b/src/trajectory_analyzer/loaders/r2e_gym.py new file mode 100644 index 0000000..4b08a30 --- /dev/null +++ b/src/trajectory_analyzer/loaders/r2e_gym.py @@ -0,0 +1,240 @@ +"""Loader for R2E-Gym trajectory format.""" + +import logging +import re +from glob import glob +from pathlib import Path +from typing import Any + +from .base import TrajectoryLoader +from ..models import Trajectory, Step, ToolCall + +logger = logging.getLogger(__name__) + + +class R2EGymLoader(TrajectoryLoader): + """Loader for R2E-Gym JSONL trajectory format. + + Expected format: + - JSONL file with one record per instance + - Each record has: + - ds: dataset info with instance_id + - trajectory_steps: list of steps + - output_patch: generated patch + - reward: 1.0 if resolved, 0.0 otherwise + - exit_reason: why trajectory ended + - Each step has: + - action: XML-format function call + - observation: tool result + - thought: reasoning (may include tags) + - token_usage_total: tokens for this step + """ + + # Regex pattern for parsing XML-style function calls + FUNCTION_PATTERN = re.compile( + r'(.*?)', + re.DOTALL + ) + PARAMETER_PATTERN = re.compile( + r'(.*?)', + re.DOTALL + ) + + def load_trajectories(self, path: Path | str) -> list[Trajectory]: + """Load trajectories from R2E-Gym JSONL file(s). + + Args: + path: Path to JSONL file or glob pattern (e.g., 'trajs/*.jsonl') + + Returns: + List of Trajectory objects + """ + path_str = str(path) + + # Handle glob patterns + if '*' in path_str: + files = glob(path_str) + else: + files = [path_str] + + trajectories = [] + for file_path in files: + file_trajs = self._load_file(Path(file_path)) + trajectories.extend(file_trajs) + + logger.info(f"Loaded {len(trajectories)} trajectories from {len(files)} file(s)") + return trajectories + + def _load_file(self, path: Path) -> list[Trajectory]: + """Load trajectories from a single file.""" + records = self.load_jsonl(path) + + trajectories = [] + for record in records: + try: + traj = self._parse_record(record) + trajectories.append(traj) + except Exception as e: + ds = record.get('ds', {}) + instance_id = ds.get('instance_id', 'unknown') + logger.warning(f"Failed to parse trajectory for {instance_id}: {e}") + + return trajectories + + def _parse_record(self, record: dict[str, Any]) -> Trajectory: + """Parse a single R2E-Gym record into a Trajectory.""" + ds = record.get('ds', {}) + instance_id = ds.get('instance_id', 'unknown') + + # Parse trajectory steps + steps_data = record.get('trajectory_steps', []) + steps = [self._parse_step(s, i) for i, s in enumerate(steps_data)] + + # Get resolution status from reward + reward = record.get('reward', 0.0) + resolved = reward >= 1.0 if reward is not None else None + + return Trajectory( + instance_id=instance_id, + steps=steps, + generated_patch=record.get('output_patch'), + resolved=resolved, + exit_reason=record.get('exit_reason'), + ) + + def _parse_step(self, step_data: dict[str, Any], index: int) -> Step: + """Parse a single step from R2E-Gym format.""" + action = step_data.get('action', '') + observation = step_data.get('observation', '') + thought = step_data.get('thought', '') + + # Clean up thought (remove tags if present) + if thought: + thought = re.sub(r'', '', thought).strip() + + # Parse tool calls from action + tool_calls = self._parse_action(action, observation) + + # Use completion tokens only (not total) to avoid counting cumulative prompts + # token_usage_total includes prompt+completion, but prompts grow each step + # and include previous context, so summing totals massively overcounts + return Step( + index=index, + thought=thought if thought else None, + tool_calls=tool_calls, + token_usage=step_data.get('token_usage_completion', 0), + ) + + def _parse_action(self, action: str, observation: str) -> list[ToolCall]: + """Parse XML-style function calls from action string.""" + tool_calls = [] + + # Find all function calls in the action + for match in self.FUNCTION_PATTERN.finditer(action): + func_name = match.group(1) + func_content = match.group(2) + + # Parse parameters + arguments: dict[str, Any] = {} + for param_match in self.PARAMETER_PATTERN.finditer(func_content): + param_name = param_match.group(1) + param_value = param_match.group(2).strip() + arguments[param_name] = param_value + + # Determine success based on observation + success = self._determine_success(func_name, observation, arguments) + + # Extract shell command if applicable + shell_command = None + if func_name in ('execute_bash', 'bash', 'shell'): + cmd = arguments.get('command') or arguments.get('cmd', '') + shell_command = self.detect_shell_command(cmd) + + tool_calls.append(ToolCall( + name=func_name, + arguments=arguments, + result=observation, + success=success, + shell_command=shell_command, + )) + + return tool_calls + + def _determine_success( + self, + func_name: str, + observation: str, + arguments: dict[str, Any], + ) -> bool: + """Determine if a tool call was successful.""" + if not observation: + return False + + obs_lower = observation.lower() + + # Check for common error patterns + error_patterns = [ + 'error:', + 'failed', + 'no such file', + 'not found', + 'command not found', + 'permission denied', + 'traceback', + 'exception:', + 'syntax error', + ] + + for pattern in error_patterns: + if pattern in obs_lower: + return False + + # Check for exit code errors + if 'exit code' in obs_lower: + # Look for non-zero exit codes + exit_match = re.search(r'exit code[:\s]+(\d+)', obs_lower) + if exit_match and exit_match.group(1) != '0': + return False + + return True + + def load_run( + self, + name: str, + scaffold: str, + base_model: str, + trajectories_path: Path | str, + results_path: Path | str | None = None, + lora_adapter: str | None = None, + ): + """Load a run, using reward field as resolved status if no results file.""" + from ..models import Run + + trajectories = self.load_trajectories(trajectories_path) + + resolved_ids: set[str] = set() + if results_path: + resolved_ids = self.load_results(results_path) + else: + # Use reward field from trajectories + resolved_ids = { + t.instance_id for t in trajectories + if t.resolved is True + } + + run = Run( + name=name, + scaffold=scaffold, + base_model=base_model, + trajectories=trajectories, + resolved_ids=resolved_ids, + lora_adapter=lora_adapter, + ) + + logger.info( + f"Loaded run '{name}': {len(trajectories)} trajectories, " + f"{len(resolved_ids)} resolved" + ) + + return run + diff --git a/src/trajectory_analyzer/loaders/swe_agent.py b/src/trajectory_analyzer/loaders/swe_agent.py new file mode 100644 index 0000000..3169ee6 --- /dev/null +++ b/src/trajectory_analyzer/loaders/swe_agent.py @@ -0,0 +1,282 @@ +"""Loader for SWE-agent log file format.""" + +import logging +import re +from pathlib import Path +from typing import Any + +from .base import TrajectoryLoader +from ..models import Trajectory, Step, ToolCall + +logger = logging.getLogger(__name__) + + +class SWEAgentLoader(TrajectoryLoader): + """Loader for SWE-agent log file format. + + Expected format: + - Directory containing subdirectories for each instance + - Each subdirectory contains .log files + - Log files contain "🎬 ACTION" markers to identify tool calls + - Tool name is the first word after the ACTION marker + """ + + # Patterns for parsing SWE-agent logs + ACTION_MARKER = "🎬 ACTION" + OBSERVATION_MARKER = "🔎 OBSERVATION" + THOUGHT_MARKER = "💭 THOUGHT" + + def load_trajectories(self, path: Path | str) -> list[Trajectory]: + """Load trajectories from a SWE-agent logs directory. + + Args: + path: Path to directory containing instance subdirectories + + Returns: + List of Trajectory objects + """ + logs_dir = Path(path) + + if not logs_dir.exists(): + raise FileNotFoundError(f"Log directory not found: {logs_dir}") + + trajectories = [] + + # Find all subdirectories (each represents an instance) + for instance_dir in sorted(logs_dir.iterdir()): + if not instance_dir.is_dir(): + continue + + instance_id = instance_dir.name + + # Find .log files in the subdirectory + log_files = list(instance_dir.glob("*.log")) + if not log_files: + continue + + # Use the first .log file found + log_file = log_files[0] + + try: + traj = self._load_log_file(log_file, instance_id) + trajectories.append(traj) + except Exception as e: + logger.warning(f"Failed to load {log_file}: {e}") + + logger.info(f"Loaded {len(trajectories)} trajectories from {logs_dir}") + return trajectories + + def _load_log_file(self, log_file: Path, instance_id: str) -> Trajectory: + """Load a single log file into a Trajectory.""" + with open(log_file, 'r', encoding='utf-8') as f: + log_content = f.read() + + steps = self._parse_log_content(log_content) + + # Try to extract patch from log (if present) + generated_patch = self._extract_patch(log_content) + + return Trajectory( + instance_id=instance_id, + steps=steps, + generated_patch=generated_patch, + ) + + def _parse_log_content(self, log_content: str) -> list[Step]: + """Parse log content into Steps.""" + lines = log_content.split('\n') + steps: list[Step] = [] + + current_thought: str | None = None + current_action: str | None = None + current_observation: str | None = None + step_index = 0 + + i = 0 + while i < len(lines): + line = lines[i] + + if self.THOUGHT_MARKER in line: + # Start collecting thought + current_thought = self._extract_section(lines, i + 1) + + elif self.ACTION_MARKER in line: + # Extract action + if i + 1 < len(lines): + current_action = lines[i + 1].strip() + else: + # Check if action is on same line + parts = line.split(self.ACTION_MARKER, 1) + if len(parts) > 1: + current_action = parts[1].strip() + + elif self.OBSERVATION_MARKER in line: + # Extract observation and complete the step + current_observation = self._extract_section(lines, i + 1) + + # Create step if we have an action + if current_action: + tool_calls = self._parse_action(current_action, current_observation) + + steps.append(Step( + index=step_index, + thought=current_thought, + tool_calls=tool_calls, + token_usage=0, # Not available in log format + )) + step_index += 1 + + # Reset for next step + current_thought = None + current_action = None + current_observation = None + + i += 1 + + # Handle any remaining action without observation + if current_action: + tool_calls = self._parse_action(current_action, None) + steps.append(Step( + index=step_index, + thought=current_thought, + tool_calls=tool_calls, + token_usage=0, + )) + + return steps + + def _extract_section(self, lines: list[str], start_idx: int) -> str: + """Extract a section of text until the next marker.""" + section_lines = [] + markers = [self.THOUGHT_MARKER, self.ACTION_MARKER, self.OBSERVATION_MARKER] + + i = start_idx + while i < len(lines): + line = lines[i] + # Stop if we hit another marker + if any(marker in line for marker in markers): + break + section_lines.append(line) + i += 1 + + return '\n'.join(section_lines).strip() + + def _parse_action( + self, + action: str, + observation: str | None + ) -> list[ToolCall]: + """Parse action string into tool calls.""" + tool_calls = [] + + if not action: + return tool_calls + + # Get tool name (first word) + words = action.split() + if not words: + return tool_calls + + tool_name = words[0].strip() + + # Parse arguments (everything after tool name) + args_str = ' '.join(words[1:]) if len(words) > 1 else '' + arguments = self._parse_arguments(tool_name, args_str) + + # Determine success based on observation + success = self._determine_success(tool_name, observation) + + # Extract shell command if applicable + shell_command = None + if tool_name.lower() in ('bash', 'run_command', 'execute', 'run', 'shell'): + cmd = arguments.get('command') or arguments.get('cmd', args_str) + shell_command = self.detect_shell_command(cmd) + + tool_calls.append(ToolCall( + name=tool_name, + arguments=arguments, + result=observation, + success=success, + shell_command=shell_command, + )) + + return tool_calls + + def _parse_arguments(self, tool_name: str, args_str: str) -> dict[str, Any]: + """Parse argument string into a dictionary.""" + if not args_str: + return {} + + # Try to detect key=value patterns + args: dict[str, Any] = {} + + # Check for common patterns + # Pattern 1: key=value pairs + kv_pattern = re.findall(r'(\w+)=(["\']?)(.+?)\2(?:\s|$)', args_str) + if kv_pattern: + for key, _, value in kv_pattern: + args[key] = value + + # Pattern 2: Just a command/path + if not args: + if tool_name.lower() in ('bash', 'run_command', 'execute', 'run', 'shell'): + args['command'] = args_str + else: + args['raw'] = args_str + + return args + + def _determine_success(self, tool_name: str, observation: str | None) -> bool: + """Determine if a tool call was successful.""" + if observation is None: + return True # Assume success if no observation + + obs_lower = observation.lower() + + error_patterns = [ + 'error:', + 'failed', + 'no such file', + 'not found', + 'command not found', + 'permission denied', + 'traceback', + 'exception', + ] + + for pattern in error_patterns: + if pattern in obs_lower: + return False + + return True + + def _extract_patch(self, log_content: str) -> str | None: + """Try to extract generated patch from log content.""" + # Look for common patch markers + patch_markers = [ + 'diff --git', + '--- a/', + '+++ b/', + ] + + for marker in patch_markers: + if marker in log_content: + # Try to extract the diff section + start = log_content.find('diff --git') + if start == -1: + start = log_content.find('--- a/') + + if start != -1: + # Find the end of the patch (look for common end patterns) + end = len(log_content) + for end_marker in ['🎬', '💭', '🔎', '\n\n\n']: + pos = log_content.find(end_marker, start) + if pos != -1 and pos < end: + end = pos + + patch = log_content[start:end].strip() + if patch: + return patch + + return None + diff --git a/src/trajectory_analyzer/models/__init__.py b/src/trajectory_analyzer/models/__init__.py new file mode 100644 index 0000000..3c8bcd4 --- /dev/null +++ b/src/trajectory_analyzer/models/__init__.py @@ -0,0 +1,7 @@ +"""Data models for trajectory analysis.""" + +from .trajectory import ToolCall, Step, Trajectory +from .run import Run + +__all__ = ["ToolCall", "Step", "Trajectory", "Run"] + diff --git a/src/trajectory_analyzer/models/run.py b/src/trajectory_analyzer/models/run.py new file mode 100644 index 0000000..51c0880 --- /dev/null +++ b/src/trajectory_analyzer/models/run.py @@ -0,0 +1,135 @@ +"""Run model representing a collection of trajectories with metadata.""" + +from dataclasses import dataclass, field +from typing import Iterator +from collections import defaultdict + +from .trajectory import Trajectory + + +@dataclass +class Run: + """Represents an evaluation run: a collection of trajectories with metadata.""" + + name: str + """Run identifier, e.g., 'nano-agent-DeepSWE-Preview'.""" + + scaffold: str + """Agent scaffold type: 'nano-agent', 'r2e-gym', or 'swe-agent'.""" + + base_model: str + """Base model identifier, e.g., 'Qwen/Qwen3-32B'.""" + + trajectories: list[Trajectory] = field(default_factory=list) + """List of trajectories in this run.""" + + resolved_ids: set[str] = field(default_factory=set) + """Instance IDs that were resolved (from SWE-bench results).""" + + lora_adapter: str | None = None + """LoRA adapter name if applicable, e.g., 'GSPO-Final-lora-step-460'.""" + + def __post_init__(self): + # Apply resolved status to trajectories if we have results + if self.resolved_ids: + for traj in self.trajectories: + traj.resolved = traj.instance_id in self.resolved_ids + + def add_trajectory(self, trajectory: Trajectory) -> None: + """Add a trajectory and update its resolved status.""" + if self.resolved_ids: + trajectory.resolved = trajectory.instance_id in self.resolved_ids + self.trajectories.append(trajectory) + + def set_resolved_ids(self, resolved_ids: set[str]) -> None: + """Set resolved IDs and update all trajectories.""" + self.resolved_ids = resolved_ids + for traj in self.trajectories: + traj.resolved = traj.instance_id in self.resolved_ids + + def __iter__(self) -> Iterator[Trajectory]: + return iter(self.trajectories) + + def __len__(self) -> int: + return len(self.trajectories) + + @property + def num_instances(self) -> int: + """Number of instances in this run.""" + return len(self.trajectories) + + @property + def num_resolved(self) -> int: + """Number of resolved instances.""" + return sum(1 for t in self.trajectories if t.resolved) + + @property + def num_with_patch(self) -> int: + """Number of instances where agent generated a patch.""" + return sum(1 for t in self.trajectories if t.has_patch) + + @property + def resolve_rate(self) -> float: + """Resolution rate (resolved / total).""" + if not self.trajectories: + return 0.0 + return self.num_resolved / len(self.trajectories) + + @property + def patch_rate(self) -> float: + """Patch generation rate (has_patch / total).""" + if not self.trajectories: + return 0.0 + return self.num_with_patch / len(self.trajectories) + + @property + def is_finetuned(self) -> bool: + """Whether this run uses a fine-tuned model.""" + return self.lora_adapter is not None + + def get_total_tool_counts(self) -> dict[str, int]: + """Aggregate tool counts across all trajectories.""" + counts: dict[str, int] = defaultdict(int) + for traj in self.trajectories: + for tool, count in traj.get_tool_counts().items(): + counts[tool] += count + return dict(counts) + + def get_total_shell_command_counts(self) -> dict[str, int]: + """Aggregate shell command counts across all trajectories.""" + counts: dict[str, int] = defaultdict(int) + for traj in self.trajectories: + for cmd, count in traj.get_shell_command_counts().items(): + counts[cmd] += count + return dict(counts) + + def get_avg_tool_calls(self) -> float: + """Average tool calls per trajectory.""" + if not self.trajectories: + return 0.0 + return sum(t.total_tool_calls for t in self.trajectories) / len(self.trajectories) + + def get_avg_tokens(self) -> float: + """Average tokens per trajectory.""" + if not self.trajectories: + return 0.0 + return sum(t.total_tokens for t in self.trajectories) / len(self.trajectories) + + def get_avg_steps(self) -> float: + """Average steps per trajectory.""" + if not self.trajectories: + return 0.0 + return sum(t.num_steps for t in self.trajectories) / len(self.trajectories) + + def get_resolved_trajectories(self) -> list[Trajectory]: + """Get trajectories that were resolved.""" + return [t for t in self.trajectories if t.resolved] + + def get_unresolved_trajectories(self) -> list[Trajectory]: + """Get trajectories that were not resolved.""" + return [t for t in self.trajectories if t.resolved is False] + + def get_unknown_trajectories(self) -> list[Trajectory]: + """Get trajectories with unknown resolution status.""" + return [t for t in self.trajectories if t.resolved is None] + diff --git a/src/trajectory_analyzer/models/trajectory.py b/src/trajectory_analyzer/models/trajectory.py new file mode 100644 index 0000000..1c831e3 --- /dev/null +++ b/src/trajectory_analyzer/models/trajectory.py @@ -0,0 +1,168 @@ +"""Core trajectory data models.""" + +from dataclasses import dataclass, field +from typing import Any + + +@dataclass +class ToolCall: + """Represents a single tool call within a trajectory step. + + This is a pure data container. All parsing/extraction logic + should be handled by the format-specific loaders. + """ + + name: str + """Tool name, e.g., 'shell', 'str_replace_editor', 'search'.""" + + arguments: dict[str, Any] = field(default_factory=dict) + """Tool-specific parameters.""" + + result: str | None = None + """Tool output/observation.""" + + success: bool = True + """Whether tool executed successfully.""" + + shell_command: str | None = None + """Base shell command if this is a shell tool call (e.g., 'grep', 'cat'). + + Should be set by the loader when parsing shell/bash tool calls. + """ + + +@dataclass +class Step: + """Represents a single step in an agent trajectory.""" + + index: int + """Step index within the trajectory.""" + + thought: str | None = None + """Reasoning/thinking content before tool call.""" + + tool_calls: list[ToolCall] = field(default_factory=list) + """Tool calls made in this step.""" + + token_usage: int = 0 + """Tokens used in this step (total).""" + + input_tokens: int = 0 + """Input tokens used in this step.""" + + output_tokens: int = 0 + """Output tokens used in this step.""" + + cache_creation_input_tokens: int = 0 + """Cache creation input tokens (for cached runs).""" + + cache_read_input_tokens: int = 0 + """Cache read input tokens (tokens read from cache).""" + + @property + def num_tool_calls(self) -> int: + """Number of tool calls in this step.""" + return len(self.tool_calls) + + @property + def successful_tool_calls(self) -> int: + """Number of successful tool calls.""" + return sum(1 for tc in self.tool_calls if tc.success) + + +@dataclass +class Trajectory: + """Represents a complete agent trajectory for solving one instance.""" + + instance_id: str + """SWE-bench instance ID (e.g., 'astropy__astropy-14096').""" + + steps: list[Step] = field(default_factory=list) + """Sequence of steps in the trajectory.""" + + generated_patch: str | None = None + """The diff/patch generated by the agent.""" + + resolved: bool | None = None + """Whether the instance was resolved (from SWE-bench results). None if unknown.""" + + exit_reason: str | None = None + """Why the trajectory ended (e.g., 'agent', 'max_steps', 'error').""" + + @property + def total_tokens(self) -> int: + """Total tokens used across all steps.""" + return sum(step.token_usage for step in self.steps) + + @property + def total_input_tokens(self) -> int: + """Total input tokens used across all steps.""" + return sum(step.input_tokens for step in self.steps) + + @property + def total_output_tokens(self) -> int: + """Total output tokens used across all steps.""" + return sum(step.output_tokens for step in self.steps) + + @property + def total_cache_creation_input_tokens(self) -> int: + """Total cache creation input tokens used across all steps.""" + return sum(step.cache_creation_input_tokens for step in self.steps) + + @property + def total_cache_read_input_tokens(self) -> int: + """Total cache read input tokens used across all steps.""" + return sum(step.cache_read_input_tokens for step in self.steps) + + @property + def total_input_tokens_all(self) -> int: + """Total input tokens including cache reads, cache creation, and regular input.""" + return (self.total_cache_read_input_tokens + + self.total_cache_creation_input_tokens + + self.total_input_tokens) + + @property + def total_tool_calls(self) -> int: + """Total tool calls across all steps.""" + return sum(step.num_tool_calls for step in self.steps) + + @property + def has_patch(self) -> bool: + """Whether the agent generated a non-empty patch.""" + return bool(self.generated_patch and self.generated_patch.strip()) + + @property + def num_steps(self) -> int: + """Number of steps in the trajectory.""" + return len(self.steps) + + def get_tool_calls(self) -> list[ToolCall]: + """Get all tool calls across all steps.""" + return [tc for step in self.steps for tc in step.tool_calls] + + def get_tool_counts(self) -> dict[str, int]: + """Count tool calls by tool name.""" + counts: dict[str, int] = {} + for tc in self.get_tool_calls(): + counts[tc.name] = counts.get(tc.name, 0) + 1 + return counts + + def get_shell_command_counts(self) -> dict[str, int]: + """Count shell commands by base command.""" + counts: dict[str, int] = {} + for tc in self.get_tool_calls(): + if tc.shell_command: + counts[tc.shell_command] = counts.get(tc.shell_command, 0) + 1 + return counts + + def get_tool_success_rate(self, tool_name: str | None = None) -> float: + """Get success rate for tool calls, optionally filtered by tool name.""" + tool_calls = self.get_tool_calls() + if tool_name: + tool_calls = [tc for tc in tool_calls if tc.name == tool_name] + + if not tool_calls: + return 0.0 + + return sum(1 for tc in tool_calls if tc.success) / len(tool_calls) + diff --git a/src/trajectory_analyzer/plotting/__init__.py b/src/trajectory_analyzer/plotting/__init__.py new file mode 100644 index 0000000..854a29d --- /dev/null +++ b/src/trajectory_analyzer/plotting/__init__.py @@ -0,0 +1,6 @@ +"""Plotting functions for trajectory analysis.""" + +from .plots import TrajectoryPlotter + +__all__ = ["TrajectoryPlotter"] + diff --git a/src/trajectory_analyzer/plotting/plots.py b/src/trajectory_analyzer/plotting/plots.py new file mode 100644 index 0000000..a806419 --- /dev/null +++ b/src/trajectory_analyzer/plotting/plots.py @@ -0,0 +1,1464 @@ +"""Plotting functions for trajectory analysis visualization.""" + +import logging +from pathlib import Path +from typing import Any + +import matplotlib.pyplot as plt +import numpy as np +from matplotlib.patches import Patch + +from ..models import Run +from ..analysis import MetricsExtractor, RunMetrics, RunComparator +from ..analysis.transfer import ( + TransferAnalyzer, + DeepTransferAnalysis, + extract_error_pattern, + extract_raw_error_prefix, + format_tool_call_signature, +) + +logger = logging.getLogger(__name__) + + +class TrajectoryPlotter: + """Generate plots for trajectory analysis.""" + + def __init__(self, output_dir: Path | str = "plots"): + self.output_dir = Path(output_dir) + self.output_dir.mkdir(parents=True, exist_ok=True) + self.metrics_extractor = MetricsExtractor() + self.comparator = RunComparator() + + def plot_all( + self, + runs: list[Run], + plots: list[str] | None = None, + model_to_trained_scaffold: dict[str, str] | None = None, + ) -> list[Path]: + """Generate all requested plots. + + Args: + runs: List of runs to analyze + plots: List of plot types to generate. If None, generate all. + model_to_trained_scaffold: Mapping of model names to their training scaffold + (needed for transfer_* plots) + + Returns: + List of generated plot file paths + """ + all_plots = [ + 'tool_distribution', + 'shell_command_distribution', + 'success_rates', + 'token_analysis', + 'error_patterns', + 'failed_tool_calls', + 'error_analysis', # comprehensive error analysis + 'comparison', + 'transfer_analysis', # high-level transfer summary + 'transfer_mcnemar', # instance-level transfer (McNemar) + 'transfer_error_modes', # error mode comparison + 'transfer_vocabulary', # tool vocabulary alignment + 'transfer_error_patterns', # error pattern deltas + ] + + if plots is None: + plots = all_plots + + generated: list[Path] = [] + + for run in runs: + if 'tool_distribution' in plots: + path = self.plot_tool_distribution(run) + if path: + generated.append(path) + + if 'shell_command_distribution' in plots: + path = self.plot_shell_command_distribution(run) + if path: + generated.append(path) + + if 'success_rates' in plots: + path = self.plot_success_rates(run) + if path: + generated.append(path) + + if 'token_analysis' in plots: + path = self.plot_token_analysis(run) + if path: + generated.append(path) + + if 'error_patterns' in plots: + path = self.plot_error_patterns(run) + if path: + generated.append(path) + + if 'failed_tool_calls' in plots: + path = self.plot_failed_tool_calls(run) + if path: + generated.append(path) + + if 'error_analysis' in plots: + path = self.plot_error_analysis(run) + if path: + generated.append(path) + + if len(runs) > 1: + if 'comparison' in plots: + path = self.plot_comparison(runs) + if path: + generated.append(path) + + if 'transfer_analysis' in plots: + path = self.plot_transfer_analysis(runs, model_to_trained_scaffold) + if path: + generated.append(path) + + # Transfer sub-plots (per transfer pair) + if 'transfer_mcnemar' in plots: + generated.extend( + self.plot_transfer_mcnemar_all(runs, model_to_trained_scaffold) + ) + if 'transfer_error_modes' in plots: + generated.extend( + self.plot_transfer_error_modes_all(runs, model_to_trained_scaffold) + ) + if 'transfer_vocabulary' in plots: + generated.extend( + self.plot_transfer_vocabulary_all(runs, model_to_trained_scaffold) + ) + if 'transfer_error_patterns' in plots: + generated.extend( + self.plot_transfer_error_patterns_all(runs, model_to_trained_scaffold) + ) + + return generated + + def plot_tool_distribution(self, run: Run) -> Path | None: + """Plot distribution of tools used in a run.""" + tool_counts = run.get_total_tool_counts() + if not tool_counts: + logger.warning(f"No tool data found for {run.name}") + return None + + # Sort by count + sorted_tools = sorted(tool_counts.items(), key=lambda x: x[1], reverse=True) + tools, counts = zip(*sorted_tools) + + plt.figure(figsize=(12, 6)) + bars = plt.bar(range(len(tools)), counts, color='steelblue', alpha=0.7) + plt.xlabel('Tool', fontsize=12) + plt.ylabel('Total Count', fontsize=12) + plt.title(f'Tool Distribution - {run.name}', fontsize=14, fontweight='bold') + plt.xticks(range(len(tools)), tools, rotation=45, ha='right') + plt.grid(axis='y', alpha=0.3) + + # Add value labels on bars + for bar in bars: + height = bar.get_height() + plt.text(bar.get_x() + bar.get_width()/2., height, + f'{int(height)}', ha='center', va='bottom', fontsize=9) + + plt.tight_layout() + output_path = self.output_dir / f'{self._safe_name(run.name)}_tool_distribution.png' + plt.savefig(output_path, dpi=300, bbox_inches='tight') + plt.close() + logger.info(f"Saved tool distribution plot to {output_path}") + return output_path + + def plot_shell_command_distribution(self, run: Run) -> Path | None: + """Plot distribution of shell commands used.""" + shell_counts = run.get_total_shell_command_counts() + if not shell_counts: + logger.warning(f"No shell command data found for {run.name}") + return None + + # Sort by count and take top 20 + sorted_cmds = sorted(shell_counts.items(), key=lambda x: x[1], reverse=True)[:20] + commands, counts = zip(*sorted_cmds) + + plt.figure(figsize=(14, 7)) + bars = plt.bar(range(len(commands)), counts, color='coral', alpha=0.7) + plt.xlabel('Shell Command', fontsize=12) + plt.ylabel('Total Count', fontsize=12) + plt.title(f'Shell Command Distribution - {run.name}', fontsize=14, fontweight='bold') + plt.xticks(range(len(commands)), commands, rotation=45, ha='right') + plt.grid(axis='y', alpha=0.3) + + for bar in bars: + height = bar.get_height() + plt.text(bar.get_x() + bar.get_width()/2., height, + f'{int(height)}', ha='center', va='bottom', fontsize=9) + + plt.tight_layout() + output_path = self.output_dir / f'{self._safe_name(run.name)}_shell_command_distribution.png' + plt.savefig(output_path, dpi=300, bbox_inches='tight') + plt.close() + logger.info(f"Saved shell command distribution plot to {output_path}") + return output_path + + def plot_success_rates(self, run: Run) -> Path | None: + """Plot success rates and metrics for a run.""" + metrics = self.metrics_extractor.extract_run_metrics(run) + + fig, axes = plt.subplots(2, 2, figsize=(14, 10)) + fig.suptitle(f'Success Rates and Metrics - {run.name}', fontsize=16, fontweight='bold') + + # 1. Resolution rate pie chart + resolved = metrics.resolved_instances + unresolved = metrics.total_instances - resolved + + if metrics.total_instances > 0: + axes[0, 0].pie( + [resolved, unresolved], + labels=[f'Resolved\n({resolved})', f'Unresolved\n({unresolved})'], + autopct='%1.1f%%', + startangle=90, + colors=['#2ecc71', '#e74c3c'] + ) + axes[0, 0].set_title('Resolution Rate') + + # 2. Tool success rates + if metrics.tool_success_rates: + sorted_rates = sorted(metrics.tool_success_rates.items(), key=lambda x: x[1], reverse=True) + tools, rates = zip(*sorted_rates[:10]) # Top 10 + + bars = axes[0, 1].barh(range(len(tools)), rates, color='#3498db', alpha=0.7) + axes[0, 1].set_yticks(range(len(tools))) + axes[0, 1].set_yticklabels(tools) + axes[0, 1].set_xlabel('Success Rate') + axes[0, 1].set_title('Tool Success Rates') + axes[0, 1].set_xlim(0, 1.1) + axes[0, 1].xaxis.set_major_formatter(plt.FuncFormatter(lambda y, _: f'{y:.0%}')) + axes[0, 1].grid(axis='x', alpha=0.3) + + # 3. Tool usage distribution + if metrics.tool_calls_per_traj: + axes[1, 0].hist(metrics.tool_calls_per_traj, bins=30, color='#f39c12', alpha=0.7, edgecolor='black') + axes[1, 0].axvline(metrics.avg_tool_calls, color='red', linestyle='--', + label=f'Mean: {metrics.avg_tool_calls:.1f}') + axes[1, 0].axvline(metrics.median_tool_calls, color='blue', linestyle='--', + label=f'Median: {metrics.median_tool_calls:.1f}') + axes[1, 0].set_xlabel('Total Tool Calls per Instance') + axes[1, 0].set_ylabel('Frequency') + axes[1, 0].set_title('Tool Usage Distribution') + axes[1, 0].legend() + axes[1, 0].grid(axis='y', alpha=0.3) + + # 4. Resolved vs unresolved comparison + if metrics.resolved_avg_tool_calls > 0 or metrics.unresolved_avg_tool_calls > 0: + categories = ['Resolved', 'Unresolved'] + tool_values = [metrics.resolved_avg_tool_calls, metrics.unresolved_avg_tool_calls] + colors = ['#2ecc71', '#e74c3c'] + + bars = axes[1, 1].bar(categories, tool_values, color=colors, alpha=0.7) + axes[1, 1].set_ylabel('Average Tool Calls') + axes[1, 1].set_title('Avg Tool Calls: Resolved vs Unresolved') + axes[1, 1].grid(axis='y', alpha=0.3) + + for bar in bars: + height = bar.get_height() + axes[1, 1].text(bar.get_x() + bar.get_width()/2., height, + f'{height:.1f}', ha='center', va='bottom') + + plt.tight_layout() + output_path = self.output_dir / f'{self._safe_name(run.name)}_success_rates.png' + plt.savefig(output_path, dpi=300, bbox_inches='tight') + plt.close() + logger.info(f"Saved success rates plot to {output_path}") + return output_path + + def plot_token_analysis(self, run: Run) -> Path | None: + """Plot token usage analysis.""" + metrics = self.metrics_extractor.extract_run_metrics(run) + + if not metrics.tokens_per_traj: + logger.warning(f"No token data found for {run.name}") + return None + + fig, axes = plt.subplots(2, 2, figsize=(14, 10)) + fig.suptitle(f'Token Usage Analysis - {run.name}', fontsize=14, fontweight='bold') + + # 1. Token usage by resolution status (stacked bar) + resolved_trajs = run.get_resolved_trajectories() + unresolved_trajs = run.get_unresolved_trajectories() + + if resolved_trajs or unresolved_trajs: + # Calculate average token breakdowns + # Input tokens breakdown: cache_read (bottom), cache_creation (middle), regular input (top) + resolved_cache_read = np.mean([t.total_cache_read_input_tokens for t in resolved_trajs]) if resolved_trajs else 0 + resolved_cache_creation = np.mean([t.total_cache_creation_input_tokens for t in resolved_trajs]) if resolved_trajs else 0 + resolved_input = np.mean([t.total_input_tokens for t in resolved_trajs]) if resolved_trajs else 0 + resolved_output = np.mean([t.total_output_tokens for t in resolved_trajs]) if resolved_trajs else 0 + + unresolved_cache_read = np.mean([t.total_cache_read_input_tokens for t in unresolved_trajs]) if unresolved_trajs else 0 + unresolved_cache_creation = np.mean([t.total_cache_creation_input_tokens for t in unresolved_trajs]) if unresolved_trajs else 0 + unresolved_input = np.mean([t.total_input_tokens for t in unresolved_trajs]) if unresolved_trajs else 0 + unresolved_output = np.mean([t.total_output_tokens for t in unresolved_trajs]) if unresolved_trajs else 0 + + categories = [] + cache_read_vals = [] + cache_creation_vals = [] + input_vals = [] + output_vals = [] + + if resolved_trajs: + categories.append(f'Resolved\n(n={len(resolved_trajs)})') + cache_read_vals.append(resolved_cache_read) + cache_creation_vals.append(resolved_cache_creation) + input_vals.append(resolved_input) + output_vals.append(resolved_output) + + if unresolved_trajs: + categories.append(f'Unresolved\n(n={len(unresolved_trajs)})') + cache_read_vals.append(unresolved_cache_read) + cache_creation_vals.append(unresolved_cache_creation) + input_vals.append(unresolved_input) + output_vals.append(unresolved_output) + + if categories: + x = np.arange(len(categories)) + width = 0.6 + + # Stack input tokens: cache_read (bottom), cache_creation (middle), regular input (top) + bottom = np.zeros(len(categories)) + if any(cache_read_vals): + axes[0, 0].bar(x, cache_read_vals, width, bottom=bottom, + label='Cache Read Input Tokens', color='#9b59b6', alpha=0.7) + bottom += np.array(cache_read_vals) + + if any(cache_creation_vals): + axes[0, 0].bar(x, cache_creation_vals, width, bottom=bottom, + label='Cache Creation Input Tokens', color='#f39c12', alpha=0.7) + bottom += np.array(cache_creation_vals) + + axes[0, 0].bar(x, input_vals, width, bottom=bottom, + label='Input Tokens (after cache)', color='#3498db', alpha=0.7) + bottom += np.array(input_vals) + + # Output tokens on top of all input + axes[0, 0].bar(x, output_vals, width, bottom=bottom, + label='Output Tokens', color='#e74c3c', alpha=0.7) + + axes[0, 0].set_xticks(x) + axes[0, 0].set_xticklabels(categories) + axes[0, 0].set_ylabel('Average Token Usage') + axes[0, 0].set_title('Average Token Usage by Resolution Status') + axes[0, 0].legend(fontsize=8) + axes[0, 0].grid(axis='y', alpha=0.3) + + # 2. Token usage distribution (boxplot with total tokens) + tokens_resolved = [t.total_tokens for t in resolved_trajs] + tokens_unresolved = [t.total_tokens for t in unresolved_trajs] + + if tokens_resolved or tokens_unresolved: + data = [] + labels = [] + if tokens_resolved: + data.append(tokens_resolved) + labels.append(f'Resolved\n(n={len(tokens_resolved)})') + if tokens_unresolved: + data.append(tokens_unresolved) + labels.append(f'Unresolved\n(n={len(tokens_unresolved)})') + + bp = axes[0, 1].boxplot(data, labels=labels, patch_artist=True) + if len(bp['boxes']) > 0: + bp['boxes'][0].set_facecolor('#2ecc71') + if len(bp['boxes']) > 1: + bp['boxes'][1].set_facecolor('#e74c3c') + axes[0, 1].set_ylabel('Total Token Usage') + axes[0, 1].set_title('Token Usage Distribution by Resolution Status') + axes[0, 1].grid(axis='y', alpha=0.3) + + # 3. Scatter: tokens vs tool usage + tokens = metrics.tokens_per_traj + tool_calls = metrics.tool_calls_per_traj + colors = ['#2ecc71' if t.resolved else '#e74c3c' for t in run.trajectories] + + axes[1, 0].scatter(tokens, tool_calls, c=colors, alpha=0.6, s=50) + axes[1, 0].set_xlabel('Token Usage') + axes[1, 0].set_ylabel('Tool Calls') + axes[1, 0].set_title('Token Usage vs Tool Calls') + axes[1, 0].grid(alpha=0.3) + + legend_elements = [ + Patch(facecolor='#2ecc71', label='Resolved'), + Patch(facecolor='#e74c3c', label='Unresolved') + ] + axes[1, 0].legend(handles=legend_elements) + + # 4. Token type breakdown (stacked bar for all trajectories) + all_cache_read = [t.total_cache_read_input_tokens for t in run.trajectories] + all_cache_creation = [t.total_cache_creation_input_tokens for t in run.trajectories] + all_input = [t.total_input_tokens for t in run.trajectories] + all_output = [t.total_output_tokens for t in run.trajectories] + + avg_cache_read = np.mean(all_cache_read) if all_cache_read else 0 + avg_cache_creation = np.mean(all_cache_creation) if all_cache_creation else 0 + avg_input = np.mean(all_input) if all_input else 0 + avg_output = np.mean(all_output) if all_output else 0 + + # Create a single stacked bar + x_pos = 0 + width = 0.6 + bottom = 0 + + if avg_cache_read > 0: + axes[1, 1].bar(x_pos, avg_cache_read, width, bottom=bottom, + label='Cache Read Input Tokens', color='#9b59b6', alpha=0.7) + bottom += avg_cache_read + + if avg_cache_creation > 0: + axes[1, 1].bar(x_pos, avg_cache_creation, width, bottom=bottom, + label='Cache Creation Input Tokens', color='#f39c12', alpha=0.7) + bottom += avg_cache_creation + + if avg_input > 0: + axes[1, 1].bar(x_pos, avg_input, width, bottom=bottom, + label='Input Tokens (after cache)', color='#3498db', alpha=0.7) + bottom += avg_input + + if avg_output > 0: + axes[1, 1].bar(x_pos, avg_output, width, bottom=bottom, + label='Output Tokens', color='#e74c3c', alpha=0.7) + bottom += avg_output + + axes[1, 1].set_ylabel('Average Token Usage') + axes[1, 1].set_title('Average Token Type Breakdown') + axes[1, 1].set_xticks([]) + axes[1, 1].legend(fontsize=8) + axes[1, 1].grid(axis='y', alpha=0.3) + + # Add total value label + total = bottom + if total > 0: + axes[1, 1].text(x_pos, total + max([avg_cache_read, avg_cache_creation, avg_input, avg_output]) * 0.02, + f'Total: {int(total):,}', ha='center', va='bottom', fontsize=10, fontweight='bold') + + plt.tight_layout() + output_path = self.output_dir / f'{self._safe_name(run.name)}_token_analysis.png' + plt.savefig(output_path, dpi=300, bbox_inches='tight') + plt.close() + logger.info(f"Saved token analysis plot to {output_path}") + return output_path + + def plot_error_patterns( + self, + run: Run, + top_n: int = 20, + mode: str = "raw" + ) -> Path | None: + """Plot top tool execution error patterns for a run. + + Args: + run: Run to analyze + top_n: Number of top error patterns to show + mode: "categorized" for predefined patterns, "raw" for first 5 words + + Returns: + Path to generated plot or None + """ + # Collect error patterns from failed tool calls + error_patterns: dict[str, int] = {} + tool_error_patterns: dict[str, dict[str, int]] = {} + + for traj in run.trajectories: + for tc in traj.get_tool_calls(): + if not tc.success and tc.result: + pattern = extract_error_pattern(tc.result, mode=mode) + error_patterns[pattern] = error_patterns.get(pattern, 0) + 1 + + if tc.name not in tool_error_patterns: + tool_error_patterns[tc.name] = {} + tool_error_patterns[tc.name][pattern] = tool_error_patterns[tc.name].get(pattern, 0) + 1 + + if not error_patterns: + logger.warning(f"No error patterns found for {run.name}") + return None + + # Sort and get top N + sorted_patterns = sorted(error_patterns.items(), key=lambda x: x[1], reverse=True)[:top_n] + patterns, counts = zip(*sorted_patterns) + + fig, axes = plt.subplots(1, 2, figsize=(18, max(8, len(patterns) * 0.4))) + mode_label = "Raw Error Messages" if mode == "raw" else "Categorized Patterns" + fig.suptitle(f'Tool Execution Errors - {run.name}\n({mode_label})', fontsize=14, fontweight='bold') + + # 1. Top error patterns bar chart + y_pos = np.arange(len(patterns)) + bars = axes[0].barh(y_pos, counts, color='#e74c3c', alpha=0.7) + axes[0].set_yticks(y_pos) + # For raw mode, show actual text; for categorized, title-case + if mode == "raw": + axes[0].set_yticklabels(patterns, fontsize=8) + else: + axes[0].set_yticklabels([p.replace('_', ' ').title() for p in patterns]) + axes[0].invert_yaxis() # Top pattern at top + axes[0].set_xlabel('Frequency') + axes[0].set_title(f'Top {len(patterns)} Error Patterns') + axes[0].grid(axis='x', alpha=0.3) + + # Add count labels + for bar, count in zip(bars, counts): + axes[0].text(bar.get_width() + max(counts)*0.01, bar.get_y() + bar.get_height()/2, + str(count), va='center', fontsize=9) + + # 2. Error patterns by tool (stacked or grouped) + # Get top tools by error count + tool_totals = {tool: sum(patterns.values()) for tool, patterns in tool_error_patterns.items()} + top_tools = sorted(tool_totals.items(), key=lambda x: x[1], reverse=True)[:6] + + if top_tools: + # Get top 5 patterns for these tools + top_5_patterns = [p for p, _ in sorted_patterns[:5]] + + x = np.arange(len(top_tools)) + width = 0.15 + colors = plt.cm.Set2(np.linspace(0, 1, len(top_5_patterns))) + + for i, pattern in enumerate(top_5_patterns): + tool_counts = [tool_error_patterns.get(tool, {}).get(pattern, 0) for tool, _ in top_tools] + axes[1].bar(x + i*width, tool_counts, width, label=pattern.replace('_', ' '), color=colors[i], alpha=0.8) + + axes[1].set_xticks(x + width * 2) + axes[1].set_xticklabels([tool for tool, _ in top_tools], rotation=45, ha='right') + axes[1].set_ylabel('Error Count') + axes[1].set_title('Top Error Patterns by Tool') + axes[1].legend(loc='upper right', fontsize=8) + axes[1].grid(axis='y', alpha=0.3) + + plt.tight_layout() + output_path = self.output_dir / f'{self._safe_name(run.name)}_error_patterns.png' + plt.savefig(output_path, dpi=300, bbox_inches='tight') + plt.close() + logger.info(f"Saved error patterns plot to {output_path}") + return output_path + + def plot_failed_tool_calls( + self, + run: Run, + top_n: int = 25, + ) -> Path | None: + """Plot the most common failing tool calls with their arguments. + + Args: + run: Run to analyze + top_n: Number of top failing calls to show + + Returns: + Path to generated plot or None + """ + # Collect failed tool calls with their signatures + failed_calls: dict[str, int] = {} + failed_calls_with_error: dict[str, list[str]] = {} # signature -> sample errors + + for traj in run.trajectories: + for tc in traj.get_tool_calls(): + if not tc.success: + signature = format_tool_call_signature(tc.name, tc.arguments) + failed_calls[signature] = failed_calls.get(signature, 0) + 1 + + # Store sample errors for this signature + if signature not in failed_calls_with_error: + failed_calls_with_error[signature] = [] + if len(failed_calls_with_error[signature]) < 3 and tc.result: + error_preview = extract_raw_error_prefix(tc.result, num_words=8) + failed_calls_with_error[signature].append(error_preview) + + if not failed_calls: + logger.warning(f"No failed tool calls found for {run.name}") + return None + + # Sort and get top N + sorted_calls = sorted(failed_calls.items(), key=lambda x: x[1], reverse=True)[:top_n] + signatures, counts = zip(*sorted_calls) + + # Create figure + fig, ax = plt.subplots(figsize=(16, max(10, len(signatures) * 0.5))) + fig.suptitle( + f'Most Common Failing Tool Calls - {run.name}\n(with arguments)', + fontsize=14, fontweight='bold' + ) + + # Horizontal bar chart + y_pos = np.arange(len(signatures)) + bars = ax.barh(y_pos, counts, color='#e74c3c', alpha=0.7) + ax.set_yticks(y_pos) + ax.set_yticklabels(signatures, fontsize=8, fontfamily='monospace') + ax.invert_yaxis() + ax.set_xlabel('Failure Count') + ax.set_title(f'Top {len(signatures)} Failing Tool Calls') + ax.grid(axis='x', alpha=0.3) + + # Add count labels + max_count = max(counts) + for bar, count in zip(bars, counts): + ax.text(bar.get_width() + max_count * 0.01, bar.get_y() + bar.get_height()/2, + str(count), va='center', fontsize=9) + + plt.tight_layout() + output_path = self.output_dir / f'{self._safe_name(run.name)}_failed_tool_calls.png' + plt.savefig(output_path, dpi=300, bbox_inches='tight') + plt.close() + logger.info(f"Saved failed tool calls plot to {output_path}") + return output_path + + def plot_error_analysis(self, run: Run) -> Path | None: + """Comprehensive error analysis showing main reasons for tool call errors. + + Args: + run: Run to analyze + + Returns: + Path to generated plot or None + """ + from collections import defaultdict + + # Collect error data + error_categories: dict[str, int] = defaultdict(int) + tool_error_counts: dict[str, int] = defaultdict(int) + tool_total_counts: dict[str, int] = defaultdict(int) + error_samples: dict[str, list[tuple[str, str]]] = defaultdict(list) # category -> [(tool, error_msg)] + tool_error_patterns: dict[str, dict[str, int]] = defaultdict(lambda: defaultdict(int)) + + for traj in run.trajectories: + for tc in traj.get_tool_calls(): + tool_total_counts[tc.name] += 1 + + if not tc.success and tc.result: + # Categorize error + category = extract_error_pattern(tc.result, mode="categorized") + error_categories[category] += 1 + tool_error_counts[tc.name] += 1 + + # Store sample errors (up to 3 per category) + if len(error_samples[category]) < 3: + error_preview = (tc.result or "")[:150] + error_samples[category].append((tc.name, error_preview)) + + # Track error patterns by tool + pattern = extract_error_pattern(tc.result, mode="categorized") + tool_error_patterns[tc.name][pattern] += 1 + + if not error_categories: + logger.warning(f"No errors found for {run.name}") + return None + + # Calculate error rates + tool_error_rates = { + tool: tool_error_counts[tool] / tool_total_counts[tool] + for tool in tool_total_counts + if tool_total_counts[tool] > 0 + } + + # Sort data + sorted_categories = sorted(error_categories.items(), key=lambda x: x[1], reverse=True) + sorted_tools_by_errors = sorted(tool_error_counts.items(), key=lambda x: x[1], reverse=True) + sorted_tools_by_rate = sorted(tool_error_rates.items(), key=lambda x: x[1], reverse=True) + + # Create figure with 2x2 subplots + fig, axes = plt.subplots(2, 2, figsize=(16, 12)) + fig.suptitle(f'Comprehensive Error Analysis - {run.name}', fontsize=16, fontweight='bold') + + # 1. Top error categories (pie chart + bar chart) + top_categories = sorted_categories[:10] + if top_categories: + categories, counts = zip(*top_categories) + + # Pie chart + colors = plt.cm.Set3(np.linspace(0, 1, len(categories))) + wedges, texts, autotexts = axes[0, 0].pie( + counts, labels=categories, autopct='%1.1f%%', + startangle=90, colors=colors, textprops={'fontsize': 8} + ) + axes[0, 0].set_title('Error Categories Distribution', fontweight='bold') + + # Bar chart with counts + y_pos = np.arange(len(categories)) + bars = axes[0, 1].barh(y_pos, counts, color=colors, alpha=0.7) + axes[0, 1].set_yticks(y_pos) + axes[0, 1].set_yticklabels([c.replace('_', ' ').title() for c in categories], fontsize=9) + axes[0, 1].invert_yaxis() + axes[0, 1].set_xlabel('Error Count') + axes[0, 1].set_title('Top Error Categories (Count)', fontweight='bold') + axes[0, 1].grid(axis='x', alpha=0.3) + + # Add count labels + for bar, count in zip(bars, counts): + axes[0, 1].text(bar.get_width() + max(counts)*0.01, bar.get_y() + bar.get_height()/2, + str(count), va='center', fontsize=9) + + # 2. Error-prone tools (by count and rate) + top_tools_by_count = sorted_tools_by_errors[:10] + top_tools_by_rate = [t for t in sorted_tools_by_rate if t[1] > 0][:10] + + if top_tools_by_count: + tools, error_counts = zip(*top_tools_by_count) + x = np.arange(len(tools)) + width = 0.35 + + bars = axes[1, 0].bar(x, error_counts, width, color='#e74c3c', alpha=0.7, label='Error Count') + axes[1, 0].set_xticks(x) + axes[1, 0].set_xticklabels(tools, rotation=45, ha='right', fontsize=9) + axes[1, 0].set_ylabel('Error Count') + axes[1, 0].set_title('Most Error-Prone Tools (by Count)', fontweight='bold') + axes[1, 0].grid(axis='y', alpha=0.3) + + # Add count labels + for bar, count in zip(bars, error_counts): + axes[1, 0].text(bar.get_x() + bar.get_width()/2., bar.get_height(), + str(count), ha='center', va='bottom', fontsize=8) + + if top_tools_by_rate: + tools_rate, rates = zip(*top_tools_by_rate) + x = np.arange(len(tools_rate)) + + bars = axes[1, 1].barh(x, rates, color='#c0392b', alpha=0.7) + axes[1, 1].set_yticks(x) + axes[1, 1].set_yticklabels(tools_rate, fontsize=9) + axes[1, 1].invert_yaxis() + axes[1, 1].set_xlabel('Error Rate') + axes[1, 1].set_title('Tools with Highest Error Rates', fontweight='bold') + axes[1, 1].set_xlim(0, 1.1) + axes[1, 1].xaxis.set_major_formatter(plt.FuncFormatter(lambda y, _: f'{y:.0%}')) + axes[1, 1].grid(axis='x', alpha=0.3) + + # Add rate labels + for bar, rate in zip(bars, rates): + axes[1, 1].text(bar.get_width() + 0.02, bar.get_y() + bar.get_height()/2, + f'{rate:.1%}', va='center', fontsize=9) + + plt.tight_layout() + output_path = self.output_dir / f'{self._safe_name(run.name)}_error_analysis.png' + plt.savefig(output_path, dpi=300, bbox_inches='tight') + plt.close() + logger.info(f"Saved error analysis plot to {output_path}") + return output_path + + def plot_comparison(self, runs: list[Run]) -> Path | None: + """Plot comparison across multiple runs.""" + if len(runs) < 2: + logger.warning("Need at least 2 runs for comparison") + return None + + metrics_dict = self.comparator.compare_runs(runs) + run_names = list(metrics_dict.keys()) + + fig, axes = plt.subplots(2, 2, figsize=(16, 12)) + fig.suptitle('Comparison Across Runs', fontsize=16, fontweight='bold') + + # 1. Resolution rate comparison + resolve_rates = [metrics_dict[name].resolve_rate for name in run_names] + + bars = axes[0, 0].bar(range(len(run_names)), resolve_rates, color='steelblue', alpha=0.7) + axes[0, 0].set_ylabel('Resolution Rate') + axes[0, 0].set_title('Resolution Rate Comparison') + axes[0, 0].set_ylim(0, 1.1) + axes[0, 0].yaxis.set_major_formatter(plt.FuncFormatter(lambda y, _: f'{y:.0%}')) + axes[0, 0].set_xticks(range(len(run_names))) + axes[0, 0].set_xticklabels(run_names, rotation=45, ha='right') + axes[0, 0].grid(axis='y', alpha=0.3) + + for i, (bar, rate) in enumerate(zip(bars, resolve_rates)): + axes[0, 0].text(bar.get_x() + bar.get_width()/2., rate, + f'{rate:.1%}', ha='center', va='bottom') + + # 2. Average tool usage comparison + avg_tool_calls = [metrics_dict[name].avg_tool_calls for name in run_names] + + bars = axes[0, 1].bar(range(len(run_names)), avg_tool_calls, color='orange', alpha=0.7) + axes[0, 1].set_ylabel('Average Tool Calls') + axes[0, 1].set_title('Average Tool Usage Comparison') + axes[0, 1].set_xticks(range(len(run_names))) + axes[0, 1].set_xticklabels(run_names, rotation=45, ha='right') + axes[0, 1].grid(axis='y', alpha=0.3) + + for bar, avg in zip(bars, avg_tool_calls): + axes[0, 1].text(bar.get_x() + bar.get_width()/2., avg, + f'{avg:.1f}', ha='center', va='bottom') + + # 3. Average tokens comparison (stacked by type) + # Calculate token breakdowns for each run + run_cache_read = [] + run_cache_creation = [] + run_input_tokens = [] + run_output_tokens = [] + + for name in run_names: + run = next(r for r in runs if r.name == name) + cache_read_avg = np.mean([t.total_cache_read_input_tokens for t in run.trajectories]) if run.trajectories else 0 + cache_creation_avg = np.mean([t.total_cache_creation_input_tokens for t in run.trajectories]) if run.trajectories else 0 + input_avg = np.mean([t.total_input_tokens for t in run.trajectories]) if run.trajectories else 0 + output_avg = np.mean([t.total_output_tokens for t in run.trajectories]) if run.trajectories else 0 + + run_cache_read.append(cache_read_avg) + run_cache_creation.append(cache_creation_avg) + run_input_tokens.append(input_avg) + run_output_tokens.append(output_avg) + + x = np.arange(len(run_names)) + width = 0.6 + + # Stack input tokens: cache_read (bottom), cache_creation (middle), regular input (top) + bottom = np.zeros(len(run_names)) + if any(run_cache_read): + axes[1, 0].bar(x, run_cache_read, width, bottom=bottom, + label='Cache Read Input Tokens', color='#9b59b6', alpha=0.7) + bottom += np.array(run_cache_read) + + if any(run_cache_creation): + axes[1, 0].bar(x, run_cache_creation, width, bottom=bottom, + label='Cache Creation Input Tokens', color='#f39c12', alpha=0.7) + bottom += np.array(run_cache_creation) + + axes[1, 0].bar(x, run_input_tokens, width, bottom=bottom, + label='Input Tokens (after cache)', color='#3498db', alpha=0.7) + bottom += np.array(run_input_tokens) + + # Output tokens on top of all input + axes[1, 0].bar(x, run_output_tokens, width, bottom=bottom, + label='Output Tokens', color='#e74c3c', alpha=0.7) + + axes[1, 0].set_ylabel('Average Tokens') + axes[1, 0].set_title('Average Token Usage Comparison (by Type)') + axes[1, 0].set_xticks(x) + axes[1, 0].set_xticklabels(run_names, rotation=45, ha='right') + axes[1, 0].legend(fontsize=8) + axes[1, 0].grid(axis='y', alpha=0.3) + + # Add total value labels on top of stacked bars + avg_tokens = [metrics_dict[name].avg_tokens for name in run_names] + for i, (x_pos, total) in enumerate(zip(x, avg_tokens)): + axes[1, 0].text(x_pos, total + max(avg_tokens) * 0.02, + f'{total:.0f}', ha='center', va='bottom', fontsize=9) + + # 4. Scaffold comparison (group by scaffold) + scaffold_metrics: dict[str, list[float]] = {} + for name in run_names: + scaffold = metrics_dict[name].scaffold + if scaffold not in scaffold_metrics: + scaffold_metrics[scaffold] = [] + scaffold_metrics[scaffold].append(metrics_dict[name].resolve_rate) + + scaffolds = list(scaffold_metrics.keys()) + avg_by_scaffold = [np.mean(scaffold_metrics[s]) for s in scaffolds] + + bars = axes[1, 1].bar(scaffolds, avg_by_scaffold, color='green', alpha=0.7) + axes[1, 1].set_ylabel('Average Resolution Rate') + axes[1, 1].set_title('Resolution Rate by Scaffold') + axes[1, 1].set_ylim(0, 1.1) + axes[1, 1].yaxis.set_major_formatter(plt.FuncFormatter(lambda y, _: f'{y:.0%}')) + axes[1, 1].grid(axis='y', alpha=0.3) + + for bar, avg in zip(bars, avg_by_scaffold): + axes[1, 1].text(bar.get_x() + bar.get_width()/2., avg, + f'{avg:.1%}', ha='center', va='bottom') + + plt.tight_layout() + output_path = self.output_dir / 'comparison_across_runs.png' + plt.savefig(output_path, dpi=300, bbox_inches='tight') + plt.close() + logger.info(f"Saved comparison plot to {output_path}") + return output_path + + def plot_transfer_analysis( + self, + runs: list[Run], + model_to_trained_scaffold: dict[str, str] | None = None, + ) -> Path | None: + """Plot transfer learning analysis. + + Args: + runs: List of runs to analyze + model_to_trained_scaffold: Mapping of models to their training scaffold + """ + if model_to_trained_scaffold is None: + # Default known mappings + model_to_trained_scaffold = { + "agentica-org/DeepSWE-Preview": "r2e-gym", + "mistralai/devstral-2512:free": "mistral-vibe-cli", + "anthropic/claude-3-5-haiku-20241022": "claude-code", + } + + analyses = self.comparator.find_transfer_pairs(runs, model_to_trained_scaffold) + + if not analyses: + logger.warning("No transfer pairs found") + return None + + fig, axes = plt.subplots(1, 2, figsize=(14, 6)) + fig.suptitle('Transfer Learning Analysis', fontsize=16, fontweight='bold') + + # 1. Transfer delta by model/scaffold + labels = [f"{a.base_model.split('/')[-1]}\n{a.source_scaffold}→{a.target_scaffold}" + for a in analyses] + deltas = [a.transfer_delta for a in analyses] + colors = ['#2ecc71' if d >= 0 else '#e74c3c' for d in deltas] + + bars = axes[0].barh(range(len(labels)), deltas, color=colors, alpha=0.7) + axes[0].set_yticks(range(len(labels))) + axes[0].set_yticklabels(labels) + axes[0].set_xlabel('Resolution Rate Delta') + axes[0].set_title('Transfer Learning Impact') + axes[0].axvline(0, color='black', linestyle='-', linewidth=0.5) + axes[0].xaxis.set_major_formatter(plt.FuncFormatter(lambda y, _: f'{y:+.1%}')) + axes[0].grid(axis='x', alpha=0.3) + + # 2. Source vs target performance + source_rates = [a.source_resolve_rate for a in analyses] + target_rates = [a.target_resolve_rate for a in analyses] + + x = np.arange(len(analyses)) + width = 0.35 + + bars1 = axes[1].bar(x - width/2, source_rates, width, label='Source Scaffold', color='#3498db', alpha=0.7) + bars2 = axes[1].bar(x + width/2, target_rates, width, label='Target Scaffold', color='#9b59b6', alpha=0.7) + + axes[1].set_ylabel('Resolution Rate') + axes[1].set_title('Source vs Target Performance') + axes[1].set_xticks(x) + axes[1].set_xticklabels([a.base_model.split('/')[-1] for a in analyses], rotation=45, ha='right') + axes[1].set_ylim(0, 1.1) + axes[1].yaxis.set_major_formatter(plt.FuncFormatter(lambda y, _: f'{y:.0%}')) + axes[1].legend() + axes[1].grid(axis='y', alpha=0.3) + + plt.tight_layout() + output_path = self.output_dir / 'transfer_analysis.png' + plt.savefig(output_path, dpi=300, bbox_inches='tight') + plt.close() + logger.info(f"Saved transfer analysis plot to {output_path}") + return output_path + + def _safe_name(self, name: str) -> str: + """Convert run name to safe filename.""" + return name.replace('/', '_').replace(' ', '_').replace(':', '_') + + def _generate_transfer_analyses( + self, + runs: list[Run], + model_to_trained_scaffold: dict[str, str] | None = None, + ) -> list[DeepTransferAnalysis]: + """Compute deep transfer analyses for all source→target pairs.""" + if model_to_trained_scaffold is None: + model_to_trained_scaffold = { + "agentica-org/DeepSWE-Preview": "r2e-gym", + "mistralai/devstral-2512:free": "mistral-vibe-cli", + "anthropic/claude-3-5-haiku-20241022": "claude-code", + } + + from collections import defaultdict + + runs_by_model: dict[str, list[Run]] = defaultdict(list) + for run in runs: + runs_by_model[run.base_model].append(run) + + analyzer = TransferAnalyzer() + analyses: list[DeepTransferAnalysis] = [] + + for model, model_runs in runs_by_model.items(): + trained_scaffold = model_to_trained_scaffold.get(model) + if not trained_scaffold: + continue + + source_runs = [r for r in model_runs if r.scaffold == trained_scaffold] + if not source_runs: + continue + + source_run = source_runs[0] + + for target_run in model_runs: + if target_run.scaffold == trained_scaffold: + continue + + logger.info( + f"Generating deep transfer analysis: {source_run.name} -> {target_run.name}" + ) + analyses.append(analyzer.analyze_transfer(source_run, target_run)) + + return analyses + + def plot_transfer_mcnemar_all( + self, + runs: list[Run], + model_to_trained_scaffold: dict[str, str] | None = None, + ) -> list[Path]: + """Generate McNemar transfer plots for all transfer pairs.""" + generated: list[Path] = [] + for analysis in self._generate_transfer_analyses(runs, model_to_trained_scaffold): + path = self._plot_mcnemar(analysis) + if path: + generated.append(path) + return generated + + def plot_transfer_error_modes_all( + self, + runs: list[Run], + model_to_trained_scaffold: dict[str, str] | None = None, + ) -> list[Path]: + """Generate transfer error-mode plots for all transfer pairs.""" + generated: list[Path] = [] + for analysis in self._generate_transfer_analyses(runs, model_to_trained_scaffold): + path = self._plot_error_modes(analysis) + if path: + generated.append(path) + return generated + + def plot_transfer_vocabulary_all( + self, + runs: list[Run], + model_to_trained_scaffold: dict[str, str] | None = None, + ) -> list[Path]: + """Generate transfer vocabulary plots for all transfer pairs.""" + generated: list[Path] = [] + for analysis in self._generate_transfer_analyses(runs, model_to_trained_scaffold): + path = self._plot_vocabulary(analysis) + if path: + generated.append(path) + return generated + + def plot_transfer_error_patterns_all( + self, + runs: list[Run], + model_to_trained_scaffold: dict[str, str] | None = None, + ) -> list[Path]: + """Generate transfer error-pattern plots for all transfer pairs.""" + generated: list[Path] = [] + for analysis in self._generate_transfer_analyses(runs, model_to_trained_scaffold): + path = self._plot_error_patterns_comparison(analysis) + if path: + generated.append(path) + return generated + + def _plot_mcnemar(self, analysis: DeepTransferAnalysis) -> Path | None: + """Plot McNemar's test results with contingency table.""" + mcnemar = analysis.mcnemar + + fig, axes = plt.subplots(1, 3, figsize=(16, 5)) + fig.suptitle( + f'Instance-Level Transfer Analysis: {analysis.source_scaffold} → {analysis.target_scaffold}\n' + f'Model: {analysis.base_model}', + fontsize=14, fontweight='bold' + ) + + # 1. Contingency table heatmap + contingency = np.array([ + [mcnemar.both_success, mcnemar.target_only], + [mcnemar.source_only, mcnemar.both_failure] + ]) + + im = axes[0].imshow(contingency, cmap='Blues', aspect='auto') + + # Add text annotations + for i in range(2): + for j in range(2): + val = contingency[i, j] + pct = val / mcnemar.total_instances * 100 if mcnemar.total_instances > 0 else 0 + axes[0].text(j, i, f'{val}\n({pct:.1f}%)', ha='center', va='center', + fontsize=12, fontweight='bold') + + axes[0].set_xticks([0, 1]) + axes[0].set_yticks([0, 1]) + axes[0].set_xticklabels(['Target ✓', 'Target ✗']) + axes[0].set_yticklabels(['Source ✓', 'Source ✗']) + axes[0].set_xlabel('Target Scaffold') + axes[0].set_ylabel('Source Scaffold') + axes[0].set_title('Contingency Table') + + # Add colorbar + plt.colorbar(im, ax=axes[0], label='Count') + + # 2. Transfer outcome breakdown (pie chart) + labels = ['Both Success', 'Transfer Loss\n(Source only)', + 'Transfer Gain\n(Target only)', 'Both Failure'] + sizes = [mcnemar.both_success, mcnemar.source_only, + mcnemar.target_only, mcnemar.both_failure] + colors = ['#2ecc71', '#e74c3c', '#3498db', '#95a5a6'] + explode = (0, 0.05, 0.05, 0) # Highlight discordant pairs + + # Filter out zero values for cleaner pie + non_zero = [(l, s, c, e) for l, s, c, e in zip(labels, sizes, colors, explode) if s > 0] + if non_zero: + labels, sizes, colors, explode = zip(*non_zero) + axes[1].pie(sizes, explode=explode, labels=labels, colors=colors, + autopct='%1.1f%%', startangle=90) + axes[1].set_title('Transfer Outcome Distribution') + + # 3. Statistical summary + axes[2].axis('off') + + # Build summary text + sig_text = "Yes (p < 0.05)" if mcnemar.is_significant else "No (p ≥ 0.05)" + direction = mcnemar.transfer_direction.capitalize() + + summary_text = f""" + McNemar's Test Results + ══════════════════════════════ + + Total Paired Instances: {mcnemar.total_instances} + + Source Resolution Rate: {mcnemar.source_resolve_rate:.1%} + Target Resolution Rate: {mcnemar.target_resolve_rate:.1%} + + Discordant Pairs: + • Transfer Loss (source→fail): {mcnemar.source_only} + • Transfer Gain (fail→target): {mcnemar.target_only} + + Chi-squared Statistic: {mcnemar.chi_squared:.3f} + P-value: {mcnemar.p_value:.4f} + + Statistically Significant: {sig_text} + Transfer Direction: {direction} + """ + + axes[2].text(0.1, 0.5, summary_text, transform=axes[2].transAxes, + fontsize=11, verticalalignment='center', fontfamily='monospace', + bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5)) + axes[2].set_title('Statistical Summary') + + plt.tight_layout() + output_path = self.output_dir / f'transfer_mcnemar_{self._safe_name(analysis.source_scaffold)}_{self._safe_name(analysis.target_scaffold)}.png' + plt.savefig(output_path, dpi=300, bbox_inches='tight') + plt.close() + logger.info(f"Saved McNemar analysis plot to {output_path}") + return output_path + + def _plot_error_modes(self, analysis: DeepTransferAnalysis) -> Path | None: + """Plot error mode comparison between scaffolds.""" + if not analysis.source_errors or not analysis.target_errors: + return None + + fig, axes = plt.subplots(2, 2, figsize=(14, 10)) + fig.suptitle( + f'Error Mode Analysis: {analysis.source_scaffold} vs {analysis.target_scaffold}', + fontsize=14, fontweight='bold' + ) + + source_errors = analysis.source_errors + target_errors = analysis.target_errors + + # 1. Error category comparison + all_categories = set(source_errors.error_counts.keys()) | set(target_errors.error_counts.keys()) + categories = sorted(all_categories) + + if categories: + source_counts = [source_errors.error_counts.get(c, 0) for c in categories] + target_counts = [target_errors.error_counts.get(c, 0) for c in categories] + + x = np.arange(len(categories)) + width = 0.35 + + bars1 = axes[0, 0].bar(x - width/2, source_counts, width, + label=f'Source ({analysis.source_scaffold})', color='#3498db', alpha=0.7) + bars2 = axes[0, 0].bar(x + width/2, target_counts, width, + label=f'Target ({analysis.target_scaffold})', color='#e74c3c', alpha=0.7) + + # Clean up category names for display + display_names = [c.replace('_', ' ').title() for c in categories] + axes[0, 0].set_xticks(x) + axes[0, 0].set_xticklabels(display_names, rotation=45, ha='right') + axes[0, 0].set_ylabel('Count') + axes[0, 0].set_title('Error Categories Comparison') + axes[0, 0].legend() + axes[0, 0].grid(axis='y', alpha=0.3) + + # 2. Error-prone tools comparison + source_tools = dict(source_errors.error_prone_tools[:8]) + target_tools = dict(target_errors.error_prone_tools[:8]) + all_tools = sorted(set(source_tools.keys()) | set(target_tools.keys()), + key=lambda t: source_tools.get(t, 0) + target_tools.get(t, 0), + reverse=True)[:10] + + if all_tools: + source_tool_counts = [source_tools.get(t, 0) for t in all_tools] + target_tool_counts = [target_tools.get(t, 0) for t in all_tools] + + x = np.arange(len(all_tools)) + width = 0.35 + + axes[0, 1].barh(x - width/2, source_tool_counts, width, + label=f'Source', color='#3498db', alpha=0.7) + axes[0, 1].barh(x + width/2, target_tool_counts, width, + label=f'Target', color='#e74c3c', alpha=0.7) + + axes[0, 1].set_yticks(x) + axes[0, 1].set_yticklabels(all_tools) + axes[0, 1].set_xlabel('Error Count') + axes[0, 1].set_title('Error-Prone Tools') + axes[0, 1].legend() + axes[0, 1].grid(axis='x', alpha=0.3) + + # 3. Tool error rates comparison + source_rates = source_errors.tool_error_rates + target_rates = target_errors.tool_error_rates + all_rate_tools = sorted(set(source_rates.keys()) | set(target_rates.keys()), + key=lambda t: max(source_rates.get(t, 0), target_rates.get(t, 0)), + reverse=True)[:10] + + if all_rate_tools: + source_rate_vals = [source_rates.get(t, 0) for t in all_rate_tools] + target_rate_vals = [target_rates.get(t, 0) for t in all_rate_tools] + + x = np.arange(len(all_rate_tools)) + width = 0.35 + + axes[1, 0].bar(x - width/2, source_rate_vals, width, + label=f'Source', color='#3498db', alpha=0.7) + axes[1, 0].bar(x + width/2, target_rate_vals, width, + label=f'Target', color='#e74c3c', alpha=0.7) + + axes[1, 0].set_xticks(x) + axes[1, 0].set_xticklabels(all_rate_tools, rotation=45, ha='right') + axes[1, 0].set_ylabel('Error Rate') + axes[1, 0].set_title('Tool Error Rates') + axes[1, 0].yaxis.set_major_formatter(plt.FuncFormatter(lambda y, _: f'{y:.0%}')) + axes[1, 0].legend() + axes[1, 0].grid(axis='y', alpha=0.3) + + # 4. Summary statistics + axes[1, 1].axis('off') + + summary_text = f""" + Error Summary + ═══════════════════════════════ + + Source ({analysis.source_scaffold}): + Total Errors: {source_errors.total_errors} + Most Common: {source_errors.error_prone_tools[0][0] if source_errors.error_prone_tools else 'N/A'} + + Target ({analysis.target_scaffold}): + Total Errors: {target_errors.total_errors} + Most Common: {target_errors.error_prone_tools[0][0] if target_errors.error_prone_tools else 'N/A'} + + Error Increase on Target: {target_errors.total_errors - source_errors.total_errors:+d} + """ + + axes[1, 1].text(0.1, 0.5, summary_text, transform=axes[1, 1].transAxes, + fontsize=11, verticalalignment='center', fontfamily='monospace', + bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5)) + + plt.tight_layout() + output_path = self.output_dir / f'transfer_error_modes_{self._safe_name(analysis.source_scaffold)}_{self._safe_name(analysis.target_scaffold)}.png' + plt.savefig(output_path, dpi=300, bbox_inches='tight') + plt.close() + logger.info(f"Saved error mode analysis plot to {output_path}") + return output_path + + def _plot_vocabulary(self, analysis: DeepTransferAnalysis) -> Path | None: + """Plot tool vocabulary alignment analysis.""" + if not analysis.vocabulary: + return None + + vocab = analysis.vocabulary + + fig, axes = plt.subplots(2, 2, figsize=(14, 10)) + fig.suptitle( + f'Tool Vocabulary Analysis: {vocab.source_scaffold} vs {vocab.target_scaffold}', + fontsize=14, fontweight='bold' + ) + + # 1. Vocabulary overlap (horizontal bar showing sets) + ax = axes[0, 0] + + # Create a simple Venn-like visualization + total_source = len(vocab.source_tools) + total_target = len(vocab.target_tools) + shared = len(vocab.shared_tools) + source_only = len(vocab.source_only_tools) + target_only = len(vocab.target_only_tools) + + categories = ['Source Only', 'Shared', 'Target Only'] + values = [source_only, shared, target_only] + colors = ['#3498db', '#2ecc71', '#e74c3c'] + + bars = ax.barh(categories, values, color=colors, alpha=0.7) + ax.set_xlabel('Number of Tools') + ax.set_title(f'Tool Vocabulary Overlap (Jaccard: {vocab.jaccard_index:.2f})') + + for bar, val in zip(bars, values): + ax.text(bar.get_width() + 0.1, bar.get_y() + bar.get_height()/2, + str(val), va='center', fontweight='bold') + + ax.grid(axis='x', alpha=0.3) + + # 2. Tool usage distribution comparison + ax = axes[0, 1] + + # Get top tools from each + source_sorted = sorted(vocab.source_tool_counts.items(), key=lambda x: x[1], reverse=True)[:10] + target_sorted = sorted(vocab.target_tool_counts.items(), key=lambda x: x[1], reverse=True)[:10] + + all_top_tools = [] + seen = set() + for tool, _ in source_sorted + target_sorted: + if tool not in seen: + all_top_tools.append(tool) + seen.add(tool) + all_top_tools = all_top_tools[:12] + + if all_top_tools: + source_vals = [vocab.source_tool_counts.get(t, 0) for t in all_top_tools] + target_vals = [vocab.target_tool_counts.get(t, 0) for t in all_top_tools] + + x = np.arange(len(all_top_tools)) + width = 0.35 + + ax.bar(x - width/2, source_vals, width, label='Source', color='#3498db', alpha=0.7) + ax.bar(x + width/2, target_vals, width, label='Target', color='#e74c3c', alpha=0.7) + + ax.set_xticks(x) + ax.set_xticklabels(all_top_tools, rotation=45, ha='right') + ax.set_ylabel('Call Count') + ax.set_title('Tool Usage Comparison') + ax.legend() + ax.grid(axis='y', alpha=0.3) + + # 3. Hallucinated tools + ax = axes[1, 0] + + if vocab.hallucinated_tools: + tools = list(vocab.hallucinated_tools.keys()) + counts = list(vocab.hallucinated_tools.values()) + + bars = ax.barh(range(len(tools)), counts, color='#e74c3c', alpha=0.7) + ax.set_yticks(range(len(tools))) + ax.set_yticklabels(tools) + ax.set_xlabel('Call Count') + ax.set_title(f'Hallucinated Tools on Target\n(Rate: {vocab.hallucination_rate:.1%})') + ax.grid(axis='x', alpha=0.3) + else: + ax.text(0.5, 0.5, 'No hallucinated tools detected', + ha='center', va='center', transform=ax.transAxes, fontsize=12) + ax.set_title('Hallucinated Tools on Target') + ax.axis('off') + + # 4. Tool mapping suggestions + ax = axes[1, 1] + ax.axis('off') + + # Build tool list text + source_only_text = ', '.join(sorted(vocab.source_only_tools)[:10]) or 'None' + target_only_text = ', '.join(sorted(vocab.target_only_tools)[:10]) or 'None' + shared_text = ', '.join(sorted(vocab.shared_tools)[:10]) or 'None' + + mapping_text = '\n'.join([f" {s} → {t}" for s, t in vocab.tool_mappings.items()]) or ' (none defined)' + + summary_text = f""" + Tool Vocabulary Summary + ════════════════════════════════════ + + Source Tools ({len(vocab.source_tools)}): + {source_only_text} + + Target Tools ({len(vocab.target_tools)}): + {target_only_text} + + Shared Tools ({len(vocab.shared_tools)}): + {shared_text} + + Known Tool Mappings: + {mapping_text} + + Jaccard Similarity: {vocab.jaccard_index:.2f} + Hallucination Rate: {vocab.hallucination_rate:.1%} + """ + + ax.text(0.05, 0.5, summary_text, transform=ax.transAxes, + fontsize=10, verticalalignment='center', fontfamily='monospace', + bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5)) + + plt.tight_layout() + output_path = self.output_dir / f'transfer_vocabulary_{self._safe_name(vocab.source_scaffold)}_{self._safe_name(vocab.target_scaffold)}.png' + plt.savefig(output_path, dpi=300, bbox_inches='tight') + plt.close() + logger.info(f"Saved vocabulary analysis plot to {output_path}") + return output_path + + def _plot_error_patterns_comparison( + self, + analysis: DeepTransferAnalysis, + top_n: int = 20 + ) -> Path | None: + """Plot error pattern comparison between source and target scaffolds.""" + if not analysis.source_errors or not analysis.target_errors: + return None + + source_patterns = analysis.source_errors.error_pattern_counts + target_patterns = analysis.target_errors.error_pattern_counts + + if not source_patterns and not target_patterns: + logger.warning("No error patterns to compare") + return None + + fig, axes = plt.subplots(1, 2, figsize=(20, max(10, len(source_patterns) * 0.5))) + fig.suptitle( + f'Error Pattern Comparison: {analysis.source_scaffold} vs {analysis.target_scaffold}\n' + f'Model: {analysis.base_model} (Raw Error Messages)', + fontsize=14, fontweight='bold' + ) + + # Combine and sort patterns by total frequency + all_patterns = set(source_patterns.keys()) | set(target_patterns.keys()) + pattern_totals = { + p: source_patterns.get(p, 0) + target_patterns.get(p, 0) + for p in all_patterns + } + top_patterns = sorted(pattern_totals.items(), key=lambda x: x[1], reverse=True)[:top_n] + patterns = [p for p, _ in top_patterns] + + # 1. Side-by-side comparison of top patterns + source_counts = [source_patterns.get(p, 0) for p in patterns] + target_counts = [target_patterns.get(p, 0) for p in patterns] + + y_pos = np.arange(len(patterns)) + height = 0.35 + + bars1 = axes[0].barh(y_pos - height/2, source_counts, height, + label=f'Source ({analysis.source_scaffold})', color='#3498db', alpha=0.7) + bars2 = axes[0].barh(y_pos + height/2, target_counts, height, + label=f'Target ({analysis.target_scaffold})', color='#e74c3c', alpha=0.7) + + axes[0].set_yticks(y_pos) + # Show raw error messages (not title-cased) + axes[0].set_yticklabels(patterns, fontsize=8) + axes[0].invert_yaxis() + axes[0].set_xlabel('Frequency') + axes[0].set_title(f'Top {len(patterns)} Error Messages Comparison') + axes[0].legend(loc='lower right') + axes[0].grid(axis='x', alpha=0.3) + + # 2. Delta plot (target - source) to show what increased/decreased + deltas = [target_counts[i] - source_counts[i] for i in range(len(patterns))] + colors = ['#e74c3c' if d > 0 else '#3498db' for d in deltas] + + bars = axes[1].barh(y_pos, deltas, color=colors, alpha=0.7) + axes[1].set_yticks(y_pos) + axes[1].set_yticklabels(patterns, fontsize=8) + axes[1].invert_yaxis() + axes[1].set_xlabel('Delta (Target - Source)') + axes[1].set_title('Error Pattern Change\n(Red = More on Target, Blue = More on Source)') + axes[1].axvline(0, color='black', linestyle='-', linewidth=0.5) + axes[1].grid(axis='x', alpha=0.3) + + # Add annotations for significant changes + max_delta = max(abs(d) for d in deltas) if deltas else 1 + for bar, delta in zip(bars, deltas): + if abs(delta) > max_delta * 0.1: # Only annotate significant changes + sign = '+' if delta > 0 else '' + axes[1].text( + delta + (max_delta * 0.02 if delta >= 0 else -max_delta * 0.02), + bar.get_y() + bar.get_height()/2, + f'{sign}{delta}', + va='center', + ha='left' if delta >= 0 else 'right', + fontsize=8 + ) + + plt.tight_layout() + output_path = self.output_dir / f'transfer_error_patterns_{self._safe_name(analysis.source_scaffold)}_{self._safe_name(analysis.target_scaffold)}.png' + plt.savefig(output_path, dpi=300, bbox_inches='tight') + plt.close() + logger.info(f"Saved error patterns comparison plot to {output_path}") + return output_path + diff --git a/tests/test_swebench_environment.py b/tests/test_swebench_environment.py new file mode 100644 index 0000000..070c4ec --- /dev/null +++ b/tests/test_swebench_environment.py @@ -0,0 +1,238 @@ +""" +Test for SWE-Bench Verified environment setup with Apptainer backend. + +This test verifies that the environment setup in CodeRepairRL matches R2E-Gym's setup: +- PATH is set correctly to DOCKER_PATH +- chardet is installed +- ripgrep is installed +- run_tests.sh is executable +- venv symlink is created +- Basic file operations work +- Commands can be executed +""" + +import pytest +import os +import sys +import shutil +import logging +from datasets import load_dataset + +# Add src to path +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) + +from nano.env import ApptainerEnvironment + +# Configure logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +# Expected PATH from R2E-Gym +EXPECTED_DOCKER_PATH = "/root/.venv/bin:/root/.local/bin:/root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + + +def get_swebench_sample(): + """Load a single sample from SWE-Bench Verified.""" + try: + ds = load_dataset("princeton-nlp/SWE-bench_Verified", split="test", streaming=True) + # Get the first example + return next(iter(ds)) + except Exception as e: + pytest.skip(f"Failed to load SWE-Bench Verified dataset: {e}") + + +@pytest.fixture(scope="module") +def swebench_sample(): + return get_swebench_sample() + + +@pytest.fixture(scope="module") +def apptainer_env(swebench_sample): + """Create and setup an Apptainer environment for testing.""" + # Check if apptainer is available + if not shutil.which("apptainer"): + pytest.skip("Apptainer not installed") + + instance_id = swebench_sample.get("instance_id", "") + if not instance_id: + pytest.skip("Sample does not have instance_id") + + # Construct image name + image_name = f"docker.io/slimshetty/swebench-verified:sweb.eval.x86_64.{instance_id}" + workdir = "/testbed" + + logger.info(f"Creating ApptainerEnvironment for {instance_id}") + logger.info(f"Image: {image_name}") + + # Create environment + env = ApptainerEnvironment(image=f"docker://{image_name}", workdir=workdir) + + try: + # Start the environment (this also runs setup) + env.start() + + # Import and run the setup function + from src.agents.nano_agent import setup_swebench_environment + setup_swebench_environment(env) + + yield env + + finally: + # Cleanup + logger.info("Stopping environment...") + env.stop() + + +def test_apptainer_available(): + """Test that Apptainer is installed.""" + assert shutil.which("apptainer"), "Apptainer not installed" + + +def test_environment_starts(apptainer_env): + """Test that the Apptainer environment starts successfully.""" + assert apptainer_env.started, "Environment failed to start" + logger.info("✓ Environment started successfully") + + +def test_path_is_set(apptainer_env): + """Test that PATH is set to DOCKER_PATH.""" + result = apptainer_env.run_shell("echo $PATH", timeout=30) + assert result.returncode == 0, f"Failed to get PATH: {result.stdout}" + + path = result.stdout.strip() + logger.info(f"PATH: {path}") + + # Check that the path contains key directories + assert "/root/.venv/bin" in path, "PATH missing /root/.venv/bin" + assert "/usr/local/bin" in path, "PATH missing /usr/local/bin" + logger.info("✓ PATH is set correctly") + + +def test_venv_symlink_exists(apptainer_env): + """Test that /root/.venv symlink is created.""" + result = apptainer_env.run_shell("test -L /root/.venv && echo 'EXISTS'", timeout=30) + assert result.returncode == 0, f"Symlink check failed: {result.stdout}" + assert "EXISTS" in result.stdout, "/root/.venv symlink does not exist" + + # Verify it points to the right location + result = apptainer_env.run_shell("readlink /root/.venv", timeout=30) + assert result.returncode == 0, f"Failed to read symlink: {result.stdout}" + assert "/opt/miniconda3/envs/testbed" in result.stdout, "Symlink points to wrong location" + logger.info("✓ /root/.venv symlink exists and points correctly") + + +def test_chardet_installed(apptainer_env): + """Test that chardet package is installed.""" + result = apptainer_env.run_shell("python -c 'import chardet; print(chardet.__version__)'", timeout=60) + assert result.returncode == 0, f"chardet not installed: {result.stdout}" + logger.info(f"✓ chardet is installed (version: {result.stdout.strip()})") + + +def test_ripgrep_installed(apptainer_env): + """Test that ripgrep is installed.""" + result = apptainer_env.run_shell("which rg", timeout=30) + assert result.returncode == 0, f"ripgrep not installed: {result.stdout}" + + result = apptainer_env.run_shell("rg --version", timeout=30) + assert result.returncode == 0, f"Failed to get ripgrep version: {result.stdout}" + logger.info(f"✓ ripgrep is installed: {result.stdout.strip().split()[0]}") + + +def test_run_tests_executable(apptainer_env): + """Test that /run_tests.sh exists and is executable.""" + result = apptainer_env.run_shell("test -x /run_tests.sh && echo 'EXECUTABLE'", timeout=30) + assert result.returncode == 0, f"run_tests.sh check failed: {result.stdout}" + assert "EXECUTABLE" in result.stdout, "/run_tests.sh is not executable" + logger.info("✓ /run_tests.sh is executable") + + +def test_python_version(apptainer_env): + """Test that Python is accessible and get its version.""" + result = apptainer_env.run_shell("python --version", timeout=30) + assert result.returncode == 0, f"Failed to get Python version: {result.stdout}" + logger.info(f"✓ Python version: {result.stdout.strip()}") + + +def test_git_repository(apptainer_env): + """Test that the workdir is a git repository.""" + result = apptainer_env.run_shell("test -d .git && echo 'IS_GIT_REPO'", timeout=30) + assert result.returncode == 0, f"Git check failed: {result.stdout}" + assert "IS_GIT_REPO" in result.stdout, "Workdir is not a git repository" + logger.info("✓ Workdir is a git repository") + + +def test_basic_shell_commands(apptainer_env): + """Test that basic shell commands work.""" + commands = [ + ("pwd", "/testbed"), + ("whoami", "root"), + ("echo 'test'", "test"), + ] + + for cmd, expected in commands: + result = apptainer_env.run_shell(cmd, timeout=30) + assert result.returncode == 0, f"Command '{cmd}' failed: {result.stdout}" + assert expected in result.stdout, f"Expected '{expected}' in output of '{cmd}'" + logger.info(f"✓ Command '{cmd}' works") + + +def test_file_operations(apptainer_env): + """Test that file read/write operations work.""" + import uuid + test_file = f"test_file_{uuid.uuid4().hex[:8]}.txt" + test_content = "Hello from CodeRepairRL test!" + + # Write file + result = apptainer_env.run_shell(f"echo '{test_content}' > {test_file}", timeout=30) + assert result.returncode == 0, f"Failed to write file: {result.stdout}" + + # Read file + result = apptainer_env.run_shell(f"cat {test_file}", timeout=30) + assert result.returncode == 0, f"Failed to read file: {result.stdout}" + assert test_content in result.stdout, "File content mismatch" + + # Delete file + result = apptainer_env.run_shell(f"rm {test_file}", timeout=30) + assert result.returncode == 0, f"Failed to delete file: {result.stdout}" + + logger.info("✓ File operations work correctly") + + +def test_python_imports(apptainer_env): + """Test that common Python packages are available.""" + packages = [ + "sys", + "os", + "subprocess", + "pytest", + ] + + for package in packages: + result = apptainer_env.run_shell(f"python -c 'import {package}'", timeout=30) + # Some packages might not be installed, but core ones should be + if package in ["sys", "os", "subprocess"]: + assert result.returncode == 0, f"Failed to import {package}: {result.stdout}" + logger.info(f"✓ Can import {package}" if result.returncode == 0 else f"- {package} not available (OK)") + + +def test_workdir_location(apptainer_env): + """Test that we're in the correct workdir.""" + result = apptainer_env.run_shell("pwd", timeout=30) + assert result.returncode == 0, f"Failed to get pwd: {result.stdout}" + assert "/testbed" in result.stdout, f"Not in correct workdir. Got: {result.stdout}" + logger.info("✓ Workdir is /testbed") + + +def test_repository_files_exist(apptainer_env): + """Test that repository files exist in the workdir.""" + result = apptainer_env.run_shell("ls -la", timeout=30) + assert result.returncode == 0, f"Failed to list files: {result.stdout}" + + # Should have some files (not empty directory) + lines = result.stdout.strip().split("\n") + assert len(lines) > 3, "Workdir appears to be empty" # > 3 to account for ., .., and at least one file + logger.info("✓ Repository files exist in workdir") + + +if __name__ == "__main__": + pytest.main([__file__, "-v", "-s"]) diff --git a/uv.lock b/uv.lock index a811ea7..e95d1bb 100644 --- a/uv.lock +++ b/uv.lock @@ -1,9 +1,11 @@ version = 1 revision = 3 -requires-python = "==3.11.*" +requires-python = ">=3.11, <3.13" resolution-markers = [ - "sys_platform == 'linux'", - "sys_platform != 'linux'", + "python_full_version >= '3.12' and sys_platform == 'linux'", + "python_full_version >= '3.12' and sys_platform != 'linux'", + "python_full_version < '3.12' and sys_platform == 'linux'", + "python_full_version < '3.12' and sys_platform != 'linux'", ] [[package]] @@ -65,6 +67,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/11/91133c8b68b1da9fc16555706aa7276fdf781ae2bb0876c838dd86b8116e/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9acda8604a57bb60544e4646a4615c1866ee6c04a8edef9b8ee6fd1d8fa2ddc8", size = 1739532, upload-time = "2025-10-28T20:56:25.924Z" }, { url = "https://files.pythonhosted.org/packages/17/6b/3747644d26a998774b21a616016620293ddefa4d63af6286f389aedac844/aiohttp-3.13.2-cp311-cp311-win32.whl", hash = "sha256:868e195e39b24aaa930b063c08bb0c17924899c16c672a28a65afded9c46c6ec", size = 431876, upload-time = "2025-10-28T20:56:27.524Z" }, { url = "https://files.pythonhosted.org/packages/c3/63/688462108c1a00eb9f05765331c107f95ae86f6b197b865d29e930b7e462/aiohttp-3.13.2-cp311-cp311-win_amd64.whl", hash = "sha256:7fd19df530c292542636c2a9a85854fab93474396a52f1695e799186bbd7f24c", size = 456205, upload-time = "2025-10-28T20:56:29.062Z" }, + { url = "https://files.pythonhosted.org/packages/29/9b/01f00e9856d0a73260e86dd8ed0c2234a466c5c1712ce1c281548df39777/aiohttp-3.13.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b1e56bab2e12b2b9ed300218c351ee2a3d8c8fdab5b1ec6193e11a817767e47b", size = 737623, upload-time = "2025-10-28T20:56:30.797Z" }, + { url = "https://files.pythonhosted.org/packages/5a/1b/4be39c445e2b2bd0aab4ba736deb649fabf14f6757f405f0c9685019b9e9/aiohttp-3.13.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:364e25edaabd3d37b1db1f0cbcee8c73c9a3727bfa262b83e5e4cf3489a2a9dc", size = 492664, upload-time = "2025-10-28T20:56:32.708Z" }, + { url = "https://files.pythonhosted.org/packages/28/66/d35dcfea8050e131cdd731dff36434390479b4045a8d0b9d7111b0a968f1/aiohttp-3.13.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c5c94825f744694c4b8db20b71dba9a257cd2ba8e010a803042123f3a25d50d7", size = 491808, upload-time = "2025-10-28T20:56:34.57Z" }, + { url = "https://files.pythonhosted.org/packages/00/29/8e4609b93e10a853b65f8291e64985de66d4f5848c5637cddc70e98f01f8/aiohttp-3.13.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba2715d842ffa787be87cbfce150d5e88c87a98e0b62e0f5aa489169a393dbbb", size = 1738863, upload-time = "2025-10-28T20:56:36.377Z" }, + { url = "https://files.pythonhosted.org/packages/9d/fa/4ebdf4adcc0def75ced1a0d2d227577cd7b1b85beb7edad85fcc87693c75/aiohttp-3.13.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:585542825c4bc662221fb257889e011a5aa00f1ae4d75d1d246a5225289183e3", size = 1700586, upload-time = "2025-10-28T20:56:38.034Z" }, + { url = "https://files.pythonhosted.org/packages/da/04/73f5f02ff348a3558763ff6abe99c223381b0bace05cd4530a0258e52597/aiohttp-3.13.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:39d02cb6025fe1aabca329c5632f48c9532a3dabccd859e7e2f110668972331f", size = 1768625, upload-time = "2025-10-28T20:56:39.75Z" }, + { url = "https://files.pythonhosted.org/packages/f8/49/a825b79ffec124317265ca7d2344a86bcffeb960743487cb11988ffb3494/aiohttp-3.13.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e67446b19e014d37342f7195f592a2a948141d15a312fe0e700c2fd2f03124f6", size = 1867281, upload-time = "2025-10-28T20:56:41.471Z" }, + { url = "https://files.pythonhosted.org/packages/b9/48/adf56e05f81eac31edcfae45c90928f4ad50ef2e3ea72cb8376162a368f8/aiohttp-3.13.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4356474ad6333e41ccefd39eae869ba15a6c5299c9c01dfdcfdd5c107be4363e", size = 1752431, upload-time = "2025-10-28T20:56:43.162Z" }, + { url = "https://files.pythonhosted.org/packages/30/ab/593855356eead019a74e862f21523db09c27f12fd24af72dbc3555b9bfd9/aiohttp-3.13.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eeacf451c99b4525f700f078becff32c32ec327b10dcf31306a8a52d78166de7", size = 1562846, upload-time = "2025-10-28T20:56:44.85Z" }, + { url = "https://files.pythonhosted.org/packages/39/0f/9f3d32271aa8dc35036e9668e31870a9d3b9542dd6b3e2c8a30931cb27ae/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8a9b889aeabd7a4e9af0b7f4ab5ad94d42e7ff679aaec6d0db21e3b639ad58d", size = 1699606, upload-time = "2025-10-28T20:56:46.519Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3c/52d2658c5699b6ef7692a3f7128b2d2d4d9775f2a68093f74bca06cf01e1/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:fa89cb11bc71a63b69568d5b8a25c3ca25b6d54c15f907ca1c130d72f320b76b", size = 1720663, upload-time = "2025-10-28T20:56:48.528Z" }, + { url = "https://files.pythonhosted.org/packages/9b/d4/8f8f3ff1fb7fb9e3f04fcad4e89d8a1cd8fc7d05de67e3de5b15b33008ff/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8aa7c807df234f693fed0ecd507192fc97692e61fee5702cdc11155d2e5cadc8", size = 1737939, upload-time = "2025-10-28T20:56:50.77Z" }, + { url = "https://files.pythonhosted.org/packages/03/d3/ddd348f8a27a634daae39a1b8e291ff19c77867af438af844bf8b7e3231b/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9eb3e33fdbe43f88c3c75fa608c25e7c47bbd80f48d012763cb67c47f39a7e16", size = 1555132, upload-time = "2025-10-28T20:56:52.568Z" }, + { url = "https://files.pythonhosted.org/packages/39/b8/46790692dc46218406f94374903ba47552f2f9f90dad554eed61bfb7b64c/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9434bc0d80076138ea986833156c5a48c9c7a8abb0c96039ddbb4afc93184169", size = 1764802, upload-time = "2025-10-28T20:56:54.292Z" }, + { url = "https://files.pythonhosted.org/packages/ba/e4/19ce547b58ab2a385e5f0b8aa3db38674785085abcf79b6e0edd1632b12f/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ff15c147b2ad66da1f2cbb0622313f2242d8e6e8f9b79b5206c84523a4473248", size = 1719512, upload-time = "2025-10-28T20:56:56.428Z" }, + { url = "https://files.pythonhosted.org/packages/70/30/6355a737fed29dcb6dfdd48682d5790cb5eab050f7b4e01f49b121d3acad/aiohttp-3.13.2-cp312-cp312-win32.whl", hash = "sha256:27e569eb9d9e95dbd55c0fc3ec3a9335defbf1d8bc1d20171a49f3c4c607b93e", size = 426690, upload-time = "2025-10-28T20:56:58.736Z" }, + { url = "https://files.pythonhosted.org/packages/0a/0d/b10ac09069973d112de6ef980c1f6bb31cb7dcd0bc363acbdad58f927873/aiohttp-3.13.2-cp312-cp312-win_amd64.whl", hash = "sha256:8709a0f05d59a71f33fd05c17fc11fcb8c30140506e13c2f5e8ee1b8964e1b45", size = 453465, upload-time = "2025-10-28T20:57:00.795Z" }, ] [[package]] @@ -118,6 +137,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc", size = 109097, upload-time = "2025-09-23T09:19:10.601Z" }, ] +[[package]] +name = "apache-tvm-ffi" +version = "0.1.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/07/6fbc8fbef1d04bd290f2dcdb3091ae784ac526b62649ec52993a41c65f72/apache_tvm_ffi-0.1.7.tar.gz", hash = "sha256:737cd4a067d6c6c7ad7dd909a0708eb3dc28540299039ea636f8ff5766b122be", size = 2397940, upload-time = "2025-12-28T09:13:25.52Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/b9/3bb4099a82b4c7198823b67067a3d206ec8a0b32204a559c5cca1bee54bd/apache_tvm_ffi-0.1.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f0e010e61d1f220ec4ce3d15053db3f8c8d9c79230ea763343fc5e4acf53ef17", size = 1975412, upload-time = "2025-12-28T09:12:34.737Z" }, + { url = "https://files.pythonhosted.org/packages/48/53/423788fb9b26460b3d7ceb8588d172dfe7ae4abcc335931fcbf08a859904/apache_tvm_ffi-0.1.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9b05155b4b60ebd3642213d0489b6ef24aff17b268960dbb5f106a39899bb8b1", size = 2047974, upload-time = "2025-12-28T09:12:36.296Z" }, + { url = "https://files.pythonhosted.org/packages/a6/30/45d4acf7f99e1fc79a8663f2111901b8031e1f9b316860af7acf4859c964/apache_tvm_ffi-0.1.7-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cceaddc7636060231aca4ada2632814189b1169224b2b451f41984145ef615fc", size = 1919697, upload-time = "2025-12-28T09:12:38.15Z" }, + { url = "https://files.pythonhosted.org/packages/dd/bb/fa5042076bf6e7daaf9774389f99149c1851434fc0d8e4cb34aa0c4a3810/apache_tvm_ffi-0.1.7-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5769cadc42e70522e2a523f1dfe24f48dbe3bf384e63f95df251f9d572ffcf23", size = 2030760, upload-time = "2025-12-28T09:12:39.813Z" }, + { url = "https://files.pythonhosted.org/packages/fe/74/fd06e97699e9cbf36d887c5fbbc56b14e896e2652bbe1781ab84cef82a40/apache_tvm_ffi-0.1.7-cp311-cp311-win_amd64.whl", hash = "sha256:b5c7716429ce2beb0a5b00c5a3bdd90b8a5891838afb782491c576ade42ba7c4", size = 1788026, upload-time = "2025-12-28T09:12:42.142Z" }, + { url = "https://files.pythonhosted.org/packages/b9/d3/05ba0a63baba1e3aec0f6303c4bc567493fb1c070d9f298f929a7703c0fb/apache_tvm_ffi-0.1.7-cp312-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d0e579234ce6fb2899377335a881ecf15d0197d833e2d370c9269ea6ca578f6f", size = 1947362, upload-time = "2025-12-28T09:12:45.921Z" }, + { url = "https://files.pythonhosted.org/packages/f1/11/b69df7685d75144fd9f57e5155cdf4ff91d6617a9f8b89b1415204863da0/apache_tvm_ffi-0.1.7-cp312-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:258a4aecc16e963def8ba0ab07f585147c7e7f586156b9496bfdf34af229443d", size = 2024240, upload-time = "2025-12-28T09:12:47.337Z" }, + { url = "https://files.pythonhosted.org/packages/cf/b6/31459f4141ea8621377fecac7c29e1568d494cbf95c5aa1ddf2cbc12a8ff/apache_tvm_ffi-0.1.7-cp312-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:363701589349e11a945dabce026578203bd83cb8de71af9a066beadd77af085a", size = 1891485, upload-time = "2025-12-28T09:12:49.171Z" }, + { url = "https://files.pythonhosted.org/packages/a5/4d/d21874eda6e3ea59c5a84aa010b24b84617e3b286ad759ac5eadccb1a88c/apache_tvm_ffi-0.1.7-cp312-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fbbf87df625930bafbd979c2c510d5bd989e9171098e5bb65320d0e7336d0095", size = 2003196, upload-time = "2025-12-28T09:12:50.891Z" }, + { url = "https://files.pythonhosted.org/packages/3f/d4/37102d96e359386107f5ce3751c4e2a8c1b8df3d34f65b701810ba59465c/apache_tvm_ffi-0.1.7-cp312-abi3-win_amd64.whl", hash = "sha256:d2fb56f53e33c7ddf7d6d340d44cbc440d205f7dab4bc5ed1ad20c8fc779250f", size = 1768697, upload-time = "2025-12-28T09:12:52.394Z" }, +] + [[package]] name = "astor" version = "0.8.1" @@ -169,7 +209,7 @@ name = "blake3" version = "1.0.8" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions" }, + { name = "typing-extensions", marker = "python_full_version < '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/75/aa/abcd75e9600987a0bc6cfe9b6b2ff3f0e2cb08c170addc6e76035b5c4cb3/blake3-1.0.8.tar.gz", hash = "sha256:513cc7f0f5a7c035812604c2c852a0c1468311345573de647e310aca4ab165ba", size = 117308, upload-time = "2025-10-14T06:47:48.83Z" } wheels = [ @@ -183,6 +223,16 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7e/75/0252be37620699b79dbaa799c9b402d63142a131d16731df4ef09d135dd7/blake3-1.0.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c63ece266a43014cf29e772a82857cd8e90315ae3ed53e3c5204851596edd5f2", size = 554463, upload-time = "2025-10-14T06:45:43.22Z" }, { url = "https://files.pythonhosted.org/packages/8c/6d/d698ae2d5ddd25976fd2c11b079ca071334aecbba6414da8c9cc8e19d833/blake3-1.0.8-cp311-cp311-win32.whl", hash = "sha256:44c2815d4616fad7e2d757d121c0a11780f70ffc817547b3059b5c7e224031a7", size = 228375, upload-time = "2025-10-14T06:45:44.425Z" }, { url = "https://files.pythonhosted.org/packages/34/d7/33b01e27dc3542dc9ec44132684506f880cd0257b04da0bf7f4b2afa41c8/blake3-1.0.8-cp311-cp311-win_amd64.whl", hash = "sha256:8f2ef8527a7a8afd99b16997d015851ccc0fe2a409082cebb980af2554e5c74c", size = 215733, upload-time = "2025-10-14T06:45:46.049Z" }, + { url = "https://files.pythonhosted.org/packages/ee/7d/85a4c0782f613de23d114a7a78fcce270f75b193b3ff3493a0de24ba104a/blake3-1.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:269f255b110840e52b6ce9db02217e39660ebad3e34ddd5bca8b8d378a77e4e1", size = 371296, upload-time = "2025-10-14T06:45:49.674Z" }, + { url = "https://files.pythonhosted.org/packages/e3/20/488475254976ed93fab57c67aa80d3b40df77f7d9db6528c9274bff53e08/blake3-1.0.8-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:66ca28a673025c40db3eba21a9cac52f559f83637efa675b3f6bd8683f0415f3", size = 374516, upload-time = "2025-10-14T06:45:51.23Z" }, + { url = "https://files.pythonhosted.org/packages/7b/21/2a1c47fedb77fb396512677ec6d46caf42ac6e9a897db77edd0a2a46f7bb/blake3-1.0.8-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcb04966537777af56c1f399b35525aa70a1225816e121ff95071c33c0f7abca", size = 447911, upload-time = "2025-10-14T06:45:52.637Z" }, + { url = "https://files.pythonhosted.org/packages/cb/7d/db0626df16029713e7e61b67314c4835e85c296d82bd907c21c6ea271da2/blake3-1.0.8-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e5b5da177d62cc4b7edf0cea08fe4dec960c9ac27f916131efa890a01f747b93", size = 505420, upload-time = "2025-10-14T06:45:54.445Z" }, + { url = "https://files.pythonhosted.org/packages/5b/55/6e737850c2d58a6d9de8a76dad2ae0f75b852a23eb4ecb07a0b165e6e436/blake3-1.0.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:38209b10482c97e151681ea3e91cc7141f56adbbf4820a7d701a923124b41e6a", size = 394189, upload-time = "2025-10-14T06:45:55.719Z" }, + { url = "https://files.pythonhosted.org/packages/5b/94/eafaa5cdddadc0c9c603a6a6d8339433475e1a9f60c8bb9c2eed2d8736b6/blake3-1.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:504d1399b7fb91dfe5c25722d2807990493185faa1917456455480c36867adb5", size = 388001, upload-time = "2025-10-14T06:45:57.067Z" }, + { url = "https://files.pythonhosted.org/packages/17/81/735fa00d13de7f68b25e1b9cb36ff08c6f165e688d85d8ec2cbfcdedccc5/blake3-1.0.8-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c84af132aa09abeadf9a0118c8fb26f4528f3f42c10ef8be0fcf31c478774ec4", size = 550302, upload-time = "2025-10-14T06:45:58.657Z" }, + { url = "https://files.pythonhosted.org/packages/0e/c6/d1fe8bdea4a6088bd54b5a58bc40aed89a4e784cd796af7722a06f74bae7/blake3-1.0.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a25db3d36b55f5ed6a86470155cc749fc9c5b91c949b8d14f48658f9d960d9ec", size = 554211, upload-time = "2025-10-14T06:46:00.269Z" }, + { url = "https://files.pythonhosted.org/packages/55/d1/ca74aa450cbe10e396e061f26f7a043891ffa1485537d6b30d3757e20995/blake3-1.0.8-cp312-cp312-win32.whl", hash = "sha256:e0fee93d5adcd44378b008c147e84f181f23715307a64f7b3db432394bbfce8b", size = 228343, upload-time = "2025-10-14T06:46:01.533Z" }, + { url = "https://files.pythonhosted.org/packages/4d/42/bbd02647169e3fbed27558555653ac2578c6f17ccacf7d1956c58ef1d214/blake3-1.0.8-cp312-cp312-win_amd64.whl", hash = "sha256:6a6eafc29e4f478d365a87d2f25782a521870c8514bb43734ac85ae9be71caf7", size = 215704, upload-time = "2025-10-14T06:46:02.79Z" }, ] [[package]] @@ -236,6 +286,14 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/34/d5/252657bc5af964fc5f19c0e0e82031b4c32eba5d3ed4098e963e0e8c47a6/cbor2-5.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9f6cdf7eb604ea0e7ef34e3f0b5447da0029ecd3ab7b2dc70e43fa5f7bcfca89", size = 251494, upload-time = "2025-10-24T09:22:21.986Z" }, { url = "https://files.pythonhosted.org/packages/8a/3a/503ea4c2977411858ca287808d077fdb4bb1fafdb4b39177b8ce3d5619ac/cbor2-5.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:dd25cbef8e8e6dbf69f0de95311aecaca7217230cda83ae99fdc37cd20d99250", size = 68147, upload-time = "2025-10-24T09:22:23.136Z" }, { url = "https://files.pythonhosted.org/packages/49/9e/fe4c9703fd444da193f892787110c5da2a85c16d26917fcb2584f5d00077/cbor2-5.7.1-cp311-cp311-win_arm64.whl", hash = "sha256:40cc9c67242a7abac5a4e062bc4d1d2376979878c0565a4b2f08fd9ed9212945", size = 64126, upload-time = "2025-10-24T09:22:24.197Z" }, + { url = "https://files.pythonhosted.org/packages/56/54/48426472f0c051982c647331441aed09b271a0500356ae0b7054c813d174/cbor2-5.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bd5ca44891c06f6b85d440836c967187dc1d30b15f86f315d55c675d3a841078", size = 69031, upload-time = "2025-10-24T09:22:25.438Z" }, + { url = "https://files.pythonhosted.org/packages/d3/68/1dd58c7706e9752188358223db58c83f3c48e07f728aa84221ffd244652f/cbor2-5.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:537d73ef930ccc1a7b6a2e8d2cbf81407d270deb18e40cda5eb511bd70f71078", size = 68825, upload-time = "2025-10-24T09:22:26.497Z" }, + { url = "https://files.pythonhosted.org/packages/09/4e/380562fe9f9995a1875fb5ec26fd041e19d61f4630cb690a98c5195945fc/cbor2-5.7.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:edbf814dd7763b6eda27a5770199f6ccd55bd78be8f4367092460261bfbf19d0", size = 286222, upload-time = "2025-10-24T09:22:27.546Z" }, + { url = "https://files.pythonhosted.org/packages/7c/bb/9eccdc1ea3c4d5c7cdb2e49b9de49534039616be5455ce69bd64c0b2efe2/cbor2-5.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9fc81da8c0e09beb42923e455e477b36ff14a03b9ca18a8a2e9b462de9a953e8", size = 285688, upload-time = "2025-10-24T09:22:28.651Z" }, + { url = "https://files.pythonhosted.org/packages/59/8c/4696d82f5bd04b3d45d9a64ec037fa242630c134e3218d6c252b4f59b909/cbor2-5.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e4a7d660d428911a3aadb7105e94438d7671ab977356fdf647a91aab751033bd", size = 277063, upload-time = "2025-10-24T09:22:29.775Z" }, + { url = "https://files.pythonhosted.org/packages/95/50/6538e44ca970caaad2fa376b81701d073d84bf597aac07a59d0a253b1a7f/cbor2-5.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:228e0af9c0a9ddf6375b6ae010eaa1942a1901d403f134ac9ee6a76a322483f9", size = 278334, upload-time = "2025-10-24T09:22:30.904Z" }, + { url = "https://files.pythonhosted.org/packages/64/a9/156ccd2207fb26b5b61d23728b4dbdc595d1600125aa79683a4a8ddc9313/cbor2-5.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:2d08a6c0d9ed778448e185508d870f4160ba74f59bb17a966abd0d14d0ff4dd3", size = 68404, upload-time = "2025-10-24T09:22:32.108Z" }, + { url = "https://files.pythonhosted.org/packages/4f/49/adc53615e9dd32c4421f6935dfa2235013532c6e6b28ee515bbdd92618be/cbor2-5.7.1-cp312-cp312-win_arm64.whl", hash = "sha256:752506cfe72da0f4014b468b30191470ee8919a64a0772bd3b36a4fccf5fcefc", size = 64047, upload-time = "2025-10-24T09:22:33.147Z" }, { url = "https://files.pythonhosted.org/packages/d5/7d/383bafeabb54c17fe5b6d5aca4e863e6b7df10bcc833b34aa169e9dfce1a/cbor2-5.7.1-py3-none-any.whl", hash = "sha256:68834e4eff2f56629ce6422b0634bc3f74c5a4269de5363f5265fe452c706ba7", size = 23829, upload-time = "2025-10-24T09:23:05.54Z" }, ] @@ -268,6 +326,16 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload-time = "2025-09-08T23:22:40.95Z" }, { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload-time = "2025-09-08T23:22:42.463Z" }, { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload-time = "2025-09-08T23:22:43.623Z" }, + { url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" }, + { url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" }, + { url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" }, + { url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" }, + { url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" }, + { url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" }, + { url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" }, + { url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" }, ] [[package]] @@ -310,6 +378,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1a/86/584869fe4ddb6ffa3bd9f491b87a01568797fb9bd8933f557dba9771beaf/charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a", size = 99456, upload-time = "2025-10-14T04:40:49.376Z" }, { url = "https://files.pythonhosted.org/packages/65/f6/62fdd5feb60530f50f7e38b4f6a1d5203f4d16ff4f9f0952962c044e919a/charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016", size = 106978, upload-time = "2025-10-14T04:40:50.844Z" }, { url = "https://files.pythonhosted.org/packages/7a/9d/0710916e6c82948b3be62d9d398cb4fcf4e97b56d6a6aeccd66c4b2f2bd5/charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1", size = 99969, upload-time = "2025-10-14T04:40:52.272Z" }, + { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, + { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, + { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, + { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, + { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, + { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, + { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, + { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, + { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, + { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, ] @@ -345,16 +429,17 @@ wheels = [ [[package]] name = "compressed-tensors" -version = "0.10.2" +version = "0.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ + { name = "frozendict" }, { name = "pydantic" }, { name = "torch" }, { name = "transformers" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c0/86/d43d369abc81ec63ec7b8f6f27fc8b113ea0fd18a4116ae12063387b8b34/compressed_tensors-0.10.2.tar.gz", hash = "sha256:6de13ac535d7ffdd8890fad3d229444c33076170acaa8fab6bab8ecfa96c1d8f", size = 173459, upload-time = "2025-06-23T13:19:06.135Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b8/99/3fdabfc95609d6efdf02fa7f1ed0245524cb1209d3d4a17109d3205d2eed/compressed_tensors-0.11.0.tar.gz", hash = "sha256:95ddf19699f775df6494dd864e5f52e8a24f8015496520190c1a22c6cfc44b1f", size = 187566, upload-time = "2025-08-19T18:59:31.854Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/ac/56bb4b6b3150783119479e2f05e32ebfc39ca6ff8e6fcd45eb178743b39e/compressed_tensors-0.10.2-py3-none-any.whl", hash = "sha256:e1b4d9bc2006e3fd3a938e59085f318fdb280c5af64688a4792bf1bc263e579d", size = 169030, upload-time = "2025-06-23T13:19:03.487Z" }, + { url = "https://files.pythonhosted.org/packages/d2/81/e3073017a8f5c75169e79108eda209e6089e3f96c9f197d307cbda7df71c/compressed_tensors-0.11.0-py3-none-any.whl", hash = "sha256:e1cbc46e1ae032b7ceea915fe18c8d2de5a54d3a50a607969b6bdfe703b6cb83", size = 179951, upload-time = "2025-08-19T18:59:29.308Z" }, ] [[package]] @@ -377,6 +462,17 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff", size = 183677, upload-time = "2025-07-26T12:01:17.088Z" }, { url = "https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42", size = 225234, upload-time = "2025-07-26T12:01:18.256Z" }, { url = "https://files.pythonhosted.org/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470", size = 193123, upload-time = "2025-07-26T12:01:19.848Z" }, + { url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419, upload-time = "2025-07-26T12:01:21.16Z" }, + { url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979, upload-time = "2025-07-26T12:01:22.448Z" }, + { url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653, upload-time = "2025-07-26T12:01:24.155Z" }, + { url = "https://files.pythonhosted.org/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8", size = 379536, upload-time = "2025-07-26T12:01:25.91Z" }, + { url = "https://files.pythonhosted.org/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea", size = 384397, upload-time = "2025-07-26T12:01:27.152Z" }, + { url = "https://files.pythonhosted.org/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1", size = 362601, upload-time = "2025-07-26T12:01:28.808Z" }, + { url = "https://files.pythonhosted.org/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7", size = 1331288, upload-time = "2025-07-26T12:01:31.198Z" }, + { url = "https://files.pythonhosted.org/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411", size = 1403386, upload-time = "2025-07-26T12:01:33.947Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69", size = 185018, upload-time = "2025-07-26T12:01:35.64Z" }, + { url = "https://files.pythonhosted.org/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b", size = 226567, upload-time = "2025-07-26T12:01:36.804Z" }, + { url = "https://files.pythonhosted.org/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc", size = 193655, upload-time = "2025-07-26T12:01:37.999Z" }, { url = "https://files.pythonhosted.org/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497", size = 278809, upload-time = "2025-07-26T12:02:52.74Z" }, { url = "https://files.pythonhosted.org/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8", size = 261593, upload-time = "2025-07-26T12:02:54.037Z" }, { url = "https://files.pythonhosted.org/packages/0a/59/ebfb8c677c75605cc27f7122c90313fd2f375ff3c8d19a1694bda74aaa63/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e", size = 302202, upload-time = "2025-07-26T12:02:55.947Z" }, @@ -402,7 +498,8 @@ dependencies = [ { name = "mini-swe-agent" }, { name = "nano-agent" }, { name = "peft" }, - { name = "setuptools" }, + { name = "setuptools", version = "79.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "setuptools", version = "80.9.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, { name = "swebench" }, { name = "transformers" }, { name = "trl" }, @@ -429,16 +526,16 @@ requires-dist = [ { name = "bitsandbytes", marker = "sys_platform != 'darwin'", specifier = ">=0.44.1" }, { name = "boto3", specifier = ">=1.34,<2" }, { name = "botocore", specifier = ">=1.34,<2" }, - { name = "datasets", specifier = ">=3.3.0" }, + { name = "datasets", specifier = ">=4.4.1" }, { name = "deepspeed" }, { name = "flash-attn", marker = "sys_platform != 'darwin' and extra == 'flash'", specifier = "==2.8.3" }, - { name = "flashinfer-python", marker = "sys_platform != 'darwin' and extra == 'flash'", specifier = "==0.3.1" }, - { name = "gitpython", specifier = ">=3.1.44" }, + { name = "flashinfer-python", marker = "sys_platform != 'darwin' and extra == 'flash'", specifier = "==0.5.0" }, + { name = "gitpython", specifier = ">=3.1.45" }, { name = "huggingface-hub" }, { name = "hydra-core", specifier = ">=1.3.2" }, { name = "liger-kernel", git = "https://github.com/BjarniHaukur/liger-kernel.git" }, { name = "matplotlib", marker = "extra == 'dev'", specifier = ">=3.10.0" }, - { name = "mini-swe-agent", specifier = ">=1.13.0" }, + { name = "mini-swe-agent", specifier = ">=1.17.0" }, { name = "nano-agent", git = "https://github.com/ASSERT-KTH/nano-agent.git" }, { name = "peft", specifier = ">=0.15.0" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3.4" }, @@ -447,12 +544,48 @@ requires-dist = [ { name = "swebench", specifier = ">=4.1.0" }, { name = "transformers" }, { name = "trl", git = "https://github.com/ASSERT-KTH/trl.git?rev=dev" }, - { name = "vllm", marker = "sys_platform != 'darwin' and extra == 'vllm'", specifier = "==0.10.1" }, + { name = "vllm", marker = "sys_platform != 'darwin' and extra == 'vllm'", specifier = "==0.11.0" }, { name = "wandb", specifier = ">=0.18.4" }, - { name = "wandb", specifier = ">=0.19.6" }, + { name = "wandb", specifier = ">=0.23.0" }, ] provides-extras = ["vllm", "flash", "dev"] +[[package]] +name = "cuda-bindings" +version = "13.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cuda-pathfinder" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/58/b8d4c7c5fb29ba46088a7e78d1065484219f8fe41a08adc4a85b1ee56149/cuda_bindings-13.1.1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a5f5a6ade0ad45096568bc4dd1eb3377b65884d29124338fe9a4353130ef6631", size = 15771605, upload-time = "2025-12-09T22:05:48.266Z" }, + { url = "https://files.pythonhosted.org/packages/17/af/710403f76f2d608d483d87089465e1f666351641dbd73d19bd025e652bad/cuda_bindings-13.1.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9348f69b03b257f07159dd4c869615e139722c2bd81e96c66f6b8f77615efd82", size = 16338970, upload-time = "2025-12-09T22:05:50.598Z" }, + { url = "https://files.pythonhosted.org/packages/64/1c/e7ea27d4cb7d07331c88e3bbed3cacc947d2237471801086c7447b3e195d/cuda_bindings-13.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:ec33b84f4bd65a86a734427f2b9cb8f221bedab2c4cfb681488cabc82f1d64ab", size = 15210672, upload-time = "2025-12-09T22:05:53.369Z" }, + { url = "https://files.pythonhosted.org/packages/53/3d/c8ed9d169843091f3f0d6b8218e826fd59520a37e0434c204feada597988/cuda_bindings-13.1.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e75ad0cb863330df784236d289612d71ca855c013d19ae00e5693574abd6915", size = 15530160, upload-time = "2025-12-09T22:05:55.386Z" }, + { url = "https://files.pythonhosted.org/packages/4a/8e/368295623ee43fba622909d780fbb6863efc1638dff55f67a0f04eac6470/cuda_bindings-13.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:25785d1a3cdcd98f151240fd5efd025609319a6720a217dee2a929241749d488", size = 16110386, upload-time = "2025-12-09T22:05:57.71Z" }, + { url = "https://files.pythonhosted.org/packages/60/1f/ecc4701ade3e85f091c625a920574527b9daf7fb354189fbfbc5516af6cd/cuda_bindings-13.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:ccde9c95c0e953b31fe7731bb08da9d0a34b1770498df9a3c156fdfdbe3951ad", size = 15250028, upload-time = "2025-12-09T22:06:00.346Z" }, +] + +[[package]] +name = "cuda-pathfinder" +version = "1.3.3" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/02/4dbe7568a42e46582248942f54dc64ad094769532adbe21e525e4edf7bc4/cuda_pathfinder-1.3.3-py3-none-any.whl", hash = "sha256:9984b664e404f7c134954a771be8775dfd6180ea1e1aef4a5a37d4be05d9bbb1", size = 27154, upload-time = "2025-12-04T22:35:08.996Z" }, +] + +[[package]] +name = "cuda-python" +version = "13.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cuda-bindings" }, + { name = "cuda-pathfinder" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/08/b5e3b9822662d72d540d830531e3ab6a7cabbda3dd56175696aabccfeb76/cuda_python-13.1.1-py3-none-any.whl", hash = "sha256:944cc4fe6482673d28dd545797a28840945a1668739328fa2ad1e9be4f7050d9", size = 8038, upload-time = "2025-12-09T22:13:10.719Z" }, +] + [[package]] name = "cupy-cuda12x" version = "13.6.0" @@ -465,6 +598,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/64/71c6e08f76c06639e5112f69ee3bc1129be00054ad5f906d7fd3138af579/cupy_cuda12x-13.6.0-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:c790d012fd4d86872b9c89af9f5f15d91c30b8e3a4aa4dd04c2610f45f06ac44", size = 128016458, upload-time = "2025-08-18T08:24:26.394Z" }, { url = "https://files.pythonhosted.org/packages/fc/d9/5c5077243cd92368c3eccecdbf91d76db15db338169042ffd1647533c6b1/cupy_cuda12x-13.6.0-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:77ba6745a130d880c962e687e4e146ebbb9014f290b0a80dbc4e4634eb5c3b48", size = 113039337, upload-time = "2025-08-18T08:24:31.814Z" }, { url = "https://files.pythonhosted.org/packages/88/f5/02bea5cdf108e2a66f98e7d107b4c9a6709e5dbfedf663340e5c11719d83/cupy_cuda12x-13.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:a20b7acdc583643a623c8d8e3efbe0db616fbcf5916e9c99eedf73859b6133af", size = 89885526, upload-time = "2025-08-18T08:24:37.258Z" }, + { url = "https://files.pythonhosted.org/packages/12/c5/7e7fc4816d0de0154e5d9053242c3a08a0ca8b43ee656a6f7b3b95055a7b/cupy_cuda12x-13.6.0-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:a6970ceefe40f9acbede41d7fe17416bd277b1bd2093adcde457b23b578c5a59", size = 127334633, upload-time = "2025-08-18T08:24:43.065Z" }, + { url = "https://files.pythonhosted.org/packages/e0/95/d7e1295141e7d530674a3cc567e13ed0eb6b81524cb122d797ed996b5bea/cupy_cuda12x-13.6.0-cp312-cp312-manylinux2014_x86_64.whl", hash = "sha256:79b0cacb5e8b190ef409f9e03f06ac8de1b021b0c0dda47674d446f5557e0eb1", size = 112886268, upload-time = "2025-08-18T08:24:49.294Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8c/14555b63fd78cfac7b88af0094cea0a3cb845d243661ec7da69f7b3ea0de/cupy_cuda12x-13.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca06fede7b8b83ca9ad80062544ef2e5bb8d4762d1c4fc3ac8349376de9c8a5e", size = 89785108, upload-time = "2025-08-18T08:24:54.527Z" }, ] [[package]] @@ -697,6 +833,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f2/7a/3ea4726bae3ac9358d02107ae48f3e10ee186dbed554af79e00b7b498c44/fastar-0.8.0-cp311-cp311-win32.whl", hash = "sha256:661a47ed90762f419406c47e802f46af63a08254ba96abd1c8191e4ce967b665", size = 456449, upload-time = "2025-11-26T02:36:25.291Z" }, { url = "https://files.pythonhosted.org/packages/cb/3c/0142bee993c431ee91cf5535e6e4b079ad491f620c215fcd79b7e5ffeb2b/fastar-0.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:b48abd6056fef7bc3d414aafb453c5b07fdf06d2df5a2841d650288a3aa1e9d3", size = 490863, upload-time = "2025-11-26T02:36:11.114Z" }, { url = "https://files.pythonhosted.org/packages/3b/18/d119944f6bdbf6e722e204e36db86390ea45684a1bf6be6e3aa42abd471f/fastar-0.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:50c18788b3c6ffb85e176dcb8548bb8e54616a0519dcdbbfba66f6bbc4316933", size = 462230, upload-time = "2025-11-26T02:36:01.917Z" }, + { url = "https://files.pythonhosted.org/packages/22/7e/1ae005addc789924a9268da2394d3bb5c6f96836f7e37b7e3d23c2362675/fastar-0.8.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9d210da2de733ca801de83e931012349d209f38b92d9630ccaa94bd445bdc9b8", size = 868938, upload-time = "2025-11-26T02:33:51.119Z" }, + { url = "https://files.pythonhosted.org/packages/a6/77/290a892b073b84bf82e6b2259708dfe79c54f356e252c2dd40180b16fe07/fastar-0.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa02270721517078a5bd61a38719070ac2537a4aa6b6c48cf369cf2abc59174a", size = 765204, upload-time = "2025-11-26T02:32:47.02Z" }, + { url = "https://files.pythonhosted.org/packages/d0/00/c3155171b976003af3281f5258189f1935b15d1221bfc7467b478c631216/fastar-0.8.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:83c391e5b789a720e4d0029b9559f5d6dee3226693c5b39c0eab8eaece997e0f", size = 764717, upload-time = "2025-11-26T02:33:02.453Z" }, + { url = "https://files.pythonhosted.org/packages/b7/43/405b7ad76207b2c11b7b59335b70eac19e4a2653977f5588a1ac8fed54f4/fastar-0.8.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3258d7a78a72793cdd081545da61cabe85b1f37634a1d0b97ffee0ff11d105ef", size = 931502, upload-time = "2025-11-26T02:33:18.619Z" }, + { url = "https://files.pythonhosted.org/packages/da/8a/a3dde6d37cc3da4453f2845cdf16675b5686b73b164f37e2cc579b057c2c/fastar-0.8.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e6eab95dd985cdb6a50666cbeb9e4814676e59cfe52039c880b69d67cfd44767", size = 821454, upload-time = "2025-11-26T02:33:33.427Z" }, + { url = "https://files.pythonhosted.org/packages/da/c1/904fe2468609c8990dce9fe654df3fbc7324a8d8e80d8240ae2c89757064/fastar-0.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:829b1854166141860887273c116c94e31357213fa8e9fe8baeb18bd6c38aa8d9", size = 821647, upload-time = "2025-11-26T02:34:07Z" }, + { url = "https://files.pythonhosted.org/packages/c8/73/a0642ab7a400bc07528091785e868ace598fde06fcd139b8f865ec1b6f3c/fastar-0.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b1667eae13f9457a3c737f4376d68e8c3e548353538b28f7e4273a30cb3965cd", size = 986342, upload-time = "2025-11-26T02:34:53.371Z" }, + { url = "https://files.pythonhosted.org/packages/af/af/60c1bfa6edab72366461a95f053d0f5f7ab1825fe65ca2ca367432cd8629/fastar-0.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b864a95229a7db0814cd9ef7987cb713fd43dce1b0d809dd17d9cd6f02fdde3e", size = 1040207, upload-time = "2025-11-26T02:35:10.65Z" }, + { url = "https://files.pythonhosted.org/packages/f6/a0/0d624290dec622e7fa084b6881f456809f68777d54a314f5dde932714506/fastar-0.8.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c05fbc5618ce17675a42576fa49858d79734627f0a0c74c0875ab45ee8de340c", size = 1045031, upload-time = "2025-11-26T02:35:28.108Z" }, + { url = "https://files.pythonhosted.org/packages/a7/74/cf663af53c4706ba88e6b4af44a6b0c3bd7d7ca09f079dc40647a8f06585/fastar-0.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7f41c51ee96f338662ee3c3df4840511ba3f9969606840f1b10b7cb633a3c716", size = 994877, upload-time = "2025-11-26T02:35:45.797Z" }, + { url = "https://files.pythonhosted.org/packages/52/17/444c8be6e77206050e350da7c338102b6cab384be937fa0b1d6d1f9ede73/fastar-0.8.0-cp312-cp312-win32.whl", hash = "sha256:d949a1a2ea7968b734632c009df0571c94636a5e1622c87a6e2bf712a7334f47", size = 455996, upload-time = "2025-11-26T02:36:26.938Z" }, + { url = "https://files.pythonhosted.org/packages/dc/34/fc3b5e56d71a17b1904800003d9251716e8fd65f662e1b10a26881698a74/fastar-0.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:fc645994d5b927d769121094e8a649b09923b3c13a8b0b98696d8f853f23c532", size = 490429, upload-time = "2025-11-26T02:36:12.707Z" }, + { url = "https://files.pythonhosted.org/packages/35/a8/5608cc837417107c594e2e7be850b9365bcb05e99645966a5d6a156285fe/fastar-0.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:d81ee82e8dc78a0adb81728383bd39611177d642a8fa2d601d4ad5ad59e5f3bd", size = 461297, upload-time = "2025-11-26T02:36:03.546Z" }, { url = "https://files.pythonhosted.org/packages/8f/ee/aa4d08aea25b5419a7277132e738ab1cd775f26aebddce11413b07e2fdff/fastar-0.8.0-pp311-pypy311_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:299672e1c74d8b73c61684fac9159cfc063d35f4b165996a88facb0e26862cb5", size = 872055, upload-time = "2025-11-26T02:34:01.377Z" }, { url = "https://files.pythonhosted.org/packages/92/9a/2bf2f77aade575e67997e0c759fd55cb1c66b7a5b437b1cd0e97d8b241bc/fastar-0.8.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3d3a27066b84d015deab5faee78565509bb33b137896443e4144cb1be1a5f90", size = 766787, upload-time = "2025-11-26T02:32:57.161Z" }, { url = "https://files.pythonhosted.org/packages/0b/90/23a3f6c252f11b10c70f854bce09abc61f71b5a0e6a4b0eac2bcb9a2c583/fastar-0.8.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ef0bcf4385bbdd3c1acecce2d9ea7dab7cc9b8ee0581bbccb7ab11908a7ce288", size = 766861, upload-time = "2025-11-26T02:33:12.824Z" }, @@ -734,6 +883,11 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c0/8f/65907405a8cdb2fc8beaf7d09a9a07bb58deff478ff391ca95be4f130b70/fastrlock-0.8.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c9d459ce344c21ff03268212a1845aa37feab634d242131bc16c2a2355d5f65", size = 53362, upload-time = "2024-12-17T11:02:12.476Z" }, { url = "https://files.pythonhosted.org/packages/ec/b9/ae6511e52738ba4e3a6adb7c6a20158573fbc98aab448992ece25abb0b07/fastrlock-0.8.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33e6fa4af4f3af3e9c747ec72d1eadc0b7ba2035456c2afb51c24d9e8a56f8fd", size = 52836, upload-time = "2024-12-17T11:02:13.74Z" }, { url = "https://files.pythonhosted.org/packages/88/3e/c26f8192c93e8e43b426787cec04bb46ac36e72b1033b7fe5a9267155fdf/fastrlock-0.8.3-cp311-cp311-win_amd64.whl", hash = "sha256:5e5f1665d8e70f4c5b4a67f2db202f354abc80a321ce5a26ac1493f055e3ae2c", size = 31046, upload-time = "2024-12-17T11:02:15.033Z" }, + { url = "https://files.pythonhosted.org/packages/57/21/ea1511b0ef0d5457efca3bf1823effb9c5cad4fc9dca86ce08e4d65330ce/fastrlock-0.8.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:85a49a1f1e020097d087e1963e42cea6f307897d5ebe2cb6daf4af47ffdd3eed", size = 52201, upload-time = "2024-12-17T11:02:19.512Z" }, + { url = "https://files.pythonhosted.org/packages/80/07/cdecb7aa976f34328372f1c4efd6c9dc1b039b3cc8d3f38787d640009a25/fastrlock-0.8.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5f13ec08f1adb1aa916c384b05ecb7dbebb8df9ea81abd045f60941c6283a670", size = 53924, upload-time = "2024-12-17T11:02:20.85Z" }, + { url = "https://files.pythonhosted.org/packages/88/6d/59c497f8db9a125066dd3a7442fab6aecbe90d6fec344c54645eaf311666/fastrlock-0.8.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0ea4e53a04980d646def0f5e4b5e8bd8c7884288464acab0b37ca0c65c482bfe", size = 52140, upload-time = "2024-12-17T11:02:22.263Z" }, + { url = "https://files.pythonhosted.org/packages/62/04/9138943c2ee803d62a48a3c17b69de2f6fa27677a6896c300369e839a550/fastrlock-0.8.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:38340f6635bd4ee2a4fb02a3a725759fe921f2ca846cb9ca44531ba739cc17b4", size = 53261, upload-time = "2024-12-17T11:02:24.418Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4b/db35a52589764c7745a613b6943bbd018f128d42177ab92ee7dde88444f6/fastrlock-0.8.3-cp312-cp312-win_amd64.whl", hash = "sha256:da06d43e1625e2ffddd303edcd6d2cd068e1c486f5fd0102b3f079c44eb13e2c", size = 31235, upload-time = "2024-12-17T11:02:25.708Z" }, ] [[package]] @@ -753,6 +907,17 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5a/87/93f553111b33f9bb83145be12868c3c475bf8ea87c107063d01377cc0e8e/fastuuid-0.14.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1e690d48f923c253f28151b3a6b4e335f2b06bf669c68a02665bc150b7839e94", size = 452317, upload-time = "2025-10-19T22:25:32.75Z" }, { url = "https://files.pythonhosted.org/packages/9e/8c/a04d486ca55b5abb7eaa65b39df8d891b7b1635b22db2163734dc273579a/fastuuid-0.14.0-cp311-cp311-win32.whl", hash = "sha256:a6f46790d59ab38c6aa0e35c681c0484b50dc0acf9e2679c005d61e019313c24", size = 154804, upload-time = "2025-10-19T22:24:15.615Z" }, { url = "https://files.pythonhosted.org/packages/9c/b2/2d40bf00820de94b9280366a122cbaa60090c8cf59e89ac3938cf5d75895/fastuuid-0.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:e150eab56c95dc9e3fefc234a0eedb342fac433dacc273cd4d150a5b0871e1fa", size = 156099, upload-time = "2025-10-19T22:24:31.646Z" }, + { url = "https://files.pythonhosted.org/packages/02/a2/e78fcc5df65467f0d207661b7ef86c5b7ac62eea337c0c0fcedbeee6fb13/fastuuid-0.14.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:77e94728324b63660ebf8adb27055e92d2e4611645bf12ed9d88d30486471d0a", size = 510164, upload-time = "2025-10-19T22:31:45.635Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b3/c846f933f22f581f558ee63f81f29fa924acd971ce903dab1a9b6701816e/fastuuid-0.14.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:caa1f14d2102cb8d353096bc6ef6c13b2c81f347e6ab9d6fbd48b9dea41c153d", size = 261837, upload-time = "2025-10-19T22:38:38.53Z" }, + { url = "https://files.pythonhosted.org/packages/54/ea/682551030f8c4fa9a769d9825570ad28c0c71e30cf34020b85c1f7ee7382/fastuuid-0.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d23ef06f9e67163be38cece704170486715b177f6baae338110983f99a72c070", size = 251370, upload-time = "2025-10-19T22:40:26.07Z" }, + { url = "https://files.pythonhosted.org/packages/14/dd/5927f0a523d8e6a76b70968e6004966ee7df30322f5fc9b6cdfb0276646a/fastuuid-0.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c9ec605ace243b6dbe3bd27ebdd5d33b00d8d1d3f580b39fdd15cd96fd71796", size = 277766, upload-time = "2025-10-19T22:37:23.779Z" }, + { url = "https://files.pythonhosted.org/packages/16/6e/c0fb547eef61293153348f12e0f75a06abb322664b34a1573a7760501336/fastuuid-0.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:808527f2407f58a76c916d6aa15d58692a4a019fdf8d4c32ac7ff303b7d7af09", size = 278105, upload-time = "2025-10-19T22:26:56.821Z" }, + { url = "https://files.pythonhosted.org/packages/2d/b1/b9c75e03b768f61cf2e84ee193dc18601aeaf89a4684b20f2f0e9f52b62c/fastuuid-0.14.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2fb3c0d7fef6674bbeacdd6dbd386924a7b60b26de849266d1ff6602937675c8", size = 301564, upload-time = "2025-10-19T22:30:31.604Z" }, + { url = "https://files.pythonhosted.org/packages/fc/fa/f7395fdac07c7a54f18f801744573707321ca0cee082e638e36452355a9d/fastuuid-0.14.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab3f5d36e4393e628a4df337c2c039069344db5f4b9d2a3c9cea48284f1dd741", size = 459659, upload-time = "2025-10-19T22:31:32.341Z" }, + { url = "https://files.pythonhosted.org/packages/66/49/c9fd06a4a0b1f0f048aacb6599e7d96e5d6bc6fa680ed0d46bf111929d1b/fastuuid-0.14.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b9a0ca4f03b7e0b01425281ffd44e99d360e15c895f1907ca105854ed85e2057", size = 478430, upload-time = "2025-10-19T22:26:22.962Z" }, + { url = "https://files.pythonhosted.org/packages/be/9c/909e8c95b494e8e140e8be6165d5fc3f61fdc46198c1554df7b3e1764471/fastuuid-0.14.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3acdf655684cc09e60fb7e4cf524e8f42ea760031945aa8086c7eae2eeeabeb8", size = 450894, upload-time = "2025-10-19T22:27:01.647Z" }, + { url = "https://files.pythonhosted.org/packages/90/eb/d29d17521976e673c55ef7f210d4cdd72091a9ec6755d0fd4710d9b3c871/fastuuid-0.14.0-cp312-cp312-win32.whl", hash = "sha256:9579618be6280700ae36ac42c3efd157049fe4dd40ca49b021280481c78c3176", size = 154374, upload-time = "2025-10-19T22:29:19.879Z" }, + { url = "https://files.pythonhosted.org/packages/cc/fc/f5c799a6ea6d877faec0472d0b27c079b47c86b1cdc577720a5386483b36/fastuuid-0.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:d9e4332dc4ba054434a9594cbfaf7823b57993d7d8e7267831c3e059857cf397", size = 156550, upload-time = "2025-10-19T22:27:49.658Z" }, ] [[package]] @@ -776,22 +941,27 @@ sdist = { url = "https://files.pythonhosted.org/packages/3b/b2/8d76c41ad7974ee26 [[package]] name = "flashinfer-python" -version = "0.3.1" +version = "0.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ + { name = "apache-tvm-ffi" }, { name = "click" }, { name = "einops" }, { name = "ninja" }, { name = "numpy" }, { name = "nvidia-cudnn-frontend" }, + { name = "nvidia-cutlass-dsl" }, + { name = "nvidia-ml-py" }, { name = "packaging" }, - { name = "pynvml" }, { name = "requests" }, { name = "tabulate" }, { name = "torch" }, { name = "tqdm" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ba/71/dd3001b8be8174d90561764a5f3be4ca219517bde2841189ea6973a3873f/flashinfer_python-0.3.1.tar.gz", hash = "sha256:992017d193dfbbc62e67401a6d5416629bf90b640872d14b7863de45e9371446", size = 3817118, upload-time = "2025-09-05T06:21:45.229Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/1d/b82cd2606f4f0033e2fb28194dc3b04fd8101643e4ceb1d13fb1466cfd28/flashinfer_python-0.5.0.tar.gz", hash = "sha256:68692f9cdfe8fcd75b6940fc5f9f400bdd7a68d6aaae20a225cc63ad1484d133", size = 4627840, upload-time = "2025-11-02T05:59:21.868Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/8a/425b75b44ce5eeefe01dd61d4ee260b8e5f9dcf1a500d5f08d6cd4095d3a/flashinfer_python-0.5.0-py3-none-any.whl", hash = "sha256:f02f13c616482617e7bee0031e5777a3328989a0b1842496ce273086f6a5aeab", size = 6932399, upload-time = "2025-11-02T05:59:19.782Z" }, +] [[package]] name = "fonttools" @@ -807,9 +977,26 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0c/d5/495fc7ae2fab20223cc87179a8f50f40f9a6f821f271ba8301ae12bb580f/fonttools-4.60.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f4b5c37a5f40e4d733d3bbaaef082149bee5a5ea3156a785ff64d949bd1353fa", size = 5132562, upload-time = "2025-09-29T21:11:32.737Z" }, { url = "https://files.pythonhosted.org/packages/bc/fa/021dab618526323c744e0206b3f5c8596a2e7ae9aa38db5948a131123e83/fonttools-4.60.1-cp311-cp311-win32.whl", hash = "sha256:398447f3d8c0c786cbf1209711e79080a40761eb44b27cdafffb48f52bcec258", size = 2230288, upload-time = "2025-09-29T21:11:35.015Z" }, { url = "https://files.pythonhosted.org/packages/bb/78/0e1a6d22b427579ea5c8273e1c07def2f325b977faaf60bb7ddc01456cb1/fonttools-4.60.1-cp311-cp311-win_amd64.whl", hash = "sha256:d066ea419f719ed87bc2c99a4a4bfd77c2e5949cb724588b9dd58f3fd90b92bf", size = 2278184, upload-time = "2025-09-29T21:11:37.434Z" }, + { url = "https://files.pythonhosted.org/packages/e3/f7/a10b101b7a6f8836a5adb47f2791f2075d044a6ca123f35985c42edc82d8/fonttools-4.60.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:7b0c6d57ab00dae9529f3faf187f2254ea0aa1e04215cf2f1a8ec277c96661bc", size = 2832953, upload-time = "2025-09-29T21:11:39.616Z" }, + { url = "https://files.pythonhosted.org/packages/ed/fe/7bd094b59c926acf2304d2151354ddbeb74b94812f3dc943c231db09cb41/fonttools-4.60.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:839565cbf14645952d933853e8ade66a463684ed6ed6c9345d0faf1f0e868877", size = 2352706, upload-time = "2025-09-29T21:11:41.826Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ca/4bb48a26ed95a1e7eba175535fe5805887682140ee0a0d10a88e1de84208/fonttools-4.60.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8177ec9676ea6e1793c8a084a90b65a9f778771998eb919d05db6d4b1c0b114c", size = 4923716, upload-time = "2025-09-29T21:11:43.893Z" }, + { url = "https://files.pythonhosted.org/packages/b8/9f/2cb82999f686c1d1ddf06f6ae1a9117a880adbec113611cc9d22b2fdd465/fonttools-4.60.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:996a4d1834524adbb423385d5a629b868ef9d774670856c63c9a0408a3063401", size = 4968175, upload-time = "2025-09-29T21:11:46.439Z" }, + { url = "https://files.pythonhosted.org/packages/18/79/be569699e37d166b78e6218f2cde8c550204f2505038cdd83b42edc469b9/fonttools-4.60.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a46b2f450bc79e06ef3b6394f0c68660529ed51692606ad7f953fc2e448bc903", size = 4911031, upload-time = "2025-09-29T21:11:48.977Z" }, + { url = "https://files.pythonhosted.org/packages/cc/9f/89411cc116effaec5260ad519162f64f9c150e5522a27cbb05eb62d0c05b/fonttools-4.60.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6ec722ee589e89a89f5b7574f5c45604030aa6ae24cb2c751e2707193b466fed", size = 5062966, upload-time = "2025-09-29T21:11:54.344Z" }, + { url = "https://files.pythonhosted.org/packages/62/a1/f888221934b5731d46cb9991c7a71f30cb1f97c0ef5fcf37f8da8fce6c8e/fonttools-4.60.1-cp312-cp312-win32.whl", hash = "sha256:b2cf105cee600d2de04ca3cfa1f74f1127f8455b71dbad02b9da6ec266e116d6", size = 2218750, upload-time = "2025-09-29T21:11:56.601Z" }, + { url = "https://files.pythonhosted.org/packages/88/8f/a55b5550cd33cd1028601df41acd057d4be20efa5c958f417b0c0613924d/fonttools-4.60.1-cp312-cp312-win_amd64.whl", hash = "sha256:992775c9fbe2cf794786fa0ffca7f09f564ba3499b8fe9f2f80bd7197db60383", size = 2267026, upload-time = "2025-09-29T21:11:58.852Z" }, { url = "https://files.pythonhosted.org/packages/c7/93/0dd45cd283c32dea1545151d8c3637b4b8c53cdb3a625aeb2885b184d74d/fonttools-4.60.1-py3-none-any.whl", hash = "sha256:906306ac7afe2156fcf0042173d6ebbb05416af70f6b370967b47f8f00103bbb", size = 1143175, upload-time = "2025-09-29T21:13:24.134Z" }, ] +[[package]] +name = "frozendict" +version = "2.4.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/90/b2/2a3d1374b7780999d3184e171e25439a8358c47b481f68be883c14086b4c/frozendict-2.4.7.tar.gz", hash = "sha256:e478fb2a1391a56c8a6e10cc97c4a9002b410ecd1ac28c18d780661762e271bd", size = 317082, upload-time = "2025-11-11T22:40:14.251Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/74/f94141b38a51a553efef7f510fc213894161ae49b88bffd037f8d2a7cb2f/frozendict-2.4.7-py3-none-any.whl", hash = "sha256:972af65924ea25cf5b4d9326d549e69a9a4918d8a76a9d3a7cd174d98b237550", size = 16264, upload-time = "2025-11-11T22:40:12.836Z" }, +] + [[package]] name = "frozenlist" version = "1.8.0" @@ -832,6 +1019,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/95/a3/c8fb25aac55bf5e12dae5c5aa6a98f85d436c1dc658f21c3ac73f9fa95e5/frozenlist-1.8.0-cp311-cp311-win32.whl", hash = "sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25", size = 39647, upload-time = "2025-10-06T05:36:03.409Z" }, { url = "https://files.pythonhosted.org/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b", size = 44064, upload-time = "2025-10-06T05:36:04.368Z" }, { url = "https://files.pythonhosted.org/packages/5d/16/c2c9ab44e181f043a86f9a8f84d5124b62dbcb3a02c0977ec72b9ac1d3e0/frozenlist-1.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a", size = 39937, upload-time = "2025-10-06T05:36:05.669Z" }, + { url = "https://files.pythonhosted.org/packages/69/29/948b9aa87e75820a38650af445d2ef2b6b8a6fab1a23b6bb9e4ef0be2d59/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", size = 87782, upload-time = "2025-10-06T05:36:06.649Z" }, + { url = "https://files.pythonhosted.org/packages/64/80/4f6e318ee2a7c0750ed724fa33a4bdf1eacdc5a39a7a24e818a773cd91af/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", size = 50594, upload-time = "2025-10-06T05:36:07.69Z" }, + { url = "https://files.pythonhosted.org/packages/2b/94/5c8a2b50a496b11dd519f4a24cb5496cf125681dd99e94c604ccdea9419a/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", size = 50448, upload-time = "2025-10-06T05:36:08.78Z" }, + { url = "https://files.pythonhosted.org/packages/6a/bd/d91c5e39f490a49df14320f4e8c80161cfcce09f1e2cde1edd16a551abb3/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383", size = 242411, upload-time = "2025-10-06T05:36:09.801Z" }, + { url = "https://files.pythonhosted.org/packages/8f/83/f61505a05109ef3293dfb1ff594d13d64a2324ac3482be2cedc2be818256/frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4", size = 243014, upload-time = "2025-10-06T05:36:11.394Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cb/cb6c7b0f7d4023ddda30cf56b8b17494eb3a79e3fda666bf735f63118b35/frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8", size = 234909, upload-time = "2025-10-06T05:36:12.598Z" }, + { url = "https://files.pythonhosted.org/packages/31/c5/cd7a1f3b8b34af009fb17d4123c5a778b44ae2804e3ad6b86204255f9ec5/frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b", size = 250049, upload-time = "2025-10-06T05:36:14.065Z" }, + { url = "https://files.pythonhosted.org/packages/c0/01/2f95d3b416c584a1e7f0e1d6d31998c4a795f7544069ee2e0962a4b60740/frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52", size = 256485, upload-time = "2025-10-06T05:36:15.39Z" }, + { url = "https://files.pythonhosted.org/packages/ce/03/024bf7720b3abaebcff6d0793d73c154237b85bdf67b7ed55e5e9596dc9a/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29", size = 237619, upload-time = "2025-10-06T05:36:16.558Z" }, + { url = "https://files.pythonhosted.org/packages/69/fa/f8abdfe7d76b731f5d8bd217827cf6764d4f1d9763407e42717b4bed50a0/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3", size = 250320, upload-time = "2025-10-06T05:36:17.821Z" }, + { url = "https://files.pythonhosted.org/packages/f5/3c/b051329f718b463b22613e269ad72138cc256c540f78a6de89452803a47d/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143", size = 246820, upload-time = "2025-10-06T05:36:19.046Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/58282e8f98e444b3f4dd42448ff36fa38bef29e40d40f330b22e7108f565/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608", size = 250518, upload-time = "2025-10-06T05:36:20.763Z" }, + { url = "https://files.pythonhosted.org/packages/8f/96/007e5944694d66123183845a106547a15944fbbb7154788cbf7272789536/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa", size = 239096, upload-time = "2025-10-06T05:36:22.129Z" }, + { url = "https://files.pythonhosted.org/packages/66/bb/852b9d6db2fa40be96f29c0d1205c306288f0684df8fd26ca1951d461a56/frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf", size = 39985, upload-time = "2025-10-06T05:36:23.661Z" }, + { url = "https://files.pythonhosted.org/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591, upload-time = "2025-10-06T05:36:24.958Z" }, + { url = "https://files.pythonhosted.org/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102, upload-time = "2025-10-06T05:36:26.333Z" }, { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, ] @@ -915,6 +1118,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/75/7a/766149dcfa2dfa81835bf7df623944c1f636a15fcb9b6138ebe29baf0bc6/grpcio-1.67.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1a65b503d008f066e994f34f456e0647e5ceb34cfcec5ad180b1b44020ad4970", size = 6161799, upload-time = "2024-10-29T06:24:22.604Z" }, { url = "https://files.pythonhosted.org/packages/09/13/5b75ae88810aaea19e846f5380611837de411181df51fd7a7d10cb178dcb/grpcio-1.67.1-cp311-cp311-win32.whl", hash = "sha256:e29ca27bec8e163dca0c98084040edec3bc49afd10f18b412f483cc68c712744", size = 3616330, upload-time = "2024-10-29T06:24:25.775Z" }, { url = "https://files.pythonhosted.org/packages/aa/39/38117259613f68f072778c9638a61579c0cfa5678c2558706b10dd1d11d3/grpcio-1.67.1-cp311-cp311-win_amd64.whl", hash = "sha256:786a5b18544622bfb1e25cc08402bd44ea83edfb04b93798d85dca4d1a0b5be5", size = 4354535, upload-time = "2024-10-29T06:24:28.614Z" }, + { url = "https://files.pythonhosted.org/packages/6e/25/6f95bd18d5f506364379eabc0d5874873cc7dbdaf0757df8d1e82bc07a88/grpcio-1.67.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:267d1745894200e4c604958da5f856da6293f063327cb049a51fe67348e4f953", size = 5089809, upload-time = "2024-10-29T06:24:31.24Z" }, + { url = "https://files.pythonhosted.org/packages/10/3f/d79e32e5d0354be33a12db2267c66d3cfeff700dd5ccdd09fd44a3ff4fb6/grpcio-1.67.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:85f69fdc1d28ce7cff8de3f9c67db2b0ca9ba4449644488c1e0303c146135ddb", size = 10981985, upload-time = "2024-10-29T06:24:34.942Z" }, + { url = "https://files.pythonhosted.org/packages/21/f2/36fbc14b3542e3a1c20fb98bd60c4732c55a44e374a4eb68f91f28f14aab/grpcio-1.67.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:f26b0b547eb8d00e195274cdfc63ce64c8fc2d3e2d00b12bf468ece41a0423a0", size = 5588770, upload-time = "2024-10-29T06:24:38.145Z" }, + { url = "https://files.pythonhosted.org/packages/0d/af/bbc1305df60c4e65de8c12820a942b5e37f9cf684ef5e49a63fbb1476a73/grpcio-1.67.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4422581cdc628f77302270ff839a44f4c24fdc57887dc2a45b7e53d8fc2376af", size = 6214476, upload-time = "2024-10-29T06:24:41.006Z" }, + { url = "https://files.pythonhosted.org/packages/92/cf/1d4c3e93efa93223e06a5c83ac27e32935f998bc368e276ef858b8883154/grpcio-1.67.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d7616d2ded471231c701489190379e0c311ee0a6c756f3c03e6a62b95a7146e", size = 5850129, upload-time = "2024-10-29T06:24:43.553Z" }, + { url = "https://files.pythonhosted.org/packages/ae/ca/26195b66cb253ac4d5ef59846e354d335c9581dba891624011da0e95d67b/grpcio-1.67.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8a00efecde9d6fcc3ab00c13f816313c040a28450e5e25739c24f432fc6d3c75", size = 6568489, upload-time = "2024-10-29T06:24:46.453Z" }, + { url = "https://files.pythonhosted.org/packages/d1/94/16550ad6b3f13b96f0856ee5dfc2554efac28539ee84a51d7b14526da985/grpcio-1.67.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:699e964923b70f3101393710793289e42845791ea07565654ada0969522d0a38", size = 6149369, upload-time = "2024-10-29T06:24:49.112Z" }, + { url = "https://files.pythonhosted.org/packages/33/0d/4c3b2587e8ad7f121b597329e6c2620374fccbc2e4e1aa3c73ccc670fde4/grpcio-1.67.1-cp312-cp312-win32.whl", hash = "sha256:4e7b904484a634a0fff132958dabdb10d63e0927398273917da3ee103e8d1f78", size = 3599176, upload-time = "2024-10-29T06:24:51.443Z" }, + { url = "https://files.pythonhosted.org/packages/7d/36/0c03e2d80db69e2472cf81c6123aa7d14741de7cf790117291a703ae6ae1/grpcio-1.67.1-cp312-cp312-win_amd64.whl", hash = "sha256:5721e66a594a6c4204458004852719b38f3d5522082be9061d6510b455c90afc", size = 4346574, upload-time = "2024-10-29T06:24:54.587Z" }, ] [[package]] @@ -1009,6 +1221,11 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/30/e1/44f89b280f7e46c0b1b2ccee5737d46b3bb13136383958f20b580a821ca0/httptools-0.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274", size = 440175, upload-time = "2025-10-10T03:54:35.942Z" }, { url = "https://files.pythonhosted.org/packages/6f/7e/b9287763159e700e335028bc1824359dc736fa9b829dacedace91a39b37e/httptools-0.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec", size = 440310, upload-time = "2025-10-10T03:54:37.1Z" }, { url = "https://files.pythonhosted.org/packages/b3/07/5b614f592868e07f5c94b1f301b5e14a21df4e8076215a3bccb830a687d8/httptools-0.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb", size = 86875, upload-time = "2025-10-10T03:54:38.421Z" }, + { url = "https://files.pythonhosted.org/packages/84/a6/b3965e1e146ef5762870bbe76117876ceba51a201e18cc31f5703e454596/httptools-0.7.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03", size = 517655, upload-time = "2025-10-10T03:54:41.347Z" }, + { url = "https://files.pythonhosted.org/packages/11/7d/71fee6f1844e6fa378f2eddde6c3e41ce3a1fb4b2d81118dd544e3441ec0/httptools-0.7.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2", size = 511440, upload-time = "2025-10-10T03:54:42.452Z" }, + { url = "https://files.pythonhosted.org/packages/22/a5/079d216712a4f3ffa24af4a0381b108aa9c45b7a5cc6eb141f81726b1823/httptools-0.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362", size = 495186, upload-time = "2025-10-10T03:54:43.937Z" }, + { url = "https://files.pythonhosted.org/packages/e9/9e/025ad7b65278745dee3bd0ebf9314934c4592560878308a6121f7f812084/httptools-0.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c", size = 499192, upload-time = "2025-10-10T03:54:45.003Z" }, + { url = "https://files.pythonhosted.org/packages/6d/de/40a8f202b987d43afc4d54689600ff03ce65680ede2f31df348d7f368b8f/httptools-0.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321", size = 86694, upload-time = "2025-10-10T03:54:45.923Z" }, ] [[package]] @@ -1147,10 +1364,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ca/e4/7df62002499080dbd61b505c5cb351aa09e9959d176cac2aa8da6f93b13b/jiter-0.12.0-cp311-cp311-win32.whl", hash = "sha256:453b6035672fecce8007465896a25b28a6b59cfe8fbc974b2563a92f5a92a67c", size = 206096, upload-time = "2025-11-09T20:47:17.344Z" }, { url = "https://files.pythonhosted.org/packages/bb/60/1032b30ae0572196b0de0e87dce3b6c26a1eff71aad5fe43dee3082d32e0/jiter-0.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:ca264b9603973c2ad9435c71a8ec8b49f8f715ab5ba421c85a51cde9887e421f", size = 204899, upload-time = "2025-11-09T20:47:19.365Z" }, { url = "https://files.pythonhosted.org/packages/49/d5/c145e526fccdb834063fb45c071df78b0cc426bbaf6de38b0781f45d956f/jiter-0.12.0-cp311-cp311-win_arm64.whl", hash = "sha256:cb00ef392e7d684f2754598c02c409f376ddcef857aae796d559e6cacc2d78a5", size = 188070, upload-time = "2025-11-09T20:47:20.75Z" }, + { url = "https://files.pythonhosted.org/packages/92/c9/5b9f7b4983f1b542c64e84165075335e8a236fa9e2ea03a0c79780062be8/jiter-0.12.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:305e061fa82f4680607a775b2e8e0bcb071cd2205ac38e6ef48c8dd5ebe1cf37", size = 314449, upload-time = "2025-11-09T20:47:22.999Z" }, + { url = "https://files.pythonhosted.org/packages/98/6e/e8efa0e78de00db0aee82c0cf9e8b3f2027efd7f8a71f859d8f4be8e98ef/jiter-0.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5c1860627048e302a528333c9307c818c547f214d8659b0705d2195e1a94b274", size = 319855, upload-time = "2025-11-09T20:47:24.779Z" }, + { url = "https://files.pythonhosted.org/packages/20/26/894cd88e60b5d58af53bec5c6759d1292bd0b37a8b5f60f07abf7a63ae5f/jiter-0.12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df37577a4f8408f7e0ec3205d2a8f87672af8f17008358063a4d6425b6081ce3", size = 350171, upload-time = "2025-11-09T20:47:26.469Z" }, + { url = "https://files.pythonhosted.org/packages/f5/27/a7b818b9979ac31b3763d25f3653ec3a954044d5e9f5d87f2f247d679fd1/jiter-0.12.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:75fdd787356c1c13a4f40b43c2156276ef7a71eb487d98472476476d803fb2cf", size = 365590, upload-time = "2025-11-09T20:47:27.918Z" }, + { url = "https://files.pythonhosted.org/packages/ba/7e/e46195801a97673a83746170b17984aa8ac4a455746354516d02ca5541b4/jiter-0.12.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1eb5db8d9c65b112aacf14fcd0faae9913d07a8afea5ed06ccdd12b724e966a1", size = 479462, upload-time = "2025-11-09T20:47:29.654Z" }, + { url = "https://files.pythonhosted.org/packages/ca/75/f833bfb009ab4bd11b1c9406d333e3b4357709ed0570bb48c7c06d78c7dd/jiter-0.12.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:73c568cc27c473f82480abc15d1301adf333a7ea4f2e813d6a2c7d8b6ba8d0df", size = 378983, upload-time = "2025-11-09T20:47:31.026Z" }, + { url = "https://files.pythonhosted.org/packages/71/b3/7a69d77943cc837d30165643db753471aff5df39692d598da880a6e51c24/jiter-0.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4321e8a3d868919bcb1abb1db550d41f2b5b326f72df29e53b2df8b006eb9403", size = 361328, upload-time = "2025-11-09T20:47:33.286Z" }, + { url = "https://files.pythonhosted.org/packages/b0/ac/a78f90caf48d65ba70d8c6efc6f23150bc39dc3389d65bbec2a95c7bc628/jiter-0.12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0a51bad79f8cc9cac2b4b705039f814049142e0050f30d91695a2d9a6611f126", size = 386740, upload-time = "2025-11-09T20:47:34.703Z" }, + { url = "https://files.pythonhosted.org/packages/39/b6/5d31c2cc8e1b6a6bcf3c5721e4ca0a3633d1ab4754b09bc7084f6c4f5327/jiter-0.12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:2a67b678f6a5f1dd6c36d642d7db83e456bc8b104788262aaefc11a22339f5a9", size = 520875, upload-time = "2025-11-09T20:47:36.058Z" }, + { url = "https://files.pythonhosted.org/packages/30/b5/4df540fae4e9f68c54b8dab004bd8c943a752f0b00efd6e7d64aa3850339/jiter-0.12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efe1a211fe1fd14762adea941e3cfd6c611a136e28da6c39272dbb7a1bbe6a86", size = 511457, upload-time = "2025-11-09T20:47:37.932Z" }, + { url = "https://files.pythonhosted.org/packages/07/65/86b74010e450a1a77b2c1aabb91d4a91dd3cd5afce99f34d75fd1ac64b19/jiter-0.12.0-cp312-cp312-win32.whl", hash = "sha256:d779d97c834b4278276ec703dc3fc1735fca50af63eb7262f05bdb4e62203d44", size = 204546, upload-time = "2025-11-09T20:47:40.47Z" }, + { url = "https://files.pythonhosted.org/packages/1c/c7/6659f537f9562d963488e3e55573498a442503ced01f7e169e96a6110383/jiter-0.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:e8269062060212b373316fe69236096aaf4c49022d267c6736eebd66bbbc60bb", size = 205196, upload-time = "2025-11-09T20:47:41.794Z" }, + { url = "https://files.pythonhosted.org/packages/21/f4/935304f5169edadfec7f9c01eacbce4c90bb9a82035ac1de1f3bd2d40be6/jiter-0.12.0-cp312-cp312-win_arm64.whl", hash = "sha256:06cb970936c65de926d648af0ed3d21857f026b1cf5525cb2947aa5e01e05789", size = 186100, upload-time = "2025-11-09T20:47:43.007Z" }, { url = "https://files.pythonhosted.org/packages/fe/54/5339ef1ecaa881c6948669956567a64d2670941925f245c434f494ffb0e5/jiter-0.12.0-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:4739a4657179ebf08f85914ce50332495811004cc1747852e8b2041ed2aab9b8", size = 311144, upload-time = "2025-11-09T20:49:10.503Z" }, { url = "https://files.pythonhosted.org/packages/27/74/3446c652bffbd5e81ab354e388b1b5fc1d20daac34ee0ed11ff096b1b01a/jiter-0.12.0-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:41da8def934bf7bec16cb24bd33c0ca62126d2d45d81d17b864bd5ad721393c3", size = 305877, upload-time = "2025-11-09T20:49:12.269Z" }, { url = "https://files.pythonhosted.org/packages/a1/f4/ed76ef9043450f57aac2d4fbeb27175aa0eb9c38f833be6ef6379b3b9a86/jiter-0.12.0-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c44ee814f499c082e69872d426b624987dbc5943ab06e9bbaa4f81989fdb79e", size = 340419, upload-time = "2025-11-09T20:49:13.803Z" }, { url = "https://files.pythonhosted.org/packages/21/01/857d4608f5edb0664aa791a3d45702e1a5bcfff9934da74035e7b9803846/jiter-0.12.0-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd2097de91cf03eaa27b3cbdb969addf83f0179c6afc41bbc4513705e013c65d", size = 347212, upload-time = "2025-11-09T20:49:15.643Z" }, + { url = "https://files.pythonhosted.org/packages/cb/f5/12efb8ada5f5c9edc1d4555fe383c1fb2eac05ac5859258a72d61981d999/jiter-0.12.0-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:e8547883d7b96ef2e5fe22b88f8a4c8725a56e7f4abafff20fd5272d634c7ecb", size = 309974, upload-time = "2025-11-09T20:49:17.187Z" }, + { url = "https://files.pythonhosted.org/packages/85/15/d6eb3b770f6a0d332675141ab3962fd4a7c270ede3515d9f3583e1d28276/jiter-0.12.0-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:89163163c0934854a668ed783a2546a0617f71706a2551a4a0666d91ab365d6b", size = 304233, upload-time = "2025-11-09T20:49:18.734Z" }, + { url = "https://files.pythonhosted.org/packages/8c/3e/e7e06743294eea2cf02ced6aa0ff2ad237367394e37a0e2b4a1108c67a36/jiter-0.12.0-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d96b264ab7d34bbb2312dedc47ce07cd53f06835eacbc16dde3761f47c3a9e7f", size = 338537, upload-time = "2025-11-09T20:49:20.317Z" }, + { url = "https://files.pythonhosted.org/packages/2f/9c/6753e6522b8d0ef07d3a3d239426669e984fb0eba15a315cdbc1253904e4/jiter-0.12.0-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c24e864cb30ab82311c6425655b0cdab0a98c5d973b065c66a3f020740c2324c", size = 346110, upload-time = "2025-11-09T20:49:21.817Z" }, ] [[package]] @@ -1217,6 +1451,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/62/86/b589e5e86c7610842213994cdea5add00960076bef4ae290c5fa68589cac/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f117e1a089d9411663a3207ba874f31be9ac8eaa5b533787024dc07aeb74f464", size = 2268071, upload-time = "2025-08-10T21:26:06.686Z" }, { url = "https://files.pythonhosted.org/packages/3b/c6/f8df8509fd1eee6c622febe54384a96cfaf4d43bf2ccec7a0cc17e4715c9/kiwisolver-1.4.9-cp311-cp311-win_amd64.whl", hash = "sha256:be6a04e6c79819c9a8c2373317d19a96048e5a3f90bec587787e86a1153883c2", size = 73840, upload-time = "2025-08-10T21:26:07.94Z" }, { url = "https://files.pythonhosted.org/packages/e2/2d/16e0581daafd147bc11ac53f032a2b45eabac897f42a338d0a13c1e5c436/kiwisolver-1.4.9-cp311-cp311-win_arm64.whl", hash = "sha256:0ae37737256ba2de764ddc12aed4956460277f00c4996d51a197e72f62f5eec7", size = 65159, upload-time = "2025-08-10T21:26:09.048Z" }, + { url = "https://files.pythonhosted.org/packages/86/c9/13573a747838aeb1c76e3267620daa054f4152444d1f3d1a2324b78255b5/kiwisolver-1.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ac5a486ac389dddcc5bef4f365b6ae3ffff2c433324fb38dd35e3fab7c957999", size = 123686, upload-time = "2025-08-10T21:26:10.034Z" }, + { url = "https://files.pythonhosted.org/packages/51/ea/2ecf727927f103ffd1739271ca19c424d0e65ea473fbaeea1c014aea93f6/kiwisolver-1.4.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2ba92255faa7309d06fe44c3a4a97efe1c8d640c2a79a5ef728b685762a6fd2", size = 66460, upload-time = "2025-08-10T21:26:11.083Z" }, + { url = "https://files.pythonhosted.org/packages/5b/5a/51f5464373ce2aeb5194508298a508b6f21d3867f499556263c64c621914/kiwisolver-1.4.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a2899935e724dd1074cb568ce7ac0dce28b2cd6ab539c8e001a8578eb106d14", size = 64952, upload-time = "2025-08-10T21:26:12.058Z" }, + { url = "https://files.pythonhosted.org/packages/70/90/6d240beb0f24b74371762873e9b7f499f1e02166a2d9c5801f4dbf8fa12e/kiwisolver-1.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f6008a4919fdbc0b0097089f67a1eb55d950ed7e90ce2cc3e640abadd2757a04", size = 1474756, upload-time = "2025-08-10T21:26:13.096Z" }, + { url = "https://files.pythonhosted.org/packages/12/42/f36816eaf465220f683fb711efdd1bbf7a7005a2473d0e4ed421389bd26c/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67bb8b474b4181770f926f7b7d2f8c0248cbcb78b660fdd41a47054b28d2a752", size = 1276404, upload-time = "2025-08-10T21:26:14.457Z" }, + { url = "https://files.pythonhosted.org/packages/2e/64/bc2de94800adc830c476dce44e9b40fd0809cddeef1fde9fcf0f73da301f/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2327a4a30d3ee07d2fbe2e7933e8a37c591663b96ce42a00bc67461a87d7df77", size = 1294410, upload-time = "2025-08-10T21:26:15.73Z" }, + { url = "https://files.pythonhosted.org/packages/5f/42/2dc82330a70aa8e55b6d395b11018045e58d0bb00834502bf11509f79091/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a08b491ec91b1d5053ac177afe5290adacf1f0f6307d771ccac5de30592d198", size = 1343631, upload-time = "2025-08-10T21:26:17.045Z" }, + { url = "https://files.pythonhosted.org/packages/22/fd/f4c67a6ed1aab149ec5a8a401c323cee7a1cbe364381bb6c9c0d564e0e20/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8fc5c867c22b828001b6a38d2eaeb88160bf5783c6cb4a5e440efc981ce286d", size = 2224963, upload-time = "2025-08-10T21:26:18.737Z" }, + { url = "https://files.pythonhosted.org/packages/45/aa/76720bd4cb3713314677d9ec94dcc21ced3f1baf4830adde5bb9b2430a5f/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3b3115b2581ea35bb6d1f24a4c90af37e5d9b49dcff267eeed14c3893c5b86ab", size = 2321295, upload-time = "2025-08-10T21:26:20.11Z" }, + { url = "https://files.pythonhosted.org/packages/80/19/d3ec0d9ab711242f56ae0dc2fc5d70e298bb4a1f9dfab44c027668c673a1/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858e4c22fb075920b96a291928cb7dea5644e94c0ee4fcd5af7e865655e4ccf2", size = 2487987, upload-time = "2025-08-10T21:26:21.49Z" }, + { url = "https://files.pythonhosted.org/packages/39/e9/61e4813b2c97e86b6fdbd4dd824bf72d28bcd8d4849b8084a357bc0dd64d/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ed0fecd28cc62c54b262e3736f8bb2512d8dcfdc2bcf08be5f47f96bf405b145", size = 2291817, upload-time = "2025-08-10T21:26:22.812Z" }, + { url = "https://files.pythonhosted.org/packages/a0/41/85d82b0291db7504da3c2defe35c9a8a5c9803a730f297bd823d11d5fb77/kiwisolver-1.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:f68208a520c3d86ea51acf688a3e3002615a7f0238002cccc17affecc86a8a54", size = 73895, upload-time = "2025-08-10T21:26:24.37Z" }, + { url = "https://files.pythonhosted.org/packages/e2/92/5f3068cf15ee5cb624a0c7596e67e2a0bb2adee33f71c379054a491d07da/kiwisolver-1.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:2c1a4f57df73965f3f14df20b80ee29e6a7930a57d2d9e8491a25f676e197c60", size = 64992, upload-time = "2025-08-10T21:26:25.732Z" }, { url = "https://files.pythonhosted.org/packages/a3/0f/36d89194b5a32c054ce93e586d4049b6c2c22887b0eb229c61c68afd3078/kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:720e05574713db64c356e86732c0f3c5252818d05f9df320f0ad8380641acea5", size = 60104, upload-time = "2025-08-10T21:27:43.287Z" }, { url = "https://files.pythonhosted.org/packages/52/ba/4ed75f59e4658fd21fe7dde1fee0ac397c678ec3befba3fe6482d987af87/kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:17680d737d5335b552994a2008fab4c851bcd7de33094a82067ef3a576ff02fa", size = 58592, upload-time = "2025-08-10T21:27:44.314Z" }, { url = "https://files.pythonhosted.org/packages/33/01/a8ea7c5ea32a9b45ceeaee051a04c8ed4320f5add3c51bfa20879b765b70/kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:85b5352f94e490c028926ea567fc569c52ec79ce131dadb968d3853e809518c2", size = 80281, upload-time = "2025-08-10T21:27:45.369Z" }, @@ -1298,11 +1545,14 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/99/fe/d030f1849ebb1f394bb3f7adad5e729b634fb100515594aca25c354ffc62/llvmlite-0.44.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5d22c3bfc842668168a786af4205ec8e3ad29fb1bc03fd11fd48460d0df64c1", size = 42361858, upload-time = "2025-01-20T11:13:07.623Z" }, { url = "https://files.pythonhosted.org/packages/d7/7a/ce6174664b9077fc673d172e4c888cb0b128e707e306bc33fff8c2035f0d/llvmlite-0.44.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f01a394e9c9b7b1d4e63c327b096d10f6f0ed149ef53d38a09b3749dcf8c9610", size = 41184200, upload-time = "2025-01-20T11:13:20.058Z" }, { url = "https://files.pythonhosted.org/packages/5f/c6/258801143975a6d09a373f2641237992496e15567b907a4d401839d671b8/llvmlite-0.44.0-cp311-cp311-win_amd64.whl", hash = "sha256:d8489634d43c20cd0ad71330dde1d5bc7b9966937a263ff1ec1cebb90dc50955", size = 30331193, upload-time = "2025-01-20T11:13:26.976Z" }, + { url = "https://files.pythonhosted.org/packages/cb/da/8341fd3056419441286c8e26bf436923021005ece0bff5f41906476ae514/llvmlite-0.44.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0143a5ef336da14deaa8ec26c5449ad5b6a2b564df82fcef4be040b9cacfea9", size = 42361901, upload-time = "2025-01-20T11:13:46.711Z" }, + { url = "https://files.pythonhosted.org/packages/53/ad/d79349dc07b8a395a99153d7ce8b01d6fcdc9f8231355a5df55ded649b61/llvmlite-0.44.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d752f89e31b66db6f8da06df8b39f9b91e78c5feea1bf9e8c1fba1d1c24c065d", size = 41184247, upload-time = "2025-01-20T11:13:56.159Z" }, + { url = "https://files.pythonhosted.org/packages/e2/3b/a9a17366af80127bd09decbe2a54d8974b6d8b274b39bf47fbaedeec6307/llvmlite-0.44.0-cp312-cp312-win_amd64.whl", hash = "sha256:eae7e2d4ca8f88f89d315b48c6b741dcb925d6a1042da694aa16ab3dd4cbd3a1", size = 30332380, upload-time = "2025-01-20T11:14:02.442Z" }, ] [[package]] name = "lm-format-enforcer" -version = "0.10.12" +version = "0.11.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "interegular" }, @@ -1310,9 +1560,9 @@ dependencies = [ { name = "pydantic" }, { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/eb/e0/bdbfad8f5d319de5d05cc2b70d579b49eb8ce3a09989cd0999b8c138c068/lm_format_enforcer-0.10.12.tar.gz", hash = "sha256:130bd7ce8a6b224f25b6314ba9ae78ee4b48594db1767c74391c9182e2902a6c", size = 39481, upload-time = "2025-08-04T21:13:45.727Z" } +sdist = { url = "https://files.pythonhosted.org/packages/84/d5/41cd417ba7dfdbbcfe46cebf81fb3dfd7c591b89897560ad05bb410a465d/lm_format_enforcer-0.11.3.tar.gz", hash = "sha256:e68081c108719cce284a9bcc889709b26ffb085a1945b5eba3a12cfa96d528da", size = 40258, upload-time = "2025-08-24T19:37:47.527Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/57/1c/7bb80fe2dff9a9c38b180571ca867f518eb9110f79d4b670ea124e153680/lm_format_enforcer-0.10.12-py3-none-any.whl", hash = "sha256:267c2b421c77f7cd51ac2e0e3af8db278a373704d834b49ff55f18a2c05e9800", size = 44327, upload-time = "2025-08-04T21:13:44.492Z" }, + { url = "https://files.pythonhosted.org/packages/a0/ef/11292bb0b85cf4c93447cab5a29f64576ed14d3ab4280e35ddd23486594a/lm_format_enforcer-0.11.3-py3-none-any.whl", hash = "sha256:cf586350875def1ae7a8fba84fcbbfc8371424b6c9d05c1fcba70aa233fbf06f", size = 45418, upload-time = "2025-08-24T19:37:46.325Z" }, ] [[package]] @@ -1349,6 +1599,17 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, ] [[package]] @@ -1375,6 +1636,13 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a8/a3/37aef1404efa615f49b5758a5e0261c16dd88f389bc1861e722620e4a754/matplotlib-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6f1851eab59ca082c95df5a500106bad73672645625e04538b3ad0f69471ffcc", size = 9576878, upload-time = "2025-10-09T00:26:27.478Z" }, { url = "https://files.pythonhosted.org/packages/33/cd/b145f9797126f3f809d177ca378de57c45413c5099c5990de2658760594a/matplotlib-3.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:6516ce375109c60ceec579e699524e9d504cd7578506f01150f7a6bc174a775e", size = 8115142, upload-time = "2025-10-09T00:26:29.774Z" }, { url = "https://files.pythonhosted.org/packages/2e/39/63bca9d2b78455ed497fcf51a9c71df200a11048f48249038f06447fa947/matplotlib-3.10.7-cp311-cp311-win_arm64.whl", hash = "sha256:b172db79759f5f9bc13ef1c3ef8b9ee7b37b0247f987fbbbdaa15e4f87fd46a9", size = 7992439, upload-time = "2025-10-09T00:26:40.32Z" }, + { url = "https://files.pythonhosted.org/packages/be/b3/09eb0f7796932826ec20c25b517d568627754f6c6462fca19e12c02f2e12/matplotlib-3.10.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7a0edb7209e21840e8361e91ea84ea676658aa93edd5f8762793dec77a4a6748", size = 8272389, upload-time = "2025-10-09T00:26:42.474Z" }, + { url = "https://files.pythonhosted.org/packages/11/0b/1ae80ddafb8652fd8046cb5c8460ecc8d4afccb89e2c6d6bec61e04e1eaf/matplotlib-3.10.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c380371d3c23e0eadf8ebff114445b9f970aff2010198d498d4ab4c3b41eea4f", size = 8128247, upload-time = "2025-10-09T00:26:44.77Z" }, + { url = "https://files.pythonhosted.org/packages/7d/18/95ae2e242d4a5c98bd6e90e36e128d71cf1c7e39b0874feaed3ef782e789/matplotlib-3.10.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d5f256d49fea31f40f166a5e3131235a5d2f4b7f44520b1cf0baf1ce568ccff0", size = 8696996, upload-time = "2025-10-09T00:26:46.792Z" }, + { url = "https://files.pythonhosted.org/packages/7e/3d/5b559efc800bd05cb2033aa85f7e13af51958136a48327f7c261801ff90a/matplotlib-3.10.7-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11ae579ac83cdf3fb72573bb89f70e0534de05266728740d478f0f818983c695", size = 9530153, upload-time = "2025-10-09T00:26:49.07Z" }, + { url = "https://files.pythonhosted.org/packages/88/57/eab4a719fd110312d3c220595d63a3c85ec2a39723f0f4e7fa7e6e3f74ba/matplotlib-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4c14b6acd16cddc3569a2d515cfdd81c7a68ac5639b76548cfc1a9e48b20eb65", size = 9593093, upload-time = "2025-10-09T00:26:51.067Z" }, + { url = "https://files.pythonhosted.org/packages/31/3c/80816f027b3a4a28cd2a0a6ef7f89a2db22310e945cd886ec25bfb399221/matplotlib-3.10.7-cp312-cp312-win_amd64.whl", hash = "sha256:0d8c32b7ea6fb80b1aeff5a2ceb3fb9778e2759e899d9beff75584714afcc5ee", size = 8122771, upload-time = "2025-10-09T00:26:53.296Z" }, + { url = "https://files.pythonhosted.org/packages/de/77/ef1fc78bfe99999b2675435cc52120887191c566b25017d78beaabef7f2d/matplotlib-3.10.7-cp312-cp312-win_arm64.whl", hash = "sha256:5f3f6d315dcc176ba7ca6e74c7768fb7e4cf566c49cb143f6bc257b62e634ed8", size = 7992812, upload-time = "2025-10-09T00:26:54.882Z" }, { url = "https://files.pythonhosted.org/packages/58/8f/76d5dc21ac64a49e5498d7f0472c0781dae442dd266a67458baec38288ec/matplotlib-3.10.7-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:15112bcbaef211bd663fa935ec33313b948e214454d949b723998a43357b17b0", size = 8252283, upload-time = "2025-10-09T00:27:54.739Z" }, { url = "https://files.pythonhosted.org/packages/27/0d/9c5d4c2317feb31d819e38c9f947c942f42ebd4eb935fc6fd3518a11eaa7/matplotlib-3.10.7-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d2a959c640cdeecdd2ec3136e8ea0441da59bcaf58d67e9c590740addba2cb68", size = 8116733, upload-time = "2025-10-09T00:27:56.406Z" }, { url = "https://files.pythonhosted.org/packages/9a/cc/3fe688ff1355010937713164caacf9ed443675ac48a997bab6ed23b3f7c0/matplotlib-3.10.7-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3886e47f64611046bc1db523a09dd0a0a6bed6081e6f90e13806dd1d1d1b5e91", size = 8693919, upload-time = "2025-10-09T00:27:58.41Z" }, @@ -1501,6 +1769,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e6/ae/270cecbcf36c1dc85ec086b33a51a4d7d08fc4f404bdbc15b582255d05ff/msgpack-1.1.2-cp311-cp311-win32.whl", hash = "sha256:602b6740e95ffc55bfb078172d279de3773d7b7db1f703b2f1323566b878b90e", size = 64747, upload-time = "2025-10-08T09:14:57.882Z" }, { url = "https://files.pythonhosted.org/packages/2a/79/309d0e637f6f37e83c711f547308b91af02b72d2326ddd860b966080ef29/msgpack-1.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:d198d275222dc54244bf3327eb8cbe00307d220241d9cec4d306d49a44e85f68", size = 71633, upload-time = "2025-10-08T09:14:59.177Z" }, { url = "https://files.pythonhosted.org/packages/73/4d/7c4e2b3d9b1106cd0aa6cb56cc57c6267f59fa8bfab7d91df5adc802c847/msgpack-1.1.2-cp311-cp311-win_arm64.whl", hash = "sha256:86f8136dfa5c116365a8a651a7d7484b65b13339731dd6faebb9a0242151c406", size = 64755, upload-time = "2025-10-08T09:15:00.48Z" }, + { url = "https://files.pythonhosted.org/packages/ad/bd/8b0d01c756203fbab65d265859749860682ccd2a59594609aeec3a144efa/msgpack-1.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:70a0dff9d1f8da25179ffcf880e10cf1aad55fdb63cd59c9a49a1b82290062aa", size = 81939, upload-time = "2025-10-08T09:15:01.472Z" }, + { url = "https://files.pythonhosted.org/packages/34/68/ba4f155f793a74c1483d4bdef136e1023f7bcba557f0db4ef3db3c665cf1/msgpack-1.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:446abdd8b94b55c800ac34b102dffd2f6aa0ce643c55dfc017ad89347db3dbdb", size = 85064, upload-time = "2025-10-08T09:15:03.764Z" }, + { url = "https://files.pythonhosted.org/packages/f2/60/a064b0345fc36c4c3d2c743c82d9100c40388d77f0b48b2f04d6041dbec1/msgpack-1.1.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c63eea553c69ab05b6747901b97d620bb2a690633c77f23feb0c6a947a8a7b8f", size = 417131, upload-time = "2025-10-08T09:15:05.136Z" }, + { url = "https://files.pythonhosted.org/packages/65/92/a5100f7185a800a5d29f8d14041f61475b9de465ffcc0f3b9fba606e4505/msgpack-1.1.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:372839311ccf6bdaf39b00b61288e0557916c3729529b301c52c2d88842add42", size = 427556, upload-time = "2025-10-08T09:15:06.837Z" }, + { url = "https://files.pythonhosted.org/packages/f5/87/ffe21d1bf7d9991354ad93949286f643b2bb6ddbeab66373922b44c3b8cc/msgpack-1.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2929af52106ca73fcb28576218476ffbb531a036c2adbcf54a3664de124303e9", size = 404920, upload-time = "2025-10-08T09:15:08.179Z" }, + { url = "https://files.pythonhosted.org/packages/ff/41/8543ed2b8604f7c0d89ce066f42007faac1eaa7d79a81555f206a5cdb889/msgpack-1.1.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be52a8fc79e45b0364210eef5234a7cf8d330836d0a64dfbb878efa903d84620", size = 415013, upload-time = "2025-10-08T09:15:09.83Z" }, + { url = "https://files.pythonhosted.org/packages/41/0d/2ddfaa8b7e1cee6c490d46cb0a39742b19e2481600a7a0e96537e9c22f43/msgpack-1.1.2-cp312-cp312-win32.whl", hash = "sha256:1fff3d825d7859ac888b0fbda39a42d59193543920eda9d9bea44d958a878029", size = 65096, upload-time = "2025-10-08T09:15:11.11Z" }, + { url = "https://files.pythonhosted.org/packages/8c/ec/d431eb7941fb55a31dd6ca3404d41fbb52d99172df2e7707754488390910/msgpack-1.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:1de460f0403172cff81169a30b9a92b260cb809c4cb7e2fc79ae8d0510c78b6b", size = 72708, upload-time = "2025-10-08T09:15:12.554Z" }, + { url = "https://files.pythonhosted.org/packages/c5/31/5b1a1f70eb0e87d1678e9624908f86317787b536060641d6798e3cf70ace/msgpack-1.1.2-cp312-cp312-win_arm64.whl", hash = "sha256:be5980f3ee0e6bd44f3a9e9dea01054f175b50c3e6cdb692bc9424c0bbb8bf69", size = 64119, upload-time = "2025-10-08T09:15:13.589Z" }, ] [[package]] @@ -1515,6 +1792,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/c0/3d0cce27db9a9912421273d49eab79ce01ecd2fed1a2f1b74af9b445f33c/msgspec-0.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:562c44b047c05cc0384e006fae7a5e715740215c799429e0d7e3e5adf324285a", size = 223348, upload-time = "2025-11-24T03:55:28.311Z" }, { url = "https://files.pythonhosted.org/packages/89/5e/406b7d578926b68790e390d83a1165a9bfc2d95612a1a9c1c4d5c72ea815/msgspec-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:d1dcc93a3ce3d3195985bfff18a48274d0b5ffbc96fa1c5b89da6f0d9af81b29", size = 188713, upload-time = "2025-11-24T03:55:29.553Z" }, { url = "https://files.pythonhosted.org/packages/47/87/14fe2316624ceedf76a9e94d714d194cbcb699720b210ff189f89ca4efd7/msgspec-0.20.0-cp311-cp311-win_arm64.whl", hash = "sha256:aa387aa330d2e4bd69995f66ea8fdc87099ddeedf6fdb232993c6a67711e7520", size = 174229, upload-time = "2025-11-24T03:55:31.107Z" }, + { url = "https://files.pythonhosted.org/packages/49/d6/9709ee093b7742362c2934bfb1bbe791a1e09bed3ea5d8a18ce552fbfd73/msgspec-0.20.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:558ed73315efa51b1538fa8f1d3b22c8c5ff6d9a2a62eff87d25829b94fc5054", size = 218852, upload-time = "2025-11-24T03:55:35.575Z" }, + { url = "https://files.pythonhosted.org/packages/5c/a2/488517a43ccf5a4b6b6eca6dd4ede0bd82b043d1539dd6bb908a19f8efd3/msgspec-0.20.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:509ac1362a1d53aa66798c9b9fd76872d7faa30fcf89b2fba3bcbfd559d56eb0", size = 224937, upload-time = "2025-11-24T03:55:36.859Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e8/49b832808aa23b85d4f090d1d2e48a4e3834871415031ed7c5fe48723156/msgspec-0.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1353c2c93423602e7dea1aa4c92f3391fdfc25ff40e0bacf81d34dbc68adb870", size = 222858, upload-time = "2025-11-24T03:55:38.187Z" }, + { url = "https://files.pythonhosted.org/packages/9f/56/1dc2fa53685dca9c3f243a6cbecd34e856858354e455b77f47ebd76cf5bf/msgspec-0.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cb33b5eb5adb3c33d749684471c6a165468395d7aa02d8867c15103b81e1da3e", size = 227248, upload-time = "2025-11-24T03:55:39.496Z" }, + { url = "https://files.pythonhosted.org/packages/5a/51/aba940212c23b32eedce752896205912c2668472ed5b205fc33da28a6509/msgspec-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:fb1d934e435dd3a2b8cf4bbf47a8757100b4a1cfdc2afdf227541199885cdacb", size = 190024, upload-time = "2025-11-24T03:55:40.829Z" }, + { url = "https://files.pythonhosted.org/packages/41/ad/3b9f259d94f183daa9764fef33fdc7010f7ecffc29af977044fa47440a83/msgspec-0.20.0-cp312-cp312-win_arm64.whl", hash = "sha256:00648b1e19cf01b2be45444ba9dc961bd4c056ffb15706651e64e5d6ec6197b7", size = 175390, upload-time = "2025-11-24T03:55:42.05Z" }, ] [[package]] @@ -1541,6 +1824,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/a2/59b405d59fd39ec86d1142630e9049243015a5f5291ba49cadf3c090c541/multidict-6.7.0-cp311-cp311-win32.whl", hash = "sha256:a90af66facec4cebe4181b9e62a68be65e45ac9b52b67de9eec118701856e7ff", size = 41308, upload-time = "2025-10-06T14:49:16.871Z" }, { url = "https://files.pythonhosted.org/packages/32/0f/13228f26f8b882c34da36efa776c3b7348455ec383bab4a66390e42963ae/multidict-6.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:95b5ffa4349df2887518bb839409bcf22caa72d82beec453216802f475b23c81", size = 46037, upload-time = "2025-10-06T14:49:18.457Z" }, { url = "https://files.pythonhosted.org/packages/84/1f/68588e31b000535a3207fd3c909ebeec4fb36b52c442107499c18a896a2a/multidict-6.7.0-cp311-cp311-win_arm64.whl", hash = "sha256:329aa225b085b6f004a4955271a7ba9f1087e39dcb7e65f6284a988264a63912", size = 43023, upload-time = "2025-10-06T14:49:19.648Z" }, + { url = "https://files.pythonhosted.org/packages/c2/9e/9f61ac18d9c8b475889f32ccfa91c9f59363480613fc807b6e3023d6f60b/multidict-6.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8a3862568a36d26e650a19bb5cbbba14b71789032aebc0423f8cc5f150730184", size = 76877, upload-time = "2025-10-06T14:49:20.884Z" }, + { url = "https://files.pythonhosted.org/packages/38/6f/614f09a04e6184f8824268fce4bc925e9849edfa654ddd59f0b64508c595/multidict-6.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:960c60b5849b9b4f9dcc9bea6e3626143c252c74113df2c1540aebce70209b45", size = 45467, upload-time = "2025-10-06T14:49:22.054Z" }, + { url = "https://files.pythonhosted.org/packages/b3/93/c4f67a436dd026f2e780c433277fff72be79152894d9fc36f44569cab1a6/multidict-6.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2049be98fb57a31b4ccf870bf377af2504d4ae35646a19037ec271e4c07998aa", size = 43834, upload-time = "2025-10-06T14:49:23.566Z" }, + { url = "https://files.pythonhosted.org/packages/7f/f5/013798161ca665e4a422afbc5e2d9e4070142a9ff8905e482139cd09e4d0/multidict-6.7.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0934f3843a1860dd465d38895c17fce1f1cb37295149ab05cd1b9a03afacb2a7", size = 250545, upload-time = "2025-10-06T14:49:24.882Z" }, + { url = "https://files.pythonhosted.org/packages/71/2f/91dbac13e0ba94669ea5119ba267c9a832f0cb65419aca75549fcf09a3dc/multidict-6.7.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3e34f3a1b8131ba06f1a73adab24f30934d148afcd5f5de9a73565a4404384e", size = 258305, upload-time = "2025-10-06T14:49:26.778Z" }, + { url = "https://files.pythonhosted.org/packages/ef/b0/754038b26f6e04488b48ac621f779c341338d78503fb45403755af2df477/multidict-6.7.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:efbb54e98446892590dc2458c19c10344ee9a883a79b5cec4bc34d6656e8d546", size = 242363, upload-time = "2025-10-06T14:49:28.562Z" }, + { url = "https://files.pythonhosted.org/packages/87/15/9da40b9336a7c9fa606c4cf2ed80a649dffeb42b905d4f63a1d7eb17d746/multidict-6.7.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a35c5fc61d4f51eb045061e7967cfe3123d622cd500e8868e7c0c592a09fedc4", size = 268375, upload-time = "2025-10-06T14:49:29.96Z" }, + { url = "https://files.pythonhosted.org/packages/82/72/c53fcade0cc94dfaad583105fd92b3a783af2091eddcb41a6d5a52474000/multidict-6.7.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29fe6740ebccba4175af1b9b87bf553e9c15cd5868ee967e010efcf94e4fd0f1", size = 269346, upload-time = "2025-10-06T14:49:31.404Z" }, + { url = "https://files.pythonhosted.org/packages/0d/e2/9baffdae21a76f77ef8447f1a05a96ec4bc0a24dae08767abc0a2fe680b8/multidict-6.7.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:123e2a72e20537add2f33a79e605f6191fba2afda4cbb876e35c1a7074298a7d", size = 256107, upload-time = "2025-10-06T14:49:32.974Z" }, + { url = "https://files.pythonhosted.org/packages/3c/06/3f06f611087dc60d65ef775f1fb5aca7c6d61c6db4990e7cda0cef9b1651/multidict-6.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b284e319754366c1aee2267a2036248b24eeb17ecd5dc16022095e747f2f4304", size = 253592, upload-time = "2025-10-06T14:49:34.52Z" }, + { url = "https://files.pythonhosted.org/packages/20/24/54e804ec7945b6023b340c412ce9c3f81e91b3bf5fa5ce65558740141bee/multidict-6.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:803d685de7be4303b5a657b76e2f6d1240e7e0a8aa2968ad5811fa2285553a12", size = 251024, upload-time = "2025-10-06T14:49:35.956Z" }, + { url = "https://files.pythonhosted.org/packages/14/48/011cba467ea0b17ceb938315d219391d3e421dfd35928e5dbdc3f4ae76ef/multidict-6.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c04a328260dfd5db8c39538f999f02779012268f54614902d0afc775d44e0a62", size = 251484, upload-time = "2025-10-06T14:49:37.631Z" }, + { url = "https://files.pythonhosted.org/packages/0d/2f/919258b43bb35b99fa127435cfb2d91798eb3a943396631ef43e3720dcf4/multidict-6.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8a19cdb57cd3df4cd865849d93ee14920fb97224300c88501f16ecfa2604b4e0", size = 263579, upload-time = "2025-10-06T14:49:39.502Z" }, + { url = "https://files.pythonhosted.org/packages/31/22/a0e884d86b5242b5a74cf08e876bdf299e413016b66e55511f7a804a366e/multidict-6.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b2fd74c52accced7e75de26023b7dccee62511a600e62311b918ec5c168fc2a", size = 259654, upload-time = "2025-10-06T14:49:41.32Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e5/17e10e1b5c5f5a40f2fcbb45953c9b215f8a4098003915e46a93f5fcaa8f/multidict-6.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3e8bfdd0e487acf992407a140d2589fe598238eaeffa3da8448d63a63cd363f8", size = 251511, upload-time = "2025-10-06T14:49:46.021Z" }, + { url = "https://files.pythonhosted.org/packages/e3/9a/201bb1e17e7af53139597069c375e7b0dcbd47594604f65c2d5359508566/multidict-6.7.0-cp312-cp312-win32.whl", hash = "sha256:dd32a49400a2c3d52088e120ee00c1e3576cbff7e10b98467962c74fdb762ed4", size = 41895, upload-time = "2025-10-06T14:49:48.718Z" }, + { url = "https://files.pythonhosted.org/packages/46/e2/348cd32faad84eaf1d20cce80e2bb0ef8d312c55bca1f7fa9865e7770aaf/multidict-6.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b", size = 46073, upload-time = "2025-10-06T14:49:50.28Z" }, + { url = "https://files.pythonhosted.org/packages/25/ec/aad2613c1910dce907480e0c3aa306905830f25df2e54ccc9dea450cb5aa/multidict-6.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec", size = 43226, upload-time = "2025-10-06T14:49:52.304Z" }, { url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload-time = "2025-10-06T14:52:29.272Z" }, ] @@ -1558,14 +1859,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dd/74/cb8c831e58dc6d5cf450b17c7db87f14294a1df52eb391da948b5e0a0b94/multiprocess-0.70.18-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4d77f8e4bfe6c6e2e661925bbf9aed4d5ade9a1c6502d5dfc10129b9d1141797", size = 144745, upload-time = "2025-04-17T03:11:11.453Z" }, { url = "https://files.pythonhosted.org/packages/ba/d8/0cba6cf51a1a31f20471fbc823a716170c73012ddc4fb85d706630ed6e8f/multiprocess-0.70.18-py310-none-any.whl", hash = "sha256:60c194974c31784019c1f459d984e8f33ee48f10fcf42c309ba97b30d9bd53ea", size = 134948, upload-time = "2025-04-17T03:11:20.223Z" }, { url = "https://files.pythonhosted.org/packages/4b/88/9039f2fed1012ef584751d4ceff9ab4a51e5ae264898f0b7cbf44340a859/multiprocess-0.70.18-py311-none-any.whl", hash = "sha256:5aa6eef98e691281b3ad923be2832bf1c55dd2c859acd73e5ec53a66aae06a1d", size = 144462, upload-time = "2025-04-17T03:11:21.657Z" }, + { url = "https://files.pythonhosted.org/packages/bf/b6/5f922792be93b82ec6b5f270bbb1ef031fd0622847070bbcf9da816502cc/multiprocess-0.70.18-py312-none-any.whl", hash = "sha256:9b78f8e5024b573730bfb654783a13800c2c0f2dfc0c25e70b40d184d64adaa2", size = 150287, upload-time = "2025-04-17T03:11:22.69Z" }, { url = "https://files.pythonhosted.org/packages/3b/c3/ca84c19bd14cdfc21c388fdcebf08b86a7a470ebc9f5c3c084fc2dbc50f7/multiprocess-0.70.18-py38-none-any.whl", hash = "sha256:dbf705e52a154fe5e90fb17b38f02556169557c2dd8bb084f2e06c2784d8279b", size = 132636, upload-time = "2025-04-17T03:11:24.936Z" }, { url = "https://files.pythonhosted.org/packages/6c/28/dd72947e59a6a8c856448a5e74da6201cb5502ddff644fbc790e4bd40b9a/multiprocess-0.70.18-py39-none-any.whl", hash = "sha256:e78ca805a72b1b810c690b6b4cc32579eba34f403094bbbae962b7b5bf9dfcb8", size = 133478, upload-time = "2025-04-17T03:11:26.253Z" }, ] [[package]] name = "nano-agent" -version = "4.0.2" -source = { git = "https://github.com/ASSERT-KTH/nano-agent.git#ac97883ee65f8259127ad09954606c810a24e99c" } +version = "5.0.1" +source = { git = "https://github.com/ASSERT-KTH/nano-agent.git#92419df28f39c9fa4d18f94e3cc229f904646896" } dependencies = [ { name = "litellm" }, ] @@ -1627,6 +1929,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/97/c8/8740616c8436c86c1b9a62e72cb891177d2c34c2d24ddcde4c390371bf4c/numba-0.61.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3945615cd73c2c7eba2a85ccc9c1730c21cd3958bfcf5a44302abae0fb07bb60", size = 3829227, upload-time = "2025-04-09T02:57:46.63Z" }, { url = "https://files.pythonhosted.org/packages/fc/06/66e99ae06507c31d15ff3ecd1f108f2f59e18b6e08662cd5f8a5853fbd18/numba-0.61.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbfdf4eca202cebade0b7d43896978e146f39398909a42941c9303f82f403a18", size = 3523422, upload-time = "2025-04-09T02:57:48.222Z" }, { url = "https://files.pythonhosted.org/packages/0f/a4/2b309a6a9f6d4d8cfba583401c7c2f9ff887adb5d54d8e2e130274c0973f/numba-0.61.2-cp311-cp311-win_amd64.whl", hash = "sha256:76bcec9f46259cedf888041b9886e257ae101c6268261b19fda8cfbc52bec9d1", size = 2831505, upload-time = "2025-04-09T02:57:50.108Z" }, + { url = "https://files.pythonhosted.org/packages/9a/2d/e518df036feab381c23a624dac47f8445ac55686ec7f11083655eb707da3/numba-0.61.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b1bb509d01f23d70325d3a5a0e237cbc9544dd50e50588bc581ba860c213546", size = 3885928, upload-time = "2025-04-09T02:57:55.206Z" }, + { url = "https://files.pythonhosted.org/packages/10/0f/23cced68ead67b75d77cfcca3df4991d1855c897ee0ff3fe25a56ed82108/numba-0.61.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48a53a3de8f8793526cbe330f2a39fe9a6638efcbf11bd63f3d2f9757ae345cd", size = 3577115, upload-time = "2025-04-09T02:57:56.818Z" }, + { url = "https://files.pythonhosted.org/packages/68/1d/ddb3e704c5a8fb90142bf9dc195c27db02a08a99f037395503bfbc1d14b3/numba-0.61.2-cp312-cp312-win_amd64.whl", hash = "sha256:97cf4f12c728cf77c9c1d7c23707e4d8fb4632b46275f8f3397de33e5877af18", size = 2831929, upload-time = "2025-04-09T02:57:58.45Z" }, ] [[package]] @@ -1645,51 +1950,59 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload-time = "2025-05-17T21:33:39.139Z" }, { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload-time = "2025-05-17T21:33:50.273Z" }, { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload-time = "2025-05-17T21:34:09.135Z" }, + { url = "https://files.pythonhosted.org/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348, upload-time = "2025-05-17T21:34:39.648Z" }, + { url = "https://files.pythonhosted.org/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362, upload-time = "2025-05-17T21:35:01.241Z" }, + { url = "https://files.pythonhosted.org/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103, upload-time = "2025-05-17T21:35:10.622Z" }, + { url = "https://files.pythonhosted.org/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382, upload-time = "2025-05-17T21:35:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462, upload-time = "2025-05-17T21:35:42.174Z" }, + { url = "https://files.pythonhosted.org/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618, upload-time = "2025-05-17T21:36:06.711Z" }, + { url = "https://files.pythonhosted.org/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511, upload-time = "2025-05-17T21:36:29.965Z" }, + { url = "https://files.pythonhosted.org/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783, upload-time = "2025-05-17T21:36:56.883Z" }, + { url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506, upload-time = "2025-05-17T21:37:07.368Z" }, + { url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190, upload-time = "2025-05-17T21:37:26.213Z" }, ] [[package]] name = "nvidia-cublas-cu12" -version = "12.6.4.1" +version = "12.8.4.1" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/af/eb/ff4b8c503fa1f1796679dce648854d58751982426e4e4b37d6fce49d259c/nvidia_cublas_cu12-12.6.4.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:08ed2686e9875d01b58e3cb379c6896df8e76c75e0d4a7f7dace3d7b6d9ef8eb", size = 393138322, upload-time = "2024-11-20T17:40:25.65Z" }, + { url = "https://files.pythonhosted.org/packages/dc/61/e24b560ab2e2eaeb3c839129175fb330dfcfc29e5203196e5541a4c44682/nvidia_cublas_cu12-12.8.4.1-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:8ac4e771d5a348c551b2a426eda6193c19aa630236b418086020df5ba9667142", size = 594346921, upload-time = "2025-03-07T01:44:31.254Z" }, ] [[package]] name = "nvidia-cuda-cupti-cu12" -version = "12.6.80" +version = "12.8.90" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/49/60/7b6497946d74bcf1de852a21824d63baad12cd417db4195fc1bfe59db953/nvidia_cuda_cupti_cu12-12.6.80-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6768bad6cab4f19e8292125e5f1ac8aa7d1718704012a0e3272a6f61c4bce132", size = 8917980, upload-time = "2024-11-20T17:36:04.019Z" }, - { url = "https://files.pythonhosted.org/packages/a5/24/120ee57b218d9952c379d1e026c4479c9ece9997a4fb46303611ee48f038/nvidia_cuda_cupti_cu12-12.6.80-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a3eff6cdfcc6a4c35db968a06fcadb061cbc7d6dde548609a941ff8701b98b73", size = 8917972, upload-time = "2024-10-01T16:58:06.036Z" }, + { url = "https://files.pythonhosted.org/packages/f8/02/2adcaa145158bf1a8295d83591d22e4103dbfd821bcaf6f3f53151ca4ffa/nvidia_cuda_cupti_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea0cb07ebda26bb9b29ba82cda34849e73c166c18162d3913575b0c9db9a6182", size = 10248621, upload-time = "2025-03-07T01:40:21.213Z" }, ] [[package]] name = "nvidia-cuda-nvrtc-cu12" -version = "12.6.77" +version = "12.8.93" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/75/2e/46030320b5a80661e88039f59060d1790298b4718944a65a7f2aeda3d9e9/nvidia_cuda_nvrtc_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:35b0cc6ee3a9636d5409133e79273ce1f3fd087abb0532d2d2e8fff1fe9efc53", size = 23650380, upload-time = "2024-10-01T17:00:14.643Z" }, + { url = "https://files.pythonhosted.org/packages/05/6b/32f747947df2da6994e999492ab306a903659555dddc0fbdeb9d71f75e52/nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:a7756528852ef889772a84c6cd89d41dfa74667e24cca16bb31f8f061e3e9994", size = 88040029, upload-time = "2025-03-07T01:42:13.562Z" }, ] [[package]] name = "nvidia-cuda-runtime-cu12" -version = "12.6.77" +version = "12.8.90" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/23/e717c5ac26d26cf39a27fbc076240fad2e3b817e5889d671b67f4f9f49c5/nvidia_cuda_runtime_cu12-12.6.77-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ba3b56a4f896141e25e19ab287cd71e52a6a0f4b29d0d31609f60e3b4d5219b7", size = 897690, upload-time = "2024-11-20T17:35:30.697Z" }, - { url = "https://files.pythonhosted.org/packages/f0/62/65c05e161eeddbafeca24dc461f47de550d9fa8a7e04eb213e32b55cfd99/nvidia_cuda_runtime_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a84d15d5e1da416dd4774cb42edf5e954a3e60cc945698dc1d5be02321c44dc8", size = 897678, upload-time = "2024-10-01T16:57:33.821Z" }, + { url = "https://files.pythonhosted.org/packages/0d/9b/a997b638fcd068ad6e4d53b8551a7d30fe8b404d6f1804abf1df69838932/nvidia_cuda_runtime_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adade8dcbd0edf427b7204d480d6066d33902cab2a4707dcfc48a2d0fd44ab90", size = 954765, upload-time = "2025-03-07T01:40:01.615Z" }, ] [[package]] name = "nvidia-cudnn-cu12" -version = "9.5.1.17" +version = "9.10.2.21" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12" }, + { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux'" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/78/4535c9c7f859a64781e43c969a3a7e84c54634e319a996d43ef32ce46f83/nvidia_cudnn_cu12-9.5.1.17-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:30ac3869f6db17d170e0e556dd6cc5eee02647abc31ca856634d5a40f82c15b2", size = 570988386, upload-time = "2024-10-25T19:54:26.39Z" }, + { url = "https://files.pythonhosted.org/packages/ba/51/e123d997aa098c61d029f76663dedbfb9bc8dcf8c60cbd6adbe42f76d049/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8", size = 706758467, upload-time = "2025-06-06T21:54:08.597Z" }, ] [[package]] @@ -1700,69 +2013,84 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/10/b7/d0a3a337f5e83f26ff79a7fd63a859181ff2911f1d905d6fbab5fc80170d/nvidia_cudnn_frontend-1.16.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c360d5840d6eb597aade9e9c8780e24aec283b8e6bc97d52881c821a35c92aa9", size = 1837573, upload-time = "2025-11-07T01:29:05.507Z" }, { url = "https://files.pythonhosted.org/packages/95/dc/465a14f2d235778405f2e84fce336d07ab045bf1c7df6404bdf8033e06a8/nvidia_cudnn_frontend-1.16.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5c4a8fc573d85a86e08b15d9bf37f729e2487298781867a492a59cde6ac295e2", size = 1952630, upload-time = "2025-11-07T01:32:00.242Z" }, { url = "https://files.pythonhosted.org/packages/3b/89/f14435f616603a999975930c4456d6140127f6acb19a877c752beccad837/nvidia_cudnn_frontend-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:a257f10a932ffde9741f644efd3611acf77e2fd89d493d81bc6a8353c48f1ec2", size = 1368775, upload-time = "2025-11-07T01:25:42.252Z" }, + { url = "https://files.pythonhosted.org/packages/00/39/79b606e805abd67ab4fa72f752a5413a496159f10d94fbdb1d67bb5ae86c/nvidia_cudnn_frontend-1.16.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dd6fdd71c0896ff2ca1809d914cbd17f2904d55863f8881f47946e1d634c7a88", size = 1839271, upload-time = "2025-11-07T01:29:53.06Z" }, + { url = "https://files.pythonhosted.org/packages/09/21/a0e0d50ba8d7b639fe635500fee0d9c0319561b1ae72176d7024ec04b439/nvidia_cudnn_frontend-1.16.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:16efb069d4bda4d3b99134f59f376cfd4d09558298bd96af778fdc7f2851e696", size = 1954062, upload-time = "2025-11-07T01:32:18.556Z" }, + { url = "https://files.pythonhosted.org/packages/ce/d6/30ae67bb9c010e9459d1211c56d73373eb4e3dd9f57f4c3c1fe0966efcb1/nvidia_cudnn_frontend-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:7b7860db03767c158accbe0b4e9c9553506513cc970ff08ed28c7761681ac466", size = 1368435, upload-time = "2025-11-07T01:26:28.022Z" }, ] [[package]] name = "nvidia-cufft-cu12" -version = "11.3.0.4" +version = "11.3.3.83" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12" }, + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/16/73727675941ab8e6ffd86ca3a4b7b47065edcca7a997920b831f8147c99d/nvidia_cufft_cu12-11.3.0.4-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ccba62eb9cef5559abd5e0d54ceed2d9934030f51163df018532142a8ec533e5", size = 200221632, upload-time = "2024-11-20T17:41:32.357Z" }, - { url = "https://files.pythonhosted.org/packages/60/de/99ec247a07ea40c969d904fc14f3a356b3e2a704121675b75c366b694ee1/nvidia_cufft_cu12-11.3.0.4-py3-none-manylinux2014_x86_64.whl", hash = "sha256:768160ac89f6f7b459bee747e8d175dbf53619cfe74b2a5636264163138013ca", size = 200221622, upload-time = "2024-10-01T17:03:58.79Z" }, + { url = "https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74", size = 193118695, upload-time = "2025-03-07T01:45:27.821Z" }, ] [[package]] name = "nvidia-cufile-cu12" -version = "1.11.1.6" +version = "1.13.1.3" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b2/66/cc9876340ac68ae71b15c743ddb13f8b30d5244af344ec8322b449e35426/nvidia_cufile_cu12-1.11.1.6-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc23469d1c7e52ce6c1d55253273d32c565dd22068647f3aa59b3c6b005bf159", size = 1142103, upload-time = "2024-11-20T17:42:11.83Z" }, + { url = "https://files.pythonhosted.org/packages/bb/fe/1bcba1dfbfb8d01be8d93f07bfc502c93fa23afa6fd5ab3fc7c1df71038a/nvidia_cufile_cu12-1.13.1.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1d069003be650e131b21c932ec3d8969c1715379251f8d23a1860554b1cb24fc", size = 1197834, upload-time = "2025-03-07T01:45:50.723Z" }, ] [[package]] name = "nvidia-curand-cu12" -version = "10.3.7.77" +version = "10.3.9.90" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/73/1b/44a01c4e70933637c93e6e1a8063d1e998b50213a6b65ac5a9169c47e98e/nvidia_curand_cu12-10.3.7.77-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a42cd1344297f70b9e39a1e4f467a4e1c10f1da54ff7a85c12197f6c652c8bdf", size = 56279010, upload-time = "2024-11-20T17:42:50.958Z" }, - { url = "https://files.pythonhosted.org/packages/4a/aa/2c7ff0b5ee02eaef890c0ce7d4f74bc30901871c5e45dee1ae6d0083cd80/nvidia_curand_cu12-10.3.7.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:99f1a32f1ac2bd134897fc7a203f779303261268a65762a623bf30cc9fe79117", size = 56279000, upload-time = "2024-10-01T17:04:45.274Z" }, + { url = "https://files.pythonhosted.org/packages/fb/aa/6584b56dc84ebe9cf93226a5cde4d99080c8e90ab40f0c27bda7a0f29aa1/nvidia_curand_cu12-10.3.9.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:b32331d4f4df5d6eefa0554c565b626c7216f87a06a4f56fab27c3b68a830ec9", size = 63619976, upload-time = "2025-03-07T01:46:23.323Z" }, ] [[package]] name = "nvidia-cusolver-cu12" -version = "11.7.1.2" +version = "11.7.3.90" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12" }, - { name = "nvidia-cusparse-cu12" }, - { name = "nvidia-nvjitlink-cu12" }, + { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-cusparse-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/f0/6e/c2cf12c9ff8b872e92b4a5740701e51ff17689c4d726fca91875b07f655d/nvidia_cusolver_cu12-11.7.1.2-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e9e49843a7707e42022babb9bcfa33c29857a93b88020c4e4434656a655b698c", size = 158229790, upload-time = "2024-11-20T17:43:43.211Z" }, - { url = "https://files.pythonhosted.org/packages/9f/81/baba53585da791d043c10084cf9553e074548408e04ae884cfe9193bd484/nvidia_cusolver_cu12-11.7.1.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6cf28f17f64107a0c4d7802be5ff5537b2130bfc112f25d5a30df227058ca0e6", size = 158229780, upload-time = "2024-10-01T17:05:39.875Z" }, + { url = "https://files.pythonhosted.org/packages/85/48/9a13d2975803e8cf2777d5ed57b87a0b6ca2cc795f9a4f59796a910bfb80/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4376c11ad263152bd50ea295c05370360776f8c3427b30991df774f9fb26c450", size = 267506905, upload-time = "2025-03-07T01:47:16.273Z" }, ] [[package]] name = "nvidia-cusparse-cu12" -version = "12.5.4.2" +version = "12.5.8.93" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12" }, + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/06/1e/b8b7c2f4099a37b96af5c9bb158632ea9e5d9d27d7391d7eb8fc45236674/nvidia_cusparse_cu12-12.5.4.2-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7556d9eca156e18184b94947ade0fba5bb47d69cec46bf8660fd2c71a4b48b73", size = 216561367, upload-time = "2024-11-20T17:44:54.824Z" }, - { url = "https://files.pythonhosted.org/packages/43/ac/64c4316ba163e8217a99680c7605f779accffc6a4bcd0c778c12948d3707/nvidia_cusparse_cu12-12.5.4.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:23749a6571191a215cb74d1cdbff4a86e7b19f1200c071b3fcf844a5bea23a2f", size = 216561357, upload-time = "2024-10-01T17:06:29.861Z" }, + { url = "https://files.pythonhosted.org/packages/c2/f5/e1854cb2f2bcd4280c44736c93550cc300ff4b8c95ebe370d0aa7d2b473d/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ec05d76bbbd8b61b06a80e1eaf8cf4959c3d4ce8e711b65ebd0443bb0ebb13b", size = 288216466, upload-time = "2025-03-07T01:48:13.779Z" }, ] [[package]] name = "nvidia-cusparselt-cu12" -version = "0.6.3" +version = "0.7.1" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3b/9a/72ef35b399b0e183bc2e8f6f558036922d453c4d8237dab26c666a04244b/nvidia_cusparselt_cu12-0.6.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:e5c8a26c36445dd2e6812f1177978a24e2d37cacce7e090f297a688d1ec44f46", size = 156785796, upload-time = "2024-10-15T21:29:17.709Z" }, + { url = "https://files.pythonhosted.org/packages/56/79/12978b96bd44274fe38b5dde5cfb660b1d114f70a65ef962bcbbed99b549/nvidia_cusparselt_cu12-0.7.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f1bb701d6b930d5a7cea44c19ceb973311500847f81b634d802b7b539dc55623", size = 287193691, upload-time = "2025-02-26T00:15:44.104Z" }, +] + +[[package]] +name = "nvidia-cutlass-dsl" +version = "4.3.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cuda-python" }, + { name = "numpy" }, + { name = "typing-extensions" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/01/3067eaad7454a3e36523b6814f09344afa0d36f71719072a6eecd6c87a40/nvidia_cutlass_dsl-4.3.4-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:c5bd21ed877da171f115123a12aae4a920035fc47eb57c807f9fba9f3df97cf4", size = 58733573, upload-time = "2025-12-21T07:41:51.364Z" }, + { url = "https://files.pythonhosted.org/packages/86/3b/f8255a1fe6841955eea7a211bc9f30fd46bd8424ea15f361d5c09b29520a/nvidia_cutlass_dsl-4.3.4-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:671936f1df909e7de377d0cc00cb4287a3458c013d34947600423e9deb827e41", size = 58598831, upload-time = "2025-12-21T07:39:17.853Z" }, + { url = "https://files.pythonhosted.org/packages/86/ee/53d22e2e14cb763927d85f7ec9748f6af6d27a2b7f43d52de014728da10e/nvidia_cutlass_dsl-4.3.4-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:57693d87677919572ab9eefa386b3f39e8e888bc4a9db7ab8730a97e8dbe06b4", size = 58736300, upload-time = "2025-12-21T07:41:25.723Z" }, + { url = "https://files.pythonhosted.org/packages/66/f6/47489e07081cd4060f08bfa4166f8ff32beaecf71c06060d03bde88f3b6c/nvidia_cutlass_dsl-4.3.4-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:a48fbff859e44dd548f8f26819d97d0595acea70e3b057c91dfdb47929015c72", size = 58599014, upload-time = "2025-12-21T07:38:51.632Z" }, ] [[package]] @@ -1776,27 +2104,26 @@ wheels = [ [[package]] name = "nvidia-nccl-cu12" -version = "2.26.2" +version = "2.27.3" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/67/ca/f42388aed0fddd64ade7493dbba36e1f534d4e6fdbdd355c6a90030ae028/nvidia_nccl_cu12-2.26.2-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:694cf3879a206553cc9d7dbda76b13efaf610fdb70a50cba303de1b0d1530ac6", size = 201319755, upload-time = "2025-03-13T00:29:55.296Z" }, + { url = "https://files.pythonhosted.org/packages/5c/5b/4e4fff7bad39adf89f735f2bc87248c81db71205b62bcc0d5ca5b606b3c3/nvidia_nccl_cu12-2.27.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adf27ccf4238253e0b826bce3ff5fa532d65fc42322c8bfdfaf28024c0fbe039", size = 322364134, upload-time = "2025-06-03T21:58:04.013Z" }, ] [[package]] name = "nvidia-nvjitlink-cu12" -version = "12.6.85" +version = "12.8.93" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9d/d7/c5383e47c7e9bf1c99d5bd2a8c935af2b6d705ad831a7ec5c97db4d82f4f/nvidia_nvjitlink_cu12-12.6.85-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:eedc36df9e88b682efe4309aa16b5b4e78c2407eac59e8c10a6a47535164369a", size = 19744971, upload-time = "2024-11-20T17:46:53.366Z" }, + { url = "https://files.pythonhosted.org/packages/f6/74/86a07f1d0f42998ca31312f998bd3b9a7eff7f52378f4f270c8679c77fb9/nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:81ff63371a7ebd6e6451970684f916be2eab07321b73c9d244dc2b4da7f73b88", size = 39254836, upload-time = "2025-03-07T01:49:55.661Z" }, ] [[package]] name = "nvidia-nvtx-cu12" -version = "12.6.77" +version = "12.8.90" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/56/9a/fff8376f8e3d084cd1530e1ef7b879bb7d6d265620c95c1b322725c694f4/nvidia_nvtx_cu12-12.6.77-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b90bed3df379fa79afbd21be8e04a0314336b8ae16768b58f2d34cb1d04cd7d2", size = 89276, upload-time = "2024-11-20T17:38:27.621Z" }, - { url = "https://files.pythonhosted.org/packages/9e/4e/0d0c945463719429b7bd21dece907ad0bde437a2ff12b9b12fee94722ab0/nvidia_nvtx_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6574241a3ec5fdc9334353ab8c479fe75841dbe8f4532a8fc97ce63503330ba1", size = 89265, upload-time = "2024-10-01T17:00:38.172Z" }, + { url = "https://files.pythonhosted.org/packages/a2/eb/86626c1bbc2edb86323022371c39aa48df6fd8b0a1647bc274577f72e90b/nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b17e2001cc0d751a5bc2c6ec6d26ad95913324a4adb86788c944f8ce9ba441f", size = 89954, upload-time = "2025-03-07T01:42:44.131Z" }, ] [[package]] @@ -1870,14 +2197,18 @@ wheels = [ [[package]] name = "outlines-core" -version = "0.2.10" +version = "0.2.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/13/e2/de74a5fd00299215270a750f356ba7cb427ba5d3e495cab07cfc3110ca86/outlines_core-0.2.10.tar.gz", hash = "sha256:c9ee7be195ac18dda5acce41d8805c2fb550a4affd525414511662cfa7097dfe", size = 197140, upload-time = "2025-05-12T18:20:27.301Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1a/d3/e04e9145f8f806723dec9b9e5227ad695a3efcd3ced7794cf7c22b15df5e/outlines_core-0.2.11.tar.gz", hash = "sha256:dfce56f717ff5083e54cbcfdb66cad243365437fccbb5509adaa7e31e030f1d8", size = 197263, upload-time = "2025-05-19T10:12:51.719Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/5f/e3c4589f1814a5d50c3b1b95ef2ff151c9e6e6d5c5ab62e07078410b1c6a/outlines_core-0.2.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63b9f0ef1fb61a5e18697e885b2eaa1f244d2ea021d68fdb2c9a607a769aeaa8", size = 2274712, upload-time = "2025-05-12T18:19:34.004Z" }, - { url = "https://files.pythonhosted.org/packages/86/c5/81917cdc984b375488d7a1bd0f4dd3e7330dc9d9979289504d32e195ba29/outlines_core-0.2.10-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:7b48e4bd776d4b3083d07baa3d722654e0425780772c4217f1df49d4984041b6", size = 2102981, upload-time = "2025-05-12T18:19:36.296Z" }, - { url = "https://files.pythonhosted.org/packages/e5/2e/baebc1b4dba5c92508282471ed655eb91fc13c70bd2b55c1fd7c6f16b8b7/outlines_core-0.2.10-cp311-cp311-win32.whl", hash = "sha256:795b19362798c408113da913a03e31a562a5faf4e2ea45ec0f44435843cc185e", size = 1764124, upload-time = "2025-05-12T18:19:37.979Z" }, - { url = "https://files.pythonhosted.org/packages/03/db/70de7ed1e39efee8de6356ebd13e2e7b931b0b251bc02817238e8d288029/outlines_core-0.2.10-cp311-cp311-win_amd64.whl", hash = "sha256:b5df420c57fc257a30cf3a6e088b174aeb84a19d516f6818f00b29b626540629", size = 2054551, upload-time = "2025-05-12T18:19:39.742Z" }, + { url = "https://files.pythonhosted.org/packages/4c/db/32c6e1170f139420e948fdd18a09a6175244bc0760dcf4dc2470e18411b9/outlines_core-0.2.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:132605b8dd1e3d1369da6a851992dd357f6376068292f6bd47caa7a28b794d19", size = 2289078, upload-time = "2025-05-19T10:12:12.118Z" }, + { url = "https://files.pythonhosted.org/packages/25/c3/b6e6f4e08fa84d2424f82705a6dc47fee33cb91989010fa678736957dcf6/outlines_core-0.2.11-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:b31d5fc83b78aad282dd667b8d6e684614481fe08a7609ce0ce45dee64cd2991", size = 2115075, upload-time = "2025-05-19T10:12:13.761Z" }, + { url = "https://files.pythonhosted.org/packages/d4/9b/b84c4933e4f35b34e9b23fadd63a365ad8563cc7561d8528b33de4ee8102/outlines_core-0.2.11-cp311-cp311-win32.whl", hash = "sha256:3e316a79f3ecfa12c17746edebcbd66538ee22a43986982f6b96166fb94ee6b1", size = 1768254, upload-time = "2025-05-19T10:12:15.02Z" }, + { url = "https://files.pythonhosted.org/packages/99/5b/380c933c65ca9744c163fe4a3702ad7f3e9ca02e09ac84a09b6837cff9b6/outlines_core-0.2.11-cp311-cp311-win_amd64.whl", hash = "sha256:c260a042b5854ff69291649cfd112066e6bab0dad0bb9cec8a6c3705ef3a59cd", size = 2062167, upload-time = "2025-05-19T10:12:16.443Z" }, + { url = "https://files.pythonhosted.org/packages/92/c7/a65d1fddf49830ebc41422294eacde35286d9f68994a8aa905cb14f5aade/outlines_core-0.2.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86df9740368866295077346440d911df4972da2b3f1f54b8125e6f329e8a8891", size = 2287677, upload-time = "2025-05-19T10:12:24.24Z" }, + { url = "https://files.pythonhosted.org/packages/23/79/8795aed8be9b77dd69d78e7cfbfcf28c179e6b08da6e56bbbf48a09fe55f/outlines_core-0.2.11-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:96ce4dd78f106799be4a0a5795cefd1352806162973756a4b6fce4bb6eddd7e4", size = 2113000, upload-time = "2025-05-19T10:12:25.446Z" }, + { url = "https://files.pythonhosted.org/packages/59/e3/cbe9294b06d92ee1892dbb6f2125d833d68e8629d45d080d6daba54eec2d/outlines_core-0.2.11-cp312-cp312-win32.whl", hash = "sha256:358db161cce3650ba822e118dcf0a1efa571c7deb4864ab9d64ca2c9cca7425d", size = 1765703, upload-time = "2025-05-19T10:12:26.693Z" }, + { url = "https://files.pythonhosted.org/packages/1d/c9/ed3cf362515fac16e313368b9b2f2497051f4ded88679205830b6f889f54/outlines_core-0.2.11-cp312-cp312-win_amd64.whl", hash = "sha256:231f9d20d2630c70665345821780d7808b29539620a75c99f65113b518c51032", size = 2060945, upload-time = "2025-05-19T10:12:28.294Z" }, ] [[package]] @@ -1908,6 +2239,13 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f2/00/a5ac8c7a0e67fd1a6059e40aa08fa1c52cc00709077d2300e210c3ce0322/pandas-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791", size = 13240453, upload-time = "2025-09-29T23:19:09.247Z" }, { url = "https://files.pythonhosted.org/packages/27/4d/5c23a5bc7bd209231618dd9e606ce076272c9bc4f12023a70e03a86b4067/pandas-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151", size = 13890361, upload-time = "2025-09-29T23:19:25.342Z" }, { url = "https://files.pythonhosted.org/packages/8e/59/712db1d7040520de7a4965df15b774348980e6df45c129b8c64d0dbe74ef/pandas-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c", size = 11348702, upload-time = "2025-09-29T23:19:38.296Z" }, + { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846, upload-time = "2025-09-29T23:19:48.856Z" }, + { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618, upload-time = "2025-09-29T23:39:08.659Z" }, + { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload-time = "2025-09-29T23:19:59.765Z" }, + { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693, upload-time = "2025-09-29T23:20:14.098Z" }, + { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002, upload-time = "2025-09-29T23:20:26.76Z" }, + { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971, upload-time = "2025-09-29T23:20:41.344Z" }, + { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722, upload-time = "2025-09-29T23:20:54.139Z" }, ] [[package]] @@ -1957,6 +2295,17 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1f/3d/d5033539344ee3cbd9a4d69e12e63ca3a44a739eb2d4c8da350a3d38edd7/pillow-12.0.0-cp311-cp311-win32.whl", hash = "sha256:27f95b12453d165099c84f8a8bfdfd46b9e4bda9e0e4b65f0635430027f55739", size = 6298440, upload-time = "2025-10-15T18:22:00.982Z" }, { url = "https://files.pythonhosted.org/packages/4d/42/aaca386de5cc8bd8a0254516957c1f265e3521c91515b16e286c662854c4/pillow-12.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:b583dc9070312190192631373c6c8ed277254aa6e6084b74bdd0a6d3b221608e", size = 6999256, upload-time = "2025-10-15T18:22:02.617Z" }, { url = "https://files.pythonhosted.org/packages/ba/f1/9197c9c2d5708b785f631a6dfbfa8eb3fb9672837cb92ae9af812c13b4ed/pillow-12.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:759de84a33be3b178a64c8ba28ad5c135900359e85fb662bc6e403ad4407791d", size = 2436025, upload-time = "2025-10-15T18:22:04.598Z" }, + { url = "https://files.pythonhosted.org/packages/2c/90/4fcce2c22caf044e660a198d740e7fbc14395619e3cb1abad12192c0826c/pillow-12.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:53561a4ddc36facb432fae7a9d8afbfaf94795414f5cdc5fc52f28c1dca90371", size = 5249377, upload-time = "2025-10-15T18:22:05.993Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e0/ed960067543d080691d47d6938ebccbf3976a931c9567ab2fbfab983a5dd/pillow-12.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:71db6b4c1653045dacc1585c1b0d184004f0d7e694c7b34ac165ca70c0838082", size = 4650343, upload-time = "2025-10-15T18:22:07.718Z" }, + { url = "https://files.pythonhosted.org/packages/e7/a1/f81fdeddcb99c044bf7d6faa47e12850f13cee0849537a7d27eeab5534d4/pillow-12.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2fa5f0b6716fc88f11380b88b31fe591a06c6315e955c096c35715788b339e3f", size = 6232981, upload-time = "2025-10-15T18:22:09.287Z" }, + { url = "https://files.pythonhosted.org/packages/88/e1/9098d3ce341a8750b55b0e00c03f1630d6178f38ac191c81c97a3b047b44/pillow-12.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:82240051c6ca513c616f7f9da06e871f61bfd7805f566275841af15015b8f98d", size = 8041399, upload-time = "2025-10-15T18:22:10.872Z" }, + { url = "https://files.pythonhosted.org/packages/a7/62/a22e8d3b602ae8cc01446d0c57a54e982737f44b6f2e1e019a925143771d/pillow-12.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55f818bd74fe2f11d4d7cbc65880a843c4075e0ac7226bc1a23261dbea531953", size = 6347740, upload-time = "2025-10-15T18:22:12.769Z" }, + { url = "https://files.pythonhosted.org/packages/4f/87/424511bdcd02c8d7acf9f65caa09f291a519b16bd83c3fb3374b3d4ae951/pillow-12.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b87843e225e74576437fd5b6a4c2205d422754f84a06942cfaf1dc32243e45a8", size = 7040201, upload-time = "2025-10-15T18:22:14.813Z" }, + { url = "https://files.pythonhosted.org/packages/dc/4d/435c8ac688c54d11755aedfdd9f29c9eeddf68d150fe42d1d3dbd2365149/pillow-12.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c607c90ba67533e1b2355b821fef6764d1dd2cbe26b8c1005ae84f7aea25ff79", size = 6462334, upload-time = "2025-10-15T18:22:16.375Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f2/ad34167a8059a59b8ad10bc5c72d4d9b35acc6b7c0877af8ac885b5f2044/pillow-12.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:21f241bdd5080a15bc86d3466a9f6074a9c2c2b314100dd896ac81ee6db2f1ba", size = 7134162, upload-time = "2025-10-15T18:22:17.996Z" }, + { url = "https://files.pythonhosted.org/packages/0c/b1/a7391df6adacf0a5c2cf6ac1cf1fcc1369e7d439d28f637a847f8803beb3/pillow-12.0.0-cp312-cp312-win32.whl", hash = "sha256:dd333073e0cacdc3089525c7df7d39b211bcdf31fc2824e49d01c6b6187b07d0", size = 6298769, upload-time = "2025-10-15T18:22:19.923Z" }, + { url = "https://files.pythonhosted.org/packages/a2/0b/d87733741526541c909bbf159e338dcace4f982daac6e5a8d6be225ca32d/pillow-12.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9fe611163f6303d1619bbcb653540a4d60f9e55e622d60a3108be0d5b441017a", size = 7001107, upload-time = "2025-10-15T18:22:21.644Z" }, + { url = "https://files.pythonhosted.org/packages/bc/96/aaa61ce33cc98421fb6088af2a03be4157b1e7e0e87087c888e2370a7f45/pillow-12.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:7dfb439562f234f7d57b1ac6bc8fe7f838a4bd49c79230e0f6a1da93e82f1fad", size = 2436012, upload-time = "2025-10-15T18:22:23.621Z" }, { url = "https://files.pythonhosted.org/packages/1d/b3/582327e6c9f86d037b63beebe981425d6811104cb443e8193824ef1a2f27/pillow-12.0.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b22bd8c974942477156be55a768f7aa37c46904c175be4e158b6a86e3a6b7ca8", size = 5215068, upload-time = "2025-10-15T18:23:59.594Z" }, { url = "https://files.pythonhosted.org/packages/fd/d6/67748211d119f3b6540baf90f92fae73ae51d5217b171b0e8b5f7e5d558f/pillow-12.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:805ebf596939e48dbb2e4922a1d3852cfc25c38160751ce02da93058b48d252a", size = 4614994, upload-time = "2025-10-15T18:24:01.669Z" }, { url = "https://files.pythonhosted.org/packages/2d/e1/f8281e5d844c41872b273b9f2c34a4bf64ca08905668c8ae730eedc7c9fa/pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cae81479f77420d217def5f54b5b9d279804d17e982e0f2fa19b1d1e14ab5197", size = 5246639, upload-time = "2025-10-15T18:24:03.403Z" }, @@ -2055,6 +2404,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/61/b0/b2631c19793f869d35f47d5a3a56fb19e9160d3c119f15ac7344fc3ccae7/propcache-0.4.1-cp311-cp311-win32.whl", hash = "sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1", size = 38084, upload-time = "2025-10-08T19:46:42.693Z" }, { url = "https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6", size = 41637, upload-time = "2025-10-08T19:46:43.778Z" }, { url = "https://files.pythonhosted.org/packages/9c/e9/754f180cccd7f51a39913782c74717c581b9cc8177ad0e949f4d51812383/propcache-0.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239", size = 38064, upload-time = "2025-10-08T19:46:44.872Z" }, + { url = "https://files.pythonhosted.org/packages/a2/0f/f17b1b2b221d5ca28b4b876e8bb046ac40466513960646bda8e1853cdfa2/propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2", size = 80061, upload-time = "2025-10-08T19:46:46.075Z" }, + { url = "https://files.pythonhosted.org/packages/76/47/8ccf75935f51448ba9a16a71b783eb7ef6b9ee60f5d14c7f8a8a79fbeed7/propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403", size = 46037, upload-time = "2025-10-08T19:46:47.23Z" }, + { url = "https://files.pythonhosted.org/packages/0a/b6/5c9a0e42df4d00bfb4a3cbbe5cf9f54260300c88a0e9af1f47ca5ce17ac0/propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207", size = 47324, upload-time = "2025-10-08T19:46:48.384Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d3/6c7ee328b39a81ee877c962469f1e795f9db87f925251efeb0545e0020d0/propcache-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72", size = 225505, upload-time = "2025-10-08T19:46:50.055Z" }, + { url = "https://files.pythonhosted.org/packages/01/5d/1c53f4563490b1d06a684742cc6076ef944bc6457df6051b7d1a877c057b/propcache-0.4.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367", size = 230242, upload-time = "2025-10-08T19:46:51.815Z" }, + { url = "https://files.pythonhosted.org/packages/20/e1/ce4620633b0e2422207c3cb774a0ee61cac13abc6217763a7b9e2e3f4a12/propcache-0.4.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4", size = 238474, upload-time = "2025-10-08T19:46:53.208Z" }, + { url = "https://files.pythonhosted.org/packages/46/4b/3aae6835b8e5f44ea6a68348ad90f78134047b503765087be2f9912140ea/propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf", size = 221575, upload-time = "2025-10-08T19:46:54.511Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a5/8a5e8678bcc9d3a1a15b9a29165640d64762d424a16af543f00629c87338/propcache-0.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3", size = 216736, upload-time = "2025-10-08T19:46:56.212Z" }, + { url = "https://files.pythonhosted.org/packages/f1/63/b7b215eddeac83ca1c6b934f89d09a625aa9ee4ba158338854c87210cc36/propcache-0.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778", size = 213019, upload-time = "2025-10-08T19:46:57.595Z" }, + { url = "https://files.pythonhosted.org/packages/57/74/f580099a58c8af587cac7ba19ee7cb418506342fbbe2d4a4401661cca886/propcache-0.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6", size = 220376, upload-time = "2025-10-08T19:46:59.067Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ee/542f1313aff7eaf19c2bb758c5d0560d2683dac001a1c96d0774af799843/propcache-0.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9", size = 226988, upload-time = "2025-10-08T19:47:00.544Z" }, + { url = "https://files.pythonhosted.org/packages/8f/18/9c6b015dd9c6930f6ce2229e1f02fb35298b847f2087ea2b436a5bfa7287/propcache-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75", size = 215615, upload-time = "2025-10-08T19:47:01.968Z" }, + { url = "https://files.pythonhosted.org/packages/80/9e/e7b85720b98c45a45e1fca6a177024934dc9bc5f4d5dd04207f216fc33ed/propcache-0.4.1-cp312-cp312-win32.whl", hash = "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8", size = 38066, upload-time = "2025-10-08T19:47:03.503Z" }, + { url = "https://files.pythonhosted.org/packages/54/09/d19cff2a5aaac632ec8fc03737b223597b1e347416934c1b3a7df079784c/propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db", size = 41655, upload-time = "2025-10-08T19:47:04.973Z" }, + { url = "https://files.pythonhosted.org/packages/68/ab/6b5c191bb5de08036a8c697b265d4ca76148efb10fa162f14af14fb5f076/propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1", size = 37789, upload-time = "2025-10-08T19:47:06.077Z" }, { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, ] @@ -2109,6 +2473,13 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/95/e1/9dbe4c465c3365959d183e6345d0a8d1dc5b02ca3f8db4760b3bc834cf25/pyarrow-22.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8382ad21458075c2e66a82a29d650f963ce51c7708c7c0ff313a8c206c4fd5e8", size = 48011148, upload-time = "2025-10-24T10:04:59.585Z" }, { url = "https://files.pythonhosted.org/packages/c5/b4/7caf5d21930061444c3cf4fa7535c82faf5263e22ce43af7c2759ceb5b8b/pyarrow-22.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1a812a5b727bc09c3d7ea072c4eebf657c2f7066155506ba31ebf4792f88f016", size = 50276964, upload-time = "2025-10-24T10:05:08.175Z" }, { url = "https://files.pythonhosted.org/packages/ae/f3/cec89bd99fa3abf826f14d4e53d3d11340ce6f6af4d14bdcd54cd83b6576/pyarrow-22.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:ec5d40dd494882704fb876c16fa7261a69791e784ae34e6b5992e977bd2e238c", size = 28106517, upload-time = "2025-10-24T10:05:14.314Z" }, + { url = "https://files.pythonhosted.org/packages/af/63/ba23862d69652f85b615ca14ad14f3bcfc5bf1b99ef3f0cd04ff93fdad5a/pyarrow-22.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:bea79263d55c24a32b0d79c00a1c58bb2ee5f0757ed95656b01c0fb310c5af3d", size = 34211578, upload-time = "2025-10-24T10:05:21.583Z" }, + { url = "https://files.pythonhosted.org/packages/b1/d0/f9ad86fe809efd2bcc8be32032fa72e8b0d112b01ae56a053006376c5930/pyarrow-22.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:12fe549c9b10ac98c91cf791d2945e878875d95508e1a5d14091a7aaa66d9cf8", size = 35989906, upload-time = "2025-10-24T10:05:29.485Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a8/f910afcb14630e64d673f15904ec27dd31f1e009b77033c365c84e8c1e1d/pyarrow-22.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:334f900ff08ce0423407af97e6c26ad5d4e3b0763645559ece6fbf3747d6a8f5", size = 45021677, upload-time = "2025-10-24T10:05:38.274Z" }, + { url = "https://files.pythonhosted.org/packages/13/95/aec81f781c75cd10554dc17a25849c720d54feafb6f7847690478dcf5ef8/pyarrow-22.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c6c791b09c57ed76a18b03f2631753a4960eefbbca80f846da8baefc6491fcfe", size = 47726315, upload-time = "2025-10-24T10:05:47.314Z" }, + { url = "https://files.pythonhosted.org/packages/bb/d4/74ac9f7a54cfde12ee42734ea25d5a3c9a45db78f9def949307a92720d37/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c3200cb41cdbc65156e5f8c908d739b0dfed57e890329413da2748d1a2cd1a4e", size = 47990906, upload-time = "2025-10-24T10:05:58.254Z" }, + { url = "https://files.pythonhosted.org/packages/2e/71/fedf2499bf7a95062eafc989ace56572f3343432570e1c54e6599d5b88da/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ac93252226cf288753d8b46280f4edf3433bf9508b6977f8dd8526b521a1bbb9", size = 50306783, upload-time = "2025-10-24T10:06:08.08Z" }, + { url = "https://files.pythonhosted.org/packages/68/ed/b202abd5a5b78f519722f3d29063dda03c114711093c1995a33b8e2e0f4b/pyarrow-22.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:44729980b6c50a5f2bfcc2668d36c569ce17f8b17bccaf470c4313dcbbf13c9d", size = 27972883, upload-time = "2025-10-24T10:06:14.204Z" }, ] [[package]] @@ -2134,6 +2505,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/3b/0645f21bb08ecf45635b624958b5f9e569069d31ecbf125dc7e0e5b83f60/pybase64-1.4.2-cp311-cp311-win32.whl", hash = "sha256:bfd828792982db8d787515535948c1e340f1819407c8832f94384c0ebeaf9d74", size = 33631, upload-time = "2025-07-27T13:03:05.194Z" }, { url = "https://files.pythonhosted.org/packages/8f/08/24f8103c1f19e78761026cdd9f3b3be73239bc19cf5ab6fef0e8042d0bc6/pybase64-1.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:7a9e89d40dbf833af481d1d5f1a44d173c9c4b56a7c8dba98e39a78ee87cfc52", size = 35781, upload-time = "2025-07-27T13:03:06.779Z" }, { url = "https://files.pythonhosted.org/packages/66/cd/832fb035a0ea7eb53d776a5cfa961849e22828f6dfdfcdb9eb43ba3c0166/pybase64-1.4.2-cp311-cp311-win_arm64.whl", hash = "sha256:ce5809fa90619b03eab1cd63fec142e6cf1d361731a9b9feacf27df76c833343", size = 30903, upload-time = "2025-07-27T13:03:07.903Z" }, + { url = "https://files.pythonhosted.org/packages/cb/2a/a24c810e7a61d2cc6f73fe9ee4872a03030887fa8654150901b15f376f65/pybase64-1.4.2-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:f48c32ac6a16cbf57a5a96a073fef6ff7e3526f623cd49faa112b7f9980bafba", size = 68192, upload-time = "2025-07-27T13:03:11.467Z" }, + { url = "https://files.pythonhosted.org/packages/ee/87/d9baf98cbfc37b8657290ad4421f3a3c36aa0eafe4872c5859cfb52f3448/pybase64-1.4.2-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ace8b23093a6bb862477080d9059b784096ab2f97541e8bfc40d42f062875149", size = 71587, upload-time = "2025-07-27T13:03:12.719Z" }, + { url = "https://files.pythonhosted.org/packages/0b/89/3df043cc56ef3b91b7aa0c26ae822a2d7ec8da0b0fd7c309c879b0eb5988/pybase64-1.4.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1772c7532a7fb6301baea3dd3e010148dbf70cd1136a83c2f5f91bdc94822145", size = 59910, upload-time = "2025-07-27T13:03:14.266Z" }, + { url = "https://files.pythonhosted.org/packages/75/4f/6641e9edf37aeb4d4524dc7ba2168eff8d96c90e77f6283c2be3400ab380/pybase64-1.4.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.whl", hash = "sha256:f86f7faddcba5cbfea475f8ab96567834c28bf09ca6c7c3d66ee445adac80d8f", size = 56701, upload-time = "2025-07-27T13:03:15.6Z" }, + { url = "https://files.pythonhosted.org/packages/2d/7f/20d8ac1046f12420a0954a45a13033e75f98aade36eecd00c64e3549b071/pybase64-1.4.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:0b8c8e275b5294089f314814b4a50174ab90af79d6a4850f6ae11261ff6a7372", size = 59288, upload-time = "2025-07-27T13:03:16.823Z" }, + { url = "https://files.pythonhosted.org/packages/17/ea/9c0ca570e3e50b3c6c3442e280c83b321a0464c86a9db1f982a4ff531550/pybase64-1.4.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:864d85a0470c615807ae8b97d724d068b940a2d10ac13a5f1b9e75a3ce441758", size = 60267, upload-time = "2025-07-27T13:03:18.132Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ac/46894929d71ccedebbfb0284173b0fea96bc029cd262654ba8451a7035d6/pybase64-1.4.2-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:47254d97ed2d8351e30ecfdb9e2414547f66ba73f8a09f932c9378ff75cd10c5", size = 54801, upload-time = "2025-07-27T13:03:19.669Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1e/02c95218ea964f0b2469717c2c69b48e63f4ca9f18af01a5b2a29e4c1216/pybase64-1.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:264b65ecc4f0ee73f3298ab83bbd8008f7f9578361b8df5b448f985d8c63e02a", size = 58599, upload-time = "2025-07-27T13:03:20.951Z" }, + { url = "https://files.pythonhosted.org/packages/15/45/ccc21004930789b8fb439d43e3212a6c260ccddb2bf450c39a20db093f33/pybase64-1.4.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:fbcc2b30cd740c16c9699f596f22c7a9e643591311ae72b1e776f2d539e9dd9d", size = 52388, upload-time = "2025-07-27T13:03:23.064Z" }, + { url = "https://files.pythonhosted.org/packages/c4/45/22e46e549710c4c237d77785b6fb1bc4c44c288a5c44237ba9daf5c34b82/pybase64-1.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cda9f79c22d51ee4508f5a43b673565f1d26af4330c99f114e37e3186fdd3607", size = 68802, upload-time = "2025-07-27T13:03:24.673Z" }, + { url = "https://files.pythonhosted.org/packages/55/0c/232c6261b81296e5593549b36e6e7884a5da008776d12665923446322c36/pybase64-1.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0c91c6d2a7232e2a1cd10b3b75a8bb657defacd4295a1e5e80455df2dfc84d4f", size = 57841, upload-time = "2025-07-27T13:03:25.948Z" }, + { url = "https://files.pythonhosted.org/packages/20/8a/b35a615ae6f04550d696bb179c414538b3b477999435fdd4ad75b76139e4/pybase64-1.4.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:a370dea7b1cee2a36a4d5445d4e09cc243816c5bc8def61f602db5a6f5438e52", size = 54320, upload-time = "2025-07-27T13:03:27.495Z" }, + { url = "https://files.pythonhosted.org/packages/d3/a9/8bd4f9bcc53689f1b457ecefed1eaa080e4949d65a62c31a38b7253d5226/pybase64-1.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9aa4de83f02e462a6f4e066811c71d6af31b52d7484de635582d0e3ec3d6cc3e", size = 56482, upload-time = "2025-07-27T13:03:28.942Z" }, + { url = "https://files.pythonhosted.org/packages/75/e5/4a7735b54a1191f61c3f5c2952212c85c2d6b06eb5fb3671c7603395f70c/pybase64-1.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:83a1c2f9ed00fee8f064d548c8654a480741131f280e5750bb32475b7ec8ee38", size = 70959, upload-time = "2025-07-27T13:03:30.171Z" }, + { url = "https://files.pythonhosted.org/packages/d3/67/e2b6cb32c782e12304d467418e70da0212567f42bd4d3b5eb1fdf64920ad/pybase64-1.4.2-cp312-cp312-win32.whl", hash = "sha256:a6e5688b18d558e8c6b8701cc8560836c4bbeba61d33c836b4dba56b19423716", size = 33683, upload-time = "2025-07-27T13:03:31.775Z" }, + { url = "https://files.pythonhosted.org/packages/4f/bc/d5c277496063a09707486180f17abbdbdebbf2f5c4441b20b11d3cb7dc7c/pybase64-1.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:c995d21b8bd08aa179cd7dd4db0695c185486ecc72da1e8f6c37ec86cadb8182", size = 35817, upload-time = "2025-07-27T13:03:32.99Z" }, + { url = "https://files.pythonhosted.org/packages/e6/69/e4be18ae685acff0ae77f75d4586590f29d2cd187bf603290cf1d635cad4/pybase64-1.4.2-cp312-cp312-win_arm64.whl", hash = "sha256:e254b9258c40509c2ea063a7784f6994988f3f26099d6e08704e3c15dfed9a55", size = 30900, upload-time = "2025-07-27T13:03:34.499Z" }, { url = "https://files.pythonhosted.org/packages/51/34/f40d3262c3953814b9bcdcf858436bd5bc1133a698be4bcc7ed2a8c0730d/pybase64-1.4.2-graalpy311-graalpy242_311_native-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:eef9255d926c64e2fca021d3aee98023bacb98e1518e5986d6aab04102411b04", size = 43212, upload-time = "2025-07-27T13:07:31.327Z" }, { url = "https://files.pythonhosted.org/packages/8c/2a/5e05d25718cb8ffd68bd46553ddfd2b660893d937feda1716b8a3b21fb38/pybase64-1.4.2-graalpy311-graalpy242_311_native-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:89614ea2d2329b6708746c540e0f14d692125df99fb1203ff0de948d9e68dfc9", size = 35789, upload-time = "2025-07-27T13:07:34.026Z" }, { url = "https://files.pythonhosted.org/packages/d5/9d/f56c3ee6e94faaae2896ecaf666428330cb24096abf7d2427371bb2b403a/pybase64-1.4.2-graalpy311-graalpy242_311_native-win_amd64.whl", hash = "sha256:e401cecd2d7ddcd558768b2140fd4430746be4d17fb14c99eec9e40789df136d", size = 35861, upload-time = "2025-07-27T13:07:37.099Z" }, @@ -2204,10 +2592,28 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fe/e6/8c9e81bb6dd7560e33b9053351c29f30c8194b72f2d6932888581f503482/pydantic_core-2.41.5-cp311-cp311-win32.whl", hash = "sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b", size = 1987549, upload-time = "2025-11-04T13:39:51.842Z" }, { url = "https://files.pythonhosted.org/packages/11/66/f14d1d978ea94d1bc21fc98fcf570f9542fe55bfcc40269d4e1a21c19bf7/pydantic_core-2.41.5-cp311-cp311-win_amd64.whl", hash = "sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe", size = 2011305, upload-time = "2025-11-04T13:39:53.485Z" }, { url = "https://files.pythonhosted.org/packages/56/d8/0e271434e8efd03186c5386671328154ee349ff0354d83c74f5caaf096ed/pydantic_core-2.41.5-cp311-cp311-win_arm64.whl", hash = "sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f", size = 1972902, upload-time = "2025-11-04T13:39:56.488Z" }, + { url = "https://files.pythonhosted.org/packages/5f/5d/5f6c63eebb5afee93bcaae4ce9a898f3373ca23df3ccaef086d0233a35a7/pydantic_core-2.41.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7", size = 2110990, upload-time = "2025-11-04T13:39:58.079Z" }, + { url = "https://files.pythonhosted.org/packages/aa/32/9c2e8ccb57c01111e0fd091f236c7b371c1bccea0fa85247ac55b1e2b6b6/pydantic_core-2.41.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0", size = 1896003, upload-time = "2025-11-04T13:39:59.956Z" }, + { url = "https://files.pythonhosted.org/packages/68/b8/a01b53cb0e59139fbc9e4fda3e9724ede8de279097179be4ff31f1abb65a/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69", size = 1919200, upload-time = "2025-11-04T13:40:02.241Z" }, + { url = "https://files.pythonhosted.org/packages/38/de/8c36b5198a29bdaade07b5985e80a233a5ac27137846f3bc2d3b40a47360/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75", size = 2052578, upload-time = "2025-11-04T13:40:04.401Z" }, + { url = "https://files.pythonhosted.org/packages/00/b5/0e8e4b5b081eac6cb3dbb7e60a65907549a1ce035a724368c330112adfdd/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05", size = 2208504, upload-time = "2025-11-04T13:40:06.072Z" }, + { url = "https://files.pythonhosted.org/packages/77/56/87a61aad59c7c5b9dc8caad5a41a5545cba3810c3e828708b3d7404f6cef/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc", size = 2335816, upload-time = "2025-11-04T13:40:07.835Z" }, + { url = "https://files.pythonhosted.org/packages/0d/76/941cc9f73529988688a665a5c0ecff1112b3d95ab48f81db5f7606f522d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c", size = 2075366, upload-time = "2025-11-04T13:40:09.804Z" }, + { url = "https://files.pythonhosted.org/packages/d3/43/ebef01f69baa07a482844faaa0a591bad1ef129253ffd0cdaa9d8a7f72d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5", size = 2171698, upload-time = "2025-11-04T13:40:12.004Z" }, + { url = "https://files.pythonhosted.org/packages/b1/87/41f3202e4193e3bacfc2c065fab7706ebe81af46a83d3e27605029c1f5a6/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c", size = 2132603, upload-time = "2025-11-04T13:40:13.868Z" }, + { url = "https://files.pythonhosted.org/packages/49/7d/4c00df99cb12070b6bccdef4a195255e6020a550d572768d92cc54dba91a/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294", size = 2329591, upload-time = "2025-11-04T13:40:15.672Z" }, + { url = "https://files.pythonhosted.org/packages/cc/6a/ebf4b1d65d458f3cda6a7335d141305dfa19bdc61140a884d165a8a1bbc7/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1", size = 2319068, upload-time = "2025-11-04T13:40:17.532Z" }, + { url = "https://files.pythonhosted.org/packages/49/3b/774f2b5cd4192d5ab75870ce4381fd89cf218af999515baf07e7206753f0/pydantic_core-2.41.5-cp312-cp312-win32.whl", hash = "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d", size = 1985908, upload-time = "2025-11-04T13:40:19.309Z" }, + { url = "https://files.pythonhosted.org/packages/86/45/00173a033c801cacf67c190fef088789394feaf88a98a7035b0e40d53dc9/pydantic_core-2.41.5-cp312-cp312-win_amd64.whl", hash = "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815", size = 2020145, upload-time = "2025-11-04T13:40:21.548Z" }, + { url = "https://files.pythonhosted.org/packages/f9/22/91fbc821fa6d261b376a3f73809f907cec5ca6025642c463d3488aad22fb/pydantic_core-2.41.5-cp312-cp312-win_arm64.whl", hash = "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3", size = 1976179, upload-time = "2025-11-04T13:40:23.393Z" }, { url = "https://files.pythonhosted.org/packages/11/72/90fda5ee3b97e51c494938a4a44c3a35a9c96c19bba12372fb9c634d6f57/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034", size = 2115441, upload-time = "2025-11-04T13:42:39.557Z" }, { url = "https://files.pythonhosted.org/packages/1f/53/8942f884fa33f50794f119012dc6a1a02ac43a56407adaac20463df8e98f/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c", size = 1930291, upload-time = "2025-11-04T13:42:42.169Z" }, { url = "https://files.pythonhosted.org/packages/79/c8/ecb9ed9cd942bce09fc888ee960b52654fbdbede4ba6c2d6e0d3b1d8b49c/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2", size = 1948632, upload-time = "2025-11-04T13:42:44.564Z" }, { url = "https://files.pythonhosted.org/packages/2e/1b/687711069de7efa6af934e74f601e2a4307365e8fdc404703afc453eab26/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad", size = 2138905, upload-time = "2025-11-04T13:42:47.156Z" }, + { url = "https://files.pythonhosted.org/packages/09/32/59b0c7e63e277fa7911c2fc70ccfb45ce4b98991e7ef37110663437005af/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd", size = 2110495, upload-time = "2025-11-04T13:42:49.689Z" }, + { url = "https://files.pythonhosted.org/packages/aa/81/05e400037eaf55ad400bcd318c05bb345b57e708887f07ddb2d20e3f0e98/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc", size = 1915388, upload-time = "2025-11-04T13:42:52.215Z" }, + { url = "https://files.pythonhosted.org/packages/6e/0d/e3549b2399f71d56476b77dbf3cf8937cec5cd70536bdc0e374a421d0599/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56", size = 1942879, upload-time = "2025-11-04T13:42:56.483Z" }, + { url = "https://files.pythonhosted.org/packages/f7/07/34573da085946b6a313d7c42f82f16e8920bfd730665de2d11c0c37a74b5/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b", size = 2139017, upload-time = "2025-11-04T13:42:59.471Z" }, { url = "https://files.pythonhosted.org/packages/5f/9b/1b3f0e9f9305839d7e84912f9e8bfbd191ed1b1ef48083609f0dabde978c/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26", size = 2101980, upload-time = "2025-11-04T13:43:25.97Z" }, { url = "https://files.pythonhosted.org/packages/a4/ed/d71fefcb4263df0da6a85b5d8a7508360f2f2e9b3bf5814be9c8bccdccc1/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808", size = 1923865, upload-time = "2025-11-04T13:43:28.763Z" }, { url = "https://files.pythonhosted.org/packages/ce/3a/626b38db460d675f873e4444b4bb030453bbe7b4ba55df821d026a0493c4/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc", size = 2134256, upload-time = "2025-11-04T13:43:31.71Z" }, @@ -2245,18 +2651,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, ] -[[package]] -name = "pynvml" -version = "13.0.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "nvidia-ml-py" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5c/57/da7dc63a79f59e082e26a66ac02d87d69ea316b35b35b7a00d82f3ce3d2f/pynvml-13.0.1.tar.gz", hash = "sha256:1245991d9db786b4d2f277ce66869bd58f38ac654e38c9397d18f243c8f6e48f", size = 35226, upload-time = "2025-09-05T20:33:25.377Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/4a/cac76c174bb439a0c46c9a4413fcbea5c6cabfb01879f7bbdb9fdfaed76c/pynvml-13.0.1-py3-none-any.whl", hash = "sha256:e2b20e0a501eeec951e2455b7ab444759cf048e0e13a57b08049fa2775266aa8", size = 28810, upload-time = "2025-09-05T20:33:24.13Z" }, -] - [[package]] name = "pyparsing" version = "3.2.5" @@ -2338,6 +2732,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7c/af/449a6a91e5d6db51420875c54f6aff7c97a86a3b13a0b4f1a5c13b988de3/pywin32-311-cp311-cp311-win32.whl", hash = "sha256:184eb5e436dea364dcd3d2316d577d625c0351bf237c4e9a5fabbcfa5a58b151", size = 8697031, upload-time = "2025-07-14T20:13:13.266Z" }, { url = "https://files.pythonhosted.org/packages/51/8f/9bb81dd5bb77d22243d33c8397f09377056d5c687aa6d4042bea7fbf8364/pywin32-311-cp311-cp311-win_amd64.whl", hash = "sha256:3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503", size = 9508308, upload-time = "2025-07-14T20:13:15.147Z" }, { url = "https://files.pythonhosted.org/packages/44/7b/9c2ab54f74a138c491aba1b1cd0795ba61f144c711daea84a88b63dc0f6c/pywin32-311-cp311-cp311-win_arm64.whl", hash = "sha256:a733f1388e1a842abb67ffa8e7aad0e70ac519e09b0f6a784e65a136ec7cefd2", size = 8703930, upload-time = "2025-07-14T20:13:16.945Z" }, + { url = "https://files.pythonhosted.org/packages/e7/ab/01ea1943d4eba0f850c3c61e78e8dd59757ff815ff3ccd0a84de5f541f42/pywin32-311-cp312-cp312-win32.whl", hash = "sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31", size = 8706543, upload-time = "2025-07-14T20:13:20.765Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a8/a0e8d07d4d051ec7502cd58b291ec98dcc0c3fff027caad0470b72cfcc2f/pywin32-311-cp312-cp312-win_amd64.whl", hash = "sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067", size = 9495040, upload-time = "2025-07-14T20:13:22.543Z" }, + { url = "https://files.pythonhosted.org/packages/ba/3a/2ae996277b4b50f17d61f0603efd8253cb2d79cc7ae159468007b586396d/pywin32-311-cp312-cp312-win_arm64.whl", hash = "sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852", size = 8710102, upload-time = "2025-07-14T20:13:24.682Z" }, ] [[package]] @@ -2355,6 +2752,16 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, ] [[package]] @@ -2408,6 +2815,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/be/89/9a11d0addbba6143f5a34929ed1fdef51159328b9b76a877c0c7f98b2848/ray-2.51.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:d2d7c8af45441ff50bc002352d31e0afec5c85dd5075bf527027178931497bce", size = 70460551, upload-time = "2025-11-01T03:24:05.77Z" }, { url = "https://files.pythonhosted.org/packages/f7/67/40a8d63e4cb3ff1a1a5a12db77ca655e21cb13f10e024a9513f24ed11d98/ray-2.51.1-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:dd353010d2548bc345e46c45795f70291bb460c236aa6a3393b51a9cd861b56f", size = 71280610, upload-time = "2025-11-01T03:24:11.981Z" }, { url = "https://files.pythonhosted.org/packages/62/97/90bcfed6b8c986f9ea24def19bbb81480575dd5fa87630eeaa4c92652507/ray-2.51.1-cp311-cp311-win_amd64.whl", hash = "sha256:606c6e0733eb18fc307c9645ea84ccbd1aad8a5ba8bad764bed54b94e926d33c", size = 26691238, upload-time = "2025-11-01T03:24:16.978Z" }, + { url = "https://files.pythonhosted.org/packages/e2/b5/a93e39e131067edb7cba3385a609f61aaaf7aa54728cd3a7474bfbf3b0fc/ray-2.51.1-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:0bed9408712bad1511e65683a455302f88d94e5e5cb6a58cc4a154b61d8a0b4a", size = 70502423, upload-time = "2025-11-01T03:24:27.398Z" }, + { url = "https://files.pythonhosted.org/packages/ee/59/69b7a653ed8176fc7fd894d462ed34bb1477e7fa71700324de99179b5b7e/ray-2.51.1-cp312-cp312-manylinux2014_x86_64.whl", hash = "sha256:4e786da7862cf73664977d0212a505d6d5a585beadf63e7dc1e1c129259bee20", size = 71353730, upload-time = "2025-11-01T03:24:33.495Z" }, + { url = "https://files.pythonhosted.org/packages/38/91/0c4fe7aed34baa14d9c050c88f39ff16083d555bd6dcd6c4ffb4332a6f8a/ray-2.51.1-cp312-cp312-win_amd64.whl", hash = "sha256:198fda93074a6863555f4003e9013bb2ba0cd50b59b18c02affdc294b28a2eef", size = 26674921, upload-time = "2025-11-01T03:24:38.394Z" }, ] [package.optional-dependencies] @@ -2449,6 +2859,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/66/47/dc2577c1f95f188c1e13e2e69d8825a5ac582ac709942f8a03af42ed6e93/regex-2025.11.3-cp311-cp311-win32.whl", hash = "sha256:3e816cc9aac1cd3cc9a4ec4d860f06d40f994b5c7b4d03b93345f44e08cc68bf", size = 265812, upload-time = "2025-11-03T21:31:29.72Z" }, { url = "https://files.pythonhosted.org/packages/50/1e/15f08b2f82a9bbb510621ec9042547b54d11e83cb620643ebb54e4eb7d71/regex-2025.11.3-cp311-cp311-win_amd64.whl", hash = "sha256:087511f5c8b7dfbe3a03f5d5ad0c2a33861b1fc387f21f6f60825a44865a385a", size = 277737, upload-time = "2025-11-03T21:31:31.422Z" }, { url = "https://files.pythonhosted.org/packages/f4/fc/6500eb39f5f76c5e47a398df82e6b535a5e345f839581012a418b16f9cc3/regex-2025.11.3-cp311-cp311-win_arm64.whl", hash = "sha256:1ff0d190c7f68ae7769cd0313fe45820ba07ffebfddfaa89cc1eb70827ba0ddc", size = 270290, upload-time = "2025-11-03T21:31:33.041Z" }, + { url = "https://files.pythonhosted.org/packages/e8/74/18f04cb53e58e3fb107439699bd8375cf5a835eec81084e0bddbd122e4c2/regex-2025.11.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bc8ab71e2e31b16e40868a40a69007bc305e1109bd4658eb6cad007e0bf67c41", size = 489312, upload-time = "2025-11-03T21:31:34.343Z" }, + { url = "https://files.pythonhosted.org/packages/78/3f/37fcdd0d2b1e78909108a876580485ea37c91e1acf66d3bb8e736348f441/regex-2025.11.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:22b29dda7e1f7062a52359fca6e58e548e28c6686f205e780b02ad8ef710de36", size = 291256, upload-time = "2025-11-03T21:31:35.675Z" }, + { url = "https://files.pythonhosted.org/packages/bf/26/0a575f58eb23b7ebd67a45fccbc02ac030b737b896b7e7a909ffe43ffd6a/regex-2025.11.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3a91e4a29938bc1a082cc28fdea44be420bf2bebe2665343029723892eb073e1", size = 288921, upload-time = "2025-11-03T21:31:37.07Z" }, + { url = "https://files.pythonhosted.org/packages/ea/98/6a8dff667d1af907150432cf5abc05a17ccd32c72a3615410d5365ac167a/regex-2025.11.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08b884f4226602ad40c5d55f52bf91a9df30f513864e0054bad40c0e9cf1afb7", size = 798568, upload-time = "2025-11-03T21:31:38.784Z" }, + { url = "https://files.pythonhosted.org/packages/64/15/92c1db4fa4e12733dd5a526c2dd2b6edcbfe13257e135fc0f6c57f34c173/regex-2025.11.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3e0b11b2b2433d1c39c7c7a30e3f3d0aeeea44c2a8d0bae28f6b95f639927a69", size = 864165, upload-time = "2025-11-03T21:31:40.559Z" }, + { url = "https://files.pythonhosted.org/packages/f9/e7/3ad7da8cdee1ce66c7cd37ab5ab05c463a86ffeb52b1a25fe7bd9293b36c/regex-2025.11.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:87eb52a81ef58c7ba4d45c3ca74e12aa4b4e77816f72ca25258a85b3ea96cb48", size = 912182, upload-time = "2025-11-03T21:31:42.002Z" }, + { url = "https://files.pythonhosted.org/packages/84/bd/9ce9f629fcb714ffc2c3faf62b6766ecb7a585e1e885eb699bcf130a5209/regex-2025.11.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a12ab1f5c29b4e93db518f5e3872116b7e9b1646c9f9f426f777b50d44a09e8c", size = 803501, upload-time = "2025-11-03T21:31:43.815Z" }, + { url = "https://files.pythonhosted.org/packages/7c/0f/8dc2e4349d8e877283e6edd6c12bdcebc20f03744e86f197ab6e4492bf08/regex-2025.11.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7521684c8c7c4f6e88e35ec89680ee1aa8358d3f09d27dfbdf62c446f5d4c695", size = 787842, upload-time = "2025-11-03T21:31:45.353Z" }, + { url = "https://files.pythonhosted.org/packages/f9/73/cff02702960bc185164d5619c0c62a2f598a6abff6695d391b096237d4ab/regex-2025.11.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7fe6e5440584e94cc4b3f5f4d98a25e29ca12dccf8873679a635638349831b98", size = 858519, upload-time = "2025-11-03T21:31:46.814Z" }, + { url = "https://files.pythonhosted.org/packages/61/83/0e8d1ae71e15bc1dc36231c90b46ee35f9d52fab2e226b0e039e7ea9c10a/regex-2025.11.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8e026094aa12b43f4fd74576714e987803a315c76edb6b098b9809db5de58f74", size = 850611, upload-time = "2025-11-03T21:31:48.289Z" }, + { url = "https://files.pythonhosted.org/packages/c8/f5/70a5cdd781dcfaa12556f2955bf170cd603cb1c96a1827479f8faea2df97/regex-2025.11.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:435bbad13e57eb5606a68443af62bed3556de2f46deb9f7d4237bc2f1c9fb3a0", size = 789759, upload-time = "2025-11-03T21:31:49.759Z" }, + { url = "https://files.pythonhosted.org/packages/59/9b/7c29be7903c318488983e7d97abcf8ebd3830e4c956c4c540005fcfb0462/regex-2025.11.3-cp312-cp312-win32.whl", hash = "sha256:3839967cf4dc4b985e1570fd8d91078f0c519f30491c60f9ac42a8db039be204", size = 266194, upload-time = "2025-11-03T21:31:51.53Z" }, + { url = "https://files.pythonhosted.org/packages/1a/67/3b92df89f179d7c367be654ab5626ae311cb28f7d5c237b6bb976cd5fbbb/regex-2025.11.3-cp312-cp312-win_amd64.whl", hash = "sha256:e721d1b46e25c481dc5ded6f4b3f66c897c58d2e8cfdf77bbced84339108b0b9", size = 277069, upload-time = "2025-11-03T21:31:53.151Z" }, + { url = "https://files.pythonhosted.org/packages/d7/55/85ba4c066fe5094d35b249c3ce8df0ba623cfd35afb22d6764f23a52a1c5/regex-2025.11.3-cp312-cp312-win_arm64.whl", hash = "sha256:64350685ff08b1d3a6fff33f45a9ca183dc1d58bbfe4981604e70ec9801bbc26", size = 270330, upload-time = "2025-11-03T21:31:54.514Z" }, ] [[package]] @@ -2512,6 +2936,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/bd/f4/1526eb01fdc2235aca1fd9d0189bee4021d009a8dcb0161540238c24166e/rignore-0.7.6-cp311-cp311-win32.whl", hash = "sha256:166ebce373105dd485ec213a6a2695986346e60c94ff3d84eb532a237b24a4d5", size = 646547, upload-time = "2025-11-05T21:41:49.439Z" }, { url = "https://files.pythonhosted.org/packages/7c/c8/dda0983e1845706beb5826459781549a840fe5a7eb934abc523e8cd17814/rignore-0.7.6-cp311-cp311-win_amd64.whl", hash = "sha256:44f35ee844b1a8cea50d056e6a595190ce9d42d3cccf9f19d280ae5f3058973a", size = 727139, upload-time = "2025-11-05T21:41:34.367Z" }, { url = "https://files.pythonhosted.org/packages/e3/47/eb1206b7bf65970d41190b879e1723fc6bbdb2d45e53565f28991a8d9d96/rignore-0.7.6-cp311-cp311-win_arm64.whl", hash = "sha256:14b58f3da4fa3d5c3fa865cab49821675371f5e979281c683e131ae29159a581", size = 657598, upload-time = "2025-11-05T21:41:23.758Z" }, + { url = "https://files.pythonhosted.org/packages/4a/c8/dea564b36dedac8de21c18e1851789545bc52a0c22ece9843444d5608a6a/rignore-0.7.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bda49950d405aa8d0ebe26af807c4e662dd281d926530f03f29690a2e07d649a", size = 897821, upload-time = "2025-11-05T20:40:52.613Z" }, + { url = "https://files.pythonhosted.org/packages/b3/2b/ee96db17ac1835e024c5d0742eefb7e46de60020385ac883dd3d1cde2c1f/rignore-0.7.6-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5fd5ab3840b8c16851d327ed06e9b8be6459702a53e5ab1fc4073b684b3789e", size = 873963, upload-time = "2025-11-05T20:41:07.49Z" }, + { url = "https://files.pythonhosted.org/packages/a5/8c/ad5a57bbb9d14d5c7e5960f712a8a0b902472ea3f4a2138cbf70d1777b75/rignore-0.7.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ced2a248352636a5c77504cb755dc02c2eef9a820a44d3f33061ce1bb8a7f2d2", size = 1169216, upload-time = "2025-11-05T20:41:23.73Z" }, + { url = "https://files.pythonhosted.org/packages/80/e6/5b00bc2a6bc1701e6878fca798cf5d9125eb3113193e33078b6fc0d99123/rignore-0.7.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a04a3b73b75ddc12c9c9b21efcdaab33ca3832941d6f1d67bffd860941cd448a", size = 942942, upload-time = "2025-11-05T20:41:39.393Z" }, + { url = "https://files.pythonhosted.org/packages/85/e5/7f99bd0cc9818a91d0e8b9acc65b792e35750e3bdccd15a7ee75e64efca4/rignore-0.7.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d24321efac92140b7ec910ac7c53ab0f0c86a41133d2bb4b0e6a7c94967f44dd", size = 959787, upload-time = "2025-11-05T20:42:09.765Z" }, + { url = "https://files.pythonhosted.org/packages/55/54/2ffea79a7c1eabcede1926347ebc2a81bc6b81f447d05b52af9af14948b9/rignore-0.7.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73c7aa109d41e593785c55fdaa89ad80b10330affa9f9d3e3a51fa695f739b20", size = 984245, upload-time = "2025-11-05T20:41:54.062Z" }, + { url = "https://files.pythonhosted.org/packages/41/f7/e80f55dfe0f35787fa482aa18689b9c8251e045076c35477deb0007b3277/rignore-0.7.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1734dc49d1e9501b07852ef44421f84d9f378da9fbeda729e77db71f49cac28b", size = 1078647, upload-time = "2025-11-05T21:40:13.463Z" }, + { url = "https://files.pythonhosted.org/packages/d4/cf/2c64f0b6725149f7c6e7e5a909d14354889b4beaadddaa5fff023ec71084/rignore-0.7.6-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5719ea14ea2b652c0c0894be5dfde954e1853a80dea27dd2fbaa749618d837f5", size = 1139186, upload-time = "2025-11-05T21:40:31.27Z" }, + { url = "https://files.pythonhosted.org/packages/75/95/a86c84909ccc24af0d094b50d54697951e576c252a4d9f21b47b52af9598/rignore-0.7.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:8e23424fc7ce35726854f639cb7968151a792c0c3d9d082f7f67e0c362cfecca", size = 1117604, upload-time = "2025-11-05T21:40:48.07Z" }, + { url = "https://files.pythonhosted.org/packages/7f/5e/13b249613fd5d18d58662490ab910a9f0be758981d1797789913adb4e918/rignore-0.7.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3efdcf1dd84d45f3e2bd2f93303d9be103888f56dfa7c3349b5bf4f0657ec696", size = 1127725, upload-time = "2025-11-05T21:41:05.804Z" }, + { url = "https://files.pythonhosted.org/packages/c7/28/fa5dcd1e2e16982c359128664e3785f202d3eca9b22dd0b2f91c4b3d242f/rignore-0.7.6-cp312-cp312-win32.whl", hash = "sha256:ccca9d1a8b5234c76b71546fc3c134533b013f40495f394a65614a81f7387046", size = 646145, upload-time = "2025-11-05T21:41:51.096Z" }, + { url = "https://files.pythonhosted.org/packages/26/87/69387fb5dd81a0f771936381431780b8cf66fcd2cfe9495e1aaf41548931/rignore-0.7.6-cp312-cp312-win_amd64.whl", hash = "sha256:c96a285e4a8bfec0652e0bfcf42b1aabcdda1e7625f5006d188e3b1c87fdb543", size = 726090, upload-time = "2025-11-05T21:41:36.485Z" }, + { url = "https://files.pythonhosted.org/packages/24/5f/e8418108dcda8087fb198a6f81caadbcda9fd115d61154bf0df4d6d3619b/rignore-0.7.6-cp312-cp312-win_arm64.whl", hash = "sha256:a64a750e7a8277a323f01ca50b7784a764845f6cce2fe38831cb93f0508d0051", size = 656317, upload-time = "2025-11-05T21:41:25.305Z" }, { url = "https://files.pythonhosted.org/packages/f1/d2/1b264f56132264ea609d3213ab603d6a27016b19559a1a1ede1a66a03dcd/rignore-0.7.6-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22baa462abdc36fdd5a5e2dae423107723351b85ff093762f9261148b9d0a04a", size = 899739, upload-time = "2025-11-05T20:41:01.518Z" }, { url = "https://files.pythonhosted.org/packages/55/e4/b3c5dfdd8d8a10741dfe7199ef45d19a0e42d0c13aa377c83bd6caf65d90/rignore-0.7.6-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53fb28882d2538cb2d231972146c4927a9d9455e62b209f85d634408c4103538", size = 874843, upload-time = "2025-11-05T20:41:17.687Z" }, { url = "https://files.pythonhosted.org/packages/cc/10/d6f3750233881a2a154cefc9a6a0a9b19da526b19f7f08221b552c6f827d/rignore-0.7.6-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87409f7eeb1103d6b77f3472a3a0d9a5953e3ae804a55080bdcb0120ee43995b", size = 1170348, upload-time = "2025-11-05T20:41:34.21Z" }, @@ -2545,6 +2982,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/40/f0/8c01aaedc0fa92156f0391f39ea93b5952bc0ec56b897763858f95da8168/rpds_py-0.29.0-cp311-cp311-win32.whl", hash = "sha256:923248a56dd8d158389a28934f6f69ebf89f218ef96a6b216a9be6861804d3f4", size = 221394, upload-time = "2025-11-16T14:48:15.374Z" }, { url = "https://files.pythonhosted.org/packages/7e/a5/a8b21c54c7d234efdc83dc034a4d7cd9668e3613b6316876a29b49dece71/rpds_py-0.29.0-cp311-cp311-win_amd64.whl", hash = "sha256:539eb77eb043afcc45314d1be09ea6d6cafb3addc73e0547c171c6d636957f60", size = 235713, upload-time = "2025-11-16T14:48:16.636Z" }, { url = "https://files.pythonhosted.org/packages/a7/1f/df3c56219523947b1be402fa12e6323fe6d61d883cf35d6cb5d5bb6db9d9/rpds_py-0.29.0-cp311-cp311-win_arm64.whl", hash = "sha256:bdb67151ea81fcf02d8f494703fb728d4d34d24556cbff5f417d74f6f5792e7c", size = 229157, upload-time = "2025-11-16T14:48:17.891Z" }, + { url = "https://files.pythonhosted.org/packages/3c/50/bc0e6e736d94e420df79be4deb5c9476b63165c87bb8f19ef75d100d21b3/rpds_py-0.29.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a0891cfd8db43e085c0ab93ab7e9b0c8fee84780d436d3b266b113e51e79f954", size = 376000, upload-time = "2025-11-16T14:48:19.141Z" }, + { url = "https://files.pythonhosted.org/packages/3e/3a/46676277160f014ae95f24de53bed0e3b7ea66c235e7de0b9df7bd5d68ba/rpds_py-0.29.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3897924d3f9a0361472d884051f9a2460358f9a45b1d85a39a158d2f8f1ad71c", size = 360575, upload-time = "2025-11-16T14:48:20.443Z" }, + { url = "https://files.pythonhosted.org/packages/75/ba/411d414ed99ea1afdd185bbabeeaac00624bd1e4b22840b5e9967ade6337/rpds_py-0.29.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a21deb8e0d1571508c6491ce5ea5e25669b1dd4adf1c9d64b6314842f708b5d", size = 392159, upload-time = "2025-11-16T14:48:22.12Z" }, + { url = "https://files.pythonhosted.org/packages/8f/b1/e18aa3a331f705467a48d0296778dc1fea9d7f6cf675bd261f9a846c7e90/rpds_py-0.29.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9efe71687d6427737a0a2de9ca1c0a216510e6cd08925c44162be23ed7bed2d5", size = 410602, upload-time = "2025-11-16T14:48:23.563Z" }, + { url = "https://files.pythonhosted.org/packages/2f/6c/04f27f0c9f2299274c76612ac9d2c36c5048bb2c6c2e52c38c60bf3868d9/rpds_py-0.29.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:40f65470919dc189c833e86b2c4bd21bd355f98436a2cef9e0a9a92aebc8e57e", size = 515808, upload-time = "2025-11-16T14:48:24.949Z" }, + { url = "https://files.pythonhosted.org/packages/83/56/a8412aa464fb151f8bc0d91fb0bb888adc9039bd41c1c6ba8d94990d8cf8/rpds_py-0.29.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:def48ff59f181130f1a2cb7c517d16328efac3ec03951cca40c1dc2049747e83", size = 416015, upload-time = "2025-11-16T14:48:26.782Z" }, + { url = "https://files.pythonhosted.org/packages/04/4c/f9b8a05faca3d9e0a6397c90d13acb9307c9792b2bff621430c58b1d6e76/rpds_py-0.29.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad7bd570be92695d89285a4b373006930715b78d96449f686af422debb4d3949", size = 395325, upload-time = "2025-11-16T14:48:28.055Z" }, + { url = "https://files.pythonhosted.org/packages/34/60/869f3bfbf8ed7b54f1ad9a5543e0fdffdd40b5a8f587fe300ee7b4f19340/rpds_py-0.29.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:5a572911cd053137bbff8e3a52d31c5d2dba51d3a67ad902629c70185f3f2181", size = 410160, upload-time = "2025-11-16T14:48:29.338Z" }, + { url = "https://files.pythonhosted.org/packages/91/aa/e5b496334e3aba4fe4c8a80187b89f3c1294c5c36f2a926da74338fa5a73/rpds_py-0.29.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d583d4403bcbf10cffc3ab5cee23d7643fcc960dff85973fd3c2d6c86e8dbb0c", size = 425309, upload-time = "2025-11-16T14:48:30.691Z" }, + { url = "https://files.pythonhosted.org/packages/85/68/4e24a34189751ceb6d66b28f18159922828dd84155876551f7ca5b25f14f/rpds_py-0.29.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:070befbb868f257d24c3bb350dbd6e2f645e83731f31264b19d7231dd5c396c7", size = 574644, upload-time = "2025-11-16T14:48:31.964Z" }, + { url = "https://files.pythonhosted.org/packages/8c/cf/474a005ea4ea9c3b4f17b6108b6b13cebfc98ebaff11d6e1b193204b3a93/rpds_py-0.29.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fc935f6b20b0c9f919a8ff024739174522abd331978f750a74bb68abd117bd19", size = 601605, upload-time = "2025-11-16T14:48:33.252Z" }, + { url = "https://files.pythonhosted.org/packages/f4/b1/c56f6a9ab8c5f6bb5c65c4b5f8229167a3a525245b0773f2c0896686b64e/rpds_py-0.29.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8c5a8ecaa44ce2d8d9d20a68a2483a74c07f05d72e94a4dff88906c8807e77b0", size = 564593, upload-time = "2025-11-16T14:48:34.643Z" }, + { url = "https://files.pythonhosted.org/packages/b3/13/0494cecce4848f68501e0a229432620b4b57022388b071eeff95f3e1e75b/rpds_py-0.29.0-cp312-cp312-win32.whl", hash = "sha256:ba5e1aeaf8dd6d8f6caba1f5539cddda87d511331714b7b5fc908b6cfc3636b7", size = 223853, upload-time = "2025-11-16T14:48:36.419Z" }, + { url = "https://files.pythonhosted.org/packages/1f/6a/51e9aeb444a00cdc520b032a28b07e5f8dc7bc328b57760c53e7f96997b4/rpds_py-0.29.0-cp312-cp312-win_amd64.whl", hash = "sha256:b5f6134faf54b3cb83375db0f113506f8b7770785be1f95a631e7e2892101977", size = 239895, upload-time = "2025-11-16T14:48:37.956Z" }, + { url = "https://files.pythonhosted.org/packages/d1/d4/8bce56cdad1ab873e3f27cb31c6a51d8f384d66b022b820525b879f8bed1/rpds_py-0.29.0-cp312-cp312-win_arm64.whl", hash = "sha256:b016eddf00dca7944721bf0cd85b6af7f6c4efaf83ee0b37c4133bd39757a8c7", size = 230321, upload-time = "2025-11-16T14:48:39.71Z" }, { url = "https://files.pythonhosted.org/packages/f2/ac/b97e80bf107159e5b9ba9c91df1ab95f69e5e41b435f27bdd737f0d583ac/rpds_py-0.29.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:acd82a9e39082dc5f4492d15a6b6c8599aa21db5c35aaf7d6889aea16502c07d", size = 373963, upload-time = "2025-11-16T14:50:16.205Z" }, { url = "https://files.pythonhosted.org/packages/40/5a/55e72962d5d29bd912f40c594e68880d3c7a52774b0f75542775f9250712/rpds_py-0.29.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:715b67eac317bf1c7657508170a3e011a1ea6ccb1c9d5f296e20ba14196be6b3", size = 364644, upload-time = "2025-11-16T14:50:18.22Z" }, { url = "https://files.pythonhosted.org/packages/99/2a/6b6524d0191b7fc1351c3c0840baac42250515afb48ae40c7ed15499a6a2/rpds_py-0.29.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3b1b87a237cb2dba4db18bcfaaa44ba4cd5936b91121b62292ff21df577fc43", size = 393847, upload-time = "2025-11-16T14:50:20.012Z" }, @@ -2610,6 +3062,11 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ef/0e/97dbca66347b8cf0ea8b529e6bb9367e337ba2e8be0ef5c1a545232abfde/scikit_learn-1.7.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:89877e19a80c7b11a2891a27c21c4894fb18e2c2e077815bcade10d34287b20d", size = 9715424, upload-time = "2025-09-09T08:20:36.776Z" }, { url = "https://files.pythonhosted.org/packages/f7/32/1f3b22e3207e1d2c883a7e09abb956362e7d1bd2f14458c7de258a26ac15/scikit_learn-1.7.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8da8bf89d4d79aaec192d2bda62f9b56ae4e5b4ef93b6a56b5de4977e375c1f1", size = 9509234, upload-time = "2025-09-09T08:20:38.957Z" }, { url = "https://files.pythonhosted.org/packages/9f/71/34ddbd21f1da67c7a768146968b4d0220ee6831e4bcbad3e03dd3eae88b6/scikit_learn-1.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:9b7ed8d58725030568523e937c43e56bc01cadb478fc43c042a9aca1dacb3ba1", size = 8894244, upload-time = "2025-09-09T08:20:41.166Z" }, + { url = "https://files.pythonhosted.org/packages/a7/aa/3996e2196075689afb9fce0410ebdb4a09099d7964d061d7213700204409/scikit_learn-1.7.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8d91a97fa2b706943822398ab943cde71858a50245e31bc71dba62aab1d60a96", size = 9259818, upload-time = "2025-09-09T08:20:43.19Z" }, + { url = "https://files.pythonhosted.org/packages/43/5d/779320063e88af9c4a7c2cf463ff11c21ac9c8bd730c4a294b0000b666c9/scikit_learn-1.7.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:acbc0f5fd2edd3432a22c69bed78e837c70cf896cd7993d71d51ba6708507476", size = 8636997, upload-time = "2025-09-09T08:20:45.468Z" }, + { url = "https://files.pythonhosted.org/packages/5c/d0/0c577d9325b05594fdd33aa970bf53fb673f051a45496842caee13cfd7fe/scikit_learn-1.7.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e5bf3d930aee75a65478df91ac1225ff89cd28e9ac7bd1196853a9229b6adb0b", size = 9478381, upload-time = "2025-09-09T08:20:47.982Z" }, + { url = "https://files.pythonhosted.org/packages/82/70/8bf44b933837ba8494ca0fc9a9ab60f1c13b062ad0197f60a56e2fc4c43e/scikit_learn-1.7.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4d6e9deed1a47aca9fe2f267ab8e8fe82ee20b4526b2c0cd9e135cea10feb44", size = 9300296, upload-time = "2025-09-09T08:20:50.366Z" }, + { url = "https://files.pythonhosted.org/packages/c6/99/ed35197a158f1fdc2fe7c3680e9c70d0128f662e1fee4ed495f4b5e13db0/scikit_learn-1.7.2-cp312-cp312-win_amd64.whl", hash = "sha256:6088aa475f0785e01bcf8529f55280a3d7d298679f50c0bb70a2364a82d0b290", size = 8731256, upload-time = "2025-09-09T08:20:52.627Z" }, ] [[package]] @@ -2631,6 +3088,16 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/39/c1/1903de608c0c924a1749c590064e65810f8046e437aba6be365abc4f7557/scipy-1.16.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:deb3841c925eeddb6afc1e4e4a45e418d19ec7b87c5df177695224078e8ec733", size = 38878540, upload-time = "2025-10-28T17:32:23.907Z" }, { url = "https://files.pythonhosted.org/packages/f1/d0/22ec7036ba0b0a35bccb7f25ab407382ed34af0b111475eb301c16f8a2e5/scipy-1.16.3-cp311-cp311-win_amd64.whl", hash = "sha256:53c3844d527213631e886621df5695d35e4f6a75f620dca412bcd292f6b87d78", size = 38722107, upload-time = "2025-10-28T17:32:29.921Z" }, { url = "https://files.pythonhosted.org/packages/7b/60/8a00e5a524bb3bf8898db1650d350f50e6cffb9d7a491c561dc9826c7515/scipy-1.16.3-cp311-cp311-win_arm64.whl", hash = "sha256:9452781bd879b14b6f055b26643703551320aa8d79ae064a71df55c00286a184", size = 25506272, upload-time = "2025-10-28T17:32:34.577Z" }, + { url = "https://files.pythonhosted.org/packages/40/41/5bf55c3f386b1643812f3a5674edf74b26184378ef0f3e7c7a09a7e2ca7f/scipy-1.16.3-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:81fc5827606858cf71446a5e98715ba0e11f0dbc83d71c7409d05486592a45d6", size = 36659043, upload-time = "2025-10-28T17:32:40.285Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0f/65582071948cfc45d43e9870bf7ca5f0e0684e165d7c9ef4e50d783073eb/scipy-1.16.3-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:c97176013d404c7346bf57874eaac5187d969293bf40497140b0a2b2b7482e07", size = 28898986, upload-time = "2025-10-28T17:32:45.325Z" }, + { url = "https://files.pythonhosted.org/packages/96/5e/36bf3f0ac298187d1ceadde9051177d6a4fe4d507e8f59067dc9dd39e650/scipy-1.16.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2b71d93c8a9936046866acebc915e2af2e292b883ed6e2cbe5c34beb094b82d9", size = 20889814, upload-time = "2025-10-28T17:32:49.277Z" }, + { url = "https://files.pythonhosted.org/packages/80/35/178d9d0c35394d5d5211bbff7ac4f2986c5488b59506fef9e1de13ea28d3/scipy-1.16.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3d4a07a8e785d80289dfe66b7c27d8634a773020742ec7187b85ccc4b0e7b686", size = 23565795, upload-time = "2025-10-28T17:32:53.337Z" }, + { url = "https://files.pythonhosted.org/packages/fa/46/d1146ff536d034d02f83c8afc3c4bab2eddb634624d6529a8512f3afc9da/scipy-1.16.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0553371015692a898e1aa858fed67a3576c34edefa6b7ebdb4e9dde49ce5c203", size = 33349476, upload-time = "2025-10-28T17:32:58.353Z" }, + { url = "https://files.pythonhosted.org/packages/79/2e/415119c9ab3e62249e18c2b082c07aff907a273741b3f8160414b0e9193c/scipy-1.16.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:72d1717fd3b5e6ec747327ce9bda32d5463f472c9dce9f54499e81fbd50245a1", size = 35676692, upload-time = "2025-10-28T17:33:03.88Z" }, + { url = "https://files.pythonhosted.org/packages/27/82/df26e44da78bf8d2aeaf7566082260cfa15955a5a6e96e6a29935b64132f/scipy-1.16.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fb2472e72e24d1530debe6ae078db70fb1605350c88a3d14bc401d6306dbffe", size = 36019345, upload-time = "2025-10-28T17:33:09.773Z" }, + { url = "https://files.pythonhosted.org/packages/82/31/006cbb4b648ba379a95c87262c2855cd0d09453e500937f78b30f02fa1cd/scipy-1.16.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c5192722cffe15f9329a3948c4b1db789fbb1f05c97899187dcf009b283aea70", size = 38678975, upload-time = "2025-10-28T17:33:15.809Z" }, + { url = "https://files.pythonhosted.org/packages/c2/7f/acbd28c97e990b421af7d6d6cd416358c9c293fc958b8529e0bd5d2a2a19/scipy-1.16.3-cp312-cp312-win_amd64.whl", hash = "sha256:56edc65510d1331dae01ef9b658d428e33ed48b4f77b1d51caf479a0253f96dc", size = 38555926, upload-time = "2025-10-28T17:33:21.388Z" }, + { url = "https://files.pythonhosted.org/packages/ce/69/c5c7807fd007dad4f48e0a5f2153038dc96e8725d3345b9ee31b2b7bed46/scipy-1.16.3-cp312-cp312-win_arm64.whl", hash = "sha256:a8a26c78ef223d3e30920ef759e25625a0ecdd0d60e5a8818b7513c3e5384cf2", size = 25463014, upload-time = "2025-10-28T17:33:25.975Z" }, ] [[package]] @@ -2644,6 +3111,11 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a9/2d/3bd9b08e70067b2124518b308db6a84a4f8901cc8a4317e2e4288cdd9b4d/sentencepiece-0.2.1-cp311-cp311-win32.whl", hash = "sha256:6d297a1748d429ba8534eebe5535448d78b8acc32d00a29b49acf28102eeb094", size = 999555, upload-time = "2025-08-12T06:59:34.475Z" }, { url = "https://files.pythonhosted.org/packages/32/b8/f709977f5fda195ae1ea24f24e7c581163b6f142b1005bc3d0bbfe4d7082/sentencepiece-0.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:82d9ead6591015f009cb1be1cb1c015d5e6f04046dbb8c9588b931e869a29728", size = 1054617, upload-time = "2025-08-12T06:59:36.461Z" }, { url = "https://files.pythonhosted.org/packages/7a/40/a1fc23be23067da0f703709797b464e8a30a1c78cc8a687120cd58d4d509/sentencepiece-0.2.1-cp311-cp311-win_arm64.whl", hash = "sha256:39f8651bd10974eafb9834ce30d9bcf5b73e1fc798a7f7d2528f9820ca86e119", size = 1033877, upload-time = "2025-08-12T06:59:38.391Z" }, + { url = "https://files.pythonhosted.org/packages/89/fa/d3d5ebcba3cb9e6d3775a096251860c41a6bc53a1b9461151df83fe93255/sentencepiece-0.2.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:99f955df238021bf11f0fc37cdb54fd5e5b5f7fd30ecc3d93fb48b6815437167", size = 1316273, upload-time = "2025-08-12T06:59:44.476Z" }, + { url = "https://files.pythonhosted.org/packages/04/88/14f2f4a2b922d8b39be45bf63d79e6cd3a9b2f248b2fcb98a69b12af12f5/sentencepiece-0.2.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0cdfecef430d985f1c2bcbfff3defd1d95dae876fbd0173376012d2d7d24044b", size = 1387881, upload-time = "2025-08-12T06:59:46.09Z" }, + { url = "https://files.pythonhosted.org/packages/fd/b8/903e5ccb77b4ef140605d5d71b4f9e0ad95d456d6184688073ed11712809/sentencepiece-0.2.1-cp312-cp312-win32.whl", hash = "sha256:a483fd29a34c3e34c39ac5556b0a90942bec253d260235729e50976f5dba1068", size = 999540, upload-time = "2025-08-12T06:59:48.023Z" }, + { url = "https://files.pythonhosted.org/packages/2d/81/92df5673c067148c2545b1bfe49adfd775bcc3a169a047f5a0e6575ddaca/sentencepiece-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:4cdc7c36234fda305e85c32949c5211faaf8dd886096c7cea289ddc12a2d02de", size = 1054671, upload-time = "2025-08-12T06:59:49.895Z" }, + { url = "https://files.pythonhosted.org/packages/fe/02/c5e3bc518655d714622bec87d83db9cdba1cd0619a4a04e2109751c4f47f/sentencepiece-0.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:daeb5e9e9fcad012324807856113708614d534f596d5008638eb9b40112cd9e4", size = 1033923, upload-time = "2025-08-12T06:59:51.952Z" }, ] [[package]] @@ -2673,14 +3145,39 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6b/63/f0b6205c64d74d2a24a58644a38ec77bdbaa6afc13747e75973bf8904932/setproctitle-1.3.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:316664d8b24a5c91ee244460bdaf7a74a707adaa9e14fbe0dc0a53168bb9aba1", size = 31836, upload-time = "2025-09-05T12:49:32.309Z" }, { url = "https://files.pythonhosted.org/packages/ba/51/e1277f9ba302f1a250bbd3eedbbee747a244b3cc682eb58fb9733968f6d8/setproctitle-1.3.7-cp311-cp311-win32.whl", hash = "sha256:b74774ca471c86c09b9d5037c8451fff06bb82cd320d26ae5a01c758088c0d5d", size = 12556, upload-time = "2025-09-05T12:49:33.529Z" }, { url = "https://files.pythonhosted.org/packages/b6/7b/822a23f17e9003dfdee92cd72758441ca2a3680388da813a371b716fb07f/setproctitle-1.3.7-cp311-cp311-win_amd64.whl", hash = "sha256:acb9097213a8dd3410ed9f0dc147840e45ca9797785272928d4be3f0e69e3be4", size = 13243, upload-time = "2025-09-05T12:49:34.553Z" }, + { url = "https://files.pythonhosted.org/packages/d0/99/71630546b9395b095f4082be41165d1078204d1696c2d9baade3de3202d0/setproctitle-1.3.7-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2906b6c7959cdb75f46159bf0acd8cc9906cf1361c9e1ded0d065fe8f9039629", size = 32932, upload-time = "2025-09-05T12:49:39.271Z" }, + { url = "https://files.pythonhosted.org/packages/50/22/cee06af4ffcfb0e8aba047bd44f5262e644199ae7527ae2c1f672b86495c/setproctitle-1.3.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6915964a6dda07920a1159321dcd6d94fc7fc526f815ca08a8063aeca3c204f1", size = 33736, upload-time = "2025-09-05T12:49:40.565Z" }, + { url = "https://files.pythonhosted.org/packages/5c/00/a5949a8bb06ef5e7df214fc393bb2fb6aedf0479b17214e57750dfdd0f24/setproctitle-1.3.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cff72899861c765bd4021d1ff1c68d60edc129711a2fdba77f9cb69ef726a8b6", size = 35605, upload-time = "2025-09-05T12:49:42.362Z" }, + { url = "https://files.pythonhosted.org/packages/b0/3a/50caca532a9343828e3bf5778c7a84d6c737a249b1796d50dd680290594d/setproctitle-1.3.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b7cb05bd446687ff816a3aaaf831047fc4c364feff7ada94a66024f1367b448c", size = 33143, upload-time = "2025-09-05T12:49:43.515Z" }, + { url = "https://files.pythonhosted.org/packages/ca/14/b843a251296ce55e2e17c017d6b9f11ce0d3d070e9265de4ecad948b913d/setproctitle-1.3.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3a57b9a00de8cae7e2a1f7b9f0c2ac7b69372159e16a7708aa2f38f9e5cc987a", size = 34434, upload-time = "2025-09-05T12:49:45.31Z" }, + { url = "https://files.pythonhosted.org/packages/c8/b7/06145c238c0a6d2c4bc881f8be230bb9f36d2bf51aff7bddcb796d5eed67/setproctitle-1.3.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d8828b356114f6b308b04afe398ed93803d7fca4a955dd3abe84430e28d33739", size = 32795, upload-time = "2025-09-05T12:49:46.419Z" }, + { url = "https://files.pythonhosted.org/packages/ef/dc/ef76a81fac9bf27b84ed23df19c1f67391a753eed6e3c2254ebcb5133f56/setproctitle-1.3.7-cp312-cp312-win32.whl", hash = "sha256:b0304f905efc845829ac2bc791ddebb976db2885f6171f4a3de678d7ee3f7c9f", size = 12552, upload-time = "2025-09-05T12:49:47.635Z" }, + { url = "https://files.pythonhosted.org/packages/e2/5b/a9fe517912cd6e28cf43a212b80cb679ff179a91b623138a99796d7d18a0/setproctitle-1.3.7-cp312-cp312-win_amd64.whl", hash = "sha256:9888ceb4faea3116cf02a920ff00bfbc8cc899743e4b4ac914b03625bdc3c300", size = 13247, upload-time = "2025-09-05T12:49:49.16Z" }, { url = "https://files.pythonhosted.org/packages/73/02/b9eadc226195dcfa90eed37afe56b5dd6fa2f0e5220ab8b7867b8862b926/setproctitle-1.3.7-pp311-pypy311_pp73-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f1704c9e041f2b1dc38f5be4552e141e1432fba3dd52c72eeffd5bc2db04dc65", size = 14286, upload-time = "2025-09-05T12:51:22.61Z" }, { url = "https://files.pythonhosted.org/packages/28/26/1be1d2a53c2a91ec48fa2ff4a409b395f836798adf194d99de9c059419ea/setproctitle-1.3.7-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b08b61976ffa548bd5349ce54404bf6b2d51bd74d4f1b241ed1b0f25bce09c3a", size = 13282, upload-time = "2025-09-05T12:51:24.094Z" }, ] +[[package]] +name = "setuptools" +version = "79.0.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.12' and sys_platform == 'linux'", + "python_full_version >= '3.12' and sys_platform != 'linux'", +] +sdist = { url = "https://files.pythonhosted.org/packages/bb/71/b6365e6325b3290e14957b2c3a804a529968c77a049b2ed40c095f749707/setuptools-79.0.1.tar.gz", hash = "sha256:128ce7b8f33c3079fd1b067ecbb4051a66e8526e7b65f6cec075dfc650ddfa88", size = 1367909, upload-time = "2025-04-23T22:20:59.241Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/6d/b4752b044bf94cb802d88a888dc7d288baaf77d7910b7dedda74b5ceea0c/setuptools-79.0.1-py3-none-any.whl", hash = "sha256:e147c0549f27767ba362f9da434eab9c5dc0045d5304feb602a0af001089fc51", size = 1256281, upload-time = "2025-04-23T22:20:56.768Z" }, +] + [[package]] name = "setuptools" version = "80.9.0" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.12' and sys_platform == 'linux'", + "python_full_version < '3.12' and sys_platform != 'linux'", +] sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, @@ -2888,6 +3385,13 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/78/db/a58e09687c1698a7c592e1038e01c206569b86a0377828d51635561f8ebf/tiktoken-0.12.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:508fa71810c0efdcd1b898fda574889ee62852989f7c1667414736bcb2b9a4bd", size = 1195080, upload-time = "2025-10-06T20:21:49.246Z" }, { url = "https://files.pythonhosted.org/packages/9e/1b/a9e4d2bf91d515c0f74afc526fd773a812232dd6cda33ebea7f531202325/tiktoken-0.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a1af81a6c44f008cba48494089dd98cccb8b313f55e961a52f5b222d1e507967", size = 1255240, upload-time = "2025-10-06T20:21:50.274Z" }, { url = "https://files.pythonhosted.org/packages/9d/15/963819345f1b1fb0809070a79e9dd96938d4ca41297367d471733e79c76c/tiktoken-0.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:3e68e3e593637b53e56f7237be560f7a394451cb8c11079755e80ae64b9e6def", size = 879422, upload-time = "2025-10-06T20:21:51.734Z" }, + { url = "https://files.pythonhosted.org/packages/a4/85/be65d39d6b647c79800fd9d29241d081d4eeb06271f383bb87200d74cf76/tiktoken-0.12.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b97f74aca0d78a1ff21b8cd9e9925714c15a9236d6ceacf5c7327c117e6e21e8", size = 1050728, upload-time = "2025-10-06T20:21:52.756Z" }, + { url = "https://files.pythonhosted.org/packages/4a/42/6573e9129bc55c9bf7300b3a35bef2c6b9117018acca0dc760ac2d93dffe/tiktoken-0.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b90f5ad190a4bb7c3eb30c5fa32e1e182ca1ca79f05e49b448438c3e225a49b", size = 994049, upload-time = "2025-10-06T20:21:53.782Z" }, + { url = "https://files.pythonhosted.org/packages/66/c5/ed88504d2f4a5fd6856990b230b56d85a777feab84e6129af0822f5d0f70/tiktoken-0.12.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:65b26c7a780e2139e73acc193e5c63ac754021f160df919add909c1492c0fb37", size = 1129008, upload-time = "2025-10-06T20:21:54.832Z" }, + { url = "https://files.pythonhosted.org/packages/f4/90/3dae6cc5436137ebd38944d396b5849e167896fc2073da643a49f372dc4f/tiktoken-0.12.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:edde1ec917dfd21c1f2f8046b86348b0f54a2c0547f68149d8600859598769ad", size = 1152665, upload-time = "2025-10-06T20:21:56.129Z" }, + { url = "https://files.pythonhosted.org/packages/a3/fe/26df24ce53ffde419a42f5f53d755b995c9318908288c17ec3f3448313a3/tiktoken-0.12.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:35a2f8ddd3824608b3d650a000c1ef71f730d0c56486845705a8248da00f9fe5", size = 1194230, upload-time = "2025-10-06T20:21:57.546Z" }, + { url = "https://files.pythonhosted.org/packages/20/cc/b064cae1a0e9fac84b0d2c46b89f4e57051a5f41324e385d10225a984c24/tiktoken-0.12.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:83d16643edb7fa2c99eff2ab7733508aae1eebb03d5dfc46f5565862810f24e3", size = 1254688, upload-time = "2025-10-06T20:21:58.619Z" }, + { url = "https://files.pythonhosted.org/packages/81/10/b8523105c590c5b8349f2587e2fdfe51a69544bd5a76295fc20f2374f470/tiktoken-0.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ffc5288f34a8bc02e1ea7047b8d041104791d2ddbf42d1e5fa07822cbffe16bd", size = 878694, upload-time = "2025-10-06T20:21:59.876Z" }, ] [[package]] @@ -2926,7 +3430,7 @@ wheels = [ [[package]] name = "torch" -version = "2.7.1" +version = "2.8.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock" }, @@ -2947,33 +3451,41 @@ dependencies = [ { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "setuptools", version = "79.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, { name = "sympy" }, { name = "triton", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "typing-extensions" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/11/56/2eae3494e3d375533034a8e8cf0ba163363e996d85f0629441fa9d9843fe/torch-2.7.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:236f501f2e383f1cb861337bdf057712182f910f10aeaf509065d54d339e49b2", size = 99093039, upload-time = "2025-06-04T17:39:06.963Z" }, - { url = "https://files.pythonhosted.org/packages/e5/94/34b80bd172d0072c9979708ccd279c2da2f55c3ef318eceec276ab9544a4/torch-2.7.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:06eea61f859436622e78dd0cdd51dbc8f8c6d76917a9cf0555a333f9eac31ec1", size = 821174704, upload-time = "2025-06-04T17:37:03.799Z" }, - { url = "https://files.pythonhosted.org/packages/50/9e/acf04ff375b0b49a45511c55d188bcea5c942da2aaf293096676110086d1/torch-2.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:8273145a2e0a3c6f9fd2ac36762d6ee89c26d430e612b95a99885df083b04e52", size = 216095937, upload-time = "2025-06-04T17:39:24.83Z" }, - { url = "https://files.pythonhosted.org/packages/5b/2b/d36d57c66ff031f93b4fa432e86802f84991477e522adcdffd314454326b/torch-2.7.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:aea4fc1bf433d12843eb2c6b2204861f43d8364597697074c8d38ae2507f8730", size = 68640034, upload-time = "2025-06-04T17:39:17.989Z" }, + { url = "https://files.pythonhosted.org/packages/8f/c4/3e7a3887eba14e815e614db70b3b529112d1513d9dae6f4d43e373360b7f/torch-2.8.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:220a06fd7af8b653c35d359dfe1aaf32f65aa85befa342629f716acb134b9710", size = 102073391, upload-time = "2025-08-06T14:53:20.937Z" }, + { url = "https://files.pythonhosted.org/packages/5a/63/4fdc45a0304536e75a5e1b1bbfb1b56dd0e2743c48ee83ca729f7ce44162/torch-2.8.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:c12fa219f51a933d5f80eeb3a7a5d0cbe9168c0a14bbb4055f1979431660879b", size = 888063640, upload-time = "2025-08-06T14:55:05.325Z" }, + { url = "https://files.pythonhosted.org/packages/84/57/2f64161769610cf6b1c5ed782bd8a780e18a3c9d48931319f2887fa9d0b1/torch-2.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:8c7ef765e27551b2fbfc0f41bcf270e1292d9bf79f8e0724848b1682be6e80aa", size = 241366752, upload-time = "2025-08-06T14:53:38.692Z" }, + { url = "https://files.pythonhosted.org/packages/a4/5e/05a5c46085d9b97e928f3f037081d3d2b87fb4b4195030fc099aaec5effc/torch-2.8.0-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:5ae0524688fb6707c57a530c2325e13bb0090b745ba7b4a2cd6a3ce262572916", size = 73621174, upload-time = "2025-08-06T14:53:25.44Z" }, + { url = "https://files.pythonhosted.org/packages/49/0c/2fd4df0d83a495bb5e54dca4474c4ec5f9c62db185421563deeb5dabf609/torch-2.8.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:e2fab4153768d433f8ed9279c8133a114a034a61e77a3a104dcdf54388838705", size = 101906089, upload-time = "2025-08-06T14:53:52.631Z" }, + { url = "https://files.pythonhosted.org/packages/99/a8/6acf48d48838fb8fe480597d98a0668c2beb02ee4755cc136de92a0a956f/torch-2.8.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b2aca0939fb7e4d842561febbd4ffda67a8e958ff725c1c27e244e85e982173c", size = 887913624, upload-time = "2025-08-06T14:56:44.33Z" }, + { url = "https://files.pythonhosted.org/packages/af/8a/5c87f08e3abd825c7dfecef5a0f1d9aa5df5dd0e3fd1fa2f490a8e512402/torch-2.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:2f4ac52f0130275d7517b03a33d2493bab3693c83dcfadf4f81688ea82147d2e", size = 241326087, upload-time = "2025-08-06T14:53:46.503Z" }, + { url = "https://files.pythonhosted.org/packages/be/66/5c9a321b325aaecb92d4d1855421e3a055abd77903b7dab6575ca07796db/torch-2.8.0-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:619c2869db3ada2c0105487ba21b5008defcc472d23f8b80ed91ac4a380283b0", size = 73630478, upload-time = "2025-08-06T14:53:57.144Z" }, ] [[package]] name = "torchaudio" -version = "2.7.1" +version = "2.8.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "torch" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/df/e6/0f3835895f9d0b8900ca4a7196932b13b74156ad9ffb76e7aacfc5bb4157/torchaudio-2.7.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:53bc4ba12e7468be34a7ca2ee837ee5c8bd5755b25c12f665af9339cae37e265", size = 1686156, upload-time = "2025-06-04T17:44:09.39Z" }, - { url = "https://files.pythonhosted.org/packages/0d/c5/8ba8869ac5607bbd83ea864bda2c628f8b7b55a9200f8147687995e95a49/torchaudio-2.7.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:f8bd69354a397753b9dea9699d9e1251f8496fbbdf3028c7086a57a615bf33c3", size = 3508053, upload-time = "2025-06-04T17:43:49.398Z" }, - { url = "https://files.pythonhosted.org/packages/78/cc/11709b2cbf841eda124918523088d9aaa1509ae4400f346192037e6de6c6/torchaudio-2.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:0ae0678ad27355eebea5a9fdd9ae9bfec444f8405f9b6c60026905ba3665c43a", size = 2488974, upload-time = "2025-06-04T17:44:04.294Z" }, + { url = "https://files.pythonhosted.org/packages/75/ca/da5d0a3bb7d114a8b590ecce14859ea0a05102bb4de68cdd1ed7a90634d6/torchaudio-2.8.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:4573c6042950c20278e3608a9a38050ba0bc72e0049e1bbfd249caf859a8029b", size = 1692033, upload-time = "2025-08-06T14:58:37.393Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ef/62ac736d8f906cc414181050e08a495a637dab985186c34bd76ea37efbc0/torchaudio-2.8.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:776c0b4ba84b9e3ddf6304b9c47cd63549d7896a6f3d5184ece074cc3d76ed6b", size = 4011716, upload-time = "2025-08-06T14:58:40.138Z" }, + { url = "https://files.pythonhosted.org/packages/14/86/015337c8434abc604b8680371df783f66c421a7f211cbe40a374b0540b6d/torchaudio-2.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:078105bf80f725c0215a0bebac8cb2fb1b3993ab32bdc3fcd50145a5b4127001", size = 2505194, upload-time = "2025-08-06T14:58:57.301Z" }, + { url = "https://files.pythonhosted.org/packages/c7/0d/24dad878784f1edd62862f27173781669f0c71eb46368636787d1e364188/torchaudio-2.8.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:862e2e40bf09d865e5df080a84c1a39bbcef40e43140f4b1737eb3a389d3b38f", size = 1692930, upload-time = "2025-08-06T14:58:41.312Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a6/84d80f34472503e9eb82245d7df501c59602d75d7360e717fb9b84f91c5e/torchaudio-2.8.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:93a8583f280fe83ba021aa713319381ea71362cc87b67ee38e97a43cb2254aee", size = 4014607, upload-time = "2025-08-06T14:58:47.234Z" }, + { url = "https://files.pythonhosted.org/packages/43/ab/96ad33afa320738a7cfb4b51ba97e2f3cfb1e04ae3115d5057655103ba4f/torchaudio-2.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:4b82cacd1b8ccd543b1149d8cab257a40dfda8119023d2e3a96c66349c84bffb", size = 2499890, upload-time = "2025-08-06T14:58:55.066Z" }, ] [[package]] name = "torchvision" -version = "0.22.1" +version = "0.23.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, @@ -2981,9 +3493,12 @@ dependencies = [ { name = "torch" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/ac/d0/18f951b2be3cfe48c0027b349dcc6fde950e3dc95dd83e037e86f284f6fd/torchvision-0.22.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:8b4a53a6067d63adba0c52f2b8dd2290db649d642021674ee43c0c922f0c6a69", size = 2514021, upload-time = "2025-06-04T17:43:07.608Z" }, - { url = "https://files.pythonhosted.org/packages/c3/1a/63eb241598b36d37a0221e10af357da34bd33402ccf5c0765e389642218a/torchvision-0.22.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:b7866a3b326413e67724ac46f1ee594996735e10521ba9e6cdbe0fa3cd98c2f2", size = 7487300, upload-time = "2025-06-04T17:42:58.349Z" }, - { url = "https://files.pythonhosted.org/packages/e5/73/1b009b42fe4a7774ba19c23c26bb0f020d68525c417a348b166f1c56044f/torchvision-0.22.1-cp311-cp311-win_amd64.whl", hash = "sha256:bb3f6df6f8fd415ce38ec4fd338376ad40c62e86052d7fc706a0dd51efac1718", size = 1707989, upload-time = "2025-06-04T17:43:14.332Z" }, + { url = "https://files.pythonhosted.org/packages/dd/14/7b44fe766b7d11e064c539d92a172fa9689a53b69029e24f2f1f51e7dc56/torchvision-0.23.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:01dc33ee24c79148aee7cdbcf34ae8a3c9da1674a591e781577b716d233b1fa6", size = 2395543, upload-time = "2025-08-06T14:58:04.373Z" }, + { url = "https://files.pythonhosted.org/packages/79/9c/fcb09aff941c8147d9e6aa6c8f67412a05622b0c750bcf796be4c85a58d4/torchvision-0.23.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:35c27941831b653f5101edfe62c03d196c13f32139310519e8228f35eae0e96a", size = 8628388, upload-time = "2025-08-06T14:58:07.802Z" }, + { url = "https://files.pythonhosted.org/packages/93/40/3415d890eb357b25a8e0a215d32365a88ecc75a283f75c4e919024b22d97/torchvision-0.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:09bfde260e7963a15b80c9e442faa9f021c7e7f877ac0a36ca6561b367185013", size = 1600741, upload-time = "2025-08-06T14:57:59.158Z" }, + { url = "https://files.pythonhosted.org/packages/e2/00/2f6454decc0cd67158c7890364e446aad4b91797087a57a78e72e1a8f8bc/torchvision-0.23.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:6dd7c4d329a0e03157803031bc856220c6155ef08c26d4f5bbac938acecf0948", size = 2396614, upload-time = "2025-08-06T14:58:03.116Z" }, + { url = "https://files.pythonhosted.org/packages/e4/b5/3e580dcbc16f39a324f3dd71b90edbf02a42548ad44d2b4893cc92b1194b/torchvision-0.23.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:4e7d31c43bc7cbecbb1a5652ac0106b436aa66e26437585fc2c4b2cf04d6014c", size = 8627108, upload-time = "2025-08-06T14:58:12.956Z" }, + { url = "https://files.pythonhosted.org/packages/82/c1/c2fe6d61e110a8d0de2f94276899a2324a8f1e6aee559eb6b4629ab27466/torchvision-0.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:a2e45272abe7b8bf0d06c405e78521b5757be1bd0ed7e5cd78120f7fdd4cbf35", size = 1600723, upload-time = "2025-08-06T14:57:57.986Z" }, ] [[package]] @@ -3021,13 +3536,15 @@ wheels = [ [[package]] name = "triton" -version = "3.3.1" +version = "3.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "setuptools" }, + { name = "setuptools", version = "79.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "setuptools", version = "80.9.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/21/2f/3e56ea7b58f80ff68899b1dbe810ff257c9d177d288c6b0f55bf2fe4eb50/triton-3.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b31e3aa26f8cb3cc5bf4e187bf737cbacf17311e1112b781d4a059353dfd731b", size = 155689937, upload-time = "2025-05-29T23:39:44.182Z" }, + { url = "https://files.pythonhosted.org/packages/7d/39/43325b3b651d50187e591eefa22e236b2981afcebaefd4f2fc0ea99df191/triton-3.4.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b70f5e6a41e52e48cfc087436c8a28c17ff98db369447bcaff3b887a3ab4467", size = 155531138, upload-time = "2025-07-30T19:58:29.908Z" }, + { url = "https://files.pythonhosted.org/packages/d0/66/b1eb52839f563623d185f0927eb3530ee4d5ffe9d377cdaf5346b306689e/triton-3.4.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:31c1d84a5c0ec2c0f8e8a072d7fd150cab84a9c239eaddc6706c081bfae4eb04", size = 155560068, upload-time = "2025-07-30T19:58:37.081Z" }, ] [[package]] @@ -3165,6 +3682,10 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/74/4f/256aca690709e9b008b7108bc85fba619a2bc37c6d80743d18abad16ee09/uvloop-0.22.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:56a2d1fae65fd82197cb8c53c367310b3eabe1bbb9fb5a04d28e3e3520e4f702", size = 3804529, upload-time = "2025-10-16T22:16:25.246Z" }, { url = "https://files.pythonhosted.org/packages/7f/74/03c05ae4737e871923d21a76fe28b6aad57f5c03b6e6bfcfa5ad616013e4/uvloop-0.22.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:40631b049d5972c6755b06d0bfe8233b1bd9a8a6392d9d1c45c10b6f9e9b2733", size = 3621267, upload-time = "2025-10-16T22:16:26.819Z" }, { url = "https://files.pythonhosted.org/packages/75/be/f8e590fe61d18b4a92070905497aec4c0e64ae1761498cad09023f3f4b3e/uvloop-0.22.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:535cc37b3a04f6cd2c1ef65fa1d370c9a35b6695df735fcff5427323f2cd5473", size = 3723105, upload-time = "2025-10-16T22:16:28.252Z" }, + { url = "https://files.pythonhosted.org/packages/24/68/a6ac446820273e71aa762fa21cdcc09861edd3536ff47c5cd3b7afb10eeb/uvloop-0.22.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:700e674a166ca5778255e0e1dc4e9d79ab2acc57b9171b79e65feba7184b3370", size = 4317413, upload-time = "2025-10-16T22:16:31.644Z" }, + { url = "https://files.pythonhosted.org/packages/5f/6f/e62b4dfc7ad6518e7eff2516f680d02a0f6eb62c0c212e152ca708a0085e/uvloop-0.22.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b5b1ac819a3f946d3b2ee07f09149578ae76066d70b44df3fa990add49a82e4", size = 4426307, upload-time = "2025-10-16T22:16:32.917Z" }, + { url = "https://files.pythonhosted.org/packages/90/60/97362554ac21e20e81bcef1150cb2a7e4ffdaf8ea1e5b2e8bf7a053caa18/uvloop-0.22.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e047cc068570bac9866237739607d1313b9253c3051ad84738cbb095be0537b2", size = 4131970, upload-time = "2025-10-16T22:16:34.015Z" }, + { url = "https://files.pythonhosted.org/packages/99/39/6b3f7d234ba3964c428a6e40006340f53ba37993f46ed6e111c6e9141d18/uvloop-0.22.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:512fec6815e2dd45161054592441ef76c830eddaad55c8aa30952e6fe1ed07c0", size = 4296343, upload-time = "2025-10-16T22:16:35.149Z" }, ] [[package]] @@ -3183,7 +3704,7 @@ wheels = [ [[package]] name = "vllm" -version = "0.10.1" +version = "0.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohttp" }, @@ -3228,6 +3749,8 @@ dependencies = [ { name = "scipy" }, { name = "sentencepiece" }, { name = "setproctitle" }, + { name = "setuptools", version = "79.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "six", marker = "python_full_version >= '3.12'" }, { name = "tiktoken" }, { name = "tokenizers" }, { name = "torch" }, @@ -3240,9 +3763,10 @@ dependencies = [ { name = "xformers", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "xgrammar", marker = "platform_machine == 'aarch64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4a/93/71caa3d72f6d87d0c700db21d72e48eb64432c5a2572fd18a246d130c156/vllm-0.10.1.tar.gz", hash = "sha256:99d00498f25b94767bb2696e88feb67730677dae605c9b8af99492dc3c34492d", size = 10507740, upload-time = "2025-08-19T02:18:19.09Z" } +sdist = { url = "https://files.pythonhosted.org/packages/82/5a/36d2351206f4d8d871b10780f874d03957985e08298d430cc837723e07af/vllm-0.11.0.tar.gz", hash = "sha256:f435a64c24e9c4178d657a76f8edd8548ddc444012f7d06a9f79ac3a6392bfae", size = 10822208, upload-time = "2025-10-04T01:39:57.798Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/82/f1/f03b4b00e304e943b57b5c3d78c741f78be534dd3d0bc2bb6baf16afbb51/vllm-0.10.1-cp38-abi3-manylinux1_x86_64.whl", hash = "sha256:df04a14116750f05099b84db4474935db80e9b13e8b7a6048d3a3cd64aa98b0c", size = 414399973, upload-time = "2025-08-19T02:18:10.549Z" }, + { url = "https://files.pythonhosted.org/packages/47/33/d19e0763c34392ec956534536fa837c060495bfff31ed83452135ea7608d/vllm-0.11.0-cp38-abi3-manylinux1_x86_64.whl", hash = "sha256:3861c75ff2b12e24f6d179ff5c084d791b42ded8675d76c8706697c79f68cd62", size = 438217982, upload-time = "2025-10-04T01:39:32.382Z" }, + { url = "https://files.pythonhosted.org/packages/d7/bf/973444bb959fc7acbbeb3d226bd4d135dcd49b6af174b29aab1b50e2d710/vllm-0.11.0-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:52369c9ee949944354bdc7afc88ded2d1ed02b098bf90db06cf80098a19787b7", size = 401003969, upload-time = "2025-10-04T01:39:50.251Z" }, ] [[package]] @@ -3296,6 +3820,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/46/ef/f2ecb9a0f342b4bfad13a2787155c6ee7ce792140eac63a34676a2feeef2/watchfiles-1.1.1-cp311-cp311-win32.whl", hash = "sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849", size = 271473, upload-time = "2025-10-14T15:04:43.624Z" }, { url = "https://files.pythonhosted.org/packages/94/bc/f42d71125f19731ea435c3948cad148d31a64fccde3867e5ba4edee901f9/watchfiles-1.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4", size = 287598, upload-time = "2025-10-14T15:04:44.516Z" }, { url = "https://files.pythonhosted.org/packages/57/c9/a30f897351f95bbbfb6abcadafbaca711ce1162f4db95fc908c98a9165f3/watchfiles-1.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e", size = 277210, upload-time = "2025-10-14T15:04:45.883Z" }, + { url = "https://files.pythonhosted.org/packages/74/d5/f039e7e3c639d9b1d09b07ea412a6806d38123f0508e5f9b48a87b0a76cc/watchfiles-1.1.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d", size = 404745, upload-time = "2025-10-14T15:04:46.731Z" }, + { url = "https://files.pythonhosted.org/packages/a5/96/a881a13aa1349827490dab2d363c8039527060cfcc2c92cc6d13d1b1049e/watchfiles-1.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610", size = 391769, upload-time = "2025-10-14T15:04:48.003Z" }, + { url = "https://files.pythonhosted.org/packages/4b/5b/d3b460364aeb8da471c1989238ea0e56bec24b6042a68046adf3d9ddb01c/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af", size = 449374, upload-time = "2025-10-14T15:04:49.179Z" }, + { url = "https://files.pythonhosted.org/packages/b9/44/5769cb62d4ed055cb17417c0a109a92f007114a4e07f30812a73a4efdb11/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6", size = 459485, upload-time = "2025-10-14T15:04:50.155Z" }, + { url = "https://files.pythonhosted.org/packages/19/0c/286b6301ded2eccd4ffd0041a1b726afda999926cf720aab63adb68a1e36/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce", size = 488813, upload-time = "2025-10-14T15:04:51.059Z" }, + { url = "https://files.pythonhosted.org/packages/c7/2b/8530ed41112dd4a22f4dcfdb5ccf6a1baad1ff6eed8dc5a5f09e7e8c41c7/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa", size = 594816, upload-time = "2025-10-14T15:04:52.031Z" }, + { url = "https://files.pythonhosted.org/packages/ce/d2/f5f9fb49489f184f18470d4f99f4e862a4b3e9ac2865688eb2099e3d837a/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb", size = 475186, upload-time = "2025-10-14T15:04:53.064Z" }, + { url = "https://files.pythonhosted.org/packages/cf/68/5707da262a119fb06fbe214d82dd1fe4a6f4af32d2d14de368d0349eb52a/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803", size = 456812, upload-time = "2025-10-14T15:04:55.174Z" }, + { url = "https://files.pythonhosted.org/packages/66/ab/3cbb8756323e8f9b6f9acb9ef4ec26d42b2109bce830cc1f3468df20511d/watchfiles-1.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94", size = 630196, upload-time = "2025-10-14T15:04:56.22Z" }, + { url = "https://files.pythonhosted.org/packages/78/46/7152ec29b8335f80167928944a94955015a345440f524d2dfe63fc2f437b/watchfiles-1.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43", size = 622657, upload-time = "2025-10-14T15:04:57.521Z" }, + { url = "https://files.pythonhosted.org/packages/0a/bf/95895e78dd75efe9a7f31733607f384b42eb5feb54bd2eb6ed57cc2e94f4/watchfiles-1.1.1-cp312-cp312-win32.whl", hash = "sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9", size = 272042, upload-time = "2025-10-14T15:04:59.046Z" }, + { url = "https://files.pythonhosted.org/packages/87/0a/90eb755f568de2688cb220171c4191df932232c20946966c27a59c400850/watchfiles-1.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9", size = 288410, upload-time = "2025-10-14T15:05:00.081Z" }, + { url = "https://files.pythonhosted.org/packages/36/76/f322701530586922fbd6723c4f91ace21364924822a8772c549483abed13/watchfiles-1.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404", size = 278209, upload-time = "2025-10-14T15:05:01.168Z" }, { url = "https://files.pythonhosted.org/packages/d3/8e/e500f8b0b77be4ff753ac94dc06b33d8f0d839377fee1b78e8c8d8f031bf/watchfiles-1.1.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88", size = 408250, upload-time = "2025-10-14T15:06:10.264Z" }, { url = "https://files.pythonhosted.org/packages/bd/95/615e72cd27b85b61eec764a5ca51bd94d40b5adea5ff47567d9ebc4d275a/watchfiles-1.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336", size = 396117, upload-time = "2025-10-14T15:06:11.28Z" }, { url = "https://files.pythonhosted.org/packages/c9/81/e7fe958ce8a7fb5c73cc9fb07f5aeaf755e6aa72498c57d760af760c91f8/watchfiles-1.1.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24", size = 450493, upload-time = "2025-10-14T15:06:12.321Z" }, @@ -3325,38 +3862,51 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/08/ff/e9eed2ee5fed6f76fdd6032ca5cd38c57ca9661430bb3d5fb2872dc8703c/websockets-15.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf", size = 181918, upload-time = "2025-03-05T20:02:11.968Z" }, { url = "https://files.pythonhosted.org/packages/d8/75/994634a49b7e12532be6a42103597b71098fd25900f7437d6055ed39930a/websockets-15.0.1-cp311-cp311-win32.whl", hash = "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85", size = 176388, upload-time = "2025-03-05T20:02:13.32Z" }, { url = "https://files.pythonhosted.org/packages/98/93/e36c73f78400a65f5e236cd376713c34182e6663f6889cd45a4a04d8f203/websockets-15.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065", size = 176828, upload-time = "2025-03-05T20:02:14.585Z" }, + { url = "https://files.pythonhosted.org/packages/a6/02/0073b3952f5bce97eafbb35757f8d0d54812b6174ed8dd952aa08429bcc3/websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215", size = 183152, upload-time = "2025-03-05T20:02:22.286Z" }, + { url = "https://files.pythonhosted.org/packages/74/45/c205c8480eafd114b428284840da0b1be9ffd0e4f87338dc95dc6ff961a1/websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5", size = 182096, upload-time = "2025-03-05T20:02:24.368Z" }, + { url = "https://files.pythonhosted.org/packages/14/8f/aa61f528fba38578ec553c145857a181384c72b98156f858ca5c8e82d9d3/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65", size = 182523, upload-time = "2025-03-05T20:02:25.669Z" }, + { url = "https://files.pythonhosted.org/packages/ec/6d/0267396610add5bc0d0d3e77f546d4cd287200804fe02323797de77dbce9/websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe", size = 182790, upload-time = "2025-03-05T20:02:26.99Z" }, + { url = "https://files.pythonhosted.org/packages/02/05/c68c5adbf679cf610ae2f74a9b871ae84564462955d991178f95a1ddb7dd/websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4", size = 182165, upload-time = "2025-03-05T20:02:30.291Z" }, + { url = "https://files.pythonhosted.org/packages/29/93/bb672df7b2f5faac89761cb5fa34f5cec45a4026c383a4b5761c6cea5c16/websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597", size = 182160, upload-time = "2025-03-05T20:02:31.634Z" }, + { url = "https://files.pythonhosted.org/packages/ff/83/de1f7709376dc3ca9b7eeb4b9a07b4526b14876b6d372a4dc62312bebee0/websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9", size = 176395, upload-time = "2025-03-05T20:02:33.017Z" }, + { url = "https://files.pythonhosted.org/packages/7d/71/abf2ebc3bbfa40f391ce1428c7168fb20582d0ff57019b69ea20fa698043/websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7", size = 176841, upload-time = "2025-03-05T20:02:34.498Z" }, { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, ] [[package]] name = "xformers" -version = "0.0.31" +version = "0.0.32.post1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy" }, - { name = "torch" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "torch", marker = "sys_platform == 'linux'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/33/35/91c172a57681e1c03de5ad1ca654dc87c282279b941052ed04e616ae5bcd/xformers-0.0.31.tar.gz", hash = "sha256:3fccb159c6327c13fc1b08f8b963c2779ca526e2e50755dee9bcc1bac67d20c6", size = 12102740, upload-time = "2025-06-25T15:12:10.241Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/33/3b9c4d3d5b2da453d27de891df4ad653ac5795324961aa3a5c15b0353fe6/xformers-0.0.32.post1.tar.gz", hash = "sha256:1de84a45c497c8d92326986508d81f4b0a8c6be4d3d62a29b8ad6048a6ab51e1", size = 12106196, upload-time = "2025-08-14T18:07:45.486Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ff/e3/ee90c62a3235152d4ea8e983a5eb7ac00b10582fee86aaadb11571c1ecba/xformers-0.0.31-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:50aedaea82a38d7d28631f77617d1ed1f6f37c60bdc4bf167a69cbc0e39cee76", size = 117057673, upload-time = "2025-06-25T15:11:59.775Z" }, + { url = "https://files.pythonhosted.org/packages/6b/df/6817346f1a77278315d5fe1fc9f239ba3282ba36e8ab3256babd448dde62/xformers-0.0.32.post1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:5f245b5555188da112070d8fefb6b7ae1ae47422856521d66c837e9d2352fbe4", size = 117199943, upload-time = "2025-08-14T18:07:34.78Z" }, ] [[package]] name = "xgrammar" -version = "0.1.21" +version = "0.1.25" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ninja" }, + { name = "numpy" }, { name = "pydantic" }, { name = "torch" }, { name = "transformers" }, { name = "triton", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e3/52/ea664a56674f21c401b45f124c207a16ca4b2318364687172edbcf255375/xgrammar-0.1.21.tar.gz", hash = "sha256:2ce1e81417ff46aa7ef26d8c0627275cb20dd1f2e8ead5bb261aecde1cc8ba57", size = 2242013, upload-time = "2025-07-10T19:34:14.336Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/a9/dc3c63cf7f082d183711e46ef34d10d8a135c2319dc581905d79449f52ea/xgrammar-0.1.25.tar.gz", hash = "sha256:70ce16b27e8082f20808ed759b0733304316facc421656f0f30cfce514b5b77a", size = 2297187, upload-time = "2025-09-21T05:58:58.942Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/83/28/628240866aa2987e79a803324b318e81006c1fff0aa86af6580efe17afe2/xgrammar-0.1.21-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6e5a171ed0b79712e82f1e2726f4deb0bc1db4476b70187fa7aea04afea3350", size = 11636319, upload-time = "2025-07-10T19:33:45.579Z" }, - { url = "https://files.pythonhosted.org/packages/07/67/e60c49fa74f5a5d86601a26d9938341d5903595fd98cd470d24ac86db2f0/xgrammar-0.1.21-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f43ee3b944da5114f564a1ca734c2e0c5baf849ae824646d3e689c5c78bc6aae", size = 11809789, upload-time = "2025-07-10T19:33:47.924Z" }, - { url = "https://files.pythonhosted.org/packages/ec/e8/7923733d826453c58d35538b54cd158ebb89d8a86e830578fc2162b4850c/xgrammar-0.1.21-cp311-cp311-win_amd64.whl", hash = "sha256:328c35bd62541df41f8e71b544ea73c35dd990e275cf45bad4210e4c94f4a451", size = 4250850, upload-time = "2025-07-10T19:33:50.003Z" }, + { url = "https://files.pythonhosted.org/packages/55/04/55a87e814bcab771d3e4159281fa382b3d5f14a36114f2f9e572728da831/xgrammar-0.1.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35fc135650aa204bf84db7fe9c0c0f480b6b11419fe47d89f4bd21602ac33be9", size = 8517238, upload-time = "2025-09-21T05:58:32.835Z" }, + { url = "https://files.pythonhosted.org/packages/31/f6/3c5210bc41b61fb32b66bf5c9fd8ec5edacfeddf9860e95baa9caa9a2c82/xgrammar-0.1.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc19d6d7e8e51b6c9a266e949ac7fb3d2992447efeec7df32cca109149afac18", size = 8709514, upload-time = "2025-09-21T05:58:34.727Z" }, + { url = "https://files.pythonhosted.org/packages/21/de/85714f307536b328cc16cc6755151865e8875378c8557c15447ca07dff98/xgrammar-0.1.25-cp311-cp311-win_amd64.whl", hash = "sha256:8fcb24f5a7acd5876165c50bd51ce4bf8e6ff897344a5086be92d1fe6695f7fe", size = 698722, upload-time = "2025-09-21T05:58:36.411Z" }, + { url = "https://files.pythonhosted.org/packages/99/9c/39bb38680be3b6d6aa11b8a46a69fb43e2537d6728710b299fa9fc231ff0/xgrammar-0.1.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c519518ebc65f75053123baaf23776a21bda58f64101a64c2fc4aa467c9cd480", size = 8519097, upload-time = "2025-09-21T05:58:40.831Z" }, + { url = "https://files.pythonhosted.org/packages/c6/c2/695797afa9922c30c45aa94e087ad33a9d87843f269461b622a65a39022a/xgrammar-0.1.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47fdbfc6007df47de2142613220292023e88e4a570546b39591f053e4d9ec33f", size = 8712184, upload-time = "2025-09-21T05:58:43.142Z" }, + { url = "https://files.pythonhosted.org/packages/e4/7f/aa80d1d4c4632cd3d8d083f1de8b470fcb3df23d9165992a3ced019f1b93/xgrammar-0.1.25-cp312-cp312-win_amd64.whl", hash = "sha256:c9b3defb6b45272e896da401f43b513f5ac12104ec3101bbe4d3a7d02bcf4a27", size = 698264, upload-time = "2025-09-21T05:58:44.787Z" }, ] [[package]] @@ -3380,6 +3930,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c0/01/99bfbc15fb9abb9a72b088c1d95219fc4782b7d01fc835bd5744d66dd0b8/xxhash-3.6.0-cp311-cp311-win32.whl", hash = "sha256:d1927a69feddc24c987b337ce81ac15c4720955b667fe9b588e02254b80446fd", size = 30574, upload-time = "2025-10-02T14:34:31.028Z" }, { url = "https://files.pythonhosted.org/packages/65/79/9d24d7f53819fe301b231044ea362ce64e86c74f6e8c8e51320de248b3e5/xxhash-3.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:26734cdc2d4ffe449b41d186bbeac416f704a482ed835d375a5c0cb02bc63fef", size = 31481, upload-time = "2025-10-02T14:34:32.062Z" }, { url = "https://files.pythonhosted.org/packages/30/4e/15cd0e3e8772071344eab2961ce83f6e485111fed8beb491a3f1ce100270/xxhash-3.6.0-cp311-cp311-win_arm64.whl", hash = "sha256:d72f67ef8bf36e05f5b6c65e8524f265bd61071471cd4cf1d36743ebeeeb06b7", size = 27861, upload-time = "2025-10-02T14:34:33.555Z" }, + { url = "https://files.pythonhosted.org/packages/9a/07/d9412f3d7d462347e4511181dea65e47e0d0e16e26fbee2ea86a2aefb657/xxhash-3.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:01362c4331775398e7bb34e3ab403bc9ee9f7c497bc7dee6272114055277dd3c", size = 32744, upload-time = "2025-10-02T14:34:34.622Z" }, + { url = "https://files.pythonhosted.org/packages/79/35/0429ee11d035fc33abe32dca1b2b69e8c18d236547b9a9b72c1929189b9a/xxhash-3.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b7b2df81a23f8cb99656378e72501b2cb41b1827c0f5a86f87d6b06b69f9f204", size = 30816, upload-time = "2025-10-02T14:34:36.043Z" }, + { url = "https://files.pythonhosted.org/packages/b7/f2/57eb99aa0f7d98624c0932c5b9a170e1806406cdbcdb510546634a1359e0/xxhash-3.6.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:dc94790144e66b14f67b10ac8ed75b39ca47536bf8800eb7c24b50271ea0c490", size = 194035, upload-time = "2025-10-02T14:34:37.354Z" }, + { url = "https://files.pythonhosted.org/packages/4c/ed/6224ba353690d73af7a3f1c7cdb1fc1b002e38f783cb991ae338e1eb3d79/xxhash-3.6.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:93f107c673bccf0d592cdba077dedaf52fe7f42dcd7676eba1f6d6f0c3efffd2", size = 212914, upload-time = "2025-10-02T14:34:38.6Z" }, + { url = "https://files.pythonhosted.org/packages/38/86/fb6b6130d8dd6b8942cc17ab4d90e223653a89aa32ad2776f8af7064ed13/xxhash-3.6.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aa5ee3444c25b69813663c9f8067dcfaa2e126dc55e8dddf40f4d1c25d7effa", size = 212163, upload-time = "2025-10-02T14:34:39.872Z" }, + { url = "https://files.pythonhosted.org/packages/ee/dc/e84875682b0593e884ad73b2d40767b5790d417bde603cceb6878901d647/xxhash-3.6.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f7f99123f0e1194fa59cc69ad46dbae2e07becec5df50a0509a808f90a0f03f0", size = 445411, upload-time = "2025-10-02T14:34:41.569Z" }, + { url = "https://files.pythonhosted.org/packages/11/4f/426f91b96701ec2f37bb2b8cec664eff4f658a11f3fa9d94f0a887ea6d2b/xxhash-3.6.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:49e03e6fe2cac4a1bc64952dd250cf0dbc5ef4ebb7b8d96bce82e2de163c82a2", size = 193883, upload-time = "2025-10-02T14:34:43.249Z" }, + { url = "https://files.pythonhosted.org/packages/53/5a/ddbb83eee8e28b778eacfc5a85c969673e4023cdeedcfcef61f36731610b/xxhash-3.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bd17fede52a17a4f9a7bc4472a5867cb0b160deeb431795c0e4abe158bc784e9", size = 210392, upload-time = "2025-10-02T14:34:45.042Z" }, + { url = "https://files.pythonhosted.org/packages/1e/c2/ff69efd07c8c074ccdf0a4f36fcdd3d27363665bcdf4ba399abebe643465/xxhash-3.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6fb5f5476bef678f69db04f2bd1efbed3030d2aba305b0fc1773645f187d6a4e", size = 197898, upload-time = "2025-10-02T14:34:46.302Z" }, + { url = "https://files.pythonhosted.org/packages/58/ca/faa05ac19b3b622c7c9317ac3e23954187516298a091eb02c976d0d3dd45/xxhash-3.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:843b52f6d88071f87eba1631b684fcb4b2068cd2180a0224122fe4ef011a9374", size = 210655, upload-time = "2025-10-02T14:34:47.571Z" }, + { url = "https://files.pythonhosted.org/packages/d4/7a/06aa7482345480cc0cb597f5c875b11a82c3953f534394f620b0be2f700c/xxhash-3.6.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7d14a6cfaf03b1b6f5f9790f76880601ccc7896aff7ab9cd8978a939c1eb7e0d", size = 414001, upload-time = "2025-10-02T14:34:49.273Z" }, + { url = "https://files.pythonhosted.org/packages/23/07/63ffb386cd47029aa2916b3d2f454e6cc5b9f5c5ada3790377d5430084e7/xxhash-3.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:418daf3db71e1413cfe211c2f9a528456936645c17f46b5204705581a45390ae", size = 191431, upload-time = "2025-10-02T14:34:50.798Z" }, + { url = "https://files.pythonhosted.org/packages/0f/93/14fde614cadb4ddf5e7cebf8918b7e8fac5ae7861c1875964f17e678205c/xxhash-3.6.0-cp312-cp312-win32.whl", hash = "sha256:50fc255f39428a27299c20e280d6193d8b63b8ef8028995323bf834a026b4fbb", size = 30617, upload-time = "2025-10-02T14:34:51.954Z" }, + { url = "https://files.pythonhosted.org/packages/13/5d/0d125536cbe7565a83d06e43783389ecae0c0f2ed037b48ede185de477c0/xxhash-3.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:c0f2ab8c715630565ab8991b536ecded9416d615538be8ecddce43ccf26cbc7c", size = 31534, upload-time = "2025-10-02T14:34:53.276Z" }, + { url = "https://files.pythonhosted.org/packages/54/85/6ec269b0952ec7e36ba019125982cf11d91256a778c7c3f98a4c5043d283/xxhash-3.6.0-cp312-cp312-win_arm64.whl", hash = "sha256:eae5c13f3bc455a3bbb68bdc513912dc7356de7e2280363ea235f71f54064829", size = 27876, upload-time = "2025-10-02T14:34:54.371Z" }, { url = "https://files.pythonhosted.org/packages/93/1e/8aec23647a34a249f62e2398c42955acd9b4c6ed5cf08cbea94dc46f78d2/xxhash-3.6.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0f7b7e2ec26c1666ad5fc9dbfa426a6a3367ceaf79db5dd76264659d509d73b0", size = 30662, upload-time = "2025-10-02T14:37:01.743Z" }, { url = "https://files.pythonhosted.org/packages/b8/0b/b14510b38ba91caf43006209db846a696ceea6a847a0c9ba0a5b1adc53d6/xxhash-3.6.0-pp311-pypy311_pp73-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5dc1e14d14fa0f5789ec29a7062004b5933964bb9b02aae6622b8f530dc40296", size = 41056, upload-time = "2025-10-02T14:37:02.879Z" }, { url = "https://files.pythonhosted.org/packages/50/55/15a7b8a56590e66ccd374bbfa3f9ffc45b810886c8c3b614e3f90bd2367c/xxhash-3.6.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:881b47fc47e051b37d94d13e7455131054b56749b91b508b0907eb07900d1c13", size = 36251, upload-time = "2025-10-02T14:37:04.44Z" }, @@ -3414,6 +3979,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2d/df/fadd00fb1c90e1a5a8bd731fa3d3de2e165e5a3666a095b04e31b04d9cb6/yarl-1.22.0-cp311-cp311-win32.whl", hash = "sha256:a9b1ba5610a4e20f655258d5a1fdc7ebe3d837bb0e45b581398b99eb98b1f5ca", size = 81804, upload-time = "2025-10-06T14:09:39.359Z" }, { url = "https://files.pythonhosted.org/packages/b5/f7/149bb6f45f267cb5c074ac40c01c6b3ea6d8a620d34b337f6321928a1b4d/yarl-1.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:078278b9b0b11568937d9509b589ee83ef98ed6d561dfe2020e24a9fd08eaa2b", size = 86858, upload-time = "2025-10-06T14:09:41.068Z" }, { url = "https://files.pythonhosted.org/packages/2b/13/88b78b93ad3f2f0b78e13bfaaa24d11cbc746e93fe76d8c06bf139615646/yarl-1.22.0-cp311-cp311-win_arm64.whl", hash = "sha256:b6a6f620cfe13ccec221fa312139135166e47ae169f8253f72a0abc0dae94376", size = 81637, upload-time = "2025-10-06T14:09:42.712Z" }, + { url = "https://files.pythonhosted.org/packages/75/ff/46736024fee3429b80a165a732e38e5d5a238721e634ab41b040d49f8738/yarl-1.22.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f", size = 142000, upload-time = "2025-10-06T14:09:44.631Z" }, + { url = "https://files.pythonhosted.org/packages/5a/9a/b312ed670df903145598914770eb12de1bac44599549b3360acc96878df8/yarl-1.22.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2", size = 94338, upload-time = "2025-10-06T14:09:46.372Z" }, + { url = "https://files.pythonhosted.org/packages/ba/f5/0601483296f09c3c65e303d60c070a5c19fcdbc72daa061e96170785bc7d/yarl-1.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74", size = 94909, upload-time = "2025-10-06T14:09:48.648Z" }, + { url = "https://files.pythonhosted.org/packages/60/41/9a1fe0b73dbcefce72e46cf149b0e0a67612d60bfc90fb59c2b2efdfbd86/yarl-1.22.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df", size = 372940, upload-time = "2025-10-06T14:09:50.089Z" }, + { url = "https://files.pythonhosted.org/packages/17/7a/795cb6dfee561961c30b800f0ed616b923a2ec6258b5def2a00bf8231334/yarl-1.22.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb", size = 345825, upload-time = "2025-10-06T14:09:52.142Z" }, + { url = "https://files.pythonhosted.org/packages/d7/93/a58f4d596d2be2ae7bab1a5846c4d270b894958845753b2c606d666744d3/yarl-1.22.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2", size = 386705, upload-time = "2025-10-06T14:09:54.128Z" }, + { url = "https://files.pythonhosted.org/packages/61/92/682279d0e099d0e14d7fd2e176bd04f48de1484f56546a3e1313cd6c8e7c/yarl-1.22.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82", size = 396518, upload-time = "2025-10-06T14:09:55.762Z" }, + { url = "https://files.pythonhosted.org/packages/db/0f/0d52c98b8a885aeda831224b78f3be7ec2e1aa4a62091f9f9188c3c65b56/yarl-1.22.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a", size = 377267, upload-time = "2025-10-06T14:09:57.958Z" }, + { url = "https://files.pythonhosted.org/packages/22/42/d2685e35908cbeaa6532c1fc73e89e7f2efb5d8a7df3959ea8e37177c5a3/yarl-1.22.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124", size = 365797, upload-time = "2025-10-06T14:09:59.527Z" }, + { url = "https://files.pythonhosted.org/packages/a2/83/cf8c7bcc6355631762f7d8bdab920ad09b82efa6b722999dfb05afa6cfac/yarl-1.22.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa", size = 365535, upload-time = "2025-10-06T14:10:01.139Z" }, + { url = "https://files.pythonhosted.org/packages/25/e1/5302ff9b28f0c59cac913b91fe3f16c59a033887e57ce9ca5d41a3a94737/yarl-1.22.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7", size = 382324, upload-time = "2025-10-06T14:10:02.756Z" }, + { url = "https://files.pythonhosted.org/packages/bf/cd/4617eb60f032f19ae3a688dc990d8f0d89ee0ea378b61cac81ede3e52fae/yarl-1.22.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d", size = 383803, upload-time = "2025-10-06T14:10:04.552Z" }, + { url = "https://files.pythonhosted.org/packages/59/65/afc6e62bb506a319ea67b694551dab4a7e6fb7bf604e9bd9f3e11d575fec/yarl-1.22.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520", size = 374220, upload-time = "2025-10-06T14:10:06.489Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3d/68bf18d50dc674b942daec86a9ba922d3113d8399b0e52b9897530442da2/yarl-1.22.0-cp312-cp312-win32.whl", hash = "sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8", size = 81589, upload-time = "2025-10-06T14:10:09.254Z" }, + { url = "https://files.pythonhosted.org/packages/c8/9a/6ad1a9b37c2f72874f93e691b2e7ecb6137fb2b899983125db4204e47575/yarl-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c", size = 87213, upload-time = "2025-10-06T14:10:11.369Z" }, + { url = "https://files.pythonhosted.org/packages/44/c5/c21b562d1680a77634d748e30c653c3ca918beb35555cff24986fff54598/yarl-1.22.0-cp312-cp312-win_arm64.whl", hash = "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74", size = 81330, upload-time = "2025-10-06T14:10:13.112Z" }, { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" }, ]