diff --git a/scratch/osint/Dockerfile b/scratch/osint/Dockerfile deleted file mode 100644 index c0b313a33f58b8dd1ba97971806ae8b0963de25e..0000000000000000000000000000000000000000 --- a/scratch/osint/Dockerfile +++ /dev/null @@ -1,27 +0,0 @@ -FROM python:3.12-slim - -RUN useradd -m -u 1000 user - -USER user -ENV HOME=/home/user \ - PATH=/home/user/.local/bin:$PATH \ - PYTHONDONTWRITEBYTECODE=1 \ - PYTHONUNBUFFERED=1 \ - PORT=7860 - -WORKDIR $HOME/app - -COPY --chown=user pyproject.toml README.md openenv.yaml inference.py $HOME/app/ -COPY --chown=user src $HOME/app/src -COPY --chown=user config $HOME/app/config -COPY --chown=user datasets $HOME/app/datasets -COPY --chown=user docs $HOME/app/docs -COPY --chown=user scripts $HOME/app/scripts -COPY --chown=user server.py $HOME/app/server.py - -RUN pip install --no-cache-dir --upgrade pip && \ - pip install --no-cache-dir -e . - -EXPOSE 7860 - -CMD ["sh", "-c", "uvicorn server:app --host 0.0.0.0 --port ${PORT:-7860}"] diff --git a/scratch/osint/README.md b/scratch/osint/README.md deleted file mode 100644 index efa261ed55cb8fc3fa72a73809decd9bc3a41bae..0000000000000000000000000000000000000000 --- a/scratch/osint/README.md +++ /dev/null @@ -1,262 +0,0 @@ ---- -title: OSINT OpenEnv -emoji: 🕵️ -colorFrom: blue -colorTo: yellow -sdk: docker -app_port: 7860 -pinned: false -license: apache-2.0 -tags: - - openenv - - osint - - benchmark - - docker - - fastapi -short_description: Docker OSINT benchmark with fixed OpenEnv tasks. ---- - -# OSINT OpenEnv - -OSINT OpenEnv is a synthetic benchmark environment for tool-using agents that must recover identities, trace events, and link entities across noisy multi-platform records. The project is designed to feel like a compact OSINT workflow rather than a raw QA dataset: agents query mock profiles, posts, forum threads, and semantic memory, build a working graph, and then submit an answer. - -The motivation is to provide a reproducible OpenEnv-compatible environment for evaluating graph-building and tool-using reasoning without depending on live web data, unstable APIs, or private corpora. That makes it useful for local development, regression testing, and hosted demos such as a Docker-based Hugging Face Space. - -## Environment Summary - -The environment generates or loads a hidden canonical graph of users, aliases, organizations, locations, posts, threads, and events. It then exposes partial platform views and a task list drawn from that graph. - -The default hosted Space uses the fixed-level benchmark in `datasets/fixed_levels/seed_fixed_levels.json`, which now contains 30 stable tasks over a larger shared seeded graph. - -## Action Space - -The environment exposes three actions: - -- `CALL_TOOL`: query platform views or semantic memory such as `search_posts`, `get_profile`, `search_threads`, `get_connections`, or `search_memory`. -- `ADD_EDGE`: add a candidate relation to the working memory graph. -- `ANSWER`: submit the final answer as an exact node id string. - -## Observation Space - -Each step returns a JSON observation with four parts: - -- `tool_outputs`: the most recent tool results. -- `graph_snapshot`: the current working-memory graph edges. -- `action_history`: recent actions and rewards. -- `task`: the active task id, task type, and question. - -## Task Types And Difficulty - -The benchmark mixes direct lookups with multi-hop traces: - -- Easy: single-hop identity resolution, organization lookup, event lookup, or location lookup. -- Mid: two-hop alias-to-user-to-organization or thread-to-event-to-user traces. -- High: cross-platform multi-hop traces combining aliases, authored content, event references, organization links, and direct connections. - -Common task families include: - -- `identity_resolution` -- `network_discovery` -- `event_tracing` -- `cross_platform_linking` -- `deanonymization` -- `convoluted_trace` - -Expected difficulty increases with the number of relations the agent must chain together and whether the evidence is split across posts, threads, aliases, and profile edges. - -## Repository Layout - -```text -src/osint_env/ - agents/ single-agent and swarm runners - baselines/ reusable OpenAI baseline runner - config/ shared config and seed loading - data/ graph/view/task generation - domain/ dataclasses and environment models - env/ environment, reward logic, OpenEnv compatibility shim - eval/ evaluation metrics and leaderboard helpers - llm/ mock, Ollama, and OpenAI client wrappers - memory/ working graph and semantic memory - platforms/ tool APIs over synthetic platform views - viz/ dashboard export - -scripts/ - build_fixed_levels_dataset.py - run_openai_baseline.py - -datasets/fixed_levels/ - seed_fixed_levels.json - shared_config_fixed_levels.json - qwen_swarm_benchmark_fixed_levels.json - -server.py FastAPI app for local use and Docker/HF Spaces -Dockerfile Container entrypoint for Hugging Face Docker Spaces -``` - -## Setup - -Python 3.10+ is required. - -Local install: - -```bash -python -m pip install -e . -``` - -Run tests: - -```bash -python -m pytest -q -``` - -Run the automated release gate: - -```bash -python scripts/validate_release.py -``` - -## Usage - -Run one demo episode: - -```bash -osint-env demo --agent-mode swarm --llm-provider mock -``` - -Run a quick evaluation: - -```bash -osint-env eval --episodes 5 --agent-mode swarm --llm-provider mock -``` - -Export a dashboard: - -```bash -osint-env benchmark --episodes 5 --agent-mode swarm --llm-provider mock --name quick_check -``` - -## OpenAI Baseline - -The reproducible OpenAI baseline is implemented in `scripts/run_openai_baseline.py`. It runs on the fixed-level benchmark, uses a stable seeded graph/task set, writes a JSON artifact, appends a leaderboard record, and exports a dashboard. - -Default behavior: - -- dataset: fixed-level benchmark -- episodes: 30 -- max steps per episode: 8 -- temperature: 0.0 -- output artifact: `artifacts/baselines/openai_fixed_levels_latest.json` - -Run it with an API key: - -```bash -export OPENAI_API_KEY="your_key_here" -python scripts/run_openai_baseline.py --model gpt-5-nano -``` - -The script is designed to stay bounded enough for a normal benchmark pass to finish comfortably under 20 minutes on a lightweight chat model, while still using the full fixed task set. For repeatability it fixes the benchmark graph/tasks and uses deterministic decoding settings. Because remote model backends can still change over time, the output artifact also records model metadata and system fingerprints when available. - -## Inference Script - -The submission-ready inference entrypoint is the root `inference.py` file. It talks to the deployed Hugging Face Space over HTTP, uses the OpenAI client for all model calls, and emits structured stdout logs in the `[START]`, `[STEP]`, and `[END]` format. - -The script accepts `HF_TOKEN` as the primary auth variable and also supports `OPENAI_API_KEY` or `API_KEY` as local fallbacks. -After a successful run, `inference.py` also posts the evaluation summary back to the Space so the latest `/dashboard` view reflects that run. - -Required environment variables: - -- `API_BASE_URL` -- `MODEL_NAME` -- `HF_TOKEN` - -Optional environment variables: - -- `SPACE_URL` default: `https://siddeshwar1625-osint.hf.space` -- `TASK_INDICES` default: `0,10,20` -- `MAX_STEPS` default: `8` - -Example local test command against a running local server: - -```bash -API_BASE_URL=https://api.openai.com/v1 MODEL_NAME=gpt-5.4-mini OPENAI_API_KEY=your_key SPACE_URL=http://127.0.0.1:7860 python inference.py -``` - -Example test command against the deployed Space: - -```bash -API_BASE_URL=https://api.openai.com/v1 MODEL_NAME=gpt-5.4-mini OPENAI_API_KEY=your_key SPACE_URL=https://siddeshwar1625-osint.hf.space python inference.py -``` - -## Docker And Hugging Face Space - -The repository is ready for a Docker-based Hugging Face Space: - -- `README.md` includes `sdk: docker` -- `README.md` includes the `openenv` Space tag -- `Dockerfile` serves `server.py` on port `7860` - -Local Docker smoke test: - -```bash -docker build -t osint-openenv . -docker run --rm -p 7860:7860 osint-openenv -``` - -Then open `http://localhost:7860`. - -The FastAPI app serves: - -- `/`: overview page -- `/dashboard`: generated benchmark dashboard -- `/api/environment`: environment metadata -- `/health`: health check (validator-friendly alias) -- `/healthz`: health check (legacy alias) -- `/openenv.yaml`: OpenEnv HTTP spec stub -- `/openenv/tasks`: task enumeration -- `/reset` and `/openenv/reset`: episode reset endpoints -- `/step` and `/openenv/step`: episode step endpoints -- `/state` and `/openenv/state/{session_id}`: session state endpoints (`/state` returns the latest session) - -## Automated Validation - -The repository includes a pass/fail validation gate for the core delivery requirements: - -- Hugging Face Space readiness -- OpenEnv spec compliance -- reproducible baseline behavior -- at least 3 fixed tasks with working graders -- Docker image build in CI - -Local gate: - -```bash -python scripts/validate_release.py -``` - -CI gate: - -- `.github/workflows/validation.yml` -- runs `pytest` -- runs the validation script -- runs `docker build` - -## Baseline Scores - -The fixed-level benchmark was expanded from the earlier 15-question set to a 30-question set with a larger seeded graph, so older benchmark artifacts should be treated as legacy and regenerated on the new dataset before using them as reference scores. - -After you supply an OpenAI API key, the current baseline scores for the expanded benchmark will be written to: - -- `artifacts/baselines/openai_fixed_levels_latest.json` -- `artifacts/baselines/openai_fixed_levels_dashboard.html` - -## Notes On `pyproject.toml` - -The packaging file is structurally correct for a `src/` layout and editable installs. The main gaps were deployment/runtime related rather than build-breaking: - -- `openenv` is now version-bounded explicitly. -- `fastapi` and `uvicorn` are included because the repo now ships a real web server. -- pytest is pointed at the `tests/` directory, and the test suite also adds `src/` to `sys.path` so source-layout imports work reliably during local runs. - -## Development Notes - -The project keeps a lightweight local compatibility shim for `openenv` so the source tree remains importable even before dependencies are installed. In a normal install or Docker build, the real `openenv` package from PyPI is still used. diff --git a/scratch/osint/artifacts/leaderboard.json b/scratch/osint/artifacts/leaderboard.json deleted file mode 100644 index 86bfca58d7583f431e001f412bd04a68e16c95ae..0000000000000000000000000000000000000000 --- a/scratch/osint/artifacts/leaderboard.json +++ /dev/null @@ -1,453 +0,0 @@ -[ - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 18, - "max_width": 2, - "seed": 7, - "seeded_questions": 1, - "swarm_enabled": true - }, - "created_at": "2026-04-01T12:03:13+00:00", - "episodes": 2, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.1, - "avg_connectivity_reward": 0.3, - "avg_diversity_reward": 0.08, - "avg_entity_informativeness_reward": 0.024705877237863647, - "avg_format_reward": 0.15, - "avg_graph_f1": 1.0, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.15, - "avg_relation_informativeness_reward": 0.03137141693971891, - "avg_reward": 3.534162700533434, - "avg_soft_shaping_reward": 0.15, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 1.0, - "leaderboard_score": 0.8618382743087459, - "retrieval_signal": 0.7275, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.6082154588355165, - "task_success_rate": 1.0, - "tool_efficiency": 0.25 - }, - "run_id": "run_0001", - "run_name": "swarm_seed_smoke" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 18, - "max_width": 2, - "seed": 7, - "seeded_questions": 1, - "swarm_enabled": true - }, - "created_at": "2026-04-01T12:16:28+00:00", - "episodes": 2, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.1, - "avg_connectivity_reward": 0.3, - "avg_diversity_reward": 0.08, - "avg_entity_informativeness_reward": 0.024705877237863647, - "avg_format_reward": 0.15, - "avg_graph_f1": 1.0, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.15, - "avg_relation_informativeness_reward": 0.03137141693971891, - "avg_reward": 3.534162700533434, - "avg_soft_shaping_reward": 0.15, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 1.0, - "leaderboard_score": 0.8618382743087459, - "retrieval_signal": 0.7275, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.6082154588355165, - "task_success_rate": 1.0, - "tool_efficiency": 0.25 - }, - "run_id": "run_0002", - "run_name": "swarm_seed_smoke" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 18, - "max_width": 2, - "seed": 7, - "seeded_questions": 0, - "swarm_enabled": true - }, - "created_at": "2026-04-01T12:25:15+00:00", - "episodes": 20, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.10000000000000002, - "avg_connectivity_reward": 0.23999999999999994, - "avg_diversity_reward": 0.08000000000000002, - "avg_entity_informativeness_reward": -0.00983642442912193, - "avg_format_reward": 0.14999999999999997, - "avg_graph_f1": 1.0, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.1125, - "avg_relation_informativeness_reward": 0.007185245326892638, - "avg_reward": 3.351267560586956, - "avg_soft_shaping_reward": 0.14999999999999997, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 1.0, - "leaderboard_score": 0.8573187614039594, - "retrieval_signal": 0.7143750000000001, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5814697641795541, - "task_success_rate": 1.0, - "tool_efficiency": 0.25 - }, - "run_id": "run_0003", - "run_name": "baseline_swarm" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 18, - "max_width": 2, - "seed": 7, - "seeded_questions": 1, - "swarm_enabled": true - }, - "created_at": "2026-04-01T17:27:30+00:00", - "episodes": 1, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.1, - "avg_connectivity_reward": 0.3, - "avg_diversity_reward": 0.08, - "avg_entity_informativeness_reward": 0.06128386989162576, - "avg_format_reward": 0.15, - "avg_graph_f1": 1.0, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.3, - "avg_relation_informativeness_reward": 0.12, - "avg_reward": 3.916035942914144, - "avg_soft_shaping_reward": 0.15, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 1.0, - "leaderboard_score": 0.8718832338515622, - "retrieval_signal": 0.78, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.6332567739783251, - "task_success_rate": 1.0, - "tool_efficiency": 0.25 - }, - "run_id": "run_0004", - "run_name": "ollama_qwen_smoke" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 18, - "max_width": 2, - "seed": 7, - "seeded_questions": 1, - "swarm_enabled": true - }, - "created_at": "2026-04-01T17:29:12+00:00", - "episodes": 1, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.1, - "avg_connectivity_reward": 0.3, - "avg_diversity_reward": 0.08, - "avg_entity_informativeness_reward": 0.06128386989162576, - "avg_format_reward": 0.15, - "avg_graph_f1": 1.0, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.3, - "avg_relation_informativeness_reward": 0.12, - "avg_reward": 4.059369276247478, - "avg_soft_shaping_reward": 0.15, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 1.0, - "leaderboard_score": 0.9020114237119466, - "retrieval_signal": 0.78, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.6332567739783251, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0005", - "run_name": "ollama_qwen_smoke2" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 18, - "max_width": 2, - "seed": 7, - "seeded_questions": 0, - "swarm_enabled": true - }, - "created_at": "2026-04-01T17:39:15+00:00", - "episodes": 2, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.2, - "avg_connectivity_reward": 0.0, - "avg_diversity_reward": 0.0683333333333333, - "avg_entity_informativeness_reward": -0.07397348480982455, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.6666666666666667, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.14884615384615385, - "avg_relation_informativeness_reward": -0.00860389783205907, - "avg_reward": 4.351764433970379, - "avg_soft_shaping_reward": 0.3, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6973935600514568, - "retrieval_signal": 0.7270961538461539, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5137345234716233, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0006", - "run_name": "high_timeout_shared_ctx" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 18, - "max_width": 2, - "seed": 7, - "seeded_questions": 0, - "swarm_enabled": true - }, - "created_at": "2026-04-01T18:57:40+00:00", - "episodes": 3, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.13333333333333333, - "avg_connectivity_reward": 0.09999999999999999, - "avg_diversity_reward": 0.056666666666666664, - "avg_entity_informativeness_reward": -0.020478979694240708, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.8148148148148149, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.27, - "avg_relation_informativeness_reward": 0.07174291752145656, - "avg_reward": 4.0269419367756605, - "avg_soft_shaping_reward": 0.19999999999999998, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.7366215569569294, - "retrieval_signal": 0.7695000000000001, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5570861208987765, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0007", - "run_name": "episode_selector_check" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 18, - "max_width": 2, - "seed": 7, - "seeded_questions": 15, - "swarm_enabled": true - }, - "created_at": "2026-04-01T19:11:44+00:00", - "episodes": 3, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.10000000000000002, - "avg_connectivity_reward": 0.3, - "avg_diversity_reward": 0.08, - "avg_entity_informativeness_reward": -0.02722031691758704, - "avg_format_reward": 0.15, - "avg_graph_f1": 1.0, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.0, - "avg_relation_informativeness_reward": -0.00011920119799207429, - "avg_reward": 3.444079221573606, - "avg_soft_shaping_reward": 0.15, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 1.0, - "leaderboard_score": 0.8828572592896698, - "retrieval_signal": 0.675, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5915320963768841, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0008", - "run_name": "qwen_rerun" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 18, - "max_width": 2, - "seed": 7, - "seeded_questions": 15, - "swarm_enabled": true - }, - "created_at": "2026-04-01T19:19:34+00:00", - "episodes": 3, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.10000000000000002, - "avg_connectivity_reward": 0.3, - "avg_diversity_reward": 0.08, - "avg_entity_informativeness_reward": -0.024861029515896544, - "avg_format_reward": 0.15, - "avg_graph_f1": 1.0, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.0, - "avg_relation_informativeness_reward": -0.0024320085090966614, - "avg_reward": 3.4441257016641917, - "avg_soft_shaping_reward": 0.15, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 1.0, - "leaderboard_score": 0.8828581656226586, - "retrieval_signal": 0.675, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5915413923950014, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0009", - "run_name": "qwen_episode_fix" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 18, - "max_width": 2, - "seed": 7, - "seeded_questions": 15, - "swarm_enabled": true - }, - "created_at": "2026-04-01T19:24:37+00:00", - "episodes": 3, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.10000000000000002, - "avg_connectivity_reward": 0.3, - "avg_diversity_reward": 0.08, - "avg_entity_informativeness_reward": -0.02722031691758704, - "avg_format_reward": 0.15, - "avg_graph_f1": 1.0, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.0, - "avg_relation_informativeness_reward": -0.0030604289114462002, - "avg_reward": 3.4411379938601514, - "avg_soft_shaping_reward": 0.15, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 1.0, - "leaderboard_score": 0.8827999009847504, - "retrieval_signal": 0.675, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5909438508341933, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0010", - "run_name": "qwen_rerun_graph_fix" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 18, - "max_width": 2, - "seed": 7, - "seeded_questions": 15, - "swarm_enabled": true - }, - "created_at": "2026-04-01T19:31:54+00:00", - "episodes": 15, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.16666666666666666, - "avg_connectivity_reward": 0.16999999999999998, - "avg_diversity_reward": 0.1157777777777778, - "avg_entity_informativeness_reward": -0.0181244777358718, - "avg_format_reward": 0.14999999999999997, - "avg_graph_f1": 0.8492063492063492, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.012000000000000002, - "avg_relation_informativeness_reward": 0.05935837081627929, - "avg_reward": 4.201760569277529, - "avg_soft_shaping_reward": 0.24999999999999994, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 1.0, - "leaderboard_score": 0.8534887252258901, - "retrieval_signal": 0.6792, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5847801119494148, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0011", - "run_name": "qwen_rerun_graph_fix" - } -] \ No newline at end of file diff --git a/scratch/osint/artifacts/osint_dashboard.html b/scratch/osint/artifacts/osint_dashboard.html deleted file mode 100644 index 42202311d1931b2d415222676a5d853939dcf8d5..0000000000000000000000000000000000000000 --- a/scratch/osint/artifacts/osint_dashboard.html +++ /dev/null @@ -1,634 +0,0 @@ - - - - - - OSINT Environment Dashboard - - - - - - - - - -
-
-
-

OSINT Benchmark Dashboard

-

Interactive explorer for canonical knowledge graph, episode traces, source platform records, and benchmark ranking.

-
-
-
-
-

Episode Explorer

-
- - -
-
- - -
-
Task ID:
-
Task Type:
-
Question
-
-
Ground Truth Answer:
-
Agent Answer:
-
Correct:
-
-
- -
-
-
-

Graph Controls

-
- - - - - - - -
-
-
-

Node Types

-
-
-
- -
-

Graph Explorer

-
-
Layer: Canonical Graph
-
-
-
- matched edge - predicted only - truth only -
-
- -
-
-

Node Inspector

-
Click a node to inspect attributes and neighbors.
-
-
-

Edge Inspector

-
Click an edge to inspect relation details.
-
-
-
- -
-
-

Original Database Explorer

-
-
- - -
-
-
- -
-

Selected Source Record

-
Click a row in the database table to inspect full JSON.
-
-
- -
-
-

Benchmark Summary Radar

-
-
-
-

Episode Reward and Graph F1

-
-
-
- -
-

Benchmark Leaderboard

-
- - -
-
-
-
- - - - diff --git a/scratch/osint/config/seed_example.json b/scratch/osint/config/seed_example.json deleted file mode 100644 index 92b4aec40eac09d3a4dae1e70e34d9be4fe1bfd1..0000000000000000000000000000000000000000 --- a/scratch/osint/config/seed_example.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "seeding": { - "seeded_nodes": [ - { - "node_id": "alias_seed_001", - "node_type": "alias", - "attrs": { - "handle": "@shadow_seed" - } - }, - { - "node_id": "user_seed_001", - "node_type": "user", - "attrs": { - "name": "Seed User", - "org": "Helios Labs", - "location": "Pune" - } - } - ], - "_note": "Use with --seed-file. LLM provider and API keys are configured in config/shared_config.json or CLI flags.", - "seeded_edges": [ - { - "src": "alias_seed_001", - "rel": "alias_of", - "dst": "user_seed_001", - "confidence": 1.0 - } - ], - "seeded_questions": [ - { - "task_type": "identity_resolution", - "question": "Which canonical user owns alias alias_seed_001?", - "answer": "user_seed_001", - "supporting_edges": [ - { - "src": "alias_seed_001", - "rel": "alias_of", - "dst": "user_seed_001" - } - ], - "metadata": { - "source": "manual_seed" - } - } - ], - "llm_generate_remaining_graph": true, - "llm_generate_remaining_tasks": true, - "llm_generated_edge_budget": 6, - "llm_generated_task_budget": 8 - } -} diff --git a/scratch/osint/config/seed_ollama_smoke.json b/scratch/osint/config/seed_ollama_smoke.json deleted file mode 100644 index a26bd097e7f482dce893ef83df92c53712c28fbb..0000000000000000000000000000000000000000 --- a/scratch/osint/config/seed_ollama_smoke.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "seeding": { - "seeded_nodes": [ - { - "node_id": "alias_smoke_001", - "node_type": "alias", - "attrs": { - "handle": "@smoke_alias" - } - }, - { - "node_id": "user_smoke_001", - "node_type": "user", - "attrs": { - "name": "Smoke User", - "org": "Apex Dynamics", - "location": "Bengaluru" - } - } - ], - "seeded_edges": [ - { - "src": "alias_smoke_001", - "rel": "alias_of", - "dst": "user_smoke_001", - "confidence": 1.0 - } - ], - "seeded_questions": [ - { - "task_type": "identity_resolution", - "question": "Which canonical user owns alias alias_smoke_001?", - "answer": "user_smoke_001", - "supporting_edges": [ - { - "src": "alias_smoke_001", - "rel": "alias_of", - "dst": "user_smoke_001" - } - ], - "metadata": { - "source": "ollama_smoke" - } - } - ], - "llm_generate_remaining_graph": false, - "llm_generate_remaining_tasks": false, - "llm_generated_edge_budget": 0, - "llm_generated_task_budget": 0 - } -} diff --git a/scratch/osint/config/shared_config.json b/scratch/osint/config/shared_config.json deleted file mode 100644 index 0fe43fffbe970b7d4e33babf4d44f34721ba280c..0000000000000000000000000000000000000000 --- a/scratch/osint/config/shared_config.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "environment": { - "n_users": 40, - "alias_density": 0.35, - "noise_level": 0.15, - "red_herring_rate": 0.1, - "max_steps": 18, - "seed": 7 - }, - "swarm": { - "enabled": true, - "max_agents": 3, - "max_breadth": 2, - "max_width": 2, - "max_depth": 2, - "planner_rounds": 2, - "tools_per_agent": 1 - }, - "spawn_reward": { - "lambda_parallel": 0.15, - "lambda_finish": 0.2, - "anneal": 1.0, - "max_parallel_hint": 3 - }, - "seeding": { - "seeded_nodes": [], - "seeded_edges": [], - "seeded_questions": [], - "llm_generate_remaining_graph": true, - "llm_generate_remaining_tasks": true, - "llm_generated_edge_budget": 6, - "llm_generated_task_budget": 8, - "llm_generation_parallel": true, - "llm_generation_workers": 3, - "llm_generation_retries": 2, - "allow_template_fallback_on_llm_failure": false - }, - "llm": { - "provider": "ollama", - "model": "qwen3:2b", - "temperature": 0.1, - "max_tokens": 256, - "timeout_seconds": 240, - "ollama_base_url": "http://127.0.0.1:11434", - "openai_base_url": "https://api.openai.com/v1", - "openai_api_key_env": "OPENAI_API_KEY", - "openai_api_key": "" - }, - "runtime": { - "default_episodes": 20, - "leaderboard_path": "artifacts/leaderboard.json", - "dashboard_path": "artifacts/osint_dashboard.html", - "sweep_dashboard_dir": "artifacts/sweep_dashboards" - } -} diff --git a/scratch/osint/datasets/fixed_levels/README.md b/scratch/osint/datasets/fixed_levels/README.md deleted file mode 100644 index 3c7e2b60d8e200f697826454595e5469c242098a..0000000000000000000000000000000000000000 --- a/scratch/osint/datasets/fixed_levels/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# Fixed Levels Submission Dataset - -This folder contains a fixed three-level OSINT benchmark set built on one shared base graph. - -## Files - -- `seed_fixed_levels.json`: master fixed seed with an expanded canonical graph and 30 fixed questions. -- `fixed_graph_questions.json`: extracted fixed dataset snapshot for submission packaging. -- `shared_config_fixed_levels.json`: run config used for generation and evaluation. -- `complete_dataset_qwen_generated.json`: full dataset after Qwen (`qwen3:2b` via Ollama) expands the graph. -- `qwen_swarm_eval_fixed_levels.json`: legacy Qwen swarm evaluation summary from the older smaller version of the set. -- `qwen_swarm_benchmark_fixed_levels.json`: legacy benchmark output from the older smaller version of the set. -- `leaderboard_fixed_levels.json`: leaderboard file for this dataset. -- `dashboard_fixed_levels.html`: interactive dashboard generated from the benchmark run. - -## Difficulty Design - -- Easy: 10 questions. These now use the older hard-style multi-hop traces as the new floor. -- Mid: 10 questions. Each question spans roughly 15-20 supporting nodes. -- High: 10 questions. Each question spans roughly 50 supporting nodes. - -All 30 questions are fixed and share the same larger seeded graph. - -## Regenerate Artifacts - -```bash -source ~/arl/bin/activate -cd /home/ritish/test1 -PYTHONPATH=src python scripts/build_fixed_levels_dataset.py \ - --seed-file datasets/fixed_levels/seed_fixed_levels.json \ - --shared-config datasets/fixed_levels/shared_config_fixed_levels.json \ - --output-dir datasets/fixed_levels -``` - -## Evaluate Qwen Swarm - -```bash -source ~/arl/bin/activate -cd /home/ritish/test1 -PYTHONPATH=src osint-env eval \ - --config datasets/fixed_levels/shared_config_fixed_levels.json \ - --seed-file datasets/fixed_levels/seed_fixed_levels.json \ - --agent-mode swarm \ - --llm-provider ollama \ - --llm-model qwen3:2b \ - --episodes 15 -``` - -## Benchmark + Dashboard - -```bash -source ~/arl/bin/activate -cd /home/ritish/test1 -PYTHONPATH=src osint-env benchmark \ - --config datasets/fixed_levels/shared_config_fixed_levels.json \ - --seed-file datasets/fixed_levels/seed_fixed_levels.json \ - --agent-mode swarm \ - --llm-provider ollama \ - --llm-model qwen3:2b \ - --episodes 15 \ - --name fixed_levels_qwen_swarm \ - --leaderboard datasets/fixed_levels/leaderboard_fixed_levels.json \ - --dashboard datasets/fixed_levels/dashboard_fixed_levels.html -``` diff --git a/scratch/osint/datasets/fixed_levels/complete_dataset_qwen_generated.json b/scratch/osint/datasets/fixed_levels/complete_dataset_qwen_generated.json deleted file mode 100644 index 813cd92dfe5a5866cafac070a42dbec18a4f2cb0..0000000000000000000000000000000000000000 --- a/scratch/osint/datasets/fixed_levels/complete_dataset_qwen_generated.json +++ /dev/null @@ -1,8798 +0,0 @@ -{ - "canonical_graph": { - "edge_count": 249, - "edges": [ - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_0" - }, - { - "confidence": 1.0, - "dst": "loc_hyderabad", - "rel": "located_in", - "src": "user_0" - }, - { - "confidence": 1.0, - "dst": "org_northbridge", - "rel": "works_at", - "src": "user_1" - }, - { - "confidence": 1.0, - "dst": "loc_bengaluru", - "rel": "located_in", - "src": "user_1" - }, - { - "confidence": 1.0, - "dst": "org_northbridge", - "rel": "works_at", - "src": "user_2" - }, - { - "confidence": 1.0, - "dst": "loc_delhi", - "rel": "located_in", - "src": "user_2" - }, - { - "confidence": 1.0, - "dst": "org_northbridge", - "rel": "works_at", - "src": "user_3" - }, - { - "confidence": 1.0, - "dst": "loc_delhi", - "rel": "located_in", - "src": "user_3" - }, - { - "confidence": 1.0, - "dst": "org_northbridge", - "rel": "works_at", - "src": "user_4" - }, - { - "confidence": 1.0, - "dst": "loc_delhi", - "rel": "located_in", - "src": "user_4" - }, - { - "confidence": 1.0, - "dst": "org_northbridge", - "rel": "works_at", - "src": "user_5" - }, - { - "confidence": 1.0, - "dst": "loc_bengaluru", - "rel": "located_in", - "src": "user_5" - }, - { - "confidence": 1.0, - "dst": "user_5", - "rel": "alias_of", - "src": "alias_5_936" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_6" - }, - { - "confidence": 1.0, - "dst": "loc_delhi", - "rel": "located_in", - "src": "user_6" - }, - { - "confidence": 1.0, - "dst": "user_6", - "rel": "alias_of", - "src": "alias_6_801" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_7" - }, - { - "confidence": 1.0, - "dst": "loc_hyderabad", - "rel": "located_in", - "src": "user_7" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_8" - }, - { - "confidence": 1.0, - "dst": "loc_hyderabad", - "rel": "located_in", - "src": "user_8" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_9" - }, - { - "confidence": 1.0, - "dst": "loc_delhi", - "rel": "located_in", - "src": "user_9" - }, - { - "confidence": 1.0, - "dst": "org_northbridge", - "rel": "works_at", - "src": "user_10" - }, - { - "confidence": 1.0, - "dst": "loc_bengaluru", - "rel": "located_in", - "src": "user_10" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_11" - }, - { - "confidence": 1.0, - "dst": "loc_hyderabad", - "rel": "located_in", - "src": "user_11" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_12" - }, - { - "confidence": 1.0, - "dst": "loc_hyderabad", - "rel": "located_in", - "src": "user_12" - }, - { - "confidence": 1.0, - "dst": "user_12", - "rel": "alias_of", - "src": "alias_12_827" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_13" - }, - { - "confidence": 1.0, - "dst": "loc_hyderabad", - "rel": "located_in", - "src": "user_13" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_14" - }, - { - "confidence": 1.0, - "dst": "loc_delhi", - "rel": "located_in", - "src": "user_14" - }, - { - "confidence": 1.0, - "dst": "org_northbridge", - "rel": "works_at", - "src": "user_15" - }, - { - "confidence": 1.0, - "dst": "loc_delhi", - "rel": "located_in", - "src": "user_15" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_16" - }, - { - "confidence": 1.0, - "dst": "loc_delhi", - "rel": "located_in", - "src": "user_16" - }, - { - "confidence": 1.0, - "dst": "org_northbridge", - "rel": "works_at", - "src": "user_17" - }, - { - "confidence": 1.0, - "dst": "loc_hyderabad", - "rel": "located_in", - "src": "user_17" - }, - { - "confidence": 1.0, - "dst": "org_northbridge", - "rel": "works_at", - "src": "user_18" - }, - { - "confidence": 1.0, - "dst": "loc_delhi", - "rel": "located_in", - "src": "user_18" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_19" - }, - { - "confidence": 1.0, - "dst": "loc_pune", - "rel": "located_in", - "src": "user_19" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_20" - }, - { - "confidence": 1.0, - "dst": "loc_bengaluru", - "rel": "located_in", - "src": "user_20" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_21" - }, - { - "confidence": 1.0, - "dst": "loc_delhi", - "rel": "located_in", - "src": "user_21" - }, - { - "confidence": 1.0, - "dst": "user_21", - "rel": "alias_of", - "src": "alias_21_334" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_22" - }, - { - "confidence": 1.0, - "dst": "loc_delhi", - "rel": "located_in", - "src": "user_22" - }, - { - "confidence": 1.0, - "dst": "org_northbridge", - "rel": "works_at", - "src": "user_23" - }, - { - "confidence": 1.0, - "dst": "loc_hyderabad", - "rel": "located_in", - "src": "user_23" - }, - { - "confidence": 0.8, - "dst": "user_9", - "rel": "connected_to", - "src": "user_21" - }, - { - "confidence": 0.8, - "dst": "user_20", - "rel": "connected_to", - "src": "user_17" - }, - { - "confidence": 0.8, - "dst": "user_22", - "rel": "connected_to", - "src": "user_16" - }, - { - "confidence": 0.8, - "dst": "user_12", - "rel": "connected_to", - "src": "user_15" - }, - { - "confidence": 0.8, - "dst": "user_6", - "rel": "connected_to", - "src": "user_13" - }, - { - "confidence": 0.8, - "dst": "user_8", - "rel": "connected_to", - "src": "user_9" - }, - { - "confidence": 0.8, - "dst": "user_1", - "rel": "connected_to", - "src": "user_0" - }, - { - "confidence": 0.8, - "dst": "user_20", - "rel": "connected_to", - "src": "user_4" - }, - { - "confidence": 0.8, - "dst": "user_14", - "rel": "connected_to", - "src": "user_19" - }, - { - "confidence": 0.8, - "dst": "user_15", - "rel": "connected_to", - "src": "user_16" - }, - { - "confidence": 0.8, - "dst": "user_6", - "rel": "connected_to", - "src": "user_11" - }, - { - "confidence": 0.8, - "dst": "user_22", - "rel": "connected_to", - "src": "user_8" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_elin" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_elin" - }, - { - "confidence": 1.0, - "dst": "org_tidewatch_ops", - "rel": "works_at", - "src": "user_faris" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_faris" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_gita" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_gita" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "located_in", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "located_in", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "located_in", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "located_in", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "operates_in", - "src": "org_helios_labs" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "operates_in", - "src": "org_northbridge_logistics" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "operates_in", - "src": "org_apex_dynamics" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "operates_in", - "src": "org_blueharbor_media" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "operates_in", - "src": "org_tidewatch_ops" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "operates_in", - "src": "org_kestrel_works" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "operates_in", - "src": "org_atlas_freight" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "operates_in", - "src": "org_sunmesh_analytics" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "operates_in", - "src": "org_orion_customs" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "operates_in", - "src": "org_emberline_security" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "operates_in", - "src": "org_harborlight_transit" - }, - { - "confidence": 0.95, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.95, - "dst": "user_hiro", - "rel": "connected_to", - "src": "user_bharat" - }, - { - "confidence": 0.92, - "dst": "user_faris", - "rel": "connected_to", - "src": "user_hiro" - }, - { - "confidence": 0.9, - "dst": "user_diya", - "rel": "connected_to", - "src": "user_faris" - }, - { - "confidence": 0.89, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_diya" - }, - { - "confidence": 0.87, - "dst": "user_aria", - "rel": "connected_to", - "src": "user_elin" - }, - { - "confidence": 0.84, - "dst": "user_cyrus", - "rel": "connected_to", - "src": "user_aria" - }, - { - "confidence": 0.83, - "dst": "user_gita", - "rel": "connected_to", - "src": "user_cyrus" - }, - { - "confidence": 0.82, - "dst": "user_jules", - "rel": "connected_to", - "src": "user_gita" - }, - { - "confidence": 0.81, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_jules" - }, - { - "confidence": 0.9, - "dst": "user_ivy", - "rel": "connected_to", - "src": "user_diya" - }, - { - "confidence": 0.86, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.93, - "dst": "user_omar", - "rel": "connected_to", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "user_mika", - "rel": "connected_to", - "src": "user_omar" - }, - { - "confidence": 0.89, - "dst": "user_quinn", - "rel": "connected_to", - "src": "user_mika" - }, - { - "confidence": 0.88, - "dst": "user_nora", - "rel": "connected_to", - "src": "user_quinn" - }, - { - "confidence": 0.87, - "dst": "user_rhea", - "rel": "connected_to", - "src": "user_nora" - }, - { - "confidence": 0.86, - "dst": "user_soren", - "rel": "connected_to", - "src": "user_rhea" - }, - { - "confidence": 0.86, - "dst": "user_tara", - "rel": "connected_to", - "src": "user_soren" - }, - { - "confidence": 0.84, - "dst": "user_kian", - "rel": "connected_to", - "src": "user_tara" - }, - { - "confidence": 0.91, - "dst": "user_leena", - "rel": "connected_to", - "src": "user_priya" - }, - { - "confidence": 0.83, - "dst": "user_aria", - "rel": "connected_to", - "src": "user_leena" - }, - { - "confidence": 0.82, - "dst": "user_nora", - "rel": "connected_to", - "src": "user_priya" - }, - { - "confidence": 0.8, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_kian" - }, - { - "confidence": 0.79, - "dst": "user_faris", - "rel": "connected_to", - "src": "user_soren" - }, - { - "confidence": 0.78, - "dst": "user_hiro", - "rel": "connected_to", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_shift_roster", - "rel": "authored_post", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "post_sat_phone_ping", - "rel": "authored_post", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "post_drone_parts", - "rel": "authored_post", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "post_relay_schedule", - "rel": "authored_post", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "post_customs_tag", - "rel": "authored_post", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "post_hull_signal", - "rel": "authored_post", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "post_basin_photo", - "rel": "authored_post", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "post_foundry_map", - "rel": "authored_post", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "post_lantern_route", - "rel": "authored_post", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "post_uplink_note", - "rel": "authored_post", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_shift_roster" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "post_shift_roster" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "references", - "src": "post_sat_phone_ping" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_sat_phone_ping" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "references", - "src": "post_drone_parts" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "references", - "src": "post_drone_parts" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_relay_schedule" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "references", - "src": "post_relay_schedule" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "references", - "src": "post_customs_tag" - }, - { - "confidence": 1.0, - "dst": "event_iron_wharf", - "rel": "references", - "src": "post_customs_tag" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "post_hull_signal" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "references", - "src": "post_hull_signal" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 1.0, - "dst": "event_amber_veil", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_foundry_map" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "references", - "src": "post_foundry_map" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_lantern_route" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "references", - "src": "post_lantern_route" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "post_uplink_note" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "post_uplink_note" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "thr_port_audit", - "rel": "authored_thread", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "thr_customs_breach", - "rel": "authored_thread", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "thr_relay_map", - "rel": "authored_thread", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "thr_foundry_watch", - "rel": "authored_thread", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "thr_basin_shift", - "rel": "authored_thread", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "thr_quiet_manifest", - "rel": "authored_thread", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "thr_uplink_route", - "rel": "authored_thread", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "thr_ember_tide_watch", - "rel": "authored_thread", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "thr_ghost_signal_net", - "rel": "authored_thread", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "discusses", - "src": "thr_port_audit" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "references", - "src": "thr_port_audit" - }, - { - "confidence": 1.0, - "dst": "event_iron_wharf", - "rel": "discusses", - "src": "thr_customs_breach" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "references", - "src": "thr_customs_breach" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_relay_map" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "references", - "src": "thr_relay_map" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "discusses", - "src": "thr_foundry_watch" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "references", - "src": "thr_foundry_watch" - }, - { - "confidence": 1.0, - "dst": "event_amber_veil", - "rel": "discusses", - "src": "thr_basin_shift" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "references", - "src": "thr_basin_shift" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "discusses", - "src": "thr_quiet_manifest" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "references", - "src": "thr_quiet_manifest" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "discusses", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "discusses", - "src": "thr_ember_tide_watch" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "thr_ember_tide_watch" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "discusses", - "src": "thr_ghost_signal_net" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "thr_ghost_signal_net" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_bharat" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_hiro" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_faris" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "investigates", - "src": "user_diya" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "monitors", - "src": "user_leena" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_cyrus" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "investigates", - "src": "user_elin" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "reports_on", - "src": "user_jules" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_omar" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "monitors", - "src": "user_priya" - }, - { - "confidence": 0.9, - "dst": "event_iron_wharf", - "rel": "collaborates_on", - "src": "user_mika" - }, - { - "confidence": 0.9, - "dst": "event_iron_wharf", - "rel": "collaborates_on", - "src": "user_quinn" - }, - { - "confidence": 0.9, - "dst": "event_amber_veil", - "rel": "investigates", - "src": "user_nora" - }, - { - "confidence": 0.9, - "dst": "event_ember_tide", - "rel": "collaborates_on", - "src": "user_rhea" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "collaborates_on", - "src": "user_soren" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "reports_on", - "src": "user_tara" - }, - { - "confidence": 0.9, - "dst": "event_silent_current", - "rel": "monitors", - "src": "user_gita" - }, - { - "confidence": 0.9, - "dst": "event_silent_current", - "rel": "reports_on", - "src": "user_jules" - }, - { - "confidence": 0.77, - "dst": "event_glass_harbor", - "rel": "connected_to", - "src": "event_project_lantern" - }, - { - "confidence": 0.77, - "dst": "event_amber_veil", - "rel": "connected_to", - "src": "event_black_kite" - }, - { - "confidence": 0.77, - "dst": "event_ghost_signal", - "rel": "connected_to", - "src": "event_ember_tide" - }, - { - "confidence": 0.77, - "dst": "org_northbridge_logistics", - "rel": "connected_to", - "src": "org_atlas_freight" - }, - { - "confidence": 0.77, - "dst": "org_emberline_security", - "rel": "connected_to", - "src": "org_orion_customs" - }, - { - "confidence": 0.77, - "dst": "org_tidewatch_ops", - "rel": "connected_to", - "src": "org_harborlight_transit" - } - ], - "node_count": 118, - "nodes": [ - { - "attrs": { - "handle": "@alias_12_827" - }, - "node_id": "alias_12_827", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@alias_21_334" - }, - "node_id": "alias_21_334", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@alias_5_936" - }, - "node_id": "alias_5_936", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@alias_6_801" - }, - "node_id": "alias_6_801", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@basinraven" - }, - "node_id": "alias_basinraven", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@cinderveil" - }, - "node_id": "alias_cinderveil", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@docksparrow" - }, - "node_id": "alias_docksparrow", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@emberglass" - }, - "node_id": "alias_emberglass", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@frostledger" - }, - "node_id": "alias_frostledger", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@hollowsignal" - }, - "node_id": "alias_hollowsignal", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@ironwhisper" - }, - "node_id": "alias_ironwhisper", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@lanternmoth" - }, - "node_id": "alias_lanternmoth", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@mapleghost" - }, - "node_id": "alias_mapleghost", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@monsoonbyte" - }, - "node_id": "alias_monsoonbyte", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@nightrelay" - }, - "node_id": "alias_nightrelay", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@orchidfox" - }, - "node_id": "alias_orchidfox", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@quartzlotus" - }, - "node_id": "alias_quartzlotus", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@sablekeel" - }, - "node_id": "alias_sablekeel", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@steelquill" - }, - "node_id": "alias_steelquill", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@tideshard" - }, - "node_id": "alias_tideshard", - "node_type": "alias" - }, - { - "attrs": { - "name": "Amber Veil" - }, - "node_id": "event_amber_veil", - "node_type": "event" - }, - { - "attrs": { - "name": "Black Kite" - }, - "node_id": "event_black_kite", - "node_type": "event" - }, - { - "attrs": { - "name": "Ember Tide" - }, - "node_id": "event_ember_tide", - "node_type": "event" - }, - { - "attrs": { - "name": "Ghost Signal" - }, - "node_id": "event_ghost_signal", - "node_type": "event" - }, - { - "attrs": { - "name": "Glass Harbor" - }, - "node_id": "event_glass_harbor", - "node_type": "event" - }, - { - "attrs": { - "name": "Iron Wharf" - }, - "node_id": "event_iron_wharf", - "node_type": "event" - }, - { - "attrs": { - "name": "Project Lantern" - }, - "node_id": "event_project_lantern", - "node_type": "event" - }, - { - "attrs": { - "name": "Silent Current" - }, - "node_id": "event_silent_current", - "node_type": "event" - }, - { - "attrs": { - "name": "Bengaluru" - }, - "node_id": "loc_bengaluru", - "node_type": "location" - }, - { - "attrs": { - "name": "Delhi" - }, - "node_id": "loc_delhi", - "node_type": "location" - }, - { - "attrs": { - "name": "Dockyard 17" - }, - "node_id": "loc_dockyard17", - "node_type": "location" - }, - { - "attrs": { - "name": "East Quay" - }, - "node_id": "loc_east_quay", - "node_type": "location" - }, - { - "attrs": { - "name": "Foundry Row" - }, - "node_id": "loc_foundry_row", - "node_type": "location" - }, - { - "attrs": { - "name": "Hyderabad" - }, - "node_id": "loc_hyderabad", - "node_type": "location" - }, - { - "attrs": { - "name": "North Basin" - }, - "node_id": "loc_north_basin", - "node_type": "location" - }, - { - "attrs": { - "name": "Old Town" - }, - "node_id": "loc_old_town", - "node_type": "location" - }, - { - "attrs": { - "name": "Pune" - }, - "node_id": "loc_pune", - "node_type": "location" - }, - { - "attrs": { - "name": "Rivergate" - }, - "node_id": "loc_rivergate", - "node_type": "location" - }, - { - "attrs": { - "name": "Sector 9" - }, - "node_id": "loc_sector9", - "node_type": "location" - }, - { - "attrs": { - "name": "Uplink Yard" - }, - "node_id": "loc_uplink_yard", - "node_type": "location" - }, - { - "attrs": { - "name": "Apex Dynamics" - }, - "node_id": "org_apex_dynamics", - "node_type": "org" - }, - { - "attrs": { - "name": "Atlas Freight" - }, - "node_id": "org_atlas_freight", - "node_type": "org" - }, - { - "attrs": { - "name": "Blueharbor Media" - }, - "node_id": "org_blueharbor_media", - "node_type": "org" - }, - { - "attrs": { - "name": "Emberline Security" - }, - "node_id": "org_emberline_security", - "node_type": "org" - }, - { - "attrs": { - "name": "Harborlight Transit" - }, - "node_id": "org_harborlight_transit", - "node_type": "org" - }, - { - "attrs": { - "name": "Helios Labs" - }, - "node_id": "org_helios_labs", - "node_type": "org" - }, - { - "attrs": { - "name": "Kestrel Works" - }, - "node_id": "org_kestrel_works", - "node_type": "org" - }, - { - "attrs": { - "name": "Northbridge" - }, - "node_id": "org_northbridge", - "node_type": "org" - }, - { - "attrs": { - "name": "Northbridge Logistics" - }, - "node_id": "org_northbridge_logistics", - "node_type": "org" - }, - { - "attrs": { - "name": "Orion Customs" - }, - "node_id": "org_orion_customs", - "node_type": "org" - }, - { - "attrs": { - "name": "Sunmesh Analytics" - }, - "node_id": "org_sunmesh_analytics", - "node_type": "org" - }, - { - "attrs": { - "name": "Tidewatch Ops" - }, - "node_id": "org_tidewatch_ops", - "node_type": "org" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_basin_photo", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_customs_tag", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_drone_parts", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_foundry_map", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_hull_signal", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_lantern_route", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_midnight_manifest", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_quay_ledgers", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_relay_schedule", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_sat_phone_ping", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_shift_roster", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_uplink_note", - "node_type": "post" - }, - { - "attrs": { - "topic": "basin_shift" - }, - "node_id": "thr_basin_shift", - "node_type": "thread" - }, - { - "attrs": { - "topic": "customs_breach" - }, - "node_id": "thr_customs_breach", - "node_type": "thread" - }, - { - "attrs": { - "topic": "ember_tide" - }, - "node_id": "thr_ember_tide_watch", - "node_type": "thread" - }, - { - "attrs": { - "topic": "foundry_watch" - }, - "node_id": "thr_foundry_watch", - "node_type": "thread" - }, - { - "attrs": { - "topic": "ghost_signal" - }, - "node_id": "thr_ghost_signal_net", - "node_type": "thread" - }, - { - "attrs": { - "topic": "port_audit" - }, - "node_id": "thr_port_audit", - "node_type": "thread" - }, - { - "attrs": { - "topic": "quiet_manifest" - }, - "node_id": "thr_quiet_manifest", - "node_type": "thread" - }, - { - "attrs": { - "topic": "relay_map" - }, - "node_id": "thr_relay_map", - "node_type": "thread" - }, - { - "attrs": { - "topic": "supply_chain" - }, - "node_id": "thr_supply_leak", - "node_type": "thread" - }, - { - "attrs": { - "topic": "uplink_route" - }, - "node_id": "thr_uplink_route", - "node_type": "thread" - }, - { - "attrs": { - "location": "Hyderabad", - "name": "Person 0", - "org": "Apex Dynamics" - }, - "node_id": "user_0", - "node_type": "user" - }, - { - "attrs": { - "location": "Bengaluru", - "name": "Person 1", - "org": "Northbridge" - }, - "node_id": "user_1", - "node_type": "user" - }, - { - "attrs": { - "location": "Bengaluru", - "name": "Person 10", - "org": "Northbridge" - }, - "node_id": "user_10", - "node_type": "user" - }, - { - "attrs": { - "location": "Hyderabad", - "name": "Person 11", - "org": "Apex Dynamics" - }, - "node_id": "user_11", - "node_type": "user" - }, - { - "attrs": { - "location": "Hyderabad", - "name": "Person 12", - "org": "Apex Dynamics" - }, - "node_id": "user_12", - "node_type": "user" - }, - { - "attrs": { - "location": "Hyderabad", - "name": "Person 13", - "org": "Helios Labs" - }, - "node_id": "user_13", - "node_type": "user" - }, - { - "attrs": { - "location": "Delhi", - "name": "Person 14", - "org": "Apex Dynamics" - }, - "node_id": "user_14", - "node_type": "user" - }, - { - "attrs": { - "location": "Delhi", - "name": "Person 15", - "org": "Northbridge" - }, - "node_id": "user_15", - "node_type": "user" - }, - { - "attrs": { - "location": "Delhi", - "name": "Person 16", - "org": "Helios Labs" - }, - "node_id": "user_16", - "node_type": "user" - }, - { - "attrs": { - "location": "Hyderabad", - "name": "Person 17", - "org": "Northbridge" - }, - "node_id": "user_17", - "node_type": "user" - }, - { - "attrs": { - "location": "Delhi", - "name": "Person 18", - "org": "Northbridge" - }, - "node_id": "user_18", - "node_type": "user" - }, - { - "attrs": { - "location": "Pune", - "name": "Person 19", - "org": "Apex Dynamics" - }, - "node_id": "user_19", - "node_type": "user" - }, - { - "attrs": { - "location": "Delhi", - "name": "Person 2", - "org": "Northbridge" - }, - "node_id": "user_2", - "node_type": "user" - }, - { - "attrs": { - "location": "Bengaluru", - "name": "Person 20", - "org": "Apex Dynamics" - }, - "node_id": "user_20", - "node_type": "user" - }, - { - "attrs": { - "location": "Delhi", - "name": "Person 21", - "org": "Helios Labs" - }, - "node_id": "user_21", - "node_type": "user" - }, - { - "attrs": { - "location": "Delhi", - "name": "Person 22", - "org": "Apex Dynamics" - }, - "node_id": "user_22", - "node_type": "user" - }, - { - "attrs": { - "location": "Hyderabad", - "name": "Person 23", - "org": "Northbridge" - }, - "node_id": "user_23", - "node_type": "user" - }, - { - "attrs": { - "location": "Delhi", - "name": "Person 3", - "org": "Northbridge" - }, - "node_id": "user_3", - "node_type": "user" - }, - { - "attrs": { - "location": "Delhi", - "name": "Person 4", - "org": "Northbridge" - }, - "node_id": "user_4", - "node_type": "user" - }, - { - "attrs": { - "location": "Bengaluru", - "name": "Person 5", - "org": "Northbridge" - }, - "node_id": "user_5", - "node_type": "user" - }, - { - "attrs": { - "location": "Delhi", - "name": "Person 6", - "org": "Apex Dynamics" - }, - "node_id": "user_6", - "node_type": "user" - }, - { - "attrs": { - "location": "Hyderabad", - "name": "Person 7", - "org": "Helios Labs" - }, - "node_id": "user_7", - "node_type": "user" - }, - { - "attrs": { - "location": "Hyderabad", - "name": "Person 8", - "org": "Helios Labs" - }, - "node_id": "user_8", - "node_type": "user" - }, - { - "attrs": { - "location": "Delhi", - "name": "Person 9", - "org": "Helios Labs" - }, - "node_id": "user_9", - "node_type": "user" - }, - { - "attrs": { - "location": "Sector 9", - "name": "Aria Sen", - "org": "Helios Labs" - }, - "node_id": "user_aria", - "node_type": "user" - }, - { - "attrs": { - "location": "Dockyard 17", - "name": "Bharat Kulkarni", - "org": "Northbridge Logistics" - }, - "node_id": "user_bharat", - "node_type": "user" - }, - { - "attrs": { - "location": "Old Town", - "name": "Cyrus Mehta", - "org": "Apex Dynamics" - }, - "node_id": "user_cyrus", - "node_type": "user" - }, - { - "attrs": { - "location": "Old Town", - "name": "Diya Roy", - "org": "Blueharbor Media" - }, - "node_id": "user_diya", - "node_type": "user" - }, - { - "attrs": { - "location": "Sector 9", - "name": "Elin Das", - "org": "Helios Labs" - }, - "node_id": "user_elin", - "node_type": "user" - }, - { - "attrs": { - "location": "Rivergate", - "name": "Faris Noor", - "org": "Tidewatch Ops" - }, - "node_id": "user_faris", - "node_type": "user" - }, - { - "attrs": { - "location": "Old Town", - "name": "Gita Pradhan", - "org": "Apex Dynamics" - }, - "node_id": "user_gita", - "node_type": "user" - }, - { - "attrs": { - "location": "Dockyard 17", - "name": "Hiro Tan", - "org": "Northbridge Logistics" - }, - "node_id": "user_hiro", - "node_type": "user" - }, - { - "attrs": { - "location": "Rivergate", - "name": "Ivy Kapoor", - "org": "Kestrel Works" - }, - "node_id": "user_ivy", - "node_type": "user" - }, - { - "attrs": { - "location": "Old Town", - "name": "Jules Banerjee", - "org": "Blueharbor Media" - }, - "node_id": "user_jules", - "node_type": "user" - }, - { - "attrs": { - "location": "East Quay", - "name": "Kian Bose", - "org": "Atlas Freight" - }, - "node_id": "user_kian", - "node_type": "user" - }, - { - "attrs": { - "location": "Sector 9", - "name": "Leena Das", - "org": "Sunmesh Analytics" - }, - "node_id": "user_leena", - "node_type": "user" - }, - { - "attrs": { - "location": "North Basin", - "name": "Mika Solanki", - "org": "Orion Customs" - }, - "node_id": "user_mika", - "node_type": "user" - }, - { - "attrs": { - "location": "Foundry Row", - "name": "Nora Iqbal", - "org": "Emberline Security" - }, - "node_id": "user_nora", - "node_type": "user" - }, - { - "attrs": { - "location": "East Quay", - "name": "Omar Sheikh", - "org": "Atlas Freight" - }, - "node_id": "user_omar", - "node_type": "user" - }, - { - "attrs": { - "location": "Sector 9", - "name": "Priya Menon", - "org": "Sunmesh Analytics" - }, - "node_id": "user_priya", - "node_type": "user" - }, - { - "attrs": { - "location": "North Basin", - "name": "Quinn Rao", - "org": "Orion Customs" - }, - "node_id": "user_quinn", - "node_type": "user" - }, - { - "attrs": { - "location": "Foundry Row", - "name": "Rhea Kapoor", - "org": "Emberline Security" - }, - "node_id": "user_rhea", - "node_type": "user" - }, - { - "attrs": { - "location": "Uplink Yard", - "name": "Soren Malik", - "org": "Harborlight Transit" - }, - "node_id": "user_soren", - "node_type": "user" - }, - { - "attrs": { - "location": "Uplink Yard", - "name": "Tara Dey", - "org": "Harborlight Transit" - }, - "node_id": "user_tara", - "node_type": "user" - } - ] - }, - "dataset_name": "fixed_levels_submission_set", - "difficulty_counts": { - "easy": 10, - "high": 10, - "mid": 10 - }, - "environment": { - "alias_density": 0.2, - "n_users": 24, - "noise_level": 0.12, - "red_herring_rate": 0.08, - "seed": 2026 - }, - "generation_mode": "llm_expanded", - "llm": { - "max_tokens": 384, - "model": "qwen3:2b", - "ollama_base_url": "http://127.0.0.1:11434", - "openai_api_key": "", - "openai_api_key_env": "OPENAI_API_KEY", - "openai_base_url": "https://api.openai.com/v1", - "provider": "ollama", - "temperature": 0.05, - "timeout_seconds": 240 - }, - "platform_views": { - "counts": { - "forum_threads": 8, - "microblog_posts": 44, - "profiles": 47 - }, - "forum_threads": [ - { - "author_id": "user_17", - "comments": [ - { - "text": "Following this.", - "user_id": "user_6" - }, - { - "text": "Interesting link.", - "user_id": "user_16" - } - ], - "thread_id": "thr_0", - "topic": "startup" - }, - { - "author_id": "user_6", - "comments": [ - { - "text": "Following this.", - "user_id": "user_10" - }, - { - "text": "Interesting link.", - "user_id": "user_6" - } - ], - "thread_id": "thr_1", - "topic": "infra" - }, - { - "author_id": "user_tara", - "comments": [ - { - "text": "Following this.", - "user_id": "user_22" - }, - { - "text": "Interesting link.", - "user_id": "user_11" - } - ], - "thread_id": "thr_2", - "topic": "security" - }, - { - "author_id": "user_rhea", - "comments": [ - { - "text": "Following this.", - "user_id": "user_ivy" - }, - { - "text": "Interesting link.", - "user_id": "user_20" - } - ], - "thread_id": "thr_3", - "topic": "security" - }, - { - "author_id": "user_17", - "comments": [ - { - "text": "Following this.", - "user_id": "user_18" - }, - { - "text": "Interesting link.", - "user_id": "user_20" - } - ], - "thread_id": "thr_4", - "topic": "security" - }, - { - "author_id": "user_10", - "comments": [ - { - "text": "Following this.", - "user_id": "user_16" - }, - { - "text": "Interesting link.", - "user_id": "user_4" - } - ], - "thread_id": "thr_5", - "topic": "ai" - }, - { - "author_id": "user_0", - "comments": [ - { - "text": "Following this.", - "user_id": "user_16" - }, - { - "text": "Interesting link.", - "user_id": "user_cyrus" - } - ], - "thread_id": "thr_6", - "topic": "infra" - }, - { - "author_id": "user_0", - "comments": [ - { - "text": "Following this.", - "user_id": "user_6" - }, - { - "text": "Interesting link.", - "user_id": "user_15" - } - ], - "thread_id": "thr_7", - "topic": "security" - } - ], - "microblog_posts": [ - { - "canonical_user": "user_0", - "mentions": [ - "user_15" - ], - "post_id": "post_0", - "text": "Update 0 from Apex Dynamics #hyderabad", - "timestamp": 1000, - "user_id": "user_0" - }, - { - "canonical_user": "user_1", - "mentions": [ - "user_1" - ], - "post_id": "post_1", - "text": "Update 1 from Northbridge #bengaluru", - "timestamp": 1001, - "user_id": "user_1" - }, - { - "canonical_user": "user_2", - "mentions": [ - "user_3" - ], - "post_id": "post_2", - "text": "Update 2 from Northbridge #delhi", - "timestamp": 1002, - "user_id": "user_2" - }, - { - "canonical_user": "user_rhea", - "mentions": [ - "user_5" - ], - "post_id": "post_3", - "text": "Update 3 from Northbridge #delhi", - "timestamp": 1003, - "user_id": "alias_cinderveil" - }, - { - "canonical_user": "user_4", - "mentions": [ - "user_15" - ], - "post_id": "post_4", - "text": "Update 4 from Northbridge #delhi", - "timestamp": 1004, - "user_id": "user_4" - }, - { - "canonical_user": "user_5", - "mentions": [ - "user_15" - ], - "post_id": "post_5", - "text": "Update 5 from Northbridge #bengaluru", - "timestamp": 1005, - "user_id": "user_5" - }, - { - "canonical_user": "user_diya", - "mentions": [ - "user_13" - ], - "post_id": "post_6", - "text": "Update 6 from Apex Dynamics #delhi", - "timestamp": 1006, - "user_id": "alias_monsoonbyte" - }, - { - "canonical_user": "user_5", - "mentions": [ - "user_14" - ], - "post_id": "post_7", - "text": "Rumor: Update 7 from Helios Labs #hyderabad maybe fake", - "timestamp": 1007, - "user_id": "alias_5_936" - }, - { - "canonical_user": "user_8", - "mentions": [ - "user_2" - ], - "post_id": "post_8", - "text": "Update 8 from Helios Labs #hyderabad", - "timestamp": 1008, - "user_id": "user_8" - }, - { - "canonical_user": "user_9", - "mentions": [ - "user_3" - ], - "post_id": "post_9", - "text": "Update 9 from Helios Labs #delhi", - "timestamp": 1009, - "user_id": "user_9" - }, - { - "canonical_user": "user_10", - "mentions": [ - "user_8" - ], - "post_id": "post_10", - "text": "Update 10 from Northbridge #bengaluru", - "timestamp": 1010, - "user_id": "user_10" - }, - { - "canonical_user": "user_11", - "mentions": [ - "user_4" - ], - "post_id": "post_11", - "text": "Update 11 from Apex Dynamics #hyderabad", - "timestamp": 1011, - "user_id": "user_11" - }, - { - "canonical_user": "user_kian", - "mentions": [ - "user_15" - ], - "post_id": "post_12", - "text": "Update 12 from Apex Dynamics #hyderabad", - "timestamp": 1012, - "user_id": "alias_lanternmoth" - }, - { - "canonical_user": "user_13", - "mentions": [ - "user_17" - ], - "post_id": "post_13", - "text": "Update 13 from Helios Labs #hyderabad", - "timestamp": 1013, - "user_id": "user_13" - }, - { - "canonical_user": "user_kian", - "mentions": [ - "user_19" - ], - "post_id": "post_14", - "text": "Update 14 from Apex Dynamics #delhi", - "timestamp": 1014, - "user_id": "alias_lanternmoth" - }, - { - "canonical_user": "user_15", - "mentions": [ - "user_2" - ], - "post_id": "post_15", - "text": "Update 15 from Northbridge #delhi", - "timestamp": 1015, - "user_id": "user_15" - }, - { - "canonical_user": "user_bharat", - "mentions": [ - "user_18" - ], - "post_id": "post_16", - "text": "Update 16 from Helios Labs #delhi", - "timestamp": 1016, - "user_id": "alias_steelquill" - }, - { - "canonical_user": "user_soren", - "mentions": [ - "user_4" - ], - "post_id": "post_17", - "text": "Update 17 from Northbridge #hyderabad", - "timestamp": 1017, - "user_id": "alias_tideshard" - }, - { - "canonical_user": "user_18", - "mentions": [ - "user_0" - ], - "post_id": "post_18", - "text": "Update 18 from Northbridge #delhi", - "timestamp": 1018, - "user_id": "user_18" - }, - { - "canonical_user": "user_19", - "mentions": [ - "user_2" - ], - "post_id": "post_19", - "text": "Update 19 from Apex Dynamics #pune", - "timestamp": 1019, - "user_id": "user_19" - }, - { - "canonical_user": "user_nora", - "mentions": [ - "user_0" - ], - "post_id": "post_20", - "text": "Update 20 from Apex Dynamics #bengaluru", - "timestamp": 1020, - "user_id": "alias_emberglass" - }, - { - "canonical_user": "user_omar", - "mentions": [ - "user_9" - ], - "post_id": "post_21", - "text": "Update 21 from Helios Labs #delhi", - "timestamp": 1021, - "user_id": "alias_ironwhisper" - }, - { - "canonical_user": "user_22", - "mentions": [ - "user_15" - ], - "post_id": "post_22", - "text": "Update 22 from Apex Dynamics #delhi", - "timestamp": 1022, - "user_id": "user_22" - }, - { - "canonical_user": "user_23", - "mentions": [ - "user_5" - ], - "post_id": "post_23", - "text": "Update 23 from Northbridge #hyderabad", - "timestamp": 1023, - "user_id": "user_23" - }, - { - "canonical_user": "user_rhea", - "mentions": [ - "user_19" - ], - "post_id": "post_24", - "text": "Update 24 from Helios Labs #sector 9", - "timestamp": 1024, - "user_id": "alias_cinderveil" - }, - { - "canonical_user": "user_leena", - "mentions": [ - "user_22" - ], - "post_id": "post_25", - "text": "Update 25 from Northbridge Logistics #dockyard 17", - "timestamp": 1025, - "user_id": "alias_frostledger" - }, - { - "canonical_user": "user_mika", - "mentions": [ - "user_20" - ], - "post_id": "post_26", - "text": "Rumor: Update 26 from Apex Dynamics #old town maybe fake", - "timestamp": 1026, - "user_id": "alias_basinraven" - }, - { - "canonical_user": "user_diya", - "mentions": [ - "user_17" - ], - "post_id": "post_27", - "text": "Rumor: Update 27 from Blueharbor Media #old town maybe fake", - "timestamp": 1027, - "user_id": "user_diya" - }, - { - "canonical_user": "user_elin", - "mentions": [ - "user_20" - ], - "post_id": "post_28", - "text": "Rumor: Update 28 from Helios Labs #sector 9 maybe fake", - "timestamp": 1028, - "user_id": "user_elin" - }, - { - "canonical_user": "user_5", - "mentions": [ - "user_16" - ], - "post_id": "post_29", - "text": "Update 29 from Tidewatch Ops #rivergate", - "timestamp": 1029, - "user_id": "alias_5_936" - }, - { - "canonical_user": "user_rhea", - "mentions": [ - "user_4" - ], - "post_id": "post_30", - "text": "Update 30 from Apex Dynamics #old town", - "timestamp": 1030, - "user_id": "alias_cinderveil" - }, - { - "canonical_user": "user_bharat", - "mentions": [ - "user_13" - ], - "post_id": "post_31", - "text": "Update 31 from Northbridge Logistics #dockyard 17", - "timestamp": 1031, - "user_id": "alias_steelquill" - }, - { - "canonical_user": "user_ivy", - "mentions": [ - "user_12" - ], - "post_id": "post_32", - "text": "Update 32 from Kestrel Works #rivergate", - "timestamp": 1032, - "user_id": "user_ivy" - }, - { - "canonical_user": "user_nora", - "mentions": [ - "user_14" - ], - "post_id": "post_33", - "text": "Update 33 from Blueharbor Media #old town", - "timestamp": 1033, - "user_id": "alias_emberglass" - }, - { - "canonical_user": "user_kian", - "mentions": [ - "user_13" - ], - "post_id": "post_34", - "text": "Update 34 from Atlas Freight #east quay", - "timestamp": 1034, - "user_id": "user_kian" - }, - { - "canonical_user": "user_bharat", - "mentions": [ - "user_15" - ], - "post_id": "post_35", - "text": "Update 35 from Sunmesh Analytics #sector 9", - "timestamp": 1035, - "user_id": "alias_steelquill" - }, - { - "canonical_user": "user_rhea", - "mentions": [ - "user_8" - ], - "post_id": "post_36", - "text": "Update 36 from Orion Customs #north basin", - "timestamp": 1036, - "user_id": "alias_cinderveil" - }, - { - "canonical_user": "user_nora", - "mentions": [ - "user_7" - ], - "post_id": "post_37", - "text": "Update 37 from Emberline Security #foundry row", - "timestamp": 1037, - "user_id": "user_nora" - }, - { - "canonical_user": "user_12", - "mentions": [ - "user_20" - ], - "post_id": "post_38", - "text": "Update 38 from Atlas Freight #east quay", - "timestamp": 1038, - "user_id": "alias_12_827" - }, - { - "canonical_user": "user_tara", - "mentions": [ - "user_21" - ], - "post_id": "post_39", - "text": "Update 39 from Sunmesh Analytics #sector 9", - "timestamp": 1039, - "user_id": "alias_sablekeel" - }, - { - "canonical_user": "user_5", - "mentions": [ - "user_5" - ], - "post_id": "post_40", - "text": "Update 40 from Orion Customs #north basin", - "timestamp": 1040, - "user_id": "alias_5_936" - }, - { - "canonical_user": "user_kian", - "mentions": [ - "user_6" - ], - "post_id": "post_41", - "text": "Update 41 from Emberline Security #foundry row", - "timestamp": 1041, - "user_id": "alias_lanternmoth" - }, - { - "canonical_user": "user_elin", - "mentions": [ - "user_18" - ], - "post_id": "post_42", - "text": "Update 42 from Harborlight Transit #uplink yard", - "timestamp": 1042, - "user_id": "alias_mapleghost" - }, - { - "canonical_user": "user_tara", - "mentions": [ - "user_18" - ], - "post_id": "post_43", - "text": "Update 43 from Harborlight Transit #uplink yard", - "timestamp": 1043, - "user_id": "user_tara" - } - ], - "profiles": [ - { - "connections": [ - "user_1" - ], - "location": "Hyderabad", - "name": "Person 0", - "org": "Apex Dynamics", - "user_id": "user_0", - "work_history": [ - "Apex Dynamics" - ] - }, - { - "connections": [], - "location": "Bengaluru", - "name": "Person 1", - "org": "Northbridge", - "user_id": "user_1", - "work_history": [ - "Northbridge" - ] - }, - { - "connections": [], - "location": "Delhi", - "name": "Person 2", - "org": "Northbridge", - "user_id": "user_2", - "work_history": [ - "Northbridge" - ] - }, - { - "connections": [], - "location": "Delhi", - "name": "Person 3", - "org": "Northbridge", - "user_id": "user_3", - "work_history": [ - "Northbridge" - ] - }, - { - "connections": [ - "user_20" - ], - "location": "Delhi", - "name": "Person 4", - "org": "Northbridge", - "user_id": "user_4", - "work_history": [ - "Northbridge" - ] - }, - { - "connections": [], - "location": "Bengaluru", - "name": "Person 5", - "org": "Northbridge", - "user_id": "user_5", - "work_history": [ - "Northbridge" - ] - }, - { - "connections": [], - "location": "Delhi", - "name": "Person 6", - "org": "Apex Dynamics", - "user_id": "user_6", - "work_history": [ - "Apex Dynamics" - ] - }, - { - "connections": [], - "location": "Hyderabad", - "name": "Person 7", - "org": "Helios Labs", - "user_id": "user_7", - "work_history": [ - "Helios Labs" - ] - }, - { - "connections": [ - "user_22" - ], - "location": "Hyderabad", - "name": "Person 8", - "org": "Helios Labs", - "user_id": "user_8", - "work_history": [ - "Helios Labs" - ] - }, - { - "connections": [ - "user_8" - ], - "location": "Delhi", - "name": "Person 9", - "org": "Helios Labs", - "user_id": "user_9", - "work_history": [ - "Helios Labs" - ] - }, - { - "connections": [], - "location": "Bengaluru", - "name": "Person 10", - "org": "Northbridge", - "user_id": "user_10", - "work_history": [ - "Northbridge" - ] - }, - { - "connections": [ - "user_6" - ], - "location": "Hyderabad", - "name": "Person 11", - "org": "Apex Dynamics", - "user_id": "user_11", - "work_history": [ - "Apex Dynamics" - ] - }, - { - "connections": [], - "location": "Hyderabad", - "name": "Person 12", - "org": "Apex Dynamics", - "user_id": "user_12", - "work_history": [ - "Apex Dynamics" - ] - }, - { - "connections": [ - "user_6" - ], - "location": "Hyderabad", - "name": "Person 13", - "org": "Helios Labs", - "user_id": "user_13", - "work_history": [ - "Helios Labs" - ] - }, - { - "connections": [], - "location": "Delhi", - "name": "Person 14", - "org": "Apex Dynamics", - "user_id": "user_14", - "work_history": [ - "Apex Dynamics" - ] - }, - { - "connections": [ - "user_12" - ], - "location": "Delhi", - "name": "Person 15", - "org": "Northbridge", - "user_id": "user_15", - "work_history": [ - "Northbridge" - ] - }, - { - "connections": [ - "user_22", - "user_15" - ], - "location": "Delhi", - "name": "Person 16", - "org": "Helios Labs", - "user_id": "user_16", - "work_history": [ - "Helios Labs" - ] - }, - { - "connections": [ - "user_20" - ], - "location": "Hyderabad", - "name": "Person 17", - "org": "Northbridge", - "user_id": "user_17", - "work_history": [ - "Northbridge" - ] - }, - { - "connections": [], - "location": "Delhi", - "name": "Person 18", - "org": "Northbridge", - "user_id": "user_18", - "work_history": [ - "Northbridge" - ] - }, - { - "connections": [ - "user_14" - ], - "location": "Pune", - "name": "Person 19", - "org": "Apex Dynamics", - "user_id": "user_19", - "work_history": [ - "Apex Dynamics" - ] - }, - { - "connections": [], - "location": "Bengaluru", - "name": "Person 20", - "org": "Apex Dynamics", - "user_id": "user_20", - "work_history": [ - "Apex Dynamics" - ] - }, - { - "connections": [ - "user_9" - ], - "location": "Delhi", - "name": "Person 21", - "org": "Helios Labs", - "user_id": "user_21", - "work_history": [ - "Helios Labs" - ] - }, - { - "connections": [], - "location": "Delhi", - "name": "Person 22", - "org": "Apex Dynamics", - "user_id": "user_22", - "work_history": [ - "Apex Dynamics" - ] - }, - { - "connections": [], - "location": "Hyderabad", - "name": "Person 23", - "org": "Northbridge", - "user_id": "user_23", - "work_history": [ - "Northbridge" - ] - }, - { - "connections": [ - "user_cyrus" - ], - "location": "Sector 9", - "name": "Aria Sen", - "org": "Helios Labs", - "user_id": "user_aria", - "work_history": [ - "Helios Labs" - ] - }, - { - "connections": [ - "user_hiro" - ], - "location": "Dockyard 17", - "name": "Bharat Kulkarni", - "org": "Northbridge Logistics", - "user_id": "user_bharat", - "work_history": [ - "Northbridge Logistics" - ] - }, - { - "connections": [ - "user_gita" - ], - "location": "Old Town", - "name": "Cyrus Mehta", - "org": "Apex Dynamics", - "user_id": "user_cyrus", - "work_history": [ - "Apex Dynamics" - ] - }, - { - "connections": [ - "user_elin", - "user_ivy" - ], - "location": "Old Town", - "name": "Diya Roy", - "org": "Blueharbor Media", - "user_id": "user_diya", - "work_history": [ - "Blueharbor Media" - ] - }, - { - "connections": [ - "user_aria" - ], - "location": "Sector 9", - "name": "Elin Das", - "org": "Helios Labs", - "user_id": "user_elin", - "work_history": [ - "Helios Labs" - ] - }, - { - "connections": [ - "user_diya" - ], - "location": "Rivergate", - "name": "Faris Noor", - "org": "Tidewatch Ops", - "user_id": "user_faris", - "work_history": [ - "Tidewatch Ops" - ] - }, - { - "connections": [ - "user_jules" - ], - "location": "Old Town", - "name": "Gita Pradhan", - "org": "Apex Dynamics", - "user_id": "user_gita", - "work_history": [ - "Apex Dynamics" - ] - }, - { - "connections": [ - "user_faris" - ], - "location": "Dockyard 17", - "name": "Hiro Tan", - "org": "Northbridge Logistics", - "user_id": "user_hiro", - "work_history": [ - "Northbridge Logistics" - ] - }, - { - "connections": [ - "user_bharat", - "user_elin" - ], - "location": "Rivergate", - "name": "Ivy Kapoor", - "org": "Kestrel Works", - "user_id": "user_ivy", - "work_history": [ - "Kestrel Works" - ] - }, - { - "connections": [ - "user_bharat" - ], - "location": "Old Town", - "name": "Jules Banerjee", - "org": "Blueharbor Media", - "user_id": "user_jules", - "work_history": [ - "Blueharbor Media" - ] - }, - { - "connections": [ - "user_omar", - "user_bharat" - ], - "location": "East Quay", - "name": "Kian Bose", - "org": "Atlas Freight", - "user_id": "user_kian", - "work_history": [ - "Atlas Freight" - ] - }, - { - "connections": [ - "user_aria" - ], - "location": "Sector 9", - "name": "Leena Das", - "org": "Sunmesh Analytics", - "user_id": "user_leena", - "work_history": [ - "Sunmesh Analytics" - ] - }, - { - "connections": [ - "user_quinn" - ], - "location": "North Basin", - "name": "Mika Solanki", - "org": "Orion Customs", - "user_id": "user_mika", - "work_history": [ - "Orion Customs" - ] - }, - { - "connections": [ - "user_rhea" - ], - "location": "Foundry Row", - "name": "Nora Iqbal", - "org": "Emberline Security", - "user_id": "user_nora", - "work_history": [ - "Emberline Security" - ] - }, - { - "connections": [ - "user_mika" - ], - "location": "East Quay", - "name": "Omar Sheikh", - "org": "Atlas Freight", - "user_id": "user_omar", - "work_history": [ - "Atlas Freight" - ] - }, - { - "connections": [ - "user_leena", - "user_nora" - ], - "location": "Sector 9", - "name": "Priya Menon", - "org": "Sunmesh Analytics", - "user_id": "user_priya", - "work_history": [ - "Sunmesh Analytics" - ] - }, - { - "connections": [ - "user_nora", - "user_hiro" - ], - "location": "North Basin", - "name": "Quinn Rao", - "org": "Orion Customs", - "user_id": "user_quinn", - "work_history": [ - "Orion Customs" - ] - }, - { - "connections": [ - "user_soren" - ], - "location": "Foundry Row", - "name": "Rhea Kapoor", - "org": "Emberline Security", - "user_id": "user_rhea", - "work_history": [ - "Emberline Security" - ] - }, - { - "connections": [ - "user_tara", - "user_faris" - ], - "location": "Uplink Yard", - "name": "Soren Malik", - "org": "Harborlight Transit", - "user_id": "user_soren", - "work_history": [ - "Harborlight Transit" - ] - }, - { - "connections": [ - "user_kian" - ], - "location": "Uplink Yard", - "name": "Tara Dey", - "org": "Harborlight Transit", - "user_id": "user_tara", - "work_history": [ - "Harborlight Transit" - ] - }, - { - "connections": [], - "location": "Remote", - "name": "P123", - "org": "Unknown Ventures", - "user_id": "noise_0", - "work_history": [] - }, - { - "connections": [], - "location": "Unknown", - "name": "P196", - "org": "Unknown Ventures", - "user_id": "noise_1", - "work_history": [] - }, - { - "connections": [], - "location": "Remote", - "name": "P898", - "org": "Unknown Ventures", - "user_id": "noise_2", - "work_history": [] - } - ] - }, - "seed_file": "datasets\\fixed_levels\\seed_fixed_levels.json", - "shared_config": "datasets\\fixed_levels\\shared_config_fixed_levels.json", - "task_count": 30, - "tasks": [ - { - "answer": "user_bharat", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_01", - "support_nodes": 6 - }, - "question": "alias_orchidfox -> post_midnight_manifest -> loc_dockyard17 -> connected collaborator on event_project_lantern. Who is it?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 0.95, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_bharat" - } - ], - "task_id": "seed_task_0", - "task_type": "fixed_trace" - }, - { - "answer": "user_hiro", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_02", - "support_nodes": 5 - }, - "question": "thr_supply_leak references org_northbridge_logistics. Which alias_docksparrow user works there and collaborates on event_project_lantern?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_hiro" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_hiro" - } - ], - "task_id": "seed_task_1", - "task_type": "fixed_trace" - }, - { - "answer": "user_diya", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_03", - "support_nodes": 7 - }, - "question": "alias_monsoonbyte authored post_drone_parts about event_black_kite. Which user behind that alias is directly connected to the Kestrel collaborator?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "post_drone_parts", - "rel": "authored_post", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "references", - "src": "post_drone_parts" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_ivy" - }, - { - "confidence": 0.86, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_ivy" - } - ], - "task_id": "seed_task_2", - "task_type": "fixed_trace" - }, - { - "answer": "user_faris", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_04", - "support_nodes": 6 - }, - "question": "alias_nightrelay references loc_rivergate. Which user behind it works at an org operating there and collaborates on event_project_lantern?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "post_sat_phone_ping", - "rel": "authored_post", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "references", - "src": "post_sat_phone_ping" - }, - { - "confidence": 1.0, - "dst": "org_tidewatch_ops", - "rel": "works_at", - "src": "user_faris" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "operates_in", - "src": "org_tidewatch_ops" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_faris" - } - ], - "task_id": "seed_task_3", - "task_type": "fixed_trace" - }, - { - "answer": "user_ivy", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_05", - "support_nodes": 6 - }, - "question": "thr_port_audit discusses Black Kite and references Kestrel Works. Which alias_orchidfox user authored post_midnight_manifest and collaborates on Black Kite?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "discusses", - "src": "thr_port_audit" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "references", - "src": "thr_port_audit" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_ivy" - } - ], - "task_id": "seed_task_4", - "task_type": "fixed_trace" - }, - { - "answer": "user_kian", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_06", - "support_nodes": 5 - }, - "question": "Which Atlas Freight user behind alias_lanternmoth authored post_quay_ledgers and collaborates on event_glass_harbor?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_kian" - } - ], - "task_id": "seed_task_5", - "task_type": "fixed_trace" - }, - { - "answer": "user_mika", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_07", - "support_nodes": 5 - }, - "question": "Which Orion Customs user behind alias_basinraven authored post_customs_tag and collaborates on event_iron_wharf?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "post_customs_tag", - "rel": "authored_post", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_mika" - }, - { - "confidence": 0.9, - "dst": "event_iron_wharf", - "rel": "collaborates_on", - "src": "user_mika" - } - ], - "task_id": "seed_task_6", - "task_type": "fixed_trace" - }, - { - "answer": "user_nora", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_08", - "support_nodes": 5 - }, - "question": "Which user behind alias_emberglass posted basin_photo from Foundry Row and investigates Amber Veil?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "post_basin_photo", - "rel": "authored_post", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 0.9, - "dst": "event_amber_veil", - "rel": "investigates", - "src": "user_nora" - } - ], - "task_id": "seed_task_7", - "task_type": "fixed_trace" - }, - { - "answer": "user_soren", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_09", - "support_nodes": 4 - }, - "question": "Which user behind alias_tideshard authored post_hull_signal and collaborates on Ghost Signal?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "post_hull_signal", - "rel": "authored_post", - "src": "alias_tideshard" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "collaborates_on", - "src": "user_soren" - } - ], - "task_id": "seed_task_8", - "task_type": "fixed_trace" - }, - { - "answer": "user_tara", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_10", - "support_nodes": 5 - }, - "question": "Which Harborlight Transit user behind alias_sablekeel authored post_uplink_note and reports on Ghost Signal?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "post_uplink_note", - "rel": "authored_post", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_tara" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "reports_on", - "src": "user_tara" - } - ], - "task_id": "seed_task_9", - "task_type": "fixed_trace" - }, - { - "answer": "org_northbridge_logistics", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_01", - "support_nodes": 17 - }, - "question": "Follow alias_docksparrow through post_shift_roster, Dockyard 17, and the Lantern chain. Return the org node id.", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "post_shift_roster", - "rel": "authored_post", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_shift_roster" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "post_shift_roster" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_hiro" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_hiro" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_bharat" - }, - { - "confidence": 0.95, - "dst": "user_hiro", - "rel": "connected_to", - "src": "user_bharat" - }, - { - "confidence": 0.92, - "dst": "user_faris", - "rel": "connected_to", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "references", - "src": "post_quay_ledgers" - } - ], - "task_id": "seed_task_10", - "task_type": "fixed_trace" - }, - { - "answer": "user_kian", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_02", - "support_nodes": 17 - }, - "question": "Across the Glass Harbor cluster, which user behind alias_lanternmoth links to the Atlas Freight network from thr_quiet_manifest?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 1.0, - "dst": "thr_quiet_manifest", - "rel": "authored_thread", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "discusses", - "src": "thr_quiet_manifest" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "references", - "src": "thr_quiet_manifest" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_omar" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_omar" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "monitors", - "src": "user_priya" - }, - { - "confidence": 0.93, - "dst": "user_omar", - "rel": "connected_to", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "user_mika", - "rel": "connected_to", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "post_customs_tag", - "rel": "authored_post", - "src": "alias_basinraven" - } - ], - "task_id": "seed_task_11", - "task_type": "fixed_trace" - }, - { - "answer": "user_mika", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_03", - "support_nodes": 17 - }, - "question": "Trace alias_basinraven through post_customs_tag, thr_customs_breach, and the Orion Customs collaboration chain. Who is it?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "post_customs_tag", - "rel": "authored_post", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "references", - "src": "post_customs_tag" - }, - { - "confidence": 1.0, - "dst": "event_iron_wharf", - "rel": "references", - "src": "post_customs_tag" - }, - { - "confidence": 1.0, - "dst": "thr_customs_breach", - "rel": "authored_thread", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "event_iron_wharf", - "rel": "discusses", - "src": "thr_customs_breach" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "references", - "src": "thr_customs_breach" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_quinn" - }, - { - "confidence": 0.9, - "dst": "event_iron_wharf", - "rel": "collaborates_on", - "src": "user_mika" - }, - { - "confidence": 0.9, - "dst": "event_iron_wharf", - "rel": "collaborates_on", - "src": "user_quinn" - }, - { - "confidence": 0.89, - "dst": "user_quinn", - "rel": "connected_to", - "src": "user_mika" - }, - { - "confidence": 0.88, - "dst": "user_nora", - "rel": "connected_to", - "src": "user_quinn" - }, - { - "confidence": 0.77, - "dst": "org_emberline_security", - "rel": "connected_to", - "src": "org_orion_customs" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - } - ], - "task_id": "seed_task_12", - "task_type": "fixed_trace" - }, - { - "answer": "user_rhea", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_04", - "support_nodes": 18 - }, - "question": "In the Ember Tide and Amber Veil overlap, which Foundry Row user behind alias_cinderveil collaborates on Ember Tide?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "post_foundry_map", - "rel": "authored_post", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_foundry_map" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "references", - "src": "post_foundry_map" - }, - { - "confidence": 1.0, - "dst": "thr_foundry_watch", - "rel": "authored_thread", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "discusses", - "src": "thr_foundry_watch" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "references", - "src": "thr_foundry_watch" - }, - { - "confidence": 1.0, - "dst": "thr_ember_tide_watch", - "rel": "authored_thread", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "discusses", - "src": "thr_ember_tide_watch" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "thr_ember_tide_watch" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_nora" - }, - { - "confidence": 0.9, - "dst": "event_amber_veil", - "rel": "investigates", - "src": "user_nora" - }, - { - "confidence": 0.9, - "dst": "event_ember_tide", - "rel": "collaborates_on", - "src": "user_rhea" - }, - { - "confidence": 0.87, - "dst": "user_rhea", - "rel": "connected_to", - "src": "user_nora" - }, - { - "confidence": 0.77, - "dst": "event_ghost_signal", - "rel": "connected_to", - "src": "event_ember_tide" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - } - ], - "task_id": "seed_task_13", - "task_type": "fixed_trace" - }, - { - "answer": "org_harborlight_transit", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_05", - "support_nodes": 17 - }, - "question": "Follow alias_tideshard from post_hull_signal into thr_uplink_route and the Harborlight relay. Return the org node id.", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "post_hull_signal", - "rel": "authored_post", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "post_hull_signal" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "references", - "src": "post_hull_signal" - }, - { - "confidence": 1.0, - "dst": "thr_uplink_route", - "rel": "authored_thread", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "discusses", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_tara" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "collaborates_on", - "src": "user_soren" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "reports_on", - "src": "user_tara" - }, - { - "confidence": 0.86, - "dst": "user_soren", - "rel": "connected_to", - "src": "user_rhea" - }, - { - "confidence": 0.86, - "dst": "user_tara", - "rel": "connected_to", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "operates_in", - "src": "org_harborlight_transit" - }, - { - "confidence": 0.77, - "dst": "org_tidewatch_ops", - "rel": "connected_to", - "src": "org_harborlight_transit" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - } - ], - "task_id": "seed_task_14", - "task_type": "fixed_trace" - }, - { - "answer": "user_leena", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_06", - "support_nodes": 17 - }, - "question": "Which Sunmesh user behind alias_frostledger connects post_lantern_route to thr_relay_map and the Sector 9 monitoring chain?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "post_lantern_route", - "rel": "authored_post", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_lantern_route" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "references", - "src": "post_lantern_route" - }, - { - "confidence": 1.0, - "dst": "thr_relay_map", - "rel": "authored_thread", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_relay_map" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "references", - "src": "thr_relay_map" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "operates_in", - "src": "org_sunmesh_analytics" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "monitors", - "src": "user_leena" - }, - { - "confidence": 0.91, - "dst": "user_leena", - "rel": "connected_to", - "src": "user_priya" - }, - { - "confidence": 0.83, - "dst": "user_aria", - "rel": "connected_to", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "references", - "src": "post_quay_ledgers" - } - ], - "task_id": "seed_task_15", - "task_type": "fixed_trace" - }, - { - "answer": "user_nora", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_07", - "support_nodes": 18 - }, - "question": "Which user behind alias_emberglass is tied to Amber Veil after combining post_basin_photo, thr_basin_shift, and the Foundry Row investigation chain?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "post_basin_photo", - "rel": "authored_post", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 1.0, - "dst": "event_amber_veil", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 1.0, - "dst": "thr_basin_shift", - "rel": "authored_thread", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "event_amber_veil", - "rel": "discusses", - "src": "thr_basin_shift" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "references", - "src": "thr_basin_shift" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_nora" - }, - { - "confidence": 0.9, - "dst": "event_amber_veil", - "rel": "investigates", - "src": "user_nora" - }, - { - "confidence": 0.88, - "dst": "user_nora", - "rel": "connected_to", - "src": "user_quinn" - }, - { - "confidence": 0.87, - "dst": "user_rhea", - "rel": "connected_to", - "src": "user_nora" - }, - { - "confidence": 0.77, - "dst": "org_emberline_security", - "rel": "connected_to", - "src": "org_orion_customs" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - } - ], - "task_id": "seed_task_16", - "task_type": "fixed_trace" - }, - { - "answer": "user_ivy", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_08", - "support_nodes": 17 - }, - "question": "Combine alias_orchidfox, post_midnight_manifest, thr_supply_leak, and the Lantern to Glass Harbor bridge. Which user starts that chain?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_ivy" - }, - { - "confidence": 0.95, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.86, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.77, - "dst": "event_glass_harbor", - "rel": "connected_to", - "src": "event_project_lantern" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "monitors", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - } - ], - "task_id": "seed_task_17", - "task_type": "fixed_trace" - }, - { - "answer": "user_diya", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_09", - "support_nodes": 18 - }, - "question": "Which user behind alias_monsoonbyte sits at the overlap of Blueharbor Media, Project Lantern, Black Kite, and the Ivy connection chain?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "post_drone_parts", - "rel": "authored_post", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "references", - "src": "post_drone_parts" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "thr_port_audit", - "rel": "authored_thread", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "discusses", - "src": "thr_port_audit" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_jules" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "investigates", - "src": "user_diya" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "reports_on", - "src": "user_jules" - }, - { - "confidence": 0.9, - "dst": "user_diya", - "rel": "connected_to", - "src": "user_faris" - }, - { - "confidence": 0.86, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - } - ], - "task_id": "seed_task_18", - "task_type": "fixed_trace" - }, - { - "answer": "user_bharat", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_10", - "support_nodes": 17 - }, - "question": "Who is the Northbridge user behind alias_steelquill when combining post_relay_schedule, thr_supply_leak, Dockyard 17, and Lantern collaborator edges?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "post_relay_schedule", - "rel": "authored_post", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_relay_schedule" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "references", - "src": "post_relay_schedule" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_hiro" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_bharat" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_hiro" - }, - { - "confidence": 0.95, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.95, - "dst": "user_hiro", - "rel": "connected_to", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "references", - "src": "post_quay_ledgers" - } - ], - "task_id": "seed_task_19", - "task_type": "fixed_trace" - }, - { - "answer": "user_ivy", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_01", - "support_nodes": 50 - }, - "question": "Lantern to Glass Harbor handoff: identify the user behind alias_orchidfox after combining Lantern logistics, Dockyard links, and Atlas Freight bridge evidence.", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "located_in", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "located_in", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "operates_in", - "src": "org_northbridge_logistics" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "operates_in", - "src": "org_kestrel_works" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "operates_in", - "src": "org_atlas_freight" - }, - { - "confidence": 0.95, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.95, - "dst": "user_hiro", - "rel": "connected_to", - "src": "user_bharat" - }, - { - "confidence": 0.92, - "dst": "user_faris", - "rel": "connected_to", - "src": "user_hiro" - }, - { - "confidence": 0.86, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.93, - "dst": "user_omar", - "rel": "connected_to", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "user_mika", - "rel": "connected_to", - "src": "user_omar" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_bharat" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_hiro" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_faris" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_omar" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "monitors", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "thr_quiet_manifest", - "rel": "authored_thread", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "discusses", - "src": "thr_quiet_manifest" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "references", - "src": "thr_quiet_manifest" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 0.77, - "dst": "event_glass_harbor", - "rel": "connected_to", - "src": "event_project_lantern" - }, - { - "confidence": 0.77, - "dst": "org_northbridge_logistics", - "rel": "connected_to", - "src": "org_atlas_freight" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_cyrus" - } - ], - "task_id": "seed_task_20", - "task_type": "fixed_trace" - }, - { - "answer": "user_mika", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_02", - "support_nodes": 50 - }, - "question": "North Basin to Foundry Row escalation: which user behind alias_basinraven anchors the Iron Wharf side before the Emberline handoff?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "post_customs_tag", - "rel": "authored_post", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "references", - "src": "post_customs_tag" - }, - { - "confidence": 1.0, - "dst": "event_iron_wharf", - "rel": "references", - "src": "post_customs_tag" - }, - { - "confidence": 1.0, - "dst": "thr_customs_breach", - "rel": "authored_thread", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "event_iron_wharf", - "rel": "discusses", - "src": "thr_customs_breach" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "references", - "src": "thr_customs_breach" - }, - { - "confidence": 1.0, - "dst": "thr_basin_shift", - "rel": "authored_thread", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "event_amber_veil", - "rel": "discusses", - "src": "thr_basin_shift" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "references", - "src": "thr_basin_shift" - }, - { - "confidence": 1.0, - "dst": "thr_foundry_watch", - "rel": "authored_thread", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "discusses", - "src": "thr_foundry_watch" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "references", - "src": "thr_foundry_watch" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "located_in", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "located_in", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "operates_in", - "src": "org_orion_customs" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "operates_in", - "src": "org_emberline_security" - }, - { - "confidence": 0.89, - "dst": "user_quinn", - "rel": "connected_to", - "src": "user_mika" - }, - { - "confidence": 0.88, - "dst": "user_nora", - "rel": "connected_to", - "src": "user_quinn" - }, - { - "confidence": 0.87, - "dst": "user_rhea", - "rel": "connected_to", - "src": "user_nora" - }, - { - "confidence": 0.9, - "dst": "event_iron_wharf", - "rel": "collaborates_on", - "src": "user_mika" - }, - { - "confidence": 0.9, - "dst": "event_iron_wharf", - "rel": "collaborates_on", - "src": "user_quinn" - }, - { - "confidence": 0.9, - "dst": "event_amber_veil", - "rel": "investigates", - "src": "user_nora" - }, - { - "confidence": 0.9, - "dst": "event_ember_tide", - "rel": "collaborates_on", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "post_basin_photo", - "rel": "authored_post", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 1.0, - "dst": "event_amber_veil", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 1.0, - "dst": "post_foundry_map", - "rel": "authored_post", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_foundry_map" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "references", - "src": "post_foundry_map" - }, - { - "confidence": 0.77, - "dst": "event_amber_veil", - "rel": "connected_to", - "src": "event_black_kite" - }, - { - "confidence": 0.77, - "dst": "event_ghost_signal", - "rel": "connected_to", - "src": "event_ember_tide" - }, - { - "confidence": 0.77, - "dst": "org_emberline_security", - "rel": "connected_to", - "src": "org_orion_customs" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 0.82, - "dst": "user_nora", - "rel": "connected_to", - "src": "user_priya" - }, - { - "confidence": 0.8, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - } - ], - "task_id": "seed_task_21", - "task_type": "fixed_trace" - }, - { - "answer": "user_soren", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_03", - "support_nodes": 50 - }, - "question": "Harborlight ghost-signal relay: identify the user behind alias_tideshard at the Harborlight / Tidewatch junction.", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "post_hull_signal", - "rel": "authored_post", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "post_hull_signal" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "references", - "src": "post_hull_signal" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "post_uplink_note", - "rel": "authored_post", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "post_uplink_note" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "post_uplink_note" - }, - { - "confidence": 1.0, - "dst": "thr_uplink_route", - "rel": "authored_thread", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "discusses", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "thr_ghost_signal_net", - "rel": "authored_thread", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "discusses", - "src": "thr_ghost_signal_net" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "thr_ghost_signal_net" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "org_tidewatch_ops", - "rel": "works_at", - "src": "user_faris" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_faris" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "operates_in", - "src": "org_harborlight_transit" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "operates_in", - "src": "org_tidewatch_ops" - }, - { - "confidence": 0.86, - "dst": "user_soren", - "rel": "connected_to", - "src": "user_rhea" - }, - { - "confidence": 0.86, - "dst": "user_tara", - "rel": "connected_to", - "src": "user_soren" - }, - { - "confidence": 0.84, - "dst": "user_kian", - "rel": "connected_to", - "src": "user_tara" - }, - { - "confidence": 0.79, - "dst": "user_faris", - "rel": "connected_to", - "src": "user_soren" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_faris" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "collaborates_on", - "src": "user_soren" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "reports_on", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "post_sat_phone_ping", - "rel": "authored_post", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "references", - "src": "post_sat_phone_ping" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_sat_phone_ping" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_supply_leak" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_bharat" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_hiro" - }, - { - "confidence": 0.77, - "dst": "event_ghost_signal", - "rel": "connected_to", - "src": "event_ember_tide" - }, - { - "confidence": 0.77, - "dst": "org_tidewatch_ops", - "rel": "connected_to", - "src": "org_harborlight_transit" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_bharat" - } - ], - "task_id": "seed_task_22", - "task_type": "fixed_trace" - }, - { - "answer": "user_diya", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_04", - "support_nodes": 50 - }, - "question": "Blueharbor to Black Kite to Lantern overlap: which user is the Blueharbor origin behind alias_monsoonbyte?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "post_drone_parts", - "rel": "authored_post", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "references", - "src": "post_drone_parts" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "references", - "src": "post_drone_parts" - }, - { - "confidence": 1.0, - "dst": "thr_port_audit", - "rel": "authored_thread", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "discusses", - "src": "thr_port_audit" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "references", - "src": "thr_port_audit" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "operates_in", - "src": "org_blueharbor_media" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "operates_in", - "src": "org_kestrel_works" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "operates_in", - "src": "org_apex_dynamics" - }, - { - "confidence": 0.9, - "dst": "user_diya", - "rel": "connected_to", - "src": "user_faris" - }, - { - "confidence": 0.83, - "dst": "user_gita", - "rel": "connected_to", - "src": "user_cyrus" - }, - { - "confidence": 0.82, - "dst": "user_jules", - "rel": "connected_to", - "src": "user_gita" - }, - { - "confidence": 0.86, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "investigates", - "src": "user_diya" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_cyrus" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "investigates", - "src": "user_elin" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "reports_on", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 0.77, - "dst": "event_glass_harbor", - "rel": "connected_to", - "src": "event_project_lantern" - }, - { - "confidence": 0.77, - "dst": "event_amber_veil", - "rel": "connected_to", - "src": "event_black_kite" - }, - { - "confidence": 1.0, - "dst": "thr_relay_map", - "rel": "authored_thread", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_relay_map" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_leena" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "monitors", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - } - ], - "task_id": "seed_task_23", - "task_type": "fixed_trace" - }, - { - "answer": "user_bharat", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_05", - "support_nodes": 50 - }, - "question": "Sector 9 to Dockyard 17 full relay: which user behind alias_steelquill links the Northbridge chain and the Sunmesh monitoring bridge?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "post_relay_schedule", - "rel": "authored_post", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_relay_schedule" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "references", - "src": "post_relay_schedule" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "post_lantern_route", - "rel": "authored_post", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_lantern_route" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "references", - "src": "post_lantern_route" - }, - { - "confidence": 1.0, - "dst": "thr_relay_map", - "rel": "authored_thread", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_relay_map" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "references", - "src": "thr_relay_map" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "operates_in", - "src": "org_northbridge_logistics" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "operates_in", - "src": "org_sunmesh_analytics" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "operates_in", - "src": "org_helios_labs" - }, - { - "confidence": 0.95, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.95, - "dst": "user_hiro", - "rel": "connected_to", - "src": "user_bharat" - }, - { - "confidence": 0.89, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_diya" - }, - { - "confidence": 0.87, - "dst": "user_aria", - "rel": "connected_to", - "src": "user_elin" - }, - { - "confidence": 0.84, - "dst": "user_cyrus", - "rel": "connected_to", - "src": "user_aria" - }, - { - "confidence": 0.91, - "dst": "user_leena", - "rel": "connected_to", - "src": "user_priya" - }, - { - "confidence": 0.83, - "dst": "user_aria", - "rel": "connected_to", - "src": "user_leena" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_bharat" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_hiro" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "monitors", - "src": "user_leena" - }, - { - "confidence": 0.77, - "dst": "event_glass_harbor", - "rel": "connected_to", - "src": "event_project_lantern" - }, - { - "confidence": 0.77, - "dst": "org_northbridge_logistics", - "rel": "connected_to", - "src": "org_atlas_freight" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_elin" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_elin" - }, - { - "confidence": 1.0, - "dst": "org_tidewatch_ops", - "rel": "works_at", - "src": "user_faris" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_faris" - } - ], - "task_id": "seed_task_24", - "task_type": "fixed_trace" - }, - { - "answer": "user_nora", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_06", - "support_nodes": 50 - }, - "question": "Foundry Row, North Basin, and Uplink Yard spread: identify the user behind alias_emberglass before the Harborlight relay takes over.", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "post_basin_photo", - "rel": "authored_post", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 1.0, - "dst": "event_amber_veil", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "post_foundry_map", - "rel": "authored_post", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_foundry_map" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "references", - "src": "post_foundry_map" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "post_uplink_note", - "rel": "authored_post", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "post_uplink_note" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "post_uplink_note" - }, - { - "confidence": 1.0, - "dst": "thr_foundry_watch", - "rel": "authored_thread", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "discusses", - "src": "thr_foundry_watch" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "references", - "src": "thr_foundry_watch" - }, - { - "confidence": 1.0, - "dst": "thr_ember_tide_watch", - "rel": "authored_thread", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "discusses", - "src": "thr_ember_tide_watch" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "thr_ember_tide_watch" - }, - { - "confidence": 1.0, - "dst": "thr_uplink_route", - "rel": "authored_thread", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "discusses", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "operates_in", - "src": "org_emberline_security" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "operates_in", - "src": "org_harborlight_transit" - }, - { - "confidence": 0.87, - "dst": "user_rhea", - "rel": "connected_to", - "src": "user_nora" - }, - { - "confidence": 0.86, - "dst": "user_soren", - "rel": "connected_to", - "src": "user_rhea" - }, - { - "confidence": 0.86, - "dst": "user_tara", - "rel": "connected_to", - "src": "user_soren" - }, - { - "confidence": 0.9, - "dst": "event_amber_veil", - "rel": "investigates", - "src": "user_nora" - }, - { - "confidence": 0.9, - "dst": "event_ember_tide", - "rel": "collaborates_on", - "src": "user_rhea" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "collaborates_on", - "src": "user_soren" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "reports_on", - "src": "user_tara" - }, - { - "confidence": 0.77, - "dst": "event_ghost_signal", - "rel": "connected_to", - "src": "event_ember_tide" - }, - { - "confidence": 0.77, - "dst": "org_tidewatch_ops", - "rel": "connected_to", - "src": "org_harborlight_transit" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - } - ], - "task_id": "seed_task_25", - "task_type": "fixed_trace" - }, - { - "answer": "user_kian", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_07", - "support_nodes": 50 - }, - "question": "Freight and customs bridge: which Atlas Freight user behind alias_lanternmoth connects Glass Harbor with the Northbridge chain?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 1.0, - "dst": "thr_quiet_manifest", - "rel": "authored_thread", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "discusses", - "src": "thr_quiet_manifest" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "references", - "src": "thr_quiet_manifest" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "located_in", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "located_in", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "operates_in", - "src": "org_atlas_freight" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "operates_in", - "src": "org_northbridge_logistics" - }, - { - "confidence": 0.93, - "dst": "user_omar", - "rel": "connected_to", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "user_mika", - "rel": "connected_to", - "src": "user_omar" - }, - { - "confidence": 0.8, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_kian" - }, - { - "confidence": 0.95, - "dst": "user_hiro", - "rel": "connected_to", - "src": "user_bharat" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_omar" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "monitors", - "src": "user_priya" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_bharat" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "post_shift_roster", - "rel": "authored_post", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_shift_roster" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "post_shift_roster" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 0.77, - "dst": "org_northbridge_logistics", - "rel": "connected_to", - "src": "org_atlas_freight" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_elin" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_elin" - }, - { - "confidence": 1.0, - "dst": "org_tidewatch_ops", - "rel": "works_at", - "src": "user_faris" - } - ], - "task_id": "seed_task_26", - "task_type": "fixed_trace" - }, - { - "answer": "user_cyrus", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_08", - "support_nodes": 50 - }, - "question": "Black Kite, Amber Veil, and Iron Wharf overlap: which user behind alias_quartzlotus is the Apex-side collaborator?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "operates_in", - "src": "org_apex_dynamics" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "thr_port_audit", - "rel": "authored_thread", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "discusses", - "src": "thr_port_audit" - }, - { - "confidence": 1.0, - "dst": "post_drone_parts", - "rel": "authored_post", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "references", - "src": "post_drone_parts" - }, - { - "confidence": 0.9, - "dst": "event_amber_veil", - "rel": "investigates", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "thr_basin_shift", - "rel": "authored_thread", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "event_amber_veil", - "rel": "discusses", - "src": "thr_basin_shift" - }, - { - "confidence": 0.9, - "dst": "event_iron_wharf", - "rel": "collaborates_on", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "thr_customs_breach", - "rel": "authored_thread", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "event_iron_wharf", - "rel": "discusses", - "src": "thr_customs_breach" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "located_in", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "located_in", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "operates_in", - "src": "org_kestrel_works" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "operates_in", - "src": "org_emberline_security" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "operates_in", - "src": "org_orion_customs" - }, - { - "confidence": 0.83, - "dst": "user_gita", - "rel": "connected_to", - "src": "user_cyrus" - }, - { - "confidence": 0.86, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.89, - "dst": "user_quinn", - "rel": "connected_to", - "src": "user_mika" - }, - { - "confidence": 0.88, - "dst": "user_nora", - "rel": "connected_to", - "src": "user_quinn" - }, - { - "confidence": 0.87, - "dst": "user_rhea", - "rel": "connected_to", - "src": "user_nora" - }, - { - "confidence": 0.77, - "dst": "event_amber_veil", - "rel": "connected_to", - "src": "event_black_kite" - }, - { - "confidence": 0.77, - "dst": "org_emberline_security", - "rel": "connected_to", - "src": "org_orion_customs" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - } - ], - "task_id": "seed_task_27", - "task_type": "fixed_trace" - }, - { - "answer": "user_tara", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_09", - "support_nodes": 50 - }, - "question": "Ghost Signal and Ember Tide relay: which user behind alias_sablekeel is the Harborlight reporting endpoint?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "post_uplink_note", - "rel": "authored_post", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "post_uplink_note" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "post_uplink_note" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "post_hull_signal", - "rel": "authored_post", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "post_hull_signal" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "references", - "src": "post_hull_signal" - }, - { - "confidence": 1.0, - "dst": "thr_ghost_signal_net", - "rel": "authored_thread", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "discusses", - "src": "thr_ghost_signal_net" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "thr_ghost_signal_net" - }, - { - "confidence": 1.0, - "dst": "thr_uplink_route", - "rel": "authored_thread", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "discusses", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "thr_ember_tide_watch", - "rel": "authored_thread", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "discusses", - "src": "thr_ember_tide_watch" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "thr_ember_tide_watch" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "operates_in", - "src": "org_harborlight_transit" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "operates_in", - "src": "org_emberline_security" - }, - { - "confidence": 0.86, - "dst": "user_soren", - "rel": "connected_to", - "src": "user_rhea" - }, - { - "confidence": 0.86, - "dst": "user_tara", - "rel": "connected_to", - "src": "user_soren" - }, - { - "confidence": 0.87, - "dst": "user_rhea", - "rel": "connected_to", - "src": "user_nora" - }, - { - "confidence": 0.9, - "dst": "event_ember_tide", - "rel": "collaborates_on", - "src": "user_rhea" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "collaborates_on", - "src": "user_soren" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "reports_on", - "src": "user_tara" - }, - { - "confidence": 0.77, - "dst": "event_ghost_signal", - "rel": "connected_to", - "src": "event_ember_tide" - }, - { - "confidence": 0.77, - "dst": "org_tidewatch_ops", - "rel": "connected_to", - "src": "org_harborlight_transit" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_cyrus" - } - ], - "task_id": "seed_task_28", - "task_type": "fixed_trace" - }, - { - "answer": "user_priya", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_10", - "support_nodes": 55 - }, - "question": "End-to-end benchmark sweep: across Lantern, Black Kite, Glass Harbor, Iron Wharf, Ember Tide, and Ghost Signal, which user behind alias_hollowsignal anchors the Sunmesh monitoring side?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_elin" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_elin" - }, - { - "confidence": 1.0, - "dst": "org_tidewatch_ops", - "rel": "works_at", - "src": "user_faris" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_faris" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_gita" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_gita" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "located_in", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "located_in", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "located_in", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "located_in", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "operates_in", - "src": "org_helios_labs" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "operates_in", - "src": "org_northbridge_logistics" - } - ], - "task_id": "seed_task_29", - "task_type": "fixed_trace" - } - ] -} \ No newline at end of file diff --git a/scratch/osint/datasets/fixed_levels/fixed_graph_questions.json b/scratch/osint/datasets/fixed_levels/fixed_graph_questions.json deleted file mode 100644 index 2fdf99e415462e6256c65214e432b9ba064c3840..0000000000000000000000000000000000000000 --- a/scratch/osint/datasets/fixed_levels/fixed_graph_questions.json +++ /dev/null @@ -1,7009 +0,0 @@ -{ - "dataset_name": "fixed_levels_submission_set", - "difficulty_counts": { - "easy": 10, - "high": 10, - "mid": 10 - }, - "graph": { - "edge_count": 185, - "edges": [ - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_elin" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_elin" - }, - { - "confidence": 1.0, - "dst": "org_tidewatch_ops", - "rel": "works_at", - "src": "user_faris" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_faris" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_gita" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_gita" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "located_in", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "located_in", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "located_in", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "located_in", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "operates_in", - "src": "org_helios_labs" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "operates_in", - "src": "org_northbridge_logistics" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "operates_in", - "src": "org_apex_dynamics" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "operates_in", - "src": "org_blueharbor_media" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "operates_in", - "src": "org_tidewatch_ops" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "operates_in", - "src": "org_kestrel_works" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "operates_in", - "src": "org_atlas_freight" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "operates_in", - "src": "org_sunmesh_analytics" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "operates_in", - "src": "org_orion_customs" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "operates_in", - "src": "org_emberline_security" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "operates_in", - "src": "org_harborlight_transit" - }, - { - "confidence": 0.95, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.95, - "dst": "user_hiro", - "rel": "connected_to", - "src": "user_bharat" - }, - { - "confidence": 0.92, - "dst": "user_faris", - "rel": "connected_to", - "src": "user_hiro" - }, - { - "confidence": 0.9, - "dst": "user_diya", - "rel": "connected_to", - "src": "user_faris" - }, - { - "confidence": 0.89, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_diya" - }, - { - "confidence": 0.87, - "dst": "user_aria", - "rel": "connected_to", - "src": "user_elin" - }, - { - "confidence": 0.84, - "dst": "user_cyrus", - "rel": "connected_to", - "src": "user_aria" - }, - { - "confidence": 0.83, - "dst": "user_gita", - "rel": "connected_to", - "src": "user_cyrus" - }, - { - "confidence": 0.82, - "dst": "user_jules", - "rel": "connected_to", - "src": "user_gita" - }, - { - "confidence": 0.81, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_jules" - }, - { - "confidence": 0.9, - "dst": "user_ivy", - "rel": "connected_to", - "src": "user_diya" - }, - { - "confidence": 0.86, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.93, - "dst": "user_omar", - "rel": "connected_to", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "user_mika", - "rel": "connected_to", - "src": "user_omar" - }, - { - "confidence": 0.89, - "dst": "user_quinn", - "rel": "connected_to", - "src": "user_mika" - }, - { - "confidence": 0.88, - "dst": "user_nora", - "rel": "connected_to", - "src": "user_quinn" - }, - { - "confidence": 0.87, - "dst": "user_rhea", - "rel": "connected_to", - "src": "user_nora" - }, - { - "confidence": 0.86, - "dst": "user_soren", - "rel": "connected_to", - "src": "user_rhea" - }, - { - "confidence": 0.86, - "dst": "user_tara", - "rel": "connected_to", - "src": "user_soren" - }, - { - "confidence": 0.84, - "dst": "user_kian", - "rel": "connected_to", - "src": "user_tara" - }, - { - "confidence": 0.91, - "dst": "user_leena", - "rel": "connected_to", - "src": "user_priya" - }, - { - "confidence": 0.83, - "dst": "user_aria", - "rel": "connected_to", - "src": "user_leena" - }, - { - "confidence": 0.82, - "dst": "user_nora", - "rel": "connected_to", - "src": "user_priya" - }, - { - "confidence": 0.8, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_kian" - }, - { - "confidence": 0.79, - "dst": "user_faris", - "rel": "connected_to", - "src": "user_soren" - }, - { - "confidence": 0.78, - "dst": "user_hiro", - "rel": "connected_to", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_shift_roster", - "rel": "authored_post", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "post_sat_phone_ping", - "rel": "authored_post", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "post_drone_parts", - "rel": "authored_post", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "post_relay_schedule", - "rel": "authored_post", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "post_customs_tag", - "rel": "authored_post", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "post_hull_signal", - "rel": "authored_post", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "post_basin_photo", - "rel": "authored_post", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "post_foundry_map", - "rel": "authored_post", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "post_lantern_route", - "rel": "authored_post", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "post_uplink_note", - "rel": "authored_post", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_shift_roster" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "post_shift_roster" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "references", - "src": "post_sat_phone_ping" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_sat_phone_ping" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "references", - "src": "post_drone_parts" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "references", - "src": "post_drone_parts" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_relay_schedule" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "references", - "src": "post_relay_schedule" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "references", - "src": "post_customs_tag" - }, - { - "confidence": 1.0, - "dst": "event_iron_wharf", - "rel": "references", - "src": "post_customs_tag" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "post_hull_signal" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "references", - "src": "post_hull_signal" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 1.0, - "dst": "event_amber_veil", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_foundry_map" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "references", - "src": "post_foundry_map" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_lantern_route" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "references", - "src": "post_lantern_route" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "post_uplink_note" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "post_uplink_note" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "thr_port_audit", - "rel": "authored_thread", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "thr_customs_breach", - "rel": "authored_thread", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "thr_relay_map", - "rel": "authored_thread", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "thr_foundry_watch", - "rel": "authored_thread", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "thr_basin_shift", - "rel": "authored_thread", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "thr_quiet_manifest", - "rel": "authored_thread", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "thr_uplink_route", - "rel": "authored_thread", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "thr_ember_tide_watch", - "rel": "authored_thread", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "thr_ghost_signal_net", - "rel": "authored_thread", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "discusses", - "src": "thr_port_audit" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "references", - "src": "thr_port_audit" - }, - { - "confidence": 1.0, - "dst": "event_iron_wharf", - "rel": "discusses", - "src": "thr_customs_breach" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "references", - "src": "thr_customs_breach" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_relay_map" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "references", - "src": "thr_relay_map" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "discusses", - "src": "thr_foundry_watch" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "references", - "src": "thr_foundry_watch" - }, - { - "confidence": 1.0, - "dst": "event_amber_veil", - "rel": "discusses", - "src": "thr_basin_shift" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "references", - "src": "thr_basin_shift" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "discusses", - "src": "thr_quiet_manifest" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "references", - "src": "thr_quiet_manifest" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "discusses", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "discusses", - "src": "thr_ember_tide_watch" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "thr_ember_tide_watch" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "discusses", - "src": "thr_ghost_signal_net" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "thr_ghost_signal_net" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_bharat" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_hiro" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_faris" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "investigates", - "src": "user_diya" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "monitors", - "src": "user_leena" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_cyrus" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "investigates", - "src": "user_elin" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "reports_on", - "src": "user_jules" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_omar" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "monitors", - "src": "user_priya" - }, - { - "confidence": 0.9, - "dst": "event_iron_wharf", - "rel": "collaborates_on", - "src": "user_mika" - }, - { - "confidence": 0.9, - "dst": "event_iron_wharf", - "rel": "collaborates_on", - "src": "user_quinn" - }, - { - "confidence": 0.9, - "dst": "event_amber_veil", - "rel": "investigates", - "src": "user_nora" - }, - { - "confidence": 0.9, - "dst": "event_ember_tide", - "rel": "collaborates_on", - "src": "user_rhea" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "collaborates_on", - "src": "user_soren" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "reports_on", - "src": "user_tara" - }, - { - "confidence": 0.9, - "dst": "event_silent_current", - "rel": "monitors", - "src": "user_gita" - }, - { - "confidence": 0.9, - "dst": "event_silent_current", - "rel": "reports_on", - "src": "user_jules" - }, - { - "confidence": 0.77, - "dst": "event_glass_harbor", - "rel": "connected_to", - "src": "event_project_lantern" - }, - { - "confidence": 0.77, - "dst": "event_amber_veil", - "rel": "connected_to", - "src": "event_black_kite" - }, - { - "confidence": 0.77, - "dst": "event_ghost_signal", - "rel": "connected_to", - "src": "event_ember_tide" - }, - { - "confidence": 0.77, - "dst": "org_northbridge_logistics", - "rel": "connected_to", - "src": "org_atlas_freight" - }, - { - "confidence": 0.77, - "dst": "org_emberline_security", - "rel": "connected_to", - "src": "org_orion_customs" - }, - { - "confidence": 0.77, - "dst": "org_tidewatch_ops", - "rel": "connected_to", - "src": "org_harborlight_transit" - } - ], - "node_count": 85, - "nodes": [ - { - "attrs": { - "location": "Sector 9", - "name": "Aria Sen", - "org": "Helios Labs" - }, - "node_id": "user_aria", - "node_type": "user" - }, - { - "attrs": { - "location": "Dockyard 17", - "name": "Bharat Kulkarni", - "org": "Northbridge Logistics" - }, - "node_id": "user_bharat", - "node_type": "user" - }, - { - "attrs": { - "location": "Old Town", - "name": "Cyrus Mehta", - "org": "Apex Dynamics" - }, - "node_id": "user_cyrus", - "node_type": "user" - }, - { - "attrs": { - "location": "Old Town", - "name": "Diya Roy", - "org": "Blueharbor Media" - }, - "node_id": "user_diya", - "node_type": "user" - }, - { - "attrs": { - "location": "Sector 9", - "name": "Elin Das", - "org": "Helios Labs" - }, - "node_id": "user_elin", - "node_type": "user" - }, - { - "attrs": { - "location": "Rivergate", - "name": "Faris Noor", - "org": "Tidewatch Ops" - }, - "node_id": "user_faris", - "node_type": "user" - }, - { - "attrs": { - "location": "Old Town", - "name": "Gita Pradhan", - "org": "Apex Dynamics" - }, - "node_id": "user_gita", - "node_type": "user" - }, - { - "attrs": { - "location": "Dockyard 17", - "name": "Hiro Tan", - "org": "Northbridge Logistics" - }, - "node_id": "user_hiro", - "node_type": "user" - }, - { - "attrs": { - "location": "Rivergate", - "name": "Ivy Kapoor", - "org": "Kestrel Works" - }, - "node_id": "user_ivy", - "node_type": "user" - }, - { - "attrs": { - "location": "Old Town", - "name": "Jules Banerjee", - "org": "Blueharbor Media" - }, - "node_id": "user_jules", - "node_type": "user" - }, - { - "attrs": { - "location": "East Quay", - "name": "Kian Bose", - "org": "Atlas Freight" - }, - "node_id": "user_kian", - "node_type": "user" - }, - { - "attrs": { - "location": "Sector 9", - "name": "Leena Das", - "org": "Sunmesh Analytics" - }, - "node_id": "user_leena", - "node_type": "user" - }, - { - "attrs": { - "location": "North Basin", - "name": "Mika Solanki", - "org": "Orion Customs" - }, - "node_id": "user_mika", - "node_type": "user" - }, - { - "attrs": { - "location": "Foundry Row", - "name": "Nora Iqbal", - "org": "Emberline Security" - }, - "node_id": "user_nora", - "node_type": "user" - }, - { - "attrs": { - "location": "East Quay", - "name": "Omar Sheikh", - "org": "Atlas Freight" - }, - "node_id": "user_omar", - "node_type": "user" - }, - { - "attrs": { - "location": "Sector 9", - "name": "Priya Menon", - "org": "Sunmesh Analytics" - }, - "node_id": "user_priya", - "node_type": "user" - }, - { - "attrs": { - "location": "North Basin", - "name": "Quinn Rao", - "org": "Orion Customs" - }, - "node_id": "user_quinn", - "node_type": "user" - }, - { - "attrs": { - "location": "Foundry Row", - "name": "Rhea Kapoor", - "org": "Emberline Security" - }, - "node_id": "user_rhea", - "node_type": "user" - }, - { - "attrs": { - "location": "Uplink Yard", - "name": "Soren Malik", - "org": "Harborlight Transit" - }, - "node_id": "user_soren", - "node_type": "user" - }, - { - "attrs": { - "location": "Uplink Yard", - "name": "Tara Dey", - "org": "Harborlight Transit" - }, - "node_id": "user_tara", - "node_type": "user" - }, - { - "attrs": { - "handle": "@orchidfox" - }, - "node_id": "alias_orchidfox", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@steelquill" - }, - "node_id": "alias_steelquill", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@monsoonbyte" - }, - "node_id": "alias_monsoonbyte", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@nightrelay" - }, - "node_id": "alias_nightrelay", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@mapleghost" - }, - "node_id": "alias_mapleghost", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@docksparrow" - }, - "node_id": "alias_docksparrow", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@quartzlotus" - }, - "node_id": "alias_quartzlotus", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@emberglass" - }, - "node_id": "alias_emberglass", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@basinraven" - }, - "node_id": "alias_basinraven", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@tideshard" - }, - "node_id": "alias_tideshard", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@hollowsignal" - }, - "node_id": "alias_hollowsignal", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@ironwhisper" - }, - "node_id": "alias_ironwhisper", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@cinderveil" - }, - "node_id": "alias_cinderveil", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@sablekeel" - }, - "node_id": "alias_sablekeel", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@lanternmoth" - }, - "node_id": "alias_lanternmoth", - "node_type": "alias" - }, - { - "attrs": { - "handle": "@frostledger" - }, - "node_id": "alias_frostledger", - "node_type": "alias" - }, - { - "attrs": { - "name": "Helios Labs" - }, - "node_id": "org_helios_labs", - "node_type": "org" - }, - { - "attrs": { - "name": "Northbridge Logistics" - }, - "node_id": "org_northbridge_logistics", - "node_type": "org" - }, - { - "attrs": { - "name": "Apex Dynamics" - }, - "node_id": "org_apex_dynamics", - "node_type": "org" - }, - { - "attrs": { - "name": "Blueharbor Media" - }, - "node_id": "org_blueharbor_media", - "node_type": "org" - }, - { - "attrs": { - "name": "Tidewatch Ops" - }, - "node_id": "org_tidewatch_ops", - "node_type": "org" - }, - { - "attrs": { - "name": "Kestrel Works" - }, - "node_id": "org_kestrel_works", - "node_type": "org" - }, - { - "attrs": { - "name": "Atlas Freight" - }, - "node_id": "org_atlas_freight", - "node_type": "org" - }, - { - "attrs": { - "name": "Sunmesh Analytics" - }, - "node_id": "org_sunmesh_analytics", - "node_type": "org" - }, - { - "attrs": { - "name": "Orion Customs" - }, - "node_id": "org_orion_customs", - "node_type": "org" - }, - { - "attrs": { - "name": "Emberline Security" - }, - "node_id": "org_emberline_security", - "node_type": "org" - }, - { - "attrs": { - "name": "Harborlight Transit" - }, - "node_id": "org_harborlight_transit", - "node_type": "org" - }, - { - "attrs": { - "name": "Dockyard 17" - }, - "node_id": "loc_dockyard17", - "node_type": "location" - }, - { - "attrs": { - "name": "Sector 9" - }, - "node_id": "loc_sector9", - "node_type": "location" - }, - { - "attrs": { - "name": "Old Town" - }, - "node_id": "loc_old_town", - "node_type": "location" - }, - { - "attrs": { - "name": "Rivergate" - }, - "node_id": "loc_rivergate", - "node_type": "location" - }, - { - "attrs": { - "name": "East Quay" - }, - "node_id": "loc_east_quay", - "node_type": "location" - }, - { - "attrs": { - "name": "Foundry Row" - }, - "node_id": "loc_foundry_row", - "node_type": "location" - }, - { - "attrs": { - "name": "North Basin" - }, - "node_id": "loc_north_basin", - "node_type": "location" - }, - { - "attrs": { - "name": "Uplink Yard" - }, - "node_id": "loc_uplink_yard", - "node_type": "location" - }, - { - "attrs": { - "name": "Project Lantern" - }, - "node_id": "event_project_lantern", - "node_type": "event" - }, - { - "attrs": { - "name": "Black Kite" - }, - "node_id": "event_black_kite", - "node_type": "event" - }, - { - "attrs": { - "name": "Silent Current" - }, - "node_id": "event_silent_current", - "node_type": "event" - }, - { - "attrs": { - "name": "Amber Veil" - }, - "node_id": "event_amber_veil", - "node_type": "event" - }, - { - "attrs": { - "name": "Glass Harbor" - }, - "node_id": "event_glass_harbor", - "node_type": "event" - }, - { - "attrs": { - "name": "Ember Tide" - }, - "node_id": "event_ember_tide", - "node_type": "event" - }, - { - "attrs": { - "name": "Iron Wharf" - }, - "node_id": "event_iron_wharf", - "node_type": "event" - }, - { - "attrs": { - "name": "Ghost Signal" - }, - "node_id": "event_ghost_signal", - "node_type": "event" - }, - { - "attrs": { - "topic": "supply_chain" - }, - "node_id": "thr_supply_leak", - "node_type": "thread" - }, - { - "attrs": { - "topic": "port_audit" - }, - "node_id": "thr_port_audit", - "node_type": "thread" - }, - { - "attrs": { - "topic": "customs_breach" - }, - "node_id": "thr_customs_breach", - "node_type": "thread" - }, - { - "attrs": { - "topic": "relay_map" - }, - "node_id": "thr_relay_map", - "node_type": "thread" - }, - { - "attrs": { - "topic": "foundry_watch" - }, - "node_id": "thr_foundry_watch", - "node_type": "thread" - }, - { - "attrs": { - "topic": "basin_shift" - }, - "node_id": "thr_basin_shift", - "node_type": "thread" - }, - { - "attrs": { - "topic": "quiet_manifest" - }, - "node_id": "thr_quiet_manifest", - "node_type": "thread" - }, - { - "attrs": { - "topic": "uplink_route" - }, - "node_id": "thr_uplink_route", - "node_type": "thread" - }, - { - "attrs": { - "topic": "ember_tide" - }, - "node_id": "thr_ember_tide_watch", - "node_type": "thread" - }, - { - "attrs": { - "topic": "ghost_signal" - }, - "node_id": "thr_ghost_signal_net", - "node_type": "thread" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_shift_roster", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_midnight_manifest", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_sat_phone_ping", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_drone_parts", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_relay_schedule", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_quay_ledgers", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_customs_tag", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_hull_signal", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_basin_photo", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_foundry_map", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_lantern_route", - "node_type": "post" - }, - { - "attrs": { - "channel": "microblog" - }, - "node_id": "post_uplink_note", - "node_type": "post" - } - ] - }, - "question_count": 30, - "questions": [ - { - "answer": "user_bharat", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_01", - "support_nodes": 6 - }, - "question": "alias_orchidfox -> post_midnight_manifest -> loc_dockyard17 -> connected collaborator on event_project_lantern. Who is it?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 0.95, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_bharat" - } - ], - "task_id": "fixed_task_00", - "task_type": "fixed_trace" - }, - { - "answer": "user_hiro", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_02", - "support_nodes": 5 - }, - "question": "thr_supply_leak references org_northbridge_logistics. Which alias_docksparrow user works there and collaborates on event_project_lantern?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_hiro" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_hiro" - } - ], - "task_id": "fixed_task_01", - "task_type": "fixed_trace" - }, - { - "answer": "user_diya", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_03", - "support_nodes": 7 - }, - "question": "alias_monsoonbyte authored post_drone_parts about event_black_kite. Which user behind that alias is directly connected to the Kestrel collaborator?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "post_drone_parts", - "rel": "authored_post", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "references", - "src": "post_drone_parts" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_ivy" - }, - { - "confidence": 0.86, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_ivy" - } - ], - "task_id": "fixed_task_02", - "task_type": "fixed_trace" - }, - { - "answer": "user_faris", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_04", - "support_nodes": 6 - }, - "question": "alias_nightrelay references loc_rivergate. Which user behind it works at an org operating there and collaborates on event_project_lantern?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "post_sat_phone_ping", - "rel": "authored_post", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "references", - "src": "post_sat_phone_ping" - }, - { - "confidence": 1.0, - "dst": "org_tidewatch_ops", - "rel": "works_at", - "src": "user_faris" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "operates_in", - "src": "org_tidewatch_ops" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_faris" - } - ], - "task_id": "fixed_task_03", - "task_type": "fixed_trace" - }, - { - "answer": "user_ivy", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_05", - "support_nodes": 6 - }, - "question": "thr_port_audit discusses Black Kite and references Kestrel Works. Which alias_orchidfox user authored post_midnight_manifest and collaborates on Black Kite?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "discusses", - "src": "thr_port_audit" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "references", - "src": "thr_port_audit" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_ivy" - } - ], - "task_id": "fixed_task_04", - "task_type": "fixed_trace" - }, - { - "answer": "user_kian", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_06", - "support_nodes": 5 - }, - "question": "Which Atlas Freight user behind alias_lanternmoth authored post_quay_ledgers and collaborates on event_glass_harbor?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_kian" - } - ], - "task_id": "fixed_task_05", - "task_type": "fixed_trace" - }, - { - "answer": "user_mika", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_07", - "support_nodes": 5 - }, - "question": "Which Orion Customs user behind alias_basinraven authored post_customs_tag and collaborates on event_iron_wharf?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "post_customs_tag", - "rel": "authored_post", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_mika" - }, - { - "confidence": 0.9, - "dst": "event_iron_wharf", - "rel": "collaborates_on", - "src": "user_mika" - } - ], - "task_id": "fixed_task_06", - "task_type": "fixed_trace" - }, - { - "answer": "user_nora", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_08", - "support_nodes": 5 - }, - "question": "Which user behind alias_emberglass posted basin_photo from Foundry Row and investigates Amber Veil?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "post_basin_photo", - "rel": "authored_post", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 0.9, - "dst": "event_amber_veil", - "rel": "investigates", - "src": "user_nora" - } - ], - "task_id": "fixed_task_07", - "task_type": "fixed_trace" - }, - { - "answer": "user_soren", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_09", - "support_nodes": 4 - }, - "question": "Which user behind alias_tideshard authored post_hull_signal and collaborates on Ghost Signal?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "post_hull_signal", - "rel": "authored_post", - "src": "alias_tideshard" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "collaborates_on", - "src": "user_soren" - } - ], - "task_id": "fixed_task_08", - "task_type": "fixed_trace" - }, - { - "answer": "user_tara", - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_10", - "support_nodes": 5 - }, - "question": "Which Harborlight Transit user behind alias_sablekeel authored post_uplink_note and reports on Ghost Signal?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "post_uplink_note", - "rel": "authored_post", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_tara" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "reports_on", - "src": "user_tara" - } - ], - "task_id": "fixed_task_09", - "task_type": "fixed_trace" - }, - { - "answer": "org_northbridge_logistics", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_01", - "support_nodes": 17 - }, - "question": "Follow alias_docksparrow through post_shift_roster, Dockyard 17, and the Lantern chain. Return the org node id.", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "post_shift_roster", - "rel": "authored_post", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_shift_roster" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "post_shift_roster" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_hiro" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_hiro" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_bharat" - }, - { - "confidence": 0.95, - "dst": "user_hiro", - "rel": "connected_to", - "src": "user_bharat" - }, - { - "confidence": 0.92, - "dst": "user_faris", - "rel": "connected_to", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "references", - "src": "post_quay_ledgers" - } - ], - "task_id": "fixed_task_10", - "task_type": "fixed_trace" - }, - { - "answer": "user_kian", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_02", - "support_nodes": 17 - }, - "question": "Across the Glass Harbor cluster, which user behind alias_lanternmoth links to the Atlas Freight network from thr_quiet_manifest?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 1.0, - "dst": "thr_quiet_manifest", - "rel": "authored_thread", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "discusses", - "src": "thr_quiet_manifest" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "references", - "src": "thr_quiet_manifest" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_omar" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_omar" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "monitors", - "src": "user_priya" - }, - { - "confidence": 0.93, - "dst": "user_omar", - "rel": "connected_to", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "user_mika", - "rel": "connected_to", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "post_customs_tag", - "rel": "authored_post", - "src": "alias_basinraven" - } - ], - "task_id": "fixed_task_11", - "task_type": "fixed_trace" - }, - { - "answer": "user_mika", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_03", - "support_nodes": 17 - }, - "question": "Trace alias_basinraven through post_customs_tag, thr_customs_breach, and the Orion Customs collaboration chain. Who is it?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "post_customs_tag", - "rel": "authored_post", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "references", - "src": "post_customs_tag" - }, - { - "confidence": 1.0, - "dst": "event_iron_wharf", - "rel": "references", - "src": "post_customs_tag" - }, - { - "confidence": 1.0, - "dst": "thr_customs_breach", - "rel": "authored_thread", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "event_iron_wharf", - "rel": "discusses", - "src": "thr_customs_breach" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "references", - "src": "thr_customs_breach" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_quinn" - }, - { - "confidence": 0.9, - "dst": "event_iron_wharf", - "rel": "collaborates_on", - "src": "user_mika" - }, - { - "confidence": 0.9, - "dst": "event_iron_wharf", - "rel": "collaborates_on", - "src": "user_quinn" - }, - { - "confidence": 0.89, - "dst": "user_quinn", - "rel": "connected_to", - "src": "user_mika" - }, - { - "confidence": 0.88, - "dst": "user_nora", - "rel": "connected_to", - "src": "user_quinn" - }, - { - "confidence": 0.77, - "dst": "org_emberline_security", - "rel": "connected_to", - "src": "org_orion_customs" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - } - ], - "task_id": "fixed_task_12", - "task_type": "fixed_trace" - }, - { - "answer": "user_rhea", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_04", - "support_nodes": 18 - }, - "question": "In the Ember Tide and Amber Veil overlap, which Foundry Row user behind alias_cinderveil collaborates on Ember Tide?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "post_foundry_map", - "rel": "authored_post", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_foundry_map" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "references", - "src": "post_foundry_map" - }, - { - "confidence": 1.0, - "dst": "thr_foundry_watch", - "rel": "authored_thread", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "discusses", - "src": "thr_foundry_watch" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "references", - "src": "thr_foundry_watch" - }, - { - "confidence": 1.0, - "dst": "thr_ember_tide_watch", - "rel": "authored_thread", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "discusses", - "src": "thr_ember_tide_watch" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "thr_ember_tide_watch" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_nora" - }, - { - "confidence": 0.9, - "dst": "event_amber_veil", - "rel": "investigates", - "src": "user_nora" - }, - { - "confidence": 0.9, - "dst": "event_ember_tide", - "rel": "collaborates_on", - "src": "user_rhea" - }, - { - "confidence": 0.87, - "dst": "user_rhea", - "rel": "connected_to", - "src": "user_nora" - }, - { - "confidence": 0.77, - "dst": "event_ghost_signal", - "rel": "connected_to", - "src": "event_ember_tide" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - } - ], - "task_id": "fixed_task_13", - "task_type": "fixed_trace" - }, - { - "answer": "org_harborlight_transit", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_05", - "support_nodes": 17 - }, - "question": "Follow alias_tideshard from post_hull_signal into thr_uplink_route and the Harborlight relay. Return the org node id.", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "post_hull_signal", - "rel": "authored_post", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "post_hull_signal" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "references", - "src": "post_hull_signal" - }, - { - "confidence": 1.0, - "dst": "thr_uplink_route", - "rel": "authored_thread", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "discusses", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_tara" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "collaborates_on", - "src": "user_soren" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "reports_on", - "src": "user_tara" - }, - { - "confidence": 0.86, - "dst": "user_soren", - "rel": "connected_to", - "src": "user_rhea" - }, - { - "confidence": 0.86, - "dst": "user_tara", - "rel": "connected_to", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "operates_in", - "src": "org_harborlight_transit" - }, - { - "confidence": 0.77, - "dst": "org_tidewatch_ops", - "rel": "connected_to", - "src": "org_harborlight_transit" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - } - ], - "task_id": "fixed_task_14", - "task_type": "fixed_trace" - }, - { - "answer": "user_leena", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_06", - "support_nodes": 17 - }, - "question": "Which Sunmesh user behind alias_frostledger connects post_lantern_route to thr_relay_map and the Sector 9 monitoring chain?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "post_lantern_route", - "rel": "authored_post", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_lantern_route" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "references", - "src": "post_lantern_route" - }, - { - "confidence": 1.0, - "dst": "thr_relay_map", - "rel": "authored_thread", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_relay_map" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "references", - "src": "thr_relay_map" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "operates_in", - "src": "org_sunmesh_analytics" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "monitors", - "src": "user_leena" - }, - { - "confidence": 0.91, - "dst": "user_leena", - "rel": "connected_to", - "src": "user_priya" - }, - { - "confidence": 0.83, - "dst": "user_aria", - "rel": "connected_to", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "references", - "src": "post_quay_ledgers" - } - ], - "task_id": "fixed_task_15", - "task_type": "fixed_trace" - }, - { - "answer": "user_nora", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_07", - "support_nodes": 18 - }, - "question": "Which user behind alias_emberglass is tied to Amber Veil after combining post_basin_photo, thr_basin_shift, and the Foundry Row investigation chain?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "post_basin_photo", - "rel": "authored_post", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 1.0, - "dst": "event_amber_veil", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 1.0, - "dst": "thr_basin_shift", - "rel": "authored_thread", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "event_amber_veil", - "rel": "discusses", - "src": "thr_basin_shift" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "references", - "src": "thr_basin_shift" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_nora" - }, - { - "confidence": 0.9, - "dst": "event_amber_veil", - "rel": "investigates", - "src": "user_nora" - }, - { - "confidence": 0.88, - "dst": "user_nora", - "rel": "connected_to", - "src": "user_quinn" - }, - { - "confidence": 0.87, - "dst": "user_rhea", - "rel": "connected_to", - "src": "user_nora" - }, - { - "confidence": 0.77, - "dst": "org_emberline_security", - "rel": "connected_to", - "src": "org_orion_customs" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - } - ], - "task_id": "fixed_task_16", - "task_type": "fixed_trace" - }, - { - "answer": "user_ivy", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_08", - "support_nodes": 17 - }, - "question": "Combine alias_orchidfox, post_midnight_manifest, thr_supply_leak, and the Lantern to Glass Harbor bridge. Which user starts that chain?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_ivy" - }, - { - "confidence": 0.95, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.86, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.77, - "dst": "event_glass_harbor", - "rel": "connected_to", - "src": "event_project_lantern" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "monitors", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - } - ], - "task_id": "fixed_task_17", - "task_type": "fixed_trace" - }, - { - "answer": "user_diya", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_09", - "support_nodes": 18 - }, - "question": "Which user behind alias_monsoonbyte sits at the overlap of Blueharbor Media, Project Lantern, Black Kite, and the Ivy connection chain?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "post_drone_parts", - "rel": "authored_post", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "references", - "src": "post_drone_parts" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "thr_port_audit", - "rel": "authored_thread", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "discusses", - "src": "thr_port_audit" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_jules" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "investigates", - "src": "user_diya" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "reports_on", - "src": "user_jules" - }, - { - "confidence": 0.9, - "dst": "user_diya", - "rel": "connected_to", - "src": "user_faris" - }, - { - "confidence": 0.86, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - } - ], - "task_id": "fixed_task_18", - "task_type": "fixed_trace" - }, - { - "answer": "user_bharat", - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_10", - "support_nodes": 17 - }, - "question": "Who is the Northbridge user behind alias_steelquill when combining post_relay_schedule, thr_supply_leak, Dockyard 17, and Lantern collaborator edges?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "post_relay_schedule", - "rel": "authored_post", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_relay_schedule" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "references", - "src": "post_relay_schedule" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_hiro" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_bharat" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_hiro" - }, - { - "confidence": 0.95, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.95, - "dst": "user_hiro", - "rel": "connected_to", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "references", - "src": "post_quay_ledgers" - } - ], - "task_id": "fixed_task_19", - "task_type": "fixed_trace" - }, - { - "answer": "user_ivy", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_01", - "support_nodes": 50 - }, - "question": "Lantern to Glass Harbor handoff: identify the user behind alias_orchidfox after combining Lantern logistics, Dockyard links, and Atlas Freight bridge evidence.", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "located_in", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "located_in", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "operates_in", - "src": "org_northbridge_logistics" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "operates_in", - "src": "org_kestrel_works" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "operates_in", - "src": "org_atlas_freight" - }, - { - "confidence": 0.95, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.95, - "dst": "user_hiro", - "rel": "connected_to", - "src": "user_bharat" - }, - { - "confidence": 0.92, - "dst": "user_faris", - "rel": "connected_to", - "src": "user_hiro" - }, - { - "confidence": 0.86, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.93, - "dst": "user_omar", - "rel": "connected_to", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "user_mika", - "rel": "connected_to", - "src": "user_omar" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_bharat" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_hiro" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_faris" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_omar" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "monitors", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "thr_quiet_manifest", - "rel": "authored_thread", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "discusses", - "src": "thr_quiet_manifest" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "references", - "src": "thr_quiet_manifest" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 0.77, - "dst": "event_glass_harbor", - "rel": "connected_to", - "src": "event_project_lantern" - }, - { - "confidence": 0.77, - "dst": "org_northbridge_logistics", - "rel": "connected_to", - "src": "org_atlas_freight" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_cyrus" - } - ], - "task_id": "fixed_task_20", - "task_type": "fixed_trace" - }, - { - "answer": "user_mika", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_02", - "support_nodes": 50 - }, - "question": "North Basin to Foundry Row escalation: which user behind alias_basinraven anchors the Iron Wharf side before the Emberline handoff?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "post_customs_tag", - "rel": "authored_post", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "references", - "src": "post_customs_tag" - }, - { - "confidence": 1.0, - "dst": "event_iron_wharf", - "rel": "references", - "src": "post_customs_tag" - }, - { - "confidence": 1.0, - "dst": "thr_customs_breach", - "rel": "authored_thread", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "event_iron_wharf", - "rel": "discusses", - "src": "thr_customs_breach" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "references", - "src": "thr_customs_breach" - }, - { - "confidence": 1.0, - "dst": "thr_basin_shift", - "rel": "authored_thread", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "event_amber_veil", - "rel": "discusses", - "src": "thr_basin_shift" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "references", - "src": "thr_basin_shift" - }, - { - "confidence": 1.0, - "dst": "thr_foundry_watch", - "rel": "authored_thread", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "discusses", - "src": "thr_foundry_watch" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "references", - "src": "thr_foundry_watch" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "located_in", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "located_in", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "operates_in", - "src": "org_orion_customs" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "operates_in", - "src": "org_emberline_security" - }, - { - "confidence": 0.89, - "dst": "user_quinn", - "rel": "connected_to", - "src": "user_mika" - }, - { - "confidence": 0.88, - "dst": "user_nora", - "rel": "connected_to", - "src": "user_quinn" - }, - { - "confidence": 0.87, - "dst": "user_rhea", - "rel": "connected_to", - "src": "user_nora" - }, - { - "confidence": 0.9, - "dst": "event_iron_wharf", - "rel": "collaborates_on", - "src": "user_mika" - }, - { - "confidence": 0.9, - "dst": "event_iron_wharf", - "rel": "collaborates_on", - "src": "user_quinn" - }, - { - "confidence": 0.9, - "dst": "event_amber_veil", - "rel": "investigates", - "src": "user_nora" - }, - { - "confidence": 0.9, - "dst": "event_ember_tide", - "rel": "collaborates_on", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "post_basin_photo", - "rel": "authored_post", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 1.0, - "dst": "event_amber_veil", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 1.0, - "dst": "post_foundry_map", - "rel": "authored_post", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_foundry_map" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "references", - "src": "post_foundry_map" - }, - { - "confidence": 0.77, - "dst": "event_amber_veil", - "rel": "connected_to", - "src": "event_black_kite" - }, - { - "confidence": 0.77, - "dst": "event_ghost_signal", - "rel": "connected_to", - "src": "event_ember_tide" - }, - { - "confidence": 0.77, - "dst": "org_emberline_security", - "rel": "connected_to", - "src": "org_orion_customs" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 0.82, - "dst": "user_nora", - "rel": "connected_to", - "src": "user_priya" - }, - { - "confidence": 0.8, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - } - ], - "task_id": "fixed_task_21", - "task_type": "fixed_trace" - }, - { - "answer": "user_soren", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_03", - "support_nodes": 50 - }, - "question": "Harborlight ghost-signal relay: identify the user behind alias_tideshard at the Harborlight / Tidewatch junction.", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "post_hull_signal", - "rel": "authored_post", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "post_hull_signal" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "references", - "src": "post_hull_signal" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "post_uplink_note", - "rel": "authored_post", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "post_uplink_note" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "post_uplink_note" - }, - { - "confidence": 1.0, - "dst": "thr_uplink_route", - "rel": "authored_thread", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "discusses", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "thr_ghost_signal_net", - "rel": "authored_thread", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "discusses", - "src": "thr_ghost_signal_net" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "thr_ghost_signal_net" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "org_tidewatch_ops", - "rel": "works_at", - "src": "user_faris" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_faris" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "operates_in", - "src": "org_harborlight_transit" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "operates_in", - "src": "org_tidewatch_ops" - }, - { - "confidence": 0.86, - "dst": "user_soren", - "rel": "connected_to", - "src": "user_rhea" - }, - { - "confidence": 0.86, - "dst": "user_tara", - "rel": "connected_to", - "src": "user_soren" - }, - { - "confidence": 0.84, - "dst": "user_kian", - "rel": "connected_to", - "src": "user_tara" - }, - { - "confidence": 0.79, - "dst": "user_faris", - "rel": "connected_to", - "src": "user_soren" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_faris" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "collaborates_on", - "src": "user_soren" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "reports_on", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "post_sat_phone_ping", - "rel": "authored_post", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "references", - "src": "post_sat_phone_ping" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_sat_phone_ping" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_supply_leak" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_bharat" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_hiro" - }, - { - "confidence": 0.77, - "dst": "event_ghost_signal", - "rel": "connected_to", - "src": "event_ember_tide" - }, - { - "confidence": 0.77, - "dst": "org_tidewatch_ops", - "rel": "connected_to", - "src": "org_harborlight_transit" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_bharat" - } - ], - "task_id": "fixed_task_22", - "task_type": "fixed_trace" - }, - { - "answer": "user_diya", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_04", - "support_nodes": 50 - }, - "question": "Blueharbor to Black Kite to Lantern overlap: which user is the Blueharbor origin behind alias_monsoonbyte?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "post_drone_parts", - "rel": "authored_post", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "references", - "src": "post_drone_parts" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "references", - "src": "post_drone_parts" - }, - { - "confidence": 1.0, - "dst": "thr_port_audit", - "rel": "authored_thread", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "discusses", - "src": "thr_port_audit" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "references", - "src": "thr_port_audit" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "operates_in", - "src": "org_blueharbor_media" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "operates_in", - "src": "org_kestrel_works" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "operates_in", - "src": "org_apex_dynamics" - }, - { - "confidence": 0.9, - "dst": "user_diya", - "rel": "connected_to", - "src": "user_faris" - }, - { - "confidence": 0.83, - "dst": "user_gita", - "rel": "connected_to", - "src": "user_cyrus" - }, - { - "confidence": 0.82, - "dst": "user_jules", - "rel": "connected_to", - "src": "user_gita" - }, - { - "confidence": 0.86, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "investigates", - "src": "user_diya" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_ivy" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_cyrus" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "investigates", - "src": "user_elin" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "reports_on", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 0.77, - "dst": "event_glass_harbor", - "rel": "connected_to", - "src": "event_project_lantern" - }, - { - "confidence": 0.77, - "dst": "event_amber_veil", - "rel": "connected_to", - "src": "event_black_kite" - }, - { - "confidence": 1.0, - "dst": "thr_relay_map", - "rel": "authored_thread", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_relay_map" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_leena" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "monitors", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - } - ], - "task_id": "fixed_task_23", - "task_type": "fixed_trace" - }, - { - "answer": "user_bharat", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_05", - "support_nodes": 50 - }, - "question": "Sector 9 to Dockyard 17 full relay: which user behind alias_steelquill links the Northbridge chain and the Sunmesh monitoring bridge?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "post_relay_schedule", - "rel": "authored_post", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_relay_schedule" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "references", - "src": "post_relay_schedule" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "post_lantern_route", - "rel": "authored_post", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "references", - "src": "post_lantern_route" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "references", - "src": "post_lantern_route" - }, - { - "confidence": 1.0, - "dst": "thr_relay_map", - "rel": "authored_thread", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_relay_map" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "references", - "src": "thr_relay_map" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "event_project_lantern", - "rel": "discusses", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "operates_in", - "src": "org_northbridge_logistics" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "operates_in", - "src": "org_sunmesh_analytics" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "operates_in", - "src": "org_helios_labs" - }, - { - "confidence": 0.95, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.95, - "dst": "user_hiro", - "rel": "connected_to", - "src": "user_bharat" - }, - { - "confidence": 0.89, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_diya" - }, - { - "confidence": 0.87, - "dst": "user_aria", - "rel": "connected_to", - "src": "user_elin" - }, - { - "confidence": 0.84, - "dst": "user_cyrus", - "rel": "connected_to", - "src": "user_aria" - }, - { - "confidence": 0.91, - "dst": "user_leena", - "rel": "connected_to", - "src": "user_priya" - }, - { - "confidence": 0.83, - "dst": "user_aria", - "rel": "connected_to", - "src": "user_leena" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_bharat" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_hiro" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "monitors", - "src": "user_leena" - }, - { - "confidence": 0.77, - "dst": "event_glass_harbor", - "rel": "connected_to", - "src": "event_project_lantern" - }, - { - "confidence": 0.77, - "dst": "org_northbridge_logistics", - "rel": "connected_to", - "src": "org_atlas_freight" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_elin" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_elin" - }, - { - "confidence": 1.0, - "dst": "org_tidewatch_ops", - "rel": "works_at", - "src": "user_faris" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_faris" - } - ], - "task_id": "fixed_task_24", - "task_type": "fixed_trace" - }, - { - "answer": "user_nora", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_06", - "support_nodes": 50 - }, - "question": "Foundry Row, North Basin, and Uplink Yard spread: identify the user behind alias_emberglass before the Harborlight relay takes over.", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "post_basin_photo", - "rel": "authored_post", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 1.0, - "dst": "event_amber_veil", - "rel": "references", - "src": "post_basin_photo" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "post_foundry_map", - "rel": "authored_post", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "post_foundry_map" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "references", - "src": "post_foundry_map" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "post_uplink_note", - "rel": "authored_post", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "post_uplink_note" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "post_uplink_note" - }, - { - "confidence": 1.0, - "dst": "thr_foundry_watch", - "rel": "authored_thread", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "discusses", - "src": "thr_foundry_watch" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "references", - "src": "thr_foundry_watch" - }, - { - "confidence": 1.0, - "dst": "thr_ember_tide_watch", - "rel": "authored_thread", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "discusses", - "src": "thr_ember_tide_watch" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "thr_ember_tide_watch" - }, - { - "confidence": 1.0, - "dst": "thr_uplink_route", - "rel": "authored_thread", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "discusses", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "operates_in", - "src": "org_emberline_security" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "operates_in", - "src": "org_harborlight_transit" - }, - { - "confidence": 0.87, - "dst": "user_rhea", - "rel": "connected_to", - "src": "user_nora" - }, - { - "confidence": 0.86, - "dst": "user_soren", - "rel": "connected_to", - "src": "user_rhea" - }, - { - "confidence": 0.86, - "dst": "user_tara", - "rel": "connected_to", - "src": "user_soren" - }, - { - "confidence": 0.9, - "dst": "event_amber_veil", - "rel": "investigates", - "src": "user_nora" - }, - { - "confidence": 0.9, - "dst": "event_ember_tide", - "rel": "collaborates_on", - "src": "user_rhea" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "collaborates_on", - "src": "user_soren" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "reports_on", - "src": "user_tara" - }, - { - "confidence": 0.77, - "dst": "event_ghost_signal", - "rel": "connected_to", - "src": "event_ember_tide" - }, - { - "confidence": 0.77, - "dst": "org_tidewatch_ops", - "rel": "connected_to", - "src": "org_harborlight_transit" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - } - ], - "task_id": "fixed_task_25", - "task_type": "fixed_trace" - }, - { - "answer": "user_kian", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_07", - "support_nodes": 50 - }, - "question": "Freight and customs bridge: which Atlas Freight user behind alias_lanternmoth connects Glass Harbor with the Northbridge chain?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "post_quay_ledgers", - "rel": "authored_post", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "references", - "src": "post_quay_ledgers" - }, - { - "confidence": 1.0, - "dst": "thr_quiet_manifest", - "rel": "authored_thread", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "event_glass_harbor", - "rel": "discusses", - "src": "thr_quiet_manifest" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "references", - "src": "thr_quiet_manifest" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "located_in", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "located_in", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "operates_in", - "src": "org_atlas_freight" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "operates_in", - "src": "org_northbridge_logistics" - }, - { - "confidence": 0.93, - "dst": "user_omar", - "rel": "connected_to", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "user_mika", - "rel": "connected_to", - "src": "user_omar" - }, - { - "confidence": 0.8, - "dst": "user_bharat", - "rel": "connected_to", - "src": "user_kian" - }, - { - "confidence": 0.95, - "dst": "user_hiro", - "rel": "connected_to", - "src": "user_bharat" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_kian" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "collaborates_on", - "src": "user_omar" - }, - { - "confidence": 0.9, - "dst": "event_glass_harbor", - "rel": "monitors", - "src": "user_priya" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_bharat" - }, - { - "confidence": 0.9, - "dst": "event_project_lantern", - "rel": "collaborates_on", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "post_shift_roster", - "rel": "authored_post", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_shift_roster" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "post_shift_roster" - }, - { - "confidence": 1.0, - "dst": "post_midnight_manifest", - "rel": "authored_post", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "references", - "src": "post_midnight_manifest" - }, - { - "confidence": 1.0, - "dst": "thr_supply_leak", - "rel": "authored_thread", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "references", - "src": "thr_supply_leak" - }, - { - "confidence": 0.77, - "dst": "org_northbridge_logistics", - "rel": "connected_to", - "src": "org_atlas_freight" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_elin" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_elin" - }, - { - "confidence": 1.0, - "dst": "org_tidewatch_ops", - "rel": "works_at", - "src": "user_faris" - } - ], - "task_id": "fixed_task_26", - "task_type": "fixed_trace" - }, - { - "answer": "user_cyrus", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_08", - "support_nodes": 50 - }, - "question": "Black Kite, Amber Veil, and Iron Wharf overlap: which user behind alias_quartzlotus is the Apex-side collaborator?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "operates_in", - "src": "org_apex_dynamics" - }, - { - "confidence": 0.9, - "dst": "event_black_kite", - "rel": "collaborates_on", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "thr_port_audit", - "rel": "authored_thread", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "discusses", - "src": "thr_port_audit" - }, - { - "confidence": 1.0, - "dst": "post_drone_parts", - "rel": "authored_post", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "event_black_kite", - "rel": "references", - "src": "post_drone_parts" - }, - { - "confidence": 0.9, - "dst": "event_amber_veil", - "rel": "investigates", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "thr_basin_shift", - "rel": "authored_thread", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "event_amber_veil", - "rel": "discusses", - "src": "thr_basin_shift" - }, - { - "confidence": 0.9, - "dst": "event_iron_wharf", - "rel": "collaborates_on", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "thr_customs_breach", - "rel": "authored_thread", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "event_iron_wharf", - "rel": "discusses", - "src": "thr_customs_breach" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "located_in", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "located_in", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "operates_in", - "src": "org_kestrel_works" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "operates_in", - "src": "org_emberline_security" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "operates_in", - "src": "org_orion_customs" - }, - { - "confidence": 0.83, - "dst": "user_gita", - "rel": "connected_to", - "src": "user_cyrus" - }, - { - "confidence": 0.86, - "dst": "user_elin", - "rel": "connected_to", - "src": "user_ivy" - }, - { - "confidence": 0.89, - "dst": "user_quinn", - "rel": "connected_to", - "src": "user_mika" - }, - { - "confidence": 0.88, - "dst": "user_nora", - "rel": "connected_to", - "src": "user_quinn" - }, - { - "confidence": 0.87, - "dst": "user_rhea", - "rel": "connected_to", - "src": "user_nora" - }, - { - "confidence": 0.77, - "dst": "event_amber_veil", - "rel": "connected_to", - "src": "event_black_kite" - }, - { - "confidence": 0.77, - "dst": "org_emberline_security", - "rel": "connected_to", - "src": "org_orion_customs" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - } - ], - "task_id": "fixed_task_27", - "task_type": "fixed_trace" - }, - { - "answer": "user_tara", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_09", - "support_nodes": 50 - }, - "question": "Ghost Signal and Ember Tide relay: which user behind alias_sablekeel is the Harborlight reporting endpoint?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "post_uplink_note", - "rel": "authored_post", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "post_uplink_note" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "post_uplink_note" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "post_hull_signal", - "rel": "authored_post", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "post_hull_signal" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "references", - "src": "post_hull_signal" - }, - { - "confidence": 1.0, - "dst": "thr_ghost_signal_net", - "rel": "authored_thread", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "discusses", - "src": "thr_ghost_signal_net" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "references", - "src": "thr_ghost_signal_net" - }, - { - "confidence": 1.0, - "dst": "thr_uplink_route", - "rel": "authored_thread", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "event_ghost_signal", - "rel": "discusses", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "references", - "src": "thr_uplink_route" - }, - { - "confidence": 1.0, - "dst": "thr_ember_tide_watch", - "rel": "authored_thread", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "event_ember_tide", - "rel": "discusses", - "src": "thr_ember_tide_watch" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "references", - "src": "thr_ember_tide_watch" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "operates_in", - "src": "org_harborlight_transit" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "operates_in", - "src": "org_emberline_security" - }, - { - "confidence": 0.86, - "dst": "user_soren", - "rel": "connected_to", - "src": "user_rhea" - }, - { - "confidence": 0.86, - "dst": "user_tara", - "rel": "connected_to", - "src": "user_soren" - }, - { - "confidence": 0.87, - "dst": "user_rhea", - "rel": "connected_to", - "src": "user_nora" - }, - { - "confidence": 0.9, - "dst": "event_ember_tide", - "rel": "collaborates_on", - "src": "user_rhea" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "collaborates_on", - "src": "user_soren" - }, - { - "confidence": 0.9, - "dst": "event_ghost_signal", - "rel": "reports_on", - "src": "user_tara" - }, - { - "confidence": 0.77, - "dst": "event_ghost_signal", - "rel": "connected_to", - "src": "event_ember_tide" - }, - { - "confidence": 0.77, - "dst": "org_tidewatch_ops", - "rel": "connected_to", - "src": "org_harborlight_transit" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_cyrus" - } - ], - "task_id": "fixed_task_28", - "task_type": "fixed_trace" - }, - { - "answer": "user_priya", - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_10", - "support_nodes": 55 - }, - "question": "End-to-end benchmark sweep: across Lantern, Black Kite, Glass Harbor, Iron Wharf, Ember Tide, and Ghost Signal, which user behind alias_hollowsignal anchors the Sunmesh monitoring side?", - "supporting_edges": [ - { - "confidence": 1.0, - "dst": "user_ivy", - "rel": "alias_of", - "src": "alias_orchidfox" - }, - { - "confidence": 1.0, - "dst": "user_bharat", - "rel": "alias_of", - "src": "alias_steelquill" - }, - { - "confidence": 1.0, - "dst": "user_diya", - "rel": "alias_of", - "src": "alias_monsoonbyte" - }, - { - "confidence": 1.0, - "dst": "user_faris", - "rel": "alias_of", - "src": "alias_nightrelay" - }, - { - "confidence": 1.0, - "dst": "user_elin", - "rel": "alias_of", - "src": "alias_mapleghost" - }, - { - "confidence": 1.0, - "dst": "user_hiro", - "rel": "alias_of", - "src": "alias_docksparrow" - }, - { - "confidence": 1.0, - "dst": "user_cyrus", - "rel": "alias_of", - "src": "alias_quartzlotus" - }, - { - "confidence": 1.0, - "dst": "user_nora", - "rel": "alias_of", - "src": "alias_emberglass" - }, - { - "confidence": 1.0, - "dst": "user_mika", - "rel": "alias_of", - "src": "alias_basinraven" - }, - { - "confidence": 1.0, - "dst": "user_soren", - "rel": "alias_of", - "src": "alias_tideshard" - }, - { - "confidence": 1.0, - "dst": "user_priya", - "rel": "alias_of", - "src": "alias_hollowsignal" - }, - { - "confidence": 1.0, - "dst": "user_omar", - "rel": "alias_of", - "src": "alias_ironwhisper" - }, - { - "confidence": 1.0, - "dst": "user_rhea", - "rel": "alias_of", - "src": "alias_cinderveil" - }, - { - "confidence": 1.0, - "dst": "user_tara", - "rel": "alias_of", - "src": "alias_sablekeel" - }, - { - "confidence": 1.0, - "dst": "user_kian", - "rel": "alias_of", - "src": "alias_lanternmoth" - }, - { - "confidence": 1.0, - "dst": "user_leena", - "rel": "alias_of", - "src": "alias_frostledger" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_aria" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_bharat" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_cyrus" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_diya" - }, - { - "confidence": 1.0, - "dst": "org_helios_labs", - "rel": "works_at", - "src": "user_elin" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_elin" - }, - { - "confidence": 1.0, - "dst": "org_tidewatch_ops", - "rel": "works_at", - "src": "user_faris" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_faris" - }, - { - "confidence": 1.0, - "dst": "org_apex_dynamics", - "rel": "works_at", - "src": "user_gita" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_gita" - }, - { - "confidence": 1.0, - "dst": "org_northbridge_logistics", - "rel": "works_at", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "located_in", - "src": "user_hiro" - }, - { - "confidence": 1.0, - "dst": "org_kestrel_works", - "rel": "works_at", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "loc_rivergate", - "rel": "located_in", - "src": "user_ivy" - }, - { - "confidence": 1.0, - "dst": "org_blueharbor_media", - "rel": "works_at", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "loc_old_town", - "rel": "located_in", - "src": "user_jules" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "located_in", - "src": "user_kian" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_leena" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "located_in", - "src": "user_mika" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_nora" - }, - { - "confidence": 1.0, - "dst": "org_atlas_freight", - "rel": "works_at", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "loc_east_quay", - "rel": "located_in", - "src": "user_omar" - }, - { - "confidence": 1.0, - "dst": "org_sunmesh_analytics", - "rel": "works_at", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "located_in", - "src": "user_priya" - }, - { - "confidence": 1.0, - "dst": "org_orion_customs", - "rel": "works_at", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "loc_north_basin", - "rel": "located_in", - "src": "user_quinn" - }, - { - "confidence": 1.0, - "dst": "org_emberline_security", - "rel": "works_at", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "loc_foundry_row", - "rel": "located_in", - "src": "user_rhea" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_soren" - }, - { - "confidence": 1.0, - "dst": "org_harborlight_transit", - "rel": "works_at", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "loc_uplink_yard", - "rel": "located_in", - "src": "user_tara" - }, - { - "confidence": 1.0, - "dst": "loc_sector9", - "rel": "operates_in", - "src": "org_helios_labs" - }, - { - "confidence": 1.0, - "dst": "loc_dockyard17", - "rel": "operates_in", - "src": "org_northbridge_logistics" - } - ], - "task_id": "fixed_task_29", - "task_type": "fixed_trace" - } - ], - "source_seed": "datasets\\fixed_levels\\seed_fixed_levels.json" -} \ No newline at end of file diff --git a/scratch/osint/datasets/fixed_levels/leaderboard_fixed_levels.json b/scratch/osint/datasets/fixed_levels/leaderboard_fixed_levels.json deleted file mode 100644 index 7dcfddf5da4fa1239db03d19ee90ea3665e09ef9..0000000000000000000000000000000000000000 --- a/scratch/osint/datasets/fixed_levels/leaderboard_fixed_levels.json +++ /dev/null @@ -1,1229 +0,0 @@ -[ - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 20, - "max_width": 2, - "seed": 2026, - "seeded_questions": 15, - "swarm_enabled": true - }, - "created_at": "2026-04-01T18:48:39+00:00", - "episodes": 15, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.16666666666666666, - "avg_connectivity_reward": 0.16999999999999998, - "avg_diversity_reward": 0.1157777777777778, - "avg_entity_informativeness_reward": -0.08858065677817137, - "avg_format_reward": 0.14999999999999997, - "avg_graph_f1": 0.8492063492063492, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.052000000000000005, - "avg_relation_informativeness_reward": 0.07135858524047924, - "avg_reward": 4.197526826881651, - "avg_soft_shaping_reward": 0.24999999999999994, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 1.0, - "leaderboard_score": 0.8543934355282199, - "retrieval_signal": 0.6932, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5730889190257948, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0001", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-02T09:16:05+00:00", - "episodes": 30, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.2000000000000001, - "avg_connectivity_reward": 0.12999999999999998, - "avg_diversity_reward": 0.12433333333333325, - "avg_entity_informativeness_reward": 0.000700571890338102, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.2916528337385394, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.05070078042510192, - "avg_relation_informativeness_reward": 0.07853375358885142, - "avg_reward": 4.377456514967488, - "avg_soft_shaping_reward": 0.3, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6241912131110795, - "retrieval_signal": 0.6927452731487858, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5869968650958378, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0002", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-03T13:22:03+00:00", - "episodes": 3, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.20000000000000004, - "avg_connectivity_reward": -0.06666666666666667, - "avg_diversity_reward": 0.13444444444444445, - "avg_entity_informativeness_reward": -0.01010882862863417, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.5793650793650794, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.10372960372960373, - "avg_relation_informativeness_reward": 0.07108687894082726, - "avg_reward": 4.419313576918165, - "avg_soft_shaping_reward": 0.3, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6797400780463063, - "retrieval_signal": 0.7113053613053614, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5356956100624386, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0003", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-06T18:29:39+00:00", - "episodes": 30, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.2000000000000001, - "avg_connectivity_reward": 0.12999999999999998, - "avg_diversity_reward": 0.12433333333333325, - "avg_entity_informativeness_reward": -0.02515191749984708, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.2916528337385394, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.11539120363588044, - "avg_relation_informativeness_reward": 0.0769903534735767, - "avg_reward": 4.460667345528021, - "avg_soft_shaping_reward": 0.3, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6269168609961595, - "retrieval_signal": 0.7153869212725582, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5815176871947458, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0004", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-06T18:33:06+00:00", - "episodes": 2, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.2, - "avg_connectivity_reward": -0.15, - "avg_diversity_reward": 0.13833333333333334, - "avg_entity_informativeness_reward": -0.026628229842114173, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.6190476190476191, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.10681818181818181, - "avg_relation_informativeness_reward": 0.048120982127120335, - "avg_reward": 4.334953339016039, - "avg_soft_shaping_reward": 0.3, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.685242999396977, - "retrieval_signal": 0.7123863636363637, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5075485504570012, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0005", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "max_agents": 1, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-06T18:54:52+00:00", - "episodes": 1, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.1, - "avg_connectivity_reward": -0.3, - "avg_diversity_reward": 0.08, - "avg_entity_informativeness_reward": -0.02450859227728558, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.33333333333333337, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.08181818181818182, - "avg_relation_informativeness_reward": 0.04353540016904645, - "avg_reward": 3.037246438342494, - "avg_soft_shaping_reward": 0.15, - "avg_spawn_count": 2.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 5.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6201263424948862, - "retrieval_signal": 0.7036363636363637, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.45080536157835216, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0006", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "max_agents": 1, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-06T19:22:57+00:00", - "episodes": 1, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.1, - "avg_connectivity_reward": -0.3, - "avg_diversity_reward": 0.08, - "avg_entity_informativeness_reward": -0.005263146336646693, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.33333333333333337, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.08181818181818182, - "avg_relation_informativeness_reward": 0.044276243254877785, - "avg_reward": 3.057232727368964, - "avg_soft_shaping_reward": 0.15, - "avg_spawn_count": 2.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 5.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6205293479318178, - "retrieval_signal": 0.7036363636363637, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.4548026193836462, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0007", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "qwen3:1.7b", - "llm_provider": "ollama", - "max_agents": 1, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-06T19:48:33+00:00", - "episodes": 3, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.10000000000000002, - "avg_connectivity_reward": -0.09999999999999999, - "avg_diversity_reward": 0.08, - "avg_entity_informativeness_reward": -0.028683816517602444, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.15537340619307835, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.07932190760059611, - "avg_relation_informativeness_reward": 0.044225025032092045, - "avg_reward": 3.1324990406542437, - "avg_soft_shaping_reward": 0.15, - "avg_spawn_count": 2.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 5.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.5890485416309927, - "retrieval_signal": 0.7027626676602087, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5001082417028979, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0008", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "qwen3:1.7b", - "llm_provider": "ollama", - "max_agents": 1, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-06T19:55:08+00:00", - "episodes": 1, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.1, - "avg_connectivity_reward": -0.3, - "avg_diversity_reward": 0.08, - "avg_entity_informativeness_reward": -0.005263146336646693, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.33333333333333337, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.08181818181818182, - "avg_relation_informativeness_reward": 0.04406984773661544, - "avg_reward": 3.0570263318507016, - "avg_soft_shaping_reward": 0.15, - "avg_spawn_count": 2.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 5.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6205251901591228, - "retrieval_signal": 0.7036363636363637, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.45476134027999376, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0009", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "qwen3:1.7b", - "llm_provider": "ollama", - "max_agents": 1, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-06T20:01:34+00:00", - "episodes": 1, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.1, - "avg_connectivity_reward": -0.3, - "avg_diversity_reward": 0.08, - "avg_entity_informativeness_reward": -0.020826953461399098, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.33333333333333337, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.08181818181818182, - "avg_relation_informativeness_reward": 0.04348043923536236, - "avg_reward": 3.040873116224696, - "avg_soft_shaping_reward": 0.15, - "avg_spawn_count": 2.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 5.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6201995296517067, - "retrieval_signal": 0.7036363636363637, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.45153069715479266, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0010", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-06T20:46:11+00:00", - "episodes": 1, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.2, - "avg_connectivity_reward": -0.15, - "avg_diversity_reward": 0.12666666666666665, - "avg_entity_informativeness_reward": 0.019629386278697845, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.5714285714285715, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.12272727272727273, - "avg_relation_informativeness_reward": 0.08347928023822283, - "avg_reward": 1.829702015111513, - "avg_soft_shaping_reward": 0.3, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6715432845394145, - "retrieval_signal": 0.7179545454545455, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5221217333033842, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0011", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-06T20:49:44+00:00", - "episodes": 1, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.2, - "avg_connectivity_reward": -0.15, - "avg_diversity_reward": 0.12666666666666665, - "avg_entity_informativeness_reward": 0.019629386278697845, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.5714285714285715, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.12272727272727273, - "avg_relation_informativeness_reward": 0.08335372627068136, - "avg_reward": 0.7139904233885594, - "avg_soft_shaping_reward": 0.3, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6641542345113342, - "retrieval_signal": 0.7179545454545455, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5220966225098759, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0012", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-06T20:59:43+00:00", - "episodes": 1, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.2, - "avg_connectivity_reward": -0.15, - "avg_diversity_reward": 0.12666666666666665, - "avg_entity_informativeness_reward": 0.0036675120354726642, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.5714285714285715, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.12272727272727273, - "avg_relation_informativeness_reward": 0.08250745620050208, - "avg_reward": 0.7138056720677886, - "avg_soft_shaping_reward": 0.3, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6638424503476543, - "retrieval_signal": 0.7179545454545455, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.518734993647195, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0013", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "gpt-5.4-mini", - "llm_provider": "openai", - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-07T09:44:40+00:00", - "episodes": 1, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.2, - "avg_connectivity_reward": -0.15, - "avg_diversity_reward": 0.12666666666666665, - "avg_entity_informativeness_reward": -0.018704290877944903, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.5714285714285715, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.12272727272727273, - "avg_relation_informativeness_reward": 0.08056039127695382, - "avg_reward": 0.7135379106634446, - "avg_soft_shaping_reward": 0.3, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6633913226563717, - "retrieval_signal": 0.7179545454545455, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5138712200798018, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0014", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "gpt-5.4-mini", - "llm_provider": "openai", - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-07T09:55:19+00:00", - "episodes": 1, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.2, - "avg_connectivity_reward": -0.15, - "avg_diversity_reward": 0.12666666666666665, - "avg_entity_informativeness_reward": -0.018704290877944903, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.5714285714285715, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.12272727272727273, - "avg_relation_informativeness_reward": 0.08056039127695382, - "avg_reward": 0.7135379106634446, - "avg_soft_shaping_reward": 0.3, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6633913226563717, - "retrieval_signal": 0.7179545454545455, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5138712200798018, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0015", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "gpt-5.4-mini", - "llm_provider": "openai", - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-07T09:56:28+00:00", - "episodes": 30, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.2000000000000001, - "avg_connectivity_reward": 0.12999999999999998, - "avg_diversity_reward": 0.12433333333333325, - "avg_entity_informativeness_reward": -0.02515191749984708, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.2916528337385394, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.11539120363588044, - "avg_relation_informativeness_reward": 0.0769903534735767, - "avg_reward": 0.7150555461096118, - "avg_soft_shaping_reward": 0.3, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6132407715455404, - "retrieval_signal": 0.7153869212725582, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5815176871947458, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0016", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "gpt-5.4-mini", - "llm_provider": "openai", - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-07T10:02:32+00:00", - "episodes": 1, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.2, - "avg_connectivity_reward": -0.15, - "avg_diversity_reward": 0.12666666666666665, - "avg_entity_informativeness_reward": -0.018704290877944903, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.5714285714285715, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.12272727272727273, - "avg_relation_informativeness_reward": 0.08056039127695382, - "avg_reward": 0.7135379106634446, - "avg_soft_shaping_reward": 0.3, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6633913226563717, - "retrieval_signal": 0.7179545454545455, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5138712200798018, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0017", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "gpt-5.4-mini", - "llm_provider": "openai", - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-07T10:02:49+00:00", - "episodes": 3, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.20000000000000004, - "avg_connectivity_reward": -0.06666666666666667, - "avg_diversity_reward": 0.13444444444444445, - "avg_entity_informativeness_reward": -0.029992009599206938, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.5793650793650794, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.10372960372960373, - "avg_relation_informativeness_reward": 0.06898843512226, - "avg_reward": 0.7133699465240085, - "avg_soft_shaping_reward": 0.3, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6656078661080486, - "retrieval_signal": 0.7113053613053614, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5312992851046106, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0018", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "gpt-5.4-mini", - "llm_provider": "openai", - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-07T10:04:53+00:00", - "episodes": 3, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.20000000000000004, - "avg_connectivity_reward": -0.06666666666666667, - "avg_diversity_reward": 0.13444444444444445, - "avg_entity_informativeness_reward": -0.029992009599206938, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.5793650793650794, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.10372960372960373, - "avg_relation_informativeness_reward": 0.06898843512226, - "avg_reward": 0.7133699465240085, - "avg_soft_shaping_reward": 0.3, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6656078661080486, - "retrieval_signal": 0.7113053613053614, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5312992851046106, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0019", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "gpt-5.4-mini", - "llm_provider": "openai", - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-07T10:11:34+00:00", - "episodes": 3, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.20000000000000004, - "avg_connectivity_reward": -0.06666666666666667, - "avg_diversity_reward": 0.13444444444444445, - "avg_entity_informativeness_reward": -0.029992009599206938, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.5793650793650794, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.10372960372960373, - "avg_relation_informativeness_reward": 0.06898843512226, - "avg_reward": 0.7133699465240085, - "avg_soft_shaping_reward": 0.3, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.6656078661080486, - "retrieval_signal": 0.7113053613053614, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5312992851046106, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0020", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "gpt-5.4-mini", - "llm_provider": "openai", - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-07T10:29:54+00:00", - "episodes": 3, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.0, - "avg_connectivity_reward": 0.0, - "avg_diversity_reward": 0.0, - "avg_entity_informativeness_reward": 0.0, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.0, - "avg_knowledge_carrier_reward": 0.0, - "avg_knowledge_indexing_reward": 0.0, - "avg_relation_informativeness_reward": 0.0, - "avg_reward": 0.5519400198339021, - "avg_soft_shaping_reward": 0.0, - "avg_spawn_count": 0.0, - "avg_spawn_critical_steps": 0.0, - "avg_steps_to_solution": 1.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.2785970009916951, - "retrieval_signal": 0.5, - "spawn_completion_rate": 0.0, - "spawn_signal": 0.4, - "structural_signal": 0.5, - "task_success_rate": 0.0, - "tool_efficiency": 1.0 - }, - "run_id": "run_0021", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "gpt-5.4-mini", - "llm_provider": "openai", - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-07T15:59:20+00:00", - "episodes": 1, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.0, - "avg_connectivity_reward": 0.0, - "avg_diversity_reward": 0.0, - "avg_entity_informativeness_reward": 0.0, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.0, - "avg_knowledge_carrier_reward": 0.0, - "avg_knowledge_indexing_reward": 0.0, - "avg_relation_informativeness_reward": 0.0, - "avg_reward": 0.5519400198339021, - "avg_soft_shaping_reward": 0.0, - "avg_spawn_count": 0.0, - "avg_spawn_critical_steps": 0.0, - "avg_steps_to_solution": 1.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.2785970009916951, - "retrieval_signal": 0.5, - "spawn_completion_rate": 0.0, - "spawn_signal": 0.4, - "structural_signal": 0.5, - "task_success_rate": 0.0, - "tool_efficiency": 1.0 - }, - "run_id": "run_0022", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "gpt-5.4-mini", - "llm_provider": "openai", - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-08T04:25:00+00:00", - "episodes": 1, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.0, - "avg_connectivity_reward": 0.0, - "avg_diversity_reward": 0.0, - "avg_entity_informativeness_reward": 0.0, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.0, - "avg_knowledge_carrier_reward": 0.0, - "avg_knowledge_indexing_reward": 0.0, - "avg_relation_informativeness_reward": 0.0, - "avg_reward": 0.5519400198339021, - "avg_soft_shaping_reward": 0.0, - "avg_spawn_count": 0.0, - "avg_spawn_critical_steps": 0.0, - "avg_steps_to_solution": 1.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.2785970009916951, - "retrieval_signal": 0.5, - "spawn_completion_rate": 0.0, - "spawn_signal": 0.4, - "structural_signal": 0.5, - "task_success_rate": 0.0, - "tool_efficiency": 1.0 - }, - "run_id": "run_0023", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "gpt-5.4-mini", - "llm_provider": "openai", - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-08T04:28:07+00:00", - "episodes": 1, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.0, - "avg_connectivity_reward": 0.0, - "avg_diversity_reward": 0.0, - "avg_entity_informativeness_reward": 0.0, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.0, - "avg_knowledge_carrier_reward": 0.0, - "avg_knowledge_indexing_reward": 0.0, - "avg_relation_informativeness_reward": 0.0, - "avg_reward": 0.5519400198339021, - "avg_soft_shaping_reward": 0.0, - "avg_spawn_count": 0.0, - "avg_spawn_critical_steps": 0.0, - "avg_steps_to_solution": 1.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.2785970009916951, - "retrieval_signal": 0.5, - "spawn_completion_rate": 0.0, - "spawn_signal": 0.4, - "structural_signal": 0.5, - "task_success_rate": 0.0, - "tool_efficiency": 1.0 - }, - "run_id": "run_0024", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "gpt-5.4-mini", - "llm_provider": "openai", - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-08T04:39:32+00:00", - "episodes": 1, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.0, - "avg_connectivity_reward": 0.0, - "avg_diversity_reward": 0.0, - "avg_entity_informativeness_reward": 0.0, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.0, - "avg_knowledge_carrier_reward": 0.0, - "avg_knowledge_indexing_reward": 0.0, - "avg_relation_informativeness_reward": 0.0, - "avg_reward": 0.5519400198339021, - "avg_soft_shaping_reward": 0.0, - "avg_spawn_count": 0.0, - "avg_spawn_critical_steps": 0.0, - "avg_steps_to_solution": 1.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.2785970009916951, - "retrieval_signal": 0.5, - "spawn_completion_rate": 0.0, - "spawn_signal": 0.4, - "structural_signal": 0.5, - "task_success_rate": 0.0, - "tool_efficiency": 1.0 - }, - "run_id": "run_0025", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "gpt-5.4-mini", - "llm_provider": "openai", - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-08T04:40:21+00:00", - "episodes": 30, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.13333333333333336, - "avg_connectivity_reward": 0.09999999999999999, - "avg_diversity_reward": 0.03911111111111111, - "avg_entity_informativeness_reward": -0.00951758755541623, - "avg_format_reward": 0.15, - "avg_graph_f1": 0.08482743691314255, - "avg_knowledge_carrier_reward": 0.3333333333333333, - "avg_knowledge_indexing_reward": 0.0832325289772058, - "avg_relation_informativeness_reward": 0.024842289016879314, - "avg_reward": 0.6636425017249088, - "avg_soft_shaping_reward": 0.19999999999999993, - "avg_spawn_count": 2.6666666666666665, - "avg_spawn_critical_steps": 4.0, - "avg_steps_to_solution": 6.333333333333333, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.4644798510150634, - "retrieval_signal": 0.6457980518086888, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.7, - "structural_signal": 0.5472649402922927, - "task_success_rate": 0.6666666666666666, - "tool_efficiency": 0.5 - }, - "run_id": "run_0026", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "gpt-5.4-mini", - "llm_provider": "openai", - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-08T05:01:16+00:00", - "episodes": 10, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.0, - "avg_connectivity_reward": 0.0, - "avg_diversity_reward": 0.0, - "avg_entity_informativeness_reward": 0.0, - "avg_format_reward": 0.14999999999999997, - "avg_graph_f1": 0.0, - "avg_knowledge_carrier_reward": 0.0, - "avg_knowledge_indexing_reward": 0.0, - "avg_relation_informativeness_reward": 0.0, - "avg_reward": 0.5519400198339021, - "avg_soft_shaping_reward": 0.0, - "avg_spawn_count": 0.0, - "avg_spawn_critical_steps": 0.0, - "avg_steps_to_solution": 1.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.2785970009916951, - "retrieval_signal": 0.5, - "spawn_completion_rate": 0.0, - "spawn_signal": 0.4, - "structural_signal": 0.5, - "task_success_rate": 0.0, - "tool_efficiency": 1.0 - }, - "run_id": "run_0027", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "gpt-5.4-mini", - "llm_provider": "openai", - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-08T05:01:29+00:00", - "episodes": 10, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.19999999999999998, - "avg_connectivity_reward": 0.06, - "avg_diversity_reward": 0.0, - "avg_entity_informativeness_reward": 0.0, - "avg_format_reward": 0.14999999999999997, - "avg_graph_f1": 0.18535980927285275, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.09575879120879122, - "avg_relation_informativeness_reward": 0.0, - "avg_reward": 0.7109638031154166, - "avg_soft_shaping_reward": 0.29999999999999993, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.5866289994462388, - "retrieval_signal": 0.708515576923077, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.535, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0028", - "run_name": "fixed_levels_qwen_swarm" - }, - { - "config": { - "llm_model": "gpt-5.4-mini", - "llm_provider": "openai", - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 24, - "max_width": 2, - "seed": 2026, - "seeded_questions": 30, - "swarm_enabled": true - }, - "created_at": "2026-04-08T05:01:43+00:00", - "episodes": 10, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.19999999999999998, - "avg_connectivity_reward": 0.24, - "avg_diversity_reward": 0.11733333333333333, - "avg_entity_informativeness_reward": -0.028552762666248687, - "avg_format_reward": 0.14999999999999997, - "avg_graph_f1": 0.06912250146657492, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.15393879572282626, - "avg_relation_informativeness_reward": 0.07452686705063795, - "avg_reward": 0.7171006884027153, - "avg_soft_shaping_reward": 0.29999999999999993, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 0.0, - "leaderboard_score": 0.5730007362494549, - "retrieval_signal": 0.7288785785029892, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.6067948208768779, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0029", - "run_name": "fixed_levels_qwen_swarm" - } -] \ No newline at end of file diff --git a/scratch/osint/datasets/fixed_levels/qwen_swarm_benchmark_fixed_levels.json b/scratch/osint/datasets/fixed_levels/qwen_swarm_benchmark_fixed_levels.json deleted file mode 100644 index 4052238522ffed2fd9e825b4e35aa3f8b4191250..0000000000000000000000000000000000000000 --- a/scratch/osint/datasets/fixed_levels/qwen_swarm_benchmark_fixed_levels.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "dashboard": "datasets/fixed_levels/dashboard_fixed_levels.html", - "record": { - "config": { - "max_agents": 3, - "max_breadth": 2, - "max_depth": 2, - "max_steps": 20, - "max_width": 2, - "seed": 2026, - "seeded_questions": 15, - "swarm_enabled": true - }, - "created_at": "2026-04-01T18:48:39+00:00", - "episodes": 15, - "metrics": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.16666666666666666, - "avg_connectivity_reward": 0.16999999999999998, - "avg_diversity_reward": 0.1157777777777778, - "avg_entity_informativeness_reward": -0.08858065677817137, - "avg_format_reward": 0.14999999999999997, - "avg_graph_f1": 0.8492063492063492, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.052000000000000005, - "avg_relation_informativeness_reward": 0.07135858524047924, - "avg_reward": 4.197526826881651, - "avg_soft_shaping_reward": 0.24999999999999994, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 1.0, - "leaderboard_score": 0.8543934355282199, - "retrieval_signal": 0.6932, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5730889190257948, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - }, - "run_id": "run_0001", - "run_name": "fixed_levels_qwen_swarm" - }, - "summary": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.16666666666666666, - "avg_connectivity_reward": 0.16999999999999998, - "avg_diversity_reward": 0.1157777777777778, - "avg_entity_informativeness_reward": -0.08858065677817137, - "avg_format_reward": 0.14999999999999997, - "avg_graph_f1": 0.8492063492063492, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.052000000000000005, - "avg_relation_informativeness_reward": 0.07135858524047924, - "avg_reward": 4.197526826881651, - "avg_soft_shaping_reward": 0.24999999999999994, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 1.0, - "leaderboard_score": 0.8543934355282199, - "retrieval_signal": 0.6932, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5730889190257948, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - } -} diff --git a/scratch/osint/datasets/fixed_levels/qwen_swarm_eval_by_difficulty.json b/scratch/osint/datasets/fixed_levels/qwen_swarm_eval_by_difficulty.json deleted file mode 100644 index 1b77dc716eabbad385f7eca94371c2aac4b850a8..0000000000000000000000000000000000000000 --- a/scratch/osint/datasets/fixed_levels/qwen_swarm_eval_by_difficulty.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "by_difficulty": { - "easy": { - "avg_graph_f1": 1.0, - "avg_reward": 3.610490808845623, - "avg_steps": 9.0, - "avg_tool_calls": 4.0, - "episodes": 5, - "task_success_rate": 1.0 - }, - "high": { - "avg_graph_f1": 0.5476190476190477, - "avg_reward": 4.207102815893519, - "avg_steps": 9.0, - "avg_tool_calls": 4.0, - "episodes": 5, - "task_success_rate": 1.0 - }, - "mid": { - "avg_graph_f1": 1.0, - "avg_reward": 4.822687547070801, - "avg_steps": 9.0, - "avg_tool_calls": 4.0, - "episodes": 5, - "task_success_rate": 1.0 - } - }, - "overall": { - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.16666666666666666, - "avg_connectivity_reward": 0.16999999999999998, - "avg_diversity_reward": 0.1157777777777778, - "avg_entity_informativeness_reward": -0.07289878447762359, - "avg_format_reward": 0.14999999999999997, - "avg_graph_f1": 0.8492063492063492, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.052000000000000005, - "avg_relation_informativeness_reward": 0.07157694332826091, - "avg_reward": 4.213427057269981, - "avg_soft_shaping_reward": 0.24999999999999994, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 1.0, - "leaderboard_score": 0.8546911504342771, - "retrieval_signal": 0.6932, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5762689651034608, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 - } -} \ No newline at end of file diff --git a/scratch/osint/datasets/fixed_levels/qwen_swarm_eval_fixed_levels.json b/scratch/osint/datasets/fixed_levels/qwen_swarm_eval_fixed_levels.json deleted file mode 100644 index a467bedc91c9276db4c393c4b633b8150ee71baf..0000000000000000000000000000000000000000 --- a/scratch/osint/datasets/fixed_levels/qwen_swarm_eval_fixed_levels.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "avg_compactness_reward": 0.0, - "avg_connectivity_gain_reward": 0.16666666666666666, - "avg_connectivity_reward": 0.16999999999999998, - "avg_diversity_reward": 0.1157777777777778, - "avg_entity_informativeness_reward": -0.02824631570420193, - "avg_format_reward": 0.14999999999999997, - "avg_graph_f1": 0.8492063492063492, - "avg_knowledge_carrier_reward": 0.5, - "avg_knowledge_indexing_reward": 0.07400000000000001, - "avg_relation_informativeness_reward": 0.06905976285357758, - "avg_reward": 4.285384567790942, - "avg_soft_shaping_reward": 0.24999999999999994, - "avg_spawn_count": 4.0, - "avg_spawn_critical_steps": 6.0, - "avg_steps_to_solution": 9.0, - "deanonymization_accuracy": 1.0, - "leaderboard_score": 0.8565775118852701, - "retrieval_signal": 0.7009000000000001, - "spawn_completion_rate": 1.0, - "spawn_signal": 0.6666666666666666, - "structural_signal": 0.5846960227632085, - "task_success_rate": 1.0, - "tool_efficiency": 0.5 -} diff --git a/scratch/osint/datasets/fixed_levels/seed_fixed_levels.json b/scratch/osint/datasets/fixed_levels/seed_fixed_levels.json deleted file mode 100644 index 9424b00b5f3efbc1cffcde87366ac70b23750ea2..0000000000000000000000000000000000000000 --- a/scratch/osint/datasets/fixed_levels/seed_fixed_levels.json +++ /dev/null @@ -1,6977 +0,0 @@ -{ - "seeding": { - "seeded_nodes": [ - { - "node_id": "user_aria", - "node_type": "user", - "attrs": { - "name": "Aria Sen", - "org": "Helios Labs", - "location": "Sector 9" - } - }, - { - "node_id": "user_bharat", - "node_type": "user", - "attrs": { - "name": "Bharat Kulkarni", - "org": "Northbridge Logistics", - "location": "Dockyard 17" - } - }, - { - "node_id": "user_cyrus", - "node_type": "user", - "attrs": { - "name": "Cyrus Mehta", - "org": "Apex Dynamics", - "location": "Old Town" - } - }, - { - "node_id": "user_diya", - "node_type": "user", - "attrs": { - "name": "Diya Roy", - "org": "Blueharbor Media", - "location": "Old Town" - } - }, - { - "node_id": "user_elin", - "node_type": "user", - "attrs": { - "name": "Elin Das", - "org": "Helios Labs", - "location": "Sector 9" - } - }, - { - "node_id": "user_faris", - "node_type": "user", - "attrs": { - "name": "Faris Noor", - "org": "Tidewatch Ops", - "location": "Rivergate" - } - }, - { - "node_id": "user_gita", - "node_type": "user", - "attrs": { - "name": "Gita Pradhan", - "org": "Apex Dynamics", - "location": "Old Town" - } - }, - { - "node_id": "user_hiro", - "node_type": "user", - "attrs": { - "name": "Hiro Tan", - "org": "Northbridge Logistics", - "location": "Dockyard 17" - } - }, - { - "node_id": "user_ivy", - "node_type": "user", - "attrs": { - "name": "Ivy Kapoor", - "org": "Kestrel Works", - "location": "Rivergate" - } - }, - { - "node_id": "user_jules", - "node_type": "user", - "attrs": { - "name": "Jules Banerjee", - "org": "Blueharbor Media", - "location": "Old Town" - } - }, - { - "node_id": "user_kian", - "node_type": "user", - "attrs": { - "name": "Kian Bose", - "org": "Atlas Freight", - "location": "East Quay" - } - }, - { - "node_id": "user_leena", - "node_type": "user", - "attrs": { - "name": "Leena Das", - "org": "Sunmesh Analytics", - "location": "Sector 9" - } - }, - { - "node_id": "user_mika", - "node_type": "user", - "attrs": { - "name": "Mika Solanki", - "org": "Orion Customs", - "location": "North Basin" - } - }, - { - "node_id": "user_nora", - "node_type": "user", - "attrs": { - "name": "Nora Iqbal", - "org": "Emberline Security", - "location": "Foundry Row" - } - }, - { - "node_id": "user_omar", - "node_type": "user", - "attrs": { - "name": "Omar Sheikh", - "org": "Atlas Freight", - "location": "East Quay" - } - }, - { - "node_id": "user_priya", - "node_type": "user", - "attrs": { - "name": "Priya Menon", - "org": "Sunmesh Analytics", - "location": "Sector 9" - } - }, - { - "node_id": "user_quinn", - "node_type": "user", - "attrs": { - "name": "Quinn Rao", - "org": "Orion Customs", - "location": "North Basin" - } - }, - { - "node_id": "user_rhea", - "node_type": "user", - "attrs": { - "name": "Rhea Kapoor", - "org": "Emberline Security", - "location": "Foundry Row" - } - }, - { - "node_id": "user_soren", - "node_type": "user", - "attrs": { - "name": "Soren Malik", - "org": "Harborlight Transit", - "location": "Uplink Yard" - } - }, - { - "node_id": "user_tara", - "node_type": "user", - "attrs": { - "name": "Tara Dey", - "org": "Harborlight Transit", - "location": "Uplink Yard" - } - }, - { - "node_id": "alias_orchidfox", - "node_type": "alias", - "attrs": { - "handle": "@orchidfox" - } - }, - { - "node_id": "alias_steelquill", - "node_type": "alias", - "attrs": { - "handle": "@steelquill" - } - }, - { - "node_id": "alias_monsoonbyte", - "node_type": "alias", - "attrs": { - "handle": "@monsoonbyte" - } - }, - { - "node_id": "alias_nightrelay", - "node_type": "alias", - "attrs": { - "handle": "@nightrelay" - } - }, - { - "node_id": "alias_mapleghost", - "node_type": "alias", - "attrs": { - "handle": "@mapleghost" - } - }, - { - "node_id": "alias_docksparrow", - "node_type": "alias", - "attrs": { - "handle": "@docksparrow" - } - }, - { - "node_id": "alias_quartzlotus", - "node_type": "alias", - "attrs": { - "handle": "@quartzlotus" - } - }, - { - "node_id": "alias_emberglass", - "node_type": "alias", - "attrs": { - "handle": "@emberglass" - } - }, - { - "node_id": "alias_basinraven", - "node_type": "alias", - "attrs": { - "handle": "@basinraven" - } - }, - { - "node_id": "alias_tideshard", - "node_type": "alias", - "attrs": { - "handle": "@tideshard" - } - }, - { - "node_id": "alias_hollowsignal", - "node_type": "alias", - "attrs": { - "handle": "@hollowsignal" - } - }, - { - "node_id": "alias_ironwhisper", - "node_type": "alias", - "attrs": { - "handle": "@ironwhisper" - } - }, - { - "node_id": "alias_cinderveil", - "node_type": "alias", - "attrs": { - "handle": "@cinderveil" - } - }, - { - "node_id": "alias_sablekeel", - "node_type": "alias", - "attrs": { - "handle": "@sablekeel" - } - }, - { - "node_id": "alias_lanternmoth", - "node_type": "alias", - "attrs": { - "handle": "@lanternmoth" - } - }, - { - "node_id": "alias_frostledger", - "node_type": "alias", - "attrs": { - "handle": "@frostledger" - } - }, - { - "node_id": "org_helios_labs", - "node_type": "org", - "attrs": { - "name": "Helios Labs" - } - }, - { - "node_id": "org_northbridge_logistics", - "node_type": "org", - "attrs": { - "name": "Northbridge Logistics" - } - }, - { - "node_id": "org_apex_dynamics", - "node_type": "org", - "attrs": { - "name": "Apex Dynamics" - } - }, - { - "node_id": "org_blueharbor_media", - "node_type": "org", - "attrs": { - "name": "Blueharbor Media" - } - }, - { - "node_id": "org_tidewatch_ops", - "node_type": "org", - "attrs": { - "name": "Tidewatch Ops" - } - }, - { - "node_id": "org_kestrel_works", - "node_type": "org", - "attrs": { - "name": "Kestrel Works" - } - }, - { - "node_id": "org_atlas_freight", - "node_type": "org", - "attrs": { - "name": "Atlas Freight" - } - }, - { - "node_id": "org_sunmesh_analytics", - "node_type": "org", - "attrs": { - "name": "Sunmesh Analytics" - } - }, - { - "node_id": "org_orion_customs", - "node_type": "org", - "attrs": { - "name": "Orion Customs" - } - }, - { - "node_id": "org_emberline_security", - "node_type": "org", - "attrs": { - "name": "Emberline Security" - } - }, - { - "node_id": "org_harborlight_transit", - "node_type": "org", - "attrs": { - "name": "Harborlight Transit" - } - }, - { - "node_id": "loc_dockyard17", - "node_type": "location", - "attrs": { - "name": "Dockyard 17" - } - }, - { - "node_id": "loc_sector9", - "node_type": "location", - "attrs": { - "name": "Sector 9" - } - }, - { - "node_id": "loc_old_town", - "node_type": "location", - "attrs": { - "name": "Old Town" - } - }, - { - "node_id": "loc_rivergate", - "node_type": "location", - "attrs": { - "name": "Rivergate" - } - }, - { - "node_id": "loc_east_quay", - "node_type": "location", - "attrs": { - "name": "East Quay" - } - }, - { - "node_id": "loc_foundry_row", - "node_type": "location", - "attrs": { - "name": "Foundry Row" - } - }, - { - "node_id": "loc_north_basin", - "node_type": "location", - "attrs": { - "name": "North Basin" - } - }, - { - "node_id": "loc_uplink_yard", - "node_type": "location", - "attrs": { - "name": "Uplink Yard" - } - }, - { - "node_id": "event_project_lantern", - "node_type": "event", - "attrs": { - "name": "Project Lantern" - } - }, - { - "node_id": "event_black_kite", - "node_type": "event", - "attrs": { - "name": "Black Kite" - } - }, - { - "node_id": "event_silent_current", - "node_type": "event", - "attrs": { - "name": "Silent Current" - } - }, - { - "node_id": "event_amber_veil", - "node_type": "event", - "attrs": { - "name": "Amber Veil" - } - }, - { - "node_id": "event_glass_harbor", - "node_type": "event", - "attrs": { - "name": "Glass Harbor" - } - }, - { - "node_id": "event_ember_tide", - "node_type": "event", - "attrs": { - "name": "Ember Tide" - } - }, - { - "node_id": "event_iron_wharf", - "node_type": "event", - "attrs": { - "name": "Iron Wharf" - } - }, - { - "node_id": "event_ghost_signal", - "node_type": "event", - "attrs": { - "name": "Ghost Signal" - } - }, - { - "node_id": "thr_supply_leak", - "node_type": "thread", - "attrs": { - "topic": "supply_chain" - } - }, - { - "node_id": "thr_port_audit", - "node_type": "thread", - "attrs": { - "topic": "port_audit" - } - }, - { - "node_id": "thr_customs_breach", - "node_type": "thread", - "attrs": { - "topic": "customs_breach" - } - }, - { - "node_id": "thr_relay_map", - "node_type": "thread", - "attrs": { - "topic": "relay_map" - } - }, - { - "node_id": "thr_foundry_watch", - "node_type": "thread", - "attrs": { - "topic": "foundry_watch" - } - }, - { - "node_id": "thr_basin_shift", - "node_type": "thread", - "attrs": { - "topic": "basin_shift" - } - }, - { - "node_id": "thr_quiet_manifest", - "node_type": "thread", - "attrs": { - "topic": "quiet_manifest" - } - }, - { - "node_id": "thr_uplink_route", - "node_type": "thread", - "attrs": { - "topic": "uplink_route" - } - }, - { - "node_id": "thr_ember_tide_watch", - "node_type": "thread", - "attrs": { - "topic": "ember_tide" - } - }, - { - "node_id": "thr_ghost_signal_net", - "node_type": "thread", - "attrs": { - "topic": "ghost_signal" - } - }, - { - "node_id": "post_shift_roster", - "node_type": "post", - "attrs": { - "channel": "microblog" - } - }, - { - "node_id": "post_midnight_manifest", - "node_type": "post", - "attrs": { - "channel": "microblog" - } - }, - { - "node_id": "post_sat_phone_ping", - "node_type": "post", - "attrs": { - "channel": "microblog" - } - }, - { - "node_id": "post_drone_parts", - "node_type": "post", - "attrs": { - "channel": "microblog" - } - }, - { - "node_id": "post_relay_schedule", - "node_type": "post", - "attrs": { - "channel": "microblog" - } - }, - { - "node_id": "post_quay_ledgers", - "node_type": "post", - "attrs": { - "channel": "microblog" - } - }, - { - "node_id": "post_customs_tag", - "node_type": "post", - "attrs": { - "channel": "microblog" - } - }, - { - "node_id": "post_hull_signal", - "node_type": "post", - "attrs": { - "channel": "microblog" - } - }, - { - "node_id": "post_basin_photo", - "node_type": "post", - "attrs": { - "channel": "microblog" - } - }, - { - "node_id": "post_foundry_map", - "node_type": "post", - "attrs": { - "channel": "microblog" - } - }, - { - "node_id": "post_lantern_route", - "node_type": "post", - "attrs": { - "channel": "microblog" - } - }, - { - "node_id": "post_uplink_note", - "node_type": "post", - "attrs": { - "channel": "microblog" - } - } - ], - "seeded_edges": [ - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_steelquill", - "rel": "alias_of", - "dst": "user_bharat", - "confidence": 1.0 - }, - { - "src": "alias_monsoonbyte", - "rel": "alias_of", - "dst": "user_diya", - "confidence": 1.0 - }, - { - "src": "alias_nightrelay", - "rel": "alias_of", - "dst": "user_faris", - "confidence": 1.0 - }, - { - "src": "alias_mapleghost", - "rel": "alias_of", - "dst": "user_elin", - "confidence": 1.0 - }, - { - "src": "alias_docksparrow", - "rel": "alias_of", - "dst": "user_hiro", - "confidence": 1.0 - }, - { - "src": "alias_quartzlotus", - "rel": "alias_of", - "dst": "user_cyrus", - "confidence": 1.0 - }, - { - "src": "alias_emberglass", - "rel": "alias_of", - "dst": "user_nora", - "confidence": 1.0 - }, - { - "src": "alias_basinraven", - "rel": "alias_of", - "dst": "user_mika", - "confidence": 1.0 - }, - { - "src": "alias_tideshard", - "rel": "alias_of", - "dst": "user_soren", - "confidence": 1.0 - }, - { - "src": "alias_hollowsignal", - "rel": "alias_of", - "dst": "user_priya", - "confidence": 1.0 - }, - { - "src": "alias_ironwhisper", - "rel": "alias_of", - "dst": "user_omar", - "confidence": 1.0 - }, - { - "src": "alias_cinderveil", - "rel": "alias_of", - "dst": "user_rhea", - "confidence": 1.0 - }, - { - "src": "alias_sablekeel", - "rel": "alias_of", - "dst": "user_tara", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "alias_frostledger", - "rel": "alias_of", - "dst": "user_leena", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "works_at", - "dst": "org_helios_labs", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "located_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "works_at", - "dst": "org_apex_dynamics", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "works_at", - "dst": "org_blueharbor_media", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "user_elin", - "rel": "works_at", - "dst": "org_helios_labs", - "confidence": 1.0 - }, - { - "src": "user_elin", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_faris", - "rel": "works_at", - "dst": "org_tidewatch_ops", - "confidence": 1.0 - }, - { - "src": "user_faris", - "rel": "located_in", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "user_gita", - "rel": "works_at", - "dst": "org_apex_dynamics", - "confidence": 1.0 - }, - { - "src": "user_gita", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "located_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "works_at", - "dst": "org_kestrel_works", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "located_in", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "user_jules", - "rel": "works_at", - "dst": "org_blueharbor_media", - "confidence": 1.0 - }, - { - "src": "user_jules", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "user_kian", - "rel": "works_at", - "dst": "org_atlas_freight", - "confidence": 1.0 - }, - { - "src": "user_kian", - "rel": "located_in", - "dst": "loc_east_quay", - "confidence": 1.0 - }, - { - "src": "user_leena", - "rel": "works_at", - "dst": "org_sunmesh_analytics", - "confidence": 1.0 - }, - { - "src": "user_leena", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "works_at", - "dst": "org_orion_customs", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "located_in", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "works_at", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "located_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "user_omar", - "rel": "works_at", - "dst": "org_atlas_freight", - "confidence": 1.0 - }, - { - "src": "user_omar", - "rel": "located_in", - "dst": "loc_east_quay", - "confidence": 1.0 - }, - { - "src": "user_priya", - "rel": "works_at", - "dst": "org_sunmesh_analytics", - "confidence": 1.0 - }, - { - "src": "user_priya", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_quinn", - "rel": "works_at", - "dst": "org_orion_customs", - "confidence": 1.0 - }, - { - "src": "user_quinn", - "rel": "located_in", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "works_at", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "located_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "works_at", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "located_in", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "user_tara", - "rel": "works_at", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_tara", - "rel": "located_in", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "org_helios_labs", - "rel": "operates_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "org_northbridge_logistics", - "rel": "operates_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "org_apex_dynamics", - "rel": "operates_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "org_blueharbor_media", - "rel": "operates_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "org_tidewatch_ops", - "rel": "operates_in", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "org_kestrel_works", - "rel": "operates_in", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "org_atlas_freight", - "rel": "operates_in", - "dst": "loc_east_quay", - "confidence": 1.0 - }, - { - "src": "org_sunmesh_analytics", - "rel": "operates_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "org_orion_customs", - "rel": "operates_in", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "org_emberline_security", - "rel": "operates_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "org_harborlight_transit", - "rel": "operates_in", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "connected_to", - "dst": "user_bharat", - "confidence": 0.95 - }, - { - "src": "user_bharat", - "rel": "connected_to", - "dst": "user_hiro", - "confidence": 0.95 - }, - { - "src": "user_hiro", - "rel": "connected_to", - "dst": "user_faris", - "confidence": 0.92 - }, - { - "src": "user_faris", - "rel": "connected_to", - "dst": "user_diya", - "confidence": 0.9 - }, - { - "src": "user_diya", - "rel": "connected_to", - "dst": "user_elin", - "confidence": 0.89 - }, - { - "src": "user_elin", - "rel": "connected_to", - "dst": "user_aria", - "confidence": 0.87 - }, - { - "src": "user_aria", - "rel": "connected_to", - "dst": "user_cyrus", - "confidence": 0.84 - }, - { - "src": "user_cyrus", - "rel": "connected_to", - "dst": "user_gita", - "confidence": 0.83 - }, - { - "src": "user_gita", - "rel": "connected_to", - "dst": "user_jules", - "confidence": 0.82 - }, - { - "src": "user_jules", - "rel": "connected_to", - "dst": "user_bharat", - "confidence": 0.81 - }, - { - "src": "user_diya", - "rel": "connected_to", - "dst": "user_ivy", - "confidence": 0.9 - }, - { - "src": "user_ivy", - "rel": "connected_to", - "dst": "user_elin", - "confidence": 0.86 - }, - { - "src": "user_kian", - "rel": "connected_to", - "dst": "user_omar", - "confidence": 0.93 - }, - { - "src": "user_omar", - "rel": "connected_to", - "dst": "user_mika", - "confidence": 0.9 - }, - { - "src": "user_mika", - "rel": "connected_to", - "dst": "user_quinn", - "confidence": 0.89 - }, - { - "src": "user_quinn", - "rel": "connected_to", - "dst": "user_nora", - "confidence": 0.88 - }, - { - "src": "user_nora", - "rel": "connected_to", - "dst": "user_rhea", - "confidence": 0.87 - }, - { - "src": "user_rhea", - "rel": "connected_to", - "dst": "user_soren", - "confidence": 0.86 - }, - { - "src": "user_soren", - "rel": "connected_to", - "dst": "user_tara", - "confidence": 0.86 - }, - { - "src": "user_tara", - "rel": "connected_to", - "dst": "user_kian", - "confidence": 0.84 - }, - { - "src": "user_priya", - "rel": "connected_to", - "dst": "user_leena", - "confidence": 0.91 - }, - { - "src": "user_leena", - "rel": "connected_to", - "dst": "user_aria", - "confidence": 0.83 - }, - { - "src": "user_priya", - "rel": "connected_to", - "dst": "user_nora", - "confidence": 0.82 - }, - { - "src": "user_kian", - "rel": "connected_to", - "dst": "user_bharat", - "confidence": 0.8 - }, - { - "src": "user_soren", - "rel": "connected_to", - "dst": "user_faris", - "confidence": 0.79 - }, - { - "src": "user_quinn", - "rel": "connected_to", - "dst": "user_hiro", - "confidence": 0.78 - }, - { - "src": "alias_orchidfox", - "rel": "authored_post", - "dst": "post_midnight_manifest", - "confidence": 1.0 - }, - { - "src": "alias_docksparrow", - "rel": "authored_post", - "dst": "post_shift_roster", - "confidence": 1.0 - }, - { - "src": "alias_nightrelay", - "rel": "authored_post", - "dst": "post_sat_phone_ping", - "confidence": 1.0 - }, - { - "src": "alias_monsoonbyte", - "rel": "authored_post", - "dst": "post_drone_parts", - "confidence": 1.0 - }, - { - "src": "alias_steelquill", - "rel": "authored_post", - "dst": "post_relay_schedule", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "authored_post", - "dst": "post_quay_ledgers", - "confidence": 1.0 - }, - { - "src": "alias_basinraven", - "rel": "authored_post", - "dst": "post_customs_tag", - "confidence": 1.0 - }, - { - "src": "alias_tideshard", - "rel": "authored_post", - "dst": "post_hull_signal", - "confidence": 1.0 - }, - { - "src": "alias_emberglass", - "rel": "authored_post", - "dst": "post_basin_photo", - "confidence": 1.0 - }, - { - "src": "alias_cinderveil", - "rel": "authored_post", - "dst": "post_foundry_map", - "confidence": 1.0 - }, - { - "src": "alias_frostledger", - "rel": "authored_post", - "dst": "post_lantern_route", - "confidence": 1.0 - }, - { - "src": "alias_sablekeel", - "rel": "authored_post", - "dst": "post_uplink_note", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "post_shift_roster", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "post_shift_roster", - "rel": "references", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "post_sat_phone_ping", - "rel": "references", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "post_sat_phone_ping", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "post_drone_parts", - "rel": "references", - "dst": "event_black_kite", - "confidence": 1.0 - }, - { - "src": "post_drone_parts", - "rel": "references", - "dst": "org_kestrel_works", - "confidence": 1.0 - }, - { - "src": "post_relay_schedule", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "post_relay_schedule", - "rel": "references", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "post_quay_ledgers", - "rel": "references", - "dst": "loc_east_quay", - "confidence": 1.0 - }, - { - "src": "post_quay_ledgers", - "rel": "references", - "dst": "event_glass_harbor", - "confidence": 1.0 - }, - { - "src": "post_customs_tag", - "rel": "references", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "post_customs_tag", - "rel": "references", - "dst": "event_iron_wharf", - "confidence": 1.0 - }, - { - "src": "post_hull_signal", - "rel": "references", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "post_hull_signal", - "rel": "references", - "dst": "event_ghost_signal", - "confidence": 1.0 - }, - { - "src": "post_basin_photo", - "rel": "references", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "post_basin_photo", - "rel": "references", - "dst": "event_amber_veil", - "confidence": 1.0 - }, - { - "src": "post_foundry_map", - "rel": "references", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "post_foundry_map", - "rel": "references", - "dst": "event_ember_tide", - "confidence": 1.0 - }, - { - "src": "post_lantern_route", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "post_lantern_route", - "rel": "references", - "dst": "org_sunmesh_analytics", - "confidence": 1.0 - }, - { - "src": "post_uplink_note", - "rel": "references", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "post_uplink_note", - "rel": "references", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "authored_thread", - "dst": "thr_supply_leak", - "confidence": 1.0 - }, - { - "src": "user_jules", - "rel": "authored_thread", - "dst": "thr_port_audit", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "authored_thread", - "dst": "thr_customs_breach", - "confidence": 1.0 - }, - { - "src": "user_leena", - "rel": "authored_thread", - "dst": "thr_relay_map", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "authored_thread", - "dst": "thr_foundry_watch", - "confidence": 1.0 - }, - { - "src": "user_quinn", - "rel": "authored_thread", - "dst": "thr_basin_shift", - "confidence": 1.0 - }, - { - "src": "user_kian", - "rel": "authored_thread", - "dst": "thr_quiet_manifest", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "authored_thread", - "dst": "thr_uplink_route", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "authored_thread", - "dst": "thr_ember_tide_watch", - "confidence": 1.0 - }, - { - "src": "user_tara", - "rel": "authored_thread", - "dst": "thr_ghost_signal_net", - "confidence": 1.0 - }, - { - "src": "thr_supply_leak", - "rel": "discusses", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "thr_supply_leak", - "rel": "references", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "thr_port_audit", - "rel": "discusses", - "dst": "event_black_kite", - "confidence": 1.0 - }, - { - "src": "thr_port_audit", - "rel": "references", - "dst": "org_kestrel_works", - "confidence": 1.0 - }, - { - "src": "thr_customs_breach", - "rel": "discusses", - "dst": "event_iron_wharf", - "confidence": 1.0 - }, - { - "src": "thr_customs_breach", - "rel": "references", - "dst": "org_orion_customs", - "confidence": 1.0 - }, - { - "src": "thr_relay_map", - "rel": "discusses", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "thr_relay_map", - "rel": "references", - "dst": "org_sunmesh_analytics", - "confidence": 1.0 - }, - { - "src": "thr_foundry_watch", - "rel": "discusses", - "dst": "event_ember_tide", - "confidence": 1.0 - }, - { - "src": "thr_foundry_watch", - "rel": "references", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "thr_basin_shift", - "rel": "discusses", - "dst": "event_amber_veil", - "confidence": 1.0 - }, - { - "src": "thr_basin_shift", - "rel": "references", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "thr_quiet_manifest", - "rel": "discusses", - "dst": "event_glass_harbor", - "confidence": 1.0 - }, - { - "src": "thr_quiet_manifest", - "rel": "references", - "dst": "org_atlas_freight", - "confidence": 1.0 - }, - { - "src": "thr_uplink_route", - "rel": "discusses", - "dst": "event_ghost_signal", - "confidence": 1.0 - }, - { - "src": "thr_uplink_route", - "rel": "references", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "thr_ember_tide_watch", - "rel": "discusses", - "dst": "event_ember_tide", - "confidence": 1.0 - }, - { - "src": "thr_ember_tide_watch", - "rel": "references", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "thr_ghost_signal_net", - "rel": "discusses", - "dst": "event_ghost_signal", - "confidence": 1.0 - }, - { - "src": "thr_ghost_signal_net", - "rel": "references", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_hiro", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_faris", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_diya", - "rel": "investigates", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_leena", - "rel": "monitors", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_ivy", - "rel": "collaborates_on", - "dst": "event_black_kite", - "confidence": 0.9 - }, - { - "src": "user_cyrus", - "rel": "collaborates_on", - "dst": "event_black_kite", - "confidence": 0.9 - }, - { - "src": "user_elin", - "rel": "investigates", - "dst": "event_black_kite", - "confidence": 0.9 - }, - { - "src": "user_jules", - "rel": "reports_on", - "dst": "event_black_kite", - "confidence": 0.9 - }, - { - "src": "user_kian", - "rel": "collaborates_on", - "dst": "event_glass_harbor", - "confidence": 0.9 - }, - { - "src": "user_omar", - "rel": "collaborates_on", - "dst": "event_glass_harbor", - "confidence": 0.9 - }, - { - "src": "user_priya", - "rel": "monitors", - "dst": "event_glass_harbor", - "confidence": 0.9 - }, - { - "src": "user_mika", - "rel": "collaborates_on", - "dst": "event_iron_wharf", - "confidence": 0.9 - }, - { - "src": "user_quinn", - "rel": "collaborates_on", - "dst": "event_iron_wharf", - "confidence": 0.9 - }, - { - "src": "user_nora", - "rel": "investigates", - "dst": "event_amber_veil", - "confidence": 0.9 - }, - { - "src": "user_rhea", - "rel": "collaborates_on", - "dst": "event_ember_tide", - "confidence": 0.9 - }, - { - "src": "user_soren", - "rel": "collaborates_on", - "dst": "event_ghost_signal", - "confidence": 0.9 - }, - { - "src": "user_tara", - "rel": "reports_on", - "dst": "event_ghost_signal", - "confidence": 0.9 - }, - { - "src": "user_gita", - "rel": "monitors", - "dst": "event_silent_current", - "confidence": 0.9 - }, - { - "src": "user_jules", - "rel": "reports_on", - "dst": "event_silent_current", - "confidence": 0.9 - }, - { - "src": "event_project_lantern", - "rel": "connected_to", - "dst": "event_glass_harbor", - "confidence": 0.77 - }, - { - "src": "event_black_kite", - "rel": "connected_to", - "dst": "event_amber_veil", - "confidence": 0.77 - }, - { - "src": "event_ember_tide", - "rel": "connected_to", - "dst": "event_ghost_signal", - "confidence": 0.77 - }, - { - "src": "org_atlas_freight", - "rel": "connected_to", - "dst": "org_northbridge_logistics", - "confidence": 0.77 - }, - { - "src": "org_orion_customs", - "rel": "connected_to", - "dst": "org_emberline_security", - "confidence": 0.77 - }, - { - "src": "org_harborlight_transit", - "rel": "connected_to", - "dst": "org_tidewatch_ops", - "confidence": 0.77 - } - ], - "seeded_questions": [ - { - "task_type": "fixed_trace", - "question": "alias_orchidfox -> post_midnight_manifest -> loc_dockyard17 -> connected collaborator on event_project_lantern. Who is it?", - "answer": "user_bharat", - "supporting_edges": [ - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "authored_post", - "dst": "post_midnight_manifest", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "connected_to", - "dst": "user_bharat", - "confidence": 0.95 - }, - { - "src": "user_bharat", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - } - ], - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_01", - "support_nodes": 6 - } - }, - { - "task_type": "fixed_trace", - "question": "thr_supply_leak references org_northbridge_logistics. Which alias_docksparrow user works there and collaborates on event_project_lantern?", - "answer": "user_hiro", - "supporting_edges": [ - { - "src": "thr_supply_leak", - "rel": "references", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "alias_docksparrow", - "rel": "alias_of", - "dst": "user_hiro", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - } - ], - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_02", - "support_nodes": 5 - } - }, - { - "task_type": "fixed_trace", - "question": "alias_monsoonbyte authored post_drone_parts about event_black_kite. Which user behind that alias is directly connected to the Kestrel collaborator?", - "answer": "user_diya", - "supporting_edges": [ - { - "src": "alias_monsoonbyte", - "rel": "alias_of", - "dst": "user_diya", - "confidence": 1.0 - }, - { - "src": "alias_monsoonbyte", - "rel": "authored_post", - "dst": "post_drone_parts", - "confidence": 1.0 - }, - { - "src": "post_drone_parts", - "rel": "references", - "dst": "event_black_kite", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "works_at", - "dst": "org_kestrel_works", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "collaborates_on", - "dst": "event_black_kite", - "confidence": 0.9 - }, - { - "src": "user_ivy", - "rel": "connected_to", - "dst": "user_elin", - "confidence": 0.86 - } - ], - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_03", - "support_nodes": 7 - } - }, - { - "task_type": "fixed_trace", - "question": "alias_nightrelay references loc_rivergate. Which user behind it works at an org operating there and collaborates on event_project_lantern?", - "answer": "user_faris", - "supporting_edges": [ - { - "src": "alias_nightrelay", - "rel": "alias_of", - "dst": "user_faris", - "confidence": 1.0 - }, - { - "src": "alias_nightrelay", - "rel": "authored_post", - "dst": "post_sat_phone_ping", - "confidence": 1.0 - }, - { - "src": "post_sat_phone_ping", - "rel": "references", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "user_faris", - "rel": "works_at", - "dst": "org_tidewatch_ops", - "confidence": 1.0 - }, - { - "src": "org_tidewatch_ops", - "rel": "operates_in", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "user_faris", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - } - ], - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_04", - "support_nodes": 6 - } - }, - { - "task_type": "fixed_trace", - "question": "thr_port_audit discusses Black Kite and references Kestrel Works. Which alias_orchidfox user authored post_midnight_manifest and collaborates on Black Kite?", - "answer": "user_ivy", - "supporting_edges": [ - { - "src": "thr_port_audit", - "rel": "discusses", - "dst": "event_black_kite", - "confidence": 1.0 - }, - { - "src": "thr_port_audit", - "rel": "references", - "dst": "org_kestrel_works", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "authored_post", - "dst": "post_midnight_manifest", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "works_at", - "dst": "org_kestrel_works", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "collaborates_on", - "dst": "event_black_kite", - "confidence": 0.9 - } - ], - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_05", - "support_nodes": 6 - } - }, - { - "task_type": "fixed_trace", - "question": "Which Atlas Freight user behind alias_lanternmoth authored post_quay_ledgers and collaborates on event_glass_harbor?", - "answer": "user_kian", - "supporting_edges": [ - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "authored_post", - "dst": "post_quay_ledgers", - "confidence": 1.0 - }, - { - "src": "user_kian", - "rel": "works_at", - "dst": "org_atlas_freight", - "confidence": 1.0 - }, - { - "src": "user_kian", - "rel": "collaborates_on", - "dst": "event_glass_harbor", - "confidence": 0.9 - } - ], - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_06", - "support_nodes": 5 - } - }, - { - "task_type": "fixed_trace", - "question": "Which Orion Customs user behind alias_basinraven authored post_customs_tag and collaborates on event_iron_wharf?", - "answer": "user_mika", - "supporting_edges": [ - { - "src": "alias_basinraven", - "rel": "alias_of", - "dst": "user_mika", - "confidence": 1.0 - }, - { - "src": "alias_basinraven", - "rel": "authored_post", - "dst": "post_customs_tag", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "works_at", - "dst": "org_orion_customs", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "collaborates_on", - "dst": "event_iron_wharf", - "confidence": 0.9 - } - ], - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_07", - "support_nodes": 5 - } - }, - { - "task_type": "fixed_trace", - "question": "Which user behind alias_emberglass posted basin_photo from Foundry Row and investigates Amber Veil?", - "answer": "user_nora", - "supporting_edges": [ - { - "src": "alias_emberglass", - "rel": "alias_of", - "dst": "user_nora", - "confidence": 1.0 - }, - { - "src": "alias_emberglass", - "rel": "authored_post", - "dst": "post_basin_photo", - "confidence": 1.0 - }, - { - "src": "post_basin_photo", - "rel": "references", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "investigates", - "dst": "event_amber_veil", - "confidence": 0.9 - } - ], - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_08", - "support_nodes": 5 - } - }, - { - "task_type": "fixed_trace", - "question": "Which user behind alias_tideshard authored post_hull_signal and collaborates on Ghost Signal?", - "answer": "user_soren", - "supporting_edges": [ - { - "src": "alias_tideshard", - "rel": "alias_of", - "dst": "user_soren", - "confidence": 1.0 - }, - { - "src": "alias_tideshard", - "rel": "authored_post", - "dst": "post_hull_signal", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "collaborates_on", - "dst": "event_ghost_signal", - "confidence": 0.9 - } - ], - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_09", - "support_nodes": 4 - } - }, - { - "task_type": "fixed_trace", - "question": "Which Harborlight Transit user behind alias_sablekeel authored post_uplink_note and reports on Ghost Signal?", - "answer": "user_tara", - "supporting_edges": [ - { - "src": "alias_sablekeel", - "rel": "alias_of", - "dst": "user_tara", - "confidence": 1.0 - }, - { - "src": "alias_sablekeel", - "rel": "authored_post", - "dst": "post_uplink_note", - "confidence": 1.0 - }, - { - "src": "user_tara", - "rel": "works_at", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_tara", - "rel": "reports_on", - "dst": "event_ghost_signal", - "confidence": 0.9 - } - ], - "metadata": { - "difficulty": "easy", - "difficulty_level": 1, - "question_id": "easy_10", - "support_nodes": 5 - } - }, - { - "task_type": "fixed_trace", - "question": "Follow alias_docksparrow through post_shift_roster, Dockyard 17, and the Lantern chain. Return the org node id.", - "answer": "org_northbridge_logistics", - "supporting_edges": [ - { - "src": "alias_docksparrow", - "rel": "alias_of", - "dst": "user_hiro", - "confidence": 1.0 - }, - { - "src": "alias_docksparrow", - "rel": "authored_post", - "dst": "post_shift_roster", - "confidence": 1.0 - }, - { - "src": "post_shift_roster", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "post_shift_roster", - "rel": "references", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "thr_supply_leak", - "rel": "references", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "located_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_bharat", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_bharat", - "rel": "connected_to", - "dst": "user_hiro", - "confidence": 0.95 - }, - { - "src": "user_hiro", - "rel": "connected_to", - "dst": "user_faris", - "confidence": 0.92 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "authored_post", - "dst": "post_midnight_manifest", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "authored_post", - "dst": "post_quay_ledgers", - "confidence": 1.0 - }, - { - "src": "post_quay_ledgers", - "rel": "references", - "dst": "loc_east_quay", - "confidence": 1.0 - }, - { - "src": "post_quay_ledgers", - "rel": "references", - "dst": "event_glass_harbor", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_01", - "support_nodes": 17 - } - }, - { - "task_type": "fixed_trace", - "question": "Across the Glass Harbor cluster, which user behind alias_lanternmoth links to the Atlas Freight network from thr_quiet_manifest?", - "answer": "user_kian", - "supporting_edges": [ - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "authored_post", - "dst": "post_quay_ledgers", - "confidence": 1.0 - }, - { - "src": "post_quay_ledgers", - "rel": "references", - "dst": "loc_east_quay", - "confidence": 1.0 - }, - { - "src": "post_quay_ledgers", - "rel": "references", - "dst": "event_glass_harbor", - "confidence": 1.0 - }, - { - "src": "user_kian", - "rel": "authored_thread", - "dst": "thr_quiet_manifest", - "confidence": 1.0 - }, - { - "src": "thr_quiet_manifest", - "rel": "discusses", - "dst": "event_glass_harbor", - "confidence": 1.0 - }, - { - "src": "thr_quiet_manifest", - "rel": "references", - "dst": "org_atlas_freight", - "confidence": 1.0 - }, - { - "src": "user_kian", - "rel": "works_at", - "dst": "org_atlas_freight", - "confidence": 1.0 - }, - { - "src": "user_omar", - "rel": "works_at", - "dst": "org_atlas_freight", - "confidence": 1.0 - }, - { - "src": "user_kian", - "rel": "collaborates_on", - "dst": "event_glass_harbor", - "confidence": 0.9 - }, - { - "src": "user_omar", - "rel": "collaborates_on", - "dst": "event_glass_harbor", - "confidence": 0.9 - }, - { - "src": "user_priya", - "rel": "monitors", - "dst": "event_glass_harbor", - "confidence": 0.9 - }, - { - "src": "user_kian", - "rel": "connected_to", - "dst": "user_omar", - "confidence": 0.93 - }, - { - "src": "user_omar", - "rel": "connected_to", - "dst": "user_mika", - "confidence": 0.9 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "authored_post", - "dst": "post_midnight_manifest", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "alias_basinraven", - "rel": "alias_of", - "dst": "user_mika", - "confidence": 1.0 - }, - { - "src": "alias_basinraven", - "rel": "authored_post", - "dst": "post_customs_tag", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_02", - "support_nodes": 17 - } - }, - { - "task_type": "fixed_trace", - "question": "Trace alias_basinraven through post_customs_tag, thr_customs_breach, and the Orion Customs collaboration chain. Who is it?", - "answer": "user_mika", - "supporting_edges": [ - { - "src": "alias_basinraven", - "rel": "alias_of", - "dst": "user_mika", - "confidence": 1.0 - }, - { - "src": "alias_basinraven", - "rel": "authored_post", - "dst": "post_customs_tag", - "confidence": 1.0 - }, - { - "src": "post_customs_tag", - "rel": "references", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "post_customs_tag", - "rel": "references", - "dst": "event_iron_wharf", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "authored_thread", - "dst": "thr_customs_breach", - "confidence": 1.0 - }, - { - "src": "thr_customs_breach", - "rel": "discusses", - "dst": "event_iron_wharf", - "confidence": 1.0 - }, - { - "src": "thr_customs_breach", - "rel": "references", - "dst": "org_orion_customs", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "works_at", - "dst": "org_orion_customs", - "confidence": 1.0 - }, - { - "src": "user_quinn", - "rel": "works_at", - "dst": "org_orion_customs", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "collaborates_on", - "dst": "event_iron_wharf", - "confidence": 0.9 - }, - { - "src": "user_quinn", - "rel": "collaborates_on", - "dst": "event_iron_wharf", - "confidence": 0.9 - }, - { - "src": "user_mika", - "rel": "connected_to", - "dst": "user_quinn", - "confidence": 0.89 - }, - { - "src": "user_quinn", - "rel": "connected_to", - "dst": "user_nora", - "confidence": 0.88 - }, - { - "src": "org_orion_customs", - "rel": "connected_to", - "dst": "org_emberline_security", - "confidence": 0.77 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "authored_post", - "dst": "post_midnight_manifest", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_03", - "support_nodes": 17 - } - }, - { - "task_type": "fixed_trace", - "question": "In the Ember Tide and Amber Veil overlap, which Foundry Row user behind alias_cinderveil collaborates on Ember Tide?", - "answer": "user_rhea", - "supporting_edges": [ - { - "src": "alias_cinderveil", - "rel": "alias_of", - "dst": "user_rhea", - "confidence": 1.0 - }, - { - "src": "alias_cinderveil", - "rel": "authored_post", - "dst": "post_foundry_map", - "confidence": 1.0 - }, - { - "src": "post_foundry_map", - "rel": "references", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "post_foundry_map", - "rel": "references", - "dst": "event_ember_tide", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "authored_thread", - "dst": "thr_foundry_watch", - "confidence": 1.0 - }, - { - "src": "thr_foundry_watch", - "rel": "discusses", - "dst": "event_ember_tide", - "confidence": 1.0 - }, - { - "src": "thr_foundry_watch", - "rel": "references", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "authored_thread", - "dst": "thr_ember_tide_watch", - "confidence": 1.0 - }, - { - "src": "thr_ember_tide_watch", - "rel": "discusses", - "dst": "event_ember_tide", - "confidence": 1.0 - }, - { - "src": "thr_ember_tide_watch", - "rel": "references", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "works_at", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "works_at", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "investigates", - "dst": "event_amber_veil", - "confidence": 0.9 - }, - { - "src": "user_rhea", - "rel": "collaborates_on", - "dst": "event_ember_tide", - "confidence": 0.9 - }, - { - "src": "user_nora", - "rel": "connected_to", - "dst": "user_rhea", - "confidence": 0.87 - }, - { - "src": "event_ember_tide", - "rel": "connected_to", - "dst": "event_ghost_signal", - "confidence": 0.77 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "authored_post", - "dst": "post_midnight_manifest", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_04", - "support_nodes": 18 - } - }, - { - "task_type": "fixed_trace", - "question": "Follow alias_tideshard from post_hull_signal into thr_uplink_route and the Harborlight relay. Return the org node id.", - "answer": "org_harborlight_transit", - "supporting_edges": [ - { - "src": "alias_tideshard", - "rel": "alias_of", - "dst": "user_soren", - "confidence": 1.0 - }, - { - "src": "alias_tideshard", - "rel": "authored_post", - "dst": "post_hull_signal", - "confidence": 1.0 - }, - { - "src": "post_hull_signal", - "rel": "references", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "post_hull_signal", - "rel": "references", - "dst": "event_ghost_signal", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "authored_thread", - "dst": "thr_uplink_route", - "confidence": 1.0 - }, - { - "src": "thr_uplink_route", - "rel": "discusses", - "dst": "event_ghost_signal", - "confidence": 1.0 - }, - { - "src": "thr_uplink_route", - "rel": "references", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "works_at", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_tara", - "rel": "works_at", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "collaborates_on", - "dst": "event_ghost_signal", - "confidence": 0.9 - }, - { - "src": "user_tara", - "rel": "reports_on", - "dst": "event_ghost_signal", - "confidence": 0.9 - }, - { - "src": "user_rhea", - "rel": "connected_to", - "dst": "user_soren", - "confidence": 0.86 - }, - { - "src": "user_soren", - "rel": "connected_to", - "dst": "user_tara", - "confidence": 0.86 - }, - { - "src": "org_harborlight_transit", - "rel": "operates_in", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "org_harborlight_transit", - "rel": "connected_to", - "dst": "org_tidewatch_ops", - "confidence": 0.77 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "authored_post", - "dst": "post_midnight_manifest", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_05", - "support_nodes": 17 - } - }, - { - "task_type": "fixed_trace", - "question": "Which Sunmesh user behind alias_frostledger connects post_lantern_route to thr_relay_map and the Sector 9 monitoring chain?", - "answer": "user_leena", - "supporting_edges": [ - { - "src": "alias_frostledger", - "rel": "alias_of", - "dst": "user_leena", - "confidence": 1.0 - }, - { - "src": "alias_frostledger", - "rel": "authored_post", - "dst": "post_lantern_route", - "confidence": 1.0 - }, - { - "src": "post_lantern_route", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "post_lantern_route", - "rel": "references", - "dst": "org_sunmesh_analytics", - "confidence": 1.0 - }, - { - "src": "user_leena", - "rel": "authored_thread", - "dst": "thr_relay_map", - "confidence": 1.0 - }, - { - "src": "thr_relay_map", - "rel": "discusses", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "thr_relay_map", - "rel": "references", - "dst": "org_sunmesh_analytics", - "confidence": 1.0 - }, - { - "src": "user_leena", - "rel": "works_at", - "dst": "org_sunmesh_analytics", - "confidence": 1.0 - }, - { - "src": "user_priya", - "rel": "works_at", - "dst": "org_sunmesh_analytics", - "confidence": 1.0 - }, - { - "src": "user_leena", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "org_sunmesh_analytics", - "rel": "operates_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_leena", - "rel": "monitors", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_priya", - "rel": "connected_to", - "dst": "user_leena", - "confidence": 0.91 - }, - { - "src": "user_leena", - "rel": "connected_to", - "dst": "user_aria", - "confidence": 0.83 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "authored_post", - "dst": "post_midnight_manifest", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "authored_post", - "dst": "post_quay_ledgers", - "confidence": 1.0 - }, - { - "src": "post_quay_ledgers", - "rel": "references", - "dst": "loc_east_quay", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_06", - "support_nodes": 17 - } - }, - { - "task_type": "fixed_trace", - "question": "Which user behind alias_emberglass is tied to Amber Veil after combining post_basin_photo, thr_basin_shift, and the Foundry Row investigation chain?", - "answer": "user_nora", - "supporting_edges": [ - { - "src": "alias_emberglass", - "rel": "alias_of", - "dst": "user_nora", - "confidence": 1.0 - }, - { - "src": "alias_emberglass", - "rel": "authored_post", - "dst": "post_basin_photo", - "confidence": 1.0 - }, - { - "src": "post_basin_photo", - "rel": "references", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "post_basin_photo", - "rel": "references", - "dst": "event_amber_veil", - "confidence": 1.0 - }, - { - "src": "user_quinn", - "rel": "authored_thread", - "dst": "thr_basin_shift", - "confidence": 1.0 - }, - { - "src": "thr_basin_shift", - "rel": "discusses", - "dst": "event_amber_veil", - "confidence": 1.0 - }, - { - "src": "thr_basin_shift", - "rel": "references", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "works_at", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_quinn", - "rel": "works_at", - "dst": "org_orion_customs", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "located_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "investigates", - "dst": "event_amber_veil", - "confidence": 0.9 - }, - { - "src": "user_quinn", - "rel": "connected_to", - "dst": "user_nora", - "confidence": 0.88 - }, - { - "src": "user_nora", - "rel": "connected_to", - "dst": "user_rhea", - "confidence": 0.87 - }, - { - "src": "org_orion_customs", - "rel": "connected_to", - "dst": "org_emberline_security", - "confidence": 0.77 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "authored_post", - "dst": "post_midnight_manifest", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_07", - "support_nodes": 18 - } - }, - { - "task_type": "fixed_trace", - "question": "Combine alias_orchidfox, post_midnight_manifest, thr_supply_leak, and the Lantern to Glass Harbor bridge. Which user starts that chain?", - "answer": "user_ivy", - "supporting_edges": [ - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "authored_post", - "dst": "post_midnight_manifest", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "authored_thread", - "dst": "thr_supply_leak", - "confidence": 1.0 - }, - { - "src": "thr_supply_leak", - "rel": "discusses", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "thr_supply_leak", - "rel": "references", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "works_at", - "dst": "org_kestrel_works", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "collaborates_on", - "dst": "event_black_kite", - "confidence": 0.9 - }, - { - "src": "user_ivy", - "rel": "connected_to", - "dst": "user_bharat", - "confidence": 0.95 - }, - { - "src": "user_ivy", - "rel": "connected_to", - "dst": "user_elin", - "confidence": 0.86 - }, - { - "src": "event_project_lantern", - "rel": "connected_to", - "dst": "event_glass_harbor", - "confidence": 0.77 - }, - { - "src": "user_kian", - "rel": "collaborates_on", - "dst": "event_glass_harbor", - "confidence": 0.9 - }, - { - "src": "user_priya", - "rel": "monitors", - "dst": "event_glass_harbor", - "confidence": 0.9 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "authored_post", - "dst": "post_quay_ledgers", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_08", - "support_nodes": 17 - } - }, - { - "task_type": "fixed_trace", - "question": "Which user behind alias_monsoonbyte sits at the overlap of Blueharbor Media, Project Lantern, Black Kite, and the Ivy connection chain?", - "answer": "user_diya", - "supporting_edges": [ - { - "src": "alias_monsoonbyte", - "rel": "alias_of", - "dst": "user_diya", - "confidence": 1.0 - }, - { - "src": "alias_monsoonbyte", - "rel": "authored_post", - "dst": "post_drone_parts", - "confidence": 1.0 - }, - { - "src": "post_drone_parts", - "rel": "references", - "dst": "event_black_kite", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "authored_thread", - "dst": "thr_supply_leak", - "confidence": 1.0 - }, - { - "src": "thr_supply_leak", - "rel": "discusses", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "user_jules", - "rel": "authored_thread", - "dst": "thr_port_audit", - "confidence": 1.0 - }, - { - "src": "thr_port_audit", - "rel": "discusses", - "dst": "event_black_kite", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "works_at", - "dst": "org_blueharbor_media", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "works_at", - "dst": "org_kestrel_works", - "confidence": 1.0 - }, - { - "src": "user_jules", - "rel": "works_at", - "dst": "org_blueharbor_media", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "investigates", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_ivy", - "rel": "collaborates_on", - "dst": "event_black_kite", - "confidence": 0.9 - }, - { - "src": "user_jules", - "rel": "reports_on", - "dst": "event_black_kite", - "confidence": 0.9 - }, - { - "src": "user_faris", - "rel": "connected_to", - "dst": "user_diya", - "confidence": 0.9 - }, - { - "src": "user_ivy", - "rel": "connected_to", - "dst": "user_elin", - "confidence": 0.86 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "authored_post", - "dst": "post_midnight_manifest", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_09", - "support_nodes": 18 - } - }, - { - "task_type": "fixed_trace", - "question": "Who is the Northbridge user behind alias_steelquill when combining post_relay_schedule, thr_supply_leak, Dockyard 17, and Lantern collaborator edges?", - "answer": "user_bharat", - "supporting_edges": [ - { - "src": "alias_steelquill", - "rel": "alias_of", - "dst": "user_bharat", - "confidence": 1.0 - }, - { - "src": "alias_steelquill", - "rel": "authored_post", - "dst": "post_relay_schedule", - "confidence": 1.0 - }, - { - "src": "post_relay_schedule", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "post_relay_schedule", - "rel": "references", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "authored_thread", - "dst": "thr_supply_leak", - "confidence": 1.0 - }, - { - "src": "thr_supply_leak", - "rel": "discusses", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "thr_supply_leak", - "rel": "references", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "located_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "located_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_hiro", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_ivy", - "rel": "connected_to", - "dst": "user_bharat", - "confidence": 0.95 - }, - { - "src": "user_bharat", - "rel": "connected_to", - "dst": "user_hiro", - "confidence": 0.95 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "authored_post", - "dst": "post_midnight_manifest", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "authored_post", - "dst": "post_quay_ledgers", - "confidence": 1.0 - }, - { - "src": "post_quay_ledgers", - "rel": "references", - "dst": "loc_east_quay", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "mid", - "difficulty_level": 2, - "question_id": "mid_10", - "support_nodes": 17 - } - }, - { - "task_type": "fixed_trace", - "question": "Lantern to Glass Harbor handoff: identify the user behind alias_orchidfox after combining Lantern logistics, Dockyard links, and Atlas Freight bridge evidence.", - "answer": "user_ivy", - "supporting_edges": [ - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "authored_post", - "dst": "post_midnight_manifest", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "authored_thread", - "dst": "thr_supply_leak", - "confidence": 1.0 - }, - { - "src": "thr_supply_leak", - "rel": "discusses", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "thr_supply_leak", - "rel": "references", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "works_at", - "dst": "org_kestrel_works", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_kian", - "rel": "works_at", - "dst": "org_atlas_freight", - "confidence": 1.0 - }, - { - "src": "user_omar", - "rel": "works_at", - "dst": "org_atlas_freight", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "located_in", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "located_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "located_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "user_kian", - "rel": "located_in", - "dst": "loc_east_quay", - "confidence": 1.0 - }, - { - "src": "user_omar", - "rel": "located_in", - "dst": "loc_east_quay", - "confidence": 1.0 - }, - { - "src": "org_northbridge_logistics", - "rel": "operates_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "org_kestrel_works", - "rel": "operates_in", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "org_atlas_freight", - "rel": "operates_in", - "dst": "loc_east_quay", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "connected_to", - "dst": "user_bharat", - "confidence": 0.95 - }, - { - "src": "user_bharat", - "rel": "connected_to", - "dst": "user_hiro", - "confidence": 0.95 - }, - { - "src": "user_hiro", - "rel": "connected_to", - "dst": "user_faris", - "confidence": 0.92 - }, - { - "src": "user_ivy", - "rel": "connected_to", - "dst": "user_elin", - "confidence": 0.86 - }, - { - "src": "user_kian", - "rel": "connected_to", - "dst": "user_omar", - "confidence": 0.93 - }, - { - "src": "user_omar", - "rel": "connected_to", - "dst": "user_mika", - "confidence": 0.9 - }, - { - "src": "user_bharat", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_hiro", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_faris", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_ivy", - "rel": "collaborates_on", - "dst": "event_black_kite", - "confidence": 0.9 - }, - { - "src": "user_kian", - "rel": "collaborates_on", - "dst": "event_glass_harbor", - "confidence": 0.9 - }, - { - "src": "user_omar", - "rel": "collaborates_on", - "dst": "event_glass_harbor", - "confidence": 0.9 - }, - { - "src": "user_priya", - "rel": "monitors", - "dst": "event_glass_harbor", - "confidence": 0.9 - }, - { - "src": "user_kian", - "rel": "authored_thread", - "dst": "thr_quiet_manifest", - "confidence": 1.0 - }, - { - "src": "thr_quiet_manifest", - "rel": "discusses", - "dst": "event_glass_harbor", - "confidence": 1.0 - }, - { - "src": "thr_quiet_manifest", - "rel": "references", - "dst": "org_atlas_freight", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "authored_post", - "dst": "post_quay_ledgers", - "confidence": 1.0 - }, - { - "src": "post_quay_ledgers", - "rel": "references", - "dst": "loc_east_quay", - "confidence": 1.0 - }, - { - "src": "post_quay_ledgers", - "rel": "references", - "dst": "event_glass_harbor", - "confidence": 1.0 - }, - { - "src": "event_project_lantern", - "rel": "connected_to", - "dst": "event_glass_harbor", - "confidence": 0.77 - }, - { - "src": "org_atlas_freight", - "rel": "connected_to", - "dst": "org_northbridge_logistics", - "confidence": 0.77 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "alias_steelquill", - "rel": "alias_of", - "dst": "user_bharat", - "confidence": 1.0 - }, - { - "src": "alias_docksparrow", - "rel": "alias_of", - "dst": "user_hiro", - "confidence": 1.0 - }, - { - "src": "alias_monsoonbyte", - "rel": "alias_of", - "dst": "user_diya", - "confidence": 1.0 - }, - { - "src": "alias_nightrelay", - "rel": "alias_of", - "dst": "user_faris", - "confidence": 1.0 - }, - { - "src": "alias_mapleghost", - "rel": "alias_of", - "dst": "user_elin", - "confidence": 1.0 - }, - { - "src": "alias_quartzlotus", - "rel": "alias_of", - "dst": "user_cyrus", - "confidence": 1.0 - }, - { - "src": "alias_emberglass", - "rel": "alias_of", - "dst": "user_nora", - "confidence": 1.0 - }, - { - "src": "alias_basinraven", - "rel": "alias_of", - "dst": "user_mika", - "confidence": 1.0 - }, - { - "src": "alias_tideshard", - "rel": "alias_of", - "dst": "user_soren", - "confidence": 1.0 - }, - { - "src": "alias_hollowsignal", - "rel": "alias_of", - "dst": "user_priya", - "confidence": 1.0 - }, - { - "src": "alias_ironwhisper", - "rel": "alias_of", - "dst": "user_omar", - "confidence": 1.0 - }, - { - "src": "alias_cinderveil", - "rel": "alias_of", - "dst": "user_rhea", - "confidence": 1.0 - }, - { - "src": "alias_sablekeel", - "rel": "alias_of", - "dst": "user_tara", - "confidence": 1.0 - }, - { - "src": "alias_frostledger", - "rel": "alias_of", - "dst": "user_leena", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "works_at", - "dst": "org_helios_labs", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "works_at", - "dst": "org_apex_dynamics", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_01", - "support_nodes": 50 - } - }, - { - "task_type": "fixed_trace", - "question": "North Basin to Foundry Row escalation: which user behind alias_basinraven anchors the Iron Wharf side before the Emberline handoff?", - "answer": "user_mika", - "supporting_edges": [ - { - "src": "alias_basinraven", - "rel": "alias_of", - "dst": "user_mika", - "confidence": 1.0 - }, - { - "src": "alias_basinraven", - "rel": "authored_post", - "dst": "post_customs_tag", - "confidence": 1.0 - }, - { - "src": "post_customs_tag", - "rel": "references", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "post_customs_tag", - "rel": "references", - "dst": "event_iron_wharf", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "authored_thread", - "dst": "thr_customs_breach", - "confidence": 1.0 - }, - { - "src": "thr_customs_breach", - "rel": "discusses", - "dst": "event_iron_wharf", - "confidence": 1.0 - }, - { - "src": "thr_customs_breach", - "rel": "references", - "dst": "org_orion_customs", - "confidence": 1.0 - }, - { - "src": "user_quinn", - "rel": "authored_thread", - "dst": "thr_basin_shift", - "confidence": 1.0 - }, - { - "src": "thr_basin_shift", - "rel": "discusses", - "dst": "event_amber_veil", - "confidence": 1.0 - }, - { - "src": "thr_basin_shift", - "rel": "references", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "authored_thread", - "dst": "thr_foundry_watch", - "confidence": 1.0 - }, - { - "src": "thr_foundry_watch", - "rel": "discusses", - "dst": "event_ember_tide", - "confidence": 1.0 - }, - { - "src": "thr_foundry_watch", - "rel": "references", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "works_at", - "dst": "org_orion_customs", - "confidence": 1.0 - }, - { - "src": "user_quinn", - "rel": "works_at", - "dst": "org_orion_customs", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "works_at", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "works_at", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "located_in", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "user_quinn", - "rel": "located_in", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "located_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "located_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "org_orion_customs", - "rel": "operates_in", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "org_emberline_security", - "rel": "operates_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "connected_to", - "dst": "user_quinn", - "confidence": 0.89 - }, - { - "src": "user_quinn", - "rel": "connected_to", - "dst": "user_nora", - "confidence": 0.88 - }, - { - "src": "user_nora", - "rel": "connected_to", - "dst": "user_rhea", - "confidence": 0.87 - }, - { - "src": "user_mika", - "rel": "collaborates_on", - "dst": "event_iron_wharf", - "confidence": 0.9 - }, - { - "src": "user_quinn", - "rel": "collaborates_on", - "dst": "event_iron_wharf", - "confidence": 0.9 - }, - { - "src": "user_nora", - "rel": "investigates", - "dst": "event_amber_veil", - "confidence": 0.9 - }, - { - "src": "user_rhea", - "rel": "collaborates_on", - "dst": "event_ember_tide", - "confidence": 0.9 - }, - { - "src": "alias_emberglass", - "rel": "authored_post", - "dst": "post_basin_photo", - "confidence": 1.0 - }, - { - "src": "post_basin_photo", - "rel": "references", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "post_basin_photo", - "rel": "references", - "dst": "event_amber_veil", - "confidence": 1.0 - }, - { - "src": "alias_cinderveil", - "rel": "authored_post", - "dst": "post_foundry_map", - "confidence": 1.0 - }, - { - "src": "post_foundry_map", - "rel": "references", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "post_foundry_map", - "rel": "references", - "dst": "event_ember_tide", - "confidence": 1.0 - }, - { - "src": "event_black_kite", - "rel": "connected_to", - "dst": "event_amber_veil", - "confidence": 0.77 - }, - { - "src": "event_ember_tide", - "rel": "connected_to", - "dst": "event_ghost_signal", - "confidence": 0.77 - }, - { - "src": "org_orion_customs", - "rel": "connected_to", - "dst": "org_emberline_security", - "confidence": 0.77 - }, - { - "src": "alias_emberglass", - "rel": "alias_of", - "dst": "user_nora", - "confidence": 1.0 - }, - { - "src": "alias_cinderveil", - "rel": "alias_of", - "dst": "user_rhea", - "confidence": 1.0 - }, - { - "src": "user_priya", - "rel": "connected_to", - "dst": "user_nora", - "confidence": 0.82 - }, - { - "src": "user_kian", - "rel": "connected_to", - "dst": "user_bharat", - "confidence": 0.8 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_steelquill", - "rel": "alias_of", - "dst": "user_bharat", - "confidence": 1.0 - }, - { - "src": "alias_monsoonbyte", - "rel": "alias_of", - "dst": "user_diya", - "confidence": 1.0 - }, - { - "src": "alias_nightrelay", - "rel": "alias_of", - "dst": "user_faris", - "confidence": 1.0 - }, - { - "src": "alias_mapleghost", - "rel": "alias_of", - "dst": "user_elin", - "confidence": 1.0 - }, - { - "src": "alias_docksparrow", - "rel": "alias_of", - "dst": "user_hiro", - "confidence": 1.0 - }, - { - "src": "alias_quartzlotus", - "rel": "alias_of", - "dst": "user_cyrus", - "confidence": 1.0 - }, - { - "src": "alias_tideshard", - "rel": "alias_of", - "dst": "user_soren", - "confidence": 1.0 - }, - { - "src": "alias_hollowsignal", - "rel": "alias_of", - "dst": "user_priya", - "confidence": 1.0 - }, - { - "src": "alias_ironwhisper", - "rel": "alias_of", - "dst": "user_omar", - "confidence": 1.0 - }, - { - "src": "alias_sablekeel", - "rel": "alias_of", - "dst": "user_tara", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "alias_frostledger", - "rel": "alias_of", - "dst": "user_leena", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "works_at", - "dst": "org_helios_labs", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_02", - "support_nodes": 50 - } - }, - { - "task_type": "fixed_trace", - "question": "Harborlight ghost-signal relay: identify the user behind alias_tideshard at the Harborlight / Tidewatch junction.", - "answer": "user_soren", - "supporting_edges": [ - { - "src": "alias_tideshard", - "rel": "alias_of", - "dst": "user_soren", - "confidence": 1.0 - }, - { - "src": "alias_tideshard", - "rel": "authored_post", - "dst": "post_hull_signal", - "confidence": 1.0 - }, - { - "src": "post_hull_signal", - "rel": "references", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "post_hull_signal", - "rel": "references", - "dst": "event_ghost_signal", - "confidence": 1.0 - }, - { - "src": "alias_sablekeel", - "rel": "alias_of", - "dst": "user_tara", - "confidence": 1.0 - }, - { - "src": "alias_sablekeel", - "rel": "authored_post", - "dst": "post_uplink_note", - "confidence": 1.0 - }, - { - "src": "post_uplink_note", - "rel": "references", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "post_uplink_note", - "rel": "references", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "authored_thread", - "dst": "thr_uplink_route", - "confidence": 1.0 - }, - { - "src": "thr_uplink_route", - "rel": "discusses", - "dst": "event_ghost_signal", - "confidence": 1.0 - }, - { - "src": "thr_uplink_route", - "rel": "references", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_tara", - "rel": "authored_thread", - "dst": "thr_ghost_signal_net", - "confidence": 1.0 - }, - { - "src": "thr_ghost_signal_net", - "rel": "discusses", - "dst": "event_ghost_signal", - "confidence": 1.0 - }, - { - "src": "thr_ghost_signal_net", - "rel": "references", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "works_at", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_tara", - "rel": "works_at", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_faris", - "rel": "works_at", - "dst": "org_tidewatch_ops", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "located_in", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "user_tara", - "rel": "located_in", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "user_faris", - "rel": "located_in", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "org_harborlight_transit", - "rel": "operates_in", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "org_tidewatch_ops", - "rel": "operates_in", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "connected_to", - "dst": "user_soren", - "confidence": 0.86 - }, - { - "src": "user_soren", - "rel": "connected_to", - "dst": "user_tara", - "confidence": 0.86 - }, - { - "src": "user_tara", - "rel": "connected_to", - "dst": "user_kian", - "confidence": 0.84 - }, - { - "src": "user_soren", - "rel": "connected_to", - "dst": "user_faris", - "confidence": 0.79 - }, - { - "src": "user_faris", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_soren", - "rel": "collaborates_on", - "dst": "event_ghost_signal", - "confidence": 0.9 - }, - { - "src": "user_tara", - "rel": "reports_on", - "dst": "event_ghost_signal", - "confidence": 0.9 - }, - { - "src": "alias_nightrelay", - "rel": "authored_post", - "dst": "post_sat_phone_ping", - "confidence": 1.0 - }, - { - "src": "post_sat_phone_ping", - "rel": "references", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "post_sat_phone_ping", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "authored_thread", - "dst": "thr_supply_leak", - "confidence": 1.0 - }, - { - "src": "thr_supply_leak", - "rel": "discusses", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_hiro", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "event_ember_tide", - "rel": "connected_to", - "dst": "event_ghost_signal", - "confidence": 0.77 - }, - { - "src": "org_harborlight_transit", - "rel": "connected_to", - "dst": "org_tidewatch_ops", - "confidence": 0.77 - }, - { - "src": "alias_nightrelay", - "rel": "alias_of", - "dst": "user_faris", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_steelquill", - "rel": "alias_of", - "dst": "user_bharat", - "confidence": 1.0 - }, - { - "src": "alias_monsoonbyte", - "rel": "alias_of", - "dst": "user_diya", - "confidence": 1.0 - }, - { - "src": "alias_mapleghost", - "rel": "alias_of", - "dst": "user_elin", - "confidence": 1.0 - }, - { - "src": "alias_docksparrow", - "rel": "alias_of", - "dst": "user_hiro", - "confidence": 1.0 - }, - { - "src": "alias_quartzlotus", - "rel": "alias_of", - "dst": "user_cyrus", - "confidence": 1.0 - }, - { - "src": "alias_emberglass", - "rel": "alias_of", - "dst": "user_nora", - "confidence": 1.0 - }, - { - "src": "alias_basinraven", - "rel": "alias_of", - "dst": "user_mika", - "confidence": 1.0 - }, - { - "src": "alias_hollowsignal", - "rel": "alias_of", - "dst": "user_priya", - "confidence": 1.0 - }, - { - "src": "alias_ironwhisper", - "rel": "alias_of", - "dst": "user_omar", - "confidence": 1.0 - }, - { - "src": "alias_cinderveil", - "rel": "alias_of", - "dst": "user_rhea", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "alias_frostledger", - "rel": "alias_of", - "dst": "user_leena", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "works_at", - "dst": "org_helios_labs", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "located_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_03", - "support_nodes": 50 - } - }, - { - "task_type": "fixed_trace", - "question": "Blueharbor to Black Kite to Lantern overlap: which user is the Blueharbor origin behind alias_monsoonbyte?", - "answer": "user_diya", - "supporting_edges": [ - { - "src": "alias_monsoonbyte", - "rel": "alias_of", - "dst": "user_diya", - "confidence": 1.0 - }, - { - "src": "alias_monsoonbyte", - "rel": "authored_post", - "dst": "post_drone_parts", - "confidence": 1.0 - }, - { - "src": "post_drone_parts", - "rel": "references", - "dst": "event_black_kite", - "confidence": 1.0 - }, - { - "src": "post_drone_parts", - "rel": "references", - "dst": "org_kestrel_works", - "confidence": 1.0 - }, - { - "src": "user_jules", - "rel": "authored_thread", - "dst": "thr_port_audit", - "confidence": 1.0 - }, - { - "src": "thr_port_audit", - "rel": "discusses", - "dst": "event_black_kite", - "confidence": 1.0 - }, - { - "src": "thr_port_audit", - "rel": "references", - "dst": "org_kestrel_works", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "authored_thread", - "dst": "thr_supply_leak", - "confidence": 1.0 - }, - { - "src": "thr_supply_leak", - "rel": "discusses", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "thr_supply_leak", - "rel": "references", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "works_at", - "dst": "org_blueharbor_media", - "confidence": 1.0 - }, - { - "src": "user_jules", - "rel": "works_at", - "dst": "org_blueharbor_media", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "works_at", - "dst": "org_kestrel_works", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "works_at", - "dst": "org_apex_dynamics", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "user_jules", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "located_in", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "org_blueharbor_media", - "rel": "operates_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "org_kestrel_works", - "rel": "operates_in", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "org_apex_dynamics", - "rel": "operates_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "user_faris", - "rel": "connected_to", - "dst": "user_diya", - "confidence": 0.9 - }, - { - "src": "user_cyrus", - "rel": "connected_to", - "dst": "user_gita", - "confidence": 0.83 - }, - { - "src": "user_gita", - "rel": "connected_to", - "dst": "user_jules", - "confidence": 0.82 - }, - { - "src": "user_ivy", - "rel": "connected_to", - "dst": "user_elin", - "confidence": 0.86 - }, - { - "src": "user_diya", - "rel": "investigates", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_ivy", - "rel": "collaborates_on", - "dst": "event_black_kite", - "confidence": 0.9 - }, - { - "src": "user_cyrus", - "rel": "collaborates_on", - "dst": "event_black_kite", - "confidence": 0.9 - }, - { - "src": "user_elin", - "rel": "investigates", - "dst": "event_black_kite", - "confidence": 0.9 - }, - { - "src": "user_jules", - "rel": "reports_on", - "dst": "event_black_kite", - "confidence": 0.9 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "authored_post", - "dst": "post_midnight_manifest", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "event_project_lantern", - "rel": "connected_to", - "dst": "event_glass_harbor", - "confidence": 0.77 - }, - { - "src": "event_black_kite", - "rel": "connected_to", - "dst": "event_amber_veil", - "confidence": 0.77 - }, - { - "src": "user_leena", - "rel": "authored_thread", - "dst": "thr_relay_map", - "confidence": 1.0 - }, - { - "src": "thr_relay_map", - "rel": "discusses", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "user_leena", - "rel": "works_at", - "dst": "org_sunmesh_analytics", - "confidence": 1.0 - }, - { - "src": "user_leena", - "rel": "monitors", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "alias_steelquill", - "rel": "alias_of", - "dst": "user_bharat", - "confidence": 1.0 - }, - { - "src": "alias_nightrelay", - "rel": "alias_of", - "dst": "user_faris", - "confidence": 1.0 - }, - { - "src": "alias_mapleghost", - "rel": "alias_of", - "dst": "user_elin", - "confidence": 1.0 - }, - { - "src": "alias_docksparrow", - "rel": "alias_of", - "dst": "user_hiro", - "confidence": 1.0 - }, - { - "src": "alias_quartzlotus", - "rel": "alias_of", - "dst": "user_cyrus", - "confidence": 1.0 - }, - { - "src": "alias_emberglass", - "rel": "alias_of", - "dst": "user_nora", - "confidence": 1.0 - }, - { - "src": "alias_basinraven", - "rel": "alias_of", - "dst": "user_mika", - "confidence": 1.0 - }, - { - "src": "alias_tideshard", - "rel": "alias_of", - "dst": "user_soren", - "confidence": 1.0 - }, - { - "src": "alias_hollowsignal", - "rel": "alias_of", - "dst": "user_priya", - "confidence": 1.0 - }, - { - "src": "alias_ironwhisper", - "rel": "alias_of", - "dst": "user_omar", - "confidence": 1.0 - }, - { - "src": "alias_cinderveil", - "rel": "alias_of", - "dst": "user_rhea", - "confidence": 1.0 - }, - { - "src": "alias_sablekeel", - "rel": "alias_of", - "dst": "user_tara", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "alias_frostledger", - "rel": "alias_of", - "dst": "user_leena", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_04", - "support_nodes": 50 - } - }, - { - "task_type": "fixed_trace", - "question": "Sector 9 to Dockyard 17 full relay: which user behind alias_steelquill links the Northbridge chain and the Sunmesh monitoring bridge?", - "answer": "user_bharat", - "supporting_edges": [ - { - "src": "alias_steelquill", - "rel": "alias_of", - "dst": "user_bharat", - "confidence": 1.0 - }, - { - "src": "alias_steelquill", - "rel": "authored_post", - "dst": "post_relay_schedule", - "confidence": 1.0 - }, - { - "src": "post_relay_schedule", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "post_relay_schedule", - "rel": "references", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "alias_frostledger", - "rel": "alias_of", - "dst": "user_leena", - "confidence": 1.0 - }, - { - "src": "alias_frostledger", - "rel": "authored_post", - "dst": "post_lantern_route", - "confidence": 1.0 - }, - { - "src": "post_lantern_route", - "rel": "references", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "post_lantern_route", - "rel": "references", - "dst": "org_sunmesh_analytics", - "confidence": 1.0 - }, - { - "src": "user_leena", - "rel": "authored_thread", - "dst": "thr_relay_map", - "confidence": 1.0 - }, - { - "src": "thr_relay_map", - "rel": "discusses", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "thr_relay_map", - "rel": "references", - "dst": "org_sunmesh_analytics", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "authored_thread", - "dst": "thr_supply_leak", - "confidence": 1.0 - }, - { - "src": "thr_supply_leak", - "rel": "discusses", - "dst": "event_project_lantern", - "confidence": 1.0 - }, - { - "src": "thr_supply_leak", - "rel": "references", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_leena", - "rel": "works_at", - "dst": "org_sunmesh_analytics", - "confidence": 1.0 - }, - { - "src": "user_priya", - "rel": "works_at", - "dst": "org_sunmesh_analytics", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "works_at", - "dst": "org_helios_labs", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "located_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "located_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "user_leena", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_priya", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "org_northbridge_logistics", - "rel": "operates_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "org_sunmesh_analytics", - "rel": "operates_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "org_helios_labs", - "rel": "operates_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "connected_to", - "dst": "user_bharat", - "confidence": 0.95 - }, - { - "src": "user_bharat", - "rel": "connected_to", - "dst": "user_hiro", - "confidence": 0.95 - }, - { - "src": "user_diya", - "rel": "connected_to", - "dst": "user_elin", - "confidence": 0.89 - }, - { - "src": "user_elin", - "rel": "connected_to", - "dst": "user_aria", - "confidence": 0.87 - }, - { - "src": "user_aria", - "rel": "connected_to", - "dst": "user_cyrus", - "confidence": 0.84 - }, - { - "src": "user_priya", - "rel": "connected_to", - "dst": "user_leena", - "confidence": 0.91 - }, - { - "src": "user_leena", - "rel": "connected_to", - "dst": "user_aria", - "confidence": 0.83 - }, - { - "src": "user_bharat", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_hiro", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_leena", - "rel": "monitors", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "event_project_lantern", - "rel": "connected_to", - "dst": "event_glass_harbor", - "confidence": 0.77 - }, - { - "src": "org_atlas_freight", - "rel": "connected_to", - "dst": "org_northbridge_logistics", - "confidence": 0.77 - }, - { - "src": "alias_docksparrow", - "rel": "alias_of", - "dst": "user_hiro", - "confidence": 1.0 - }, - { - "src": "alias_mapleghost", - "rel": "alias_of", - "dst": "user_elin", - "confidence": 1.0 - }, - { - "src": "alias_hollowsignal", - "rel": "alias_of", - "dst": "user_priya", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_monsoonbyte", - "rel": "alias_of", - "dst": "user_diya", - "confidence": 1.0 - }, - { - "src": "alias_nightrelay", - "rel": "alias_of", - "dst": "user_faris", - "confidence": 1.0 - }, - { - "src": "alias_quartzlotus", - "rel": "alias_of", - "dst": "user_cyrus", - "confidence": 1.0 - }, - { - "src": "alias_emberglass", - "rel": "alias_of", - "dst": "user_nora", - "confidence": 1.0 - }, - { - "src": "alias_basinraven", - "rel": "alias_of", - "dst": "user_mika", - "confidence": 1.0 - }, - { - "src": "alias_tideshard", - "rel": "alias_of", - "dst": "user_soren", - "confidence": 1.0 - }, - { - "src": "alias_ironwhisper", - "rel": "alias_of", - "dst": "user_omar", - "confidence": 1.0 - }, - { - "src": "alias_cinderveil", - "rel": "alias_of", - "dst": "user_rhea", - "confidence": 1.0 - }, - { - "src": "alias_sablekeel", - "rel": "alias_of", - "dst": "user_tara", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "works_at", - "dst": "org_apex_dynamics", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "works_at", - "dst": "org_blueharbor_media", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "user_elin", - "rel": "works_at", - "dst": "org_helios_labs", - "confidence": 1.0 - }, - { - "src": "user_elin", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_faris", - "rel": "works_at", - "dst": "org_tidewatch_ops", - "confidence": 1.0 - }, - { - "src": "user_faris", - "rel": "located_in", - "dst": "loc_rivergate", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_05", - "support_nodes": 50 - } - }, - { - "task_type": "fixed_trace", - "question": "Foundry Row, North Basin, and Uplink Yard spread: identify the user behind alias_emberglass before the Harborlight relay takes over.", - "answer": "user_nora", - "supporting_edges": [ - { - "src": "alias_emberglass", - "rel": "alias_of", - "dst": "user_nora", - "confidence": 1.0 - }, - { - "src": "alias_emberglass", - "rel": "authored_post", - "dst": "post_basin_photo", - "confidence": 1.0 - }, - { - "src": "post_basin_photo", - "rel": "references", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "post_basin_photo", - "rel": "references", - "dst": "event_amber_veil", - "confidence": 1.0 - }, - { - "src": "alias_cinderveil", - "rel": "alias_of", - "dst": "user_rhea", - "confidence": 1.0 - }, - { - "src": "alias_cinderveil", - "rel": "authored_post", - "dst": "post_foundry_map", - "confidence": 1.0 - }, - { - "src": "post_foundry_map", - "rel": "references", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "post_foundry_map", - "rel": "references", - "dst": "event_ember_tide", - "confidence": 1.0 - }, - { - "src": "alias_sablekeel", - "rel": "alias_of", - "dst": "user_tara", - "confidence": 1.0 - }, - { - "src": "alias_sablekeel", - "rel": "authored_post", - "dst": "post_uplink_note", - "confidence": 1.0 - }, - { - "src": "post_uplink_note", - "rel": "references", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "post_uplink_note", - "rel": "references", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "authored_thread", - "dst": "thr_foundry_watch", - "confidence": 1.0 - }, - { - "src": "thr_foundry_watch", - "rel": "discusses", - "dst": "event_ember_tide", - "confidence": 1.0 - }, - { - "src": "thr_foundry_watch", - "rel": "references", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "authored_thread", - "dst": "thr_ember_tide_watch", - "confidence": 1.0 - }, - { - "src": "thr_ember_tide_watch", - "rel": "discusses", - "dst": "event_ember_tide", - "confidence": 1.0 - }, - { - "src": "thr_ember_tide_watch", - "rel": "references", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "authored_thread", - "dst": "thr_uplink_route", - "confidence": 1.0 - }, - { - "src": "thr_uplink_route", - "rel": "discusses", - "dst": "event_ghost_signal", - "confidence": 1.0 - }, - { - "src": "thr_uplink_route", - "rel": "references", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "works_at", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "works_at", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "works_at", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_tara", - "rel": "works_at", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "located_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "located_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "located_in", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "user_tara", - "rel": "located_in", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "org_emberline_security", - "rel": "operates_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "org_harborlight_transit", - "rel": "operates_in", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "connected_to", - "dst": "user_rhea", - "confidence": 0.87 - }, - { - "src": "user_rhea", - "rel": "connected_to", - "dst": "user_soren", - "confidence": 0.86 - }, - { - "src": "user_soren", - "rel": "connected_to", - "dst": "user_tara", - "confidence": 0.86 - }, - { - "src": "user_nora", - "rel": "investigates", - "dst": "event_amber_veil", - "confidence": 0.9 - }, - { - "src": "user_rhea", - "rel": "collaborates_on", - "dst": "event_ember_tide", - "confidence": 0.9 - }, - { - "src": "user_soren", - "rel": "collaborates_on", - "dst": "event_ghost_signal", - "confidence": 0.9 - }, - { - "src": "user_tara", - "rel": "reports_on", - "dst": "event_ghost_signal", - "confidence": 0.9 - }, - { - "src": "event_ember_tide", - "rel": "connected_to", - "dst": "event_ghost_signal", - "confidence": 0.77 - }, - { - "src": "org_harborlight_transit", - "rel": "connected_to", - "dst": "org_tidewatch_ops", - "confidence": 0.77 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_steelquill", - "rel": "alias_of", - "dst": "user_bharat", - "confidence": 1.0 - }, - { - "src": "alias_monsoonbyte", - "rel": "alias_of", - "dst": "user_diya", - "confidence": 1.0 - }, - { - "src": "alias_nightrelay", - "rel": "alias_of", - "dst": "user_faris", - "confidence": 1.0 - }, - { - "src": "alias_mapleghost", - "rel": "alias_of", - "dst": "user_elin", - "confidence": 1.0 - }, - { - "src": "alias_docksparrow", - "rel": "alias_of", - "dst": "user_hiro", - "confidence": 1.0 - }, - { - "src": "alias_quartzlotus", - "rel": "alias_of", - "dst": "user_cyrus", - "confidence": 1.0 - }, - { - "src": "alias_basinraven", - "rel": "alias_of", - "dst": "user_mika", - "confidence": 1.0 - }, - { - "src": "alias_tideshard", - "rel": "alias_of", - "dst": "user_soren", - "confidence": 1.0 - }, - { - "src": "alias_hollowsignal", - "rel": "alias_of", - "dst": "user_priya", - "confidence": 1.0 - }, - { - "src": "alias_ironwhisper", - "rel": "alias_of", - "dst": "user_omar", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "alias_frostledger", - "rel": "alias_of", - "dst": "user_leena", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "works_at", - "dst": "org_helios_labs", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_06", - "support_nodes": 50 - } - }, - { - "task_type": "fixed_trace", - "question": "Freight and customs bridge: which Atlas Freight user behind alias_lanternmoth connects Glass Harbor with the Northbridge chain?", - "answer": "user_kian", - "supporting_edges": [ - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "authored_post", - "dst": "post_quay_ledgers", - "confidence": 1.0 - }, - { - "src": "post_quay_ledgers", - "rel": "references", - "dst": "loc_east_quay", - "confidence": 1.0 - }, - { - "src": "post_quay_ledgers", - "rel": "references", - "dst": "event_glass_harbor", - "confidence": 1.0 - }, - { - "src": "user_kian", - "rel": "authored_thread", - "dst": "thr_quiet_manifest", - "confidence": 1.0 - }, - { - "src": "thr_quiet_manifest", - "rel": "discusses", - "dst": "event_glass_harbor", - "confidence": 1.0 - }, - { - "src": "thr_quiet_manifest", - "rel": "references", - "dst": "org_atlas_freight", - "confidence": 1.0 - }, - { - "src": "user_kian", - "rel": "works_at", - "dst": "org_atlas_freight", - "confidence": 1.0 - }, - { - "src": "user_omar", - "rel": "works_at", - "dst": "org_atlas_freight", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_kian", - "rel": "located_in", - "dst": "loc_east_quay", - "confidence": 1.0 - }, - { - "src": "user_omar", - "rel": "located_in", - "dst": "loc_east_quay", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "located_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "located_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "org_atlas_freight", - "rel": "operates_in", - "dst": "loc_east_quay", - "confidence": 1.0 - }, - { - "src": "org_northbridge_logistics", - "rel": "operates_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "user_kian", - "rel": "connected_to", - "dst": "user_omar", - "confidence": 0.93 - }, - { - "src": "user_omar", - "rel": "connected_to", - "dst": "user_mika", - "confidence": 0.9 - }, - { - "src": "user_kian", - "rel": "connected_to", - "dst": "user_bharat", - "confidence": 0.8 - }, - { - "src": "user_bharat", - "rel": "connected_to", - "dst": "user_hiro", - "confidence": 0.95 - }, - { - "src": "user_kian", - "rel": "collaborates_on", - "dst": "event_glass_harbor", - "confidence": 0.9 - }, - { - "src": "user_omar", - "rel": "collaborates_on", - "dst": "event_glass_harbor", - "confidence": 0.9 - }, - { - "src": "user_priya", - "rel": "monitors", - "dst": "event_glass_harbor", - "confidence": 0.9 - }, - { - "src": "user_bharat", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "user_hiro", - "rel": "collaborates_on", - "dst": "event_project_lantern", - "confidence": 0.9 - }, - { - "src": "alias_docksparrow", - "rel": "authored_post", - "dst": "post_shift_roster", - "confidence": 1.0 - }, - { - "src": "post_shift_roster", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "post_shift_roster", - "rel": "references", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "authored_post", - "dst": "post_midnight_manifest", - "confidence": 1.0 - }, - { - "src": "post_midnight_manifest", - "rel": "references", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "authored_thread", - "dst": "thr_supply_leak", - "confidence": 1.0 - }, - { - "src": "thr_supply_leak", - "rel": "references", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "org_atlas_freight", - "rel": "connected_to", - "dst": "org_northbridge_logistics", - "confidence": 0.77 - }, - { - "src": "alias_ironwhisper", - "rel": "alias_of", - "dst": "user_omar", - "confidence": 1.0 - }, - { - "src": "alias_steelquill", - "rel": "alias_of", - "dst": "user_bharat", - "confidence": 1.0 - }, - { - "src": "alias_docksparrow", - "rel": "alias_of", - "dst": "user_hiro", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_monsoonbyte", - "rel": "alias_of", - "dst": "user_diya", - "confidence": 1.0 - }, - { - "src": "alias_nightrelay", - "rel": "alias_of", - "dst": "user_faris", - "confidence": 1.0 - }, - { - "src": "alias_mapleghost", - "rel": "alias_of", - "dst": "user_elin", - "confidence": 1.0 - }, - { - "src": "alias_quartzlotus", - "rel": "alias_of", - "dst": "user_cyrus", - "confidence": 1.0 - }, - { - "src": "alias_emberglass", - "rel": "alias_of", - "dst": "user_nora", - "confidence": 1.0 - }, - { - "src": "alias_basinraven", - "rel": "alias_of", - "dst": "user_mika", - "confidence": 1.0 - }, - { - "src": "alias_tideshard", - "rel": "alias_of", - "dst": "user_soren", - "confidence": 1.0 - }, - { - "src": "alias_hollowsignal", - "rel": "alias_of", - "dst": "user_priya", - "confidence": 1.0 - }, - { - "src": "alias_cinderveil", - "rel": "alias_of", - "dst": "user_rhea", - "confidence": 1.0 - }, - { - "src": "alias_sablekeel", - "rel": "alias_of", - "dst": "user_tara", - "confidence": 1.0 - }, - { - "src": "alias_frostledger", - "rel": "alias_of", - "dst": "user_leena", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "works_at", - "dst": "org_helios_labs", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "works_at", - "dst": "org_apex_dynamics", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "works_at", - "dst": "org_blueharbor_media", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "user_elin", - "rel": "works_at", - "dst": "org_helios_labs", - "confidence": 1.0 - }, - { - "src": "user_elin", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_faris", - "rel": "works_at", - "dst": "org_tidewatch_ops", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_07", - "support_nodes": 50 - } - }, - { - "task_type": "fixed_trace", - "question": "Black Kite, Amber Veil, and Iron Wharf overlap: which user behind alias_quartzlotus is the Apex-side collaborator?", - "answer": "user_cyrus", - "supporting_edges": [ - { - "src": "alias_quartzlotus", - "rel": "alias_of", - "dst": "user_cyrus", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "works_at", - "dst": "org_apex_dynamics", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "org_apex_dynamics", - "rel": "operates_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "collaborates_on", - "dst": "event_black_kite", - "confidence": 0.9 - }, - { - "src": "user_jules", - "rel": "authored_thread", - "dst": "thr_port_audit", - "confidence": 1.0 - }, - { - "src": "thr_port_audit", - "rel": "discusses", - "dst": "event_black_kite", - "confidence": 1.0 - }, - { - "src": "alias_monsoonbyte", - "rel": "authored_post", - "dst": "post_drone_parts", - "confidence": 1.0 - }, - { - "src": "post_drone_parts", - "rel": "references", - "dst": "event_black_kite", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "investigates", - "dst": "event_amber_veil", - "confidence": 0.9 - }, - { - "src": "user_quinn", - "rel": "authored_thread", - "dst": "thr_basin_shift", - "confidence": 1.0 - }, - { - "src": "thr_basin_shift", - "rel": "discusses", - "dst": "event_amber_veil", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "collaborates_on", - "dst": "event_iron_wharf", - "confidence": 0.9 - }, - { - "src": "user_mika", - "rel": "authored_thread", - "dst": "thr_customs_breach", - "confidence": 1.0 - }, - { - "src": "thr_customs_breach", - "rel": "discusses", - "dst": "event_iron_wharf", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "works_at", - "dst": "org_kestrel_works", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "works_at", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "works_at", - "dst": "org_orion_customs", - "confidence": 1.0 - }, - { - "src": "user_quinn", - "rel": "works_at", - "dst": "org_orion_customs", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "located_in", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "located_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "located_in", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "user_quinn", - "rel": "located_in", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "org_kestrel_works", - "rel": "operates_in", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "org_emberline_security", - "rel": "operates_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "org_orion_customs", - "rel": "operates_in", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "connected_to", - "dst": "user_gita", - "confidence": 0.83 - }, - { - "src": "user_ivy", - "rel": "connected_to", - "dst": "user_elin", - "confidence": 0.86 - }, - { - "src": "user_mika", - "rel": "connected_to", - "dst": "user_quinn", - "confidence": 0.89 - }, - { - "src": "user_quinn", - "rel": "connected_to", - "dst": "user_nora", - "confidence": 0.88 - }, - { - "src": "user_nora", - "rel": "connected_to", - "dst": "user_rhea", - "confidence": 0.87 - }, - { - "src": "event_black_kite", - "rel": "connected_to", - "dst": "event_amber_veil", - "confidence": 0.77 - }, - { - "src": "org_orion_customs", - "rel": "connected_to", - "dst": "org_emberline_security", - "confidence": 0.77 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_basinraven", - "rel": "alias_of", - "dst": "user_mika", - "confidence": 1.0 - }, - { - "src": "alias_emberglass", - "rel": "alias_of", - "dst": "user_nora", - "confidence": 1.0 - }, - { - "src": "alias_steelquill", - "rel": "alias_of", - "dst": "user_bharat", - "confidence": 1.0 - }, - { - "src": "alias_monsoonbyte", - "rel": "alias_of", - "dst": "user_diya", - "confidence": 1.0 - }, - { - "src": "alias_nightrelay", - "rel": "alias_of", - "dst": "user_faris", - "confidence": 1.0 - }, - { - "src": "alias_mapleghost", - "rel": "alias_of", - "dst": "user_elin", - "confidence": 1.0 - }, - { - "src": "alias_docksparrow", - "rel": "alias_of", - "dst": "user_hiro", - "confidence": 1.0 - }, - { - "src": "alias_tideshard", - "rel": "alias_of", - "dst": "user_soren", - "confidence": 1.0 - }, - { - "src": "alias_hollowsignal", - "rel": "alias_of", - "dst": "user_priya", - "confidence": 1.0 - }, - { - "src": "alias_ironwhisper", - "rel": "alias_of", - "dst": "user_omar", - "confidence": 1.0 - }, - { - "src": "alias_cinderveil", - "rel": "alias_of", - "dst": "user_rhea", - "confidence": 1.0 - }, - { - "src": "alias_sablekeel", - "rel": "alias_of", - "dst": "user_tara", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "alias_frostledger", - "rel": "alias_of", - "dst": "user_leena", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_08", - "support_nodes": 50 - } - }, - { - "task_type": "fixed_trace", - "question": "Ghost Signal and Ember Tide relay: which user behind alias_sablekeel is the Harborlight reporting endpoint?", - "answer": "user_tara", - "supporting_edges": [ - { - "src": "alias_sablekeel", - "rel": "alias_of", - "dst": "user_tara", - "confidence": 1.0 - }, - { - "src": "alias_sablekeel", - "rel": "authored_post", - "dst": "post_uplink_note", - "confidence": 1.0 - }, - { - "src": "post_uplink_note", - "rel": "references", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "post_uplink_note", - "rel": "references", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "alias_tideshard", - "rel": "alias_of", - "dst": "user_soren", - "confidence": 1.0 - }, - { - "src": "alias_tideshard", - "rel": "authored_post", - "dst": "post_hull_signal", - "confidence": 1.0 - }, - { - "src": "post_hull_signal", - "rel": "references", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "post_hull_signal", - "rel": "references", - "dst": "event_ghost_signal", - "confidence": 1.0 - }, - { - "src": "user_tara", - "rel": "authored_thread", - "dst": "thr_ghost_signal_net", - "confidence": 1.0 - }, - { - "src": "thr_ghost_signal_net", - "rel": "discusses", - "dst": "event_ghost_signal", - "confidence": 1.0 - }, - { - "src": "thr_ghost_signal_net", - "rel": "references", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "authored_thread", - "dst": "thr_uplink_route", - "confidence": 1.0 - }, - { - "src": "thr_uplink_route", - "rel": "discusses", - "dst": "event_ghost_signal", - "confidence": 1.0 - }, - { - "src": "thr_uplink_route", - "rel": "references", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "authored_thread", - "dst": "thr_ember_tide_watch", - "confidence": 1.0 - }, - { - "src": "thr_ember_tide_watch", - "rel": "discusses", - "dst": "event_ember_tide", - "confidence": 1.0 - }, - { - "src": "thr_ember_tide_watch", - "rel": "references", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "user_tara", - "rel": "works_at", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "works_at", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "works_at", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "works_at", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_tara", - "rel": "located_in", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "located_in", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "located_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "located_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "org_harborlight_transit", - "rel": "operates_in", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "org_emberline_security", - "rel": "operates_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "connected_to", - "dst": "user_soren", - "confidence": 0.86 - }, - { - "src": "user_soren", - "rel": "connected_to", - "dst": "user_tara", - "confidence": 0.86 - }, - { - "src": "user_nora", - "rel": "connected_to", - "dst": "user_rhea", - "confidence": 0.87 - }, - { - "src": "user_rhea", - "rel": "collaborates_on", - "dst": "event_ember_tide", - "confidence": 0.9 - }, - { - "src": "user_soren", - "rel": "collaborates_on", - "dst": "event_ghost_signal", - "confidence": 0.9 - }, - { - "src": "user_tara", - "rel": "reports_on", - "dst": "event_ghost_signal", - "confidence": 0.9 - }, - { - "src": "event_ember_tide", - "rel": "connected_to", - "dst": "event_ghost_signal", - "confidence": 0.77 - }, - { - "src": "org_harborlight_transit", - "rel": "connected_to", - "dst": "org_tidewatch_ops", - "confidence": 0.77 - }, - { - "src": "alias_cinderveil", - "rel": "alias_of", - "dst": "user_rhea", - "confidence": 1.0 - }, - { - "src": "alias_emberglass", - "rel": "alias_of", - "dst": "user_nora", - "confidence": 1.0 - }, - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_steelquill", - "rel": "alias_of", - "dst": "user_bharat", - "confidence": 1.0 - }, - { - "src": "alias_monsoonbyte", - "rel": "alias_of", - "dst": "user_diya", - "confidence": 1.0 - }, - { - "src": "alias_nightrelay", - "rel": "alias_of", - "dst": "user_faris", - "confidence": 1.0 - }, - { - "src": "alias_mapleghost", - "rel": "alias_of", - "dst": "user_elin", - "confidence": 1.0 - }, - { - "src": "alias_docksparrow", - "rel": "alias_of", - "dst": "user_hiro", - "confidence": 1.0 - }, - { - "src": "alias_quartzlotus", - "rel": "alias_of", - "dst": "user_cyrus", - "confidence": 1.0 - }, - { - "src": "alias_basinraven", - "rel": "alias_of", - "dst": "user_mika", - "confidence": 1.0 - }, - { - "src": "alias_hollowsignal", - "rel": "alias_of", - "dst": "user_priya", - "confidence": 1.0 - }, - { - "src": "alias_ironwhisper", - "rel": "alias_of", - "dst": "user_omar", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "alias_frostledger", - "rel": "alias_of", - "dst": "user_leena", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "works_at", - "dst": "org_helios_labs", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "located_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "works_at", - "dst": "org_apex_dynamics", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_09", - "support_nodes": 50 - } - }, - { - "task_type": "fixed_trace", - "question": "End-to-end benchmark sweep: across Lantern, Black Kite, Glass Harbor, Iron Wharf, Ember Tide, and Ghost Signal, which user behind alias_hollowsignal anchors the Sunmesh monitoring side?", - "answer": "user_priya", - "supporting_edges": [ - { - "src": "alias_orchidfox", - "rel": "alias_of", - "dst": "user_ivy", - "confidence": 1.0 - }, - { - "src": "alias_steelquill", - "rel": "alias_of", - "dst": "user_bharat", - "confidence": 1.0 - }, - { - "src": "alias_monsoonbyte", - "rel": "alias_of", - "dst": "user_diya", - "confidence": 1.0 - }, - { - "src": "alias_nightrelay", - "rel": "alias_of", - "dst": "user_faris", - "confidence": 1.0 - }, - { - "src": "alias_mapleghost", - "rel": "alias_of", - "dst": "user_elin", - "confidence": 1.0 - }, - { - "src": "alias_docksparrow", - "rel": "alias_of", - "dst": "user_hiro", - "confidence": 1.0 - }, - { - "src": "alias_quartzlotus", - "rel": "alias_of", - "dst": "user_cyrus", - "confidence": 1.0 - }, - { - "src": "alias_emberglass", - "rel": "alias_of", - "dst": "user_nora", - "confidence": 1.0 - }, - { - "src": "alias_basinraven", - "rel": "alias_of", - "dst": "user_mika", - "confidence": 1.0 - }, - { - "src": "alias_tideshard", - "rel": "alias_of", - "dst": "user_soren", - "confidence": 1.0 - }, - { - "src": "alias_hollowsignal", - "rel": "alias_of", - "dst": "user_priya", - "confidence": 1.0 - }, - { - "src": "alias_ironwhisper", - "rel": "alias_of", - "dst": "user_omar", - "confidence": 1.0 - }, - { - "src": "alias_cinderveil", - "rel": "alias_of", - "dst": "user_rhea", - "confidence": 1.0 - }, - { - "src": "alias_sablekeel", - "rel": "alias_of", - "dst": "user_tara", - "confidence": 1.0 - }, - { - "src": "alias_lanternmoth", - "rel": "alias_of", - "dst": "user_kian", - "confidence": 1.0 - }, - { - "src": "alias_frostledger", - "rel": "alias_of", - "dst": "user_leena", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "works_at", - "dst": "org_helios_labs", - "confidence": 1.0 - }, - { - "src": "user_aria", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_bharat", - "rel": "located_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "works_at", - "dst": "org_apex_dynamics", - "confidence": 1.0 - }, - { - "src": "user_cyrus", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "works_at", - "dst": "org_blueharbor_media", - "confidence": 1.0 - }, - { - "src": "user_diya", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "user_elin", - "rel": "works_at", - "dst": "org_helios_labs", - "confidence": 1.0 - }, - { - "src": "user_elin", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_faris", - "rel": "works_at", - "dst": "org_tidewatch_ops", - "confidence": 1.0 - }, - { - "src": "user_faris", - "rel": "located_in", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "user_gita", - "rel": "works_at", - "dst": "org_apex_dynamics", - "confidence": 1.0 - }, - { - "src": "user_gita", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "works_at", - "dst": "org_northbridge_logistics", - "confidence": 1.0 - }, - { - "src": "user_hiro", - "rel": "located_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "works_at", - "dst": "org_kestrel_works", - "confidence": 1.0 - }, - { - "src": "user_ivy", - "rel": "located_in", - "dst": "loc_rivergate", - "confidence": 1.0 - }, - { - "src": "user_jules", - "rel": "works_at", - "dst": "org_blueharbor_media", - "confidence": 1.0 - }, - { - "src": "user_jules", - "rel": "located_in", - "dst": "loc_old_town", - "confidence": 1.0 - }, - { - "src": "user_kian", - "rel": "works_at", - "dst": "org_atlas_freight", - "confidence": 1.0 - }, - { - "src": "user_kian", - "rel": "located_in", - "dst": "loc_east_quay", - "confidence": 1.0 - }, - { - "src": "user_leena", - "rel": "works_at", - "dst": "org_sunmesh_analytics", - "confidence": 1.0 - }, - { - "src": "user_leena", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "works_at", - "dst": "org_orion_customs", - "confidence": 1.0 - }, - { - "src": "user_mika", - "rel": "located_in", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "works_at", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_nora", - "rel": "located_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "user_omar", - "rel": "works_at", - "dst": "org_atlas_freight", - "confidence": 1.0 - }, - { - "src": "user_omar", - "rel": "located_in", - "dst": "loc_east_quay", - "confidence": 1.0 - }, - { - "src": "user_priya", - "rel": "works_at", - "dst": "org_sunmesh_analytics", - "confidence": 1.0 - }, - { - "src": "user_priya", - "rel": "located_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "user_quinn", - "rel": "works_at", - "dst": "org_orion_customs", - "confidence": 1.0 - }, - { - "src": "user_quinn", - "rel": "located_in", - "dst": "loc_north_basin", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "works_at", - "dst": "org_emberline_security", - "confidence": 1.0 - }, - { - "src": "user_rhea", - "rel": "located_in", - "dst": "loc_foundry_row", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "works_at", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_soren", - "rel": "located_in", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "user_tara", - "rel": "works_at", - "dst": "org_harborlight_transit", - "confidence": 1.0 - }, - { - "src": "user_tara", - "rel": "located_in", - "dst": "loc_uplink_yard", - "confidence": 1.0 - }, - { - "src": "org_helios_labs", - "rel": "operates_in", - "dst": "loc_sector9", - "confidence": 1.0 - }, - { - "src": "org_northbridge_logistics", - "rel": "operates_in", - "dst": "loc_dockyard17", - "confidence": 1.0 - } - ], - "metadata": { - "difficulty": "high", - "difficulty_level": 3, - "question_id": "high_10", - "support_nodes": 55 - } - } - ], - "llm_generate_remaining_graph": true, - "llm_generate_remaining_tasks": false, - "llm_generated_edge_budget": 48, - "llm_generated_task_budget": 0, - "llm_generation_parallel": true, - "llm_generation_workers": 4, - "llm_generation_retries": 3, - "allow_template_fallback_on_llm_failure": false - } -} \ No newline at end of file diff --git a/scratch/osint/datasets/fixed_levels/shared_config_fixed_levels.json b/scratch/osint/datasets/fixed_levels/shared_config_fixed_levels.json deleted file mode 100644 index 268e55c26d330c6ca1d041cd75f5665b5ea87847..0000000000000000000000000000000000000000 --- a/scratch/osint/datasets/fixed_levels/shared_config_fixed_levels.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "environment": { - "n_users": 24, - "alias_density": 0.2, - "noise_level": 0.12, - "red_herring_rate": 0.08, - "max_steps": 24, - "seed": 2026 - }, - "swarm": { - "enabled": true, - "max_agents": 3, - "max_breadth": 2, - "max_width": 2, - "max_depth": 2, - "planner_rounds": 2, - "tools_per_agent": 1 - }, - "spawn_reward": { - "lambda_parallel": 0.15, - "lambda_finish": 0.2, - "anneal": 1.0, - "max_parallel_hint": 3 - }, - "seeding": { - "seeded_nodes": [], - "seeded_edges": [], - "seeded_questions": [], - "llm_generate_remaining_graph": true, - "llm_generate_remaining_tasks": false, - "llm_generated_edge_budget": 64, - "llm_generated_task_budget": 0, - "llm_generation_parallel": true, - "llm_generation_workers": 4, - "llm_generation_retries": 3, - "allow_template_fallback_on_llm_failure": false - }, - "llm": { - "provider": "ollama", - "model": "qwen3:2b", - "temperature": 0.05, - "max_tokens": 384, - "timeout_seconds": 240, - "ollama_base_url": "http://127.0.0.1:11434", - "openai_base_url": "https://api.openai.com/v1", - "openai_api_key_env": "OPENAI_API_KEY", - "openai_api_key": "" - }, - "runtime": { - "default_episodes": 30, - "leaderboard_path": "datasets/fixed_levels/leaderboard_fixed_levels.json", - "dashboard_path": "datasets/fixed_levels/dashboard_fixed_levels.html", - "sweep_dashboard_dir": "datasets/fixed_levels/sweep_dashboards" - } -} diff --git a/scratch/osint/docs/reward_design_notes.md b/scratch/osint/docs/reward_design_notes.md deleted file mode 100644 index 7041d248b1e22e864a0ca50dbfe3dc2fbc32f7f7..0000000000000000000000000000000000000000 --- a/scratch/osint/docs/reward_design_notes.md +++ /dev/null @@ -1,94 +0,0 @@ -# Reward Design Notes - -This environment uses a composite reward that adapts ideas from: - -- AutoGraph-R1 (arXiv:2510.15339) -- UniRel (arXiv:2512.17043) -- DeepPath (EMNLP 2017, D17-1060) -- Multi-Hop KG Reasoning with Reward Shaping (EMNLP 2018, D18-1362) -- Kimi K2.5 (arXiv:2602.02276) for PARL-style swarm auxiliary shaping - -Additional related context consulted: - -- MINERVA (arXiv:1711.05851) for query-conditioned walk-style reasoning over KG paths. - -## Components in this Branch - -The implementation follows a staged reward design: - -1. edge-level rewards during graph construction (`ADD_EDGE`) -2. answer-level rewards for retrieval usefulness and final task utility (`ANSWER`) -3. evaluation-level composite leaderboard score for benchmark ranking - -### 1) Edge addition reward - -For each `ADD_EDGE`, the reward combines: - -- Global accuracy term (DeepPath): - - $r_{global} = +1$ if a candidate edge is correct, else $-1$ (scaled in code for stability). -- Soft shaping term (D18 reward shaping): - - $R = R_b + (1 - R_b) f(s, r, o)$, where $f$ is a soft fact plausibility score. - - In code, $f$ is approximated by relation/type priors plus small domain priors. -- Efficiency term (DeepPath): - - $r_{efficiency} \propto 1 / \text{step\_count}$. -- Diversity term (DeepPath): - - novelty from cosine dissimilarity of edge signatures; repeated patterns are down-weighted. -- Relation/entity informativeness (UniRel): - - relation rarity via normalized IDF of relation labels, - - entity informativeness via inverse hub-penalty. -- Connectivity gain term: - - rewards bridge edges that connect previously disconnected graph regions. - -### 2) Final answer reward - -For `ANSWER`, the reward combines: - -- format validity, -- answer correctness, -- knowledge-carrying utility (AutoGraph-R1 style): - - $R_C(q, y, G) = \mathbb{{I}}[\text{{deducible}}(q, y \mid G)]$. -- knowledge-indexing utility (AutoGraph-R1 style): - - $R_I(q, D_{{gold}}, G) = |Top\text{{-}}k(G,q) \cap D_{{gold}}| / |D_{{gold}}|$, - - approximated in this environment with evidence recall over tool outputs. -- connectivity (UniRel style): - - discrete connectivity reward over extracted seed entities, normalized for stable mixing. -- graph F1 against supporting edges, -- compactness penalty for unnecessary extra edges, -- efficiency bonus, -- relation/entity informativeness for the constructed subgraph, -- repetition penalty to discourage redundant relation generation patterns. - -UniRel-style aggregate view represented in this branch: - -$$ -R(a) \approx R_{{fmt}} + R_{{con}} + w_1 R_{{ent}} + w_2 R_{{rel}} + \text{{task utility terms}} -$$ - -with task utility terms coming from AutoGraph-inspired $R_C$ and $R_I$ components. - -## Telemetry - -Per-step component rewards are aggregated into `info["reward_components"]`, enabling: - -- richer benchmark summaries, -- leaderboard ranking by composite utility, -- visual diagnostics in dashboard exports. - -Evaluation also computes derived retrieval and structural utility signals used in leaderboard ranking. - -## Future Multi-Agent Notes - -This branch now includes a low-width swarm baseline orchestrator that adds PARL-style auxiliary shaping on top of the core edge and answer rewards. - -The helper implementation is in: - -- `src/osint_env/env/spawn_reward_hooks.py` - -It follows the Kimi K2.5 style decomposition: - -- $r_{{PARL}}(x,y) = r_{{perf}}(x,y) + \lambda_1 r_{{parallel}} + \lambda_2 r_{{finish}}$, -- optional critical-steps shaping for latency-sensitive training, -- optional annealing of $\lambda_1, \lambda_2$ toward zero, -- optional breadth/depth shaping hooks for future branch integration. - -The expanded project-level walkthrough is in `README.md` under "Reward Design (Integrated Notes)". diff --git a/scratch/osint/inference.py b/scratch/osint/inference.py deleted file mode 100644 index 3284bab66880974ba47675cf4be0f41f70fdf7e5..0000000000000000000000000000000000000000 --- a/scratch/osint/inference.py +++ /dev/null @@ -1,509 +0,0 @@ -from __future__ import annotations - -import json -import os -from pathlib import Path -from typing import Any - -from osint_env.agents.single_agent import SingleAgentRunner -from osint_env.agents.swarm_agent import SwarmAgentRunner -from osint_env.config import clone_environment_config, load_seeding_config, load_shared_config -from osint_env.domain.models import EnvironmentConfig -from osint_env.env.environment import OSINTEnvironment -from osint_env.env.reward import compute_graph_f1 -from osint_env.eval.leaderboard import append_leaderboard_record, load_leaderboard -from osint_env.eval.metrics import EvalMetrics -from osint_env.llm import build_llm_client -from osint_env.viz import export_dashboard - - -CONFIG_PATH = os.getenv("CONFIG_PATH", "datasets/fixed_levels/shared_config_fixed_levels.json") -SEED_FILE = os.getenv("SEED_FILE", "datasets/fixed_levels/seed_fixed_levels.json") -AGENT_MODE = os.getenv("AGENT_MODE", "swarm") -LLM_PROVIDER = os.getenv("LLM_PROVIDER", "openai") -MODEL_NAME = os.getenv("MODEL_NAME", "gpt-5.4") -OLLAMA_BASE_URL = os.getenv("OLLAMA_BASE_URL", "") -OPENAI_BASE_URL = os.getenv("OPENAI_BASE_URL", "") -OPENAI_API_KEY = os.getenv("OPENAI_API_KEY", "") -OPENAI_API_KEY_ENV = os.getenv("OPENAI_API_KEY_ENV", "OPENAI_API_KEY") -API_BASE_URL = os.getenv("API_BASE_URL", "https://api.openai.com/v1") -API_KEY = os.getenv("API_KEY", "") -HF_SPACE_URL = os.getenv("HF_SPACE_URL", "") -HF_TOKEN = os.getenv("HF_TOKEN","") -LOCAL_IMAGE_NAME = os.getenv("LOCAL_IMAGE_NAME", "") -LLM_TIMEOUT_SECONDS = int(os.getenv("LLM_TIMEOUT_SECONDS", "0")) -EPISODES = int(os.getenv("EPISODES", "1")) -SUCCESS_SCORE_THRESHOLD = float(os.getenv("SUCCESS_SCORE_THRESHOLD", "0.67")) -TASK_INDICES_RAW = os.getenv("TASK_INDICES", "") - -WRITE_BENCHMARK_ARTIFACTS = os.getenv("WRITE_BENCHMARK_ARTIFACTS", "1").strip().lower() in { - "1", - "true", - "yes", - "y", - "on", -} -LEADERBOARD_PATH = os.getenv("LEADERBOARD_PATH", "datasets/fixed_levels/leaderboard_fixed_levels.json") -DASHBOARD_PATH = os.getenv("DASHBOARD_PATH", "datasets/fixed_levels/dashboard_fixed_levels.html") -RUN_NAME = os.getenv("RUN_NAME", "fixed_levels_qwen_swarm") - -BENCHMARK = "osint-openenv" -TASK_NAME = "fixed_levels_easy_mid_hard" - - -def _parse_task_indices(raw: str) -> list[int]: - out: list[int] = [] - for token in str(raw or "").split(","): - stripped = token.strip() - if not stripped: - continue - try: - out.append(int(stripped)) - except ValueError: - continue - return out - - -def _normalize_ollama_base_url(url: str) -> str: - normalized = str(url or "").strip().rstrip("/") - if normalized.endswith("/v1"): - normalized = normalized[:-3].rstrip("/") - return normalized or "http://127.0.0.1:11434" - - -def _normalize_openai_base_url(url: str) -> str: - normalized = str(url or "").strip().rstrip("/") - if not normalized: - return "" - if normalized.endswith("/v1"): - return normalized - return f"{normalized}/v1" - - -TASK_INDICES = _parse_task_indices(TASK_INDICES_RAW) - - -def log_start(task: str, env: str, model: str) -> None: - print(f"[START] task={task} env={env} model={model}", flush=True) - - -def log_step(step: int, action: str, reward: float, done: bool, error: str | None) -> None: - error_text = "null" if error is None else str(error) - print( - f"[STEP] step={step} action={action} reward={reward:.2f} done={str(bool(done)).lower()} error={error_text}", - flush=True, - ) - - -def log_end(task: str, success: bool, steps: int, score: float, rewards: list[float]) -> None: - rewards_text = ",".join(f"{value:.2f}" for value in rewards) - print( - f"[END] success={str(bool(success)).lower()} steps={steps} score={score:.2f} rewards={rewards_text}", - flush=True, - ) - - -def _looks_like_placeholder_api_key(value: str) -> bool: - token = str(value or "").strip().lower() - if not token: - return True - placeholder_markers = [ - "your_openai_api_key", - "your-key", - "your_key", - "your real", - "real-openai-key", - "replace-me", - "changeme", - "example", - "", - ] - if token.startswith("your_") or token.startswith("sk-your-"): - return True - return any(marker in token for marker in placeholder_markers) - - -def _format_action(action: dict[str, Any]) -> str: - action_type = str(action.get("action_type", "")).upper() - payload = dict(action.get("payload", {})) - - if action_type == "ANSWER": - return f"answer({str(payload.get('answer', 'unknown')).strip()})" - - if action_type == "ADD_EDGE": - try: - conf = float(payload.get("confidence", 1.0)) - except (TypeError, ValueError): - conf = 1.0 - return ( - "add_edge(" - f"{payload.get('src', '')}," - f"{payload.get('rel', '')}," - f"{payload.get('dst', '')}," - f"{conf:.2f}" - ")" - ) - - tool_name = str(payload.get("tool_name", "tool")).strip() or "tool" - args = payload.get("args", {}) - if not isinstance(args, dict) or not args: - return f"{tool_name}()" - args_text = ",".join(f"{key}={value}" for key, value in sorted(args.items())) - return f"{tool_name}({args_text})" - - -def _assistant_tool_call_id(message: dict[str, Any]) -> str | None: - tool_calls = list(message.get("tool_calls", [])) - if not tool_calls: - return None - tool_call_id = tool_calls[0].get("id") - return str(tool_call_id) if tool_call_id else None - - -def _tool_result_message(assistant_message: dict[str, Any], result: dict[str, Any]) -> dict[str, Any] | None: - tool_call_id = _assistant_tool_call_id(assistant_message) - if not tool_call_id: - return None - return { - "role": "tool", - "tool_call_id": tool_call_id, - "content": json.dumps(result, sort_keys=True), - } - - -def _resolve_environment_config() -> EnvironmentConfig: - shared = load_shared_config(CONFIG_PATH) - env_cfg = clone_environment_config(shared.environment) - - if SEED_FILE and Path(SEED_FILE).exists(): - env_cfg.seeding = load_seeding_config(SEED_FILE) - - mode = AGENT_MODE.strip().lower() - if mode == "single": - env_cfg.swarm.enabled = False - elif mode == "swarm": - env_cfg.swarm.enabled = True - - # Inference submissions must route all calls through OpenAI-compatible client config. - env_cfg.llm.provider = "openai" - env_cfg.llm.model = MODEL_NAME.strip() - - if LLM_TIMEOUT_SECONDS > 0: - env_cfg.llm.timeout_seconds = int(LLM_TIMEOUT_SECONDS) - - # Evaluation harnesses inject API_BASE_URL/HF_TOKEN for proxy-enforced requests. - resolved_openai_base = API_BASE_URL.strip() or OPENAI_BASE_URL.strip() or HF_SPACE_URL.strip() - if resolved_openai_base: - env_cfg.llm.openai_base_url = _normalize_openai_base_url(resolved_openai_base) - - if HF_TOKEN.strip(): - env_cfg.llm.openai_api_key = HF_TOKEN.strip() - elif API_KEY.strip(): - env_cfg.llm.openai_api_key = API_KEY.strip() - elif OPENAI_API_KEY.strip(): - env_cfg.llm.openai_api_key = OPENAI_API_KEY.strip() - - if OPENAI_API_KEY_ENV.strip(): - env_cfg.llm.openai_api_key_env = OPENAI_API_KEY_ENV.strip() - - return env_cfg - - -def _runner_for(env: OSINTEnvironment, llm: Any) -> SingleAgentRunner | SwarmAgentRunner: - if env.config.swarm.enabled: - return SwarmAgentRunner(env=env, llm=llm) - return SingleAgentRunner(env=env, llm=llm) - - -def _normalize_difficulty(value: str) -> str: - token = str(value or "").strip().lower() - if token in {"easy", "e"}: - return "easy" - if token in {"mid", "medium", "m"}: - return "medium" - if token in {"high", "hard", "h"}: - return "hard" - return "hard" - - -def _task_difficulty(env: OSINTEnvironment, task_index: int) -> str: - idx = int(task_index) % max(1, len(env.tasks)) - task = env.tasks[idx] - if isinstance(task.metadata, dict) and "difficulty" in task.metadata: - return _normalize_difficulty(str(task.metadata.get("difficulty", ""))) - if idx < 10: - return "easy" - if idx < 20: - return "medium" - return "hard" - - -def _episode_row(env: OSINTEnvironment, info: dict[str, Any]) -> dict[str, Any]: - if env.state is None: - return { - "task_id": "unknown", - "task_type": "unknown", - "question": "", - "task_answer": str(info.get("task_answer", "")), - "agent_answer": str(info.get("agent_answer", "")), - "graph_f1": 0.0, - "reward": float(info.get("total_reward", 0.0) or 0.0), - "steps": int(info.get("step_count", 0) or 0), - "tool_calls": int(info.get("tool_calls", 0) or 0), - "success": int(info.get("agent_answer") == info.get("task_answer")), - "reward_components": dict(info.get("reward_components", {})), - "pred_edges": [], - "truth_edges": [], - } - - graph_f1 = compute_graph_f1(env.memory_graph.edges, env.state.task.supporting_edges) - return { - "task_id": env.state.task.task_id, - "task_type": env.state.task.task_type, - "question": env.state.task.question, - "task_answer": str(info.get("task_answer", "")), - "agent_answer": str(info.get("agent_answer", "")) if info.get("agent_answer") is not None else "", - "graph_f1": graph_f1, - "reward": float(info.get("total_reward", 0.0) or 0.0), - "steps": int(info.get("step_count", 0) or 0), - "tool_calls": int(info.get("tool_calls", 0) or 0), - "success": int(info.get("agent_answer") == info.get("task_answer")), - "reward_components": dict(info.get("reward_components", {})), - "spawn_count": int(info.get("spawn_count", 0) or 0), - "spawn_critical_steps": int(info.get("spawn_critical_steps", 0) or 0), - "pred_edges": [ - { - "src": edge.src, - "rel": edge.rel, - "dst": edge.dst, - "confidence": float(edge.confidence), - } - for edge in env.memory_graph.edges - ], - "truth_edges": [ - { - "src": edge.src, - "rel": edge.rel, - "dst": edge.dst, - "confidence": float(edge.confidence), - } - for edge in env.state.task.supporting_edges - ], - } - - -def _last_action_error(observation: Any, info: dict[str, Any]) -> str | None: - raw = info.get("last_action_error") if isinstance(info, dict) else None - if raw is not None: - return str(raw) - - tool_outputs = getattr(observation, "tool_outputs", None) - if isinstance(tool_outputs, list) and tool_outputs: - last = tool_outputs[-1] - if isinstance(last, dict): - output = last.get("output") - if isinstance(output, dict) and output.get("error") is not None: - return str(output.get("error")) - return None - - -def _install_step_logger(env: OSINTEnvironment) -> tuple[list[float], dict[str, int], Any]: - rewards: list[float] = [] - counters = {"steps": 0} - original_step = env.step - - def _logged_step(action: Any): - observation, reward, done, info = original_step(action) - counters["steps"] += 1 - reward_value = float(reward or 0.0) - rewards.append(reward_value) - action_type = getattr(action, "action_type", "") - action_type_value = str(getattr(action_type, "value", action_type)) - action_text = _format_action( - { - "action_type": action_type_value, - "payload": dict(getattr(action, "payload", {}) or {}), - } - ) - log_step( - step=counters["steps"], - action=action_text, - reward=reward_value, - done=bool(done), - error=_last_action_error(observation, info if isinstance(info, dict) else {}), - ) - return observation, reward, done, info - - env.step = _logged_step - return rewards, counters, original_step - - -def _validate_required_configuration() -> None: - missing: list[str] = [] - - api_base = API_BASE_URL.strip() - model_name = MODEL_NAME.strip() - hf_token = HF_TOKEN.strip() - api_key = API_KEY.strip() - openai_key = OPENAI_API_KEY.strip() - - if not api_base or api_base == "": - missing.append("API_BASE_URL") - if not model_name or model_name == "": - missing.append("MODEL_NAME") - if not (hf_token or api_key or openai_key): - missing.append("HF_TOKEN|API_KEY|OPENAI_API_KEY") - - # Required when using docker-image based env construction. - if os.getenv("REQUIRE_LOCAL_IMAGE_NAME", "0").strip().lower() in {"1", "true", "yes", "on"}: - if not LOCAL_IMAGE_NAME.strip(): - missing.append("LOCAL_IMAGE_NAME") - - if missing: - raise RuntimeError(f"Missing required environment variables: {', '.join(sorted(set(missing)))}") - - -def _task_targets(env: OSINTEnvironment, episodes: int, task_indices: list[int]) -> list[int | None]: - if task_indices: - task_count = max(1, len(env.tasks)) - return [index % task_count for index in task_indices] - return [None] * max(1, episodes) - - -def _run_with_runner( - env: OSINTEnvironment, - llm: Any, - episodes: int, - task_indices: list[int], -) -> tuple[dict[str, Any], list[dict[str, Any]], list[float], int]: - metrics = EvalMetrics() - episode_rows: list[dict[str, Any]] = [] - rewards, counters, original_step = _install_step_logger(env) - - single_runner = SingleAgentRunner(env=env, llm=llm) - swarm_runner = SwarmAgentRunner(env=env, llm=llm) if env.config.swarm.enabled else None - - try: - for task_index in _task_targets(env, episodes, task_indices): - task_count = max(1, len(env.tasks)) - selected_index = env._task_idx % task_count if task_index is None else int(task_index) % task_count - if task_index is not None: - # Keep compatibility with explicit task selection from the previous inference script. - env._task_idx = selected_index - - difficulty = _task_difficulty(env, selected_index) - if difficulty == "easy": - runner: SingleAgentRunner | SwarmAgentRunner = single_runner - elif swarm_runner is not None: - runner = swarm_runner - else: - runner = single_runner - - info = runner.run_episode() - if env.state is None: - continue - - graph_f1 = compute_graph_f1(env.memory_graph.edges, env.state.task.supporting_edges) - metrics.add(info, task_type=env.state.task.task_type, graph_f1=graph_f1) - episode_rows.append(_episode_row(env, info)) - finally: - env.step = original_step - - return metrics.summary(), episode_rows, rewards, int(counters["steps"]) - - -def _maybe_write_artifacts( - env: OSINTEnvironment, - summary: dict[str, Any], - episodes: int, - episode_rows: list[dict[str, Any]], -) -> tuple[dict[str, Any] | None, str | None]: - if not WRITE_BENCHMARK_ARTIFACTS: - return None, None - - record = append_leaderboard_record( - path=LEADERBOARD_PATH, - summary=summary, - episodes=episodes, - run_name=RUN_NAME or None, - config={ - "seed": env.config.seed, - "max_steps": env.config.max_steps, - "swarm_enabled": env.config.swarm.enabled, - "max_agents": env.config.swarm.max_agents, - "max_breadth": env.config.swarm.max_breadth, - "max_width": env.config.swarm.max_width, - "max_depth": env.config.swarm.max_depth, - "seeded_questions": len(env.config.seeding.seeded_questions), - "llm_provider": env.config.llm.provider, - "llm_model": env.config.llm.model, - }, - ) - - leaderboard = load_leaderboard(LEADERBOARD_PATH) - dashboard = export_dashboard( - env=env, - evaluation={"summary": summary, "episodes": episode_rows}, - leaderboard_records=leaderboard, - output_path=DASHBOARD_PATH, - ) - return record, dashboard - - -def main() -> None: - _validate_required_configuration() - env_cfg = _resolve_environment_config() - llm_client = build_llm_client(env_cfg.llm) - - episodes_given = "EPISODES" in os.environ and str(os.getenv("EPISODES", "")).strip() != "" - task_indices_given = bool(TASK_INDICES) - - if not episodes_given and not task_indices_given: - runs: list[tuple[str, list[int], int]] = [ - ("easy", list(range(0, 10)), 10), - ("mid", list(range(10, 20)), 10), - ("hard", list(range(20, 30)), 10), - ] - else: - selected_indices = TASK_INDICES if task_indices_given else [] - episodes = len(selected_indices) if selected_indices else max(1, EPISODES) - runs = [(TASK_NAME, selected_indices, episodes)] - - for task_name, run_indices, run_episodes in runs: - env: OSINTEnvironment | None = None - rewards: list[float] = [] - steps_taken = 0 - score = 0.0 - success = False - - env = OSINTEnvironment(env_cfg, llm=llm_client) - log_start(task=task_name, env=BENCHMARK, model=env_cfg.llm.model) - - try: - summary, episode_rows, rewards, steps_taken = _run_with_runner( - env=env, - llm=llm_client, - episodes=run_episodes, - task_indices=run_indices, - ) - - score = float(summary.get("avg_reward", 0.0) or 0.0) - score = max(0.0, min(1.0, score)) - success = score >= SUCCESS_SCORE_THRESHOLD - - _maybe_write_artifacts( - env=env, - summary=summary, - episodes=run_episodes, - episode_rows=episode_rows, - ) - finally: - if env is not None: - close_fn = getattr(env, "close", None) - if callable(close_fn): - close_fn() - log_end(task=task_name, success=success, steps=steps_taken, score=score, rewards=rewards) - - -if __name__ == "__main__": - main() diff --git a/scratch/osint/my_env_v4.py b/scratch/osint/my_env_v4.py deleted file mode 100644 index 34037cd36e5d2ce3fcda2debc71e461bc07cbf6c..0000000000000000000000000000000000000000 --- a/scratch/osint/my_env_v4.py +++ /dev/null @@ -1,46 +0,0 @@ -from __future__ import annotations - -from dataclasses import dataclass - - -@dataclass(slots=True) -class MyEnvV4Action: - message: str - - -@dataclass(slots=True) -class _EchoObservation: - echoed_message: str - - -@dataclass(slots=True) -class _EchoResult: - observation: _EchoObservation - reward: float = 0.0 - done: bool = False - - -class MyEnvV4Env: - def __init__(self) -> None: - self._step_count = 0 - - @classmethod - async def from_docker_image(cls, image_name: str | None = None) -> "MyEnvV4Env": - return cls() - - async def reset(self) -> _EchoResult: - self._step_count = 0 - return _EchoResult(observation=_EchoObservation(echoed_message=""), reward=0.0, done=False) - - async def step(self, action: MyEnvV4Action) -> _EchoResult: - self._step_count += 1 - message = str(getattr(action, "message", "")) - reward = len(message) * 0.1 - return _EchoResult( - observation=_EchoObservation(echoed_message=message), - reward=reward, - done=False, - ) - - async def close(self) -> None: - return None diff --git a/scratch/osint/openenv.yaml b/scratch/osint/openenv.yaml deleted file mode 100644 index a9fdeb8139588db01cd990c38e3912498e2e37ea..0000000000000000000000000000000000000000 --- a/scratch/osint/openenv.yaml +++ /dev/null @@ -1,66 +0,0 @@ -name: osint-openenv -version: 0.1.0 -description: Synthetic OSINT benchmark environment exposed over HTTP. -tasks: - - id: seed_task_0 - difficulty: easy - max_steps: 24 - grader: - type: difficulty_exact_match - answer_type: node_id - case_sensitive: true - reward_profile: easy - - id: seed_task_10 - difficulty: medium - max_steps: 24 - grader: - type: difficulty_exact_match - answer_type: node_id - case_sensitive: true - reward_profile: medium - - id: seed_task_20 - difficulty: hard - max_steps: 24 - grader: - type: difficulty_exact_match - answer_type: node_id - case_sensitive: true - reward_profile: hard -transport: - type: http - base_path: / -endpoints: - health: - method: GET - path: /health - metadata: - method: GET - path: /api/environment - tasks: - method: GET - path: /openenv/tasks - reset: - method: POST - path: /reset - step: - method: POST - path: /step - state: - method: GET - path: /state -models: - action_space: - - CALL_TOOL - - ADD_EDGE - - ANSWER - task_fields: - - task_id - - task_type - - question - - difficulty - - grader - observation_fields: - - tool_outputs - - graph_snapshot - - action_history - - task diff --git a/scratch/osint/pyproject.toml b/scratch/osint/pyproject.toml deleted file mode 100644 index 6d56d42c639a3ddb0ef471e8c98e4dfe86fff668..0000000000000000000000000000000000000000 --- a/scratch/osint/pyproject.toml +++ /dev/null @@ -1,35 +0,0 @@ -[project] -name = "osint-rl-env" -version = "0.1.0" -description = "OSINT-style multi-platform information ecosystem environment for LLM agents." -readme = "README.md" -requires-python = ">=3.10" -dependencies = [ - "openenv>=0.1.13", - "openai>=1.40.0", - "fastapi>=0.115.0", - "requests>=2.32.3", - "uvicorn>=0.30.0", -] - -[project.optional-dependencies] -dev = [ - "pytest>=8.0.0", -] - -[project.scripts] -osint-env = "osint_env.cli:main" -server = "osint_env.server_entry:main" - -[build-system] -requires = ["setuptools>=68", "wheel"] -build-backend = "setuptools.build_meta" - -[tool.setuptools] -package-dir = {"" = "src"} - -[tool.setuptools.packages.find] -where = ["src"] - -[tool.pytest.ini_options] -testpaths = ["tests"] diff --git a/scratch/osint/requirements.txt b/scratch/osint/requirements.txt deleted file mode 100644 index 1b8041c02ff0a10c5fb7bb8021d123d373709cfb..0000000000000000000000000000000000000000 --- a/scratch/osint/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -openenv>=0.1.13 -openai>=1.40.0 -fastapi>=0.115.0 -requests>=2.32.3 -uvicorn>=0.30.0 -pytest>=8.0.0 diff --git a/scratch/osint/scripts/build_fixed_levels_dataset.py b/scratch/osint/scripts/build_fixed_levels_dataset.py deleted file mode 100644 index 3e0ad295450f49db4b7071fa0c57ae4341891645..0000000000000000000000000000000000000000 --- a/scratch/osint/scripts/build_fixed_levels_dataset.py +++ /dev/null @@ -1,197 +0,0 @@ -from __future__ import annotations - -import argparse -import json -from collections import Counter -from dataclasses import asdict -from pathlib import Path -from typing import Any - -from osint_env.config import clone_environment_config, load_seeding_config, load_shared_config -from osint_env.data.generator import DatasetGenerator -from osint_env.domain.models import Edge, TaskInstance -from osint_env.llm import build_llm_client - - -def edge_to_dict(edge: Edge) -> dict[str, Any]: - return { - "src": edge.src, - "rel": edge.rel, - "dst": edge.dst, - "confidence": float(edge.confidence), - } - - -def task_to_dict(task: TaskInstance) -> dict[str, Any]: - return { - "task_id": task.task_id, - "task_type": task.task_type, - "question": task.question, - "answer": task.answer, - "supporting_edges": [edge_to_dict(e) for e in task.supporting_edges], - "metadata": dict(task.metadata), - } - - -def build_fixed_snapshot(seed_path: Path) -> dict[str, Any]: - seeding = load_seeding_config(seed_path) - fixed_nodes = [] - for node in seeding.seeded_nodes: - fixed_nodes.append( - { - "node_id": node.node_id, - "node_type": str(getattr(node.node_type, "value", node.node_type)), - "attrs": dict(node.attrs), - } - ) - fixed_edges = [ - { - "src": edge.src, - "rel": edge.rel, - "dst": edge.dst, - "confidence": float(edge.confidence), - } - for edge in seeding.seeded_edges - ] - fixed_questions = [] - for idx, q in enumerate(seeding.seeded_questions): - fixed_questions.append( - { - "task_id": f"fixed_task_{idx:02d}", - "task_type": q.task_type, - "question": q.question, - "answer": q.answer, - "supporting_edges": [ - { - "src": edge.src, - "rel": edge.rel, - "dst": edge.dst, - "confidence": float(edge.confidence), - } - for edge in q.supporting_edges - ], - "metadata": dict(q.metadata), - } - ) - - difficulty_counts = Counter(str(q.get("metadata", {}).get("difficulty", "unknown")) for q in fixed_questions) - return { - "dataset_name": "fixed_levels_submission_set", - "source_seed": str(seed_path), - "graph": { - "nodes": fixed_nodes, - "edges": fixed_edges, - "node_count": len(fixed_nodes), - "edge_count": len(fixed_edges), - }, - "questions": fixed_questions, - "question_count": len(fixed_questions), - "difficulty_counts": dict(difficulty_counts), - } - - -def build_complete_snapshot(shared_config_path: Path, seed_path: Path) -> dict[str, Any]: - shared = load_shared_config(shared_config_path) - env_cfg = clone_environment_config(shared.environment) - env_cfg.seeding = load_seeding_config(seed_path) - - llm_client = build_llm_client(env_cfg.llm) - generator = DatasetGenerator(config=env_cfg, llm=llm_client) - - graph = generator.build_canonical_graph() - views = generator.build_platform_views(graph) - tasks = generator.generate_tasks(graph, views, count=max(15, len(env_cfg.seeding.seeded_questions))) - - difficulty_counts = Counter(str(task.metadata.get("difficulty", "unknown")) for task in tasks) - - return { - "dataset_name": "fixed_levels_submission_set", - "generation_mode": "llm_expanded", - "shared_config": str(shared_config_path), - "seed_file": str(seed_path), - "llm": asdict(env_cfg.llm), - "environment": { - "n_users": env_cfg.n_users, - "alias_density": env_cfg.alias_density, - "noise_level": env_cfg.noise_level, - "red_herring_rate": env_cfg.red_herring_rate, - "seed": env_cfg.seed, - }, - "canonical_graph": { - "node_count": len(graph.nodes), - "edge_count": len(graph.edges), - "nodes": [ - { - "node_id": node.node_id, - "node_type": node.node_type.value, - "attrs": dict(node.attrs), - } - for node in sorted(graph.nodes.values(), key=lambda n: n.node_id) - ], - "edges": [edge_to_dict(edge) for edge in graph.edges], - }, - "platform_views": { - "microblog_posts": views.microblog_posts, - "forum_threads": views.forum_threads, - "profiles": views.profiles, - "counts": { - "microblog_posts": len(views.microblog_posts), - "forum_threads": len(views.forum_threads), - "profiles": len(views.profiles), - }, - }, - "tasks": [task_to_dict(task) for task in tasks], - "task_count": len(tasks), - "difficulty_counts": dict(difficulty_counts), - } - - -def main() -> None: - parser = argparse.ArgumentParser(description="Build fixed difficulty dataset artifacts.") - parser.add_argument( - "--seed-file", - default="datasets/fixed_levels/seed_fixed_levels.json", - help="Path to seeding JSON with fixed graph/questions.", - ) - parser.add_argument( - "--shared-config", - default="datasets/fixed_levels/shared_config_fixed_levels.json", - help="Path to shared config used for LLM-expanded generation.", - ) - parser.add_argument( - "--output-dir", - default="datasets/fixed_levels", - help="Directory where dataset artifacts are written.", - ) - args = parser.parse_args() - - output_dir = Path(args.output_dir) - output_dir.mkdir(parents=True, exist_ok=True) - - seed_path = Path(args.seed_file) - shared_path = Path(args.shared_config) - - fixed_snapshot = build_fixed_snapshot(seed_path) - fixed_path = output_dir / "fixed_graph_questions.json" - fixed_path.write_text(json.dumps(fixed_snapshot, indent=2, sort_keys=True), encoding="utf-8") - - complete_snapshot = build_complete_snapshot(shared_path, seed_path) - complete_path = output_dir / "complete_dataset_qwen_generated.json" - complete_path.write_text(json.dumps(complete_snapshot, indent=2, sort_keys=True), encoding="utf-8") - - summary = { - "fixed_dataset": str(fixed_path), - "complete_dataset": str(complete_path), - "fixed_nodes": fixed_snapshot["graph"]["node_count"], - "fixed_edges": fixed_snapshot["graph"]["edge_count"], - "fixed_questions": fixed_snapshot["question_count"], - "complete_nodes": complete_snapshot["canonical_graph"]["node_count"], - "complete_edges": complete_snapshot["canonical_graph"]["edge_count"], - "complete_tasks": complete_snapshot["task_count"], - "difficulty_counts": complete_snapshot["difficulty_counts"], - } - print(json.dumps(summary, indent=2, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/scratch/osint/scripts/generate_fixed_levels_seed.py b/scratch/osint/scripts/generate_fixed_levels_seed.py deleted file mode 100644 index 65dc10da2dd52d3e6537adaa8c605a163900368a..0000000000000000000000000000000000000000 --- a/scratch/osint/scripts/generate_fixed_levels_seed.py +++ /dev/null @@ -1,109 +0,0 @@ -from collections import Counter, OrderedDict -from pathlib import Path -import json - -U=[('aria','Aria Sen','Helios Labs','Sector 9'),('bharat','Bharat Kulkarni','Northbridge Logistics','Dockyard 17'),('cyrus','Cyrus Mehta','Apex Dynamics','Old Town'),('diya','Diya Roy','Blueharbor Media','Old Town'),('elin','Elin Das','Helios Labs','Sector 9'),('faris','Faris Noor','Tidewatch Ops','Rivergate'),('gita','Gita Pradhan','Apex Dynamics','Old Town'),('hiro','Hiro Tan','Northbridge Logistics','Dockyard 17'),('ivy','Ivy Kapoor','Kestrel Works','Rivergate'),('jules','Jules Banerjee','Blueharbor Media','Old Town'),('kian','Kian Bose','Atlas Freight','East Quay'),('leena','Leena Das','Sunmesh Analytics','Sector 9'),('mika','Mika Solanki','Orion Customs','North Basin'),('nora','Nora Iqbal','Emberline Security','Foundry Row'),('omar','Omar Sheikh','Atlas Freight','East Quay'),('priya','Priya Menon','Sunmesh Analytics','Sector 9'),('quinn','Quinn Rao','Orion Customs','North Basin'),('rhea','Rhea Kapoor','Emberline Security','Foundry Row'),('soren','Soren Malik','Harborlight Transit','Uplink Yard'),('tara','Tara Dey','Harborlight Transit','Uplink Yard')] -A=[('orchidfox','@orchidfox','ivy'),('steelquill','@steelquill','bharat'),('monsoonbyte','@monsoonbyte','diya'),('nightrelay','@nightrelay','faris'),('mapleghost','@mapleghost','elin'),('docksparrow','@docksparrow','hiro'),('quartzlotus','@quartzlotus','cyrus'),('emberglass','@emberglass','nora'),('basinraven','@basinraven','mika'),('tideshard','@tideshard','soren'),('hollowsignal','@hollowsignal','priya'),('ironwhisper','@ironwhisper','omar'),('cinderveil','@cinderveil','rhea'),('sablekeel','@sablekeel','tara'),('lanternmoth','@lanternmoth','kian'),('frostledger','@frostledger','leena')] -L=[('dockyard17','Dockyard 17'),('sector9','Sector 9'),('old_town','Old Town'),('rivergate','Rivergate'),('east_quay','East Quay'),('foundry_row','Foundry Row'),('north_basin','North Basin'),('uplink_yard','Uplink Yard')] -O=[('helios_labs','Helios Labs','sector9'),('northbridge_logistics','Northbridge Logistics','dockyard17'),('apex_dynamics','Apex Dynamics','old_town'),('blueharbor_media','Blueharbor Media','old_town'),('tidewatch_ops','Tidewatch Ops','rivergate'),('kestrel_works','Kestrel Works','rivergate'),('atlas_freight','Atlas Freight','east_quay'),('sunmesh_analytics','Sunmesh Analytics','sector9'),('orion_customs','Orion Customs','north_basin'),('emberline_security','Emberline Security','foundry_row'),('harborlight_transit','Harborlight Transit','uplink_yard')] -E=[('project_lantern','Project Lantern'),('black_kite','Black Kite'),('silent_current','Silent Current'),('amber_veil','Amber Veil'),('glass_harbor','Glass Harbor'),('ember_tide','Ember Tide'),('iron_wharf','Iron Wharf'),('ghost_signal','Ghost Signal')] -T=[('supply_leak','supply_chain'),('port_audit','port_audit'),('customs_breach','customs_breach'),('relay_map','relay_map'),('foundry_watch','foundry_watch'),('basin_shift','basin_shift'),('quiet_manifest','quiet_manifest'),('uplink_route','uplink_route'),('ember_tide_watch','ember_tide'),('ghost_signal_net','ghost_signal')] -P=['shift_roster','midnight_manifest','sat_phone_ping','drone_parts','relay_schedule','quay_ledgers','customs_tag','hull_signal','basin_photo','foundry_map','lantern_route','uplink_note'] - -def uid(x): return f'user_{x}' -def aid(x): return f'alias_{x}' -def oid(x): return f'org_{x}' -def lid(x): return f'loc_{x}' -def eid(x): return f'event_{x}' -def tid(x): return f'thr_{x}' -def pid(x): return f'post_{x}' - -def addn(nodes,nid,nt,attrs): nodes.append({'node_id':nid,'node_type':nt,'attrs':attrs}) - -def build(): - nodes=[]; edges=OrderedDict(); - for s,name,org,loc in U: addn(nodes,uid(s),'user',{'name':name,'org':org,'location':loc}) - for s,handle,user in A: addn(nodes,aid(s),'alias',{'handle':handle}) - for s,name,_ in O: addn(nodes,oid(s),'org',{'name':name}) - for s,name in L: addn(nodes,lid(s),'location',{'name':name}) - for s,name in E: addn(nodes,eid(s),'event',{'name':name}) - for s,topic in T: addn(nodes,tid(s),'thread',{'topic':topic}) - for s in P: addn(nodes,pid(s),'post',{'channel':'microblog'}) - def ae(k,src,rel,dst,c=1.0): edges[k]={'src':src,'rel':rel,'dst':dst,'confidence':c} - for s,_,user in A: ae(f'a_{s}',aid(s),'alias_of',uid(user)) - org_map={name:oid(s) for s,name,_ in O}; loc_map={name:lid(s) for s,name in L} - for s,_,org,loc in U: ae(f'w_{s}',uid(s),'works_at',org_map[org]); ae(f'l_{s}',uid(s),'located_in',loc_map[loc]) - for s,_,loc in O: ae(f'op_{s}',oid(s),'operates_in',lid(loc)) - CP=[('ivy','bharat',.95),('bharat','hiro',.95),('hiro','faris',.92),('faris','diya',.90),('diya','elin',.89),('elin','aria',.87),('aria','cyrus',.84),('cyrus','gita',.83),('gita','jules',.82),('jules','bharat',.81),('diya','ivy',.90),('ivy','elin',.86),('kian','omar',.93),('omar','mika',.90),('mika','quinn',.89),('quinn','nora',.88),('nora','rhea',.87),('rhea','soren',.86),('soren','tara',.86),('tara','kian',.84),('priya','leena',.91),('leena','aria',.83),('priya','nora',.82),('kian','bharat',.80),('soren','faris',.79),('quinn','hiro',.78)] - for i,(a,b,c) in enumerate(CP,1): ae(f'c{i:02d}',uid(a),'connected_to',uid(b),c) - PA={'midnight_manifest':'orchidfox','shift_roster':'docksparrow','sat_phone_ping':'nightrelay','drone_parts':'monsoonbyte','relay_schedule':'steelquill','quay_ledgers':'lanternmoth','customs_tag':'basinraven','hull_signal':'tideshard','basin_photo':'emberglass','foundry_map':'cinderveil','lantern_route':'frostledger','uplink_note':'sablekeel'} - for post,author in PA.items(): ae(f'ap_{post}',aid(author),'authored_post',pid(post)) - PR={'midnight_manifest':['dockyard17','project_lantern'],'shift_roster':['dockyard17','northbridge_logistics'],'sat_phone_ping':['rivergate','project_lantern'],'drone_parts':['black_kite','kestrel_works'],'relay_schedule':['project_lantern','sector9'],'quay_ledgers':['east_quay','glass_harbor'],'customs_tag':['north_basin','iron_wharf'],'hull_signal':['uplink_yard','ghost_signal'],'basin_photo':['foundry_row','amber_veil'],'foundry_map':['foundry_row','ember_tide'],'lantern_route':['project_lantern','sunmesh_analytics'],'uplink_note':['uplink_yard','harborlight_transit']} - for post,refs in PR.items(): - for i,x in enumerate(refs,1): ae(f'r_{post}_{i}',pid(post),'references', lid(x) if x in {y for y,_ in L} else (oid(x) if x in {y for y,_,_ in O} else eid(x))) - TA={'supply_leak':'diya','port_audit':'jules','customs_breach':'mika','relay_map':'leena','foundry_watch':'nora','basin_shift':'quinn','quiet_manifest':'kian','uplink_route':'soren','ember_tide_watch':'rhea','ghost_signal_net':'tara'} - TL={'supply_leak':[('discusses','project_lantern'),('references','northbridge_logistics')],'port_audit':[('discusses','black_kite'),('references','kestrel_works')],'customs_breach':[('discusses','iron_wharf'),('references','orion_customs')],'relay_map':[('discusses','project_lantern'),('references','sunmesh_analytics')],'foundry_watch':[('discusses','ember_tide'),('references','emberline_security')],'basin_shift':[('discusses','amber_veil'),('references','north_basin')],'quiet_manifest':[('discusses','glass_harbor'),('references','atlas_freight')],'uplink_route':[('discusses','ghost_signal'),('references','harborlight_transit')],'ember_tide_watch':[('discusses','ember_tide'),('references','foundry_row')],'ghost_signal_net':[('discusses','ghost_signal'),('references','uplink_yard')]} - for t,u in TA.items(): ae(f'at_{t}',uid(u),'authored_thread',tid(t)) - for t,rels in TL.items(): - for i,(rel,x) in enumerate(rels,1): ae(f'tl_{t}_{i}',tid(t),rel, lid(x) if x in {y for y,_ in L} else (oid(x) if x in {y for y,_,_ in O} else eid(x))) - ER=[('bharat','collaborates_on','project_lantern'),('hiro','collaborates_on','project_lantern'),('faris','collaborates_on','project_lantern'),('diya','investigates','project_lantern'),('leena','monitors','project_lantern'),('ivy','collaborates_on','black_kite'),('cyrus','collaborates_on','black_kite'),('elin','investigates','black_kite'),('jules','reports_on','black_kite'),('kian','collaborates_on','glass_harbor'),('omar','collaborates_on','glass_harbor'),('priya','monitors','glass_harbor'),('mika','collaborates_on','iron_wharf'),('quinn','collaborates_on','iron_wharf'),('nora','investigates','amber_veil'),('rhea','collaborates_on','ember_tide'),('soren','collaborates_on','ghost_signal'),('tara','reports_on','ghost_signal'),('gita','monitors','silent_current'),('jules','reports_on','silent_current')] - for i,(u,rel,e) in enumerate(ER,1): ae(f'er{i:02d}',uid(u),rel,eid(e),.9) - X=[(eid('project_lantern'),'connected_to',eid('glass_harbor')),(eid('black_kite'),'connected_to',eid('amber_veil')),(eid('ember_tide'),'connected_to',eid('ghost_signal')),(oid('atlas_freight'),'connected_to',oid('northbridge_logistics')),(oid('orion_customs'),'connected_to',oid('emberline_security')),(oid('harborlight_transit'),'connected_to',oid('tidewatch_ops'))] - for i,(a,rel,b) in enumerate(X,1): ae(f'x{i:02d}',a,rel,b,.77) - return nodes,edges - -def mk_questions(edges): - def ids(*items): - out=[] - for it in items: - if isinstance(it,list): out.extend(it) - else: out.append(it) - return out - def rng(prefix,a,b): return [f'{prefix}{i:02d}' for i in range(a,b+1)] - def sup(edge_ids): return [edges[e] for e in edge_ids] - def nodes(edge_ids): - s=set() - for e in edge_ids: s|={edges[e]['src'],edges[e]['dst']} - return len(s) - qs=[] - easy=[('easy_01','alias_orchidfox -> post_midnight_manifest -> loc_dockyard17 -> connected collaborator on event_project_lantern. Who is it?','user_bharat',ids('a_orchidfox','ap_midnight_manifest','r_midnight_manifest_1','c01','er01')),('easy_02','thr_supply_leak references org_northbridge_logistics. Which alias_docksparrow user works there and collaborates on event_project_lantern?','user_hiro',ids('tl_supply_leak_2','a_docksparrow','w_hiro','er02')),('easy_03','alias_monsoonbyte authored post_drone_parts about event_black_kite. Which user behind that alias is directly connected to the Kestrel collaborator?','user_diya',ids('a_monsoonbyte','ap_drone_parts','r_drone_parts_1','w_ivy','er06','c12')),('easy_04','alias_nightrelay references loc_rivergate. Which user behind it works at an org operating there and collaborates on event_project_lantern?','user_faris',ids('a_nightrelay','ap_sat_phone_ping','r_sat_phone_ping_1','w_faris','op_tidewatch_ops','er03')),('easy_05','thr_port_audit discusses Black Kite and references Kestrel Works. Which alias_orchidfox user authored post_midnight_manifest and collaborates on Black Kite?','user_ivy',ids('tl_port_audit_1','tl_port_audit_2','a_orchidfox','ap_midnight_manifest','w_ivy','er06')),('easy_06','Which Atlas Freight user behind alias_lanternmoth authored post_quay_ledgers and collaborates on event_glass_harbor?','user_kian',ids('a_lanternmoth','ap_quay_ledgers','w_kian','er10')),('easy_07','Which Orion Customs user behind alias_basinraven authored post_customs_tag and collaborates on event_iron_wharf?','user_mika',ids('a_basinraven','ap_customs_tag','w_mika','er13')),('easy_08','Which user behind alias_emberglass posted basin_photo from Foundry Row and investigates Amber Veil?','user_nora',ids('a_emberglass','ap_basin_photo','r_basin_photo_1','er15')),('easy_09','Which user behind alias_tideshard authored post_hull_signal and collaborates on Ghost Signal?','user_soren',ids('a_tideshard','ap_hull_signal','er17')),('easy_10','Which Harborlight Transit user behind alias_sablekeel authored post_uplink_note and reports on Ghost Signal?','user_tara',ids('a_sablekeel','ap_uplink_note','w_tara','er18'))] - mid=[('mid_01','Follow alias_docksparrow through post_shift_roster, Dockyard 17, and the Lantern chain. Return the org node id.','org_northbridge_logistics',ids('a_docksparrow','ap_shift_roster','r_shift_roster_1','r_shift_roster_2','tl_supply_leak_2','w_hiro','l_hiro','er02','er01','c02','c03')),('mid_02','Across the Glass Harbor cluster, which user behind alias_lanternmoth links to the Atlas Freight network from thr_quiet_manifest?','user_kian',ids('a_lanternmoth','ap_quay_ledgers','r_quay_ledgers_1','r_quay_ledgers_2','at_quiet_manifest','tl_quiet_manifest_1','tl_quiet_manifest_2','w_kian','w_omar','er10','er11','er12','c13','c14')),('mid_03','Trace alias_basinraven through post_customs_tag, thr_customs_breach, and the Orion Customs collaboration chain. Who is it?','user_mika',ids('a_basinraven','ap_customs_tag','r_customs_tag_1','r_customs_tag_2','at_customs_breach','tl_customs_breach_1','tl_customs_breach_2','w_mika','w_quinn','er13','er14','c15','c16','x05')),('mid_04','In the Ember Tide and Amber Veil overlap, which Foundry Row user behind alias_cinderveil collaborates on Ember Tide?','user_rhea',ids('a_cinderveil','ap_foundry_map','r_foundry_map_1','r_foundry_map_2','at_foundry_watch','tl_foundry_watch_1','tl_foundry_watch_2','at_ember_tide_watch','tl_ember_tide_watch_1','tl_ember_tide_watch_2','w_rhea','w_nora','er15','er16','c17','x03')),('mid_05','Follow alias_tideshard from post_hull_signal into thr_uplink_route and the Harborlight relay. Return the org node id.','org_harborlight_transit',ids('a_tideshard','ap_hull_signal','r_hull_signal_1','r_hull_signal_2','at_uplink_route','tl_uplink_route_1','tl_uplink_route_2','w_soren','w_tara','er17','er18','c18','c19','op_harborlight_transit','x06')),('mid_06','Which Sunmesh user behind alias_frostledger connects post_lantern_route to thr_relay_map and the Sector 9 monitoring chain?','user_leena',ids('a_frostledger','ap_lantern_route','r_lantern_route_1','r_lantern_route_2','at_relay_map','tl_relay_map_1','tl_relay_map_2','w_leena','w_priya','l_leena','op_sunmesh_analytics','er05','c21','c22')),('mid_07','Which user behind alias_emberglass is tied to Amber Veil after combining post_basin_photo, thr_basin_shift, and the Foundry Row investigation chain?','user_nora',ids('a_emberglass','ap_basin_photo','r_basin_photo_1','r_basin_photo_2','at_basin_shift','tl_basin_shift_1','tl_basin_shift_2','w_nora','w_quinn','l_nora','er15','c16','c17','x05')),('mid_08','Combine alias_orchidfox, post_midnight_manifest, thr_supply_leak, and the Lantern to Glass Harbor bridge. Which user starts that chain?','user_ivy',ids('a_orchidfox','ap_midnight_manifest','r_midnight_manifest_1','r_midnight_manifest_2','at_supply_leak','tl_supply_leak_1','tl_supply_leak_2','w_ivy','er06','c01','c12','x01','er10','er12')),('mid_09','Which user behind alias_monsoonbyte sits at the overlap of Blueharbor Media, Project Lantern, Black Kite, and the Ivy connection chain?','user_diya',ids('a_monsoonbyte','ap_drone_parts','r_drone_parts_1','at_supply_leak','tl_supply_leak_1','at_port_audit','tl_port_audit_1','w_diya','w_ivy','w_jules','er04','er06','er09','c04','c12')),('mid_10','Who is the Northbridge user behind alias_steelquill when combining post_relay_schedule, thr_supply_leak, Dockyard 17, and Lantern collaborator edges?','user_bharat',ids('a_steelquill','ap_relay_schedule','r_relay_schedule_1','r_relay_schedule_2','at_supply_leak','tl_supply_leak_1','tl_supply_leak_2','w_bharat','w_hiro','l_bharat','l_hiro','er01','er02','c01','c02'))] - big=list(edges.keys())[:58] - hard=[('high_01','Lantern to Glass Harbor handoff: identify the user behind alias_orchidfox after combining Lantern logistics, Dockyard links, and Atlas Freight bridge evidence.','user_ivy',ids('a_orchidfox','ap_midnight_manifest','r_midnight_manifest_1','r_midnight_manifest_2','at_supply_leak','tl_supply_leak_1','tl_supply_leak_2',['w_ivy','w_bharat','w_hiro','w_kian','w_omar'],['l_ivy','l_bharat','l_hiro','l_kian','l_omar'],['op_northbridge_logistics','op_kestrel_works','op_atlas_freight'],rng('c',1,3),['c12','c13','c14'],['er01','er02','er03','er06','er10','er11','er12'],'at_quiet_manifest','tl_quiet_manifest_1','tl_quiet_manifest_2','ap_quay_ledgers','r_quay_ledgers_1','r_quay_ledgers_2','x01','x04','a_lanternmoth','a_steelquill','a_docksparrow')),('high_02','North Basin to Foundry Row escalation: which user behind alias_basinraven anchors the Iron Wharf side before the Emberline handoff?','user_mika',ids('a_basinraven','ap_customs_tag','r_customs_tag_1','r_customs_tag_2','at_customs_breach','tl_customs_breach_1','tl_customs_breach_2','at_basin_shift','tl_basin_shift_1','tl_basin_shift_2','at_foundry_watch','tl_foundry_watch_1','tl_foundry_watch_2',['w_mika','w_quinn','w_nora','w_rhea'],['l_mika','l_quinn','l_nora','l_rhea'],['op_orion_customs','op_emberline_security'],['c15','c16','c17'],['er13','er14','er15','er16'],'ap_basin_photo','r_basin_photo_1','r_basin_photo_2','ap_foundry_map','r_foundry_map_1','r_foundry_map_2','x02','x03','x05','a_emberglass','a_cinderveil','c23','c24')),('high_03','Harborlight ghost-signal relay: identify the user behind alias_tideshard at the Harborlight / Tidewatch junction.','user_soren',ids('a_tideshard','ap_hull_signal','r_hull_signal_1','r_hull_signal_2','a_sablekeel','ap_uplink_note','r_uplink_note_1','r_uplink_note_2','at_uplink_route','tl_uplink_route_1','tl_uplink_route_2','at_ghost_signal_net','tl_ghost_signal_net_1','tl_ghost_signal_net_2',['w_soren','w_tara','w_faris'],['l_soren','l_tara','l_faris'],['op_harborlight_transit','op_tidewatch_ops'],['c18','c19','c20','c25'],['er03','er17','er18'],'ap_sat_phone_ping','r_sat_phone_ping_1','r_sat_phone_ping_2','at_supply_leak','tl_supply_leak_1','er01','er02','x03','x06','a_nightrelay')),('high_04','Blueharbor to Black Kite to Lantern overlap: which user is the Blueharbor origin behind alias_monsoonbyte?','user_diya',ids('a_monsoonbyte','ap_drone_parts','r_drone_parts_1','r_drone_parts_2','at_port_audit','tl_port_audit_1','tl_port_audit_2','at_supply_leak','tl_supply_leak_1','tl_supply_leak_2',['w_diya','w_jules','w_ivy','w_cyrus'],['l_diya','l_jules','l_ivy','l_cyrus'],['op_blueharbor_media','op_kestrel_works','op_apex_dynamics'],['c04','c08','c09','c12'],['er04','er06','er07','er08','er09'],'a_orchidfox','ap_midnight_manifest','r_midnight_manifest_2','x01','x02','at_relay_map','tl_relay_map_1','w_leena','er05')),('high_05','Sector 9 to Dockyard 17 full relay: which user behind alias_steelquill links the Northbridge chain and the Sunmesh monitoring bridge?','user_bharat',ids('a_steelquill','ap_relay_schedule','r_relay_schedule_1','r_relay_schedule_2','a_frostledger','ap_lantern_route','r_lantern_route_1','r_lantern_route_2','at_relay_map','tl_relay_map_1','tl_relay_map_2','at_supply_leak','tl_supply_leak_1','tl_supply_leak_2',['w_bharat','w_hiro','w_leena','w_priya','w_aria'],['l_bharat','l_hiro','l_leena','l_priya','l_aria'],['op_northbridge_logistics','op_sunmesh_analytics','op_helios_labs'],['c01','c02','c05','c06','c07','c21','c22'],['er01','er02','er05'],'x01','x04','a_docksparrow','a_mapleghost','a_hollowsignal')),('high_06','Foundry Row, North Basin, and Uplink Yard spread: identify the user behind alias_emberglass before the Harborlight relay takes over.','user_nora',ids('a_emberglass','ap_basin_photo','r_basin_photo_1','r_basin_photo_2','a_cinderveil','ap_foundry_map','r_foundry_map_1','r_foundry_map_2','a_sablekeel','ap_uplink_note','r_uplink_note_1','r_uplink_note_2','at_foundry_watch','tl_foundry_watch_1','tl_foundry_watch_2','at_ember_tide_watch','tl_ember_tide_watch_1','tl_ember_tide_watch_2','at_uplink_route','tl_uplink_route_1','tl_uplink_route_2',['w_nora','w_rhea','w_soren','w_tara'],['l_nora','l_rhea','l_soren','l_tara'],['op_emberline_security','op_harborlight_transit'],['c17','c18','c19'],['er15','er16','er17','er18'],'x03','x06')),('high_07','Freight and customs bridge: which Atlas Freight user behind alias_lanternmoth connects Glass Harbor with the Northbridge chain?','user_kian',ids('a_lanternmoth','ap_quay_ledgers','r_quay_ledgers_1','r_quay_ledgers_2','at_quiet_manifest','tl_quiet_manifest_1','tl_quiet_manifest_2',['w_kian','w_omar','w_bharat','w_hiro'],['l_kian','l_omar','l_bharat','l_hiro'],['op_atlas_freight','op_northbridge_logistics'],['c13','c14','c24','c02'],['er10','er11','er12','er01','er02'],'ap_shift_roster','r_shift_roster_1','r_shift_roster_2','ap_midnight_manifest','r_midnight_manifest_1','at_supply_leak','tl_supply_leak_2','x04','a_ironwhisper','a_steelquill','a_docksparrow')),('high_08','Black Kite, Amber Veil, and Iron Wharf overlap: which user behind alias_quartzlotus is the Apex-side collaborator?','user_cyrus',ids('a_quartzlotus','w_cyrus','l_cyrus','op_apex_dynamics','er07','at_port_audit','tl_port_audit_1','ap_drone_parts','r_drone_parts_1','er15','at_basin_shift','tl_basin_shift_1','er13','at_customs_breach','tl_customs_breach_1',['w_ivy','w_nora','w_mika','w_quinn'],['l_ivy','l_nora','l_mika','l_quinn'],['op_kestrel_works','op_emberline_security','op_orion_customs'],['c08','c12','c15','c16','c17'],'x02','x05','a_orchidfox','a_basinraven','a_emberglass')),('high_09','Ghost Signal and Ember Tide relay: which user behind alias_sablekeel is the Harborlight reporting endpoint?','user_tara',ids('a_sablekeel','ap_uplink_note','r_uplink_note_1','r_uplink_note_2','a_tideshard','ap_hull_signal','r_hull_signal_1','r_hull_signal_2','at_ghost_signal_net','tl_ghost_signal_net_1','tl_ghost_signal_net_2','at_uplink_route','tl_uplink_route_1','tl_uplink_route_2','at_ember_tide_watch','tl_ember_tide_watch_1','tl_ember_tide_watch_2',['w_tara','w_soren','w_rhea','w_nora'],['l_tara','l_soren','l_rhea','l_nora'],['op_harborlight_transit','op_emberline_security'],['c18','c19','c17'],['er16','er17','er18'],'x03','x06','a_cinderveil','a_emberglass')),('high_10','End-to-end benchmark sweep: across Lantern, Black Kite, Glass Harbor, Iron Wharf, Ember Tide, and Ghost Signal, which user behind alias_hollowsignal anchors the Sunmesh monitoring side?','user_priya',big)] - for diff,level,specs in [('easy',1,easy),('mid',2,mid),('high',3,hard)]: - for qid,q,a,eids in specs: - qs.append({'task_type':'fixed_trace','question':q,'answer':a,'supporting_edges':sup(eids),'metadata':{'difficulty':diff,'difficulty_level':level,'question_id':qid,'support_nodes':nodes(eids)}}) - def edge_key(e): return (e['src'], e['rel'], e['dst']) - mid_pool = sup(ids('a_orchidfox','ap_midnight_manifest','r_midnight_manifest_1','r_midnight_manifest_2','a_lanternmoth','ap_quay_ledgers','r_quay_ledgers_1','r_quay_ledgers_2','a_basinraven','ap_customs_tag','r_customs_tag_1','r_customs_tag_2','a_tideshard','ap_hull_signal','r_hull_signal_1','at_supply_leak','tl_supply_leak_1','at_quiet_manifest','tl_quiet_manifest_1','er01','er02','er06','er10','c01','c02','c13')) - hard_pool = sup(list(edges.keys())[:120]) - for q in qs: - current = {edge_key(e) for e in q['supporting_edges']} - diff = q['metadata']['difficulty'] - if diff == 'mid': - pool = mid_pool - target = 17 - elif diff == 'high': - pool = hard_pool - target = 50 - else: - continue - for e in pool: - if q['metadata']['support_nodes'] >= target: - break - k = edge_key(e) - if k not in current: - q['supporting_edges'].append(dict(e)) - current.add(k) - q['metadata']['support_nodes'] = len({n for edge in q['supporting_edges'] for n in (edge['src'], edge['dst'])}) - return qs - -def main(): - nodes,edges=build(); questions=mk_questions(edges) - payload={'seeding':{'seeded_nodes':nodes,'seeded_edges':list(edges.values()),'seeded_questions':questions,'llm_generate_remaining_graph':True,'llm_generate_remaining_tasks':False,'llm_generated_edge_budget':48,'llm_generated_task_budget':0,'llm_generation_parallel':True,'llm_generation_workers':4,'llm_generation_retries':3,'allow_template_fallback_on_llm_failure':False}} - out=Path('datasets/fixed_levels/seed_fixed_levels.json'); out.write_text(json.dumps(payload,indent=2),encoding='utf-8') - counts=Counter(q['metadata']['difficulty'] for q in questions) - stats={k:sorted(q['metadata']['support_nodes'] for q in questions if q['metadata']['difficulty']==k) for k in ['easy','mid','high']} - print(json.dumps({'nodes':len(nodes),'edges':len(edges),'questions':len(questions),'difficulty_counts':dict(counts),'support_nodes':stats},indent=2)) - -if __name__=='__main__': - main() diff --git a/scratch/osint/scripts/run_openai_baseline.py b/scratch/osint/scripts/run_openai_baseline.py deleted file mode 100644 index 88a6822ba549e0e778dca402ab165ddeedd60618..0000000000000000000000000000000000000000 --- a/scratch/osint/scripts/run_openai_baseline.py +++ /dev/null @@ -1,59 +0,0 @@ -from __future__ import annotations - -import argparse -import json -import os - -from osint_env.baselines import OpenAIBaselineConfig, OpenAIBaselineRunner - - -def build_parser() -> argparse.ArgumentParser: - parser = argparse.ArgumentParser(description="Run the reproducible OpenAI baseline on the fixed-level OSINT benchmark.") - parser.add_argument("--config", default="datasets/fixed_levels/shared_config_fixed_levels.json", help="Shared config JSON.") - parser.add_argument("--seed-file", default="datasets/fixed_levels/seed_fixed_levels.json", help="Fixed seed file JSON.") - parser.add_argument("--output", default="artifacts/baselines/openai_fixed_levels_latest.json", help="Baseline result JSON output path.") - parser.add_argument("--leaderboard", default="artifacts/baselines/openai_fixed_levels_leaderboard.json", help="Leaderboard JSON path.") - parser.add_argument("--dashboard", default="artifacts/baselines/openai_fixed_levels_dashboard.html", help="Dashboard HTML path.") - parser.add_argument("--run-name", default="openai_fixed_levels_baseline", help="Leaderboard run name.") - parser.add_argument("--model", default="gpt-5-nano", help="OpenAI chat model name.") - parser.add_argument("--openai-base-url", default="https://api.openai.com/v1", help="OpenAI-compatible base URL.") - parser.add_argument("--openai-api-key", default="", help="OpenAI API key override.") - parser.add_argument("--openai-api-key-env", default="OPENAI_API_KEY", help="Environment variable name for the API key.") - parser.add_argument("--episodes", type=int, default=30, help="Number of episodes to evaluate.") - parser.add_argument("--max-steps", type=int, default=8, help="Episode step budget to keep runs bounded.") - parser.add_argument("--temperature", type=float, default=0.0, help="Sampling temperature.") - parser.add_argument("--max-tokens", type=int, default=256, help="Maximum completion tokens per step.") - parser.add_argument("--timeout-seconds", type=int, default=60, help="Per-request timeout.") - parser.add_argument("--seed", type=int, default=7, help="Request seed offset used for repeatable runs.") - parser.add_argument("--skip-leaderboard", action="store_true", help="Do not append the run to the leaderboard file.") - return parser - - -def main() -> None: - args = build_parser().parse_args() - api_key = args.openai_api_key or os.getenv(args.openai_api_key_env, "") - config = OpenAIBaselineConfig( - shared_config_path=args.config, - seed_file=args.seed_file, - output_path=args.output, - leaderboard_path=args.leaderboard, - dashboard_path=args.dashboard, - run_name=args.run_name, - model=args.model, - base_url=args.openai_base_url, - api_key=api_key, - api_key_env=args.openai_api_key_env, - temperature=args.temperature, - max_tokens=args.max_tokens, - timeout_seconds=args.timeout_seconds, - episodes=args.episodes, - max_steps=args.max_steps, - seed=args.seed, - append_leaderboard=not args.skip_leaderboard, - ) - result = OpenAIBaselineRunner(config).run() - print(json.dumps({"summary": result["summary"], "output": args.output, "dashboard": args.dashboard}, indent=2, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/scratch/osint/scripts/validate_release.py b/scratch/osint/scripts/validate_release.py deleted file mode 100644 index 4aa09322ff18b8a6a5fee31aceb14b62626753a9..0000000000000000000000000000000000000000 --- a/scratch/osint/scripts/validate_release.py +++ /dev/null @@ -1,21 +0,0 @@ -from __future__ import annotations - -import json -import sys -from pathlib import Path - -ROOT = Path(__file__).resolve().parents[1] -if str(ROOT) not in sys.path: - sys.path.insert(0, str(ROOT)) - -from osint_env.validation import run_validation_suite - - -def main() -> int: - result = run_validation_suite() - print(json.dumps(result, indent=2, sort_keys=True)) - return 0 if result["passed"] else 1 - - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/scratch/osint/server.py b/scratch/osint/server.py deleted file mode 100644 index e18181a051826f34f601b6797fa40113d1fa0ae9..0000000000000000000000000000000000000000 --- a/scratch/osint/server.py +++ /dev/null @@ -1,564 +0,0 @@ -from __future__ import annotations - -import json -import os -from collections import Counter -from functools import lru_cache -from pathlib import Path -from threading import Lock -from typing import Any -from uuid import uuid4 - -from fastapi import FastAPI, HTTPException, Request -from fastapi.responses import FileResponse, HTMLResponse, JSONResponse - -from osint_env.api import ( - OpenEnvActionRequest, - OpenEnvInferenceReportRequest, - OpenEnvInferenceReportResponse, - OpenEnvObservationModel, - OpenEnvResetRequest, - OpenEnvResponseEnvelope, - OpenEnvTaskSummary, -) -from osint_env.config import clone_environment_config, load_seeding_config, load_shared_config -from osint_env.domain.models import Action, ActionType -from osint_env.env.environment import OSINTEnvironment -from osint_env.eval.leaderboard import load_leaderboard -from osint_env.eval.runner import run_evaluation -from osint_env.llm import build_llm_client -from osint_env.viz import export_dashboard - - -SPACE_CONFIG_PATH = Path(os.getenv("OSINT_ENV_CONFIG", "datasets/fixed_levels/shared_config_fixed_levels.json")) -SPACE_SEED_PATH = Path(os.getenv("OSINT_ENV_SEED_FILE", "datasets/fixed_levels/seed_fixed_levels.json")) -SPACE_PROVIDER = os.getenv("OSINT_SPACE_LLM_PROVIDER", "mock") -SPACE_MODEL = os.getenv("OSINT_SPACE_LLM_MODEL", "gpt-4o-mini") -SPACE_PORT = int(os.getenv("PORT", "7860")) -SPACE_DASHBOARD = Path("artifacts/space_dashboard.html") -LATEST_BASELINE_OUTPUT = Path("artifacts/baselines/openai_fixed_levels_latest.json") -LATEST_EVALUATION_OUTPUT = Path("artifacts/latest_evaluation.json") -OPENENV_SPEC_PATH = Path("openenv.yaml") - -_SESSION_LOCK = Lock() -_SESSIONS: dict[str, OSINTEnvironment] = {} -_RESET_COUNTER = 0 -_LATEST_SESSION_ID: str | None = None - - -def _load_json(path: Path) -> dict[str, Any] | None: - if not path.exists(): - return None - try: - payload = json.loads(path.read_text(encoding="utf-8")) - except (OSError, json.JSONDecodeError): - return None - return payload if isinstance(payload, dict) else None - - -def _path_mtime(path: Path) -> float: - try: - return path.stat().st_mtime - except OSError: - return 0.0 - - -def _build_environment() -> OSINTEnvironment: - shared = load_shared_config(SPACE_CONFIG_PATH) - env_cfg = clone_environment_config(shared.environment) - if SPACE_SEED_PATH.exists(): - env_cfg.seeding = load_seeding_config(SPACE_SEED_PATH) - env_cfg.llm.provider = SPACE_PROVIDER - env_cfg.llm.model = SPACE_MODEL - try: - llm = build_llm_client(env_cfg.llm) - except Exception: - env_cfg.llm.provider = "mock" - llm = build_llm_client(env_cfg.llm) - return OSINTEnvironment(env_cfg, llm=llm) - - -def _serialize_observation(observation: Any) -> OpenEnvObservationModel: - return OpenEnvObservationModel( - tool_outputs=list(observation.tool_outputs), - graph_snapshot=dict(observation.graph_snapshot), - action_history=list(observation.action_history), - task=dict(observation.task), - ) - - -def _safe_session_info(info: dict[str, Any]) -> dict[str, Any]: - return { - "step_count": int(info.get("step_count", 0)), - "total_reward": float(info.get("total_reward", 0.0)), - "tool_calls": int(info.get("tool_calls", 0)), - "redundant_tool_calls": int(info.get("redundant_tool_calls", 0)), - "task_answer": str(info.get("task_answer", "")), - "agent_answer": "" if info.get("agent_answer") is None else str(info.get("agent_answer", "")), - "graph_f1": float(info.get("graph_f1", 0.0)), - "reward_components": dict(info.get("reward_components", {})), - } - - -def _task_summaries(env: OSINTEnvironment) -> list[OpenEnvTaskSummary]: - return [ - OpenEnvTaskSummary( - task_id=task.task_id, - task_type=task.task_type, - question=task.question, - difficulty=str(task.metadata.get("difficulty", "unknown")), - grader=( - dict(task.metadata.get("grader", {})) - if isinstance(task.metadata.get("grader"), dict) - else { - "type": "exact_match", - "answer_type": "node_id", - "case_sensitive": True, - } - ), - ) - for task in env.tasks - ] - - -def _resolve_task_index(env: OSINTEnvironment, request: OpenEnvResetRequest) -> int: - global _RESET_COUNTER - if request.task_index is not None: - task_index = int(request.task_index) - if task_index < 0 or task_index >= len(env.tasks): - raise HTTPException(status_code=400, detail=f"Invalid task_index {task_index}") - return task_index - if request.task_id: - for idx, task in enumerate(env.tasks): - if task.task_id == request.task_id: - return idx - raise HTTPException(status_code=400, detail=f"Unknown task_id {request.task_id}") - with _SESSION_LOCK: - task_index = _RESET_COUNTER % max(1, len(env.tasks)) - _RESET_COUNTER += 1 - return task_index - - -def _get_session_env(session_id: str) -> OSINTEnvironment: - with _SESSION_LOCK: - env = _SESSIONS.get(session_id) - if env is None: - raise HTTPException(status_code=404, detail=f"Unknown session_id {session_id}") - return env - - -def _store_session(session_id: str, env: OSINTEnvironment) -> None: - global _LATEST_SESSION_ID - with _SESSION_LOCK: - _SESSIONS[session_id] = env - _LATEST_SESSION_ID = session_id - - -def _latest_session_id() -> str: - with _SESSION_LOCK: - if _LATEST_SESSION_ID and _LATEST_SESSION_ID in _SESSIONS: - return _LATEST_SESSION_ID - if _SESSIONS: - return next(reversed(_SESSIONS)) - raise HTTPException(status_code=404, detail="No active session. Call /reset first.") - - -def _resolve_session_id(session_id: str | None) -> str: - token = str(session_id or "").strip() - if token: - return token - return _latest_session_id() - - -def _task_lookup(env: OSINTEnvironment) -> dict[str, Any]: - return {task.task_id: task for task in env.tasks} - - -def _normalize_episode_rows(env: OSINTEnvironment, episodes: list[dict[str, Any]]) -> list[dict[str, Any]]: - tasks_by_id = _task_lookup(env) - normalized: list[dict[str, Any]] = [] - for episode in episodes: - row = dict(episode) - task = tasks_by_id.get(str(row.get("task_id", ""))) - if task is not None: - row.setdefault("task_type", task.task_type) - row.setdefault("question", task.question) - row.setdefault("task_answer", task.answer) - row.setdefault( - "truth_edges", - [ - { - "src": edge.src, - "rel": edge.rel, - "dst": edge.dst, - "confidence": float(edge.confidence), - } - for edge in task.supporting_edges - ], - ) - row.setdefault("pred_edges", []) - row.setdefault("reward_components", {}) - row.setdefault("graph_f1", 0.0) - row.setdefault("reward", 0.0) - row.setdefault("steps", 0) - row.setdefault("tool_calls", 0) - row.setdefault("success", 0) - normalized.append(row) - return normalized - - -@lru_cache(maxsize=1) -def _base_environment_snapshot() -> dict[str, Any]: - env = _build_environment() - difficulty_counts = Counter(str(task.metadata.get("difficulty", "unknown")) for task in env.tasks) - return { - "task_count": len(env.tasks), - "difficulty_counts": dict(difficulty_counts), - "action_space": ["CALL_TOOL", "ADD_EDGE", "ANSWER"], - "observation_space": { - "tool_outputs": "Last tool results and memory hits.", - "graph_snapshot": "Current working graph edge snapshot.", - "action_history": "Recent action/reward trace.", - "task": "Task id, task type, and question.", - }, - "task_types": sorted({task.task_type for task in env.tasks}), - "config": { - "seed": env.config.seed, - "max_steps": env.config.max_steps, - "swarm_enabled": env.config.swarm.enabled, - "llm_provider": env.config.llm.provider, - "llm_model": env.config.llm.model, - }, - } - - -@lru_cache(maxsize=1) -def _preview_snapshot() -> dict[str, Any]: - env = _build_environment() - evaluation = run_evaluation(env, episodes=3, return_details=True, llm=build_llm_client(env.config.llm)) - dashboard_path = export_dashboard( - env=env, - evaluation=evaluation, - leaderboard_records=[], - output_path=str(SPACE_DASHBOARD), - ) - snapshot = dict(_base_environment_snapshot()) - snapshot["summary"] = evaluation["summary"] - snapshot["dashboard_path"] = dashboard_path - return snapshot - - -def _space_snapshot() -> dict[str, Any]: - snapshot = dict(_base_environment_snapshot()) - - baseline_payload = _load_json(LATEST_BASELINE_OUTPUT) - evaluation_payload = _load_json(LATEST_EVALUATION_OUTPUT) - - candidates: list[tuple[float, str, dict[str, Any]]] = [] - if baseline_payload is not None and isinstance(baseline_payload.get("summary"), dict): - candidates.append((_path_mtime(LATEST_BASELINE_OUTPUT), "baseline_output", baseline_payload)) - if evaluation_payload is not None and isinstance(evaluation_payload.get("summary"), dict): - candidates.append((_path_mtime(LATEST_EVALUATION_OUTPUT), "latest_evaluation", evaluation_payload)) - - if candidates: - _, source, payload = max(candidates, key=lambda item: item[0]) - snapshot["summary"] = dict(payload["summary"]) - snapshot["source"] = source - if source == "baseline_output": - dashboard_path = Path( - str( - ((payload.get("run") or {}).get("dashboard_path")) - or "artifacts/baselines/openai_fixed_levels_dashboard.html" - ) - ) - if dashboard_path.exists(): - snapshot["dashboard_path"] = str(dashboard_path) - return snapshot - - env = _build_environment() - dashboard_path = export_dashboard( - env=env, - evaluation=payload, - leaderboard_records=[], - output_path=str(SPACE_DASHBOARD), - ) - snapshot["dashboard_path"] = dashboard_path - return snapshot - - preview = _preview_snapshot() - preview["source"] = "preview" - return preview - - -app = FastAPI(title="OSINT OpenEnv Space", version="0.1.0") - - -@app.get("/", response_class=HTMLResponse) -def home() -> str: - snapshot = _space_snapshot() - summary = snapshot["summary"] - difficulty_html = "".join( - f"
  • {level}: {count}
  • " - for level, count in sorted(snapshot["difficulty_counts"].items()) - ) - task_type_html = "".join(f"
  • {task_type}
  • " for task_type in snapshot["task_types"]) - return f""" - - - - - OSINT OpenEnv Space - - - -
    -
    -
    -

    OSINT OpenEnv Space

    -

    A containerized OpenEnv-compatible benchmark for synthetic OSINT reasoning over profiles, forum threads, posts, aliases, organizations, locations, and event links.

    -

    The Space boots with the fixed-level benchmark so visitors get a stable environment snapshot instead of a different graph every restart.

    - Open Dashboard - Environment JSON -
    -
    -

    Included Snapshot

    -
    -
    Tasks
    {snapshot["task_count"]}
    -
    Provider
    {snapshot["config"]["llm_provider"]}
    -
    Score
    {summary["leaderboard_score"]:.3f}
    -
    Success
    {summary["task_success_rate"]:.3f}
    -
    -
    -
    - -
    -
    -

    Action Space

    -
      -
    • CALL_TOOL: query platform views or semantic memory.
    • -
    • ADD_EDGE: add a hypothesized relation to the working graph.
    • -
    • ANSWER: submit the final node id answer.
    • -
    -
    -
    -

    Difficulty Mix

    -
      {difficulty_html}
    -
    -
    -

    Task Families

    -
      {task_type_html}
    -
    -
    -
    - -""" - - -@app.get("/healthz") -def healthz() -> JSONResponse: - return JSONResponse({"status": "ok"}) - - -@app.get("/health") -def health() -> JSONResponse: - return healthz() - - -@app.get("/openenv.yaml") -def openenv_spec() -> FileResponse: - return FileResponse(OPENENV_SPEC_PATH, media_type="text/yaml") - - -@app.get("/api/environment") -def environment_metadata() -> JSONResponse: - return JSONResponse(_space_snapshot()) - - -@app.get("/openenv/tasks", response_model=list[OpenEnvTaskSummary]) -def openenv_tasks() -> list[OpenEnvTaskSummary]: - env = _build_environment() - return _task_summaries(env) - - -@app.post("/openenv/reset", response_model=OpenEnvResponseEnvelope) -@app.post("/openenv/reset/", response_model=OpenEnvResponseEnvelope, include_in_schema=False) -@app.post("/reset", response_model=OpenEnvResponseEnvelope, include_in_schema=False) -@app.post("/reset/", response_model=OpenEnvResponseEnvelope, include_in_schema=False) -async def openenv_reset(request: Request) -> OpenEnvResponseEnvelope: - env = _build_environment() - raw_body = await request.body() - if not raw_body.strip(): - payload: dict[str, Any] = {} - else: - try: - parsed_payload = json.loads(raw_body) - except json.JSONDecodeError as exc: - raise HTTPException(status_code=400, detail="Reset body must be valid JSON") from exc - if parsed_payload is None: - payload = {} - elif isinstance(parsed_payload, dict): - payload = parsed_payload - else: - raise HTTPException(status_code=400, detail="Reset body must be a JSON object") - - try: - reset_request = OpenEnvResetRequest.model_validate(payload) - except Exception as exc: - raise HTTPException(status_code=422, detail="Invalid reset request payload") from exc - - env._task_idx = _resolve_task_index(env, reset_request) - observation = env.reset() - session_id = str(uuid4()) - _store_session(session_id, env) - return OpenEnvResponseEnvelope( - session_id=session_id, - observation=_serialize_observation(observation), - reward=0.0, - done=False, - info=_safe_session_info(env._info()), - ) - - -@app.post("/openenv/step", response_model=OpenEnvResponseEnvelope) -@app.post("/openenv/step/", response_model=OpenEnvResponseEnvelope, include_in_schema=False) -@app.post("/step", response_model=OpenEnvResponseEnvelope, include_in_schema=False) -@app.post("/step/", response_model=OpenEnvResponseEnvelope, include_in_schema=False) -def openenv_step(request: OpenEnvActionRequest) -> OpenEnvResponseEnvelope: - session_id = _resolve_session_id(request.session_id) - env = _get_session_env(session_id) - action_type_raw = request.resolved_action_type().strip() - if not action_type_raw: - raise HTTPException(status_code=400, detail="Missing action_type") - try: - action_type = ActionType(action_type_raw) - except ValueError as exc: - raise HTTPException(status_code=400, detail=f"Unsupported action_type {action_type_raw}") from exc - observation, reward, done, info = env.step(Action(action_type=action_type, payload=request.resolved_payload())) - return OpenEnvResponseEnvelope( - session_id=session_id, - observation=_serialize_observation(observation), - reward=float(reward), - done=bool(done), - info=_safe_session_info(info), - ) - - -def _state_response(session_id: str) -> OpenEnvResponseEnvelope: - env = _get_session_env(session_id) - if env.state is None: - raise HTTPException(status_code=400, detail="Session has not been reset yet") - return OpenEnvResponseEnvelope( - session_id=session_id, - observation=_serialize_observation(env._observation()), - reward=0.0, - done=bool(env.state.done), - info=_safe_session_info(env._info()), - ) - - -@app.get("/openenv/state/{session_id}", response_model=OpenEnvResponseEnvelope) -def openenv_state(session_id: str) -> OpenEnvResponseEnvelope: - return _state_response(session_id) - - -@app.get("/openenv/state", response_model=OpenEnvResponseEnvelope, include_in_schema=False) -@app.get("/state", response_model=OpenEnvResponseEnvelope, include_in_schema=False) -@app.get("/state/", response_model=OpenEnvResponseEnvelope, include_in_schema=False) -def openenv_state_latest() -> OpenEnvResponseEnvelope: - return _state_response(_latest_session_id()) - - -@app.post("/openenv/report_inference", response_model=OpenEnvInferenceReportResponse) -def openenv_report_inference(request: OpenEnvInferenceReportRequest) -> OpenEnvInferenceReportResponse: - env = _build_environment() - normalized_episodes = _normalize_episode_rows(env, list(request.episodes)) - payload = { - "run": dict(request.run), - "summary": dict(request.summary), - "episodes": normalized_episodes, - } - LATEST_EVALUATION_OUTPUT.parent.mkdir(parents=True, exist_ok=True) - LATEST_EVALUATION_OUTPUT.write_text(json.dumps(payload, indent=2, sort_keys=True), encoding="utf-8") - dashboard_path = export_dashboard( - env=env, - evaluation=payload, - leaderboard_records=load_leaderboard("artifacts/baselines/openai_fixed_levels_leaderboard.json"), - output_path=str(SPACE_DASHBOARD), - ) - return OpenEnvInferenceReportResponse( - status="ok", - output_path=str(LATEST_EVALUATION_OUTPUT), - dashboard_path=str(dashboard_path), - ) - - -@app.get("/dashboard") -def dashboard() -> FileResponse: - snapshot = _space_snapshot() - return FileResponse(snapshot["dashboard_path"], media_type="text/html") - - -if __name__ == "__main__": - import uvicorn - - uvicorn.run("server:app", host="0.0.0.0", port=SPACE_PORT) diff --git a/scratch/osint/server/app.py b/scratch/osint/server/app.py deleted file mode 100644 index 0fcf128fd22e0af85ebe3f83e325b3f84f06279d..0000000000000000000000000000000000000000 --- a/scratch/osint/server/app.py +++ /dev/null @@ -1,26 +0,0 @@ -from __future__ import annotations - -import importlib.util -import os -from pathlib import Path - -import uvicorn - - -_ROOT_SERVER_PATH = Path(__file__).resolve().parents[1] / "server.py" -_SPEC = importlib.util.spec_from_file_location("osint_root_server", _ROOT_SERVER_PATH) -if _SPEC is None or _SPEC.loader is None: - raise RuntimeError(f"Unable to load server module from {_ROOT_SERVER_PATH}") - -_MODULE = importlib.util.module_from_spec(_SPEC) -_SPEC.loader.exec_module(_MODULE) -app = _MODULE.app - - -def main() -> None: - port = int(os.getenv("PORT", "7860")) - uvicorn.run("server.app:app", host="0.0.0.0", port=port) - - -if __name__ == "__main__": - main() diff --git a/scratch/osint/src/osint_env/__init__.py b/scratch/osint/src/osint_env/__init__.py deleted file mode 100644 index baddf8bf6a3ce397a17fd78ccee11fcb6c8446e8..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -"""OSINT RL environment package.""" - -from .env.environment import OSINTEnvironment - -__all__ = ["OSINTEnvironment"] diff --git a/scratch/osint/src/osint_env/agents/__init__.py b/scratch/osint/src/osint_env/agents/__init__.py deleted file mode 100644 index 884d50b613e3bf492ff2ea1fbd2aec4656833975..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/agents/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -"""Agent implementations.""" - -from osint_env.agents.single_agent import SingleAgentRunner -from osint_env.agents.swarm_agent import SwarmAgentRunner - -__all__ = ["SingleAgentRunner", "SwarmAgentRunner"] - diff --git a/scratch/osint/src/osint_env/agents/single_agent.py b/scratch/osint/src/osint_env/agents/single_agent.py deleted file mode 100644 index 7e523af80f778911a42486bf380997c982ce10fd..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/agents/single_agent.py +++ /dev/null @@ -1,41 +0,0 @@ -from __future__ import annotations - -from osint_env.domain.models import Action, ActionType -from osint_env.env.environment import OSINTEnvironment -from osint_env.llm.interface import LLMClient, RuleBasedMockLLM - - -class SingleAgentRunner: - def __init__(self, env: OSINTEnvironment, llm: LLMClient | None = None): - self.env = env - self.llm = llm or RuleBasedMockLLM() - - def run_episode(self) -> dict: - obs = self.env.reset() - done = False - info = {} - while not done: - messages = [{"role": "system", "content": f"question: {obs.task['question']}"}] - tools = [] - try: - llm_resp = self.llm.generate(messages, tools) - planned_calls = llm_resp.tool_calls[:2] - except Exception: - planned_calls = [] - - for call in planned_calls: - obs, _, done, info = self.env.step(Action(ActionType.CALL_TOOL, call)) - if done: - break - if done: - break - answer_guess = self._heuristic_answer(obs.task["question"]) - obs, _, done, info = self.env.step(Action(ActionType.ANSWER, {"answer": answer_guess})) - return info - - @staticmethod - def _heuristic_answer(question: str) -> str: - for token in question.replace("?", "").split(): - if token.startswith("alias_") or token.startswith("user_"): - return token - return "unknown" diff --git a/scratch/osint/src/osint_env/agents/swarm_agent.py b/scratch/osint/src/osint_env/agents/swarm_agent.py deleted file mode 100644 index 534d526aea89593f452655f3e95284e1d957d4df..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/agents/swarm_agent.py +++ /dev/null @@ -1,209 +0,0 @@ -from __future__ import annotations - -import re -from typing import Any - -from osint_env.domain.models import Action, ActionType -from osint_env.env.environment import OSINTEnvironment -from osint_env.env.spawn_reward_hooks import critical_steps, parl_style_spawn_reward -from osint_env.llm.interface import LLMClient, RuleBasedMockLLM - - -class SwarmAgentRunner: - """Low-width multi-agent orchestrator over a single environment episode.""" - - def __init__(self, env: OSINTEnvironment, llm: LLMClient | None = None): - self.env = env - self.llm = llm or RuleBasedMockLLM() - - def run_episode(self) -> dict[str, Any]: - obs = self.env.reset() - done = False - info: dict[str, Any] = {} - - swarm_cfg = self.env.config.swarm - spawn_cfg = self.env.config.spawn_reward - - spawn_count = 0 - finished_subtasks = 0 - depth_used = 0 - max_breadth_used = 0 - - stage_main_steps: list[int] = [] - stage_sub_steps: list[list[int]] = [] - - for _ in range(max(1, swarm_cfg.planner_rounds)): - if done: - break - - active_agents = max(1, min(swarm_cfg.max_agents, swarm_cfg.max_breadth, swarm_cfg.max_width)) - max_breadth_used = max(max_breadth_used, active_agents) - depth_used += 1 - spawn_count += active_agents - stage_main_steps.append(1) - - stage_steps: list[int] = [] - for agent_idx in range(active_agents): - if done: - break - - steps_for_agent = 0 - role = self._agent_role(agent_idx) - planned_calls = self._tool_plan( - obs=obs, - agent_idx=agent_idx, - role=role, - limit=swarm_cfg.tools_per_agent, - ) - for call in planned_calls: - obs, _, done, info = self.env.step(Action(ActionType.CALL_TOOL, call)) - steps_for_agent += 1 - if done: - break - - if not done: - edge_payload = self._edge_plan(agent_idx=agent_idx) - if edge_payload is not None: - obs, _, done, info = self.env.step(Action(ActionType.ADD_EDGE, edge_payload)) - steps_for_agent += 1 - - if steps_for_agent > 0: - finished_subtasks += 1 - stage_steps.append(steps_for_agent) - - stage_sub_steps.append(stage_steps) - - if depth_used >= swarm_cfg.max_depth: - break - - if not done: - answer_guess = self._vote_answer() - obs, _, done, info = self.env.step(Action(ActionType.ANSWER, {"answer": answer_guess})) - - crit_steps = critical_steps( - main_steps=stage_main_steps or [1], - parallel_subagent_steps=stage_sub_steps or [[]], - ) - - base_total = float(info.get("total_reward", 0.0)) - shaped_total = parl_style_spawn_reward( - task_outcome_reward=base_total, - spawn_count=spawn_count, - finished_subtasks=finished_subtasks, - critical_steps=max(1, crit_steps), - lambda_parallel=spawn_cfg.lambda_parallel, - lambda_finish=spawn_cfg.lambda_finish, - anneal=spawn_cfg.anneal, - breadth=max_breadth_used, - depth=depth_used, - max_parallel_hint=spawn_cfg.max_parallel_hint, - ) - spawn_aux = shaped_total - base_total - - components = dict(info.get("reward_components", {})) - components["spawn_auxiliary"] = components.get("spawn_auxiliary", 0.0) + float(spawn_aux) - components["spawn_count"] = float(spawn_count) - components["spawn_finished_subtasks"] = float(finished_subtasks) - components["spawn_critical_steps"] = float(crit_steps) - components["spawn_depth"] = float(depth_used) - components["spawn_breadth"] = float(max_breadth_used) - - info["total_reward"] = shaped_total - info["reward_components"] = components - info["spawn_count"] = spawn_count - info["spawn_finished_subtasks"] = finished_subtasks - info["spawn_critical_steps"] = crit_steps - info["spawn_depth"] = depth_used - info["spawn_breadth"] = max_breadth_used - info["swarm_roles"] = [self._agent_role(i) for i in range(max_breadth_used)] - - if self.env.state is not None: - self.env.state.total_reward = shaped_total - self.env.state.reward_components.update(components) - - return info - - @staticmethod - def _agent_role(agent_idx: int) -> str: - roles = ["explorer", "linker", "reasoner"] - return roles[agent_idx % len(roles)] - - def _tool_plan(self, obs: Any, agent_idx: int, role: str, limit: int) -> list[dict[str, Any]]: - messages = [ - { - "role": "system", - "content": ( - f"question: {obs.task['question']}\n" - f"agent_role: {role}_{agent_idx}\n" - "Return concise tool plan." - ), - } - ] - try: - response = self.llm.generate(messages, tools=[]) - except Exception: - response = None - - calls: list[dict[str, Any]] = [] - for call in (response.tool_calls if response is not None else []): - if not isinstance(call, dict): - continue - tool_name = str(call.get("tool_name", "")).strip() - args = call.get("args", {}) - if not tool_name or not isinstance(args, dict): - continue - calls.append({"tool_name": tool_name, "args": args}) - if len(calls) >= max(1, limit): - break - - if calls: - return calls - - question = str(obs.task.get("question", "")).lower() - if role == "explorer": - if "event" in question: - return [{"tool_name": "search_threads", "args": {"topic": "security"}}] - return [{"tool_name": "search_posts", "args": {"query": "Update"}}] - - if role == "linker": - if "alias" in question: - return [{"tool_name": "search_posts", "args": {"query": "alias"}}] - return [{"tool_name": "search_people", "args": {"org": "Apex"}}] - - if role == "reasoner": - return [{"tool_name": "search_memory", "args": {"query": obs.task.get("question", ""), "k": 5}}] - - if "alias" in question: - return [{"tool_name": "search_posts", "args": {"query": "Update"}}] - - user_tokens = re.findall(r"\buser_[a-zA-Z0-9_]+\b", question) - if user_tokens: - return [{"tool_name": "get_profile", "args": {"user_id": user_tokens[0]}}] - - return [{"tool_name": "search_people", "args": {"org": "Apex"}}] - - def _edge_plan(self, agent_idx: int) -> dict[str, Any] | None: - if self.env.state is None or not self.env.state.task.supporting_edges: - return None - edge = self.env.state.task.supporting_edges[agent_idx % len(self.env.state.task.supporting_edges)] - return { - "src": edge.src, - "rel": edge.rel, - "dst": edge.dst, - "confidence": float(edge.confidence), - } - - def _vote_answer(self) -> str: - if self.env.state is None: - return "unknown" - - truth = {(e.src, e.rel, e.dst) for e in self.env.state.task.supporting_edges} - pred = {(e.src, e.rel, e.dst) for e in self.env.memory_graph.edges} - if truth & pred: - return self.env.state.task.answer - - question = self.env.state.task.question - for token in question.replace("?", "").split(): - if token.startswith("alias_") or token.startswith("user_"): - return token - return "unknown" diff --git a/scratch/osint/src/osint_env/api/__init__.py b/scratch/osint/src/osint_env/api/__init__.py deleted file mode 100644 index ecc3ec5bd47138834c3f4763f951b8cae9a28282..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/api/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -from osint_env.api.models import ( - OpenEnvActionRequest, - OpenEnvInferenceReportRequest, - OpenEnvInferenceReportResponse, - OpenEnvObservationModel, - OpenEnvResetRequest, - OpenEnvResponseEnvelope, - OpenEnvTaskSummary, -) - -__all__ = [ - "OpenEnvActionRequest", - "OpenEnvInferenceReportRequest", - "OpenEnvInferenceReportResponse", - "OpenEnvObservationModel", - "OpenEnvResetRequest", - "OpenEnvResponseEnvelope", - "OpenEnvTaskSummary", -] diff --git a/scratch/osint/src/osint_env/api/models.py b/scratch/osint/src/osint_env/api/models.py deleted file mode 100644 index 67cfae4cd577057ba2ab65953970f391358579c3..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/api/models.py +++ /dev/null @@ -1,73 +0,0 @@ -from __future__ import annotations - -from typing import Any - -from pydantic import BaseModel, Field - - -class OpenEnvTaskSummary(BaseModel): - task_id: str - task_type: str - question: str - difficulty: str = "unknown" - grader: dict[str, Any] = Field(default_factory=dict) - - -class OpenEnvObservationModel(BaseModel): - tool_outputs: list[dict[str, Any]] - graph_snapshot: dict[str, Any] - action_history: list[dict[str, Any]] - task: dict[str, Any] - - -class OpenEnvResetRequest(BaseModel): - task_id: str | None = None - task_index: int | None = None - - -class OpenEnvActionRequest(BaseModel): - session_id: str | None = Field( - default=None, - description="Session identifier. Optional for /step compatibility alias, which uses the latest session.", - ) - action_type: str | None = Field(default=None, description="One of CALL_TOOL, ADD_EDGE, ANSWER.") - payload: dict[str, Any] = Field(default_factory=dict) - action: dict[str, Any] | None = None - - def resolved_action_type(self) -> str: - if self.action_type: - return str(self.action_type) - if isinstance(self.action, dict): - nested = self.action.get("action_type") - if nested: - return str(nested) - return "" - - def resolved_payload(self) -> dict[str, Any]: - if self.payload: - return dict(self.payload) - if isinstance(self.action, dict): - nested = self.action.get("payload") - if isinstance(nested, dict): - return dict(nested) - return {} - - -class OpenEnvResponseEnvelope(BaseModel): - session_id: str - observation: OpenEnvObservationModel - reward: float - done: bool - info: dict[str, Any] - - -class OpenEnvInferenceReportRequest(BaseModel): - run: dict[str, Any] = Field(default_factory=dict) - summary: dict[str, Any] - episodes: list[dict[str, Any]] = Field(default_factory=list) - - -class OpenEnvInferenceReportResponse(BaseModel): - status: str - output_path: str - dashboard_path: str diff --git a/scratch/osint/src/osint_env/baselines/__init__.py b/scratch/osint/src/osint_env/baselines/__init__.py deleted file mode 100644 index 1bba1e79c306b0b02a2760fa37703138be49db22..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/baselines/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from osint_env.baselines.openai_runner import OpenAIBaselineConfig, OpenAIBaselineRunner - -__all__ = ["OpenAIBaselineConfig", "OpenAIBaselineRunner"] - diff --git a/scratch/osint/src/osint_env/baselines/openai_runner.py b/scratch/osint/src/osint_env/baselines/openai_runner.py deleted file mode 100644 index 6fedfc3e830f0b0b542df0fbcf82b46109a9f786..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/baselines/openai_runner.py +++ /dev/null @@ -1,533 +0,0 @@ -from __future__ import annotations - -import json -from dataclasses import asdict, dataclass -from pathlib import Path -from time import perf_counter -from typing import Any - -from osint_env.config import clone_environment_config, load_seeding_config, load_shared_config -from osint_env.domain.models import Action, ActionType, Edge -from osint_env.env.environment import OSINTEnvironment -from osint_env.env.reward import compute_graph_f1 -from osint_env.eval.leaderboard import append_leaderboard_record, load_leaderboard -from osint_env.eval.metrics import EvalMetrics -from osint_env.viz import export_dashboard - - -SYSTEM_PROMPT = """You are an OSINT benchmark agent operating in a synthetic OpenEnv task. - -Available actions are provided as function tools. On every turn, call exactly one tool. - -Rules: -- Solve the question using only tool outputs and the current graph snapshot. -- When you have enough evidence, call submit_answer with the exact node id string. -- Questions may contain exact node ids such as alias_*, user_*, post_*, thr_*, org_*, loc_*, and event_*. -- Prefer direct id lookups when an exact id is present in the question. -- get_post and get_thread retrieve exact seeded records by id. -- Use add_edge only for relationships strongly supported by the evidence you have already collected. -- Prefer concise, high-signal tool queries. -- Never guess free-form prose when a node id answer is required. -""" - - -@dataclass(slots=True) -class OpenAIBaselineConfig: - shared_config_path: str = "datasets/fixed_levels/shared_config_fixed_levels.json" - seed_file: str = "datasets/fixed_levels/seed_fixed_levels.json" - output_path: str = "artifacts/baselines/openai_fixed_levels_latest.json" - leaderboard_path: str = "artifacts/baselines/openai_fixed_levels_leaderboard.json" - dashboard_path: str = "artifacts/baselines/openai_fixed_levels_dashboard.html" - run_name: str = "openai_fixed_levels_baseline" - model: str = "gpt-5-nano" - base_url: str = "https://api.openai.com/v1" - api_key: str = "" - api_key_env: str = "OPENAI_API_KEY" - temperature: float = 0.0 - max_tokens: int = 256 - timeout_seconds: int = 60 - episodes: int = 30 - max_steps: int = 8 - seed: int | None = 7 - append_leaderboard: bool = True - - -def _tool_schema( - name: str, - description: str, - properties: dict[str, Any], - required: list[str], -) -> dict[str, Any]: - return { - "type": "function", - "function": { - "name": name, - "description": description, - "parameters": { - "type": "object", - "properties": properties, - "required": required, - "additionalProperties": False, - }, - }, - } - - -def build_action_tools() -> list[dict[str, Any]]: - return [ - _tool_schema( - "search_posts", - "Search microblog posts by substring over post text, post id, author id, canonical user id, or referenced entity ids/names.", - {"query": {"type": "string", "description": "Substring to search for in post text."}}, - ["query"], - ), - _tool_schema( - "get_post", - "Fetch a specific microblog post by exact post id.", - {"post_id": {"type": "string", "description": "Post node id such as post_midnight_manifest."}}, - ["post_id"], - ), - _tool_schema( - "get_user_posts", - "Fetch posts authored by a user or alias id. Alias ids are resolved to the canonical user and vice versa.", - {"user_id": {"type": "string", "description": "User or alias node id."}}, - ["user_id"], - ), - _tool_schema( - "get_mentions", - "Fetch posts that mention a given canonical user id.", - {"user_id": {"type": "string", "description": "Canonical user node id."}}, - ["user_id"], - ), - _tool_schema( - "search_threads", - "Search forum threads by exact topic name.", - {"topic": {"type": "string", "description": "Thread topic such as security or ai."}}, - ["topic"], - ), - _tool_schema( - "get_thread", - "Fetch a specific forum thread by id.", - {"thread_id": {"type": "string", "description": "Thread node id."}}, - ["thread_id"], - ), - _tool_schema( - "get_user_activity", - "Fetch a user's known forum activity.", - {"user_id": {"type": "string", "description": "Canonical user node id."}}, - ["user_id"], - ), - _tool_schema( - "get_profile", - "Fetch a profile record by canonical user id or alias id.", - {"user_id": {"type": "string", "description": "Canonical user node id or alias id."}}, - ["user_id"], - ), - _tool_schema( - "search_people", - "Search profiles by name, alias id, organization name, or organization id.", - { - "name": {"type": "string", "description": "Optional name substring.", "default": ""}, - "org": {"type": "string", "description": "Optional organization substring.", "default": ""}, - }, - [], - ), - _tool_schema( - "get_connections", - "Fetch explicit profile connections for a user or alias id.", - {"user_id": {"type": "string", "description": "Canonical user node id or alias id."}}, - ["user_id"], - ), - _tool_schema( - "search_memory", - "Search semantic memory over prior observations and tool outputs.", - { - "query": {"type": "string", "description": "Memory retrieval query."}, - "k": {"type": "integer", "description": "Top-k matches.", "default": 5}, - }, - ["query"], - ), - _tool_schema( - "add_edge", - "Add a supported graph edge to the working memory graph.", - { - "src": {"type": "string"}, - "rel": {"type": "string"}, - "dst": {"type": "string"}, - "confidence": {"type": "number", "default": 1.0}, - }, - ["src", "rel", "dst"], - ), - _tool_schema( - "submit_answer", - "Finish the episode by submitting the exact node id answer.", - {"answer": {"type": "string", "description": "Exact node id answer for the task."}}, - ["answer"], - ), - ] - - -def _message_text(message: Any) -> str: - content = getattr(message, "content", "") - if isinstance(content, str): - return content - if isinstance(content, list): - parts: list[str] = [] - for item in content: - if isinstance(item, dict) and item.get("type") == "text": - parts.append(str(item.get("text", ""))) - else: - text = getattr(item, "text", None) - if text: - parts.append(str(text)) - return "\n".join(part for part in parts if part) - return str(content or "") - - -def _safe_info(info: dict[str, Any]) -> dict[str, Any]: - return { - "step_count": int(info.get("step_count", 0)), - "total_reward": float(info.get("total_reward", 0.0)), - "tool_calls": int(info.get("tool_calls", 0)), - "redundant_tool_calls": int(info.get("redundant_tool_calls", 0)), - "reward_components": dict(info.get("reward_components", {})), - } - - -def _observation_payload(env: OSINTEnvironment, observation: Any, step_limit: int) -> dict[str, Any]: - task = dict(observation.task) - return { - "task": { - "task_id": task.get("task_id", ""), - "task_type": task.get("task_type", ""), - "question": task.get("question", ""), - }, - "remaining_steps": max(0, step_limit - int(env.state.step_count if env.state else 0)), - "recent_tool_outputs": list(observation.tool_outputs), - "graph_snapshot": dict(observation.graph_snapshot), - "recent_action_history": list(observation.action_history), - } - - -class OpenAIBaselineRunner: - def __init__(self, config: OpenAIBaselineConfig): - self.config = config - - from openai import OpenAI - - if not config.api_key: - raise ValueError( - "OpenAI baseline requires an API key. " - f"Set {config.api_key_env} or pass --openai-api-key." - ) - - self.client = OpenAI( - api_key=config.api_key, - base_url=config.base_url, - timeout=config.timeout_seconds, - ) - self.tools = build_action_tools() - - @staticmethod - def _is_gpt5_family(model: str) -> bool: - return str(model).strip().lower().startswith("gpt-5") - - @staticmethod - def _supports_reasoning_effort_in_chat_completions(model: str) -> bool: - model_name = str(model).strip().lower() - if model_name.startswith("gpt-5.4-mini"): - return False - return model_name.startswith("gpt-5") - - def _request_kwargs(self, messages: list[dict[str, Any]], episode_index: int) -> dict[str, Any]: - kwargs: dict[str, Any] = { - "model": self.config.model, - "messages": messages, - "tools": self.tools, - "tool_choice": "required", - "parallel_tool_calls": False, - "max_completion_tokens": self.config.max_tokens, - } - if self.config.seed is not None: - kwargs["seed"] = int(self.config.seed) + episode_index - - if self._is_gpt5_family(self.config.model): - # GPT-5 family chat-completions compatibility: - # use max_completion_tokens and avoid temperature for older GPT-5 models. - if self._supports_reasoning_effort_in_chat_completions(self.config.model): - kwargs["reasoning_effort"] = "none" - else: - kwargs["temperature"] = self.config.temperature - - return kwargs - - def _build_environment(self) -> OSINTEnvironment: - shared = load_shared_config(self.config.shared_config_path) - env_cfg = clone_environment_config(shared.environment) - env_cfg.seeding = load_seeding_config(self.config.seed_file) - env_cfg.llm.provider = "mock" - env_cfg.llm.model = self.config.model - env_cfg.llm.temperature = self.config.temperature - env_cfg.llm.max_tokens = self.config.max_tokens - env_cfg.max_steps = min(int(env_cfg.max_steps), int(self.config.max_steps)) - return OSINTEnvironment(env_cfg) - - def _execute_action( - self, - env: OSINTEnvironment, - tool_name: str, - args: dict[str, Any], - ) -> tuple[Any, float, bool, dict[str, Any], dict[str, Any]]: - if tool_name == "submit_answer": - answer = str(args.get("answer", "")).strip() - obs, reward, done, info = env.step(Action(ActionType.ANSWER, {"answer": answer})) - result = {"submitted_answer": answer} - return obs, reward, done, info, result - - if tool_name == "add_edge": - payload = { - "src": str(args.get("src", "")).strip(), - "rel": str(args.get("rel", "")).strip(), - "dst": str(args.get("dst", "")).strip(), - "confidence": float(args.get("confidence", 1.0)), - } - obs, reward, done, info = env.step(Action(ActionType.ADD_EDGE, payload)) - return obs, reward, done, info, payload - - payload = {"tool_name": tool_name, "args": dict(args)} - obs, reward, done, info = env.step(Action(ActionType.CALL_TOOL, payload)) - result = obs.tool_outputs[-1]["output"] if obs.tool_outputs else {} - return obs, reward, done, info, result - - def _episode(self, env: OSINTEnvironment, episode_index: int) -> tuple[dict[str, Any], dict[str, Any]]: - obs = env.reset() - initial_observation = _observation_payload(env, obs, env.config.max_steps) - messages: list[dict[str, Any]] = [ - {"role": "system", "content": SYSTEM_PROMPT}, - { - "role": "user", - "content": json.dumps(initial_observation, indent=2, sort_keys=True), - }, - ] - - turn_trace: list[dict[str, Any]] = [] - raw_fingerprints: list[str] = [] - info: dict[str, Any] = {} - done = False - usage_totals = {"prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0} - - while not done and env.state is not None and env.state.step_count < env.config.max_steps: - completion = self.client.chat.completions.create(**self._request_kwargs(messages, episode_index)) - if getattr(completion, "system_fingerprint", None): - raw_fingerprints.append(str(completion.system_fingerprint)) - if getattr(completion, "usage", None) is not None: - usage_totals["prompt_tokens"] += int(getattr(completion.usage, "prompt_tokens", 0) or 0) - usage_totals["completion_tokens"] += int(getattr(completion.usage, "completion_tokens", 0) or 0) - usage_totals["total_tokens"] += int(getattr(completion.usage, "total_tokens", 0) or 0) - - message = completion.choices[0].message - content = _message_text(message) - tool_calls = list(message.tool_calls or []) - if not tool_calls: - fallback_answer = content.strip() or "unknown" - obs, reward, done, info = env.step(Action(ActionType.ANSWER, {"answer": fallback_answer})) - tool_result = { - "submitted_answer": fallback_answer, - "reward": reward, - "done": done, - "observation": _observation_payload(env, obs, env.config.max_steps), - "info": _safe_info(info), - } - messages.append({"role": "assistant", "content": content}) - messages.append({"role": "tool", "tool_call_id": "fallback_submit", "content": json.dumps(tool_result)}) - turn_trace.append( - { - "assistant_content": content, - "tool_name": "submit_answer", - "args": {"answer": fallback_answer}, - "tool_payload": tool_result, - } - ) - break - - tool_call = tool_calls[0] - tool_name = str(tool_call.function.name) - try: - args = json.loads(tool_call.function.arguments or "{}") - except json.JSONDecodeError: - args = {} - if not isinstance(args, dict): - args = {} - - obs, reward, done, info, result = self._execute_action(env, tool_name, args) - tool_payload = { - "tool_name": tool_name, - "args": args, - "result": result, - "reward": reward, - "done": done, - "observation": _observation_payload(env, obs, env.config.max_steps), - "info": _safe_info(info), - } - assistant_message = { - "role": "assistant", - "content": content, - "tool_calls": [ - { - "id": tool_call.id, - "type": "function", - "function": { - "name": tool_name, - "arguments": json.dumps(args, sort_keys=True), - }, - } - ], - } - messages.append(assistant_message) - messages.append({"role": "tool", "tool_call_id": tool_call.id, "content": json.dumps(tool_payload, sort_keys=True)}) - turn_trace.append( - { - "assistant_content": content, - "tool_name": tool_name, - "args": args, - "reward": reward, - "done": done, - "tool_payload": tool_payload, - } - ) - - if not done: - obs, _, done, info = env.step(Action(ActionType.ANSWER, {"answer": "unknown"})) - final_payload = { - "submitted_answer": "unknown", - "reward": 0.0, - "done": done, - "observation": _observation_payload(env, obs, env.config.max_steps), - "info": _safe_info(info), - } - turn_trace.append( - { - "assistant_content": "", - "tool_name": "submit_answer", - "args": {"answer": "unknown"}, - "reward": 0.0, - "done": done, - "tool_payload": final_payload, - } - ) - - info = dict(info) - info["openai_system_fingerprints"] = raw_fingerprints - info["usage"] = usage_totals - return info, {"initial_observation": initial_observation, "turns": turn_trace} - - def run(self) -> dict[str, Any]: - env = self._build_environment() - metrics = EvalMetrics() - episode_rows: list[dict[str, Any]] = [] - - started = perf_counter() - run_usage = {"prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0} - for episode_index in range(int(self.config.episodes)): - info, trace = self._episode(env, episode_index) - episode_usage = dict(info.get("usage", {})) - for key in run_usage: - run_usage[key] += int(episode_usage.get(key, 0) or 0) - task_type = env.state.task.task_type if env.state else "unknown" - task_id = env.state.task.task_id if env.state else f"episode_{episode_index}" - truth = env.state.task.supporting_edges if env.state else [] - pred = env.memory_graph.edges if env.state else [] - graph_f1 = compute_graph_f1(pred, truth) - metrics.add(info, task_type=task_type, graph_f1=graph_f1) - episode_rows.append( - { - "task_id": task_id, - "task_type": task_type, - "question": env.state.task.question if env.state else "", - "task_answer": str(info.get("task_answer", "")), - "agent_answer": str(info.get("agent_answer", "")) if info.get("agent_answer") is not None else "", - "graph_f1": graph_f1, - "reward": float(info.get("total_reward", 0.0)), - "steps": int(info.get("step_count", 0)), - "tool_calls": int(info.get("tool_calls", 0)), - "success": int(info.get("agent_answer") == info.get("task_answer")), - "reward_components": dict(info.get("reward_components", {})), - "pred_edges": [ - { - "src": edge.src, - "rel": edge.rel, - "dst": edge.dst, - "confidence": float(edge.confidence), - } - for edge in pred - ], - "truth_edges": [ - { - "src": edge.src, - "rel": edge.rel, - "dst": edge.dst, - "confidence": float(edge.confidence), - } - for edge in truth - ], - "trace": trace, - "openai_system_fingerprints": list(info.get("openai_system_fingerprints", [])), - "usage": episode_usage, - } - ) - - summary = metrics.summary() - duration_seconds = perf_counter() - started - if self.config.append_leaderboard: - record = append_leaderboard_record( - path=self.config.leaderboard_path, - summary=summary, - episodes=int(self.config.episodes), - run_name=self.config.run_name, - config={ - "provider": "openai", - "model": self.config.model, - "seed": self.config.seed, - "max_steps": self.config.max_steps, - "shared_config_path": self.config.shared_config_path, - "seed_file": self.config.seed_file, - }, - ) - else: - record = None - dashboard_path = export_dashboard( - env=env, - evaluation={"summary": summary, "episodes": episode_rows}, - leaderboard_records=load_leaderboard(self.config.leaderboard_path), - output_path=self.config.dashboard_path, - ) - - payload: dict[str, Any] = { - "run": { - "name": self.config.run_name, - "model": self.config.model, - "episodes": int(self.config.episodes), - "temperature": float(self.config.temperature), - "max_tokens": int(self.config.max_tokens), - "timeout_seconds": int(self.config.timeout_seconds), - "max_steps": int(self.config.max_steps), - "seed": self.config.seed, - "shared_config_path": self.config.shared_config_path, - "seed_file": self.config.seed_file, - "duration_seconds": duration_seconds, - "dashboard_path": dashboard_path, - }, - "summary": summary, - "usage": run_usage, - "episodes": episode_rows, - } - - output = Path(self.config.output_path) - output.parent.mkdir(parents=True, exist_ok=True) - output.write_text(json.dumps(payload, indent=2, sort_keys=True), encoding="utf-8") - - if record is not None: - payload["record"] = record - output.write_text(json.dumps(payload, indent=2, sort_keys=True), encoding="utf-8") - - return payload diff --git a/scratch/osint/src/osint_env/cli.py b/scratch/osint/src/osint_env/cli.py deleted file mode 100644 index 707f3a492fd2513846fc1c6ee4d491fa4385e7ca..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/cli.py +++ /dev/null @@ -1,339 +0,0 @@ -from __future__ import annotations - -import argparse -import json -from pathlib import Path - -from osint_env.agents.single_agent import SingleAgentRunner -from osint_env.agents.swarm_agent import SwarmAgentRunner -from osint_env.config import clone_environment_config, load_seeding_config, load_shared_config -from osint_env.domain.models import EnvironmentConfig -from osint_env.env.environment import OSINTEnvironment -from osint_env.env.reward import compute_graph_f1 -from osint_env.eval.leaderboard import append_leaderboard_record, load_leaderboard, render_leaderboard_table -from osint_env.eval.runner import run_evaluation -from osint_env.llm import build_llm_client -from osint_env.viz import export_dashboard - - -DEFAULT_EVALUATION_PATH = "artifacts/latest_evaluation.json" - - -def _save_evaluation(path: str, payload: dict) -> None: - out = Path(path) - out.parent.mkdir(parents=True, exist_ok=True) - out.write_text(json.dumps(payload, indent=2, sort_keys=True), encoding="utf-8") - - -def _load_evaluation(path: str) -> dict | None: - file_path = Path(path) - if not file_path.exists(): - return None - try: - data = json.loads(file_path.read_text(encoding="utf-8")) - except json.JSONDecodeError: - return None - if not isinstance(data, dict): - return None - return data - - -def _add_common_args(parser: argparse.ArgumentParser) -> None: - parser.add_argument("--config", type=str, default="config/shared_config.json") - parser.add_argument("--seed-file", type=str, default="") - parser.add_argument( - "--agent-mode", - type=str, - default="config", - choices=["config", "single", "swarm"], - help="Use shared config mode or override runner mode explicitly.", - ) - parser.add_argument( - "--llm-provider", - type=str, - default="config", - choices=["config", "mock", "ollama", "openai"], - help="Use shared config provider or override explicitly.", - ) - parser.add_argument("--llm-model", type=str, default="", help="Override model name for selected LLM provider.") - parser.add_argument("--llm-timeout-seconds", type=int, default=0, help="Override LLM request timeout in seconds.") - parser.add_argument("--ollama-base-url", type=str, default="", help="Override Ollama base URL.") - parser.add_argument("--openai-base-url", type=str, default="", help="Override OpenAI base URL.") - parser.add_argument("--openai-api-key", type=str, default="", help="OpenAI API key override.") - parser.add_argument( - "--openai-api-key-env", - type=str, - default="", - help="Environment variable name for OpenAI API key.", - ) - - -def build_parser() -> argparse.ArgumentParser: - parser = argparse.ArgumentParser(prog="osint-env") - sub = parser.add_subparsers(dest="cmd", required=True) - - d = sub.add_parser("demo", help="Run one episode and print debug info.") - _add_common_args(d) - - e = sub.add_parser("eval", help="Run multiple episodes and show aggregate metrics.") - _add_common_args(e) - e.add_argument("--episodes", type=int, default=0) - - b = sub.add_parser("benchmark", help="Run eval, update leaderboard, and export interactive dashboard.") - _add_common_args(b) - b.add_argument("--episodes", type=int, default=0) - b.add_argument("--name", type=str, default="") - b.add_argument("--leaderboard", type=str, default="") - b.add_argument("--dashboard", type=str, default="") - - l = sub.add_parser("leaderboard", help="Print ranked benchmark leaderboard.") - _add_common_args(l) - l.add_argument("--leaderboard", type=str, default="") - l.add_argument("--top", type=int, default=20) - l.add_argument( - "--sort-by", - type=str, - default="leaderboard_score", - choices=[ - "leaderboard_score", - "task_success_rate", - "avg_graph_f1", - "tool_efficiency", - "avg_reward", - "retrieval_signal", - "structural_signal", - "deanonymization_accuracy", - "spawn_signal", - ], - ) - - s = sub.add_parser("benchmark-sweep", help="Run benchmark across multiple seeds and append all runs to leaderboard.") - _add_common_args(s) - s.add_argument("--episodes", type=int, default=0) - s.add_argument("--seeds", type=str, default="7,11,17,23,31") - s.add_argument("--name-prefix", type=str, default="sweep") - s.add_argument("--leaderboard", type=str, default="") - s.add_argument("--dashboard-dir", type=str, default="") - - v = sub.add_parser("viz", help="Export an interactive graph/database explorer.") - _add_common_args(v) - v.add_argument("--output", type=str, default="artifacts/osint_explorer.html") - v.add_argument("--with-demo", action="store_true") - v.add_argument("--leaderboard", type=str, default="") - v.add_argument( - "--evaluation", - type=str, - default=DEFAULT_EVALUATION_PATH, - help="Path to a saved evaluation payload with episode details.", - ) - return parser - - -def _resolve_environment_config(args: argparse.Namespace) -> tuple[EnvironmentConfig, dict[str, str | int]]: - shared = load_shared_config(args.config) - env_cfg = clone_environment_config(shared.environment) - - if args.seed_file: - env_cfg.seeding = load_seeding_config(args.seed_file) - - if args.llm_provider != "config": - env_cfg.llm.provider = args.llm_provider - if args.llm_model: - env_cfg.llm.model = args.llm_model - if int(args.llm_timeout_seconds) > 0: - env_cfg.llm.timeout_seconds = int(args.llm_timeout_seconds) - if args.ollama_base_url: - env_cfg.llm.ollama_base_url = args.ollama_base_url - if args.openai_base_url: - env_cfg.llm.openai_base_url = args.openai_base_url - if args.openai_api_key: - env_cfg.llm.openai_api_key = args.openai_api_key - if args.openai_api_key_env: - env_cfg.llm.openai_api_key_env = args.openai_api_key_env - - if args.agent_mode == "single": - env_cfg.swarm.enabled = False - elif args.agent_mode == "swarm": - env_cfg.swarm.enabled = True - - runtime = { - "default_episodes": shared.runtime.default_episodes, - "leaderboard_path": shared.runtime.leaderboard_path, - "dashboard_path": shared.runtime.dashboard_path, - "sweep_dashboard_dir": shared.runtime.sweep_dashboard_dir, - } - return env_cfg, runtime - - -def _runner_for(env: OSINTEnvironment) -> SingleAgentRunner | SwarmAgentRunner: - if env.config.swarm.enabled: - return SwarmAgentRunner(env, llm=build_llm_client(env.config.llm)) - return SingleAgentRunner(env, llm=build_llm_client(env.config.llm)) - - -def main() -> None: - args = build_parser().parse_args() - env_cfg, runtime = _resolve_environment_config(args) - - episodes = int(args.episodes) if getattr(args, "episodes", 0) else int(runtime["default_episodes"]) - leaderboard_path = str(args.leaderboard) if getattr(args, "leaderboard", "") else str(runtime["leaderboard_path"]) - dashboard_path = str(args.dashboard) if getattr(args, "dashboard", "") else str(runtime["dashboard_path"]) - sweep_dashboard_dir = ( - str(args.dashboard_dir) if getattr(args, "dashboard_dir", "") else str(runtime["sweep_dashboard_dir"]) - ) - evaluation_path = str(getattr(args, "evaluation", "") or DEFAULT_EVALUATION_PATH) - - if args.cmd == "leaderboard": - records = load_leaderboard(leaderboard_path) - print(render_leaderboard_table(records, top_k=args.top, sort_by=args.sort_by)) - return - - if args.cmd == "benchmark-sweep": - seed_values = [int(x.strip()) for x in args.seeds.split(",") if x.strip()] - outputs: list[dict[str, object]] = [] - for seed in seed_values: - seeded_cfg = clone_environment_config(env_cfg) - seeded_cfg.seed = seed - env = OSINTEnvironment(seeded_cfg, llm=build_llm_client(seeded_cfg.llm)) - evaluation = run_evaluation(env, episodes=episodes, return_details=True, llm=build_llm_client(seeded_cfg.llm)) - summary = evaluation["summary"] - run_name = f"{args.name_prefix}_seed{seed}" - record = append_leaderboard_record( - path=leaderboard_path, - summary=summary, - episodes=episodes, - run_name=run_name, - config={ - "seed": seed, - "max_steps": env.config.max_steps, - "swarm_enabled": env.config.swarm.enabled, - "max_agents": env.config.swarm.max_agents, - "max_breadth": env.config.swarm.max_breadth, - "max_width": env.config.swarm.max_width, - "max_depth": env.config.swarm.max_depth, - "seeded_questions": len(env.config.seeding.seeded_questions), - }, - ) - dashboard_path = export_dashboard( - env=env, - evaluation=evaluation, - leaderboard_records=load_leaderboard(leaderboard_path), - output_path=f"{sweep_dashboard_dir}/{run_name}.html", - ) - _save_evaluation(DEFAULT_EVALUATION_PATH, evaluation) - outputs.append({"seed": seed, "record": record, "dashboard": dashboard_path, "summary": summary}) - - records = load_leaderboard(leaderboard_path) - print( - json.dumps( - { - "runs": outputs, - "leaderboard_preview": render_leaderboard_table(records, top_k=min(10, len(records))), - }, - indent=2, - sort_keys=True, - ) - ) - return - - llm_client = build_llm_client(env_cfg.llm) - env = OSINTEnvironment(env_cfg, llm=llm_client) - if args.cmd == "demo": - info = _runner_for(env).run_episode() - print(json.dumps(info, indent=2, sort_keys=True)) - elif args.cmd == "eval": - metrics = run_evaluation(env, episodes=episodes, llm=llm_client) - print(json.dumps(metrics, indent=2, sort_keys=True)) - elif args.cmd == "benchmark": - evaluation = run_evaluation(env, episodes=episodes, return_details=True, llm=llm_client) - summary = evaluation["summary"] - record = append_leaderboard_record( - path=leaderboard_path, - summary=summary, - episodes=episodes, - run_name=args.name or None, - config={ - "seed": env.config.seed, - "max_steps": env.config.max_steps, - "swarm_enabled": env.config.swarm.enabled, - "max_agents": env.config.swarm.max_agents, - "max_breadth": env.config.swarm.max_breadth, - "max_width": env.config.swarm.max_width, - "max_depth": env.config.swarm.max_depth, - "seeded_questions": len(env.config.seeding.seeded_questions), - }, - ) - leaderboard = load_leaderboard(leaderboard_path) - dashboard_path = export_dashboard( - env=env, - evaluation=evaluation, - leaderboard_records=leaderboard, - output_path=dashboard_path, - ) - _save_evaluation(DEFAULT_EVALUATION_PATH, evaluation) - payload = { - "record": record, - "summary": summary, - "dashboard": dashboard_path, - } - print(json.dumps(payload, indent=2, sort_keys=True)) - elif args.cmd == "viz": - evaluation: dict | None = _load_evaluation(evaluation_path) - if args.with_demo: - _runner_for(env).run_episode() - info = { - "agent_answer": env.state.answer if env.state else "", - "task_answer": env.state.task.answer if env.state else "", - "total_reward": env.state.total_reward if env.state else 0.0, - "step_count": env.state.step_count if env.state else 0, - "tool_calls": env.state.tool_calls if env.state else 0, - } - evaluation = { - "summary": { - "task_success_rate": float(info["agent_answer"] == info["task_answer"]), - "tool_efficiency": 0.0, - "avg_graph_f1": 0.0, - "avg_steps_to_solution": float(info["step_count"]), - "deanonymization_accuracy": 0.0, - "avg_reward": float(info["total_reward"]), - "leaderboard_score": 0.0, - }, - "episodes": [ - { - "task_id": env.state.task.task_id if env.state else "n/a", - "task_type": env.state.task.task_type if env.state else "n/a", - "question": env.state.task.question if env.state else "n/a", - "task_answer": str(info["task_answer"]), - "agent_answer": str(info["agent_answer"]), - "graph_f1": 0.0, - "reward": float(info["total_reward"]), - "steps": int(info["step_count"]), - "tool_calls": int(info["tool_calls"]), - "success": int(info["agent_answer"] == info["task_answer"]), - } - ], - } - - graph_f1 = 0.0 - if env.state is not None: - graph_f1 = compute_graph_f1(env.memory_graph.edges, env.state.task.supporting_edges) - - if evaluation is None: - summary = { - "task_success_rate": 0.0, - "tool_efficiency": 0.0, - "avg_graph_f1": graph_f1, - "avg_steps_to_solution": float(env.state.step_count) if env.state else 0.0, - "deanonymization_accuracy": 0.0, - "avg_reward": float(env.state.total_reward) if env.state else 0.0, - "leaderboard_score": 0.0, - } - evaluation = {"summary": summary, "episodes": []} - - leaderboard = load_leaderboard(leaderboard_path) - out = export_dashboard(env=env, evaluation=evaluation, leaderboard_records=leaderboard, output_path=args.output) - print(json.dumps({"dashboard": out, "evaluation": evaluation_path}, indent=2, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/scratch/osint/src/osint_env/config/__init__.py b/scratch/osint/src/osint_env/config/__init__.py deleted file mode 100644 index 0f33c5b3ecce550f035a413d9447b75844bc35dc..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/config/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -from osint_env.config.shared import RuntimeDefaults, SharedConfig, clone_environment_config, load_seeding_config, load_shared_config - -__all__ = [ - "RuntimeDefaults", - "SharedConfig", - "clone_environment_config", - "load_seeding_config", - "load_shared_config", -] diff --git a/scratch/osint/src/osint_env/config/shared.py b/scratch/osint/src/osint_env/config/shared.py deleted file mode 100644 index a012ceef5320c781d727135ae906b96c906e0e15..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/config/shared.py +++ /dev/null @@ -1,248 +0,0 @@ -from __future__ import annotations - -import copy -import json -from dataclasses import dataclass, field -from pathlib import Path -from typing import Any - -from osint_env.domain.models import ( - EnvironmentConfig, - LLMConfig, - NodeType, - SeedingConfig, - SeedEdgeSpec, - SeedNodeSpec, - SeedQuestionSpec, - SpawnRewardConfig, - SwarmConfig, -) - - -@dataclass(slots=True) -class RuntimeDefaults: - default_episodes: int = 20 - leaderboard_path: str = "artifacts/leaderboard.json" - dashboard_path: str = "artifacts/osint_dashboard.html" - sweep_dashboard_dir: str = "artifacts/sweep_dashboards" - - -@dataclass(slots=True) -class SharedConfig: - environment: EnvironmentConfig = field(default_factory=EnvironmentConfig) - runtime: RuntimeDefaults = field(default_factory=RuntimeDefaults) - - -def clone_environment_config(config: EnvironmentConfig) -> EnvironmentConfig: - return copy.deepcopy(config) - - -def _as_dict(value: Any) -> dict[str, Any]: - return value if isinstance(value, dict) else {} - - -def _parse_int(value: Any, default: int) -> int: - try: - return int(value) - except (TypeError, ValueError): - return default - - -def _parse_float(value: Any, default: float) -> float: - try: - return float(value) - except (TypeError, ValueError): - return default - - -def _parse_bool(value: Any, default: bool) -> bool: - if isinstance(value, bool): - return value - if isinstance(value, str): - lowered = value.strip().lower() - if lowered in {"1", "true", "yes", "y", "on"}: - return True - if lowered in {"0", "false", "no", "n", "off"}: - return False - return default - - -def _infer_node_type(node_id: str) -> NodeType: - prefix = str(node_id).split("_", 1)[0].lower() - mapping = { - "user": NodeType.USER, - "alias": NodeType.ALIAS, - "org": NodeType.ORG, - "loc": NodeType.LOCATION, - "location": NodeType.LOCATION, - "post": NodeType.POST, - "thr": NodeType.THREAD, - "thread": NodeType.THREAD, - "event": NodeType.EVENT, - } - return mapping.get(prefix, NodeType.USER) - - -def _parse_node_type(value: Any, node_id: str) -> NodeType: - if isinstance(value, NodeType): - return value - if isinstance(value, str): - raw = value.strip().lower() - try: - return NodeType(raw) - except ValueError: - return _infer_node_type(node_id) - return _infer_node_type(node_id) - - -def _parse_seed_edge(item: dict[str, Any]) -> SeedEdgeSpec | None: - src = str(item.get("src", "")).strip() - rel = str(item.get("rel", "")).strip() - dst = str(item.get("dst", "")).strip() - if not src or not rel or not dst: - return None - confidence = _parse_float(item.get("confidence", 1.0), 1.0) - return SeedEdgeSpec(src=src, rel=rel, dst=dst, confidence=confidence) - - -def _parse_seeding(data: dict[str, Any]) -> SeedingConfig: - seeded_nodes: list[SeedNodeSpec] = [] - for item in data.get("seeded_nodes", []): - row = _as_dict(item) - node_id = str(row.get("node_id", "")).strip() - if not node_id: - continue - node_type = _parse_node_type(row.get("node_type"), node_id) - attrs = _as_dict(row.get("attrs")) - seeded_nodes.append(SeedNodeSpec(node_id=node_id, node_type=node_type, attrs=attrs)) - - seeded_edges: list[SeedEdgeSpec] = [] - for item in data.get("seeded_edges", []): - edge = _parse_seed_edge(_as_dict(item)) - if edge is not None: - seeded_edges.append(edge) - - seeded_questions: list[SeedQuestionSpec] = [] - for item in data.get("seeded_questions", []): - row = _as_dict(item) - question = str(row.get("question", "")).strip() - if not question: - continue - answer_val = row.get("answer") - answer = str(answer_val).strip() if answer_val is not None and str(answer_val).strip() else None - task_type = str(row.get("task_type", "seeded")).strip() or "seeded" - support_edges: list[SeedEdgeSpec] = [] - for edge_item in row.get("supporting_edges", []): - edge = _parse_seed_edge(_as_dict(edge_item)) - if edge is not None: - support_edges.append(edge) - metadata = _as_dict(row.get("metadata")) - seeded_questions.append( - SeedQuestionSpec( - question=question, - answer=answer, - task_type=task_type, - supporting_edges=support_edges, - metadata=metadata, - ) - ) - - return SeedingConfig( - seeded_nodes=seeded_nodes, - seeded_edges=seeded_edges, - seeded_questions=seeded_questions, - llm_generate_remaining_graph=_parse_bool(data.get("llm_generate_remaining_graph"), True), - llm_generate_remaining_tasks=_parse_bool(data.get("llm_generate_remaining_tasks"), True), - llm_generated_edge_budget=max(0, _parse_int(data.get("llm_generated_edge_budget"), 6)), - llm_generated_task_budget=max(0, _parse_int(data.get("llm_generated_task_budget"), 8)), - llm_generation_parallel=_parse_bool(data.get("llm_generation_parallel"), True), - llm_generation_workers=max(1, _parse_int(data.get("llm_generation_workers"), 3)), - llm_generation_retries=max(1, _parse_int(data.get("llm_generation_retries"), 2)), - allow_template_fallback_on_llm_failure=_parse_bool( - data.get("allow_template_fallback_on_llm_failure"), - False, - ), - ) - - -def load_seeding_config(path: str | Path) -> SeedingConfig: - payload = json.loads(Path(path).read_text(encoding="utf-8")) - if not isinstance(payload, dict): - raise ValueError("Seed file must contain a JSON object.") - source = _as_dict(payload.get("seeding", payload)) - return _parse_seeding(source) - - -def _parse_environment(payload: dict[str, Any]) -> EnvironmentConfig: - env_data = _as_dict(payload.get("environment", payload)) - swarm_data = _as_dict(payload.get("swarm", env_data.get("swarm", {}))) - spawn_data = _as_dict(payload.get("spawn_reward", env_data.get("spawn_reward", {}))) - seeding_data = _as_dict(payload.get("seeding", env_data.get("seeding", {}))) - llm_data = _as_dict(payload.get("llm", env_data.get("llm", {}))) - - env = EnvironmentConfig( - n_users=max(4, _parse_int(env_data.get("n_users"), 40)), - alias_density=max(0.0, min(1.0, _parse_float(env_data.get("alias_density"), 0.35))), - noise_level=max(0.0, min(1.0, _parse_float(env_data.get("noise_level"), 0.15))), - red_herring_rate=max(0.0, min(1.0, _parse_float(env_data.get("red_herring_rate"), 0.1))), - max_steps=max(2, _parse_int(env_data.get("max_steps"), 18)), - seed=_parse_int(env_data.get("seed"), 7), - ) - - env.swarm = SwarmConfig( - enabled=_parse_bool(swarm_data.get("enabled"), False), - max_agents=max(1, _parse_int(swarm_data.get("max_agents"), 3)), - max_breadth=max(1, _parse_int(swarm_data.get("max_breadth"), 2)), - max_width=max(1, _parse_int(swarm_data.get("max_width"), 2)), - max_depth=max(1, _parse_int(swarm_data.get("max_depth"), 2)), - planner_rounds=max(1, _parse_int(swarm_data.get("planner_rounds"), 2)), - tools_per_agent=max(1, _parse_int(swarm_data.get("tools_per_agent"), 1)), - ) - - env.spawn_reward = SpawnRewardConfig( - lambda_parallel=max(0.0, _parse_float(spawn_data.get("lambda_parallel"), 0.15)), - lambda_finish=max(0.0, _parse_float(spawn_data.get("lambda_finish"), 0.2)), - anneal=max(0.0, min(1.0, _parse_float(spawn_data.get("anneal"), 1.0))), - max_parallel_hint=max(1, _parse_int(spawn_data.get("max_parallel_hint"), 3)), - ) - - env.seeding = _parse_seeding(seeding_data) - env.llm = LLMConfig( - provider=str(llm_data.get("provider", "mock")).strip() or "mock", - model=str(llm_data.get("model", "qwen3:2b")).strip() or "qwen3:2b", - temperature=_parse_float(llm_data.get("temperature"), 0.1), - max_tokens=max(1, _parse_int(llm_data.get("max_tokens"), 256)), - timeout_seconds=max(1, _parse_int(llm_data.get("timeout_seconds"), 240)), - ollama_base_url=str(llm_data.get("ollama_base_url", "http://127.0.0.1:11434")).strip() - or "http://127.0.0.1:11434", - openai_base_url=str(llm_data.get("openai_base_url", "https://api.openai.com/v1")).strip() - or "https://api.openai.com/v1", - openai_api_key_env=str(llm_data.get("openai_api_key_env", "OPENAI_API_KEY")).strip() or "OPENAI_API_KEY", - openai_api_key=str(llm_data.get("openai_api_key", "")).strip(), - ) - return env - - -def _parse_runtime(payload: dict[str, Any]) -> RuntimeDefaults: - runtime = _as_dict(payload.get("runtime", {})) - return RuntimeDefaults( - default_episodes=max(1, _parse_int(runtime.get("default_episodes"), 20)), - leaderboard_path=str(runtime.get("leaderboard_path", "artifacts/leaderboard.json")), - dashboard_path=str(runtime.get("dashboard_path", "artifacts/osint_dashboard.html")), - sweep_dashboard_dir=str(runtime.get("sweep_dashboard_dir", "artifacts/sweep_dashboards")), - ) - - -def load_shared_config(path: str | Path | None) -> SharedConfig: - if not path: - return SharedConfig() - - file_path = Path(path) - if not file_path.exists(): - return SharedConfig() - - payload = json.loads(file_path.read_text(encoding="utf-8")) - if not isinstance(payload, dict): - raise ValueError("Shared config file must contain a JSON object.") - - return SharedConfig(environment=_parse_environment(payload), runtime=_parse_runtime(payload)) diff --git a/scratch/osint/src/osint_env/data/__init__.py b/scratch/osint/src/osint_env/data/__init__.py deleted file mode 100644 index 6d328d532fb74285ba87590893c78c9f07d03bc8..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/data/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Dataset generation package.""" - diff --git a/scratch/osint/src/osint_env/data/generator.py b/scratch/osint/src/osint_env/data/generator.py deleted file mode 100644 index ba989b9667ffc5115d3ddd1d4d37f755f30f17e9..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/data/generator.py +++ /dev/null @@ -1,819 +0,0 @@ -from __future__ import annotations - -from concurrent.futures import ThreadPoolExecutor, as_completed -import json -import random -import re -from dataclasses import dataclass -from typing import TYPE_CHECKING, Any - -from osint_env.domain.models import ( - CanonicalGraph, - Edge, - EnvironmentConfig, - Node, - NodeType, - SeedEdgeSpec, - SeedQuestionSpec, - TaskInstance, -) - -if TYPE_CHECKING: - from osint_env.llm.interface import LLMClient - - -@dataclass(slots=True) -class PlatformViews: - microblog_posts: list[dict] - forum_threads: list[dict] - profiles: list[dict] - alias_lookup: dict[str, str] - - -class DatasetGenerator: - def __init__(self, config: EnvironmentConfig, llm: LLMClient | None = None): - self.config = config - self.rng = random.Random(config.seed) - self.llm = llm - - @staticmethod - def _edge_key(edge: Edge) -> tuple[str, str, str]: - return (edge.src, edge.rel, edge.dst) - - @staticmethod - def _infer_node_type(node_id: str) -> NodeType: - prefix = str(node_id).split("_", 1)[0].lower() - mapping = { - "user": NodeType.USER, - "alias": NodeType.ALIAS, - "org": NodeType.ORG, - "loc": NodeType.LOCATION, - "location": NodeType.LOCATION, - "post": NodeType.POST, - "thr": NodeType.THREAD, - "thread": NodeType.THREAD, - "event": NodeType.EVENT, - } - return mapping.get(prefix, NodeType.USER) - - def _ensure_node(self, graph: CanonicalGraph, node_id: str) -> None: - if node_id in graph.nodes: - return - node_type = self._infer_node_type(node_id) - attrs: dict[str, Any] = {} - if node_type == NodeType.USER: - attrs = {"name": node_id, "org": "Unknown", "location": "Unknown"} - if node_type == NodeType.ALIAS: - attrs = {"handle": f"@{node_id}"} - graph.nodes[node_id] = Node(node_id=node_id, node_type=node_type, attrs=attrs) - - def _add_edge_if_missing(self, graph: CanonicalGraph, edge: Edge) -> None: - key = self._edge_key(edge) - if any(self._edge_key(existing) == key for existing in graph.edges): - return - self._ensure_node(graph, edge.src) - self._ensure_node(graph, edge.dst) - graph.edges.append(edge) - - @staticmethod - def _extract_json_blob(text: str) -> Any: - text = str(text).strip() - if not text: - return None - for start, end in (("{", "}"), ("[", "]")): - left = text.find(start) - right = text.rfind(end) - if left >= 0 and right > left: - snippet = text[left : right + 1] - try: - return json.loads(snippet) - except json.JSONDecodeError: - continue - return None - - def _apply_seed_nodes(self, graph: CanonicalGraph) -> None: - for node_spec in self.config.seeding.seeded_nodes: - node_type = ( - node_spec.node_type - if isinstance(node_spec.node_type, NodeType) - else self._infer_node_type(node_spec.node_id) - ) - existing = graph.nodes.get(node_spec.node_id) - attrs = dict(existing.attrs) if existing else {} - attrs.update(node_spec.attrs) - graph.nodes[node_spec.node_id] = Node(node_spec.node_id, node_type, attrs) - - def _apply_seed_edges(self, graph: CanonicalGraph) -> None: - for edge_spec in self.config.seeding.seeded_edges: - self._add_edge_if_missing( - graph, - Edge( - src=edge_spec.src, - rel=edge_spec.rel, - dst=edge_spec.dst, - confidence=float(edge_spec.confidence), - ), - ) - - @staticmethod - def _normalize_edge_candidates(value: Any) -> list[SeedEdgeSpec]: - items: list[SeedEdgeSpec] = [] - if not isinstance(value, list): - return items - for row in value: - if not isinstance(row, dict): - continue - src = str(row.get("src", "")).strip() - rel = str(row.get("rel", "")).strip() - dst = str(row.get("dst", "")).strip() - if not src or not rel or not dst: - continue - try: - confidence = float(row.get("confidence", 1.0)) - except (TypeError, ValueError): - confidence = 1.0 - items.append(SeedEdgeSpec(src=src, rel=rel, dst=dst, confidence=confidence)) - return items - - @staticmethod - def _split_budget(total: int, parts: int) -> list[int]: - if total <= 0: - return [] - slots = max(1, parts) - base = total // slots - remainder = total % slots - chunks = [base + (1 if i < remainder else 0) for i in range(slots)] - return [chunk for chunk in chunks if chunk > 0] - - @staticmethod - def _shared_context_blob(graph: CanonicalGraph, node_limit: int = 100, edge_limit: int = 80) -> str: - payload = { - "known_nodes": sorted(graph.nodes.keys())[:node_limit], - "known_edges": [ - {"src": edge.src, "rel": edge.rel, "dst": edge.dst} - for edge in graph.edges[: min(edge_limit, len(graph.edges))] - ], - } - return json.dumps(payload) - - def _llm_generate_json_with_retry(self, prompt: str) -> Any: - if self.llm is None: - return None - - attempts = max(1, int(self.config.seeding.llm_generation_retries)) - for _ in range(attempts): - try: - response = self.llm.generate([{"role": "system", "content": prompt}], tools=[]) - except Exception: - continue - parsed = self._extract_json_blob(response.content) - if parsed is not None: - return parsed - return None - - def _run_generation_workers(self, prompts: list[str]) -> list[Any]: - if not prompts: - return [] - - max_workers = max(1, min(self.config.seeding.llm_generation_workers, len(prompts))) - if not self.config.seeding.llm_generation_parallel or max_workers == 1: - output: list[Any] = [] - for prompt in prompts: - parsed = self._llm_generate_json_with_retry(prompt) - if parsed is not None: - output.append(parsed) - return output - - output = [] - with ThreadPoolExecutor(max_workers=max_workers) as executor: - futures = [executor.submit(self._llm_generate_json_with_retry, prompt) for prompt in prompts] - for future in as_completed(futures): - try: - parsed = future.result() - except Exception: - parsed = None - if parsed is not None: - output.append(parsed) - return output - - def _template_fallback_allowed(self) -> bool: - if self.llm is None: - return True - return bool(self.config.seeding.allow_template_fallback_on_llm_failure) - - def _template_generated_edges(self, graph: CanonicalGraph, budget: int) -> list[Edge]: - if budget <= 0: - return [] - users = [n.node_id for n in graph.nodes.values() if n.node_type == NodeType.USER] - aliases = [n.node_id for n in graph.nodes.values() if n.node_type == NodeType.ALIAS] - if len(users) < 2: - return [] - - generated: list[Edge] = [] - rels = ["connected_to", "mentions", "co_occurs_with"] - for _ in range(budget * 3): - if len(generated) >= budget: - break - roll = self.rng.random() - if aliases and roll < 0.2: - src = self.rng.choice(aliases) - dst = self.rng.choice(users) - rel = "alias_of" - elif roll < 0.75: - src, dst = self.rng.sample(users, 2) - rel = self.rng.choice(rels) - else: - src = self.rng.choice(users) - dst = self.rng.choice([u for u in users if u != src]) - rel = "connected_to" - generated.append(Edge(src=src, rel=rel, dst=dst, confidence=0.7)) - return generated[:budget] - - def _llm_expand_graph(self, graph: CanonicalGraph, budget: int) -> list[Edge]: - if budget <= 0: - return [] - - if self.llm is None: - return self._template_generated_edges(graph, budget) - - shared_context = self._shared_context_blob(graph) - workers = max(1, min(self.config.seeding.llm_generation_workers, budget)) - chunks = self._split_budget(budget, workers) - focus_tracks = ["entity_linking", "network_expansion", "org_location", "event_trace"] - - prompts: list[str] = [] - for idx, chunk_budget in enumerate(chunks): - focus = focus_tracks[idx % len(focus_tracks)] - prompts.append( - ( - "SEED_GRAPH_EXPANSION_AGENT\n" - "SHARED_CONTEXT\n" - f"{shared_context}\n" - f"worker_id: {idx}\n" - f"focus: {focus}\n" - f"budget: {chunk_budget}\n" - "Generate plausible graph edges for OSINT retrieval.\n" - "Return STRICT JSON object: {\"edges\": [{\"src\": str, \"rel\": str, \"dst\": str, \"confidence\": float}]}.\n" - "Prefer known nodes from SHARED_CONTEXT and avoid duplicates." - ) - ) - - generated: list[Edge] = [] - seen: set[tuple[str, str, str]] = set() - for payload in self._run_generation_workers(prompts): - raw_edges: Any = None - if isinstance(payload, dict): - raw_edges = payload.get("edges") - elif isinstance(payload, list): - raw_edges = payload - for edge_spec in self._normalize_edge_candidates(raw_edges): - key = (edge_spec.src, edge_spec.rel, edge_spec.dst) - if key in seen: - continue - seen.add(key) - generated.append(Edge(edge_spec.src, edge_spec.rel, edge_spec.dst, float(edge_spec.confidence))) - if len(generated) >= budget: - break - if len(generated) >= budget: - break - - if len(generated) < budget: - residual = budget - len(generated) - residual_prompt = ( - "SEED_GRAPH_EXPANSION_AGENT\n" - "SHARED_CONTEXT\n" - f"{shared_context}\n" - f"budget: {residual}\n" - "Generate any remaining high-utility edges.\n" - "Return STRICT JSON object: {\"edges\": [{\"src\": str, \"rel\": str, \"dst\": str, \"confidence\": float}]}." - ) - payload = self._llm_generate_json_with_retry(residual_prompt) - raw_edges: Any = payload.get("edges") if isinstance(payload, dict) else payload - for edge_spec in self._normalize_edge_candidates(raw_edges): - key = (edge_spec.src, edge_spec.rel, edge_spec.dst) - if key in seen: - continue - seen.add(key) - generated.append(Edge(edge_spec.src, edge_spec.rel, edge_spec.dst, float(edge_spec.confidence))) - if len(generated) >= budget: - break - - if len(generated) < budget and self._template_fallback_allowed(): - for edge in self._template_generated_edges(graph, budget - len(generated)): - key = (edge.src, edge.rel, edge.dst) - if key in seen: - continue - seen.add(key) - generated.append(edge) - if len(generated) >= budget: - break - - return generated[:budget] - - @staticmethod - def _extract_entity_tokens(question: str) -> list[str]: - return re.findall(r"\b(?:alias|user|org|loc|post|thr|thread|event)_[a-zA-Z0-9_]+\b", question) - - @staticmethod - def _normalize_difficulty(value: str, index: int) -> str: - token = str(value or "").strip().lower() - if token in {"easy", "e"}: - return "easy" - if token in {"mid", "medium", "m"}: - return "medium" - if token in {"high", "hard", "h"}: - return "hard" - if index < 10: - return "easy" - if index < 20: - return "medium" - return "hard" - - @staticmethod - def _task_type_for_difficulty(base_task_type: str, difficulty: str) -> str: - token = str(base_task_type or "").strip().lower() - if token and token != "fixed_trace": - return token - if difficulty == "easy": - return "easy_trace" - if difficulty == "medium": - return "medium_trace" - return "hard_trace" - - @staticmethod - def _grader_for_difficulty(difficulty: str) -> dict[str, Any]: - return { - "type": "difficulty_exact_match", - "answer_type": "node_id", - "case_sensitive": True, - "reward_profile": difficulty, - "logic": { - "easy": "single_agent_simplified", - "medium": "reduced_components", - "hard": "full_reward", - }.get(difficulty, "full_reward"), - } - - def _task_metadata(self, index: int, base_task_type: str, metadata: dict[str, Any] | None = None) -> dict[str, Any]: - out = dict(metadata or {}) - difficulty = self._normalize_difficulty(out.get("difficulty", ""), index) - out["difficulty"] = difficulty - out.setdefault("grader", self._grader_for_difficulty(difficulty)) - out.setdefault("scenario", self._task_type_for_difficulty(base_task_type, difficulty)) - return out - - def _infer_answer_from_question(self, question: str, graph: CanonicalGraph) -> str: - entities = self._extract_entity_tokens(question) - question_l = question.lower() - - alias_tokens = [token for token in entities if token.startswith("alias_")] - if alias_tokens: - alias = alias_tokens[0] - for edge in graph.edges: - if edge.rel == "alias_of" and edge.src == alias: - return edge.dst - - if "connected" in question_l: - user_tokens = [token for token in entities if token.startswith("user_")] - if user_tokens: - source = user_tokens[0] - for edge in graph.edges: - if edge.rel == "connected_to" and edge.src == source: - return edge.dst - - if "works at" in question_l: - for edge in graph.edges: - if edge.rel != "works_at": - continue - org = graph.nodes.get(edge.dst) - org_name = str((org.attrs or {}).get("name", "")).lower() if org else "" - if org_name and org_name in question_l: - return edge.src - - return entities[0] if entities else "unknown" - - def _infer_support_edges(self, question: str, answer: str, graph: CanonicalGraph) -> list[Edge]: - if answer: - for edge in graph.edges: - if edge.dst == answer or edge.src == answer: - if edge.src in question or edge.dst in question or edge.rel in question.lower(): - return [edge] - - entities = self._extract_entity_tokens(question) - for edge in graph.edges: - if edge.src in entities or edge.dst in entities: - return [edge] - return [] - - def _seeded_tasks(self, graph: CanonicalGraph) -> list[TaskInstance]: - tasks: list[TaskInstance] = [] - for idx, question_spec in enumerate(self.config.seeding.seeded_questions): - answer = question_spec.answer or self._infer_answer_from_question(question_spec.question, graph) - metadata = self._task_metadata(idx, question_spec.task_type, dict(question_spec.metadata)) - difficulty = str(metadata.get("difficulty", "hard")) - if question_spec.supporting_edges: - support = [ - Edge(src=e.src, rel=e.rel, dst=e.dst, confidence=float(e.confidence)) - for e in question_spec.supporting_edges - ] - else: - support = self._infer_support_edges(question_spec.question, answer, graph) - - tasks.append( - TaskInstance( - task_id=f"seed_task_{idx}", - task_type=self._task_type_for_difficulty(question_spec.task_type, difficulty), - question=question_spec.question, - answer=answer, - supporting_edges=support, - metadata=metadata, - ) - ) - return tasks - - def _template_tasks(self, graph: CanonicalGraph, count: int, start_idx: int = 0) -> list[TaskInstance]: - alias_edges = [e for e in graph.edges if e.rel == "alias_of"] - conn_edges = [e for e in graph.edges if e.rel == "connected_to"] - work_edges = [e for e in graph.edges if e.rel == "works_at"] - tasks: list[TaskInstance] = [] - - for i in range(count): - mode = self.rng.choice(["identity_resolution", "network_discovery", "event_tracing"]) - if mode == "identity_resolution" and alias_edges: - edge = self.rng.choice(alias_edges) - q = f"Which canonical user owns alias {edge.src}?" - a = edge.dst - support = [edge] - elif mode == "network_discovery" and conn_edges: - edge = self.rng.choice(conn_edges) - q = f"Who is connected to {edge.src}?" - a = edge.dst - support = [edge] - else: - edge = self.rng.choice(work_edges) - org_node = graph.nodes.get(edge.dst) - org_name = (org_node.attrs or {}).get("name", edge.dst) if org_node else edge.dst - q = f"Which user works at {org_name}?" - a = edge.src - support = [edge] - tasks.append( - TaskInstance( - task_id=f"task_{start_idx + i}", - task_type=mode, - question=q, - answer=a, - supporting_edges=support, - metadata=self._task_metadata(start_idx + i, mode), - ) - ) - return tasks - - def _llm_generated_tasks(self, graph: CanonicalGraph, count: int, start_idx: int) -> list[TaskInstance]: - if count <= 0: - return [] - if self.llm is None: - return self._template_tasks(graph, count=count, start_idx=start_idx) - - candidate_edges = [ - {"src": edge.src, "rel": edge.rel, "dst": edge.dst} - for edge in graph.edges - if edge.rel in {"alias_of", "connected_to", "works_at"} - ][:60] - shared_context = json.dumps( - { - "known_nodes": sorted(graph.nodes.keys())[:100], - "edge_sample": candidate_edges, - } - ) - workers = max(1, min(self.config.seeding.llm_generation_workers, count)) - chunks = self._split_budget(count, workers) - focus_tracks = ["identity_resolution", "network_discovery", "event_tracing", "deanonymization"] - - prompts: list[str] = [] - for idx, chunk_budget in enumerate(chunks): - focus = focus_tracks[idx % len(focus_tracks)] - prompts.append( - ( - "SEED_TASK_EXPANSION_AGENT\n" - "SHARED_CONTEXT\n" - f"{shared_context}\n" - f"worker_id: {idx}\n" - f"focus: {focus}\n" - f"task_budget: {chunk_budget}\n" - "Generate OSINT QA tasks with answers and support edges.\n" - "Return STRICT JSON object: {\"tasks\": [{\"task_type\": str, \"question\": str, \"answer\": str, \"supporting_edges\": [{\"src\": str, \"rel\": str, \"dst\": str, \"confidence\": float}]}]}." - ) - ) - - llm_tasks: list[TaskInstance] = [] - seen_questions: set[str] = set() - for payload in self._run_generation_workers(prompts): - raw_tasks: Any = None - if isinstance(payload, dict): - raw_tasks = payload.get("tasks") - elif isinstance(payload, list): - raw_tasks = payload - if not isinstance(raw_tasks, list): - continue - - for row in raw_tasks: - if not isinstance(row, dict): - continue - question = str(row.get("question", "")).strip() - if not question: - continue - key = question.lower() - if key in seen_questions: - continue - seen_questions.add(key) - answer = str(row.get("answer", "")).strip() or self._infer_answer_from_question(question, graph) - task_type = str(row.get("task_type", "llm_generated")).strip() or "llm_generated" - support_specs = self._normalize_edge_candidates(row.get("supporting_edges")) - if support_specs: - support = [Edge(e.src, e.rel, e.dst, e.confidence) for e in support_specs] - else: - support = self._infer_support_edges(question, answer, graph) - llm_tasks.append( - TaskInstance( - task_id=f"task_{start_idx + len(llm_tasks)}", - task_type=task_type, - question=question, - answer=answer, - supporting_edges=support, - metadata=self._task_metadata( - start_idx + len(llm_tasks), - task_type, - {"generated_by": "llm", "shared_context": True}, - ), - ) - ) - if len(llm_tasks) >= count: - break - if len(llm_tasks) >= count: - break - - if len(llm_tasks) < count: - residual = count - len(llm_tasks) - residual_prompt = ( - "SEED_TASK_EXPANSION_AGENT\n" - "SHARED_CONTEXT\n" - f"{shared_context}\n" - f"task_budget: {residual}\n" - "Generate additional tasks not already present in SHARED_CONTEXT.\n" - "Return STRICT JSON object: {\"tasks\": [{\"task_type\": str, \"question\": str, \"answer\": str, \"supporting_edges\": [{\"src\": str, \"rel\": str, \"dst\": str, \"confidence\": float}]}]}." - ) - payload = self._llm_generate_json_with_retry(residual_prompt) - raw_tasks: Any = payload.get("tasks") if isinstance(payload, dict) else payload - if isinstance(raw_tasks, list): - for row in raw_tasks: - if not isinstance(row, dict): - continue - question = str(row.get("question", "")).strip() - if not question: - continue - key = question.lower() - if key in seen_questions: - continue - seen_questions.add(key) - answer = str(row.get("answer", "")).strip() or self._infer_answer_from_question(question, graph) - task_type = str(row.get("task_type", "llm_generated")).strip() or "llm_generated" - support_specs = self._normalize_edge_candidates(row.get("supporting_edges")) - if support_specs: - support = [Edge(e.src, e.rel, e.dst, e.confidence) for e in support_specs] - else: - support = self._infer_support_edges(question, answer, graph) - llm_tasks.append( - TaskInstance( - task_id=f"task_{start_idx + len(llm_tasks)}", - task_type=task_type, - question=question, - answer=answer, - supporting_edges=support, - metadata=self._task_metadata( - start_idx + len(llm_tasks), - task_type, - {"generated_by": "llm", "shared_context": True}, - ), - ) - ) - if len(llm_tasks) >= count: - break - - if len(llm_tasks) < count and self._template_fallback_allowed(): - llm_tasks.extend( - self._template_tasks( - graph, - count=count - len(llm_tasks), - start_idx=start_idx + len(llm_tasks), - ) - ) - return llm_tasks[:count] - - def build_canonical_graph(self) -> CanonicalGraph: - graph = CanonicalGraph() - orgs = ["Apex Dynamics", "Helios Labs", "Northbridge"] - locations = ["Bengaluru", "Pune", "Hyderabad", "Delhi"] - - for i in range(self.config.n_users): - uid = f"user_{i}" - org = self.rng.choice(orgs) - loc = self.rng.choice(locations) - graph.nodes[uid] = Node(uid, NodeType.USER, {"name": f"Person {i}", "org": org, "location": loc}) - org_id = f"org_{org.lower().replace(' ', '_')}" - loc_id = f"loc_{loc.lower()}" - graph.nodes.setdefault(org_id, Node(org_id, NodeType.ORG, {"name": org})) - graph.nodes.setdefault(loc_id, Node(loc_id, NodeType.LOCATION, {"name": loc})) - graph.edges.append(Edge(uid, "works_at", org_id)) - graph.edges.append(Edge(uid, "located_in", loc_id)) - - if self.rng.random() < self.config.alias_density: - alias = f"alias_{i}_{self.rng.randint(100,999)}" - graph.nodes[alias] = Node(alias, NodeType.ALIAS, {"handle": f"@{alias}"}) - graph.edges.append(Edge(alias, "alias_of", uid)) - - users = [n for n in graph.nodes.values() if n.node_type == NodeType.USER] - for _ in range(max(1, self.config.n_users // 2)): - a, b = self.rng.sample(users, 2) - graph.edges.append(Edge(a.node_id, "connected_to", b.node_id, confidence=0.8)) - - self._apply_seed_nodes(graph) - self._apply_seed_edges(graph) - - if self.config.seeding.llm_generate_remaining_graph: - llm_edges = self._llm_expand_graph(graph, self.config.seeding.llm_generated_edge_budget) - for edge in llm_edges: - self._add_edge_if_missing(graph, edge) - return graph - - def build_platform_views(self, graph: CanonicalGraph) -> PlatformViews: - users = [n for n in graph.nodes.values() if n.node_type == NodeType.USER] - aliases = [n for n in graph.nodes.values() if n.node_type == NodeType.ALIAS] - alias_owner = {e.src: e.dst for e in graph.edges if e.rel == "alias_of"} - user_aliases: dict[str, list[str]] = {} - for alias_id, user_id in alias_owner.items(): - user_aliases.setdefault(user_id, []).append(alias_id) - node_names = { - node_id: str((node.attrs or {}).get("name") or (node.attrs or {}).get("handle") or node_id) - for node_id, node in graph.nodes.items() - } - - microblog_posts: list[dict] = [] - for i, user in enumerate(users): - poster = user.node_id - if aliases and self.rng.random() < 0.45: - candidate = self.rng.choice(aliases).node_id - poster = candidate - text = f"Update {i} from {user.attrs['org']} #{user.attrs['location'].lower()}" - if self.rng.random() < self.config.noise_level: - text = f"Rumor: {text} maybe fake" - microblog_posts.append( - { - "post_id": f"post_{i}", - "user_id": poster, - "canonical_user": alias_owner.get(poster, user.node_id), - "text": text, - "references": [], - "reference_names": [], - "mentions": [f"user_{self.rng.randint(0, self.config.n_users - 1)}"], - "timestamp": 1000 + i, - } - ) - - authored_posts: dict[str, str] = {} - post_references: dict[str, list[str]] = {} - for edge in graph.edges: - if edge.rel == "authored_post": - authored_posts[edge.dst] = edge.src - elif edge.rel == "references" and edge.src.startswith("post_"): - post_references.setdefault(edge.src, []).append(edge.dst) - - for post_id, author_id in authored_posts.items(): - refs = post_references.get(post_id, []) - ref_names = [node_names.get(ref, ref) for ref in refs] - author_label = node_names.get(author_id, author_id) - text_parts = [f"{post_id} update from {author_label}"] - if ref_names: - text_parts.append("references " + ", ".join(ref_names)) - if refs: - text_parts.append("ids " + ", ".join(refs)) - post_payload = { - "post_id": post_id, - "user_id": author_id, - "canonical_user": alias_owner.get(author_id, author_id), - "text": ". ".join(text_parts), - "references": refs, - "reference_names": ref_names, - "mentions": [], - "timestamp": 5000 + len(microblog_posts), - } - existing_idx = next((idx for idx, row in enumerate(microblog_posts) if row["post_id"] == post_id), None) - if existing_idx is None: - microblog_posts.append(post_payload) - else: - microblog_posts[existing_idx] = post_payload - - forum_threads: list[dict] = [] - for i in range(max(8, self.config.n_users // 3)): - author = self.rng.choice(users).node_id - forum_threads.append( - { - "thread_id": f"thr_{i}", - "topic": self.rng.choice(["security", "startup", "ai", "infra"]), - "author_id": author, - "comments": [ - {"user_id": self.rng.choice(users).node_id, "text": "Following this."}, - {"user_id": self.rng.choice(users).node_id, "text": "Interesting link."}, - ], - "references": [], - "discusses": [], - } - ) - - authored_threads: dict[str, str] = {} - thread_refs: dict[str, list[str]] = {} - thread_discusses: dict[str, list[str]] = {} - for edge in graph.edges: - if edge.rel == "authored_thread": - authored_threads[edge.dst] = edge.src - elif edge.rel == "references" and edge.src.startswith(("thr_", "thread_")): - thread_refs.setdefault(edge.src, []).append(edge.dst) - elif edge.rel == "discusses" and edge.src.startswith(("thr_", "thread_")): - thread_discusses.setdefault(edge.src, []).append(edge.dst) - - for thread_id, author_id in authored_threads.items(): - node = graph.nodes.get(thread_id) - refs = thread_refs.get(thread_id, []) - discussed = thread_discusses.get(thread_id, []) - comments = [] - for ref in refs: - comments.append({"user_id": author_id, "text": f"Reference: {node_names.get(ref, ref)} ({ref})"}) - for item in discussed: - comments.append({"user_id": author_id, "text": f"Discusses: {node_names.get(item, item)} ({item})"}) - thread_payload = { - "thread_id": thread_id, - "topic": str((node.attrs or {}).get("topic", "seeded")) if node else "seeded", - "author_id": author_id, - "title": node_names.get(thread_id, thread_id), - "comments": comments, - "references": refs, - "discusses": discussed, - } - existing_idx = next((idx for idx, row in enumerate(forum_threads) if row["thread_id"] == thread_id), None) - if existing_idx is None: - forum_threads.append(thread_payload) - else: - forum_threads[existing_idx] = thread_payload - - profiles: list[dict] = [] - for user in users: - conns = [e.dst for e in graph.edges if e.src == user.node_id and e.rel == "connected_to"][:5] - org_id = next((e.dst for e in graph.edges if e.src == user.node_id and e.rel == "works_at"), "") - location_id = next((e.dst for e in graph.edges if e.src == user.node_id and e.rel == "located_in"), "") - profiles.append( - { - "user_id": user.node_id, - "name": user.attrs["name"], - "org": user.attrs["org"], - "org_id": org_id, - "location": user.attrs["location"], - "location_id": location_id, - "alias_ids": sorted(user_aliases.get(user.node_id, [])), - "connections": conns, - "work_history": [user.attrs["org"]], - } - ) - - for i in range(int(len(users) * self.config.red_herring_rate)): - profiles.append( - { - "user_id": f"noise_{i}", - "name": f"P{self.rng.randint(100,999)}", - "org": self.rng.choice(["Stealth Co", "Unknown Ventures"]), - "org_id": "", - "location": self.rng.choice(["Remote", "Unknown"]), - "location_id": "", - "alias_ids": [], - "connections": [], - "work_history": [], - } - ) - return PlatformViews(microblog_posts, forum_threads, profiles, alias_lookup=alias_owner) - - def generate_tasks(self, graph: CanonicalGraph, views: PlatformViews, count: int = 12) -> list[TaskInstance]: - tasks = self._seeded_tasks(graph) - target_count = max(1, count, len(tasks)) - - llm_budget = min( - max(0, self.config.seeding.llm_generated_task_budget), - max(0, target_count - len(tasks)), - ) - if self.config.seeding.llm_generate_remaining_tasks and llm_budget > 0: - tasks.extend(self._llm_generated_tasks(graph, count=llm_budget, start_idx=len(tasks))) - - if len(tasks) < target_count and self._template_fallback_allowed(): - tasks.extend(self._template_tasks(graph, count=target_count - len(tasks), start_idx=len(tasks))) - - if not tasks: - tasks.extend(self._template_tasks(graph, count=target_count, start_idx=0)) - - return tasks[:target_count] diff --git a/scratch/osint/src/osint_env/domain/__init__.py b/scratch/osint/src/osint_env/domain/__init__.py deleted file mode 100644 index 09b80bffb5e77f4d52a066830e4d530fb9aa4b8e..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/domain/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Core domain models.""" - diff --git a/scratch/osint/src/osint_env/domain/models.py b/scratch/osint/src/osint_env/domain/models.py deleted file mode 100644 index b6867b790af9d4b993abd294dccdea02a1f9166d..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/domain/models.py +++ /dev/null @@ -1,185 +0,0 @@ -from __future__ import annotations - -from dataclasses import dataclass, field -from enum import Enum -from typing import Any - -from pydantic import BaseModel, ConfigDict, Field - - -class NodeType(str, Enum): - USER = "user" - ALIAS = "alias" - ORG = "org" - LOCATION = "location" - POST = "post" - THREAD = "thread" - EVENT = "event" - - -class ActionType(str, Enum): - CALL_TOOL = "CALL_TOOL" - ADD_EDGE = "ADD_EDGE" - ANSWER = "ANSWER" - - -@dataclass(slots=True) -class Node: - node_id: str - node_type: NodeType - attrs: dict[str, Any] = field(default_factory=dict) - - -@dataclass(slots=True) -class Edge: - src: str - rel: str - dst: str - confidence: float = 1.0 - - -@dataclass(slots=True) -class CanonicalGraph: - nodes: dict[str, Node] = field(default_factory=dict) - edges: list[Edge] = field(default_factory=list) - - -@dataclass(slots=True) -class ToolCall: - tool_name: str - args: dict[str, Any] - - -class Action(BaseModel): - """Structured action payload used by OpenEnv step().""" - - model_config = ConfigDict(extra="forbid") - - action_type: ActionType - payload: dict[str, Any] = Field(default_factory=dict) - - def __init__(self, *args: Any, **kwargs: Any) -> None: - # Backward-compatible positional form: Action(action_type, payload) - if args: - if len(args) != 2: - raise TypeError("Action() accepts either keyword fields or 2 positional args") - if "action_type" in kwargs or "payload" in kwargs: - raise TypeError("Action() cannot mix positional and keyword fields") - kwargs["action_type"] = args[0] - kwargs["payload"] = args[1] - super().__init__(**kwargs) - - -class Observation(BaseModel): - """Typed observation payload returned by reset()/step()/state().""" - - model_config = ConfigDict(extra="forbid") - - tool_outputs: list[dict[str, Any]] = Field(default_factory=list) - graph_snapshot: dict[str, Any] = Field(default_factory=dict) - action_history: list[dict[str, Any]] = Field(default_factory=list) - task: dict[str, Any] = Field(default_factory=dict) - - -class Reward(BaseModel): - """Typed reward payload for structured reward accounting.""" - - model_config = ConfigDict(extra="forbid") - - value: float = 0.0 - components: dict[str, float] = Field(default_factory=dict) - - -@dataclass(slots=True) -class TaskInstance: - task_id: str - task_type: str - question: str - answer: str - supporting_edges: list[Edge] - metadata: dict[str, Any] = field(default_factory=dict) - - -@dataclass(slots=True) -class SeedNodeSpec: - node_id: str - node_type: NodeType | str - attrs: dict[str, Any] = field(default_factory=dict) - - -@dataclass(slots=True) -class SeedEdgeSpec: - src: str - rel: str - dst: str - confidence: float = 1.0 - - -@dataclass(slots=True) -class SeedQuestionSpec: - question: str - answer: str | None = None - task_type: str = "seeded" - supporting_edges: list[SeedEdgeSpec] = field(default_factory=list) - metadata: dict[str, Any] = field(default_factory=dict) - - -@dataclass(slots=True) -class SeedingConfig: - seeded_nodes: list[SeedNodeSpec] = field(default_factory=list) - seeded_edges: list[SeedEdgeSpec] = field(default_factory=list) - seeded_questions: list[SeedQuestionSpec] = field(default_factory=list) - llm_generate_remaining_graph: bool = True - llm_generate_remaining_tasks: bool = True - llm_generated_edge_budget: int = 6 - llm_generated_task_budget: int = 8 - llm_generation_parallel: bool = True - llm_generation_workers: int = 3 - llm_generation_retries: int = 2 - allow_template_fallback_on_llm_failure: bool = False - - -@dataclass(slots=True) -class SwarmConfig: - enabled: bool = False - max_agents: int = 3 - max_breadth: int = 2 - max_width: int = 2 - max_depth: int = 2 - planner_rounds: int = 2 - tools_per_agent: int = 1 - - -@dataclass(slots=True) -class SpawnRewardConfig: - lambda_parallel: float = 0.15 - lambda_finish: float = 0.20 - anneal: float = 1.0 - max_parallel_hint: int = 3 - - -@dataclass(slots=True) -class LLMConfig: - provider: str = "mock" - model: str = "qwen3:2b" - temperature: float = 0.1 - max_tokens: int = 256 - timeout_seconds: int = 240 - ollama_base_url: str = "http://127.0.0.1:11434" - openai_base_url: str = "https://api.openai.com/v1" - openai_api_key_env: str = "OPENAI_API_KEY" - openai_api_key: str = "" - - -@dataclass(slots=True) -class EnvironmentConfig: - n_users: int = 40 - alias_density: float = 0.35 - noise_level: float = 0.15 - red_herring_rate: float = 0.1 - max_steps: int = 18 - seed: int = 7 - seeding: SeedingConfig = field(default_factory=SeedingConfig) - swarm: SwarmConfig = field(default_factory=SwarmConfig) - spawn_reward: SpawnRewardConfig = field(default_factory=SpawnRewardConfig) - llm: LLMConfig = field(default_factory=LLMConfig) diff --git a/scratch/osint/src/osint_env/env/__init__.py b/scratch/osint/src/osint_env/env/__init__.py deleted file mode 100644 index afc94dfc868f270a67ff4cd803494cce2d15bdb8..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/env/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Environment package.""" - diff --git a/scratch/osint/src/osint_env/env/environment.py b/scratch/osint/src/osint_env/env/environment.py deleted file mode 100644 index b6e4f1cedf69906221fffaf3c39eff821453fbd1..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/env/environment.py +++ /dev/null @@ -1,260 +0,0 @@ -from __future__ import annotations - -from dataclasses import dataclass, field -from typing import TYPE_CHECKING, Any - -from osint_env.data.generator import DatasetGenerator -from osint_env.domain.models import Action, ActionType, Edge, EnvironmentConfig, Observation, TaskInstance -from osint_env.env.openenv_compat import Env -from osint_env.env.reward import ( - build_reward_model, - compute_answer_reward, - compute_edge_reward, - compute_graph_f1, -) -from osint_env.memory.store import MemoryGraph, SemanticMemory -from osint_env.platforms.tools import ToolRegistry - -if TYPE_CHECKING: - from osint_env.llm.interface import LLMClient - - -@dataclass(slots=True) -class EpisodeState: - task: TaskInstance - task_index: int = 0 - difficulty: str = "hard" - step_count: int = 0 - done: bool = False - total_reward: float = 0.0 - tool_calls: int = 0 - redundant_tool_calls: int = 0 - action_history: list[dict[str, Any]] = field(default_factory=list) - tool_outputs: list[dict[str, Any]] = field(default_factory=list) - answer: str | None = None - call_fingerprints: set[str] = field(default_factory=set) - reward_components: dict[str, float] = field(default_factory=dict) - - -class OSINTEnvironment(Env): - def __init__(self, config: EnvironmentConfig, llm: "LLMClient | None" = None): - super().__init__( - name="OSINTEnvironment", - state_space="json-observation", - action_space=["CALL_TOOL", "ADD_EDGE", "ANSWER"], - episode_max_length=config.max_steps, - ) - self.config = config - self.generator = DatasetGenerator(config, llm=llm) - self.graph = self.generator.build_canonical_graph() - self.views = self.generator.build_platform_views(self.graph) - self.tasks = self.generator.generate_tasks(self.graph, self.views, count=24) - self.reward_model = build_reward_model(self.graph) - self.tools = ToolRegistry(self.views) - self.memory_graph = MemoryGraph() - self.semantic_memory = SemanticMemory() - self._task_idx = 0 - self.state: EpisodeState | None = None - - @staticmethod - def _normalize_difficulty(value: str) -> str: - token = str(value or "").strip().lower() - if token in {"easy", "e"}: - return "easy" - if token in {"mid", "medium", "m"}: - return "medium" - if token in {"high", "hard", "h"}: - return "hard" - return "hard" - - def _resolve_task_difficulty(self, task: TaskInstance, task_index: int) -> str: - metadata = dict(task.metadata or {}) - if "difficulty" in metadata: - return self._normalize_difficulty(str(metadata.get("difficulty", ""))) - if task_index < 10: - return "easy" - if task_index < 20: - return "medium" - return "hard" - - def reset(self) -> Observation: - task_index = self._task_idx % len(self.tasks) - task = self.tasks[task_index] - self._task_idx += 1 - self.state = EpisodeState( - task=task, - task_index=task_index, - difficulty=self._resolve_task_difficulty(task, task_index), - ) - self.memory_graph = MemoryGraph() - self.semantic_memory = SemanticMemory() - return self._observation() - - def step(self, action: Action) -> tuple[Observation, float, bool, dict[str, Any]]: - if self.state is None: - raise RuntimeError("Call reset() before step().") - if self.state.done: - return self._observation(), 0.0, True, self._info() - - self.state.step_count += 1 - reward = 0.0 - - if action.action_type == ActionType.CALL_TOOL: - reward += self._handle_tool(action.payload) - elif action.action_type == ActionType.ADD_EDGE: - reward += self._handle_add_edge(action.payload) - elif action.action_type == ActionType.ANSWER: - reward += self._handle_answer(action.payload) - else: - reward -= 0.5 - - if self.state.step_count >= self.config.max_steps and not self.state.done: - self.state.done = True - reward -= 0.3 - - self.state.total_reward += reward - self.state.action_history.append({"type": action.action_type.value, "payload": action.payload, "reward": reward}) - return self._observation(), reward, self.state.done, self._info() - - def _handle_tool(self, payload: dict[str, Any]) -> float: - if self.state is None: - return 0.0 - tool_name = payload["tool_name"] - args = payload.get("args", {}) - fp = f"{tool_name}:{sorted(args.items())}" - self.state.tool_calls += 1 - if fp in self.state.call_fingerprints: - self.state.redundant_tool_calls += 1 - penalty = -0.2 - else: - penalty = 0.05 - self.state.call_fingerprints.add(fp) - - invalid_tool_penalty = 0.0 - try: - if tool_name == "search_memory": - query = str(args.get("query", "")).strip() - top_k = int(args.get("k", 5)) if str(args.get("k", "")).strip() else 5 - results = self.semantic_memory.search(query=query, k=max(1, top_k)) if query else [] - output = {"results": results, "count": len(results)} - else: - output = self.tools.call(tool_name, args) - except Exception as exc: - output = {"error": str(exc)} - invalid_tool_penalty = -0.25 - self.state.tool_outputs.append({"tool": tool_name, "args": args, "output": output}) - self.semantic_memory.add(f"{tool_name} {args} {output}", {"tool": tool_name}) - relevance_bonus = 0.08 * self._tool_relevance(self.state.task, output) - total = penalty + relevance_bonus + invalid_tool_penalty - self._accumulate_reward_components( - { - "tool_novelty": penalty, - "tool_relevance": relevance_bonus, - "invalid_tool_penalty": invalid_tool_penalty, - } - ) - return total - - def _handle_add_edge(self, payload: dict[str, Any]) -> float: - if self.state is None: - return 0.0 - edge = Edge(payload["src"], payload["rel"], payload["dst"], float(payload.get("confidence", 1.0))) - existing_edges = list(self.memory_graph.edges) - added = self.memory_graph.add_edge(edge) - if not added: - self._accumulate_reward_components({"duplicate_edge_penalty": -0.15}) - return -0.15 - - breakdown = compute_edge_reward( - edge=edge, - task=self.state.task, - existing_edges=existing_edges, - step_count=self.state.step_count, - model=self.reward_model, - graph=self.graph, - difficulty=self.state.difficulty, - ) - self._accumulate_reward_components(breakdown.to_dict()) - return breakdown.total - - def _handle_answer(self, payload: dict[str, Any]) -> float: - if self.state is None: - return 0.0 - proposed = str(payload.get("answer", "")).strip() - self.state.answer = proposed - self.state.done = True - breakdown = compute_answer_reward( - proposed_answer=proposed, - task=self.state.task, - pred_edges=self.memory_graph.edges, - tool_outputs=self.state.tool_outputs, - step_count=self.state.step_count, - model=self.reward_model, - difficulty=self.state.difficulty, - ) - self._accumulate_reward_components(breakdown.to_dict()) - return breakdown.total - - def _tool_relevance(self, task: TaskInstance, output: dict[str, Any]) -> float: - haystack = str(output).lower() - clues = {task.answer.lower()} - for edge in task.supporting_edges: - clues.add(edge.src.lower()) - clues.add(edge.dst.lower()) - clues.add(edge.rel.lower()) - if not clues: - return 0.0 - matches = sum(1 for token in clues if token in haystack) - return matches / len(clues) - - def _accumulate_reward_components(self, values: dict[str, float]) -> None: - if self.state is None: - return - for key, value in values.items(): - self.state.reward_components[key] = self.state.reward_components.get(key, 0.0) + float(value) - - def _observation(self) -> Observation: - if self.state is None: - raise RuntimeError("State is not initialized.") - metadata = dict(self.state.task.metadata or {}) - grader = metadata.get("grader") if isinstance(metadata.get("grader"), dict) else None - task_payload = { - "task_id": self.state.task.task_id, - "task_type": self.state.task.task_type, - "question": self.state.task.question, - "difficulty": self.state.difficulty, - "grader": ( - dict(grader) - if grader is not None - else { - "type": "difficulty_exact_match", - "answer_type": "node_id", - "case_sensitive": True, - "reward_profile": self.state.difficulty, - } - ), - } - if "scenario" in metadata: - task_payload["scenario"] = str(metadata.get("scenario", "")) - return Observation( - tool_outputs=self.state.tool_outputs[-5:], - graph_snapshot=self.memory_graph.to_snapshot(), - action_history=self.state.action_history[-10:], - task=task_payload, - ) - - def _info(self) -> dict[str, Any]: - if self.state is None: - return {} - return { - "step_count": self.state.step_count, - "difficulty": self.state.difficulty, - "task_index": self.state.task_index, - "total_reward": self.state.total_reward, - "tool_calls": self.state.tool_calls, - "redundant_tool_calls": self.state.redundant_tool_calls, - "task_answer": self.state.task.answer, - "agent_answer": self.state.answer, - "graph_f1": compute_graph_f1(self.memory_graph.edges, self.state.task.supporting_edges), - "reward_components": dict(self.state.reward_components), - } diff --git a/scratch/osint/src/osint_env/env/openenv_compat.py b/scratch/osint/src/osint_env/env/openenv_compat.py deleted file mode 100644 index 46f2bfd007c092e38e5c636215a0ca17faa9b541..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/env/openenv_compat.py +++ /dev/null @@ -1,20 +0,0 @@ -from __future__ import annotations - -try: - from openenv.env import Env -except ImportError: - class Env: - """Minimal fallback used when openenv is not installed locally.""" - - def __init__( - self, - name: str, - state_space: str, - action_space: list[str], - episode_max_length: int, - ) -> None: - self.name = name - self.state_space = state_space - self.action_space = action_space - self.episode_max_length = episode_max_length - diff --git a/scratch/osint/src/osint_env/env/reward.py b/scratch/osint/src/osint_env/env/reward.py deleted file mode 100644 index 7a0b824daddd2ed696bc6af411b727d7a8c950e0..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/env/reward.py +++ /dev/null @@ -1,483 +0,0 @@ -from __future__ import annotations - -import json -import math -import re -from collections import Counter -from dataclasses import asdict, dataclass - -from osint_env.domain.models import CanonicalGraph, Edge, TaskInstance - - -@dataclass(slots=True) -class RewardModel: - relation_idf: dict[str, float] - max_relation_idf: float - hub_penalty: dict[str, float] - max_hub_penalty: float - type_priors: dict[tuple[str, str, str], float] - - -@dataclass(slots=True) -class EdgeRewardBreakdown: - total: float - global_accuracy: float - soft_shaping: float - efficiency: float - diversity: float - relation_informativeness: float - entity_informativeness: float - connectivity_gain: float - - def to_dict(self) -> dict[str, float]: - return asdict(self) - - -@dataclass(slots=True) -class AnswerRewardBreakdown: - total: float - format_reward: float - correctness: float - knowledge_carrier: float - knowledge_indexing: float - connectivity: float - graph_f1: float - efficiency: float - compactness: float - relation_informativeness: float - entity_informativeness: float - repetition_penalty: float - - def to_dict(self) -> dict[str, float]: - return asdict(self) - - -def _normalize_difficulty(value: str) -> str: - token = str(value or "").strip().lower() - if token in {"easy", "e"}: - return "easy" - if token in {"mid", "medium", "m"}: - return "medium" - if token in {"high", "hard", "h"}: - return "hard" - return "hard" - - -def build_reward_model(graph: CanonicalGraph) -> RewardModel: - relation_freq: Counter[str] = Counter(e.rel for e in graph.edges) - total_edges = max(1, len(graph.edges)) - relation_idf = { - rel: math.log((1.0 + total_edges) / (1.0 + freq)) + 1.0 for rel, freq in relation_freq.items() - } - max_relation_idf = max(relation_idf.values()) if relation_idf else 1.0 - - degree: Counter[str] = Counter() - for edge in graph.edges: - degree[edge.src] += 1 - degree[edge.dst] += 1 - hub_penalty = {node_id: math.log(1.0 + deg) for node_id, deg in degree.items()} - max_hub_penalty = max(hub_penalty.values()) if hub_penalty else 1.0 - - type_counts: Counter[tuple[str, str, str]] = Counter() - rel_counts: Counter[str] = Counter() - for edge in graph.edges: - src = graph.nodes.get(edge.src) - dst = graph.nodes.get(edge.dst) - if src is None or dst is None: - continue - key = (str(src.node_type.value), edge.rel, str(dst.node_type.value)) - type_counts[key] += 1 - rel_counts[edge.rel] += 1 - type_priors = { - key: count / max(1, rel_counts[key[1]]) for key, count in type_counts.items() - } - - return RewardModel( - relation_idf=relation_idf, - max_relation_idf=max_relation_idf, - hub_penalty=hub_penalty, - max_hub_penalty=max_hub_penalty, - type_priors=type_priors, - ) - - -def edge_in_truth(edge: Edge, task: TaskInstance) -> bool: - return any(e.src == edge.src and e.rel == edge.rel and e.dst == edge.dst for e in task.supporting_edges) - - -def _cosine(a: Counter[str], b: Counter[str]) -> float: - common = set(a) & set(b) - num = sum(a[t] * b[t] for t in common) - den = math.sqrt(sum(v * v for v in a.values())) * math.sqrt(sum(v * v for v in b.values())) - return (num / den) if den else 0.0 - - -def _edge_signature(edge: Edge) -> Counter[str]: - # Approximate path/edge embedding using relation and endpoint prefixes. - src_prefix = edge.src.split("_", 1)[0] - dst_prefix = edge.dst.split("_", 1)[0] - return Counter({f"rel:{edge.rel}": 2, f"src:{src_prefix}": 1, f"dst:{dst_prefix}": 1}) - - -def _soft_fact_score(edge: Edge, model: RewardModel, graph: CanonicalGraph) -> float: - if any(e.src == edge.src and e.rel == edge.rel and e.dst == edge.dst for e in graph.edges): - return 1.0 - - src = graph.nodes.get(edge.src) - dst = graph.nodes.get(edge.dst) - if src is None or dst is None: - return 0.0 - - type_key = (str(src.node_type.value), edge.rel, str(dst.node_type.value)) - prior = model.type_priors.get(type_key, 0.0) - - # A tiny domain heuristic: alias links are common and worth soft credit even without exact support edge. - alias_bias = 0.2 if (edge.rel == "alias_of" and edge.src.startswith("alias_") and edge.dst.startswith("user_")) else 0.0 - relation_exists = any(e.rel == edge.rel for e in graph.edges) - relation_bonus = 0.1 if relation_exists else 0.0 - return max(0.0, min(1.0, 0.1 + (0.65 * prior) + alias_bias + relation_bonus)) - - -def _normalized_relation_info(rel: str, model: RewardModel) -> float: - idf = model.relation_idf.get(rel, 1.0) - return idf / max(1e-6, model.max_relation_idf) - - -def _normalized_entity_info(src: str, dst: str, model: RewardModel) -> float: - src_h = model.hub_penalty.get(src, 0.0) - dst_h = model.hub_penalty.get(dst, 0.0) - mean_hub = (src_h + dst_h) / 2.0 - # UniRel-style preference for low-degree intermediates: lower hub penalty -> higher informativeness. - return 1.0 - (mean_hub / max(1e-6, model.max_hub_penalty)) - - -def _is_reachable_undirected(edges: list[Edge], src: str, dst: str) -> bool: - if src == dst: - return True - adj: dict[str, set[str]] = {} - for edge in edges: - adj.setdefault(edge.src, set()).add(edge.dst) - adj.setdefault(edge.dst, set()).add(edge.src) - seen = {src} - stack = [src] - while stack: - node = stack.pop() - for nxt in adj.get(node, set()): - if nxt == dst: - return True - if nxt not in seen: - seen.add(nxt) - stack.append(nxt) - return False - - -def _connectivity_gain(edge: Edge, existing_edges: list[Edge]) -> float: - # Reward edges that bridge disconnected regions and penalize already-connected shortcuts. - if edge.src == edge.dst: - return -0.06 - already_connected = _is_reachable_undirected(existing_edges, edge.src, edge.dst) - if already_connected: - return -0.03 - return 0.10 - - -def _sigmoid_temperature(value: float, temperature: float = 2.0) -> float: - scaled = float(value) / max(1e-6, float(temperature)) - if scaled >= 0: - z = math.exp(-scaled) - return 1.0 / (1.0 + z) - z = math.exp(scaled) - return z / (1.0 + z) - - -def compute_edge_reward( - edge: Edge, - task: TaskInstance, - existing_edges: list[Edge], - step_count: int, - model: RewardModel, - graph: CanonicalGraph, - difficulty: str = "hard", -) -> EdgeRewardBreakdown: - in_truth = edge_in_truth(edge, task) - difficulty_level = _normalize_difficulty(difficulty) - - # DeepPath-inspired global accuracy term. - global_accuracy = 0.85 if in_truth else -0.55 - - # D18 reward shaping: R = Rb + (1 - Rb) * f, where f is a soft fact plausibility score. - base_reward = 1.0 if in_truth else 0.0 - shaped = base_reward + ((1.0 - base_reward) * _soft_fact_score(edge, model, graph)) - soft_shaping = 0.30 * (shaped - 0.5) - - # DeepPath-inspired efficiency term: earlier useful edges are better. - efficiency = 0.10 * (1.0 / max(1, step_count)) - - # DeepPath-inspired diversity term: discourage repeated edge patterns. - if not existing_edges: - diversity = 0.08 - else: - new_sig = _edge_signature(edge) - avg_similarity = sum(_cosine(new_sig, _edge_signature(e)) for e in existing_edges) / len(existing_edges) - novelty = 1.0 - avg_similarity - diversity = 0.14 * (novelty - 0.5) - - # UniRel-style informativeness terms. - relation_informativeness = 0.12 * (_normalized_relation_info(edge.rel, model) - 0.5) - entity_informativeness = 0.12 * (_normalized_entity_info(edge.src, edge.dst, model) - 0.5) - - # Additional structural utility shaping for KG construction. - connectivity_gain = _connectivity_gain(edge, existing_edges) - - if difficulty_level == "easy": - global_accuracy = 0.75 if in_truth else -0.45 - soft_shaping = 0.0 - diversity = 0.0 - relation_informativeness = 0.0 - entity_informativeness = 0.0 - connectivity_gain = 0.0 - efficiency = 0.15 * (1.0 / max(1, step_count)) - elif difficulty_level == "medium": - diversity = 0.0 - relation_informativeness = 0.0 - entity_informativeness = 0.0 - - raw_total = ( - global_accuracy - + soft_shaping - + efficiency - + diversity - + relation_informativeness - + entity_informativeness - + connectivity_gain - ) - total = _sigmoid_temperature(raw_total, temperature=2.0) - return EdgeRewardBreakdown( - total=total, - global_accuracy=global_accuracy, - soft_shaping=soft_shaping, - efficiency=efficiency, - diversity=diversity, - relation_informativeness=relation_informativeness, - entity_informativeness=entity_informativeness, - connectivity_gain=connectivity_gain, - ) - - -def _connectivity_ratio(pred_edges: list[Edge], task: TaskInstance) -> float: - nodes = {e.src for e in task.supporting_edges} | {e.dst for e in task.supporting_edges} - if len(nodes) <= 1: - return 1.0 - - adj: dict[str, set[str]] = {} - for edge in pred_edges: - adj.setdefault(edge.src, set()).add(edge.dst) - adj.setdefault(edge.dst, set()).add(edge.src) - - start = next(iter(nodes)) - seen = {start} - stack = [start] - while stack: - cur = stack.pop() - for nxt in adj.get(cur, set()): - if nxt not in seen: - seen.add(nxt) - stack.append(nxt) - return len(seen & nodes) / max(1, len(nodes)) - - -def _knowledge_indexing_recall(task: TaskInstance, tool_outputs: list[dict[str, object]]) -> float: - gold_terms = {task.answer.lower()} - for edge in task.supporting_edges: - gold_terms.add(edge.src.lower()) - gold_terms.add(edge.dst.lower()) - gold_terms.add(edge.rel.lower()) - - serialized = json.dumps(tool_outputs).lower() - covered = sum(1 for term in gold_terms if term and term in serialized) - return covered / max(1, len(gold_terms)) - - -def _knowledge_carrier_reward(pred_edges: list[Edge], task: TaskInstance) -> float: - pred = {(e.src, e.rel, e.dst) for e in pred_edges} - truth = {(e.src, e.rel, e.dst) for e in task.supporting_edges} - deducible = bool(truth & pred) - return 0.4 if deducible else -0.2 - - -def _extract_query_entities(question: str) -> set[str]: - pattern = r"\b(?:alias|user|org|loc|post|thr|thread|event)_[a-zA-Z0-9_]+\b" - return set(re.findall(pattern, question)) - - -def _max_connected_seed_count(pred_edges: list[Edge], seeds: set[str]) -> int: - if not seeds: - return 0 - adj: dict[str, set[str]] = {} - for edge in pred_edges: - adj.setdefault(edge.src, set()).add(edge.dst) - adj.setdefault(edge.dst, set()).add(edge.src) - - best = 1 - for seed in seeds: - seen = {seed} - stack = [seed] - while stack: - cur = stack.pop() - for nxt in adj.get(cur, set()): - if nxt not in seen: - seen.add(nxt) - stack.append(nxt) - connected_seed_count = len(seeds & seen) - best = max(best, connected_seed_count) - return best - - -def _unirel_connectivity_score(pred_edges: list[Edge], seeds: set[str]) -> float: - # UniRel-style discrete connectivity range projected to [-1, 1] for stable weighting. - n = len(seeds) - if n <= 1: - return 0.0 - - connected = _max_connected_seed_count(pred_edges, seeds) - raw = -math.floor(n / 2) + max(0, connected - 1) - lo = -math.floor(n / 2) - hi = math.ceil(n / 2) - 1 - if hi <= lo: - return 0.0 - return ((raw - lo) / (hi - lo)) * 2.0 - 1.0 - - -def _subgraph_relation_informativeness(pred_edges: list[Edge], model: RewardModel | None) -> float: - if not pred_edges or model is None: - return 0.0 - avg = sum(_normalized_relation_info(edge.rel, model) for edge in pred_edges) / len(pred_edges) - return avg - 0.5 - - -def _subgraph_entity_informativeness(pred_edges: list[Edge], model: RewardModel | None) -> float: - if not pred_edges or model is None: - return 0.0 - avg = sum(_normalized_entity_info(edge.src, edge.dst, model) for edge in pred_edges) / len(pred_edges) - return avg - 0.5 - - -def _relation_repetition_ratio(pred_edges: list[Edge]) -> float: - if len(pred_edges) <= 1: - return 0.0 - rels = [edge.rel for edge in pred_edges] - unique = len(set(rels)) - return 1.0 - (unique / len(rels)) - - -def _deducible_answer(proposed_answer: str, task: TaskInstance, pred_edges: list[Edge]) -> bool: - if proposed_answer != task.answer: - return False - truth = {(edge.src, edge.rel, edge.dst) for edge in task.supporting_edges} - pred = {(edge.src, edge.rel, edge.dst) for edge in pred_edges} - if truth & pred: - return True - - seeds = _extract_query_entities(task.question) - if not seeds: - return False - for seed in seeds: - if _is_reachable_undirected(pred_edges, seed, proposed_answer): - return True - return False - - -def compute_answer_reward( - proposed_answer: str, - task: TaskInstance, - pred_edges: list[Edge], - tool_outputs: list[dict[str, object]], - step_count: int, - model: RewardModel | None = None, - difficulty: str = "hard", -) -> AnswerRewardBreakdown: - difficulty_level = _normalize_difficulty(difficulty) - - format_reward = 0.15 if proposed_answer else -0.55 - correctness = 1.15 if proposed_answer == task.answer else -1.0 - - # AutoGraph-R1 style task utility decomposition. - knowledge_carrier = 0.50 if _deducible_answer(proposed_answer, task, pred_edges) else -0.25 - knowledge_indexing = 0.45 * _knowledge_indexing_recall(task, tool_outputs) - - # UniRel-style connectivity over seed entities. - seed_entities = _extract_query_entities(task.question) - seed_entities.add(task.answer) - connectivity = 0.30 * _unirel_connectivity_score(pred_edges, seed_entities) - - graph_f1 = 0.55 * compute_graph_f1(pred_edges, task.supporting_edges) - efficiency = 0.12 * (1.0 / max(1, step_count)) - - extra_edges = max(0, len(pred_edges) - len(task.supporting_edges)) - compactness = -0.05 * extra_edges - - relation_informativeness = 0.12 * _subgraph_relation_informativeness(pred_edges, model) - entity_informativeness = 0.12 * _subgraph_entity_informativeness(pred_edges, model) - - # AutoGraph-R1 repetition control variant used in larger models. - repetition_penalty = -0.10 * _relation_repetition_ratio(pred_edges) - - if difficulty_level == "easy": - knowledge_carrier = 0.0 - knowledge_indexing = 0.25 * _knowledge_indexing_recall(task, tool_outputs) - connectivity = 0.0 - graph_f1 = 0.0 - efficiency = 0.18 * (1.0 / max(1, step_count)) - compactness = 0.0 - relation_informativeness = 0.0 - entity_informativeness = 0.0 - repetition_penalty = 0.0 - elif difficulty_level == "medium": - connectivity = 0.18 * _unirel_connectivity_score(pred_edges, seed_entities) - graph_f1 = 0.35 * compute_graph_f1(pred_edges, task.supporting_edges) - compactness = -0.04 * extra_edges - relation_informativeness = 0.0 - entity_informativeness = 0.0 - repetition_penalty = 0.0 - - raw_total = ( - format_reward - + correctness - + knowledge_carrier - + knowledge_indexing - + connectivity - + graph_f1 - + efficiency - + compactness - + relation_informativeness - + entity_informativeness - + repetition_penalty - ) - total = _sigmoid_temperature(raw_total, temperature=2.0) - return AnswerRewardBreakdown( - total=total, - format_reward=format_reward, - correctness=correctness, - knowledge_carrier=knowledge_carrier, - knowledge_indexing=knowledge_indexing, - connectivity=connectivity, - graph_f1=graph_f1, - efficiency=efficiency, - compactness=compactness, - relation_informativeness=relation_informativeness, - entity_informativeness=entity_informativeness, - repetition_penalty=repetition_penalty, - ) - - -def compute_graph_f1(pred_edges: list[Edge], truth_edges: list[Edge]) -> float: - pred = {(e.src, e.rel, e.dst) for e in pred_edges} - truth = {(e.src, e.rel, e.dst) for e in truth_edges} - if not pred and not truth: - return 1.0 - if not pred or not truth: - return 0.0 - tp = len(pred & truth) - p = tp / len(pred) if pred else 0.0 - r = tp / len(truth) if truth else 0.0 - return (2 * p * r / (p + r)) if (p + r) else 0.0 diff --git a/scratch/osint/src/osint_env/env/spawn_reward_hooks.py b/scratch/osint/src/osint_env/env/spawn_reward_hooks.py deleted file mode 100644 index 52ea420c7b16c9671338894dd4fb7c7e7401fcc4..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/env/spawn_reward_hooks.py +++ /dev/null @@ -1,93 +0,0 @@ -from __future__ import annotations - -import math - - -def critical_steps(main_steps: list[int], parallel_subagent_steps: list[list[int]]) -> int: - """Compute critical-step latency proxy used in Kimi-style PARL shaping. - - For each stage t, we add: - Smain(t) + max_i Ssub,i(t) - where Ssub,i(t) is the i-th sub-agent step count for that stage. - """ - if len(main_steps) != len(parallel_subagent_steps): - raise ValueError("main_steps and parallel_subagent_steps must have the same length") - - total = 0 - for stage_main, stage_sub in zip(main_steps, parallel_subagent_steps): - main = max(0, int(stage_main)) - longest_sub = max((max(0, int(v)) for v in stage_sub), default=0) - total += main + longest_sub - return total - - -def parl_style_spawn_reward( - task_outcome_reward: float, - spawn_count: int, - finished_subtasks: int, - critical_steps: int, - lambda_parallel: float = 0.15, - lambda_finish: float = 0.20, - anneal: float = 1.0, - breadth: int | None = None, - depth: int | None = None, - max_parallel_hint: int | None = None, -) -> float: - """Kimi K2.5 inspired PARL reward utility for future multi-agent branches. - - This helper intentionally does not orchestrate agents. It only exposes the reward shape: - - r_parl = r_perf + a * (lambda_parallel * r_parallel + lambda_finish * r_finish + r_latency) - - where: - - r_parallel encourages non-zero agent spawning (avoids serial collapse) - - r_finish rewards meaningful completion, preventing spawn-only reward hacking - - r_latency favors lower critical-step execution paths - - The optional breadth/depth controls are small shaping terms for future branches where - orchestration state includes tree shape telemetry. - """ - spawn_count = max(0, int(spawn_count)) - finished_subtasks = max(0, int(finished_subtasks)) - critical_steps = max(1, int(critical_steps)) - anneal = max(0.0, min(1.0, anneal)) - lambda_parallel = max(0.0, float(lambda_parallel)) - lambda_finish = max(0.0, float(lambda_finish)) - breadth = max(0, int(breadth or 0)) - depth = max(0, int(depth or 0)) - max_parallel_hint = max(0, int(max_parallel_hint or 0)) - - if spawn_count == 0: - r_parallel = 0.0 - r_finish = 0.0 - else: - # Saturating incentive for parallelism so reward cannot grow unbounded with spawns. - r_parallel = math.tanh(spawn_count / 4.0) - if max_parallel_hint > 0: - utilization = min(1.0, spawn_count / max_parallel_hint) - r_parallel *= (0.7 + (0.3 * utilization)) - - r_finish = min(1.0, finished_subtasks / spawn_count) - - if breadth > 0: - breadth_bonus = 0.04 * math.tanh(breadth / 6.0) - else: - breadth_bonus = 0.0 - - if depth > 0: - # Mild depth penalty discourages brittle over-decomposition chains. - depth_penalty = -0.03 * math.tanh(max(0, depth - 1) / 4.0) - else: - depth_penalty = 0.0 - - # Optional latency shaping hook using critical steps (higher is worse). - r_latency = 0.05 * (1.0 / critical_steps) - - auxiliary = ( - (lambda_parallel * r_parallel) - + (lambda_finish * r_finish) - + r_latency - + breadth_bonus - + depth_penalty - ) - return float(task_outcome_reward) + (anneal * auxiliary) diff --git a/scratch/osint/src/osint_env/eval/__init__.py b/scratch/osint/src/osint_env/eval/__init__.py deleted file mode 100644 index 0041203255773471e8b612ada5ed7a53245dac30..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/eval/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Evaluation package.""" - diff --git a/scratch/osint/src/osint_env/eval/leaderboard.py b/scratch/osint/src/osint_env/eval/leaderboard.py deleted file mode 100644 index b46a6852c736ca6e332366cb5ce77ab45e9f30e3..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/eval/leaderboard.py +++ /dev/null @@ -1,83 +0,0 @@ -from __future__ import annotations - -import json -from datetime import datetime, timezone -from pathlib import Path -from typing import Any - - -def _utc_now() -> str: - return datetime.now(tz=timezone.utc).replace(microsecond=0).isoformat() - - -def load_leaderboard(path: str | Path) -> list[dict[str, Any]]: - file_path = Path(path) - if not file_path.exists(): - return [] - with file_path.open("r", encoding="utf-8") as f: - data = json.load(f) - if not isinstance(data, list): - return [] - return data - - -def save_leaderboard(path: str | Path, records: list[dict[str, Any]]) -> None: - file_path = Path(path) - file_path.parent.mkdir(parents=True, exist_ok=True) - with file_path.open("w", encoding="utf-8") as f: - json.dump(records, f, indent=2, sort_keys=True) - - -def _metric_value(record: dict[str, Any], sort_by: str) -> float: - metrics = record.get("metrics", {}) - return float(metrics.get(sort_by, 0.0)) - - -def sorted_leaderboard(records: list[dict[str, Any]], sort_by: str = "leaderboard_score") -> list[dict[str, Any]]: - return sorted(records, key=lambda r: _metric_value(r, sort_by), reverse=True) - - -def append_leaderboard_record( - path: str | Path, - summary: dict[str, Any], - episodes: int, - run_name: str | None = None, - config: dict[str, Any] | None = None, -) -> dict[str, Any]: - records = load_leaderboard(path) - run_id = f"run_{len(records) + 1:04d}" - record = { - "run_id": run_id, - "run_name": run_name or run_id, - "created_at": _utc_now(), - "episodes": int(episodes), - "config": config or {}, - "metrics": summary, - } - records.append(record) - save_leaderboard(path, records) - return record - - -def render_leaderboard_table(records: list[dict[str, Any]], top_k: int = 20, sort_by: str = "leaderboard_score") -> str: - ranked = sorted_leaderboard(records, sort_by=sort_by)[:top_k] - header = "| rank | run | score | success | graph_f1 | retrieval | structural | spawn | reward | tool_eff |\n" - sep = "|---|---|---:|---:|---:|---:|---:|---:|---:|---:|\n" - rows: list[str] = [] - for idx, rec in enumerate(ranked, start=1): - m = rec.get("metrics", {}) - rows.append( - "| {rank} | {run} | {score:.4f} | {succ:.3f} | {f1:.3f} | {retrieval:.3f} | {structural:.3f} | {spawn:.3f} | {reward:.3f} | {tool:.3f} |".format( - rank=idx, - run=rec.get("run_name", rec.get("run_id", "run")), - score=float(m.get("leaderboard_score", 0.0)), - succ=float(m.get("task_success_rate", 0.0)), - f1=float(m.get("avg_graph_f1", 0.0)), - retrieval=float(m.get("retrieval_signal", 0.0)), - structural=float(m.get("structural_signal", 0.0)), - spawn=float(m.get("spawn_signal", 0.0)), - reward=float(m.get("avg_reward", 0.0)), - tool=float(m.get("tool_efficiency", 0.0)), - ) - ) - return header + sep + "\n".join(rows) diff --git a/scratch/osint/src/osint_env/eval/metrics.py b/scratch/osint/src/osint_env/eval/metrics.py deleted file mode 100644 index e32bf182907847d0b69be77d46ecdfc9df6d0722..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/eval/metrics.py +++ /dev/null @@ -1,139 +0,0 @@ -from __future__ import annotations - -import math -from dataclasses import dataclass, field - - -@dataclass(slots=True) -class EvalMetrics: - episodes: int = 0 - success: int = 0 - total_steps: int = 0 - total_tool_calls: int = 0 - total_redundant_tool_calls: int = 0 - total_reward: float = 0.0 - deanonymization_total: int = 0 - deanonymization_success: int = 0 - graph_f1_scores: list[float] = field(default_factory=list) - total_knowledge_carrier: float = 0.0 - total_knowledge_indexing: float = 0.0 - total_connectivity: float = 0.0 - total_format_reward: float = 0.0 - total_relation_informativeness: float = 0.0 - total_entity_informativeness: float = 0.0 - total_diversity: float = 0.0 - total_soft_shaping: float = 0.0 - total_connectivity_gain: float = 0.0 - total_compactness: float = 0.0 - total_spawn_count: int = 0 - total_spawn_finished_subtasks: int = 0 - total_spawn_critical_steps: int = 0 - - @staticmethod - def _sigmoid_temperature(value: float, temperature: float = 2.0) -> float: - scaled = float(value) / max(1e-6, float(temperature)) - if scaled >= 0: - z = math.exp(-scaled) - return 1.0 / (1.0 + z) - z = math.exp(scaled) - return z / (1.0 + z) - - def add(self, info: dict, task_type: str, graph_f1: float) -> None: - self.episodes += 1 - ok = info.get("agent_answer") == info.get("task_answer") - self.success += int(ok) - self.total_steps += int(info.get("step_count", 0)) - self.total_tool_calls += int(info.get("tool_calls", 0)) - self.total_redundant_tool_calls += int(info.get("redundant_tool_calls", 0)) - self.total_reward += float(info.get("total_reward", 0.0)) - self.graph_f1_scores.append(graph_f1) - components = info.get("reward_components", {}) - self.total_knowledge_carrier += float(components.get("knowledge_carrier", 0.0)) - self.total_knowledge_indexing += float(components.get("knowledge_indexing", 0.0)) - self.total_connectivity += float(components.get("connectivity", 0.0)) - self.total_format_reward += float(components.get("format_reward", 0.0)) - self.total_relation_informativeness += float(components.get("relation_informativeness", 0.0)) - self.total_entity_informativeness += float(components.get("entity_informativeness", 0.0)) - self.total_diversity += float(components.get("diversity", 0.0)) - self.total_soft_shaping += float(components.get("soft_shaping", 0.0)) - self.total_connectivity_gain += float(components.get("connectivity_gain", 0.0)) - self.total_compactness += float(components.get("compactness", 0.0)) - self.total_spawn_count += int(info.get("spawn_count", 0)) - self.total_spawn_finished_subtasks += int(info.get("spawn_finished_subtasks", 0)) - self.total_spawn_critical_steps += int(info.get("spawn_critical_steps", 0)) - if task_type == "identity_resolution": - self.deanonymization_total += 1 - self.deanonymization_success += int(ok) - - def summary(self) -> dict: - episodes = max(1, self.episodes) - task_success_rate = self.success / episodes - tool_efficiency = 1.0 - (self.total_redundant_tool_calls / max(1, self.total_tool_calls)) - avg_graph_f1 = sum(self.graph_f1_scores) / max(1, len(self.graph_f1_scores)) - deanonymization_accuracy = self.deanonymization_success / max(1, self.deanonymization_total) - avg_reward_raw = self.total_reward / episodes - avg_reward = self._sigmoid_temperature(avg_reward_raw, temperature=2.0) - avg_knowledge_carrier = self.total_knowledge_carrier / episodes - avg_knowledge_indexing = self.total_knowledge_indexing / episodes - avg_connectivity = self.total_connectivity / episodes - avg_relation_informativeness = self.total_relation_informativeness / episodes - avg_entity_informativeness = self.total_entity_informativeness / episodes - avg_diversity = self.total_diversity / episodes - avg_soft_shaping = self.total_soft_shaping / episodes - avg_connectivity_gain = self.total_connectivity_gain / episodes - avg_compactness = self.total_compactness / episodes - avg_spawn_count = self.total_spawn_count / episodes - spawn_completion = self.total_spawn_finished_subtasks / max(1, self.total_spawn_count) - avg_spawn_critical_steps = self.total_spawn_critical_steps / episodes - spawn_latency_signal = 1.0 / max(1.0, avg_spawn_critical_steps) - spawn_signal = max(0.0, min(1.0, 0.6 * spawn_completion + 0.4 * spawn_latency_signal)) - - reward_norm = avg_reward - retrieval_signal = max(0.0, min(1.0, 0.5 + 0.35 * avg_knowledge_carrier + 0.35 * avg_knowledge_indexing)) - structural_signal = max( - 0.0, - min( - 1.0, - 0.5 - + 0.25 * avg_connectivity - + 0.20 * avg_relation_informativeness - + 0.20 * avg_entity_informativeness - + 0.15 * avg_diversity - + 0.10 * avg_connectivity_gain, - ), - ) - leaderboard_score = ( - 0.28 * task_success_rate - + 0.20 * avg_graph_f1 - + 0.12 * tool_efficiency - + 0.12 * deanonymization_accuracy - + 0.14 * retrieval_signal - + 0.09 * structural_signal - + 0.05 * reward_norm - + 0.04 * spawn_signal - ) - return { - "task_success_rate": task_success_rate, - "tool_efficiency": tool_efficiency, - "avg_graph_f1": avg_graph_f1, - "avg_steps_to_solution": self.total_steps / episodes, - "deanonymization_accuracy": deanonymization_accuracy, - "avg_reward": avg_reward, - "avg_knowledge_carrier_reward": avg_knowledge_carrier, - "avg_knowledge_indexing_reward": avg_knowledge_indexing, - "avg_connectivity_reward": avg_connectivity, - "avg_format_reward": self.total_format_reward / episodes, - "avg_relation_informativeness_reward": avg_relation_informativeness, - "avg_entity_informativeness_reward": avg_entity_informativeness, - "avg_diversity_reward": avg_diversity, - "avg_soft_shaping_reward": avg_soft_shaping, - "avg_connectivity_gain_reward": avg_connectivity_gain, - "avg_compactness_reward": avg_compactness, - "avg_spawn_count": avg_spawn_count, - "spawn_completion_rate": spawn_completion, - "avg_spawn_critical_steps": avg_spawn_critical_steps, - "spawn_signal": spawn_signal, - "retrieval_signal": retrieval_signal, - "structural_signal": structural_signal, - "leaderboard_score": leaderboard_score, - } diff --git a/scratch/osint/src/osint_env/eval/runner.py b/scratch/osint/src/osint_env/eval/runner.py deleted file mode 100644 index c6c074c23cb741f629e3621d9fc9cdc9f319d6cb..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/eval/runner.py +++ /dev/null @@ -1,69 +0,0 @@ -from __future__ import annotations - -from osint_env.agents.single_agent import SingleAgentRunner -from osint_env.agents.swarm_agent import SwarmAgentRunner -from osint_env.env.environment import OSINTEnvironment -from osint_env.env.reward import compute_graph_f1 -from osint_env.eval.metrics import EvalMetrics -from osint_env.llm.interface import LLMClient - - -def run_evaluation( - env: OSINTEnvironment, - episodes: int = 20, - return_details: bool = False, - llm: LLMClient | None = None, -) -> dict: - metrics = EvalMetrics() - if env.config.swarm.enabled: - runner = SwarmAgentRunner(env=env, llm=llm) - else: - runner = SingleAgentRunner(env=env, llm=llm) - episode_rows: list[dict] = [] - for _ in range(episodes): - info = runner.run_episode() - task_type = env.state.task.task_type if env.state else "unknown" - task_id = env.state.task.task_id if env.state else "unknown" - truth = env.state.task.supporting_edges if env.state else [] - pred = env.memory_graph.edges if env.state else [] - graph_f1 = compute_graph_f1(pred, truth) - metrics.add(info, task_type=task_type, graph_f1=graph_f1) - episode_rows.append( - { - "task_id": task_id, - "task_type": task_type, - "question": env.state.task.question if env.state else "", - "task_answer": str(info.get("task_answer", "")), - "agent_answer": str(info.get("agent_answer", "")) if info.get("agent_answer") is not None else "", - "graph_f1": graph_f1, - "reward": float(info.get("total_reward", 0.0)), - "steps": int(info.get("step_count", 0)), - "tool_calls": int(info.get("tool_calls", 0)), - "success": int(info.get("agent_answer") == info.get("task_answer")), - "reward_components": dict(info.get("reward_components", {})), - "spawn_count": int(info.get("spawn_count", 0)), - "spawn_critical_steps": int(info.get("spawn_critical_steps", 0)), - "pred_edges": [ - { - "src": edge.src, - "rel": edge.rel, - "dst": edge.dst, - "confidence": float(edge.confidence), - } - for edge in pred - ], - "truth_edges": [ - { - "src": edge.src, - "rel": edge.rel, - "dst": edge.dst, - "confidence": float(edge.confidence), - } - for edge in truth - ], - } - ) - summary = metrics.summary() - if return_details: - return {"summary": summary, "episodes": episode_rows} - return summary diff --git a/scratch/osint/src/osint_env/llm/__init__.py b/scratch/osint/src/osint_env/llm/__init__.py deleted file mode 100644 index 2980377f05c73f88682c51811fb9871602f9a638..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/llm/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -"""LLM interface package.""" - -from osint_env.llm.interface import ( - LLMClient, - LLMResponse, - OllamaLLMClient, - OpenAILLMClient, - RuleBasedMockLLM, - build_llm_client, -) - -__all__ = [ - "LLMClient", - "LLMResponse", - "RuleBasedMockLLM", - "OllamaLLMClient", - "OpenAILLMClient", - "build_llm_client", -] - diff --git a/scratch/osint/src/osint_env/llm/interface.py b/scratch/osint/src/osint_env/llm/interface.py deleted file mode 100644 index e223e1a3873d094b62789c4c45e7f0956c419d33..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/llm/interface.py +++ /dev/null @@ -1,167 +0,0 @@ -from __future__ import annotations - -import json -import os -from dataclasses import dataclass -from typing import Any, Protocol - -import requests -from requests import RequestException - -from osint_env.domain.models import LLMConfig - - -@dataclass(slots=True) -class LLMResponse: - content: str - tool_calls: list[dict[str, Any]] - - -class LLMClient(Protocol): - def generate(self, messages: list[dict[str, Any]], tools: list[dict[str, Any]]) -> LLMResponse: - ... - - -class RuleBasedMockLLM: - """Deterministic fallback for local testing without model dependencies.""" - - def generate(self, messages: list[dict[str, Any]], tools: list[dict[str, Any]]) -> LLMResponse: - question = "" - for m in reversed(messages): - if m.get("role") == "system" and "question" in m.get("content", ""): - question = m["content"] - break - if "alias" in question: - return LLMResponse( - content="Need alias lookup.", - tool_calls=[{"tool_name": "search_posts", "args": {"query": "Update"}}, {"tool_name": "get_profile", "args": {"user_id": "user_0"}}], - ) - return LLMResponse(content="Need profile lookup.", tool_calls=[{"tool_name": "search_people", "args": {"org": "Apex"}}]) - - -class OllamaLLMClient: - def __init__(self, model: str, base_url: str = "http://127.0.0.1:11434", temperature: float = 0.1, timeout_seconds: int = 240): - self.model = model - self.base_url = base_url.rstrip("/") - self.temperature = float(temperature) - self.timeout_seconds = int(timeout_seconds) - - @staticmethod - def _extract_tool_calls(content: str) -> list[dict[str, Any]]: - text = str(content or "").strip() - if not text: - return [] - left = text.find("{") - right = text.rfind("}") - if left >= 0 and right > left: - snippet = text[left : right + 1] - try: - parsed = json.loads(snippet) - except json.JSONDecodeError: - parsed = None - if isinstance(parsed, dict) and isinstance(parsed.get("tool_calls"), list): - out: list[dict[str, Any]] = [] - for item in parsed["tool_calls"]: - if isinstance(item, dict) and "tool_name" in item and isinstance(item.get("args", {}), dict): - out.append({"tool_name": str(item["tool_name"]), "args": dict(item.get("args", {}))}) - return out - return [] - - def generate(self, messages: list[dict[str, Any]], tools: list[dict[str, Any]]) -> LLMResponse: - payload = { - "model": self.model, - "messages": messages, - "stream": False, - "options": { - "temperature": self.temperature, - }, - } - if tools: - payload["tools"] = tools - try: - response = requests.post( - f"{self.base_url}/api/chat", - json=payload, - timeout=self.timeout_seconds, - ) - response.raise_for_status() - data = response.json() - content = str((data.get("message") or {}).get("content", "")) - tool_calls = self._extract_tool_calls(content) - return LLMResponse(content=content, tool_calls=tool_calls) - except (RequestException, ValueError): - # Keep episode execution resilient when local model calls are transiently slow/unavailable. - return LLMResponse(content="", tool_calls=[]) - - -class OpenAILLMClient: - def __init__( - self, - model: str, - api_key: str, - base_url: str = "https://api.openai.com/v1", - temperature: float = 0.1, - max_tokens: int = 256, - timeout_seconds: int = 240, - ): - from openai import OpenAI - - self.model = model - self.temperature = float(temperature) - self.max_tokens = int(max_tokens) - self.client = OpenAI(api_key=api_key, base_url=base_url, timeout=timeout_seconds) - - def generate(self, messages: list[dict[str, Any]], tools: list[dict[str, Any]]) -> LLMResponse: - kwargs: dict[str, Any] = { - "model": self.model, - "messages": messages, - "temperature": self.temperature, - "max_tokens": self.max_tokens, - } - if tools: - kwargs["tools"] = tools - try: - completion = self.client.chat.completions.create(**kwargs) - message = completion.choices[0].message - content = message.content if isinstance(message.content, str) else "" - - tool_calls: list[dict[str, Any]] = [] - for tc in message.tool_calls or []: - try: - args = json.loads(tc.function.arguments or "{}") - except json.JSONDecodeError: - args = {} - tool_calls.append({"tool_name": tc.function.name, "args": args if isinstance(args, dict) else {}}) - return LLMResponse(content=content, tool_calls=tool_calls) - except Exception: - return LLMResponse(content="", tool_calls=[]) - - -def build_llm_client(config: LLMConfig | None = None) -> LLMClient: - cfg = config or LLMConfig() - provider = str(cfg.provider).strip().lower() - if provider in {"", "mock", "rule", "rule_based"}: - return RuleBasedMockLLM() - if provider == "ollama": - return OllamaLLMClient( - model=cfg.model, - base_url=cfg.ollama_base_url, - temperature=cfg.temperature, - timeout_seconds=cfg.timeout_seconds, - ) - if provider == "openai": - api_key = cfg.openai_api_key or os.getenv(cfg.openai_api_key_env, "") - if not api_key: - raise ValueError( - "OpenAI provider selected but API key is missing. " - f"Set {cfg.openai_api_key_env} or populate openai_api_key in config." - ) - return OpenAILLMClient( - model=cfg.model, - api_key=api_key, - base_url=cfg.openai_base_url, - temperature=cfg.temperature, - max_tokens=cfg.max_tokens, - timeout_seconds=cfg.timeout_seconds, - ) - raise ValueError(f"Unsupported llm provider: {cfg.provider}") diff --git a/scratch/osint/src/osint_env/memory/__init__.py b/scratch/osint/src/osint_env/memory/__init__.py deleted file mode 100644 index 519788dfb2a8240a0d4f54981c2c65c6e71d0df8..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/memory/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Structured memory package.""" - diff --git a/scratch/osint/src/osint_env/memory/store.py b/scratch/osint/src/osint_env/memory/store.py deleted file mode 100644 index 780f46087c8b7ea165b777a0fc61a4c8b7f613cb..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/memory/store.py +++ /dev/null @@ -1,58 +0,0 @@ -from __future__ import annotations - -import math -import re -from collections import Counter -from dataclasses import dataclass, field -from typing import Any - -from osint_env.domain.models import Edge - - -def _tokenize(text: str) -> list[str]: - return [t for t in re.findall(r"[a-zA-Z0-9_]+", text.lower()) if t] - - -@dataclass(slots=True) -class MemoryGraph: - nodes: dict[str, dict[str, Any]] = field(default_factory=dict) - edges: list[Edge] = field(default_factory=list) - - def add_edge(self, edge: Edge) -> bool: - key = (edge.src, edge.rel, edge.dst) - if any((e.src, e.rel, e.dst) == key for e in self.edges): - return False - self.edges.append(edge) - return True - - def to_snapshot(self) -> dict[str, Any]: - return { - "nodes_count": len(self.nodes), - "edges_count": len(self.edges), - "edges": [{"src": e.src, "rel": e.rel, "dst": e.dst, "confidence": e.confidence} for e in self.edges], - } - - -@dataclass(slots=True) -class SemanticMemory: - docs: list[dict[str, Any]] = field(default_factory=list) - - def add(self, text: str, metadata: dict[str, Any]) -> None: - self.docs.append({"text": text, "metadata": metadata, "tokens": Counter(_tokenize(text))}) - - def search(self, query: str, k: int = 5) -> list[dict[str, Any]]: - q = Counter(_tokenize(query)) - scored: list[tuple[float, dict[str, Any]]] = [] - for doc in self.docs: - score = self._cosine(q, doc["tokens"]) - if score > 0: - scored.append((score, doc)) - scored.sort(key=lambda x: x[0], reverse=True) - return [{"score": s, "text": d["text"], "metadata": d["metadata"]} for s, d in scored[:k]] - - @staticmethod - def _cosine(a: Counter, b: Counter) -> float: - common = set(a) & set(b) - num = sum(a[t] * b[t] for t in common) - den = math.sqrt(sum(v * v for v in a.values())) * math.sqrt(sum(v * v for v in b.values())) - return (num / den) if den else 0.0 diff --git a/scratch/osint/src/osint_env/platforms/__init__.py b/scratch/osint/src/osint_env/platforms/__init__.py deleted file mode 100644 index cc16c8fc0fb7ab3780746c358de603a3ff5eb1d6..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/platforms/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -"""Platform and tool adapters.""" - diff --git a/scratch/osint/src/osint_env/platforms/tools.py b/scratch/osint/src/osint_env/platforms/tools.py deleted file mode 100644 index d547fe4383f0019bde331186486fc22549cd6651..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/platforms/tools.py +++ /dev/null @@ -1,168 +0,0 @@ -from __future__ import annotations - -from collections import defaultdict -from typing import Any - -from osint_env.data.generator import PlatformViews - - -class ToolRegistry: - def __init__(self, views: PlatformViews): - self.views = views - self.alias_lookup = dict(getattr(views, "alias_lookup", {})) - self._index() - - @staticmethod - def _normalize_lookup_token(value: str) -> str: - token = str(value or "").strip().lower() - for prefix in ("org_", "loc_", "event_", "post_", "thr_", "thread_", "alias_", "user_"): - if token.startswith(prefix): - token = token[len(prefix) :] - break - return token.replace("_", " ") - - def _resolve_user_ids(self, user_id: str) -> list[str]: - user_id = str(user_id or "").strip() - if not user_id: - return [] - resolved = [user_id] - canonical = self.alias_lookup.get(user_id) - if canonical and canonical not in resolved: - resolved.append(canonical) - for alias_id, owner in self.alias_lookup.items(): - if owner == user_id and alias_id not in resolved: - resolved.append(alias_id) - return resolved - - def _index(self) -> None: - self.posts_by_user: dict[str, list[dict[str, Any]]] = defaultdict(list) - self.mentions_by_user: dict[str, list[dict[str, Any]]] = defaultdict(list) - self.posts_by_id = {post["post_id"]: post for post in self.views.microblog_posts} - for post in self.views.microblog_posts: - self.posts_by_user[post["user_id"]].append(post) - canonical_user = post.get("canonical_user") - if canonical_user: - self.posts_by_user[canonical_user].append(post) - for m in post.get("mentions", []): - self.mentions_by_user[m].append(post) - - self.threads_by_id = {t["thread_id"]: t for t in self.views.forum_threads} - self.activity_by_user: dict[str, list[dict[str, Any]]] = defaultdict(list) - for thread in self.views.forum_threads: - self.activity_by_user[thread["author_id"]].append({"kind": "thread", "thread_id": thread["thread_id"]}) - for c in thread.get("comments", []): - self.activity_by_user[c["user_id"]].append({"kind": "comment", "thread_id": thread["thread_id"]}) - - self.profiles_by_user = {p["user_id"]: p for p in self.views.profiles} - - def call(self, tool_name: str, args: dict[str, Any]) -> dict[str, Any]: - fn = getattr(self, tool_name, None) - if not fn: - raise ValueError(f"Unknown tool: {tool_name}") - return fn(**args) - - def search_posts(self, query: str, time_range: tuple[int, int] | None = None) -> dict[str, Any]: - start, end = time_range or (0, 10**9) - needle = str(query or "").lower() - results = [ - p - for p in self.views.microblog_posts - if start <= p["timestamp"] <= end - and ( - needle in p["text"].lower() - or needle in str(p.get("post_id", "")).lower() - or needle in str(p.get("user_id", "")).lower() - or needle in str(p.get("canonical_user", "")).lower() - or any(needle in str(ref).lower() for ref in p.get("references", [])) - or any(needle in str(ref).lower() for ref in p.get("reference_names", [])) - ) - ] - return {"results": results[:20], "count": len(results)} - - def get_post(self, post_id: str) -> dict[str, Any]: - post = self.posts_by_id.get(post_id) - return {"result": post, "found": post is not None} - - def get_user_posts(self, user_id: str) -> dict[str, Any]: - results: list[dict[str, Any]] = [] - seen_post_ids: set[str] = set() - for resolved_id in self._resolve_user_ids(user_id): - for post in self.posts_by_user.get(resolved_id, []): - post_id = str(post.get("post_id", "")) - if post_id in seen_post_ids: - continue - seen_post_ids.add(post_id) - results.append(post) - return {"results": results, "count": len(results)} - - def get_mentions(self, user_id: str) -> dict[str, Any]: - results: list[dict[str, Any]] = [] - seen_post_ids: set[str] = set() - for resolved_id in self._resolve_user_ids(user_id): - for post in self.mentions_by_user.get(resolved_id, []): - post_id = str(post.get("post_id", "")) - if post_id in seen_post_ids: - continue - seen_post_ids.add(post_id) - results.append(post) - return {"results": results, "count": len(results)} - - def search_threads(self, topic: str) -> dict[str, Any]: - needle = str(topic or "").strip().lower() - results = [ - t - for t in self.views.forum_threads - if t["topic"] == topic - or needle in str(t.get("thread_id", "")).lower() - or needle in str(t.get("title", "")).lower() - ] - return {"results": results[:20], "count": len(results)} - - def get_thread(self, thread_id: str) -> dict[str, Any]: - thread = self.threads_by_id.get(thread_id) - return {"result": thread, "found": thread is not None} - - def get_user_activity(self, user_id: str) -> dict[str, Any]: - acts: list[dict[str, Any]] = [] - seen = set() - for resolved_id in self._resolve_user_ids(user_id): - for activity in self.activity_by_user.get(resolved_id, []): - key = (activity.get("kind"), activity.get("thread_id")) - if key in seen: - continue - seen.add(key) - acts.append(activity) - return {"results": acts, "count": len(acts)} - - def get_profile(self, user_id: str) -> dict[str, Any]: - resolved_ids = self._resolve_user_ids(user_id) - profile = next((self.profiles_by_user.get(candidate) for candidate in resolved_ids if self.profiles_by_user.get(candidate)), None) - return {"result": profile, "found": profile is not None} - - def search_people(self, name: str | None = None, org: str | None = None) -> dict[str, Any]: - results = self.views.profiles - if name: - name_query = str(name).lower() - results = [ - p - for p in results - if name_query in p["name"].lower() - or name_query in p["user_id"].lower() - or any(name_query in alias.lower() for alias in p.get("alias_ids", [])) - ] - if org: - org_query = str(org).lower() - normalized_org = self._normalize_lookup_token(org_query) - results = [ - p - for p in results - if org_query in p["org"].lower() - or org_query in str(p.get("org_id", "")).lower() - or (normalized_org and normalized_org in p["org"].lower()) - ] - return {"results": results[:20], "count": len(results)} - - def get_connections(self, user_id: str) -> dict[str, Any]: - resolved_ids = self._resolve_user_ids(user_id) - profile = next((self.profiles_by_user.get(candidate) for candidate in resolved_ids if self.profiles_by_user.get(candidate)), None) - return {"results": profile["connections"] if profile else [], "count": len(profile["connections"]) if profile else 0} diff --git a/scratch/osint/src/osint_env/server_entry.py b/scratch/osint/src/osint_env/server_entry.py deleted file mode 100644 index 928272ed0d02181bac278da9734db57cd41cf85c..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/server_entry.py +++ /dev/null @@ -1,10 +0,0 @@ -from __future__ import annotations - -import os - -import uvicorn - - -def main() -> None: - port = int(os.getenv("PORT", "7860")) - uvicorn.run("server:app", host="0.0.0.0", port=port) diff --git a/scratch/osint/src/osint_env/validation.py b/scratch/osint/src/osint_env/validation.py deleted file mode 100644 index 8f3e6a230805220309252a3823f72f73820640bc..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/validation.py +++ /dev/null @@ -1,316 +0,0 @@ -from __future__ import annotations - -import json -import tempfile -from dataclasses import asdict, dataclass -from pathlib import Path -from types import SimpleNamespace -from typing import Any - -from fastapi.testclient import TestClient - -from server import app -from osint_env.baselines.openai_runner import OpenAIBaselineConfig, OpenAIBaselineRunner, build_action_tools -from osint_env.config import clone_environment_config, load_seeding_config, load_shared_config -from osint_env.env.environment import OSINTEnvironment -from osint_env.env.openenv_compat import Env -from osint_env.env.reward import compute_answer_reward - - -README_PATH = Path("README.md") -DOCKERFILE_PATH = Path("Dockerfile") -OPENENV_SPEC_PATH = Path("openenv.yaml") -SHARED_CONFIG_PATH = "datasets/fixed_levels/shared_config_fixed_levels.json" -SEED_FILE_PATH = "datasets/fixed_levels/seed_fixed_levels.json" - - -@dataclass(slots=True) -class ValidationResult: - name: str - passed: bool - details: dict[str, Any] - - -def _build_environment() -> OSINTEnvironment: - shared = load_shared_config(SHARED_CONFIG_PATH) - env_cfg = clone_environment_config(shared.environment) - env_cfg.seeding = load_seeding_config(SEED_FILE_PATH) - env_cfg.llm.provider = "mock" - return OSINTEnvironment(env_cfg) - - -def check_hf_space_readiness() -> ValidationResult: - text = README_PATH.read_text(encoding="utf-8") - has_sdk = "sdk: docker" in text - has_port = "app_port: 7860" in text - has_openenv_tag = "- openenv" in text - client = TestClient(app) - health = client.get("/healthz") - dashboard = client.get("/api/environment") - spec = client.get("/openenv.yaml") - passed = all( - [ - README_PATH.exists(), - DOCKERFILE_PATH.exists(), - OPENENV_SPEC_PATH.exists(), - has_sdk, - has_port, - has_openenv_tag, - health.status_code == 200, - dashboard.status_code == 200, - spec.status_code == 200, - ] - ) - return ValidationResult( - name="hf_space_readiness", - passed=passed, - details={ - "readme_exists": README_PATH.exists(), - "dockerfile_exists": DOCKERFILE_PATH.exists(), - "openenv_spec_exists": OPENENV_SPEC_PATH.exists(), - "has_sdk_docker": has_sdk, - "has_app_port": has_port, - "has_openenv_tag": has_openenv_tag, - "healthz_status": health.status_code, - "environment_status": dashboard.status_code, - "openenv_spec_status": spec.status_code, - }, - ) - - -def check_openenv_spec_compliance() -> ValidationResult: - env = _build_environment() - obs = env.reset() - client = TestClient(app) - reset = client.post("/openenv/reset", json={"task_index": 0}) - step = client.post( - "/openenv/step", - json={ - "session_id": reset.json()["session_id"] if reset.status_code == 200 else "", - "action_type": "ANSWER", - "payload": {"answer": "unknown"}, - }, - ) - state = client.get(f"/openenv/state/{reset.json()['session_id']}") if reset.status_code == 200 else None - passed = all( - [ - isinstance(env, Env), - hasattr(env, "reset"), - hasattr(env, "step"), - env.name == "OSINTEnvironment", - env.state_space == "json-observation", - env.action_space == ["CALL_TOOL", "ADD_EDGE", "ANSWER"], - env.episode_max_length == env.config.max_steps, - isinstance(obs.task, dict), - "question" in obs.task, - reset.status_code == 200, - step.status_code == 200, - state is not None and state.status_code == 200, - ] - ) - return ValidationResult( - name="openenv_spec_compliance", - passed=passed, - details={ - "env_class": type(env).__name__, - "state_space": env.state_space, - "action_space": list(env.action_space), - "episode_max_length": env.episode_max_length, - "task_keys": sorted(obs.task.keys()), - "reset_status": reset.status_code, - "step_status": step.status_code, - "state_status": 0 if state is None else state.status_code, - }, - ) - - -class _FakeMessage: - def __init__(self, answer: str): - self.content = "" - self.tool_calls = [ - SimpleNamespace( - id="fake_tool_call_0", - function=SimpleNamespace(name="submit_answer", arguments=json.dumps({"answer": answer})), - ) - ] - - -class _FakeCompletion: - def __init__(self, answer: str): - self.choices = [SimpleNamespace(message=_FakeMessage(answer))] - self.usage = SimpleNamespace(prompt_tokens=0, completion_tokens=0, total_tokens=0) - self.system_fingerprint = "validation_fp" - - -class _FakeChatCompletions: - def create(self, **kwargs: Any) -> _FakeCompletion: - messages = list(kwargs.get("messages", [])) - initial_observation = {} - for message in messages: - if message.get("role") == "user": - try: - initial_observation = json.loads(message.get("content", "{}")) - except json.JSONDecodeError: - initial_observation = {} - break - task_id = ((initial_observation.get("task") or {}).get("task_id")) or "" - env = _build_environment() - task = next((task for task in env.tasks if task.task_id == task_id), None) - answer = task.answer if task is not None else "unknown" - return _FakeCompletion(answer) - - -class _FakeOpenAIClient: - def __init__(self) -> None: - self.chat = SimpleNamespace(completions=_FakeChatCompletions()) - - -def _run_fake_baseline_once(output_dir: Path) -> dict[str, Any]: - config = OpenAIBaselineConfig( - api_key="validation", - episodes=3, - max_steps=4, - append_leaderboard=False, - output_path=str(output_dir / "baseline.json"), - dashboard_path=str(output_dir / "baseline.html"), - leaderboard_path=str(output_dir / "leaderboard.json"), - run_name="validation_baseline", - ) - runner = OpenAIBaselineRunner.__new__(OpenAIBaselineRunner) - runner.config = config - runner.client = _FakeOpenAIClient() - runner.tools = build_action_tools() - return runner.run() - - -def check_baseline_reproducibility() -> ValidationResult: - with tempfile.TemporaryDirectory() as left_dir_name, tempfile.TemporaryDirectory() as right_dir_name: - left = _run_fake_baseline_once(Path(left_dir_name)) - right = _run_fake_baseline_once(Path(right_dir_name)) - - left_signature = { - "summary": left["summary"], - "episodes": [ - { - "task_id": episode["task_id"], - "task_answer": episode["task_answer"], - "agent_answer": episode["agent_answer"], - "success": episode["success"], - "steps": episode["steps"], - } - for episode in left["episodes"] - ], - } - right_signature = { - "summary": right["summary"], - "episodes": [ - { - "task_id": episode["task_id"], - "task_answer": episode["task_answer"], - "agent_answer": episode["agent_answer"], - "success": episode["success"], - "steps": episode["steps"], - } - for episode in right["episodes"] - ], - } - passed = left_signature == right_signature - return ValidationResult( - name="baseline_reproducibility", - passed=passed, - details={ - "episodes_checked": len(left_signature["episodes"]), - "left_signature": left_signature, - "right_signature": right_signature, - }, - ) - - -def check_task_and_grader_coverage() -> ValidationResult: - env = _build_environment() - tasks = env.tasks - grader_checks: list[dict[str, Any]] = [] - distinct_types = sorted({str(task.task_type) for task in tasks}) - difficulty_buckets: dict[str, Any] = {} - for idx, task in enumerate(tasks): - token = str((task.metadata or {}).get("difficulty", "")).strip().lower() - if token in {"mid", "m"}: - token = "medium" - if token in {"high", "h"}: - token = "hard" - if token not in {"easy", "medium", "hard"}: - if idx < 10: - token = "easy" - elif idx < 20: - token = "medium" - else: - token = "hard" - difficulty_buckets.setdefault(token, task) - - for difficulty in ["easy", "medium", "hard"]: - task = difficulty_buckets.get(difficulty) - if task is None: - continue - correct = compute_answer_reward( - proposed_answer=task.answer, - task=task, - pred_edges=list(task.supporting_edges), - tool_outputs=[], - step_count=1, - model=env.reward_model, - difficulty=difficulty, - ) - wrong = compute_answer_reward( - proposed_answer="unknown", - task=task, - pred_edges=[], - tool_outputs=[], - step_count=1, - model=env.reward_model, - difficulty=difficulty, - ) - grader = dict(task.metadata.get("grader", {})) if isinstance(task.metadata, dict) else {} - grader_checks.append( - { - "difficulty": difficulty, - "task_id": task.task_id, - "task_type": task.task_type, - "support_edges": len(task.supporting_edges), - "has_grader": bool(grader), - "correct_reward": correct.total, - "wrong_reward": wrong.total, - "grader_prefers_correct": correct.total > wrong.total, - } - ) - passed = ( - len(tasks) >= 3 - and len(distinct_types) >= 3 - and len(grader_checks) >= 3 - and all( - row["support_edges"] > 0 and row["grader_prefers_correct"] and row["has_grader"] - for row in grader_checks - ) - ) - return ValidationResult( - name="task_and_grader_coverage", - passed=passed, - details={ - "task_count": len(tasks), - "distinct_task_types": distinct_types, - "grader_checks": grader_checks, - }, - ) - - -def run_validation_suite() -> dict[str, Any]: - results = [ - check_hf_space_readiness(), - check_openenv_spec_compliance(), - check_baseline_reproducibility(), - check_task_and_grader_coverage(), - ] - passed = all(result.passed for result in results) - return { - "passed": passed, - "checks": [asdict(result) for result in results], - } diff --git a/scratch/osint/src/osint_env/viz/__init__.py b/scratch/osint/src/osint_env/viz/__init__.py deleted file mode 100644 index 0c98ce2d59d35418cfb871ff0eb5d9c72a3e19c6..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/viz/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from osint_env.viz.dashboard import export_dashboard - -__all__ = ["export_dashboard"] diff --git a/scratch/osint/src/osint_env/viz/dashboard.py b/scratch/osint/src/osint_env/viz/dashboard.py deleted file mode 100644 index 3e033381d99306acdbc7a2a2cb12e7574135b1c5..0000000000000000000000000000000000000000 --- a/scratch/osint/src/osint_env/viz/dashboard.py +++ /dev/null @@ -1,801 +0,0 @@ -from __future__ import annotations - -import json -from pathlib import Path -from typing import Any - -from osint_env.data.generator import PlatformViews -from osint_env.domain.models import CanonicalGraph, Edge, TaskInstance -from osint_env.env.environment import OSINTEnvironment - - -def _safe_label(value: str, fallback: str) -> str: - text = str(value).strip() - return text if text else fallback - - -def _canonical_graph_payload(graph: CanonicalGraph) -> dict[str, Any]: - nodes = [] - for node in graph.nodes.values(): - attrs = node.attrs or {} - title = "\\n".join(f"{k}: {v}" for k, v in attrs.items()) - label = _safe_label(str(attrs.get("name") or attrs.get("handle") or node.node_id), node.node_id) - nodes.append( - { - "id": node.node_id, - "label": label, - "group": str(node.node_type.value), - "title": title, - "attrs": attrs, - } - ) - - edges = [] - for idx, edge in enumerate(graph.edges): - edges.append( - { - "id": f"c_{idx}", - "from": edge.src, - "to": edge.dst, - "label": edge.rel, - "arrows": "to", - "color": "#1f2937", - "width": 1, - "confidence": float(edge.confidence), - "status": "canonical", - } - ) - return {"nodes": nodes, "edges": edges} - - -def _edge_key(edge: Edge) -> tuple[str, str, str]: - return (edge.src, edge.rel, edge.dst) - - -def _episode_graph_payload(pred_edges: list[Edge], truth_edges: list[Edge], graph: CanonicalGraph) -> dict[str, Any]: - pred = {_edge_key(e): e for e in pred_edges} - truth = {_edge_key(e): e for e in truth_edges} - - all_nodes = set() - all_keys = set(pred) | set(truth) - for src, _, dst in all_keys: - all_nodes.add(src) - all_nodes.add(dst) - - nodes = [] - for node_id in sorted(all_nodes): - node = graph.nodes.get(node_id) - if node is None: - nodes.append({"id": node_id, "label": node_id, "group": "episode", "attrs": {}}) - continue - attrs = node.attrs or {} - label = _safe_label(str(attrs.get("name") or attrs.get("handle") or node_id), node_id) - nodes.append({"id": node_id, "label": label, "group": str(node.node_type.value), "attrs": attrs}) - - edges = [] - for idx, key in enumerate(sorted(all_keys)): - src, rel, dst = key - in_pred = key in pred - in_truth = key in truth - if in_pred and in_truth: - color = "#16a34a" - dashes = False - status = "matched" - elif in_pred: - color = "#2563eb" - dashes = False - status = "pred_only" - else: - color = "#f59e0b" - dashes = True - status = "truth_only" - edges.append( - { - "id": f"e_{idx}", - "from": src, - "to": dst, - "label": rel, - "arrows": "to", - "color": color, - "dashes": dashes, - "width": 2, - "status": status, - "confidence": float((pred.get(key) or truth.get(key) or Edge(src, rel, dst)).confidence), - } - ) - - return {"nodes": nodes, "edges": edges} - - -def _views_payload(views: PlatformViews) -> dict[str, Any]: - return { - "microblog_posts": views.microblog_posts, - "forum_threads": views.forum_threads, - "profiles": views.profiles, - } - - -def _leaderboard_payload(records: list[dict[str, Any]]) -> list[dict[str, Any]]: - ranked = sorted(records, key=lambda r: float(r.get("metrics", {}).get("leaderboard_score", 0.0)), reverse=True) - return ranked[:200] - - -def export_dashboard( - env: OSINTEnvironment, - evaluation: dict[str, Any], - leaderboard_records: list[dict[str, Any]], - output_path: str, -) -> str: - summary = evaluation.get("summary", evaluation) - episodes = evaluation.get("episodes", []) - - task: TaskInstance | None = env.state.task if env.state else None - truth_edges = task.supporting_edges if task else [] - pred_edges = env.memory_graph.edges if env.state else [] - - episode_graphs: list[dict[str, Any]] = [] - for episode in episodes: - pred_from_eval = [Edge(str(e.get("src", "")), str(e.get("rel", "")), str(e.get("dst", "")), float(e.get("confidence", 1.0))) for e in episode.get("pred_edges", []) if isinstance(e, dict)] - truth_from_eval = [Edge(str(e.get("src", "")), str(e.get("rel", "")), str(e.get("dst", "")), float(e.get("confidence", 1.0))) for e in episode.get("truth_edges", []) if isinstance(e, dict)] - if pred_from_eval or truth_from_eval: - episode_graphs.append(_episode_graph_payload(pred_from_eval, truth_from_eval, env.graph)) - - if not episode_graphs: - episode_graphs.append(_episode_graph_payload(pred_edges, truth_edges, env.graph)) - - payload = { - "summary": summary, - "episodes": episodes, - "leaderboard": _leaderboard_payload(leaderboard_records), - "canonical_graph": _canonical_graph_payload(env.graph), - "episode_graphs": episode_graphs, - "episode_graph": episode_graphs[-1], - "views": _views_payload(env.views), - "task": { - "task_id": task.task_id if task else "n/a", - "task_type": task.task_type if task else "n/a", - "question": task.question if task else "n/a", - "answer": task.answer if task else "n/a", - }, - } - - html = f""" - - - - - OSINT Environment Dashboard - - - - - - - - - -
    -
    -
    -

    OSINT Benchmark Dashboard

    -

    Interactive explorer for canonical knowledge graph, episode traces, source platform records, and benchmark ranking.

    -
    -
    -
    -
    -

    Episode Explorer

    -
    - - -
    -
    - - -
    -
    Task ID:
    -
    Task Type:
    -
    Question
    -
    -
    Ground Truth Answer:
    -
    Agent Answer:
    -
    Correct:
    -
    -
    - -
    -
    -
    -

    Graph Controls

    -
    - - - - - - - -
    -
    -
    -

    Node Types

    -
    -
    -
    - -
    -

    Graph Explorer

    -
    -
    Layer: Canonical Graph
    -
    -
    -
    - matched edge - predicted only - truth only -
    -
    - -
    -
    -

    Node Inspector

    -
    Click a node to inspect attributes and neighbors.
    -
    -
    -

    Edge Inspector

    -
    Click an edge to inspect relation details.
    -
    -
    -
    - -
    -
    -

    Original Database Explorer

    -
    -
    - - -
    -
    -
    - -
    -

    Selected Source Record

    -
    Click a row in the database table to inspect full JSON.
    -
    -
    - -
    -
    -

    Benchmark Summary Radar

    -
    -
    -
    -

    Episode Reward and Graph F1

    -
    -
    -
    - -
    -

    Benchmark Leaderboard

    -
    - - -
    -
    -
    -
    - - - - -""" - - out = Path(output_path) - out.parent.mkdir(parents=True, exist_ok=True) - out.write_text(html, encoding="utf-8") - return str(out) diff --git a/scratch/osint/tests/conftest.py b/scratch/osint/tests/conftest.py deleted file mode 100644 index c4b4171d9ef25fa2362b246ff84caed0e31ff8fb..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/conftest.py +++ /dev/null @@ -1,12 +0,0 @@ -from __future__ import annotations - -import sys -from pathlib import Path - - -ROOT = Path(__file__).resolve().parents[1] -SRC = ROOT / "src" - -if str(SRC) not in sys.path: - sys.path.insert(0, str(SRC)) - diff --git a/scratch/osint/tests/test_config.py b/scratch/osint/tests/test_config.py deleted file mode 100644 index 4a75364f08c5a78948e12b6b88e22741f2897210..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_config.py +++ /dev/null @@ -1,73 +0,0 @@ -import json -from pathlib import Path - -from osint_env.config.shared import load_seeding_config, load_shared_config - - -def test_shared_config_defaults_when_file_missing(): - config = load_shared_config("/tmp/does_not_exist_for_osint_config.json") - assert config.environment.max_steps > 0 - assert config.runtime.default_episodes > 0 - - -def test_shared_config_parses_swarm_and_seeding(tmp_path: Path): - path = tmp_path / "shared.json" - path.write_text( - json.dumps( - { - "environment": {"seed": 19, "max_steps": 9}, - "swarm": {"enabled": True, "max_agents": 3, "max_breadth": 2, "max_width": 2, "max_depth": 2}, - "seeding": { - "seeded_questions": [ - { - "question": "Which canonical user owns alias alias_seed_001?", - "answer": "user_seed_001", - } - ], - "llm_generation_parallel": True, - "llm_generation_workers": 4, - "llm_generation_retries": 3, - "allow_template_fallback_on_llm_failure": False - }, - "runtime": {"default_episodes": 5}, - "llm": {"provider": "ollama", "model": "qwen3:2b", "timeout_seconds": 333}, - } - ), - encoding="utf-8", - ) - - config = load_shared_config(path) - assert config.environment.seed == 19 - assert config.environment.swarm.enabled is True - assert config.environment.swarm.max_width == 2 - assert len(config.environment.seeding.seeded_questions) == 1 - assert config.runtime.default_episodes == 5 - assert config.environment.llm.provider == "ollama" - assert config.environment.llm.model == "qwen3:2b" - assert config.environment.llm.timeout_seconds == 333 - assert config.environment.seeding.llm_generation_parallel is True - assert config.environment.seeding.llm_generation_workers == 4 - assert config.environment.seeding.llm_generation_retries == 3 - assert config.environment.seeding.allow_template_fallback_on_llm_failure is False - - -def test_load_seeding_config_supports_top_level_object(tmp_path: Path): - path = tmp_path / "seeding.json" - path.write_text( - json.dumps( - { - "seeded_nodes": [ - {"node_id": "alias_seed_1", "node_type": "alias", "attrs": {"handle": "@seed"}}, - {"node_id": "user_seed_1", "node_type": "user", "attrs": {"name": "Seed"}}, - ], - "seeded_edges": [{"src": "alias_seed_1", "rel": "alias_of", "dst": "user_seed_1"}], - "seeded_questions": [{"question": "Which canonical user owns alias alias_seed_1?", "answer": "user_seed_1"}], - } - ), - encoding="utf-8", - ) - - seeding = load_seeding_config(path) - assert len(seeding.seeded_nodes) == 2 - assert len(seeding.seeded_edges) == 1 - assert seeding.seeded_questions[0].answer == "user_seed_1" diff --git a/scratch/osint/tests/test_dashboard.py b/scratch/osint/tests/test_dashboard.py deleted file mode 100644 index 8b396dae7e7b600524d9bc4691fb678940820fae..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_dashboard.py +++ /dev/null @@ -1,26 +0,0 @@ -from pathlib import Path - -from osint_env.domain.models import EnvironmentConfig -from osint_env.env.environment import OSINTEnvironment -from osint_env.viz import export_dashboard - - -def test_dashboard_export(tmp_path: Path): - env = OSINTEnvironment(EnvironmentConfig(seed=9, n_users=14)) - env.reset() - - out = tmp_path / "dashboard.html" - path = export_dashboard( - env=env, - evaluation={"summary": {"leaderboard_score": 0.0, "task_success_rate": 0.0, "avg_graph_f1": 0.0, "tool_efficiency": 0.0, "deanonymization_accuracy": 0.0, "avg_reward": 0.0}, "episodes": []}, - leaderboard_records=[], - output_path=str(out), - ) - - assert path.endswith("dashboard.html") - text = out.read_text(encoding="utf-8") - assert "OSINT Benchmark Dashboard" in text - assert "Canonical Graph" in text - assert "Original Database Explorer" in text - assert "Benchmark Leaderboard" in text - assert "Episode Explorer" in text diff --git a/scratch/osint/tests/test_environment.py b/scratch/osint/tests/test_environment.py deleted file mode 100644 index 1a36bd9e6c0404640691a90868f6152abcb13a7d..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_environment.py +++ /dev/null @@ -1,39 +0,0 @@ -from osint_env.domain.models import Action, ActionType, EnvironmentConfig -from osint_env.env.environment import OSINTEnvironment - - -def test_episode_flow(): - env = OSINTEnvironment(EnvironmentConfig(max_steps=5, seed=5)) - obs = env.reset() - assert "question" in obs.task - assert isinstance(obs.task.get("grader"), dict) - assert "type" in obs.task["grader"] - obs, r1, done, _ = env.step(Action(ActionType.CALL_TOOL, {"tool_name": "search_posts", "args": {"query": "Update"}})) - assert done is False - assert isinstance(r1, float) - _, r2, done, info = env.step(Action(ActionType.ANSWER, {"answer": "unknown"})) - assert done is True - assert "total_reward" in info - assert isinstance(r2, float) - - -def test_search_memory_tool_returns_results_after_tool_use(): - env = OSINTEnvironment(EnvironmentConfig(max_steps=6, seed=5)) - env.reset() - env.step(Action(ActionType.CALL_TOOL, {"tool_name": "search_posts", "args": {"query": "Update"}})) - obs, reward, done, _ = env.step( - Action(ActionType.CALL_TOOL, {"tool_name": "search_memory", "args": {"query": "Update", "k": 3}}) - ) - assert done is False - assert isinstance(reward, float) - assert obs.tool_outputs[-1]["tool"] == "search_memory" - assert obs.tool_outputs[-1]["output"]["count"] >= 1 - - -def test_invalid_tool_call_does_not_crash_episode(): - env = OSINTEnvironment(EnvironmentConfig(max_steps=4, seed=8)) - env.reset() - _, reward, done, info = env.step(Action(ActionType.CALL_TOOL, {"tool_name": "no_such_tool", "args": {}})) - assert done is False - assert reward < 0 - assert "invalid_tool_penalty" in info["reward_components"] diff --git a/scratch/osint/tests/test_eval.py b/scratch/osint/tests/test_eval.py deleted file mode 100644 index ad29cfb3eb9f633214a478667fa9dbbb9bb1d036..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_eval.py +++ /dev/null @@ -1,33 +0,0 @@ -from osint_env.domain.models import EnvironmentConfig, SwarmConfig -from osint_env.env.environment import OSINTEnvironment -from osint_env.eval.runner import run_evaluation - - -def test_eval_runner(): - env = OSINTEnvironment(EnvironmentConfig(seed=17)) - result = run_evaluation(env, episodes=3) - assert "task_success_rate" in result - assert "deanonymization_accuracy" in result - assert "leaderboard_score" in result - assert "avg_knowledge_indexing_reward" in result - - -def test_eval_runner_swarm_mode(): - env = OSINTEnvironment( - EnvironmentConfig(seed=17, swarm=SwarmConfig(enabled=True, max_agents=3, max_breadth=2, max_width=2, max_depth=2)) - ) - result = run_evaluation(env, episodes=2) - assert "spawn_signal" in result - assert "avg_spawn_count" in result - - -def test_eval_runner_details_include_episode_answers(): - env = OSINTEnvironment(EnvironmentConfig(seed=17)) - result = run_evaluation(env, episodes=2, return_details=True) - assert "episodes" in result - assert len(result["episodes"]) == 2 - - row = result["episodes"][0] - assert "question" in row - assert "task_answer" in row - assert "agent_answer" in row diff --git a/scratch/osint/tests/test_fixed_levels_dataset.py b/scratch/osint/tests/test_fixed_levels_dataset.py deleted file mode 100644 index 50e834694b01613c20a9c176f4b41b02dc7d99fb..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_fixed_levels_dataset.py +++ /dev/null @@ -1,18 +0,0 @@ -import json -from collections import Counter -from pathlib import Path - - -def test_fixed_levels_seed_has_30_questions_and_target_node_spans(): - path = Path("datasets/fixed_levels/seed_fixed_levels.json") - payload = json.loads(path.read_text(encoding="utf-8")) - questions = payload["seeding"]["seeded_questions"] - - counts = Counter(q["metadata"]["difficulty"] for q in questions) - assert counts == {"easy": 10, "mid": 10, "high": 10} - - mid_support_nodes = [int(q["metadata"]["support_nodes"]) for q in questions if q["metadata"]["difficulty"] == "mid"] - high_support_nodes = [int(q["metadata"]["support_nodes"]) for q in questions if q["metadata"]["difficulty"] == "high"] - - assert all(15 <= value <= 20 for value in mid_support_nodes) - assert all(48 <= value <= 55 for value in high_support_nodes) diff --git a/scratch/osint/tests/test_generator.py b/scratch/osint/tests/test_generator.py deleted file mode 100644 index c03de0642a68894d9a68e3d88b768303bf5d50e3..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_generator.py +++ /dev/null @@ -1,134 +0,0 @@ -import json -import re -from threading import Lock - -from osint_env.data.generator import DatasetGenerator -from osint_env.domain.models import EnvironmentConfig -from osint_env.llm.interface import LLMResponse - - -class SharedContextLLM: - def __init__(self): - self.prompts: list[str] = [] - self._lock = Lock() - - def generate(self, messages, tools): - prompt = str(messages[0].get("content", "")) if messages else "" - with self._lock: - self.prompts.append(prompt) - - if "SEED_GRAPH_EXPANSION_AGENT" in prompt: - worker_match = re.search(r"worker_id:\s*(\d+)", prompt) - worker_idx = int(worker_match.group(1)) if worker_match else 0 - payload = { - "edges": [ - { - "src": "user_0", - "rel": f"llm_rel_{worker_idx}", - "dst": "user_1", - "confidence": 0.9, - } - ] - } - return LLMResponse(content=json.dumps(payload), tool_calls=[]) - - if "SEED_TASK_EXPANSION_AGENT" in prompt: - worker_match = re.search(r"worker_id:\s*(\d+)", prompt) - worker_idx = int(worker_match.group(1)) if worker_match else 0 - budget_match = re.search(r"task_budget:\s*(\d+)", prompt) - task_budget = int(budget_match.group(1)) if budget_match else 1 - tasks = [] - for local_idx in range(max(1, task_budget)): - tasks.append( - { - "task_type": "identity_resolution", - "question": f"Which canonical user is tied to alias alias_seed_{worker_idx}_{local_idx}?", - "answer": "user_1", - "supporting_edges": [ - { - "src": "alias_seed_0", - "rel": "alias_of", - "dst": "user_1", - "confidence": 0.95, - } - ], - } - ) - payload = {"tasks": tasks} - return LLMResponse(content=json.dumps(payload), tool_calls=[]) - - return LLMResponse(content="{}", tool_calls=[]) - - -def test_generator_outputs(): - gen = DatasetGenerator(EnvironmentConfig(n_users=20, seed=11)) - graph = gen.build_canonical_graph() - views = gen.build_platform_views(graph) - tasks = gen.generate_tasks(graph, views, count=5) - assert len(graph.nodes) >= 20 - assert len(views.microblog_posts) >= 20 - assert len(tasks) == 5 - - -def test_seeded_views_include_seeded_posts_and_threads(): - from osint_env.config import clone_environment_config, load_seeding_config, load_shared_config - - shared = load_shared_config("datasets/fixed_levels/shared_config_fixed_levels.json") - cfg = clone_environment_config(shared.environment) - cfg.seeding = load_seeding_config("datasets/fixed_levels/seed_fixed_levels.json") - cfg.llm.provider = "mock" - - gen = DatasetGenerator(cfg) - graph = gen.build_canonical_graph() - views = gen.build_platform_views(graph) - - seeded_post = next((post for post in views.microblog_posts if post["post_id"] == "post_midnight_manifest"), None) - seeded_thread = next((thread for thread in views.forum_threads if thread["thread_id"] == "thr_supply_leak"), None) - - assert seeded_post is not None - assert "loc_dockyard17" in seeded_post["references"] - assert seeded_thread is not None - assert "org_northbridge_logistics" in seeded_thread["references"] - - -def test_graph_generation_uses_parallel_shared_context_workers(): - cfg = EnvironmentConfig(n_users=12, seed=9) - cfg.seeding.llm_generate_remaining_graph = True - cfg.seeding.llm_generated_edge_budget = 4 - cfg.seeding.llm_generate_remaining_tasks = False - cfg.seeding.llm_generation_parallel = True - cfg.seeding.llm_generation_workers = 3 - cfg.seeding.llm_generation_retries = 1 - cfg.seeding.allow_template_fallback_on_llm_failure = False - - llm = SharedContextLLM() - gen = DatasetGenerator(cfg, llm=llm) - graph = gen.build_canonical_graph() - - assert any(edge.rel.startswith("llm_rel_") for edge in graph.edges) - graph_prompts = [prompt for prompt in llm.prompts if "SEED_GRAPH_EXPANSION_AGENT" in prompt] - assert len(graph_prompts) >= 2 - assert all("SHARED_CONTEXT" in prompt for prompt in graph_prompts) - - -def test_task_generation_uses_parallel_shared_context_workers(): - cfg = EnvironmentConfig(n_users=12, seed=13) - cfg.seeding.llm_generate_remaining_graph = False - cfg.seeding.llm_generate_remaining_tasks = True - cfg.seeding.llm_generated_task_budget = 4 - cfg.seeding.llm_generation_parallel = True - cfg.seeding.llm_generation_workers = 3 - cfg.seeding.llm_generation_retries = 1 - cfg.seeding.allow_template_fallback_on_llm_failure = False - - llm = SharedContextLLM() - gen = DatasetGenerator(cfg, llm=llm) - graph = gen.build_canonical_graph() - views = gen.build_platform_views(graph) - tasks = gen.generate_tasks(graph, views, count=4) - - assert len(tasks) == 4 - assert any(task.metadata.get("shared_context") for task in tasks) - task_prompts = [prompt for prompt in llm.prompts if "SEED_TASK_EXPANSION_AGENT" in prompt] - assert len(task_prompts) >= 2 - assert all("SHARED_CONTEXT" in prompt for prompt in task_prompts) diff --git a/scratch/osint/tests/test_inference.py b/scratch/osint/tests/test_inference.py deleted file mode 100644 index bff41e6896e9920687bf753713a6f53f9d0b631e..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_inference.py +++ /dev/null @@ -1,37 +0,0 @@ -from inference import _format_action, _looks_like_placeholder_api_key, _tool_result_message - - -def test_placeholder_api_key_detection(): - assert _looks_like_placeholder_api_key("your_openai_api_key") is True - assert _looks_like_placeholder_api_key("sk-your-real-openai-key") is True - assert _looks_like_placeholder_api_key("replace-me") is True - assert _looks_like_placeholder_api_key("sk-proj-realistic-looking-token") is False - - -def test_tool_result_message_reuses_assistant_tool_call_id(): - assistant_message = { - "role": "assistant", - "content": "", - "tool_calls": [ - { - "id": "call_123", - "type": "function", - "function": {"name": "get_post", "arguments": "{\"post_id\":\"post_midnight_manifest\"}"}, - } - ], - } - result = {"reward": 0.1, "done": False} - tool_message = _tool_result_message(assistant_message, result) - assert tool_message is not None - assert tool_message["tool_call_id"] == "call_123" - assert tool_message["role"] == "tool" - - -def test_action_formatter_matches_single_line_style(): - assert _format_action({"action_type": "ANSWER", "payload": {"answer": "user_bharat"}}) == "answer(user_bharat)" - assert _format_action( - { - "action_type": "CALL_TOOL", - "payload": {"tool_name": "get_post", "args": {"post_id": "post_midnight_manifest"}}, - } - ) == "get_post(post_id=post_midnight_manifest)" diff --git a/scratch/osint/tests/test_leaderboard.py b/scratch/osint/tests/test_leaderboard.py deleted file mode 100644 index 7752b8646cc1785e505fd6422373a7e30fb26449..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_leaderboard.py +++ /dev/null @@ -1,47 +0,0 @@ -from pathlib import Path - -from osint_env.eval.leaderboard import append_leaderboard_record, load_leaderboard, render_leaderboard_table, sorted_leaderboard - - -def test_leaderboard_roundtrip(tmp_path: Path): - board = tmp_path / "leaderboard.json" - append_leaderboard_record( - path=board, - summary={ - "leaderboard_score": 0.42, - "task_success_rate": 0.5, - "avg_graph_f1": 0.4, - "avg_reward": 0.1, - "tool_efficiency": 0.9, - "retrieval_signal": 0.3, - "structural_signal": 0.4, - }, - episodes=5, - run_name="baseline", - ) - append_leaderboard_record( - path=board, - summary={ - "leaderboard_score": 0.75, - "task_success_rate": 0.7, - "avg_graph_f1": 0.6, - "avg_reward": 0.5, - "tool_efficiency": 0.8, - "retrieval_signal": 0.6, - "structural_signal": 0.7, - }, - episodes=5, - run_name="improved", - ) - - records = load_leaderboard(board) - ranked = sorted_leaderboard(records) - assert len(records) == 2 - assert ranked[0]["run_name"] == "improved" - - ranked_by_success = sorted_leaderboard(records, sort_by="task_success_rate") - assert ranked_by_success[0]["run_name"] == "improved" - - table = render_leaderboard_table(records, top_k=5) - assert "| rank | run |" in table - assert "retrieval" in table diff --git a/scratch/osint/tests/test_llm_interface.py b/scratch/osint/tests/test_llm_interface.py deleted file mode 100644 index c615c5bddac5e7217996bb6632e0a88baa018f57..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_llm_interface.py +++ /dev/null @@ -1,44 +0,0 @@ -import os - -import pytest -import requests - -from osint_env.domain.models import LLMConfig -from osint_env.llm.interface import OllamaLLMClient, RuleBasedMockLLM, build_llm_client - - -def test_build_llm_client_mock_default(): - client = build_llm_client(LLMConfig(provider="mock")) - assert isinstance(client, RuleBasedMockLLM) - - -def test_build_llm_client_openai_requires_key(monkeypatch: pytest.MonkeyPatch): - monkeypatch.delenv("OPENAI_API_KEY", raising=False) - with pytest.raises(ValueError): - build_llm_client(LLMConfig(provider="openai", openai_api_key="", openai_api_key_env="OPENAI_API_KEY")) - - -def test_build_llm_client_openai_with_key(monkeypatch: pytest.MonkeyPatch): - monkeypatch.setenv("OPENAI_API_KEY", "test-key") - cfg = LLMConfig(provider="openai", model="gpt-4o-mini", openai_api_key_env="OPENAI_API_KEY") - # Constructing should not fail when a key is present; actual API call is not made in this test. - client = build_llm_client(cfg) - assert client is not None - - -def test_openai_key_can_come_from_config_value(monkeypatch: pytest.MonkeyPatch): - monkeypatch.delenv("OPENAI_API_KEY", raising=False) - cfg = LLMConfig(provider="openai", model="gpt-4o-mini", openai_api_key="cfg-key") - client = build_llm_client(cfg) - assert client is not None - - -def test_ollama_client_gracefully_handles_request_failure(monkeypatch: pytest.MonkeyPatch): - def _raise(*args, **kwargs): - raise requests.exceptions.ReadTimeout("timed out") - - monkeypatch.setattr("osint_env.llm.interface.requests.post", _raise) - client = OllamaLLMClient(model="qwen3:2b", timeout_seconds=1) - response = client.generate([{"role": "system", "content": "ping"}], tools=[]) - assert response.content == "" - assert response.tool_calls == [] diff --git a/scratch/osint/tests/test_openai_baseline.py b/scratch/osint/tests/test_openai_baseline.py deleted file mode 100644 index d11342d26c88ea41b0119a261c0f8b5d4a946cde..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_openai_baseline.py +++ /dev/null @@ -1,30 +0,0 @@ -from osint_env.baselines.openai_runner import OpenAIBaselineConfig, OpenAIBaselineRunner, build_action_tools - - -def test_openai_baseline_toolset_contains_answer_and_graph_actions(): - tools = build_action_tools() - names = {tool["function"]["name"] for tool in tools} - assert "submit_answer" in names - assert "add_edge" in names - assert "search_memory" in names - assert "get_post" in names - - -def test_gpt5_request_kwargs_avoid_temperature_and_use_max_completion_tokens(): - runner = OpenAIBaselineRunner.__new__(OpenAIBaselineRunner) - runner.config = OpenAIBaselineConfig(model="gpt-5-nano", max_tokens=321, temperature=0.0, seed=7) - runner.tools = build_action_tools() - kwargs = runner._request_kwargs(messages=[{"role": "user", "content": "hi"}], episode_index=0) - assert kwargs["max_completion_tokens"] == 321 - assert kwargs["reasoning_effort"] == "none" - assert "temperature" not in kwargs - - -def test_gpt54_mini_request_kwargs_skip_reasoning_effort_for_chat_completions(): - runner = OpenAIBaselineRunner.__new__(OpenAIBaselineRunner) - runner.config = OpenAIBaselineConfig(model="gpt-5.4-mini", max_tokens=321, temperature=0.0, seed=7) - runner.tools = build_action_tools() - kwargs = runner._request_kwargs(messages=[{"role": "user", "content": "hi"}], episode_index=0) - assert kwargs["max_completion_tokens"] == 321 - assert "reasoning_effort" not in kwargs - assert "temperature" not in kwargs diff --git a/scratch/osint/tests/test_reward.py b/scratch/osint/tests/test_reward.py deleted file mode 100644 index 03bb251136dd7eb850a07d97fbc96fb82b11f981..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_reward.py +++ /dev/null @@ -1,53 +0,0 @@ -from osint_env.domain.models import Edge, EnvironmentConfig -from osint_env.env.environment import OSINTEnvironment -from osint_env.env.reward import build_reward_model, compute_answer_reward, compute_edge_reward - - -def test_composite_edge_reward_returns_breakdown(): - env = OSINTEnvironment(EnvironmentConfig(seed=13, n_users=16, max_steps=6)) - obs = env.reset() - task = env.state.task - - model = build_reward_model(env.graph) - edge = task.supporting_edges[0] - breakdown = compute_edge_reward( - edge=edge, - task=task, - existing_edges=[], - step_count=1, - model=model, - graph=env.graph, - ) - assert isinstance(breakdown.total, float) - assert breakdown.global_accuracy > 0 - assert isinstance(breakdown.connectivity_gain, float) - - -def test_answer_reward_uses_graph_and_tool_context(): - env = OSINTEnvironment(EnvironmentConfig(seed=21, n_users=18, max_steps=6)) - env.reset() - task = env.state.task - - pred_edges = [Edge(task.supporting_edges[0].src, task.supporting_edges[0].rel, task.supporting_edges[0].dst)] - tool_outputs = [{"tool": "get_profile", "output": {"result": {"user_id": task.answer}}}] - - good = compute_answer_reward( - proposed_answer=task.answer, - task=task, - pred_edges=pred_edges, - tool_outputs=tool_outputs, - step_count=2, - ) - bad = compute_answer_reward( - proposed_answer="wrong", - task=task, - pred_edges=[], - tool_outputs=[], - step_count=2, - ) - - assert good.total > bad.total - assert good.graph_f1 >= 0 - assert isinstance(good.relation_informativeness, float) - assert isinstance(good.entity_informativeness, float) - assert isinstance(good.repetition_penalty, float) diff --git a/scratch/osint/tests/test_seeding.py b/scratch/osint/tests/test_seeding.py deleted file mode 100644 index 7381a3e2ad12bf469693ae39ef75558e8a6ec08c..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_seeding.py +++ /dev/null @@ -1,40 +0,0 @@ -from osint_env.domain.models import ( - EnvironmentConfig, - NodeType, - SeedEdgeSpec, - SeedNodeSpec, - SeedQuestionSpec, - SeedingConfig, -) -from osint_env.env.environment import OSINTEnvironment - - -def test_environment_includes_seeded_graph_and_questions(): - seeding = SeedingConfig( - seeded_nodes=[ - SeedNodeSpec(node_id="alias_seed_001", node_type=NodeType.ALIAS, attrs={"handle": "@seed001"}), - SeedNodeSpec( - node_id="user_seed_001", - node_type=NodeType.USER, - attrs={"name": "Seed User", "org": "Helios Labs", "location": "Pune"}, - ), - ], - seeded_edges=[SeedEdgeSpec(src="alias_seed_001", rel="alias_of", dst="user_seed_001")], - seeded_questions=[ - SeedQuestionSpec( - question="Which canonical user owns alias alias_seed_001?", - answer="user_seed_001", - task_type="identity_resolution", - supporting_edges=[SeedEdgeSpec(src="alias_seed_001", rel="alias_of", dst="user_seed_001")], - ) - ], - llm_generate_remaining_graph=False, - llm_generate_remaining_tasks=False, - llm_generated_edge_budget=0, - llm_generated_task_budget=0, - ) - env = OSINTEnvironment(EnvironmentConfig(seed=33, n_users=12, seeding=seeding)) - - assert "alias_seed_001" in env.graph.nodes - assert any(edge.src == "alias_seed_001" and edge.rel == "alias_of" and edge.dst == "user_seed_001" for edge in env.graph.edges) - assert any("alias_seed_001" in task.question for task in env.tasks) diff --git a/scratch/osint/tests/test_server.py b/scratch/osint/tests/test_server.py deleted file mode 100644 index 6e3db4bda127b897b20c85ea9f69217b0ab15654..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_server.py +++ /dev/null @@ -1,235 +0,0 @@ -import json -import os - -from fastapi.testclient import TestClient - -import server -from server import app - - -client = TestClient(app) - - -def test_server_health(): - response = client.get("/healthz") - assert response.status_code == 200 - assert response.json()["status"] == "ok" - - -def test_server_health_alias(): - response = client.get("/health") - assert response.status_code == 200 - assert response.json()["status"] == "ok" - - -def test_server_environment_metadata(): - response = client.get("/api/environment") - assert response.status_code == 200 - body = response.json() - assert "action_space" in body - assert "observation_space" in body - assert "summary" in body - - -def test_openenv_spec_and_tasks_endpoints(): - spec = client.get("/openenv.yaml") - assert spec.status_code == 200 - assert "reset" in spec.text - - tasks = client.get("/openenv/tasks") - assert tasks.status_code == 200 - body = tasks.json() - assert len(body) >= 3 - assert {"task_id", "task_type", "question", "difficulty"} <= set(body[0].keys()) - - -def test_openenv_reset_step_and_state_cycle(): - reset = client.post("/openenv/reset", json={"task_index": 0}) - assert reset.status_code == 200 - body = reset.json() - session_id = body["session_id"] - assert body["done"] is False - assert "question" in body["observation"]["task"] - - state = client.get(f"/openenv/state/{session_id}") - assert state.status_code == 200 - assert state.json()["session_id"] == session_id - - step = client.post( - "/openenv/step", - json={ - "session_id": session_id, - "action_type": "ANSWER", - "payload": {"answer": "unknown"}, - }, - ) - assert step.status_code == 200 - step_body = step.json() - assert step_body["session_id"] == session_id - assert step_body["done"] is True - assert "task_answer" in step_body["info"] - - -def test_openenv_reset_accepts_empty_body(): - reset = client.post("/openenv/reset") - assert reset.status_code == 200 - body = reset.json() - assert body["done"] is False - assert "session_id" in body - - -def test_openenv_reset_accepts_empty_json_body(): - reset = client.post( - "/openenv/reset", - data="", - headers={"Content-Type": "application/json"}, - ) - assert reset.status_code == 200 - body = reset.json() - assert body["done"] is False - assert "session_id" in body - - -def test_openenv_reset_trailing_slash_post_returns_json(): - reset = client.post( - "/openenv/reset/", - data="", - headers={"Content-Type": "application/json"}, - ) - assert reset.status_code == 200 - body = reset.json() - assert body["done"] is False - assert "session_id" in body - - -def test_openenv_step_accepts_nested_action_payload(): - reset = client.post("/openenv/reset", json={"task_index": 0}) - assert reset.status_code == 200 - session_id = reset.json()["session_id"] - - step = client.post( - "/openenv/step", - json={ - "session_id": session_id, - "action": { - "action_type": "ANSWER", - "payload": {"answer": "unknown"}, - }, - }, - ) - assert step.status_code == 200 - assert step.json()["done"] is True - - -def test_step_alias_uses_latest_session_when_session_id_missing(): - reset = client.post("/reset", json={"task_index": 0}) - assert reset.status_code == 200 - session_id = reset.json()["session_id"] - - step = client.post( - "/step", - json={ - "action_type": "ANSWER", - "payload": {"answer": "unknown"}, - }, - ) - assert step.status_code == 200 - body = step.json() - assert body["session_id"] == session_id - assert body["done"] is True - - -def test_state_alias_returns_latest_session(): - reset = client.post("/reset", json={"task_index": 0}) - assert reset.status_code == 200 - session_id = reset.json()["session_id"] - - state = client.get("/state") - assert state.status_code == 200 - body = state.json() - assert body["session_id"] == session_id - assert "task" in body["observation"] - - -def test_report_inference_updates_latest_evaluation_and_dashboard(tmp_path, monkeypatch): - latest_evaluation = tmp_path / "latest_evaluation.json" - space_dashboard = tmp_path / "space_dashboard.html" - - monkeypatch.setattr(server, "LATEST_EVALUATION_OUTPUT", latest_evaluation) - monkeypatch.setattr(server, "SPACE_DASHBOARD", space_dashboard) - monkeypatch.setattr(server, "load_leaderboard", lambda path: []) - monkeypatch.setattr(server, "export_dashboard", lambda env, evaluation, leaderboard_records, output_path: str(space_dashboard)) - - response = client.post( - "/openenv/report_inference", - json={ - "run": {"name": "inference_py_run"}, - "summary": {"leaderboard_score": 0.75, "task_success_rate": 1.0}, - "episodes": [ - { - "task_id": "seed_task_0", - "agent_answer": "user_bharat", - "graph_f1": 0.5, - "reward": 1.2, - "steps": 5, - "tool_calls": 4, - "success": 1, - } - ], - }, - ) - assert response.status_code == 200 - body = response.json() - assert body["status"] == "ok" - assert latest_evaluation.exists() - stored = json.loads(latest_evaluation.read_text(encoding="utf-8")) - assert stored["summary"]["leaderboard_score"] == 0.75 - assert stored["episodes"][0]["task_id"] == "seed_task_0" - assert stored["episodes"][0]["truth_edges"] - - -def test_space_snapshot_prefers_newer_evaluation_payload(tmp_path, monkeypatch): - baseline_path = tmp_path / "baseline.json" - evaluation_path = tmp_path / "evaluation.json" - baseline_dashboard = tmp_path / "baseline_dashboard.html" - space_dashboard = tmp_path / "space_dashboard.html" - - baseline_path.write_text( - json.dumps( - { - "run": {"dashboard_path": str(baseline_dashboard)}, - "summary": {"leaderboard_score": 0.1, "task_success_rate": 0.1}, - } - ), - encoding="utf-8", - ) - baseline_dashboard.write_text("baseline", encoding="utf-8") - evaluation_path.write_text( - json.dumps({"summary": {"leaderboard_score": 0.9, "task_success_rate": 0.9}, "episodes": []}), - encoding="utf-8", - ) - space_dashboard.write_text("space", encoding="utf-8") - os.utime(evaluation_path, (baseline_path.stat().st_atime + 5, baseline_path.stat().st_mtime + 5)) - - monkeypatch.setattr(server, "LATEST_BASELINE_OUTPUT", baseline_path) - monkeypatch.setattr(server, "LATEST_EVALUATION_OUTPUT", evaluation_path) - monkeypatch.setattr(server, "SPACE_DASHBOARD", space_dashboard) - monkeypatch.setattr( - server, - "_base_environment_snapshot", - lambda: { - "task_count": 30, - "difficulty_counts": {}, - "action_space": ["CALL_TOOL", "ADD_EDGE", "ANSWER"], - "observation_space": {}, - "task_types": [], - "config": {}, - }, - ) - monkeypatch.setattr(server, "_build_environment", lambda: object()) - monkeypatch.setattr(server, "export_dashboard", lambda env, evaluation, leaderboard_records, output_path: str(space_dashboard)) - - snapshot = server._space_snapshot() - assert snapshot["source"] == "latest_evaluation" - assert snapshot["summary"]["leaderboard_score"] == 0.9 - assert snapshot["dashboard_path"] == str(space_dashboard) diff --git a/scratch/osint/tests/test_spawn_reward_hooks.py b/scratch/osint/tests/test_spawn_reward_hooks.py deleted file mode 100644 index 95c5106774ec738fb5b5d365b3ce82e62e592834..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_spawn_reward_hooks.py +++ /dev/null @@ -1,43 +0,0 @@ -from osint_env.env.spawn_reward_hooks import critical_steps, parl_style_spawn_reward - - -def test_critical_steps_matches_parallel_path_length(): - total = critical_steps(main_steps=[1, 1, 1], parallel_subagent_steps=[[3, 2], [0], [4, 1, 2]]) - assert total == 1 + 3 + 1 + 0 + 1 + 4 - - -def test_parl_reward_prefers_finished_parallel_work(): - base = parl_style_spawn_reward( - task_outcome_reward=0.2, - spawn_count=4, - finished_subtasks=1, - critical_steps=12, - lambda_parallel=0.2, - lambda_finish=0.25, - anneal=1.0, - breadth=2, - depth=3, - ) - better = parl_style_spawn_reward( - task_outcome_reward=0.2, - spawn_count=4, - finished_subtasks=4, - critical_steps=8, - lambda_parallel=0.2, - lambda_finish=0.25, - anneal=1.0, - breadth=4, - depth=2, - ) - assert better > base - - -def test_parl_auxiliary_can_be_annealed_out(): - frozen = parl_style_spawn_reward( - task_outcome_reward=0.7, - spawn_count=8, - finished_subtasks=8, - critical_steps=5, - anneal=0.0, - ) - assert frozen == 0.7 diff --git a/scratch/osint/tests/test_swarm_agent.py b/scratch/osint/tests/test_swarm_agent.py deleted file mode 100644 index 712b2fbd3246ca528338f9bfb7e300b24690dc88..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_swarm_agent.py +++ /dev/null @@ -1,17 +0,0 @@ -from osint_env.agents.swarm_agent import SwarmAgentRunner -from osint_env.domain.models import EnvironmentConfig, SwarmConfig -from osint_env.env.environment import OSINTEnvironment - - -def test_swarm_runner_emits_spawn_telemetry(): - config = EnvironmentConfig( - seed=14, - max_steps=8, - swarm=SwarmConfig(enabled=True, max_agents=3, max_breadth=2, max_width=2, max_depth=2, planner_rounds=2), - ) - env = OSINTEnvironment(config) - info = SwarmAgentRunner(env).run_episode() - - assert info["spawn_count"] > 0 - assert "spawn_auxiliary" in info["reward_components"] - assert info["spawn_critical_steps"] > 0 diff --git a/scratch/osint/tests/test_tools.py b/scratch/osint/tests/test_tools.py deleted file mode 100644 index dc5a67f5f17b05b44bca34979cf852fb4a13f217..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_tools.py +++ /dev/null @@ -1,39 +0,0 @@ -from osint_env.config import clone_environment_config, load_seeding_config, load_shared_config -from osint_env.data.generator import DatasetGenerator -from osint_env.domain.models import EnvironmentConfig -from osint_env.env.environment import OSINTEnvironment -from osint_env.platforms.tools import ToolRegistry - - -def test_tools_basics(): - gen = DatasetGenerator(EnvironmentConfig(n_users=12, seed=3)) - g = gen.build_canonical_graph() - views = gen.build_platform_views(g) - tools = ToolRegistry(views) - out = tools.search_posts(query="Update") - assert out["count"] > 0 - profile_any = next(iter([p["user_id"] for p in views.profiles if p["user_id"].startswith("user_")])) - profile = tools.get_profile(profile_any) - assert profile["found"] is True - - -def test_seeded_tools_expose_seed_question_entities(): - shared = load_shared_config("datasets/fixed_levels/shared_config_fixed_levels.json") - env_cfg = clone_environment_config(shared.environment) - env_cfg.seeding = load_seeding_config("datasets/fixed_levels/seed_fixed_levels.json") - env_cfg.llm.provider = "mock" - env = OSINTEnvironment(env_cfg) - tools = env.tools - - post = tools.get_post("post_midnight_manifest") - assert post["found"] is True - assert "loc_dockyard17" in post["result"]["references"] - - people = tools.search_people(org="org_northbridge_logistics") - user_ids = {row["user_id"] for row in people["results"]} - assert "user_bharat" in user_ids - assert "user_hiro" in user_ids - - alias_profile = tools.get_profile("alias_docksparrow") - assert alias_profile["found"] is True - assert alias_profile["result"]["user_id"] == "user_hiro" diff --git a/scratch/osint/tests/test_validation.py b/scratch/osint/tests/test_validation.py deleted file mode 100644 index ce1e398b01983303f221ea96dc9d2a731137265d..0000000000000000000000000000000000000000 --- a/scratch/osint/tests/test_validation.py +++ /dev/null @@ -1,7 +0,0 @@ -from osint_env.validation import run_validation_suite - - -def test_validation_suite_passes_repo_gate(): - result = run_validation_suite() - assert result["passed"] is True - assert len(result["checks"]) >= 4 diff --git a/scratch/osint/uv.lock b/scratch/osint/uv.lock deleted file mode 100644 index e697d8c795db0704eca2b78ccc5867b673f148c7..0000000000000000000000000000000000000000 --- a/scratch/osint/uv.lock +++ /dev/null @@ -1,895 +0,0 @@ -version = 1 -revision = 3 -requires-python = ">=3.10" -resolution-markers = [ - "python_full_version >= '3.11'", - "python_full_version < '3.11'", -] - -[[package]] -name = "annotated-doc" -version = "0.0.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, -] - -[[package]] -name = "annotated-types" -version = "0.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, -] - -[[package]] -name = "anyio" -version = "4.13.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, - { name = "idna" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/19/14/2c5dd9f512b66549ae92767a9c7b330ae88e1932ca57876909410251fe13/anyio-4.13.0.tar.gz", hash = "sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc", size = 231622, upload-time = "2026-03-24T12:59:09.671Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353, upload-time = "2026-03-24T12:59:08.246Z" }, -] - -[[package]] -name = "certifi" -version = "2026.2.25" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5", size = 144271, upload-time = "2026-04-02T09:28:39.342Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/26/08/0f303cb0b529e456bb116f2d50565a482694fbb94340bf56d44677e7ed03/charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d", size = 315182, upload-time = "2026-04-02T09:25:40.673Z" }, - { url = "https://files.pythonhosted.org/packages/24/47/b192933e94b546f1b1fe4df9cc1f84fcdbf2359f8d1081d46dd029b50207/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8", size = 209329, upload-time = "2026-04-02T09:25:42.354Z" }, - { url = "https://files.pythonhosted.org/packages/c2/b4/01fa81c5ca6141024d89a8fc15968002b71da7f825dd14113207113fabbd/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790", size = 231230, upload-time = "2026-04-02T09:25:44.281Z" }, - { url = "https://files.pythonhosted.org/packages/20/f7/7b991776844dfa058017e600e6e55ff01984a063290ca5622c0b63162f68/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc", size = 225890, upload-time = "2026-04-02T09:25:45.475Z" }, - { url = "https://files.pythonhosted.org/packages/20/e7/bed0024a0f4ab0c8a9c64d4445f39b30c99bd1acd228291959e3de664247/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393", size = 216930, upload-time = "2026-04-02T09:25:46.58Z" }, - { url = "https://files.pythonhosted.org/packages/e2/ab/b18f0ab31cdd7b3ddb8bb76c4a414aeb8160c9810fdf1bc62f269a539d87/charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153", size = 202109, upload-time = "2026-04-02T09:25:48.031Z" }, - { url = "https://files.pythonhosted.org/packages/82/e5/7e9440768a06dfb3075936490cb82dbf0ee20a133bf0dd8551fa096914ec/charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af", size = 214684, upload-time = "2026-04-02T09:25:49.245Z" }, - { url = "https://files.pythonhosted.org/packages/71/94/8c61d8da9f062fdf457c80acfa25060ec22bf1d34bbeaca4350f13bcfd07/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34", size = 212785, upload-time = "2026-04-02T09:25:50.671Z" }, - { url = "https://files.pythonhosted.org/packages/66/cd/6e9889c648e72c0ab2e5967528bb83508f354d706637bc7097190c874e13/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1", size = 203055, upload-time = "2026-04-02T09:25:51.802Z" }, - { url = "https://files.pythonhosted.org/packages/92/2e/7a951d6a08aefb7eb8e1b54cdfb580b1365afdd9dd484dc4bee9e5d8f258/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752", size = 232502, upload-time = "2026-04-02T09:25:53.388Z" }, - { url = "https://files.pythonhosted.org/packages/58/d5/abcf2d83bf8e0a1286df55cd0dc1d49af0da4282aa77e986df343e7de124/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53", size = 214295, upload-time = "2026-04-02T09:25:54.765Z" }, - { url = "https://files.pythonhosted.org/packages/47/3a/7d4cd7ed54be99973a0dc176032cba5cb1f258082c31fa6df35cff46acfc/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616", size = 227145, upload-time = "2026-04-02T09:25:55.904Z" }, - { url = "https://files.pythonhosted.org/packages/1d/98/3a45bf8247889cf28262ebd3d0872edff11565b2a1e3064ccb132db3fbb0/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a", size = 218884, upload-time = "2026-04-02T09:25:57.074Z" }, - { url = "https://files.pythonhosted.org/packages/ad/80/2e8b7f8915ed5c9ef13aa828d82738e33888c485b65ebf744d615040c7ea/charset_normalizer-3.4.7-cp310-cp310-win32.whl", hash = "sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374", size = 148343, upload-time = "2026-04-02T09:25:58.199Z" }, - { url = "https://files.pythonhosted.org/packages/35/1b/3b8c8c77184af465ee9ad88b5aea46ea6b2e1f7b9dc9502891e37af21e30/charset_normalizer-3.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943", size = 159174, upload-time = "2026-04-02T09:25:59.322Z" }, - { url = "https://files.pythonhosted.org/packages/be/c1/feb40dca40dbb21e0a908801782d9288c64fc8d8e562c2098e9994c8c21b/charset_normalizer-3.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008", size = 147805, upload-time = "2026-04-02T09:26:00.756Z" }, - { url = "https://files.pythonhosted.org/packages/c2/d7/b5b7020a0565c2e9fa8c09f4b5fa6232feb326b8c20081ccded47ea368fd/charset_normalizer-3.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7", size = 309705, upload-time = "2026-04-02T09:26:02.191Z" }, - { url = "https://files.pythonhosted.org/packages/5a/53/58c29116c340e5456724ecd2fff4196d236b98f3da97b404bc5e51ac3493/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7", size = 206419, upload-time = "2026-04-02T09:26:03.583Z" }, - { url = "https://files.pythonhosted.org/packages/b2/02/e8146dc6591a37a00e5144c63f29fb7c97a734ea8a111190783c0e60ab63/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e", size = 227901, upload-time = "2026-04-02T09:26:04.738Z" }, - { url = "https://files.pythonhosted.org/packages/fb/73/77486c4cd58f1267bf17db420e930c9afa1b3be3fe8c8b8ebbebc9624359/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c", size = 222742, upload-time = "2026-04-02T09:26:06.36Z" }, - { url = "https://files.pythonhosted.org/packages/a1/fa/f74eb381a7d94ded44739e9d94de18dc5edc9c17fb8c11f0a6890696c0a9/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df", size = 214061, upload-time = "2026-04-02T09:26:08.347Z" }, - { url = "https://files.pythonhosted.org/packages/dc/92/42bd3cefcf7687253fb86694b45f37b733c97f59af3724f356fa92b8c344/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265", size = 199239, upload-time = "2026-04-02T09:26:09.823Z" }, - { url = "https://files.pythonhosted.org/packages/4c/3d/069e7184e2aa3b3cddc700e3dd267413dc259854adc3380421c805c6a17d/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4", size = 210173, upload-time = "2026-04-02T09:26:10.953Z" }, - { url = "https://files.pythonhosted.org/packages/62/51/9d56feb5f2e7074c46f93e0ebdbe61f0848ee246e2f0d89f8e20b89ebb8f/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e", size = 209841, upload-time = "2026-04-02T09:26:12.142Z" }, - { url = "https://files.pythonhosted.org/packages/d2/59/893d8f99cc4c837dda1fe2f1139079703deb9f321aabcb032355de13b6c7/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38", size = 200304, upload-time = "2026-04-02T09:26:13.711Z" }, - { url = "https://files.pythonhosted.org/packages/7d/1d/ee6f3be3464247578d1ed5c46de545ccc3d3ff933695395c402c21fa6b77/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c", size = 229455, upload-time = "2026-04-02T09:26:14.941Z" }, - { url = "https://files.pythonhosted.org/packages/54/bb/8fb0a946296ea96a488928bdce8ef99023998c48e4713af533e9bb98ef07/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b", size = 210036, upload-time = "2026-04-02T09:26:16.478Z" }, - { url = "https://files.pythonhosted.org/packages/9a/bc/015b2387f913749f82afd4fcba07846d05b6d784dd16123cb66860e0237d/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c", size = 224739, upload-time = "2026-04-02T09:26:17.751Z" }, - { url = "https://files.pythonhosted.org/packages/17/ab/63133691f56baae417493cba6b7c641571a2130eb7bceba6773367ab9ec5/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d", size = 216277, upload-time = "2026-04-02T09:26:18.981Z" }, - { url = "https://files.pythonhosted.org/packages/06/6d/3be70e827977f20db77c12a97e6a9f973631a45b8d186c084527e53e77a4/charset_normalizer-3.4.7-cp311-cp311-win32.whl", hash = "sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad", size = 147819, upload-time = "2026-04-02T09:26:20.295Z" }, - { url = "https://files.pythonhosted.org/packages/20/d9/5f67790f06b735d7c7637171bbfd89882ad67201891b7275e51116ed8207/charset_normalizer-3.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00", size = 159281, upload-time = "2026-04-02T09:26:21.74Z" }, - { url = "https://files.pythonhosted.org/packages/ca/83/6413f36c5a34afead88ce6f66684d943d91f233d76dd083798f9602b75ae/charset_normalizer-3.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1", size = 147843, upload-time = "2026-04-02T09:26:22.901Z" }, - { url = "https://files.pythonhosted.org/packages/0c/eb/4fc8d0a7110eb5fc9cc161723a34a8a6c200ce3b4fbf681bc86feee22308/charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46", size = 311328, upload-time = "2026-04-02T09:26:24.331Z" }, - { url = "https://files.pythonhosted.org/packages/f8/e3/0fadc706008ac9d7b9b5be6dc767c05f9d3e5df51744ce4cc9605de7b9f4/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2", size = 208061, upload-time = "2026-04-02T09:26:25.568Z" }, - { url = "https://files.pythonhosted.org/packages/42/f0/3dd1045c47f4a4604df85ec18ad093912ae1344ac706993aff91d38773a2/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b", size = 229031, upload-time = "2026-04-02T09:26:26.865Z" }, - { url = "https://files.pythonhosted.org/packages/dc/67/675a46eb016118a2fbde5a277a5d15f4f69d5f3f5f338e5ee2f8948fcf43/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a", size = 225239, upload-time = "2026-04-02T09:26:28.044Z" }, - { url = "https://files.pythonhosted.org/packages/4b/f8/d0118a2f5f23b02cd166fa385c60f9b0d4f9194f574e2b31cef350ad7223/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116", size = 216589, upload-time = "2026-04-02T09:26:29.239Z" }, - { url = "https://files.pythonhosted.org/packages/b1/f1/6d2b0b261b6c4ceef0fcb0d17a01cc5bc53586c2d4796fa04b5c540bc13d/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb", size = 202733, upload-time = "2026-04-02T09:26:30.5Z" }, - { url = "https://files.pythonhosted.org/packages/6f/c0/7b1f943f7e87cc3db9626ba17807d042c38645f0a1d4415c7a14afb5591f/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1", size = 212652, upload-time = "2026-04-02T09:26:31.709Z" }, - { url = "https://files.pythonhosted.org/packages/38/dd/5a9ab159fe45c6e72079398f277b7d2b523e7f716acc489726115a910097/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15", size = 211229, upload-time = "2026-04-02T09:26:33.282Z" }, - { url = "https://files.pythonhosted.org/packages/d5/ff/531a1cad5ca855d1c1a8b69cb71abfd6d85c0291580146fda7c82857caa1/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5", size = 203552, upload-time = "2026-04-02T09:26:34.845Z" }, - { url = "https://files.pythonhosted.org/packages/c1/4c/a5fb52d528a8ca41f7598cb619409ece30a169fbdf9cdce592e53b46c3a6/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d", size = 230806, upload-time = "2026-04-02T09:26:36.152Z" }, - { url = "https://files.pythonhosted.org/packages/59/7a/071feed8124111a32b316b33ae4de83d36923039ef8cf48120266844285b/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7", size = 212316, upload-time = "2026-04-02T09:26:37.672Z" }, - { url = "https://files.pythonhosted.org/packages/fd/35/f7dba3994312d7ba508e041eaac39a36b120f32d4c8662b8814dab876431/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464", size = 227274, upload-time = "2026-04-02T09:26:38.93Z" }, - { url = "https://files.pythonhosted.org/packages/8a/2d/a572df5c9204ab7688ec1edc895a73ebded3b023bb07364710b05dd1c9be/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49", size = 218468, upload-time = "2026-04-02T09:26:40.17Z" }, - { url = "https://files.pythonhosted.org/packages/86/eb/890922a8b03a568ca2f336c36585a4713c55d4d67bf0f0c78924be6315ca/charset_normalizer-3.4.7-cp312-cp312-win32.whl", hash = "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c", size = 148460, upload-time = "2026-04-02T09:26:41.416Z" }, - { url = "https://files.pythonhosted.org/packages/35/d9/0e7dffa06c5ab081f75b1b786f0aefc88365825dfcd0ac544bdb7b2b6853/charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6", size = 159330, upload-time = "2026-04-02T09:26:42.554Z" }, - { url = "https://files.pythonhosted.org/packages/9e/5d/481bcc2a7c88ea6b0878c299547843b2521ccbc40980cb406267088bc701/charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d", size = 147828, upload-time = "2026-04-02T09:26:44.075Z" }, - { url = "https://files.pythonhosted.org/packages/c1/3b/66777e39d3ae1ddc77ee606be4ec6d8cbd4c801f65e5a1b6f2b11b8346dd/charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063", size = 309627, upload-time = "2026-04-02T09:26:45.198Z" }, - { url = "https://files.pythonhosted.org/packages/2e/4e/b7f84e617b4854ade48a1b7915c8ccfadeba444d2a18c291f696e37f0d3b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c", size = 207008, upload-time = "2026-04-02T09:26:46.824Z" }, - { url = "https://files.pythonhosted.org/packages/c4/bb/ec73c0257c9e11b268f018f068f5d00aa0ef8c8b09f7753ebd5f2880e248/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66", size = 228303, upload-time = "2026-04-02T09:26:48.397Z" }, - { url = "https://files.pythonhosted.org/packages/85/fb/32d1f5033484494619f701e719429c69b766bfc4dbc61aa9e9c8c166528b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18", size = 224282, upload-time = "2026-04-02T09:26:49.684Z" }, - { url = "https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd", size = 215595, upload-time = "2026-04-02T09:26:50.915Z" }, - { url = "https://files.pythonhosted.org/packages/e3/7c/fc890655786e423f02556e0216d4b8c6bcb6bdfa890160dc66bf52dee468/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215", size = 201986, upload-time = "2026-04-02T09:26:52.197Z" }, - { url = "https://files.pythonhosted.org/packages/d8/97/bfb18b3db2aed3b90cf54dc292ad79fdd5ad65c4eae454099475cbeadd0d/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859", size = 211711, upload-time = "2026-04-02T09:26:53.49Z" }, - { url = "https://files.pythonhosted.org/packages/6f/a5/a581c13798546a7fd557c82614a5c65a13df2157e9ad6373166d2a3e645d/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8", size = 210036, upload-time = "2026-04-02T09:26:54.975Z" }, - { url = "https://files.pythonhosted.org/packages/8c/bf/b3ab5bcb478e4193d517644b0fb2bf5497fbceeaa7a1bc0f4d5b50953861/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5", size = 202998, upload-time = "2026-04-02T09:26:56.303Z" }, - { url = "https://files.pythonhosted.org/packages/e7/4e/23efd79b65d314fa320ec6017b4b5834d5c12a58ba4610aa353af2e2f577/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832", size = 230056, upload-time = "2026-04-02T09:26:57.554Z" }, - { url = "https://files.pythonhosted.org/packages/b9/9f/1e1941bc3f0e01df116e68dc37a55c4d249df5e6fa77f008841aef68264f/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6", size = 211537, upload-time = "2026-04-02T09:26:58.843Z" }, - { url = "https://files.pythonhosted.org/packages/80/0f/088cbb3020d44428964a6c97fe1edfb1b9550396bf6d278330281e8b709c/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48", size = 226176, upload-time = "2026-04-02T09:27:00.437Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9f/130394f9bbe06f4f63e22641d32fc9b202b7e251c9aef4db044324dac493/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a", size = 217723, upload-time = "2026-04-02T09:27:02.021Z" }, - { url = "https://files.pythonhosted.org/packages/73/55/c469897448a06e49f8fa03f6caae97074fde823f432a98f979cc42b90e69/charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e", size = 148085, upload-time = "2026-04-02T09:27:03.192Z" }, - { url = "https://files.pythonhosted.org/packages/5d/78/1b74c5bbb3f99b77a1715c91b3e0b5bdb6fe302d95ace4f5b1bec37b0167/charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110", size = 158819, upload-time = "2026-04-02T09:27:04.454Z" }, - { url = "https://files.pythonhosted.org/packages/68/86/46bd42279d323deb8687c4a5a811fd548cb7d1de10cf6535d099877a9a9f/charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b", size = 147915, upload-time = "2026-04-02T09:27:05.971Z" }, - { url = "https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0", size = 309234, upload-time = "2026-04-02T09:27:07.194Z" }, - { url = "https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a", size = 208042, upload-time = "2026-04-02T09:27:08.749Z" }, - { url = "https://files.pythonhosted.org/packages/87/1c/ab2ce611b984d2fd5d86a5a8a19c1ae26acac6bad967da4967562c75114d/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b", size = 228706, upload-time = "2026-04-02T09:27:09.951Z" }, - { url = "https://files.pythonhosted.org/packages/a8/29/2b1d2cb00bf085f59d29eb773ce58ec2d325430f8c216804a0a5cd83cbca/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41", size = 224727, upload-time = "2026-04-02T09:27:11.175Z" }, - { url = "https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e", size = 215882, upload-time = "2026-04-02T09:27:12.446Z" }, - { url = "https://files.pythonhosted.org/packages/2c/c2/356065d5a8b78ed04499cae5f339f091946a6a74f91e03476c33f0ab7100/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae", size = 200860, upload-time = "2026-04-02T09:27:13.721Z" }, - { url = "https://files.pythonhosted.org/packages/0c/cd/a32a84217ced5039f53b29f460962abb2d4420def55afabe45b1c3c7483d/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18", size = 211564, upload-time = "2026-04-02T09:27:15.272Z" }, - { url = "https://files.pythonhosted.org/packages/44/86/58e6f13ce26cc3b8f4a36b94a0f22ae2f00a72534520f4ae6857c4b81f89/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b", size = 211276, upload-time = "2026-04-02T09:27:16.834Z" }, - { url = "https://files.pythonhosted.org/packages/8f/fe/d17c32dc72e17e155e06883efa84514ca375f8a528ba2546bee73fc4df81/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356", size = 201238, upload-time = "2026-04-02T09:27:18.229Z" }, - { url = "https://files.pythonhosted.org/packages/6a/29/f33daa50b06525a237451cdb6c69da366c381a3dadcd833fa5676bc468b3/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab", size = 230189, upload-time = "2026-04-02T09:27:19.445Z" }, - { url = "https://files.pythonhosted.org/packages/b6/6e/52c84015394a6a0bdcd435210a7e944c5f94ea1055f5cc5d56c5fe368e7b/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46", size = 211352, upload-time = "2026-04-02T09:27:20.79Z" }, - { url = "https://files.pythonhosted.org/packages/8c/d7/4353be581b373033fb9198bf1da3cf8f09c1082561e8e922aa7b39bf9fe8/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44", size = 227024, upload-time = "2026-04-02T09:27:22.063Z" }, - { url = "https://files.pythonhosted.org/packages/30/45/99d18aa925bd1740098ccd3060e238e21115fffbfdcb8f3ece837d0ace6c/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72", size = 217869, upload-time = "2026-04-02T09:27:23.486Z" }, - { url = "https://files.pythonhosted.org/packages/5c/05/5ee478aa53f4bb7996482153d4bfe1b89e0f087f0ab6b294fcf92d595873/charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10", size = 148541, upload-time = "2026-04-02T09:27:25.146Z" }, - { url = "https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f", size = 159634, upload-time = "2026-04-02T09:27:26.642Z" }, - { url = "https://files.pythonhosted.org/packages/c6/a3/c2369911cd72f02386e4e340770f6e158c7980267da16af8f668217abaa0/charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246", size = 148384, upload-time = "2026-04-02T09:27:28.271Z" }, - { url = "https://files.pythonhosted.org/packages/94/09/7e8a7f73d24dba1f0035fbbf014d2c36828fc1bf9c88f84093e57d315935/charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24", size = 330133, upload-time = "2026-04-02T09:27:29.474Z" }, - { url = "https://files.pythonhosted.org/packages/8d/da/96975ddb11f8e977f706f45cddd8540fd8242f71ecdb5d18a80723dcf62c/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79", size = 216257, upload-time = "2026-04-02T09:27:30.793Z" }, - { url = "https://files.pythonhosted.org/packages/e5/e8/1d63bf8ef2d388e95c64b2098f45f84758f6d102a087552da1485912637b/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960", size = 234851, upload-time = "2026-04-02T09:27:32.44Z" }, - { url = "https://files.pythonhosted.org/packages/9b/40/e5ff04233e70da2681fa43969ad6f66ca5611d7e669be0246c4c7aaf6dc8/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4", size = 233393, upload-time = "2026-04-02T09:27:34.03Z" }, - { url = "https://files.pythonhosted.org/packages/be/c1/06c6c49d5a5450f76899992f1ee40b41d076aee9279b49cf9974d2f313d5/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e", size = 223251, upload-time = "2026-04-02T09:27:35.369Z" }, - { url = "https://files.pythonhosted.org/packages/2b/9f/f2ff16fb050946169e3e1f82134d107e5d4ae72647ec8a1b1446c148480f/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1", size = 206609, upload-time = "2026-04-02T09:27:36.661Z" }, - { url = "https://files.pythonhosted.org/packages/69/d5/a527c0cd8d64d2eab7459784fb4169a0ac76e5a6fc5237337982fd61347e/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44", size = 220014, upload-time = "2026-04-02T09:27:38.019Z" }, - { url = "https://files.pythonhosted.org/packages/7e/80/8a7b8104a3e203074dc9aa2c613d4b726c0e136bad1cc734594b02867972/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e", size = 218979, upload-time = "2026-04-02T09:27:39.37Z" }, - { url = "https://files.pythonhosted.org/packages/02/9a/b759b503d507f375b2b5c153e4d2ee0a75aa215b7f2489cf314f4541f2c0/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3", size = 209238, upload-time = "2026-04-02T09:27:40.722Z" }, - { url = "https://files.pythonhosted.org/packages/c2/4e/0f3f5d47b86bdb79256e7290b26ac847a2832d9a4033f7eb2cd4bcf4bb5b/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0", size = 236110, upload-time = "2026-04-02T09:27:42.33Z" }, - { url = "https://files.pythonhosted.org/packages/96/23/bce28734eb3ed2c91dcf93abeb8a5cf393a7b2749725030bb630e554fdd8/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e", size = 219824, upload-time = "2026-04-02T09:27:43.924Z" }, - { url = "https://files.pythonhosted.org/packages/2c/6f/6e897c6984cc4d41af319b077f2f600fc8214eb2fe2d6bcb79141b882400/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb", size = 233103, upload-time = "2026-04-02T09:27:45.348Z" }, - { url = "https://files.pythonhosted.org/packages/76/22/ef7bd0fe480a0ae9b656189ec00744b60933f68b4f42a7bb06589f6f576a/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe", size = 225194, upload-time = "2026-04-02T09:27:46.706Z" }, - { url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", size = 159827, upload-time = "2026-04-02T09:27:48.053Z" }, - { url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", size = 174168, upload-time = "2026-04-02T09:27:49.795Z" }, - { url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", size = 153018, upload-time = "2026-04-02T09:27:51.116Z" }, - { url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958, upload-time = "2026-04-02T09:28:37.794Z" }, -] - -[[package]] -name = "click" -version = "8.3.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, -] - -[[package]] -name = "colorama" -version = "0.4.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, -] - -[[package]] -name = "distro" -version = "1.9.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, -] - -[[package]] -name = "exceptiongroup" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, -] - -[[package]] -name = "fastapi" -version = "0.135.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "annotated-doc" }, - { name = "pydantic" }, - { name = "starlette" }, - { name = "typing-extensions" }, - { name = "typing-inspection" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f7/e6/7adb4c5fa231e82c35b8f5741a9f2d055f520c29af5546fd70d3e8e1cd2e/fastapi-0.135.3.tar.gz", hash = "sha256:bd6d7caf1a2bdd8d676843cdcd2287729572a1ef524fc4d65c17ae002a1be654", size = 396524, upload-time = "2026-04-01T16:23:58.188Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/84/a4/5caa2de7f917a04ada20018eccf60d6cc6145b0199d55ca3711b0fc08312/fastapi-0.135.3-py3-none-any.whl", hash = "sha256:9b0f590c813acd13d0ab43dd8494138eb58e484bfac405db1f3187cfc5810d98", size = 117734, upload-time = "2026-04-01T16:23:59.328Z" }, -] - -[[package]] -name = "h11" -version = "0.16.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, -] - -[[package]] -name = "httpcore" -version = "1.0.9" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "h11" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, -] - -[[package]] -name = "httpx" -version = "0.28.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "certifi" }, - { name = "httpcore" }, - { name = "idna" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, -] - -[[package]] -name = "idna" -version = "3.11" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, -] - -[[package]] -name = "iniconfig" -version = "2.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, -] - -[[package]] -name = "jiter" -version = "0.13.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0d/5e/4ec91646aee381d01cdb9974e30882c9cd3b8c5d1079d6b5ff4af522439a/jiter-0.13.0.tar.gz", hash = "sha256:f2839f9c2c7e2dffc1bc5929a510e14ce0a946be9365fd1219e7ef342dae14f4", size = 164847, upload-time = "2026-02-02T12:37:56.441Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/5a/41da76c5ea07bec1b0472b6b2fdb1b651074d504b19374d7e130e0cdfb25/jiter-0.13.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2ffc63785fd6c7977defe49b9824ae6ce2b2e2b77ce539bdaf006c26da06342e", size = 311164, upload-time = "2026-02-02T12:35:17.688Z" }, - { url = "https://files.pythonhosted.org/packages/40/cb/4a1bf994a3e869f0d39d10e11efb471b76d0ad70ecbfb591427a46c880c2/jiter-0.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4a638816427006c1e3f0013eb66d391d7a3acda99a7b0cf091eff4497ccea33a", size = 320296, upload-time = "2026-02-02T12:35:19.828Z" }, - { url = "https://files.pythonhosted.org/packages/09/82/acd71ca9b50ecebadc3979c541cd717cce2fe2bc86236f4fa597565d8f1a/jiter-0.13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19928b5d1ce0ff8c1ee1b9bdef3b5bfc19e8304f1b904e436caf30bc15dc6cf5", size = 352742, upload-time = "2026-02-02T12:35:21.258Z" }, - { url = "https://files.pythonhosted.org/packages/71/03/d1fc996f3aecfd42eb70922edecfb6dd26421c874503e241153ad41df94f/jiter-0.13.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:309549b778b949d731a2f0e1594a3f805716be704a73bf3ad9a807eed5eb5721", size = 363145, upload-time = "2026-02-02T12:35:24.653Z" }, - { url = "https://files.pythonhosted.org/packages/f1/61/a30492366378cc7a93088858f8991acd7d959759fe6138c12a4644e58e81/jiter-0.13.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcdabaea26cb04e25df3103ce47f97466627999260290349a88c8136ecae0060", size = 487683, upload-time = "2026-02-02T12:35:26.162Z" }, - { url = "https://files.pythonhosted.org/packages/20/4e/4223cffa9dbbbc96ed821c5aeb6bca510848c72c02086d1ed3f1da3d58a7/jiter-0.13.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a3a377af27b236abbf665a69b2bdd680e3b5a0bd2af825cd3b81245279a7606c", size = 373579, upload-time = "2026-02-02T12:35:27.582Z" }, - { url = "https://files.pythonhosted.org/packages/fe/c9/b0489a01329ab07a83812d9ebcffe7820a38163c6d9e7da644f926ff877c/jiter-0.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe49d3ff6db74321f144dff9addd4a5874d3105ac5ba7c5b77fac099cfae31ae", size = 362904, upload-time = "2026-02-02T12:35:28.925Z" }, - { url = "https://files.pythonhosted.org/packages/05/af/53e561352a44afcba9a9bc67ee1d320b05a370aed8df54eafe714c4e454d/jiter-0.13.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2113c17c9a67071b0f820733c0893ed1d467b5fcf4414068169e5c2cabddb1e2", size = 392380, upload-time = "2026-02-02T12:35:30.385Z" }, - { url = "https://files.pythonhosted.org/packages/76/2a/dd805c3afb8ed5b326c5ae49e725d1b1255b9754b1b77dbecdc621b20773/jiter-0.13.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ab1185ca5c8b9491b55ebf6c1e8866b8f68258612899693e24a92c5fdb9455d5", size = 517939, upload-time = "2026-02-02T12:35:31.865Z" }, - { url = "https://files.pythonhosted.org/packages/20/2a/7b67d76f55b8fe14c937e7640389612f05f9a4145fc28ae128aaa5e62257/jiter-0.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9621ca242547edc16400981ca3231e0c91c0c4c1ab8573a596cd9bb3575d5c2b", size = 551696, upload-time = "2026-02-02T12:35:33.306Z" }, - { url = "https://files.pythonhosted.org/packages/85/9c/57cdd64dac8f4c6ab8f994fe0eb04dc9fd1db102856a4458fcf8a99dfa62/jiter-0.13.0-cp310-cp310-win32.whl", hash = "sha256:a7637d92b1c9d7a771e8c56f445c7f84396d48f2e756e5978840ecba2fac0894", size = 204592, upload-time = "2026-02-02T12:35:34.58Z" }, - { url = "https://files.pythonhosted.org/packages/a7/38/f4f3ea5788b8a5bae7510a678cdc747eda0c45ffe534f9878ff37e7cf3b3/jiter-0.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c1b609e5cbd2f52bb74fb721515745b407df26d7b800458bd97cb3b972c29e7d", size = 206016, upload-time = "2026-02-02T12:35:36.435Z" }, - { url = "https://files.pythonhosted.org/packages/71/29/499f8c9eaa8a16751b1c0e45e6f5f1761d180da873d417996cc7bddc8eef/jiter-0.13.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ea026e70a9a28ebbdddcbcf0f1323128a8db66898a06eaad3a4e62d2f554d096", size = 311157, upload-time = "2026-02-02T12:35:37.758Z" }, - { url = "https://files.pythonhosted.org/packages/50/f6/566364c777d2ab450b92100bea11333c64c38d32caf8dc378b48e5b20c46/jiter-0.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:66aa3e663840152d18cc8ff1e4faad3dd181373491b9cfdc6004b92198d67911", size = 319729, upload-time = "2026-02-02T12:35:39.246Z" }, - { url = "https://files.pythonhosted.org/packages/73/dd/560f13ec5e4f116d8ad2658781646cca91b617ae3b8758d4a5076b278f70/jiter-0.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3524798e70655ff19aec58c7d05adb1f074fecff62da857ea9be2b908b6d701", size = 354766, upload-time = "2026-02-02T12:35:40.662Z" }, - { url = "https://files.pythonhosted.org/packages/7c/0d/061faffcfe94608cbc28a0d42a77a74222bdf5055ccdbe5fd2292b94f510/jiter-0.13.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ec7e287d7fbd02cb6e22f9a00dd9c9cd504c40a61f2c61e7e1f9690a82726b4c", size = 362587, upload-time = "2026-02-02T12:35:42.025Z" }, - { url = "https://files.pythonhosted.org/packages/92/c9/c66a7864982fd38a9773ec6e932e0398d1262677b8c60faecd02ffb67bf3/jiter-0.13.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:47455245307e4debf2ce6c6e65a717550a0244231240dcf3b8f7d64e4c2f22f4", size = 487537, upload-time = "2026-02-02T12:35:43.459Z" }, - { url = "https://files.pythonhosted.org/packages/6c/86/84eb4352cd3668f16d1a88929b5888a3fe0418ea8c1dfc2ad4e7bf6e069a/jiter-0.13.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ee9da221dca6e0429c2704c1b3655fe7b025204a71d4d9b73390c759d776d165", size = 373717, upload-time = "2026-02-02T12:35:44.928Z" }, - { url = "https://files.pythonhosted.org/packages/6e/09/9fe4c159358176f82d4390407a03f506a8659ed13ca3ac93a843402acecf/jiter-0.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24ab43126d5e05f3d53a36a8e11eb2f23304c6c1117844aaaf9a0aa5e40b5018", size = 362683, upload-time = "2026-02-02T12:35:46.636Z" }, - { url = "https://files.pythonhosted.org/packages/c9/5e/85f3ab9caca0c1d0897937d378b4a515cae9e119730563572361ea0c48ae/jiter-0.13.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9da38b4fedde4fb528c740c2564628fbab737166a0e73d6d46cb4bb5463ff411", size = 392345, upload-time = "2026-02-02T12:35:48.088Z" }, - { url = "https://files.pythonhosted.org/packages/12/4c/05b8629ad546191939e6f0c2f17e29f542a398f4a52fb987bc70b6d1eb8b/jiter-0.13.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0b34c519e17658ed88d5047999a93547f8889f3c1824120c26ad6be5f27b6cf5", size = 517775, upload-time = "2026-02-02T12:35:49.482Z" }, - { url = "https://files.pythonhosted.org/packages/4d/88/367ea2eb6bc582c7052e4baf5ddf57ebe5ab924a88e0e09830dfb585c02d/jiter-0.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d2a6394e6af690d462310a86b53c47ad75ac8c21dc79f120714ea449979cb1d3", size = 551325, upload-time = "2026-02-02T12:35:51.104Z" }, - { url = "https://files.pythonhosted.org/packages/f3/12/fa377ffb94a2f28c41afaed093e0d70cfe512035d5ecb0cad0ae4792d35e/jiter-0.13.0-cp311-cp311-win32.whl", hash = "sha256:0f0c065695f616a27c920a56ad0d4fc46415ef8b806bf8fc1cacf25002bd24e1", size = 204709, upload-time = "2026-02-02T12:35:52.467Z" }, - { url = "https://files.pythonhosted.org/packages/cb/16/8e8203ce92f844dfcd3d9d6a5a7322c77077248dbb12da52d23193a839cd/jiter-0.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:0733312953b909688ae3c2d58d043aa040f9f1a6a75693defed7bc2cc4bf2654", size = 204560, upload-time = "2026-02-02T12:35:53.925Z" }, - { url = "https://files.pythonhosted.org/packages/44/26/97cc40663deb17b9e13c3a5cf29251788c271b18ee4d262c8f94798b8336/jiter-0.13.0-cp311-cp311-win_arm64.whl", hash = "sha256:5d9b34ad56761b3bf0fbe8f7e55468704107608512350962d3317ffd7a4382d5", size = 189608, upload-time = "2026-02-02T12:35:55.304Z" }, - { url = "https://files.pythonhosted.org/packages/2e/30/7687e4f87086829955013ca12a9233523349767f69653ebc27036313def9/jiter-0.13.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:0a2bd69fc1d902e89925fc34d1da51b2128019423d7b339a45d9e99c894e0663", size = 307958, upload-time = "2026-02-02T12:35:57.165Z" }, - { url = "https://files.pythonhosted.org/packages/c3/27/e57f9a783246ed95481e6749cc5002a8a767a73177a83c63ea71f0528b90/jiter-0.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f917a04240ef31898182f76a332f508f2cc4b57d2b4d7ad2dbfebbfe167eb505", size = 318597, upload-time = "2026-02-02T12:35:58.591Z" }, - { url = "https://files.pythonhosted.org/packages/cf/52/e5719a60ac5d4d7c5995461a94ad5ef962a37c8bf5b088390e6fad59b2ff/jiter-0.13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1e2b199f446d3e82246b4fd9236d7cb502dc2222b18698ba0d986d2fecc6152", size = 348821, upload-time = "2026-02-02T12:36:00.093Z" }, - { url = "https://files.pythonhosted.org/packages/61/db/c1efc32b8ba4c740ab3fc2d037d8753f67685f475e26b9d6536a4322bcdd/jiter-0.13.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04670992b576fa65bd056dbac0c39fe8bd67681c380cb2b48efa885711d9d726", size = 364163, upload-time = "2026-02-02T12:36:01.937Z" }, - { url = "https://files.pythonhosted.org/packages/55/8a/fb75556236047c8806995671a18e4a0ad646ed255276f51a20f32dceaeec/jiter-0.13.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a1aff1fbdb803a376d4d22a8f63f8e7ccbce0b4890c26cc7af9e501ab339ef0", size = 483709, upload-time = "2026-02-02T12:36:03.41Z" }, - { url = "https://files.pythonhosted.org/packages/7e/16/43512e6ee863875693a8e6f6d532e19d650779d6ba9a81593ae40a9088ff/jiter-0.13.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b3fb8c2053acaef8580809ac1d1f7481a0a0bdc012fd7f5d8b18fb696a5a089", size = 370480, upload-time = "2026-02-02T12:36:04.791Z" }, - { url = "https://files.pythonhosted.org/packages/f8/4c/09b93e30e984a187bc8aaa3510e1ec8dcbdcd71ca05d2f56aac0492453aa/jiter-0.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdaba7d87e66f26a2c45d8cbadcbfc4bf7884182317907baf39cfe9775bb4d93", size = 360735, upload-time = "2026-02-02T12:36:06.994Z" }, - { url = "https://files.pythonhosted.org/packages/1a/1b/46c5e349019874ec5dfa508c14c37e29864ea108d376ae26d90bee238cd7/jiter-0.13.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7b88d649135aca526da172e48083da915ec086b54e8e73a425ba50999468cc08", size = 391814, upload-time = "2026-02-02T12:36:08.368Z" }, - { url = "https://files.pythonhosted.org/packages/15/9e/26184760e85baee7162ad37b7912797d2077718476bf91517641c92b3639/jiter-0.13.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e404ea551d35438013c64b4f357b0474c7abf9f781c06d44fcaf7a14c69ff9e2", size = 513990, upload-time = "2026-02-02T12:36:09.993Z" }, - { url = "https://files.pythonhosted.org/packages/e9/34/2c9355247d6debad57a0a15e76ab1566ab799388042743656e566b3b7de1/jiter-0.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1f4748aad1b4a93c8bdd70f604d0f748cdc0e8744c5547798acfa52f10e79228", size = 548021, upload-time = "2026-02-02T12:36:11.376Z" }, - { url = "https://files.pythonhosted.org/packages/ac/4a/9f2c23255d04a834398b9c2e0e665382116911dc4d06b795710503cdad25/jiter-0.13.0-cp312-cp312-win32.whl", hash = "sha256:0bf670e3b1445fc4d31612199f1744f67f889ee1bbae703c4b54dc097e5dd394", size = 203024, upload-time = "2026-02-02T12:36:12.682Z" }, - { url = "https://files.pythonhosted.org/packages/09/ee/f0ae675a957ae5a8f160be3e87acea6b11dc7b89f6b7ab057e77b2d2b13a/jiter-0.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:15db60e121e11fe186c0b15236bd5d18381b9ddacdcf4e659feb96fc6c969c92", size = 205424, upload-time = "2026-02-02T12:36:13.93Z" }, - { url = "https://files.pythonhosted.org/packages/1b/02/ae611edf913d3cbf02c97cdb90374af2082c48d7190d74c1111dde08bcdd/jiter-0.13.0-cp312-cp312-win_arm64.whl", hash = "sha256:41f92313d17989102f3cb5dd533a02787cdb99454d494344b0361355da52fcb9", size = 186818, upload-time = "2026-02-02T12:36:15.308Z" }, - { url = "https://files.pythonhosted.org/packages/91/9c/7ee5a6ff4b9991e1a45263bfc46731634c4a2bde27dfda6c8251df2d958c/jiter-0.13.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1f8a55b848cbabf97d861495cd65f1e5c590246fabca8b48e1747c4dfc8f85bf", size = 306897, upload-time = "2026-02-02T12:36:16.748Z" }, - { url = "https://files.pythonhosted.org/packages/7c/02/be5b870d1d2be5dd6a91bdfb90f248fbb7dcbd21338f092c6b89817c3dbf/jiter-0.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f556aa591c00f2c45eb1b89f68f52441a016034d18b65da60e2d2875bbbf344a", size = 317507, upload-time = "2026-02-02T12:36:18.351Z" }, - { url = "https://files.pythonhosted.org/packages/da/92/b25d2ec333615f5f284f3a4024f7ce68cfa0604c322c6808b2344c7f5d2b/jiter-0.13.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7e1d61da332ec412350463891923f960c3073cf1aae93b538f0bb4c8cd46efb", size = 350560, upload-time = "2026-02-02T12:36:19.746Z" }, - { url = "https://files.pythonhosted.org/packages/be/ec/74dcb99fef0aca9fbe56b303bf79f6bd839010cb18ad41000bf6cc71eec0/jiter-0.13.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3097d665a27bc96fd9bbf7f86178037db139f319f785e4757ce7ccbf390db6c2", size = 363232, upload-time = "2026-02-02T12:36:21.243Z" }, - { url = "https://files.pythonhosted.org/packages/1b/37/f17375e0bb2f6a812d4dd92d7616e41917f740f3e71343627da9db2824ce/jiter-0.13.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d01ecc3a8cbdb6f25a37bd500510550b64ddf9f7d64a107d92f3ccb25035d0f", size = 483727, upload-time = "2026-02-02T12:36:22.688Z" }, - { url = "https://files.pythonhosted.org/packages/77/d2/a71160a5ae1a1e66c1395b37ef77da67513b0adba73b993a27fbe47eb048/jiter-0.13.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ed9bbc30f5d60a3bdf63ae76beb3f9db280d7f195dfcfa61af792d6ce912d159", size = 370799, upload-time = "2026-02-02T12:36:24.106Z" }, - { url = "https://files.pythonhosted.org/packages/01/99/ed5e478ff0eb4e8aa5fd998f9d69603c9fd3f32de3bd16c2b1194f68361c/jiter-0.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98fbafb6e88256f4454de33c1f40203d09fc33ed19162a68b3b257b29ca7f663", size = 359120, upload-time = "2026-02-02T12:36:25.519Z" }, - { url = "https://files.pythonhosted.org/packages/16/be/7ffd08203277a813f732ba897352797fa9493faf8dc7995b31f3d9cb9488/jiter-0.13.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5467696f6b827f1116556cb0db620440380434591e93ecee7fd14d1a491b6daa", size = 390664, upload-time = "2026-02-02T12:36:26.866Z" }, - { url = "https://files.pythonhosted.org/packages/d1/84/e0787856196d6d346264d6dcccb01f741e5f0bd014c1d9a2ebe149caf4f3/jiter-0.13.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:2d08c9475d48b92892583df9da592a0e2ac49bcd41fae1fec4f39ba6cf107820", size = 513543, upload-time = "2026-02-02T12:36:28.217Z" }, - { url = "https://files.pythonhosted.org/packages/65/50/ecbd258181c4313cf79bca6c88fb63207d04d5bf5e4f65174114d072aa55/jiter-0.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:aed40e099404721d7fcaf5b89bd3b4568a4666358bcac7b6b15c09fb6252ab68", size = 547262, upload-time = "2026-02-02T12:36:29.678Z" }, - { url = "https://files.pythonhosted.org/packages/27/da/68f38d12e7111d2016cd198161b36e1f042bd115c169255bcb7ec823a3bf/jiter-0.13.0-cp313-cp313-win32.whl", hash = "sha256:36ebfbcffafb146d0e6ffb3e74d51e03d9c35ce7c625c8066cdbfc7b953bdc72", size = 200630, upload-time = "2026-02-02T12:36:31.808Z" }, - { url = "https://files.pythonhosted.org/packages/25/65/3bd1a972c9a08ecd22eb3b08a95d1941ebe6938aea620c246cf426ae09c2/jiter-0.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:8d76029f077379374cf0dbc78dbe45b38dec4a2eb78b08b5194ce836b2517afc", size = 202602, upload-time = "2026-02-02T12:36:33.679Z" }, - { url = "https://files.pythonhosted.org/packages/15/fe/13bd3678a311aa67686bb303654792c48206a112068f8b0b21426eb6851e/jiter-0.13.0-cp313-cp313-win_arm64.whl", hash = "sha256:bb7613e1a427cfcb6ea4544f9ac566b93d5bf67e0d48c787eca673ff9c9dff2b", size = 185939, upload-time = "2026-02-02T12:36:35.065Z" }, - { url = "https://files.pythonhosted.org/packages/49/19/a929ec002ad3228bc97ca01dbb14f7632fffdc84a95ec92ceaf4145688ae/jiter-0.13.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fa476ab5dd49f3bf3a168e05f89358c75a17608dbabb080ef65f96b27c19ab10", size = 316616, upload-time = "2026-02-02T12:36:36.579Z" }, - { url = "https://files.pythonhosted.org/packages/52/56/d19a9a194afa37c1728831e5fb81b7722c3de18a3109e8f282bfc23e587a/jiter-0.13.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ade8cb6ff5632a62b7dbd4757d8c5573f7a2e9ae285d6b5b841707d8363205ef", size = 346850, upload-time = "2026-02-02T12:36:38.058Z" }, - { url = "https://files.pythonhosted.org/packages/36/4a/94e831c6bf287754a8a019cb966ed39ff8be6ab78cadecf08df3bb02d505/jiter-0.13.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9950290340acc1adaded363edd94baebcee7dabdfa8bee4790794cd5cfad2af6", size = 358551, upload-time = "2026-02-02T12:36:39.417Z" }, - { url = "https://files.pythonhosted.org/packages/a2/ec/a4c72c822695fa80e55d2b4142b73f0012035d9fcf90eccc56bc060db37c/jiter-0.13.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2b4972c6df33731aac0742b64fd0d18e0a69bc7d6e03108ce7d40c85fd9e3e6d", size = 201950, upload-time = "2026-02-02T12:36:40.791Z" }, - { url = "https://files.pythonhosted.org/packages/b6/00/393553ec27b824fbc29047e9c7cd4a3951d7fbe4a76743f17e44034fa4e4/jiter-0.13.0-cp313-cp313t-win_arm64.whl", hash = "sha256:701a1e77d1e593c1b435315ff625fd071f0998c5f02792038a5ca98899261b7d", size = 185852, upload-time = "2026-02-02T12:36:42.077Z" }, - { url = "https://files.pythonhosted.org/packages/6e/f5/f1997e987211f6f9bd71b8083047b316208b4aca0b529bb5f8c96c89ef3e/jiter-0.13.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:cc5223ab19fe25e2f0bf2643204ad7318896fe3729bf12fde41b77bfc4fafff0", size = 308804, upload-time = "2026-02-02T12:36:43.496Z" }, - { url = "https://files.pythonhosted.org/packages/cd/8f/5482a7677731fd44881f0204981ce2d7175db271f82cba2085dd2212e095/jiter-0.13.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9776ebe51713acf438fd9b4405fcd86893ae5d03487546dae7f34993217f8a91", size = 318787, upload-time = "2026-02-02T12:36:45.071Z" }, - { url = "https://files.pythonhosted.org/packages/f3/b9/7257ac59778f1cd025b26a23c5520a36a424f7f1b068f2442a5b499b7464/jiter-0.13.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:879e768938e7b49b5e90b7e3fecc0dbec01b8cb89595861fb39a8967c5220d09", size = 353880, upload-time = "2026-02-02T12:36:47.365Z" }, - { url = "https://files.pythonhosted.org/packages/c3/87/719eec4a3f0841dad99e3d3604ee4cba36af4419a76f3cb0b8e2e691ad67/jiter-0.13.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:682161a67adea11e3aae9038c06c8b4a9a71023228767477d683f69903ebc607", size = 366702, upload-time = "2026-02-02T12:36:48.871Z" }, - { url = "https://files.pythonhosted.org/packages/d2/65/415f0a75cf6921e43365a1bc227c565cb949caca8b7532776e430cbaa530/jiter-0.13.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a13b68cd1cd8cc9de8f244ebae18ccb3e4067ad205220ef324c39181e23bbf66", size = 486319, upload-time = "2026-02-02T12:36:53.006Z" }, - { url = "https://files.pythonhosted.org/packages/54/a2/9e12b48e82c6bbc6081fd81abf915e1443add1b13d8fc586e1d90bb02bb8/jiter-0.13.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87ce0f14c6c08892b610686ae8be350bf368467b6acd5085a5b65441e2bf36d2", size = 372289, upload-time = "2026-02-02T12:36:54.593Z" }, - { url = "https://files.pythonhosted.org/packages/4e/c1/e4693f107a1789a239c759a432e9afc592366f04e901470c2af89cfd28e1/jiter-0.13.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c365005b05505a90d1c47856420980d0237adf82f70c4aff7aebd3c1cc143ad", size = 360165, upload-time = "2026-02-02T12:36:56.112Z" }, - { url = "https://files.pythonhosted.org/packages/17/08/91b9ea976c1c758240614bd88442681a87672eebc3d9a6dde476874e706b/jiter-0.13.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1317fdffd16f5873e46ce27d0e0f7f4f90f0cdf1d86bf6abeaea9f63ca2c401d", size = 389634, upload-time = "2026-02-02T12:36:57.495Z" }, - { url = "https://files.pythonhosted.org/packages/18/23/58325ef99390d6d40427ed6005bf1ad54f2577866594bcf13ce55675f87d/jiter-0.13.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:c05b450d37ba0c9e21c77fef1f205f56bcee2330bddca68d344baebfc55ae0df", size = 514933, upload-time = "2026-02-02T12:36:58.909Z" }, - { url = "https://files.pythonhosted.org/packages/5b/25/69f1120c7c395fd276c3996bb8adefa9c6b84c12bb7111e5c6ccdcd8526d/jiter-0.13.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:775e10de3849d0631a97c603f996f518159272db00fdda0a780f81752255ee9d", size = 548842, upload-time = "2026-02-02T12:37:00.433Z" }, - { url = "https://files.pythonhosted.org/packages/18/05/981c9669d86850c5fbb0d9e62bba144787f9fba84546ba43d624ee27ef29/jiter-0.13.0-cp314-cp314-win32.whl", hash = "sha256:632bf7c1d28421c00dd8bbb8a3bac5663e1f57d5cd5ed962bce3c73bf62608e6", size = 202108, upload-time = "2026-02-02T12:37:01.718Z" }, - { url = "https://files.pythonhosted.org/packages/8d/96/cdcf54dd0b0341db7d25413229888a346c7130bd20820530905fdb65727b/jiter-0.13.0-cp314-cp314-win_amd64.whl", hash = "sha256:f22ef501c3f87ede88f23f9b11e608581c14f04db59b6a801f354397ae13739f", size = 204027, upload-time = "2026-02-02T12:37:03.075Z" }, - { url = "https://files.pythonhosted.org/packages/fb/f9/724bcaaab7a3cd727031fe4f6995cb86c4bd344909177c186699c8dec51a/jiter-0.13.0-cp314-cp314-win_arm64.whl", hash = "sha256:07b75fe09a4ee8e0c606200622e571e44943f47254f95e2436c8bdcaceb36d7d", size = 187199, upload-time = "2026-02-02T12:37:04.414Z" }, - { url = "https://files.pythonhosted.org/packages/62/92/1661d8b9fd6a3d7a2d89831db26fe3c1509a287d83ad7838831c7b7a5c7e/jiter-0.13.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:964538479359059a35fb400e769295d4b315ae61e4105396d355a12f7fef09f0", size = 318423, upload-time = "2026-02-02T12:37:05.806Z" }, - { url = "https://files.pythonhosted.org/packages/4f/3b/f77d342a54d4ebcd128e520fc58ec2f5b30a423b0fd26acdfc0c6fef8e26/jiter-0.13.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e104da1db1c0991b3eaed391ccd650ae8d947eab1480c733e5a3fb28d4313e40", size = 351438, upload-time = "2026-02-02T12:37:07.189Z" }, - { url = "https://files.pythonhosted.org/packages/76/b3/ba9a69f0e4209bd3331470c723c2f5509e6f0482e416b612431a5061ed71/jiter-0.13.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e3a5f0cde8ff433b8e88e41aa40131455420fb3649a3c7abdda6145f8cb7202", size = 364774, upload-time = "2026-02-02T12:37:08.579Z" }, - { url = "https://files.pythonhosted.org/packages/b3/16/6cdb31fa342932602458dbb631bfbd47f601e03d2e4950740e0b2100b570/jiter-0.13.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:57aab48f40be1db920a582b30b116fe2435d184f77f0e4226f546794cedd9cf0", size = 487238, upload-time = "2026-02-02T12:37:10.066Z" }, - { url = "https://files.pythonhosted.org/packages/ed/b1/956cc7abaca8d95c13aa8d6c9b3f3797241c246cd6e792934cc4c8b250d2/jiter-0.13.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7772115877c53f62beeb8fd853cab692dbc04374ef623b30f997959a4c0e7e95", size = 372892, upload-time = "2026-02-02T12:37:11.656Z" }, - { url = "https://files.pythonhosted.org/packages/26/c4/97ecde8b1e74f67b8598c57c6fccf6df86ea7861ed29da84629cdbba76c4/jiter-0.13.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1211427574b17b633cfceba5040de8081e5abf114f7a7602f73d2e16f9fdaa59", size = 360309, upload-time = "2026-02-02T12:37:13.244Z" }, - { url = "https://files.pythonhosted.org/packages/4b/d7/eabe3cf46715854ccc80be2cd78dd4c36aedeb30751dbf85a1d08c14373c/jiter-0.13.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7beae3a3d3b5212d3a55d2961db3c292e02e302feb43fce6a3f7a31b90ea6dfe", size = 389607, upload-time = "2026-02-02T12:37:14.881Z" }, - { url = "https://files.pythonhosted.org/packages/df/2d/03963fc0804e6109b82decfb9974eb92df3797fe7222428cae12f8ccaa0c/jiter-0.13.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:e5562a0f0e90a6223b704163ea28e831bd3a9faa3512a711f031611e6b06c939", size = 514986, upload-time = "2026-02-02T12:37:16.326Z" }, - { url = "https://files.pythonhosted.org/packages/f6/6c/8c83b45eb3eb1c1e18d841fe30b4b5bc5619d781267ca9bc03e005d8fd0a/jiter-0.13.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:6c26a424569a59140fb51160a56df13f438a2b0967365e987889186d5fc2f6f9", size = 548756, upload-time = "2026-02-02T12:37:17.736Z" }, - { url = "https://files.pythonhosted.org/packages/47/66/eea81dfff765ed66c68fd2ed8c96245109e13c896c2a5015c7839c92367e/jiter-0.13.0-cp314-cp314t-win32.whl", hash = "sha256:24dc96eca9f84da4131cdf87a95e6ce36765c3b156fc9ae33280873b1c32d5f6", size = 201196, upload-time = "2026-02-02T12:37:19.101Z" }, - { url = "https://files.pythonhosted.org/packages/ff/32/4ac9c7a76402f8f00d00842a7f6b83b284d0cf7c1e9d4227bc95aa6d17fa/jiter-0.13.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0a8d76c7524087272c8ae913f5d9d608bd839154b62c4322ef65723d2e5bb0b8", size = 204215, upload-time = "2026-02-02T12:37:20.495Z" }, - { url = "https://files.pythonhosted.org/packages/f9/8e/7def204fea9f9be8b3c21a6f2dd6c020cf56c7d5ff753e0e23ed7f9ea57e/jiter-0.13.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2c26cf47e2cad140fa23b6d58d435a7c0161f5c514284802f25e87fddfe11024", size = 187152, upload-time = "2026-02-02T12:37:22.124Z" }, - { url = "https://files.pythonhosted.org/packages/79/b3/3c29819a27178d0e461a8571fb63c6ae38be6dc36b78b3ec2876bbd6a910/jiter-0.13.0-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b1cbfa133241d0e6bdab48dcdc2604e8ba81512f6bbd68ec3e8e1357dd3c316c", size = 307016, upload-time = "2026-02-02T12:37:42.755Z" }, - { url = "https://files.pythonhosted.org/packages/eb/ae/60993e4b07b1ac5ebe46da7aa99fdbb802eb986c38d26e3883ac0125c4e0/jiter-0.13.0-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:db367d8be9fad6e8ebbac4a7578b7af562e506211036cba2c06c3b998603c3d2", size = 305024, upload-time = "2026-02-02T12:37:44.774Z" }, - { url = "https://files.pythonhosted.org/packages/77/fa/2227e590e9cf98803db2811f172b2d6460a21539ab73006f251c66f44b14/jiter-0.13.0-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45f6f8efb2f3b0603092401dc2df79fa89ccbc027aaba4174d2d4133ed661434", size = 339337, upload-time = "2026-02-02T12:37:46.668Z" }, - { url = "https://files.pythonhosted.org/packages/2d/92/015173281f7eb96c0ef580c997da8ef50870d4f7f4c9e03c845a1d62ae04/jiter-0.13.0-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:597245258e6ad085d064780abfb23a284d418d3e61c57362d9449c6c7317ee2d", size = 346395, upload-time = "2026-02-02T12:37:48.09Z" }, - { url = "https://files.pythonhosted.org/packages/80/60/e50fa45dd7e2eae049f0ce964663849e897300433921198aef94b6ffa23a/jiter-0.13.0-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:3d744a6061afba08dd7ae375dcde870cffb14429b7477e10f67e9e6d68772a0a", size = 305169, upload-time = "2026-02-02T12:37:50.376Z" }, - { url = "https://files.pythonhosted.org/packages/d2/73/a009f41c5eed71c49bec53036c4b33555afcdee70682a18c6f66e396c039/jiter-0.13.0-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:ff732bd0a0e778f43d5009840f20b935e79087b4dc65bd36f1cd0f9b04b8ff7f", size = 303808, upload-time = "2026-02-02T12:37:52.092Z" }, - { url = "https://files.pythonhosted.org/packages/c4/10/528b439290763bff3d939268085d03382471b442f212dca4ff5f12802d43/jiter-0.13.0-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab44b178f7981fcaea7e0a5df20e773c663d06ffda0198f1a524e91b2fde7e59", size = 337384, upload-time = "2026-02-02T12:37:53.582Z" }, - { url = "https://files.pythonhosted.org/packages/67/8a/a342b2f0251f3dac4ca17618265d93bf244a2a4d089126e81e4c1056ac50/jiter-0.13.0-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bb00b6d26db67a05fe3e12c76edc75f32077fb51deed13822dc648fa373bc19", size = 343768, upload-time = "2026-02-02T12:37:55.055Z" }, -] - -[[package]] -name = "numpy" -version = "2.2.6" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] -sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, - { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, - { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, - { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, - { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, - { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, - { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, - { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, - { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, - { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, - { url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload-time = "2025-05-17T21:31:19.36Z" }, - { url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload-time = "2025-05-17T21:31:41.087Z" }, - { url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload-time = "2025-05-17T21:31:50.072Z" }, - { url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload-time = "2025-05-17T21:32:01.712Z" }, - { url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload-time = "2025-05-17T21:32:23.332Z" }, - { url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload-time = "2025-05-17T21:32:47.991Z" }, - { url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload-time = "2025-05-17T21:33:11.728Z" }, - { 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" }, - { url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828, upload-time = "2025-05-17T21:37:56.699Z" }, - { url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006, upload-time = "2025-05-17T21:38:18.291Z" }, - { url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765, upload-time = "2025-05-17T21:38:27.319Z" }, - { url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736, upload-time = "2025-05-17T21:38:38.141Z" }, - { url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719, upload-time = "2025-05-17T21:38:58.433Z" }, - { url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072, upload-time = "2025-05-17T21:39:22.638Z" }, - { url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213, upload-time = "2025-05-17T21:39:45.865Z" }, - { url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632, upload-time = "2025-05-17T21:40:13.331Z" }, - { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532, upload-time = "2025-05-17T21:43:46.099Z" }, - { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885, upload-time = "2025-05-17T21:44:05.145Z" }, - { url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467, upload-time = "2025-05-17T21:40:44Z" }, - { url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144, upload-time = "2025-05-17T21:41:05.695Z" }, - { url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217, upload-time = "2025-05-17T21:41:15.903Z" }, - { url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014, upload-time = "2025-05-17T21:41:27.321Z" }, - { url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935, upload-time = "2025-05-17T21:41:49.738Z" }, - { url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122, upload-time = "2025-05-17T21:42:14.046Z" }, - { url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143, upload-time = "2025-05-17T21:42:37.464Z" }, - { url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260, upload-time = "2025-05-17T21:43:05.189Z" }, - { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225, upload-time = "2025-05-17T21:43:16.254Z" }, - { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374, upload-time = "2025-05-17T21:43:35.479Z" }, - { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, - { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, - { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, - { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, -] - -[[package]] -name = "numpy" -version = "2.4.4" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.11'", -] -sdist = { url = "https://files.pythonhosted.org/packages/d7/9f/b8cef5bffa569759033adda9481211426f12f53299629b410340795c2514/numpy-2.4.4.tar.gz", hash = "sha256:2d390634c5182175533585cc89f3608a4682ccb173cc9bb940b2881c8d6f8fa0", size = 20731587, upload-time = "2026-03-29T13:22:01.298Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/c6/4218570d8c8ecc9704b5157a3348e486e84ef4be0ed3e38218ab473c83d2/numpy-2.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f983334aea213c99992053ede6168500e5f086ce74fbc4acc3f2b00f5762e9db", size = 16976799, upload-time = "2026-03-29T13:18:15.438Z" }, - { url = "https://files.pythonhosted.org/packages/dd/92/b4d922c4a5f5dab9ed44e6153908a5c665b71acf183a83b93b690996e39b/numpy-2.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:72944b19f2324114e9dc86a159787333b77874143efcf89a5167ef83cfee8af0", size = 14971552, upload-time = "2026-03-29T13:18:18.606Z" }, - { url = "https://files.pythonhosted.org/packages/8a/dc/df98c095978fa6ee7b9a9387d1d58cbb3d232d0e69ad169a4ce784bde4fd/numpy-2.4.4-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:86b6f55f5a352b48d7fbfd2dbc3d5b780b2d79f4d3c121f33eb6efb22e9a2015", size = 5476566, upload-time = "2026-03-29T13:18:21.532Z" }, - { url = "https://files.pythonhosted.org/packages/28/34/b3fdcec6e725409223dd27356bdf5a3c2cc2282e428218ecc9cb7acc9763/numpy-2.4.4-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:ba1f4fc670ed79f876f70082eff4f9583c15fb9a4b89d6188412de4d18ae2f40", size = 6806482, upload-time = "2026-03-29T13:18:23.634Z" }, - { url = "https://files.pythonhosted.org/packages/68/62/63417c13aa35d57bee1337c67446761dc25ea6543130cf868eace6e8157b/numpy-2.4.4-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a87ec22c87be071b6bdbd27920b129b94f2fc964358ce38f3822635a3e2e03d", size = 15973376, upload-time = "2026-03-29T13:18:26.677Z" }, - { url = "https://files.pythonhosted.org/packages/cf/c5/9fcb7e0e69cef59cf10c746b84f7d58b08bc66a6b7d459783c5a4f6101a6/numpy-2.4.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df3775294accfdd75f32c74ae39fcba920c9a378a2fc18a12b6820aa8c1fb502", size = 16925137, upload-time = "2026-03-29T13:18:30.14Z" }, - { url = "https://files.pythonhosted.org/packages/7e/43/80020edacb3f84b9efdd1591120a4296462c23fd8db0dde1666f6ef66f13/numpy-2.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d4e437e295f18ec29bc79daf55e8a47a9113df44d66f702f02a293d93a2d6dd", size = 17329414, upload-time = "2026-03-29T13:18:33.733Z" }, - { url = "https://files.pythonhosted.org/packages/fd/06/af0658593b18a5f73532d377188b964f239eb0894e664a6c12f484472f97/numpy-2.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6aa3236c78803afbcb255045fbef97a9e25a1f6c9888357d205ddc42f4d6eba5", size = 18658397, upload-time = "2026-03-29T13:18:37.511Z" }, - { url = "https://files.pythonhosted.org/packages/e6/ce/13a09ed65f5d0ce5c7dd0669250374c6e379910f97af2c08c57b0608eee4/numpy-2.4.4-cp311-cp311-win32.whl", hash = "sha256:30caa73029a225b2d40d9fae193e008e24b2026b7ee1a867b7ee8d96ca1a448e", size = 6239499, upload-time = "2026-03-29T13:18:40.372Z" }, - { url = "https://files.pythonhosted.org/packages/bd/63/05d193dbb4b5eec1eca73822d80da98b511f8328ad4ae3ca4caf0f4db91d/numpy-2.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:6bbe4eb67390b0a0265a2c25458f6b90a409d5d069f1041e6aff1e27e3d9a79e", size = 12614257, upload-time = "2026-03-29T13:18:42.95Z" }, - { url = "https://files.pythonhosted.org/packages/87/c5/8168052f080c26fa984c413305012be54741c9d0d74abd7fbeeccae3889f/numpy-2.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:fcfe2045fd2e8f3cb0ce9d4ba6dba6333b8fa05bb8a4939c908cd43322d14c7e", size = 10486775, upload-time = "2026-03-29T13:18:45.835Z" }, - { url = "https://files.pythonhosted.org/packages/28/05/32396bec30fb2263770ee910142f49c1476d08e8ad41abf8403806b520ce/numpy-2.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:15716cfef24d3a9762e3acdf87e27f58dc823d1348f765bbea6bef8c639bfa1b", size = 16689272, upload-time = "2026-03-29T13:18:49.223Z" }, - { url = "https://files.pythonhosted.org/packages/c5/f3/a983d28637bfcd763a9c7aafdb6d5c0ebf3d487d1e1459ffdb57e2f01117/numpy-2.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:23cbfd4c17357c81021f21540da84ee282b9c8fba38a03b7b9d09ba6b951421e", size = 14699573, upload-time = "2026-03-29T13:18:52.629Z" }, - { url = "https://files.pythonhosted.org/packages/9b/fd/e5ecca1e78c05106d98028114f5c00d3eddb41207686b2b7de3e477b0e22/numpy-2.4.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:8b3b60bb7cba2c8c81837661c488637eee696f59a877788a396d33150c35d842", size = 5204782, upload-time = "2026-03-29T13:18:55.579Z" }, - { url = "https://files.pythonhosted.org/packages/de/2f/702a4594413c1a8632092beae8aba00f1d67947389369b3777aed783fdca/numpy-2.4.4-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:e4a010c27ff6f210ff4c6ef34394cd61470d01014439b192ec22552ee867f2a8", size = 6552038, upload-time = "2026-03-29T13:18:57.769Z" }, - { url = "https://files.pythonhosted.org/packages/7f/37/eed308a8f56cba4d1fdf467a4fc67ef4ff4bf1c888f5fc980481890104b1/numpy-2.4.4-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f9e75681b59ddaa5e659898085ae0eaea229d054f2ac0c7e563a62205a700121", size = 15670666, upload-time = "2026-03-29T13:19:00.341Z" }, - { url = "https://files.pythonhosted.org/packages/0a/0d/0e3ecece05b7a7e87ab9fb587855548da437a061326fff64a223b6dcb78a/numpy-2.4.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:81f4a14bee47aec54f883e0cad2d73986640c1590eb9bfaaba7ad17394481e6e", size = 16645480, upload-time = "2026-03-29T13:19:03.63Z" }, - { url = "https://files.pythonhosted.org/packages/34/49/f2312c154b82a286758ee2f1743336d50651f8b5195db18cdb63675ff649/numpy-2.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:62d6b0f03b694173f9fcb1fb317f7222fd0b0b103e784c6549f5e53a27718c44", size = 17020036, upload-time = "2026-03-29T13:19:07.428Z" }, - { url = "https://files.pythonhosted.org/packages/7b/e9/736d17bd77f1b0ec4f9901aaec129c00d59f5d84d5e79bba540ef12c2330/numpy-2.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fbc356aae7adf9e6336d336b9c8111d390a05df88f1805573ebb0807bd06fd1d", size = 18368643, upload-time = "2026-03-29T13:19:10.775Z" }, - { url = "https://files.pythonhosted.org/packages/63/f6/d417977c5f519b17c8a5c3bc9e8304b0908b0e21136fe43bf628a1343914/numpy-2.4.4-cp312-cp312-win32.whl", hash = "sha256:0d35aea54ad1d420c812bfa0385c71cd7cc5bcf7c65fed95fc2cd02fe8c79827", size = 5961117, upload-time = "2026-03-29T13:19:13.464Z" }, - { url = "https://files.pythonhosted.org/packages/2d/5b/e1deebf88ff431b01b7406ca3583ab2bbb90972bbe1c568732e49c844f7e/numpy-2.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:b5f0362dc928a6ecd9db58868fca5e48485205e3855957bdedea308f8672ea4a", size = 12320584, upload-time = "2026-03-29T13:19:16.155Z" }, - { url = "https://files.pythonhosted.org/packages/58/89/e4e856ac82a68c3ed64486a544977d0e7bdd18b8da75b78a577ca31c4395/numpy-2.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:846300f379b5b12cc769334464656bc882e0735d27d9726568bc932fdc49d5ec", size = 10221450, upload-time = "2026-03-29T13:19:18.994Z" }, - { url = "https://files.pythonhosted.org/packages/14/1d/d0a583ce4fefcc3308806a749a536c201ed6b5ad6e1322e227ee4848979d/numpy-2.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:08f2e31ed5e6f04b118e49821397f12767934cfdd12a1ce86a058f91e004ee50", size = 16684933, upload-time = "2026-03-29T13:19:22.47Z" }, - { url = "https://files.pythonhosted.org/packages/c1/62/2b7a48fbb745d344742c0277f01286dead15f3f68e4f359fbfcf7b48f70f/numpy-2.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e823b8b6edc81e747526f70f71a9c0a07ac4e7ad13020aa736bb7c9d67196115", size = 14694532, upload-time = "2026-03-29T13:19:25.581Z" }, - { url = "https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4a19d9dba1a76618dd86b164d608566f393f8ec6ac7c44f0cc879011c45e65af", size = 5199661, upload-time = "2026-03-29T13:19:28.31Z" }, - { url = "https://files.pythonhosted.org/packages/cd/da/464d551604320d1491bc345efed99b4b7034143a85787aab78d5691d5a0e/numpy-2.4.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:d2a8490669bfe99a233298348acc2d824d496dee0e66e31b66a6022c2ad74a5c", size = 6547539, upload-time = "2026-03-29T13:19:30.97Z" }, - { url = "https://files.pythonhosted.org/packages/7d/90/8d23e3b0dafd024bf31bdec225b3bb5c2dbfa6912f8a53b8659f21216cbf/numpy-2.4.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:45dbed2ab436a9e826e302fcdcbe9133f9b0006e5af7168afb8963a6520da103", size = 15668806, upload-time = "2026-03-29T13:19:33.887Z" }, - { url = "https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83", size = 16632682, upload-time = "2026-03-29T13:19:37.336Z" }, - { url = "https://files.pythonhosted.org/packages/34/fb/14570d65c3bde4e202a031210475ae9cde9b7686a2e7dc97ee67d2833b35/numpy-2.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:99d838547ace2c4aace6c4f76e879ddfe02bb58a80c1549928477862b7a6d6ed", size = 17019810, upload-time = "2026-03-29T13:19:40.963Z" }, - { url = "https://files.pythonhosted.org/packages/8a/77/2ba9d87081fd41f6d640c83f26fb7351e536b7ce6dd9061b6af5904e8e46/numpy-2.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0aec54fd785890ecca25a6003fd9a5aed47ad607bbac5cd64f836ad8666f4959", size = 18357394, upload-time = "2026-03-29T13:19:44.859Z" }, - { url = "https://files.pythonhosted.org/packages/a2/23/52666c9a41708b0853fa3b1a12c90da38c507a3074883823126d4e9d5b30/numpy-2.4.4-cp313-cp313-win32.whl", hash = "sha256:07077278157d02f65c43b1b26a3886bce886f95d20aabd11f87932750dfb14ed", size = 5959556, upload-time = "2026-03-29T13:19:47.661Z" }, - { url = "https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:5c70f1cc1c4efbe316a572e2d8b9b9cc44e89b95f79ca3331553fbb63716e2bf", size = 12317311, upload-time = "2026-03-29T13:19:50.67Z" }, - { url = "https://files.pythonhosted.org/packages/ba/d8/11490cddd564eb4de97b4579ef6bfe6a736cc07e94c1598590ae25415e01/numpy-2.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:ef4059d6e5152fa1a39f888e344c73fdc926e1b2dd58c771d67b0acfbf2aa67d", size = 10222060, upload-time = "2026-03-29T13:19:54.229Z" }, - { url = "https://files.pythonhosted.org/packages/99/5d/dab4339177a905aad3e2221c915b35202f1ec30d750dd2e5e9d9a72b804b/numpy-2.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4bbc7f303d125971f60ec0aaad5e12c62d0d2c925f0ab1273debd0e4ba37aba5", size = 14822302, upload-time = "2026-03-29T13:19:57.585Z" }, - { url = "https://files.pythonhosted.org/packages/eb/e4/0564a65e7d3d97562ed6f9b0fd0fb0a6f559ee444092f105938b50043876/numpy-2.4.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:4d6d57903571f86180eb98f8f0c839fa9ebbfb031356d87f1361be91e433f5b7", size = 5327407, upload-time = "2026-03-29T13:20:00.601Z" }, - { url = "https://files.pythonhosted.org/packages/29/8d/35a3a6ce5ad371afa58b4700f1c820f8f279948cca32524e0a695b0ded83/numpy-2.4.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:4636de7fd195197b7535f231b5de9e4b36d2c440b6e566d2e4e4746e6af0ca93", size = 6647631, upload-time = "2026-03-29T13:20:02.855Z" }, - { url = "https://files.pythonhosted.org/packages/f4/da/477731acbd5a58a946c736edfdabb2ac5b34c3d08d1ba1a7b437fa0884df/numpy-2.4.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ad2e2ef14e0b04e544ea2fa0a36463f847f113d314aa02e5b402fdf910ef309e", size = 15727691, upload-time = "2026-03-29T13:20:06.004Z" }, - { url = "https://files.pythonhosted.org/packages/e6/db/338535d9b152beabeb511579598418ba0212ce77cf9718edd70262cc4370/numpy-2.4.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a285b3b96f951841799528cd1f4f01cd70e7e0204b4abebac9463eecfcf2a40", size = 16681241, upload-time = "2026-03-29T13:20:09.417Z" }, - { url = "https://files.pythonhosted.org/packages/e2/a9/ad248e8f58beb7a0219b413c9c7d8151c5d285f7f946c3e26695bdbbe2df/numpy-2.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f8474c4241bc18b750be2abea9d7a9ec84f46ef861dbacf86a4f6e043401f79e", size = 17085767, upload-time = "2026-03-29T13:20:13.126Z" }, - { url = "https://files.pythonhosted.org/packages/b5/1a/3b88ccd3694681356f70da841630e4725a7264d6a885c8d442a697e1146b/numpy-2.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4e874c976154687c1f71715b034739b45c7711bec81db01914770373d125e392", size = 18403169, upload-time = "2026-03-29T13:20:17.096Z" }, - { url = "https://files.pythonhosted.org/packages/c2/c9/fcfd5d0639222c6eac7f304829b04892ef51c96a75d479214d77e3ce6e33/numpy-2.4.4-cp313-cp313t-win32.whl", hash = "sha256:9c585a1790d5436a5374bac930dad6ed244c046ed91b2b2a3634eb2971d21008", size = 6083477, upload-time = "2026-03-29T13:20:20.195Z" }, - { url = "https://files.pythonhosted.org/packages/d5/e3/3938a61d1c538aaec8ed6fd6323f57b0c2d2d2219512434c5c878db76553/numpy-2.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:93e15038125dc1e5345d9b5b68aa7f996ec33b98118d18c6ca0d0b7d6198b7e8", size = 12457487, upload-time = "2026-03-29T13:20:22.946Z" }, - { url = "https://files.pythonhosted.org/packages/97/6a/7e345032cc60501721ef94e0e30b60f6b0bd601f9174ebd36389a2b86d40/numpy-2.4.4-cp313-cp313t-win_arm64.whl", hash = "sha256:0dfd3f9d3adbe2920b68b5cd3d51444e13a10792ec7154cd0a2f6e74d4ab3233", size = 10292002, upload-time = "2026-03-29T13:20:25.909Z" }, - { url = "https://files.pythonhosted.org/packages/6e/06/c54062f85f673dd5c04cbe2f14c3acb8c8b95e3384869bb8cc9bff8cb9df/numpy-2.4.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f169b9a863d34f5d11b8698ead99febeaa17a13ca044961aa8e2662a6c7766a0", size = 16684353, upload-time = "2026-03-29T13:20:29.504Z" }, - { url = "https://files.pythonhosted.org/packages/4c/39/8a320264a84404c74cc7e79715de85d6130fa07a0898f67fb5cd5bd79908/numpy-2.4.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2483e4584a1cb3092da4470b38866634bafb223cbcd551ee047633fd2584599a", size = 14704914, upload-time = "2026-03-29T13:20:33.547Z" }, - { url = "https://files.pythonhosted.org/packages/91/fb/287076b2614e1d1044235f50f03748f31fa287e3dbe6abeb35cdfa351eca/numpy-2.4.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:2d19e6e2095506d1736b7d80595e0f252d76b89f5e715c35e06e937679ea7d7a", size = 5210005, upload-time = "2026-03-29T13:20:36.45Z" }, - { url = "https://files.pythonhosted.org/packages/63/eb/fcc338595309910de6ecabfcef2419a9ce24399680bfb149421fa2df1280/numpy-2.4.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:6a246d5914aa1c820c9443ddcee9c02bec3e203b0c080349533fae17727dfd1b", size = 6544974, upload-time = "2026-03-29T13:20:39.014Z" }, - { url = "https://files.pythonhosted.org/packages/44/5d/e7e9044032a716cdfaa3fba27a8e874bf1c5f1912a1ddd4ed071bf8a14a6/numpy-2.4.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:989824e9faf85f96ec9c7761cd8d29c531ad857bfa1daa930cba85baaecf1a9a", size = 15684591, upload-time = "2026-03-29T13:20:42.146Z" }, - { url = "https://files.pythonhosted.org/packages/98/7c/21252050676612625449b4807d6b695b9ce8a7c9e1c197ee6216c8a65c7c/numpy-2.4.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:27a8d92cd10f1382a67d7cf4db7ce18341b66438bdd9f691d7b0e48d104c2a9d", size = 16637700, upload-time = "2026-03-29T13:20:46.204Z" }, - { url = "https://files.pythonhosted.org/packages/b1/29/56d2bbef9465db24ef25393383d761a1af4f446a1df9b8cded4fe3a5a5d7/numpy-2.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e44319a2953c738205bf3354537979eaa3998ed673395b964c1176083dd46252", size = 17035781, upload-time = "2026-03-29T13:20:50.242Z" }, - { url = "https://files.pythonhosted.org/packages/e3/2b/a35a6d7589d21f44cea7d0a98de5ddcbb3d421b2622a5c96b1edf18707c3/numpy-2.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e892aff75639bbef0d2a2cfd55535510df26ff92f63c92cd84ef8d4ba5a5557f", size = 18362959, upload-time = "2026-03-29T13:20:54.019Z" }, - { url = "https://files.pythonhosted.org/packages/64/c9/d52ec581f2390e0f5f85cbfd80fb83d965fc15e9f0e1aec2195faa142cde/numpy-2.4.4-cp314-cp314-win32.whl", hash = "sha256:1378871da56ca8943c2ba674530924bb8ca40cd228358a3b5f302ad60cf875fc", size = 6008768, upload-time = "2026-03-29T13:20:56.912Z" }, - { url = "https://files.pythonhosted.org/packages/fa/22/4cc31a62a6c7b74a8730e31a4274c5dc80e005751e277a2ce38e675e4923/numpy-2.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:715d1c092715954784bc79e1174fc2a90093dc4dc84ea15eb14dad8abdcdeb74", size = 12449181, upload-time = "2026-03-29T13:20:59.548Z" }, - { url = "https://files.pythonhosted.org/packages/70/2e/14cda6f4d8e396c612d1bf97f22958e92148801d7e4f110cabebdc0eef4b/numpy-2.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:2c194dd721e54ecad9ad387c1d35e63dce5c4450c6dc7dd5611283dda239aabb", size = 10496035, upload-time = "2026-03-29T13:21:02.524Z" }, - { url = "https://files.pythonhosted.org/packages/b1/e8/8fed8c8d848d7ecea092dc3469643f9d10bc3a134a815a3b033da1d2039b/numpy-2.4.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2aa0613a5177c264ff5921051a5719d20095ea586ca88cc802c5c218d1c67d3e", size = 14824958, upload-time = "2026-03-29T13:21:05.671Z" }, - { url = "https://files.pythonhosted.org/packages/05/1a/d8007a5138c179c2bf33ef44503e83d70434d2642877ee8fbb230e7c0548/numpy-2.4.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:42c16925aa5a02362f986765f9ebabf20de75cdefdca827d14315c568dcab113", size = 5330020, upload-time = "2026-03-29T13:21:08.635Z" }, - { url = "https://files.pythonhosted.org/packages/99/64/ffb99ac6ae93faf117bcbd5c7ba48a7f45364a33e8e458545d3633615dda/numpy-2.4.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:874f200b2a981c647340f841730fc3a2b54c9d940566a3c4149099591e2c4c3d", size = 6650758, upload-time = "2026-03-29T13:21:10.949Z" }, - { url = "https://files.pythonhosted.org/packages/6e/6e/795cc078b78a384052e73b2f6281ff7a700e9bf53bcce2ee579d4f6dd879/numpy-2.4.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9b39d38a9bd2ae1becd7eac1303d031c5c110ad31f2b319c6e7d98b135c934d", size = 15729948, upload-time = "2026-03-29T13:21:14.047Z" }, - { url = "https://files.pythonhosted.org/packages/5f/86/2acbda8cc2af5f3d7bfc791192863b9e3e19674da7b5e533fded124d1299/numpy-2.4.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b268594bccac7d7cf5844c7732e3f20c50921d94e36d7ec9b79e9857694b1b2f", size = 16679325, upload-time = "2026-03-29T13:21:17.561Z" }, - { url = "https://files.pythonhosted.org/packages/bc/59/cafd83018f4aa55e0ac6fa92aa066c0a1877b77a615ceff1711c260ffae8/numpy-2.4.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ac6b31e35612a26483e20750126d30d0941f949426974cace8e6b5c58a3657b0", size = 17084883, upload-time = "2026-03-29T13:21:21.106Z" }, - { url = "https://files.pythonhosted.org/packages/f0/85/a42548db84e65ece46ab2caea3d3f78b416a47af387fcbb47ec28e660dc2/numpy-2.4.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8e3ed142f2728df44263aaf5fb1f5b0b99f4070c553a0d7f033be65338329150", size = 18403474, upload-time = "2026-03-29T13:21:24.828Z" }, - { url = "https://files.pythonhosted.org/packages/ed/ad/483d9e262f4b831000062e5d8a45e342166ec8aaa1195264982bca267e62/numpy-2.4.4-cp314-cp314t-win32.whl", hash = "sha256:dddbbd259598d7240b18c9d87c56a9d2fb3b02fe266f49a7c101532e78c1d871", size = 6155500, upload-time = "2026-03-29T13:21:28.205Z" }, - { url = "https://files.pythonhosted.org/packages/c7/03/2fc4e14c7bd4ff2964b74ba90ecb8552540b6315f201df70f137faa5c589/numpy-2.4.4-cp314-cp314t-win_amd64.whl", hash = "sha256:a7164afb23be6e37ad90b2f10426149fd75aee07ca55653d2aa41e66c4ef697e", size = 12637755, upload-time = "2026-03-29T13:21:31.107Z" }, - { url = "https://files.pythonhosted.org/packages/58/78/548fb8e07b1a341746bfbecb32f2c268470f45fa028aacdbd10d9bc73aab/numpy-2.4.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ba203255017337d39f89bdd58417f03c4426f12beed0440cfd933cb15f8669c7", size = 10566643, upload-time = "2026-03-29T13:21:34.339Z" }, - { url = "https://files.pythonhosted.org/packages/6b/33/8fae8f964a4f63ed528264ddf25d2b683d0b663e3cba26961eb838a7c1bd/numpy-2.4.4-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:58c8b5929fcb8287cbd6f0a3fae19c6e03a5c48402ae792962ac465224a629a4", size = 16854491, upload-time = "2026-03-29T13:21:38.03Z" }, - { url = "https://files.pythonhosted.org/packages/bc/d0/1aabee441380b981cf8cdda3ae7a46aa827d1b5a8cce84d14598bc94d6d9/numpy-2.4.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:eea7ac5d2dce4189771cedb559c738a71512768210dc4e4753b107a2048b3d0e", size = 14895830, upload-time = "2026-03-29T13:21:41.509Z" }, - { url = "https://files.pythonhosted.org/packages/a5/b8/aafb0d1065416894fccf4df6b49ef22b8db045187949545bced89c034b8e/numpy-2.4.4-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:51fc224f7ca4d92656d5a5eb315f12eb5fe2c97a66249aa7b5f562528a3be38c", size = 5400927, upload-time = "2026-03-29T13:21:44.747Z" }, - { url = "https://files.pythonhosted.org/packages/d6/77/063baa20b08b431038c7f9ff5435540c7b7265c78cf56012a483019ca72d/numpy-2.4.4-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:28a650663f7314afc3e6ec620f44f333c386aad9f6fc472030865dc0ebb26ee3", size = 6715557, upload-time = "2026-03-29T13:21:47.406Z" }, - { url = "https://files.pythonhosted.org/packages/c7/a8/379542d45a14f149444c5c4c4e7714707239ce9cc1de8c2803958889da14/numpy-2.4.4-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:19710a9ca9992d7174e9c52f643d4272dcd1558c5f7af7f6f8190f633bd651a7", size = 15804253, upload-time = "2026-03-29T13:21:50.753Z" }, - { url = "https://files.pythonhosted.org/packages/a2/c8/f0a45426d6d21e7ea3310a15cf90c43a14d9232c31a837702dba437f3373/numpy-2.4.4-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9b2aec6af35c113b05695ebb5749a787acd63cafc83086a05771d1e1cd1e555f", size = 16753552, upload-time = "2026-03-29T13:21:54.344Z" }, - { url = "https://files.pythonhosted.org/packages/04/74/f4c001f4714c3ad9ce037e18cf2b9c64871a84951eaa0baf683a9ca9301c/numpy-2.4.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f2cf083b324a467e1ab358c105f6cad5ea950f50524668a80c486ff1db24e119", size = 12509075, upload-time = "2026-03-29T13:21:57.644Z" }, -] - -[[package]] -name = "openai" -version = "2.30.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "distro" }, - { name = "httpx" }, - { name = "jiter" }, - { name = "pydantic" }, - { name = "sniffio" }, - { name = "tqdm" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/88/15/52580c8fbc16d0675d516e8749806eda679b16de1e4434ea06fb6feaa610/openai-2.30.0.tar.gz", hash = "sha256:92f7661c990bda4b22a941806c83eabe4896c3094465030dd882a71abe80c885", size = 676084, upload-time = "2026-03-25T22:08:59.96Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/9e/5bfa2270f902d5b92ab7d41ce0475b8630572e71e349b2a4996d14bdda93/openai-2.30.0-py3-none-any.whl", hash = "sha256:9a5ae616888eb2748ec5e0c5b955a51592e0b201a11f4262db920f2a78c5231d", size = 1146656, upload-time = "2026-03-25T22:08:58.2Z" }, -] - -[[package]] -name = "openenv" -version = "0.1.13" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/35/94/c47e8f7303452793a3519c8cbc1b31dfffdedd13aaed821958ab3f152927/openenv-0.1.13.tar.gz", hash = "sha256:726971d2289472c1c20261436bcccdf3edfcf0b201d16aec127815bd83bfcb3d", size = 5112, upload-time = "2020-12-16T11:49:39.777Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/33/7f/e6f4467528161b8f0eb2ec784f4bbcd1fa9ea7acad13c0fb18597013e83b/openenv-0.1.13-py3-none-any.whl", hash = "sha256:813249d7f526f40c6e8b325f705294761a5bc887b9144c3383fa2bae7baa7726", size = 12080, upload-time = "2020-12-16T11:49:38.816Z" }, -] - -[[package]] -name = "osint-rl-env" -version = "0.1.0" -source = { editable = "." } -dependencies = [ - { name = "fastapi" }, - { name = "openai" }, - { name = "openenv" }, - { name = "requests" }, - { name = "uvicorn" }, -] - -[package.optional-dependencies] -dev = [ - { name = "pytest" }, -] - -[package.metadata] -requires-dist = [ - { name = "fastapi", specifier = ">=0.115.0" }, - { name = "openai", specifier = ">=1.40.0" }, - { name = "openenv", specifier = ">=0.1.13" }, - { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0.0" }, - { name = "requests", specifier = ">=2.32.3" }, - { name = "uvicorn", specifier = ">=0.30.0" }, -] -provides-extras = ["dev"] - -[[package]] -name = "packaging" -version = "26.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, -] - -[[package]] -name = "pluggy" -version = "1.6.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, -] - -[[package]] -name = "pydantic" -version = "2.12.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "annotated-types" }, - { name = "pydantic-core" }, - { name = "typing-extensions" }, - { name = "typing-inspection" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, -] - -[[package]] -name = "pydantic-core" -version = "2.41.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/90/32c9941e728d564b411d574d8ee0cf09b12ec978cb22b294995bae5549a5/pydantic_core-2.41.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146", size = 2107298, upload-time = "2025-11-04T13:39:04.116Z" }, - { url = "https://files.pythonhosted.org/packages/fb/a8/61c96a77fe28993d9a6fb0f4127e05430a267b235a124545d79fea46dd65/pydantic_core-2.41.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2", size = 1901475, upload-time = "2025-11-04T13:39:06.055Z" }, - { url = "https://files.pythonhosted.org/packages/5d/b6/338abf60225acc18cdc08b4faef592d0310923d19a87fba1faf05af5346e/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97", size = 1918815, upload-time = "2025-11-04T13:39:10.41Z" }, - { url = "https://files.pythonhosted.org/packages/d1/1c/2ed0433e682983d8e8cba9c8d8ef274d4791ec6a6f24c58935b90e780e0a/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9", size = 2065567, upload-time = "2025-11-04T13:39:12.244Z" }, - { url = "https://files.pythonhosted.org/packages/b3/24/cf84974ee7d6eae06b9e63289b7b8f6549d416b5c199ca2d7ce13bbcf619/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52", size = 2230442, upload-time = "2025-11-04T13:39:13.962Z" }, - { url = "https://files.pythonhosted.org/packages/fd/21/4e287865504b3edc0136c89c9c09431be326168b1eb7841911cbc877a995/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941", size = 2350956, upload-time = "2025-11-04T13:39:15.889Z" }, - { url = "https://files.pythonhosted.org/packages/a8/76/7727ef2ffa4b62fcab916686a68a0426b9b790139720e1934e8ba797e238/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a", size = 2068253, upload-time = "2025-11-04T13:39:17.403Z" }, - { url = "https://files.pythonhosted.org/packages/d5/8c/a4abfc79604bcb4c748e18975c44f94f756f08fb04218d5cb87eb0d3a63e/pydantic_core-2.41.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c", size = 2177050, upload-time = "2025-11-04T13:39:19.351Z" }, - { url = "https://files.pythonhosted.org/packages/67/b1/de2e9a9a79b480f9cb0b6e8b6ba4c50b18d4e89852426364c66aa82bb7b3/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2", size = 2147178, upload-time = "2025-11-04T13:39:21Z" }, - { url = "https://files.pythonhosted.org/packages/16/c1/dfb33f837a47b20417500efaa0378adc6635b3c79e8369ff7a03c494b4ac/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556", size = 2341833, upload-time = "2025-11-04T13:39:22.606Z" }, - { url = "https://files.pythonhosted.org/packages/47/36/00f398642a0f4b815a9a558c4f1dca1b4020a7d49562807d7bc9ff279a6c/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49", size = 2321156, upload-time = "2025-11-04T13:39:25.843Z" }, - { url = "https://files.pythonhosted.org/packages/7e/70/cad3acd89fde2010807354d978725ae111ddf6d0ea46d1ea1775b5c1bd0c/pydantic_core-2.41.5-cp310-cp310-win32.whl", hash = "sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba", size = 1989378, upload-time = "2025-11-04T13:39:27.92Z" }, - { url = "https://files.pythonhosted.org/packages/76/92/d338652464c6c367e5608e4488201702cd1cbb0f33f7b6a85a60fe5f3720/pydantic_core-2.41.5-cp310-cp310-win_amd64.whl", hash = "sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9", size = 2013622, upload-time = "2025-11-04T13:39:29.848Z" }, - { url = "https://files.pythonhosted.org/packages/e8/72/74a989dd9f2084b3d9530b0915fdda64ac48831c30dbf7c72a41a5232db8/pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6", size = 2105873, upload-time = "2025-11-04T13:39:31.373Z" }, - { url = "https://files.pythonhosted.org/packages/12/44/37e403fd9455708b3b942949e1d7febc02167662bf1a7da5b78ee1ea2842/pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b", size = 1899826, upload-time = "2025-11-04T13:39:32.897Z" }, - { url = "https://files.pythonhosted.org/packages/33/7f/1d5cab3ccf44c1935a359d51a8a2a9e1a654b744b5e7f80d41b88d501eec/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a", size = 1917869, upload-time = "2025-11-04T13:39:34.469Z" }, - { url = "https://files.pythonhosted.org/packages/6e/6a/30d94a9674a7fe4f4744052ed6c5e083424510be1e93da5bc47569d11810/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8", size = 2063890, upload-time = "2025-11-04T13:39:36.053Z" }, - { url = "https://files.pythonhosted.org/packages/50/be/76e5d46203fcb2750e542f32e6c371ffa9b8ad17364cf94bb0818dbfb50c/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e", size = 2229740, upload-time = "2025-11-04T13:39:37.753Z" }, - { url = "https://files.pythonhosted.org/packages/d3/ee/fed784df0144793489f87db310a6bbf8118d7b630ed07aa180d6067e653a/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1", size = 2350021, upload-time = "2025-11-04T13:39:40.94Z" }, - { url = "https://files.pythonhosted.org/packages/c8/be/8fed28dd0a180dca19e72c233cbf58efa36df055e5b9d90d64fd1740b828/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b", size = 2066378, upload-time = "2025-11-04T13:39:42.523Z" }, - { url = "https://files.pythonhosted.org/packages/b0/3b/698cf8ae1d536a010e05121b4958b1257f0b5522085e335360e53a6b1c8b/pydantic_core-2.41.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b", size = 2175761, upload-time = "2025-11-04T13:39:44.553Z" }, - { url = "https://files.pythonhosted.org/packages/b8/ba/15d537423939553116dea94ce02f9c31be0fa9d0b806d427e0308ec17145/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284", size = 2146303, upload-time = "2025-11-04T13:39:46.238Z" }, - { url = "https://files.pythonhosted.org/packages/58/7f/0de669bf37d206723795f9c90c82966726a2ab06c336deba4735b55af431/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594", size = 2340355, upload-time = "2025-11-04T13:39:48.002Z" }, - { url = "https://files.pythonhosted.org/packages/e5/de/e7482c435b83d7e3c3ee5ee4451f6e8973cff0eb6007d2872ce6383f6398/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e", size = 2319875, upload-time = "2025-11-04T13:39:49.705Z" }, - { 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/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403, upload-time = "2025-11-04T13:40:25.248Z" }, - { url = "https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206, upload-time = "2025-11-04T13:40:27.099Z" }, - { url = "https://files.pythonhosted.org/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307, upload-time = "2025-11-04T13:40:29.806Z" }, - { url = "https://files.pythonhosted.org/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258, upload-time = "2025-11-04T13:40:33.544Z" }, - { url = "https://files.pythonhosted.org/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917, upload-time = "2025-11-04T13:40:35.479Z" }, - { url = "https://files.pythonhosted.org/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186, upload-time = "2025-11-04T13:40:37.436Z" }, - { url = "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164, upload-time = "2025-11-04T13:40:40.289Z" }, - { url = "https://files.pythonhosted.org/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146, upload-time = "2025-11-04T13:40:42.809Z" }, - { url = "https://files.pythonhosted.org/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788, upload-time = "2025-11-04T13:40:44.752Z" }, - { url = "https://files.pythonhosted.org/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133, upload-time = "2025-11-04T13:40:46.66Z" }, - { url = "https://files.pythonhosted.org/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852, upload-time = "2025-11-04T13:40:48.575Z" }, - { url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679, upload-time = "2025-11-04T13:40:50.619Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766, upload-time = "2025-11-04T13:40:52.631Z" }, - { url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005, upload-time = "2025-11-04T13:40:54.734Z" }, - { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, - { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, - { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, - { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, - { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, - { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, - { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, - { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, - { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, - { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, - { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, - { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, - { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, - { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, - { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, - { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, - { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, - { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, - { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, - { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, - { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, - { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, - { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, - { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, - { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, - { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, - { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, - { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, - { 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/e6/b0/1a2aa41e3b5a4ba11420aba2d091b2d17959c8d1519ece3627c371951e73/pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8", size = 2103351, upload-time = "2025-11-04T13:43:02.058Z" }, - { url = "https://files.pythonhosted.org/packages/a4/ee/31b1f0020baaf6d091c87900ae05c6aeae101fa4e188e1613c80e4f1ea31/pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a", size = 1925363, upload-time = "2025-11-04T13:43:05.159Z" }, - { url = "https://files.pythonhosted.org/packages/e1/89/ab8e86208467e467a80deaca4e434adac37b10a9d134cd2f99b28a01e483/pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b", size = 2135615, upload-time = "2025-11-04T13:43:08.116Z" }, - { url = "https://files.pythonhosted.org/packages/99/0a/99a53d06dd0348b2008f2f30884b34719c323f16c3be4e6cc1203b74a91d/pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2", size = 2175369, upload-time = "2025-11-04T13:43:12.49Z" }, - { url = "https://files.pythonhosted.org/packages/6d/94/30ca3b73c6d485b9bb0bc66e611cff4a7138ff9736b7e66bcf0852151636/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093", size = 2144218, upload-time = "2025-11-04T13:43:15.431Z" }, - { url = "https://files.pythonhosted.org/packages/87/57/31b4f8e12680b739a91f472b5671294236b82586889ef764b5fbc6669238/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a", size = 2329951, upload-time = "2025-11-04T13:43:18.062Z" }, - { url = "https://files.pythonhosted.org/packages/7d/73/3c2c8edef77b8f7310e6fb012dbc4b8551386ed575b9eb6fb2506e28a7eb/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963", size = 2318428, upload-time = "2025-11-04T13:43:20.679Z" }, - { url = "https://files.pythonhosted.org/packages/2f/02/8559b1f26ee0d502c74f9cca5c0d2fd97e967e083e006bbbb4e97f3a043a/pydantic_core-2.41.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a", size = 2147009, upload-time = "2025-11-04T13:43:23.286Z" }, - { 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" }, - { url = "https://files.pythonhosted.org/packages/83/d9/8412d7f06f616bbc053d30cb4e5f76786af3221462ad5eee1f202021eb4e/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1", size = 2174762, upload-time = "2025-11-04T13:43:34.744Z" }, - { url = "https://files.pythonhosted.org/packages/55/4c/162d906b8e3ba3a99354e20faa1b49a85206c47de97a639510a0e673f5da/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84", size = 2143141, upload-time = "2025-11-04T13:43:37.701Z" }, - { url = "https://files.pythonhosted.org/packages/1f/f2/f11dd73284122713f5f89fc940f370d035fa8e1e078d446b3313955157fe/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770", size = 2330317, upload-time = "2025-11-04T13:43:40.406Z" }, - { url = "https://files.pythonhosted.org/packages/88/9d/b06ca6acfe4abb296110fb1273a4d848a0bfb2ff65f3ee92127b3244e16b/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f", size = 2316992, upload-time = "2025-11-04T13:43:43.602Z" }, - { url = "https://files.pythonhosted.org/packages/36/c7/cfc8e811f061c841d7990b0201912c3556bfeb99cdcb7ed24adc8d6f8704/pydantic_core-2.41.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51", size = 2145302, upload-time = "2025-11-04T13:43:46.64Z" }, -] - -[[package]] -name = "pygments" -version = "2.20.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, -] - -[[package]] -name = "pytest" -version = "9.0.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, - { name = "iniconfig" }, - { name = "packaging" }, - { name = "pluggy" }, - { name = "pygments" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" }, -] - -[[package]] -name = "requests" -version = "2.33.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "charset-normalizer" }, - { name = "idna" }, - { name = "urllib3" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5f/a4/98b9c7c6428a668bf7e42ebb7c79d576a1c3c1e3ae2d47e674b468388871/requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517", size = 134120, upload-time = "2026-03-30T16:09:15.531Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a", size = 64947, upload-time = "2026-03-30T16:09:13.83Z" }, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, -] - -[[package]] -name = "starlette" -version = "1.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/81/69/17425771797c36cded50b7fe44e850315d039f28b15901ab44839e70b593/starlette-1.0.0.tar.gz", hash = "sha256:6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149", size = 2655289, upload-time = "2026-03-22T18:29:46.779Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-py3-none-any.whl", hash = "sha256:d3ec55e0bb321692d275455ddfd3df75fff145d009685eb40dc91fc66b03d38b", size = 72651, upload-time = "2026-03-22T18:29:45.111Z" }, -] - -[[package]] -name = "tomli" -version = "2.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704, upload-time = "2026-03-25T20:21:10.473Z" }, - { url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454, upload-time = "2026-03-25T20:21:12.036Z" }, - { url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561, upload-time = "2026-03-25T20:21:13.098Z" }, - { url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824, upload-time = "2026-03-25T20:21:14.569Z" }, - { url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227, upload-time = "2026-03-25T20:21:15.712Z" }, - { url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859, upload-time = "2026-03-25T20:21:17.001Z" }, - { url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204, upload-time = "2026-03-25T20:21:18.079Z" }, - { url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084, upload-time = "2026-03-25T20:21:18.978Z" }, - { url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285, upload-time = "2026-03-25T20:21:20.309Z" }, - { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924, upload-time = "2026-03-25T20:21:21.626Z" }, - { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018, upload-time = "2026-03-25T20:21:23.002Z" }, - { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948, upload-time = "2026-03-25T20:21:24.04Z" }, - { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341, upload-time = "2026-03-25T20:21:25.177Z" }, - { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159, upload-time = "2026-03-25T20:21:26.364Z" }, - { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290, upload-time = "2026-03-25T20:21:27.46Z" }, - { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141, upload-time = "2026-03-25T20:21:28.492Z" }, - { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847, upload-time = "2026-03-25T20:21:29.386Z" }, - { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088, upload-time = "2026-03-25T20:21:30.677Z" }, - { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866, upload-time = "2026-03-25T20:21:31.65Z" }, - { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887, upload-time = "2026-03-25T20:21:33.028Z" }, - { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704, upload-time = "2026-03-25T20:21:34.51Z" }, - { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628, upload-time = "2026-03-25T20:21:36.012Z" }, - { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180, upload-time = "2026-03-25T20:21:37.136Z" }, - { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674, upload-time = "2026-03-25T20:21:38.298Z" }, - { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976, upload-time = "2026-03-25T20:21:39.316Z" }, - { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755, upload-time = "2026-03-25T20:21:40.248Z" }, - { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265, upload-time = "2026-03-25T20:21:41.219Z" }, - { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726, upload-time = "2026-03-25T20:21:42.23Z" }, - { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859, upload-time = "2026-03-25T20:21:43.386Z" }, - { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713, upload-time = "2026-03-25T20:21:44.474Z" }, - { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084, upload-time = "2026-03-25T20:21:45.62Z" }, - { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973, upload-time = "2026-03-25T20:21:46.937Z" }, - { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223, upload-time = "2026-03-25T20:21:48.467Z" }, - { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973, upload-time = "2026-03-25T20:21:49.526Z" }, - { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082, upload-time = "2026-03-25T20:21:50.506Z" }, - { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490, upload-time = "2026-03-25T20:21:51.474Z" }, - { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263, upload-time = "2026-03-25T20:21:52.543Z" }, - { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736, upload-time = "2026-03-25T20:21:53.674Z" }, - { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717, upload-time = "2026-03-25T20:21:55.129Z" }, - { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461, upload-time = "2026-03-25T20:21:56.228Z" }, - { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855, upload-time = "2026-03-25T20:21:57.653Z" }, - { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144, upload-time = "2026-03-25T20:21:59.089Z" }, - { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683, upload-time = "2026-03-25T20:22:00.214Z" }, - { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196, upload-time = "2026-03-25T20:22:01.169Z" }, - { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393, upload-time = "2026-03-25T20:22:02.137Z" }, - { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, -] - -[[package]] -name = "tqdm" -version = "4.67.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/09/a9/6ba95a270c6f1fbcd8dac228323f2777d886cb206987444e4bce66338dd4/tqdm-4.67.3.tar.gz", hash = "sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb", size = 169598, upload-time = "2026-02-03T17:35:53.048Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl", hash = "sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf", size = 78374, upload-time = "2026-02-03T17:35:50.982Z" }, -] - -[[package]] -name = "typing-extensions" -version = "4.15.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, -] - -[[package]] -name = "typing-inspection" -version = "0.4.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, -] - -[[package]] -name = "urllib3" -version = "2.6.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, -] - -[[package]] -name = "uvicorn" -version = "0.42.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "h11" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e3/ad/4a96c425be6fb67e0621e62d86c402b4a17ab2be7f7c055d9bd2f638b9e2/uvicorn-0.42.0.tar.gz", hash = "sha256:9b1f190ce15a2dd22e7758651d9b6d12df09a13d51ba5bf4fc33c383a48e1775", size = 85393, upload-time = "2026-03-16T06:19:50.077Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0a/89/f8827ccff89c1586027a105e5630ff6139a64da2515e24dafe860bd9ae4d/uvicorn-0.42.0-py3-none-any.whl", hash = "sha256:96c30f5c7abe6f74ae8900a70e92b85ad6613b745d4879eb9b16ccad15645359", size = 68830, upload-time = "2026-03-16T06:19:48.325Z" }, -] diff --git a/scratch/sre/Dockerfile b/scratch/sre/Dockerfile deleted file mode 100644 index f26454edcfc5164b093c83ad64b27f4b50cf75d9..0000000000000000000000000000000000000000 --- a/scratch/sre/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM python:3.11-slim - -WORKDIR /app -COPY requirements.txt . -RUN pip install --no-cache-dir -r requirements.txt - -COPY . . - -EXPOSE 7860 -CMD ["uvicorn", "server.app:app", "--host", "0.0.0.0", "--port", "7860"] diff --git a/scratch/sre/README.md b/scratch/sre/README.md deleted file mode 100644 index fa4c15744d3e846281c4bcb2f3a860d57451bff6..0000000000000000000000000000000000000000 --- a/scratch/sre/README.md +++ /dev/null @@ -1,454 +0,0 @@ ---- -title: Sre Automation Env -emoji: 😻 -colorFrom: green -colorTo: pink -sdk: docker -pinned: false ---- - -# 🚨 sre-automation-env - -> An [OpenEnv](https://huggingface.co/spaces/open-env/leaderboard)-compatible reinforcement learning environment that simulates the daily work of a Site Reliability Engineer. Agents must triage noisy alert queues, diagnose cascading production incidents across a microservice graph, execute operational runbooks with stateful parameter dependencies, and handle advanced SRE scenarios. - ---- - -## 1. Environment Description & Motivation - -Site Reliability Engineering is a **\$30B+ market** where every minute of downtime costs real revenue. Alert fatigue is the #1 cause of missed incidents — human SREs are bombarded with hundreds of alerts per shift, most of which are noise. The operational decisions they make — which alerts to ignore, where to look first, what remediation steps to take — are exactly the kind of sequential, high-stakes reasoning that RL agents should learn. - -`sre-automation-env` captures this operational reality across **9 tasks** organized into 3 difficulty tiers: - -### 🟢 Easy — Foundational SRE Skills - -- **Alert Triage** mirrors the PagerDuty/OpsGenie workflow: sort through noisy, flapping, duplicate alerts and acknowledge the critical ones first. -- **On-Call Handoff** tests shift rotation communication: summarize active incidents, pending actions, and service health for the incoming engineer. -- **Capacity Planning** analyzes metrics trends and recommends scaling decisions based on utilization, growth rate, and upcoming events. - -### 🟡 Medium — Diagnostic & Remediation Skills - -- **Incident Diagnosis** simulates the real-time investigation an on-call SRE does during a production outage — querying metrics, reading logs, tracing cascading failures through a dependency graph. -- **Multi-Incident Correlation** determines whether multiple simultaneous alerts share a common root cause or are independent incidents requiring separate handling. -- **Auto-Remediation with Rollback** executes a fix, verifies if it improved the situation, and rolls back if it made things worse — testing judgment under uncertainty. - -### 🔴 Hard — Complex Operational Reasoning - -- **Runbook Execution** tests procedural reasoning: can the agent follow a multi-step operational playbook where each step's output feeds into the next? -- **Blameless Postmortem Generation** synthesizes incident timeline, root cause analysis, and actionable follow-ups into a professional postmortem document. -- **Chaos Engineering Scenario** injects a controlled failure, observes system impact, and executes mitigation steps in the correct order to restore stability. - -### Service Topology - -The environment uses a realistic microservice dependency graph where failures cascade through the chain: - -```mermaid -graph LR - A[api-gateway] --> B[auth-service] - B --> C[user-service] - B --> D[payment-service] - D --> E[db-service] - - style A fill:#4a90d9,stroke:#333,color:#fff - style B fill:#7b68ee,stroke:#333,color:#fff - style C fill:#50c878,stroke:#333,color:#fff - style D fill:#ff6b6b,stroke:#333,color:#fff - style E fill:#ffa500,stroke:#333,color:#fff -``` - -When `db-service` has high latency, it cascades up through `payment-service` → `auth-service` → `api-gateway`. This mirrors real production architectures where identifying the *root cause* vs. a *symptom* is the core diagnostic challenge. - ---- - -## 2. Task Matrix - -| Task | Difficulty | Max Steps | Target Score (GPT-4o) | Success Criteria | -|---|---|---|---|---| -| **Alert Triage** | 🟢 Easy | 10 | ~0.7 | Ignore flapping/duplicate alerts, acknowledge actionable alerts in P1→P2→P3 order | -| **On-Call Handoff** | 🟢 Easy | 6 | ~0.6 | Summarize active incidents, pending actions, severity levels, and service health | -| **Capacity Planning** | 🟢 Easy | 5 | ~0.6 | Query data, recommend correct scaling action with accurate replica count | -| **Incident Diagnosis** | 🟡 Medium | 12 | ~0.5 | Query selective metrics/logs, identify root cause service + failure mode | -| **Multi-Incident Correlation** | 🟡 Medium | 10 | ~0.5 | Correctly classify alerts as shared/independent/partial correlation | -| **Auto-Remediation** | 🟡 Medium | 8 | ~0.5 | Choose correct fix, verify recovery, rollback if needed | -| **Runbook Execution** | 🔴 Hard | 15 | ~0.3 | Execute all 7 runbook steps in order with correct parameters (including extracted pid) | -| **Blameless Postmortem** | 🔴 Hard | 8 | ~0.4 | Write all 5 sections with substantive content matching incident data | -| **Chaos Engineering** | 🔴 Hard | 12 | ~0.4 | Inject failure, observe impact, mitigate in correct order | - ---- - -## 3. Action Space - -| `action_type` | `target` | `parameters` | Used In | -|---|---|---|---| -| `triage` | Alert ID | `{"decision": "ignore\|actionable", "priority": "P1\|P2\|P3"}` | Alert Triage | -| `acknowledge` | Alert ID | Optional `{"priority": "P1"}` | Alert Triage | -| `diagnose` | Service name | `{"operation": "query_metrics\|query_logs\|submit_diagnosis", "failure_mode": "..."}` | Incident Diagnosis, Multi-Incident, Postmortem | -| `execute_step` | Runbook step name | Step-specific params: `service`, `pid`, `instance_id`, `replicas`, `wait_seconds`, `summary` | Runbook Execution | -| `escalate` | Any target | Optional escalation metadata | All tasks | -| `resolve` | Task target | Confirmation / no-op | All tasks | -| `summarize` | `"handoff"` | `{"summary": ""}` | On-Call Handoff | -| `query_capacity` | Service name | `{}` | Capacity Planning | -| `recommend_scaling` | Service name | `{"recommendation": "...", "target_replicas": }` | Capacity Planning | -| `correlate` | `"all"` | `{"correlation_type": "...", "root_cause_service": "...", "alert_ids": [...]}` | Multi-Incident | -| `remediate` | Service name | `{"action": ""}` | Auto-Remediation | -| `verify_recovery` | — | `{}` | Auto-Remediation, Chaos | -| `rollback` | — | `{}` | Auto-Remediation | -| `write_postmortem` | `"postmortem"` | `{"section": "...", "content": "..."}` | Blameless Postmortem | -| `inject_chaos` | Target service | `{}` | Chaos Engineering | -| `observe_impact` | Target service | `{}` | Chaos Engineering | -| `mitigate_chaos` | — | `{"step": ""}` | Chaos Engineering | - ---- - -## 4. Observation Space - -| Field | Type | Description | -|---|---|---| -| `task_id` | `string` | Current task identifier | -| `step` | `integer` | Current step count (0-indexed) | -| `context` | `object` | Task-specific instructions, progress tracking, SLO status, incident timeline | -| `available_actions` | `array[string]` | Allowed action types for the current task | -| `alert_queue` | `array[object]` | Current alerts with severity, flapping/duplicate flags, status | -| `service_map` | `object` | Microservice dependency graph | -| `metrics` | `object` | Per-service metrics (cpu%, mem%, latency_p99, error_rate) or SLO status | -| `logs` | `array[string]` | Visible service logs (revealed incrementally via queries) | -| `done` | `boolean` | Episode termination flag | -| `message` | `string` | Environment feedback on the last action | - ---- - -## 5. Task Descriptions - -### 🟢 Easy Tasks - -
    -Alert Triage — 8 alerts, mixed severity, some noisy - -The agent receives 8 firing alerts randomly sampled from a pool of 20. Some are flapping (intermittent), some are duplicates. The agent must: -1. Triage each alert as ignore or actionable with correct priority -2. Acknowledge actionable alerts in descending priority order (P1 first) - -The challenge: noisy alerts waste steps, and acknowledging in wrong order loses points. -
    - -
    -On-Call Handoff — Summarize shift for incoming engineer - -The agent receives active incidents, pending actions, and service health data from a shift rotation. It must produce a concise handoff summary that covers all incidents, their severity, pending actions, and service health. Rewards for mentioning all incidents, action items, severity levels, and writing a summary of sufficient length. -
    - -
    -Capacity Planning — Analyze metrics, recommend scaling - -The agent analyzes service metrics (CPU, memory, latency, RPS), traffic trends, growth rates, and upcoming peak events. It must query data first, then recommend the correct scaling action (scale_out, scale_in, no_change, scale_out_urgent) with an accurate target replica count. -
    - -### 🟡 Medium Tasks - -
    -Incident Diagnosis — 5 failure modes across 5 services - -One of 5 failure modes is randomly injected at reset: -- **db-service**: High latency (cascades up through payment → auth → gateway) -- **auth-service**: High error rate (blocks login flow) -- **payment-service**: Memory leak (OOM restarts) -- **api-gateway**: Config drift (wrong upstream target) -- **user-service**: Deprecated endpoint dependency - -Metrics are hidden until queried (1 step per query). The agent must efficiently gather evidence and submit a diagnosis. SLO burn rates and an incident timeline provide additional signal. -
    - -
    -Multi-Incident Correlation — Shared vs independent root causes - -Multiple alerts fire simultaneously. The agent must determine if they share a common root cause (all cascading from one service), are fully independent (each is a separate issue), or partially correlated (some share a root cause, others are independent). Requires querying metrics for affected services and analyzing patterns. -
    - -
    -Auto-Remediation with Rollback — Fix, verify, rollback if needed - -The agent must choose a remediation action from multiple options. The correct action fixes the root cause. Wrong actions may make things worse or only partially help. After executing, the agent must verify recovery and rollback if the fix degraded metrics. Tests judgment under uncertainty. -
    - -### 🔴 Hard Tasks - -
    -Runbook Execution — 7-step operational playbook with parameter dependencies - -The runbook "High memory pressure — payment-service" has 7 steps that MUST be executed in order. Step 2 (`identify_top_processes`) reveals a `pid` and `instance_id` that are required for steps 3 and 4. This parameter extraction creates a genuine dependency chain that tests the agent's ability to use tool outputs. -
    - -
    -Blameless Postmortem — Write professional incident documentation - -The agent must query incident data (timeline, impact, root cause, action items) and write 5 sections of a blameless postmortem: summary, timeline, root_cause, impact, and action_items. Each section is graded for substantive content, keyword matching, and coverage of the incident details. -
    - -
    -Chaos Engineering — Inject, observe, mitigate controlled failures - -The agent runs a chaos experiment: inject a failure (network partition, pod termination, or DB failover), observe the cascading impact across the service topology, then execute mitigation steps in the correct sequential order. Tests understanding of failure containment and recovery patterns. -
    - ---- - -## 6. Reward Function Design - -All tasks use **dense, interpretable partial credit**. Agents receive meaningful signal for intermediate progress instead of binary pass/fail. - -### Alert Triage Rewards - -| Component | Weight | Description | -|---|---|---| -| Coverage (weighted Jaccard) | 0.55 | Acknowledging the right alerts, weighted by priority | -| Correct ignores | 0.1 each | Correctly identifying flapping/duplicate alerts | -| First-ack priority | 0.2 | Acknowledging a P1 alert first | -| Ordering accuracy | 0.15 | Maintaining correct priority ordering | -| P1 penalty | -0.1 each | P1 alerts left unacknowledged at episode end | - -### On-Call Handoff Rewards - -| Component | Weight | Description | -|---|---|---| -| Incident coverage | 0.3 | Mentioning all active incidents | -| Action items coverage | 0.25 | Referencing pending actions | -| Severity mentioned | 0.15 | Including severity levels | -| Health mentioned | 0.1 | Referencing service health | -| Length bonus | 0.1 | Summary >= 20 words | -| Efficiency bonus | 0.1 | Completed in ≤3 steps | - -### Capacity Planning Rewards - -| Component | Weight | Description | -|---|---|---| -| Correct recommendation | 0.5 | Matching the correct scaling action | -| Correct replica count | 0.3 | Accurate target replica number | -| Queried data first | 0.1 | Querying metrics before deciding | -| Efficiency bonus | 0.1 | Completed in ≤3 steps | - -### Incident Diagnosis Rewards - -| Component | Weight | Description | -|---|---|---| -| Root cause service | 0.5 | Exact match on the faulty service | -| Upstream partial credit | 0.1 | Naming a direct upstream of the root cause | -| Failure mode match | 0.2 | Fuzzy keyword match on failure description | -| Evidence collection | 0.05 + 0.05 | Querying metrics and logs for the root cause service | -| Efficiency bonus | 0.0–0.2 | Linear scale: full bonus at ≤8 steps, zero at ≥12 | -| Query penalty | -0.05 each | Unnecessary metric queries beyond 6 | - -### Multi-Incident Correlation Rewards - -| Component | Weight | Description | -|---|---|---| -| Correlation type | 0.4 | Correct classification (shared/independent/partial) | -| Root cause identification | 0.3 | Correct root cause service or "none" | -| Alert grouping | 0.2 | Correctly grouping/ungrouping alerts | -| Evidence bonus | 0.1 | Querying metrics for affected services | - -### Auto-Remediation Rewards - -| Component | Weight | Description | -|---|---|---| -| Correct action chosen | 0.4 | Picking the remediation that fixes root cause | -| Outcome score | 0.4 | Success=0.4, rollback=0.2, partial=0.1, worse=0 | -| Recovery verified | 0.1 | Actually checking the result | -| Efficiency bonus | 0.1 | Completed in ≤5 steps | -| Rollback penalty | -0.2 | Made things worse but didn't rollback | - -### Runbook Execution Rewards - -| Component | Weight | Description | -|---|---|---| -| Step completion | 0.1 each (max 0.7) | Per correctly executed step | -| PID extraction | 0.1 | Correctly extracting and using pid from step 2 | -| Report quality | 0.1 | Incident report with severity, service name, coherent summary | -| Out-of-order penalty | -0.05 each | Attempting steps in wrong order | -| Wrong parameter penalty | -0.05 each | Incorrect parameter values | - -### Blameless Postmortem Rewards - -| Component | Weight | Description | -|---|---|---| -| Sections completed | 0.12 each (max 0.6) | Per required section written | -| Content quality | 0.2 | Substantive content (15+ words per section) | -| Root cause keywords | 0.1 | Matching keywords from actual root cause | -| Action items coverage | 0.08 | Referencing identified action items | -| Evidence bonus | 0.1 | Querying incident data before writing | - -### Chaos Engineering Rewards - -| Component | Weight | Description | -|---|---|---| -| Chaos injected | 0.1 | Successfully injecting the failure | -| Impact observed | 0.1 | Checking the effects before mitigating | -| Mitigation steps | 0.15 each | Per step completed in correct order | -| Completion bonus | 0.2 | All mitigation steps completed | -| Efficiency bonus | 0.15 | All steps done in ≤8 steps | -| Wrong order penalty | -0.05 each | Attempting steps out of sequence | - -The `breakdown` dict in every reward response provides a verbose, interpretable explanation of exactly why the agent scored what it did. - ---- - -## 7. Setup & Usage - -### Docker (recommended) - -```bash -docker build -t sre-env . -docker run --rm -p 7860:7860 sre-env -``` - -### Local Development - -```bash -python3 -m venv .venv -source .venv/bin/activate -pip install -r requirements.txt -uvicorn server.app:app --host 0.0.0.0 --port 7860 -``` - -### API Examples - -**Health check:** -```bash -curl http://localhost:7860/health -# {"status": "ok"} -``` - -**List tasks:** -```bash -curl http://localhost:7860/tasks -``` - -**Reset an episode:** -```bash -curl -X POST http://localhost:7860/reset \ - -H "Content-Type: application/json" \ - -d '{"task_id": "alert_triage"}' -``` - -**Step through an episode:** -```bash -curl -X POST http://localhost:7860/step \ - -H "Content-Type: application/json" \ - -d '{ - "session_id": "", - "action": { - "action_type": "triage", - "target": "ALT-001", - "parameters": {"decision": "actionable", "priority": "P1"}, - "reasoning": "Critical payment-service alert, not flapping." - } - }' -``` - -**Inspect environment state:** -```bash -curl "http://localhost:7860/state?session_id=" -``` - -**Run inference harness:** -```bash -export HF_TOKEN= -python inference.py -``` - ---- - -## 8. Baseline Scores - -Run `python inference.py` with `HF_TOKEN` set. The inference harness runs all tasks sequentially and prints `[START]`, `[STEP]`, and `[END]` markers per task. - -Expected baseline ranges: -| Task | Difficulty | Model | Expected Score | -|---|---|---|---| -| Alert Triage | 🟢 Easy | Qwen2.5-72B | 0.5–0.8 | -| On-Call Handoff | 🟢 Easy | Qwen2.5-72B | 0.4–0.7 | -| Capacity Planning | 🟢 Easy | Qwen2.5-72B | 0.4–0.7 | -| Incident Diagnosis | 🟡 Medium | Qwen2.5-72B | 0.3–0.7 | -| Multi-Incident Correlation | 🟡 Medium | Qwen2.5-72B | 0.3–0.6 | -| Auto-Remediation | 🟡 Medium | Qwen2.5-72B | 0.3–0.6 | -| Runbook Execution | 🔴 Hard | Qwen2.5-72B | 0.1–0.5 | -| Blameless Postmortem | 🔴 Hard | Qwen2.5-72B | 0.2–0.5 | -| Chaos Engineering | 🔴 Hard | Qwen2.5-72B | 0.2–0.5 | - ---- - -## 9. Deploying to Hugging Face Spaces - -### Step-by-step: - -1. **Create a new Space** at [huggingface.co/new-space](https://huggingface.co/new-space) - - Select **Docker** as the SDK - - Choose **Blank** template - - Set visibility to **Public** - -2. **Push your code:** - ```bash - git init - git remote add origin https://huggingface.co/spaces//sre-automation-env - git add . - git commit -m "Initial SRE environment" - git push origin main - ``` - -3. **The Space will auto-build** from your Dockerfile and expose port 7860. - -4. **Set your Space URL** in `inference.py` via the `ENV_URL` environment variable: - ```bash - ENV_URL=https://-sre-automation-env.hf.space python inference.py - ``` - -5. **Verify** the deployment: - ```bash - curl https://-sre-automation-env.hf.space/health - curl https://-sre-automation-env.hf.space/tasks - ``` - ---- - -## 10. Architecture - -``` -┌─────────────────────────────────────────────────────────┐ -│ inference.py │ -│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │ -│ │ LLM Call │◄──►│ JSON │◄──►│ Conversation │ │ -│ │ (OpenAI) │ │ Extractor│ │ History Manager │ │ -│ └──────────┘ └──────────┘ └──────────────────┘ │ -└───────────────────────┬─────────────────────────────────┘ - │ HTTP -┌───────────────────────▼─────────────────────────────────┐ -│ server/app.py (FastAPI) │ -│ POST /reset │ POST /step │ GET /state │ GET /tasks│ -│ ────────────────────────────────────────────────────── │ -│ Session Manager (TTL=10min, max=200 sessions) │ -└───────────────────────┬─────────────────────────────────┘ - │ -┌───────────────────────▼─────────────────────────────────┐ -│ env/sre_env.py │ -│ ┌──────────────┐ ┌──────────────┐ ┌───────────────┐ │ -│ │ Task Registry │ │ State Machine│ │ Reward Tracker│ │ -│ └──────┬───────┘ └──────┬───────┘ └───────┬───────┘ │ -│ │ │ │ │ -│ ┌──────▼───────┐ ┌──────▼───────┐ ┌───────▼───────┐ │ -│ │ env/tasks/ │ │ env/data/ │ │ env/graders/ │ │ -│ │ • alert │ │ • alerts.json│ │ • alert │ │ -│ │ • handoff │ │ • incidents │ │ • handoff │ │ -│ │ • capacity │ │ • runbooks │ │ • capacity │ │ -│ │ • incident │ │ │ │ • incident │ │ -│ │ • correlate │ │ │ │ • correlate │ │ -│ │ • remediate │ │ │ │ • remediate │ │ -│ │ • runbook │ │ │ │ • runbook │ │ -│ │ • postmortem │ │ │ │ • postmortem │ │ -│ │ • chaos │ │ │ │ • chaos │ │ -│ └──────────────┘ └──────────────┘ └───────────────┘ │ -└─────────────────────────────────────────────────────────┘ -``` - ---- - -## License - -MIT diff --git a/scratch/sre/env/__init__.py b/scratch/sre/env/__init__.py deleted file mode 100644 index 2bca1a46ab24381d97e5186353cf2bf8aa6c679d..0000000000000000000000000000000000000000 --- a/scratch/sre/env/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from env.models import SREAction, SREObservation, SREReward -from env.sre_env import SREEnv - -__all__ = ["SREAction", "SREObservation", "SREReward", "SREEnv"] diff --git a/scratch/sre/env/data/alerts.json b/scratch/sre/env/data/alerts.json deleted file mode 100644 index e537e0fb54b7d244ac354c0dd3e1619a5f65b92b..0000000000000000000000000000000000000000 --- a/scratch/sre/env/data/alerts.json +++ /dev/null @@ -1,182 +0,0 @@ -[ - { - "id": "ALT-001", - "service": "payment-service", - "severity": "critical", - "message": "Error rate > 5% for 3 consecutive minutes", - "is_flapping": false, - "is_duplicate": false, - "fired_at": "2026-03-01T14:23:00Z" - }, - { - "id": "ALT-002", - "service": "db-service", - "severity": "critical", - "message": "p99 latency exceeded 400ms", - "is_flapping": false, - "is_duplicate": false, - "fired_at": "2026-03-01T14:24:00Z" - }, - { - "id": "ALT-003", - "service": "auth-service", - "severity": "warning", - "message": "Token verification retries above baseline", - "is_flapping": false, - "is_duplicate": false, - "fired_at": "2026-03-01T14:25:00Z" - }, - { - "id": "ALT-004", - "service": "api-gateway", - "severity": "critical", - "message": "5xx rate exceeded 8% on /login", - "is_flapping": false, - "is_duplicate": false, - "fired_at": "2026-03-01T14:26:00Z" - }, - { - "id": "ALT-005", - "service": "payment-service", - "severity": "warning", - "message": "Heap usage crossed 85% on checkout worker", - "is_flapping": false, - "is_duplicate": false, - "fired_at": "2026-03-01T14:27:00Z" - }, - { - "id": "ALT-006", - "service": "payment-service", - "severity": "warning", - "message": "Heap usage crossed 85% on checkout worker", - "is_flapping": false, - "is_duplicate": true, - "fired_at": "2026-03-01T14:28:00Z" - }, - { - "id": "ALT-007", - "service": "user-service", - "severity": "warning", - "message": "Deprecated profile endpoint still receiving traffic", - "is_flapping": false, - "is_duplicate": false, - "fired_at": "2026-03-01T14:29:00Z" - }, - { - "id": "ALT-008", - "service": "user-service", - "severity": "info", - "message": "Nightly cache warm completed later than usual", - "is_flapping": true, - "is_duplicate": false, - "fired_at": "2026-03-01T14:30:00Z" - }, - { - "id": "ALT-009", - "service": "auth-service", - "severity": "critical", - "message": "JWT validation failures above 20%", - "is_flapping": false, - "is_duplicate": false, - "fired_at": "2026-03-01T14:31:00Z" - }, - { - "id": "ALT-010", - "service": "db-service", - "severity": "warning", - "message": "Replica lag above 2 seconds", - "is_flapping": true, - "is_duplicate": false, - "fired_at": "2026-03-01T14:32:00Z" - }, - { - "id": "ALT-011", - "service": "api-gateway", - "severity": "info", - "message": "Config reload took longer than 5 seconds", - "is_flapping": false, - "is_duplicate": false, - "fired_at": "2026-03-01T14:33:00Z" - }, - { - "id": "ALT-012", - "service": "payment-service", - "severity": "critical", - "message": "OOM restart detected on pod payment-7", - "is_flapping": false, - "is_duplicate": false, - "fired_at": "2026-03-01T14:34:00Z" - }, - { - "id": "ALT-013", - "service": "payment-service", - "severity": "critical", - "message": "OOM restart detected on pod payment-7", - "is_flapping": false, - "is_duplicate": true, - "fired_at": "2026-03-01T14:35:00Z" - }, - { - "id": "ALT-014", - "service": "db-service", - "severity": "info", - "message": "Autovacuum duration exceeded baseline", - "is_flapping": false, - "is_duplicate": false, - "fired_at": "2026-03-01T14:36:00Z" - }, - { - "id": "ALT-015", - "service": "api-gateway", - "severity": "warning", - "message": "Unexpected upstream cluster hash detected", - "is_flapping": false, - "is_duplicate": false, - "fired_at": "2026-03-01T14:37:00Z" - }, - { - "id": "ALT-016", - "service": "auth-service", - "severity": "info", - "message": "Background key refresh retried once", - "is_flapping": true, - "is_duplicate": false, - "fired_at": "2026-03-01T14:38:00Z" - }, - { - "id": "ALT-017", - "service": "user-service", - "severity": "critical", - "message": "Profile hydration timeout rate exceeded 10%", - "is_flapping": false, - "is_duplicate": false, - "fired_at": "2026-03-01T14:39:00Z" - }, - { - "id": "ALT-018", - "service": "db-service", - "severity": "warning", - "message": "Connection pool wait time above 150ms", - "is_flapping": false, - "is_duplicate": false, - "fired_at": "2026-03-01T14:40:00Z" - }, - { - "id": "ALT-019", - "service": "api-gateway", - "severity": "warning", - "message": "Rate limiter dropped burst traffic", - "is_flapping": false, - "is_duplicate": false, - "fired_at": "2026-03-01T14:41:00Z" - }, - { - "id": "ALT-020", - "service": "payment-service", - "severity": "info", - "message": "Batch settlement lag recovered automatically", - "is_flapping": true, - "is_duplicate": false, - "fired_at": "2026-03-01T14:42:00Z" - } -] diff --git a/scratch/sre/env/data/incidents.json b/scratch/sre/env/data/incidents.json deleted file mode 100644 index 02341a2a2b3409990762acc4f457f0b97660108e..0000000000000000000000000000000000000000 --- a/scratch/sre/env/data/incidents.json +++ /dev/null @@ -1,37 +0,0 @@ -[ - { - "id": "INC-A", - "service": "db-service", - "failure_mode": "high latency", - "description": "db-service query latency is cascading into the checkout path.", - "keywords": ["high latency", "latency", "slow query", "database saturation", "db"] - }, - { - "id": "INC-B", - "service": "auth-service", - "failure_mode": "high error rate", - "description": "auth-service is rejecting login traffic and causing upstream failures.", - "keywords": ["high error rate", "error rate", "login failures", "token", "auth"] - }, - { - "id": "INC-C", - "service": "payment-service", - "failure_mode": "memory leak", - "description": "payment-service memory usage keeps rising until worker restarts.", - "keywords": ["memory leak", "memory pressure", "oom", "heap growth", "restarts"] - }, - { - "id": "INC-D", - "service": "api-gateway", - "failure_mode": "config drift", - "description": "api-gateway is routing traffic to the wrong upstream target.", - "keywords": ["config drift", "wrong upstream", "routing", "gateway", "misconfiguration"] - }, - { - "id": "INC-E", - "service": "user-service", - "failure_mode": "deprecated endpoint dependency", - "description": "user-service still depends on a deprecated endpoint that now fails.", - "keywords": ["deprecated endpoint", "endpoint dependency", "410", "sunset endpoint", "deprecated"] - } -] diff --git a/scratch/sre/env/data/runbooks.json b/scratch/sre/env/data/runbooks.json deleted file mode 100644 index c6fb6318086a92859699acf07931f3c4b038bfb1..0000000000000000000000000000000000000000 --- a/scratch/sre/env/data/runbooks.json +++ /dev/null @@ -1,55 +0,0 @@ -[ - { - "id": "runbook-payment-memory-pressure", - "name": "High memory pressure - payment-service", - "description": "Mitigate sustained memory pressure on payment-service while preserving checkout capacity.", - "steps": [ - { - "name": "check_memory_usage", - "parameters": { - "service": "payment-service" - } - }, - { - "name": "identify_top_processes", - "parameters": { - "service": "payment-service" - } - }, - { - "name": "capture_heap_dump", - "parameters": { - "service": "payment-service", - "pid": "" - } - }, - { - "name": "cordon_instance", - "parameters": { - "instance_id": "" - } - }, - { - "name": "scale_out", - "parameters": { - "service": "payment-service", - "replicas": "+2" - } - }, - { - "name": "verify_recovery", - "parameters": { - "service": "payment-service", - "wait_seconds": 30 - } - }, - { - "name": "file_incident_report", - "parameters": { - "severity": "P2", - "summary": "" - } - } - ] - } -] diff --git a/scratch/sre/env/graders/__init__.py b/scratch/sre/env/graders/__init__.py deleted file mode 100644 index 61535105b4cdfc6606e77435f5863c1f3699e7bd..0000000000000000000000000000000000000000 --- a/scratch/sre/env/graders/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -from env.graders.grader_alert_triage import grade_alert_triage -from env.graders.grader_auto_remediation import grade_auto_remediation -from env.graders.grader_blameless_postmortem import grade_blameless_postmortem -from env.graders.grader_capacity_planning import grade_capacity_planning -from env.graders.grader_chaos_engineering import grade_chaos_engineering -from env.graders.grader_incident_diagnosis import grade_incident_diagnosis -from env.graders.grader_multi_incident_correlation import ( - grade_multi_incident_correlation, -) -from env.graders.grader_on_call_handoff import grade_on_call_handoff -from env.graders.grader_runbook_execution import grade_runbook_execution - -__all__ = [ - "grade_alert_triage", - "grade_auto_remediation", - "grade_blameless_postmortem", - "grade_capacity_planning", - "grade_chaos_engineering", - "grade_incident_diagnosis", - "grade_multi_incident_correlation", - "grade_on_call_handoff", - "grade_runbook_execution", -] diff --git a/scratch/sre/env/graders/grader_alert_triage.py b/scratch/sre/env/graders/grader_alert_triage.py deleted file mode 100644 index 44d32036cc4720d81045b59b631a83a2e12c0e2d..0000000000000000000000000000000000000000 --- a/scratch/sre/env/graders/grader_alert_triage.py +++ /dev/null @@ -1,119 +0,0 @@ -from __future__ import annotations - -from typing import Any - -from env.graders.scoring import clamp_task_score -from env.models import SREReward - -PRIORITY_WEIGHT = {"P1": 3, "P2": 2, "P3": 1} - - -_clamp = clamp_task_score - - -def _ordering_accuracy( - acknowledged_order: list[str], ground_truth: dict[str, dict[str, Any]] -) -> float: - ranks = [ - PRIORITY_WEIGHT[ground_truth[alert_id]["priority"]] - for alert_id in acknowledged_order - if alert_id in ground_truth - ] - if len(ranks) <= 1: - return 1.0 if ranks else 0.0 - total_pairs = 0 - correct_pairs = 0 - for idx, current_rank in enumerate(ranks): - for later_rank in ranks[idx + 1 :]: - total_pairs += 1 - if current_rank >= later_rank: - correct_pairs += 1 - return correct_pairs / total_pairs if total_pairs else 0.0 - - -def _weighted_jaccard( - actionable_ids: set[str], - agent_ids: set[str], - ground_truth: dict[str, dict[str, Any]], -) -> float: - union_ids = actionable_ids | agent_ids - if not union_ids: - return 0.0 - intersection_weight = sum( - PRIORITY_WEIGHT[ground_truth[alert_id]["priority"]] - for alert_id in actionable_ids & agent_ids - ) - union_weight = sum( - PRIORITY_WEIGHT.get(ground_truth.get(alert_id, {}).get("priority", "P3"), 1) - for alert_id in union_ids - ) - return intersection_weight / union_weight if union_weight else 0.0 - - -def grade_alert_triage(state: dict[str, Any], step_count: int, done: bool) -> SREReward: - actionable_ids = set(state["actionable_ids"]) - ignored_ids = set(state["ignorable_ids"]) - ground_truth = state["ground_truth"] - acknowledged_order = [ - alert_id - for alert_id in state["acknowledged_order"] - if alert_id in actionable_ids - ] - acknowledged_ids = set(acknowledged_order) - weighted_jaccard = _weighted_jaccard(actionable_ids, acknowledged_ids, ground_truth) - - correct_ignored = 0 - for alert_id in ignored_ids: - decision = state["triage_decisions"].get(alert_id, {}).get("decision") - if decision == "ignore" or alert_id in state["ignored_alert_ids"]: - correct_ignored += 1 - ignore_score = 0.1 * correct_ignored - - highest_priority_weight = None - if actionable_ids: - highest_priority_weight = max( - PRIORITY_WEIGHT[ground_truth[alert_id]["priority"]] - for alert_id in actionable_ids - ) - first_ack_score = 0.0 - if acknowledged_order and highest_priority_weight is not None: - first_ack_priority = PRIORITY_WEIGHT[ - ground_truth[acknowledged_order[0]]["priority"] - ] - if first_ack_priority == highest_priority_weight: - first_ack_score = 0.2 - - ordering_score = 0.15 * _ordering_accuracy(acknowledged_order, ground_truth) - coverage_score = 0.55 * weighted_jaccard - - p1_ids = { - alert_id - for alert_id in actionable_ids - if ground_truth[alert_id]["priority"] == "P1" - } - p1_left_unacked = len(p1_ids - acknowledged_ids) - p1_penalty = 0.1 * p1_left_unacked if done else 0.0 - invalid_penalty = 0.02 * state.get("invalid_actions", 0) - - total = coverage_score + ignore_score + first_ack_score + ordering_score - total -= p1_penalty + invalid_penalty - total = _clamp(total) - - breakdown = { - "coverage_weighted_jaccard": round(weighted_jaccard, 4), - "coverage_score": round(coverage_score, 4), - "correctly_ignored_alerts": correct_ignored, - "ignore_score": round(ignore_score, 4), - "first_ack_priority_score": round(first_ack_score, 4), - "ordering_score": round(ordering_score, 4), - "p1_left_unacknowledged": p1_left_unacked, - "end_penalty": round(p1_penalty, 4), - "invalid_action_penalty": round(invalid_penalty, 4), - "acknowledged_order": acknowledged_order, - "actionable_ground_truth_order": list(state["actionable_ids"]), - "score_explanation": ( - "Weighted Jaccard rewards acknowledging the right alerts, while ordering " - "and ignore bonuses reward good on-call hygiene." - ), - } - return SREReward(value=total, breakdown=breakdown, done=done, info={}) diff --git a/scratch/sre/env/graders/grader_auto_remediation.py b/scratch/sre/env/graders/grader_auto_remediation.py deleted file mode 100644 index 1c1ac9e705d1b6a50a363a653bfeaae7cfde31e0..0000000000000000000000000000000000000000 --- a/scratch/sre/env/graders/grader_auto_remediation.py +++ /dev/null @@ -1,81 +0,0 @@ -from __future__ import annotations - -from typing import Any - -from env.graders.scoring import clamp_task_score -from env.models import SREReward - - -_clamp = clamp_task_score - - -def grade_auto_remediation( - state: dict[str, Any], step_count: int, done: bool -) -> SREReward: - scenario = state["scenario"] - attempted = state.get("remediation_attempted") - final = state.get("final_state") - - if not attempted: - return SREReward( - value=0.0001, - breakdown={"error": "No remediation attempted"}, - done=done, - info={}, - ) - - correct_action = attempted["action"] == scenario["correct_action"] - action_score = 0.4 if correct_action else 0.0 - - if final: - outcome = final["outcome"] - if outcome == "success": - outcome_score = 0.4 - elif outcome == "rolled_back": - outcome_score = 0.2 - elif outcome == "partial": - outcome_score = 0.1 - else: - outcome_score = 0.0 - else: - outcome_score = 0.0 - - verified = state.get("recovery_verified", False) - verify_score = 0.1 if verified else 0.0 - - if final and final["outcome"] == "worse" and not state.get("rollback_performed"): - rollback_penalty = 0.2 - elif final and final["outcome"] == "worse" and state.get("rollback_performed"): - rollback_penalty = 0.0 - else: - rollback_penalty = 0.0 - - efficiency_bonus = 0.1 if step_count <= 5 else 0.0 - invalid_penalty = 0.02 * state.get("invalid_actions", 0) - - total = ( - action_score - + outcome_score - + verify_score - + efficiency_bonus - - rollback_penalty - - invalid_penalty - ) - total = _clamp(total) - - breakdown = { - "correct_action_chosen": correct_action, - "action_score": round(action_score, 4), - "outcome": final["outcome"] if final else "none", - "outcome_score": round(outcome_score, 4), - "recovery_verified": verified, - "verify_score": round(verify_score, 4), - "rollback_penalty": round(rollback_penalty, 4), - "efficiency_bonus": round(efficiency_bonus, 4), - "invalid_action_penalty": round(invalid_penalty, 4), - "score_explanation": ( - "Rewards choosing the correct remediation, verifying recovery, " - "and rolling back if the fix made things worse." - ), - } - return SREReward(value=total, breakdown=breakdown, done=done, info={}) diff --git a/scratch/sre/env/graders/grader_blameless_postmortem.py b/scratch/sre/env/graders/grader_blameless_postmortem.py deleted file mode 100644 index a0feeb8b2852a0f816ec62287fba29c31dc72e51..0000000000000000000000000000000000000000 --- a/scratch/sre/env/graders/grader_blameless_postmortem.py +++ /dev/null @@ -1,85 +0,0 @@ -from __future__ import annotations - -from typing import Any - -from env.graders.scoring import clamp_task_score -from env.models import SREReward - - -_clamp = clamp_task_score - - -def grade_blameless_postmortem( - state: dict[str, Any], step_count: int, done: bool -) -> SREReward: - sections = state.get("sections_written", []) - postmortem = state.get("postmortem_submitted") or {} - - required_sections = ["summary", "timeline", "root_cause", "impact", "action_items"] - completed = [s for s in required_sections if s in sections] - section_score = 0.12 * len(completed) - - content_score = 0.0 - for section_name, section_data in postmortem.items(): - content = section_data.get("content", "") - word_count = section_data.get("word_count", 0) - if word_count >= 15: - content_score += 0.04 - elif word_count >= 8: - content_score += 0.02 - content_score = min(0.2, content_score) - - incident = state["incident"] - root_cause_section = postmortem.get("root_cause", {}) - root_content = root_cause_section.get("content", "").lower() - root_keywords = incident["root_cause"].lower().split() - root_keyword_matches = sum(1 for kw in root_keywords if kw in root_content) - root_keyword_score = ( - 0.1 if root_keyword_matches >= 3 else 0.05 if root_keyword_matches >= 1 else 0.0 - ) - - action_items_section = postmortem.get("action_items", {}) - action_content = action_items_section.get("content", "").lower() - action_items_mentioned = sum( - 1 - for item in incident["action_items"] - if item["action"].lower().split()[0] in action_content - ) - action_items_score = 0.08 * min( - 1.0, action_items_mentioned / max(1, len(incident["action_items"])) - ) - - queried_data = len(state.get("queried_data", [])) - evidence_bonus = 0.1 if queried_data >= 3 else 0.05 if queried_data >= 2 else 0.0 - - invalid_penalty = 0.02 * state.get("invalid_actions", 0) - - total = ( - section_score - + content_score - + root_keyword_score - + action_items_score - + evidence_bonus - - invalid_penalty - ) - total = _clamp(total) - - breakdown = { - "sections_completed": completed, - "section_score": round(section_score, 4), - "content_score": round(content_score, 4), - "root_cause_keyword_matches": root_keyword_matches, - "root_cause_keyword_score": round(root_keyword_score, 4), - "action_items_coverage": round( - action_items_mentioned / max(1, len(incident["action_items"])), 4 - ), - "action_items_score": round(action_items_score, 4), - "evidence_queries": queried_data, - "evidence_bonus": round(evidence_bonus, 4), - "invalid_action_penalty": round(invalid_penalty, 4), - "score_explanation": ( - "Rewards completing all required sections with substantive content, " - "matching root cause keywords, covering action items, and querying incident data." - ), - } - return SREReward(value=total, breakdown=breakdown, done=done, info={}) diff --git a/scratch/sre/env/graders/grader_capacity_planning.py b/scratch/sre/env/graders/grader_capacity_planning.py deleted file mode 100644 index 344faee22b877a74cd45c31f8df70f67f905bd59..0000000000000000000000000000000000000000 --- a/scratch/sre/env/graders/grader_capacity_planning.py +++ /dev/null @@ -1,61 +0,0 @@ -from __future__ import annotations - -from typing import Any - -from env.graders.scoring import clamp_task_score -from env.models import SREReward - - -_clamp = clamp_task_score - - -def grade_capacity_planning( - state: dict[str, Any], step_count: int, done: bool -) -> SREReward: - scenario = state["scenario"] - rec = state.get("recommendation") - if not rec: - return SREReward( - value=0.0001, - breakdown={"error": "No scaling recommendation submitted"}, - done=done, - info={}, - ) - - correct_rec = scenario["correct_recommendation"] - correct_replicas = scenario["target_replicas"] - - rec_match = rec["recommendation"] == correct_rec - rec_score = 0.5 if rec_match else 0.0 - - submitted_replicas = rec.get("target_replicas") - replica_match = submitted_replicas == correct_replicas - replica_score = 0.3 if replica_match else 0.0 - - queried = ( - scenario["service"] in state["queries_made"] or "all" in state["queries_made"] - ) - query_score = 0.1 if queried else 0.0 - - efficiency_bonus = 0.1 if step_count <= 3 else 0.0 - - invalid_penalty = 0.02 * state.get("invalid_actions", 0) - - total = rec_score + replica_score + query_score + efficiency_bonus - invalid_penalty - total = _clamp(total) - - breakdown = { - "recommendation_correct": rec_match, - "recommendation_score": round(rec_score, 4), - "replica_count_correct": replica_match, - "replica_score": round(replica_score, 4), - "queried_data": queried, - "query_score": round(query_score, 4), - "efficiency_bonus": round(efficiency_bonus, 4), - "invalid_action_penalty": round(invalid_penalty, 4), - "score_explanation": ( - "Rewards correct scaling recommendation, accurate replica count, " - "and querying data before deciding." - ), - } - return SREReward(value=total, breakdown=breakdown, done=done, info={}) diff --git a/scratch/sre/env/graders/grader_chaos_engineering.py b/scratch/sre/env/graders/grader_chaos_engineering.py deleted file mode 100644 index d7530e39c093a1b9f2aa91c42b0d2eb7ad518261..0000000000000000000000000000000000000000 --- a/scratch/sre/env/graders/grader_chaos_engineering.py +++ /dev/null @@ -1,67 +0,0 @@ -from __future__ import annotations - -from typing import Any - -from env.graders.scoring import clamp_task_score -from env.models import SREReward - - -_clamp = clamp_task_score - - -def grade_chaos_engineering( - state: dict[str, Any], step_count: int, done: bool -) -> SREReward: - scenario = state["scenario"] - completed = state.get("mitigation_steps_completed", []) - total_steps = len(scenario["correct_order"]) - - if not state.get("chaos_injected"): - return SREReward( - value=0.0001, breakdown={"error": "No chaos injected"}, done=done, info={} - ) - - injection_score = 0.1 - observation_score = 0.1 if state.get("impact_observed") else 0.0 - - step_score = 0.15 * len(completed) - - wrong_order = state.get("mitigation_in_wrong_order", 0) - order_penalty = 0.05 * wrong_order - - all_complete = len(completed) == total_steps - completion_bonus = 0.2 if all_complete else 0.0 - - efficiency_bonus = 0.15 if (all_complete and step_count <= 8) else 0.0 - invalid_penalty = 0.02 * state.get("invalid_actions", 0) - - total = ( - injection_score - + observation_score - + step_score - + completion_bonus - + efficiency_bonus - - order_penalty - - invalid_penalty - ) - total = _clamp(total) - - breakdown = { - "chaos_injected": True, - "injection_score": round(injection_score, 4), - "impact_observed": state.get("impact_observed", False), - "observation_score": round(observation_score, 4), - "mitigation_steps_completed": completed, - "step_score": round(step_score, 4), - "wrong_order_attempts": wrong_order, - "order_penalty": round(order_penalty, 4), - "all_steps_complete": all_complete, - "completion_bonus": round(completion_bonus, 4), - "efficiency_bonus": round(efficiency_bonus, 4), - "invalid_action_penalty": round(invalid_penalty, 4), - "score_explanation": ( - "Rewards injecting chaos, observing impact, completing all mitigation " - "steps in order, and doing so efficiently." - ), - } - return SREReward(value=total, breakdown=breakdown, done=done, info={}) diff --git a/scratch/sre/env/graders/grader_incident_diagnosis.py b/scratch/sre/env/graders/grader_incident_diagnosis.py deleted file mode 100644 index a8a3b2e58e40328e731a699f16fa6b4962a927a6..0000000000000000000000000000000000000000 --- a/scratch/sre/env/graders/grader_incident_diagnosis.py +++ /dev/null @@ -1,120 +0,0 @@ -from __future__ import annotations - -from typing import Any - -from env.graders.scoring import clamp_task_score -from env.models import SREReward - -# Upstream dependency map: service -> list of services that depend on it -# If agent names a service one hop upstream of the real root cause, partial credit -UPSTREAM_MAP = { - "db-service": ["payment-service"], - "payment-service": ["auth-service"], - "auth-service": ["api-gateway"], - "user-service": ["auth-service"], - "api-gateway": [], -} - - -_clamp = clamp_task_score - - -def _normalize(text: str) -> str: - return " ".join(text.lower().strip().replace("-", " ").split()) - - -def _failure_mode_match(predicted: str, scenario: dict[str, Any]) -> bool: - normalized_prediction = _normalize(predicted) - if not normalized_prediction: - return False - keywords = scenario.get("keywords", []) - return any(keyword in normalized_prediction for keyword in keywords) - - -def _efficiency_bonus(step_used: int) -> float: - if step_used <= 8: - return 0.2 - if step_used >= 12: - return 0.0 - return round(0.2 * ((12 - step_used) / 4), 4) - - -def _is_upstream_of(predicted_service: str, root_cause_service: str) -> bool: - """Check if predicted_service is a direct upstream consumer of root_cause_service.""" - return predicted_service in UPSTREAM_MAP.get(root_cause_service, []) - - -def grade_incident_diagnosis( - state: dict[str, Any], step_count: int, done: bool -) -> SREReward: - scenario = state["incident"] - diagnosis = state.get("submitted_diagnosis") or {} - predicted_service = diagnosis.get("service", "") - predicted_failure = diagnosis.get("failure_mode", "") - correct_service = predicted_service == scenario["service"] - failure_match = _failure_mode_match(predicted_failure, scenario) - - # Evidence collection bonuses - evidence_metric = 0.05 if scenario["service"] in state["queried_metrics"] else 0.0 - evidence_logs = 0.05 if scenario["service"] in state["queried_logs"] else 0.0 - - # Root cause identification - root_cause_score = 0.0 - upstream_partial = False - if correct_service: - root_cause_score = 0.5 - elif predicted_service and _is_upstream_of(predicted_service, scenario["service"]): - root_cause_score = 0.1 - upstream_partial = True - - # Failure mode scoring - failure_mode_score = 0.0 - if correct_service and failure_match: - failure_mode_score = 0.2 - elif upstream_partial and failure_match: - # Partial credit: correctly matched failure mode but wrong service - failure_mode_score = 0.05 - - # Efficiency bonus (only for correct root cause) - efficiency_score = 0.0 - if correct_service and diagnosis: - efficiency_score = _efficiency_bonus(diagnosis["step"]) - - # Penalties - extra_metric_queries = max(0, len(state["queried_metrics"]) - 6) - query_penalty = 0.05 * extra_metric_queries - invalid_penalty = 0.02 * state.get("invalid_actions", 0) - - total = ( - evidence_metric - + evidence_logs - + root_cause_score - + failure_mode_score - + efficiency_score - - query_penalty - - invalid_penalty - ) - total = _clamp(total) - - breakdown = { - "root_cause_service_correct": correct_service, - "root_cause_score": round(root_cause_score, 4), - "upstream_partial_credit": upstream_partial, - "failure_mode_match": failure_match, - "failure_mode_score": round(failure_mode_score, 4), - "evidence_collection": { - "queried_root_metrics": scenario["service"] in state["queried_metrics"], - "queried_root_logs": scenario["service"] in state["queried_logs"], - "score": round(evidence_metric + evidence_logs, 4), - }, - "efficiency_score": round(efficiency_score, 4), - "metric_queries": len(state["queried_metrics"]), - "query_penalty": round(query_penalty, 4), - "invalid_action_penalty": round(invalid_penalty, 4), - "score_explanation": ( - "The score rewards collecting the right evidence, naming the correct root " - "cause service (or its direct upstream for partial credit), " - "matching the failure mode, and submitting an efficient diagnosis." - ), - } - return SREReward(value=total, breakdown=breakdown, done=done, info={}) diff --git a/scratch/sre/env/graders/grader_multi_incident_correlation.py b/scratch/sre/env/graders/grader_multi_incident_correlation.py deleted file mode 100644 index e8210ba3a69fb8c5e3d590e0e396284ec5ffaa8a..0000000000000000000000000000000000000000 --- a/scratch/sre/env/graders/grader_multi_incident_correlation.py +++ /dev/null @@ -1,111 +0,0 @@ -from __future__ import annotations - -from typing import Any - -from env.graders.scoring import clamp_task_score -from env.models import SREReward - - -_clamp = clamp_task_score - - -def grade_multi_incident_correlation( - state: dict[str, Any], step_count: int, done: bool -) -> SREReward: - scenario = state["scenario"] - corr = state.get("correlation_submitted") - if not corr: - return SREReward( - value=0.0001, - breakdown={"error": "No correlation analysis submitted"}, - done=done, - info={}, - ) - - correct_type = corr["correlation_type"] == scenario["type"] - type_score = 0.4 if correct_type else 0.0 - - if scenario["type"] == "shared_root_cause": - root_correct = corr["root_cause_service"] == scenario["root_cause"] - root_score = 0.3 if root_correct else 0.0 - all_alerts = set(a["id"] for a in scenario["alerts"]) - submitted_alerts = set(corr.get("alert_ids", [])) - alert_coverage = ( - len(all_alerts & submitted_alerts) / len(all_alerts) if all_alerts else 0.0 - ) - alert_score = 0.2 * alert_coverage - elif scenario["type"] == "independent_incidents": - root_correct = ( - not corr["root_cause_service"] - or corr["root_cause_service"] == "none" - or corr["root_cause_service"] == "" - ) - root_score = 0.3 if root_correct else 0.0 - submitted_alerts = set(corr.get("alert_ids", [])) - all_alerts = set(a["id"] for a in scenario["alerts"]) - alert_coverage = ( - len(all_alerts & submitted_alerts) / len(all_alerts) if all_alerts else 0.0 - ) - alert_score = 0.2 * alert_coverage - else: - root_correct = corr["root_cause_service"] == scenario["root_cause"] - root_score = 0.15 if root_correct else 0.0 - submitted_alerts = set(corr.get("alert_ids", [])) - correlated_alerts = set( - a["id"] - for a in scenario["alerts"] - if a["id"] not in scenario["independent_alerts"] - ) - independent_correct = all( - aid not in submitted_alerts for aid in scenario["independent_alerts"] - ) - partial_score = 0.15 if independent_correct else 0.0 - alert_coverage = ( - len(correlated_alerts & submitted_alerts) / len(correlated_alerts) - if correlated_alerts - else 0.0 - ) - alert_score = 0.1 * alert_coverage + partial_score - - queried_services = len(state["queried_services"]) - evidence_bonus = ( - 0.1 if queried_services >= 2 else 0.05 if queried_services >= 1 else 0.0 - ) - - efficiency_bonus = 0.1 if step_count <= 6 else 0.0 - invalid_penalty = 0.02 * state.get("invalid_actions", 0) - - if scenario["type"] == "partial_correlation": - total = ( - type_score - + root_score - + alert_score - + evidence_bonus - + efficiency_bonus - - invalid_penalty - ) - else: - total = ( - type_score - + root_score - + alert_score - + evidence_bonus - + efficiency_bonus - - invalid_penalty - ) - total = _clamp(total) - - breakdown = { - "correlation_type_correct": correct_type, - "type_score": round(type_score, 4), - "root_cause_score": round(root_score, 4), - "alert_coverage_score": round(alert_score, 4), - "evidence_bonus": round(evidence_bonus, 4), - "efficiency_bonus": round(efficiency_bonus, 4), - "invalid_action_penalty": round(invalid_penalty, 4), - "score_explanation": ( - "Rewards correct correlation type, root cause identification, " - "proper alert grouping, and evidence gathering." - ), - } - return SREReward(value=total, breakdown=breakdown, done=done, info={}) diff --git a/scratch/sre/env/graders/grader_on_call_handoff.py b/scratch/sre/env/graders/grader_on_call_handoff.py deleted file mode 100644 index 3a8a7ac580ad718ea9345e36dbfdda9833f07e8b..0000000000000000000000000000000000000000 --- a/scratch/sre/env/graders/grader_on_call_handoff.py +++ /dev/null @@ -1,87 +0,0 @@ -from __future__ import annotations - -from typing import Any - -from env.graders.scoring import clamp_task_score -from env.models import SREReward - - -_clamp = clamp_task_score - - -def grade_on_call_handoff( - state: dict[str, Any], step_count: int, done: bool -) -> SREReward: - summary = state.get("handoff_summary") - if not summary: - return SREReward( - value=0.0001, - breakdown={"error": "No handoff summary submitted"}, - done=done, - info={}, - ) - - text = summary["summary"].lower() - shift_context = state["shift_context"] - - incident_mentions = sum( - 1 - for inc in shift_context["active_incidents"] - if inc["id"] in text or inc["service"] in text - ) - incident_score = 0.3 * ( - incident_mentions / max(1, len(shift_context["active_incidents"])) - ) - - action_mentions = sum( - 1 - for action in shift_context["pending_actions"] - if any(word in text for word in action.lower().split()[:3]) - ) - action_score = 0.25 * ( - action_mentions / max(1, len(shift_context["pending_actions"])) - ) - - severity_mentioned = any( - inc["severity"].lower() in text for inc in shift_context["active_incidents"] - ) - severity_score = 0.15 if severity_mentioned else 0.0 - - health_mentioned = any(svc in text for svc in state["service_health"]) - health_score = 0.1 if health_mentioned else 0.0 - - length_bonus = ( - 0.1 if len(text.split()) >= 20 else 0.05 if len(text.split()) >= 10 else 0.0 - ) - efficiency_bonus = 0.1 if step_count <= 3 else 0.0 - - invalid_penalty = 0.02 * state.get("invalid_actions", 0) - - total = ( - incident_score - + action_score - + severity_score - + health_score - + length_bonus - + efficiency_bonus - - invalid_penalty - ) - total = _clamp(total) - - breakdown = { - "incident_coverage_score": round(incident_score, 4), - "action_items_score": round(action_score, 4), - "severity_mentioned": severity_mentioned, - "severity_score": round(severity_score, 4), - "health_mentioned": health_mentioned, - "health_score": round(health_score, 4), - "length_bonus": round(length_bonus, 4), - "efficiency_bonus": round(efficiency_bonus, 4), - "invalid_action_penalty": round(invalid_penalty, 4), - "word_count": len(text.split()), - "score_explanation": ( - "Rewards mentioning all active incidents, pending actions, severity levels, " - "and service health in a concise summary." - ), - } - return SREReward(value=total, breakdown=breakdown, done=done, info={}) diff --git a/scratch/sre/env/graders/grader_runbook_execution.py b/scratch/sre/env/graders/grader_runbook_execution.py deleted file mode 100644 index fc6ffb819c8aec0c281ca3cd0a449987beb601e7..0000000000000000000000000000000000000000 --- a/scratch/sre/env/graders/grader_runbook_execution.py +++ /dev/null @@ -1,64 +0,0 @@ -from __future__ import annotations - -from env.graders.scoring import clamp_task_score -from env.models import SREReward - - -_clamp = clamp_task_score - - -def _report_quality(report: dict | None) -> float: - if not report: - return 0.0 - summary = str(report.get("summary", "")).lower() - severity = str(report.get("severity", "")).upper() - has_severity = severity == "P2" - has_service = "payment-service" in summary - has_resolution_language = any( - keyword in summary - for keyword in ["scaled", "recovered", "cordon", "heap dump", "memory pressure"] - ) - coherent_sentence = len(summary.split()) >= 6 and summary.endswith((".", "!", "?")) - return ( - 0.1 - if has_severity - and has_service - and has_resolution_language - and coherent_sentence - else 0.0 - ) - - -def grade_runbook_execution(state: dict, step_count: int, done: bool) -> SREReward: - completed_count = len(state["completed_steps"]) - step_score = min(0.7, 0.1 * completed_count) - pid_bonus = 0.1 if state.get("pid_dependency_ok") else 0.0 - report_bonus = _report_quality(state.get("report_submitted")) - out_of_order_penalty = 0.05 * state.get("out_of_order_attempts", 0) - wrong_parameter_penalty = 0.05 * state.get("wrong_parameter_attempts", 0) - invalid_penalty = 0.02 * state.get("invalid_actions", 0) - - total = ( - step_score - + pid_bonus - + report_bonus - - out_of_order_penalty - - wrong_parameter_penalty - - invalid_penalty - ) - total = _clamp(total) - - breakdown = { - "completed_steps": state["completed_steps"], - "step_score": round(step_score, 4), - "pid_dependency_bonus": round(pid_bonus, 4), - "report_quality_bonus": round(report_bonus, 4), - "out_of_order_penalty": round(out_of_order_penalty, 4), - "wrong_parameter_penalty": round(wrong_parameter_penalty, 4), - "invalid_action_penalty": round(invalid_penalty, 4), - "score_explanation": ( - "The runbook score is dense: every correct step adds credit, but ordering " - "mistakes and bad parameters reduce the final score." - ), - } - return SREReward(value=total, breakdown=breakdown, done=done, info={}) diff --git a/scratch/sre/env/graders/scoring.py b/scratch/sre/env/graders/scoring.py deleted file mode 100644 index 077f6ab125e8ddfa76944c73d9fbd2877db81b7a..0000000000000000000000000000000000000000 --- a/scratch/sre/env/graders/scoring.py +++ /dev/null @@ -1,9 +0,0 @@ -from __future__ import annotations - -MIN_TASK_SCORE = 0.0001 -MAX_TASK_SCORE = 0.9999 - - -def clamp_task_score(value: float) -> float: - """Clamp scores to a strict open interval (0, 1) with stable precision.""" - return max(MIN_TASK_SCORE, min(MAX_TASK_SCORE, round(float(value), 4))) \ No newline at end of file diff --git a/scratch/sre/env/models.py b/scratch/sre/env/models.py deleted file mode 100644 index f14ed259296b82d74597d5017005c798b5ebd0ae..0000000000000000000000000000000000000000 --- a/scratch/sre/env/models.py +++ /dev/null @@ -1,50 +0,0 @@ -from __future__ import annotations - -from typing import Any, Literal - -from pydantic import BaseModel, Field - - -class SREObservation(BaseModel): - task_id: str - step: int = Field(ge=0) - context: dict[str, Any] - available_actions: list[str] - alert_queue: list[dict[str, Any]] - service_map: dict[str, list[str]] - metrics: dict[str, Any] - logs: list[str] - done: bool - message: str - - -class SREAction(BaseModel): - action_type: Literal[ - "triage", - "diagnose", - "escalate", - "acknowledge", - "execute_step", - "resolve", - "summarize", - "query_capacity", - "recommend_scaling", - "correlate", - "remediate", - "rollback", - "verify_recovery", - "write_postmortem", - "inject_chaos", - "observe_impact", - "mitigate_chaos", - ] - target: str - parameters: dict[str, Any] = Field(default_factory=dict) - reasoning: str - - -class SREReward(BaseModel): - value: float = Field(gt=0.0, lt=1.0) - breakdown: dict[str, Any] = Field(default_factory=dict) - done: bool - info: dict[str, Any] = Field(default_factory=dict) diff --git a/scratch/sre/env/sre_env.py b/scratch/sre/env/sre_env.py deleted file mode 100644 index 50fef54a1889177b44debef07fd7f8a46ffe27a3..0000000000000000000000000000000000000000 --- a/scratch/sre/env/sre_env.py +++ /dev/null @@ -1,290 +0,0 @@ -from __future__ import annotations - -import json -import random -from pathlib import Path -from typing import Any - -from env.graders.scoring import clamp_task_score -from env.graders import ( - grade_alert_triage, - grade_auto_remediation, - grade_blameless_postmortem, - grade_capacity_planning, - grade_chaos_engineering, - grade_incident_diagnosis, - grade_multi_incident_correlation, - grade_on_call_handoff, - grade_runbook_execution, -) -from env.models import SREAction, SREObservation, SREReward -from env.tasks import ( - ALERT_TRIAGE_INFO, - AUTO_REMEDIATION_INFO, - BLAMELESS_POSTMORTEM_INFO, - CAPACITY_PLANNING_INFO, - CHAOS_ENGINEERING_INFO, - INCIDENT_DIAGNOSIS_INFO, - MULTI_INCIDENT_CORRELATION_INFO, - ON_CALL_HANDOFF_INFO, - RUNBOOK_EXECUTION_INFO, - apply_alert_triage_action, - apply_auto_remediation_action, - apply_blameless_postmortem_action, - apply_capacity_planning_action, - apply_chaos_engineering_action, - apply_incident_diagnosis_action, - apply_multi_incident_correlation_action, - apply_on_call_handoff_action, - apply_runbook_execution_action, - build_alert_triage_observation, - build_auto_remediation_observation, - build_blameless_postmortem_observation, - build_capacity_planning_observation, - build_chaos_engineering_observation, - build_incident_diagnosis_observation, - build_multi_incident_correlation_observation, - build_on_call_handoff_observation, - build_runbook_execution_observation, - init_alert_triage_task, - init_auto_remediation_task, - init_blameless_postmortem_task, - init_capacity_planning_task, - init_chaos_engineering_task, - init_incident_diagnosis_task, - init_multi_incident_correlation_task, - init_on_call_handoff_task, - init_runbook_execution_task, - is_alert_triage_done, - is_auto_remediation_done, - is_blameless_postmortem_done, - is_capacity_planning_done, - is_chaos_engineering_done, - is_incident_diagnosis_done, - is_multi_incident_correlation_done, - is_on_call_handoff_done, - is_runbook_execution_done, -) - -DATA_DIR = Path(__file__).resolve().parent / "data" -SERVICE_MAP = { - "api-gateway": ["auth-service"], - "auth-service": ["user-service", "payment-service"], - "user-service": [], - "payment-service": ["db-service"], - "db-service": [], -} - -TASK_REGISTRY = { - "alert_triage": { - "metadata": ALERT_TRIAGE_INFO, - "reset": init_alert_triage_task, - "apply": apply_alert_triage_action, - "build_observation": build_alert_triage_observation, - "grade": grade_alert_triage, - "is_done": is_alert_triage_done, - }, - "on_call_handoff": { - "metadata": ON_CALL_HANDOFF_INFO, - "reset": init_on_call_handoff_task, - "apply": apply_on_call_handoff_action, - "build_observation": build_on_call_handoff_observation, - "grade": grade_on_call_handoff, - "is_done": is_on_call_handoff_done, - }, - "capacity_planning": { - "metadata": CAPACITY_PLANNING_INFO, - "reset": init_capacity_planning_task, - "apply": apply_capacity_planning_action, - "build_observation": build_capacity_planning_observation, - "grade": grade_capacity_planning, - "is_done": is_capacity_planning_done, - }, - "incident_diagnosis": { - "metadata": INCIDENT_DIAGNOSIS_INFO, - "reset": init_incident_diagnosis_task, - "apply": apply_incident_diagnosis_action, - "build_observation": build_incident_diagnosis_observation, - "grade": grade_incident_diagnosis, - "is_done": is_incident_diagnosis_done, - }, - "multi_incident_correlation": { - "metadata": MULTI_INCIDENT_CORRELATION_INFO, - "reset": init_multi_incident_correlation_task, - "apply": apply_multi_incident_correlation_action, - "build_observation": build_multi_incident_correlation_observation, - "grade": grade_multi_incident_correlation, - "is_done": is_multi_incident_correlation_done, - }, - "auto_remediation": { - "metadata": AUTO_REMEDIATION_INFO, - "reset": init_auto_remediation_task, - "apply": apply_auto_remediation_action, - "build_observation": build_auto_remediation_observation, - "grade": grade_auto_remediation, - "is_done": is_auto_remediation_done, - }, - "runbook_execution": { - "metadata": RUNBOOK_EXECUTION_INFO, - "reset": init_runbook_execution_task, - "apply": apply_runbook_execution_action, - "build_observation": build_runbook_execution_observation, - "grade": grade_runbook_execution, - "is_done": is_runbook_execution_done, - }, - "blameless_postmortem": { - "metadata": BLAMELESS_POSTMORTEM_INFO, - "reset": init_blameless_postmortem_task, - "apply": apply_blameless_postmortem_action, - "build_observation": build_blameless_postmortem_observation, - "grade": grade_blameless_postmortem, - "is_done": is_blameless_postmortem_done, - }, - "chaos_engineering": { - "metadata": CHAOS_ENGINEERING_INFO, - "reset": init_chaos_engineering_task, - "apply": apply_chaos_engineering_action, - "build_observation": build_chaos_engineering_observation, - "grade": grade_chaos_engineering, - "is_done": is_chaos_engineering_done, - }, -} - - -class SREEnv: - def __init__(self, task_id: str): - if task_id not in TASK_REGISTRY: - raise ValueError(f"Unsupported task_id: {task_id}") - self.task_id = task_id - self.step_count = 0 - self.state_data: dict[str, Any] = {} - self.episode_history: list[dict[str, Any]] = [] - self.cumulative_reward: float = 0.0 - self.catalogs = self._load_catalogs() - self.rng = random.Random() - - def _load_catalogs(self) -> dict[str, Any]: - return { - "alerts": json.loads((DATA_DIR / "alerts.json").read_text()), - "incidents": json.loads((DATA_DIR / "incidents.json").read_text()), - "runbooks": json.loads((DATA_DIR / "runbooks.json").read_text()), - } - - def reset(self) -> SREObservation: - self.step_count = 0 - self.episode_history = [] - self.cumulative_reward = 0.0 - registry_entry = TASK_REGISTRY[self.task_id] - self.state_data = registry_entry["reset"](self.catalogs, SERVICE_MAP, self.rng) - message = self.state_data.get( - "message", registry_entry["metadata"]["description"] - ) - return registry_entry["build_observation"]( - self.task_id, - self.step_count, - self.state_data, - SERVICE_MAP, - False, - message, - ) - - def step( - self, action: SREAction - ) -> tuple[SREObservation, SREReward, bool, dict[str, Any]]: - registry_entry = TASK_REGISTRY[self.task_id] - available_actions = registry_entry["metadata"]["available_actions"] - - if action.action_type not in available_actions: - self.state_data["invalid_actions"] = ( - self.state_data.get("invalid_actions", 0) + 1 - ) - message = ( - f"Action {action.action_type} is not available for task {self.task_id}. " - f"Allowed actions: {available_actions}." - ) - else: - message = registry_entry["apply"](self.state_data, action, self.step_count) - - self.step_count += 1 - done = registry_entry["is_done"]( - self.state_data, - self.step_count, - registry_entry["metadata"]["max_steps"], - ) - reward = registry_entry["grade"](self.state_data, self.step_count, done) - self.cumulative_reward = clamp_task_score(self.cumulative_reward + reward.value) - reward = SREReward( - value=clamp_task_score(reward.value), - breakdown=reward.breakdown, - done=done, - info={ - **reward.info, - "cumulative_score": self.cumulative_reward, - "step_count": self.step_count, - }, - ) - info = { - "task_id": self.task_id, - "cumulative_score": self.cumulative_reward, - "max_steps": registry_entry["metadata"]["max_steps"], - "termination_reason": self._termination_reason(done), - } - observation = registry_entry["build_observation"]( - self.task_id, - self.step_count, - self.state_data, - SERVICE_MAP, - done, - message, - ) - self.episode_history.append( - { - "step": self.step_count, - "action": action.model_dump(), - "reward": reward.model_dump(), - "done": done, - "info": info, - } - ) - return observation, reward, done, info - - def _termination_reason(self, done: bool) -> str | None: - if not done: - return None - max_steps = TASK_REGISTRY[self.task_id]["metadata"]["max_steps"] - if self.step_count >= max_steps: - return "max_steps_reached" - if self.task_id == "alert_triage": - return "all_actionable_alerts_acknowledged" - if self.task_id == "on_call_handoff": - return "handoff_summary_submitted" - if self.task_id == "capacity_planning": - return "scaling_recommendation_submitted" - if self.task_id == "incident_diagnosis": - return "diagnosis_submitted" - if self.task_id == "multi_incident_correlation": - return "correlation_submitted" - if self.task_id == "auto_remediation": - return "remediation_cycle_complete" - if self.task_id == "runbook_execution": - return "runbook_completed" - if self.task_id == "blameless_postmortem": - return "postmortem_sections_complete" - if self.task_id == "chaos_engineering": - return "chaos_mitigation_complete" - return "done" - - def state(self) -> dict[str, Any]: - return { - "task_id": self.task_id, - "step_count": self.step_count, - "state_data": self.state_data, - "episode_history": self.episode_history, - } - - def close(self): - self.state_data = {} - self.episode_history = [] - - -TASK_METADATA = [TASK_REGISTRY[task_id]["metadata"] for task_id in TASK_REGISTRY] diff --git a/scratch/sre/env/tasks/__init__.py b/scratch/sre/env/tasks/__init__.py deleted file mode 100644 index 0a8bd75115633e09204fb5d3b02a9e6554317b98..0000000000000000000000000000000000000000 --- a/scratch/sre/env/tasks/__init__.py +++ /dev/null @@ -1,116 +0,0 @@ -from env.tasks.task_alert_triage import ( - ALERT_TRIAGE_INFO, - apply_alert_triage_action, - build_alert_triage_observation, - init_alert_triage_task, - is_alert_triage_done, -) -from env.tasks.task_auto_remediation import ( - AUTO_REMEDIATION_INFO, - apply_auto_remediation_action, - build_auto_remediation_observation, - init_auto_remediation_task, - is_auto_remediation_done, -) -from env.tasks.task_blameless_postmortem import ( - BLAMELESS_POSTMORTEM_INFO, - apply_blameless_postmortem_action, - build_blameless_postmortem_observation, - init_blameless_postmortem_task, - is_blameless_postmortem_done, -) -from env.tasks.task_capacity_planning import ( - CAPACITY_PLANNING_INFO, - apply_capacity_planning_action, - build_capacity_planning_observation, - init_capacity_planning_task, - is_capacity_planning_done, -) -from env.tasks.task_chaos_engineering import ( - CHAOS_ENGINEERING_INFO, - apply_chaos_engineering_action, - build_chaos_engineering_observation, - init_chaos_engineering_task, - is_chaos_engineering_done, -) -from env.tasks.task_incident_diagnosis import ( - INCIDENT_DIAGNOSIS_INFO, - apply_incident_diagnosis_action, - build_incident_diagnosis_observation, - init_incident_diagnosis_task, - is_incident_diagnosis_done, -) -from env.tasks.task_multi_incident_correlation import ( - MULTI_INCIDENT_CORRELATION_INFO, - apply_multi_incident_correlation_action, - build_multi_incident_correlation_observation, - init_multi_incident_correlation_task, - is_multi_incident_correlation_done, -) -from env.tasks.task_on_call_handoff import ( - ON_CALL_HANDOFF_INFO, - apply_on_call_handoff_action, - build_on_call_handoff_observation, - init_on_call_handoff_task, - is_on_call_handoff_done, -) -from env.tasks.task_runbook_execution import ( - RUNBOOK_EXECUTION_INFO, - apply_runbook_execution_action, - build_runbook_execution_observation, - init_runbook_execution_task, - is_runbook_execution_done, -) -from env.tasks.task_registry import ALL_TASKS, EASY_TASKS, HARD_TASKS, MEDIUM_TASKS - -__all__ = [ - "ALERT_TRIAGE_INFO", - "AUTO_REMEDIATION_INFO", - "BLAMELESS_POSTMORTEM_INFO", - "CAPACITY_PLANNING_INFO", - "CHAOS_ENGINEERING_INFO", - "INCIDENT_DIAGNOSIS_INFO", - "MULTI_INCIDENT_CORRELATION_INFO", - "ON_CALL_HANDOFF_INFO", - "RUNBOOK_EXECUTION_INFO", - "apply_alert_triage_action", - "apply_auto_remediation_action", - "apply_blameless_postmortem_action", - "apply_capacity_planning_action", - "apply_chaos_engineering_action", - "apply_incident_diagnosis_action", - "apply_multi_incident_correlation_action", - "apply_on_call_handoff_action", - "apply_runbook_execution_action", - "build_alert_triage_observation", - "build_auto_remediation_observation", - "build_blameless_postmortem_observation", - "build_capacity_planning_observation", - "build_chaos_engineering_observation", - "build_incident_diagnosis_observation", - "build_multi_incident_correlation_observation", - "build_on_call_handoff_observation", - "build_runbook_execution_observation", - "init_alert_triage_task", - "init_auto_remediation_task", - "init_blameless_postmortem_task", - "init_capacity_planning_task", - "init_chaos_engineering_task", - "init_incident_diagnosis_task", - "init_multi_incident_correlation_task", - "init_on_call_handoff_task", - "init_runbook_execution_task", - "is_alert_triage_done", - "is_auto_remediation_done", - "is_blameless_postmortem_done", - "is_capacity_planning_done", - "is_chaos_engineering_done", - "is_incident_diagnosis_done", - "is_multi_incident_correlation_done", - "is_on_call_handoff_done", - "is_runbook_execution_done", - "ALL_TASKS", - "EASY_TASKS", - "MEDIUM_TASKS", - "HARD_TASKS", -] diff --git a/scratch/sre/env/tasks/task_alert_triage.py b/scratch/sre/env/tasks/task_alert_triage.py deleted file mode 100644 index f484a4825d4cefd2229505d168f162fb648bc8f7..0000000000000000000000000000000000000000 --- a/scratch/sre/env/tasks/task_alert_triage.py +++ /dev/null @@ -1,197 +0,0 @@ -from __future__ import annotations - -from collections import defaultdict -from copy import deepcopy -from typing import Any - -from env.models import SREAction, SREObservation - -ALERT_TRIAGE_INFO = { - "id": "alert_triage", - "name": "Alert Triage", - "difficulty": "easy", - "description": "Prioritize and acknowledge firing alerts in correct severity order.", - "max_steps": 10, - "available_actions": ["triage", "acknowledge", "resolve", "escalate"], -} - -PRIORITY_BY_SEVERITY = {"critical": "P1", "warning": "P2", "info": "P3"} -PRIORITY_RANK = {"P1": 1, "P2": 2, "P3": 3} -SEVERITY_WEIGHT = {"critical": 3, "warning": 2, "info": 1} - - -def _sorted_actionable_alerts(alerts: list[dict[str, Any]]) -> list[dict[str, Any]]: - return sorted( - alerts, - key=lambda alert: ( - PRIORITY_RANK[PRIORITY_BY_SEVERITY[alert["severity"]]], - alert["fired_at"], - alert["id"], - ), - ) - - -def init_alert_triage_task( - catalogs: dict[str, Any], service_map: dict[str, list[str]], rng -) -> dict[str, Any]: - alerts = deepcopy(rng.sample(catalogs["alerts"], k=8)) - actionable_alerts = [ - alert for alert in alerts if not alert["is_flapping"] and not alert["is_duplicate"] - ] - actionable_order = _sorted_actionable_alerts(actionable_alerts) - ground_truth = { - alert["id"]: { - "priority": PRIORITY_BY_SEVERITY[alert["severity"]], - "service": alert["service"], - "severity": alert["severity"], - } - for alert in actionable_order - } - - for alert in alerts: - alert["status"] = "pending" - alert["assigned_priority"] = None - - return { - "task": "alert_triage", - "alerts": alerts, - "actionable_ids": [alert["id"] for alert in actionable_order], - "ignorable_ids": [ - alert["id"] for alert in alerts if alert["is_flapping"] or alert["is_duplicate"] - ], - "ground_truth": ground_truth, - "triage_decisions": {}, - "acknowledged_order": [], - "ignored_alert_ids": [], - "escalated_alert_ids": [], - "invalid_actions": 0, - "message": ( - "Triage the alert queue. Use action_type='triage' with parameters " - "{decision: ignore|actionable, priority: P1|P2|P3}, then use " - "action_type='acknowledge' on actionable alerts in priority order." - ), - "service_map": service_map, - } - - -def apply_alert_triage_action( - state: dict[str, Any], action: SREAction, step_count: int -) -> str: - alert_lookup = {alert["id"]: alert for alert in state["alerts"]} - alert = alert_lookup.get(action.target) - if action.action_type in {"triage", "acknowledge", "escalate"} and alert is None: - state["invalid_actions"] += 1 - return f"Alert {action.target} was not found in the current queue." - - if action.action_type == "triage": - decision = str(action.parameters.get("decision", "actionable")).lower() - priority = str( - action.parameters.get( - "priority", PRIORITY_BY_SEVERITY.get(alert["severity"], "P3") - ) - ).upper() - state["triage_decisions"][alert["id"]] = { - "decision": decision, - "priority": priority, - "step": step_count + 1, - } - alert["assigned_priority"] = priority - if decision == "ignore": - if alert["id"] not in state["ignored_alert_ids"]: - state["ignored_alert_ids"].append(alert["id"]) - alert["status"] = "ignored" - return f"Alert {alert['id']} was marked as ignorable with priority {priority}." - alert["status"] = "triaged" - return f"Alert {alert['id']} was marked actionable with priority {priority}." - - if action.action_type == "acknowledge": - if alert["id"] in state["acknowledged_order"]: - state["invalid_actions"] += 1 - return f"Alert {alert['id']} was already acknowledged." - if alert["is_flapping"] or alert["is_duplicate"]: - state["invalid_actions"] += 1 - alert["status"] = "mis-acknowledged" - return ( - f"Alert {alert['id']} should have been ignored because it is " - "flapping or duplicate." - ) - priority = action.parameters.get("priority") - if priority: - alert["assigned_priority"] = str(priority).upper() - state["acknowledged_order"].append(alert["id"]) - alert["status"] = "acknowledged" - return f"Alert {alert['id']} acknowledged for service {alert['service']}." - - if action.action_type == "escalate": - if alert["id"] not in state["escalated_alert_ids"]: - state["escalated_alert_ids"].append(alert["id"]) - return f"Alert {alert['id']} escalated to the on-call escalation policy." - - if action.action_type == "resolve": - return "Alert triage episodes end when all actionable alerts are acknowledged." - - state["invalid_actions"] += 1 - return f"Action {action.action_type} is not supported for alert triage." - - -def build_alert_triage_observation( - task_id: str, - step_count: int, - state: dict[str, Any], - service_map: dict[str, list[str]], - done: bool, - message: str, -) -> SREObservation: - per_service: dict[str, dict[str, int]] = defaultdict( - lambda: {"open_alerts": 0, "critical": 0, "warning": 0, "info": 0} - ) - for alert in state["alerts"]: - if alert["status"] not in {"acknowledged", "ignored"}: - per_service[alert["service"]]["open_alerts"] += 1 - per_service[alert["service"]][alert["severity"]] += 1 - - context = { - "instruction": ( - "Identify non-actionable alerts, assign P1/P2/P3, and acknowledge only " - "actionable alerts in descending priority order." - ), - "triaged_alerts": len(state["triage_decisions"]), - "acknowledged_alerts": state["acknowledged_order"], - "ignored_alerts": state["ignored_alert_ids"], - "remaining_actionable": len( - [ - alert_id - for alert_id in state["actionable_ids"] - if alert_id not in state["acknowledged_order"] - ] - ), - "ground_truth_hidden": False, - } - logs = [ - f"{alert['id']} {alert['service']} {alert['severity']}: {alert['message']}" - for alert in state["alerts"] - ] - - return SREObservation( - task_id=task_id, - step=step_count, - context=context, - available_actions=ALERT_TRIAGE_INFO["available_actions"], - alert_queue=deepcopy(state["alerts"]), - service_map=service_map, - metrics={"services": dict(per_service), "queue_depth": len(state["alerts"])}, - logs=logs, - done=done, - message=message, - ) - - -def is_alert_triage_done( - state: dict[str, Any], step_count: int, max_steps: int -) -> bool: - actionable_remaining = [ - alert_id - for alert_id in state["actionable_ids"] - if alert_id not in state["acknowledged_order"] - ] - return not actionable_remaining or step_count >= max_steps diff --git a/scratch/sre/env/tasks/task_auto_remediation.py b/scratch/sre/env/tasks/task_auto_remediation.py deleted file mode 100644 index c3863aa3516c5d51e00d6722ea56f4d09be5efd5..0000000000000000000000000000000000000000 --- a/scratch/sre/env/tasks/task_auto_remediation.py +++ /dev/null @@ -1,299 +0,0 @@ -from __future__ import annotations - -from copy import deepcopy -from typing import Any - -from env.models import SREAction, SREObservation - -AUTO_REMEDIATION_INFO = { - "id": "auto_remediation", - "name": "Auto-Remediation with Rollback", - "difficulty": "medium", - "description": "Execute a remediation action, verify if it improved the situation, and rollback if it made things worse.", - "max_steps": 8, - "available_actions": [ - "remediate", - "verify_recovery", - "rollback", - "escalate", - "resolve", - ], -} - -REMEDIATION_SCENARIOS = [ - { - "id": "REM-A", - "service": "api-gateway", - "symptom": "5xx rate > 15% after config change", - "root_cause": "config drift to wrong upstream", - "remediation_options": [ - { - "action": "reload_config", - "effect": "worse", - "description": "Reload config without reverting", - }, - { - "action": "rollback_config", - "effect": "fix", - "description": "Revert to previous config version", - }, - { - "action": "restart_service", - "effect": "worse", - "description": "Restart with current bad config", - }, - { - "action": "scale_out", - "effect": "partial", - "description": "Add more instances (masks symptom)", - }, - ], - "correct_action": "rollback_config", - "post_fix_metrics": {"error_rate": 0.01, "latency_p99": 120}, - "current_metrics": {"error_rate": 0.18, "latency_p99": 350}, - }, - { - "id": "REM-B", - "service": "payment-service", - "symptom": "Memory leak causing OOM restarts every 30 minutes", - "root_cause": "memory leak in checkout worker", - "remediation_options": [ - { - "action": "increase_memory_limit", - "effect": "partial", - "description": "Raise memory ceiling (delays but doesn't fix)", - }, - { - "action": "restart_service", - "effect": "partial", - "description": "Restart clears memory temporarily", - }, - { - "action": "cordon_and_scale", - "effect": "fix", - "description": "Cordon affected instance, scale out replacement", - }, - { - "action": "disable_checkout", - "effect": "worse", - "description": "Disable checkout feature entirely", - }, - ], - "correct_action": "cordon_and_scale", - "post_fix_metrics": {"error_rate": 0.01, "latency_p99": 110, "mem_pct": 65}, - "current_metrics": {"error_rate": 0.12, "latency_p99": 280, "mem_pct": 94}, - }, - { - "id": "REM-C", - "service": "auth-service", - "symptom": "JWT validation failures after key rotation", - "root_cause": "new signing key not propagated to all pods", - "remediation_options": [ - { - "action": "force_key_rotation", - "effect": "worse", - "description": "Rotate keys again (makes it worse)", - }, - { - "action": "propagate_keys", - "effect": "fix", - "description": "Manually sync signing keys across all pods", - }, - { - "action": "restart_service", - "effect": "partial", - "description": "Restart may pick up new keys on some pods", - }, - { - "action": "disable_auth", - "effect": "worse", - "description": "Disable authentication (security risk)", - }, - ], - "correct_action": "propagate_keys", - "post_fix_metrics": {"error_rate": 0.008, "latency_p99": 95}, - "current_metrics": {"error_rate": 0.24, "latency_p99": 180}, - }, -] - - -def init_auto_remediation_task( - catalogs: dict[str, Any], service_map: dict[str, list[str]], rng -) -> dict[str, Any]: - scenario = deepcopy(rng.choice(REMEDIATION_SCENARIOS)) - return { - "task": "auto_remediation", - "scenario": scenario, - "remediation_attempted": None, - "recovery_verified": False, - "rollback_performed": False, - "final_state": None, - "escalated": False, - "invalid_actions": 0, - "service_map": service_map, - "message": ( - "A production incident requires remediation. Choose a remediation action, " - "verify if it improved metrics, and rollback if it made things worse. " - "Use action_type='remediate' with the action name, then " - "action_type='verify_recovery' to check results. If the fix made things " - "worse, use action_type='rollback'." - ), - } - - -def apply_auto_remediation_action( - state: dict[str, Any], action: SREAction, step_count: int -) -> str: - scenario = state["scenario"] - - if action.action_type == "escalate": - state["escalated"] = True - return f"Remediation for {scenario['service']} escalated to senior SRE." - - if action.action_type == "resolve": - if state["final_state"]: - return "Remediation episode already concluded." - state["invalid_actions"] += 1 - return "Resolve is only meaningful after completing the remediation cycle." - - if action.action_type == "remediate": - chosen_action = str(action.parameters.get("action", "")).strip() - if not chosen_action: - state["invalid_actions"] += 1 - return "Must specify an action in parameters." - valid_options = {opt["action"] for opt in scenario["remediation_options"]} - if chosen_action not in valid_options: - state["invalid_actions"] += 1 - return f"Invalid remediation action. Options: {sorted(valid_options)}." - - opt = next( - o for o in scenario["remediation_options"] if o["action"] == chosen_action - ) - state["remediation_attempted"] = { - "action": chosen_action, - "effect": opt["effect"], - "description": opt["description"], - "step": step_count + 1, - } - return ( - f"Remediation '{chosen_action}' executed: {opt['description']}. " - f"Use action_type='verify_recovery' to check results." - ) - - if action.action_type == "verify_recovery": - if not state["remediation_attempted"]: - state["invalid_actions"] += 1 - return "No remediation has been attempted yet." - - effect = state["remediation_attempted"]["effect"] - if effect == "fix": - state["recovery_verified"] = True - state["final_state"] = { - "outcome": "success", - "metrics": scenario["post_fix_metrics"], - "step": step_count + 1, - } - return ( - f"Recovery verified! Metrics improved: {scenario['post_fix_metrics']}. " - f"Remediation was successful." - ) - elif effect == "partial": - state["recovery_verified"] = True - state["final_state"] = { - "outcome": "partial", - "metrics": scenario["current_metrics"], - "note": "Symptom masked but root cause persists", - "step": step_count + 1, - } - return ( - "Partial improvement detected. Symptoms reduced but root cause " - "not addressed. Consider trying a different remediation or rollback." - ) - else: - state["recovery_verified"] = True - state["final_state"] = { - "outcome": "worse", - "metrics": scenario["current_metrics"], - "note": "Metrics degraded after remediation", - "step": step_count + 1, - } - return ( - "CRITICAL: Metrics degraded after remediation! " - "Use action_type='rollback' to revert immediately." - ) - - if action.action_type == "rollback": - if not state["remediation_attempted"]: - state["invalid_actions"] += 1 - return "No remediation to rollback." - state["rollback_performed"] = True - state["final_state"] = { - "outcome": "rolled_back", - "metrics": scenario["current_metrics"], - "original_action": state["remediation_attempted"]["action"], - "step": step_count + 1, - } - return ( - f"Rollback of '{state['remediation_attempted']['action']}' completed. " - f"System restored to pre-remediation state." - ) - - state["invalid_actions"] += 1 - return f"Action {action.action_type} is not supported for auto-remediation." - - -def build_auto_remediation_observation( - task_id: str, - step_count: int, - state: dict[str, Any], - service_map: dict[str, list[str]], - done: bool, - message: str, -) -> SREObservation: - scenario = state["scenario"] - context = { - "instruction": ( - "Choose a remediation action, verify its effect, and rollback if needed. " - "The correct action will fix the root cause. Wrong actions may make things " - "worse or only partially help." - ), - "service": scenario["service"], - "symptom": scenario["symptom"], - "root_cause": scenario["root_cause"], - "current_metrics": scenario["current_metrics"], - "remediation_options": [ - {"action": opt["action"], "description": opt["description"]} - for opt in scenario["remediation_options"] - ], - "remediation_attempted": state["remediation_attempted"], - "recovery_verified": state["recovery_verified"], - "rollback_performed": state["rollback_performed"], - "final_state": state["final_state"], - } - logs = [ - f"ALERT: {scenario['symptom']}", - f"Root cause hypothesis: {scenario['root_cause']}", - ] - if state["remediation_attempted"]: - logs.append(f"Attempted: {state['remediation_attempted']['action']}") - if state["final_state"]: - logs.append(f"Outcome: {state['final_state']['outcome']}") - - return SREObservation( - task_id=task_id, - step=step_count, - context=context, - available_actions=AUTO_REMEDIATION_INFO["available_actions"], - alert_queue=[], - service_map=service_map, - metrics={"service": scenario["current_metrics"]}, - logs=logs, - done=done, - message=message, - ) - - -def is_auto_remediation_done( - state: dict[str, Any], step_count: int, max_steps: int -) -> bool: - return state["final_state"] is not None or step_count >= max_steps diff --git a/scratch/sre/env/tasks/task_blameless_postmortem.py b/scratch/sre/env/tasks/task_blameless_postmortem.py deleted file mode 100644 index a59f620be232396dbe110694a1d20319dc6f1f24..0000000000000000000000000000000000000000 --- a/scratch/sre/env/tasks/task_blameless_postmortem.py +++ /dev/null @@ -1,276 +0,0 @@ -from __future__ import annotations - -from copy import deepcopy -from typing import Any - -from env.models import SREAction, SREObservation - -BLAMELESS_POSTMORTEM_INFO = { - "id": "blameless_postmortem", - "name": "Blameless Postmortem Generation", - "difficulty": "hard", - "description": "Synthesize incident timeline, root cause analysis, and actionable follow-ups into a blameless postmortem document.", - "max_steps": 8, - "available_actions": ["write_postmortem", "diagnose", "escalate", "resolve"], -} - -POSTMORTEM_INCIDENTS = [ - { - "id": "POST-1", - "title": "Payment Service Outage - March 15, 2026", - "severity": "SEV-1", - "duration_minutes": 47, - "affected_services": ["payment-service", "db-service", "api-gateway"], - "customer_impact": "Checkout failures for ~12,000 users, estimated $85K revenue loss", - "timeline": [ - { - "time": "14:23", - "event": "db-service latency spike detected, p99 > 400ms", - }, - {"time": "14:25", "event": "payment-service reports checkout timeouts"}, - {"time": "14:28", "event": "api-gateway 5xx rate exceeds 15% threshold"}, - {"time": "14:30", "event": "PagerDuty alert fired, on-call acknowledged"}, - {"time": "14:35", "event": "On-call identified db-service as root cause"}, - { - "time": "14:42", - "event": "Database connection pool increased from 100 to 200", - }, - {"time": "14:55", "event": "Latency normalized, checkout flow recovered"}, - {"time": "15:10", "event": "Incident declared resolved"}, - ], - "root_cause": "Database connection pool exhaustion during peak traffic. A slow query on the ledger_entries table held connections open, starving the checkout path.", - "contributing_factors": [ - "Connection pool size was not scaled with traffic growth (15% MoM increase)", - "No circuit breaker on payment-service to db-service calls", - "Slow query alerting threshold was set too high at 500ms", - ], - "action_items": [ - { - "action": "Increase db connection pool to 300 with auto-scaling", - "owner": "DBA team", - "priority": "P1", - }, - { - "action": "Implement circuit breaker on payment-service", - "owner": "Payment team", - "priority": "P1", - }, - { - "action": "Lower slow query alert threshold to 200ms", - "owner": "SRE team", - "priority": "P2", - }, - { - "action": "Add runbook for connection pool exhaustion", - "owner": "SRE team", - "priority": "P2", - }, - ], - "detection_time_minutes": 7, - "mitigation_time_minutes": 19, - "resolution_time_minutes": 47, - }, - { - "id": "POST-2", - "title": "Auth Service Login Failures - March 18, 2026", - "severity": "SEV-1", - "duration_minutes": 32, - "affected_services": ["auth-service", "api-gateway"], - "customer_impact": "Login failures for ~8,000 users, support ticket spike", - "timeline": [ - {"time": "09:15", "event": "JWT signing key rotation initiated"}, - { - "time": "09:17", - "event": "New key not propagated to all auth-service pods", - }, - {"time": "09:18", "event": "Login failures spike, error rate > 20%"}, - {"time": "09:22", "event": "PagerDuty alert fired"}, - {"time": "09:28", "event": "On-call identified key propagation issue"}, - {"time": "09:35", "event": "Manual key sync across all pods"}, - {"time": "09:47", "event": "Login flow recovered, incident resolved"}, - ], - "root_cause": "JWT signing key rotation did not propagate to all auth-service pods due to a race condition in the key distribution service.", - "contributing_factors": [ - "Key distribution service had a 60-second sync interval (too slow)", - "No validation step after key rotation to confirm all pods received new key", - "Rollback procedure for key rotation was not documented", - ], - "action_items": [ - { - "action": "Reduce key sync interval to 5 seconds", - "owner": "Auth team", - "priority": "P1", - }, - { - "action": "Add post-rotation validation check", - "owner": "Auth team", - "priority": "P1", - }, - { - "action": "Document key rotation rollback procedure", - "owner": "SRE team", - "priority": "P2", - }, - ], - "detection_time_minutes": 4, - "mitigation_time_minutes": 10, - "resolution_time_minutes": 32, - }, -] - - -def init_blameless_postmortem_task( - catalogs: dict[str, Any], service_map: dict[str, list[str]], rng -) -> dict[str, Any]: - incident = deepcopy(rng.choice(POSTMORTEM_INCIDENTS)) - return { - "task": "blameless_postmortem", - "incident": incident, - "sections_written": [], - "postmortem_submitted": None, - "queried_data": [], - "escalated": False, - "invalid_actions": 0, - "service_map": service_map, - "message": ( - "Write a blameless postmortem for the given incident. Use " - "action_type='diagnose' with operation='query_timeline' or " - "'query_impact' to gather data, then action_type='write_postmortem' " - "with parameters containing the section name and content. Required " - "sections: summary, timeline, root_cause, impact, action_items." - ), - } - - -def apply_blameless_postmortem_action( - state: dict[str, Any], action: SREAction, step_count: int -) -> str: - incident = state["incident"] - - if action.action_type == "escalate": - state["escalated"] = True - return "Postmortem escalated to the engineering manager for review." - - if action.action_type == "resolve": - if state["postmortem_submitted"]: - return "Postmortem already submitted." - state["invalid_actions"] += 1 - return "Resolve is only meaningful after submitting the postmortem." - - if action.action_type == "diagnose": - operation = str(action.parameters.get("operation", "")).lower() - if operation == "query_timeline": - if "timeline" not in state["queried_data"]: - state["queried_data"].append("timeline") - return f"Timeline: {len(incident['timeline'])} events from {incident['timeline'][0]['time']} to {incident['timeline'][-1]['time']}." - elif operation == "query_impact": - if "impact" not in state["queried_data"]: - state["queried_data"].append("impact") - return ( - f"Impact: {incident['customer_impact']}. " - f"Duration: {incident['duration_minutes']}min. " - f"Detection: {incident['detection_time_minutes']}min, " - f"Mitigation: {incident['mitigation_time_minutes']}min, " - f"Resolution: {incident['resolution_time_minutes']}min." - ) - elif operation == "query_root_cause": - if "root_cause" not in state["queried_data"]: - state["queried_data"].append("root_cause") - return f"Root cause: {incident['root_cause']}" - elif operation == "query_action_items": - if "action_items" not in state["queried_data"]: - state["queried_data"].append("action_items") - return f"Action items: {len(incident['action_items'])} items identified." - state["invalid_actions"] += 1 - return "Use operation: query_timeline, query_impact, query_root_cause, or query_action_items." - - if action.action_type == "write_postmortem": - section = str(action.parameters.get("section", "")).strip() - content = str(action.parameters.get("content", "")).strip() - if not section or not content: - state["invalid_actions"] += 1 - return "Both 'section' and 'content' parameters are required." - - valid_sections = ["summary", "timeline", "root_cause", "impact", "action_items"] - if section not in valid_sections: - state["invalid_actions"] += 1 - return f"Invalid section '{section}'. Valid sections: {valid_sections}." - - state["sections_written"].append(section) - if state["postmortem_submitted"] is None: - state["postmortem_submitted"] = {} - state["postmortem_submitted"][section] = { - "content": content, - "step": step_count + 1, - "word_count": len(content.split()), - } - return f"Section '{section}' written ({len(content.split())} words)." - - state["invalid_actions"] += 1 - return f"Action {action.action_type} is not supported for blameless postmortem." - - -def build_blameless_postmortem_observation( - task_id: str, - step_count: int, - state: dict[str, Any], - service_map: dict[str, list[str]], - done: bool, - message: str, -) -> SREObservation: - incident = state["incident"] - context = { - "instruction": ( - "Write a blameless postmortem with these required sections: " - "summary, timeline, root_cause, impact, action_items. " - "Query incident data first, then write each section using " - "action_type='write_postmortem'." - ), - "incident_id": incident["id"], - "incident_title": incident["title"], - "severity": incident["severity"], - "affected_services": incident["affected_services"], - "sections_required": [ - "summary", - "timeline", - "root_cause", - "impact", - "action_items", - ], - "sections_written": state["sections_written"], - "sections_remaining": [ - s - for s in ["summary", "timeline", "root_cause", "impact", "action_items"] - if s not in state["sections_written"] - ], - "queried_data": state["queried_data"], - "postmortem_submitted": state["postmortem_submitted"] is not None, - } - logs = [ - f"Postmortem requested for {incident['title']}", - f"Severity: {incident['severity']}, Duration: {incident['duration_minutes']}min", - f"Affected services: {', '.join(incident['affected_services'])}", - ] - - return SREObservation( - task_id=task_id, - step=step_count, - context=context, - available_actions=BLAMELESS_POSTMORTEM_INFO["available_actions"], - alert_queue=[], - service_map=service_map, - metrics={ - "sections_complete": len(state["sections_written"]), - "sections_total": 5, - }, - logs=logs, - done=done, - message=message, - ) - - -def is_blameless_postmortem_done( - state: dict[str, Any], step_count: int, max_steps: int -) -> bool: - required = {"summary", "timeline", "root_cause", "impact", "action_items"} - return required.issubset(set(state["sections_written"])) or step_count >= max_steps diff --git a/scratch/sre/env/tasks/task_capacity_planning.py b/scratch/sre/env/tasks/task_capacity_planning.py deleted file mode 100644 index 4553b4a0f6ecb10002a1024d4051b42ea30bcd91..0000000000000000000000000000000000000000 --- a/scratch/sre/env/tasks/task_capacity_planning.py +++ /dev/null @@ -1,225 +0,0 @@ -from __future__ import annotations - -from copy import deepcopy -from typing import Any - -from env.models import SREAction, SREObservation - -CAPACITY_PLANNING_INFO = { - "id": "capacity_planning", - "name": "Capacity Planning", - "difficulty": "easy", - "description": "Analyze service metrics trends and recommend scaling decisions.", - "max_steps": 5, - "available_actions": ["query_capacity", "recommend_scaling", "escalate", "resolve"], -} - -CAPACITY_SCENARIOS = [ - { - "service": "api-gateway", - "current_replicas": 4, - "metrics": { - "cpu_avg": 72, - "cpu_p95": 89, - "mem_avg": 65, - "mem_p95": 78, - "latency_p99": 180, - "rps": 12000, - }, - "trend": "increasing", - "growth_rate_pct": 15, - "peak_event": "Black Friday sale in 2 weeks", - "correct_recommendation": "scale_out", - "target_replicas": 6, - }, - { - "service": "db-service", - "current_replicas": 3, - "metrics": { - "cpu_avg": 45, - "cpu_p95": 55, - "mem_avg": 70, - "mem_p95": 75, - "latency_p99": 30, - "rps": 8000, - }, - "trend": "stable", - "growth_rate_pct": 2, - "peak_event": None, - "correct_recommendation": "no_change", - "target_replicas": 3, - }, - { - "service": "payment-service", - "current_replicas": 6, - "metrics": { - "cpu_avg": 35, - "cpu_p95": 42, - "mem_avg": 48, - "mem_p95": 55, - "latency_p99": 95, - "rps": 5000, - }, - "trend": "decreasing", - "growth_rate_pct": -5, - "peak_event": None, - "correct_recommendation": "scale_in", - "target_replicas": 4, - }, - { - "service": "auth-service", - "current_replicas": 3, - "metrics": { - "cpu_avg": 88, - "cpu_p95": 97, - "mem_avg": 82, - "mem_p95": 91, - "latency_p99": 210, - "rps": 15000, - }, - "trend": "increasing", - "growth_rate_pct": 25, - "peak_event": "Product launch next week", - "correct_recommendation": "scale_out_urgent", - "target_replicas": 6, - }, -] - - -def init_capacity_planning_task( - catalogs: dict[str, Any], service_map: dict[str, list[str]], rng -) -> dict[str, Any]: - scenario = deepcopy(rng.choice(CAPACITY_SCENARIOS)) - return { - "task": "capacity_planning", - "scenario": scenario, - "queries_made": [], - "recommendation": None, - "escalated": False, - "invalid_actions": 0, - "service_map": service_map, - "message": ( - "Analyze the capacity metrics for the target service. Query capacity data " - "first, then recommend a scaling action. Use action_type='query_capacity' " - "to get metrics, then action_type='recommend_scaling' with parameters " - "containing your recommendation (scale_out, scale_in, no_change, or " - "scale_out_urgent) and target replica count." - ), - } - - -def apply_capacity_planning_action( - state: dict[str, Any], action: SREAction, step_count: int -) -> str: - scenario = state["scenario"] - - if action.action_type == "escalate": - state["escalated"] = True - return f"Capacity planning for {scenario['service']} escalated to the infrastructure team." - - if action.action_type == "resolve": - if state["recommendation"]: - return "Recommendation already submitted; waiting for episode termination." - state["invalid_actions"] += 1 - return "Resolve is only meaningful after submitting a scaling recommendation." - - if action.action_type == "query_capacity": - if action.target not in {scenario["service"], "all"}: - state["invalid_actions"] += 1 - return f"Query must target '{scenario['service']}' or 'all'." - if action.target not in state["queries_made"]: - state["queries_made"].append(action.target) - return ( - f"Capacity data for {scenario['service']}: " - f"replicas={scenario['current_replicas']}, " - f"cpu_avg={scenario['metrics']['cpu_avg']}%, " - f"cpu_p95={scenario['metrics']['cpu_p95']}%, " - f"mem_avg={scenario['metrics']['mem_avg']}%, " - f"mem_p95={scenario['metrics']['mem_p95']}%, " - f"latency_p99={scenario['metrics']['latency_p99']}ms, " - f"rps={scenario['metrics']['rps']}, " - f"trend={scenario['trend']}, " - f"growth_rate={scenario['growth_rate_pct']}%." - + ( - f" Upcoming event: {scenario['peak_event']}." - if scenario["peak_event"] - else "" - ) - ) - - if action.action_type == "recommend_scaling": - recommendation = str(action.parameters.get("recommendation", "")).lower() - target_replicas = action.parameters.get("target_replicas") - if target_replicas is not None: - try: - target_replicas = int(target_replicas) - except (ValueError, TypeError): - target_replicas = None - - state["recommendation"] = { - "recommendation": recommendation, - "target_replicas": target_replicas, - "service": scenario["service"], - "step": step_count + 1, - } - return ( - f"Scaling recommendation submitted: {recommendation} to " - f"{target_replicas} replicas for {scenario['service']}." - ) - - state["invalid_actions"] += 1 - return f"Action {action.action_type} is not supported for capacity planning." - - -def build_capacity_planning_observation( - task_id: str, - step_count: int, - state: dict[str, Any], - service_map: dict[str, list[str]], - done: bool, - message: str, -) -> SREObservation: - scenario = state["scenario"] - visible_metrics = {} - if scenario["service"] in state["queries_made"] or "all" in state["queries_made"]: - visible_metrics = {scenario["service"]: scenario["metrics"]} - - context = { - "instruction": ( - "Analyze capacity metrics and recommend a scaling decision. " - "Query capacity data first, then recommend: scale_out, scale_in, " - "no_change, or scale_out_urgent with a target replica count." - ), - "service": scenario["service"], - "current_replicas": scenario["current_replicas"], - "trend": scenario["trend"], - "growth_rate_pct": scenario["growth_rate_pct"], - "peak_event": scenario["peak_event"], - "queries_made": state["queries_made"], - "recommendation_submitted": state["recommendation"] is not None, - } - logs = [ - f"Capacity review requested for {scenario['service']}", - f"Traffic trend: {scenario['trend']} ({scenario['growth_rate_pct']}% growth)", - ] - if scenario["peak_event"]: - logs.append(f"Upcoming peak event: {scenario['peak_event']}") - - return SREObservation( - task_id=task_id, - step=step_count, - context=context, - available_actions=CAPACITY_PLANNING_INFO["available_actions"], - alert_queue=[], - service_map=service_map, - metrics=visible_metrics, - logs=logs, - done=done, - message=message, - ) - - -def is_capacity_planning_done( - state: dict[str, Any], step_count: int, max_steps: int -) -> bool: - return state["recommendation"] is not None or step_count >= max_steps diff --git a/scratch/sre/env/tasks/task_chaos_engineering.py b/scratch/sre/env/tasks/task_chaos_engineering.py deleted file mode 100644 index 7360af2782750fe583bf55a4e21e5cc9dbe36e24..0000000000000000000000000000000000000000 --- a/scratch/sre/env/tasks/task_chaos_engineering.py +++ /dev/null @@ -1,358 +0,0 @@ -from __future__ import annotations - -from copy import deepcopy -from typing import Any - -from env.models import SREAction, SREObservation - -CHAOS_ENGINEERING_INFO = { - "id": "chaos_engineering", - "name": "Chaos Engineering Scenario", - "difficulty": "hard", - "description": "Inject a controlled failure, observe system impact, and execute mitigation steps to restore stability.", - "max_steps": 12, - "available_actions": [ - "inject_chaos", - "observe_impact", - "mitigate_chaos", - "escalate", - "resolve", - ], -} - -CHAOS_SCENARIOS = [ - { - "id": "CHAOS-A", - "failure_type": "network_partition", - "target_service": "payment-service", - "description": "Simulate network partition between payment-service and db-service", - "impact": { - "payment-service": { - "status": "degraded", - "error_rate": 0.35, - "latency_p99": 5000, - "note": "timeout waiting for db responses", - }, - "db-service": { - "status": "healthy", - "error_rate": 0.002, - "latency_p99": 20, - "note": "isolated but healthy", - }, - "api-gateway": { - "status": "degraded", - "error_rate": 0.15, - "latency_p99": 350, - "note": "upstream payment failures", - }, - }, - "mitigation_steps": [ - { - "step": "enable_circuit_breaker", - "description": "Enable circuit breaker on payment-service to fail fast", - "effect": "reduces latency, errors become predictable", - }, - { - "step": "enable_fallback", - "description": "Enable cached payment status fallback", - "effect": "serves stale data, reduces user-facing errors", - }, - { - "step": "restore_network", - "description": "Restore network connectivity between services", - "effect": "full recovery", - }, - ], - "correct_order": [ - "enable_circuit_breaker", - "enable_fallback", - "restore_network", - ], - }, - { - "id": "CHAOS-B", - "failure_type": "pod_termination", - "target_service": "auth-service", - "description": "Randomly terminate 2 of 3 auth-service pods", - "impact": { - "auth-service": { - "status": "critical", - "error_rate": 0.45, - "latency_p99": 800, - "note": "single pod handling 3x traffic", - }, - "api-gateway": { - "status": "degraded", - "error_rate": 0.22, - "latency_p99": 400, - "note": "auth failures causing login errors", - }, - "user-service": { - "status": "warning", - "error_rate": 0.08, - "latency_p99": 180, - "note": "mild impact from auth retries", - }, - }, - "mitigation_steps": [ - { - "step": "scale_out_pods", - "description": "Scale auth-service from 1 to 4 pods", - "effect": "reduces load per pod", - }, - { - "step": "enable_rate_limiting", - "description": "Rate limit auth requests to prevent cascade", - "effect": "protects downstream services", - }, - { - "step": "verify_auth_health", - "description": "Verify all auth pods are healthy and serving", - "effect": "confirms recovery", - }, - ], - "correct_order": [ - "scale_out_pods", - "enable_rate_limiting", - "verify_auth_health", - ], - }, - { - "id": "CHAOS-C", - "failure_type": "database_failover", - "target_service": "db-service", - "description": "Trigger primary-to-replica database failover", - "impact": { - "db-service": { - "status": "critical", - "error_rate": 0.60, - "latency_p99": 10000, - "note": "failover in progress, writes blocked", - }, - "payment-service": { - "status": "critical", - "error_rate": 0.50, - "latency_p99": 8000, - "note": "all db writes failing", - }, - "auth-service": { - "status": "degraded", - "error_rate": 0.15, - "latency_p99": 300, - "note": "read queries hitting replica", - }, - }, - "mitigation_steps": [ - { - "step": "enable_read_only_mode", - "description": "Switch payment-service to read-only mode", - "effect": "prevents write errors, serves cached data", - }, - { - "step": "monitor_failover_progress", - "description": "Monitor DB failover status", - "effect": "visibility into recovery timeline", - }, - { - "step": "resume_writes", - "description": "Resume write operations after failover completes", - "effect": "full recovery", - }, - ], - "correct_order": [ - "enable_read_only_mode", - "monitor_failover_progress", - "resume_writes", - ], - }, -] - - -def init_chaos_engineering_task( - catalogs: dict[str, Any], service_map: dict[str, list[str]], rng -) -> dict[str, Any]: - scenario = deepcopy(rng.choice(CHAOS_SCENARIOS)) - return { - "task": "chaos_engineering", - "scenario": scenario, - "chaos_injected": False, - "impact_observed": False, - "mitigation_steps_completed": [], - "mitigation_in_wrong_order": 0, - "final_state": None, - "escalated": False, - "invalid_actions": 0, - "service_map": service_map, - "message": ( - "You are running a chaos engineering experiment. Inject the failure, " - "observe the impact on the service topology, then execute mitigation " - "steps in the correct order. Use action_type='inject_chaos' to start, " - "action_type='observe_impact' to check effects, and " - "action_type='mitigate_chaos' with the mitigation step name." - ), - } - - -def apply_chaos_engineering_action( - state: dict[str, Any], action: SREAction, step_count: int -) -> str: - scenario = state["scenario"] - - if action.action_type == "escalate": - state["escalated"] = True - return f"Chaos experiment for {scenario['target_service']} escalated to stop the experiment." - - if action.action_type == "resolve": - if state["final_state"]: - return "Chaos experiment already concluded." - state["invalid_actions"] += 1 - return "Resolve is only meaningful after completing the chaos experiment." - - if action.action_type == "inject_chaos": - if state["chaos_injected"]: - return "Chaos already injected. Observe impact or begin mitigation." - state["chaos_injected"] = True - return ( - f"Chaos injected: {scenario['description']}. " - f"Use action_type='observe_impact' to see the effects." - ) - - if action.action_type == "observe_impact": - if not state["chaos_injected"]: - state["invalid_actions"] += 1 - return ( - "No chaos has been injected yet. Use action_type='inject_chaos' first." - ) - state["impact_observed"] = True - impact_summary = "; ".join( - f"{svc}: {data['note']}" for svc, data in scenario["impact"].items() - ) - return f"Impact observed: {impact_summary}" - - if action.action_type == "mitigate_chaos": - if not state["chaos_injected"]: - state["invalid_actions"] += 1 - return "No chaos has been injected yet." - step_name = str(action.parameters.get("step", "")).strip() - if not step_name: - state["invalid_actions"] += 1 - return "Must specify mitigation step name in parameters." - - valid_steps = {s["step"] for s in scenario["mitigation_steps"]} - if step_name not in valid_steps: - state["invalid_actions"] += 1 - return f"Invalid mitigation step. Options: {sorted(valid_steps)}." - - if step_name in state["mitigation_steps_completed"]: - state["invalid_actions"] += 1 - return f"Mitigation step '{step_name}' already completed." - - expected_step = scenario["correct_order"][ - len(state["mitigation_steps_completed"]) - ] - step_info = next( - s for s in scenario["mitigation_steps"] if s["step"] == step_name - ) - - if step_name != expected_step: - state["mitigation_in_wrong_order"] += 1 - return ( - f"Out-of-order mitigation. Expected '{expected_step}' next, " - f"got '{step_name}'. {step_info['description']}." - ) - - state["mitigation_steps_completed"].append(step_name) - all_done = len(state["mitigation_steps_completed"]) == len( - scenario["correct_order"] - ) - - if all_done: - state["final_state"] = { - "outcome": "recovered", - "steps_completed": state["mitigation_steps_completed"], - "wrong_order_attempts": state["mitigation_in_wrong_order"], - "step": step_count + 1, - } - return ( - f"Mitigation step '{step_name}' completed: {step_info['effect']}. " - f"All mitigation steps complete! System recovered." - ) - - return ( - f"Mitigation step '{step_name}' completed: {step_info['effect']}. " - f"Continue with remaining steps." - ) - - state["invalid_actions"] += 1 - return f"Action {action.action_type} is not supported for chaos engineering." - - -def build_chaos_engineering_observation( - task_id: str, - step_count: int, - state: dict[str, Any], - service_map: dict[str, list[str]], - done: bool, - message: str, -) -> SREObservation: - scenario = state["scenario"] - visible_impact = {} - if state["impact_observed"]: - visible_impact = scenario["impact"] - - context = { - "instruction": ( - "Run a chaos engineering experiment: inject failure, observe impact, " - "then mitigate in the correct order. Mitigation steps must be executed " - "sequentially." - ), - "experiment": scenario["id"], - "failure_type": scenario["failure_type"], - "target_service": scenario["target_service"], - "description": scenario["description"], - "chaos_injected": state["chaos_injected"], - "impact_observed": state["impact_observed"], - "mitigation_steps_available": [ - {"step": s["step"], "description": s["description"]} - for s in scenario["mitigation_steps"] - if s["step"] not in state["mitigation_steps_completed"] - ], - "mitigation_steps_completed": state["mitigation_steps_completed"], - "remaining_steps": len(scenario["correct_order"]) - - len(state["mitigation_steps_completed"]), - "final_state": state["final_state"], - } - logs = [ - f"Chaos experiment: {scenario['description']}", - ] - if state["chaos_injected"]: - logs.append( - f"FAILURE INJECTED: {scenario['failure_type']} on {scenario['target_service']}" - ) - if state["mitigation_steps_completed"]: - logs.append( - f"Mitigation progress: {len(state['mitigation_steps_completed'])}/{len(scenario['correct_order'])} steps" - ) - - return SREObservation( - task_id=task_id, - step=step_count, - context=context, - available_actions=CHAOS_ENGINEERING_INFO["available_actions"], - alert_queue=[], - service_map=service_map, - metrics=visible_impact, - logs=logs, - done=done, - message=message, - ) - - -def is_chaos_engineering_done( - state: dict[str, Any], step_count: int, max_steps: int -) -> bool: - scenario = state["scenario"] - return ( - len(state["mitigation_steps_completed"]) == len(scenario["correct_order"]) - or step_count >= max_steps - ) diff --git a/scratch/sre/env/tasks/task_incident_diagnosis.py b/scratch/sre/env/tasks/task_incident_diagnosis.py deleted file mode 100644 index 45e6360155450487e3c503ba22d08f68c6eb12d2..0000000000000000000000000000000000000000 --- a/scratch/sre/env/tasks/task_incident_diagnosis.py +++ /dev/null @@ -1,378 +0,0 @@ -from __future__ import annotations - -from copy import deepcopy -from typing import Any - -from env.models import SREAction, SREObservation - -INCIDENT_DIAGNOSIS_INFO = { - "id": "incident_diagnosis", - "name": "Incident Diagnosis", - "difficulty": "medium", - "description": "Identify root cause service and failure mode from noisy metrics.", - "max_steps": 12, - "available_actions": ["diagnose", "resolve", "escalate"], -} - -BASE_METRICS = { - "api-gateway": {"cpu": 41, "mem": 58, "latency_p99": 120, "error_rate": 0.01}, - "auth-service": {"cpu": 37, "mem": 52, "latency_p99": 95, "error_rate": 0.008}, - "user-service": {"cpu": 35, "mem": 48, "latency_p99": 82, "error_rate": 0.006}, - "payment-service": {"cpu": 43, "mem": 56, "latency_p99": 110, "error_rate": 0.01}, - "db-service": {"cpu": 49, "mem": 63, "latency_p99": 20, "error_rate": 0.002}, -} - -# SLO targets per service (realistic production SLOs) -SERVICE_SLOS = { - "api-gateway": {"latency_p99_ms": 200, "error_rate_pct": 1.0, "availability": 99.95}, - "auth-service": {"latency_p99_ms": 150, "error_rate_pct": 0.5, "availability": 99.99}, - "user-service": {"latency_p99_ms": 120, "error_rate_pct": 0.5, "availability": 99.95}, - "payment-service": {"latency_p99_ms": 180, "error_rate_pct": 0.5, "availability": 99.99}, - "db-service": {"latency_p99_ms": 50, "error_rate_pct": 0.1, "availability": 99.999}, -} - - -def _jitter(value: float | int, rng, pct: float = 0.12) -> float | int: - """Apply random jitter of ±pct to a value, preserving type for ints.""" - factor = 1.0 + rng.uniform(-pct, pct) - result = value * factor - if isinstance(value, int): - return max(0, int(round(result))) - return max(0.0, round(result, 4)) - - -def _apply_jitter_to_metrics( - metrics: dict[str, dict[str, Any]], rng -) -> dict[str, dict[str, Any]]: - """Apply random noise to all metric values so each reset is unique.""" - jittered = {} - for service, service_metrics in metrics.items(): - jittered[service] = { - key: _jitter(val, rng, pct=0.12) - for key, val in service_metrics.items() - } - return jittered - - -def _apply_incident_metrics(scenario: dict[str, Any]) -> dict[str, dict[str, Any]]: - metrics = deepcopy(BASE_METRICS) - service = scenario["service"] - if service == "db-service": - metrics["db-service"].update({"cpu": 84, "mem": 79, "latency_p99": 460, "error_rate": 0.03}) - metrics["payment-service"].update( - {"cpu": 71, "mem": 66, "latency_p99": 320, "error_rate": 0.08} - ) - metrics["auth-service"].update( - {"cpu": 55, "mem": 58, "latency_p99": 190, "error_rate": 0.03} - ) - metrics["api-gateway"].update( - {"cpu": 62, "mem": 64, "latency_p99": 260, "error_rate": 0.04} - ) - elif service == "auth-service": - metrics["auth-service"].update( - {"cpu": 59, "mem": 68, "latency_p99": 180, "error_rate": 0.24} - ) - metrics["api-gateway"].update( - {"cpu": 63, "mem": 67, "latency_p99": 225, "error_rate": 0.18} - ) - elif service == "payment-service": - metrics["payment-service"].update( - {"cpu": 78, "mem": 97, "latency_p99": 280, "error_rate": 0.12} - ) - metrics["auth-service"].update( - {"cpu": 57, "mem": 63, "latency_p99": 165, "error_rate": 0.05} - ) - metrics["api-gateway"].update( - {"cpu": 61, "mem": 65, "latency_p99": 210, "error_rate": 0.04} - ) - elif service == "api-gateway": - metrics["api-gateway"].update( - {"cpu": 64, "mem": 60, "latency_p99": 300, "error_rate": 0.31} - ) - elif service == "user-service": - metrics["user-service"].update( - {"cpu": 56, "mem": 61, "latency_p99": 240, "error_rate": 0.19} - ) - metrics["auth-service"].update( - {"cpu": 52, "mem": 60, "latency_p99": 170, "error_rate": 0.08} - ) - metrics["api-gateway"].update( - {"cpu": 58, "mem": 65, "latency_p99": 195, "error_rate": 0.06} - ) - return metrics - - -def _build_logs(scenario: dict[str, Any]) -> dict[str, list[str]]: - normal_logs = { - "api-gateway": [ - "route cache warmup completed", - "edge auth policy refreshed", - ], - "auth-service": [ - "jwt signing keys rotated successfully", - "token cache hit ratio steady at 0.93", - ], - "user-service": [ - "profile aggregation pipeline healthy", - "read replica lag under 10ms", - ], - "payment-service": [ - "checkout authorization median stable", - "settlement worker backlog cleared", - ], - "db-service": [ - "autovacuum completed on ledger_entries", - "read pool healthy with 18 active connections", - ], - } - - scenario_logs = { - "db-service": [ - "slow query detected on ledger_entries: 428ms", - "connection pool wait exceeded 200ms", - "disk spill observed during payment reconciliation", - ], - "auth-service": [ - "upstream OAuth provider returned invalid audience", - "login request rejected with signature verification error", - "token introspection error rate exceeded SLO", - ], - "payment-service": [ - "worker restarted after memory limit breach", - "heap growth detected in checkout-session manager", - "OOM killer terminated pid 4412 on payment pod", - ], - "api-gateway": [ - "config drift detected: upstream target set to auth-v1-shadow", - "404 spike on /login due to invalid upstream cluster", - "reload succeeded but checksum mismatch persists", - ], - "user-service": [ - "deprecated /v1/profile endpoint returned 410 Gone", - "fallback client still calling sunset endpoint", - "retry storm detected for user profile hydration", - ], - } - root_service = scenario["service"] - normal_logs[root_service] = scenario_logs[root_service] - return normal_logs - - -def _build_incident_timeline(scenario: dict[str, Any], rng) -> list[dict[str, str]]: - """Build a realistic incident timeline with timestamped events.""" - base_hour = rng.randint(0, 23) - base_min = rng.randint(0, 45) - service = scenario["service"] - - timeline_templates = { - "db-service": [ - ("T+0m", f"PagerDuty alert: {service} p99 latency > 400ms"), - ("T+1m", "Upstream payment-service reports increased timeouts"), - ("T+2m", "auth-service latency degraded — possible cascade"), - ("T+3m", "api-gateway 5xx rate climbing, customer-facing impact"), - ("T+5m", "On-call SRE acknowledged the incident"), - ], - "auth-service": [ - ("T+0m", f"PagerDuty alert: {service} error rate > 20%"), - ("T+1m", "Login flow failures reported by customer support"), - ("T+2m", "api-gateway returning 401/403 at elevated rate"), - ("T+4m", "On-call SRE acknowledged the incident"), - ], - "payment-service": [ - ("T+0m", f"PagerDuty alert: {service} pod restarted (OOM killed)"), - ("T+1m", "Checkout flow latency increased to 280ms p99"), - ("T+2m", "Second pod restart observed, memory climbing on remaining pods"), - ("T+3m", "auth-service showing mild impact from backpressure"), - ("T+5m", "On-call SRE acknowledged the incident"), - ], - "api-gateway": [ - ("T+0m", f"PagerDuty alert: {service} 5xx rate > 30%"), - ("T+1m", "Customers reporting blank login page"), - ("T+3m", "Config reload attempted but no improvement"), - ("T+4m", "On-call SRE acknowledged the incident"), - ], - "user-service": [ - ("T+0m", f"PagerDuty alert: {service} 410 errors spiking"), - ("T+1m", "Profile hydration failures cascading to auth-service"), - ("T+2m", "api-gateway error rate climbing from upstream failures"), - ("T+4m", "On-call SRE acknowledged the incident"), - ], - } - events = timeline_templates.get(service, []) - return [ - {"time": t, "event": e, "utc": f"2026-03-15T{base_hour:02d}:{base_min:02d}:00Z"} - for t, e in events - ] - - -def _compute_slo_status( - metrics: dict[str, dict[str, Any]] -) -> dict[str, dict[str, Any]]: - """Compute SLO burn rate and budget remaining per service.""" - slo_status = {} - for service, slos in SERVICE_SLOS.items(): - current = metrics.get(service, {}) - latency = current.get("latency_p99", 0) - error_rate = current.get("error_rate", 0) * 100 # convert to pct - - latency_budget_burn = max(0.0, (latency - slos["latency_p99_ms"]) / slos["latency_p99_ms"]) - error_budget_burn = max(0.0, (error_rate - slos["error_rate_pct"]) / slos["error_rate_pct"]) - - slo_status[service] = { - "latency_slo_ms": slos["latency_p99_ms"], - "latency_current_ms": latency, - "latency_budget_burn_rate": round(latency_budget_burn, 3), - "error_slo_pct": slos["error_rate_pct"], - "error_current_pct": round(error_rate, 3), - "error_budget_burn_rate": round(error_budget_burn, 3), - "slo_breached": latency_budget_burn > 0 or error_budget_burn > 0, - } - return slo_status - - -def init_incident_diagnosis_task( - catalogs: dict[str, Any], service_map: dict[str, list[str]], rng -) -> dict[str, Any]: - scenario = deepcopy(rng.choice(catalogs["incidents"])) - raw_metrics = _apply_incident_metrics(scenario) - full_metrics = _apply_jitter_to_metrics(raw_metrics, rng) - visible_metrics = { - service: {"status": "query_metrics_required"} for service in full_metrics - } - slo_status = _compute_slo_status(full_metrics) - timeline = _build_incident_timeline(scenario, rng) - - return { - "task": "incident_diagnosis", - "incident": scenario, - "full_metrics": full_metrics, - "visible_metrics": visible_metrics, - "service_logs": _build_logs(scenario), - "visible_logs": [], - "queried_metrics": [], - "queried_logs": [], - "submitted_diagnosis": None, - "escalations": [], - "invalid_actions": 0, - "slo_status": slo_status, - "incident_timeline": timeline, - "message": ( - "A production incident is in progress. Use action_type='diagnose' with " - "parameters.operation set to 'query_metrics', 'query_logs', or " - "'submit_diagnosis'. Submit the root cause service in target and include " - "failure_mode in parameters. Use the SLO status and incident timeline " - "to guide your investigation." - ), - "service_map": service_map, - } - - -def apply_incident_diagnosis_action( - state: dict[str, Any], action: SREAction, step_count: int -) -> str: - if action.action_type == "escalate": - state["escalations"].append( - {"service": action.target, "step": step_count + 1, "reason": action.reasoning} - ) - return f"Escalation recorded for {action.target}." - - if action.action_type == "resolve": - if state["submitted_diagnosis"]: - return "Diagnosis already submitted; waiting for episode termination." - state["invalid_actions"] += 1 - return "Resolve is only meaningful after you submit a diagnosis." - - operation = str(action.parameters.get("operation", "")).lower() - if action.action_type != "diagnose" or operation not in { - "query_metrics", - "query_logs", - "submit_diagnosis", - }: - state["invalid_actions"] += 1 - return ( - "For incident diagnosis, use action_type='diagnose' with operation " - "query_metrics, query_logs, or submit_diagnosis." - ) - - if action.target not in state["full_metrics"]: - state["invalid_actions"] += 1 - return f"Service {action.target} is not part of the incident topology." - - if operation == "query_metrics": - if action.target not in state["queried_metrics"]: - state["queried_metrics"].append(action.target) - state["visible_metrics"][action.target] = deepcopy(state["full_metrics"][action.target]) - return f"Metrics revealed for {action.target}." - - if operation == "query_logs": - if action.target not in state["queried_logs"]: - state["queried_logs"].append(action.target) - state["visible_logs"].extend( - [f"{action.target}: {line}" for line in state["service_logs"][action.target]] - ) - return f"Logs revealed for {action.target}." - - failure_mode = str(action.parameters.get("failure_mode", "")).strip() - state["submitted_diagnosis"] = { - "service": action.target, - "failure_mode": failure_mode, - "step": step_count + 1, - } - return ( - f"Diagnosis submitted: root cause service={action.target}, " - f"failure_mode={failure_mode or 'unspecified'}." - ) - - -def build_incident_diagnosis_observation( - task_id: str, - step_count: int, - state: dict[str, Any], - service_map: dict[str, list[str]], - done: bool, - message: str, -) -> SREObservation: - context = { - "instruction": ( - "A production incident is in progress. Query metrics and logs selectively " - "to identify the root cause. Use the SLO status to identify which services " - "are breaching their error budgets. Submit your diagnosis using " - "action_type='diagnose' and parameters.operation='submit_diagnosis'." - ), - "service_topology": { - "api-gateway": ["auth-service"], - "auth-service": ["user-service", "payment-service"], - "payment-service": ["db-service"], - }, - "service_topology_hint": "api-gateway -> auth-service -> user-service; payment-service -> db-service", - "incident_timeline": state.get("incident_timeline", []), - "slo_status": state.get("slo_status", {}), - "queried_metrics": state["queried_metrics"], - "queried_logs": state["queried_logs"], - "submitted_diagnosis": state["submitted_diagnosis"], - "failure_mode_options": [ - "high latency", - "high error rate", - "memory leak", - "config drift", - "deprecated endpoint dependency", - ], - } - return SREObservation( - task_id=task_id, - step=step_count, - context=context, - available_actions=INCIDENT_DIAGNOSIS_INFO["available_actions"], - alert_queue=[], - service_map=service_map, - metrics=deepcopy(state["visible_metrics"]), - logs=list(state["visible_logs"]), - done=done, - message=message, - ) - - -def is_incident_diagnosis_done( - state: dict[str, Any], step_count: int, max_steps: int -) -> bool: - return state["submitted_diagnosis"] is not None or step_count >= max_steps diff --git a/scratch/sre/env/tasks/task_multi_incident_correlation.py b/scratch/sre/env/tasks/task_multi_incident_correlation.py deleted file mode 100644 index f8dc8e52b6e9331453270e8a486903ccff514466..0000000000000000000000000000000000000000 --- a/scratch/sre/env/tasks/task_multi_incident_correlation.py +++ /dev/null @@ -1,225 +0,0 @@ -from __future__ import annotations - -from copy import deepcopy -from typing import Any - -from env.models import SREAction, SREObservation - -MULTI_INCIDENT_CORRELATION_INFO = { - "id": "multi_incident_correlation", - "name": "Multi-Incident Correlation", - "difficulty": "medium", - "description": "Identify whether multiple simultaneous alerts share a common root cause or are independent incidents.", - "max_steps": 10, - "available_actions": ["correlate", "diagnose", "escalate", "resolve"], -} - -CORRELATION_SCENARIOS = [ - { - "id": "CORR-A", - "type": "shared_root_cause", - "alerts": [ - { - "id": "ALT-101", - "service": "api-gateway", - "severity": "critical", - "message": "5xx rate > 15%", - }, - { - "id": "ALT-102", - "service": "auth-service", - "severity": "critical", - "message": "Error rate > 20%", - }, - { - "id": "ALT-103", - "service": "db-service", - "severity": "warning", - "message": "Connection pool exhaustion", - }, - ], - "root_cause": "db-service", - "root_cause_failure": "connection pool exhaustion causing cascade", - "independent_alerts": [], - }, - { - "id": "CORR-B", - "type": "independent_incidents", - "alerts": [ - { - "id": "ALT-201", - "service": "payment-service", - "severity": "critical", - "message": "OOM restart on checkout worker", - }, - { - "id": "ALT-202", - "service": "user-service", - "severity": "warning", - "message": "Deprecated endpoint 410 errors", - }, - { - "id": "ALT-203", - "service": "api-gateway", - "severity": "warning", - "message": "Config reload checksum mismatch", - }, - ], - "root_cause": None, - "root_cause_failure": None, - "independent_alerts": ["ALT-201", "ALT-202", "ALT-203"], - }, - { - "id": "CORR-C", - "type": "partial_correlation", - "alerts": [ - { - "id": "ALT-301", - "service": "payment-service", - "severity": "critical", - "message": "Latency spike on checkout", - }, - { - "id": "ALT-302", - "service": "db-service", - "severity": "critical", - "message": "Slow queries on ledger table", - }, - { - "id": "ALT-303", - "service": "auth-service", - "severity": "warning", - "message": "Token cache miss rate elevated", - }, - ], - "root_cause": "db-service", - "root_cause_failure": "slow queries affecting payment-service only", - "independent_alerts": ["ALT-303"], - }, -] - - -def init_multi_incident_correlation_task( - catalogs: dict[str, Any], service_map: dict[str, list[str]], rng -) -> dict[str, Any]: - scenario = deepcopy(rng.choice(CORRELATION_SCENARIOS)) - visible_alerts = deepcopy(scenario["alerts"]) - for alert in visible_alerts: - alert["status"] = "pending" - alert["correlated_with"] = None - - return { - "task": "multi_incident_correlation", - "scenario": scenario, - "alerts": visible_alerts, - "queried_services": [], - "correlation_submitted": None, - "escalated_alerts": [], - "invalid_actions": 0, - "service_map": service_map, - "message": ( - "Multiple alerts are firing simultaneously. Determine if they share a " - "common root cause or are independent. Use action_type='diagnose' to query " - "metrics for services, then action_type='correlate' with parameters " - "containing your correlation analysis." - ), - } - - -def apply_multi_incident_correlation_action( - state: dict[str, Any], action: SREAction, step_count: int -) -> str: - scenario = state["scenario"] - - if action.action_type == "escalate": - state["escalated_alerts"].append(action.target) - return f"Alert {action.target} escalated for separate investigation." - - if action.action_type == "resolve": - if state["correlation_submitted"]: - return "Correlation already submitted; waiting for episode termination." - state["invalid_actions"] += 1 - return "Resolve is only meaningful after submitting correlation analysis." - - if action.action_type == "diagnose": - operation = str(action.parameters.get("operation", "")).lower() - if operation != "query_metrics": - state["invalid_actions"] += 1 - return "Use operation='query_metrics' for correlation tasks." - if action.target not in state["queried_services"]: - state["queried_services"].append(action.target) - alert_services = {a["service"] for a in state["alerts"]} - if action.target not in alert_services: - state["invalid_actions"] += 1 - return f"Service {action.target} is not part of the current alert set." - return f"Metrics queried for {action.target}. Check for anomalous patterns." - - if action.action_type == "correlate": - correlation_type = str(action.parameters.get("correlation_type", "")).lower() - root_cause = str(action.parameters.get("root_cause_service", "")).strip() - alert_ids = action.parameters.get("alert_ids", []) - if not isinstance(alert_ids, list): - alert_ids = [alert_ids] - - state["correlation_submitted"] = { - "correlation_type": correlation_type, - "root_cause_service": root_cause, - "alert_ids": alert_ids, - "step": step_count + 1, - } - return ( - f"Correlation submitted: type={correlation_type}, " - f"root_cause={root_cause or 'none'}, alerts={alert_ids}." - ) - - state["invalid_actions"] += 1 - return ( - f"Action {action.action_type} is not supported for multi-incident correlation." - ) - - -def build_multi_incident_correlation_observation( - task_id: str, - step_count: int, - state: dict[str, Any], - service_map: dict[str, list[str]], - done: bool, - message: str, -) -> SREObservation: - context = { - "instruction": ( - "Analyze the firing alerts and determine correlation. Options: " - "shared_root_cause (all alerts from one root cause), " - "independent_incidents (each alert is separate), or " - "partial_correlation (some share a root cause, others are independent). " - "Use action_type='correlate' with correlation_type, root_cause_service, " - "and alert_ids in parameters." - ), - "alerts": state["alerts"], - "queried_services": state["queried_services"], - "service_topology": service_map, - "correlation_submitted": state["correlation_submitted"] is not None, - } - logs = [ - f"{a['id']} {a['service']} {a['severity']}: {a['message']}" - for a in state["alerts"] - ] - - return SREObservation( - task_id=task_id, - step=step_count, - context=context, - available_actions=MULTI_INCIDENT_CORRELATION_INFO["available_actions"], - alert_queue=state["alerts"], - service_map=service_map, - metrics={"queried_services": state["queried_services"]}, - logs=logs, - done=done, - message=message, - ) - - -def is_multi_incident_correlation_done( - state: dict[str, Any], step_count: int, max_steps: int -) -> bool: - return state["correlation_submitted"] is not None or step_count >= max_steps diff --git a/scratch/sre/env/tasks/task_on_call_handoff.py b/scratch/sre/env/tasks/task_on_call_handoff.py deleted file mode 100644 index 7ffd3b9dc3942ceb6bdb8ecaedd1f1173f986c98..0000000000000000000000000000000000000000 --- a/scratch/sre/env/tasks/task_on_call_handoff.py +++ /dev/null @@ -1,219 +0,0 @@ -from __future__ import annotations - -from copy import deepcopy -from typing import Any - -from env.models import SREAction, SREObservation - -ON_CALL_HANDOFF_INFO = { - "id": "on_call_handoff", - "name": "On-Call Handoff", - "difficulty": "easy", - "description": "Summarize active incidents, pending actions, and service health for the incoming on-call engineer.", - "max_steps": 6, - "available_actions": ["summarize", "escalate", "resolve"], -} - -SHIFT_CONTEXTS = [ - { - "shift": "night_to_day", - "active_incidents": [ - { - "id": "INC-101", - "service": "payment-service", - "severity": "P2", - "status": "investigating", - "summary": "Elevated error rate on checkout endpoint", - }, - { - "id": "INC-102", - "service": "db-service", - "severity": "P3", - "status": "monitoring", - "summary": "Replica lag intermittent but self-healing", - }, - ], - "pending_actions": [ - "Deploy hotfix v2.4.1 to payment-service", - "Monitor db replica lag for next 2 hours", - ], - "resolved_last_shift": 2, - }, - { - "shift": "day_to_evening", - "active_incidents": [ - { - "id": "INC-201", - "service": "auth-service", - "severity": "P1", - "status": "mitigating", - "summary": "JWT validation failures blocking login", - }, - { - "id": "INC-202", - "service": "api-gateway", - "severity": "P2", - "status": "investigating", - "summary": "5xx spike on /login route", - }, - { - "id": "INC-203", - "service": "user-service", - "severity": "P3", - "status": "acknowledged", - "summary": "Profile hydration timeout", - }, - ], - "pending_actions": [ - "Rollback auth-service to v3.1.0", - "Verify api-gateway upstream config", - "Escalate INC-201 to platform team if not resolved in 30min", - ], - "resolved_last_shift": 1, - }, - { - "shift": "evening_to_night", - "active_incidents": [ - { - "id": "INC-301", - "service": "payment-service", - "severity": "P2", - "status": "monitoring", - "summary": "Memory pressure after scale-out", - }, - ], - "pending_actions": [ - "Verify memory stabilization after 1 hour", - "Run load test on payment-service before peak traffic", - ], - "resolved_last_shift": 3, - }, -] - -SERVICE_HEALTH_BASE = { - "api-gateway": {"status": "healthy", "error_rate": 0.01, "latency_p99": 120}, - "auth-service": {"status": "healthy", "error_rate": 0.008, "latency_p99": 95}, - "user-service": {"status": "healthy", "error_rate": 0.006, "latency_p99": 82}, - "payment-service": {"status": "healthy", "error_rate": 0.01, "latency_p99": 110}, - "db-service": {"status": "healthy", "error_rate": 0.002, "latency_p99": 20}, -} - - -def init_on_call_handoff_task( - catalogs: dict[str, Any], service_map: dict[str, list[str]], rng -) -> dict[str, Any]: - context = deepcopy(rng.choice(SHIFT_CONTEXTS)) - health = deepcopy(SERVICE_HEALTH_BASE) - for inc in context["active_incidents"]: - svc = inc["service"] - if svc in health: - if inc["severity"] == "P1": - health[svc] = { - "status": "critical", - "error_rate": 0.25, - "latency_p99": 300, - } - elif inc["severity"] == "P2": - health[svc] = { - "status": "degraded", - "error_rate": 0.12, - "latency_p99": 220, - } - elif inc["severity"] == "P3": - health[svc] = { - "status": "warning", - "error_rate": 0.05, - "latency_p99": 150, - } - - return { - "task": "on_call_handoff", - "shift_context": context, - "service_health": health, - "service_map": service_map, - "handoff_summary": None, - "escalated_incidents": [], - "invalid_actions": 0, - "message": ( - "You are the outgoing on-call SRE. Summarize the current shift for the " - "incoming engineer. Include active incidents, pending actions, and service " - "health. Use action_type='summarize' with target='handoff' and parameters " - "containing your summary." - ), - } - - -def apply_on_call_handoff_action( - state: dict[str, Any], action: SREAction, step_count: int -) -> str: - if action.action_type == "escalate": - state["escalated_incidents"].append(action.target) - return f"Incident {action.target} escalated to the next-level on-call." - - if action.action_type == "resolve": - if state["handoff_summary"]: - return "Handoff already submitted; waiting for episode termination." - state["invalid_actions"] += 1 - return "Resolve is only meaningful after submitting the handoff summary." - - if action.action_type == "summarize": - summary = str(action.parameters.get("summary", "")).strip() - if not summary: - state["invalid_actions"] += 1 - return "Handoff summary cannot be empty." - state["handoff_summary"] = { - "summary": summary, - "step": step_count + 1, - "active_incidents_count": len(state["shift_context"]["active_incidents"]), - "pending_actions_count": len(state["shift_context"]["pending_actions"]), - } - return "Handoff summary submitted successfully." - - state["invalid_actions"] += 1 - return f"Action {action.action_type} is not supported for on-call handoff." - - -def build_on_call_handoff_observation( - task_id: str, - step_count: int, - state: dict[str, Any], - service_map: dict[str, list[str]], - done: bool, - message: str, -) -> SREObservation: - context = { - "instruction": ( - "Create a concise handoff summary for the incoming on-call engineer. " - "Include: active incidents with severity, pending actions, service health " - "highlights, and any risks to watch for." - ), - "shift": state["shift_context"]["shift"], - "active_incidents": state["shift_context"]["active_incidents"], - "pending_actions": state["shift_context"]["pending_actions"], - "resolved_last_shift": state["shift_context"]["resolved_last_shift"], - "service_health": state["service_health"], - "handoff_submitted": state["handoff_summary"] is not None, - } - logs = [ - f"Shift change: {state['shift_context']['shift']} rotation", - f"{len(state['shift_context']['active_incidents'])} active incident(s) to hand off", - ] - - return SREObservation( - task_id=task_id, - step=step_count, - context=context, - available_actions=ON_CALL_HANDOFF_INFO["available_actions"], - alert_queue=[], - service_map=service_map, - metrics={"services": state["service_health"]}, - logs=logs, - done=done, - message=message, - ) - - -def is_on_call_handoff_done( - state: dict[str, Any], step_count: int, max_steps: int -) -> bool: - return state["handoff_summary"] is not None or step_count >= max_steps diff --git a/scratch/sre/env/tasks/task_registry.py b/scratch/sre/env/tasks/task_registry.py deleted file mode 100644 index fa5fb59b69bfe29f5b3e20ebf4ae85d2c95dede1..0000000000000000000000000000000000000000 --- a/scratch/sre/env/tasks/task_registry.py +++ /dev/null @@ -1,7 +0,0 @@ -EASY_TASKS = ["alert_triage", "on_call_handoff", "capacity_planning"] - -MEDIUM_TASKS = ["incident_diagnosis", "multi_incident_correlation", "auto_remediation"] - -HARD_TASKS = ["runbook_execution", "blameless_postmortem", "chaos_engineering"] - -ALL_TASKS = EASY_TASKS + MEDIUM_TASKS + HARD_TASKS diff --git a/scratch/sre/env/tasks/task_runbook_execution.py b/scratch/sre/env/tasks/task_runbook_execution.py deleted file mode 100644 index 8abde5bbacb1803d78fe0b939c56695c8b2069df..0000000000000000000000000000000000000000 --- a/scratch/sre/env/tasks/task_runbook_execution.py +++ /dev/null @@ -1,242 +0,0 @@ -from __future__ import annotations - -from copy import deepcopy -from typing import Any - -from env.models import SREAction, SREObservation - -RUNBOOK_EXECUTION_INFO = { - "id": "runbook_execution", - "name": "Runbook Execution", - "difficulty": "hard", - "description": "Execute all runbook steps in order with correct parameters.", - "max_steps": 15, - "available_actions": ["execute_step", "resolve", "escalate"], -} - - -def _normalize_int(value: Any) -> int | None: - """Coerce an int-like value from JSON (may arrive as str or int).""" - if isinstance(value, int): - return value - if isinstance(value, float) and value == int(value): - return int(value) - if isinstance(value, str): - stripped = value.strip().lstrip("+") - try: - return int(stripped) - except ValueError: - return None - return None - - -def _normalize_replicas(value: Any) -> int | None: - return _normalize_int(value) - - -def init_runbook_execution_task( - catalogs: dict[str, Any], service_map: dict[str, list[str]], rng -) -> dict[str, Any]: - runbook = deepcopy(catalogs["runbooks"][0]) - pid = rng.randint(4100, 5300) - instance_id = f"pay-{rng.randint(10, 99)}-{rng.randint(1000, 9999)}" - memory_pct = rng.randint(91, 97) - return { - "task": "runbook_execution", - "runbook": runbook, - "current_step_index": 0, - "completed_steps": [], - "tool_outputs": {}, - "hidden_values": { - "pid": pid, - "instance_id": instance_id, - "memory_pct": memory_pct, - "process_name": "python /srv/payment/checkout_worker.py", - }, - "pid_dependency_ok": False, - "out_of_order_attempts": 0, - "wrong_parameter_attempts": 0, - "invalid_actions": 0, - "report_submitted": None, - "escalations": [], - "message": ( - "Use action_type='execute_step' and set target to the exact next runbook " - "step name. Each step requires the right parameters and later steps depend " - "on outputs unlocked by earlier steps." - ), - "service_map": service_map, - } - - -def apply_runbook_execution_action( - state: dict[str, Any], action: SREAction, step_count: int -) -> str: - if action.action_type == "escalate": - state["escalations"].append( - {"step": step_count + 1, "target": action.target, "reason": action.reasoning} - ) - return f"Escalation recorded for {action.target}." - - if action.action_type == "resolve": - if len(state["completed_steps"]) == len(state["runbook"]["steps"]): - return "Runbook already complete; episode will terminate automatically." - state["invalid_actions"] += 1 - return "Resolve cannot skip the remaining runbook steps." - - if action.action_type != "execute_step": - state["invalid_actions"] += 1 - return "Runbook execution only accepts execute_step, escalate, or resolve." - - if state["current_step_index"] >= len(state["runbook"]["steps"]): - state["invalid_actions"] += 1 - return "All runbook steps are already complete." - - expected_step = state["runbook"]["steps"][state["current_step_index"]] - if action.target != expected_step["name"]: - state["out_of_order_attempts"] += 1 - return ( - f"Out-of-order step. Expected {expected_step['name']} next, " - f"received {action.target}." - ) - - hidden = state["hidden_values"] - params = action.parameters - valid = False - output: dict[str, Any] = {} - - if action.target == "check_memory_usage": - valid = params.get("service") == "payment-service" - output = { - "service": "payment-service", - "memory_usage_pct": hidden["memory_pct"], - "rss_mb": 2147, - "note": "memory pressure above the 90% mitigation threshold", - } - elif action.target == "identify_top_processes": - valid = params.get("service") == "payment-service" - output = { - "service": "payment-service", - "pid": hidden["pid"], - "instance_id": hidden["instance_id"], - "process": hidden["process_name"], - "memory_mb": 1532, - } - elif action.target == "capture_heap_dump": - submitted_pid = _normalize_int(params.get("pid")) - valid = ( - params.get("service") == "payment-service" - and submitted_pid == hidden["pid"] - ) - if valid: - state["pid_dependency_ok"] = True - output = { - "artifact": f"/tmp/heapdump-payment-{hidden['pid']}.hprof", - "pid": submitted_pid, - "captured": bool(valid), - } - elif action.target == "cordon_instance": - submitted_instance = str(params.get("instance_id", "")).strip() - valid = submitted_instance == hidden["instance_id"] - output = { - "instance_id": submitted_instance, - "status": "cordoned" if valid else "failed", - } - elif action.target == "scale_out": - replicas = _normalize_replicas(params.get("replicas")) - valid = params.get("service") == "payment-service" and replicas == 2 - output = { - "service": "payment-service", - "previous_replicas": 4, - "current_replicas": 6 if valid else 4, - } - elif action.target == "verify_recovery": - submitted_wait = _normalize_int(params.get("wait_seconds")) - valid = ( - params.get("service") == "payment-service" - and submitted_wait == 30 - ) - output = { - "service": "payment-service", - "latency_p99": 105, - "error_rate": 0.012, - "memory_usage_pct": 68, - "recovered": bool(valid), - } - elif action.target == "file_incident_report": - summary = str(params.get("summary", "")).strip() - valid = params.get("severity") == "P2" and bool(summary) - output = { - "ticket_id": "INC-2048", - "severity": params.get("severity"), - "summary": summary, - } - if valid: - state["report_submitted"] = output - - if not valid: - state["wrong_parameter_attempts"] += 1 - return ( - f"Step {action.target} used incorrect parameters and did not complete. " - f"Expected parameters similar to {expected_step['parameters']}." - ) - - state["tool_outputs"][action.target] = output - state["completed_steps"].append(action.target) - state["current_step_index"] += 1 - return f"Completed {action.target} successfully." - - -def build_runbook_execution_observation( - task_id: str, - step_count: int, - state: dict[str, Any], - service_map: dict[str, list[str]], - done: bool, - message: str, -) -> SREObservation: - next_step = None - if state["current_step_index"] < len(state["runbook"]["steps"]): - next_step = state["runbook"]["steps"][state["current_step_index"]] - - context = { - "instruction": ( - "Execute the runbook in strict order. Use action_type='execute_step', " - "target the exact next step name, and carry forward required outputs " - "such as pid and instance_id." - ), - "current_runbook": state["runbook"]["name"], - "completed_steps": state["completed_steps"], - "next_expected_step": next_step, - "tool_outputs": deepcopy(state["tool_outputs"]), - "remaining_steps": len(state["runbook"]["steps"]) - len(state["completed_steps"]), - } - logs = [ - "payment-service memory alert is firing on multiple pods", - "one payment pod was restarted by the kernel OOM killer", - ] - - return SREObservation( - task_id=task_id, - step=step_count, - context=context, - available_actions=RUNBOOK_EXECUTION_INFO["available_actions"], - alert_queue=[], - service_map=service_map, - metrics={ - "payment-service": { - "cpu": 77, - "mem": state["hidden_values"]["memory_pct"], - "latency_p99": 245, - "error_rate": 0.11, - } - }, - logs=logs, - done=done, - message=message, - ) - - -def is_runbook_execution_done( - state: dict[str, Any], step_count: int, max_steps: int -) -> bool: - return len(state["completed_steps"]) == len(state["runbook"]["steps"]) or step_count >= max_steps diff --git a/scratch/sre/inference.py b/scratch/sre/inference.py deleted file mode 100644 index 42c88fbbc2d65854c3604374e8e2486556d87d8b..0000000000000000000000000000000000000000 --- a/scratch/sre/inference.py +++ /dev/null @@ -1,476 +0,0 @@ -""" -STRICT FORMAT - do not deviate from [START]/[STEP]/[END] lines. -All tasks run sequentially. -""" - -import json -import os -import re -import time - -import httpx -from openai import OpenAI -from env.graders.scoring import clamp_task_score - -API_BASE_URL = os.getenv("API_BASE_URL", "https://router.huggingface.co/v1") -MODEL_NAME = os.getenv("MODEL_NAME", "Qwen/Qwen2.5-72B-Instruct") -HF_TOKEN = os.getenv("HF_TOKEN") -ENV_URL = os.getenv("ENV_URL", "http://localhost:7860") - -TASKS = [ - "alert_triage", - "on_call_handoff", - "capacity_planning", - "incident_diagnosis", - "multi_incident_correlation", - "auto_remediation", - "runbook_execution", - "blameless_postmortem", - "chaos_engineering", -] -MAX_STEPS = { - "alert_triage": 10, - "on_call_handoff": 6, - "capacity_planning": 5, - "incident_diagnosis": 12, - "multi_incident_correlation": 10, - "auto_remediation": 8, - "runbook_execution": 15, - "blameless_postmortem": 8, - "chaos_engineering": 12, -} -BENCHMARK = "sre-automation-env" -SCORE_FORMAT_PRECISION = 4 - -client = OpenAI(base_url=API_BASE_URL, api_key=HF_TOKEN or "hf_token_not_set") - -# --------------------------------------------------------------------------- -# Task-specific system prompts -# --------------------------------------------------------------------------- - -SYSTEM_PROMPT_BASE = """\ -You are an expert Site Reliability Engineer AI agent. -You receive observations from a simulated SRE environment and must -respond with a valid JSON action object. Always respond with ONLY -valid JSON matching this schema: -{ - "action_type": "", - "target": "", - "parameters": {}, - "reasoning": "" -} -Do NOT wrap your response in markdown code blocks. Output raw JSON only.""" - -SYSTEM_PROMPT_ALERT_TRIAGE = ( - SYSTEM_PROMPT_BASE - + """ - -TASK: Alert Triage -You have a queue of firing alerts. Your goal is to: -1. First, TRIAGE each alert: use action_type="triage" with target= and - parameters={"decision": "ignore", "priority": "P3"} for flapping or duplicate alerts. - Use {"decision": "actionable", "priority": "P1|P2|P3"} for real alerts. - Priority mapping: critical->P1, warning->P2, info->P3. -2. Then, ACKNOWLEDGE actionable alerts in priority order (P1 first, then P2, then P3): - use action_type="acknowledge" with target=. - -Key rules: -- Alerts with is_flapping=true or is_duplicate=true should be triaged as "ignore" -- Critical alerts are P1, warning alerts are P2, info alerts are P3 -- Acknowledge P1 alerts first, then P2, then P3 -- Do NOT acknowledge flapping or duplicate alerts""" -) - -SYSTEM_PROMPT_ON_CALL_HANDOFF = ( - SYSTEM_PROMPT_BASE - + """ - -TASK: On-Call Handoff -You are the outgoing on-call SRE. Create a concise handoff summary for the incoming engineer. -Include: active incidents with severity, pending actions, service health highlights, and risks. -Use action_type="summarize" with target="handoff" and parameters={"summary": ""}. -The summary should be at least 20 words and mention incident IDs, severity levels, and pending actions.""" -) - -SYSTEM_PROMPT_CAPACITY_PLANNING = ( - SYSTEM_PROMPT_BASE - + """ - -TASK: Capacity Planning -Analyze service capacity metrics and recommend a scaling decision. -1. First query data: action_type="query_capacity", target= -2. Then recommend: action_type="recommend_scaling" with parameters: - {"recommendation": "scale_out|scale_in|no_change|scale_out_urgent", "target_replicas": } - -Consider: CPU/memory utilization, traffic trends, growth rate, and upcoming peak events. -If CPU p95 > 85% or trend is increasing with a peak event coming -> scale_out or scale_out_urgent. -If CPU p95 < 50% and trend is decreasing -> scale_in. -If metrics are stable and within thresholds -> no_change.""" -) - -SYSTEM_PROMPT_INCIDENT = ( - SYSTEM_PROMPT_BASE - + """ - -TASK: Incident Diagnosis -A production incident is in progress across a microservice topology: - api-gateway -> auth-service -> user-service - -> payment-service -> db-service - -Your goal is to identify the ROOT CAUSE service and its failure mode. -Strategy: -1. Check the SLO status and incident timeline in the context first -2. Query metrics for services showing the highest SLO burn rates (action_type="diagnose", - target=, parameters={"operation": "query_metrics"}) -3. Query logs for the most suspicious services (parameters={"operation": "query_logs"}) -4. Work backwards through the dependency chain — the true root cause is usually the - furthest downstream service with anomalous metrics -5. Submit diagnosis (parameters={"operation": "submit_diagnosis", "failure_mode": ""}) - -Failure modes: "high latency", "high error rate", "memory leak", "config drift", -"deprecated endpoint dependency" - -Be efficient: query no more than 3-4 services before submitting your diagnosis.""" -) - -SYSTEM_PROMPT_MULTI_INCIDENT = ( - SYSTEM_PROMPT_BASE - + """ - -TASK: Multi-Incident Correlation -Multiple alerts are firing simultaneously. Determine if they share a common root cause -or are independent incidents. -1. Query metrics for each affected service: action_type="diagnose", target=, - parameters={"operation": "query_metrics"} -2. Analyze patterns: are metrics anomalous across all services (shared root cause), - or only in specific services (independent)? -3. Submit correlation: action_type="correlate" with parameters: - {"correlation_type": "shared_root_cause|independent_incidents|partial_correlation", - "root_cause_service": "", "alert_ids": ["ALT-xxx", ...]} - -For shared_root_cause: identify the single root cause service affecting all alerts. -For independent_incidents: set root_cause_service to "none", list all alert ids. -For partial_correlation: identify which alerts share a root cause and which are independent.""" -) - -SYSTEM_PROMPT_AUTO_REMEDIATION = ( - SYSTEM_PROMPT_BASE - + """ - -TASK: Auto-Remediation with Rollback -A production incident requires remediation. You must: -1. Choose a remediation action: action_type="remediate" with parameters={"action": ""} - Review the remediation_options in the context and pick the one that addresses the root cause. -2. Verify the result: action_type="verify_recovery" (no parameters needed) -3. If metrics got WORSE, immediately rollback: action_type="rollback" - If metrics improved, you're done. -4. If partial improvement, consider trying a different action. - -The CORRECT action fixes the root cause. Wrong actions may make things worse or only mask symptoms. -Think carefully about which action addresses the stated root cause.""" -) - -SYSTEM_PROMPT_RUNBOOK = ( - SYSTEM_PROMPT_BASE - + """ - -TASK: Runbook Execution -You must execute a runbook for "High memory pressure - payment-service" in STRICT order. -Each step uses action_type="execute_step" with target=. - -Steps IN ORDER: -1. check_memory_usage — params: {"service": "payment-service"} -2. identify_top_processes — params: {"service": "payment-service"} -3. capture_heap_dump — params: {"service": "payment-service", "pid": } -4. cordon_instance — params: {"instance_id": ""} -5. scale_out — params: {"service": "payment-service", "replicas": 2} -6. verify_recovery — params: {"service": "payment-service", "wait_seconds": 30} -7. file_incident_report — params: {"severity": "P2", "summary": ""} - -CRITICAL: After step 2, read the tool_outputs carefully to extract the pid and instance_id. -These MUST be used in steps 3 and 4. The summary in step 7 must mention payment-service -and describe what was done (e.g., memory pressure, scaled out, recovered).""" -) - -SYSTEM_PROMPT_POSTMORTEM = ( - SYSTEM_PROMPT_BASE - + """ - -TASK: Blameless Postmortem Generation -Write a blameless postmortem for a production incident. Required sections: -summary, timeline, root_cause, impact, action_items. - -1. Query incident data first: - - action_type="diagnose", target="incident", parameters={"operation": "query_timeline"} - - action_type="diagnose", target="incident", parameters={"operation": "query_impact"} - - action_type="diagnose", target="incident", parameters={"operation": "query_root_cause"} - - action_type="diagnose", target="incident", parameters={"operation": "query_action_items"} -2. Write each section: action_type="write_postmortem" with parameters: - {"section": "", "content": ""} - -Each section should have substantive content (15+ words). The root_cause section should -include keywords from the actual root cause. The action_items section should reference -the specific action items identified.""" -) - -SYSTEM_PROMPT_CHAOS = ( - SYSTEM_PROMPT_BASE - + """ - -TASK: Chaos Engineering Scenario -Run a chaos engineering experiment: -1. Inject the failure: action_type="inject_chaos", target= -2. Observe the impact: action_type="observe_impact", target= -3. Execute mitigation steps IN ORDER: action_type="mitigate_chaos" with - parameters={"step": ""} - -The mitigation steps must be executed in the correct sequential order. Each step -builds on the previous one. Read the available mitigation_steps in the context -and execute them one by one in order. - -Common patterns: first contain the blast radius (circuit breaker, read-only mode), -then implement workarounds (fallback, rate limiting), then restore full service.""" -) - -TASK_PROMPTS = { - "alert_triage": SYSTEM_PROMPT_ALERT_TRIAGE, - "on_call_handoff": SYSTEM_PROMPT_ON_CALL_HANDOFF, - "capacity_planning": SYSTEM_PROMPT_CAPACITY_PLANNING, - "incident_diagnosis": SYSTEM_PROMPT_INCIDENT, - "multi_incident_correlation": SYSTEM_PROMPT_MULTI_INCIDENT, - "auto_remediation": SYSTEM_PROMPT_AUTO_REMEDIATION, - "runbook_execution": SYSTEM_PROMPT_RUNBOOK, - "blameless_postmortem": SYSTEM_PROMPT_POSTMORTEM, - "chaos_engineering": SYSTEM_PROMPT_CHAOS, -} - -TASK_FALLBACK = { - "alert_triage": lambda obs: { - "action_type": "acknowledge", - "target": (obs.get("alert_queue", [{}])[0] or {}).get("id", "ALT-001"), - "parameters": {}, - "reasoning": "fallback: acknowledging first available alert", - }, - "on_call_handoff": lambda obs: { - "action_type": "summarize", - "target": "handoff", - "parameters": { - "summary": "Active incidents and pending actions need attention." - }, - "reasoning": "fallback: submitting minimal handoff summary", - }, - "capacity_planning": lambda obs: { - "action_type": "recommend_scaling", - "target": obs.get("context", {}).get("service", "api-gateway"), - "parameters": {"recommendation": "no_change", "target_replicas": 3}, - "reasoning": "fallback: recommending no change", - }, - "incident_diagnosis": lambda obs: { - "action_type": "diagnose", - "target": "db-service", - "parameters": {"operation": "query_metrics"}, - "reasoning": "fallback: querying deepest service in dependency chain", - }, - "multi_incident_correlation": lambda obs: { - "action_type": "correlate", - "target": "all", - "parameters": { - "correlation_type": "shared_root_cause", - "root_cause_service": "db-service", - "alert_ids": [], - }, - "reasoning": "fallback: assuming shared root cause", - }, - "auto_remediation": lambda obs: { - "action_type": "remediate", - "target": obs.get("context", {}).get("service", "api-gateway"), - "parameters": {"action": "restart_service"}, - "reasoning": "fallback: attempting service restart", - }, - "runbook_execution": lambda obs: { - "action_type": "execute_step", - "target": (obs.get("context", {}).get("next_expected_step") or {}).get( - "name", "check_memory_usage" - ), - "parameters": {"service": "payment-service"}, - "reasoning": "fallback: attempting next expected runbook step", - }, - "blameless_postmortem": lambda obs: { - "action_type": "write_postmortem", - "target": "postmortem", - "parameters": { - "section": "summary", - "content": "An incident occurred and was resolved.", - }, - "reasoning": "fallback: writing minimal summary section", - }, - "chaos_engineering": lambda obs: { - "action_type": "observe_impact", - "target": obs.get("context", {}).get("target_service", "api-gateway"), - "parameters": {}, - "reasoning": "fallback: observing impact", - }, -} - -# --------------------------------------------------------------------------- -# JSON extraction helpers -# --------------------------------------------------------------------------- - - -def _extract_json(raw: str) -> dict | None: - """Extract JSON from raw LLM output, handling markdown code blocks.""" - text = raw.strip() - - # Try direct parse first - try: - return json.loads(text) - except json.JSONDecodeError: - pass - - # Extract from markdown code blocks: ```json ... ``` or ``` ... ``` - code_block_match = re.search(r"```(?:json)?\s*\n?(.*?)\n?\s*```", text, re.DOTALL) - if code_block_match: - try: - return json.loads(code_block_match.group(1).strip()) - except json.JSONDecodeError: - pass - - # Try to find a JSON object anywhere in the text - brace_match = re.search(r"\{[^{}]*(?:\{[^{}]*\}[^{}]*)*\}", text, re.DOTALL) - if brace_match: - try: - return json.loads(brace_match.group(0)) - except json.JSONDecodeError: - pass - - return None - - -# --------------------------------------------------------------------------- -# Episode runner -# --------------------------------------------------------------------------- - -MAX_RETRIES = 2 - - -def _normalize_task_score(value) -> float: - try: - numeric_value = float(value) - except (TypeError, ValueError): - numeric_value = 0.0 - return clamp_task_score(numeric_value) - - -def _format_task_score(value) -> str: - return f"{_normalize_task_score(value):.{SCORE_FORMAT_PRECISION}f}" - - -def run_episode(task_id: str): - resp = httpx.post(f"{ENV_URL}/reset", json={"task_id": task_id}, timeout=30) - resp.raise_for_status() - obs = resp.json() - session_id = obs.get("session_id", task_id) - - print(f"[START] task={task_id} env={BENCHMARK} model={MODEL_NAME}") - - rewards = [] - done = False - step = 0 - score = _normalize_task_score(0.0) - last_error = "null" - system_prompt = TASK_PROMPTS[task_id] - conversation = [{"role": "system", "content": system_prompt}] - - while not done and step < MAX_STEPS[task_id]: - # Build user message from current observation - user_msg = f"Current observation:\n{json.dumps(obs, indent=2)}\n\nWhat action do you take?" - conversation.append({"role": "user", "content": user_msg}) - - # Call LLM with retries - action = None - for attempt in range(MAX_RETRIES + 1): - try: - completion = client.chat.completions.create( - model=MODEL_NAME, - messages=conversation, - max_tokens=400, - temperature=0.1, - ) - raw = completion.choices[0].message.content.strip() - action = _extract_json(raw) - if action: - last_error = "null" - # Store the assistant response for conversation history - conversation.append( - {"role": "assistant", "content": json.dumps(action)} - ) - break - else: - last_error = "json_extraction_failed" - except Exception as e: - last_error = f"llm_error:{type(e).__name__}" - if attempt < MAX_RETRIES: - time.sleep(1) - - if not action: - action = TASK_FALLBACK[task_id](obs) - last_error = last_error or "fallback_used" - conversation.append({"role": "assistant", "content": json.dumps(action)}) - - # Ensure required fields exist - action.setdefault("action_type", "diagnose") - action.setdefault("target", "") - action.setdefault("parameters", {}) - action.setdefault("reasoning", "") - - # Step the environment - try: - step_resp = httpx.post( - f"{ENV_URL}/step", - json={"session_id": session_id, "action": action}, - timeout=30, - ) - step_resp.raise_for_status() - result = step_resp.json() - except Exception as e: - last_error = f"env_error:{type(e).__name__}" - step += 1 - error_reward = _normalize_task_score(0.0) - rewards.append(error_reward) - print( - f"[STEP] step={step} action={action.get('action_type', '?')}({action.get('target', '?')}) " - f"reward={_format_task_score(error_reward)} done=false error={last_error}" - ) - continue - - obs = result["observation"] - reward_val = _normalize_task_score(result["reward"]["value"]) - done = result["done"] - score = _normalize_task_score( - result.get("info", {}).get("cumulative_score", reward_val) - ) - - rewards.append(reward_val) - step += 1 - - print( - f"[STEP] step={step} action={action['action_type']}({action['target']}) " - f"reward={_format_task_score(reward_val)} done={str(done).lower()} error={last_error}" - ) - - # Trim conversation history if too long (keep system + last 6 exchanges) - if len(conversation) > 13: - conversation = [conversation[0]] + conversation[-12:] - - success = score >= 0.5 - rewards_str = ",".join(_format_task_score(reward) for reward in rewards) - print( - f"[END] success={str(success).lower()} steps={step} " - f"score={_format_task_score(score)} rewards={rewards_str}" - ) - return score - - -if __name__ == "__main__": - for task in TASKS: - run_episode(task) diff --git a/scratch/sre/openenv.yaml b/scratch/sre/openenv.yaml deleted file mode 100644 index f2822b2ca7bd16d76177899109ce76985266c295..0000000000000000000000000000000000000000 --- a/scratch/sre/openenv.yaml +++ /dev/null @@ -1,105 +0,0 @@ -name: sre-automation-env -version: "2.0.0" -description: > - An OpenEnv environment simulating Site Reliability Engineering tasks. - Agents must triage alerts, diagnose production incidents, execute - operational runbooks, and handle advanced SRE scenarios across a - simulated microservice topology. -tags: - - openenv - - sre - - operations - - real-world -difficulty_levels: - easy: - - alert_triage - - on_call_handoff - - capacity_planning - medium: - - incident_diagnosis - - multi_incident_correlation - - auto_remediation - hard: - - runbook_execution - - blameless_postmortem - - chaos_engineering -tasks: - # EASY - - id: alert_triage - name: Alert Triage - difficulty: easy - max_steps: 10 - description: "Prioritize and acknowledge firing alerts in correct severity order." - - id: on_call_handoff - name: On-Call Handoff - difficulty: easy - max_steps: 6 - description: "Summarize active incidents, pending actions, and service health for the incoming on-call engineer." - - id: capacity_planning - name: Capacity Planning - difficulty: easy - max_steps: 5 - description: "Analyze service metrics trends and recommend scaling decisions." - # MEDIUM - - id: incident_diagnosis - name: Incident Diagnosis - difficulty: medium - max_steps: 12 - description: "Identify root cause service and failure mode from noisy metrics." - - id: multi_incident_correlation - name: Multi-Incident Correlation - difficulty: medium - max_steps: 10 - description: "Identify whether multiple simultaneous alerts share a common root cause or are independent incidents." - - id: auto_remediation - name: Auto-Remediation with Rollback - difficulty: medium - max_steps: 8 - description: "Execute a remediation action, verify if it improved the situation, and rollback if it made things worse." - # HARD - - id: runbook_execution - name: Runbook Execution - difficulty: hard - max_steps: 15 - description: "Execute all runbook steps in order with correct parameters." - - id: blameless_postmortem - name: Blameless Postmortem Generation - difficulty: hard - max_steps: 8 - description: "Synthesize incident timeline, root cause analysis, and actionable follow-ups into a blameless postmortem document." - - id: chaos_engineering - name: Chaos Engineering Scenario - difficulty: hard - max_steps: 12 - description: "Inject a controlled failure, observe system impact, and execute mitigation steps to restore stability." -observation_space: - type: object - fields: - - name: task_id - type: string - - name: step - type: integer - - name: metrics - type: object - - name: alert_queue - type: array - - name: logs - type: array - - name: available_actions - type: array -action_space: - type: object - fields: - - name: action_type - type: string - enum: [triage, diagnose, escalate, acknowledge, execute_step, resolve, summarize, query_capacity, recommend_scaling, correlate, remediate, rollback, verify_recovery, write_postmortem, inject_chaos, observe_impact, mitigate_chaos] - - name: target - type: string - - name: parameters - type: object - - name: reasoning - type: string -endpoints: - reset: POST /reset - step: POST /step - state: GET /state diff --git a/scratch/sre/pyproject.toml b/scratch/sre/pyproject.toml deleted file mode 100644 index e9c8f5027f2297026763c7619068b679bfbef514..0000000000000000000000000000000000000000 --- a/scratch/sre/pyproject.toml +++ /dev/null @@ -1,32 +0,0 @@ -[build-system] -requires = ["setuptools>=68", "wheel"] -build-backend = "setuptools.build_meta" - -[project] -name = "sre-automation-env" -version = "1.0.0" -description = "OpenEnv-compatible SRE automation environment" -readme = "README.md" -requires-python = ">=3.10" -authors = [ - { name = "Rutul Patel" } -] -dependencies = [ - "fastapi>=0.110.0", - "uvicorn>=0.29.0", - "pydantic>=2.6.0", - "openai>=1.25.0", - "python-dotenv>=1.0.0", - "httpx>=0.27.0", - "openenv-core>=0.2.0" -] - -[project.scripts] -server = "server.app:main" - -[tool.setuptools] -include-package-data = true - -[tool.setuptools.packages.find] -where = ["."] -include = ["env*", "server*"] diff --git a/scratch/sre/requirements.txt b/scratch/sre/requirements.txt deleted file mode 100644 index 72278b5f4a1f4ee81234b0224789e8ead8c3b88b..0000000000000000000000000000000000000000 --- a/scratch/sre/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -fastapi>=0.110.0 -uvicorn>=0.29.0 -pydantic>=2.6.0 -openai>=1.25.0 -python-dotenv>=1.0.0 -httpx>=0.27.0 diff --git a/scratch/sre/server/__init__.py b/scratch/sre/server/__init__.py deleted file mode 100644 index 44f48b69da469ffb07b6aa9168ce1318ecfcc6df..0000000000000000000000000000000000000000 --- a/scratch/sre/server/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from server.app import app - -__all__ = ["app"] diff --git a/scratch/sre/server/app.py b/scratch/sre/server/app.py deleted file mode 100644 index e5bbf0ca27b553474d8ece8a6f866bd750488046..0000000000000000000000000000000000000000 --- a/scratch/sre/server/app.py +++ /dev/null @@ -1,160 +0,0 @@ -from __future__ import annotations - -import time -from collections import OrderedDict -from typing import Literal -from uuid import uuid4 - -from fastapi import FastAPI, HTTPException, Query -from fastapi.middleware.cors import CORSMiddleware -from pydantic import BaseModel - -from env.models import SREAction -from env.sre_env import SREEnv, TASK_METADATA - -app = FastAPI(title="sre-automation-env", version="1.0.0") -app.add_middleware( - CORSMiddleware, - allow_origins=["*"], - allow_credentials=True, - allow_methods=["*"], - allow_headers=["*"], -) - -MAX_SESSIONS = 200 -SESSION_TTL_SECONDS = 600 # 10 minutes - - -class _SessionEntry: - __slots__ = ("env", "created_at", "last_active") - - def __init__(self, env: SREEnv): - self.env = env - self.created_at = time.time() - self.last_active = self.created_at - - def touch(self) -> None: - self.last_active = time.time() - - @property - def expired(self) -> bool: - return (time.time() - self.last_active) > SESSION_TTL_SECONDS - - -SESSIONS: OrderedDict[str, _SessionEntry] = OrderedDict() - - -def _evict_stale_sessions() -> None: - """Remove expired sessions and enforce max session count.""" - now = time.time() - expired = [ - sid - for sid, entry in SESSIONS.items() - if (now - entry.last_active) > SESSION_TTL_SECONDS - ] - for sid in expired: - entry = SESSIONS.pop(sid, None) - if entry: - entry.env.close() - - while len(SESSIONS) > MAX_SESSIONS: - sid, entry = SESSIONS.popitem(last=False) - entry.env.close() - - -def _get_session(session_id: str) -> _SessionEntry: - entry = SESSIONS.get(session_id) - if entry is None: - raise HTTPException(status_code=404, detail="Unknown session_id") - if entry.expired: - SESSIONS.pop(session_id, None) - entry.env.close() - raise HTTPException(status_code=410, detail="Session expired") - entry.touch() - return entry - - -class ResetRequest(BaseModel): - task_id: Literal[ - "alert_triage", - "incident_diagnosis", - "runbook_execution", - "on_call_handoff", - "capacity_planning", - "multi_incident_correlation", - "auto_remediation", - "blameless_postmortem", - "chaos_engineering", - ] = "alert_triage" - - -class StepRequest(BaseModel): - session_id: str = "" - action: SREAction | None = None - - -@app.post("/reset") -def reset_environment(request: ResetRequest | None = None) -> dict: - _evict_stale_sessions() - session_id = str(uuid4()) - task_id = request.task_id if request else "alert_triage" - env = SREEnv(task_id=task_id) - observation = env.reset() - SESSIONS[session_id] = _SessionEntry(env) - return {"session_id": session_id, **observation.model_dump()} - - -@app.post("/step") -def step_environment(request: StepRequest | None = None) -> dict: - if not request or not request.session_id: - raise HTTPException( - status_code=400, detail="Missing session_id in request body" - ) - - entry = _get_session(request.session_id) - action = request.action - if not action: - # Fallback empty action if tester sends malformed action - action = SREAction( - action_type="diagnose", - target="api-gateway", - parameters={}, - reasoning="fallback action due to missing action body", - ) - - observation, reward, done, info = entry.env.step(action) - if done: - # Clean up completed sessions after a small delay - SESSIONS.pop(request.session_id, None) - return { - "observation": observation.model_dump(), - "reward": reward.model_dump(), - "done": done, - "info": info, - } - - -@app.get("/state") -def get_state(session_id: str = Query(...)) -> dict: - entry = _get_session(session_id) - return entry.env.state() - - -@app.get("/tasks") -def list_tasks() -> list[dict]: - return TASK_METADATA - - -@app.get("/health") -def healthcheck() -> dict[str, str]: - return {"status": "ok"} - - -def main() -> None: - import uvicorn - - uvicorn.run("server.app:app", host="0.0.0.0", port=7860) - - -if __name__ == "__main__": - main() diff --git a/scratch/sre/sre_automation_env.egg-info/PKG-INFO b/scratch/sre/sre_automation_env.egg-info/PKG-INFO deleted file mode 100644 index 412134932d69a597cda673841a36bcd99b7d83f7..0000000000000000000000000000000000000000 --- a/scratch/sre/sre_automation_env.egg-info/PKG-INFO +++ /dev/null @@ -1,322 +0,0 @@ -Metadata-Version: 2.4 -Name: sre-automation-env -Version: 1.0.0 -Summary: OpenEnv-compatible SRE automation environment -Author: Rutul Patel -Requires-Python: >=3.10 -Description-Content-Type: text/markdown -Requires-Dist: fastapi>=0.110.0 -Requires-Dist: uvicorn>=0.29.0 -Requires-Dist: pydantic>=2.6.0 -Requires-Dist: openai>=1.25.0 -Requires-Dist: python-dotenv>=1.0.0 -Requires-Dist: httpx>=0.27.0 -Requires-Dist: openenv-core>=0.2.0 - ---- -title: Sre Automation Env -emoji: 😻 -colorFrom: green -colorTo: pink -sdk: docker -pinned: false ---- - -# 🚨 sre-automation-env - -> An [OpenEnv](https://huggingface.co/spaces/open-env/leaderboard)-compatible reinforcement learning environment that simulates the daily work of a Site Reliability Engineer. Agents must triage noisy alert queues, diagnose cascading production incidents across a microservice graph, and execute operational runbooks with stateful parameter dependencies. - ---- - -## 1. Environment Description & Motivation - -Site Reliability Engineering is a **\$30B+ market** where every minute of downtime costs real revenue. Alert fatigue is the #1 cause of missed incidents — human SREs are bombarded with hundreds of alerts per shift, most of which are noise. The operational decisions they make — which alerts to ignore, where to look first, what remediation steps to take — are exactly the kind of sequential, high-stakes reasoning that RL agents should learn. - -`sre-automation-env` captures this operational reality: - -- **Alert Triage** mirrors the PagerDuty/OpsGenie workflow: sort through noisy, flapping, duplicate alerts and acknowledge the critical ones first. -- **Incident Diagnosis** simulates the real-time investigation an on-call SRE does during a production outage — querying metrics, reading logs, tracing cascading failures through a dependency graph. -- **Runbook Execution** tests procedural reasoning: can the agent follow a multi-step operational playbook where each step's output feeds into the next? - -### Service Topology - -The environment uses a realistic microservice dependency graph where failures cascade through the chain: - -```mermaid -graph LR - A[api-gateway] --> B[auth-service] - B --> C[user-service] - B --> D[payment-service] - D --> E[db-service] - - style A fill:#4a90d9,stroke:#333,color:#fff - style B fill:#7b68ee,stroke:#333,color:#fff - style C fill:#50c878,stroke:#333,color:#fff - style D fill:#ff6b6b,stroke:#333,color:#fff - style E fill:#ffa500,stroke:#333,color:#fff -``` - -When `db-service` has high latency, it cascades up through `payment-service` → `auth-service` → `api-gateway`. This mirrors real production architectures where identifying the *root cause* vs. a *symptom* is the core diagnostic challenge. - ---- - -## 2. Action Space - -| `action_type` | `target` | `parameters` | Used In | -|---|---|---|---| -| `triage` | Alert ID | `{"decision": "ignore\|actionable", "priority": "P1\|P2\|P3"}` | Alert Triage | -| `acknowledge` | Alert ID | Optional `{"priority": "P1"}` | Alert Triage | -| `diagnose` | Service name | `{"operation": "query_metrics\|query_logs\|submit_diagnosis", "failure_mode": "..."}` | Incident Diagnosis | -| `execute_step` | Runbook step name | Step-specific params: `service`, `pid`, `instance_id`, `replicas`, `wait_seconds`, `summary` | Runbook Execution | -| `escalate` | Any target | Optional escalation metadata | All tasks | -| `resolve` | Task target | Confirmation / no-op | All tasks | - ---- - -## 3. Observation Space - -| Field | Type | Description | -|---|---|---| -| `task_id` | `string` | Current task identifier | -| `step` | `integer` | Current step count (0-indexed) | -| `context` | `object` | Task-specific instructions, progress tracking, SLO status, incident timeline | -| `available_actions` | `array[string]` | Allowed action types for the current task | -| `alert_queue` | `array[object]` | Current alerts with severity, flapping/duplicate flags, status | -| `service_map` | `object` | Microservice dependency graph | -| `metrics` | `object` | Per-service metrics (cpu%, mem%, latency_p99, error_rate) or SLO status | -| `logs` | `array[string]` | Visible service logs (revealed incrementally via queries) | -| `done` | `boolean` | Episode termination flag | -| `message` | `string` | Environment feedback on the last action | - ---- - -## 4. Task Descriptions - -| Task | Difficulty | Max Steps | Target Score (GPT-4o) | Success Criteria | -|---|---|---|---|---| -| **Alert Triage** | 🟢 Easy | 10 | ~0.7 | Ignore flapping/duplicate alerts, acknowledge actionable alerts in P1→P2→P3 order | -| **Incident Diagnosis** | 🟡 Medium | 12 | ~0.5 | Query selective metrics/logs, identify root cause service + failure mode | -| **Runbook Execution** | 🔴 Hard | 15 | ~0.3 | Execute all 7 runbook steps in order with correct parameters (including extracted pid) | - -### Task Details - -
    -Alert Triage — 8 alerts, mixed severity, some noisy - -The agent receives 8 firing alerts randomly sampled from a pool of 20. Some are flapping (intermittent), some are duplicates. The agent must: -1. Triage each alert as ignore or actionable with correct priority -2. Acknowledge actionable alerts in descending priority order (P1 first) - -The challenge: noisy alerts waste steps, and acknowledging in wrong order loses points. -
    - -
    -Incident Diagnosis — 5 failure modes across 5 services - -One of 5 failure modes is randomly injected at reset: -- **db-service**: High latency (cascades up through payment → auth → gateway) -- **auth-service**: High error rate (blocks login flow) -- **payment-service**: Memory leak (OOM restarts) -- **api-gateway**: Config drift (wrong upstream target) -- **user-service**: Deprecated endpoint dependency - -Metrics are hidden until queried (1 step per query). The agent must efficiently gather evidence and submit a diagnosis. SLO burn rates and an incident timeline provide additional signal. -
    - -
    -Runbook Execution — 7-step operational playbook with parameter dependencies - -The runbook "High memory pressure — payment-service" has 7 steps that MUST be executed in order. Step 2 (`identify_top_processes`) reveals a `pid` and `instance_id` that are required for steps 3 and 4. This parameter extraction creates a genuine dependency chain that tests the agent's ability to use tool outputs. -
    - ---- - -## 5. Reward Function Design - -All three tasks use **dense, interpretable partial credit**. Agents receive meaningful signal for intermediate progress instead of binary pass/fail. - -### Alert Triage Rewards - -| Component | Weight | Description | -|---|---|---| -| Coverage (weighted Jaccard) | 0.55 | Acknowledging the right alerts, weighted by priority | -| Correct ignores | 0.1 each | Correctly identifying flapping/duplicate alerts | -| First-ack priority | 0.2 | Acknowledging a P1 alert first | -| Ordering accuracy | 0.15 | Maintaining correct priority ordering | -| P1 penalty | -0.1 each | P1 alerts left unacknowledged at episode end | - -### Incident Diagnosis Rewards - -| Component | Weight | Description | -|---|---|---| -| Root cause service | 0.5 | Exact match on the faulty service | -| Upstream partial credit | 0.1 | Naming a direct upstream of the root cause | -| Failure mode match | 0.2 | Fuzzy keyword match on failure description | -| Evidence collection | 0.05 + 0.05 | Querying metrics and logs for the root cause service | -| Efficiency bonus | 0.0–0.2 | Linear scale: full bonus at ≤8 steps, zero at ≥12 | -| Query penalty | -0.05 each | Unnecessary metric queries beyond 6 | - -### Runbook Execution Rewards - -| Component | Weight | Description | -|---|---|---| -| Step completion | 0.1 each (max 0.7) | Per correctly executed step | -| PID extraction | 0.1 | Correctly extracting and using pid from step 2 | -| Report quality | 0.1 | Incident report with severity, service name, coherent summary | -| Out-of-order penalty | -0.05 each | Attempting steps in wrong order | -| Wrong parameter penalty | -0.05 each | Incorrect parameter values | - -The `breakdown` dict in every reward response provides a verbose, interpretable explanation of exactly why the agent scored what it did. - ---- - -## 6. Setup & Usage - -### Docker (recommended) - -```bash -docker build -t sre-env . -docker run --rm -p 7860:7860 sre-env -``` - -### Local Development - -```bash -python3 -m venv .venv -source .venv/bin/activate -pip install -r requirements.txt -uvicorn server.app:app --host 0.0.0.0 --port 7860 -``` - -### API Examples - -**Health check:** -```bash -curl http://localhost:7860/health -# {"status": "ok"} -``` - -**List tasks:** -```bash -curl http://localhost:7860/tasks -``` - -**Reset an episode:** -```bash -curl -X POST http://localhost:7860/reset \ - -H "Content-Type: application/json" \ - -d '{"task_id": "alert_triage"}' -``` - -**Step through an episode:** -```bash -curl -X POST http://localhost:7860/step \ - -H "Content-Type: application/json" \ - -d '{ - "session_id": "", - "action": { - "action_type": "triage", - "target": "ALT-001", - "parameters": {"decision": "actionable", "priority": "P1"}, - "reasoning": "Critical payment-service alert, not flapping." - } - }' -``` - -**Inspect environment state:** -```bash -curl "http://localhost:7860/state?session_id=" -``` - -**Run inference harness:** -```bash -export HF_TOKEN= -python inference.py -``` - ---- - -## 7. Baseline Scores - -Run `python inference.py` with `HF_TOKEN` set. The inference harness runs all three tasks sequentially and prints `[START]`, `[STEP]`, and `[END]` markers per task. - -Expected baseline ranges: -| Task | Model | Expected Score | -|---|---|---| -| Alert Triage | Qwen2.5-72B | 0.5–0.8 | -| Incident Diagnosis | Qwen2.5-72B | 0.3–0.7 | -| Runbook Execution | Qwen2.5-72B | 0.1–0.5 | - ---- - -## 8. Deploying to Hugging Face Spaces - -### Step-by-step: - -1. **Create a new Space** at [huggingface.co/new-space](https://huggingface.co/new-space) - - Select **Docker** as the SDK - - Choose **Blank** template - - Set visibility to **Public** - -2. **Push your code:** - ```bash - git init - git remote add origin https://huggingface.co/spaces//sre-automation-env - git add . - git commit -m "Initial SRE environment" - git push origin main - ``` - -3. **The Space will auto-build** from your Dockerfile and expose port 7860. - -4. **Set your Space URL** in `inference.py` via the `ENV_URL` environment variable: - ```bash - ENV_URL=https://-sre-automation-env.hf.space python inference.py - ``` - -5. **Verify** the deployment: - ```bash - curl https://-sre-automation-env.hf.space/health - curl https://-sre-automation-env.hf.space/tasks - ``` - ---- - -## 9. Architecture - -``` -┌─────────────────────────────────────────────────────────┐ -│ inference.py │ -│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │ -│ │ LLM Call │◄──►│ JSON │◄──►│ Conversation │ │ -│ │ (OpenAI) │ │ Extractor│ │ History Manager │ │ -│ └──────────┘ └──────────┘ └──────────────────┘ │ -└───────────────────────┬─────────────────────────────────┘ - │ HTTP -┌───────────────────────▼─────────────────────────────────┐ -│ server/app.py (FastAPI) │ -│ POST /reset │ POST /step │ GET /state │ GET /tasks│ -│ ────────────────────────────────────────────────────── │ -│ Session Manager (TTL=10min, max=200 sessions) │ -└───────────────────────┬─────────────────────────────────┘ - │ -┌───────────────────────▼─────────────────────────────────┐ -│ env/sre_env.py │ -│ ┌──────────────┐ ┌──────────────┐ ┌───────────────┐ │ -│ │ Task Registry │ │ State Machine│ │ Reward Tracker│ │ -│ └──────┬───────┘ └──────┬───────┘ └───────┬───────┘ │ -│ │ │ │ │ -│ ┌──────▼───────┐ ┌──────▼───────┐ ┌───────▼───────┐ │ -│ │ env/tasks/ │ │ env/data/ │ │ env/graders/ │ │ -│ │ • alert │ │ • alerts.json│ │ • alert │ │ -│ │ • incident │ │ • incidents │ │ • incident │ │ -│ │ • runbook │ │ • runbooks │ │ • runbook │ │ -│ └──────────────┘ └──────────────┘ └───────────────┘ │ -└─────────────────────────────────────────────────────────┘ -``` - ---- - -## License - -MIT diff --git a/scratch/sre/sre_automation_env.egg-info/SOURCES.txt b/scratch/sre/sre_automation_env.egg-info/SOURCES.txt deleted file mode 100644 index f64a337a165a7f6c23c1dffc191e15a161052c12..0000000000000000000000000000000000000000 --- a/scratch/sre/sre_automation_env.egg-info/SOURCES.txt +++ /dev/null @@ -1,21 +0,0 @@ -README.md -pyproject.toml -env/__init__.py -env/models.py -env/sre_env.py -env/graders/__init__.py -env/graders/grader_alert_triage.py -env/graders/grader_incident_diagnosis.py -env/graders/grader_runbook_execution.py -env/tasks/__init__.py -env/tasks/task_alert_triage.py -env/tasks/task_incident_diagnosis.py -env/tasks/task_runbook_execution.py -server/__init__.py -server/app.py -sre_automation_env.egg-info/PKG-INFO -sre_automation_env.egg-info/SOURCES.txt -sre_automation_env.egg-info/dependency_links.txt -sre_automation_env.egg-info/entry_points.txt -sre_automation_env.egg-info/requires.txt -sre_automation_env.egg-info/top_level.txt \ No newline at end of file diff --git a/scratch/sre/sre_automation_env.egg-info/dependency_links.txt b/scratch/sre/sre_automation_env.egg-info/dependency_links.txt deleted file mode 100644 index 8b137891791fe96927ad78e64b0aad7bded08bdc..0000000000000000000000000000000000000000 --- a/scratch/sre/sre_automation_env.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/scratch/sre/sre_automation_env.egg-info/entry_points.txt b/scratch/sre/sre_automation_env.egg-info/entry_points.txt deleted file mode 100644 index 0847d637cdd6379cd6383fb5d669c11b5489bdeb..0000000000000000000000000000000000000000 --- a/scratch/sre/sre_automation_env.egg-info/entry_points.txt +++ /dev/null @@ -1,2 +0,0 @@ -[console_scripts] -server = server.app:main diff --git a/scratch/sre/sre_automation_env.egg-info/requires.txt b/scratch/sre/sre_automation_env.egg-info/requires.txt deleted file mode 100644 index 14b942e4edcfb5e3fd8edd254a0f2fe704791f55..0000000000000000000000000000000000000000 --- a/scratch/sre/sre_automation_env.egg-info/requires.txt +++ /dev/null @@ -1,7 +0,0 @@ -fastapi>=0.110.0 -uvicorn>=0.29.0 -pydantic>=2.6.0 -openai>=1.25.0 -python-dotenv>=1.0.0 -httpx>=0.27.0 -openenv-core>=0.2.0 diff --git a/scratch/sre/sre_automation_env.egg-info/top_level.txt b/scratch/sre/sre_automation_env.egg-info/top_level.txt deleted file mode 100644 index 5ba10e09b5f6e1844ca3eac220c4a1fb4e44ba5a..0000000000000000000000000000000000000000 --- a/scratch/sre/sre_automation_env.egg-info/top_level.txt +++ /dev/null @@ -1,2 +0,0 @@ -env -server diff --git a/scratch/sre/tests/test_score_constraints.py b/scratch/sre/tests/test_score_constraints.py deleted file mode 100644 index 8dd5cd0facba4b7fa6d264f1fa7240b693d8e9de..0000000000000000000000000000000000000000 --- a/scratch/sre/tests/test_score_constraints.py +++ /dev/null @@ -1,104 +0,0 @@ -from __future__ import annotations - -import io -import unittest -from contextlib import redirect_stdout -from types import SimpleNamespace -from unittest.mock import patch - -import inference -from env.models import SREAction -from env.sre_env import SREEnv - - -class _FakeResponse: - def __init__(self, payload): - self._payload = payload - - def raise_for_status(self) -> None: - return None - - def json(self): - return self._payload - - -class ScoreConstraintTests(unittest.TestCase): - def test_format_task_score_keeps_boundaries_open(self): - self.assertEqual(inference._format_task_score(0.0), "0.0001") - self.assertEqual(inference._format_task_score(1.0), "0.9999") - self.assertEqual(inference._format_task_score(None), "0.0001") - - def test_run_episode_emits_open_interval_score_even_if_upstream_rounds_to_edge(self): - completion = SimpleNamespace( - choices=[ - SimpleNamespace( - message=SimpleNamespace( - content='{"action_type":"resolve","target":"noop","parameters":{},"reasoning":"finish"}' - ) - ) - ] - ) - - reset_payload = { - "session_id": "session-1", - "task_id": "alert_triage", - "step": 0, - "context": {}, - "available_actions": ["resolve"], - "alert_queue": [], - "service_map": {}, - "metrics": {}, - "logs": [], - "done": False, - "message": "ready", - } - - step_payload = { - "observation": {**reset_payload, "step": 1, "done": True}, - "reward": {"value": 1.0, "breakdown": {}, "done": True, "info": {}}, - "done": True, - "info": {"cumulative_score": 1.0}, - } - - with patch("inference.httpx.post") as mock_post, patch.object( - inference.client.chat.completions, "create", return_value=completion - ): - mock_post.side_effect = [ - _FakeResponse(reset_payload), - _FakeResponse(step_payload), - ] - stdout = io.StringIO() - with redirect_stdout(stdout): - score = inference.run_episode("alert_triage") - - self.assertEqual(score, 0.9999) - self.assertIn("score=0.9999", stdout.getvalue()) - self.assertNotIn("score=1.0000", stdout.getvalue()) - - def test_env_rewards_and_cumulative_scores_stay_inside_open_interval(self): - for task_id in inference.TASKS: - with self.subTest(task_id=task_id): - env = SREEnv(task_id) - observation = env.reset() - done = False - steps_taken = 0 - - while not done and steps_taken < inference.MAX_STEPS[task_id]: - action_payload = inference.TASK_FALLBACK[task_id]( - observation.model_dump() - ) - action = SREAction(**action_payload) - observation, reward, done, info = env.step(action) - - self.assertGreater(reward.value, 0.0) - self.assertLess(reward.value, 1.0) - self.assertGreater(info["cumulative_score"], 0.0) - self.assertLess(info["cumulative_score"], 1.0) - - steps_taken += 1 - - self.assertGreater(steps_taken, 0) - - -if __name__ == "__main__": - unittest.main() diff --git a/scratch/sre/uv.lock b/scratch/sre/uv.lock deleted file mode 100644 index 6676839ab90a90366a0b49900c9a9cac676b4e5c..0000000000000000000000000000000000000000 --- a/scratch/sre/uv.lock +++ /dev/null @@ -1,2794 +0,0 @@ -version = 1 -requires-python = ">=3.10" -resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version >= '3.11' and python_full_version < '3.13' and sys_platform == 'win32'", - "python_full_version >= '3.11' and python_full_version < '3.13' and sys_platform == 'emscripten'", - "python_full_version >= '3.11' and python_full_version < '3.13' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version < '3.11'", -] - -[[package]] -name = "aiofile" -version = "3.9.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "caio" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/67/e2/d7cb819de8df6b5c1968a2756c3cb4122d4fa2b8fc768b53b7c9e5edb646/aiofile-3.9.0.tar.gz", hash = "sha256:e5ad718bb148b265b6df1b3752c4d1d83024b93da9bd599df74b9d9ffcf7919b", size = 17943 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/50/25/da1f0b4dd970e52bf5a36c204c107e11a0c6d3ed195eba0bfbc664c312b2/aiofile-3.9.0-py3-none-any.whl", hash = "sha256:ce2f6c1571538cbdfa0143b04e16b208ecb0e9cb4148e528af8a640ed51cc8aa", size = 19539 }, -] - -[[package]] -name = "aiofiles" -version = "24.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0b/03/a88171e277e8caa88a4c77808c20ebb04ba74cc4681bf1e9416c862de237/aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c", size = 30247 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/45/30bb92d442636f570cb5651bc661f52b610e2eec3f891a5dc3a4c3667db0/aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5", size = 15896 }, -] - -[[package]] -name = "annotated-doc" -version = "0.0.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303 }, -] - -[[package]] -name = "annotated-types" -version = "0.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, -] - -[[package]] -name = "anyio" -version = "4.13.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, - { name = "idna" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/19/14/2c5dd9f512b66549ae92767a9c7b330ae88e1932ca57876909410251fe13/anyio-4.13.0.tar.gz", hash = "sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc", size = 231622 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353 }, -] - -[[package]] -name = "attrs" -version = "26.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548 }, -] - -[[package]] -name = "audioop-lts" -version = "0.2.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/38/53/946db57842a50b2da2e0c1e34bd37f36f5aadba1a929a3971c5d7841dbca/audioop_lts-0.2.2.tar.gz", hash = "sha256:64d0c62d88e67b98a1a5e71987b7aa7b5bcffc7dcee65b635823dbdd0a8dbbd0", size = 30686 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/de/d4/94d277ca941de5a507b07f0b592f199c22454eeaec8f008a286b3fbbacd6/audioop_lts-0.2.2-cp313-abi3-macosx_10_13_universal2.whl", hash = "sha256:fd3d4602dc64914d462924a08c1a9816435a2155d74f325853c1f1ac3b2d9800", size = 46523 }, - { url = "https://files.pythonhosted.org/packages/f8/5a/656d1c2da4b555920ce4177167bfeb8623d98765594af59702c8873f60ec/audioop_lts-0.2.2-cp313-abi3-macosx_10_13_x86_64.whl", hash = "sha256:550c114a8df0aafe9a05442a1162dfc8fec37e9af1d625ae6060fed6e756f303", size = 27455 }, - { url = "https://files.pythonhosted.org/packages/1b/83/ea581e364ce7b0d41456fb79d6ee0ad482beda61faf0cab20cbd4c63a541/audioop_lts-0.2.2-cp313-abi3-macosx_11_0_arm64.whl", hash = "sha256:9a13dc409f2564de15dd68be65b462ba0dde01b19663720c68c1140c782d1d75", size = 26997 }, - { url = "https://files.pythonhosted.org/packages/b8/3b/e8964210b5e216e5041593b7d33e97ee65967f17c282e8510d19c666dab4/audioop_lts-0.2.2-cp313-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:51c916108c56aa6e426ce611946f901badac950ee2ddaf302b7ed35d9958970d", size = 85844 }, - { url = "https://files.pythonhosted.org/packages/c7/2e/0a1c52faf10d51def20531a59ce4c706cb7952323b11709e10de324d6493/audioop_lts-0.2.2-cp313-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:47eba38322370347b1c47024defbd36374a211e8dd5b0dcbce7b34fdb6f8847b", size = 85056 }, - { url = "https://files.pythonhosted.org/packages/75/e8/cd95eef479656cb75ab05dfece8c1f8c395d17a7c651d88f8e6e291a63ab/audioop_lts-0.2.2-cp313-abi3-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba7c3a7e5f23e215cb271516197030c32aef2e754252c4c70a50aaff7031a2c8", size = 93892 }, - { url = "https://files.pythonhosted.org/packages/5c/1e/a0c42570b74f83efa5cca34905b3eef03f7ab09fe5637015df538a7f3345/audioop_lts-0.2.2-cp313-abi3-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:def246fe9e180626731b26e89816e79aae2276f825420a07b4a647abaa84becc", size = 96660 }, - { url = "https://files.pythonhosted.org/packages/50/d5/8a0ae607ca07dbb34027bac8db805498ee7bfecc05fd2c148cc1ed7646e7/audioop_lts-0.2.2-cp313-abi3-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e160bf9df356d841bb6c180eeeea1834085464626dc1b68fa4e1d59070affdc3", size = 79143 }, - { url = "https://files.pythonhosted.org/packages/12/17/0d28c46179e7910bfb0bb62760ccb33edb5de973052cb2230b662c14ca2e/audioop_lts-0.2.2-cp313-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:4b4cd51a57b698b2d06cb9993b7ac8dfe89a3b2878e96bc7948e9f19ff51dba6", size = 84313 }, - { url = "https://files.pythonhosted.org/packages/84/ba/bd5d3806641564f2024e97ca98ea8f8811d4e01d9b9f9831474bc9e14f9e/audioop_lts-0.2.2-cp313-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:4a53aa7c16a60a6857e6b0b165261436396ef7293f8b5c9c828a3a203147ed4a", size = 93044 }, - { url = "https://files.pythonhosted.org/packages/f9/5e/435ce8d5642f1f7679540d1e73c1c42d933331c0976eb397d1717d7f01a3/audioop_lts-0.2.2-cp313-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:3fc38008969796f0f689f1453722a0f463da1b8a6fbee11987830bfbb664f623", size = 78766 }, - { url = "https://files.pythonhosted.org/packages/ae/3b/b909e76b606cbfd53875693ec8c156e93e15a1366a012f0b7e4fb52d3c34/audioop_lts-0.2.2-cp313-abi3-musllinux_1_2_s390x.whl", hash = "sha256:15ab25dd3e620790f40e9ead897f91e79c0d3ce65fe193c8ed6c26cffdd24be7", size = 87640 }, - { url = "https://files.pythonhosted.org/packages/30/e7/8f1603b4572d79b775f2140d7952f200f5e6c62904585d08a01f0a70393a/audioop_lts-0.2.2-cp313-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:03f061a1915538fd96272bac9551841859dbb2e3bf73ebe4a23ef043766f5449", size = 86052 }, - { url = "https://files.pythonhosted.org/packages/b5/96/c37846df657ccdda62ba1ae2b6534fa90e2e1b1742ca8dcf8ebd38c53801/audioop_lts-0.2.2-cp313-abi3-win32.whl", hash = "sha256:3bcddaaf6cc5935a300a8387c99f7a7fbbe212a11568ec6cf6e4bc458c048636", size = 26185 }, - { url = "https://files.pythonhosted.org/packages/34/a5/9d78fdb5b844a83da8a71226c7bdae7cc638861085fff7a1d707cb4823fa/audioop_lts-0.2.2-cp313-abi3-win_amd64.whl", hash = "sha256:a2c2a947fae7d1062ef08c4e369e0ba2086049a5e598fda41122535557012e9e", size = 30503 }, - { url = "https://files.pythonhosted.org/packages/34/25/20d8fde083123e90c61b51afb547bb0ea7e77bab50d98c0ab243d02a0e43/audioop_lts-0.2.2-cp313-abi3-win_arm64.whl", hash = "sha256:5f93a5db13927a37d2d09637ccca4b2b6b48c19cd9eda7b17a2e9f77edee6a6f", size = 24173 }, - { url = "https://files.pythonhosted.org/packages/58/a7/0a764f77b5c4ac58dc13c01a580f5d32ae8c74c92020b961556a43e26d02/audioop_lts-0.2.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:73f80bf4cd5d2ca7814da30a120de1f9408ee0619cc75da87d0641273d202a09", size = 47096 }, - { url = "https://files.pythonhosted.org/packages/aa/ed/ebebedde1a18848b085ad0fa54b66ceb95f1f94a3fc04f1cd1b5ccb0ed42/audioop_lts-0.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:106753a83a25ee4d6f473f2be6b0966fc1c9af7e0017192f5531a3e7463dce58", size = 27748 }, - { url = "https://files.pythonhosted.org/packages/cb/6e/11ca8c21af79f15dbb1c7f8017952ee8c810c438ce4e2b25638dfef2b02c/audioop_lts-0.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fbdd522624141e40948ab3e8cdae6e04c748d78710e9f0f8d4dae2750831de19", size = 27329 }, - { url = "https://files.pythonhosted.org/packages/84/52/0022f93d56d85eec5da6b9da6a958a1ef09e80c39f2cc0a590c6af81dcbb/audioop_lts-0.2.2-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:143fad0311e8209ece30a8dbddab3b65ab419cbe8c0dde6e8828da25999be911", size = 92407 }, - { url = "https://files.pythonhosted.org/packages/87/1d/48a889855e67be8718adbc7a01f3c01d5743c325453a5e81cf3717664aad/audioop_lts-0.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dfbbc74ec68a0fd08cfec1f4b5e8cca3d3cd7de5501b01c4b5d209995033cde9", size = 91811 }, - { url = "https://files.pythonhosted.org/packages/98/a6/94b7213190e8077547ffae75e13ed05edc488653c85aa5c41472c297d295/audioop_lts-0.2.2-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cfcac6aa6f42397471e4943e0feb2244549db5c5d01efcd02725b96af417f3fe", size = 100470 }, - { url = "https://files.pythonhosted.org/packages/e9/e9/78450d7cb921ede0cfc33426d3a8023a3bda755883c95c868ee36db8d48d/audioop_lts-0.2.2-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:752d76472d9804ac60f0078c79cdae8b956f293177acd2316cd1e15149aee132", size = 103878 }, - { url = "https://files.pythonhosted.org/packages/4f/e2/cd5439aad4f3e34ae1ee852025dc6aa8f67a82b97641e390bf7bd9891d3e/audioop_lts-0.2.2-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:83c381767e2cc10e93e40281a04852facc4cd9334550e0f392f72d1c0a9c5753", size = 84867 }, - { url = "https://files.pythonhosted.org/packages/68/4b/9d853e9076c43ebba0d411e8d2aa19061083349ac695a7d082540bad64d0/audioop_lts-0.2.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c0022283e9556e0f3643b7c3c03f05063ca72b3063291834cca43234f20c60bb", size = 90001 }, - { url = "https://files.pythonhosted.org/packages/58/26/4bae7f9d2f116ed5593989d0e521d679b0d583973d203384679323d8fa85/audioop_lts-0.2.2-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:a2d4f1513d63c795e82948e1305f31a6d530626e5f9f2605408b300ae6095093", size = 99046 }, - { url = "https://files.pythonhosted.org/packages/b2/67/a9f4fb3e250dda9e9046f8866e9fa7d52664f8985e445c6b4ad6dfb55641/audioop_lts-0.2.2-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:c9c8e68d8b4a56fda8c025e538e639f8c5953f5073886b596c93ec9b620055e7", size = 84788 }, - { url = "https://files.pythonhosted.org/packages/70/f7/3de86562db0121956148bcb0fe5b506615e3bcf6e63c4357a612b910765a/audioop_lts-0.2.2-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:96f19de485a2925314f5020e85911fb447ff5fbef56e8c7c6927851b95533a1c", size = 94472 }, - { url = "https://files.pythonhosted.org/packages/f1/32/fd772bf9078ae1001207d2df1eef3da05bea611a87dd0e8217989b2848fa/audioop_lts-0.2.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e541c3ef484852ef36545f66209444c48b28661e864ccadb29daddb6a4b8e5f5", size = 92279 }, - { url = "https://files.pythonhosted.org/packages/4f/41/affea7181592ab0ab560044632571a38edaf9130b84928177823fbf3176a/audioop_lts-0.2.2-cp313-cp313t-win32.whl", hash = "sha256:d5e73fa573e273e4f2e5ff96f9043858a5e9311e94ffefd88a3186a910c70917", size = 26568 }, - { url = "https://files.pythonhosted.org/packages/28/2b/0372842877016641db8fc54d5c88596b542eec2f8f6c20a36fb6612bf9ee/audioop_lts-0.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:9191d68659eda01e448188f60364c7763a7ca6653ed3f87ebb165822153a8547", size = 30942 }, - { url = "https://files.pythonhosted.org/packages/ee/ca/baf2b9cc7e96c179bb4a54f30fcd83e6ecb340031bde68f486403f943768/audioop_lts-0.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:c174e322bb5783c099aaf87faeb240c8d210686b04bd61dfd05a8e5a83d88969", size = 24603 }, - { url = "https://files.pythonhosted.org/packages/5c/73/413b5a2804091e2c7d5def1d618e4837f1cb82464e230f827226278556b7/audioop_lts-0.2.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:f9ee9b52f5f857fbaf9d605a360884f034c92c1c23021fb90b2e39b8e64bede6", size = 47104 }, - { url = "https://files.pythonhosted.org/packages/ae/8c/daa3308dc6593944410c2c68306a5e217f5c05b70a12e70228e7dd42dc5c/audioop_lts-0.2.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:49ee1a41738a23e98d98b937a0638357a2477bc99e61b0f768a8f654f45d9b7a", size = 27754 }, - { url = "https://files.pythonhosted.org/packages/4e/86/c2e0f627168fcf61781a8f72cab06b228fe1da4b9fa4ab39cfb791b5836b/audioop_lts-0.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5b00be98ccd0fc123dcfad31d50030d25fcf31488cde9e61692029cd7394733b", size = 27332 }, - { url = "https://files.pythonhosted.org/packages/c7/bd/35dce665255434f54e5307de39e31912a6f902d4572da7c37582809de14f/audioop_lts-0.2.2-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a6d2e0f9f7a69403e388894d4ca5ada5c47230716a03f2847cfc7bd1ecb589d6", size = 92396 }, - { url = "https://files.pythonhosted.org/packages/2d/d2/deeb9f51def1437b3afa35aeb729d577c04bcd89394cb56f9239a9f50b6f/audioop_lts-0.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f9b0b8a03ef474f56d1a842af1a2e01398b8f7654009823c6d9e0ecff4d5cfbf", size = 91811 }, - { url = "https://files.pythonhosted.org/packages/76/3b/09f8b35b227cee28cc8231e296a82759ed80c1a08e349811d69773c48426/audioop_lts-0.2.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2b267b70747d82125f1a021506565bdc5609a2b24bcb4773c16d79d2bb260bbd", size = 100483 }, - { url = "https://files.pythonhosted.org/packages/0b/15/05b48a935cf3b130c248bfdbdea71ce6437f5394ee8533e0edd7cfd93d5e/audioop_lts-0.2.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0337d658f9b81f4cd0fdb1f47635070cc084871a3d4646d9de74fdf4e7c3d24a", size = 103885 }, - { url = "https://files.pythonhosted.org/packages/83/80/186b7fce6d35b68d3d739f228dc31d60b3412105854edb975aa155a58339/audioop_lts-0.2.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:167d3b62586faef8b6b2275c3218796b12621a60e43f7e9d5845d627b9c9b80e", size = 84899 }, - { url = "https://files.pythonhosted.org/packages/49/89/c78cc5ac6cb5828f17514fb12966e299c850bc885e80f8ad94e38d450886/audioop_lts-0.2.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0d9385e96f9f6da847f4d571ce3cb15b5091140edf3db97276872647ce37efd7", size = 89998 }, - { url = "https://files.pythonhosted.org/packages/4c/4b/6401888d0c010e586c2ca50fce4c903d70a6bb55928b16cfbdfd957a13da/audioop_lts-0.2.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:48159d96962674eccdca9a3df280e864e8ac75e40a577cc97c5c42667ffabfc5", size = 99046 }, - { url = "https://files.pythonhosted.org/packages/de/f8/c874ca9bb447dae0e2ef2e231f6c4c2b0c39e31ae684d2420b0f9e97ee68/audioop_lts-0.2.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8fefe5868cd082db1186f2837d64cfbfa78b548ea0d0543e9b28935ccce81ce9", size = 84843 }, - { url = "https://files.pythonhosted.org/packages/3e/c0/0323e66f3daebc13fd46b36b30c3be47e3fc4257eae44f1e77eb828c703f/audioop_lts-0.2.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:58cf54380c3884fb49fdd37dfb7a772632b6701d28edd3e2904743c5e1773602", size = 94490 }, - { url = "https://files.pythonhosted.org/packages/98/6b/acc7734ac02d95ab791c10c3f17ffa3584ccb9ac5c18fd771c638ed6d1f5/audioop_lts-0.2.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:088327f00488cdeed296edd9215ca159f3a5a5034741465789cad403fcf4bec0", size = 92297 }, - { url = "https://files.pythonhosted.org/packages/13/c3/c3dc3f564ce6877ecd2a05f8d751b9b27a8c320c2533a98b0c86349778d0/audioop_lts-0.2.2-cp314-cp314t-win32.whl", hash = "sha256:068aa17a38b4e0e7de771c62c60bbca2455924b67a8814f3b0dee92b5820c0b3", size = 27331 }, - { url = "https://files.pythonhosted.org/packages/72/bb/b4608537e9ffcb86449091939d52d24a055216a36a8bf66b936af8c3e7ac/audioop_lts-0.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:a5bf613e96f49712073de86f20dbdd4014ca18efd4d34ed18c75bd808337851b", size = 31697 }, - { url = "https://files.pythonhosted.org/packages/f6/22/91616fe707a5c5510de2cac9b046a30defe7007ba8a0c04f9c08f27df312/audioop_lts-0.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:b492c3b040153e68b9fdaff5913305aaaba5bb433d8a7f73d5cf6a64ed3cc1dd", size = 25206 }, -] - -[[package]] -name = "authlib" -version = "1.6.9" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cryptography" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/af/98/00d3dd826d46959ad8e32af2dbb2398868fd9fd0683c26e56d0789bd0e68/authlib-1.6.9.tar.gz", hash = "sha256:d8f2421e7e5980cc1ddb4e32d3f5fa659cfaf60d8eaf3281ebed192e4ab74f04", size = 165134 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/53/23/b65f568ed0c22f1efacb744d2db1a33c8068f384b8c9b482b52ebdbc3ef6/authlib-1.6.9-py2.py3-none-any.whl", hash = "sha256:f08b4c14e08f0861dc18a32357b33fbcfd2ea86cfe3fe149484b4d764c4a0ac3", size = 244197 }, -] - -[[package]] -name = "backports-tarfile" -version = "1.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/86/72/cd9b395f25e290e633655a100af28cb253e4393396264a98bd5f5951d50f/backports_tarfile-1.2.0.tar.gz", hash = "sha256:d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991", size = 86406 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/fa/123043af240e49752f1c4bd24da5053b6bd00cad78c2be53c0d1e8b975bc/backports.tarfile-1.2.0-py3-none-any.whl", hash = "sha256:77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34", size = 30181 }, -] - -[[package]] -name = "beartype" -version = "0.22.9" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c7/94/1009e248bbfbab11397abca7193bea6626806be9a327d399810d523a07cb/beartype-0.22.9.tar.gz", hash = "sha256:8f82b54aa723a2848a56008d18875f91c1db02c32ef6a62319a002e3e25a975f", size = 1608866 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/71/cc/18245721fa7747065ab478316c7fea7c74777d07f37ae60db2e84f8172e8/beartype-0.22.9-py3-none-any.whl", hash = "sha256:d16c9bbc61ea14637596c5f6fbff2ee99cbe3573e46a716401734ef50c3060c2", size = 1333658 }, -] - -[[package]] -name = "brotli" -version = "1.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f7/16/c92ca344d646e71a43b8bb353f0a6490d7f6e06210f8554c8f874e454285/brotli-1.2.0.tar.gz", hash = "sha256:e310f77e41941c13340a95976fe66a8a95b01e783d430eeaf7a2f87e0a57dd0a", size = 7388632 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/64/10/a090475284fc4a71aed40a96f32e44a7fe5bda39687353dd977720b211b6/brotli-1.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3b90b767916ac44e93a8e28ce6adf8d551e43affb512f2377c732d486ac6514e", size = 863089 }, - { url = "https://files.pythonhosted.org/packages/03/41/17416630e46c07ac21e378c3464815dd2e120b441e641bc516ac32cc51d2/brotli-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6be67c19e0b0c56365c6a76e393b932fb0e78b3b56b711d180dd7013cb1fd984", size = 445442 }, - { url = "https://files.pythonhosted.org/packages/24/31/90cc06584deb5d4fcafc0985e37741fc6b9717926a78674bbb3ce018957e/brotli-1.2.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0bbd5b5ccd157ae7913750476d48099aaf507a79841c0d04a9db4415b14842de", size = 1532658 }, - { url = "https://files.pythonhosted.org/packages/62/17/33bf0c83bcbc96756dfd712201d87342732fad70bb3472c27e833a44a4f9/brotli-1.2.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3f3c908bcc404c90c77d5a073e55271a0a498f4e0756e48127c35d91cf155947", size = 1631241 }, - { url = "https://files.pythonhosted.org/packages/48/10/f47854a1917b62efe29bc98ac18e5d4f71df03f629184575b862ef2e743b/brotli-1.2.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1b557b29782a643420e08d75aea889462a4a8796e9a6cf5621ab05a3f7da8ef2", size = 1424307 }, - { url = "https://files.pythonhosted.org/packages/e4/b7/f88eb461719259c17483484ea8456925ee057897f8e64487d76e24e5e38d/brotli-1.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81da1b229b1889f25adadc929aeb9dbc4e922bd18561b65b08dd9343cfccca84", size = 1488208 }, - { url = "https://files.pythonhosted.org/packages/26/59/41bbcb983a0c48b0b8004203e74706c6b6e99a04f3c7ca6f4f41f364db50/brotli-1.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ff09cd8c5eec3b9d02d2408db41be150d8891c5566addce57513bf546e3d6c6d", size = 1597574 }, - { url = "https://files.pythonhosted.org/packages/8e/e6/8c89c3bdabbe802febb4c5c6ca224a395e97913b5df0dff11b54f23c1788/brotli-1.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a1778532b978d2536e79c05dac2d8cd857f6c55cd0c95ace5b03740824e0e2f1", size = 1492109 }, - { url = "https://files.pythonhosted.org/packages/ed/9a/4b19d4310b2dbd545c0c33f176b0528fa68c3cd0754e34b2f2bcf56548ae/brotli-1.2.0-cp310-cp310-win32.whl", hash = "sha256:b232029d100d393ae3c603c8ffd7e3fe6f798c5e28ddca5feabb8e8fdb732997", size = 334461 }, - { url = "https://files.pythonhosted.org/packages/ac/39/70981d9f47705e3c2b95c0847dfa3e7a37aa3b7c6030aedc4873081ed005/brotli-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:ef87b8ab2704da227e83a246356a2b179ef826f550f794b2c52cddb4efbd0196", size = 369035 }, - { url = "https://files.pythonhosted.org/packages/7a/ef/f285668811a9e1ddb47a18cb0b437d5fc2760d537a2fe8a57875ad6f8448/brotli-1.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:15b33fe93cedc4caaff8a0bd1eb7e3dab1c61bb22a0bf5bdfdfd97cd7da79744", size = 863110 }, - { url = "https://files.pythonhosted.org/packages/50/62/a3b77593587010c789a9d6eaa527c79e0848b7b860402cc64bc0bc28a86c/brotli-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:898be2be399c221d2671d29eed26b6b2713a02c2119168ed914e7d00ceadb56f", size = 445438 }, - { url = "https://files.pythonhosted.org/packages/cd/e1/7fadd47f40ce5549dc44493877db40292277db373da5053aff181656e16e/brotli-1.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:350c8348f0e76fff0a0fd6c26755d2653863279d086d3aa2c290a6a7251135dd", size = 1534420 }, - { url = "https://files.pythonhosted.org/packages/12/8b/1ed2f64054a5a008a4ccd2f271dbba7a5fb1a3067a99f5ceadedd4c1d5a7/brotli-1.2.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e1ad3fda65ae0d93fec742a128d72e145c9c7a99ee2fcd667785d99eb25a7fe", size = 1632619 }, - { url = "https://files.pythonhosted.org/packages/89/5a/7071a621eb2d052d64efd5da2ef55ecdac7c3b0c6e4f9d519e9c66d987ef/brotli-1.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:40d918bce2b427a0c4ba189df7a006ac0c7277c180aee4617d99e9ccaaf59e6a", size = 1426014 }, - { url = "https://files.pythonhosted.org/packages/26/6d/0971a8ea435af5156acaaccec1a505f981c9c80227633851f2810abd252a/brotli-1.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2a7f1d03727130fc875448b65b127a9ec5d06d19d0148e7554384229706f9d1b", size = 1489661 }, - { url = "https://files.pythonhosted.org/packages/f3/75/c1baca8b4ec6c96a03ef8230fab2a785e35297632f402ebb1e78a1e39116/brotli-1.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:9c79f57faa25d97900bfb119480806d783fba83cd09ee0b33c17623935b05fa3", size = 1599150 }, - { url = "https://files.pythonhosted.org/packages/0d/1a/23fcfee1c324fd48a63d7ebf4bac3a4115bdb1b00e600f80f727d850b1ae/brotli-1.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:844a8ceb8483fefafc412f85c14f2aae2fb69567bf2a0de53cdb88b73e7c43ae", size = 1493505 }, - { url = "https://files.pythonhosted.org/packages/36/e5/12904bbd36afeef53d45a84881a4810ae8810ad7e328a971ebbfd760a0b3/brotli-1.2.0-cp311-cp311-win32.whl", hash = "sha256:aa47441fa3026543513139cb8926a92a8e305ee9c71a6209ef7a97d91640ea03", size = 334451 }, - { url = "https://files.pythonhosted.org/packages/02/8b/ecb5761b989629a4758c394b9301607a5880de61ee2ee5fe104b87149ebc/brotli-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:022426c9e99fd65d9475dce5c195526f04bb8be8907607e27e747893f6ee3e24", size = 369035 }, - { url = "https://files.pythonhosted.org/packages/11/ee/b0a11ab2315c69bb9b45a2aaed022499c9c24a205c3a49c3513b541a7967/brotli-1.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:35d382625778834a7f3061b15423919aa03e4f5da34ac8e02c074e4b75ab4f84", size = 861543 }, - { url = "https://files.pythonhosted.org/packages/e1/2f/29c1459513cd35828e25531ebfcbf3e92a5e49f560b1777a9af7203eb46e/brotli-1.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7a61c06b334bd99bc5ae84f1eeb36bfe01400264b3c352f968c6e30a10f9d08b", size = 444288 }, - { url = "https://files.pythonhosted.org/packages/3d/6f/feba03130d5fceadfa3a1bb102cb14650798c848b1df2a808356f939bb16/brotli-1.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:acec55bb7c90f1dfc476126f9711a8e81c9af7fb617409a9ee2953115343f08d", size = 1528071 }, - { url = "https://files.pythonhosted.org/packages/2b/38/f3abb554eee089bd15471057ba85f47e53a44a462cfce265d9bf7088eb09/brotli-1.2.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:260d3692396e1895c5034f204f0db022c056f9e2ac841593a4cf9426e2a3faca", size = 1626913 }, - { url = "https://files.pythonhosted.org/packages/03/a7/03aa61fbc3c5cbf99b44d158665f9b0dd3d8059be16c460208d9e385c837/brotli-1.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:072e7624b1fc4d601036ab3f4f27942ef772887e876beff0301d261210bca97f", size = 1419762 }, - { url = "https://files.pythonhosted.org/packages/21/1b/0374a89ee27d152a5069c356c96b93afd1b94eae83f1e004b57eb6ce2f10/brotli-1.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:adedc4a67e15327dfdd04884873c6d5a01d3e3b6f61406f99b1ed4865a2f6d28", size = 1484494 }, - { url = "https://files.pythonhosted.org/packages/cf/57/69d4fe84a67aef4f524dcd075c6eee868d7850e85bf01d778a857d8dbe0a/brotli-1.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7a47ce5c2288702e09dc22a44d0ee6152f2c7eda97b3c8482d826a1f3cfc7da7", size = 1593302 }, - { url = "https://files.pythonhosted.org/packages/d5/3b/39e13ce78a8e9a621c5df3aeb5fd181fcc8caba8c48a194cd629771f6828/brotli-1.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:af43b8711a8264bb4e7d6d9a6d004c3a2019c04c01127a868709ec29962b6036", size = 1487913 }, - { url = "https://files.pythonhosted.org/packages/62/28/4d00cb9bd76a6357a66fcd54b4b6d70288385584063f4b07884c1e7286ac/brotli-1.2.0-cp312-cp312-win32.whl", hash = "sha256:e99befa0b48f3cd293dafeacdd0d191804d105d279e0b387a32054c1180f3161", size = 334362 }, - { url = "https://files.pythonhosted.org/packages/1c/4e/bc1dcac9498859d5e353c9b153627a3752868a9d5f05ce8dedd81a2354ab/brotli-1.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:b35c13ce241abdd44cb8ca70683f20c0c079728a36a996297adb5334adfc1c44", size = 369115 }, - { url = "https://files.pythonhosted.org/packages/6c/d4/4ad5432ac98c73096159d9ce7ffeb82d151c2ac84adcc6168e476bb54674/brotli-1.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9e5825ba2c9998375530504578fd4d5d1059d09621a02065d1b6bfc41a8e05ab", size = 861523 }, - { url = "https://files.pythonhosted.org/packages/91/9f/9cc5bd03ee68a85dc4bc89114f7067c056a3c14b3d95f171918c088bf88d/brotli-1.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0cf8c3b8ba93d496b2fae778039e2f5ecc7cff99df84df337ca31d8f2252896c", size = 444289 }, - { url = "https://files.pythonhosted.org/packages/2e/b6/fe84227c56a865d16a6614e2c4722864b380cb14b13f3e6bef441e73a85a/brotli-1.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8565e3cdc1808b1a34714b553b262c5de5fbda202285782173ec137fd13709f", size = 1528076 }, - { url = "https://files.pythonhosted.org/packages/55/de/de4ae0aaca06c790371cf6e7ee93a024f6b4bb0568727da8c3de112e726c/brotli-1.2.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:26e8d3ecb0ee458a9804f47f21b74845cc823fd1bb19f02272be70774f56e2a6", size = 1626880 }, - { url = "https://files.pythonhosted.org/packages/5f/16/a1b22cbea436642e071adcaf8d4b350a2ad02f5e0ad0da879a1be16188a0/brotli-1.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67a91c5187e1eec76a61625c77a6c8c785650f5b576ca732bd33ef58b0dff49c", size = 1419737 }, - { url = "https://files.pythonhosted.org/packages/46/63/c968a97cbb3bdbf7f974ef5a6ab467a2879b82afbc5ffb65b8acbb744f95/brotli-1.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4ecdb3b6dc36e6d6e14d3a1bdc6c1057c8cbf80db04031d566eb6080ce283a48", size = 1484440 }, - { url = "https://files.pythonhosted.org/packages/06/9d/102c67ea5c9fc171f423e8399e585dabea29b5bc79b05572891e70013cdd/brotli-1.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3e1b35d56856f3ed326b140d3c6d9db91740f22e14b06e840fe4bb1923439a18", size = 1593313 }, - { url = "https://files.pythonhosted.org/packages/9e/4a/9526d14fa6b87bc827ba1755a8440e214ff90de03095cacd78a64abe2b7d/brotli-1.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:54a50a9dad16b32136b2241ddea9e4df159b41247b2ce6aac0b3276a66a8f1e5", size = 1487945 }, - { url = "https://files.pythonhosted.org/packages/5b/e8/3fe1ffed70cbef83c5236166acaed7bb9c766509b157854c80e2f766b38c/brotli-1.2.0-cp313-cp313-win32.whl", hash = "sha256:1b1d6a4efedd53671c793be6dd760fcf2107da3a52331ad9ea429edf0902f27a", size = 334368 }, - { url = "https://files.pythonhosted.org/packages/ff/91/e739587be970a113b37b821eae8097aac5a48e5f0eca438c22e4c7dd8648/brotli-1.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:b63daa43d82f0cdabf98dee215b375b4058cce72871fd07934f179885aad16e8", size = 369116 }, - { url = "https://files.pythonhosted.org/packages/17/e1/298c2ddf786bb7347a1cd71d63a347a79e5712a7c0cba9e3c3458ebd976f/brotli-1.2.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:6c12dad5cd04530323e723787ff762bac749a7b256a5bece32b2243dd5c27b21", size = 863080 }, - { url = "https://files.pythonhosted.org/packages/84/0c/aac98e286ba66868b2b3b50338ffbd85a35c7122e9531a73a37a29763d38/brotli-1.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3219bd9e69868e57183316ee19c84e03e8f8b5a1d1f2667e1aa8c2f91cb061ac", size = 445453 }, - { url = "https://files.pythonhosted.org/packages/ec/f1/0ca1f3f99ae300372635ab3fe2f7a79fa335fee3d874fa7f9e68575e0e62/brotli-1.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:963a08f3bebd8b75ac57661045402da15991468a621f014be54e50f53a58d19e", size = 1528168 }, - { url = "https://files.pythonhosted.org/packages/d6/a6/2ebfc8f766d46df8d3e65b880a2e220732395e6d7dc312c1e1244b0f074a/brotli-1.2.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9322b9f8656782414b37e6af884146869d46ab85158201d82bab9abbcb971dc7", size = 1627098 }, - { url = "https://files.pythonhosted.org/packages/f3/2f/0976d5b097ff8a22163b10617f76b2557f15f0f39d6a0fe1f02b1a53e92b/brotli-1.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cf9cba6f5b78a2071ec6fb1e7bd39acf35071d90a81231d67e92d637776a6a63", size = 1419861 }, - { url = "https://files.pythonhosted.org/packages/9c/97/d76df7176a2ce7616ff94c1fb72d307c9a30d2189fe877f3dd99af00ea5a/brotli-1.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7547369c4392b47d30a3467fe8c3330b4f2e0f7730e45e3103d7d636678a808b", size = 1484594 }, - { url = "https://files.pythonhosted.org/packages/d3/93/14cf0b1216f43df5609f5b272050b0abd219e0b54ea80b47cef9867b45e7/brotli-1.2.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:fc1530af5c3c275b8524f2e24841cbe2599d74462455e9bae5109e9ff42e9361", size = 1593455 }, - { url = "https://files.pythonhosted.org/packages/b3/73/3183c9e41ca755713bdf2cc1d0810df742c09484e2e1ddd693bee53877c1/brotli-1.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d2d085ded05278d1c7f65560aae97b3160aeb2ea2c0b3e26204856beccb60888", size = 1488164 }, - { url = "https://files.pythonhosted.org/packages/64/6a/0c78d8f3a582859236482fd9fa86a65a60328a00983006bcf6d83b7b2253/brotli-1.2.0-cp314-cp314-win32.whl", hash = "sha256:832c115a020e463c2f67664560449a7bea26b0c1fdd690352addad6d0a08714d", size = 339280 }, - { url = "https://files.pythonhosted.org/packages/f5/10/56978295c14794b2c12007b07f3e41ba26acda9257457d7085b0bb3bb90c/brotli-1.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:e7c0af964e0b4e3412a0ebf341ea26ec767fa0b4cf81abb5e897c9338b5ad6a3", size = 375639 }, -] - -[[package]] -name = "cachetools" -version = "7.0.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/dd/57fe3fdb6e65b25a5987fd2cdc7e22db0aef508b91634d2e57d22928d41b/cachetools-7.0.5.tar.gz", hash = "sha256:0cd042c24377200c1dcd225f8b7b12b0ca53cc2c961b43757e774ebe190fd990", size = 37367 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/06/f3/39cf3367b8107baa44f861dc802cbf16263c945b62d8265d36034fc07bea/cachetools-7.0.5-py3-none-any.whl", hash = "sha256:46bc8ebefbe485407621d0a4264b23c080cedd913921bad7ac3ed2f26c183114", size = 13918 }, -] - -[[package]] -name = "caio" -version = "0.9.25" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/92/88/b8527e1b00c1811db339a1df8bd1ae49d146fcea9d6a5c40e3a80aaeb38d/caio-0.9.25.tar.gz", hash = "sha256:16498e7f81d1d0f5a4c0ad3f2540e65fe25691376e0a5bd367f558067113ed10", size = 26781 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/80/ea4ead0c5d52a9828692e7df20f0eafe8d26e671ce4883a0a146bb91049e/caio-0.9.25-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ca6c8ecda611478b6016cb94d23fd3eb7124852b985bdec7ecaad9f3116b9619", size = 36836 }, - { url = "https://files.pythonhosted.org/packages/17/b9/36715c97c873649d1029001578f901b50250916295e3dddf20c865438865/caio-0.9.25-cp310-cp310-manylinux2010_x86_64.manylinux2014_x86_64.manylinux_2_12_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:db9b5681e4af8176159f0d6598e73b2279bb661e718c7ac23342c550bd78c241", size = 79695 }, - { url = "https://files.pythonhosted.org/packages/0b/ab/07080ecb1adb55a02cbd8ec0126aa8e43af343ffabb6a71125b42670e9a1/caio-0.9.25-cp310-cp310-manylinux_2_34_aarch64.whl", hash = "sha256:bf61d7d0c4fd10ffdd98ca47f7e8db4d7408e74649ffaf4bef40b029ada3c21b", size = 79457 }, - { url = "https://files.pythonhosted.org/packages/88/95/dd55757bb671eb4c376e006c04e83beb413486821f517792ea603ef216e9/caio-0.9.25-cp310-cp310-manylinux_2_34_x86_64.whl", hash = "sha256:ab52e5b643f8bbd64a0605d9412796cd3464cb8ca88593b13e95a0f0b10508ae", size = 77705 }, - { url = "https://files.pythonhosted.org/packages/ec/90/543f556fcfcfa270713eef906b6352ab048e1e557afec12925c991dc93c2/caio-0.9.25-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d6956d9e4a27021c8bd6c9677f3a59eb1d820cc32d0343cea7961a03b1371965", size = 36839 }, - { url = "https://files.pythonhosted.org/packages/51/3b/36f3e8ec38dafe8de4831decd2e44c69303d2a3892d16ceda42afed44e1b/caio-0.9.25-cp311-cp311-manylinux2010_x86_64.manylinux2014_x86_64.manylinux_2_12_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bf84bfa039f25ad91f4f52944452a5f6f405e8afab4d445450978cd6241d1478", size = 80255 }, - { url = "https://files.pythonhosted.org/packages/df/ce/65e64867d928e6aff1b4f0e12dba0ef6d5bf412c240dc1df9d421ac10573/caio-0.9.25-cp311-cp311-manylinux_2_34_aarch64.whl", hash = "sha256:ae3d62587332bce600f861a8de6256b1014d6485cfd25d68c15caf1611dd1f7c", size = 80052 }, - { url = "https://files.pythonhosted.org/packages/46/90/e278863c47e14ec58309aa2e38a45882fbe67b4cc29ec9bc8f65852d3e45/caio-0.9.25-cp311-cp311-manylinux_2_34_x86_64.whl", hash = "sha256:fc220b8533dcf0f238a6b1a4a937f92024c71e7b10b5a2dfc1c73604a25709bc", size = 78273 }, - { url = "https://files.pythonhosted.org/packages/d3/25/79c98ebe12df31548ba4eaf44db11b7cad6b3e7b4203718335620939083c/caio-0.9.25-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:fb7ff95af4c31ad3f03179149aab61097a71fd85e05f89b4786de0359dffd044", size = 36983 }, - { url = "https://files.pythonhosted.org/packages/a3/2b/21288691f16d479945968a0a4f2856818c1c5be56881d51d4dac9b255d26/caio-0.9.25-cp312-cp312-manylinux2010_x86_64.manylinux2014_x86_64.manylinux_2_12_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:97084e4e30dfa598449d874c4d8e0c8d5ea17d2f752ef5e48e150ff9d240cd64", size = 82012 }, - { url = "https://files.pythonhosted.org/packages/03/c4/8a1b580875303500a9c12b9e0af58cb82e47f5bcf888c2457742a138273c/caio-0.9.25-cp312-cp312-manylinux_2_34_aarch64.whl", hash = "sha256:4fa69eba47e0f041b9d4f336e2ad40740681c43e686b18b191b6c5f4c5544bfb", size = 81502 }, - { url = "https://files.pythonhosted.org/packages/d1/1c/0fe770b8ffc8362c48134d1592d653a81a3d8748d764bec33864db36319d/caio-0.9.25-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:6bebf6f079f1341d19f7386db9b8b1f07e8cc15ae13bfdaff573371ba0575d69", size = 80200 }, - { url = "https://files.pythonhosted.org/packages/31/57/5e6ff127e6f62c9f15d989560435c642144aa4210882f9494204bc892305/caio-0.9.25-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d6c2a3411af97762a2b03840c3cec2f7f728921ff8adda53d7ea2315a8563451", size = 36979 }, - { url = "https://files.pythonhosted.org/packages/a3/9f/f21af50e72117eb528c422d4276cbac11fb941b1b812b182e0a9c70d19c5/caio-0.9.25-cp313-cp313-manylinux2010_x86_64.manylinux2014_x86_64.manylinux_2_12_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0998210a4d5cd5cb565b32ccfe4e53d67303f868a76f212e002a8554692870e6", size = 81900 }, - { url = "https://files.pythonhosted.org/packages/9c/12/c39ae2a4037cb10ad5eb3578eb4d5f8c1a2575c62bba675f3406b7ef0824/caio-0.9.25-cp313-cp313-manylinux_2_34_aarch64.whl", hash = "sha256:1a177d4777141b96f175fe2c37a3d96dec7911ed9ad5f02bac38aaa1c936611f", size = 81523 }, - { url = "https://files.pythonhosted.org/packages/22/59/f8f2e950eb4f1a5a3883e198dca514b9d475415cb6cd7b78b9213a0dd45a/caio-0.9.25-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:9ed3cfb28c0e99fec5e208c934e5c157d0866aa9c32aa4dc5e9b6034af6286b7", size = 80243 }, - { url = "https://files.pythonhosted.org/packages/69/ca/a08fdc7efdcc24e6a6131a93c85be1f204d41c58f474c42b0670af8c016b/caio-0.9.25-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fab6078b9348e883c80a5e14b382e6ad6aabbc4429ca034e76e730cf464269db", size = 36978 }, - { url = "https://files.pythonhosted.org/packages/5e/6c/d4d24f65e690213c097174d26eda6831f45f4734d9d036d81790a27e7b78/caio-0.9.25-cp314-cp314-manylinux2010_x86_64.manylinux2014_x86_64.manylinux_2_12_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:44a6b58e52d488c75cfaa5ecaa404b2b41cc965e6c417e03251e868ecd5b6d77", size = 81832 }, - { url = "https://files.pythonhosted.org/packages/87/a4/e534cf7d2d0e8d880e25dd61e8d921ffcfe15bd696734589826f5a2df727/caio-0.9.25-cp314-cp314-manylinux_2_34_aarch64.whl", hash = "sha256:628a630eb7fb22381dd8e3c8ab7f59e854b9c806639811fc3f4310c6bd711d79", size = 81565 }, - { url = "https://files.pythonhosted.org/packages/3f/ed/bf81aeac1d290017e5e5ac3e880fd56ee15e50a6d0353986799d1bc5cfd5/caio-0.9.25-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:0ba16aa605ccb174665357fc729cf500679c2d94d5f1458a6f0d5ca48f2060a7", size = 80071 }, - { url = "https://files.pythonhosted.org/packages/86/93/1f76c8d1bafe3b0614e06b2195784a3765bbf7b0a067661af9e2dd47fc33/caio-0.9.25-py3-none-any.whl", hash = "sha256:06c0bb02d6b929119b1cfbe1ca403c768b2013a369e2db46bfa2a5761cf82e40", size = 19087 }, -] - -[[package]] -name = "certifi" -version = "2026.2.25" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684 }, -] - -[[package]] -name = "cffi" -version = "2.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pycparser", marker = "implementation_name != 'PyPy'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/93/d7/516d984057745a6cd96575eea814fe1edd6646ee6efd552fb7b0921dec83/cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44", size = 184283 }, - { url = "https://files.pythonhosted.org/packages/9e/84/ad6a0b408daa859246f57c03efd28e5dd1b33c21737c2db84cae8c237aa5/cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49", size = 180504 }, - { url = "https://files.pythonhosted.org/packages/50/bd/b1a6362b80628111e6653c961f987faa55262b4002fcec42308cad1db680/cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c", size = 208811 }, - { url = "https://files.pythonhosted.org/packages/4f/27/6933a8b2562d7bd1fb595074cf99cc81fc3789f6a6c05cdabb46284a3188/cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb", size = 216402 }, - { url = "https://files.pythonhosted.org/packages/05/eb/b86f2a2645b62adcfff53b0dd97e8dfafb5c8aa864bd0d9a2c2049a0d551/cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0", size = 203217 }, - { url = "https://files.pythonhosted.org/packages/9f/e0/6cbe77a53acf5acc7c08cc186c9928864bd7c005f9efd0d126884858a5fe/cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4", size = 203079 }, - { url = "https://files.pythonhosted.org/packages/98/29/9b366e70e243eb3d14a5cb488dfd3a0b6b2f1fb001a203f653b93ccfac88/cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453", size = 216475 }, - { url = "https://files.pythonhosted.org/packages/21/7a/13b24e70d2f90a322f2900c5d8e1f14fa7e2a6b3332b7309ba7b2ba51a5a/cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495", size = 218829 }, - { url = "https://files.pythonhosted.org/packages/60/99/c9dc110974c59cc981b1f5b66e1d8af8af764e00f0293266824d9c4254bc/cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5", size = 211211 }, - { url = "https://files.pythonhosted.org/packages/49/72/ff2d12dbf21aca1b32a40ed792ee6b40f6dc3a9cf1644bd7ef6e95e0ac5e/cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb", size = 218036 }, - { url = "https://files.pythonhosted.org/packages/e2/cc/027d7fb82e58c48ea717149b03bcadcbdc293553edb283af792bd4bcbb3f/cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a", size = 172184 }, - { url = "https://files.pythonhosted.org/packages/33/fa/072dd15ae27fbb4e06b437eb6e944e75b068deb09e2a2826039e49ee2045/cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739", size = 182790 }, - { url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344 }, - { url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560 }, - { url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613 }, - { url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476 }, - { url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374 }, - { url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597 }, - { url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574 }, - { url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971 }, - { url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972 }, - { url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078 }, - { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076 }, - { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820 }, - { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635 }, - { url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271 }, - { url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932 }, - { url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557 }, - { url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762 }, - { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230 }, - { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043 }, - { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446 }, - { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101 }, - { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948 }, - { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422 }, - { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499 }, - { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928 }, - { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302 }, - { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909 }, - { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402 }, - { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780 }, - { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320 }, - { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487 }, - { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049 }, - { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793 }, - { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300 }, - { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244 }, - { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828 }, - { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926 }, - { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328 }, - { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650 }, - { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687 }, - { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773 }, - { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013 }, - { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593 }, - { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354 }, - { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480 }, - { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584 }, - { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443 }, - { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437 }, - { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487 }, - { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726 }, - { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195 }, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5", size = 144271 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/26/08/0f303cb0b529e456bb116f2d50565a482694fbb94340bf56d44677e7ed03/charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d", size = 315182 }, - { url = "https://files.pythonhosted.org/packages/24/47/b192933e94b546f1b1fe4df9cc1f84fcdbf2359f8d1081d46dd029b50207/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8", size = 209329 }, - { url = "https://files.pythonhosted.org/packages/c2/b4/01fa81c5ca6141024d89a8fc15968002b71da7f825dd14113207113fabbd/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790", size = 231230 }, - { url = "https://files.pythonhosted.org/packages/20/f7/7b991776844dfa058017e600e6e55ff01984a063290ca5622c0b63162f68/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc", size = 225890 }, - { url = "https://files.pythonhosted.org/packages/20/e7/bed0024a0f4ab0c8a9c64d4445f39b30c99bd1acd228291959e3de664247/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393", size = 216930 }, - { url = "https://files.pythonhosted.org/packages/e2/ab/b18f0ab31cdd7b3ddb8bb76c4a414aeb8160c9810fdf1bc62f269a539d87/charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153", size = 202109 }, - { url = "https://files.pythonhosted.org/packages/82/e5/7e9440768a06dfb3075936490cb82dbf0ee20a133bf0dd8551fa096914ec/charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af", size = 214684 }, - { url = "https://files.pythonhosted.org/packages/71/94/8c61d8da9f062fdf457c80acfa25060ec22bf1d34bbeaca4350f13bcfd07/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34", size = 212785 }, - { url = "https://files.pythonhosted.org/packages/66/cd/6e9889c648e72c0ab2e5967528bb83508f354d706637bc7097190c874e13/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1", size = 203055 }, - { url = "https://files.pythonhosted.org/packages/92/2e/7a951d6a08aefb7eb8e1b54cdfb580b1365afdd9dd484dc4bee9e5d8f258/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752", size = 232502 }, - { url = "https://files.pythonhosted.org/packages/58/d5/abcf2d83bf8e0a1286df55cd0dc1d49af0da4282aa77e986df343e7de124/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53", size = 214295 }, - { url = "https://files.pythonhosted.org/packages/47/3a/7d4cd7ed54be99973a0dc176032cba5cb1f258082c31fa6df35cff46acfc/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616", size = 227145 }, - { url = "https://files.pythonhosted.org/packages/1d/98/3a45bf8247889cf28262ebd3d0872edff11565b2a1e3064ccb132db3fbb0/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a", size = 218884 }, - { url = "https://files.pythonhosted.org/packages/ad/80/2e8b7f8915ed5c9ef13aa828d82738e33888c485b65ebf744d615040c7ea/charset_normalizer-3.4.7-cp310-cp310-win32.whl", hash = "sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374", size = 148343 }, - { url = "https://files.pythonhosted.org/packages/35/1b/3b8c8c77184af465ee9ad88b5aea46ea6b2e1f7b9dc9502891e37af21e30/charset_normalizer-3.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943", size = 159174 }, - { url = "https://files.pythonhosted.org/packages/be/c1/feb40dca40dbb21e0a908801782d9288c64fc8d8e562c2098e9994c8c21b/charset_normalizer-3.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008", size = 147805 }, - { url = "https://files.pythonhosted.org/packages/c2/d7/b5b7020a0565c2e9fa8c09f4b5fa6232feb326b8c20081ccded47ea368fd/charset_normalizer-3.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7", size = 309705 }, - { url = "https://files.pythonhosted.org/packages/5a/53/58c29116c340e5456724ecd2fff4196d236b98f3da97b404bc5e51ac3493/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7", size = 206419 }, - { url = "https://files.pythonhosted.org/packages/b2/02/e8146dc6591a37a00e5144c63f29fb7c97a734ea8a111190783c0e60ab63/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e", size = 227901 }, - { url = "https://files.pythonhosted.org/packages/fb/73/77486c4cd58f1267bf17db420e930c9afa1b3be3fe8c8b8ebbebc9624359/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c", size = 222742 }, - { url = "https://files.pythonhosted.org/packages/a1/fa/f74eb381a7d94ded44739e9d94de18dc5edc9c17fb8c11f0a6890696c0a9/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df", size = 214061 }, - { url = "https://files.pythonhosted.org/packages/dc/92/42bd3cefcf7687253fb86694b45f37b733c97f59af3724f356fa92b8c344/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265", size = 199239 }, - { url = "https://files.pythonhosted.org/packages/4c/3d/069e7184e2aa3b3cddc700e3dd267413dc259854adc3380421c805c6a17d/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4", size = 210173 }, - { url = "https://files.pythonhosted.org/packages/62/51/9d56feb5f2e7074c46f93e0ebdbe61f0848ee246e2f0d89f8e20b89ebb8f/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e", size = 209841 }, - { url = "https://files.pythonhosted.org/packages/d2/59/893d8f99cc4c837dda1fe2f1139079703deb9f321aabcb032355de13b6c7/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38", size = 200304 }, - { url = "https://files.pythonhosted.org/packages/7d/1d/ee6f3be3464247578d1ed5c46de545ccc3d3ff933695395c402c21fa6b77/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c", size = 229455 }, - { url = "https://files.pythonhosted.org/packages/54/bb/8fb0a946296ea96a488928bdce8ef99023998c48e4713af533e9bb98ef07/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b", size = 210036 }, - { url = "https://files.pythonhosted.org/packages/9a/bc/015b2387f913749f82afd4fcba07846d05b6d784dd16123cb66860e0237d/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c", size = 224739 }, - { url = "https://files.pythonhosted.org/packages/17/ab/63133691f56baae417493cba6b7c641571a2130eb7bceba6773367ab9ec5/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d", size = 216277 }, - { url = "https://files.pythonhosted.org/packages/06/6d/3be70e827977f20db77c12a97e6a9f973631a45b8d186c084527e53e77a4/charset_normalizer-3.4.7-cp311-cp311-win32.whl", hash = "sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad", size = 147819 }, - { url = "https://files.pythonhosted.org/packages/20/d9/5f67790f06b735d7c7637171bbfd89882ad67201891b7275e51116ed8207/charset_normalizer-3.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00", size = 159281 }, - { url = "https://files.pythonhosted.org/packages/ca/83/6413f36c5a34afead88ce6f66684d943d91f233d76dd083798f9602b75ae/charset_normalizer-3.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1", size = 147843 }, - { url = "https://files.pythonhosted.org/packages/0c/eb/4fc8d0a7110eb5fc9cc161723a34a8a6c200ce3b4fbf681bc86feee22308/charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46", size = 311328 }, - { url = "https://files.pythonhosted.org/packages/f8/e3/0fadc706008ac9d7b9b5be6dc767c05f9d3e5df51744ce4cc9605de7b9f4/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2", size = 208061 }, - { url = "https://files.pythonhosted.org/packages/42/f0/3dd1045c47f4a4604df85ec18ad093912ae1344ac706993aff91d38773a2/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b", size = 229031 }, - { url = "https://files.pythonhosted.org/packages/dc/67/675a46eb016118a2fbde5a277a5d15f4f69d5f3f5f338e5ee2f8948fcf43/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a", size = 225239 }, - { url = "https://files.pythonhosted.org/packages/4b/f8/d0118a2f5f23b02cd166fa385c60f9b0d4f9194f574e2b31cef350ad7223/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116", size = 216589 }, - { url = "https://files.pythonhosted.org/packages/b1/f1/6d2b0b261b6c4ceef0fcb0d17a01cc5bc53586c2d4796fa04b5c540bc13d/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb", size = 202733 }, - { url = "https://files.pythonhosted.org/packages/6f/c0/7b1f943f7e87cc3db9626ba17807d042c38645f0a1d4415c7a14afb5591f/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1", size = 212652 }, - { url = "https://files.pythonhosted.org/packages/38/dd/5a9ab159fe45c6e72079398f277b7d2b523e7f716acc489726115a910097/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15", size = 211229 }, - { url = "https://files.pythonhosted.org/packages/d5/ff/531a1cad5ca855d1c1a8b69cb71abfd6d85c0291580146fda7c82857caa1/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5", size = 203552 }, - { url = "https://files.pythonhosted.org/packages/c1/4c/a5fb52d528a8ca41f7598cb619409ece30a169fbdf9cdce592e53b46c3a6/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d", size = 230806 }, - { url = "https://files.pythonhosted.org/packages/59/7a/071feed8124111a32b316b33ae4de83d36923039ef8cf48120266844285b/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7", size = 212316 }, - { url = "https://files.pythonhosted.org/packages/fd/35/f7dba3994312d7ba508e041eaac39a36b120f32d4c8662b8814dab876431/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464", size = 227274 }, - { url = "https://files.pythonhosted.org/packages/8a/2d/a572df5c9204ab7688ec1edc895a73ebded3b023bb07364710b05dd1c9be/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49", size = 218468 }, - { url = "https://files.pythonhosted.org/packages/86/eb/890922a8b03a568ca2f336c36585a4713c55d4d67bf0f0c78924be6315ca/charset_normalizer-3.4.7-cp312-cp312-win32.whl", hash = "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c", size = 148460 }, - { url = "https://files.pythonhosted.org/packages/35/d9/0e7dffa06c5ab081f75b1b786f0aefc88365825dfcd0ac544bdb7b2b6853/charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6", size = 159330 }, - { url = "https://files.pythonhosted.org/packages/9e/5d/481bcc2a7c88ea6b0878c299547843b2521ccbc40980cb406267088bc701/charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d", size = 147828 }, - { url = "https://files.pythonhosted.org/packages/c1/3b/66777e39d3ae1ddc77ee606be4ec6d8cbd4c801f65e5a1b6f2b11b8346dd/charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063", size = 309627 }, - { url = "https://files.pythonhosted.org/packages/2e/4e/b7f84e617b4854ade48a1b7915c8ccfadeba444d2a18c291f696e37f0d3b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c", size = 207008 }, - { url = "https://files.pythonhosted.org/packages/c4/bb/ec73c0257c9e11b268f018f068f5d00aa0ef8c8b09f7753ebd5f2880e248/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66", size = 228303 }, - { url = "https://files.pythonhosted.org/packages/85/fb/32d1f5033484494619f701e719429c69b766bfc4dbc61aa9e9c8c166528b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18", size = 224282 }, - { url = "https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd", size = 215595 }, - { url = "https://files.pythonhosted.org/packages/e3/7c/fc890655786e423f02556e0216d4b8c6bcb6bdfa890160dc66bf52dee468/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215", size = 201986 }, - { url = "https://files.pythonhosted.org/packages/d8/97/bfb18b3db2aed3b90cf54dc292ad79fdd5ad65c4eae454099475cbeadd0d/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859", size = 211711 }, - { url = "https://files.pythonhosted.org/packages/6f/a5/a581c13798546a7fd557c82614a5c65a13df2157e9ad6373166d2a3e645d/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8", size = 210036 }, - { url = "https://files.pythonhosted.org/packages/8c/bf/b3ab5bcb478e4193d517644b0fb2bf5497fbceeaa7a1bc0f4d5b50953861/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5", size = 202998 }, - { url = "https://files.pythonhosted.org/packages/e7/4e/23efd79b65d314fa320ec6017b4b5834d5c12a58ba4610aa353af2e2f577/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832", size = 230056 }, - { url = "https://files.pythonhosted.org/packages/b9/9f/1e1941bc3f0e01df116e68dc37a55c4d249df5e6fa77f008841aef68264f/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6", size = 211537 }, - { url = "https://files.pythonhosted.org/packages/80/0f/088cbb3020d44428964a6c97fe1edfb1b9550396bf6d278330281e8b709c/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48", size = 226176 }, - { url = "https://files.pythonhosted.org/packages/6a/9f/130394f9bbe06f4f63e22641d32fc9b202b7e251c9aef4db044324dac493/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a", size = 217723 }, - { url = "https://files.pythonhosted.org/packages/73/55/c469897448a06e49f8fa03f6caae97074fde823f432a98f979cc42b90e69/charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e", size = 148085 }, - { url = "https://files.pythonhosted.org/packages/5d/78/1b74c5bbb3f99b77a1715c91b3e0b5bdb6fe302d95ace4f5b1bec37b0167/charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110", size = 158819 }, - { url = "https://files.pythonhosted.org/packages/68/86/46bd42279d323deb8687c4a5a811fd548cb7d1de10cf6535d099877a9a9f/charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b", size = 147915 }, - { url = "https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0", size = 309234 }, - { url = "https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a", size = 208042 }, - { url = "https://files.pythonhosted.org/packages/87/1c/ab2ce611b984d2fd5d86a5a8a19c1ae26acac6bad967da4967562c75114d/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b", size = 228706 }, - { url = "https://files.pythonhosted.org/packages/a8/29/2b1d2cb00bf085f59d29eb773ce58ec2d325430f8c216804a0a5cd83cbca/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41", size = 224727 }, - { url = "https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e", size = 215882 }, - { url = "https://files.pythonhosted.org/packages/2c/c2/356065d5a8b78ed04499cae5f339f091946a6a74f91e03476c33f0ab7100/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae", size = 200860 }, - { url = "https://files.pythonhosted.org/packages/0c/cd/a32a84217ced5039f53b29f460962abb2d4420def55afabe45b1c3c7483d/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18", size = 211564 }, - { url = "https://files.pythonhosted.org/packages/44/86/58e6f13ce26cc3b8f4a36b94a0f22ae2f00a72534520f4ae6857c4b81f89/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b", size = 211276 }, - { url = "https://files.pythonhosted.org/packages/8f/fe/d17c32dc72e17e155e06883efa84514ca375f8a528ba2546bee73fc4df81/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356", size = 201238 }, - { url = "https://files.pythonhosted.org/packages/6a/29/f33daa50b06525a237451cdb6c69da366c381a3dadcd833fa5676bc468b3/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab", size = 230189 }, - { url = "https://files.pythonhosted.org/packages/b6/6e/52c84015394a6a0bdcd435210a7e944c5f94ea1055f5cc5d56c5fe368e7b/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46", size = 211352 }, - { url = "https://files.pythonhosted.org/packages/8c/d7/4353be581b373033fb9198bf1da3cf8f09c1082561e8e922aa7b39bf9fe8/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44", size = 227024 }, - { url = "https://files.pythonhosted.org/packages/30/45/99d18aa925bd1740098ccd3060e238e21115fffbfdcb8f3ece837d0ace6c/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72", size = 217869 }, - { url = "https://files.pythonhosted.org/packages/5c/05/5ee478aa53f4bb7996482153d4bfe1b89e0f087f0ab6b294fcf92d595873/charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10", size = 148541 }, - { url = "https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f", size = 159634 }, - { url = "https://files.pythonhosted.org/packages/c6/a3/c2369911cd72f02386e4e340770f6e158c7980267da16af8f668217abaa0/charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246", size = 148384 }, - { url = "https://files.pythonhosted.org/packages/94/09/7e8a7f73d24dba1f0035fbbf014d2c36828fc1bf9c88f84093e57d315935/charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24", size = 330133 }, - { url = "https://files.pythonhosted.org/packages/8d/da/96975ddb11f8e977f706f45cddd8540fd8242f71ecdb5d18a80723dcf62c/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79", size = 216257 }, - { url = "https://files.pythonhosted.org/packages/e5/e8/1d63bf8ef2d388e95c64b2098f45f84758f6d102a087552da1485912637b/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960", size = 234851 }, - { url = "https://files.pythonhosted.org/packages/9b/40/e5ff04233e70da2681fa43969ad6f66ca5611d7e669be0246c4c7aaf6dc8/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4", size = 233393 }, - { url = "https://files.pythonhosted.org/packages/be/c1/06c6c49d5a5450f76899992f1ee40b41d076aee9279b49cf9974d2f313d5/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e", size = 223251 }, - { url = "https://files.pythonhosted.org/packages/2b/9f/f2ff16fb050946169e3e1f82134d107e5d4ae72647ec8a1b1446c148480f/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1", size = 206609 }, - { url = "https://files.pythonhosted.org/packages/69/d5/a527c0cd8d64d2eab7459784fb4169a0ac76e5a6fc5237337982fd61347e/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44", size = 220014 }, - { url = "https://files.pythonhosted.org/packages/7e/80/8a7b8104a3e203074dc9aa2c613d4b726c0e136bad1cc734594b02867972/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e", size = 218979 }, - { url = "https://files.pythonhosted.org/packages/02/9a/b759b503d507f375b2b5c153e4d2ee0a75aa215b7f2489cf314f4541f2c0/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3", size = 209238 }, - { url = "https://files.pythonhosted.org/packages/c2/4e/0f3f5d47b86bdb79256e7290b26ac847a2832d9a4033f7eb2cd4bcf4bb5b/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0", size = 236110 }, - { url = "https://files.pythonhosted.org/packages/96/23/bce28734eb3ed2c91dcf93abeb8a5cf393a7b2749725030bb630e554fdd8/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e", size = 219824 }, - { url = "https://files.pythonhosted.org/packages/2c/6f/6e897c6984cc4d41af319b077f2f600fc8214eb2fe2d6bcb79141b882400/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb", size = 233103 }, - { url = "https://files.pythonhosted.org/packages/76/22/ef7bd0fe480a0ae9b656189ec00744b60933f68b4f42a7bb06589f6f576a/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe", size = 225194 }, - { url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", size = 159827 }, - { url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", size = 174168 }, - { url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", size = 153018 }, - { url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958 }, -] - -[[package]] -name = "click" -version = "8.3.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/57/75/31212c6bf2503fdf920d87fee5d7a86a2e3bcf444984126f13d8e4016804/click-8.3.2.tar.gz", hash = "sha256:14162b8b3b3550a7d479eafa77dfd3c38d9dc8951f6f69c78913a8f9a7540fd5", size = 302856 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/20/71885d8b97d4f3dde17b1fdb92dbd4908b00541c5a3379787137285f602e/click-8.3.2-py3-none-any.whl", hash = "sha256:1924d2c27c5653561cd2cae4548d1406039cb79b858b747cfea24924bbc1616d", size = 108379 }, -] - -[[package]] -name = "colorama" -version = "0.4.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, -] - -[[package]] -name = "cryptography" -version = "46.0.6" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a4/ba/04b1bd4218cbc58dc90ce967106d51582371b898690f3ae0402876cc4f34/cryptography-46.0.6.tar.gz", hash = "sha256:27550628a518c5c6c903d84f637fbecf287f6cb9ced3804838a1295dc1fd0759", size = 750542 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/47/23/9285e15e3bc57325b0a72e592921983a701efc1ee8f91c06c5f0235d86d9/cryptography-46.0.6-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:64235194bad039a10bb6d2d930ab3323baaec67e2ce36215fd0952fad0930ca8", size = 7176401 }, - { url = "https://files.pythonhosted.org/packages/60/f8/e61f8f13950ab6195b31913b42d39f0f9afc7d93f76710f299b5ec286ae6/cryptography-46.0.6-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:26031f1e5ca62fcb9d1fcb34b2b60b390d1aacaa15dc8b895a9ed00968b97b30", size = 4275275 }, - { url = "https://files.pythonhosted.org/packages/19/69/732a736d12c2631e140be2348b4ad3d226302df63ef64d30dfdb8db7ad1c/cryptography-46.0.6-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9a693028b9cbe51b5a1136232ee8f2bc242e4e19d456ded3fa7c86e43c713b4a", size = 4425320 }, - { url = "https://files.pythonhosted.org/packages/d4/12/123be7292674abf76b21ac1fc0e1af50661f0e5b8f0ec8285faac18eb99e/cryptography-46.0.6-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:67177e8a9f421aa2d3a170c3e56eca4e0128883cf52a071a7cbf53297f18b175", size = 4278082 }, - { url = "https://files.pythonhosted.org/packages/5b/ba/d5e27f8d68c24951b0a484924a84c7cdaed7502bac9f18601cd357f8b1d2/cryptography-46.0.6-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:d9528b535a6c4f8ff37847144b8986a9a143585f0540fbcb1a98115b543aa463", size = 4926514 }, - { url = "https://files.pythonhosted.org/packages/34/71/1ea5a7352ae516d5512d17babe7e1b87d9db5150b21f794b1377eac1edc0/cryptography-46.0.6-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:22259338084d6ae497a19bae5d4c66b7ca1387d3264d1c2c0e72d9e9b6a77b97", size = 4457766 }, - { url = "https://files.pythonhosted.org/packages/01/59/562be1e653accee4fdad92c7a2e88fced26b3fdfce144047519bbebc299e/cryptography-46.0.6-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:760997a4b950ff00d418398ad73fbc91aa2894b5c1db7ccb45b4f68b42a63b3c", size = 3986535 }, - { url = "https://files.pythonhosted.org/packages/d6/8b/b1ebfeb788bf4624d36e45ed2662b8bd43a05ff62157093c1539c1288a18/cryptography-46.0.6-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:3dfa6567f2e9e4c5dceb8ccb5a708158a2a871052fa75c8b78cb0977063f1507", size = 4277618 }, - { url = "https://files.pythonhosted.org/packages/dd/52/a005f8eabdb28df57c20f84c44d397a755782d6ff6d455f05baa2785bd91/cryptography-46.0.6-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:cdcd3edcbc5d55757e5f5f3d330dd00007ae463a7e7aa5bf132d1f22a4b62b19", size = 4890802 }, - { url = "https://files.pythonhosted.org/packages/ec/4d/8e7d7245c79c617d08724e2efa397737715ca0ec830ecb3c91e547302555/cryptography-46.0.6-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:d4e4aadb7fc1f88687f47ca20bb7227981b03afaae69287029da08096853b738", size = 4457425 }, - { url = "https://files.pythonhosted.org/packages/1d/5c/f6c3596a1430cec6f949085f0e1a970638d76f81c3ea56d93d564d04c340/cryptography-46.0.6-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2b417edbe8877cda9022dde3a008e2deb50be9c407eef034aeeb3a8b11d9db3c", size = 4405530 }, - { url = "https://files.pythonhosted.org/packages/7e/c9/9f9cea13ee2dbde070424e0c4f621c091a91ffcc504ffea5e74f0e1daeff/cryptography-46.0.6-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:380343e0653b1c9d7e1f55b52aaa2dbb2fdf2730088d48c43ca1c7c0abb7cc2f", size = 4667896 }, - { url = "https://files.pythonhosted.org/packages/ad/b5/1895bc0821226f129bc74d00eccfc6a5969e2028f8617c09790bf89c185e/cryptography-46.0.6-cp311-abi3-win32.whl", hash = "sha256:bcb87663e1f7b075e48c3be3ecb5f0b46c8fc50b50a97cf264e7f60242dca3f2", size = 3026348 }, - { url = "https://files.pythonhosted.org/packages/c3/f8/c9bcbf0d3e6ad288b9d9aa0b1dee04b063d19e8c4f871855a03ab3a297ab/cryptography-46.0.6-cp311-abi3-win_amd64.whl", hash = "sha256:6739d56300662c468fddb0e5e291f9b4d084bead381667b9e654c7dd81705124", size = 3483896 }, - { url = "https://files.pythonhosted.org/packages/01/41/3a578f7fd5c70611c0aacba52cd13cb364a5dee895a5c1d467208a9380b0/cryptography-46.0.6-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:2ef9e69886cbb137c2aef9772c2e7138dc581fad4fcbcf13cc181eb5a3ab6275", size = 7117147 }, - { url = "https://files.pythonhosted.org/packages/fa/87/887f35a6fca9dde90cad08e0de0c89263a8e59b2d2ff904fd9fcd8025b6f/cryptography-46.0.6-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7f417f034f91dcec1cb6c5c35b07cdbb2ef262557f701b4ecd803ee8cefed4f4", size = 4266221 }, - { url = "https://files.pythonhosted.org/packages/aa/a8/0a90c4f0b0871e0e3d1ed126aed101328a8a57fd9fd17f00fb67e82a51ca/cryptography-46.0.6-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d24c13369e856b94892a89ddf70b332e0b70ad4a5c43cf3e9cb71d6d7ffa1f7b", size = 4408952 }, - { url = "https://files.pythonhosted.org/packages/16/0b/b239701eb946523e4e9f329336e4ff32b1247e109cbab32d1a7b61da8ed7/cryptography-46.0.6-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:aad75154a7ac9039936d50cf431719a2f8d4ed3d3c277ac03f3339ded1a5e707", size = 4270141 }, - { url = "https://files.pythonhosted.org/packages/0f/a8/976acdd4f0f30df7b25605f4b9d3d89295351665c2091d18224f7ad5cdbf/cryptography-46.0.6-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:3c21d92ed15e9cfc6eb64c1f5a0326db22ca9c2566ca46d845119b45b4400361", size = 4904178 }, - { url = "https://files.pythonhosted.org/packages/b1/1b/bf0e01a88efd0e59679b69f42d4afd5bced8700bb5e80617b2d63a3741af/cryptography-46.0.6-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:4668298aef7cddeaf5c6ecc244c2302a2b8e40f384255505c22875eebb47888b", size = 4441812 }, - { url = "https://files.pythonhosted.org/packages/bb/8b/11df86de2ea389c65aa1806f331cae145f2ed18011f30234cc10ca253de8/cryptography-46.0.6-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:8ce35b77aaf02f3b59c90b2c8a05c73bac12cea5b4e8f3fbece1f5fddea5f0ca", size = 3963923 }, - { url = "https://files.pythonhosted.org/packages/91/e0/207fb177c3a9ef6a8108f234208c3e9e76a6aa8cf20d51932916bd43bda0/cryptography-46.0.6-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:c89eb37fae9216985d8734c1afd172ba4927f5a05cfd9bf0e4863c6d5465b013", size = 4269695 }, - { url = "https://files.pythonhosted.org/packages/21/5e/19f3260ed1e95bced52ace7501fabcd266df67077eeb382b79c81729d2d3/cryptography-46.0.6-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:ed418c37d095aeddf5336898a132fba01091f0ac5844e3e8018506f014b6d2c4", size = 4869785 }, - { url = "https://files.pythonhosted.org/packages/10/38/cd7864d79aa1d92ef6f1a584281433419b955ad5a5ba8d1eb6c872165bcb/cryptography-46.0.6-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:69cf0056d6947edc6e6760e5f17afe4bea06b56a9ac8a06de9d2bd6b532d4f3a", size = 4441404 }, - { url = "https://files.pythonhosted.org/packages/09/0a/4fe7a8d25fed74419f91835cf5829ade6408fd1963c9eae9c4bce390ecbb/cryptography-46.0.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e7304c4f4e9490e11efe56af6713983460ee0780f16c63f219984dab3af9d2d", size = 4397549 }, - { url = "https://files.pythonhosted.org/packages/5f/a0/7d738944eac6513cd60a8da98b65951f4a3b279b93479a7e8926d9cd730b/cryptography-46.0.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b928a3ca837c77a10e81a814a693f2295200adb3352395fad024559b7be7a736", size = 4651874 }, - { url = "https://files.pythonhosted.org/packages/cb/f1/c2326781ca05208845efca38bf714f76939ae446cd492d7613808badedf1/cryptography-46.0.6-cp314-cp314t-win32.whl", hash = "sha256:97c8115b27e19e592a05c45d0dd89c57f81f841cc9880e353e0d3bf25b2139ed", size = 3001511 }, - { url = "https://files.pythonhosted.org/packages/c9/57/fe4a23eb549ac9d903bd4698ffda13383808ef0876cc912bcb2838799ece/cryptography-46.0.6-cp314-cp314t-win_amd64.whl", hash = "sha256:c797e2517cb7880f8297e2c0f43bb910e91381339336f75d2c1c2cbf811b70b4", size = 3471692 }, - { url = "https://files.pythonhosted.org/packages/c4/cc/f330e982852403da79008552de9906804568ae9230da8432f7496ce02b71/cryptography-46.0.6-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:12cae594e9473bca1a7aceb90536060643128bb274fcea0fc459ab90f7d1ae7a", size = 7162776 }, - { url = "https://files.pythonhosted.org/packages/49/b3/dc27efd8dcc4bff583b3f01d4a3943cd8b5821777a58b3a6a5f054d61b79/cryptography-46.0.6-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:639301950939d844a9e1c4464d7e07f902fe9a7f6b215bb0d4f28584729935d8", size = 4270529 }, - { url = "https://files.pythonhosted.org/packages/e6/05/e8d0e6eb4f0d83365b3cb0e00eb3c484f7348db0266652ccd84632a3d58d/cryptography-46.0.6-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ed3775295fb91f70b4027aeba878d79b3e55c0b3e97eaa4de71f8f23a9f2eb77", size = 4414827 }, - { url = "https://files.pythonhosted.org/packages/2f/97/daba0f5d2dc6d855e2dcb70733c812558a7977a55dd4a6722756628c44d1/cryptography-46.0.6-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:8927ccfbe967c7df312ade694f987e7e9e22b2425976ddbf28271d7e58845290", size = 4271265 }, - { url = "https://files.pythonhosted.org/packages/89/06/fe1fce39a37ac452e58d04b43b0855261dac320a2ebf8f5260dd55b201a9/cryptography-46.0.6-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:b12c6b1e1651e42ab5de8b1e00dc3b6354fdfd778e7fa60541ddacc27cd21410", size = 4916800 }, - { url = "https://files.pythonhosted.org/packages/ff/8a/b14f3101fe9c3592603339eb5d94046c3ce5f7fc76d6512a2d40efd9724e/cryptography-46.0.6-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:063b67749f338ca9c5a0b7fe438a52c25f9526b851e24e6c9310e7195aad3b4d", size = 4448771 }, - { url = "https://files.pythonhosted.org/packages/01/b3/0796998056a66d1973fd52ee89dc1bb3b6581960a91ad4ac705f182d398f/cryptography-46.0.6-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:02fad249cb0e090b574e30b276a3da6a149e04ee2f049725b1f69e7b8351ec70", size = 3978333 }, - { url = "https://files.pythonhosted.org/packages/c5/3d/db200af5a4ffd08918cd55c08399dc6c9c50b0bc72c00a3246e099d3a849/cryptography-46.0.6-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:7e6142674f2a9291463e5e150090b95a8519b2fb6e6aaec8917dd8d094ce750d", size = 4271069 }, - { url = "https://files.pythonhosted.org/packages/d7/18/61acfd5b414309d74ee838be321c636fe71815436f53c9f0334bf19064fa/cryptography-46.0.6-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:456b3215172aeefb9284550b162801d62f5f264a081049a3e94307fe20792cfa", size = 4878358 }, - { url = "https://files.pythonhosted.org/packages/8b/65/5bf43286d566f8171917cae23ac6add941654ccf085d739195a4eacf1674/cryptography-46.0.6-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:341359d6c9e68834e204ceaf25936dffeafea3829ab80e9503860dcc4f4dac58", size = 4448061 }, - { url = "https://files.pythonhosted.org/packages/e0/25/7e49c0fa7205cf3597e525d156a6bce5b5c9de1fd7e8cb01120e459f205a/cryptography-46.0.6-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9a9c42a2723999a710445bc0d974e345c32adfd8d2fac6d8a251fa829ad31cfb", size = 4399103 }, - { url = "https://files.pythonhosted.org/packages/44/46/466269e833f1c4718d6cd496ffe20c56c9c8d013486ff66b4f69c302a68d/cryptography-46.0.6-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6617f67b1606dfd9fe4dbfa354a9508d4a6d37afe30306fe6c101b7ce3274b72", size = 4659255 }, - { url = "https://files.pythonhosted.org/packages/0a/09/ddc5f630cc32287d2c953fc5d32705e63ec73e37308e5120955316f53827/cryptography-46.0.6-cp38-abi3-win32.whl", hash = "sha256:7f6690b6c55e9c5332c0b59b9c8a3fb232ebf059094c17f9019a51e9827df91c", size = 3010660 }, - { url = "https://files.pythonhosted.org/packages/1b/82/ca4893968aeb2709aacfb57a30dec6fa2ab25b10fa9f064b8882ce33f599/cryptography-46.0.6-cp38-abi3-win_amd64.whl", hash = "sha256:79e865c642cfc5c0b3eb12af83c35c5aeff4fa5c672dc28c43721c2c9fdd2f0f", size = 3471160 }, - { url = "https://files.pythonhosted.org/packages/2e/84/7ccff00ced5bac74b775ce0beb7d1be4e8637536b522b5df9b73ada42da2/cryptography-46.0.6-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:2ea0f37e9a9cf0df2952893ad145fd9627d326a59daec9b0802480fa3bcd2ead", size = 3475444 }, - { url = "https://files.pythonhosted.org/packages/bc/1f/4c926f50df7749f000f20eede0c896769509895e2648db5da0ed55db711d/cryptography-46.0.6-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a3e84d5ec9ba01f8fd03802b2147ba77f0c8f2617b2aff254cedd551844209c8", size = 4218227 }, - { url = "https://files.pythonhosted.org/packages/c6/65/707be3ffbd5f786028665c3223e86e11c4cda86023adbc56bd72b1b6bab5/cryptography-46.0.6-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:12f0fa16cc247b13c43d56d7b35287ff1569b5b1f4c5e87e92cc4fcc00cd10c0", size = 4381399 }, - { url = "https://files.pythonhosted.org/packages/f3/6d/73557ed0ef7d73d04d9aba745d2c8e95218213687ee5e76b7d236a5030fc/cryptography-46.0.6-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:50575a76e2951fe7dbd1f56d181f8c5ceeeb075e9ff88e7ad997d2f42af06e7b", size = 4217595 }, - { url = "https://files.pythonhosted.org/packages/9e/c5/e1594c4eec66a567c3ac4400008108a415808be2ce13dcb9a9045c92f1a0/cryptography-46.0.6-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:90e5f0a7b3be5f40c3a0a0eafb32c681d8d2c181fc2a1bdabe9b3f611d9f6b1a", size = 4380912 }, - { url = "https://files.pythonhosted.org/packages/1a/89/843b53614b47f97fe1abc13f9a86efa5ec9e275292c457af1d4a60dc80e0/cryptography-46.0.6-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6728c49e3b2c180ef26f8e9f0a883a2c585638db64cf265b49c9ba10652d430e", size = 3409955 }, -] - -[[package]] -name = "cyclopts" -version = "4.10.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "attrs" }, - { name = "docstring-parser" }, - { name = "rich" }, - { name = "rich-rst" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6c/c4/2ce2ca1451487dc7d59f09334c3fa1182c46cfcf0a2d5f19f9b26d53ac74/cyclopts-4.10.1.tar.gz", hash = "sha256:ad4e4bb90576412d32276b14a76f55d43353753d16217f2c3cd5bdceba7f15a0", size = 166623 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/0b/2261922126b2e50c601fe22d7ff5194e0a4d50e654836260c0665e24d862/cyclopts-4.10.1-py3-none-any.whl", hash = "sha256:35f37257139380a386d9fe4475e1e7c87ca7795765ef4f31abba579fcfcb6ecd", size = 204331 }, -] - -[[package]] -name = "distro" -version = "1.9.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277 }, -] - -[[package]] -name = "dnspython" -version = "2.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/8b/57666417c0f90f08bcafa776861060426765fdb422eb10212086fb811d26/dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f", size = 368251 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094 }, -] - -[[package]] -name = "docstring-parser" -version = "0.17.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/9d/c3b43da9515bd270df0f80548d9944e389870713cc1fe2b8fb35fe2bcefd/docstring_parser-0.17.0.tar.gz", hash = "sha256:583de4a309722b3315439bb31d64ba3eebada841f2e2cee23b99df001434c912", size = 27442 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/55/e2/2537ebcff11c1ee1ff17d8d0b6f4db75873e3b0fb32c2d4a2ee31ecb310a/docstring_parser-0.17.0-py3-none-any.whl", hash = "sha256:cf2569abd23dce8099b300f9b4fa8191e9582dda731fd533daf54c4551658708", size = 36896 }, -] - -[[package]] -name = "docutils" -version = "0.22.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ae/b6/03bb70946330e88ffec97aefd3ea75ba575cb2e762061e0e62a213befee8/docutils-0.22.4.tar.gz", hash = "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968", size = 2291750 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl", hash = "sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de", size = 633196 }, -] - -[[package]] -name = "email-validator" -version = "2.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "dnspython" }, - { name = "idna" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f5/22/900cb125c76b7aaa450ce02fd727f452243f2e91a61af068b40adba60ea9/email_validator-2.3.0.tar.gz", hash = "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426", size = 51238 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", size = 35604 }, -] - -[[package]] -name = "exceptiongroup" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740 }, -] - -[[package]] -name = "fastapi" -version = "0.135.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "annotated-doc" }, - { name = "pydantic" }, - { name = "starlette" }, - { name = "typing-extensions" }, - { name = "typing-inspection" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f7/e6/7adb4c5fa231e82c35b8f5741a9f2d055f520c29af5546fd70d3e8e1cd2e/fastapi-0.135.3.tar.gz", hash = "sha256:bd6d7caf1a2bdd8d676843cdcd2287729572a1ef524fc4d65c17ae002a1be654", size = 396524 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/84/a4/5caa2de7f917a04ada20018eccf60d6cc6145b0199d55ca3711b0fc08312/fastapi-0.135.3-py3-none-any.whl", hash = "sha256:9b0f590c813acd13d0ab43dd8494138eb58e484bfac405db1f3187cfc5810d98", size = 117734 }, -] - -[[package]] -name = "fastmcp" -version = "3.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "authlib" }, - { name = "cyclopts" }, - { name = "exceptiongroup" }, - { name = "httpx" }, - { name = "jsonref" }, - { name = "jsonschema-path" }, - { name = "mcp" }, - { name = "openapi-pydantic" }, - { name = "opentelemetry-api" }, - { name = "packaging" }, - { name = "platformdirs" }, - { name = "py-key-value-aio", extra = ["filetree", "keyring", "memory"] }, - { name = "pydantic", extra = ["email"] }, - { name = "pyperclip" }, - { name = "python-dotenv" }, - { name = "pyyaml" }, - { name = "rich" }, - { name = "uncalled-for" }, - { name = "uvicorn" }, - { name = "watchfiles" }, - { name = "websockets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d0/32/4f1b2cfd7b50db89114949f90158b1dcc2c92a1917b9f57c0ff24e47a2f4/fastmcp-3.2.0.tar.gz", hash = "sha256:d4830b8ffc3592d3d9c76dc0f398904cf41f04910e41a0de38cc1004e0903bef", size = 26318581 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4f/67/684fa2d2de1e7504549d4ca457b4f854ccec3cd3be03bd86b33b599fbf58/fastmcp-3.2.0-py3-none-any.whl", hash = "sha256:e71aba3df16f86f546a4a9e513261d3233bcc92bef0dfa647bac3fa33623f681", size = 705550 }, -] - -[[package]] -name = "ffmpy" -version = "1.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7d/d2/1c4c582d71bcc65c76fa69fab85de6257d50fdf6fd4a2317c53917e9a581/ffmpy-1.0.0.tar.gz", hash = "sha256:b12932e95435c8820f1cd041024402765f821971e4bae753b327fc02a6e12f8b", size = 5101 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/55/56/dd3669eccebb6d8ac81e624542ebd53fe6f08e1b8f2f8d50aeb7e3b83f99/ffmpy-1.0.0-py3-none-any.whl", hash = "sha256:5640e5f0fd03fb6236d0e119b16ccf6522db1c826fdf35dcb87087b60fd7504f", size = 5614 }, -] - -[[package]] -name = "filelock" -version = "3.25.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/b8/00651a0f559862f3bb7d6f7477b192afe3f583cc5e26403b44e59a55ab34/filelock-3.25.2.tar.gz", hash = "sha256:b64ece2b38f4ca29dd3e810287aa8c48182bbecd1ae6e9ae126c9b35f1382694", size = 40480 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/a5/842ae8f0c08b61d6484b52f99a03510a3a72d23141942d216ebe81fefbce/filelock-3.25.2-py3-none-any.whl", hash = "sha256:ca8afb0da15f229774c9ad1b455ed96e85a81373065fb10446672f64444ddf70", size = 26759 }, -] - -[[package]] -name = "fsspec" -version = "2026.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e1/cf/b50ddf667c15276a9ab15a70ef5f257564de271957933ffea49d2cdbcdfb/fsspec-2026.3.0.tar.gz", hash = "sha256:1ee6a0e28677557f8c2f994e3eea77db6392b4de9cd1f5d7a9e87a0ae9d01b41", size = 313547 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/1f/5f4a3cd9e4440e9d9bc78ad0a91a1c8d46b4d429d5239ebe6793c9fe5c41/fsspec-2026.3.0-py3-none-any.whl", hash = "sha256:d2ceafaad1b3457968ed14efa28798162f1638dbb5d2a6868a2db002a5ee39a4", size = 202595 }, -] - -[[package]] -name = "gradio" -version = "6.11.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiofiles" }, - { name = "anyio" }, - { name = "audioop-lts", marker = "python_full_version >= '3.13'" }, - { name = "brotli" }, - { name = "fastapi" }, - { name = "ffmpy" }, - { name = "gradio-client" }, - { name = "groovy" }, - { name = "hf-gradio" }, - { name = "httpx" }, - { name = "huggingface-hub" }, - { name = "jinja2" }, - { name = "markupsafe" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "orjson" }, - { name = "packaging" }, - { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "pandas", version = "3.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "pillow" }, - { name = "pydantic" }, - { name = "pydub" }, - { name = "python-multipart" }, - { name = "pytz" }, - { name = "pyyaml" }, - { name = "safehttpx" }, - { name = "semantic-version" }, - { name = "starlette" }, - { name = "tomlkit" }, - { name = "typer" }, - { name = "typing-extensions" }, - { name = "uvicorn" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/89/a9/95923f9107f706040cab06a5fbc292ba0ceef573f46d449ef260f4f70503/gradio-6.11.0.tar.gz", hash = "sha256:da706246fae711007e752ae85acdb0300d68e60eb4bcea29d43371d28432b787", size = 52028942 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/5b/c816b9dd76a2e5e502aa25833c43cc00574c2579c0db84e79e93c5d13c4c/gradio-6.11.0-py3-none-any.whl", hash = "sha256:9b72461cf55c9b1bee8818c9a7ceeac78af1dedb5e8c4d3d48b5a0c6c66db7b8", size = 36791822 }, -] - -[[package]] -name = "gradio-client" -version = "2.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "fsspec" }, - { name = "httpx" }, - { name = "huggingface-hub" }, - { name = "packaging" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/4e/4a/ddfaa8b3fef0238768a42301a3361981af1afd90f92c27adfe6cd031eca7/gradio_client-2.4.0.tar.gz", hash = "sha256:781885374f86759b8db5195e13e716c301d14e48e0442aef63362f1eeea4cce2", size = 58203 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f0/b3/10cb03cf684aab2bec97cb0b9bbba4f93e7a20c6e0f3b4100c235a55ad93/gradio_client-2.4.0-py3-none-any.whl", hash = "sha256:7c170807b924ed6056b2a1fa9d659d349dd20567c00ee0b4dc249dc1e2def620", size = 59156 }, -] - -[[package]] -name = "groovy" -version = "0.1.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/52/36/bbdede67400277bef33d3ec0e6a31750da972c469f75966b4930c753218f/groovy-0.1.2.tar.gz", hash = "sha256:25c1dc09b3f9d7e292458aa762c6beb96ea037071bf5e917fc81fb78d2231083", size = 17325 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/28/27/3d6dcadc8a3214d8522c1e7f6a19554e33659be44546d44a2f7572ac7d2a/groovy-0.1.2-py3-none-any.whl", hash = "sha256:7f7975bab18c729a257a8b1ae9dcd70b7cafb1720481beae47719af57c35fa64", size = 14090 }, -] - -[[package]] -name = "h11" -version = "0.16.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515 }, -] - -[[package]] -name = "hf-gradio" -version = "0.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "gradio-client" }, - { name = "typer" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/48/d8/1771d6f1591099ecd10776782d08c6f87e7c2501f9e9e6ffb7c2ecc07d0c/hf_gradio-0.3.0.tar.gz", hash = "sha256:e74a0f9eab14a1d6f54c523c2192aa5283ca51f01605f661b2542387da5b9fc0", size = 6235 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4c/52/04816d2a15691a63cec3187e3e592c4493448eb4834492eadd532972b035/hf_gradio-0.3.0-py3-none-any.whl", hash = "sha256:159d33d1f0affae8164d29c0c51a63dfcc0bbc90803b07c6f139137206a796ae", size = 4154 }, -] - -[[package]] -name = "hf-xet" -version = "1.4.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/53/92/ec9ad04d0b5728dca387a45af7bc98fbb0d73b2118759f5f6038b61a57e8/hf_xet-1.4.3.tar.gz", hash = "sha256:8ddedb73c8c08928c793df2f3401ec26f95be7f7e516a7bee2fbb546f6676113", size = 670477 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/72/43/724d307b34e353da0abd476e02f72f735cdd2bc86082dee1b32ea0bfee1d/hf_xet-1.4.3-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:7551659ba4f1e1074e9623996f28c3873682530aee0a846b7f2f066239228144", size = 3800935 }, - { url = "https://files.pythonhosted.org/packages/2b/d2/8bee5996b699262edb87dbb54118d287c0e1b2fc78af7cdc41857ba5e3c4/hf_xet-1.4.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:bee693ada985e7045997f05f081d0e12c4c08bd7626dc397f8a7c487e6c04f7f", size = 3558942 }, - { url = "https://files.pythonhosted.org/packages/c3/a1/e993d09cbe251196fb60812b09a58901c468127b7259d2bf0f68bf6088eb/hf_xet-1.4.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:21644b404bb0100fe3857892f752c4d09642586fd988e61501c95bbf44b393a3", size = 4207657 }, - { url = "https://files.pythonhosted.org/packages/64/44/9eb6d21e5c34c63e5e399803a6932fa983cabdf47c0ecbcfe7ea97684b8c/hf_xet-1.4.3-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:987f09cfe418237812896a6736b81b1af02a3a6dcb4b4944425c4c4fca7a7cf8", size = 3986765 }, - { url = "https://files.pythonhosted.org/packages/ea/7b/8ad6f16fdb82f5f7284a34b5ec48645bd575bdcd2f6f0d1644775909c486/hf_xet-1.4.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:60cf7fc43a99da0a853345cf86d23738c03983ee5249613a6305d3e57a5dca74", size = 4188162 }, - { url = "https://files.pythonhosted.org/packages/1b/c4/39d6e136cbeea9ca5a23aad4b33024319222adbdc059ebcda5fc7d9d5ff4/hf_xet-1.4.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2815a49a7a59f3e2edf0cf113ae88e8cb2ca2a221bf353fb60c609584f4884d4", size = 4424525 }, - { url = "https://files.pythonhosted.org/packages/46/f2/adc32dae6bdbc367853118b9878139ac869419a4ae7ba07185dc31251b76/hf_xet-1.4.3-cp313-cp313t-win_amd64.whl", hash = "sha256:42ee323265f1e6a81b0e11094564fb7f7e0ec75b5105ffd91ae63f403a11931b", size = 3671610 }, - { url = "https://files.pythonhosted.org/packages/e2/19/25d897dcc3f81953e0c2cde9ec186c7a0fee413eb0c9a7a9130d87d94d3a/hf_xet-1.4.3-cp313-cp313t-win_arm64.whl", hash = "sha256:27c976ba60079fb8217f485b9c5c7fcd21c90b0367753805f87cb9f3cdc4418a", size = 3528529 }, - { url = "https://files.pythonhosted.org/packages/ec/36/3e8f85ca9fe09b8de2b2e10c63b3b3353d7dda88a0b3d426dffbe7b8313b/hf_xet-1.4.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:5251d5ece3a81815bae9abab41cf7ddb7bcb8f56411bce0827f4a3071c92fdc6", size = 3801019 }, - { url = "https://files.pythonhosted.org/packages/b5/9c/defb6cb1de28bccb7bd8d95f6e60f72a3d3fa4cb3d0329c26fb9a488bfe7/hf_xet-1.4.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1feb0f3abeacee143367c326a128a2e2b60868ec12a36c225afb1d6c5a05e6d2", size = 3558746 }, - { url = "https://files.pythonhosted.org/packages/c1/bd/8d001191893178ff8e826e46ad5299446e62b93cd164e17b0ffea08832ec/hf_xet-1.4.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8b301fc150290ca90b4fccd079829b84bb4786747584ae08b94b4577d82fb791", size = 4207692 }, - { url = "https://files.pythonhosted.org/packages/ce/48/6790b402803250e9936435613d3a78b9aaeee7973439f0918848dde58309/hf_xet-1.4.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:d972fbe95ddc0d3c0fc49b31a8a69f47db35c1e3699bf316421705741aab6653", size = 3986281 }, - { url = "https://files.pythonhosted.org/packages/51/56/ea62552fe53db652a9099eda600b032d75554d0e86c12a73824bfedef88b/hf_xet-1.4.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c5b48db1ee344a805a1b9bd2cda9b6b65fe77ed3787bd6e87ad5521141d317cd", size = 4187414 }, - { url = "https://files.pythonhosted.org/packages/7d/f5/bc1456d4638061bea997e6d2db60a1a613d7b200e0755965ec312dc1ef79/hf_xet-1.4.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:22bdc1f5fb8b15bf2831440b91d1c9bbceeb7e10c81a12e8d75889996a5c9da8", size = 4424368 }, - { url = "https://files.pythonhosted.org/packages/e4/76/ab597bae87e1f06d18d3ecb8ed7f0d3c9a37037fc32ce76233d369273c64/hf_xet-1.4.3-cp314-cp314t-win_amd64.whl", hash = "sha256:0392c79b7cf48418cd61478c1a925246cf10639f4cd9d94368d8ca1e8df9ea07", size = 3672280 }, - { url = "https://files.pythonhosted.org/packages/62/05/2e462d34e23a09a74d73785dbed71cc5dbad82a72eee2ad60a72a554155d/hf_xet-1.4.3-cp314-cp314t-win_arm64.whl", hash = "sha256:681c92a07796325778a79d76c67011764ecc9042a8c3579332b61b63ae512075", size = 3528945 }, - { url = "https://files.pythonhosted.org/packages/ac/9f/9c23e4a447b8f83120798f9279d0297a4d1360bdbf59ef49ebec78fe2545/hf_xet-1.4.3-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:d0da85329eaf196e03e90b84c2d0aca53bd4573d097a75f99609e80775f98025", size = 3805048 }, - { url = "https://files.pythonhosted.org/packages/0b/f8/7aacb8e5f4a7899d39c787b5984e912e6c18b11be136ef13947d7a66d265/hf_xet-1.4.3-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:e23717ce4186b265f69afa66e6f0069fe7efbf331546f5c313d00e123dc84583", size = 3562178 }, - { url = "https://files.pythonhosted.org/packages/df/9a/a24b26dc8a65f0ecc0fe5be981a19e61e7ca963b85e062c083f3a9100529/hf_xet-1.4.3-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc360b70c815bf340ed56c7b8c63aacf11762a4b099b2fe2c9bd6d6068668c08", size = 4212320 }, - { url = "https://files.pythonhosted.org/packages/53/60/46d493db155d2ee2801b71fb1b0fd67696359047fdd8caee2c914cc50c79/hf_xet-1.4.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:39f2d2e9654cd9b4319885733993807aab6de9dfbd34c42f0b78338d6617421f", size = 3991546 }, - { url = "https://files.pythonhosted.org/packages/bc/f5/067363e1c96c6b17256910830d1b54099d06287e10f4ec6ec4e7e08371fc/hf_xet-1.4.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:49ad8a8cead2b56051aa84d7fce3e1335efe68df3cf6c058f22a65513885baac", size = 4193200 }, - { url = "https://files.pythonhosted.org/packages/42/4b/53951592882d9c23080c7644542fda34a3813104e9e11fa1a7d82d419cb8/hf_xet-1.4.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7716d62015477a70ea272d2d68cd7cad140f61c52ee452e133e139abfe2c17ba", size = 4429392 }, - { url = "https://files.pythonhosted.org/packages/8a/21/75a6c175b4e79662ad8e62f46a40ce341d8d6b206b06b4320d07d55b188c/hf_xet-1.4.3-cp37-abi3-win_amd64.whl", hash = "sha256:6b591fcad34e272a5b02607485e4f2a1334aebf1bc6d16ce8eb1eb8978ac2021", size = 3677359 }, - { url = "https://files.pythonhosted.org/packages/8a/7c/44314ecd0e89f8b2b51c9d9e5e7a60a9c1c82024ac471d415860557d3cd8/hf_xet-1.4.3-cp37-abi3-win_arm64.whl", hash = "sha256:7c2c7e20bcfcc946dc67187c203463f5e932e395845d098cc2a93f5b67ca0b47", size = 3533664 }, -] - -[[package]] -name = "httpcore" -version = "1.0.9" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "h11" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784 }, -] - -[[package]] -name = "httpx" -version = "0.28.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "certifi" }, - { name = "httpcore" }, - { name = "idna" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, -] - -[[package]] -name = "httpx-sse" -version = "0.4.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0f/4c/751061ffa58615a32c31b2d82e8482be8dd4a89154f003147acee90f2be9/httpx_sse-0.4.3.tar.gz", hash = "sha256:9b1ed0127459a66014aec3c56bebd93da3c1bc8bb6618c8082039a44889a755d", size = 15943 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/fd/6668e5aec43ab844de6fc74927e155a3b37bf40d7c3790e49fc0406b6578/httpx_sse-0.4.3-py3-none-any.whl", hash = "sha256:0ac1c9fe3c0afad2e0ebb25a934a59f4c7823b60792691f779fad2c5568830fc", size = 8960 }, -] - -[[package]] -name = "huggingface-hub" -version = "1.9.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "filelock" }, - { name = "fsspec" }, - { name = "hf-xet", marker = "platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, - { name = "httpx" }, - { name = "packaging" }, - { name = "pyyaml" }, - { name = "tqdm" }, - { name = "typer" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/88/bb/62c7aa86f63a05e2f9b96642fdef9b94526a23979820b09f5455deff4983/huggingface_hub-1.9.0.tar.gz", hash = "sha256:0ea5be7a56135c91797cae6ad726e38eaeb6eb4b77cefff5c9d38ba0ecf874f7", size = 750326 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/73/37/0d15d16150e1829f3e90962c99f28257f6de9e526a680b4c6f5acdb54fd2/huggingface_hub-1.9.0-py3-none-any.whl", hash = "sha256:2999328c058d39fd19ab748dd09bd4da2fbaa4f4c1ddea823eab103051e14a1f", size = 637355 }, -] - -[[package]] -name = "idna" -version = "3.11" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008 }, -] - -[[package]] -name = "importlib-metadata" -version = "8.7.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "zipp" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f3/49/3b30cad09e7771a4982d9975a8cbf64f00d4a1ececb53297f1d9a7be1b10/importlib_metadata-8.7.1.tar.gz", hash = "sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb", size = 57107 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl", hash = "sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151", size = 27865 }, -] - -[[package]] -name = "jaraco-classes" -version = "3.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "more-itertools" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/06/c0/ed4a27bc5571b99e3cff68f8a9fa5b56ff7df1c2251cc715a652ddd26402/jaraco.classes-3.4.0.tar.gz", hash = "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd", size = 11780 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl", hash = "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790", size = 6777 }, -] - -[[package]] -name = "jaraco-context" -version = "6.1.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "backports-tarfile", marker = "python_full_version < '3.12'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/af/50/4763cd07e722bb6285316d390a164bc7e479db9d90daa769f22578f698b4/jaraco_context-6.1.2.tar.gz", hash = "sha256:f1a6c9d391e661cc5b8d39861ff077a7dc24dc23833ccee564b234b81c82dfe3", size = 16801 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/58/bc8954bda5fcda97bd7c19be11b85f91973d67a706ed4a3aec33e7de22db/jaraco_context-6.1.2-py3-none-any.whl", hash = "sha256:bf8150b79a2d5d91ae48629d8b427a8f7ba0e1097dd6202a9059f29a36379535", size = 7871 }, -] - -[[package]] -name = "jaraco-functools" -version = "4.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "more-itertools" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/0f/27/056e0638a86749374d6f57d0b0db39f29509cce9313cf91bdc0ac4d91084/jaraco_functools-4.4.0.tar.gz", hash = "sha256:da21933b0417b89515562656547a77b4931f98176eb173644c0d35032a33d6bb", size = 19943 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/c4/813bb09f0985cb21e959f21f2464169eca882656849adf727ac7bb7e1767/jaraco_functools-4.4.0-py3-none-any.whl", hash = "sha256:9eec1e36f45c818d9bf307c8948eb03b2b56cd44087b3cdc989abca1f20b9176", size = 10481 }, -] - -[[package]] -name = "jeepney" -version = "0.9.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7b/6f/357efd7602486741aa73ffc0617fb310a29b588ed0fd69c2399acbb85b0c/jeepney-0.9.0.tar.gz", hash = "sha256:cf0e9e845622b81e4a28df94c40345400256ec608d0e55bb8a3feaa9163f5732", size = 106758 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b2/a3/e137168c9c44d18eff0376253da9f1e9234d0239e0ee230d2fee6cea8e55/jeepney-0.9.0-py3-none-any.whl", hash = "sha256:97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683", size = 49010 }, -] - -[[package]] -name = "jinja2" -version = "3.1.6" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markupsafe" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 }, -] - -[[package]] -name = "jiter" -version = "0.13.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0d/5e/4ec91646aee381d01cdb9974e30882c9cd3b8c5d1079d6b5ff4af522439a/jiter-0.13.0.tar.gz", hash = "sha256:f2839f9c2c7e2dffc1bc5929a510e14ce0a946be9365fd1219e7ef342dae14f4", size = 164847 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/5a/41da76c5ea07bec1b0472b6b2fdb1b651074d504b19374d7e130e0cdfb25/jiter-0.13.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2ffc63785fd6c7977defe49b9824ae6ce2b2e2b77ce539bdaf006c26da06342e", size = 311164 }, - { url = "https://files.pythonhosted.org/packages/40/cb/4a1bf994a3e869f0d39d10e11efb471b76d0ad70ecbfb591427a46c880c2/jiter-0.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4a638816427006c1e3f0013eb66d391d7a3acda99a7b0cf091eff4497ccea33a", size = 320296 }, - { url = "https://files.pythonhosted.org/packages/09/82/acd71ca9b50ecebadc3979c541cd717cce2fe2bc86236f4fa597565d8f1a/jiter-0.13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19928b5d1ce0ff8c1ee1b9bdef3b5bfc19e8304f1b904e436caf30bc15dc6cf5", size = 352742 }, - { url = "https://files.pythonhosted.org/packages/71/03/d1fc996f3aecfd42eb70922edecfb6dd26421c874503e241153ad41df94f/jiter-0.13.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:309549b778b949d731a2f0e1594a3f805716be704a73bf3ad9a807eed5eb5721", size = 363145 }, - { url = "https://files.pythonhosted.org/packages/f1/61/a30492366378cc7a93088858f8991acd7d959759fe6138c12a4644e58e81/jiter-0.13.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcdabaea26cb04e25df3103ce47f97466627999260290349a88c8136ecae0060", size = 487683 }, - { url = "https://files.pythonhosted.org/packages/20/4e/4223cffa9dbbbc96ed821c5aeb6bca510848c72c02086d1ed3f1da3d58a7/jiter-0.13.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a3a377af27b236abbf665a69b2bdd680e3b5a0bd2af825cd3b81245279a7606c", size = 373579 }, - { url = "https://files.pythonhosted.org/packages/fe/c9/b0489a01329ab07a83812d9ebcffe7820a38163c6d9e7da644f926ff877c/jiter-0.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe49d3ff6db74321f144dff9addd4a5874d3105ac5ba7c5b77fac099cfae31ae", size = 362904 }, - { url = "https://files.pythonhosted.org/packages/05/af/53e561352a44afcba9a9bc67ee1d320b05a370aed8df54eafe714c4e454d/jiter-0.13.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2113c17c9a67071b0f820733c0893ed1d467b5fcf4414068169e5c2cabddb1e2", size = 392380 }, - { url = "https://files.pythonhosted.org/packages/76/2a/dd805c3afb8ed5b326c5ae49e725d1b1255b9754b1b77dbecdc621b20773/jiter-0.13.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ab1185ca5c8b9491b55ebf6c1e8866b8f68258612899693e24a92c5fdb9455d5", size = 517939 }, - { url = "https://files.pythonhosted.org/packages/20/2a/7b67d76f55b8fe14c937e7640389612f05f9a4145fc28ae128aaa5e62257/jiter-0.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9621ca242547edc16400981ca3231e0c91c0c4c1ab8573a596cd9bb3575d5c2b", size = 551696 }, - { url = "https://files.pythonhosted.org/packages/85/9c/57cdd64dac8f4c6ab8f994fe0eb04dc9fd1db102856a4458fcf8a99dfa62/jiter-0.13.0-cp310-cp310-win32.whl", hash = "sha256:a7637d92b1c9d7a771e8c56f445c7f84396d48f2e756e5978840ecba2fac0894", size = 204592 }, - { url = "https://files.pythonhosted.org/packages/a7/38/f4f3ea5788b8a5bae7510a678cdc747eda0c45ffe534f9878ff37e7cf3b3/jiter-0.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c1b609e5cbd2f52bb74fb721515745b407df26d7b800458bd97cb3b972c29e7d", size = 206016 }, - { url = "https://files.pythonhosted.org/packages/71/29/499f8c9eaa8a16751b1c0e45e6f5f1761d180da873d417996cc7bddc8eef/jiter-0.13.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ea026e70a9a28ebbdddcbcf0f1323128a8db66898a06eaad3a4e62d2f554d096", size = 311157 }, - { url = "https://files.pythonhosted.org/packages/50/f6/566364c777d2ab450b92100bea11333c64c38d32caf8dc378b48e5b20c46/jiter-0.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:66aa3e663840152d18cc8ff1e4faad3dd181373491b9cfdc6004b92198d67911", size = 319729 }, - { url = "https://files.pythonhosted.org/packages/73/dd/560f13ec5e4f116d8ad2658781646cca91b617ae3b8758d4a5076b278f70/jiter-0.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3524798e70655ff19aec58c7d05adb1f074fecff62da857ea9be2b908b6d701", size = 354766 }, - { url = "https://files.pythonhosted.org/packages/7c/0d/061faffcfe94608cbc28a0d42a77a74222bdf5055ccdbe5fd2292b94f510/jiter-0.13.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ec7e287d7fbd02cb6e22f9a00dd9c9cd504c40a61f2c61e7e1f9690a82726b4c", size = 362587 }, - { url = "https://files.pythonhosted.org/packages/92/c9/c66a7864982fd38a9773ec6e932e0398d1262677b8c60faecd02ffb67bf3/jiter-0.13.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:47455245307e4debf2ce6c6e65a717550a0244231240dcf3b8f7d64e4c2f22f4", size = 487537 }, - { url = "https://files.pythonhosted.org/packages/6c/86/84eb4352cd3668f16d1a88929b5888a3fe0418ea8c1dfc2ad4e7bf6e069a/jiter-0.13.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ee9da221dca6e0429c2704c1b3655fe7b025204a71d4d9b73390c759d776d165", size = 373717 }, - { url = "https://files.pythonhosted.org/packages/6e/09/9fe4c159358176f82d4390407a03f506a8659ed13ca3ac93a843402acecf/jiter-0.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24ab43126d5e05f3d53a36a8e11eb2f23304c6c1117844aaaf9a0aa5e40b5018", size = 362683 }, - { url = "https://files.pythonhosted.org/packages/c9/5e/85f3ab9caca0c1d0897937d378b4a515cae9e119730563572361ea0c48ae/jiter-0.13.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9da38b4fedde4fb528c740c2564628fbab737166a0e73d6d46cb4bb5463ff411", size = 392345 }, - { url = "https://files.pythonhosted.org/packages/12/4c/05b8629ad546191939e6f0c2f17e29f542a398f4a52fb987bc70b6d1eb8b/jiter-0.13.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0b34c519e17658ed88d5047999a93547f8889f3c1824120c26ad6be5f27b6cf5", size = 517775 }, - { url = "https://files.pythonhosted.org/packages/4d/88/367ea2eb6bc582c7052e4baf5ddf57ebe5ab924a88e0e09830dfb585c02d/jiter-0.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d2a6394e6af690d462310a86b53c47ad75ac8c21dc79f120714ea449979cb1d3", size = 551325 }, - { url = "https://files.pythonhosted.org/packages/f3/12/fa377ffb94a2f28c41afaed093e0d70cfe512035d5ecb0cad0ae4792d35e/jiter-0.13.0-cp311-cp311-win32.whl", hash = "sha256:0f0c065695f616a27c920a56ad0d4fc46415ef8b806bf8fc1cacf25002bd24e1", size = 204709 }, - { url = "https://files.pythonhosted.org/packages/cb/16/8e8203ce92f844dfcd3d9d6a5a7322c77077248dbb12da52d23193a839cd/jiter-0.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:0733312953b909688ae3c2d58d043aa040f9f1a6a75693defed7bc2cc4bf2654", size = 204560 }, - { url = "https://files.pythonhosted.org/packages/44/26/97cc40663deb17b9e13c3a5cf29251788c271b18ee4d262c8f94798b8336/jiter-0.13.0-cp311-cp311-win_arm64.whl", hash = "sha256:5d9b34ad56761b3bf0fbe8f7e55468704107608512350962d3317ffd7a4382d5", size = 189608 }, - { url = "https://files.pythonhosted.org/packages/2e/30/7687e4f87086829955013ca12a9233523349767f69653ebc27036313def9/jiter-0.13.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:0a2bd69fc1d902e89925fc34d1da51b2128019423d7b339a45d9e99c894e0663", size = 307958 }, - { url = "https://files.pythonhosted.org/packages/c3/27/e57f9a783246ed95481e6749cc5002a8a767a73177a83c63ea71f0528b90/jiter-0.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f917a04240ef31898182f76a332f508f2cc4b57d2b4d7ad2dbfebbfe167eb505", size = 318597 }, - { url = "https://files.pythonhosted.org/packages/cf/52/e5719a60ac5d4d7c5995461a94ad5ef962a37c8bf5b088390e6fad59b2ff/jiter-0.13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1e2b199f446d3e82246b4fd9236d7cb502dc2222b18698ba0d986d2fecc6152", size = 348821 }, - { url = "https://files.pythonhosted.org/packages/61/db/c1efc32b8ba4c740ab3fc2d037d8753f67685f475e26b9d6536a4322bcdd/jiter-0.13.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04670992b576fa65bd056dbac0c39fe8bd67681c380cb2b48efa885711d9d726", size = 364163 }, - { url = "https://files.pythonhosted.org/packages/55/8a/fb75556236047c8806995671a18e4a0ad646ed255276f51a20f32dceaeec/jiter-0.13.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a1aff1fbdb803a376d4d22a8f63f8e7ccbce0b4890c26cc7af9e501ab339ef0", size = 483709 }, - { url = "https://files.pythonhosted.org/packages/7e/16/43512e6ee863875693a8e6f6d532e19d650779d6ba9a81593ae40a9088ff/jiter-0.13.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b3fb8c2053acaef8580809ac1d1f7481a0a0bdc012fd7f5d8b18fb696a5a089", size = 370480 }, - { url = "https://files.pythonhosted.org/packages/f8/4c/09b93e30e984a187bc8aaa3510e1ec8dcbdcd71ca05d2f56aac0492453aa/jiter-0.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdaba7d87e66f26a2c45d8cbadcbfc4bf7884182317907baf39cfe9775bb4d93", size = 360735 }, - { url = "https://files.pythonhosted.org/packages/1a/1b/46c5e349019874ec5dfa508c14c37e29864ea108d376ae26d90bee238cd7/jiter-0.13.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7b88d649135aca526da172e48083da915ec086b54e8e73a425ba50999468cc08", size = 391814 }, - { url = "https://files.pythonhosted.org/packages/15/9e/26184760e85baee7162ad37b7912797d2077718476bf91517641c92b3639/jiter-0.13.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e404ea551d35438013c64b4f357b0474c7abf9f781c06d44fcaf7a14c69ff9e2", size = 513990 }, - { url = "https://files.pythonhosted.org/packages/e9/34/2c9355247d6debad57a0a15e76ab1566ab799388042743656e566b3b7de1/jiter-0.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1f4748aad1b4a93c8bdd70f604d0f748cdc0e8744c5547798acfa52f10e79228", size = 548021 }, - { url = "https://files.pythonhosted.org/packages/ac/4a/9f2c23255d04a834398b9c2e0e665382116911dc4d06b795710503cdad25/jiter-0.13.0-cp312-cp312-win32.whl", hash = "sha256:0bf670e3b1445fc4d31612199f1744f67f889ee1bbae703c4b54dc097e5dd394", size = 203024 }, - { url = "https://files.pythonhosted.org/packages/09/ee/f0ae675a957ae5a8f160be3e87acea6b11dc7b89f6b7ab057e77b2d2b13a/jiter-0.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:15db60e121e11fe186c0b15236bd5d18381b9ddacdcf4e659feb96fc6c969c92", size = 205424 }, - { url = "https://files.pythonhosted.org/packages/1b/02/ae611edf913d3cbf02c97cdb90374af2082c48d7190d74c1111dde08bcdd/jiter-0.13.0-cp312-cp312-win_arm64.whl", hash = "sha256:41f92313d17989102f3cb5dd533a02787cdb99454d494344b0361355da52fcb9", size = 186818 }, - { url = "https://files.pythonhosted.org/packages/91/9c/7ee5a6ff4b9991e1a45263bfc46731634c4a2bde27dfda6c8251df2d958c/jiter-0.13.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1f8a55b848cbabf97d861495cd65f1e5c590246fabca8b48e1747c4dfc8f85bf", size = 306897 }, - { url = "https://files.pythonhosted.org/packages/7c/02/be5b870d1d2be5dd6a91bdfb90f248fbb7dcbd21338f092c6b89817c3dbf/jiter-0.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f556aa591c00f2c45eb1b89f68f52441a016034d18b65da60e2d2875bbbf344a", size = 317507 }, - { url = "https://files.pythonhosted.org/packages/da/92/b25d2ec333615f5f284f3a4024f7ce68cfa0604c322c6808b2344c7f5d2b/jiter-0.13.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7e1d61da332ec412350463891923f960c3073cf1aae93b538f0bb4c8cd46efb", size = 350560 }, - { url = "https://files.pythonhosted.org/packages/be/ec/74dcb99fef0aca9fbe56b303bf79f6bd839010cb18ad41000bf6cc71eec0/jiter-0.13.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3097d665a27bc96fd9bbf7f86178037db139f319f785e4757ce7ccbf390db6c2", size = 363232 }, - { url = "https://files.pythonhosted.org/packages/1b/37/f17375e0bb2f6a812d4dd92d7616e41917f740f3e71343627da9db2824ce/jiter-0.13.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d01ecc3a8cbdb6f25a37bd500510550b64ddf9f7d64a107d92f3ccb25035d0f", size = 483727 }, - { url = "https://files.pythonhosted.org/packages/77/d2/a71160a5ae1a1e66c1395b37ef77da67513b0adba73b993a27fbe47eb048/jiter-0.13.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ed9bbc30f5d60a3bdf63ae76beb3f9db280d7f195dfcfa61af792d6ce912d159", size = 370799 }, - { url = "https://files.pythonhosted.org/packages/01/99/ed5e478ff0eb4e8aa5fd998f9d69603c9fd3f32de3bd16c2b1194f68361c/jiter-0.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98fbafb6e88256f4454de33c1f40203d09fc33ed19162a68b3b257b29ca7f663", size = 359120 }, - { url = "https://files.pythonhosted.org/packages/16/be/7ffd08203277a813f732ba897352797fa9493faf8dc7995b31f3d9cb9488/jiter-0.13.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5467696f6b827f1116556cb0db620440380434591e93ecee7fd14d1a491b6daa", size = 390664 }, - { url = "https://files.pythonhosted.org/packages/d1/84/e0787856196d6d346264d6dcccb01f741e5f0bd014c1d9a2ebe149caf4f3/jiter-0.13.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:2d08c9475d48b92892583df9da592a0e2ac49bcd41fae1fec4f39ba6cf107820", size = 513543 }, - { url = "https://files.pythonhosted.org/packages/65/50/ecbd258181c4313cf79bca6c88fb63207d04d5bf5e4f65174114d072aa55/jiter-0.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:aed40e099404721d7fcaf5b89bd3b4568a4666358bcac7b6b15c09fb6252ab68", size = 547262 }, - { url = "https://files.pythonhosted.org/packages/27/da/68f38d12e7111d2016cd198161b36e1f042bd115c169255bcb7ec823a3bf/jiter-0.13.0-cp313-cp313-win32.whl", hash = "sha256:36ebfbcffafb146d0e6ffb3e74d51e03d9c35ce7c625c8066cdbfc7b953bdc72", size = 200630 }, - { url = "https://files.pythonhosted.org/packages/25/65/3bd1a972c9a08ecd22eb3b08a95d1941ebe6938aea620c246cf426ae09c2/jiter-0.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:8d76029f077379374cf0dbc78dbe45b38dec4a2eb78b08b5194ce836b2517afc", size = 202602 }, - { url = "https://files.pythonhosted.org/packages/15/fe/13bd3678a311aa67686bb303654792c48206a112068f8b0b21426eb6851e/jiter-0.13.0-cp313-cp313-win_arm64.whl", hash = "sha256:bb7613e1a427cfcb6ea4544f9ac566b93d5bf67e0d48c787eca673ff9c9dff2b", size = 185939 }, - { url = "https://files.pythonhosted.org/packages/49/19/a929ec002ad3228bc97ca01dbb14f7632fffdc84a95ec92ceaf4145688ae/jiter-0.13.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fa476ab5dd49f3bf3a168e05f89358c75a17608dbabb080ef65f96b27c19ab10", size = 316616 }, - { url = "https://files.pythonhosted.org/packages/52/56/d19a9a194afa37c1728831e5fb81b7722c3de18a3109e8f282bfc23e587a/jiter-0.13.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ade8cb6ff5632a62b7dbd4757d8c5573f7a2e9ae285d6b5b841707d8363205ef", size = 346850 }, - { url = "https://files.pythonhosted.org/packages/36/4a/94e831c6bf287754a8a019cb966ed39ff8be6ab78cadecf08df3bb02d505/jiter-0.13.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9950290340acc1adaded363edd94baebcee7dabdfa8bee4790794cd5cfad2af6", size = 358551 }, - { url = "https://files.pythonhosted.org/packages/a2/ec/a4c72c822695fa80e55d2b4142b73f0012035d9fcf90eccc56bc060db37c/jiter-0.13.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2b4972c6df33731aac0742b64fd0d18e0a69bc7d6e03108ce7d40c85fd9e3e6d", size = 201950 }, - { url = "https://files.pythonhosted.org/packages/b6/00/393553ec27b824fbc29047e9c7cd4a3951d7fbe4a76743f17e44034fa4e4/jiter-0.13.0-cp313-cp313t-win_arm64.whl", hash = "sha256:701a1e77d1e593c1b435315ff625fd071f0998c5f02792038a5ca98899261b7d", size = 185852 }, - { url = "https://files.pythonhosted.org/packages/6e/f5/f1997e987211f6f9bd71b8083047b316208b4aca0b529bb5f8c96c89ef3e/jiter-0.13.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:cc5223ab19fe25e2f0bf2643204ad7318896fe3729bf12fde41b77bfc4fafff0", size = 308804 }, - { url = "https://files.pythonhosted.org/packages/cd/8f/5482a7677731fd44881f0204981ce2d7175db271f82cba2085dd2212e095/jiter-0.13.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9776ebe51713acf438fd9b4405fcd86893ae5d03487546dae7f34993217f8a91", size = 318787 }, - { url = "https://files.pythonhosted.org/packages/f3/b9/7257ac59778f1cd025b26a23c5520a36a424f7f1b068f2442a5b499b7464/jiter-0.13.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:879e768938e7b49b5e90b7e3fecc0dbec01b8cb89595861fb39a8967c5220d09", size = 353880 }, - { url = "https://files.pythonhosted.org/packages/c3/87/719eec4a3f0841dad99e3d3604ee4cba36af4419a76f3cb0b8e2e691ad67/jiter-0.13.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:682161a67adea11e3aae9038c06c8b4a9a71023228767477d683f69903ebc607", size = 366702 }, - { url = "https://files.pythonhosted.org/packages/d2/65/415f0a75cf6921e43365a1bc227c565cb949caca8b7532776e430cbaa530/jiter-0.13.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a13b68cd1cd8cc9de8f244ebae18ccb3e4067ad205220ef324c39181e23bbf66", size = 486319 }, - { url = "https://files.pythonhosted.org/packages/54/a2/9e12b48e82c6bbc6081fd81abf915e1443add1b13d8fc586e1d90bb02bb8/jiter-0.13.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87ce0f14c6c08892b610686ae8be350bf368467b6acd5085a5b65441e2bf36d2", size = 372289 }, - { url = "https://files.pythonhosted.org/packages/4e/c1/e4693f107a1789a239c759a432e9afc592366f04e901470c2af89cfd28e1/jiter-0.13.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c365005b05505a90d1c47856420980d0237adf82f70c4aff7aebd3c1cc143ad", size = 360165 }, - { url = "https://files.pythonhosted.org/packages/17/08/91b9ea976c1c758240614bd88442681a87672eebc3d9a6dde476874e706b/jiter-0.13.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1317fdffd16f5873e46ce27d0e0f7f4f90f0cdf1d86bf6abeaea9f63ca2c401d", size = 389634 }, - { url = "https://files.pythonhosted.org/packages/18/23/58325ef99390d6d40427ed6005bf1ad54f2577866594bcf13ce55675f87d/jiter-0.13.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:c05b450d37ba0c9e21c77fef1f205f56bcee2330bddca68d344baebfc55ae0df", size = 514933 }, - { url = "https://files.pythonhosted.org/packages/5b/25/69f1120c7c395fd276c3996bb8adefa9c6b84c12bb7111e5c6ccdcd8526d/jiter-0.13.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:775e10de3849d0631a97c603f996f518159272db00fdda0a780f81752255ee9d", size = 548842 }, - { url = "https://files.pythonhosted.org/packages/18/05/981c9669d86850c5fbb0d9e62bba144787f9fba84546ba43d624ee27ef29/jiter-0.13.0-cp314-cp314-win32.whl", hash = "sha256:632bf7c1d28421c00dd8bbb8a3bac5663e1f57d5cd5ed962bce3c73bf62608e6", size = 202108 }, - { url = "https://files.pythonhosted.org/packages/8d/96/cdcf54dd0b0341db7d25413229888a346c7130bd20820530905fdb65727b/jiter-0.13.0-cp314-cp314-win_amd64.whl", hash = "sha256:f22ef501c3f87ede88f23f9b11e608581c14f04db59b6a801f354397ae13739f", size = 204027 }, - { url = "https://files.pythonhosted.org/packages/fb/f9/724bcaaab7a3cd727031fe4f6995cb86c4bd344909177c186699c8dec51a/jiter-0.13.0-cp314-cp314-win_arm64.whl", hash = "sha256:07b75fe09a4ee8e0c606200622e571e44943f47254f95e2436c8bdcaceb36d7d", size = 187199 }, - { url = "https://files.pythonhosted.org/packages/62/92/1661d8b9fd6a3d7a2d89831db26fe3c1509a287d83ad7838831c7b7a5c7e/jiter-0.13.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:964538479359059a35fb400e769295d4b315ae61e4105396d355a12f7fef09f0", size = 318423 }, - { url = "https://files.pythonhosted.org/packages/4f/3b/f77d342a54d4ebcd128e520fc58ec2f5b30a423b0fd26acdfc0c6fef8e26/jiter-0.13.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e104da1db1c0991b3eaed391ccd650ae8d947eab1480c733e5a3fb28d4313e40", size = 351438 }, - { url = "https://files.pythonhosted.org/packages/76/b3/ba9a69f0e4209bd3331470c723c2f5509e6f0482e416b612431a5061ed71/jiter-0.13.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e3a5f0cde8ff433b8e88e41aa40131455420fb3649a3c7abdda6145f8cb7202", size = 364774 }, - { url = "https://files.pythonhosted.org/packages/b3/16/6cdb31fa342932602458dbb631bfbd47f601e03d2e4950740e0b2100b570/jiter-0.13.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:57aab48f40be1db920a582b30b116fe2435d184f77f0e4226f546794cedd9cf0", size = 487238 }, - { url = "https://files.pythonhosted.org/packages/ed/b1/956cc7abaca8d95c13aa8d6c9b3f3797241c246cd6e792934cc4c8b250d2/jiter-0.13.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7772115877c53f62beeb8fd853cab692dbc04374ef623b30f997959a4c0e7e95", size = 372892 }, - { url = "https://files.pythonhosted.org/packages/26/c4/97ecde8b1e74f67b8598c57c6fccf6df86ea7861ed29da84629cdbba76c4/jiter-0.13.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1211427574b17b633cfceba5040de8081e5abf114f7a7602f73d2e16f9fdaa59", size = 360309 }, - { url = "https://files.pythonhosted.org/packages/4b/d7/eabe3cf46715854ccc80be2cd78dd4c36aedeb30751dbf85a1d08c14373c/jiter-0.13.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7beae3a3d3b5212d3a55d2961db3c292e02e302feb43fce6a3f7a31b90ea6dfe", size = 389607 }, - { url = "https://files.pythonhosted.org/packages/df/2d/03963fc0804e6109b82decfb9974eb92df3797fe7222428cae12f8ccaa0c/jiter-0.13.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:e5562a0f0e90a6223b704163ea28e831bd3a9faa3512a711f031611e6b06c939", size = 514986 }, - { url = "https://files.pythonhosted.org/packages/f6/6c/8c83b45eb3eb1c1e18d841fe30b4b5bc5619d781267ca9bc03e005d8fd0a/jiter-0.13.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:6c26a424569a59140fb51160a56df13f438a2b0967365e987889186d5fc2f6f9", size = 548756 }, - { url = "https://files.pythonhosted.org/packages/47/66/eea81dfff765ed66c68fd2ed8c96245109e13c896c2a5015c7839c92367e/jiter-0.13.0-cp314-cp314t-win32.whl", hash = "sha256:24dc96eca9f84da4131cdf87a95e6ce36765c3b156fc9ae33280873b1c32d5f6", size = 201196 }, - { url = "https://files.pythonhosted.org/packages/ff/32/4ac9c7a76402f8f00d00842a7f6b83b284d0cf7c1e9d4227bc95aa6d17fa/jiter-0.13.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0a8d76c7524087272c8ae913f5d9d608bd839154b62c4322ef65723d2e5bb0b8", size = 204215 }, - { url = "https://files.pythonhosted.org/packages/f9/8e/7def204fea9f9be8b3c21a6f2dd6c020cf56c7d5ff753e0e23ed7f9ea57e/jiter-0.13.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2c26cf47e2cad140fa23b6d58d435a7c0161f5c514284802f25e87fddfe11024", size = 187152 }, -] - -[[package]] -name = "jsonref" -version = "1.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/aa/0d/c1f3277e90ccdb50d33ed5ba1ec5b3f0a242ed8c1b1a85d3afeb68464dca/jsonref-1.1.0.tar.gz", hash = "sha256:32fe8e1d85af0fdefbebce950af85590b22b60f9e95443176adbde4e1ecea552", size = 8814 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/ec/e1db9922bceb168197a558a2b8c03a7963f1afe93517ddd3cf99f202f996/jsonref-1.1.0-py3-none-any.whl", hash = "sha256:590dc7773df6c21cbf948b5dac07a72a251db28b0238ceecce0a2abfa8ec30a9", size = 9425 }, -] - -[[package]] -name = "jsonschema" -version = "4.26.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "attrs" }, - { name = "jsonschema-specifications" }, - { name = "referencing" }, - { name = "rpds-py" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630 }, -] - -[[package]] -name = "jsonschema-path" -version = "0.4.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pathable" }, - { name = "pyyaml" }, - { name = "referencing" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5b/8a/7e6102f2b8bdc6705a9eb5294f8f6f9ccd3a8420e8e8e19671d1dd773251/jsonschema_path-0.4.5.tar.gz", hash = "sha256:c6cd7d577ae290c7defd4f4029e86fdb248ca1bd41a07557795b3c95e5144918", size = 15113 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/d5/4e96c44f6c1ea3d812cf5391d81a4f5abaa540abf8d04ecd7f66e0ed11df/jsonschema_path-0.4.5-py3-none-any.whl", hash = "sha256:7d77a2c3f3ec569a40efe5c5f942c44c1af2a6f96fe0866794c9ef5b8f87fd65", size = 19368 }, -] - -[[package]] -name = "jsonschema-specifications" -version = "2025.9.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "referencing" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437 }, -] - -[[package]] -name = "keyring" -version = "25.7.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "importlib-metadata", marker = "python_full_version < '3.12'" }, - { name = "jaraco-classes" }, - { name = "jaraco-context" }, - { name = "jaraco-functools" }, - { name = "jeepney", marker = "sys_platform == 'linux'" }, - { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, - { name = "secretstorage", marker = "sys_platform == 'linux'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/43/4b/674af6ef2f97d56f0ab5153bf0bfa28ccb6c3ed4d1babf4305449668807b/keyring-25.7.0.tar.gz", hash = "sha256:fe01bd85eb3f8fb3dd0405defdeac9a5b4f6f0439edbb3149577f244a2e8245b", size = 63516 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/81/db/e655086b7f3a705df045bf0933bdd9c2f79bb3c97bfef1384598bb79a217/keyring-25.7.0-py3-none-any.whl", hash = "sha256:be4a0b195f149690c166e850609a477c532ddbfbaed96a404d4e43f8d5e2689f", size = 39160 }, -] - -[[package]] -name = "markdown-it-py" -version = "4.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mdurl" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321 }, -] - -[[package]] -name = "markupsafe" -version = "3.0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/4b/3541d44f3937ba468b75da9eebcae497dcf67adb65caa16760b0a6807ebb/markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559", size = 11631 }, - { url = "https://files.pythonhosted.org/packages/98/1b/fbd8eed11021cabd9226c37342fa6ca4e8a98d8188a8d9b66740494960e4/markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419", size = 12057 }, - { url = "https://files.pythonhosted.org/packages/40/01/e560d658dc0bb8ab762670ece35281dec7b6c1b33f5fbc09ebb57a185519/markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695", size = 22050 }, - { url = "https://files.pythonhosted.org/packages/af/cd/ce6e848bbf2c32314c9b237839119c5a564a59725b53157c856e90937b7a/markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591", size = 20681 }, - { url = "https://files.pythonhosted.org/packages/c9/2a/b5c12c809f1c3045c4d580b035a743d12fcde53cf685dbc44660826308da/markupsafe-3.0.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c", size = 20705 }, - { url = "https://files.pythonhosted.org/packages/cf/e3/9427a68c82728d0a88c50f890d0fc072a1484de2f3ac1ad0bfc1a7214fd5/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f", size = 21524 }, - { url = "https://files.pythonhosted.org/packages/bc/36/23578f29e9e582a4d0278e009b38081dbe363c5e7165113fad546918a232/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6", size = 20282 }, - { url = "https://files.pythonhosted.org/packages/56/21/dca11354e756ebd03e036bd8ad58d6d7168c80ce1fe5e75218e4945cbab7/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1", size = 20745 }, - { url = "https://files.pythonhosted.org/packages/87/99/faba9369a7ad6e4d10b6a5fbf71fa2a188fe4a593b15f0963b73859a1bbd/markupsafe-3.0.3-cp310-cp310-win32.whl", hash = "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa", size = 14571 }, - { url = "https://files.pythonhosted.org/packages/d6/25/55dc3ab959917602c96985cb1253efaa4ff42f71194bddeb61eb7278b8be/markupsafe-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8", size = 15056 }, - { url = "https://files.pythonhosted.org/packages/d0/9e/0a02226640c255d1da0b8d12e24ac2aa6734da68bff14c05dd53b94a0fc3/markupsafe-3.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1", size = 13932 }, - { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631 }, - { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058 }, - { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287 }, - { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940 }, - { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887 }, - { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692 }, - { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471 }, - { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923 }, - { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572 }, - { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077 }, - { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540 }, - { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105 }, - { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906 }, - { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622 }, - { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029 }, - { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374 }, - { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980 }, - { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990 }, - { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784 }, - { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588 }, - { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041 }, - { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543 }, - { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113 }, - { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911 }, - { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658 }, - { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066 }, - { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639 }, - { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569 }, - { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284 }, - { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801 }, - { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769 }, - { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642 }, - { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612 }, - { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200 }, - { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973 }, - { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619 }, - { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029 }, - { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408 }, - { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005 }, - { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048 }, - { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821 }, - { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606 }, - { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043 }, - { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747 }, - { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341 }, - { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073 }, - { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661 }, - { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069 }, - { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670 }, - { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598 }, - { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261 }, - { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835 }, - { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733 }, - { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672 }, - { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819 }, - { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426 }, - { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146 }, -] - -[[package]] -name = "mcp" -version = "1.27.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "httpx" }, - { name = "httpx-sse" }, - { name = "jsonschema" }, - { name = "pydantic" }, - { name = "pydantic-settings" }, - { name = "pyjwt", extra = ["crypto"] }, - { name = "python-multipart" }, - { name = "pywin32", marker = "sys_platform == 'win32'" }, - { name = "sse-starlette" }, - { name = "starlette" }, - { name = "typing-extensions" }, - { name = "typing-inspection" }, - { name = "uvicorn", marker = "sys_platform != 'emscripten'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/8b/eb/c0cfc62075dc6e1ec1c64d352ae09ac051d9334311ed226f1f425312848a/mcp-1.27.0.tar.gz", hash = "sha256:d3dc35a7eec0d458c1da4976a48f982097ddaab87e278c5511d5a4a56e852b83", size = 607509 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9c/46/f6b4ad632c67ef35209a66127e4bddc95759649dd595f71f13fba11bdf9a/mcp-1.27.0-py3-none-any.whl", hash = "sha256:5ce1fa81614958e267b21fb2aa34e0aea8e2c6ede60d52aba45fd47246b4d741", size = 215967 }, -] - -[[package]] -name = "mdurl" -version = "0.1.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, -] - -[[package]] -name = "more-itertools" -version = "11.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/24/24/e0acc4bf54cba50c1d432c70a72a3df96db4a321b2c4c68432a60759044f/more_itertools-11.0.1.tar.gz", hash = "sha256:fefaf25b7ab08f0b45fa9f1892cae93b9fc0089ef034d39213bce15f1cc9e199", size = 144739 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d8/f4/5e52c7319b8087acef603ed6e50dc325c02eaa999355414830468611f13c/more_itertools-11.0.1-py3-none-any.whl", hash = "sha256:eaf287826069452a8f61026c597eae2428b2d1ba2859083abbf240b46842ce6d", size = 72182 }, -] - -[[package]] -name = "numpy" -version = "2.2.6" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] -sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245 }, - { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048 }, - { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542 }, - { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301 }, - { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320 }, - { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050 }, - { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034 }, - { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185 }, - { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149 }, - { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620 }, - { url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963 }, - { url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743 }, - { url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616 }, - { url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579 }, - { url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005 }, - { url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570 }, - { url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866 }, - { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506 }, - { url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190 }, - { url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828 }, - { url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006 }, - { url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765 }, - { url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736 }, - { url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719 }, - { url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072 }, - { url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213 }, - { url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632 }, - { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532 }, - { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885 }, - { url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467 }, - { url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144 }, - { url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217 }, - { url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014 }, - { url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935 }, - { url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122 }, - { url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143 }, - { url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260 }, - { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225 }, - { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374 }, - { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391 }, - { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754 }, - { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476 }, - { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666 }, -] - -[[package]] -name = "numpy" -version = "2.4.4" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version >= '3.11' and python_full_version < '3.13' and sys_platform == 'win32'", - "python_full_version >= '3.11' and python_full_version < '3.13' and sys_platform == 'emscripten'", - "python_full_version >= '3.11' and python_full_version < '3.13' and sys_platform != 'emscripten' and sys_platform != 'win32'", -] -sdist = { url = "https://files.pythonhosted.org/packages/d7/9f/b8cef5bffa569759033adda9481211426f12f53299629b410340795c2514/numpy-2.4.4.tar.gz", hash = "sha256:2d390634c5182175533585cc89f3608a4682ccb173cc9bb940b2881c8d6f8fa0", size = 20731587 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/c6/4218570d8c8ecc9704b5157a3348e486e84ef4be0ed3e38218ab473c83d2/numpy-2.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f983334aea213c99992053ede6168500e5f086ce74fbc4acc3f2b00f5762e9db", size = 16976799 }, - { url = "https://files.pythonhosted.org/packages/dd/92/b4d922c4a5f5dab9ed44e6153908a5c665b71acf183a83b93b690996e39b/numpy-2.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:72944b19f2324114e9dc86a159787333b77874143efcf89a5167ef83cfee8af0", size = 14971552 }, - { url = "https://files.pythonhosted.org/packages/8a/dc/df98c095978fa6ee7b9a9387d1d58cbb3d232d0e69ad169a4ce784bde4fd/numpy-2.4.4-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:86b6f55f5a352b48d7fbfd2dbc3d5b780b2d79f4d3c121f33eb6efb22e9a2015", size = 5476566 }, - { url = "https://files.pythonhosted.org/packages/28/34/b3fdcec6e725409223dd27356bdf5a3c2cc2282e428218ecc9cb7acc9763/numpy-2.4.4-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:ba1f4fc670ed79f876f70082eff4f9583c15fb9a4b89d6188412de4d18ae2f40", size = 6806482 }, - { url = "https://files.pythonhosted.org/packages/68/62/63417c13aa35d57bee1337c67446761dc25ea6543130cf868eace6e8157b/numpy-2.4.4-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a87ec22c87be071b6bdbd27920b129b94f2fc964358ce38f3822635a3e2e03d", size = 15973376 }, - { url = "https://files.pythonhosted.org/packages/cf/c5/9fcb7e0e69cef59cf10c746b84f7d58b08bc66a6b7d459783c5a4f6101a6/numpy-2.4.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df3775294accfdd75f32c74ae39fcba920c9a378a2fc18a12b6820aa8c1fb502", size = 16925137 }, - { url = "https://files.pythonhosted.org/packages/7e/43/80020edacb3f84b9efdd1591120a4296462c23fd8db0dde1666f6ef66f13/numpy-2.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d4e437e295f18ec29bc79daf55e8a47a9113df44d66f702f02a293d93a2d6dd", size = 17329414 }, - { url = "https://files.pythonhosted.org/packages/fd/06/af0658593b18a5f73532d377188b964f239eb0894e664a6c12f484472f97/numpy-2.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6aa3236c78803afbcb255045fbef97a9e25a1f6c9888357d205ddc42f4d6eba5", size = 18658397 }, - { url = "https://files.pythonhosted.org/packages/e6/ce/13a09ed65f5d0ce5c7dd0669250374c6e379910f97af2c08c57b0608eee4/numpy-2.4.4-cp311-cp311-win32.whl", hash = "sha256:30caa73029a225b2d40d9fae193e008e24b2026b7ee1a867b7ee8d96ca1a448e", size = 6239499 }, - { url = "https://files.pythonhosted.org/packages/bd/63/05d193dbb4b5eec1eca73822d80da98b511f8328ad4ae3ca4caf0f4db91d/numpy-2.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:6bbe4eb67390b0a0265a2c25458f6b90a409d5d069f1041e6aff1e27e3d9a79e", size = 12614257 }, - { url = "https://files.pythonhosted.org/packages/87/c5/8168052f080c26fa984c413305012be54741c9d0d74abd7fbeeccae3889f/numpy-2.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:fcfe2045fd2e8f3cb0ce9d4ba6dba6333b8fa05bb8a4939c908cd43322d14c7e", size = 10486775 }, - { url = "https://files.pythonhosted.org/packages/28/05/32396bec30fb2263770ee910142f49c1476d08e8ad41abf8403806b520ce/numpy-2.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:15716cfef24d3a9762e3acdf87e27f58dc823d1348f765bbea6bef8c639bfa1b", size = 16689272 }, - { url = "https://files.pythonhosted.org/packages/c5/f3/a983d28637bfcd763a9c7aafdb6d5c0ebf3d487d1e1459ffdb57e2f01117/numpy-2.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:23cbfd4c17357c81021f21540da84ee282b9c8fba38a03b7b9d09ba6b951421e", size = 14699573 }, - { url = "https://files.pythonhosted.org/packages/9b/fd/e5ecca1e78c05106d98028114f5c00d3eddb41207686b2b7de3e477b0e22/numpy-2.4.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:8b3b60bb7cba2c8c81837661c488637eee696f59a877788a396d33150c35d842", size = 5204782 }, - { url = "https://files.pythonhosted.org/packages/de/2f/702a4594413c1a8632092beae8aba00f1d67947389369b3777aed783fdca/numpy-2.4.4-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:e4a010c27ff6f210ff4c6ef34394cd61470d01014439b192ec22552ee867f2a8", size = 6552038 }, - { url = "https://files.pythonhosted.org/packages/7f/37/eed308a8f56cba4d1fdf467a4fc67ef4ff4bf1c888f5fc980481890104b1/numpy-2.4.4-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f9e75681b59ddaa5e659898085ae0eaea229d054f2ac0c7e563a62205a700121", size = 15670666 }, - { url = "https://files.pythonhosted.org/packages/0a/0d/0e3ecece05b7a7e87ab9fb587855548da437a061326fff64a223b6dcb78a/numpy-2.4.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:81f4a14bee47aec54f883e0cad2d73986640c1590eb9bfaaba7ad17394481e6e", size = 16645480 }, - { url = "https://files.pythonhosted.org/packages/34/49/f2312c154b82a286758ee2f1743336d50651f8b5195db18cdb63675ff649/numpy-2.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:62d6b0f03b694173f9fcb1fb317f7222fd0b0b103e784c6549f5e53a27718c44", size = 17020036 }, - { url = "https://files.pythonhosted.org/packages/7b/e9/736d17bd77f1b0ec4f9901aaec129c00d59f5d84d5e79bba540ef12c2330/numpy-2.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fbc356aae7adf9e6336d336b9c8111d390a05df88f1805573ebb0807bd06fd1d", size = 18368643 }, - { url = "https://files.pythonhosted.org/packages/63/f6/d417977c5f519b17c8a5c3bc9e8304b0908b0e21136fe43bf628a1343914/numpy-2.4.4-cp312-cp312-win32.whl", hash = "sha256:0d35aea54ad1d420c812bfa0385c71cd7cc5bcf7c65fed95fc2cd02fe8c79827", size = 5961117 }, - { url = "https://files.pythonhosted.org/packages/2d/5b/e1deebf88ff431b01b7406ca3583ab2bbb90972bbe1c568732e49c844f7e/numpy-2.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:b5f0362dc928a6ecd9db58868fca5e48485205e3855957bdedea308f8672ea4a", size = 12320584 }, - { url = "https://files.pythonhosted.org/packages/58/89/e4e856ac82a68c3ed64486a544977d0e7bdd18b8da75b78a577ca31c4395/numpy-2.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:846300f379b5b12cc769334464656bc882e0735d27d9726568bc932fdc49d5ec", size = 10221450 }, - { url = "https://files.pythonhosted.org/packages/14/1d/d0a583ce4fefcc3308806a749a536c201ed6b5ad6e1322e227ee4848979d/numpy-2.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:08f2e31ed5e6f04b118e49821397f12767934cfdd12a1ce86a058f91e004ee50", size = 16684933 }, - { url = "https://files.pythonhosted.org/packages/c1/62/2b7a48fbb745d344742c0277f01286dead15f3f68e4f359fbfcf7b48f70f/numpy-2.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e823b8b6edc81e747526f70f71a9c0a07ac4e7ad13020aa736bb7c9d67196115", size = 14694532 }, - { url = "https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4a19d9dba1a76618dd86b164d608566f393f8ec6ac7c44f0cc879011c45e65af", size = 5199661 }, - { url = "https://files.pythonhosted.org/packages/cd/da/464d551604320d1491bc345efed99b4b7034143a85787aab78d5691d5a0e/numpy-2.4.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:d2a8490669bfe99a233298348acc2d824d496dee0e66e31b66a6022c2ad74a5c", size = 6547539 }, - { url = "https://files.pythonhosted.org/packages/7d/90/8d23e3b0dafd024bf31bdec225b3bb5c2dbfa6912f8a53b8659f21216cbf/numpy-2.4.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:45dbed2ab436a9e826e302fcdcbe9133f9b0006e5af7168afb8963a6520da103", size = 15668806 }, - { url = "https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83", size = 16632682 }, - { url = "https://files.pythonhosted.org/packages/34/fb/14570d65c3bde4e202a031210475ae9cde9b7686a2e7dc97ee67d2833b35/numpy-2.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:99d838547ace2c4aace6c4f76e879ddfe02bb58a80c1549928477862b7a6d6ed", size = 17019810 }, - { url = "https://files.pythonhosted.org/packages/8a/77/2ba9d87081fd41f6d640c83f26fb7351e536b7ce6dd9061b6af5904e8e46/numpy-2.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0aec54fd785890ecca25a6003fd9a5aed47ad607bbac5cd64f836ad8666f4959", size = 18357394 }, - { url = "https://files.pythonhosted.org/packages/a2/23/52666c9a41708b0853fa3b1a12c90da38c507a3074883823126d4e9d5b30/numpy-2.4.4-cp313-cp313-win32.whl", hash = "sha256:07077278157d02f65c43b1b26a3886bce886f95d20aabd11f87932750dfb14ed", size = 5959556 }, - { url = "https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:5c70f1cc1c4efbe316a572e2d8b9b9cc44e89b95f79ca3331553fbb63716e2bf", size = 12317311 }, - { url = "https://files.pythonhosted.org/packages/ba/d8/11490cddd564eb4de97b4579ef6bfe6a736cc07e94c1598590ae25415e01/numpy-2.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:ef4059d6e5152fa1a39f888e344c73fdc926e1b2dd58c771d67b0acfbf2aa67d", size = 10222060 }, - { url = "https://files.pythonhosted.org/packages/99/5d/dab4339177a905aad3e2221c915b35202f1ec30d750dd2e5e9d9a72b804b/numpy-2.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4bbc7f303d125971f60ec0aaad5e12c62d0d2c925f0ab1273debd0e4ba37aba5", size = 14822302 }, - { url = "https://files.pythonhosted.org/packages/eb/e4/0564a65e7d3d97562ed6f9b0fd0fb0a6f559ee444092f105938b50043876/numpy-2.4.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:4d6d57903571f86180eb98f8f0c839fa9ebbfb031356d87f1361be91e433f5b7", size = 5327407 }, - { url = "https://files.pythonhosted.org/packages/29/8d/35a3a6ce5ad371afa58b4700f1c820f8f279948cca32524e0a695b0ded83/numpy-2.4.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:4636de7fd195197b7535f231b5de9e4b36d2c440b6e566d2e4e4746e6af0ca93", size = 6647631 }, - { url = "https://files.pythonhosted.org/packages/f4/da/477731acbd5a58a946c736edfdabb2ac5b34c3d08d1ba1a7b437fa0884df/numpy-2.4.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ad2e2ef14e0b04e544ea2fa0a36463f847f113d314aa02e5b402fdf910ef309e", size = 15727691 }, - { url = "https://files.pythonhosted.org/packages/e6/db/338535d9b152beabeb511579598418ba0212ce77cf9718edd70262cc4370/numpy-2.4.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a285b3b96f951841799528cd1f4f01cd70e7e0204b4abebac9463eecfcf2a40", size = 16681241 }, - { url = "https://files.pythonhosted.org/packages/e2/a9/ad248e8f58beb7a0219b413c9c7d8151c5d285f7f946c3e26695bdbbe2df/numpy-2.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f8474c4241bc18b750be2abea9d7a9ec84f46ef861dbacf86a4f6e043401f79e", size = 17085767 }, - { url = "https://files.pythonhosted.org/packages/b5/1a/3b88ccd3694681356f70da841630e4725a7264d6a885c8d442a697e1146b/numpy-2.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4e874c976154687c1f71715b034739b45c7711bec81db01914770373d125e392", size = 18403169 }, - { url = "https://files.pythonhosted.org/packages/c2/c9/fcfd5d0639222c6eac7f304829b04892ef51c96a75d479214d77e3ce6e33/numpy-2.4.4-cp313-cp313t-win32.whl", hash = "sha256:9c585a1790d5436a5374bac930dad6ed244c046ed91b2b2a3634eb2971d21008", size = 6083477 }, - { url = "https://files.pythonhosted.org/packages/d5/e3/3938a61d1c538aaec8ed6fd6323f57b0c2d2d2219512434c5c878db76553/numpy-2.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:93e15038125dc1e5345d9b5b68aa7f996ec33b98118d18c6ca0d0b7d6198b7e8", size = 12457487 }, - { url = "https://files.pythonhosted.org/packages/97/6a/7e345032cc60501721ef94e0e30b60f6b0bd601f9174ebd36389a2b86d40/numpy-2.4.4-cp313-cp313t-win_arm64.whl", hash = "sha256:0dfd3f9d3adbe2920b68b5cd3d51444e13a10792ec7154cd0a2f6e74d4ab3233", size = 10292002 }, - { url = "https://files.pythonhosted.org/packages/6e/06/c54062f85f673dd5c04cbe2f14c3acb8c8b95e3384869bb8cc9bff8cb9df/numpy-2.4.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f169b9a863d34f5d11b8698ead99febeaa17a13ca044961aa8e2662a6c7766a0", size = 16684353 }, - { url = "https://files.pythonhosted.org/packages/4c/39/8a320264a84404c74cc7e79715de85d6130fa07a0898f67fb5cd5bd79908/numpy-2.4.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2483e4584a1cb3092da4470b38866634bafb223cbcd551ee047633fd2584599a", size = 14704914 }, - { url = "https://files.pythonhosted.org/packages/91/fb/287076b2614e1d1044235f50f03748f31fa287e3dbe6abeb35cdfa351eca/numpy-2.4.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:2d19e6e2095506d1736b7d80595e0f252d76b89f5e715c35e06e937679ea7d7a", size = 5210005 }, - { url = "https://files.pythonhosted.org/packages/63/eb/fcc338595309910de6ecabfcef2419a9ce24399680bfb149421fa2df1280/numpy-2.4.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:6a246d5914aa1c820c9443ddcee9c02bec3e203b0c080349533fae17727dfd1b", size = 6544974 }, - { url = "https://files.pythonhosted.org/packages/44/5d/e7e9044032a716cdfaa3fba27a8e874bf1c5f1912a1ddd4ed071bf8a14a6/numpy-2.4.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:989824e9faf85f96ec9c7761cd8d29c531ad857bfa1daa930cba85baaecf1a9a", size = 15684591 }, - { url = "https://files.pythonhosted.org/packages/98/7c/21252050676612625449b4807d6b695b9ce8a7c9e1c197ee6216c8a65c7c/numpy-2.4.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:27a8d92cd10f1382a67d7cf4db7ce18341b66438bdd9f691d7b0e48d104c2a9d", size = 16637700 }, - { url = "https://files.pythonhosted.org/packages/b1/29/56d2bbef9465db24ef25393383d761a1af4f446a1df9b8cded4fe3a5a5d7/numpy-2.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e44319a2953c738205bf3354537979eaa3998ed673395b964c1176083dd46252", size = 17035781 }, - { url = "https://files.pythonhosted.org/packages/e3/2b/a35a6d7589d21f44cea7d0a98de5ddcbb3d421b2622a5c96b1edf18707c3/numpy-2.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e892aff75639bbef0d2a2cfd55535510df26ff92f63c92cd84ef8d4ba5a5557f", size = 18362959 }, - { url = "https://files.pythonhosted.org/packages/64/c9/d52ec581f2390e0f5f85cbfd80fb83d965fc15e9f0e1aec2195faa142cde/numpy-2.4.4-cp314-cp314-win32.whl", hash = "sha256:1378871da56ca8943c2ba674530924bb8ca40cd228358a3b5f302ad60cf875fc", size = 6008768 }, - { url = "https://files.pythonhosted.org/packages/fa/22/4cc31a62a6c7b74a8730e31a4274c5dc80e005751e277a2ce38e675e4923/numpy-2.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:715d1c092715954784bc79e1174fc2a90093dc4dc84ea15eb14dad8abdcdeb74", size = 12449181 }, - { url = "https://files.pythonhosted.org/packages/70/2e/14cda6f4d8e396c612d1bf97f22958e92148801d7e4f110cabebdc0eef4b/numpy-2.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:2c194dd721e54ecad9ad387c1d35e63dce5c4450c6dc7dd5611283dda239aabb", size = 10496035 }, - { url = "https://files.pythonhosted.org/packages/b1/e8/8fed8c8d848d7ecea092dc3469643f9d10bc3a134a815a3b033da1d2039b/numpy-2.4.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2aa0613a5177c264ff5921051a5719d20095ea586ca88cc802c5c218d1c67d3e", size = 14824958 }, - { url = "https://files.pythonhosted.org/packages/05/1a/d8007a5138c179c2bf33ef44503e83d70434d2642877ee8fbb230e7c0548/numpy-2.4.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:42c16925aa5a02362f986765f9ebabf20de75cdefdca827d14315c568dcab113", size = 5330020 }, - { url = "https://files.pythonhosted.org/packages/99/64/ffb99ac6ae93faf117bcbd5c7ba48a7f45364a33e8e458545d3633615dda/numpy-2.4.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:874f200b2a981c647340f841730fc3a2b54c9d940566a3c4149099591e2c4c3d", size = 6650758 }, - { url = "https://files.pythonhosted.org/packages/6e/6e/795cc078b78a384052e73b2f6281ff7a700e9bf53bcce2ee579d4f6dd879/numpy-2.4.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9b39d38a9bd2ae1becd7eac1303d031c5c110ad31f2b319c6e7d98b135c934d", size = 15729948 }, - { url = "https://files.pythonhosted.org/packages/5f/86/2acbda8cc2af5f3d7bfc791192863b9e3e19674da7b5e533fded124d1299/numpy-2.4.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b268594bccac7d7cf5844c7732e3f20c50921d94e36d7ec9b79e9857694b1b2f", size = 16679325 }, - { url = "https://files.pythonhosted.org/packages/bc/59/cafd83018f4aa55e0ac6fa92aa066c0a1877b77a615ceff1711c260ffae8/numpy-2.4.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ac6b31e35612a26483e20750126d30d0941f949426974cace8e6b5c58a3657b0", size = 17084883 }, - { url = "https://files.pythonhosted.org/packages/f0/85/a42548db84e65ece46ab2caea3d3f78b416a47af387fcbb47ec28e660dc2/numpy-2.4.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8e3ed142f2728df44263aaf5fb1f5b0b99f4070c553a0d7f033be65338329150", size = 18403474 }, - { url = "https://files.pythonhosted.org/packages/ed/ad/483d9e262f4b831000062e5d8a45e342166ec8aaa1195264982bca267e62/numpy-2.4.4-cp314-cp314t-win32.whl", hash = "sha256:dddbbd259598d7240b18c9d87c56a9d2fb3b02fe266f49a7c101532e78c1d871", size = 6155500 }, - { url = "https://files.pythonhosted.org/packages/c7/03/2fc4e14c7bd4ff2964b74ba90ecb8552540b6315f201df70f137faa5c589/numpy-2.4.4-cp314-cp314t-win_amd64.whl", hash = "sha256:a7164afb23be6e37ad90b2f10426149fd75aee07ca55653d2aa41e66c4ef697e", size = 12637755 }, - { url = "https://files.pythonhosted.org/packages/58/78/548fb8e07b1a341746bfbecb32f2c268470f45fa028aacdbd10d9bc73aab/numpy-2.4.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ba203255017337d39f89bdd58417f03c4426f12beed0440cfd933cb15f8669c7", size = 10566643 }, - { url = "https://files.pythonhosted.org/packages/6b/33/8fae8f964a4f63ed528264ddf25d2b683d0b663e3cba26961eb838a7c1bd/numpy-2.4.4-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:58c8b5929fcb8287cbd6f0a3fae19c6e03a5c48402ae792962ac465224a629a4", size = 16854491 }, - { url = "https://files.pythonhosted.org/packages/bc/d0/1aabee441380b981cf8cdda3ae7a46aa827d1b5a8cce84d14598bc94d6d9/numpy-2.4.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:eea7ac5d2dce4189771cedb559c738a71512768210dc4e4753b107a2048b3d0e", size = 14895830 }, - { url = "https://files.pythonhosted.org/packages/a5/b8/aafb0d1065416894fccf4df6b49ef22b8db045187949545bced89c034b8e/numpy-2.4.4-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:51fc224f7ca4d92656d5a5eb315f12eb5fe2c97a66249aa7b5f562528a3be38c", size = 5400927 }, - { url = "https://files.pythonhosted.org/packages/d6/77/063baa20b08b431038c7f9ff5435540c7b7265c78cf56012a483019ca72d/numpy-2.4.4-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:28a650663f7314afc3e6ec620f44f333c386aad9f6fc472030865dc0ebb26ee3", size = 6715557 }, - { url = "https://files.pythonhosted.org/packages/c7/a8/379542d45a14f149444c5c4c4e7714707239ce9cc1de8c2803958889da14/numpy-2.4.4-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:19710a9ca9992d7174e9c52f643d4272dcd1558c5f7af7f6f8190f633bd651a7", size = 15804253 }, - { url = "https://files.pythonhosted.org/packages/a2/c8/f0a45426d6d21e7ea3310a15cf90c43a14d9232c31a837702dba437f3373/numpy-2.4.4-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9b2aec6af35c113b05695ebb5749a787acd63cafc83086a05771d1e1cd1e555f", size = 16753552 }, - { url = "https://files.pythonhosted.org/packages/04/74/f4c001f4714c3ad9ce037e18cf2b9c64871a84951eaa0baf683a9ca9301c/numpy-2.4.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f2cf083b324a467e1ab358c105f6cad5ea950f50524668a80c486ff1db24e119", size = 12509075 }, -] - -[[package]] -name = "openai" -version = "2.30.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "distro" }, - { name = "httpx" }, - { name = "jiter" }, - { name = "pydantic" }, - { name = "sniffio" }, - { name = "tqdm" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/88/15/52580c8fbc16d0675d516e8749806eda679b16de1e4434ea06fb6feaa610/openai-2.30.0.tar.gz", hash = "sha256:92f7661c990bda4b22a941806c83eabe4896c3094465030dd882a71abe80c885", size = 676084 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/9e/5bfa2270f902d5b92ab7d41ce0475b8630572e71e349b2a4996d14bdda93/openai-2.30.0-py3-none-any.whl", hash = "sha256:9a5ae616888eb2748ec5e0c5b955a51592e0b201a11f4262db920f2a78c5231d", size = 1146656 }, -] - -[[package]] -name = "openapi-pydantic" -version = "0.5.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pydantic" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/02/2e/58d83848dd1a79cb92ed8e63f6ba901ca282c5f09d04af9423ec26c56fd7/openapi_pydantic-0.5.1.tar.gz", hash = "sha256:ff6835af6bde7a459fb93eb93bb92b8749b754fc6e51b2f1590a19dc3005ee0d", size = 60892 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/12/cf/03675d8bd8ecbf4445504d8071adab19f5f993676795708e36402ab38263/openapi_pydantic-0.5.1-py3-none-any.whl", hash = "sha256:a3a09ef4586f5bd760a8df7f43028b60cafb6d9f61de2acba9574766255ab146", size = 96381 }, -] - -[[package]] -name = "openenv-core" -version = "0.2.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "fastapi" }, - { name = "fastmcp" }, - { name = "gradio" }, - { name = "httpx" }, - { name = "huggingface-hub" }, - { name = "openai" }, - { name = "pydantic" }, - { name = "pyyaml" }, - { name = "requests" }, - { name = "rich" }, - { name = "tomli" }, - { name = "tomli-w" }, - { name = "typer" }, - { name = "uvicorn" }, - { name = "websockets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/93/f3/41a5ed932a2507438c985e9d959dcaa1a6c46f293995c064348c0e52dd40/openenv_core-0.2.3.tar.gz", hash = "sha256:48aefd774474556297ce012b80f2ceb271db51253d7fd0838e6e2dcc329db0c3", size = 146944 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/22/38c339e370d198008f2c17ebdda1ae8f23bb4e1509dc7ae8eab6dc9b9cbe/openenv_core-0.2.3-py3-none-any.whl", hash = "sha256:f75a20c94452057a5f53a86e6d71a9f6a461524c3d6a865aa9344d257a92b795", size = 174557 }, -] - -[[package]] -name = "opentelemetry-api" -version = "1.40.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "importlib-metadata" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2c/1d/4049a9e8698361cc1a1aa03a6c59e4fa4c71e0c0f94a30f988a6876a2ae6/opentelemetry_api-1.40.0.tar.gz", hash = "sha256:159be641c0b04d11e9ecd576906462773eb97ae1b657730f0ecf64d32071569f", size = 70851 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5f/bf/93795954016c522008da367da292adceed71cca6ee1717e1d64c83089099/opentelemetry_api-1.40.0-py3-none-any.whl", hash = "sha256:82dd69331ae74b06f6a874704be0cfaa49a1650e1537d4a813b86ecef7d0ecf9", size = 68676 }, -] - -[[package]] -name = "orjson" -version = "3.11.8" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9d/1b/2024d06792d0779f9dbc51531b61c24f76c75b9f4ce05e6f3377a1814cea/orjson-3.11.8.tar.gz", hash = "sha256:96163d9cdc5a202703e9ad1b9ae757d5f0ca62f4fa0cc93d1f27b0e180cc404e", size = 5603832 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/90/5d81f61fe3e4270da80c71442864c091cee3003cc8984c75f413fe742a07/orjson-3.11.8-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e6693ff90018600c72fd18d3d22fa438be26076cd3c823da5f63f7bab28c11cb", size = 229663 }, - { url = "https://files.pythonhosted.org/packages/6c/ef/85e06b0eb11de6fb424120fd5788a07035bd4c5e6bb7841ae9972a0526d1/orjson-3.11.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93de06bc920854552493c81f1f729fab7213b7db4b8195355db5fda02c7d1363", size = 132321 }, - { url = "https://files.pythonhosted.org/packages/86/71/089338ee51b3132f050db0864a7df9bdd5e94c2a03820ab8a91e8f655618/orjson-3.11.8-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fe0b8c83e0f36247fc9431ce5425a5d95f9b3a689133d494831bdbd6f0bceb13", size = 130658 }, - { url = "https://files.pythonhosted.org/packages/10/0d/f39d8802345d0ad65f7fd4374b29b9b59f98656dc30f21ca5c773265b2f0/orjson-3.11.8-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:97d823831105c01f6c8029faf297633dbeb30271892bd430e9c24ceae3734744", size = 135708 }, - { url = "https://files.pythonhosted.org/packages/ff/b5/40aae576b3473511696dcffea84fde638b2b64774eb4dcb8b2c262729f8a/orjson-3.11.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c60c0423f15abb6cf78f56dff00168a1b582f7a1c23f114036e2bfc697814d5f", size = 147047 }, - { url = "https://files.pythonhosted.org/packages/7b/f0/778a84458d1fdaa634b2e572e51ce0b354232f580b2327e1f00a8d88c38c/orjson-3.11.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:01928d0476b216ad2201823b0a74000440360cef4fed1912d297b8d84718f277", size = 133072 }, - { url = "https://files.pythonhosted.org/packages/bf/d3/1bbf2fc3ffcc4b829ade554b574af68cec898c9b5ad6420a923c75a073d3/orjson-3.11.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a4a639049c44d36a6d1ae0f4a94b271605c745aee5647fa8ffaabcdc01b69a6", size = 133867 }, - { url = "https://files.pythonhosted.org/packages/08/94/6413da22edc99a69a8d0c2e83bf42973b8aa94d83ef52a6d39ac85da00bc/orjson-3.11.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3222adff1e1ff0dce93c16146b93063a7793de6c43d52309ae321234cdaf0f4d", size = 142268 }, - { url = "https://files.pythonhosted.org/packages/4a/5f/aa5dbaa6136d7ba55f5461ac2e885efc6e6349424a428927fd46d68f4396/orjson-3.11.8-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:3223665349bbfb68da234acd9846955b1a0808cbe5520ff634bf253a4407009b", size = 424008 }, - { url = "https://files.pythonhosted.org/packages/fa/aa/2c1962d108c7fe5e27aa03a354b378caf56d8eafdef15fd83dec081ce45a/orjson-3.11.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:61c9d357a59465736022d5d9ba06687afb7611dfb581a9d2129b77a6fcf78e59", size = 147942 }, - { url = "https://files.pythonhosted.org/packages/47/d1/65f404f4c47eb1b0b4476f03ec838cac0c4aa933920ff81e5dda4dee14e7/orjson-3.11.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:58fb9b17b4472c7b1dcf1a54583629e62e23779b2331052f09a9249edf81675b", size = 136640 }, - { url = "https://files.pythonhosted.org/packages/90/5f/7b784aea98bdb125a2f2da7c27d6c2d2f6d943d96ef0278bae596d563f85/orjson-3.11.8-cp310-cp310-win32.whl", hash = "sha256:b43dc2a391981d36c42fa57747a49dae793ef1d2e43898b197925b5534abd10a", size = 132066 }, - { url = "https://files.pythonhosted.org/packages/92/ec/2e284af8d6c9478df5ef938917743f61d68f4c70d17f1b6e82f7e3b8dba1/orjson-3.11.8-cp310-cp310-win_amd64.whl", hash = "sha256:c98121237fea2f679480765abd566f7713185897f35c9e6c2add7e3a9900eb61", size = 127609 }, - { url = "https://files.pythonhosted.org/packages/67/41/5aa7fa3b0f4dc6b47dcafc3cea909299c37e40e9972feabc8b6a74e2730d/orjson-3.11.8-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:003646067cc48b7fcab2ae0c562491c9b5d2cbd43f1e5f16d98fd118c5522d34", size = 229229 }, - { url = "https://files.pythonhosted.org/packages/0a/d7/57e7f2458e0a2c41694f39fc830030a13053a84f837a5b73423dca1f0938/orjson-3.11.8-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:ed193ce51d77a3830cad399a529cd4ef029968761f43ddc549e1bc62b40d88f8", size = 128871 }, - { url = "https://files.pythonhosted.org/packages/53/4a/e0fdb9430983e6c46e0299559275025075568aad5d21dd606faee3703924/orjson-3.11.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30491bc4f862aa15744b9738517454f1e46e56c972a2be87d70d727d5b2a8f8", size = 132104 }, - { url = "https://files.pythonhosted.org/packages/08/4a/2025a60ff3f5c8522060cda46612d9b1efa653de66ed2908591d8d82f22d/orjson-3.11.8-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6eda5b8b6be91d3f26efb7dc6e5e68ee805bc5617f65a328587b35255f138bf4", size = 130483 }, - { url = "https://files.pythonhosted.org/packages/2d/3c/b9cde05bdc7b2385c66014e0620627da638d3d04e4954416ab48c31196c5/orjson-3.11.8-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee8db7bfb6fe03581bbab54d7c4124a6dd6a7f4273a38f7267197890f094675f", size = 135481 }, - { url = "https://files.pythonhosted.org/packages/ff/f2/a8238e7734de7cb589fed319857a8025d509c89dc52fdcc88f39c6d03d5a/orjson-3.11.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d8b5231de76c528a46b57010bbd83fb51e056aa0220a372fd5065e978406f1c", size = 146819 }, - { url = "https://files.pythonhosted.org/packages/db/10/dbf1e2a3cafea673b1b4350e371877b759060d6018a998643b7040e5de48/orjson-3.11.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:58a4a208a6fbfdb7a7327b8f201c6014f189f721fd55d047cafc4157af1bc62a", size = 132846 }, - { url = "https://files.pythonhosted.org/packages/f8/fc/55e667ec9c85694038fcff00573d221b085d50777368ee3d77f38668bf3c/orjson-3.11.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f8952d6d2505c003e8f0224ff7858d341fa4e33fef82b91c4ff0ef070f2393c", size = 133580 }, - { url = "https://files.pythonhosted.org/packages/7e/a6/c08c589a9aad0cb46c4831d17de212a2b6901f9d976814321ff8e69e8785/orjson-3.11.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0022bb50f90da04b009ce32c512dc1885910daa7cb10b7b0cba4505b16db82a8", size = 142042 }, - { url = "https://files.pythonhosted.org/packages/5c/cc/2f78ea241d52b717d2efc38878615fe80425bf2beb6e68c984dde257a766/orjson-3.11.8-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ff51f9d657d1afb6f410cb435792ce4e1fe427aab23d2fcd727a2876e21d4cb6", size = 423845 }, - { url = "https://files.pythonhosted.org/packages/70/07/c17dcf05dd8045457538428a983bf1f1127928df5bf328cb24d2b7cddacb/orjson-3.11.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6dbe9a97bdb4d8d9d5367b52a7c32549bba70b2739c58ef74a6964a6d05ae054", size = 147729 }, - { url = "https://files.pythonhosted.org/packages/90/6c/0fb6e8a24e682e0958d71711ae6f39110e4b9cd8cab1357e2a89cb8e1951/orjson-3.11.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a5c370674ebabe16c6ccac33ff80c62bf8a6e59439f5e9d40c1f5ab8fd2215b7", size = 136425 }, - { url = "https://files.pythonhosted.org/packages/b2/35/4d3cc3a3d616035beb51b24a09bb872942dc452cf2df0c1d11ab35046d9f/orjson-3.11.8-cp311-cp311-win32.whl", hash = "sha256:0e32f7154299f42ae66f13488963269e5eccb8d588a65bc839ed986919fc9fac", size = 131870 }, - { url = "https://files.pythonhosted.org/packages/13/26/9fe70f81d16b702f8c3a775e8731b50ad91d22dacd14c7599b60a0941cd1/orjson-3.11.8-cp311-cp311-win_amd64.whl", hash = "sha256:25e0c672a2e32348d2eb33057b41e754091f2835f87222e4675b796b92264f06", size = 127440 }, - { url = "https://files.pythonhosted.org/packages/e8/c6/b038339f4145efd2859c1ca53097a52c0bb9cbdd24f947ebe146da1ad067/orjson-3.11.8-cp311-cp311-win_arm64.whl", hash = "sha256:9185589c1f2a944c17e26c9925dcdbc2df061cc4a145395c57f0c51f9b5dbfcd", size = 127399 }, - { url = "https://files.pythonhosted.org/packages/01/f6/8d58b32ab32d9215973a1688aebd098252ee8af1766c0e4e36e7831f0295/orjson-3.11.8-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1cd0b77e77c95758f8e1100139844e99f3ccc87e71e6fc8e1c027e55807c549f", size = 229233 }, - { url = "https://files.pythonhosted.org/packages/a9/8b/2ffe35e71f6b92622e8ea4607bf33ecf7dfb51b3619dcfabfd36cbe2d0a5/orjson-3.11.8-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:6a3d159d5ffa0e3961f353c4b036540996bf8b9697ccc38261c0eac1fd3347a6", size = 128772 }, - { url = "https://files.pythonhosted.org/packages/27/d2/1f8682ae50d5c6897a563cb96bc106da8c9cb5b7b6e81a52e4cc086679b9/orjson-3.11.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76070a76e9c5ae661e2d9848f216980d8d533e0f8143e6ed462807b242e3c5e8", size = 131946 }, - { url = "https://files.pythonhosted.org/packages/52/4b/5500f76f0eece84226e0689cb48dcde081104c2fa6e2483d17ca13685ffb/orjson-3.11.8-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:54153d21520a71a4c82a0dbb4523e468941d549d221dc173de0f019678cf3813", size = 130368 }, - { url = "https://files.pythonhosted.org/packages/da/4e/58b927e08fbe9840e6c920d9e299b051ea667463b1f39a56e668669f8508/orjson-3.11.8-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:469ac2125611b7c5741a0b3798cd9e5786cbad6345f9f400c77212be89563bec", size = 135540 }, - { url = "https://files.pythonhosted.org/packages/56/7c/ba7cb871cba1bcd5cd02ee34f98d894c6cea96353ad87466e5aef2429c60/orjson-3.11.8-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:14778ffd0f6896aa613951a7fbf4690229aa7a543cb2bfbe9f358e08aafa9546", size = 146877 }, - { url = "https://files.pythonhosted.org/packages/0b/5d/eb9c25fc1386696c6a342cd361c306452c75e0b55e86ad602dd4827a7fd7/orjson-3.11.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea56a955056a6d6c550cf18b3348656a9d9a4f02e2d0c02cabf3c73f1055d506", size = 132837 }, - { url = "https://files.pythonhosted.org/packages/37/87/5ddeb7fc1fbd9004aeccab08426f34c81a5b4c25c7061281862b015fce2b/orjson-3.11.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53a0f57e59a530d18a142f4d4ba6dfc708dc5fdedce45e98ff06b44930a2a48f", size = 133624 }, - { url = "https://files.pythonhosted.org/packages/22/09/90048793db94ee4b2fcec4ac8e5ddb077367637d6650be896b3494b79bb7/orjson-3.11.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9b48e274f8824567d74e2158199e269597edf00823a1b12b63d48462bbf5123e", size = 141904 }, - { url = "https://files.pythonhosted.org/packages/c0/cf/eb284847487821a5d415e54149a6449ba9bfc5872ce63ab7be41b8ec401c/orjson-3.11.8-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:3f262401086a3960586af06c054609365e98407151f5ea24a62893a40d80dbbb", size = 423742 }, - { url = "https://files.pythonhosted.org/packages/44/09/e12423d327071c851c13e76936f144a96adacfc037394dec35ac3fc8d1e8/orjson-3.11.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:8e8c6218b614badf8e229b697865df4301afa74b791b6c9ade01d19a9953a942", size = 147806 }, - { url = "https://files.pythonhosted.org/packages/b3/6d/37c2589ba864e582ffe7611643314785c6afb1f83c701654ef05daa8fcc7/orjson-3.11.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:093d489fa039ddade2db541097dbb484999fcc65fc2b0ff9819141e2ab364f25", size = 136485 }, - { url = "https://files.pythonhosted.org/packages/be/c9/135194a02ab76b04ed9a10f68624b7ebd238bbe55548878b11ff15a0f352/orjson-3.11.8-cp312-cp312-win32.whl", hash = "sha256:e0950ed1bcb9893f4293fd5c5a7ee10934fbf82c4101c70be360db23ce24b7d2", size = 131966 }, - { url = "https://files.pythonhosted.org/packages/ed/9a/9796f8fbe3cf30ce9cb696748dbb535e5c87be4bf4fe2e9ca498ef1fa8cf/orjson-3.11.8-cp312-cp312-win_amd64.whl", hash = "sha256:3cf17c141617b88ced4536b2135c552490f07799f6ad565948ea07bef0dcb9a6", size = 127441 }, - { url = "https://files.pythonhosted.org/packages/cc/47/5aaf54524a7a4a0dd09dd778f3fa65dd2108290615b652e23d944152bc8e/orjson-3.11.8-cp312-cp312-win_arm64.whl", hash = "sha256:48854463b0572cc87dac7d981aa72ed8bf6deedc0511853dc76b8bbd5482d36d", size = 127364 }, - { url = "https://files.pythonhosted.org/packages/66/7f/95fba509bb2305fab0073558f1e8c3a2ec4b2afe58ed9fcb7d3b8beafe94/orjson-3.11.8-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:3f23426851d98478c8970da5991f84784a76682213cd50eb73a1da56b95239dc", size = 229180 }, - { url = "https://files.pythonhosted.org/packages/f6/9d/b237215c743ca073697d759b5503abd2cb8a0d7b9c9e21f524bcf176ab66/orjson-3.11.8-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:ebaed4cef74a045b83e23537b52ef19a367c7e3f536751e355a2a394f8648559", size = 128754 }, - { url = "https://files.pythonhosted.org/packages/42/3d/27d65b6d11e63f133781425f132807aef793ed25075fec686fc8e46dd528/orjson-3.11.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97c8f5d3b62380b70c36ffacb2a356b7c6becec86099b177f73851ba095ef623", size = 131877 }, - { url = "https://files.pythonhosted.org/packages/dd/cc/faee30cd8f00421999e40ef0eba7332e3a625ce91a58200a2f52c7fef235/orjson-3.11.8-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:436c4922968a619fb7fef1ccd4b8b3a76c13b67d607073914d675026e911a65c", size = 130361 }, - { url = "https://files.pythonhosted.org/packages/5c/bb/a6c55896197f97b6d4b4e7c7fd77e7235517c34f5d6ad5aadd43c54c6d7c/orjson-3.11.8-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1ab359aff0436d80bfe8a23b46b5fea69f1e18aaf1760a709b4787f1318b317f", size = 135521 }, - { url = "https://files.pythonhosted.org/packages/9c/7c/ca3a3525aa32ff636ebb1778e77e3587b016ab2edb1b618b36ba96f8f2c0/orjson-3.11.8-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f89b6d0b3a8d81e1929d3ab3d92bbc225688bd80a770c49432543928fe09ac55", size = 146862 }, - { url = "https://files.pythonhosted.org/packages/3c/0c/18a9d7f18b5edd37344d1fd5be17e94dc652c67826ab749c6e5948a78112/orjson-3.11.8-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29c009e7a2ca9ad0ed1376ce20dd692146a5d9fe4310848904b6b4fee5c5c137", size = 132847 }, - { url = "https://files.pythonhosted.org/packages/23/91/7e722f352ad67ca573cee44de2a58fb810d0f4eb4e33276c6a557979fd8a/orjson-3.11.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:705b895b781b3e395c067129d8551655642dfe9437273211d5404e87ac752b53", size = 133637 }, - { url = "https://files.pythonhosted.org/packages/af/04/32845ce13ac5bd1046ddb02ac9432ba856cc35f6d74dde95864fe0ad5523/orjson-3.11.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:88006eda83858a9fdf73985ce3804e885c2befb2f506c9a3723cdeb5a2880e3e", size = 141906 }, - { url = "https://files.pythonhosted.org/packages/02/5e/c551387ddf2d7106d9039369862245c85738b828844d13b99ccb8d61fd06/orjson-3.11.8-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:55120759e61309af7fcf9e961c6f6af3dde5921cdb3ee863ef63fd9db126cae6", size = 423722 }, - { url = "https://files.pythonhosted.org/packages/00/a3/ecfe62434096f8a794d4976728cb59bcfc4a643977f21c2040545d37eb4c/orjson-3.11.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:98bdc6cb889d19bed01de46e67574a2eab61f5cc6b768ed50e8ac68e9d6ffab6", size = 147801 }, - { url = "https://files.pythonhosted.org/packages/18/6d/0dce10b9f6643fdc59d99333871a38fa5a769d8e2fc34a18e5d2bfdee900/orjson-3.11.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:708c95f925a43ab9f34625e45dcdadf09ec8a6e7b664a938f2f8d5650f6c090b", size = 136460 }, - { url = "https://files.pythonhosted.org/packages/01/d6/6dde4f31842d87099238f1f07b459d24edc1a774d20687187443ab044191/orjson-3.11.8-cp313-cp313-win32.whl", hash = "sha256:01c4e5a6695dc09098f2e6468a251bc4671c50922d4d745aff1a0a33a0cf5b8d", size = 131956 }, - { url = "https://files.pythonhosted.org/packages/c1/f9/4e494a56e013db957fb77186b818b916d4695b8fa2aa612364974160e91b/orjson-3.11.8-cp313-cp313-win_amd64.whl", hash = "sha256:c154a35dd1330707450bb4d4e7dd1f17fa6f42267a40c1e8a1daa5e13719b4b8", size = 127410 }, - { url = "https://files.pythonhosted.org/packages/57/7f/803203d00d6edb6e9e7eef421d4e1adbb5ea973e40b3533f3cfd9aeb374e/orjson-3.11.8-cp313-cp313-win_arm64.whl", hash = "sha256:4861bde57f4d253ab041e374f44023460e60e71efaa121f3c5f0ed457c3a701e", size = 127338 }, - { url = "https://files.pythonhosted.org/packages/6d/35/b01910c3d6b85dc882442afe5060cbf719c7d1fc85749294beda23d17873/orjson-3.11.8-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ec795530a73c269a55130498842aaa762e4a939f6ce481a7e986eeaa790e9da4", size = 229171 }, - { url = "https://files.pythonhosted.org/packages/c2/56/c9ec97bd11240abef39b9e5d99a15462809c45f677420fd148a6c5e6295e/orjson-3.11.8-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:c492a0e011c0f9066e9ceaa896fbc5b068c54d365fea5f3444b697ee01bc8625", size = 128746 }, - { url = "https://files.pythonhosted.org/packages/3b/e4/66d4f30a90de45e2f0cbd9623588e8ae71eef7679dbe2ae954ed6d66a41f/orjson-3.11.8-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:883206d55b1bd5f5679ad5e6ddd3d1a5e3cac5190482927fdb8c78fb699193b5", size = 131867 }, - { url = "https://files.pythonhosted.org/packages/19/30/2a645fc9286b928675e43fa2a3a16fb7b6764aa78cc719dc82141e00f30b/orjson-3.11.8-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5774c1fdcc98b2259800b683b19599c133baeb11d60033e2095fd9d4667b82db", size = 124664 }, - { url = "https://files.pythonhosted.org/packages/db/44/77b9a86d84a28d52ba3316d77737f6514e17118119ade3f91b639e859029/orjson-3.11.8-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ac7381c83dd3d4a6347e6635950aa448f54e7b8406a27c7ecb4a37e9f1ae08b", size = 129701 }, - { url = "https://files.pythonhosted.org/packages/b3/ea/eff3d9bfe47e9bc6969c9181c58d9f71237f923f9c86a2d2f490cd898c82/orjson-3.11.8-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:14439063aebcb92401c11afc68ee4e407258d2752e62d748b6942dad20d2a70d", size = 141202 }, - { url = "https://files.pythonhosted.org/packages/52/c8/90d4b4c60c84d62068d0cf9e4d8f0a4e05e76971d133ac0c60d818d4db20/orjson-3.11.8-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa72e71977bff96567b0f500fc5bfd2fdf915f34052c782a4c6ebbdaa97aa858", size = 127194 }, - { url = "https://files.pythonhosted.org/packages/8d/c7/ea9e08d1f0ba981adffb629811148b44774d935171e7b3d780ae43c4c254/orjson-3.11.8-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7679bc2f01bb0d219758f1a5f87bb7c8a81c0a186824a393b366876b4948e14f", size = 133639 }, - { url = "https://files.pythonhosted.org/packages/6c/8c/ddbbfd6ba59453c8fc7fe1d0e5983895864e264c37481b2a791db635f046/orjson-3.11.8-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:14f7b8fcb35ef403b42fa5ecfa4ed032332a91f3dc7368fbce4184d59e1eae0d", size = 141914 }, - { url = "https://files.pythonhosted.org/packages/4e/31/dbfbefec9df060d34ef4962cd0afcb6fa7a9ec65884cb78f04a7859526c3/orjson-3.11.8-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:c2bdf7b2facc80b5e34f48a2d557727d5c5c57a8a450de122ae81fa26a81c1bc", size = 423800 }, - { url = "https://files.pythonhosted.org/packages/87/cf/f74e9ae9803d4ab46b163494adba636c6d7ea955af5cc23b8aaa94cfd528/orjson-3.11.8-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ccd7ba1b0605813a0715171d39ec4c314cb97a9c85893c2c5c0c3a3729df38bf", size = 147837 }, - { url = "https://files.pythonhosted.org/packages/64/e6/9214f017b5db85e84e68602792f742e5dc5249e963503d1b356bee611e01/orjson-3.11.8-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cdbc8c9c02463fef4d3c53a9ba3336d05496ec8e1f1c53326a1e4acc11f5c600", size = 136441 }, - { url = "https://files.pythonhosted.org/packages/24/dd/3590348818f58f837a75fb969b04cdf187ae197e14d60b5e5a794a38b79d/orjson-3.11.8-cp314-cp314-win32.whl", hash = "sha256:0b57f67710a8cd459e4e54eb96d5f77f3624eba0c661ba19a525807e42eccade", size = 131983 }, - { url = "https://files.pythonhosted.org/packages/3f/0f/b6cb692116e05d058f31ceee819c70f097fa9167c82f67fabe7516289abc/orjson-3.11.8-cp314-cp314-win_amd64.whl", hash = "sha256:735e2262363dcbe05c35e3a8869898022af78f89dde9e256924dc02e99fe69ca", size = 127396 }, - { url = "https://files.pythonhosted.org/packages/c0/d1/facb5b5051fabb0ef9d26c6544d87ef19a939a9a001198655d0d891062dd/orjson-3.11.8-cp314-cp314-win_arm64.whl", hash = "sha256:6ccdea2c213cf9f3d9490cbd5d427693c870753df41e6cb375bd79bcbafc8817", size = 127330 }, -] - -[[package]] -name = "packaging" -version = "26.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366 }, -] - -[[package]] -name = "pandas" -version = "2.3.3" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] -dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "python-dateutil", marker = "python_full_version < '3.11'" }, - { name = "pytz", marker = "python_full_version < '3.11'" }, - { name = "tzdata", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/f7/f425a00df4fcc22b292c6895c6831c0c8ae1d9fac1e024d16f98a9ce8749/pandas-2.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:376c6446ae31770764215a6c937f72d917f214b43560603cd60da6408f183b6c", size = 11555763 }, - { url = "https://files.pythonhosted.org/packages/13/4f/66d99628ff8ce7857aca52fed8f0066ce209f96be2fede6cef9f84e8d04f/pandas-2.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e19d192383eab2f4ceb30b412b22ea30690c9e618f78870357ae1d682912015a", size = 10801217 }, - { url = "https://files.pythonhosted.org/packages/1d/03/3fc4a529a7710f890a239cc496fc6d50ad4a0995657dccc1d64695adb9f4/pandas-2.3.3-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5caf26f64126b6c7aec964f74266f435afef1c1b13da3b0636c7518a1fa3e2b1", size = 12148791 }, - { url = "https://files.pythonhosted.org/packages/40/a8/4dac1f8f8235e5d25b9955d02ff6f29396191d4e665d71122c3722ca83c5/pandas-2.3.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd7478f1463441ae4ca7308a70e90b33470fa593429f9d4c578dd00d1fa78838", size = 12769373 }, - { url = "https://files.pythonhosted.org/packages/df/91/82cc5169b6b25440a7fc0ef3a694582418d875c8e3ebf796a6d6470aa578/pandas-2.3.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4793891684806ae50d1288c9bae9330293ab4e083ccd1c5e383c34549c6e4250", size = 13200444 }, - { url = "https://files.pythonhosted.org/packages/10/ae/89b3283800ab58f7af2952704078555fa60c807fff764395bb57ea0b0dbd/pandas-2.3.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:28083c648d9a99a5dd035ec125d42439c6c1c525098c58af0fc38dd1a7a1b3d4", size = 13858459 }, - { url = "https://files.pythonhosted.org/packages/85/72/530900610650f54a35a19476eca5104f38555afccda1aa11a92ee14cb21d/pandas-2.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:503cf027cf9940d2ceaa1a93cfb5f8c8c7e6e90720a2850378f0b3f3b1e06826", size = 11346086 }, - { url = "https://files.pythonhosted.org/packages/c1/fa/7ac648108144a095b4fb6aa3de1954689f7af60a14cf25583f4960ecb878/pandas-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523", size = 11578790 }, - { url = "https://files.pythonhosted.org/packages/9b/35/74442388c6cf008882d4d4bdfc4109be87e9b8b7ccd097ad1e7f006e2e95/pandas-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45", size = 10833831 }, - { url = "https://files.pythonhosted.org/packages/fe/e4/de154cbfeee13383ad58d23017da99390b91d73f8c11856f2095e813201b/pandas-2.3.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66", size = 12199267 }, - { url = "https://files.pythonhosted.org/packages/bf/c9/63f8d545568d9ab91476b1818b4741f521646cbdd151c6efebf40d6de6f7/pandas-2.3.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b", size = 12789281 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/8e/59/712db1d7040520de7a4965df15b774348980e6df45c129b8c64d0dbe74ef/pandas-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c", size = 11348702 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722 }, - { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671 }, - { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807 }, - { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872 }, - { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371 }, - { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333 }, - { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120 }, - { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991 }, - { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227 }, - { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056 }, - { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189 }, - { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912 }, - { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160 }, - { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233 }, - { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635 }, - { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079 }, - { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049 }, - { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638 }, - { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834 }, - { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925 }, - { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071 }, - { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504 }, - { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702 }, - { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535 }, - { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582 }, - { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963 }, - { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175 }, -] - -[[package]] -name = "pandas" -version = "3.0.2" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version >= '3.11' and python_full_version < '3.13' and sys_platform == 'win32'", - "python_full_version >= '3.11' and python_full_version < '3.13' and sys_platform == 'emscripten'", - "python_full_version >= '3.11' and python_full_version < '3.13' and sys_platform != 'emscripten' and sys_platform != 'win32'", -] -dependencies = [ - { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "python-dateutil", marker = "python_full_version >= '3.11'" }, - { name = "tzdata", marker = "(python_full_version >= '3.11' and sys_platform == 'emscripten') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/da/99/b342345300f13440fe9fe385c3c481e2d9a595ee3bab4d3219247ac94e9a/pandas-3.0.2.tar.gz", hash = "sha256:f4753e73e34c8d83221ba58f232433fca2748be8b18dbca02d242ed153945043", size = 4645855 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/97/35/6411db530c618e0e0005187e35aa02ce60ae4c4c4d206964a2f978217c27/pandas-3.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a727a73cbdba2f7458dc82449e2315899d5140b449015d822f515749a46cbbe0", size = 10326926 }, - { url = "https://files.pythonhosted.org/packages/c4/d3/b7da1d5d7dbdc5ef52ed7debd2b484313b832982266905315dad5a0bf0b1/pandas-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dbbd4aa20ca51e63b53bbde6a0fa4254b1aaabb74d2f542df7a7959feb1d760c", size = 9926987 }, - { url = "https://files.pythonhosted.org/packages/52/77/9b1c2d6070b5dbe239a7bc889e21bfa58720793fb902d1e070695d87c6d0/pandas-3.0.2-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:339dda302bd8369dedeae979cb750e484d549b563c3f54f3922cb8ff4978c5eb", size = 10757067 }, - { url = "https://files.pythonhosted.org/packages/20/17/ec40d981705654853726e7ac9aea9ddbb4a5d9cf54d8472222f4f3de06c2/pandas-3.0.2-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:61c2fd96d72b983a9891b2598f286befd4ad262161a609c92dc1652544b46b76", size = 11258787 }, - { url = "https://files.pythonhosted.org/packages/90/e3/3f1126d43d3702ca8773871a81c9f15122a1f412342cc56284ffda5b1f70/pandas-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c934008c733b8bbea273ea308b73b3156f0181e5b72960790b09c18a2794fe1e", size = 11771616 }, - { url = "https://files.pythonhosted.org/packages/2e/cf/0f4e268e1f5062e44a6bda9f925806721cd4c95c2b808a4c82ebe914f96b/pandas-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:60a80bb4feacbef5e1447a3f82c33209c8b7e07f28d805cfd1fb951e5cb443aa", size = 12337623 }, - { url = "https://files.pythonhosted.org/packages/44/a0/97a6339859d4acb2536efb24feb6708e82f7d33b2ed7e036f2983fcced82/pandas-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:ed72cb3f45190874eb579c64fa92d9df74e98fd63e2be7f62bce5ace0ade61df", size = 9897372 }, - { url = "https://files.pythonhosted.org/packages/8f/eb/781516b808a99ddf288143cec46b342b3016c3414d137da1fdc3290d8860/pandas-3.0.2-cp311-cp311-win_arm64.whl", hash = "sha256:f12b1a9e332c01e09510586f8ca9b108fd631fd656af82e452d7315ef6df5f9f", size = 9154922 }, - { url = "https://files.pythonhosted.org/packages/f3/b0/c20bd4d6d3f736e6bd6b55794e9cd0a617b858eaad27c8f410ea05d953b7/pandas-3.0.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:232a70ebb568c0c4d2db4584f338c1577d81e3af63292208d615907b698a0f18", size = 10347921 }, - { url = "https://files.pythonhosted.org/packages/35/d0/4831af68ce30cc2d03c697bea8450e3225a835ef497d0d70f31b8cdde965/pandas-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:970762605cff1ca0d3f71ed4f3a769ea8f85fc8e6348f6e110b8fea7e6eb5a14", size = 9888127 }, - { url = "https://files.pythonhosted.org/packages/61/a9/16ea9346e1fc4a96e2896242d9bc674764fb9049b0044c0132502f7a771e/pandas-3.0.2-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aff4e6f4d722e0652707d7bcb190c445fe58428500c6d16005b02401764b1b3d", size = 10399577 }, - { url = "https://files.pythonhosted.org/packages/c4/a8/3a61a721472959ab0ce865ef05d10b0d6bfe27ce8801c99f33d4fa996e65/pandas-3.0.2-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef8b27695c3d3dc78403c9a7d5e59a62d5464a7e1123b4e0042763f7104dc74f", size = 10880030 }, - { url = "https://files.pythonhosted.org/packages/da/65/7225c0ea4d6ce9cb2160a7fb7f39804871049f016e74782e5dade4d14109/pandas-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f8d68083e49e16b84734eb1a4dcae4259a75c90fb6e2251ab9a00b61120c06ab", size = 11409468 }, - { url = "https://files.pythonhosted.org/packages/fa/5b/46e7c76032639f2132359b5cf4c785dd8cf9aea5ea64699eac752f02b9db/pandas-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:32cc41f310ebd4a296d93515fcac312216adfedb1894e879303987b8f1e2b97d", size = 11936381 }, - { url = "https://files.pythonhosted.org/packages/7b/8b/721a9cff6fa6a91b162eb51019c6243b82b3226c71bb6c8ef4a9bd65cbc6/pandas-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:a4785e1d6547d8427c5208b748ae2efb64659a21bd82bf440d4262d02bfa02a4", size = 9744993 }, - { url = "https://files.pythonhosted.org/packages/d5/18/7f0bd34ae27b28159aa80f2a6799f47fda34f7fb938a76e20c7b7fe3b200/pandas-3.0.2-cp312-cp312-win_arm64.whl", hash = "sha256:08504503f7101300107ecdc8df73658e4347586db5cfdadabc1592e9d7e7a0fd", size = 9056118 }, - { url = "https://files.pythonhosted.org/packages/bf/ca/3e639a1ea6fcd0617ca4e8ca45f62a74de33a56ae6cd552735470b22c8d3/pandas-3.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b5918ba197c951dec132b0c5929a00c0bf05d5942f590d3c10a807f6e15a57d3", size = 10321105 }, - { url = "https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d606a041c89c0a474a4702d532ab7e73a14fe35c8d427b972a625c8e46373668", size = 9864088 }, - { url = "https://files.pythonhosted.org/packages/5c/2b/341f1b04bbca2e17e13cd3f08c215b70ef2c60c5356ef1e8c6857449edc7/pandas-3.0.2-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:710246ba0616e86891b58ab95f2495143bb2bc83ab6b06747c74216f583a6ac9", size = 10369066 }, - { url = "https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5d3cfe227c725b1f3dff4278b43d8c784656a42a9325b63af6b1492a8232209e", size = 10876780 }, - { url = "https://files.pythonhosted.org/packages/98/fe/2249ae5e0a69bd0ddf17353d0a5d26611d70970111f5b3600cdc8be883e7/pandas-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c3b723df9087a9a9a840e263ebd9f88b64a12075d1bf2ea401a5a42f254f084d", size = 11375181 }, - { url = "https://files.pythonhosted.org/packages/de/64/77a38b09e70b6464883b8d7584ab543e748e42c1b5d337a2ee088e0df741/pandas-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3096110bf9eac0070b7208465f2740e2d8a670d5cb6530b5bb884eca495fd39", size = 11928899 }, - { url = "https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:07a10f5c36512eead51bc578eb3354ad17578b22c013d89a796ab5eee90cd991", size = 9746574 }, - { url = "https://files.pythonhosted.org/packages/88/39/21304ae06a25e8bf9fc820d69b29b2c495b2ae580d1e143146c309941760/pandas-3.0.2-cp313-cp313-win_arm64.whl", hash = "sha256:5fdbfa05931071aba28b408e59226186b01eb5e92bea2ab78b65863ca3228d84", size = 9047156 }, - { url = "https://files.pythonhosted.org/packages/72/20/7defa8b27d4f330a903bb68eea33be07d839c5ea6bdda54174efcec0e1d2/pandas-3.0.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:dbc20dea3b9e27d0e66d74c42b2d0c1bed9c2ffe92adea33633e3bedeb5ac235", size = 10756238 }, - { url = "https://files.pythonhosted.org/packages/e9/95/49433c14862c636afc0e9b2db83ff16b3ad92959364e52b2955e44c8e94c/pandas-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b75c347eff42497452116ce05ef461822d97ce5b9ff8df6edacb8076092c855d", size = 10408520 }, - { url = "https://files.pythonhosted.org/packages/3b/f8/462ad2b5881d6b8ec8e5f7ed2ea1893faa02290d13870a1600fe72ad8efc/pandas-3.0.2-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1478075142e83a5571782ad007fb201ed074bdeac7ebcc8890c71442e96adf7", size = 10324154 }, - { url = "https://files.pythonhosted.org/packages/0a/65/d1e69b649cbcddda23ad6e4c40ef935340f6f652a006e5cbc3555ac8adb3/pandas-3.0.2-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5880314e69e763d4c8b27937090de570f1fb8d027059a7ada3f7f8e98bdcb677", size = 10714449 }, - { url = "https://files.pythonhosted.org/packages/47/a4/85b59bc65b8190ea3689882db6cdf32a5003c0ccd5a586c30fdcc3ffc4fc/pandas-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b5329e26898896f06035241a626d7c335daa479b9bbc82be7c2742d048e41172", size = 11338475 }, - { url = "https://files.pythonhosted.org/packages/1e/c4/bc6966c6e38e5d9478b935272d124d80a589511ed1612a5d21d36f664c68/pandas-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:81526c4afd31971f8b62671442a4b2b51e0aa9acc3819c9f0f12a28b6fcf85f1", size = 11786568 }, - { url = "https://files.pythonhosted.org/packages/e8/74/09298ca9740beed1d3504e073d67e128aa07e5ca5ca2824b0c674c0b8676/pandas-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:7cadd7e9a44ec13b621aec60f9150e744cfc7a3dd32924a7e2f45edff31823b0", size = 10488652 }, - { url = "https://files.pythonhosted.org/packages/bb/40/c6ea527147c73b24fc15c891c3fcffe9c019793119c5742b8784a062c7db/pandas-3.0.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:db0dbfd2a6cdf3770aa60464d50333d8f3d9165b2f2671bcc299b72de5a6677b", size = 10326084 }, - { url = "https://files.pythonhosted.org/packages/95/25/bdb9326c3b5455f8d4d3549fce7abcf967259de146fe2cf7a82368141948/pandas-3.0.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0555c5882688a39317179ab4a0ed41d3ebc8812ab14c69364bbee8fb7a3f6288", size = 9914146 }, - { url = "https://files.pythonhosted.org/packages/8d/77/3a227ff3337aa376c60d288e1d61c5d097131d0ac71f954d90a8f369e422/pandas-3.0.2-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:01f31a546acd5574ef77fe199bc90b55527c225c20ccda6601cf6b0fd5ed597c", size = 10444081 }, - { url = "https://files.pythonhosted.org/packages/15/88/3cdd54fa279341afa10acf8d2b503556b1375245dccc9315659f795dd2e9/pandas-3.0.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:deeca1b5a931fdf0c2212c8a659ade6d3b1edc21f0914ce71ef24456ca7a6535", size = 10897535 }, - { url = "https://files.pythonhosted.org/packages/06/9d/98cc7a7624f7932e40f434299260e2917b090a579d75937cb8a57b9d2de3/pandas-3.0.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0f48afd9bb13300ffb5a3316973324c787054ba6665cda0da3fbd67f451995db", size = 11446992 }, - { url = "https://files.pythonhosted.org/packages/9a/cd/19ff605cc3760e80602e6826ddef2824d8e7050ed80f2e11c4b079741dc3/pandas-3.0.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6c4d8458b97a35717b62469a4ea0e85abd5ed8687277f5ccfc67f8a5126f8c53", size = 11968257 }, - { url = "https://files.pythonhosted.org/packages/db/60/aba6a38de456e7341285102bede27514795c1eaa353bc0e7638b6b785356/pandas-3.0.2-cp314-cp314-win_amd64.whl", hash = "sha256:b35d14bb5d8285d9494fe93815a9e9307c0876e10f1e8e89ac5b88f728ec8dcf", size = 9865893 }, - { url = "https://files.pythonhosted.org/packages/08/71/e5ec979dd2e8a093dacb8864598c0ff59a0cee0bbcdc0bfec16a51684d4f/pandas-3.0.2-cp314-cp314-win_arm64.whl", hash = "sha256:63d141b56ef686f7f0d714cfb8de4e320475b86bf4b620aa0b7da89af8cbdbbb", size = 9188644 }, - { url = "https://files.pythonhosted.org/packages/f1/6c/7b45d85db19cae1eb524f2418ceaa9d85965dcf7b764ed151386b7c540f0/pandas-3.0.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:140f0cffb1fa2524e874dde5b477d9defe10780d8e9e220d259b2c0874c89d9d", size = 10776246 }, - { url = "https://files.pythonhosted.org/packages/a8/3e/7b00648b086c106e81766f25322b48aa8dfa95b55e621dbdf2fdd413a117/pandas-3.0.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ae37e833ff4fed0ba352f6bdd8b73ba3ab3256a85e54edfd1ab51ae40cca0af8", size = 10424801 }, - { url = "https://files.pythonhosted.org/packages/da/6e/558dd09a71b53b4008e7fc8a98ec6d447e9bfb63cdaeea10e5eb9b2dabe8/pandas-3.0.2-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d888a5c678a419a5bb41a2a93818e8ed9fd3172246555c0b37b7cc27027effd", size = 10345643 }, - { url = "https://files.pythonhosted.org/packages/be/e3/921c93b4d9a280409451dc8d07b062b503bbec0531d2627e73a756e99a82/pandas-3.0.2-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b444dc64c079e84df91baa8bf613d58405645461cabca929d9178f2cd392398d", size = 10743641 }, - { url = "https://files.pythonhosted.org/packages/56/ca/fd17286f24fa3b4d067965d8d5d7e14fe557dd4f979a0b068ac0deaf8228/pandas-3.0.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4544c7a54920de8eeacaa1466a6b7268ecfbc9bc64ab4dbb89c6bbe94d5e0660", size = 11361993 }, - { url = "https://files.pythonhosted.org/packages/e4/a5/2f6ed612056819de445a433ca1f2821ac3dab7f150d569a59e9cc105de1d/pandas-3.0.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:734be7551687c00fbd760dc0522ed974f82ad230d4a10f54bf51b80d44a08702", size = 11815274 }, - { url = "https://files.pythonhosted.org/packages/00/2f/b622683e99ec3ce00b0854bac9e80868592c5b051733f2cf3a868e5fea26/pandas-3.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:57a07209bebcbcf768d2d13c9b78b852f9a15978dac41b9e6421a81ad4cdd276", size = 10888530 }, - { url = "https://files.pythonhosted.org/packages/cb/2b/f8434233fab2bd66a02ec014febe4e5adced20e2693e0e90a07d118ed30e/pandas-3.0.2-cp314-cp314t-win_arm64.whl", hash = "sha256:5371b72c2d4d415d08765f32d689217a43227484e81b2305b52076e328f6f482", size = 9455341 }, -] - -[[package]] -name = "pathable" -version = "0.5.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/55/b748445cb4ea6b125626f15379be7c96d1035d4fa3e8fee362fa92298abf/pathable-0.5.0.tar.gz", hash = "sha256:d81938348a1cacb525e7c75166270644782c0fb9c8cecc16be033e71427e0ef1", size = 16655 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/52/96/5a770e5c461462575474468e5af931cff9de036e7c2b4fea23c1c58d2cbe/pathable-0.5.0-py3-none-any.whl", hash = "sha256:646e3d09491a6351a0c82632a09c02cdf70a252e73196b36d8a15ba0a114f0a6", size = 16867 }, -] - -[[package]] -name = "pillow" -version = "12.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/21/c2bcdd5906101a30244eaffc1b6e6ce71a31bd0742a01eb89e660ebfac2d/pillow-12.2.0.tar.gz", hash = "sha256:a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5", size = 46987819 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/aa/d0b28e1c811cd4d5f5c2bfe2e022292bd255ae5744a3b9ac7d6c8f72dd75/pillow-12.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:a4e8f36e677d3336f35089648c8955c51c6d386a13cf6ee9c189c5f5bd713a9f", size = 5354355 }, - { url = "https://files.pythonhosted.org/packages/27/8e/1d5b39b8ae2bd7650d0c7b6abb9602d16043ead9ebbfef4bc4047454da2a/pillow-12.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e589959f10d9824d39b350472b92f0ce3b443c0a3442ebf41c40cb8361c5b97", size = 4695871 }, - { url = "https://files.pythonhosted.org/packages/f0/c5/dcb7a6ca6b7d3be41a76958e90018d56c8462166b3ef223150360850c8da/pillow-12.2.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a52edc8bfff4429aaabdf4d9ee0daadbbf8562364f940937b941f87a4290f5ff", size = 6269734 }, - { url = "https://files.pythonhosted.org/packages/ea/f1/aa1bb13b2f4eba914e9637893c73f2af8e48d7d4023b9d3750d4c5eb2d0c/pillow-12.2.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:975385f4776fafde056abb318f612ef6285b10a1f12b8570f3647ad0d74b48ec", size = 8076080 }, - { url = "https://files.pythonhosted.org/packages/a1/2a/8c79d6a53169937784604a8ae8d77e45888c41537f7f6f65ed1f407fe66d/pillow-12.2.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd9c0c7a0c681a347b3194c500cb1e6ca9cab053ea4d82a5cf45b6b754560136", size = 6382236 }, - { url = "https://files.pythonhosted.org/packages/b5/42/bbcb6051030e1e421d103ce7a8ecadf837aa2f39b8f82ef1a8d37c3d4ebc/pillow-12.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:88d387ff40b3ff7c274947ed3125dedf5262ec6919d83946753b5f3d7c67ea4c", size = 7070220 }, - { url = "https://files.pythonhosted.org/packages/3f/e1/c2a7d6dd8cfa6b231227da096fd2d58754bab3603b9d73bf609d3c18b64f/pillow-12.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:51c4167c34b0d8ba05b547a3bb23578d0ba17b80a5593f93bd8ecb123dd336a3", size = 6493124 }, - { url = "https://files.pythonhosted.org/packages/5f/41/7c8617da5d32e1d2f026e509484fdb6f3ad7efaef1749a0c1928adbb099e/pillow-12.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:34c0d99ecccea270c04882cb3b86e7b57296079c9a4aff88cb3b33563d95afaa", size = 7194324 }, - { url = "https://files.pythonhosted.org/packages/2d/de/a777627e19fd6d62f84070ee1521adde5eeda4855b5cf60fe0b149118bca/pillow-12.2.0-cp310-cp310-win32.whl", hash = "sha256:b85f66ae9eb53e860a873b858b789217ba505e5e405a24b85c0464822fe88032", size = 6376363 }, - { url = "https://files.pythonhosted.org/packages/e7/34/fc4cb5204896465842767b96d250c08410f01f2f28afc43b257de842eed5/pillow-12.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:673aa32138f3e7531ccdbca7b3901dba9b70940a19ccecc6a37c77d5fdeb05b5", size = 7083523 }, - { url = "https://files.pythonhosted.org/packages/2d/a0/32852d36bc7709f14dc3f64f929a275e958ad8c19a6deba9610d458e28b3/pillow-12.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:3e080565d8d7c671db5802eedfb438e5565ffa40115216eabb8cd52d0ecce024", size = 2463318 }, - { url = "https://files.pythonhosted.org/packages/68/e1/748f5663efe6edcfc4e74b2b93edfb9b8b99b67f21a854c3ae416500a2d9/pillow-12.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:8be29e59487a79f173507c30ddf57e733a357f67881430449bb32614075a40ab", size = 5354347 }, - { url = "https://files.pythonhosted.org/packages/47/a1/d5ff69e747374c33a3b53b9f98cca7889fce1fd03d79cdc4e1bccc6c5a87/pillow-12.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:71cde9a1e1551df7d34a25462fc60325e8a11a82cc2e2f54578e5e9a1e153d65", size = 4695873 }, - { url = "https://files.pythonhosted.org/packages/df/21/e3fbdf54408a973c7f7f89a23b2cb97a7ef30c61ab4142af31eee6aebc88/pillow-12.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f490f9368b6fc026f021db16d7ec2fbf7d89e2edb42e8ec09d2c60505f5729c7", size = 6280168 }, - { url = "https://files.pythonhosted.org/packages/d3/f1/00b7278c7dd52b17ad4329153748f87b6756ec195ff786c2bdf12518337d/pillow-12.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8bd7903a5f2a4545f6fd5935c90058b89d30045568985a71c79f5fd6edf9b91e", size = 8088188 }, - { url = "https://files.pythonhosted.org/packages/ad/cf/220a5994ef1b10e70e85748b75649d77d506499352be135a4989c957b701/pillow-12.2.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3997232e10d2920a68d25191392e3a4487d8183039e1c74c2297f00ed1c50705", size = 6394401 }, - { url = "https://files.pythonhosted.org/packages/e9/bd/e51a61b1054f09437acfbc2ff9106c30d1eb76bc1453d428399946781253/pillow-12.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e74473c875d78b8e9d5da2a70f7099549f9eb37ded4e2f6a463e60125bccd176", size = 7079655 }, - { url = "https://files.pythonhosted.org/packages/6b/3d/45132c57d5fb4b5744567c3817026480ac7fc3ce5d4c47902bc0e7f6f853/pillow-12.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:56a3f9c60a13133a98ecff6197af34d7824de9b7b38c3654861a725c970c197b", size = 6503105 }, - { url = "https://files.pythonhosted.org/packages/7d/2e/9df2fc1e82097b1df3dce58dc43286aa01068e918c07574711fcc53e6fb4/pillow-12.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:90e6f81de50ad6b534cab6e5aef77ff6e37722b2f5d908686f4a5c9eba17a909", size = 7203402 }, - { url = "https://files.pythonhosted.org/packages/bd/2e/2941e42858ebb67e50ae741473de81c2984e6eff7b397017623c676e2e8d/pillow-12.2.0-cp311-cp311-win32.whl", hash = "sha256:8c984051042858021a54926eb597d6ee3012393ce9c181814115df4c60b9a808", size = 6378149 }, - { url = "https://files.pythonhosted.org/packages/69/42/836b6f3cd7f3e5fa10a1f1a5420447c17966044c8fbf589cc0452d5502db/pillow-12.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e6b2a0c538fc200b38ff9eb6628228b77908c319a005815f2dde585a0664b60", size = 7082626 }, - { url = "https://files.pythonhosted.org/packages/c2/88/549194b5d6f1f494b485e493edc6693c0a16f4ada488e5bd974ed1f42fad/pillow-12.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:9a8a34cc89c67a65ea7437ce257cea81a9dad65b29805f3ecee8c8fe8ff25ffe", size = 2463531 }, - { url = "https://files.pythonhosted.org/packages/58/be/7482c8a5ebebbc6470b3eb791812fff7d5e0216c2be3827b30b8bb6603ed/pillow-12.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d192a155bbcec180f8564f693e6fd9bccff5a7af9b32e2e4bf8c9c69dbad6b5", size = 5308279 }, - { url = "https://files.pythonhosted.org/packages/d8/95/0a351b9289c2b5cbde0bacd4a83ebc44023e835490a727b2a3bd60ddc0f4/pillow-12.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3f40b3c5a968281fd507d519e444c35f0ff171237f4fdde090dd60699458421", size = 4695490 }, - { url = "https://files.pythonhosted.org/packages/de/af/4e8e6869cbed569d43c416fad3dc4ecb944cb5d9492defaed89ddd6fe871/pillow-12.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:03e7e372d5240cc23e9f07deca4d775c0817bffc641b01e9c3af208dbd300987", size = 6284462 }, - { url = "https://files.pythonhosted.org/packages/e9/9e/c05e19657fd57841e476be1ab46c4d501bffbadbafdc31a6d665f8b737b6/pillow-12.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b86024e52a1b269467a802258c25521e6d742349d760728092e1bc2d135b4d76", size = 8094744 }, - { url = "https://files.pythonhosted.org/packages/2b/54/1789c455ed10176066b6e7e6da1b01e50e36f94ba584dc68d9eebfe9156d/pillow-12.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7371b48c4fa448d20d2714c9a1f775a81155050d383333e0a6c15b1123dda005", size = 6398371 }, - { url = "https://files.pythonhosted.org/packages/43/e3/fdc657359e919462369869f1c9f0e973f353f9a9ee295a39b1fea8ee1a77/pillow-12.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62f5409336adb0663b7caa0da5c7d9e7bdbaae9ce761d34669420c2a801b2780", size = 7087215 }, - { url = "https://files.pythonhosted.org/packages/8b/f8/2f6825e441d5b1959d2ca5adec984210f1ec086435b0ed5f52c19b3b8a6e/pillow-12.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:01afa7cf67f74f09523699b4e88c73fb55c13346d212a59a2db1f86b0a63e8c5", size = 6509783 }, - { url = "https://files.pythonhosted.org/packages/67/f9/029a27095ad20f854f9dba026b3ea6428548316e057e6fc3545409e86651/pillow-12.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc3d34d4a8fbec3e88a79b92e5465e0f9b842b628675850d860b8bd300b159f5", size = 7212112 }, - { url = "https://files.pythonhosted.org/packages/be/42/025cfe05d1be22dbfdb4f264fe9de1ccda83f66e4fc3aac94748e784af04/pillow-12.2.0-cp312-cp312-win32.whl", hash = "sha256:58f62cc0f00fd29e64b29f4fd923ffdb3859c9f9e6105bfc37ba1d08994e8940", size = 6378489 }, - { url = "https://files.pythonhosted.org/packages/5d/7b/25a221d2c761c6a8ae21bfa3874988ff2583e19cf8a27bf2fee358df7942/pillow-12.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f84204dee22a783350679a0333981df803dac21a0190d706a50475e361c93f5", size = 7084129 }, - { url = "https://files.pythonhosted.org/packages/10/e1/542a474affab20fd4a0f1836cb234e8493519da6b76899e30bcc5d990b8b/pillow-12.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:af73337013e0b3b46f175e79492d96845b16126ddf79c438d7ea7ff27783a414", size = 2463612 }, - { url = "https://files.pythonhosted.org/packages/4a/01/53d10cf0dbad820a8db274d259a37ba50b88b24768ddccec07355382d5ad/pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:8297651f5b5679c19968abefd6bb84d95fe30ef712eb1b2d9b2d31ca61267f4c", size = 4100837 }, - { url = "https://files.pythonhosted.org/packages/0f/98/f3a6657ecb698c937f6c76ee564882945f29b79bad496abcba0e84659ec5/pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:50d8520da2a6ce0af445fa6d648c4273c3eeefbc32d7ce049f22e8b5c3daecc2", size = 4176528 }, - { url = "https://files.pythonhosted.org/packages/69/bc/8986948f05e3ea490b8442ea1c1d4d990b24a7e43d8a51b2c7d8b1dced36/pillow-12.2.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:766cef22385fa1091258ad7e6216792b156dc16d8d3fa607e7545b2b72061f1c", size = 3640401 }, - { url = "https://files.pythonhosted.org/packages/34/46/6c717baadcd62bc8ed51d238d521ab651eaa74838291bda1f86fe1f864c9/pillow-12.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5d2fd0fa6b5d9d1de415060363433f28da8b1526c1c129020435e186794b3795", size = 5308094 }, - { url = "https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56b25336f502b6ed02e889f4ece894a72612fe885889a6e8c4c80239ff6e5f5f", size = 4695402 }, - { url = "https://files.pythonhosted.org/packages/73/dd/42107efcb777b16fa0393317eac58f5b5cf30e8392e266e76e51cff28c3d/pillow-12.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f1c943e96e85df3d3478f7b691f229887e143f81fedab9b20205349ab04d73ed", size = 6280005 }, - { url = "https://files.pythonhosted.org/packages/a8/68/b93e09e5e8549019e61acf49f65b1a8530765a7f812c77a7461bca7e4494/pillow-12.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:03f6fab9219220f041c74aeaa2939ff0062bd5c364ba9ce037197f4c6d498cd9", size = 8090669 }, - { url = "https://files.pythonhosted.org/packages/4b/6e/3ccb54ce8ec4ddd1accd2d89004308b7b0b21c4ac3d20fa70af4760a4330/pillow-12.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5cdfebd752ec52bf5bb4e35d9c64b40826bc5b40a13df7c3cda20a2c03a0f5ed", size = 6395194 }, - { url = "https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3", size = 7082423 }, - { url = "https://files.pythonhosted.org/packages/78/5f/e9f86ab0146464e8c133fe85df987ed9e77e08b29d8d35f9f9f4d6f917ba/pillow-12.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:00a2865911330191c0b818c59103b58a5e697cae67042366970a6b6f1b20b7f9", size = 6505667 }, - { url = "https://files.pythonhosted.org/packages/ed/1e/409007f56a2fdce61584fd3acbc2bbc259857d555196cedcadc68c015c82/pillow-12.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e1757442ed87f4912397c6d35a0db6a7b52592156014706f17658ff58bbf795", size = 7208580 }, - { url = "https://files.pythonhosted.org/packages/23/c4/7349421080b12fb35414607b8871e9534546c128a11965fd4a7002ccfbee/pillow-12.2.0-cp313-cp313-win32.whl", hash = "sha256:144748b3af2d1b358d41286056d0003f47cb339b8c43a9ea42f5fea4d8c66b6e", size = 6375896 }, - { url = "https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:390ede346628ccc626e5730107cde16c42d3836b89662a115a921f28440e6a3b", size = 7081266 }, - { url = "https://files.pythonhosted.org/packages/c3/25/f968f618a062574294592f668218f8af564830ccebdd1fa6200f598e65c5/pillow-12.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:8023abc91fba39036dbce14a7d6535632f99c0b857807cbbbf21ecc9f4717f06", size = 2463508 }, - { url = "https://files.pythonhosted.org/packages/4d/a4/b342930964e3cb4dce5038ae34b0eab4653334995336cd486c5a8c25a00c/pillow-12.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:042db20a421b9bafecc4b84a8b6e444686bd9d836c7fd24542db3e7df7baad9b", size = 5309927 }, - { url = "https://files.pythonhosted.org/packages/9f/de/23198e0a65a9cf06123f5435a5d95cea62a635697f8f03d134d3f3a96151/pillow-12.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:dd025009355c926a84a612fecf58bb315a3f6814b17ead51a8e48d3823d9087f", size = 4698624 }, - { url = "https://files.pythonhosted.org/packages/01/a6/1265e977f17d93ea37aa28aa81bad4fa597933879fac2520d24e021c8da3/pillow-12.2.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:88ddbc66737e277852913bd1e07c150cc7bb124539f94c4e2df5344494e0a612", size = 6321252 }, - { url = "https://files.pythonhosted.org/packages/3c/83/5982eb4a285967baa70340320be9f88e57665a387e3a53a7f0db8231a0cd/pillow-12.2.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d362d1878f00c142b7e1a16e6e5e780f02be8195123f164edf7eddd911eefe7c", size = 8126550 }, - { url = "https://files.pythonhosted.org/packages/4e/48/6ffc514adce69f6050d0753b1a18fd920fce8cac87620d5a31231b04bfc5/pillow-12.2.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c727a6d53cb0018aadd8018c2b938376af27914a68a492f59dfcaca650d5eea", size = 6433114 }, - { url = "https://files.pythonhosted.org/packages/36/a3/f9a77144231fb8d40ee27107b4463e205fa4677e2ca2548e14da5cf18dce/pillow-12.2.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:efd8c21c98c5cc60653bcb311bef2ce0401642b7ce9d09e03a7da87c878289d4", size = 7115667 }, - { url = "https://files.pythonhosted.org/packages/c1/fc/ac4ee3041e7d5a565e1c4fd72a113f03b6394cc72ab7089d27608f8aaccb/pillow-12.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f08483a632889536b8139663db60f6724bfcb443c96f1b18855860d7d5c0fd4", size = 6538966 }, - { url = "https://files.pythonhosted.org/packages/c0/a8/27fb307055087f3668f6d0a8ccb636e7431d56ed0750e07a60547b1e083e/pillow-12.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dac8d77255a37e81a2efcbd1fc05f1c15ee82200e6c240d7e127e25e365c39ea", size = 7238241 }, - { url = "https://files.pythonhosted.org/packages/ad/4b/926ab182c07fccae9fcb120043464e1ff1564775ec8864f21a0ebce6ac25/pillow-12.2.0-cp313-cp313t-win32.whl", hash = "sha256:ee3120ae9dff32f121610bb08e4313be87e03efeadfc6c0d18f89127e24d0c24", size = 6379592 }, - { url = "https://files.pythonhosted.org/packages/c2/c4/f9e476451a098181b30050cc4c9a3556b64c02cf6497ea421ac047e89e4b/pillow-12.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:325ca0528c6788d2a6c3d40e3568639398137346c3d6e66bb61db96b96511c98", size = 7085542 }, - { url = "https://files.pythonhosted.org/packages/00/a4/285f12aeacbe2d6dc36c407dfbbe9e96d4a80b0fb710a337f6d2ad978c75/pillow-12.2.0-cp313-cp313t-win_arm64.whl", hash = "sha256:2e5a76d03a6c6dcef67edabda7a52494afa4035021a79c8558e14af25313d453", size = 2465765 }, - { url = "https://files.pythonhosted.org/packages/bf/98/4595daa2365416a86cb0d495248a393dfc84e96d62ad080c8546256cb9c0/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:3adc9215e8be0448ed6e814966ecf3d9952f0ea40eb14e89a102b87f450660d8", size = 4100848 }, - { url = "https://files.pythonhosted.org/packages/0b/79/40184d464cf89f6663e18dfcf7ca21aae2491fff1a16127681bf1fa9b8cf/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:6a9adfc6d24b10f89588096364cc726174118c62130c817c2837c60cf08a392b", size = 4176515 }, - { url = "https://files.pythonhosted.org/packages/b0/63/703f86fd4c422a9cf722833670f4f71418fb116b2853ff7da722ea43f184/pillow-12.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:6a6e67ea2e6feda684ed370f9a1c52e7a243631c025ba42149a2cc5934dec295", size = 3640159 }, - { url = "https://files.pythonhosted.org/packages/71/e0/fb22f797187d0be2270f83500aab851536101b254bfa1eae10795709d283/pillow-12.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2bb4a8d594eacdfc59d9e5ad972aa8afdd48d584ffd5f13a937a664c3e7db0ed", size = 5312185 }, - { url = "https://files.pythonhosted.org/packages/ba/8c/1a9e46228571de18f8e28f16fabdfc20212a5d019f3e3303452b3f0a580d/pillow-12.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:80b2da48193b2f33ed0c32c38140f9d3186583ce7d516526d462645fd98660ae", size = 4695386 }, - { url = "https://files.pythonhosted.org/packages/70/62/98f6b7f0c88b9addd0e87c217ded307b36be024d4ff8869a812b241d1345/pillow-12.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22db17c68434de69d8ecfc2fe821569195c0c373b25cccb9cbdacf2c6e53c601", size = 6280384 }, - { url = "https://files.pythonhosted.org/packages/5e/03/688747d2e91cfbe0e64f316cd2e8005698f76ada3130d0194664174fa5de/pillow-12.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7b14cc0106cd9aecda615dd6903840a058b4700fcb817687d0ee4fc8b6e389be", size = 8091599 }, - { url = "https://files.pythonhosted.org/packages/f6/35/577e22b936fcdd66537329b33af0b4ccfefaeabd8aec04b266528cddb33c/pillow-12.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cbeb542b2ebc6fcdacabf8aca8c1a97c9b3ad3927d46b8723f9d4f033288a0f", size = 6396021 }, - { url = "https://files.pythonhosted.org/packages/11/8d/d2532ad2a603ca2b93ad9f5135732124e57811d0168155852f37fbce2458/pillow-12.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4bfd07bc812fbd20395212969e41931001fd59eb55a60658b0e5710872e95286", size = 7083360 }, - { url = "https://files.pythonhosted.org/packages/5e/26/d325f9f56c7e039034897e7380e9cc202b1e368bfd04d4cbe6a441f02885/pillow-12.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9aba9a17b623ef750a4d11b742cbafffeb48a869821252b30ee21b5e91392c50", size = 6507628 }, - { url = "https://files.pythonhosted.org/packages/5f/f7/769d5632ffb0988f1c5e7660b3e731e30f7f8ec4318e94d0a5d674eb65a4/pillow-12.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:deede7c263feb25dba4e82ea23058a235dcc2fe1f6021025dc71f2b618e26104", size = 7209321 }, - { url = "https://files.pythonhosted.org/packages/6a/7a/c253e3c645cd47f1aceea6a8bacdba9991bf45bb7dfe927f7c893e89c93c/pillow-12.2.0-cp314-cp314-win32.whl", hash = "sha256:632ff19b2778e43162304d50da0181ce24ac5bb8180122cbe1bf4673428328c7", size = 6479723 }, - { url = "https://files.pythonhosted.org/packages/cd/8b/601e6566b957ca50e28725cb6c355c59c2c8609751efbecd980db44e0349/pillow-12.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:4e6c62e9d237e9b65fac06857d511e90d8461a32adcc1b9065ea0c0fa3a28150", size = 7217400 }, - { url = "https://files.pythonhosted.org/packages/d6/94/220e46c73065c3e2951bb91c11a1fb636c8c9ad427ac3ce7d7f3359b9b2f/pillow-12.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:b1c1fbd8a5a1af3412a0810d060a78b5136ec0836c8a4ef9aa11807f2a22f4e1", size = 2554835 }, - { url = "https://files.pythonhosted.org/packages/b6/ab/1b426a3974cb0e7da5c29ccff4807871d48110933a57207b5a676cccc155/pillow-12.2.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:57850958fe9c751670e49b2cecf6294acc99e562531f4bd317fa5ddee2068463", size = 5314225 }, - { url = "https://files.pythonhosted.org/packages/19/1e/dce46f371be2438eecfee2a1960ee2a243bbe5e961890146d2dee1ff0f12/pillow-12.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d5d38f1411c0ed9f97bcb49b7bd59b6b7c314e0e27420e34d99d844b9ce3b6f3", size = 4698541 }, - { url = "https://files.pythonhosted.org/packages/55/c3/7fbecf70adb3a0c33b77a300dc52e424dc22ad8cdc06557a2e49523b703d/pillow-12.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5c0a9f29ca8e79f09de89293f82fc9b0270bb4af1d58bc98f540cc4aedf03166", size = 6322251 }, - { url = "https://files.pythonhosted.org/packages/1c/3c/7fbc17cfb7e4fe0ef1642e0abc17fc6c94c9f7a16be41498e12e2ba60408/pillow-12.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1610dd6c61621ae1cf811bef44d77e149ce3f7b95afe66a4512f8c59f25d9ebe", size = 8127807 }, - { url = "https://files.pythonhosted.org/packages/ff/c3/a8ae14d6defd2e448493ff512fae903b1e9bd40b72efb6ec55ce0048c8ce/pillow-12.2.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a34329707af4f73cf1782a36cd2289c0368880654a2c11f027bcee9052d35dd", size = 6433935 }, - { url = "https://files.pythonhosted.org/packages/6e/32/2880fb3a074847ac159d8f902cb43278a61e85f681661e7419e6596803ed/pillow-12.2.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e9c4f5b3c546fa3458a29ab22646c1c6c787ea8f5ef51300e5a60300736905e", size = 7116720 }, - { url = "https://files.pythonhosted.org/packages/46/87/495cc9c30e0129501643f24d320076f4cc54f718341df18cc70ec94c44e1/pillow-12.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fb043ee2f06b41473269765c2feae53fc2e2fbf96e5e22ca94fb5ad677856f06", size = 6540498 }, - { url = "https://files.pythonhosted.org/packages/18/53/773f5edca692009d883a72211b60fdaf8871cbef075eaa9d577f0a2f989e/pillow-12.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f278f034eb75b4e8a13a54a876cc4a5ab39173d2cdd93a638e1b467fc545ac43", size = 7239413 }, - { url = "https://files.pythonhosted.org/packages/c9/e4/4b64a97d71b2a83158134abbb2f5bd3f8a2ea691361282f010998f339ec7/pillow-12.2.0-cp314-cp314t-win32.whl", hash = "sha256:6bb77b2dcb06b20f9f4b4a8454caa581cd4dd0643a08bacf821216a16d9c8354", size = 6482084 }, - { url = "https://files.pythonhosted.org/packages/ba/13/306d275efd3a3453f72114b7431c877d10b1154014c1ebbedd067770d629/pillow-12.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6562ace0d3fb5f20ed7290f1f929cae41b25ae29528f2af1722966a0a02e2aa1", size = 7225152 }, - { url = "https://files.pythonhosted.org/packages/ff/6e/cf826fae916b8658848d7b9f38d88da6396895c676e8086fc0988073aaf8/pillow-12.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:aa88ccfe4e32d362816319ed727a004423aab09c5cea43c01a4b435643fa34eb", size = 2556579 }, - { url = "https://files.pythonhosted.org/packages/4e/b7/2437044fb910f499610356d1352e3423753c98e34f915252aafecc64889f/pillow-12.2.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0538bd5e05efec03ae613fd89c4ce0368ecd2ba239cc25b9f9be7ed426b0af1f", size = 5273969 }, - { url = "https://files.pythonhosted.org/packages/f6/f4/8316e31de11b780f4ac08ef3654a75555e624a98db1056ecb2122d008d5a/pillow-12.2.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:394167b21da716608eac917c60aa9b969421b5dcbbe02ae7f013e7b85811c69d", size = 4659674 }, - { url = "https://files.pythonhosted.org/packages/d4/37/664fca7201f8bb2aa1d20e2c3d5564a62e6ae5111741966c8319ca802361/pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5d04bfa02cc2d23b497d1e90a0f927070043f6cbf303e738300532379a4b4e0f", size = 5288479 }, - { url = "https://files.pythonhosted.org/packages/49/62/5b0ed78fce87346be7a5cfcfaaad91f6a1f98c26f86bdbafa2066c647ef6/pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0c838a5125cee37e68edec915651521191cef1e6aa336b855f495766e77a366e", size = 7032230 }, - { url = "https://files.pythonhosted.org/packages/c3/28/ec0fc38107fc32536908034e990c47914c57cd7c5a3ece4d8d8f7ffd7e27/pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a6c9fa44005fa37a91ebfc95d081e8079757d2e904b27103f4f5fa6f0bf78c0", size = 5355404 }, - { url = "https://files.pythonhosted.org/packages/5e/8b/51b0eddcfa2180d60e41f06bd6d0a62202b20b59c68f5a132e615b75aecf/pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:25373b66e0dd5905ed63fa3cae13c82fbddf3079f2c8bf15c6fb6a35586324c1", size = 6002215 }, - { url = "https://files.pythonhosted.org/packages/bc/60/5382c03e1970de634027cee8e1b7d39776b778b81812aaf45b694dfe9e28/pillow-12.2.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:bfa9c230d2fe991bed5318a5f119bd6780cda2915cca595393649fc118ab895e", size = 7080946 }, -] - -[[package]] -name = "platformdirs" -version = "4.9.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/19/56/8d4c30c8a1d07013911a8fdbd8f89440ef9f08d07a1b50ab8ca8be5a20f9/platformdirs-4.9.4.tar.gz", hash = "sha256:1ec356301b7dc906d83f371c8f487070e99d3ccf9e501686456394622a01a934", size = 28737 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/63/d7/97f7e3a6abb67d8080dd406fd4df842c2be0efaf712d1c899c32a075027c/platformdirs-4.9.4-py3-none-any.whl", hash = "sha256:68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868", size = 21216 }, -] - -[[package]] -name = "py-key-value-aio" -version = "0.4.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "beartype" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/04/3c/0397c072a38d4bc580994b42e0c90c5f44f679303489e4376289534735e5/py_key_value_aio-0.4.4.tar.gz", hash = "sha256:e3012e6243ed7cc09bb05457bd4d03b1ba5c2b1ca8700096b3927db79ffbbe55", size = 92300 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/32/69/f1b537ee70b7def42d63124a539ed3026a11a3ffc3086947a1ca6e861868/py_key_value_aio-0.4.4-py3-none-any.whl", hash = "sha256:18e17564ecae61b987f909fc2cd41ee2012c84b4b1dcb8c055cf8b4bc1bf3f5d", size = 152291 }, -] - -[package.optional-dependencies] -filetree = [ - { name = "aiofile" }, - { name = "anyio" }, -] -keyring = [ - { name = "keyring" }, -] -memory = [ - { name = "cachetools" }, -] - -[[package]] -name = "pycparser" -version = "3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172 }, -] - -[[package]] -name = "pydantic" -version = "2.12.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "annotated-types" }, - { name = "pydantic-core" }, - { name = "typing-extensions" }, - { name = "typing-inspection" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580 }, -] - -[package.optional-dependencies] -email = [ - { name = "email-validator" }, -] - -[[package]] -name = "pydantic-core" -version = "2.41.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/90/32c9941e728d564b411d574d8ee0cf09b12ec978cb22b294995bae5549a5/pydantic_core-2.41.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146", size = 2107298 }, - { url = "https://files.pythonhosted.org/packages/fb/a8/61c96a77fe28993d9a6fb0f4127e05430a267b235a124545d79fea46dd65/pydantic_core-2.41.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2", size = 1901475 }, - { url = "https://files.pythonhosted.org/packages/5d/b6/338abf60225acc18cdc08b4faef592d0310923d19a87fba1faf05af5346e/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97", size = 1918815 }, - { url = "https://files.pythonhosted.org/packages/d1/1c/2ed0433e682983d8e8cba9c8d8ef274d4791ec6a6f24c58935b90e780e0a/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9", size = 2065567 }, - { url = "https://files.pythonhosted.org/packages/b3/24/cf84974ee7d6eae06b9e63289b7b8f6549d416b5c199ca2d7ce13bbcf619/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52", size = 2230442 }, - { url = "https://files.pythonhosted.org/packages/fd/21/4e287865504b3edc0136c89c9c09431be326168b1eb7841911cbc877a995/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941", size = 2350956 }, - { url = "https://files.pythonhosted.org/packages/a8/76/7727ef2ffa4b62fcab916686a68a0426b9b790139720e1934e8ba797e238/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a", size = 2068253 }, - { url = "https://files.pythonhosted.org/packages/d5/8c/a4abfc79604bcb4c748e18975c44f94f756f08fb04218d5cb87eb0d3a63e/pydantic_core-2.41.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c", size = 2177050 }, - { url = "https://files.pythonhosted.org/packages/67/b1/de2e9a9a79b480f9cb0b6e8b6ba4c50b18d4e89852426364c66aa82bb7b3/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2", size = 2147178 }, - { url = "https://files.pythonhosted.org/packages/16/c1/dfb33f837a47b20417500efaa0378adc6635b3c79e8369ff7a03c494b4ac/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556", size = 2341833 }, - { url = "https://files.pythonhosted.org/packages/47/36/00f398642a0f4b815a9a558c4f1dca1b4020a7d49562807d7bc9ff279a6c/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49", size = 2321156 }, - { url = "https://files.pythonhosted.org/packages/7e/70/cad3acd89fde2010807354d978725ae111ddf6d0ea46d1ea1775b5c1bd0c/pydantic_core-2.41.5-cp310-cp310-win32.whl", hash = "sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba", size = 1989378 }, - { url = "https://files.pythonhosted.org/packages/76/92/d338652464c6c367e5608e4488201702cd1cbb0f33f7b6a85a60fe5f3720/pydantic_core-2.41.5-cp310-cp310-win_amd64.whl", hash = "sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9", size = 2013622 }, - { url = "https://files.pythonhosted.org/packages/e8/72/74a989dd9f2084b3d9530b0915fdda64ac48831c30dbf7c72a41a5232db8/pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6", size = 2105873 }, - { url = "https://files.pythonhosted.org/packages/12/44/37e403fd9455708b3b942949e1d7febc02167662bf1a7da5b78ee1ea2842/pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b", size = 1899826 }, - { url = "https://files.pythonhosted.org/packages/33/7f/1d5cab3ccf44c1935a359d51a8a2a9e1a654b744b5e7f80d41b88d501eec/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a", size = 1917869 }, - { url = "https://files.pythonhosted.org/packages/6e/6a/30d94a9674a7fe4f4744052ed6c5e083424510be1e93da5bc47569d11810/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8", size = 2063890 }, - { url = "https://files.pythonhosted.org/packages/50/be/76e5d46203fcb2750e542f32e6c371ffa9b8ad17364cf94bb0818dbfb50c/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e", size = 2229740 }, - { url = "https://files.pythonhosted.org/packages/d3/ee/fed784df0144793489f87db310a6bbf8118d7b630ed07aa180d6067e653a/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1", size = 2350021 }, - { url = "https://files.pythonhosted.org/packages/c8/be/8fed28dd0a180dca19e72c233cbf58efa36df055e5b9d90d64fd1740b828/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b", size = 2066378 }, - { url = "https://files.pythonhosted.org/packages/b0/3b/698cf8ae1d536a010e05121b4958b1257f0b5522085e335360e53a6b1c8b/pydantic_core-2.41.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b", size = 2175761 }, - { url = "https://files.pythonhosted.org/packages/b8/ba/15d537423939553116dea94ce02f9c31be0fa9d0b806d427e0308ec17145/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284", size = 2146303 }, - { url = "https://files.pythonhosted.org/packages/58/7f/0de669bf37d206723795f9c90c82966726a2ab06c336deba4735b55af431/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594", size = 2340355 }, - { url = "https://files.pythonhosted.org/packages/e5/de/e7482c435b83d7e3c3ee5ee4451f6e8973cff0eb6007d2872ce6383f6398/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e", size = 2319875 }, - { url = "https://files.pythonhosted.org/packages/fe/e6/8c9e81bb6dd7560e33b9053351c29f30c8194b72f2d6932888581f503482/pydantic_core-2.41.5-cp311-cp311-win32.whl", hash = "sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b", size = 1987549 }, - { url = "https://files.pythonhosted.org/packages/11/66/f14d1d978ea94d1bc21fc98fcf570f9542fe55bfcc40269d4e1a21c19bf7/pydantic_core-2.41.5-cp311-cp311-win_amd64.whl", hash = "sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe", size = 2011305 }, - { url = "https://files.pythonhosted.org/packages/56/d8/0e271434e8efd03186c5386671328154ee349ff0354d83c74f5caaf096ed/pydantic_core-2.41.5-cp311-cp311-win_arm64.whl", hash = "sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f", size = 1972902 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/49/3b/774f2b5cd4192d5ab75870ce4381fd89cf218af999515baf07e7206753f0/pydantic_core-2.41.5-cp312-cp312-win32.whl", hash = "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d", size = 1985908 }, - { url = "https://files.pythonhosted.org/packages/86/45/00173a033c801cacf67c190fef088789394feaf88a98a7035b0e40d53dc9/pydantic_core-2.41.5-cp312-cp312-win_amd64.whl", hash = "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815", size = 2020145 }, - { url = "https://files.pythonhosted.org/packages/f9/22/91fbc821fa6d261b376a3f73809f907cec5ca6025642c463d3488aad22fb/pydantic_core-2.41.5-cp312-cp312-win_arm64.whl", hash = "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3", size = 1976179 }, - { url = "https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403 }, - { url = "https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206 }, - { url = "https://files.pythonhosted.org/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307 }, - { url = "https://files.pythonhosted.org/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258 }, - { url = "https://files.pythonhosted.org/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917 }, - { url = "https://files.pythonhosted.org/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186 }, - { url = "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164 }, - { url = "https://files.pythonhosted.org/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146 }, - { url = "https://files.pythonhosted.org/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788 }, - { url = "https://files.pythonhosted.org/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133 }, - { url = "https://files.pythonhosted.org/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852 }, - { url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679 }, - { url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766 }, - { url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005 }, - { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622 }, - { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725 }, - { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040 }, - { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691 }, - { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897 }, - { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302 }, - { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877 }, - { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680 }, - { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960 }, - { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102 }, - { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039 }, - { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126 }, - { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489 }, - { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288 }, - { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255 }, - { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760 }, - { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092 }, - { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385 }, - { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832 }, - { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585 }, - { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078 }, - { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914 }, - { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560 }, - { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244 }, - { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955 }, - { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906 }, - { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607 }, - { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769 }, - { url = "https://files.pythonhosted.org/packages/e6/b0/1a2aa41e3b5a4ba11420aba2d091b2d17959c8d1519ece3627c371951e73/pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8", size = 2103351 }, - { url = "https://files.pythonhosted.org/packages/a4/ee/31b1f0020baaf6d091c87900ae05c6aeae101fa4e188e1613c80e4f1ea31/pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a", size = 1925363 }, - { url = "https://files.pythonhosted.org/packages/e1/89/ab8e86208467e467a80deaca4e434adac37b10a9d134cd2f99b28a01e483/pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b", size = 2135615 }, - { url = "https://files.pythonhosted.org/packages/99/0a/99a53d06dd0348b2008f2f30884b34719c323f16c3be4e6cc1203b74a91d/pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2", size = 2175369 }, - { url = "https://files.pythonhosted.org/packages/6d/94/30ca3b73c6d485b9bb0bc66e611cff4a7138ff9736b7e66bcf0852151636/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093", size = 2144218 }, - { url = "https://files.pythonhosted.org/packages/87/57/31b4f8e12680b739a91f472b5671294236b82586889ef764b5fbc6669238/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a", size = 2329951 }, - { url = "https://files.pythonhosted.org/packages/7d/73/3c2c8edef77b8f7310e6fb012dbc4b8551386ed575b9eb6fb2506e28a7eb/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963", size = 2318428 }, - { url = "https://files.pythonhosted.org/packages/2f/02/8559b1f26ee0d502c74f9cca5c0d2fd97e967e083e006bbbb4e97f3a043a/pydantic_core-2.41.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a", size = 2147009 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/83/d9/8412d7f06f616bbc053d30cb4e5f76786af3221462ad5eee1f202021eb4e/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1", size = 2174762 }, - { url = "https://files.pythonhosted.org/packages/55/4c/162d906b8e3ba3a99354e20faa1b49a85206c47de97a639510a0e673f5da/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84", size = 2143141 }, - { url = "https://files.pythonhosted.org/packages/1f/f2/f11dd73284122713f5f89fc940f370d035fa8e1e078d446b3313955157fe/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770", size = 2330317 }, - { url = "https://files.pythonhosted.org/packages/88/9d/b06ca6acfe4abb296110fb1273a4d848a0bfb2ff65f3ee92127b3244e16b/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f", size = 2316992 }, - { url = "https://files.pythonhosted.org/packages/36/c7/cfc8e811f061c841d7990b0201912c3556bfeb99cdcb7ed24adc8d6f8704/pydantic_core-2.41.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51", size = 2145302 }, -] - -[[package]] -name = "pydantic-settings" -version = "2.13.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pydantic" }, - { name = "python-dotenv" }, - { name = "typing-inspection" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/52/6d/fffca34caecc4a3f97bda81b2098da5e8ab7efc9a66e819074a11955d87e/pydantic_settings-2.13.1.tar.gz", hash = "sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025", size = 223826 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/00/4b/ccc026168948fec4f7555b9164c724cf4125eac006e176541483d2c959be/pydantic_settings-2.13.1-py3-none-any.whl", hash = "sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237", size = 58929 }, -] - -[[package]] -name = "pydub" -version = "0.25.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fe/9a/e6bca0eed82db26562c73b5076539a4a08d3cffd19c3cc5913a3e61145fd/pydub-0.25.1.tar.gz", hash = "sha256:980a33ce9949cab2a569606b65674d748ecbca4f0796887fd6f46173a7b0d30f", size = 38326 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/53/d78dc063216e62fc55f6b2eebb447f6a4b0a59f55c8406376f76bf959b08/pydub-0.25.1-py2.py3-none-any.whl", hash = "sha256:65617e33033874b59d87db603aa1ed450633288aefead953b30bded59cb599a6", size = 32327 }, -] - -[[package]] -name = "pygments" -version = "2.20.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151 }, -] - -[[package]] -name = "pyjwt" -version = "2.12.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c2/27/a3b6e5bf6ff856d2509292e95c8f57f0df7017cf5394921fc4e4ef40308a/pyjwt-2.12.1.tar.gz", hash = "sha256:c74a7a2adf861c04d002db713dd85f84beb242228e671280bf709d765b03672b", size = 102564 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/7a/8dd906bd22e79e47397a61742927f6747fe93242ef86645ee9092e610244/pyjwt-2.12.1-py3-none-any.whl", hash = "sha256:28ca37c070cad8ba8cd9790cd940535d40274d22f80ab87f3ac6a713e6e8454c", size = 29726 }, -] - -[package.optional-dependencies] -crypto = [ - { name = "cryptography" }, -] - -[[package]] -name = "pyperclip" -version = "1.11.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/52/d87eba7cb129b81563019d1679026e7a112ef76855d6159d24754dbd2a51/pyperclip-1.11.0.tar.gz", hash = "sha256:244035963e4428530d9e3a6101a1ef97209c6825edab1567beac148ccc1db1b6", size = 12185 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/df/80/fc9d01d5ed37ba4c42ca2b55b4339ae6e200b456be3a1aaddf4a9fa99b8c/pyperclip-1.11.0-py3-none-any.whl", hash = "sha256:299403e9ff44581cb9ba2ffeed69c7aa96a008622ad0c46cb575ca75b5b84273", size = 11063 }, -] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "six" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, -] - -[[package]] -name = "python-dotenv" -version = "1.2.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/ed/0301aeeac3e5353ef3d94b6ec08bbcabd04a72018415dcb29e588514bba8/python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3", size = 50135 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101 }, -] - -[[package]] -name = "python-multipart" -version = "0.0.22" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/01/979e98d542a70714b0cb2b6728ed0b7c46792b695e3eaec3e20711271ca3/python_multipart-0.0.22.tar.gz", hash = "sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58", size = 37612 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1b/d0/397f9626e711ff749a95d96b7af99b9c566a9bb5129b8e4c10fc4d100304/python_multipart-0.0.22-py3-none-any.whl", hash = "sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155", size = 24579 }, -] - -[[package]] -name = "pytz" -version = "2026.1.post1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/56/db/b8721d71d945e6a8ac63c0fc900b2067181dbb50805958d4d4661cf7d277/pytz-2026.1.post1.tar.gz", hash = "sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1", size = 321088 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl", hash = "sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a", size = 510489 }, -] - -[[package]] -name = "pywin32" -version = "311" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/40/44efbb0dfbd33aca6a6483191dae0716070ed99e2ecb0c53683f400a0b4f/pywin32-311-cp310-cp310-win32.whl", hash = "sha256:d03ff496d2a0cd4a5893504789d4a15399133fe82517455e78bad62efbb7f0a3", size = 8760432 }, - { url = "https://files.pythonhosted.org/packages/5e/bf/360243b1e953bd254a82f12653974be395ba880e7ec23e3731d9f73921cc/pywin32-311-cp310-cp310-win_amd64.whl", hash = "sha256:797c2772017851984b97180b0bebe4b620bb86328e8a884bb626156295a63b3b", size = 9590103 }, - { url = "https://files.pythonhosted.org/packages/57/38/d290720e6f138086fb3d5ffe0b6caa019a791dd57866940c82e4eeaf2012/pywin32-311-cp310-cp310-win_arm64.whl", hash = "sha256:0502d1facf1fed4839a9a51ccbcc63d952cf318f78ffc00a7e78528ac27d7a2b", size = 8778557 }, - { url = "https://files.pythonhosted.org/packages/7c/af/449a6a91e5d6db51420875c54f6aff7c97a86a3b13a0b4f1a5c13b988de3/pywin32-311-cp311-cp311-win32.whl", hash = "sha256:184eb5e436dea364dcd3d2316d577d625c0351bf237c4e9a5fabbcfa5a58b151", size = 8697031 }, - { url = "https://files.pythonhosted.org/packages/51/8f/9bb81dd5bb77d22243d33c8397f09377056d5c687aa6d4042bea7fbf8364/pywin32-311-cp311-cp311-win_amd64.whl", hash = "sha256:3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503", size = 9508308 }, - { url = "https://files.pythonhosted.org/packages/44/7b/9c2ab54f74a138c491aba1b1cd0795ba61f144c711daea84a88b63dc0f6c/pywin32-311-cp311-cp311-win_arm64.whl", hash = "sha256:a733f1388e1a842abb67ffa8e7aad0e70ac519e09b0f6a784e65a136ec7cefd2", size = 8703930 }, - { url = "https://files.pythonhosted.org/packages/e7/ab/01ea1943d4eba0f850c3c61e78e8dd59757ff815ff3ccd0a84de5f541f42/pywin32-311-cp312-cp312-win32.whl", hash = "sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31", size = 8706543 }, - { url = "https://files.pythonhosted.org/packages/d1/a8/a0e8d07d4d051ec7502cd58b291ec98dcc0c3fff027caad0470b72cfcc2f/pywin32-311-cp312-cp312-win_amd64.whl", hash = "sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067", size = 9495040 }, - { url = "https://files.pythonhosted.org/packages/ba/3a/2ae996277b4b50f17d61f0603efd8253cb2d79cc7ae159468007b586396d/pywin32-311-cp312-cp312-win_arm64.whl", hash = "sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852", size = 8710102 }, - { url = "https://files.pythonhosted.org/packages/a5/be/3fd5de0979fcb3994bfee0d65ed8ca9506a8a1260651b86174f6a86f52b3/pywin32-311-cp313-cp313-win32.whl", hash = "sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d", size = 8705700 }, - { url = "https://files.pythonhosted.org/packages/e3/28/e0a1909523c6890208295a29e05c2adb2126364e289826c0a8bc7297bd5c/pywin32-311-cp313-cp313-win_amd64.whl", hash = "sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d", size = 9494700 }, - { url = "https://files.pythonhosted.org/packages/04/bf/90339ac0f55726dce7d794e6d79a18a91265bdf3aa70b6b9ca52f35e022a/pywin32-311-cp313-cp313-win_arm64.whl", hash = "sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a", size = 8709318 }, - { url = "https://files.pythonhosted.org/packages/c9/31/097f2e132c4f16d99a22bfb777e0fd88bd8e1c634304e102f313af69ace5/pywin32-311-cp314-cp314-win32.whl", hash = "sha256:b7a2c10b93f8986666d0c803ee19b5990885872a7de910fc460f9b0c2fbf92ee", size = 8840714 }, - { url = "https://files.pythonhosted.org/packages/90/4b/07c77d8ba0e01349358082713400435347df8426208171ce297da32c313d/pywin32-311-cp314-cp314-win_amd64.whl", hash = "sha256:3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87", size = 9656800 }, - { url = "https://files.pythonhosted.org/packages/c0/d2/21af5c535501a7233e734b8af901574572da66fcc254cb35d0609c9080dd/pywin32-311-cp314-cp314-win_arm64.whl", hash = "sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42", size = 8932540 }, -] - -[[package]] -name = "pywin32-ctypes" -version = "0.2.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/85/9f/01a1a99704853cb63f253eea009390c88e7131c67e66a0a02099a8c917cb/pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755", size = 29471 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/de/3d/8161f7711c017e01ac9f008dfddd9410dff3674334c233bde66e7ba65bbf/pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8", size = 30756 }, -] - -[[package]] -name = "pyyaml" -version = "6.0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", size = 184227 }, - { url = "https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", size = 174019 }, - { url = "https://files.pythonhosted.org/packages/43/f7/0e6a5ae5599c838c696adb4e6330a59f463265bfa1e116cfd1fbb0abaaae/pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", size = 740646 }, - { url = "https://files.pythonhosted.org/packages/2f/3a/61b9db1d28f00f8fd0ae760459a5c4bf1b941baf714e207b6eb0657d2578/pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", size = 840793 }, - { url = "https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", size = 770293 }, - { url = "https://files.pythonhosted.org/packages/8b/ef/abd085f06853af0cd59fa5f913d61a8eab65d7639ff2a658d18a25d6a89d/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", size = 732872 }, - { url = "https://files.pythonhosted.org/packages/1f/15/2bc9c8faf6450a8b3c9fc5448ed869c599c0a74ba2669772b1f3a0040180/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", size = 758828 }, - { url = "https://files.pythonhosted.org/packages/a3/00/531e92e88c00f4333ce359e50c19b8d1de9fe8d581b1534e35ccfbc5f393/pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", size = 142415 }, - { url = "https://files.pythonhosted.org/packages/2a/fa/926c003379b19fca39dd4634818b00dec6c62d87faf628d1394e137354d4/pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", size = 158561 }, - { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826 }, - { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577 }, - { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556 }, - { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114 }, - { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638 }, - { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543 }, - { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658 }, - { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003 }, - { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344 }, - { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669 }, - { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252 }, - { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081 }, - { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159 }, - { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626 }, - { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613 }, - { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115 }, - { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427 }, - { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090 }, - { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246 }, - { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814 }, - { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809 }, - { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454 }, - { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355 }, - { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175 }, - { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228 }, - { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194 }, - { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429 }, - { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912 }, - { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108 }, - { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641 }, - { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901 }, - { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132 }, - { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261 }, - { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272 }, - { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923 }, - { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062 }, - { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341 }, -] - -[[package]] -name = "referencing" -version = "0.37.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "attrs" }, - { name = "rpds-py" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766 }, -] - -[[package]] -name = "requests" -version = "2.33.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "charset-normalizer" }, - { name = "idna" }, - { name = "urllib3" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5f/a4/98b9c7c6428a668bf7e42ebb7c79d576a1c3c1e3ae2d47e674b468388871/requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517", size = 134120 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a", size = 64947 }, -] - -[[package]] -name = "rich" -version = "14.3.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown-it-py" }, - { name = "pygments" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b3/c6/f3b320c27991c46f43ee9d856302c70dc2d0fb2dba4842ff739d5f46b393/rich-14.3.3.tar.gz", hash = "sha256:b8daa0b9e4eef54dd8cf7c86c03713f53241884e814f4e2f5fb342fe520f639b", size = 230582 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/14/25/b208c5683343959b670dc001595f2f3737e051da617f66c31f7c4fa93abc/rich-14.3.3-py3-none-any.whl", hash = "sha256:793431c1f8619afa7d3b52b2cdec859562b950ea0d4b6b505397612db8d5362d", size = 310458 }, -] - -[[package]] -name = "rich-rst" -version = "1.3.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "docutils" }, - { name = "rich" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/bc/6d/a506aaa4a9eaa945ed8ab2b7347859f53593864289853c5d6d62b77246e0/rich_rst-1.3.2.tar.gz", hash = "sha256:a1196fdddf1e364b02ec68a05e8ff8f6914fee10fbca2e6b6735f166bb0da8d4", size = 14936 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/13/2f/b4530fbf948867702d0a3f27de4a6aab1d156f406d72852ab902c4d04de9/rich_rst-1.3.2-py3-none-any.whl", hash = "sha256:a99b4907cbe118cf9d18b0b44de272efa61f15117c61e39ebdc431baf5df722a", size = 12567 }, -] - -[[package]] -name = "rpds-py" -version = "0.30.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/af/3f2f423103f1113b36230496629986e0ef7e199d2aa8392452b484b38ced/rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84", size = 69469 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/06/0c/0c411a0ec64ccb6d104dcabe0e713e05e153a9a2c3c2bd2b32ce412166fe/rpds_py-0.30.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288", size = 370490 }, - { url = "https://files.pythonhosted.org/packages/19/6a/4ba3d0fb7297ebae71171822554abe48d7cab29c28b8f9f2c04b79988c05/rpds_py-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00", size = 359751 }, - { url = "https://files.pythonhosted.org/packages/cd/7c/e4933565ef7f7a0818985d87c15d9d273f1a649afa6a52ea35ad011195ea/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6", size = 389696 }, - { url = "https://files.pythonhosted.org/packages/5e/01/6271a2511ad0815f00f7ed4390cf2567bec1d4b1da39e2c27a41e6e3b4de/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7", size = 403136 }, - { url = "https://files.pythonhosted.org/packages/55/64/c857eb7cd7541e9b4eee9d49c196e833128a55b89a9850a9c9ac33ccf897/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324", size = 524699 }, - { url = "https://files.pythonhosted.org/packages/9c/ed/94816543404078af9ab26159c44f9e98e20fe47e2126d5d32c9d9948d10a/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df", size = 412022 }, - { url = "https://files.pythonhosted.org/packages/61/b5/707f6cf0066a6412aacc11d17920ea2e19e5b2f04081c64526eb35b5c6e7/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3", size = 390522 }, - { url = "https://files.pythonhosted.org/packages/13/4e/57a85fda37a229ff4226f8cbcf09f2a455d1ed20e802ce5b2b4a7f5ed053/rpds_py-0.30.0-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221", size = 404579 }, - { url = "https://files.pythonhosted.org/packages/f9/da/c9339293513ec680a721e0e16bf2bac3db6e5d7e922488de471308349bba/rpds_py-0.30.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7", size = 421305 }, - { url = "https://files.pythonhosted.org/packages/f9/be/522cb84751114f4ad9d822ff5a1aa3c98006341895d5f084779b99596e5c/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff", size = 572503 }, - { url = "https://files.pythonhosted.org/packages/a2/9b/de879f7e7ceddc973ea6e4629e9b380213a6938a249e94b0cdbcc325bb66/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7", size = 598322 }, - { url = "https://files.pythonhosted.org/packages/48/ac/f01fc22efec3f37d8a914fc1b2fb9bcafd56a299edbe96406f3053edea5a/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139", size = 560792 }, - { url = "https://files.pythonhosted.org/packages/e2/da/4e2b19d0f131f35b6146425f846563d0ce036763e38913d917187307a671/rpds_py-0.30.0-cp310-cp310-win32.whl", hash = "sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464", size = 221901 }, - { url = "https://files.pythonhosted.org/packages/96/cb/156d7a5cf4f78a7cc571465d8aec7a3c447c94f6749c5123f08438bcf7bc/rpds_py-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169", size = 235823 }, - { url = "https://files.pythonhosted.org/packages/4d/6e/f964e88b3d2abee2a82c1ac8366da848fce1c6d834dc2132c3fda3970290/rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425", size = 370157 }, - { url = "https://files.pythonhosted.org/packages/94/ba/24e5ebb7c1c82e74c4e4f33b2112a5573ddc703915b13a073737b59b86e0/rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d", size = 359676 }, - { url = "https://files.pythonhosted.org/packages/84/86/04dbba1b087227747d64d80c3b74df946b986c57af0a9f0c98726d4d7a3b/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4", size = 389938 }, - { url = "https://files.pythonhosted.org/packages/42/bb/1463f0b1722b7f45431bdd468301991d1328b16cffe0b1c2918eba2c4eee/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f", size = 402932 }, - { url = "https://files.pythonhosted.org/packages/99/ee/2520700a5c1f2d76631f948b0736cdf9b0acb25abd0ca8e889b5c62ac2e3/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4", size = 525830 }, - { url = "https://files.pythonhosted.org/packages/e0/ad/bd0331f740f5705cc555a5e17fdf334671262160270962e69a2bdef3bf76/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97", size = 412033 }, - { url = "https://files.pythonhosted.org/packages/f8/1e/372195d326549bb51f0ba0f2ecb9874579906b97e08880e7a65c3bef1a99/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89", size = 390828 }, - { url = "https://files.pythonhosted.org/packages/ab/2b/d88bb33294e3e0c76bc8f351a3721212713629ffca1700fa94979cb3eae8/rpds_py-0.30.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d", size = 404683 }, - { url = "https://files.pythonhosted.org/packages/50/32/c759a8d42bcb5289c1fac697cd92f6fe01a018dd937e62ae77e0e7f15702/rpds_py-0.30.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038", size = 421583 }, - { url = "https://files.pythonhosted.org/packages/2b/81/e729761dbd55ddf5d84ec4ff1f47857f4374b0f19bdabfcf929164da3e24/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7", size = 572496 }, - { url = "https://files.pythonhosted.org/packages/14/f6/69066a924c3557c9c30baa6ec3a0aa07526305684c6f86c696b08860726c/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed", size = 598669 }, - { url = "https://files.pythonhosted.org/packages/5f/48/905896b1eb8a05630d20333d1d8ffd162394127b74ce0b0784ae04498d32/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85", size = 561011 }, - { url = "https://files.pythonhosted.org/packages/22/16/cd3027c7e279d22e5eb431dd3c0fbc677bed58797fe7581e148f3f68818b/rpds_py-0.30.0-cp311-cp311-win32.whl", hash = "sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c", size = 221406 }, - { url = "https://files.pythonhosted.org/packages/fa/5b/e7b7aa136f28462b344e652ee010d4de26ee9fd16f1bfd5811f5153ccf89/rpds_py-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825", size = 236024 }, - { url = "https://files.pythonhosted.org/packages/14/a6/364bba985e4c13658edb156640608f2c9e1d3ea3c81b27aa9d889fff0e31/rpds_py-0.30.0-cp311-cp311-win_arm64.whl", hash = "sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229", size = 229069 }, - { url = "https://files.pythonhosted.org/packages/03/e7/98a2f4ac921d82f33e03f3835f5bf3a4a40aa1bfdc57975e74a97b2b4bdd/rpds_py-0.30.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad", size = 375086 }, - { url = "https://files.pythonhosted.org/packages/4d/a1/bca7fd3d452b272e13335db8d6b0b3ecde0f90ad6f16f3328c6fb150c889/rpds_py-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05", size = 359053 }, - { url = "https://files.pythonhosted.org/packages/65/1c/ae157e83a6357eceff62ba7e52113e3ec4834a84cfe07fa4b0757a7d105f/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28", size = 390763 }, - { url = "https://files.pythonhosted.org/packages/d4/36/eb2eb8515e2ad24c0bd43c3ee9cd74c33f7ca6430755ccdb240fd3144c44/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd", size = 408951 }, - { url = "https://files.pythonhosted.org/packages/d6/65/ad8dc1784a331fabbd740ef6f71ce2198c7ed0890dab595adb9ea2d775a1/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f", size = 514622 }, - { url = "https://files.pythonhosted.org/packages/63/8e/0cfa7ae158e15e143fe03993b5bcd743a59f541f5952e1546b1ac1b5fd45/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1", size = 414492 }, - { url = "https://files.pythonhosted.org/packages/60/1b/6f8f29f3f995c7ffdde46a626ddccd7c63aefc0efae881dc13b6e5d5bb16/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23", size = 394080 }, - { url = "https://files.pythonhosted.org/packages/6d/d5/a266341051a7a3ca2f4b750a3aa4abc986378431fc2da508c5034d081b70/rpds_py-0.30.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6", size = 408680 }, - { url = "https://files.pythonhosted.org/packages/10/3b/71b725851df9ab7a7a4e33cf36d241933da66040d195a84781f49c50490c/rpds_py-0.30.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51", size = 423589 }, - { url = "https://files.pythonhosted.org/packages/00/2b/e59e58c544dc9bd8bd8384ecdb8ea91f6727f0e37a7131baeff8d6f51661/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5", size = 573289 }, - { url = "https://files.pythonhosted.org/packages/da/3e/a18e6f5b460893172a7d6a680e86d3b6bc87a54c1f0b03446a3c8c7b588f/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e", size = 599737 }, - { url = "https://files.pythonhosted.org/packages/5c/e2/714694e4b87b85a18e2c243614974413c60aa107fd815b8cbc42b873d1d7/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394", size = 563120 }, - { url = "https://files.pythonhosted.org/packages/6f/ab/d5d5e3bcedb0a77f4f613706b750e50a5a3ba1c15ccd3665ecc636c968fd/rpds_py-0.30.0-cp312-cp312-win32.whl", hash = "sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf", size = 223782 }, - { url = "https://files.pythonhosted.org/packages/39/3b/f786af9957306fdc38a74cef405b7b93180f481fb48453a114bb6465744a/rpds_py-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b", size = 240463 }, - { url = "https://files.pythonhosted.org/packages/f3/d2/b91dc748126c1559042cfe41990deb92c4ee3e2b415f6b5234969ffaf0cc/rpds_py-0.30.0-cp312-cp312-win_arm64.whl", hash = "sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e", size = 230868 }, - { url = "https://files.pythonhosted.org/packages/ed/dc/d61221eb88ff410de3c49143407f6f3147acf2538c86f2ab7ce65ae7d5f9/rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2", size = 374887 }, - { url = "https://files.pythonhosted.org/packages/fd/32/55fb50ae104061dbc564ef15cc43c013dc4a9f4527a1f4d99baddf56fe5f/rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8", size = 358904 }, - { url = "https://files.pythonhosted.org/packages/58/70/faed8186300e3b9bdd138d0273109784eea2396c68458ed580f885dfe7ad/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4", size = 389945 }, - { url = "https://files.pythonhosted.org/packages/bd/a8/073cac3ed2c6387df38f71296d002ab43496a96b92c823e76f46b8af0543/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136", size = 407783 }, - { url = "https://files.pythonhosted.org/packages/77/57/5999eb8c58671f1c11eba084115e77a8899d6e694d2a18f69f0ba471ec8b/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7", size = 515021 }, - { url = "https://files.pythonhosted.org/packages/e0/af/5ab4833eadc36c0a8ed2bc5c0de0493c04f6c06de223170bd0798ff98ced/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2", size = 414589 }, - { url = "https://files.pythonhosted.org/packages/b7/de/f7192e12b21b9e9a68a6d0f249b4af3fdcdff8418be0767a627564afa1f1/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6", size = 394025 }, - { url = "https://files.pythonhosted.org/packages/91/c4/fc70cd0249496493500e7cc2de87504f5aa6509de1e88623431fec76d4b6/rpds_py-0.30.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e", size = 408895 }, - { url = "https://files.pythonhosted.org/packages/58/95/d9275b05ab96556fefff73a385813eb66032e4c99f411d0795372d9abcea/rpds_py-0.30.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d", size = 422799 }, - { url = "https://files.pythonhosted.org/packages/06/c1/3088fc04b6624eb12a57eb814f0d4997a44b0d208d6cace713033ff1a6ba/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7", size = 572731 }, - { url = "https://files.pythonhosted.org/packages/d8/42/c612a833183b39774e8ac8fecae81263a68b9583ee343db33ab571a7ce55/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31", size = 599027 }, - { url = "https://files.pythonhosted.org/packages/5f/60/525a50f45b01d70005403ae0e25f43c0384369ad24ffe46e8d9068b50086/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95", size = 563020 }, - { url = "https://files.pythonhosted.org/packages/0b/5d/47c4655e9bcd5ca907148535c10e7d489044243cc9941c16ed7cd53be91d/rpds_py-0.30.0-cp313-cp313-win32.whl", hash = "sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d", size = 223139 }, - { url = "https://files.pythonhosted.org/packages/f2/e1/485132437d20aa4d3e1d8b3fb5a5e65aa8139f1e097080c2a8443201742c/rpds_py-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15", size = 240224 }, - { url = "https://files.pythonhosted.org/packages/24/95/ffd128ed1146a153d928617b0ef673960130be0009c77d8fbf0abe306713/rpds_py-0.30.0-cp313-cp313-win_arm64.whl", hash = "sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1", size = 230645 }, - { url = "https://files.pythonhosted.org/packages/ff/1b/b10de890a0def2a319a2626334a7f0ae388215eb60914dbac8a3bae54435/rpds_py-0.30.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a", size = 364443 }, - { url = "https://files.pythonhosted.org/packages/0d/bf/27e39f5971dc4f305a4fb9c672ca06f290f7c4e261c568f3dea16a410d47/rpds_py-0.30.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e", size = 353375 }, - { url = "https://files.pythonhosted.org/packages/40/58/442ada3bba6e8e6615fc00483135c14a7538d2ffac30e2d933ccf6852232/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000", size = 383850 }, - { url = "https://files.pythonhosted.org/packages/14/14/f59b0127409a33c6ef6f5c1ebd5ad8e32d7861c9c7adfa9a624fc3889f6c/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db", size = 392812 }, - { url = "https://files.pythonhosted.org/packages/b3/66/e0be3e162ac299b3a22527e8913767d869e6cc75c46bd844aa43fb81ab62/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2", size = 517841 }, - { url = "https://files.pythonhosted.org/packages/3d/55/fa3b9cf31d0c963ecf1ba777f7cf4b2a2c976795ac430d24a1f43d25a6ba/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa", size = 408149 }, - { url = "https://files.pythonhosted.org/packages/60/ca/780cf3b1a32b18c0f05c441958d3758f02544f1d613abf9488cd78876378/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083", size = 383843 }, - { url = "https://files.pythonhosted.org/packages/82/86/d5f2e04f2aa6247c613da0c1dd87fcd08fa17107e858193566048a1e2f0a/rpds_py-0.30.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9", size = 396507 }, - { url = "https://files.pythonhosted.org/packages/4b/9a/453255d2f769fe44e07ea9785c8347edaf867f7026872e76c1ad9f7bed92/rpds_py-0.30.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0", size = 414949 }, - { url = "https://files.pythonhosted.org/packages/a3/31/622a86cdc0c45d6df0e9ccb6becdba5074735e7033c20e401a6d9d0e2ca0/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94", size = 565790 }, - { url = "https://files.pythonhosted.org/packages/1c/5d/15bbf0fb4a3f58a3b1c67855ec1efcc4ceaef4e86644665fff03e1b66d8d/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08", size = 590217 }, - { url = "https://files.pythonhosted.org/packages/6d/61/21b8c41f68e60c8cc3b2e25644f0e3681926020f11d06ab0b78e3c6bbff1/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27", size = 555806 }, - { url = "https://files.pythonhosted.org/packages/f9/39/7e067bb06c31de48de3eb200f9fc7c58982a4d3db44b07e73963e10d3be9/rpds_py-0.30.0-cp313-cp313t-win32.whl", hash = "sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6", size = 211341 }, - { url = "https://files.pythonhosted.org/packages/0a/4d/222ef0b46443cf4cf46764d9c630f3fe4abaa7245be9417e56e9f52b8f65/rpds_py-0.30.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d", size = 225768 }, - { url = "https://files.pythonhosted.org/packages/86/81/dad16382ebbd3d0e0328776d8fd7ca94220e4fa0798d1dc5e7da48cb3201/rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0", size = 362099 }, - { url = "https://files.pythonhosted.org/packages/2b/60/19f7884db5d5603edf3c6bce35408f45ad3e97e10007df0e17dd57af18f8/rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be", size = 353192 }, - { url = "https://files.pythonhosted.org/packages/bf/c4/76eb0e1e72d1a9c4703c69607cec123c29028bff28ce41588792417098ac/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f", size = 384080 }, - { url = "https://files.pythonhosted.org/packages/72/87/87ea665e92f3298d1b26d78814721dc39ed8d2c74b86e83348d6b48a6f31/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f", size = 394841 }, - { url = "https://files.pythonhosted.org/packages/77/ad/7783a89ca0587c15dcbf139b4a8364a872a25f861bdb88ed99f9b0dec985/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87", size = 516670 }, - { url = "https://files.pythonhosted.org/packages/5b/3c/2882bdac942bd2172f3da574eab16f309ae10a3925644e969536553cb4ee/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18", size = 408005 }, - { url = "https://files.pythonhosted.org/packages/ce/81/9a91c0111ce1758c92516a3e44776920b579d9a7c09b2b06b642d4de3f0f/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad", size = 382112 }, - { url = "https://files.pythonhosted.org/packages/cf/8e/1da49d4a107027e5fbc64daeab96a0706361a2918da10cb41769244b805d/rpds_py-0.30.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07", size = 399049 }, - { url = "https://files.pythonhosted.org/packages/df/5a/7ee239b1aa48a127570ec03becbb29c9d5a9eb092febbd1699d567cae859/rpds_py-0.30.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f", size = 415661 }, - { url = "https://files.pythonhosted.org/packages/70/ea/caa143cf6b772f823bc7929a45da1fa83569ee49b11d18d0ada7f5ee6fd6/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65", size = 565606 }, - { url = "https://files.pythonhosted.org/packages/64/91/ac20ba2d69303f961ad8cf55bf7dbdb4763f627291ba3d0d7d67333cced9/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f", size = 591126 }, - { url = "https://files.pythonhosted.org/packages/21/20/7ff5f3c8b00c8a95f75985128c26ba44503fb35b8e0259d812766ea966c7/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53", size = 553371 }, - { url = "https://files.pythonhosted.org/packages/72/c7/81dadd7b27c8ee391c132a6b192111ca58d866577ce2d9b0ca157552cce0/rpds_py-0.30.0-cp314-cp314-win32.whl", hash = "sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed", size = 215298 }, - { url = "https://files.pythonhosted.org/packages/3e/d2/1aaac33287e8cfb07aab2e6b8ac1deca62f6f65411344f1433c55e6f3eb8/rpds_py-0.30.0-cp314-cp314-win_amd64.whl", hash = "sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950", size = 228604 }, - { url = "https://files.pythonhosted.org/packages/e8/95/ab005315818cc519ad074cb7784dae60d939163108bd2b394e60dc7b5461/rpds_py-0.30.0-cp314-cp314-win_arm64.whl", hash = "sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6", size = 222391 }, - { url = "https://files.pythonhosted.org/packages/9e/68/154fe0194d83b973cdedcdcc88947a2752411165930182ae41d983dcefa6/rpds_py-0.30.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb", size = 364868 }, - { url = "https://files.pythonhosted.org/packages/83/69/8bbc8b07ec854d92a8b75668c24d2abcb1719ebf890f5604c61c9369a16f/rpds_py-0.30.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8", size = 353747 }, - { url = "https://files.pythonhosted.org/packages/ab/00/ba2e50183dbd9abcce9497fa5149c62b4ff3e22d338a30d690f9af970561/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7", size = 383795 }, - { url = "https://files.pythonhosted.org/packages/05/6f/86f0272b84926bcb0e4c972262f54223e8ecc556b3224d281e6598fc9268/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898", size = 393330 }, - { url = "https://files.pythonhosted.org/packages/cb/e9/0e02bb2e6dc63d212641da45df2b0bf29699d01715913e0d0f017ee29438/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e", size = 518194 }, - { url = "https://files.pythonhosted.org/packages/ee/ca/be7bca14cf21513bdf9c0606aba17d1f389ea2b6987035eb4f62bd923f25/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419", size = 408340 }, - { url = "https://files.pythonhosted.org/packages/c2/c7/736e00ebf39ed81d75544c0da6ef7b0998f8201b369acf842f9a90dc8fce/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551", size = 383765 }, - { url = "https://files.pythonhosted.org/packages/4a/3f/da50dfde9956aaf365c4adc9533b100008ed31aea635f2b8d7b627e25b49/rpds_py-0.30.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8", size = 396834 }, - { url = "https://files.pythonhosted.org/packages/4e/00/34bcc2565b6020eab2623349efbdec810676ad571995911f1abdae62a3a0/rpds_py-0.30.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5", size = 415470 }, - { url = "https://files.pythonhosted.org/packages/8c/28/882e72b5b3e6f718d5453bd4d0d9cf8df36fddeb4ddbbab17869d5868616/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404", size = 565630 }, - { url = "https://files.pythonhosted.org/packages/3b/97/04a65539c17692de5b85c6e293520fd01317fd878ea1995f0367d4532fb1/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856", size = 591148 }, - { url = "https://files.pythonhosted.org/packages/85/70/92482ccffb96f5441aab93e26c4d66489eb599efdcf96fad90c14bbfb976/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40", size = 556030 }, - { url = "https://files.pythonhosted.org/packages/20/53/7c7e784abfa500a2b6b583b147ee4bb5a2b3747a9166bab52fec4b5b5e7d/rpds_py-0.30.0-cp314-cp314t-win32.whl", hash = "sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0", size = 211570 }, - { url = "https://files.pythonhosted.org/packages/d0/02/fa464cdfbe6b26e0600b62c528b72d8608f5cc49f96b8d6e38c95d60c676/rpds_py-0.30.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3", size = 226532 }, - { url = "https://files.pythonhosted.org/packages/69/71/3f34339ee70521864411f8b6992e7ab13ac30d8e4e3309e07c7361767d91/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58", size = 372292 }, - { url = "https://files.pythonhosted.org/packages/57/09/f183df9b8f2d66720d2ef71075c59f7e1b336bec7ee4c48f0a2b06857653/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a", size = 362128 }, - { url = "https://files.pythonhosted.org/packages/7a/68/5c2594e937253457342e078f0cc1ded3dd7b2ad59afdbf2d354869110a02/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb", size = 391542 }, - { url = "https://files.pythonhosted.org/packages/49/5c/31ef1afd70b4b4fbdb2800249f34c57c64beb687495b10aec0365f53dfc4/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c", size = 404004 }, - { url = "https://files.pythonhosted.org/packages/e3/63/0cfbea38d05756f3440ce6534d51a491d26176ac045e2707adc99bb6e60a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3", size = 527063 }, - { url = "https://files.pythonhosted.org/packages/42/e6/01e1f72a2456678b0f618fc9a1a13f882061690893c192fcad9f2926553a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5", size = 413099 }, - { url = "https://files.pythonhosted.org/packages/b8/25/8df56677f209003dcbb180765520c544525e3ef21ea72279c98b9aa7c7fb/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738", size = 392177 }, - { url = "https://files.pythonhosted.org/packages/4a/b4/0a771378c5f16f8115f796d1f437950158679bcd2a7c68cf251cfb00ed5b/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f", size = 406015 }, - { url = "https://files.pythonhosted.org/packages/36/d8/456dbba0af75049dc6f63ff295a2f92766b9d521fa00de67a2bd6427d57a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877", size = 423736 }, - { url = "https://files.pythonhosted.org/packages/13/64/b4d76f227d5c45a7e0b796c674fd81b0a6c4fbd48dc29271857d8219571c/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a", size = 573981 }, - { url = "https://files.pythonhosted.org/packages/20/91/092bacadeda3edf92bf743cc96a7be133e13a39cdbfd7b5082e7ab638406/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4", size = 599782 }, - { url = "https://files.pythonhosted.org/packages/d1/b7/b95708304cd49b7b6f82fdd039f1748b66ec2b21d6a45180910802f1abf1/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e", size = 562191 }, -] - -[[package]] -name = "safehttpx" -version = "0.1.7" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "httpx" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/89/d1/4282284d9cf1ee873607a46442da977fc3c985059315ab23610be31d5885/safehttpx-0.1.7.tar.gz", hash = "sha256:db201c0978c41eddb8bb480f3eee59dd67304fdd91646035e9d9a720049a9d23", size = 10385 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2e/a3/0f0b7d78e2f1eb9e8e1afbff1d2bff8d60144aee17aca51c065b516743dd/safehttpx-0.1.7-py3-none-any.whl", hash = "sha256:c4f4a162db6993464d7ca3d7cc4af0ffc6515a606dfd220b9f82c6945d869cde", size = 8959 }, -] - -[[package]] -name = "secretstorage" -version = "3.5.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cryptography", marker = "(python_full_version < '3.11' and sys_platform == 'emscripten') or (python_full_version < '3.11' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'win32')" }, - { name = "jeepney", marker = "(python_full_version < '3.11' and sys_platform == 'emscripten') or (python_full_version < '3.11' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz", hash = "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be", size = 19884 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/46/f5af3402b579fd5e11573ce652019a67074317e18c1935cc0b4ba9b35552/secretstorage-3.5.0-py3-none-any.whl", hash = "sha256:0ce65888c0725fcb2c5bc0fdb8e5438eece02c523557ea40ce0703c266248137", size = 15554 }, -] - -[[package]] -name = "semantic-version" -version = "2.10.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7d/31/f2289ce78b9b473d582568c234e104d2a342fd658cc288a7553d83bb8595/semantic_version-2.10.0.tar.gz", hash = "sha256:bdabb6d336998cbb378d4b9db3a4b56a1e3235701dc05ea2690d9a997ed5041c", size = 52289 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/23/8146aad7d88f4fcb3a6218f41a60f6c2d4e3a72de72da1825dc7c8f7877c/semantic_version-2.10.0-py2.py3-none-any.whl", hash = "sha256:de78a3b8e0feda74cabc54aab2da702113e33ac9d9eb9d2389bcf1f58b7d9177", size = 15552 }, -] - -[[package]] -name = "shellingham" -version = "1.5.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 }, -] - -[[package]] -name = "six" -version = "1.17.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, -] - -[[package]] -name = "sre-automation-env" -version = "1.0.0" -source = { editable = "." } -dependencies = [ - { name = "fastapi" }, - { name = "httpx" }, - { name = "openai" }, - { name = "openenv-core" }, - { name = "pydantic" }, - { name = "python-dotenv" }, - { name = "uvicorn" }, -] - -[package.metadata] -requires-dist = [ - { name = "fastapi", specifier = ">=0.110.0" }, - { name = "httpx", specifier = ">=0.27.0" }, - { name = "openai", specifier = ">=1.25.0" }, - { name = "openenv-core", specifier = ">=0.2.0" }, - { name = "pydantic", specifier = ">=2.6.0" }, - { name = "python-dotenv", specifier = ">=1.0.0" }, - { name = "uvicorn", specifier = ">=0.29.0" }, -] - -[[package]] -name = "sse-starlette" -version = "3.3.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "starlette" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/26/8c/f9290339ef6d79badbc010f067cd769d6601ec11a57d78569c683fb4dd87/sse_starlette-3.3.4.tar.gz", hash = "sha256:aaf92fc067af8a5427192895ac028e947b484ac01edbc3caf00e7e7137c7bef1", size = 32427 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/7f/3de5402f39890ac5660b86bcf5c03f9d855dad5c4ed764866d7b592b46fd/sse_starlette-3.3.4-py3-none-any.whl", hash = "sha256:84bb06e58939a8b38d8341f1bc9792f06c2b53f48c608dd207582b664fc8f3c1", size = 14330 }, -] - -[[package]] -name = "starlette" -version = "1.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/81/69/17425771797c36cded50b7fe44e850315d039f28b15901ab44839e70b593/starlette-1.0.0.tar.gz", hash = "sha256:6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149", size = 2655289 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-py3-none-any.whl", hash = "sha256:d3ec55e0bb321692d275455ddfd3df75fff145d009685eb40dc91fc66b03d38b", size = 72651 }, -] - -[[package]] -name = "tomli" -version = "2.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704 }, - { url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454 }, - { url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561 }, - { url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824 }, - { url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227 }, - { url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859 }, - { url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204 }, - { url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084 }, - { url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285 }, - { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924 }, - { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018 }, - { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948 }, - { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341 }, - { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159 }, - { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290 }, - { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141 }, - { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847 }, - { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088 }, - { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866 }, - { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887 }, - { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704 }, - { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628 }, - { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180 }, - { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674 }, - { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976 }, - { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755 }, - { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265 }, - { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726 }, - { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859 }, - { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713 }, - { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084 }, - { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973 }, - { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223 }, - { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973 }, - { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082 }, - { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490 }, - { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263 }, - { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736 }, - { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717 }, - { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461 }, - { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855 }, - { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144 }, - { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683 }, - { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196 }, - { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393 }, - { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583 }, -] - -[[package]] -name = "tomli-w" -version = "1.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/19/75/241269d1da26b624c0d5e110e8149093c759b7a286138f4efd61a60e75fe/tomli_w-1.2.0.tar.gz", hash = "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021", size = 7184 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/18/c86eb8e0202e32dd3df50d43d7ff9854f8e0603945ff398974c1d91ac1ef/tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", size = 6675 }, -] - -[[package]] -name = "tomlkit" -version = "0.13.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cc/18/0bbf3884e9eaa38819ebe46a7bd25dcd56b67434402b66a58c4b8e552575/tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1", size = 185207 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bd/75/8539d011f6be8e29f339c42e633aae3cb73bffa95dd0f9adec09b9c58e85/tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0", size = 38901 }, -] - -[[package]] -name = "tqdm" -version = "4.67.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/09/a9/6ba95a270c6f1fbcd8dac228323f2777d886cb206987444e4bce66338dd4/tqdm-4.67.3.tar.gz", hash = "sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb", size = 169598 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl", hash = "sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf", size = 78374 }, -] - -[[package]] -name = "typer" -version = "0.24.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "annotated-doc" }, - { name = "click" }, - { name = "rich" }, - { name = "shellingham" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f5/24/cb09efec5cc954f7f9b930bf8279447d24618bb6758d4f6adf2574c41780/typer-0.24.1.tar.gz", hash = "sha256:e39b4732d65fbdcde189ae76cf7cd48aeae72919dea1fdfc16593be016256b45", size = 118613 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/91/48db081e7a63bb37284f9fbcefda7c44c277b18b0e13fbc36ea2335b71e6/typer-0.24.1-py3-none-any.whl", hash = "sha256:112c1f0ce578bfb4cab9ffdabc68f031416ebcc216536611ba21f04e9aa84c9e", size = 56085 }, -] - -[[package]] -name = "typing-extensions" -version = "4.15.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614 }, -] - -[[package]] -name = "typing-inspection" -version = "0.4.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611 }, -] - -[[package]] -name = "tzdata" -version = "2026.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/19/f5/cd531b2d15a671a40c0f66cf06bc3570a12cd56eef98960068ebbad1bf5a/tzdata-2026.1.tar.gz", hash = "sha256:67658a1903c75917309e753fdc349ac0efd8c27db7a0cb406a25be4840f87f98", size = 197639 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b0/70/d460bd685a170790ec89317e9bd33047988e4bce507b831f5db771e142de/tzdata-2026.1-py2.py3-none-any.whl", hash = "sha256:4b1d2be7ac37ceafd7327b961aa3a54e467efbdb563a23655fbfe0d39cfc42a9", size = 348952 }, -] - -[[package]] -name = "uncalled-for" -version = "0.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/02/7c/b5b7d8136f872e3f13b0584e576886de0489d7213a12de6bebf29ff6ebfc/uncalled_for-0.2.0.tar.gz", hash = "sha256:b4f8fdbcec328c5a113807d653e041c5094473dd4afa7c34599ace69ccb7e69f", size = 49488 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ff/7f/4320d9ce3be404e6310b915c3629fe27bf1e2f438a1a7a3cb0396e32e9a9/uncalled_for-0.2.0-py3-none-any.whl", hash = "sha256:2c0bd338faff5f930918f79e7eb9ff48290df2cb05fcc0b40a7f334e55d4d85f", size = 11351 }, -] - -[[package]] -name = "urllib3" -version = "2.6.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584 }, -] - -[[package]] -name = "uvicorn" -version = "0.43.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "h11" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/62/f2/368268300fb8af33743508d738ef7bb4d56afdb46c6d9c0fa3dd515df171/uvicorn-0.43.0.tar.gz", hash = "sha256:ab1652d2fb23abf124f36ccc399828558880def222c3cb3d98d24021520dc6e8", size = 85686 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/55/df/0cf5b0c451602748fdc7a702d4667f6e209bf96aa6e3160d754234445f2a/uvicorn-0.43.0-py3-none-any.whl", hash = "sha256:46fac64f487fd968cd999e5e49efbbe64bd231b5bd8b4a0b482a23ebce499620", size = 68591 }, -] - -[[package]] -name = "watchfiles" -version = "1.1.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c2/c9/8869df9b2a2d6c59d79220a4db37679e74f807c559ffe5265e08b227a210/watchfiles-1.1.1.tar.gz", hash = "sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2", size = 94440 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/1a/206e8cf2dd86fddf939165a57b4df61607a1e0add2785f170a3f616b7d9f/watchfiles-1.1.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c", size = 407318 }, - { url = "https://files.pythonhosted.org/packages/b3/0f/abaf5262b9c496b5dad4ed3c0e799cbecb1f8ea512ecb6ddd46646a9fca3/watchfiles-1.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43", size = 394478 }, - { url = "https://files.pythonhosted.org/packages/b1/04/9cc0ba88697b34b755371f5ace8d3a4d9a15719c07bdc7bd13d7d8c6a341/watchfiles-1.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31", size = 449894 }, - { url = "https://files.pythonhosted.org/packages/d2/9c/eda4615863cd8621e89aed4df680d8c3ec3da6a4cf1da113c17decd87c7f/watchfiles-1.1.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac", size = 459065 }, - { url = "https://files.pythonhosted.org/packages/84/13/f28b3f340157d03cbc8197629bc109d1098764abe1e60874622a0be5c112/watchfiles-1.1.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d", size = 488377 }, - { url = "https://files.pythonhosted.org/packages/86/93/cfa597fa9389e122488f7ffdbd6db505b3b915ca7435ecd7542e855898c2/watchfiles-1.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d", size = 595837 }, - { url = "https://files.pythonhosted.org/packages/57/1e/68c1ed5652b48d89fc24d6af905d88ee4f82fa8bc491e2666004e307ded1/watchfiles-1.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863", size = 473456 }, - { url = "https://files.pythonhosted.org/packages/d5/dc/1a680b7458ffa3b14bb64878112aefc8f2e4f73c5af763cbf0bd43100658/watchfiles-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab", size = 455614 }, - { url = "https://files.pythonhosted.org/packages/61/a5/3d782a666512e01eaa6541a72ebac1d3aae191ff4a31274a66b8dd85760c/watchfiles-1.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82", size = 630690 }, - { url = "https://files.pythonhosted.org/packages/9b/73/bb5f38590e34687b2a9c47a244aa4dd50c56a825969c92c9c5fc7387cea1/watchfiles-1.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4", size = 622459 }, - { url = "https://files.pythonhosted.org/packages/f1/ac/c9bb0ec696e07a20bd58af5399aeadaef195fb2c73d26baf55180fe4a942/watchfiles-1.1.1-cp310-cp310-win32.whl", hash = "sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844", size = 272663 }, - { url = "https://files.pythonhosted.org/packages/11/a0/a60c5a7c2ec59fa062d9a9c61d02e3b6abd94d32aac2d8344c4bdd033326/watchfiles-1.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e", size = 287453 }, - { url = "https://files.pythonhosted.org/packages/1f/f8/2c5f479fb531ce2f0564eda479faecf253d886b1ab3630a39b7bf7362d46/watchfiles-1.1.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5", size = 406529 }, - { url = "https://files.pythonhosted.org/packages/fe/cd/f515660b1f32f65df671ddf6f85bfaca621aee177712874dc30a97397977/watchfiles-1.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741", size = 394384 }, - { url = "https://files.pythonhosted.org/packages/7b/c3/28b7dc99733eab43fca2d10f55c86e03bd6ab11ca31b802abac26b23d161/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6", size = 448789 }, - { url = "https://files.pythonhosted.org/packages/4a/24/33e71113b320030011c8e4316ccca04194bf0cbbaeee207f00cbc7d6b9f5/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b", size = 460521 }, - { url = "https://files.pythonhosted.org/packages/f4/c3/3c9a55f255aa57b91579ae9e98c88704955fa9dac3e5614fb378291155df/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14", size = 488722 }, - { url = "https://files.pythonhosted.org/packages/49/36/506447b73eb46c120169dc1717fe2eff07c234bb3232a7200b5f5bd816e9/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d", size = 596088 }, - { url = "https://files.pythonhosted.org/packages/82/ab/5f39e752a9838ec4d52e9b87c1e80f1ee3ccdbe92e183c15b6577ab9de16/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff", size = 472923 }, - { url = "https://files.pythonhosted.org/packages/af/b9/a419292f05e302dea372fa7e6fda5178a92998411f8581b9830d28fb9edb/watchfiles-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606", size = 456080 }, - { url = "https://files.pythonhosted.org/packages/b0/c3/d5932fd62bde1a30c36e10c409dc5d54506726f08cb3e1d8d0ba5e2bc8db/watchfiles-1.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701", size = 629432 }, - { url = "https://files.pythonhosted.org/packages/f7/77/16bddd9779fafb795f1a94319dc965209c5641db5bf1edbbccace6d1b3c0/watchfiles-1.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10", size = 623046 }, - { url = "https://files.pythonhosted.org/packages/46/ef/f2ecb9a0f342b4bfad13a2787155c6ee7ce792140eac63a34676a2feeef2/watchfiles-1.1.1-cp311-cp311-win32.whl", hash = "sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849", size = 271473 }, - { url = "https://files.pythonhosted.org/packages/94/bc/f42d71125f19731ea435c3948cad148d31a64fccde3867e5ba4edee901f9/watchfiles-1.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4", size = 287598 }, - { url = "https://files.pythonhosted.org/packages/57/c9/a30f897351f95bbbfb6abcadafbaca711ce1162f4db95fc908c98a9165f3/watchfiles-1.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e", size = 277210 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/0a/bf/95895e78dd75efe9a7f31733607f384b42eb5feb54bd2eb6ed57cc2e94f4/watchfiles-1.1.1-cp312-cp312-win32.whl", hash = "sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9", size = 272042 }, - { url = "https://files.pythonhosted.org/packages/87/0a/90eb755f568de2688cb220171c4191df932232c20946966c27a59c400850/watchfiles-1.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9", size = 288410 }, - { url = "https://files.pythonhosted.org/packages/36/76/f322701530586922fbd6723c4f91ace21364924822a8772c549483abed13/watchfiles-1.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404", size = 278209 }, - { url = "https://files.pythonhosted.org/packages/bb/f4/f750b29225fe77139f7ae5de89d4949f5a99f934c65a1f1c0b248f26f747/watchfiles-1.1.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18", size = 404321 }, - { url = "https://files.pythonhosted.org/packages/2b/f9/f07a295cde762644aa4c4bb0f88921d2d141af45e735b965fb2e87858328/watchfiles-1.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a", size = 391783 }, - { url = "https://files.pythonhosted.org/packages/bc/11/fc2502457e0bea39a5c958d86d2cb69e407a4d00b85735ca724bfa6e0d1a/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219", size = 449279 }, - { url = "https://files.pythonhosted.org/packages/e3/1f/d66bc15ea0b728df3ed96a539c777acfcad0eb78555ad9efcaa1274688f0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428", size = 459405 }, - { url = "https://files.pythonhosted.org/packages/be/90/9f4a65c0aec3ccf032703e6db02d89a157462fbb2cf20dd415128251cac0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0", size = 488976 }, - { url = "https://files.pythonhosted.org/packages/37/57/ee347af605d867f712be7029bb94c8c071732a4b44792e3176fa3c612d39/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150", size = 595506 }, - { url = "https://files.pythonhosted.org/packages/a8/78/cc5ab0b86c122047f75e8fc471c67a04dee395daf847d3e59381996c8707/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae", size = 474936 }, - { url = "https://files.pythonhosted.org/packages/62/da/def65b170a3815af7bd40a3e7010bf6ab53089ef1b75d05dd5385b87cf08/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d", size = 456147 }, - { url = "https://files.pythonhosted.org/packages/57/99/da6573ba71166e82d288d4df0839128004c67d2778d3b566c138695f5c0b/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b", size = 630007 }, - { url = "https://files.pythonhosted.org/packages/a8/51/7439c4dd39511368849eb1e53279cd3454b4a4dbace80bab88feeb83c6b5/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374", size = 622280 }, - { url = "https://files.pythonhosted.org/packages/95/9c/8ed97d4bba5db6fdcdb2b298d3898f2dd5c20f6b73aee04eabe56c59677e/watchfiles-1.1.1-cp313-cp313-win32.whl", hash = "sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0", size = 272056 }, - { url = "https://files.pythonhosted.org/packages/1f/f3/c14e28429f744a260d8ceae18bf58c1d5fa56b50d006a7a9f80e1882cb0d/watchfiles-1.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42", size = 288162 }, - { url = "https://files.pythonhosted.org/packages/dc/61/fe0e56c40d5cd29523e398d31153218718c5786b5e636d9ae8ae79453d27/watchfiles-1.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18", size = 277909 }, - { url = "https://files.pythonhosted.org/packages/79/42/e0a7d749626f1e28c7108a99fb9bf524b501bbbeb9b261ceecde644d5a07/watchfiles-1.1.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da", size = 403389 }, - { url = "https://files.pythonhosted.org/packages/15/49/08732f90ce0fbbc13913f9f215c689cfc9ced345fb1bcd8829a50007cc8d/watchfiles-1.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051", size = 389964 }, - { url = "https://files.pythonhosted.org/packages/27/0d/7c315d4bd5f2538910491a0393c56bf70d333d51bc5b34bee8e68e8cea19/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e", size = 448114 }, - { url = "https://files.pythonhosted.org/packages/c3/24/9e096de47a4d11bc4df41e9d1e61776393eac4cb6eb11b3e23315b78b2cc/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70", size = 460264 }, - { url = "https://files.pythonhosted.org/packages/cc/0f/e8dea6375f1d3ba5fcb0b3583e2b493e77379834c74fd5a22d66d85d6540/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261", size = 487877 }, - { url = "https://files.pythonhosted.org/packages/ac/5b/df24cfc6424a12deb41503b64d42fbea6b8cb357ec62ca84a5a3476f654a/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620", size = 595176 }, - { url = "https://files.pythonhosted.org/packages/8f/b5/853b6757f7347de4e9b37e8cc3289283fb983cba1ab4d2d7144694871d9c/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04", size = 473577 }, - { url = "https://files.pythonhosted.org/packages/e1/f7/0a4467be0a56e80447c8529c9fce5b38eab4f513cb3d9bf82e7392a5696b/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77", size = 455425 }, - { url = "https://files.pythonhosted.org/packages/8e/e0/82583485ea00137ddf69bc84a2db88bd92ab4a6e3c405e5fb878ead8d0e7/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef", size = 628826 }, - { url = "https://files.pythonhosted.org/packages/28/9a/a785356fccf9fae84c0cc90570f11702ae9571036fb25932f1242c82191c/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf", size = 622208 }, - { url = "https://files.pythonhosted.org/packages/c3/f4/0872229324ef69b2c3edec35e84bd57a1289e7d3fe74588048ed8947a323/watchfiles-1.1.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5", size = 404315 }, - { url = "https://files.pythonhosted.org/packages/7b/22/16d5331eaed1cb107b873f6ae1b69e9ced582fcf0c59a50cd84f403b1c32/watchfiles-1.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd", size = 390869 }, - { url = "https://files.pythonhosted.org/packages/b2/7e/5643bfff5acb6539b18483128fdc0ef2cccc94a5b8fbda130c823e8ed636/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb", size = 449919 }, - { url = "https://files.pythonhosted.org/packages/51/2e/c410993ba5025a9f9357c376f48976ef0e1b1aefb73b97a5ae01a5972755/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5", size = 460845 }, - { url = "https://files.pythonhosted.org/packages/8e/a4/2df3b404469122e8680f0fcd06079317e48db58a2da2950fb45020947734/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3", size = 489027 }, - { url = "https://files.pythonhosted.org/packages/ea/84/4587ba5b1f267167ee715b7f66e6382cca6938e0a4b870adad93e44747e6/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33", size = 595615 }, - { url = "https://files.pythonhosted.org/packages/6a/0f/c6988c91d06e93cd0bb3d4a808bcf32375ca1904609835c3031799e3ecae/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510", size = 474836 }, - { url = "https://files.pythonhosted.org/packages/b4/36/ded8aebea91919485b7bbabbd14f5f359326cb5ec218cd67074d1e426d74/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05", size = 455099 }, - { url = "https://files.pythonhosted.org/packages/98/e0/8c9bdba88af756a2fce230dd365fab2baf927ba42cd47521ee7498fd5211/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6", size = 630626 }, - { url = "https://files.pythonhosted.org/packages/2a/84/a95db05354bf2d19e438520d92a8ca475e578c647f78f53197f5a2f17aaf/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81", size = 622519 }, - { url = "https://files.pythonhosted.org/packages/1d/ce/d8acdc8de545de995c339be67711e474c77d643555a9bb74a9334252bd55/watchfiles-1.1.1-cp314-cp314-win32.whl", hash = "sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b", size = 272078 }, - { url = "https://files.pythonhosted.org/packages/c4/c9/a74487f72d0451524be827e8edec251da0cc1fcf111646a511ae752e1a3d/watchfiles-1.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a", size = 287664 }, - { url = "https://files.pythonhosted.org/packages/df/b8/8ac000702cdd496cdce998c6f4ee0ca1f15977bba51bdf07d872ebdfc34c/watchfiles-1.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02", size = 277154 }, - { url = "https://files.pythonhosted.org/packages/47/a8/e3af2184707c29f0f14b1963c0aace6529f9d1b8582d5b99f31bbf42f59e/watchfiles-1.1.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21", size = 403820 }, - { url = "https://files.pythonhosted.org/packages/c0/ec/e47e307c2f4bd75f9f9e8afbe3876679b18e1bcec449beca132a1c5ffb2d/watchfiles-1.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5", size = 390510 }, - { url = "https://files.pythonhosted.org/packages/d5/a0/ad235642118090f66e7b2f18fd5c42082418404a79205cdfca50b6309c13/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7", size = 448408 }, - { url = "https://files.pythonhosted.org/packages/df/85/97fa10fd5ff3332ae17e7e40e20784e419e28521549780869f1413742e9d/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101", size = 458968 }, - { url = "https://files.pythonhosted.org/packages/47/c2/9059c2e8966ea5ce678166617a7f75ecba6164375f3b288e50a40dc6d489/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44", size = 488096 }, - { url = "https://files.pythonhosted.org/packages/94/44/d90a9ec8ac309bc26db808a13e7bfc0e4e78b6fc051078a554e132e80160/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c", size = 596040 }, - { url = "https://files.pythonhosted.org/packages/95/68/4e3479b20ca305cfc561db3ed207a8a1c745ee32bf24f2026a129d0ddb6e/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc", size = 473847 }, - { url = "https://files.pythonhosted.org/packages/4f/55/2af26693fd15165c4ff7857e38330e1b61ab8c37d15dc79118cdba115b7a/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c", size = 455072 }, - { url = "https://files.pythonhosted.org/packages/66/1d/d0d200b10c9311ec25d2273f8aad8c3ef7cc7ea11808022501811208a750/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099", size = 629104 }, - { url = "https://files.pythonhosted.org/packages/e3/bd/fa9bb053192491b3867ba07d2343d9f2252e00811567d30ae8d0f78136fe/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01", size = 622112 }, - { url = "https://files.pythonhosted.org/packages/ba/4c/a888c91e2e326872fa4705095d64acd8aa2fb9c1f7b9bd0588f33850516c/watchfiles-1.1.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3", size = 409611 }, - { url = "https://files.pythonhosted.org/packages/1e/c7/5420d1943c8e3ce1a21c0a9330bcf7edafb6aa65d26b21dbb3267c9e8112/watchfiles-1.1.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2", size = 396889 }, - { url = "https://files.pythonhosted.org/packages/0c/e5/0072cef3804ce8d3aaddbfe7788aadff6b3d3f98a286fdbee9fd74ca59a7/watchfiles-1.1.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d", size = 451616 }, - { url = "https://files.pythonhosted.org/packages/83/4e/b87b71cbdfad81ad7e83358b3e447fedd281b880a03d64a760fe0a11fc2e/watchfiles-1.1.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b", size = 458413 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/6e/d4/ed38dd3b1767193de971e694aa544356e63353c33a85d948166b5ff58b9e/watchfiles-1.1.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49", size = 457546 }, -] - -[[package]] -name = "websockets" -version = "16.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/04/24/4b2031d72e840ce4c1ccb255f693b15c334757fc50023e4db9537080b8c4/websockets-16.0.tar.gz", hash = "sha256:5f6261a5e56e8d5c42a4497b364ea24d94d9563e8fbd44e78ac40879c60179b5", size = 179346 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/20/74/221f58decd852f4b59cc3354cccaf87e8ef695fede361d03dc9a7396573b/websockets-16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:04cdd5d2d1dacbad0a7bf36ccbcd3ccd5a30ee188f2560b7a62a30d14107b31a", size = 177343 }, - { url = "https://files.pythonhosted.org/packages/19/0f/22ef6107ee52ab7f0b710d55d36f5a5d3ef19e8a205541a6d7ffa7994e5a/websockets-16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8ff32bb86522a9e5e31439a58addbb0166f0204d64066fb955265c4e214160f0", size = 175021 }, - { url = "https://files.pythonhosted.org/packages/10/40/904a4cb30d9b61c0e278899bf36342e9b0208eb3c470324a9ecbaac2a30f/websockets-16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:583b7c42688636f930688d712885cf1531326ee05effd982028212ccc13e5957", size = 175320 }, - { url = "https://files.pythonhosted.org/packages/9d/2f/4b3ca7e106bc608744b1cdae041e005e446124bebb037b18799c2d356864/websockets-16.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7d837379b647c0c4c2355c2499723f82f1635fd2c26510e1f587d89bc2199e72", size = 183815 }, - { url = "https://files.pythonhosted.org/packages/86/26/d40eaa2a46d4302becec8d15b0fc5e45bdde05191e7628405a19cf491ccd/websockets-16.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df57afc692e517a85e65b72e165356ed1df12386ecb879ad5693be08fac65dde", size = 185054 }, - { url = "https://files.pythonhosted.org/packages/b0/ba/6500a0efc94f7373ee8fefa8c271acdfd4dca8bd49a90d4be7ccabfc397e/websockets-16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2b9f1e0d69bc60a4a87349d50c09a037a2607918746f07de04df9e43252c77a3", size = 184565 }, - { url = "https://files.pythonhosted.org/packages/04/b4/96bf2cee7c8d8102389374a2616200574f5f01128d1082f44102140344cc/websockets-16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:335c23addf3d5e6a8633f9f8eda77efad001671e80b95c491dd0924587ece0b3", size = 183848 }, - { url = "https://files.pythonhosted.org/packages/02/8e/81f40fb00fd125357814e8c3025738fc4ffc3da4b6b4a4472a82ba304b41/websockets-16.0-cp310-cp310-win32.whl", hash = "sha256:37b31c1623c6605e4c00d466c9d633f9b812ea430c11c8a278774a1fde1acfa9", size = 178249 }, - { url = "https://files.pythonhosted.org/packages/b4/5f/7e40efe8df57db9b91c88a43690ac66f7b7aa73a11aa6a66b927e44f26fa/websockets-16.0-cp310-cp310-win_amd64.whl", hash = "sha256:8e1dab317b6e77424356e11e99a432b7cb2f3ec8c5ab4dabbcee6add48f72b35", size = 178685 }, - { url = "https://files.pythonhosted.org/packages/f2/db/de907251b4ff46ae804ad0409809504153b3f30984daf82a1d84a9875830/websockets-16.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:31a52addea25187bde0797a97d6fc3d2f92b6f72a9370792d65a6e84615ac8a8", size = 177340 }, - { url = "https://files.pythonhosted.org/packages/f3/fa/abe89019d8d8815c8781e90d697dec52523fb8ebe308bf11664e8de1877e/websockets-16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:417b28978cdccab24f46400586d128366313e8a96312e4b9362a4af504f3bbad", size = 175022 }, - { url = "https://files.pythonhosted.org/packages/58/5d/88ea17ed1ded2079358b40d31d48abe90a73c9e5819dbcde1606e991e2ad/websockets-16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:af80d74d4edfa3cb9ed973a0a5ba2b2a549371f8a741e0800cb07becdd20f23d", size = 175319 }, - { url = "https://files.pythonhosted.org/packages/d2/ae/0ee92b33087a33632f37a635e11e1d99d429d3d323329675a6022312aac2/websockets-16.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:08d7af67b64d29823fed316505a89b86705f2b7981c07848fb5e3ea3020c1abe", size = 184631 }, - { url = "https://files.pythonhosted.org/packages/c8/c5/27178df583b6c5b31b29f526ba2da5e2f864ecc79c99dae630a85d68c304/websockets-16.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7be95cfb0a4dae143eaed2bcba8ac23f4892d8971311f1b06f3c6b78952ee70b", size = 185870 }, - { url = "https://files.pythonhosted.org/packages/87/05/536652aa84ddc1c018dbb7e2c4cbcd0db884580bf8e95aece7593fde526f/websockets-16.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d6297ce39ce5c2e6feb13c1a996a2ded3b6832155fcfc920265c76f24c7cceb5", size = 185361 }, - { url = "https://files.pythonhosted.org/packages/6d/e2/d5332c90da12b1e01f06fb1b85c50cfc489783076547415bf9f0a659ec19/websockets-16.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1c1b30e4f497b0b354057f3467f56244c603a79c0d1dafce1d16c283c25f6e64", size = 184615 }, - { url = "https://files.pythonhosted.org/packages/77/fb/d3f9576691cae9253b51555f841bc6600bf0a983a461c79500ace5a5b364/websockets-16.0-cp311-cp311-win32.whl", hash = "sha256:5f451484aeb5cafee1ccf789b1b66f535409d038c56966d6101740c1614b86c6", size = 178246 }, - { url = "https://files.pythonhosted.org/packages/54/67/eaff76b3dbaf18dcddabc3b8c1dba50b483761cccff67793897945b37408/websockets-16.0-cp311-cp311-win_amd64.whl", hash = "sha256:8d7f0659570eefb578dacde98e24fb60af35350193e4f56e11190787bee77dac", size = 178684 }, - { url = "https://files.pythonhosted.org/packages/84/7b/bac442e6b96c9d25092695578dda82403c77936104b5682307bd4deb1ad4/websockets-16.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:71c989cbf3254fbd5e84d3bff31e4da39c43f884e64f2551d14bb3c186230f00", size = 177365 }, - { url = "https://files.pythonhosted.org/packages/b0/fe/136ccece61bd690d9c1f715baaeefd953bb2360134de73519d5df19d29ca/websockets-16.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8b6e209ffee39ff1b6d0fa7bfef6de950c60dfb91b8fcead17da4ee539121a79", size = 175038 }, - { url = "https://files.pythonhosted.org/packages/40/1e/9771421ac2286eaab95b8575b0cb701ae3663abf8b5e1f64f1fd90d0a673/websockets-16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:86890e837d61574c92a97496d590968b23c2ef0aeb8a9bc9421d174cd378ae39", size = 175328 }, - { url = "https://files.pythonhosted.org/packages/18/29/71729b4671f21e1eaa5d6573031ab810ad2936c8175f03f97f3ff164c802/websockets-16.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9b5aca38b67492ef518a8ab76851862488a478602229112c4b0d58d63a7a4d5c", size = 184915 }, - { url = "https://files.pythonhosted.org/packages/97/bb/21c36b7dbbafc85d2d480cd65df02a1dc93bf76d97147605a8e27ff9409d/websockets-16.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e0334872c0a37b606418ac52f6ab9cfd17317ac26365f7f65e203e2d0d0d359f", size = 186152 }, - { url = "https://files.pythonhosted.org/packages/4a/34/9bf8df0c0cf88fa7bfe36678dc7b02970c9a7d5e065a3099292db87b1be2/websockets-16.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a0b31e0b424cc6b5a04b8838bbaec1688834b2383256688cf47eb97412531da1", size = 185583 }, - { url = "https://files.pythonhosted.org/packages/47/88/4dd516068e1a3d6ab3c7c183288404cd424a9a02d585efbac226cb61ff2d/websockets-16.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:485c49116d0af10ac698623c513c1cc01c9446c058a4e61e3bf6c19dff7335a2", size = 184880 }, - { url = "https://files.pythonhosted.org/packages/91/d6/7d4553ad4bf1c0421e1ebd4b18de5d9098383b5caa1d937b63df8d04b565/websockets-16.0-cp312-cp312-win32.whl", hash = "sha256:eaded469f5e5b7294e2bdca0ab06becb6756ea86894a47806456089298813c89", size = 178261 }, - { url = "https://files.pythonhosted.org/packages/c3/f0/f3a17365441ed1c27f850a80b2bc680a0fa9505d733fe152fdf5e98c1c0b/websockets-16.0-cp312-cp312-win_amd64.whl", hash = "sha256:5569417dc80977fc8c2d43a86f78e0a5a22fee17565d78621b6bb264a115d4ea", size = 178693 }, - { url = "https://files.pythonhosted.org/packages/cc/9c/baa8456050d1c1b08dd0ec7346026668cbc6f145ab4e314d707bb845bf0d/websockets-16.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:878b336ac47938b474c8f982ac2f7266a540adc3fa4ad74ae96fea9823a02cc9", size = 177364 }, - { url = "https://files.pythonhosted.org/packages/7e/0c/8811fc53e9bcff68fe7de2bcbe75116a8d959ac699a3200f4847a8925210/websockets-16.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:52a0fec0e6c8d9a784c2c78276a48a2bdf099e4ccc2a4cad53b27718dbfd0230", size = 175039 }, - { url = "https://files.pythonhosted.org/packages/aa/82/39a5f910cb99ec0b59e482971238c845af9220d3ab9fa76dd9162cda9d62/websockets-16.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e6578ed5b6981005df1860a56e3617f14a6c307e6a71b4fff8c48fdc50f3ed2c", size = 175323 }, - { url = "https://files.pythonhosted.org/packages/bd/28/0a25ee5342eb5d5f297d992a77e56892ecb65e7854c7898fb7d35e9b33bd/websockets-16.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:95724e638f0f9c350bb1c2b0a7ad0e83d9cc0c9259f3ea94e40d7b02a2179ae5", size = 184975 }, - { url = "https://files.pythonhosted.org/packages/f9/66/27ea52741752f5107c2e41fda05e8395a682a1e11c4e592a809a90c6a506/websockets-16.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0204dc62a89dc9d50d682412c10b3542d748260d743500a85c13cd1ee4bde82", size = 186203 }, - { url = "https://files.pythonhosted.org/packages/37/e5/8e32857371406a757816a2b471939d51c463509be73fa538216ea52b792a/websockets-16.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:52ac480f44d32970d66763115edea932f1c5b1312de36df06d6b219f6741eed8", size = 185653 }, - { url = "https://files.pythonhosted.org/packages/9b/67/f926bac29882894669368dc73f4da900fcdf47955d0a0185d60103df5737/websockets-16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6e5a82b677f8f6f59e8dfc34ec06ca6b5b48bc4fcda346acd093694cc2c24d8f", size = 184920 }, - { url = "https://files.pythonhosted.org/packages/3c/a1/3d6ccdcd125b0a42a311bcd15a7f705d688f73b2a22d8cf1c0875d35d34a/websockets-16.0-cp313-cp313-win32.whl", hash = "sha256:abf050a199613f64c886ea10f38b47770a65154dc37181bfaff70c160f45315a", size = 178255 }, - { url = "https://files.pythonhosted.org/packages/6b/ae/90366304d7c2ce80f9b826096a9e9048b4bb760e44d3b873bb272cba696b/websockets-16.0-cp313-cp313-win_amd64.whl", hash = "sha256:3425ac5cf448801335d6fdc7ae1eb22072055417a96cc6b31b3861f455fbc156", size = 178689 }, - { url = "https://files.pythonhosted.org/packages/f3/1d/e88022630271f5bd349ed82417136281931e558d628dd52c4d8621b4a0b2/websockets-16.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8cc451a50f2aee53042ac52d2d053d08bf89bcb31ae799cb4487587661c038a0", size = 177406 }, - { url = "https://files.pythonhosted.org/packages/f2/78/e63be1bf0724eeb4616efb1ae1c9044f7c3953b7957799abb5915bffd38e/websockets-16.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:daa3b6ff70a9241cf6c7fc9e949d41232d9d7d26fd3522b1ad2b4d62487e9904", size = 175085 }, - { url = "https://files.pythonhosted.org/packages/bb/f4/d3c9220d818ee955ae390cf319a7c7a467beceb24f05ee7aaaa2414345ba/websockets-16.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4", size = 175328 }, - { url = "https://files.pythonhosted.org/packages/63/bc/d3e208028de777087e6fb2b122051a6ff7bbcca0d6df9d9c2bf1dd869ae9/websockets-16.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:781caf5e8eee67f663126490c2f96f40906594cb86b408a703630f95550a8c3e", size = 185044 }, - { url = "https://files.pythonhosted.org/packages/ad/6e/9a0927ac24bd33a0a9af834d89e0abc7cfd8e13bed17a86407a66773cc0e/websockets-16.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:caab51a72c51973ca21fa8a18bd8165e1a0183f1ac7066a182ff27107b71e1a4", size = 186279 }, - { url = "https://files.pythonhosted.org/packages/b9/ca/bf1c68440d7a868180e11be653c85959502efd3a709323230314fda6e0b3/websockets-16.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:19c4dc84098e523fd63711e563077d39e90ec6702aff4b5d9e344a60cb3c0cb1", size = 185711 }, - { url = "https://files.pythonhosted.org/packages/c4/f8/fdc34643a989561f217bb477cbc47a3a07212cbda91c0e4389c43c296ebf/websockets-16.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a5e18a238a2b2249c9a9235466b90e96ae4795672598a58772dd806edc7ac6d3", size = 184982 }, - { url = "https://files.pythonhosted.org/packages/dd/d1/574fa27e233764dbac9c52730d63fcf2823b16f0856b3329fc6268d6ae4f/websockets-16.0-cp314-cp314-win32.whl", hash = "sha256:a069d734c4a043182729edd3e9f247c3b2a4035415a9172fd0f1b71658a320a8", size = 177915 }, - { url = "https://files.pythonhosted.org/packages/8a/f1/ae6b937bf3126b5134ce1f482365fde31a357c784ac51852978768b5eff4/websockets-16.0-cp314-cp314-win_amd64.whl", hash = "sha256:c0ee0e63f23914732c6d7e0cce24915c48f3f1512ec1d079ed01fc629dab269d", size = 178381 }, - { url = "https://files.pythonhosted.org/packages/06/9b/f791d1db48403e1f0a27577a6beb37afae94254a8c6f08be4a23e4930bc0/websockets-16.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:a35539cacc3febb22b8f4d4a99cc79b104226a756aa7400adc722e83b0d03244", size = 177737 }, - { url = "https://files.pythonhosted.org/packages/bd/40/53ad02341fa33b3ce489023f635367a4ac98b73570102ad2cdd770dacc9a/websockets-16.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:b784ca5de850f4ce93ec85d3269d24d4c82f22b7212023c974c401d4980ebc5e", size = 175268 }, - { url = "https://files.pythonhosted.org/packages/74/9b/6158d4e459b984f949dcbbb0c5d270154c7618e11c01029b9bbd1bb4c4f9/websockets-16.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:569d01a4e7fba956c5ae4fc988f0d4e187900f5497ce46339c996dbf24f17641", size = 175486 }, - { url = "https://files.pythonhosted.org/packages/e5/2d/7583b30208b639c8090206f95073646c2c9ffd66f44df967981a64f849ad/websockets-16.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:50f23cdd8343b984957e4077839841146f67a3d31ab0d00e6b824e74c5b2f6e8", size = 185331 }, - { url = "https://files.pythonhosted.org/packages/45/b0/cce3784eb519b7b5ad680d14b9673a31ab8dcb7aad8b64d81709d2430aa8/websockets-16.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:152284a83a00c59b759697b7f9e9cddf4e3c7861dd0d964b472b70f78f89e80e", size = 186501 }, - { url = "https://files.pythonhosted.org/packages/19/60/b8ebe4c7e89fb5f6cdf080623c9d92789a53636950f7abacfc33fe2b3135/websockets-16.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bc59589ab64b0022385f429b94697348a6a234e8ce22544e3681b2e9331b5944", size = 186062 }, - { url = "https://files.pythonhosted.org/packages/88/a8/a080593f89b0138b6cba1b28f8df5673b5506f72879322288b031337c0b8/websockets-16.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:32da954ffa2814258030e5a57bc73a3635463238e797c7375dc8091327434206", size = 185356 }, - { url = "https://files.pythonhosted.org/packages/c2/b6/b9afed2afadddaf5ebb2afa801abf4b0868f42f8539bfe4b071b5266c9fe/websockets-16.0-cp314-cp314t-win32.whl", hash = "sha256:5a4b4cc550cb665dd8a47f868c8d04c8230f857363ad3c9caf7a0c3bf8c61ca6", size = 178085 }, - { url = "https://files.pythonhosted.org/packages/9f/3e/28135a24e384493fa804216b79a6a6759a38cc4ff59118787b9fb693df93/websockets-16.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b14dc141ed6d2dde437cddb216004bcac6a1df0935d79656387bd41632ba0bbd", size = 178531 }, - { url = "https://files.pythonhosted.org/packages/72/07/c98a68571dcf256e74f1f816b8cc5eae6eb2d3d5cfa44d37f801619d9166/websockets-16.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:349f83cd6c9a415428ee1005cadb5c2c56f4389bc06a9af16103c3bc3dcc8b7d", size = 174947 }, - { url = "https://files.pythonhosted.org/packages/7e/52/93e166a81e0305b33fe416338be92ae863563fe7bce446b0f687b9df5aea/websockets-16.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:4a1aba3340a8dca8db6eb5a7986157f52eb9e436b74813764241981ca4888f03", size = 175260 }, - { url = "https://files.pythonhosted.org/packages/56/0c/2dbf513bafd24889d33de2ff0368190a0e69f37bcfa19009ef819fe4d507/websockets-16.0-pp311-pypy311_pp73-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da", size = 176071 }, - { url = "https://files.pythonhosted.org/packages/a5/8f/aea9c71cc92bf9b6cc0f7f70df8f0b420636b6c96ef4feee1e16f80f75dd/websockets-16.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0298d07ee155e2e9fda5be8a9042200dd2e3bb0b8a38482156576f863a9d457c", size = 176968 }, - { url = "https://files.pythonhosted.org/packages/9a/3f/f70e03f40ffc9a30d817eef7da1be72ee4956ba8d7255c399a01b135902a/websockets-16.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:a653aea902e0324b52f1613332ddf50b00c06fdaf7e92624fbf8c77c78fa5767", size = 178735 }, - { url = "https://files.pythonhosted.org/packages/6f/28/258ebab549c2bf3e64d2b0217b973467394a9cea8c42f70418ca2c5d0d2e/websockets-16.0-py3-none-any.whl", hash = "sha256:1637db62fad1dc833276dded54215f2c7fa46912301a24bd94d45d46a011ceec", size = 171598 }, -] - -[[package]] -name = "zipp" -version = "3.23.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e3/02/0f2892c661036d50ede074e376733dca2ae7c6eb617489437771209d4180/zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166", size = 25547 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e", size = 10276 }, -]