Dixing Xu
commited on
Init...
Browse files- .github/ISSUE_TEMPLATE/bug_report.yml +65 -0
- .github/ISSUE_TEMPLATE/feature_request.md +18 -0
- .github/ISSUE_TEMPLATE/technical_proposal.md +18 -0
- .github/pull_request_template.md +8 -0
- .github/workflows/linter.yml +25 -0
- .github/workflows/python-publish.yml +39 -0
- .gitignore +172 -0
- .python-version +1 -0
- .streamlit/config.toml +17 -0
- LICENSE +21 -0
- aide/__init__.py +62 -0
- aide/agent.py +339 -0
- aide/backend/__init__.py +52 -0
- aide/backend/backend_anthropic.py +107 -0
- aide/backend/backend_openai.py +127 -0
- aide/backend/utils.py +101 -0
- aide/example_tasks/bitcoin_price.md +5 -0
- aide/example_tasks/bitcoin_price/BTC-USD.csv +501 -0
- aide/example_tasks/house_prices.md +24 -0
- aide/example_tasks/house_prices/data_description.txt +523 -0
- aide/example_tasks/house_prices/sample_submission.csv +1460 -0
- aide/example_tasks/house_prices/test.csv +0 -0
- aide/example_tasks/house_prices/train.csv +0 -0
- aide/interpreter.py +311 -0
- aide/journal.py +192 -0
- aide/journal2report.py +31 -0
- aide/run.py +148 -0
- aide/utils/__init__.py +100 -0
- aide/utils/config.py +199 -0
- aide/utils/config.yaml +58 -0
- aide/utils/data_preview.py +153 -0
- aide/utils/metric.py +78 -0
- aide/utils/response.py +91 -0
- aide/utils/serialize.py +51 -0
- aide/utils/tree_export.py +94 -0
- aide/utils/viz_templates/template.html +61 -0
- aide/utils/viz_templates/template.js +362 -0
- aide/webui/__init__.py +0 -0
- aide/webui/app.py +599 -0
- aide/webui/style.css +173 -0
- app.py +2 -2
- requirements.txt +94 -0
- style.css +173 -0
.github/ISSUE_TEMPLATE/bug_report.yml
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Bug
|
2 |
+
description: Report a problem with AIDE
|
3 |
+
title: '[Bug]: '
|
4 |
+
labels: ['bug']
|
5 |
+
body:
|
6 |
+
- type: markdown
|
7 |
+
attributes:
|
8 |
+
value: Thank you for taking the time to fill out this bug report. Please provide as much information as possible to help us understand and address the issue effectively.
|
9 |
+
|
10 |
+
- type: checkboxes
|
11 |
+
attributes:
|
12 |
+
label: Is there an existing issue for the same bug?
|
13 |
+
description: Please check if an issue already exists for the bug you encountered.
|
14 |
+
options:
|
15 |
+
- label: I have checked the existing issues.
|
16 |
+
required: true
|
17 |
+
|
18 |
+
- type: textarea
|
19 |
+
id: bug-description
|
20 |
+
attributes:
|
21 |
+
label: Describe the bug and reproduction steps
|
22 |
+
description: Provide a description of the issue along with any reproduction steps.
|
23 |
+
validations:
|
24 |
+
required: true
|
25 |
+
|
26 |
+
- type: dropdown
|
27 |
+
id: installation
|
28 |
+
attributes:
|
29 |
+
label: AIDE Installation
|
30 |
+
description: How are you running AIDE?
|
31 |
+
options:
|
32 |
+
- Commandline
|
33 |
+
- Docker
|
34 |
+
- Python Script
|
35 |
+
- Other
|
36 |
+
default: 0
|
37 |
+
|
38 |
+
- type: input
|
39 |
+
id: aideml-version
|
40 |
+
attributes:
|
41 |
+
label: AIDE Version
|
42 |
+
description: What version of AIDE are you using?
|
43 |
+
placeholder: ex. 0.1.4, main, etc.
|
44 |
+
|
45 |
+
- type: input
|
46 |
+
id: llm
|
47 |
+
attributes:
|
48 |
+
label: LLM
|
49 |
+
description: Which llm are you using?
|
50 |
+
placeholder: ex. gpt-4-turbo, claude-3-5-sonnet, etc.
|
51 |
+
|
52 |
+
- type: dropdown
|
53 |
+
id: os
|
54 |
+
attributes:
|
55 |
+
label: Operating System
|
56 |
+
options:
|
57 |
+
- MacOS
|
58 |
+
- Linux
|
59 |
+
- WSL on Windows
|
60 |
+
|
61 |
+
- type: textarea
|
62 |
+
id: additional-context
|
63 |
+
attributes:
|
64 |
+
label: Logs, Errors, Screenshots, and Additional Context
|
65 |
+
description: Please provide any additional information you think might help.
|
.github/ISSUE_TEMPLATE/feature_request.md
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
name: Feature Request
|
3 |
+
about: Suggest an idea for new AIDE features
|
4 |
+
title: ''
|
5 |
+
labels: 'enhancement'
|
6 |
+
assignees: ''
|
7 |
+
|
8 |
+
---
|
9 |
+
|
10 |
+
**What problem or use case are you trying to solve?**
|
11 |
+
|
12 |
+
**Describe the UX of the solution you'd like**
|
13 |
+
|
14 |
+
**Do you have thoughts on the technical implementation?**
|
15 |
+
|
16 |
+
**Describe alternatives you've considered**
|
17 |
+
|
18 |
+
**Additional context**
|
.github/ISSUE_TEMPLATE/technical_proposal.md
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
name: Technical Proposal
|
3 |
+
about: Propose a new architecture or technology
|
4 |
+
title: ''
|
5 |
+
labels: 'proposal'
|
6 |
+
assignees: ''
|
7 |
+
|
8 |
+
---
|
9 |
+
|
10 |
+
**Summary**
|
11 |
+
|
12 |
+
**Motivation**
|
13 |
+
|
14 |
+
**Technical Design**
|
15 |
+
|
16 |
+
**Alternatives to Consider**
|
17 |
+
|
18 |
+
**Additional context**
|
.github/pull_request_template.md
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
## Description
|
2 |
+
|
3 |
+
* a simple description of what you're trying to accomplish
|
4 |
+
* a summary of changes in code
|
5 |
+
* which issues it fixes, if any
|
6 |
+
|
7 |
+
## Screenshots/videos:
|
8 |
+
|
.github/workflows/linter.yml
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Linter
|
2 |
+
|
3 |
+
on:
|
4 |
+
- push
|
5 |
+
- pull_request
|
6 |
+
|
7 |
+
jobs:
|
8 |
+
lint-python:
|
9 |
+
name: Python Linting
|
10 |
+
runs-on: ubuntu-latest
|
11 |
+
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
|
12 |
+
steps:
|
13 |
+
- name: Checkout Code
|
14 |
+
uses: actions/checkout@v4
|
15 |
+
- uses: actions/setup-python@v5
|
16 |
+
with:
|
17 |
+
python-version: 3.11
|
18 |
+
- name: Install Dependencies
|
19 |
+
run: |
|
20 |
+
pip install ruff==0.7.1
|
21 |
+
pip install black==24.3.0
|
22 |
+
- name: Run Ruff
|
23 |
+
run: ruff check --output-format=github aide/
|
24 |
+
- name: Run Black
|
25 |
+
run: black --check --diff aide/
|
.github/workflows/python-publish.yml
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# This workflow will upload a Python Package using Twine when a release is created
|
2 |
+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
|
3 |
+
|
4 |
+
# This workflow uses actions that are not certified by GitHub.
|
5 |
+
# They are provided by a third-party and are governed by
|
6 |
+
# separate terms of service, privacy policy, and support
|
7 |
+
# documentation.
|
8 |
+
|
9 |
+
name: Publish on PyPI
|
10 |
+
|
11 |
+
on:
|
12 |
+
release:
|
13 |
+
types: [published]
|
14 |
+
|
15 |
+
permissions:
|
16 |
+
contents: read
|
17 |
+
|
18 |
+
jobs:
|
19 |
+
deploy:
|
20 |
+
|
21 |
+
runs-on: ubuntu-latest
|
22 |
+
|
23 |
+
steps:
|
24 |
+
- uses: actions/checkout@v4
|
25 |
+
- name: Set up Python
|
26 |
+
uses: actions/setup-python@v3
|
27 |
+
with:
|
28 |
+
python-version: '3.10'
|
29 |
+
- name: Install dependencies
|
30 |
+
run: |
|
31 |
+
python -m pip install --upgrade pip
|
32 |
+
pip install build
|
33 |
+
- name: Build package
|
34 |
+
run: python -m build
|
35 |
+
- name: Publish package
|
36 |
+
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
|
37 |
+
with:
|
38 |
+
user: __token__
|
39 |
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
.gitignore
ADDED
@@ -0,0 +1,172 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Byte-compiled / optimized / DLL files
|
2 |
+
__pycache__/
|
3 |
+
*.py[cod]
|
4 |
+
*$py.class
|
5 |
+
|
6 |
+
# C extensions
|
7 |
+
*.so
|
8 |
+
|
9 |
+
# Distribution / packaging
|
10 |
+
.Python
|
11 |
+
build/
|
12 |
+
develop-eggs/
|
13 |
+
dist/
|
14 |
+
downloads/
|
15 |
+
eggs/
|
16 |
+
.eggs/
|
17 |
+
lib/
|
18 |
+
lib64/
|
19 |
+
parts/
|
20 |
+
sdist/
|
21 |
+
var/
|
22 |
+
wheels/
|
23 |
+
share/python-wheels/
|
24 |
+
*.egg-info/
|
25 |
+
.installed.cfg
|
26 |
+
*.egg
|
27 |
+
MANIFEST
|
28 |
+
|
29 |
+
# PyInstaller
|
30 |
+
# Usually these files are written by a python script from a template
|
31 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
32 |
+
*.manifest
|
33 |
+
*.spec
|
34 |
+
|
35 |
+
# Installer logs
|
36 |
+
pip-log.txt
|
37 |
+
pip-delete-this-directory.txt
|
38 |
+
|
39 |
+
# Unit test / coverage reports
|
40 |
+
htmlcov/
|
41 |
+
.tox/
|
42 |
+
.nox/
|
43 |
+
.coverage
|
44 |
+
.coverage.*
|
45 |
+
.cache
|
46 |
+
nosetests.xml
|
47 |
+
coverage.xml
|
48 |
+
*.cover
|
49 |
+
*.py,cover
|
50 |
+
.hypothesis/
|
51 |
+
.pytest_cache/
|
52 |
+
cover/
|
53 |
+
|
54 |
+
# Translations
|
55 |
+
*.mo
|
56 |
+
*.pot
|
57 |
+
|
58 |
+
# Django stuff:
|
59 |
+
*.log
|
60 |
+
local_settings.py
|
61 |
+
db.sqlite3
|
62 |
+
db.sqlite3-journal
|
63 |
+
|
64 |
+
# Flask stuff:
|
65 |
+
instance/
|
66 |
+
.webassets-cache
|
67 |
+
|
68 |
+
# Scrapy stuff:
|
69 |
+
.scrapy
|
70 |
+
|
71 |
+
# Sphinx documentation
|
72 |
+
docs/_build/
|
73 |
+
|
74 |
+
# PyBuilder
|
75 |
+
.pybuilder/
|
76 |
+
target/
|
77 |
+
|
78 |
+
# Jupyter Notebook
|
79 |
+
.ipynb_checkpoints
|
80 |
+
|
81 |
+
# IPython
|
82 |
+
profile_default/
|
83 |
+
ipython_config.py
|
84 |
+
|
85 |
+
# pyenv
|
86 |
+
# For a library or package, you might want to ignore these files since the code is
|
87 |
+
# intended to run in multiple environments; otherwise, check them in:
|
88 |
+
# .python-version
|
89 |
+
|
90 |
+
# pipenv
|
91 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
92 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
93 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
94 |
+
# install all needed dependencies.
|
95 |
+
#Pipfile.lock
|
96 |
+
|
97 |
+
# poetry
|
98 |
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
99 |
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
100 |
+
# commonly ignored for libraries.
|
101 |
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
102 |
+
#poetry.lock
|
103 |
+
|
104 |
+
# pdm
|
105 |
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
106 |
+
#pdm.lock
|
107 |
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
108 |
+
# in version control.
|
109 |
+
# https://pdm.fming.dev/#use-with-ide
|
110 |
+
.pdm.toml
|
111 |
+
|
112 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
113 |
+
__pypackages__/
|
114 |
+
|
115 |
+
# Celery stuff
|
116 |
+
celerybeat-schedule
|
117 |
+
celerybeat.pid
|
118 |
+
|
119 |
+
# SageMath parsed files
|
120 |
+
*.sage.py
|
121 |
+
|
122 |
+
# Environments
|
123 |
+
.env
|
124 |
+
.venv
|
125 |
+
env/
|
126 |
+
venv/
|
127 |
+
ENV/
|
128 |
+
env.bak/
|
129 |
+
venv.bak/
|
130 |
+
|
131 |
+
# Spyder project settings
|
132 |
+
.spyderproject
|
133 |
+
.spyproject
|
134 |
+
|
135 |
+
# Rope project settings
|
136 |
+
.ropeproject
|
137 |
+
|
138 |
+
# mkdocs documentation
|
139 |
+
/site
|
140 |
+
|
141 |
+
# mypy
|
142 |
+
.mypy_cache/
|
143 |
+
.dmypy.json
|
144 |
+
dmypy.json
|
145 |
+
|
146 |
+
# Pyre type checker
|
147 |
+
.pyre/
|
148 |
+
|
149 |
+
# pytype static type analyzer
|
150 |
+
.pytype/
|
151 |
+
|
152 |
+
# Cython debug symbols
|
153 |
+
cython_debug/
|
154 |
+
|
155 |
+
# PyCharm
|
156 |
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
157 |
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
158 |
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
159 |
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
160 |
+
.idea/
|
161 |
+
.vscode/
|
162 |
+
|
163 |
+
workspaces
|
164 |
+
logs
|
165 |
+
|
166 |
+
.DS_STORE
|
167 |
+
.trunk
|
168 |
+
|
169 |
+
.gradio/
|
170 |
+
.ruff_cache/
|
171 |
+
|
172 |
+
.env
|
.python-version
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
3.10
|
.streamlit/config.toml
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[theme]
|
2 |
+
# Primary colors
|
3 |
+
primaryColor="#0D0F18" # --wecopink: 343 98% 63%
|
4 |
+
backgroundColor="#F0EFE9" # --background: 49 10% 94%
|
5 |
+
secondaryBackgroundColor="#FFFFFF" # --card: 60 33.3% 98%
|
6 |
+
textColor="#0A0A0A" # --primary: 0 0% 17%
|
7 |
+
|
8 |
+
# Font
|
9 |
+
font="sans serif"
|
10 |
+
|
11 |
+
[ui]
|
12 |
+
hideTopBar = true
|
13 |
+
|
14 |
+
[client]
|
15 |
+
toolbarMode = "minimal"
|
16 |
+
showErrorDetails = true
|
17 |
+
showSidebarNavigation = false
|
LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
MIT License
|
2 |
+
|
3 |
+
Copyright (c) 2024 Weco AI Ltd
|
4 |
+
|
5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 |
+
of this software and associated documentation files (the "Software"), to deal
|
7 |
+
in the Software without restriction, including without limitation the rights
|
8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9 |
+
copies of the Software, and to permit persons to whom the Software is
|
10 |
+
furnished to do so, subject to the following conditions:
|
11 |
+
|
12 |
+
The above copyright notice and this permission notice shall be included in all
|
13 |
+
copies or substantial portions of the Software.
|
14 |
+
|
15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21 |
+
SOFTWARE.
|
aide/__init__.py
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dataclasses import dataclass
|
2 |
+
|
3 |
+
from .agent import Agent
|
4 |
+
from .interpreter import Interpreter
|
5 |
+
from .journal import Journal
|
6 |
+
from omegaconf import OmegaConf
|
7 |
+
from rich.status import Status
|
8 |
+
from .utils.config import (
|
9 |
+
load_task_desc,
|
10 |
+
prep_agent_workspace,
|
11 |
+
save_run,
|
12 |
+
_load_cfg,
|
13 |
+
prep_cfg,
|
14 |
+
)
|
15 |
+
|
16 |
+
|
17 |
+
@dataclass
|
18 |
+
class Solution:
|
19 |
+
code: str
|
20 |
+
valid_metric: float
|
21 |
+
|
22 |
+
|
23 |
+
class Experiment:
|
24 |
+
|
25 |
+
def __init__(self, data_dir: str, goal: str, eval: str | None = None):
|
26 |
+
"""Initialize a new experiment run.
|
27 |
+
|
28 |
+
Args:
|
29 |
+
data_dir (str): Path to the directory containing the data files.
|
30 |
+
goal (str): Description of the goal of the task.
|
31 |
+
eval (str | None, optional): Optional description of the preferred way for the agent to evaluate its solutions.
|
32 |
+
"""
|
33 |
+
|
34 |
+
_cfg = _load_cfg(use_cli_args=False)
|
35 |
+
_cfg.data_dir = data_dir
|
36 |
+
_cfg.goal = goal
|
37 |
+
_cfg.eval = eval
|
38 |
+
self.cfg = prep_cfg(_cfg)
|
39 |
+
|
40 |
+
self.task_desc = load_task_desc(self.cfg)
|
41 |
+
|
42 |
+
with Status("Preparing agent workspace (copying and extracting files) ..."):
|
43 |
+
prep_agent_workspace(self.cfg)
|
44 |
+
|
45 |
+
self.journal = Journal()
|
46 |
+
self.agent = Agent(
|
47 |
+
task_desc=self.task_desc,
|
48 |
+
cfg=self.cfg,
|
49 |
+
journal=self.journal,
|
50 |
+
)
|
51 |
+
self.interpreter = Interpreter(
|
52 |
+
self.cfg.workspace_dir, **OmegaConf.to_container(self.cfg.exec) # type: ignore
|
53 |
+
)
|
54 |
+
|
55 |
+
def run(self, steps: int) -> Solution:
|
56 |
+
for _i in range(steps):
|
57 |
+
self.agent.step(exec_callback=self.interpreter.run)
|
58 |
+
save_run(self.cfg, self.journal)
|
59 |
+
self.interpreter.cleanup_session()
|
60 |
+
|
61 |
+
best_node = self.journal.get_best_node(only_good=False)
|
62 |
+
return Solution(code=best_node.code, valid_metric=best_node.metric.value)
|
aide/agent.py
ADDED
@@ -0,0 +1,339 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
import random
|
3 |
+
from typing import Any, Callable, cast
|
4 |
+
|
5 |
+
import humanize
|
6 |
+
from .backend import FunctionSpec, query
|
7 |
+
from .interpreter import ExecutionResult
|
8 |
+
from .journal import Journal, Node
|
9 |
+
from .utils import data_preview
|
10 |
+
from .utils.config import Config
|
11 |
+
from .utils.metric import MetricValue, WorstMetricValue
|
12 |
+
from .utils.response import extract_code, extract_text_up_to_code, wrap_code
|
13 |
+
|
14 |
+
logger = logging.getLogger("aide")
|
15 |
+
|
16 |
+
|
17 |
+
ExecCallbackType = Callable[[str, bool], ExecutionResult]
|
18 |
+
|
19 |
+
review_func_spec = FunctionSpec(
|
20 |
+
name="submit_review",
|
21 |
+
json_schema={
|
22 |
+
"type": "object",
|
23 |
+
"properties": {
|
24 |
+
"is_bug": {
|
25 |
+
"type": "boolean",
|
26 |
+
"description": "true if the output log shows that the execution failed or has some bug, otherwise false.",
|
27 |
+
},
|
28 |
+
"summary": {
|
29 |
+
"type": "string",
|
30 |
+
"description": "if there is a bug, propose a fix. Otherwise, write a short summary (2-3 sentences) describing the empirical findings.",
|
31 |
+
},
|
32 |
+
"metric": {
|
33 |
+
"type": "number",
|
34 |
+
"description": "If the code ran successfully, report the value of the validation metric. Otherwise, leave it null.",
|
35 |
+
},
|
36 |
+
"lower_is_better": {
|
37 |
+
"type": "boolean",
|
38 |
+
"description": "true if the metric should be minimized (i.e. a lower metric value is better, such as with MSE), false if the metric should be maximized (i.e. a higher metric value is better, such as with accuracy).",
|
39 |
+
},
|
40 |
+
},
|
41 |
+
"required": ["is_bug", "summary", "metric", "lower_is_better"],
|
42 |
+
},
|
43 |
+
description="Submit a review evaluating the output of the training script.",
|
44 |
+
)
|
45 |
+
|
46 |
+
|
47 |
+
class Agent:
|
48 |
+
def __init__(
|
49 |
+
self,
|
50 |
+
task_desc: str,
|
51 |
+
cfg: Config,
|
52 |
+
journal: Journal,
|
53 |
+
):
|
54 |
+
super().__init__()
|
55 |
+
self.task_desc = task_desc
|
56 |
+
self.cfg = cfg
|
57 |
+
self.acfg = cfg.agent
|
58 |
+
self.journal = journal
|
59 |
+
self.data_preview: str | None = None
|
60 |
+
|
61 |
+
def search_policy(self) -> Node | None:
|
62 |
+
"""Select a node to work on (or None to draft a new node)."""
|
63 |
+
search_cfg = self.acfg.search
|
64 |
+
|
65 |
+
# initial drafting
|
66 |
+
if len(self.journal.draft_nodes) < search_cfg.num_drafts:
|
67 |
+
logger.debug("[search policy] drafting new node (not enough drafts)")
|
68 |
+
return None
|
69 |
+
|
70 |
+
# debugging
|
71 |
+
if random.random() < search_cfg.debug_prob:
|
72 |
+
# nodes that are buggy + leaf nodes + debug depth < max debug depth
|
73 |
+
debuggable_nodes = [
|
74 |
+
n
|
75 |
+
for n in self.journal.buggy_nodes
|
76 |
+
if (n.is_leaf and n.debug_depth <= search_cfg.max_debug_depth)
|
77 |
+
]
|
78 |
+
if debuggable_nodes:
|
79 |
+
logger.debug("[search policy] debugging")
|
80 |
+
return random.choice(debuggable_nodes)
|
81 |
+
logger.debug("[search policy] not debugging by chance")
|
82 |
+
|
83 |
+
# back to drafting if no nodes to improve
|
84 |
+
good_nodes = self.journal.good_nodes
|
85 |
+
if not good_nodes:
|
86 |
+
logger.debug("[search policy] drafting new node (no good nodes)")
|
87 |
+
return None
|
88 |
+
|
89 |
+
# greedy
|
90 |
+
greedy_node = self.journal.get_best_node()
|
91 |
+
logger.debug("[search policy] greedy node selected")
|
92 |
+
return greedy_node
|
93 |
+
|
94 |
+
@property
|
95 |
+
def _prompt_environment(self):
|
96 |
+
pkgs = [
|
97 |
+
"numpy",
|
98 |
+
"pandas",
|
99 |
+
"scikit-learn",
|
100 |
+
"statsmodels",
|
101 |
+
"xgboost",
|
102 |
+
"lightGBM",
|
103 |
+
"torch",
|
104 |
+
"torchvision",
|
105 |
+
"torch-geometric",
|
106 |
+
"bayesian-optimization",
|
107 |
+
"timm",
|
108 |
+
]
|
109 |
+
random.shuffle(pkgs)
|
110 |
+
pkg_str = ", ".join([f"`{p}`" for p in pkgs])
|
111 |
+
|
112 |
+
env_prompt = {
|
113 |
+
"Installed Packages": f"Your solution can use any relevant machine learning packages such as: {pkg_str}. Feel free to use any other packages too (all packages are already installed!). For neural networks we suggest using PyTorch rather than TensorFlow."
|
114 |
+
}
|
115 |
+
return env_prompt
|
116 |
+
|
117 |
+
@property
|
118 |
+
def _prompt_impl_guideline(self):
|
119 |
+
impl_guideline = [
|
120 |
+
"The code should **implement the proposed solution** and **print the value of the evaluation metric computed on a hold-out validation set**.",
|
121 |
+
"The code should be a single-file python program that is self-contained and can be executed as-is.",
|
122 |
+
"No parts of the code should be skipped, don't terminate the before finishing the script.",
|
123 |
+
"Your response should only contain a single code block.",
|
124 |
+
f"Be aware of the running time of the code, it should complete within {humanize.naturaldelta(self.cfg.exec.timeout)}.",
|
125 |
+
'All the provided input data is stored in "./input" directory.',
|
126 |
+
'**If there is test data provided for this task, please save the test predictions in a `submission.csv` file in the "./working" directory as described in the task description** This is extremely important since this file is used for grading/evaluation. DO NOT FORGET THE submission.csv file!',
|
127 |
+
'You can also use the "./working" directory to store any temporary files that your code needs to create.',
|
128 |
+
]
|
129 |
+
if self.acfg.expose_prediction:
|
130 |
+
impl_guideline.append(
|
131 |
+
"The implementation should include a predict() function, "
|
132 |
+
"allowing users to seamlessly reuse the code to make predictions on new data. "
|
133 |
+
"The prediction function should be well-documented, especially the function signature."
|
134 |
+
)
|
135 |
+
|
136 |
+
if self.acfg.k_fold_validation > 1:
|
137 |
+
impl_guideline.append(
|
138 |
+
f"The evaluation should be based on {self.acfg.k_fold_validation}-fold cross-validation but only if that's an appropriate evaluation for the task at hand."
|
139 |
+
)
|
140 |
+
|
141 |
+
return {"Implementation guideline": impl_guideline}
|
142 |
+
|
143 |
+
@property
|
144 |
+
def _prompt_resp_fmt(self):
|
145 |
+
return {
|
146 |
+
"Response format": (
|
147 |
+
"Your response should be a brief outline/sketch of your proposed solution in natural language (3-5 sentences), "
|
148 |
+
"followed by a single markdown code block (wrapped in ```) which implements this solution and prints out the evaluation metric. "
|
149 |
+
"There should be no additional headings or text in your response. Just natural language text followed by a newline and then the markdown code block. "
|
150 |
+
)
|
151 |
+
}
|
152 |
+
|
153 |
+
def plan_and_code_query(self, prompt, retries=3) -> tuple[str, str]:
|
154 |
+
"""Generate a natural language plan + code in the same LLM call and split them apart."""
|
155 |
+
completion_text = None
|
156 |
+
for _ in range(retries):
|
157 |
+
completion_text = query(
|
158 |
+
system_message=prompt,
|
159 |
+
user_message=None,
|
160 |
+
model=self.acfg.code.model,
|
161 |
+
temperature=self.acfg.code.temp,
|
162 |
+
)
|
163 |
+
|
164 |
+
code = extract_code(completion_text)
|
165 |
+
nl_text = extract_text_up_to_code(completion_text)
|
166 |
+
|
167 |
+
if code and nl_text:
|
168 |
+
# merge all code blocks into a single string
|
169 |
+
return nl_text, code
|
170 |
+
|
171 |
+
print("Plan + code extraction failed, retrying...")
|
172 |
+
print("Final plan + code extraction attempt failed, giving up...")
|
173 |
+
return "", completion_text # type: ignore
|
174 |
+
|
175 |
+
def _draft(self) -> Node:
|
176 |
+
prompt: Any = {
|
177 |
+
"Introduction": (
|
178 |
+
"You are a Kaggle grandmaster attending a competition. "
|
179 |
+
"In order to win this competition, you need to come up with an excellent and creative plan "
|
180 |
+
"for a solution and then implement this solution in Python. We will now provide a description of the task."
|
181 |
+
),
|
182 |
+
"Task description": self.task_desc,
|
183 |
+
"Memory": self.journal.generate_summary(),
|
184 |
+
"Instructions": {},
|
185 |
+
}
|
186 |
+
prompt["Instructions"] |= self._prompt_resp_fmt
|
187 |
+
prompt["Instructions"] |= {
|
188 |
+
"Solution sketch guideline": [
|
189 |
+
"This first solution design should be relatively simple, without ensembling or hyper-parameter optimization.",
|
190 |
+
"Take the Memory section into consideration when proposing the design,"
|
191 |
+
" don't propose the same modelling solution but keep the evaluation the same.",
|
192 |
+
"The solution sketch should be 3-5 sentences.",
|
193 |
+
"Propose an evaluation metric that is reasonable for this task.",
|
194 |
+
"Don't suggest to do EDA.",
|
195 |
+
"The data is already prepared and available in the `./input` directory. There is no need to unzip any files.",
|
196 |
+
],
|
197 |
+
}
|
198 |
+
prompt["Instructions"] |= self._prompt_impl_guideline
|
199 |
+
prompt["Instructions"] |= self._prompt_environment
|
200 |
+
|
201 |
+
if self.acfg.data_preview:
|
202 |
+
prompt["Data Overview"] = self.data_preview
|
203 |
+
|
204 |
+
plan, code = self.plan_and_code_query(prompt)
|
205 |
+
return Node(plan=plan, code=code)
|
206 |
+
|
207 |
+
def _improve(self, parent_node: Node) -> Node:
|
208 |
+
prompt: Any = {
|
209 |
+
"Introduction": (
|
210 |
+
"You are a Kaggle grandmaster attending a competition. You are provided with a previously developed "
|
211 |
+
"solution below and should improve it in order to further increase the (test time) performance. "
|
212 |
+
"For this you should first outline a brief plan in natural language for how the solution can be improved and "
|
213 |
+
"then implement this improvement in Python based on the provided previous solution. "
|
214 |
+
),
|
215 |
+
"Task description": self.task_desc,
|
216 |
+
"Memory": self.journal.generate_summary(),
|
217 |
+
"Instructions": {},
|
218 |
+
}
|
219 |
+
prompt["Previous solution"] = {
|
220 |
+
"Code": wrap_code(parent_node.code),
|
221 |
+
}
|
222 |
+
|
223 |
+
prompt["Instructions"] |= self._prompt_resp_fmt
|
224 |
+
prompt["Instructions"] |= {
|
225 |
+
"Solution improvement sketch guideline": [
|
226 |
+
"The solution sketch should be a brief natural language description of how the previous solution can be improved.",
|
227 |
+
"You should be very specific and should only propose a single actionable improvement.",
|
228 |
+
"This improvement should be atomic so that we can experimentally evaluate the effect of the proposed change.",
|
229 |
+
"Take the Memory section into consideration when proposing the improvement.",
|
230 |
+
"The solution sketch should be 3-5 sentences.",
|
231 |
+
"Don't suggest to do EDA.",
|
232 |
+
],
|
233 |
+
}
|
234 |
+
prompt["Instructions"] |= self._prompt_impl_guideline
|
235 |
+
|
236 |
+
plan, code = self.plan_and_code_query(prompt)
|
237 |
+
return Node(
|
238 |
+
plan=plan,
|
239 |
+
code=code,
|
240 |
+
parent=parent_node,
|
241 |
+
)
|
242 |
+
|
243 |
+
def _debug(self, parent_node: Node) -> Node:
|
244 |
+
prompt: Any = {
|
245 |
+
"Introduction": (
|
246 |
+
"You are a Kaggle grandmaster attending a competition. "
|
247 |
+
"Your previous solution had a bug, so based on the information below, you should revise it in order to fix this bug. "
|
248 |
+
"Your response should be an implementation outline in natural language,"
|
249 |
+
" followed by a single markdown code block which implements the bugfix/solution."
|
250 |
+
),
|
251 |
+
"Task description": self.task_desc,
|
252 |
+
"Previous (buggy) implementation": wrap_code(parent_node.code),
|
253 |
+
"Execution output": wrap_code(parent_node.term_out, lang=""),
|
254 |
+
"Instructions": {},
|
255 |
+
}
|
256 |
+
prompt["Instructions"] |= self._prompt_resp_fmt
|
257 |
+
prompt["Instructions"] |= {
|
258 |
+
"Bugfix improvement sketch guideline": [
|
259 |
+
"You should write a brief natural language description (3-5 sentences) of how the issue in the previous implementation can be fixed.",
|
260 |
+
"Don't suggest to do EDA.",
|
261 |
+
],
|
262 |
+
}
|
263 |
+
prompt["Instructions"] |= self._prompt_impl_guideline
|
264 |
+
|
265 |
+
if self.acfg.data_preview:
|
266 |
+
prompt["Data Overview"] = self.data_preview
|
267 |
+
|
268 |
+
plan, code = self.plan_and_code_query(prompt)
|
269 |
+
return Node(plan=plan, code=code, parent=parent_node)
|
270 |
+
|
271 |
+
def update_data_preview(
|
272 |
+
self,
|
273 |
+
):
|
274 |
+
self.data_preview = data_preview.generate(self.cfg.workspace_dir)
|
275 |
+
|
276 |
+
def step(self, exec_callback: ExecCallbackType):
|
277 |
+
if not self.journal.nodes or self.data_preview is None:
|
278 |
+
self.update_data_preview()
|
279 |
+
|
280 |
+
parent_node = self.search_policy()
|
281 |
+
logger.debug(f"Agent is generating code, parent node type: {type(parent_node)}")
|
282 |
+
|
283 |
+
if parent_node is None:
|
284 |
+
result_node = self._draft()
|
285 |
+
elif parent_node.is_buggy:
|
286 |
+
result_node = self._debug(parent_node)
|
287 |
+
else:
|
288 |
+
result_node = self._improve(parent_node)
|
289 |
+
|
290 |
+
self.parse_exec_result(
|
291 |
+
node=result_node,
|
292 |
+
exec_result=exec_callback(result_node.code, True),
|
293 |
+
)
|
294 |
+
self.journal.append(result_node)
|
295 |
+
|
296 |
+
def parse_exec_result(self, node: Node, exec_result: ExecutionResult):
|
297 |
+
logger.info(f"Agent is parsing execution results for node {node.id}")
|
298 |
+
|
299 |
+
node.absorb_exec_result(exec_result)
|
300 |
+
|
301 |
+
prompt = {
|
302 |
+
"Introduction": (
|
303 |
+
"You are a Kaggle grandmaster attending a competition. "
|
304 |
+
"You have written code to solve this task and now need to evaluate the output of the code execution. "
|
305 |
+
"You should determine if there were any bugs as well as report the empirical findings."
|
306 |
+
),
|
307 |
+
"Task description": self.task_desc,
|
308 |
+
"Implementation": wrap_code(node.code),
|
309 |
+
"Execution output": wrap_code(node.term_out, lang=""),
|
310 |
+
}
|
311 |
+
|
312 |
+
response = cast(
|
313 |
+
dict,
|
314 |
+
query(
|
315 |
+
system_message=prompt,
|
316 |
+
user_message=None,
|
317 |
+
func_spec=review_func_spec,
|
318 |
+
model=self.acfg.feedback.model,
|
319 |
+
temperature=self.acfg.feedback.temp,
|
320 |
+
),
|
321 |
+
)
|
322 |
+
|
323 |
+
# if the metric isn't a float then fill the metric with the worst metric
|
324 |
+
if not isinstance(response["metric"], float):
|
325 |
+
response["metric"] = None
|
326 |
+
|
327 |
+
node.analysis = response["summary"]
|
328 |
+
node.is_buggy = (
|
329 |
+
response["is_bug"]
|
330 |
+
or node.exc_type is not None
|
331 |
+
or response["metric"] is None
|
332 |
+
)
|
333 |
+
|
334 |
+
if node.is_buggy:
|
335 |
+
node.metric = WorstMetricValue()
|
336 |
+
else:
|
337 |
+
node.metric = MetricValue(
|
338 |
+
response["metric"], maximize=not response["lower_is_better"]
|
339 |
+
)
|
aide/backend/__init__.py
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from . import backend_anthropic, backend_openai
|
2 |
+
from .utils import FunctionSpec, OutputType, PromptType, compile_prompt_to_md
|
3 |
+
|
4 |
+
|
5 |
+
def query(
|
6 |
+
system_message: PromptType | None,
|
7 |
+
user_message: PromptType | None,
|
8 |
+
model: str,
|
9 |
+
temperature: float | None = None,
|
10 |
+
max_tokens: int | None = None,
|
11 |
+
func_spec: FunctionSpec | None = None,
|
12 |
+
**model_kwargs,
|
13 |
+
) -> OutputType:
|
14 |
+
"""
|
15 |
+
General LLM query for various backends with a single system and user message.
|
16 |
+
Supports function calling for some backends.
|
17 |
+
|
18 |
+
Args:
|
19 |
+
system_message (PromptType | None): Uncompiled system message (will generate a message following the OpenAI/Anthropic format)
|
20 |
+
user_message (PromptType | None): Uncompiled user message (will generate a message following the OpenAI/Anthropic format)
|
21 |
+
model (str): string identifier for the model to use (e.g. "gpt-4-turbo")
|
22 |
+
temperature (float | None, optional): Temperature to sample at. Defaults to the model-specific default.
|
23 |
+
max_tokens (int | None, optional): Maximum number of tokens to generate. Defaults to the model-specific max tokens.
|
24 |
+
func_spec (FunctionSpec | None, optional): Optional FunctionSpec object defining a function call. If given, the return value will be a dict.
|
25 |
+
|
26 |
+
Returns:
|
27 |
+
OutputType: A string completion if func_spec is None, otherwise a dict with the function call details.
|
28 |
+
"""
|
29 |
+
|
30 |
+
model_kwargs = model_kwargs | {
|
31 |
+
"model": model,
|
32 |
+
"temperature": temperature,
|
33 |
+
"max_tokens": max_tokens,
|
34 |
+
}
|
35 |
+
|
36 |
+
# Handle models with beta limitations
|
37 |
+
# ref: https://platform.openai.com/docs/guides/reasoning/beta-limitations
|
38 |
+
if model.startswith("o1"):
|
39 |
+
if system_message:
|
40 |
+
user_message = system_message
|
41 |
+
system_message = None
|
42 |
+
model_kwargs["temperature"] = 1
|
43 |
+
|
44 |
+
query_func = backend_anthropic.query if "claude-" in model else backend_openai.query
|
45 |
+
output, req_time, in_tok_count, out_tok_count, info = query_func(
|
46 |
+
system_message=compile_prompt_to_md(system_message) if system_message else None,
|
47 |
+
user_message=compile_prompt_to_md(user_message) if user_message else None,
|
48 |
+
func_spec=func_spec,
|
49 |
+
**model_kwargs,
|
50 |
+
)
|
51 |
+
|
52 |
+
return output
|
aide/backend/backend_anthropic.py
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""Backend for Anthropic API."""
|
2 |
+
|
3 |
+
import logging
|
4 |
+
import time
|
5 |
+
|
6 |
+
from .utils import FunctionSpec, OutputType, opt_messages_to_list, backoff_create
|
7 |
+
from funcy import notnone, once, select_values
|
8 |
+
import anthropic
|
9 |
+
|
10 |
+
logger = logging.getLogger("aide")
|
11 |
+
|
12 |
+
_client: anthropic.Anthropic = None # type: ignore
|
13 |
+
|
14 |
+
ANTHROPIC_TIMEOUT_EXCEPTIONS = (
|
15 |
+
anthropic.RateLimitError,
|
16 |
+
anthropic.APIConnectionError,
|
17 |
+
anthropic.APITimeoutError,
|
18 |
+
anthropic.InternalServerError,
|
19 |
+
)
|
20 |
+
|
21 |
+
ANTHROPIC_MODEL_ALIASES = {
|
22 |
+
"claude-3.5-sonnet": "claude-3-sonnet-20241022",
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
@once
|
27 |
+
def _setup_anthropic_client():
|
28 |
+
global _client
|
29 |
+
_client = anthropic.Anthropic(max_retries=0)
|
30 |
+
|
31 |
+
|
32 |
+
def query(
|
33 |
+
system_message: str | None,
|
34 |
+
user_message: str | None,
|
35 |
+
func_spec: FunctionSpec | None = None,
|
36 |
+
**model_kwargs,
|
37 |
+
) -> tuple[OutputType, float, int, int, dict]:
|
38 |
+
"""
|
39 |
+
Query Anthropic's API, optionally with tool use (Anthropic's equivalent to function calling).
|
40 |
+
"""
|
41 |
+
_setup_anthropic_client()
|
42 |
+
|
43 |
+
filtered_kwargs: dict = select_values(notnone, model_kwargs) # type: ignore
|
44 |
+
if "max_tokens" not in filtered_kwargs:
|
45 |
+
filtered_kwargs["max_tokens"] = 4096 # default for Claude models
|
46 |
+
|
47 |
+
model_name = filtered_kwargs.get("model", "")
|
48 |
+
logger.debug(f"Anthropic query called with model='{model_name}'")
|
49 |
+
|
50 |
+
if model_name in ANTHROPIC_MODEL_ALIASES:
|
51 |
+
model_name = ANTHROPIC_MODEL_ALIASES[model_name]
|
52 |
+
|
53 |
+
if func_spec is not None and func_spec.name == "submit_review":
|
54 |
+
filtered_kwargs["tools"] = [func_spec.as_anthropic_tool_dict]
|
55 |
+
# Force tool use
|
56 |
+
filtered_kwargs["tool_choice"] = func_spec.anthropic_tool_choice_dict
|
57 |
+
|
58 |
+
# Anthropic doesn't allow not having user messages
|
59 |
+
# if we only have system msg -> use it as user msg
|
60 |
+
if system_message is not None and user_message is None:
|
61 |
+
system_message, user_message = user_message, system_message
|
62 |
+
|
63 |
+
# Anthropic passes system messages as a separate argument
|
64 |
+
if system_message is not None:
|
65 |
+
filtered_kwargs["system"] = system_message
|
66 |
+
|
67 |
+
messages = opt_messages_to_list(None, user_message)
|
68 |
+
|
69 |
+
t0 = time.time()
|
70 |
+
message = backoff_create(
|
71 |
+
_client.messages.create,
|
72 |
+
ANTHROPIC_TIMEOUT_EXCEPTIONS,
|
73 |
+
messages=messages,
|
74 |
+
**filtered_kwargs,
|
75 |
+
)
|
76 |
+
req_time = time.time() - t0
|
77 |
+
|
78 |
+
# Handle tool calls if present
|
79 |
+
if (
|
80 |
+
func_spec is not None
|
81 |
+
and "tools" in filtered_kwargs
|
82 |
+
and len(message.content) > 0
|
83 |
+
and message.content[0].type == "tool_use"
|
84 |
+
):
|
85 |
+
block = message.content[0] # This is a "ToolUseBlock"
|
86 |
+
# block has attributes: type, id, name, input
|
87 |
+
assert (
|
88 |
+
block.name == func_spec.name
|
89 |
+
), f"Function name mismatch: expected {func_spec.name}, got {block.name}"
|
90 |
+
output = block.input # Anthropic calls the parameters "input"
|
91 |
+
else:
|
92 |
+
# For non-tool responses, ensure we have text content
|
93 |
+
assert len(message.content) == 1, "Expected single content item"
|
94 |
+
assert (
|
95 |
+
message.content[0].type == "text"
|
96 |
+
), f"Expected text response, got {message.content[0].type}"
|
97 |
+
output = message.content[0].text
|
98 |
+
|
99 |
+
in_tokens = message.usage.input_tokens
|
100 |
+
out_tokens = message.usage.output_tokens
|
101 |
+
|
102 |
+
info = {
|
103 |
+
"stop_reason": message.stop_reason,
|
104 |
+
"model": message.model,
|
105 |
+
}
|
106 |
+
|
107 |
+
return output, req_time, in_tokens, out_tokens, info
|
aide/backend/backend_openai.py
ADDED
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""Backend for OpenAI API."""
|
2 |
+
|
3 |
+
import json
|
4 |
+
import logging
|
5 |
+
import time
|
6 |
+
|
7 |
+
from .utils import FunctionSpec, OutputType, opt_messages_to_list, backoff_create
|
8 |
+
from funcy import notnone, once, select_values
|
9 |
+
import openai
|
10 |
+
|
11 |
+
logger = logging.getLogger("aide")
|
12 |
+
|
13 |
+
_client: openai.OpenAI = None # type: ignore
|
14 |
+
|
15 |
+
OPENAI_TIMEOUT_EXCEPTIONS = (
|
16 |
+
openai.RateLimitError,
|
17 |
+
openai.APIConnectionError,
|
18 |
+
openai.APITimeoutError,
|
19 |
+
openai.InternalServerError,
|
20 |
+
)
|
21 |
+
|
22 |
+
|
23 |
+
@once
|
24 |
+
def _setup_openai_client():
|
25 |
+
global _client
|
26 |
+
_client = openai.OpenAI(max_retries=0)
|
27 |
+
|
28 |
+
|
29 |
+
def query(
|
30 |
+
system_message: str | None,
|
31 |
+
user_message: str | None,
|
32 |
+
func_spec: FunctionSpec | None = None,
|
33 |
+
**model_kwargs,
|
34 |
+
) -> tuple[OutputType, float, int, int, dict]:
|
35 |
+
"""
|
36 |
+
Query the OpenAI API, optionally with function calling.
|
37 |
+
If the model doesn't support function calling, gracefully degrade to text generation.
|
38 |
+
"""
|
39 |
+
_setup_openai_client()
|
40 |
+
filtered_kwargs: dict = select_values(notnone, model_kwargs)
|
41 |
+
|
42 |
+
# Convert system/user messages to the format required by the client
|
43 |
+
messages = opt_messages_to_list(system_message, user_message)
|
44 |
+
|
45 |
+
# If function calling is requested, attach the function spec
|
46 |
+
if func_spec is not None:
|
47 |
+
filtered_kwargs["tools"] = [func_spec.as_openai_tool_dict]
|
48 |
+
filtered_kwargs["tool_choice"] = func_spec.openai_tool_choice_dict
|
49 |
+
|
50 |
+
completion = None
|
51 |
+
t0 = time.time()
|
52 |
+
|
53 |
+
# Attempt the API call
|
54 |
+
try:
|
55 |
+
completion = backoff_create(
|
56 |
+
_client.chat.completions.create,
|
57 |
+
OPENAI_TIMEOUT_EXCEPTIONS,
|
58 |
+
messages=messages,
|
59 |
+
**filtered_kwargs,
|
60 |
+
)
|
61 |
+
except openai.error.BadRequestError as e:
|
62 |
+
# Check whether the error indicates that function calling is not supported
|
63 |
+
if "function calling" in str(e).lower() or "tools" in str(e).lower():
|
64 |
+
logger.warning(
|
65 |
+
"Function calling was attempted but is not supported by this model. "
|
66 |
+
"Falling back to plain text generation."
|
67 |
+
)
|
68 |
+
# Remove function-calling parameters and retry
|
69 |
+
filtered_kwargs.pop("tools", None)
|
70 |
+
filtered_kwargs.pop("tool_choice", None)
|
71 |
+
|
72 |
+
# Retry without function calling
|
73 |
+
completion = backoff_create(
|
74 |
+
_client.chat.completions.create,
|
75 |
+
OPENAI_TIMEOUT_EXCEPTIONS,
|
76 |
+
messages=messages,
|
77 |
+
**filtered_kwargs,
|
78 |
+
)
|
79 |
+
else:
|
80 |
+
# If it's some other error, re-raise
|
81 |
+
raise
|
82 |
+
|
83 |
+
req_time = time.time() - t0
|
84 |
+
choice = completion.choices[0]
|
85 |
+
|
86 |
+
# Decide how to parse the response
|
87 |
+
if func_spec is None or "tools" not in filtered_kwargs:
|
88 |
+
# No function calling was ultimately used
|
89 |
+
output = choice.message.content
|
90 |
+
else:
|
91 |
+
# Attempt to extract tool calls
|
92 |
+
tool_calls = getattr(choice.message, "tool_calls", None)
|
93 |
+
if not tool_calls:
|
94 |
+
logger.warning(
|
95 |
+
"No function call was used despite function spec. Fallback to text.\n"
|
96 |
+
f"Message content: {choice.message.content}"
|
97 |
+
)
|
98 |
+
output = choice.message.content
|
99 |
+
else:
|
100 |
+
first_call = tool_calls[0]
|
101 |
+
# Optional: verify that the function name matches
|
102 |
+
if first_call.function.name != func_spec.name:
|
103 |
+
logger.warning(
|
104 |
+
f"Function name mismatch: expected {func_spec.name}, "
|
105 |
+
f"got {first_call.function.name}. Fallback to text."
|
106 |
+
)
|
107 |
+
output = choice.message.content
|
108 |
+
else:
|
109 |
+
try:
|
110 |
+
output = json.loads(first_call.function.arguments)
|
111 |
+
except json.JSONDecodeError as ex:
|
112 |
+
logger.error(
|
113 |
+
"Error decoding function arguments:\n"
|
114 |
+
f"{first_call.function.arguments}"
|
115 |
+
)
|
116 |
+
raise ex
|
117 |
+
|
118 |
+
in_tokens = completion.usage.prompt_tokens
|
119 |
+
out_tokens = completion.usage.completion_tokens
|
120 |
+
|
121 |
+
info = {
|
122 |
+
"system_fingerprint": completion.system_fingerprint,
|
123 |
+
"model": completion.model,
|
124 |
+
"created": completion.created,
|
125 |
+
}
|
126 |
+
|
127 |
+
return output, req_time, in_tokens, out_tokens, info
|
aide/backend/utils.py
ADDED
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dataclasses import dataclass
|
2 |
+
|
3 |
+
import jsonschema
|
4 |
+
from dataclasses_json import DataClassJsonMixin
|
5 |
+
import backoff
|
6 |
+
import logging
|
7 |
+
from typing import Callable
|
8 |
+
|
9 |
+
PromptType = str | dict | list
|
10 |
+
FunctionCallType = dict
|
11 |
+
OutputType = str | FunctionCallType
|
12 |
+
|
13 |
+
|
14 |
+
logger = logging.getLogger("aide")
|
15 |
+
|
16 |
+
|
17 |
+
@backoff.on_predicate(
|
18 |
+
wait_gen=backoff.expo,
|
19 |
+
max_value=60,
|
20 |
+
factor=1.5,
|
21 |
+
)
|
22 |
+
def backoff_create(
|
23 |
+
create_fn: Callable, retry_exceptions: list[Exception], *args, **kwargs
|
24 |
+
):
|
25 |
+
try:
|
26 |
+
return create_fn(*args, **kwargs)
|
27 |
+
except retry_exceptions as e:
|
28 |
+
logger.info(f"Backoff exception: {e}")
|
29 |
+
return False
|
30 |
+
|
31 |
+
|
32 |
+
def opt_messages_to_list(
|
33 |
+
system_message: str | None, user_message: str | None
|
34 |
+
) -> list[dict[str, str]]:
|
35 |
+
messages = []
|
36 |
+
if system_message:
|
37 |
+
messages.append({"role": "system", "content": system_message})
|
38 |
+
if user_message:
|
39 |
+
messages.append({"role": "user", "content": user_message})
|
40 |
+
return messages
|
41 |
+
|
42 |
+
|
43 |
+
def compile_prompt_to_md(prompt: PromptType, _header_depth: int = 1) -> str:
|
44 |
+
if isinstance(prompt, str):
|
45 |
+
return prompt.strip() + "\n"
|
46 |
+
elif isinstance(prompt, list):
|
47 |
+
return "\n".join([f"- {s.strip()}" for s in prompt] + ["\n"])
|
48 |
+
|
49 |
+
out = []
|
50 |
+
header_prefix = "#" * _header_depth
|
51 |
+
for k, v in prompt.items():
|
52 |
+
out.append(f"{header_prefix} {k}\n")
|
53 |
+
out.append(compile_prompt_to_md(v, _header_depth=_header_depth + 1))
|
54 |
+
return "\n".join(out)
|
55 |
+
|
56 |
+
|
57 |
+
@dataclass
|
58 |
+
class FunctionSpec(DataClassJsonMixin):
|
59 |
+
name: str
|
60 |
+
json_schema: dict # JSON schema
|
61 |
+
description: str
|
62 |
+
|
63 |
+
def __post_init__(self):
|
64 |
+
# validate the schema
|
65 |
+
jsonschema.Draft7Validator.check_schema(self.json_schema)
|
66 |
+
|
67 |
+
@property
|
68 |
+
def as_openai_tool_dict(self):
|
69 |
+
"""Convert to OpenAI's function format."""
|
70 |
+
return {
|
71 |
+
"type": "function",
|
72 |
+
"function": {
|
73 |
+
"name": self.name,
|
74 |
+
"description": self.description,
|
75 |
+
"parameters": self.json_schema,
|
76 |
+
},
|
77 |
+
}
|
78 |
+
|
79 |
+
@property
|
80 |
+
def openai_tool_choice_dict(self):
|
81 |
+
return {
|
82 |
+
"type": "function",
|
83 |
+
"function": {"name": self.name},
|
84 |
+
}
|
85 |
+
|
86 |
+
@property
|
87 |
+
def as_anthropic_tool_dict(self):
|
88 |
+
"""Convert to Anthropic's tool format."""
|
89 |
+
return {
|
90 |
+
"name": self.name,
|
91 |
+
"description": self.description,
|
92 |
+
"input_schema": self.json_schema, # Anthropic uses input_schema instead of parameters
|
93 |
+
}
|
94 |
+
|
95 |
+
@property
|
96 |
+
def anthropic_tool_choice_dict(self):
|
97 |
+
"""Convert to Anthropic's tool choice format."""
|
98 |
+
return {
|
99 |
+
"type": "tool", # Anthropic uses "tool" instead of "function"
|
100 |
+
"name": self.name,
|
101 |
+
}
|
aide/example_tasks/bitcoin_price.md
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
## Goal
|
2 |
+
Build a timeseries forcasting model for bitcoin close price.
|
3 |
+
|
4 |
+
## Evaluation metric
|
5 |
+
Root-Mean-Squared-Error (RMSE) between the logarithm of the predicted value and the logarithm of the observed price.
|
aide/example_tasks/bitcoin_price/BTC-USD.csv
ADDED
@@ -0,0 +1,501 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Date,Open,High,Low,Close,Adj Close,Volume
|
2 |
+
2014-09-15,465.864014,468.174011,384.532013,398.821014,398.821014,156903400
|
3 |
+
2014-09-22,399.100006,441.557007,374.332001,377.181000,377.181000,186772600
|
4 |
+
2014-09-29,376.928009,391.378998,289.295990,320.510010,320.510010,276657896
|
5 |
+
2014-10-06,320.389008,382.726013,302.559998,378.549011,378.549011,341152804
|
6 |
+
2014-10-13,377.920990,411.697998,368.897003,389.545990,389.545990,156902070
|
7 |
+
2014-10-20,389.230988,392.645996,342.877014,354.704010,354.704010,113691800
|
8 |
+
2014-10-27,354.777008,359.984009,320.626007,325.891998,325.891998,107075700
|
9 |
+
2014-11-03,325.569000,363.626007,325.076996,363.264008,363.264008,116793470
|
10 |
+
2014-11-10,362.265015,457.092987,357.561005,387.881989,387.881989,208239500
|
11 |
+
2014-11-17,388.348999,410.199005,344.112000,367.572998,367.572998,178181000
|
12 |
+
2014-11-24,366.947998,394.700989,358.454987,378.046997,378.046997,131238570
|
13 |
+
2014-12-01,378.248993,384.037994,365.756012,375.095001,375.095001,80679570
|
14 |
+
2014-12-08,374.964996,376.028992,338.763000,351.631989,351.631989,141754100
|
15 |
+
2014-12-15,351.360992,351.815002,304.231995,320.842987,320.842987,184757400
|
16 |
+
2014-12-22,321.067993,336.286987,311.078003,317.239014,317.239014,107137540
|
17 |
+
2014-12-29,317.700989,320.434998,257.612000,264.195007,264.195007,143354400
|
18 |
+
2015-01-05,265.084015,298.753998,265.039001,265.660004,265.660004,164241500
|
19 |
+
2015-01-12,266.145996,272.203003,171.509995,210.339005,210.339005,363112212
|
20 |
+
2015-01-19,211.470993,255.074005,205.153000,253.718002,253.718002,189165500
|
21 |
+
2015-01-26,254.078995,309.384003,212.014999,226.972000,226.972000,306840500
|
22 |
+
2015-02-02,226.490997,245.957001,214.725006,223.412003,223.412003,183691200
|
23 |
+
2015-02-09,223.389008,265.610992,215.332001,234.824997,234.824997,230343800
|
24 |
+
2015-02-16,234.824997,255.320007,229.022003,235.977005,235.977005,154676000
|
25 |
+
2015-02-23,235.994995,261.660004,232.421005,260.201996,260.201996,138892900
|
26 |
+
2015-03-02,260.356995,285.795990,258.312988,274.354004,274.354004,242425100
|
27 |
+
2015-03-09,274.812012,300.044006,273.893005,286.393005,286.393005,259502000
|
28 |
+
2015-03-16,285.684998,294.112000,248.636002,267.959991,267.959991,206778200
|
29 |
+
2015-03-23,267.894989,277.296997,236.514999,242.712997,242.712997,179497700
|
30 |
+
2015-03-30,242.878998,260.674988,239.214005,260.597992,260.597992,150120700
|
31 |
+
2015-04-06,260.721008,261.798004,232.770996,236.153000,236.153000,147866600
|
32 |
+
2015-04-13,235.949997,236.934998,216.322998,222.600006,222.600006,158658500
|
33 |
+
2015-04-20,222.612000,237.908997,214.873993,219.429993,219.429993,148576200
|
34 |
+
2015-04-27,219.429001,243.240005,218.022995,240.358002,240.358002,162643200
|
35 |
+
2015-05-04,240.356003,247.804001,228.572998,240.296005,240.296005,166059200
|
36 |
+
2015-05-11,240.298996,244.270004,234.057007,236.802002,236.802002,130322100
|
37 |
+
2015-05-18,236.886993,241.977997,231.817001,240.953003,240.953003,114746500
|
38 |
+
2015-05-25,240.927002,241.020996,229.542007,230.190002,230.190002,107149900
|
39 |
+
2015-06-01,230.233002,231.712997,221.296005,222.880997,222.880997,121536400
|
40 |
+
2015-06-08,222.878998,234.858002,222.839005,233.542999,233.542999,121541200
|
41 |
+
2015-06-15,233.421997,256.852997,233.421997,243.944000,243.944000,191537000
|
42 |
+
2015-06-22,243.968994,251.339005,240.365005,249.011002,249.011002,115888900
|
43 |
+
2015-06-29,248.720993,274.506012,248.580994,271.912994,271.912994,206668700
|
44 |
+
2015-07-06,271.108002,314.394012,264.385986,310.867004,310.867004,353198700
|
45 |
+
2015-07-13,310.826996,310.947998,272.042999,273.614014,273.614014,235861300
|
46 |
+
2015-07-20,273.498993,293.052002,272.959991,292.686005,292.686005,157457100
|
47 |
+
2015-07-27,292.639008,297.773987,277.528992,282.614014,282.614014,162700300
|
48 |
+
2015-08-03,282.806000,285.714996,260.467987,265.083008,265.083008,207110300
|
49 |
+
2015-08-10,265.477997,270.673004,257.040985,258.506989,258.506989,177043500
|
50 |
+
2015-08-17,258.489990,260.505005,211.078995,228.169006,228.169006,221695600
|
51 |
+
2015-08-24,228.112000,235.218994,199.567001,228.761002,228.761002,241915000
|
52 |
+
2015-08-31,229.113998,242.912003,225.914993,239.839996,239.839996,144635800
|
53 |
+
2015-09-07,239.934006,245.781006,229.332001,230.511993,230.511993,148588700
|
54 |
+
2015-09-14,230.608994,259.182007,227.401993,231.212006,231.212006,126654700
|
55 |
+
2015-09-21,231.216995,237.427002,225.117004,232.757004,232.757004,137307600
|
56 |
+
2015-09-28,232.835999,239.802002,232.466995,238.259003,238.259003,136796200
|
57 |
+
2015-10-05,238.147003,247.242996,237.035004,247.050003,247.050003,142478600
|
58 |
+
2015-10-12,246.875000,273.578003,243.757004,261.643005,261.643005,199808300
|
59 |
+
2015-10-19,261.860992,294.058990,260.950989,283.679993,283.679993,220696500
|
60 |
+
2015-10-26,283.627991,334.169006,280.510010,325.431000,325.431000,357648800
|
61 |
+
2015-11-02,325.941986,495.562012,323.209015,373.368011,373.368011,954934692
|
62 |
+
2015-11-09,374.324005,385.278015,300.997009,320.165985,320.165985,484398204
|
63 |
+
2015-11-16,319.734985,338.350006,312.217010,324.536011,324.536011,292569400
|
64 |
+
2015-11-23,324.350006,371.938995,316.769989,371.294006,371.294006,337018400
|
65 |
+
2015-11-30,371.437012,402.808990,349.464996,388.782990,388.782990,416857500
|
66 |
+
2015-12-07,389.977997,469.102997,385.411011,433.755005,433.755005,562276900
|
67 |
+
2015-12-14,433.272003,465.580994,430.455994,442.684998,442.684998,553061704
|
68 |
+
2015-12-21,442.838013,458.455994,405.760010,422.822998,422.822998,441634396
|
69 |
+
2015-12-28,423.342987,436.246002,418.480988,430.010986,430.010986,300130400
|
70 |
+
2016-01-04,430.061005,462.933990,426.341003,447.990997,447.990997,319871700
|
71 |
+
2016-01-11,448.697998,450.661987,354.914001,382.299011,382.299011,692913108
|
72 |
+
2016-01-18,381.733002,425.266998,375.282013,402.971008,402.971008,493900500
|
73 |
+
2016-01-25,402.316986,402.316986,365.451996,368.766998,368.766998,378185696
|
74 |
+
2016-02-01,369.350006,391.608002,367.957001,376.619995,376.619995,337404904
|
75 |
+
2016-02-08,376.756989,407.230011,372.898010,407.230011,407.230011,465920396
|
76 |
+
2016-02-15,407.567993,448.045990,397.748993,438.798004,438.798004,546633900
|
77 |
+
2016-02-22,438.989014,439.858002,413.907013,433.503998,433.503998,465584792
|
78 |
+
2016-02-29,433.437988,441.506989,394.035004,407.707001,407.707001,628483380
|
79 |
+
2016-03-07,407.756989,423.925995,406.308990,414.065002,414.065002,548114688
|
80 |
+
2016-03-14,414.200989,420.997009,406.136993,413.755005,413.755005,520066400
|
81 |
+
2016-03-21,413.417999,428.796997,410.381012,426.765015,426.765015,426699404
|
82 |
+
2016-03-28,426.548004,426.856995,412.496002,420.903992,420.903992,405154204
|
83 |
+
2016-04-04,421.299011,425.360992,416.515015,421.563995,421.563995,415027900
|
84 |
+
2016-04-11,421.872009,432.625000,420.532990,427.398987,427.398987,382137900
|
85 |
+
2016-04-18,427.610992,460.145996,427.085999,458.554993,458.554993,427064400
|
86 |
+
2016-04-25,459.121002,467.964996,436.649994,451.875000,451.875000,492934504
|
87 |
+
2016-05-02,451.933014,461.375000,441.776001,458.548004,458.548004,403817800
|
88 |
+
2016-05-09,458.205994,462.480988,448.954010,457.567993,457.567993,351471700
|
89 |
+
2016-05-16,457.585999,458.200012,437.389008,439.322998,439.322998,470557100
|
90 |
+
2016-05-23,439.347992,553.960022,438.822998,526.232971,526.232971,741517392
|
91 |
+
2016-05-30,528.471008,590.132019,520.661987,574.976990,574.976990,658668096
|
92 |
+
2016-06-06,574.601990,684.843994,567.513977,672.783997,672.783997,757909588
|
93 |
+
2016-06-13,671.653992,777.989990,662.804016,763.781006,763.781006,1553070776
|
94 |
+
2016-06-20,763.927002,764.083984,558.138977,629.367004,629.367004,1464507992
|
95 |
+
2016-06-27,629.348999,704.968018,620.523987,658.664001,658.664001,918252000
|
96 |
+
2016-07-04,658.804016,683.661987,611.833984,649.359985,649.359985,1040574400
|
97 |
+
2016-07-11,648.484009,682.364990,644.979980,679.458984,679.458984,682454600
|
98 |
+
2016-07-18,679.809021,681.554993,646.721985,661.284973,661.284973,607681700
|
99 |
+
2016-07-25,661.263000,661.828003,624.364990,624.681030,624.681030,747178496
|
100 |
+
2016-08-01,624.601990,626.119019,531.333984,592.690002,592.690002,1015417588
|
101 |
+
2016-08-08,592.736023,599.984009,564.781006,570.473022,570.473022,504473696
|
102 |
+
2016-08-15,570.494019,584.158020,563.239990,581.307983,581.307983,364239500
|
103 |
+
2016-08-22,581.310974,589.473999,568.630005,573.911987,573.911987,545508100
|
104 |
+
2016-08-29,574.070984,611.836975,570.810974,608.633972,608.633972,670372392
|
105 |
+
2016-09-05,608.989990,628.817993,600.505981,606.718994,606.718994,505899104
|
106 |
+
2016-09-12,607.005005,611.952026,605.192017,609.874023,609.874023,417858304
|
107 |
+
2016-09-19,609.870972,610.932007,595.786011,600.825989,600.825989,397773096
|
108 |
+
2016-09-26,600.807007,615.237000,600.348999,610.892029,610.892029,364686600
|
109 |
+
2016-10-03,610.968018,619.848999,609.479004,616.752014,616.752014,367150204
|
110 |
+
2016-10-10,616.822021,642.898010,616.197021,641.630981,641.630981,462540104
|
111 |
+
2016-10-17,641.817993,661.129028,628.013000,657.070984,657.070984,438931392
|
112 |
+
2016-10-24,657.161011,720.401978,652.594971,701.864014,701.864014,654150896
|
113 |
+
2016-10-31,702.640015,745.773010,678.156006,711.521973,711.521973,698826796
|
114 |
+
2016-11-07,710.736023,740.046021,687.315002,702.031006,702.031006,554004996
|
115 |
+
2016-11-14,701.997009,756.237000,699.807983,731.026001,731.026001,736991600
|
116 |
+
2016-11-21,731.265015,753.869995,729.625000,732.034973,732.034973,528543596
|
117 |
+
2016-11-28,732.484009,781.296021,732.484009,773.872009,773.872009,552642604
|
118 |
+
2016-12-05,773.393982,777.091980,751.713013,769.731018,769.731018,578980796
|
119 |
+
2016-12-12,770.039978,794.737000,770.039978,790.530029,790.530029,538898096
|
120 |
+
2016-12-19,790.692017,925.117004,790.320007,896.182983,896.182983,1087074704
|
121 |
+
2016-12-26,896.905029,1003.080017,896.898010,998.325012,998.325012,1161413112
|
122 |
+
2017-01-02,998.617004,1191.099976,823.556030,911.198975,911.198975,2052639008
|
123 |
+
2017-01-09,913.244019,919.447998,755.755981,821.797974,821.797974,1123984880
|
124 |
+
2017-01-16,821.783020,937.525024,820.270996,924.672974,924.672974,883611600
|
125 |
+
2017-01-23,925.499023,928.265991,891.687012,919.495972,919.495972,693151900
|
126 |
+
2017-01-30,920.151001,1045.900024,919.473999,1027.339966,1027.339966,1009290288
|
127 |
+
2017-02-06,1028.400024,1088.989990,946.690979,999.181030,999.181030,1227087016
|
128 |
+
2017-02-13,998.885010,1061.099976,976.002014,1047.869995,1047.869995,763560200
|
129 |
+
2017-02-20,1048.689941,1200.390015,1041.689941,1165.199951,1165.199951,1209106992
|
130 |
+
2017-02-27,1163.780029,1280.310059,1163.380005,1267.119995,1267.119995,1546994008
|
131 |
+
2017-03-06,1267.469971,1276.000000,1077.250000,1221.380005,1221.380005,2064090976
|
132 |
+
2017-03-13,1221.780029,1257.979980,957.655029,1036.739990,1036.739990,3296504976
|
133 |
+
2017-03-20,1037.239990,1122.430054,903.713013,966.724976,966.724976,2483811008
|
134 |
+
2017-03-27,972.054993,1107.589966,971.984009,1102.170044,1102.170044,2601401984
|
135 |
+
2017-04-03,1102.949951,1197.209961,1102.949951,1187.869995,1187.869995,2711437088
|
136 |
+
2017-04-10,1187.300049,1208.069946,1156.439941,1182.939941,1182.939941,1714353040
|
137 |
+
2017-04-17,1183.250000,1240.790039,1172.650024,1207.209961,1207.209961,1907337008
|
138 |
+
2017-04-24,1209.630005,1347.910034,1209.630005,1347.890015,1347.890015,2620499984
|
139 |
+
2017-05-01,1348.300049,1618.030029,1348.300049,1596.709961,1596.709961,5316902848
|
140 |
+
2017-05-08,1596.920044,1873.930054,1596.920044,1808.910034,1808.910034,5981268000
|
141 |
+
2017-05-15,1808.439941,2119.080078,1661.910034,2041.199951,2041.199951,6916110976
|
142 |
+
2017-05-22,2043.189941,2763.709961,1855.829956,2155.800049,2155.800049,12064150016
|
143 |
+
2017-05-29,2159.429932,2585.889893,2107.169922,2511.810059,2511.810059,9823705088
|
144 |
+
2017-06-05,2512.399902,2999.909912,2510.219971,2958.110107,2958.110107,11378039936
|
145 |
+
2017-06-12,2953.219971,2997.260010,2212.959961,2548.290039,2548.290039,11981910016
|
146 |
+
2017-06-19,2549.030029,2772.010010,2549.030029,2589.409912,2589.409912,9130718976
|
147 |
+
2017-06-26,2590.570068,2615.250000,2332.989990,2506.469971,2506.469971,7730852928
|
148 |
+
2017-07-03,2498.560059,2916.139893,2480.469971,2518.439941,2518.439941,5831748992
|
149 |
+
2017-07-10,2525.250000,2537.159912,1843.030029,1929.819946,1929.819946,7453121024
|
150 |
+
2017-07-17,1932.619995,2900.699951,1932.619995,2730.399902,2730.399902,9947990080
|
151 |
+
2017-07-24,2732.699951,2897.449951,2450.800049,2757.179932,2757.179932,6942860928
|
152 |
+
2017-07-31,2763.239990,3293.290039,2668.590088,3213.939941,3213.939941,8137841920
|
153 |
+
2017-08-07,3212.780029,4208.390137,3180.889893,4073.260010,4073.260010,13618979840
|
154 |
+
2017-08-14,4066.100098,4484.700195,3906.179932,4087.659912,4087.659912,18573839872
|
155 |
+
2017-08-21,4090.479980,4455.700195,3674.580078,4382.879883,4382.879883,15749739904
|
156 |
+
2017-08-28,4384.450195,4975.040039,4224.640137,4582.959961,4582.959961,15582599936
|
157 |
+
2017-09-04,4591.629883,4661.000000,3951.040039,4122.939941,4122.939941,15468230272
|
158 |
+
2017-09-11,4122.470215,4344.649902,2946.620117,3582.879883,3582.879883,15563199872
|
159 |
+
2017-09-18,3591.090088,4094.070068,3553.530029,3682.840088,3682.840088,9023459008
|
160 |
+
2017-09-25,3681.580078,4403.740234,3681.580078,4403.740234,4403.740234,9599860096
|
161 |
+
2017-10-02,4395.810059,4624.140137,4164.049805,4610.479980,4610.479980,8289027968
|
162 |
+
2017-10-09,4614.520020,5852.479980,4564.250000,5678.189941,5678.189941,14840320000
|
163 |
+
2017-10-16,5687.569824,6194.879883,5151.439941,6008.419922,6008.419922,14605609856
|
164 |
+
2017-10-23,6006.000000,6255.709961,5397.879883,6153.850098,6153.850098,14982660096
|
165 |
+
2017-10-30,6114.850098,7617.479980,6040.850098,7407.410156,7407.410156,19841690624
|
166 |
+
2017-11-06,7403.220215,7776.419922,5519.009766,5950.069824,5950.069824,32340969984
|
167 |
+
2017-11-13,5938.250000,8101.910156,5844.290039,8036.490234,8036.490234,30253229824
|
168 |
+
2017-11-20,8039.069824,9522.929688,7762.709961,9330.549805,9330.549805,30501020160
|
169 |
+
2017-11-27,9352.719727,11858.700195,9202.049805,11323.200195,11323.200195,50411559424
|
170 |
+
2017-12-04,11315.400391,18353.400391,11081.799805,15455.400391,15455.400391,92115268608
|
171 |
+
2017-12-11,15427.400391,20089.000000,15404.799805,19140.800781,19140.800781,93877198848
|
172 |
+
2017-12-18,19106.400391,19371.000000,11833.000000,13925.799805,13925.799805,117256598528
|
173 |
+
2017-12-25,13995.900391,16930.900391,12350.099609,14156.400391,14156.400391,88557499392
|
174 |
+
2018-01-01,14112.200195,17712.400391,13154.700195,16477.599609,16477.599609,123814400000
|
175 |
+
2018-01-08,16476.199219,16537.900391,13105.900391,13772.000000,13772.000000,106022199296
|
176 |
+
2018-01-15,13767.299805,14445.500000,9402.290039,11600.099609,11600.099609,97932879872
|
177 |
+
2018-01-22,11633.099609,12040.299805,10129.700195,11786.299805,11786.299805,64691999232
|
178 |
+
2018-01-29,11755.500000,11875.599609,7796.490234,8277.009766,8277.009766,60810019840
|
179 |
+
2018-02-05,8270.540039,9122.549805,6048.259766,8129.970215,8129.970215,62489091072
|
180 |
+
2018-02-12,8141.430176,11349.799805,8141.430176,10551.799805,10551.799805,53626569728
|
181 |
+
2018-02-19,10552.599609,11958.500000,9407.059570,9664.730469,9664.730469,55388419584
|
182 |
+
2018-02-26,9669.429688,11528.200195,9501.730469,11512.599609,11512.599609,48902649856
|
183 |
+
2018-03-05,11532.400391,11704.099609,8513.030273,9578.629883,9578.629883,49671590400
|
184 |
+
2018-03-12,9602.929688,9937.500000,7397.990234,8223.679688,8223.679688,42075919360
|
185 |
+
2018-03-19,8344.120117,9177.370117,8182.399902,8495.780273,8495.780273,40853020160
|
186 |
+
2018-03-26,8498.469727,8530.080078,6526.870117,6844.229980,6844.229980,37970689536
|
187 |
+
2018-04-02,6844.859863,7530.939941,6575.000000,7023.520020,7023.520020,31804380416
|
188 |
+
2018-04-09,7044.319824,8338.419922,6661.990234,8329.110352,8329.110352,40915320320
|
189 |
+
2018-04-16,8337.570313,9001.639648,7881.720215,8802.459961,8802.459961,48741869568
|
190 |
+
2018-04-23,8794.389648,9745.320313,8727.089844,9419.080078,9419.080078,61882420224
|
191 |
+
2018-04-30,9426.110352,9964.500000,8891.049805,9654.799805,9654.799805,57244449280
|
192 |
+
2018-05-07,9645.669922,9665.849609,8223.500000,8723.940430,8723.940430,50119759872
|
193 |
+
2018-05-14,8713.099609,8881.120117,7974.819824,8513.250000,8513.250000,42360260096
|
194 |
+
2018-05-21,8522.330078,8557.519531,7270.959961,7368.220215,7368.220215,35808230144
|
195 |
+
2018-05-28,7371.310059,7754.890137,7090.680176,7720.250000,7720.250000,35465450496
|
196 |
+
2018-06-04,7722.529785,7753.819824,6709.069824,6786.020020,6786.020020,33010609408
|
197 |
+
2018-06-11,6799.290039,6910.180176,6285.629883,6499.270020,6499.270020,29844289792
|
198 |
+
2018-06-18,6510.069824,6822.500000,5826.410156,6173.229980,6173.229980,28592079872
|
199 |
+
2018-06-25,6171.970215,6465.509766,5835.750000,6385.819824,6385.819824,28842940160
|
200 |
+
2018-07-02,6380.379883,6885.910156,6305.700195,6773.879883,6773.879883,29906419968
|
201 |
+
2018-07-09,6775.080078,6838.680176,6136.419922,6359.640137,6359.640137,25200120064
|
202 |
+
2018-07-16,6357.009766,7594.669922,6357.009766,7418.490234,7418.490234,34261730048
|
203 |
+
2018-07-23,7414.709961,8424.269531,7409.100098,8218.459961,8218.459961,36446479872
|
204 |
+
2018-07-30,8221.580078,8235.500000,6940.700195,7068.479980,7068.479980,32425310000
|
205 |
+
2018-08-06,7062.939941,7166.549805,6109.029785,6322.689941,6322.689941,32181950000
|
206 |
+
2018-08-13,6341.359863,6617.350098,5971.049805,6506.069824,6506.069824,30898230000
|
207 |
+
2018-08-20,6500.509766,6816.790039,6297.930176,6707.259766,6707.259766,25842490000
|
208 |
+
2018-08-27,6710.799805,7306.310059,6689.709961,7272.720215,7272.720215,30229310000
|
209 |
+
2018-09-03,7279.029785,7388.430176,6197.520020,6300.859863,6300.859863,31456960000
|
210 |
+
2018-09-10,6301.569824,6596.100098,6260.209961,6517.180176,6517.180176,26405400000
|
211 |
+
2018-09-17,6514.060059,6814.560059,6208.339844,6710.629883,6710.629883,32109420000
|
212 |
+
2018-09-24,6704.770020,6785.029785,6381.859863,6625.560059,6625.560059,31328000000
|
213 |
+
2018-10-01,6619.850098,6653.299805,6454.029785,6602.950195,6602.950195,25943820000
|
214 |
+
2018-10-08,6600.189941,6675.060059,6236.470215,6290.930176,6290.930176,26462410000
|
215 |
+
2018-10-15,6292.640137,6965.060059,6258.680176,6482.350098,6482.350098,29669680000
|
216 |
+
2018-10-22,6486.049805,6543.799805,6447.029785,6486.390137,6486.390137,24188720000
|
217 |
+
2018-10-29,6492.350098,6547.140137,6294.569824,6376.129883,6376.129883,28245180000
|
218 |
+
2018-11-05,6363.620117,6552.160156,6350.169922,6411.270020,6411.270020,30472560000
|
219 |
+
2018-11-12,6411.759766,6434.209961,5358.379883,5623.540039,5623.540039,36972800000
|
220 |
+
2018-11-19,5620.779785,5620.779785,3585.060059,4009.969971,4009.969971,42533970000
|
221 |
+
2018-11-26,4015.070068,4413.020508,3643.919922,4139.877930,4139.877930,42945276472
|
222 |
+
2018-12-03,4147.323730,4155.979492,3280.228760,3614.234375,3614.234375,38386467708
|
223 |
+
2018-12-10,3612.046387,3647.332520,3191.303467,3252.839111,3252.839111,29869247431
|
224 |
+
2018-12-17,3253.123047,4198.429688,3253.123047,3998.980225,3998.980225,46021506218
|
225 |
+
2018-12-24,4000.331787,4271.792480,3642.632080,3865.952637,3865.952637,39249734918
|
226 |
+
2018-12-31,3866.839111,4093.297363,3707.231201,4076.632568,4076.632568,34343716582
|
227 |
+
2019-01-07,4078.584961,4109.020996,3544.927246,3552.953125,3552.953125,37523454177
|
228 |
+
2019-01-14,3557.311035,3758.533447,3552.285156,3601.013672,3601.013672,38588596987
|
229 |
+
2019-01-21,3600.372803,3654.933105,3539.721436,3583.965820,3583.965820,36949379050
|
230 |
+
2019-01-28,3584.283203,3586.750977,3400.819824,3464.013428,3464.013428,40130888766
|
231 |
+
2019-02-04,3467.211670,3695.614014,3391.023682,3690.188232,3690.188232,41224140801
|
232 |
+
2019-02-11,3695.613037,3695.613037,3607.697754,3673.836182,3673.836182,44533597993
|
233 |
+
2019-02-18,3671.369873,4210.641602,3669.982422,3810.427490,3810.427490,63853356366
|
234 |
+
2019-02-25,3807.002441,3913.707275,3787.058838,3847.175781,3847.175781,56444684748
|
235 |
+
2019-03-04,3845.091553,3987.237793,3733.749756,3951.599854,3951.599854,69110769320
|
236 |
+
2019-03-11,3953.740234,4077.036377,3863.559082,4025.229004,4025.229004,67357766371
|
237 |
+
2019-03-18,4029.968506,4097.359863,4005.151367,4022.168213,4022.168213,67975640775
|
238 |
+
2019-03-25,4024.112793,4296.806641,3934.031250,4105.404297,4105.404297,71015021591
|
239 |
+
2019-04-01,4105.362305,5307.003418,4096.901367,5198.896973,5198.896973,123047080530
|
240 |
+
2019-04-08,5199.835449,5421.651367,4955.852539,5167.722168,5167.722168,98826873355
|
241 |
+
2019-04-15,5167.321777,5359.924805,5024.069336,5314.531250,5314.531250,90285516253
|
242 |
+
2019-04-22,5312.494629,5642.044434,5177.368652,5285.139160,5285.139160,105590631334
|
243 |
+
2019-04-29,5284.858398,5886.893555,5216.487793,5795.708496,5795.708496,107035835884
|
244 |
+
2019-05-06,5791.693359,7503.872070,5653.687500,6972.371582,6972.371582,141929602925
|
245 |
+
2019-05-13,6971.178223,8320.824219,6898.282227,8197.689453,8197.689453,199543788416
|
246 |
+
2019-05-20,8196.923828,8687.520508,7533.196777,8673.215820,8673.215820,173001140580
|
247 |
+
2019-05-27,8674.072266,9008.314453,8172.550781,8742.958008,8742.958008,173016477871
|
248 |
+
2019-06-03,8741.747070,8743.500000,7564.488770,7688.077148,7688.077148,140124650113
|
249 |
+
2019-06-10,7692.284668,9335.867188,7586.730957,8994.488281,8994.488281,135051141522
|
250 |
+
2019-06-17,8988.923828,11246.144531,8988.923828,10855.371094,10855.371094,136422336191
|
251 |
+
2019-06-24,10853.744141,13796.489258,10491.852539,10817.155273,10817.155273,221502737682
|
252 |
+
2019-07-01,10796.930664,12006.075195,9737.884766,11450.846680,11450.846680,181410821667
|
253 |
+
2019-07-08,11446.596680,13129.529297,10234.576172,10256.058594,10256.058594,180936684097
|
254 |
+
2019-07-15,10257.838867,11052.766602,9163.134766,10599.105469,10599.105469,157356814406
|
255 |
+
2019-07-22,10596.948242,10651.791016,9252.296875,9552.860352,9552.860352,112459229432
|
256 |
+
2019-07-29,9548.178711,11009.207031,9437.335938,10970.184570,10970.184570,110790788891
|
257 |
+
2019-08-05,10960.735352,12273.821289,10960.735352,11523.579102,11523.579102,141427393788
|
258 |
+
2019-08-12,11528.189453,11528.189453,9675.316406,10345.810547,10345.810547,120224711798
|
259 |
+
2019-08-19,10350.283203,10947.041992,9831.462891,10138.517578,10138.517578,112893851548
|
260 |
+
2019-08-26,10126.299805,10512.328125,9421.629883,9757.970703,9757.970703,104346358671
|
261 |
+
2019-09-02,9757.473633,10898.761719,9730.650391,10441.276367,10441.276367,116441433312
|
262 |
+
2019-09-09,10443.228516,10450.311523,9980.776367,10347.712891,10347.712891,102876391724
|
263 |
+
2019-09-16,10347.222656,10386.867188,9851.692383,10070.392578,10070.392578,107930839412
|
264 |
+
2019-09-23,10067.962891,10074.238281,7895.629395,8104.185547,8104.185547,124735468740
|
265 |
+
2019-09-30,8104.226563,8497.692383,7830.758789,7988.155762,7988.155762,97716137179
|
266 |
+
2019-10-07,7989.120605,8721.780273,7905.766113,8321.005859,8321.005859,118550918408
|
267 |
+
2019-10-14,8320.832031,8410.714844,7902.164063,8222.078125,8222.078125,105710167423
|
268 |
+
2019-10-21,8225.115234,10021.744141,7446.988770,9551.714844,9551.714844,176678165128
|
269 |
+
2019-10-28,9565.101563,9805.118164,9028.717773,9235.354492,9235.354492,180364809056
|
270 |
+
2019-11-04,9235.607422,9505.051758,8775.534180,9055.526367,9055.526367,160702732609
|
271 |
+
2019-11-11,9056.917969,9081.279297,8473.973633,8577.975586,8577.975586,134166660428
|
272 |
+
2019-11-18,8573.980469,8653.280273,6936.706543,7047.916992,7047.916992,171626385789
|
273 |
+
2019-11-25,7039.977051,7836.102051,6617.166992,7424.292480,7424.292480,162444865040
|
274 |
+
2019-12-02,7424.036133,7743.431641,7170.922852,7564.345215,7564.345215,121327747581
|
275 |
+
2019-12-09,7561.795410,7618.091797,6924.375977,7152.301758,7152.301758,122542519854
|
276 |
+
2019-12-16,7153.663086,7518.033203,6540.049316,7511.588867,7511.588867,165399102665
|
277 |
+
2019-12-23,7508.902344,7656.176270,7189.934082,7422.652832,7422.652832,161758217053
|
278 |
+
2019-12-30,7420.272949,7544.497070,6914.996094,7411.317383,7411.317383,149690652648
|
279 |
+
2020-01-06,7410.452148,8396.738281,7409.292969,8192.494141,8192.494141,184901289966
|
280 |
+
2020-01-13,8189.771973,9164.362305,8079.700684,8706.245117,8706.245117,241668743794
|
281 |
+
2020-01-20,8704.631836,8792.994141,8266.840820,8596.830078,8596.830078,165113602391
|
282 |
+
2020-01-27,8597.308594,9553.125977,8597.308594,9344.365234,9344.365234,212298356923
|
283 |
+
2020-02-03,9344.683594,10129.435547,9112.811523,10116.673828,10116.673828,239180811399
|
284 |
+
2020-02-10,10115.559570,10457.626953,9722.386719,9934.433594,9934.433594,300413081965
|
285 |
+
2020-02-17,9936.560547,10191.675781,9507.637695,9924.515625,9924.515625,303140360741
|
286 |
+
2020-02-24,9921.583008,9951.746094,8471.212891,8562.454102,8562.454102,299233009521
|
287 |
+
2020-03-02,8563.264648,9167.695313,8105.252930,8108.116211,8108.116211,276706069337
|
288 |
+
2020-03-09,8111.146484,8177.793457,4106.980957,5392.314941,5392.314941,326123224372
|
289 |
+
2020-03-16,5385.229492,6844.261719,4575.357910,5830.254883,5830.254883,309907233901
|
290 |
+
2020-03-23,5831.374512,6892.511230,5785.004395,5922.042969,5922.042969,272468247401
|
291 |
+
2020-03-30,5925.538574,7088.247559,5903.234375,6791.129395,6791.129395,259568096070
|
292 |
+
2020-04-06,6788.049805,7427.939453,6782.889648,6971.091797,6971.091797,274123270580
|
293 |
+
2020-04-13,6965.616699,7280.521973,6555.504395,7189.424805,7189.424805,248073118275
|
294 |
+
2020-04-20,7186.873535,7700.594238,6834.442383,7679.867188,7679.867188,247735013853
|
295 |
+
2020-04-27,7679.418945,9440.650391,7679.418945,8897.468750,8897.468750,327820350244
|
296 |
+
2020-05-04,8895.745117,9996.743164,8395.107422,8756.430664,8756.430664,361023995652
|
297 |
+
2020-05-11,8755.535156,9823.001953,8374.323242,9670.739258,9670.739258,325655447393
|
298 |
+
2020-05-18,9675.695313,9906.030273,8787.250977,8790.368164,8790.368164,247011272897
|
299 |
+
2020-05-25,8786.107422,9704.030273,8719.667969,9461.058594,9461.058594,221372861711
|
300 |
+
2020-06-01,9463.605469,10199.565430,9450.899414,9758.852539,9758.852539,194228716225
|
301 |
+
2020-06-08,9760.063477,9938.297852,9263.069336,9386.788086,9386.788086,160324519712
|
302 |
+
2020-06-15,9386.035156,9579.430664,8990.175781,9303.629883,9303.629883,138300100692
|
303 |
+
2020-06-22,9300.915039,9680.367188,8975.525391,9143.582031,9143.582031,125863637229
|
304 |
+
2020-06-29,9140.029297,9309.754883,8977.015625,9073.942383,9073.942383,102779717630
|
305 |
+
2020-07-06,9072.849609,9450.335938,9058.664063,9276.500000,9276.500000,113994286210
|
306 |
+
2020-07-13,9277.205078,9306.405273,9088.947266,9185.817383,9185.817383,106299733734
|
307 |
+
2020-07-20,9187.220703,10023.807617,9137.509766,9905.166992,9905.166992,120174678243
|
308 |
+
2020-07-27,9905.217773,12034.144531,9903.969727,11053.614258,11053.614258,188247005753
|
309 |
+
2020-08-03,11043.768555,11902.335938,11012.415039,11675.739258,11675.739258,147527884833
|
310 |
+
2020-08-10,11662.256836,12150.994141,11195.708984,11892.803711,11892.803711,173916901671
|
311 |
+
2020-08-17,11895.658203,12359.056641,11448.805664,11664.847656,11664.847656,161417688724
|
312 |
+
2020-08-24,11663.689453,11807.631836,11185.941406,11711.505859,11711.505859,149742951013
|
313 |
+
2020-08-31,11713.306641,12067.081055,9946.675781,10280.351563,10280.351563,221515306287
|
314 |
+
2020-09-07,10280.998047,10578.837891,9916.493164,10323.755859,10323.755859,264126813725
|
315 |
+
2020-09-14,10328.734375,11134.092773,10266.008789,10938.271484,10938.271484,210690462551
|
316 |
+
2020-09-21,10934.925781,10988.304688,10197.865234,10775.269531,10775.269531,263386919085
|
317 |
+
2020-09-28,10776.613281,10945.347656,10416.689453,10669.583008,10669.583008,343112501609
|
318 |
+
2020-10-05,10676.529297,11442.210938,10528.890625,11384.181641,11384.181641,256921249410
|
319 |
+
2020-10-12,11392.635742,11698.467773,11223.012695,11483.359375,11483.359375,162045277956
|
320 |
+
2020-10-19,11495.038086,13329.183594,11408.290039,13031.173828,13031.173828,210845277262
|
321 |
+
2020-10-26,13031.201172,14028.213867,12822.382813,13737.109375,13737.109375,240919962782
|
322 |
+
2020-11-02,13737.032227,15903.437500,13243.160156,15479.567383,15479.567383,238108964192
|
323 |
+
2020-11-09,15479.595703,16463.177734,14865.529297,15955.587891,15955.587891,206407256877
|
324 |
+
2020-11-16,15955.577148,18936.621094,15880.706055,18370.001953,18370.001953,274506990351
|
325 |
+
2020-11-23,18370.017578,19390.964844,16351.035156,18177.484375,18177.484375,301939363508
|
326 |
+
2020-11-30,18178.322266,19845.974609,18178.322266,19345.121094,19345.121094,253088772491
|
327 |
+
2020-12-07,19343.128906,19411.828125,17619.533203,19142.382813,19142.382813,193678842258
|
328 |
+
2020-12-14,19144.492188,24209.660156,19012.708984,23477.294922,23477.294922,281723269352
|
329 |
+
2020-12-21,23474.455078,28288.839844,22159.367188,26272.294922,26272.294922,339132207025
|
330 |
+
2020-12-28,26280.822266,34608.558594,25987.298828,32782.023438,32782.023438,379626054545
|
331 |
+
2021-01-04,32810.949219,41946.738281,28722.755859,38356.441406,38356.441406,538834804975
|
332 |
+
2021-01-11,38346.531250,39966.406250,30549.599609,35791.277344,35791.277344,508900951412
|
333 |
+
2021-01-18,35792.238281,37755.890625,28953.373047,32289.378906,32289.378906,423439379849
|
334 |
+
2021-01-25,32285.798828,38406.261719,29367.138672,33114.359375,33114.359375,495037340009
|
335 |
+
2021-02-01,33114.578125,40846.546875,32384.228516,38903.441406,38903.441406,449918619842
|
336 |
+
2021-02-08,38886.828125,49487.640625,38076.324219,48717.289063,48717.289063,580021243858
|
337 |
+
2021-02-15,48696.535156,58330.570313,46347.476563,57539.945313,57539.945313,470533297170
|
338 |
+
2021-02-22,57532.738281,57533.390625,43241.617188,45137.769531,45137.769531,766679775805
|
339 |
+
2021-03-01,45159.503906,52535.136719,45115.093750,51206.691406,51206.691406,333113779409
|
340 |
+
2021-03-08,51174.117188,61683.863281,49506.054688,59302.316406,59302.316406,373838576722
|
341 |
+
2021-03-15,59267.429688,60540.992188,53555.027344,57523.421875,57523.421875,393542542227
|
342 |
+
2021-03-22,57517.890625,58471.480469,50856.570313,55950.746094,55950.746094,403128836645
|
343 |
+
2021-03-29,55947.898438,60267.187500,55139.339844,58758.554688,58758.554688,408348561550
|
344 |
+
2021-04-05,58760.875000,61276.664063,55604.023438,60204.964844,60204.964844,406637390979
|
345 |
+
2021-04-12,60175.945313,64863.097656,52829.535156,56216.183594,56216.183594,508118943571
|
346 |
+
2021-04-19,56191.585938,57520.054688,47159.484375,49004.253906,49004.253906,444719708699
|
347 |
+
2021-04-26,49077.792969,58448.339844,48852.796875,56631.078125,56631.078125,335231529997
|
348 |
+
2021-05-03,56620.273438,59464.613281,52969.054688,58232.316406,58232.316406,458766142208
|
349 |
+
2021-05-10,58250.871094,59519.355469,43963.351563,46456.058594,46456.058594,483967915938
|
350 |
+
2021-05-17,46415.898438,46623.558594,30681.496094,34770.582031,34770.582031,563629210102
|
351 |
+
2021-05-24,34700.363281,40782.078125,33520.738281,35678.128906,35678.128906,350206489990
|
352 |
+
2021-05-31,35658.593750,39478.953125,34241.945313,35862.378906,35862.378906,248884892724
|
353 |
+
2021-06-07,35835.265625,39322.781250,31114.443359,39097.859375,39097.859375,298428017340
|
354 |
+
2021-06-14,39016.968750,41295.269531,33432.074219,35698.296875,35698.296875,269949570053
|
355 |
+
2021-06-21,35641.144531,35721.640625,28893.621094,34649.644531,34649.644531,305541799334
|
356 |
+
2021-06-28,34679.121094,36542.109375,32770.679688,35287.781250,35287.781250,231729218470
|
357 |
+
2021-07-05,35284.343750,35284.343750,32133.183594,34240.187500,34240.187500,178445862441
|
358 |
+
2021-07-12,34254.015625,34592.156250,31100.673828,31796.810547,31796.810547,147501894180
|
359 |
+
2021-07-19,31800.011719,35364.925781,29360.955078,35350.187500,35350.187500,156414750211
|
360 |
+
2021-07-26,35384.031250,42541.679688,35287.312500,39974.894531,39974.894531,237553113912
|
361 |
+
2021-08-02,39907.261719,45282.351563,37458.003906,43798.117188,43798.117188,226902699564
|
362 |
+
2021-08-09,43791.925781,48098.683594,42848.687500,47047.003906,47047.003906,234268000892
|
363 |
+
2021-08-16,47019.960938,49717.019531,43998.316406,49321.652344,49321.652344,236289722726
|
364 |
+
2021-08-23,49291.675781,50482.078125,46394.281250,48829.832031,48829.832031,223947952688
|
365 |
+
2021-08-30,48834.851563,51868.679688,46562.437500,51753.410156,51753.410156,256225023619
|
366 |
+
2021-09-06,51769.003906,52853.765625,43285.207031,46063.269531,46063.269531,293311066613
|
367 |
+
2021-09-13,46057.214844,48791.781250,43591.320313,47260.218750,47260.218750,226141953163
|
368 |
+
2021-09-20,47261.406250,47328.199219,39787.609375,43208.539063,43208.539063,270099994433
|
369 |
+
2021-09-27,43234.183594,49130.691406,40829.667969,48199.953125,48199.953125,223042115392
|
370 |
+
2021-10-04,48208.906250,56401.304688,47045.003906,54771.578125,54771.578125,261919545521
|
371 |
+
2021-10-11,54734.125000,62757.128906,54370.972656,61553.617188,61553.617188,277084548345
|
372 |
+
2021-10-18,61548.804688,66930.390625,59643.343750,60930.835938,60930.835938,257856648064
|
373 |
+
2021-10-25,60893.925781,63729.324219,58206.917969,61318.957031,61318.957031,256114057651
|
374 |
+
2021-11-01,61320.449219,64242.792969,59695.183594,63326.988281,63326.988281,227064607869
|
375 |
+
2021-11-08,63344.066406,68789.625000,62333.914063,65466.839844,65466.839844,259776276520
|
376 |
+
2021-11-15,65521.289063,66281.570313,55705.179688,58730.476563,58730.476563,253419951009
|
377 |
+
2021-11-22,58706.847656,59367.968750,53569.765625,57248.457031,57248.457031,243930001011
|
378 |
+
2021-11-29,57291.906250,59113.402344,42874.617188,49368.847656,49368.847656,276690611812
|
379 |
+
2021-12-06,49413.480469,51934.781250,46942.347656,50098.335938,50098.335938,208148497532
|
380 |
+
2021-12-13,50114.742188,50205.000000,45598.441406,46707.015625,46707.015625,214770398202
|
381 |
+
2021-12-20,46707.062500,51814.027344,45579.808594,50809.515625,50809.515625,175052499792
|
382 |
+
2021-12-27,50802.609375,51956.328125,45819.953125,47345.218750,47345.218750,203998848909
|
383 |
+
2022-01-03,47343.542969,47510.726563,40672.277344,41911.601563,41911.601563,276182787152
|
384 |
+
2022-01-10,41910.230469,44278.421875,39796.570313,43113.878906,43113.878906,199473804544
|
385 |
+
2022-01-17,43118.121094,43413.023438,34349.250000,36276.804688,36276.804688,196326044073
|
386 |
+
2022-01-24,36275.734375,38825.410156,33184.058594,37917.601563,37917.601563,178727434896
|
387 |
+
2022-01-31,37920.281250,42500.785156,36375.539063,42412.433594,42412.433594,143977109319
|
388 |
+
2022-02-07,42406.781250,45661.171875,41748.156250,42197.515625,42197.515625,176958095731
|
389 |
+
2022-02-14,42157.398438,44667.218750,38112.812500,38431.378906,38431.378906,144975794552
|
390 |
+
2022-02-21,38423.210938,40005.347656,34459.218750,37709.785156,37709.785156,190469710084
|
391 |
+
2022-02-28,37706.000000,45077.578125,37518.214844,38419.984375,38419.984375,187557375751
|
392 |
+
2022-03-07,38429.304688,42465.671875,37260.203125,37849.664063,37849.664063,175966999156
|
393 |
+
2022-03-14,37846.316406,42316.554688,37680.734375,41247.824219,41247.824219,184097042034
|
394 |
+
2022-03-21,41246.132813,46827.546875,40668.042969,46820.492188,46820.492188,188591889758
|
395 |
+
2022-03-28,46821.851563,48086.835938,44403.140625,46453.566406,46453.566406,223334181931
|
396 |
+
2022-04-04,46445.273438,47106.140625,42021.207031,42207.671875,42207.671875,188557001876
|
397 |
+
2022-04-11,42201.039063,42424.589844,39373.058594,39716.953125,39716.953125,174652159709
|
398 |
+
2022-04-18,39721.203125,42893.582031,38696.191406,39469.292969,39469.292969,184314843516
|
399 |
+
2022-04-25,39472.605469,40713.890625,37585.789063,38469.093750,38469.093750,216681007567
|
400 |
+
2022-05-02,38472.187500,39902.949219,33878.964844,34059.265625,34059.265625,239044762282
|
401 |
+
2022-05-09,34060.015625,34222.074219,26350.490234,31305.113281,31305.113281,357800928090
|
402 |
+
2022-05-16,31304.375000,31305.341797,28708.955078,30323.722656,30323.722656,196429842104
|
403 |
+
2022-05-23,30309.396484,30590.585938,28261.906250,29445.957031,29445.957031,212594819496
|
404 |
+
2022-05-30,29443.365234,32249.863281,29303.572266,29906.662109,29906.662109,203063587161
|
405 |
+
2022-06-06,29910.283203,31693.291016,26762.648438,26762.648438,26762.648438,215929645934
|
406 |
+
2022-06-13,26737.578125,26795.589844,17708.623047,20553.271484,20553.271484,309685915250
|
407 |
+
2022-06-20,20553.371094,21783.724609,19689.169922,21027.294922,21027.294922,175909056122
|
408 |
+
2022-06-27,21028.238281,21478.089844,18729.656250,19297.076172,19297.076172,157426002965
|
409 |
+
2022-07-04,19297.314453,22314.941406,19063.066406,20860.449219,20860.449219,206953871021
|
410 |
+
2022-07-11,20856.353516,21600.640625,18999.953125,20779.343750,20779.343750,187297974219
|
411 |
+
2022-07-18,20781.912109,24196.818359,20781.912109,22609.164063,22609.164063,244312089708
|
412 |
+
2022-07-25,22607.156250,24572.580078,20776.816406,23336.896484,23336.896484,223759636595
|
413 |
+
2022-08-01,23336.718750,23578.650391,22485.701172,23175.890625,23175.890625,166393135564
|
414 |
+
2022-08-08,23179.527344,24974.914063,22771.519531,24319.333984,24319.333984,195343016900
|
415 |
+
2022-08-15,24318.316406,25135.589844,20856.730469,21534.121094,21534.121094,208764012537
|
416 |
+
2022-08-22,21531.462891,21804.908203,19616.814453,19616.814453,19616.814453,223346042309
|
417 |
+
2022-08-29,19615.154297,20542.644531,19600.785156,19986.712891,19986.712891,208511390280
|
418 |
+
2022-09-05,19988.789063,21770.552734,18644.466797,21769.255859,21769.255859,259528892947
|
419 |
+
2022-09-12,21770.148438,22673.820313,19387.492188,19419.505859,19419.505859,261900187496
|
420 |
+
2022-09-19,19418.572266,19674.630859,18290.314453,18802.097656,18802.097656,252873598365
|
421 |
+
2022-09-26,18803.900391,20338.455078,18553.296875,19044.107422,19044.107422,280290121527
|
422 |
+
2022-10-03,19044.068359,20408.392578,19025.226563,19446.425781,19446.425781,196809212801
|
423 |
+
2022-10-10,19446.416016,19889.146484,18319.822266,19268.093750,19268.093750,197940078443
|
424 |
+
2022-10-17,19268.562500,19666.994141,18770.970703,19567.007813,19567.007813,175664450104
|
425 |
+
2022-10-24,19567.769531,20988.394531,19206.324219,20635.603516,20635.603516,302335723765
|
426 |
+
2022-10-31,20633.695313,21446.886719,20086.240234,20926.486328,20926.486328,321270158405
|
427 |
+
2022-11-07,20924.621094,21053.246094,15682.692383,16353.365234,16353.365234,471409252759
|
428 |
+
2022-11-14,16352.028320,17109.324219,15872.941406,16291.832031,16291.832031,212305927001
|
429 |
+
2022-11-21,16291.223633,16771.474609,15599.046875,16444.626953,16444.626953,184366390569
|
430 |
+
2022-11-28,16440.222656,17197.498047,16054.530273,17130.486328,17130.486328,156325682750
|
431 |
+
2022-12-05,17128.894531,17378.152344,16750.558594,17104.193359,17104.193359,129428712529
|
432 |
+
2022-12-12,17102.500000,18318.531250,16584.701172,16757.976563,16757.976563,142170798266
|
433 |
+
2022-12-19,16759.041016,17012.984375,16398.136719,16841.986328,16841.986328,107997970888
|
434 |
+
2022-12-26,16842.250000,16959.845703,16408.474609,16625.080078,16625.080078,95526200508
|
435 |
+
2023-01-02,16625.509766,17091.144531,16572.228516,17091.144531,17091.144531,90012614323
|
436 |
+
2023-01-09,17093.992188,21075.142578,17093.992188,20880.798828,20880.798828,175267920183
|
437 |
+
2023-01-16,20882.224609,23282.347656,20541.544922,22720.416016,22720.416016,188938770069
|
438 |
+
2023-01-23,22721.087891,23919.890625,22406.076172,23774.566406,23774.566406,177486927537
|
439 |
+
2023-01-30,23774.648438,24167.210938,22657.582031,22955.666016,22955.666016,171080243769
|
440 |
+
2023-02-06,22954.021484,23367.958984,21539.392578,21788.203125,21788.203125,170212590188
|
441 |
+
2023-02-13,21787.000000,25134.117188,21460.087891,24327.642578,24327.642578,209050300776
|
442 |
+
2023-02-20,24336.623047,25126.851563,22861.558594,23561.212891,23561.212891,180472737469
|
443 |
+
2023-02-27,23561.451172,23880.632813,22198.980469,22435.513672,22435.513672,138790785900
|
444 |
+
2023-03-06,22436.816406,22584.292969,19628.253906,22163.949219,22163.949219,192057466346
|
445 |
+
2023-03-13,22156.406250,28440.560547,21918.199219,28038.675781,28038.675781,305833103060
|
446 |
+
2023-03-20,28041.601563,28803.335938,26759.996094,27994.330078,27994.330078,191720356212
|
447 |
+
2023-03-27,27994.068359,29159.902344,26606.689453,28199.308594,28199.308594,121255230918
|
448 |
+
2023-04-03,28183.080078,28739.238281,27276.720703,28333.050781,28333.050781,98141424556
|
449 |
+
2023-04-10,28336.027344,31005.607422,28189.271484,30315.355469,30315.355469,122998807738
|
450 |
+
2023-04-17,30317.146484,30470.302734,27169.570313,27591.384766,27591.384766,129935327803
|
451 |
+
2023-04-24,27591.730469,29995.837891,27070.849609,29268.806641,29268.806641,137303647007
|
452 |
+
2023-05-01,29227.103516,29820.126953,27680.792969,28454.978516,28454.978516,114911964253
|
453 |
+
2023-05-08,28450.457031,28663.271484,25878.429688,26930.638672,26930.638672,109959496438
|
454 |
+
2023-05-15,26931.384766,27646.347656,26415.101563,26753.826172,26753.826172,84459727715
|
455 |
+
2023-05-22,26749.892578,28193.449219,25890.593750,28085.646484,28085.646484,90053064704
|
456 |
+
2023-05-29,28075.591797,28432.039063,26574.644531,27119.066406,27119.066406,91351657572
|
457 |
+
2023-06-05,27123.109375,27332.181641,25434.867188,25940.167969,25940.167969,116498927148
|
458 |
+
2023-06-12,25934.285156,26769.394531,24797.167969,26336.212891,26336.212891,92905085602
|
459 |
+
2023-06-19,26335.441406,31389.539063,26312.832031,30480.261719,30480.261719,138005623534
|
460 |
+
2023-06-26,30480.523438,31256.863281,29600.275391,30620.769531,30620.769531,106681707513
|
461 |
+
2023-07-03,30624.515625,31460.052734,29777.285156,30171.234375,30171.234375,90491031635
|
462 |
+
2023-07-10,30172.423828,31814.515625,29966.386719,30249.132813,30249.132813,102917922458
|
463 |
+
2023-07-17,30249.626953,30336.400391,29556.427734,30084.539063,30084.539063,81229098742
|
464 |
+
2023-07-24,30081.662109,30093.394531,28934.294922,29275.308594,29275.308594,76309629498
|
465 |
+
2023-07-31,29278.314453,29987.998047,28657.023438,29041.855469,29041.855469,87827001052
|
466 |
+
2023-08-07,29038.513672,30176.796875,28724.140625,29282.914063,29282.914063,85153014454
|
467 |
+
2023-08-14,29283.263672,29660.253906,25409.111328,26189.583984,26189.583984,116418274959
|
468 |
+
2023-08-21,26188.691406,26786.898438,25520.728516,26089.693359,26089.693359,83086807452
|
469 |
+
2023-08-28,26089.615234,28089.337891,25362.609375,25969.566406,25969.566406,113161627781
|
470 |
+
2023-09-04,25968.169922,26414.005859,25404.359375,25832.226563,25832.226563,69814611152
|
471 |
+
2023-09-11,25831.714844,26840.498047,24930.296875,26534.187500,26534.187500,85796699860
|
472 |
+
2023-09-18,26532.994141,27488.763672,26221.050781,26256.826172,26256.826172,82251905213
|
473 |
+
2023-09-25,26253.775391,28047.238281,26011.468750,27983.750000,27983.750000,73012240734
|
474 |
+
2023-10-02,27976.798828,28494.458984,27215.552734,27935.089844,27935.089844,82183775698
|
475 |
+
2023-10-09,27934.472656,27989.470703,26558.320313,27159.652344,27159.652344,72673654487
|
476 |
+
2023-10-16,27162.628906,30287.482422,27130.472656,29993.896484,29993.896484,113402383094
|
477 |
+
2023-10-23,30140.685547,35150.433594,30097.828125,34538.480469,34538.480469,165718773022
|
478 |
+
2023-10-30,34531.742188,35919.843750,34083.308594,35049.355469,35049.355469,115520056635
|
479 |
+
2023-11-06,35044.789063,37926.257813,34545.816406,37054.519531,37054.519531,134767494805
|
480 |
+
2023-11-13,37070.304688,37964.894531,34948.500000,37386.546875,37386.546875,143535361089
|
481 |
+
2023-11-20,37374.074219,38415.339844,35670.972656,37479.121094,37479.121094,130439893957
|
482 |
+
2023-11-27,37454.191406,40135.605469,36750.128906,39978.390625,39978.390625,134360107955
|
483 |
+
2023-12-04,39978.628906,44705.515625,39978.628906,43779.699219,43779.699219,188503614895
|
484 |
+
2023-12-11,43792.019531,43808.375000,40234.578125,41364.664063,41364.664063,168493481950
|
485 |
+
2023-12-18,41348.203125,44367.957031,40530.257813,43016.117188,43016.117188,152084171491
|
486 |
+
2023-12-25,43010.574219,43804.781250,41424.062500,42265.187500,42265.187500,157807126208
|
487 |
+
2024-01-01,42280.234375,45899.707031,40813.535156,43943.097656,43943.097656,202311773985
|
488 |
+
2024-01-08,43948.707031,48969.371094,41724.613281,41796.269531,41796.269531,259971819745
|
489 |
+
2024-01-15,41715.066406,43566.273438,40297.457031,41545.785156,41545.785156,139135824835
|
490 |
+
2024-01-22,41553.652344,42797.175781,38521.894531,42035.593750,42035.593750,155314602893
|
491 |
+
2024-01-29,42030.914063,43838.945313,41818.332031,42583.582031,42583.582031,135184187433
|
492 |
+
2024-02-05,42577.621094,48535.937500,42264.816406,48293.917969,48293.917969,157826395448
|
493 |
+
2024-02-12,48296.386719,52820.066406,47745.761719,52122.546875,52122.546875,213560041471
|
494 |
+
2024-02-19,52134.812500,52945.050781,50561.777344,51733.238281,51733.238281,160769145627
|
495 |
+
2024-02-26,51730.539063,63913.132813,50931.031250,63167.371094,63167.371094,322895666089
|
496 |
+
2024-03-04,63137.003906,70083.054688,59323.910156,69019.789063,69019.789063,405709693297
|
497 |
+
2024-03-11,69020.546875,73750.070313,64545.316406,68390.625000,68390.625000,405957750577
|
498 |
+
2024-03-18,68371.304688,68897.132813,60807.785156,67234.171875,67234.171875,328097121682
|
499 |
+
2024-03-25,67234.093750,71727.687500,66414.835938,71333.648438,71333.648438,216324625836
|
500 |
+
2024-04-01,71333.484375,71342.093750,68110.695313,69702.148438,69702.148438,34873527352
|
501 |
+
2024-04-02,69694.046875,69694.046875,64610.968750,66042.132813,66042.132813,49630113792
|
aide/example_tasks/house_prices.md
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
## Goal
|
2 |
+
It is your job to predict the sales price for each house. For each Id in the test set, you must predict the value of the SalePrice variable.
|
3 |
+
|
4 |
+
## Background
|
5 |
+
Ask a home buyer to describe their dream house, and they probably won't begin with the height of the basement ceiling or the proximity to an east-west railroad. But this playground competition's dataset proves that much more influences price negotiations than the number of bedrooms or a white-picket fence.
|
6 |
+
With 79 explanatory variables describing (almost) every aspect of residential homes in Ames, Iowa, this competition challenges you to predict the final price of each home.
|
7 |
+
|
8 |
+
## Evaluation
|
9 |
+
Submissions are evaluated on [Root-Mean-Squared-Error (RMSE)](https://en.wikipedia.org/wiki/Root-mean-square_deviation) between the logarithm of the predicted value and the logarithm of the observed sales price. (Taking logs means that errors in predicting expensive houses and cheap houses will affect the result equally.)
|
10 |
+
|
11 |
+
The file should contain a header and have the following format:
|
12 |
+
|
13 |
+
```
|
14 |
+
Id,SalePrice
|
15 |
+
1461,169000.1
|
16 |
+
1462,187724.1233
|
17 |
+
1463,175221
|
18 |
+
etc.
|
19 |
+
```
|
20 |
+
|
21 |
+
## Data description
|
22 |
+
- **train.csv** - the training set
|
23 |
+
- **test.csv** - the test set
|
24 |
+
- **data_description.txt** - full description of each column, originally prepared by Dean De Cock but lightly edited to match the column names used here
|
aide/example_tasks/house_prices/data_description.txt
ADDED
@@ -0,0 +1,523 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
MSSubClass: Identifies the type of dwelling involved in the sale.
|
2 |
+
|
3 |
+
20 1-STORY 1946 & NEWER ALL STYLES
|
4 |
+
30 1-STORY 1945 & OLDER
|
5 |
+
40 1-STORY W/FINISHED ATTIC ALL AGES
|
6 |
+
45 1-1/2 STORY - UNFINISHED ALL AGES
|
7 |
+
50 1-1/2 STORY FINISHED ALL AGES
|
8 |
+
60 2-STORY 1946 & NEWER
|
9 |
+
70 2-STORY 1945 & OLDER
|
10 |
+
75 2-1/2 STORY ALL AGES
|
11 |
+
80 SPLIT OR MULTI-LEVEL
|
12 |
+
85 SPLIT FOYER
|
13 |
+
90 DUPLEX - ALL STYLES AND AGES
|
14 |
+
120 1-STORY PUD (Planned Unit Development) - 1946 & NEWER
|
15 |
+
150 1-1/2 STORY PUD - ALL AGES
|
16 |
+
160 2-STORY PUD - 1946 & NEWER
|
17 |
+
180 PUD - MULTILEVEL - INCL SPLIT LEV/FOYER
|
18 |
+
190 2 FAMILY CONVERSION - ALL STYLES AND AGES
|
19 |
+
|
20 |
+
MSZoning: Identifies the general zoning classification of the sale.
|
21 |
+
|
22 |
+
A Agriculture
|
23 |
+
C Commercial
|
24 |
+
FV Floating Village Residential
|
25 |
+
I Industrial
|
26 |
+
RH Residential High Density
|
27 |
+
RL Residential Low Density
|
28 |
+
RP Residential Low Density Park
|
29 |
+
RM Residential Medium Density
|
30 |
+
|
31 |
+
LotFrontage: Linear feet of street connected to property
|
32 |
+
|
33 |
+
LotArea: Lot size in square feet
|
34 |
+
|
35 |
+
Street: Type of road access to property
|
36 |
+
|
37 |
+
Grvl Gravel
|
38 |
+
Pave Paved
|
39 |
+
|
40 |
+
Alley: Type of alley access to property
|
41 |
+
|
42 |
+
Grvl Gravel
|
43 |
+
Pave Paved
|
44 |
+
NA No alley access
|
45 |
+
|
46 |
+
LotShape: General shape of property
|
47 |
+
|
48 |
+
Reg Regular
|
49 |
+
IR1 Slightly irregular
|
50 |
+
IR2 Moderately Irregular
|
51 |
+
IR3 Irregular
|
52 |
+
|
53 |
+
LandContour: Flatness of the property
|
54 |
+
|
55 |
+
Lvl Near Flat/Level
|
56 |
+
Bnk Banked - Quick and significant rise from street grade to building
|
57 |
+
HLS Hillside - Significant slope from side to side
|
58 |
+
Low Depression
|
59 |
+
|
60 |
+
Utilities: Type of utilities available
|
61 |
+
|
62 |
+
AllPub All public Utilities (E,G,W,& S)
|
63 |
+
NoSewr Electricity, Gas, and Water (Septic Tank)
|
64 |
+
NoSeWa Electricity and Gas Only
|
65 |
+
ELO Electricity only
|
66 |
+
|
67 |
+
LotConfig: Lot configuration
|
68 |
+
|
69 |
+
Inside Inside lot
|
70 |
+
Corner Corner lot
|
71 |
+
CulDSac Cul-de-sac
|
72 |
+
FR2 Frontage on 2 sides of property
|
73 |
+
FR3 Frontage on 3 sides of property
|
74 |
+
|
75 |
+
LandSlope: Slope of property
|
76 |
+
|
77 |
+
Gtl Gentle slope
|
78 |
+
Mod Moderate Slope
|
79 |
+
Sev Severe Slope
|
80 |
+
|
81 |
+
Neighborhood: Physical locations within Ames city limits
|
82 |
+
|
83 |
+
Blmngtn Bloomington Heights
|
84 |
+
Blueste Bluestem
|
85 |
+
BrDale Briardale
|
86 |
+
BrkSide Brookside
|
87 |
+
ClearCr Clear Creek
|
88 |
+
CollgCr College Creek
|
89 |
+
Crawfor Crawford
|
90 |
+
Edwards Edwards
|
91 |
+
Gilbert Gilbert
|
92 |
+
IDOTRR Iowa DOT and Rail Road
|
93 |
+
MeadowV Meadow Village
|
94 |
+
Mitchel Mitchell
|
95 |
+
Names North Ames
|
96 |
+
NoRidge Northridge
|
97 |
+
NPkVill Northpark Villa
|
98 |
+
NridgHt Northridge Heights
|
99 |
+
NWAmes Northwest Ames
|
100 |
+
OldTown Old Town
|
101 |
+
SWISU South & West of Iowa State University
|
102 |
+
Sawyer Sawyer
|
103 |
+
SawyerW Sawyer West
|
104 |
+
Somerst Somerset
|
105 |
+
StoneBr Stone Brook
|
106 |
+
Timber Timberland
|
107 |
+
Veenker Veenker
|
108 |
+
|
109 |
+
Condition1: Proximity to various conditions
|
110 |
+
|
111 |
+
Artery Adjacent to arterial street
|
112 |
+
Feedr Adjacent to feeder street
|
113 |
+
Norm Normal
|
114 |
+
RRNn Within 200' of North-South Railroad
|
115 |
+
RRAn Adjacent to North-South Railroad
|
116 |
+
PosN Near positive off-site feature--park, greenbelt, etc.
|
117 |
+
PosA Adjacent to postive off-site feature
|
118 |
+
RRNe Within 200' of East-West Railroad
|
119 |
+
RRAe Adjacent to East-West Railroad
|
120 |
+
|
121 |
+
Condition2: Proximity to various conditions (if more than one is present)
|
122 |
+
|
123 |
+
Artery Adjacent to arterial street
|
124 |
+
Feedr Adjacent to feeder street
|
125 |
+
Norm Normal
|
126 |
+
RRNn Within 200' of North-South Railroad
|
127 |
+
RRAn Adjacent to North-South Railroad
|
128 |
+
PosN Near positive off-site feature--park, greenbelt, etc.
|
129 |
+
PosA Adjacent to postive off-site feature
|
130 |
+
RRNe Within 200' of East-West Railroad
|
131 |
+
RRAe Adjacent to East-West Railroad
|
132 |
+
|
133 |
+
BldgType: Type of dwelling
|
134 |
+
|
135 |
+
1Fam Single-family Detached
|
136 |
+
2FmCon Two-family Conversion; originally built as one-family dwelling
|
137 |
+
Duplx Duplex
|
138 |
+
TwnhsE Townhouse End Unit
|
139 |
+
TwnhsI Townhouse Inside Unit
|
140 |
+
|
141 |
+
HouseStyle: Style of dwelling
|
142 |
+
|
143 |
+
1Story One story
|
144 |
+
1.5Fin One and one-half story: 2nd level finished
|
145 |
+
1.5Unf One and one-half story: 2nd level unfinished
|
146 |
+
2Story Two story
|
147 |
+
2.5Fin Two and one-half story: 2nd level finished
|
148 |
+
2.5Unf Two and one-half story: 2nd level unfinished
|
149 |
+
SFoyer Split Foyer
|
150 |
+
SLvl Split Level
|
151 |
+
|
152 |
+
OverallQual: Rates the overall material and finish of the house
|
153 |
+
|
154 |
+
10 Very Excellent
|
155 |
+
9 Excellent
|
156 |
+
8 Very Good
|
157 |
+
7 Good
|
158 |
+
6 Above Average
|
159 |
+
5 Average
|
160 |
+
4 Below Average
|
161 |
+
3 Fair
|
162 |
+
2 Poor
|
163 |
+
1 Very Poor
|
164 |
+
|
165 |
+
OverallCond: Rates the overall condition of the house
|
166 |
+
|
167 |
+
10 Very Excellent
|
168 |
+
9 Excellent
|
169 |
+
8 Very Good
|
170 |
+
7 Good
|
171 |
+
6 Above Average
|
172 |
+
5 Average
|
173 |
+
4 Below Average
|
174 |
+
3 Fair
|
175 |
+
2 Poor
|
176 |
+
1 Very Poor
|
177 |
+
|
178 |
+
YearBuilt: Original construction date
|
179 |
+
|
180 |
+
YearRemodAdd: Remodel date (same as construction date if no remodeling or additions)
|
181 |
+
|
182 |
+
RoofStyle: Type of roof
|
183 |
+
|
184 |
+
Flat Flat
|
185 |
+
Gable Gable
|
186 |
+
Gambrel Gabrel (Barn)
|
187 |
+
Hip Hip
|
188 |
+
Mansard Mansard
|
189 |
+
Shed Shed
|
190 |
+
|
191 |
+
RoofMatl: Roof material
|
192 |
+
|
193 |
+
ClyTile Clay or Tile
|
194 |
+
CompShg Standard (Composite) Shingle
|
195 |
+
Membran Membrane
|
196 |
+
Metal Metal
|
197 |
+
Roll Roll
|
198 |
+
Tar&Grv Gravel & Tar
|
199 |
+
WdShake Wood Shakes
|
200 |
+
WdShngl Wood Shingles
|
201 |
+
|
202 |
+
Exterior1st: Exterior covering on house
|
203 |
+
|
204 |
+
AsbShng Asbestos Shingles
|
205 |
+
AsphShn Asphalt Shingles
|
206 |
+
BrkComm Brick Common
|
207 |
+
BrkFace Brick Face
|
208 |
+
CBlock Cinder Block
|
209 |
+
CemntBd Cement Board
|
210 |
+
HdBoard Hard Board
|
211 |
+
ImStucc Imitation Stucco
|
212 |
+
MetalSd Metal Siding
|
213 |
+
Other Other
|
214 |
+
Plywood Plywood
|
215 |
+
PreCast PreCast
|
216 |
+
Stone Stone
|
217 |
+
Stucco Stucco
|
218 |
+
VinylSd Vinyl Siding
|
219 |
+
Wd Sdng Wood Siding
|
220 |
+
WdShing Wood Shingles
|
221 |
+
|
222 |
+
Exterior2nd: Exterior covering on house (if more than one material)
|
223 |
+
|
224 |
+
AsbShng Asbestos Shingles
|
225 |
+
AsphShn Asphalt Shingles
|
226 |
+
BrkComm Brick Common
|
227 |
+
BrkFace Brick Face
|
228 |
+
CBlock Cinder Block
|
229 |
+
CemntBd Cement Board
|
230 |
+
HdBoard Hard Board
|
231 |
+
ImStucc Imitation Stucco
|
232 |
+
MetalSd Metal Siding
|
233 |
+
Other Other
|
234 |
+
Plywood Plywood
|
235 |
+
PreCast PreCast
|
236 |
+
Stone Stone
|
237 |
+
Stucco Stucco
|
238 |
+
VinylSd Vinyl Siding
|
239 |
+
Wd Sdng Wood Siding
|
240 |
+
WdShing Wood Shingles
|
241 |
+
|
242 |
+
MasVnrType: Masonry veneer type
|
243 |
+
|
244 |
+
BrkCmn Brick Common
|
245 |
+
BrkFace Brick Face
|
246 |
+
CBlock Cinder Block
|
247 |
+
None None
|
248 |
+
Stone Stone
|
249 |
+
|
250 |
+
MasVnrArea: Masonry veneer area in square feet
|
251 |
+
|
252 |
+
ExterQual: Evaluates the quality of the material on the exterior
|
253 |
+
|
254 |
+
Ex Excellent
|
255 |
+
Gd Good
|
256 |
+
TA Average/Typical
|
257 |
+
Fa Fair
|
258 |
+
Po Poor
|
259 |
+
|
260 |
+
ExterCond: Evaluates the present condition of the material on the exterior
|
261 |
+
|
262 |
+
Ex Excellent
|
263 |
+
Gd Good
|
264 |
+
TA Average/Typical
|
265 |
+
Fa Fair
|
266 |
+
Po Poor
|
267 |
+
|
268 |
+
Foundation: Type of foundation
|
269 |
+
|
270 |
+
BrkTil Brick & Tile
|
271 |
+
CBlock Cinder Block
|
272 |
+
PConc Poured Contrete
|
273 |
+
Slab Slab
|
274 |
+
Stone Stone
|
275 |
+
Wood Wood
|
276 |
+
|
277 |
+
BsmtQual: Evaluates the height of the basement
|
278 |
+
|
279 |
+
Ex Excellent (100+ inches)
|
280 |
+
Gd Good (90-99 inches)
|
281 |
+
TA Typical (80-89 inches)
|
282 |
+
Fa Fair (70-79 inches)
|
283 |
+
Po Poor (<70 inches
|
284 |
+
NA No Basement
|
285 |
+
|
286 |
+
BsmtCond: Evaluates the general condition of the basement
|
287 |
+
|
288 |
+
Ex Excellent
|
289 |
+
Gd Good
|
290 |
+
TA Typical - slight dampness allowed
|
291 |
+
Fa Fair - dampness or some cracking or settling
|
292 |
+
Po Poor - Severe cracking, settling, or wetness
|
293 |
+
NA No Basement
|
294 |
+
|
295 |
+
BsmtExposure: Refers to walkout or garden level walls
|
296 |
+
|
297 |
+
Gd Good Exposure
|
298 |
+
Av Average Exposure (split levels or foyers typically score average or above)
|
299 |
+
Mn Mimimum Exposure
|
300 |
+
No No Exposure
|
301 |
+
NA No Basement
|
302 |
+
|
303 |
+
BsmtFinType1: Rating of basement finished area
|
304 |
+
|
305 |
+
GLQ Good Living Quarters
|
306 |
+
ALQ Average Living Quarters
|
307 |
+
BLQ Below Average Living Quarters
|
308 |
+
Rec Average Rec Room
|
309 |
+
LwQ Low Quality
|
310 |
+
Unf Unfinshed
|
311 |
+
NA No Basement
|
312 |
+
|
313 |
+
BsmtFinSF1: Type 1 finished square feet
|
314 |
+
|
315 |
+
BsmtFinType2: Rating of basement finished area (if multiple types)
|
316 |
+
|
317 |
+
GLQ Good Living Quarters
|
318 |
+
ALQ Average Living Quarters
|
319 |
+
BLQ Below Average Living Quarters
|
320 |
+
Rec Average Rec Room
|
321 |
+
LwQ Low Quality
|
322 |
+
Unf Unfinshed
|
323 |
+
NA No Basement
|
324 |
+
|
325 |
+
BsmtFinSF2: Type 2 finished square feet
|
326 |
+
|
327 |
+
BsmtUnfSF: Unfinished square feet of basement area
|
328 |
+
|
329 |
+
TotalBsmtSF: Total square feet of basement area
|
330 |
+
|
331 |
+
Heating: Type of heating
|
332 |
+
|
333 |
+
Floor Floor Furnace
|
334 |
+
GasA Gas forced warm air furnace
|
335 |
+
GasW Gas hot water or steam heat
|
336 |
+
Grav Gravity furnace
|
337 |
+
OthW Hot water or steam heat other than gas
|
338 |
+
Wall Wall furnace
|
339 |
+
|
340 |
+
HeatingQC: Heating quality and condition
|
341 |
+
|
342 |
+
Ex Excellent
|
343 |
+
Gd Good
|
344 |
+
TA Average/Typical
|
345 |
+
Fa Fair
|
346 |
+
Po Poor
|
347 |
+
|
348 |
+
CentralAir: Central air conditioning
|
349 |
+
|
350 |
+
N No
|
351 |
+
Y Yes
|
352 |
+
|
353 |
+
Electrical: Electrical system
|
354 |
+
|
355 |
+
SBrkr Standard Circuit Breakers & Romex
|
356 |
+
FuseA Fuse Box over 60 AMP and all Romex wiring (Average)
|
357 |
+
FuseF 60 AMP Fuse Box and mostly Romex wiring (Fair)
|
358 |
+
FuseP 60 AMP Fuse Box and mostly knob & tube wiring (poor)
|
359 |
+
Mix Mixed
|
360 |
+
|
361 |
+
1stFlrSF: First Floor square feet
|
362 |
+
|
363 |
+
2ndFlrSF: Second floor square feet
|
364 |
+
|
365 |
+
LowQualFinSF: Low quality finished square feet (all floors)
|
366 |
+
|
367 |
+
GrLivArea: Above grade (ground) living area square feet
|
368 |
+
|
369 |
+
BsmtFullBath: Basement full bathrooms
|
370 |
+
|
371 |
+
BsmtHalfBath: Basement half bathrooms
|
372 |
+
|
373 |
+
FullBath: Full bathrooms above grade
|
374 |
+
|
375 |
+
HalfBath: Half baths above grade
|
376 |
+
|
377 |
+
Bedroom: Bedrooms above grade (does NOT include basement bedrooms)
|
378 |
+
|
379 |
+
Kitchen: Kitchens above grade
|
380 |
+
|
381 |
+
KitchenQual: Kitchen quality
|
382 |
+
|
383 |
+
Ex Excellent
|
384 |
+
Gd Good
|
385 |
+
TA Typical/Average
|
386 |
+
Fa Fair
|
387 |
+
Po Poor
|
388 |
+
|
389 |
+
TotRmsAbvGrd: Total rooms above grade (does not include bathrooms)
|
390 |
+
|
391 |
+
Functional: Home functionality (Assume typical unless deductions are warranted)
|
392 |
+
|
393 |
+
Typ Typical Functionality
|
394 |
+
Min1 Minor Deductions 1
|
395 |
+
Min2 Minor Deductions 2
|
396 |
+
Mod Moderate Deductions
|
397 |
+
Maj1 Major Deductions 1
|
398 |
+
Maj2 Major Deductions 2
|
399 |
+
Sev Severely Damaged
|
400 |
+
Sal Salvage only
|
401 |
+
|
402 |
+
Fireplaces: Number of fireplaces
|
403 |
+
|
404 |
+
FireplaceQu: Fireplace quality
|
405 |
+
|
406 |
+
Ex Excellent - Exceptional Masonry Fireplace
|
407 |
+
Gd Good - Masonry Fireplace in main level
|
408 |
+
TA Average - Prefabricated Fireplace in main living area or Masonry Fireplace in basement
|
409 |
+
Fa Fair - Prefabricated Fireplace in basement
|
410 |
+
Po Poor - Ben Franklin Stove
|
411 |
+
NA No Fireplace
|
412 |
+
|
413 |
+
GarageType: Garage location
|
414 |
+
|
415 |
+
2Types More than one type of garage
|
416 |
+
Attchd Attached to home
|
417 |
+
Basment Basement Garage
|
418 |
+
BuiltIn Built-In (Garage part of house - typically has room above garage)
|
419 |
+
CarPort Car Port
|
420 |
+
Detchd Detached from home
|
421 |
+
NA No Garage
|
422 |
+
|
423 |
+
GarageYrBlt: Year garage was built
|
424 |
+
|
425 |
+
GarageFinish: Interior finish of the garage
|
426 |
+
|
427 |
+
Fin Finished
|
428 |
+
RFn Rough Finished
|
429 |
+
Unf Unfinished
|
430 |
+
NA No Garage
|
431 |
+
|
432 |
+
GarageCars: Size of garage in car capacity
|
433 |
+
|
434 |
+
GarageArea: Size of garage in square feet
|
435 |
+
|
436 |
+
GarageQual: Garage quality
|
437 |
+
|
438 |
+
Ex Excellent
|
439 |
+
Gd Good
|
440 |
+
TA Typical/Average
|
441 |
+
Fa Fair
|
442 |
+
Po Poor
|
443 |
+
NA No Garage
|
444 |
+
|
445 |
+
GarageCond: Garage condition
|
446 |
+
|
447 |
+
Ex Excellent
|
448 |
+
Gd Good
|
449 |
+
TA Typical/Average
|
450 |
+
Fa Fair
|
451 |
+
Po Poor
|
452 |
+
NA No Garage
|
453 |
+
|
454 |
+
PavedDrive: Paved driveway
|
455 |
+
|
456 |
+
Y Paved
|
457 |
+
P Partial Pavement
|
458 |
+
N Dirt/Gravel
|
459 |
+
|
460 |
+
WoodDeckSF: Wood deck area in square feet
|
461 |
+
|
462 |
+
OpenPorchSF: Open porch area in square feet
|
463 |
+
|
464 |
+
EnclosedPorch: Enclosed porch area in square feet
|
465 |
+
|
466 |
+
3SsnPorch: Three season porch area in square feet
|
467 |
+
|
468 |
+
ScreenPorch: Screen porch area in square feet
|
469 |
+
|
470 |
+
PoolArea: Pool area in square feet
|
471 |
+
|
472 |
+
PoolQC: Pool quality
|
473 |
+
|
474 |
+
Ex Excellent
|
475 |
+
Gd Good
|
476 |
+
TA Average/Typical
|
477 |
+
Fa Fair
|
478 |
+
NA No Pool
|
479 |
+
|
480 |
+
Fence: Fence quality
|
481 |
+
|
482 |
+
GdPrv Good Privacy
|
483 |
+
MnPrv Minimum Privacy
|
484 |
+
GdWo Good Wood
|
485 |
+
MnWw Minimum Wood/Wire
|
486 |
+
NA No Fence
|
487 |
+
|
488 |
+
MiscFeature: Miscellaneous feature not covered in other categories
|
489 |
+
|
490 |
+
Elev Elevator
|
491 |
+
Gar2 2nd Garage (if not described in garage section)
|
492 |
+
Othr Other
|
493 |
+
Shed Shed (over 100 SF)
|
494 |
+
TenC Tennis Court
|
495 |
+
NA None
|
496 |
+
|
497 |
+
MiscVal: $Value of miscellaneous feature
|
498 |
+
|
499 |
+
MoSold: Month Sold (MM)
|
500 |
+
|
501 |
+
YrSold: Year Sold (YYYY)
|
502 |
+
|
503 |
+
SaleType: Type of sale
|
504 |
+
|
505 |
+
WD Warranty Deed - Conventional
|
506 |
+
CWD Warranty Deed - Cash
|
507 |
+
VWD Warranty Deed - VA Loan
|
508 |
+
New Home just constructed and sold
|
509 |
+
COD Court Officer Deed/Estate
|
510 |
+
Con Contract 15% Down payment regular terms
|
511 |
+
ConLw Contract Low Down payment and low interest
|
512 |
+
ConLI Contract Low Interest
|
513 |
+
ConLD Contract Low Down
|
514 |
+
Oth Other
|
515 |
+
|
516 |
+
SaleCondition: Condition of sale
|
517 |
+
|
518 |
+
Normal Normal Sale
|
519 |
+
Abnorml Abnormal Sale - trade, foreclosure, short sale
|
520 |
+
AdjLand Adjoining Land Purchase
|
521 |
+
Alloca Allocation - two linked properties with separate deeds, typically condo with a garage unit
|
522 |
+
Family Sale between family members
|
523 |
+
Partial Home was not completed when last assessed (associated with New Homes)
|
aide/example_tasks/house_prices/sample_submission.csv
ADDED
@@ -0,0 +1,1460 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Id,SalePrice
|
2 |
+
1461,169277.0524984
|
3 |
+
1462,187758.393988768
|
4 |
+
1463,183583.683569555
|
5 |
+
1464,179317.47751083
|
6 |
+
1465,150730.079976501
|
7 |
+
1466,177150.989247307
|
8 |
+
1467,172070.659229164
|
9 |
+
1468,175110.956519547
|
10 |
+
1469,162011.698831665
|
11 |
+
1470,160726.247831419
|
12 |
+
1471,157933.279456005
|
13 |
+
1472,145291.245020389
|
14 |
+
1473,159672.017631819
|
15 |
+
1474,164167.518301885
|
16 |
+
1475,150891.638244053
|
17 |
+
1476,179460.96518734
|
18 |
+
1477,185034.62891405
|
19 |
+
1478,182352.192644656
|
20 |
+
1479,183053.458213802
|
21 |
+
1480,187823.339254278
|
22 |
+
1481,186544.114327568
|
23 |
+
1482,158230.77520516
|
24 |
+
1483,190552.829321091
|
25 |
+
1484,147183.67487199
|
26 |
+
1485,185855.300905493
|
27 |
+
1486,174350.470676986
|
28 |
+
1487,201740.620690863
|
29 |
+
1488,162986.378895754
|
30 |
+
1489,162330.199085679
|
31 |
+
1490,165845.938616539
|
32 |
+
1491,180929.622876974
|
33 |
+
1492,163481.501519718
|
34 |
+
1493,187798.076714233
|
35 |
+
1494,198822.198942566
|
36 |
+
1495,194868.409899858
|
37 |
+
1496,152605.298564403
|
38 |
+
1497,147797.702836811
|
39 |
+
1498,150521.96899297
|
40 |
+
1499,146991.630153739
|
41 |
+
1500,150306.307814534
|
42 |
+
1501,151164.372534604
|
43 |
+
1502,151133.706960953
|
44 |
+
1503,156214.042540726
|
45 |
+
1504,171992.760735142
|
46 |
+
1505,173214.912549738
|
47 |
+
1506,192429.187345783
|
48 |
+
1507,190878.69508543
|
49 |
+
1508,194542.544135519
|
50 |
+
1509,191849.439072822
|
51 |
+
1510,176363.773907793
|
52 |
+
1511,176954.185412429
|
53 |
+
1512,176521.216975696
|
54 |
+
1513,179436.704810176
|
55 |
+
1514,220079.756777048
|
56 |
+
1515,175502.918109444
|
57 |
+
1516,188321.073833569
|
58 |
+
1517,163276.324450004
|
59 |
+
1518,185911.366293097
|
60 |
+
1519,171392.830997252
|
61 |
+
1520,174418.207020775
|
62 |
+
1521,179682.709603774
|
63 |
+
1522,179423.751581665
|
64 |
+
1523,171756.918091777
|
65 |
+
1524,166849.638174419
|
66 |
+
1525,181122.168676666
|
67 |
+
1526,170934.462746566
|
68 |
+
1527,159738.292580329
|
69 |
+
1528,174445.759557658
|
70 |
+
1529,174706.363659627
|
71 |
+
1530,164507.672539365
|
72 |
+
1531,163602.512172832
|
73 |
+
1532,154126.270249525
|
74 |
+
1533,171104.853481351
|
75 |
+
1534,167735.39270528
|
76 |
+
1535,183003.613338104
|
77 |
+
1536,172580.381161499
|
78 |
+
1537,165407.889104689
|
79 |
+
1538,176363.773907793
|
80 |
+
1539,175182.950898522
|
81 |
+
1540,190757.177789246
|
82 |
+
1541,167186.995771991
|
83 |
+
1542,167839.376779276
|
84 |
+
1543,173912.421165137
|
85 |
+
1544,154034.917445551
|
86 |
+
1545,156002.955794336
|
87 |
+
1546,168173.94329857
|
88 |
+
1547,168882.437104132
|
89 |
+
1548,168173.94329857
|
90 |
+
1549,157580.177551642
|
91 |
+
1550,181922.15256011
|
92 |
+
1551,155134.227842592
|
93 |
+
1552,188885.573319552
|
94 |
+
1553,183963.193012381
|
95 |
+
1554,161298.762306335
|
96 |
+
1555,188613.66763056
|
97 |
+
1556,175080.111822945
|
98 |
+
1557,174744.400305232
|
99 |
+
1558,168175.911336919
|
100 |
+
1559,182333.472575006
|
101 |
+
1560,158307.206742274
|
102 |
+
1561,193053.055502348
|
103 |
+
1562,175031.089987177
|
104 |
+
1563,160713.294602908
|
105 |
+
1564,173186.215014436
|
106 |
+
1565,191736.7598055
|
107 |
+
1566,170401.630997116
|
108 |
+
1567,164626.577880222
|
109 |
+
1568,205469.409444832
|
110 |
+
1569,209561.784211885
|
111 |
+
1570,182271.503072356
|
112 |
+
1571,178081.549427793
|
113 |
+
1572,178425.956138831
|
114 |
+
1573,162015.318511503
|
115 |
+
1574,181722.420373045
|
116 |
+
1575,156705.730169433
|
117 |
+
1576,182902.420342386
|
118 |
+
1577,157574.595395085
|
119 |
+
1578,184380.739100813
|
120 |
+
1579,169364.469225677
|
121 |
+
1580,175846.179822063
|
122 |
+
1581,189673.295302136
|
123 |
+
1582,174401.317715566
|
124 |
+
1583,179021.448718583
|
125 |
+
1584,189196.845337149
|
126 |
+
1585,139647.095720655
|
127 |
+
1586,161468.198288911
|
128 |
+
1587,171557.32317862
|
129 |
+
1588,179447.36804185
|
130 |
+
1589,169611.619017694
|
131 |
+
1590,172088.872655744
|
132 |
+
1591,171190.624128768
|
133 |
+
1592,154850.508361878
|
134 |
+
1593,158617.655719941
|
135 |
+
1594,209258.33693701
|
136 |
+
1595,177939.027626751
|
137 |
+
1596,194631.100299584
|
138 |
+
1597,213618.871562568
|
139 |
+
1598,198342.504228533
|
140 |
+
1599,138607.971472497
|
141 |
+
1600,150778.958976731
|
142 |
+
1601,146966.230339786
|
143 |
+
1602,162182.59620952
|
144 |
+
1603,176825.940961269
|
145 |
+
1604,152799.812402444
|
146 |
+
1605,180322.322067129
|
147 |
+
1606,177508.027228367
|
148 |
+
1607,208029.642652019
|
149 |
+
1608,181987.282510201
|
150 |
+
1609,160172.72797397
|
151 |
+
1610,176761.317654248
|
152 |
+
1611,176515.497545231
|
153 |
+
1612,176270.453065471
|
154 |
+
1613,183050.846258475
|
155 |
+
1614,150011.102062216
|
156 |
+
1615,159270.537808667
|
157 |
+
1616,163419.663729346
|
158 |
+
1617,163399.983345859
|
159 |
+
1618,173364.161505756
|
160 |
+
1619,169556.835902417
|
161 |
+
1620,183690.595995738
|
162 |
+
1621,176980.914909382
|
163 |
+
1622,204773.36222471
|
164 |
+
1623,174728.655998442
|
165 |
+
1624,181873.458244461
|
166 |
+
1625,177322.000823979
|
167 |
+
1626,193927.939041863
|
168 |
+
1627,181715.622732304
|
169 |
+
1628,199270.841200324
|
170 |
+
1629,177109.589956218
|
171 |
+
1630,153909.578271486
|
172 |
+
1631,162931.203336223
|
173 |
+
1632,166386.7567182
|
174 |
+
1633,173719.30379824
|
175 |
+
1634,179757.925656704
|
176 |
+
1635,179007.601964376
|
177 |
+
1636,180370.808623106
|
178 |
+
1637,185102.616730563
|
179 |
+
1638,198825.563452058
|
180 |
+
1639,184294.576009142
|
181 |
+
1640,200443.7920562
|
182 |
+
1641,181294.784484153
|
183 |
+
1642,174354.336267919
|
184 |
+
1643,172023.677781517
|
185 |
+
1644,181666.922855025
|
186 |
+
1645,179024.491269586
|
187 |
+
1646,178324.191575907
|
188 |
+
1647,184534.676687694
|
189 |
+
1648,159397.250378784
|
190 |
+
1649,178430.966728182
|
191 |
+
1650,177743.799385967
|
192 |
+
1651,179395.305519087
|
193 |
+
1652,151713.38474815
|
194 |
+
1653,151713.38474815
|
195 |
+
1654,168434.977996215
|
196 |
+
1655,153999.100311019
|
197 |
+
1656,164096.097354123
|
198 |
+
1657,166335.403036551
|
199 |
+
1658,163020.725375757
|
200 |
+
1659,155862.510668829
|
201 |
+
1660,182760.651095509
|
202 |
+
1661,201912.270622883
|
203 |
+
1662,185988.233987516
|
204 |
+
1663,183778.44888032
|
205 |
+
1664,170935.85921771
|
206 |
+
1665,184468.908382254
|
207 |
+
1666,191569.089663229
|
208 |
+
1667,232991.025583822
|
209 |
+
1668,180980.721388278
|
210 |
+
1669,164279.13048219
|
211 |
+
1670,183859.460411109
|
212 |
+
1671,185922.465682076
|
213 |
+
1672,191742.778119363
|
214 |
+
1673,199954.072465842
|
215 |
+
1674,180690.274752587
|
216 |
+
1675,163099.3096358
|
217 |
+
1676,140791.922472443
|
218 |
+
1677,166481.86647592
|
219 |
+
1678,172080.434496773
|
220 |
+
1679,191719.161659178
|
221 |
+
1680,160741.098612515
|
222 |
+
1681,157829.546854733
|
223 |
+
1682,196896.748596341
|
224 |
+
1683,159675.423990355
|
225 |
+
1684,182084.790901946
|
226 |
+
1685,179233.926374487
|
227 |
+
1686,155774.270901623
|
228 |
+
1687,181354.326716058
|
229 |
+
1688,179605.563663918
|
230 |
+
1689,181609.34866147
|
231 |
+
1690,178221.531623281
|
232 |
+
1691,175559.920735795
|
233 |
+
1692,200328.822792041
|
234 |
+
1693,178630.060559899
|
235 |
+
1694,177174.535221728
|
236 |
+
1695,172515.687368714
|
237 |
+
1696,204032.992922943
|
238 |
+
1697,176023.232787689
|
239 |
+
1698,202202.073341595
|
240 |
+
1699,181734.480075862
|
241 |
+
1700,183982.158993126
|
242 |
+
1701,188007.94241481
|
243 |
+
1702,185922.966763517
|
244 |
+
1703,183978.544874918
|
245 |
+
1704,177199.618638821
|
246 |
+
1705,181878.647956764
|
247 |
+
1706,173622.088728263
|
248 |
+
1707,180728.168562655
|
249 |
+
1708,176477.026606328
|
250 |
+
1709,184282.266697609
|
251 |
+
1710,162062.47538448
|
252 |
+
1711,182550.070992189
|
253 |
+
1712,180987.949624695
|
254 |
+
1713,178173.79762147
|
255 |
+
1714,179980.635948606
|
256 |
+
1715,173257.637826205
|
257 |
+
1716,177271.291059307
|
258 |
+
1717,175338.355442312
|
259 |
+
1718,177548.140549508
|
260 |
+
1719,175969.91662932
|
261 |
+
1720,175011.481953462
|
262 |
+
1721,185199.372568143
|
263 |
+
1722,188514.050228937
|
264 |
+
1723,185080.145268797
|
265 |
+
1724,157304.402574096
|
266 |
+
1725,194260.859481297
|
267 |
+
1726,181262.329995106
|
268 |
+
1727,157003.292706732
|
269 |
+
1728,182924.499359899
|
270 |
+
1729,181902.586375439
|
271 |
+
1730,188985.371708134
|
272 |
+
1731,185290.904495068
|
273 |
+
1732,177304.425752748
|
274 |
+
1733,166274.900490809
|
275 |
+
1734,177807.420530107
|
276 |
+
1735,180330.624816201
|
277 |
+
1736,179069.112234629
|
278 |
+
1737,175943.371816948
|
279 |
+
1738,185199.050609653
|
280 |
+
1739,167350.910824524
|
281 |
+
1740,149315.311876449
|
282 |
+
1741,139010.847766793
|
283 |
+
1742,155412.151845447
|
284 |
+
1743,171308.313985441
|
285 |
+
1744,176220.543265638
|
286 |
+
1745,177643.434991809
|
287 |
+
1746,187222.653264601
|
288 |
+
1747,185635.132083154
|
289 |
+
1748,206492.534215854
|
290 |
+
1749,181681.021081956
|
291 |
+
1750,180500.198072685
|
292 |
+
1751,206486.17086841
|
293 |
+
1752,161334.301195429
|
294 |
+
1753,176156.558313965
|
295 |
+
1754,191642.223478994
|
296 |
+
1755,191945.808027777
|
297 |
+
1756,164146.306037354
|
298 |
+
1757,179883.057071096
|
299 |
+
1758,178071.137668844
|
300 |
+
1759,188241.637896875
|
301 |
+
1760,174559.656173171
|
302 |
+
1761,182347.363042264
|
303 |
+
1762,191507.251872857
|
304 |
+
1763,199751.865597358
|
305 |
+
1764,162106.416145131
|
306 |
+
1765,164575.982314367
|
307 |
+
1766,179176.352180931
|
308 |
+
1767,177327.403857584
|
309 |
+
1768,177818.083761781
|
310 |
+
1769,186965.204048443
|
311 |
+
1770,178762.742169197
|
312 |
+
1771,183322.866146283
|
313 |
+
1772,178903.295931891
|
314 |
+
1773,186570.129421778
|
315 |
+
1774,199144.242829024
|
316 |
+
1775,172154.713310956
|
317 |
+
1776,177444.019201603
|
318 |
+
1777,166200.938073485
|
319 |
+
1778,158995.770555632
|
320 |
+
1779,168273.282454755
|
321 |
+
1780,189680.453052788
|
322 |
+
1781,181681.021081956
|
323 |
+
1782,160277.142643643
|
324 |
+
1783,197318.54715833
|
325 |
+
1784,162228.935604196
|
326 |
+
1785,187340.455456083
|
327 |
+
1786,181065.347037275
|
328 |
+
1787,190233.609102705
|
329 |
+
1788,157929.594852031
|
330 |
+
1789,168557.001935469
|
331 |
+
1790,160805.584645628
|
332 |
+
1791,221648.391978216
|
333 |
+
1792,180539.88079815
|
334 |
+
1793,182105.616283853
|
335 |
+
1794,166380.852603154
|
336 |
+
1795,178942.155617426
|
337 |
+
1796,162804.747800461
|
338 |
+
1797,183077.684392615
|
339 |
+
1798,171728.4720292
|
340 |
+
1799,164786.741540638
|
341 |
+
1800,177427.267170302
|
342 |
+
1801,197318.54715833
|
343 |
+
1802,178658.114178223
|
344 |
+
1803,185437.320523764
|
345 |
+
1804,169759.652489529
|
346 |
+
1805,173986.635055186
|
347 |
+
1806,168607.664289468
|
348 |
+
1807,194138.519145183
|
349 |
+
1808,192502.440921994
|
350 |
+
1809,176746.969818601
|
351 |
+
1810,177604.891703134
|
352 |
+
1811,193283.746584832
|
353 |
+
1812,181627.061006609
|
354 |
+
1813,169071.62025834
|
355 |
+
1814,167398.006470987
|
356 |
+
1815,150106.505141704
|
357 |
+
1816,159650.304285848
|
358 |
+
1817,179471.23597476
|
359 |
+
1818,177109.589956218
|
360 |
+
1819,166558.113328453
|
361 |
+
1820,153796.714319583
|
362 |
+
1821,174520.152570658
|
363 |
+
1822,196297.95829524
|
364 |
+
1823,169100.681601175
|
365 |
+
1824,176911.319164431
|
366 |
+
1825,169234.6454828
|
367 |
+
1826,172386.297919134
|
368 |
+
1827,156031.904802362
|
369 |
+
1828,168202.892306596
|
370 |
+
1829,166505.984017547
|
371 |
+
1830,176507.37022149
|
372 |
+
1831,180116.752553161
|
373 |
+
1832,183072.740591406
|
374 |
+
1833,189595.964677698
|
375 |
+
1834,167523.919076265
|
376 |
+
1835,210817.775863413
|
377 |
+
1836,172942.930813351
|
378 |
+
1837,145286.278144089
|
379 |
+
1838,176468.653371492
|
380 |
+
1839,159040.069562187
|
381 |
+
1840,178518.204332507
|
382 |
+
1841,169163.980786825
|
383 |
+
1842,189786.685274579
|
384 |
+
1843,181246.728523853
|
385 |
+
1844,176349.927153587
|
386 |
+
1845,205266.631009142
|
387 |
+
1846,187397.993362224
|
388 |
+
1847,208943.427726113
|
389 |
+
1848,165014.532907657
|
390 |
+
1849,182492.037566236
|
391 |
+
1850,161718.71259042
|
392 |
+
1851,180084.118941162
|
393 |
+
1852,178534.950802179
|
394 |
+
1853,151217.259961305
|
395 |
+
1854,156342.717587562
|
396 |
+
1855,188511.443835239
|
397 |
+
1856,183570.337896789
|
398 |
+
1857,225810.160292177
|
399 |
+
1858,214217.401131694
|
400 |
+
1859,187665.64101603
|
401 |
+
1860,161157.177744039
|
402 |
+
1861,187643.992594193
|
403 |
+
1862,228156.372839158
|
404 |
+
1863,220449.534665317
|
405 |
+
1864,220522.352084222
|
406 |
+
1865,156647.763531624
|
407 |
+
1866,187388.833374873
|
408 |
+
1867,178640.723791573
|
409 |
+
1868,180847.216739049
|
410 |
+
1869,159505.170529478
|
411 |
+
1870,164305.538020654
|
412 |
+
1871,180181.19673723
|
413 |
+
1872,184602.734989972
|
414 |
+
1873,193440.372174434
|
415 |
+
1874,184199.788209911
|
416 |
+
1875,196241.892907637
|
417 |
+
1876,175588.618271096
|
418 |
+
1877,179503.046546829
|
419 |
+
1878,183658.076582555
|
420 |
+
1879,193700.976276404
|
421 |
+
1880,165399.62450704
|
422 |
+
1881,186847.944787446
|
423 |
+
1882,198127.73287817
|
424 |
+
1883,183320.898107934
|
425 |
+
1884,181613.606696657
|
426 |
+
1885,178298.791761954
|
427 |
+
1886,185733.534000593
|
428 |
+
1887,180008.188485489
|
429 |
+
1888,175127.59621604
|
430 |
+
1889,183467.176862723
|
431 |
+
1890,182705.546021743
|
432 |
+
1891,152324.943593181
|
433 |
+
1892,169878.515981342
|
434 |
+
1893,183735.975076576
|
435 |
+
1894,224118.280105941
|
436 |
+
1895,169355.202465146
|
437 |
+
1896,180054.276407441
|
438 |
+
1897,174081.601977368
|
439 |
+
1898,168494.985022146
|
440 |
+
1899,181871.598843299
|
441 |
+
1900,173554.489658383
|
442 |
+
1901,169805.382165577
|
443 |
+
1902,176192.990728755
|
444 |
+
1903,204264.39284654
|
445 |
+
1904,169630.906956928
|
446 |
+
1905,185724.838807268
|
447 |
+
1906,195699.036281861
|
448 |
+
1907,189494.276162169
|
449 |
+
1908,149607.905673439
|
450 |
+
1909,154650.199045978
|
451 |
+
1910,151579.558140433
|
452 |
+
1911,185147.380531144
|
453 |
+
1912,196314.53120359
|
454 |
+
1913,210802.395364155
|
455 |
+
1914,166271.2863726
|
456 |
+
1915,154865.359142973
|
457 |
+
1916,173575.5052865
|
458 |
+
1917,179399.563554274
|
459 |
+
1918,164280.776562049
|
460 |
+
1919,171247.48948121
|
461 |
+
1920,166878.587182445
|
462 |
+
1921,188129.459710994
|
463 |
+
1922,183517.34369691
|
464 |
+
1923,175522.026925727
|
465 |
+
1924,190060.105331152
|
466 |
+
1925,174179.824771856
|
467 |
+
1926,171059.523675194
|
468 |
+
1927,183004.186769318
|
469 |
+
1928,183601.647387418
|
470 |
+
1929,163539.327185998
|
471 |
+
1930,164677.676391525
|
472 |
+
1931,162395.073865424
|
473 |
+
1932,182207.6323195
|
474 |
+
1933,192223.939790304
|
475 |
+
1934,176391.829390125
|
476 |
+
1935,181913.179121348
|
477 |
+
1936,179136.097888261
|
478 |
+
1937,196595.568243212
|
479 |
+
1938,194822.365690957
|
480 |
+
1939,148356.669440918
|
481 |
+
1940,160387.604263899
|
482 |
+
1941,181276.500571809
|
483 |
+
1942,192474.817899346
|
484 |
+
1943,157699.907796437
|
485 |
+
1944,215785.540813051
|
486 |
+
1945,181824.300998793
|
487 |
+
1946,221813.00948166
|
488 |
+
1947,165281.292597397
|
489 |
+
1948,255629.49047034
|
490 |
+
1949,173154.590990955
|
491 |
+
1950,183884.65246539
|
492 |
+
1951,200210.353608489
|
493 |
+
1952,186599.221265342
|
494 |
+
1953,192718.532696106
|
495 |
+
1954,178628.665952764
|
496 |
+
1955,180650.342418406
|
497 |
+
1956,206003.107947263
|
498 |
+
1957,166457.67844853
|
499 |
+
1958,202916.221653487
|
500 |
+
1959,192463.969983091
|
501 |
+
1960,171775.497189898
|
502 |
+
1961,175249.222149411
|
503 |
+
1962,147086.59893993
|
504 |
+
1963,149709.672100371
|
505 |
+
1964,171411.404533743
|
506 |
+
1965,178188.964799425
|
507 |
+
1966,156491.711373235
|
508 |
+
1967,180953.241201168
|
509 |
+
1968,203909.759061135
|
510 |
+
1969,175470.149087545
|
511 |
+
1970,205578.333622415
|
512 |
+
1971,199428.857699441
|
513 |
+
1972,187599.163869476
|
514 |
+
1973,192265.198109864
|
515 |
+
1974,196666.554897677
|
516 |
+
1975,155537.862252682
|
517 |
+
1976,169543.240620935
|
518 |
+
1977,202487.010170501
|
519 |
+
1978,208232.716273485
|
520 |
+
1979,173621.195202569
|
521 |
+
1980,172414.608571812
|
522 |
+
1981,164400.75641556
|
523 |
+
1982,160480.424024781
|
524 |
+
1983,156060.853810389
|
525 |
+
1984,157437.192820581
|
526 |
+
1985,158163.720929772
|
527 |
+
1986,154849.043268978
|
528 |
+
1987,152186.609341561
|
529 |
+
1988,180340.215399228
|
530 |
+
1989,178344.62451356
|
531 |
+
1990,190170.382266827
|
532 |
+
1991,168092.975480832
|
533 |
+
1992,178757.912566805
|
534 |
+
1993,174518.256882082
|
535 |
+
1994,198168.490116289
|
536 |
+
1995,176882.693978902
|
537 |
+
1996,183801.672896251
|
538 |
+
1997,196400.046680661
|
539 |
+
1998,172281.605004025
|
540 |
+
1999,196380.366297173
|
541 |
+
2000,198228.354306682
|
542 |
+
2001,195556.581268962
|
543 |
+
2002,186453.264469043
|
544 |
+
2003,181869.381196234
|
545 |
+
2004,175610.840124147
|
546 |
+
2005,183438.730800145
|
547 |
+
2006,179584.488673295
|
548 |
+
2007,182386.152242034
|
549 |
+
2008,160750.367237054
|
550 |
+
2009,182477.505046008
|
551 |
+
2010,187720.359207171
|
552 |
+
2011,187201.942081511
|
553 |
+
2012,176385.102235149
|
554 |
+
2013,175901.787841278
|
555 |
+
2014,182584.280198283
|
556 |
+
2015,195664.686104237
|
557 |
+
2016,181420.346494222
|
558 |
+
2017,176676.04995228
|
559 |
+
2018,181594.678867334
|
560 |
+
2019,178521.747964951
|
561 |
+
2020,175895.883726231
|
562 |
+
2021,168468.005916477
|
563 |
+
2022,200973.129447888
|
564 |
+
2023,197030.641992202
|
565 |
+
2024,192867.417844592
|
566 |
+
2025,196449.247639381
|
567 |
+
2026,141684.196398607
|
568 |
+
2027,153353.334123901
|
569 |
+
2028,151143.549016705
|
570 |
+
2029,163753.087114229
|
571 |
+
2030,158682.460013921
|
572 |
+
2031,144959.835250915
|
573 |
+
2032,160144.390548579
|
574 |
+
2033,156286.534303521
|
575 |
+
2034,165726.707619571
|
576 |
+
2035,182427.481047359
|
577 |
+
2036,173310.56154032
|
578 |
+
2037,173310.56154032
|
579 |
+
2038,151556.01403002
|
580 |
+
2039,158908.146068683
|
581 |
+
2040,209834.383092536
|
582 |
+
2041,192410.516550815
|
583 |
+
2042,174026.247294886
|
584 |
+
2043,195499.830115336
|
585 |
+
2044,200918.018812493
|
586 |
+
2045,207243.616023976
|
587 |
+
2046,196149.783851876
|
588 |
+
2047,192097.914850217
|
589 |
+
2048,178570.948923671
|
590 |
+
2049,228617.968325428
|
591 |
+
2050,199929.884438451
|
592 |
+
2051,160206.365612859
|
593 |
+
2052,179854.431885567
|
594 |
+
2053,185987.340461822
|
595 |
+
2054,161122.505607926
|
596 |
+
2055,175949.342720138
|
597 |
+
2056,183683.590595324
|
598 |
+
2057,176401.34762338
|
599 |
+
2058,205832.532527897
|
600 |
+
2059,177799.799849436
|
601 |
+
2060,167565.362080406
|
602 |
+
2061,186348.958436557
|
603 |
+
2062,179782.759465081
|
604 |
+
2063,169837.623333323
|
605 |
+
2064,178817.275675758
|
606 |
+
2065,174444.479149339
|
607 |
+
2066,192834.968917174
|
608 |
+
2067,196564.717984981
|
609 |
+
2068,206977.567039357
|
610 |
+
2069,157054.253944128
|
611 |
+
2070,175142.948078577
|
612 |
+
2071,159932.1643654
|
613 |
+
2072,182801.408333628
|
614 |
+
2073,181510.375176825
|
615 |
+
2074,181613.035129451
|
616 |
+
2075,186920.512597635
|
617 |
+
2076,157950.170625222
|
618 |
+
2077,176115.159022876
|
619 |
+
2078,182744.514344465
|
620 |
+
2079,180660.683691591
|
621 |
+
2080,160775.629777099
|
622 |
+
2081,186711.715848082
|
623 |
+
2082,223581.758190888
|
624 |
+
2083,172330.943236652
|
625 |
+
2084,163474.633393212
|
626 |
+
2085,175308.263299874
|
627 |
+
2086,187462.725306432
|
628 |
+
2087,180655.101535034
|
629 |
+
2088,152121.98603454
|
630 |
+
2089,159856.233909727
|
631 |
+
2090,186559.854936737
|
632 |
+
2091,183962.550959411
|
633 |
+
2092,162107.168699296
|
634 |
+
2093,162582.288981283
|
635 |
+
2094,154407.701597409
|
636 |
+
2095,181625.666399474
|
637 |
+
2096,164810.609473548
|
638 |
+
2097,176429.401241704
|
639 |
+
2098,179188.089925259
|
640 |
+
2099,145997.635377703
|
641 |
+
2100,218676.768270367
|
642 |
+
2101,188323.861214226
|
643 |
+
2102,168690.0722914
|
644 |
+
2103,165088.746797705
|
645 |
+
2104,191435.007885166
|
646 |
+
2105,168864.404664512
|
647 |
+
2106,176041.882371574
|
648 |
+
2107,215911.674390325
|
649 |
+
2108,167388.238629016
|
650 |
+
2109,163854.786753017
|
651 |
+
2110,163299.477980171
|
652 |
+
2111,178298.214633119
|
653 |
+
2112,176376.586164775
|
654 |
+
2113,170211.043976522
|
655 |
+
2114,170818.344786366
|
656 |
+
2115,174388.867432503
|
657 |
+
2116,161112.987374671
|
658 |
+
2117,172179.082325307
|
659 |
+
2118,157798.309713876
|
660 |
+
2119,169106.151422924
|
661 |
+
2120,170129.531364292
|
662 |
+
2121,157680.227412949
|
663 |
+
2122,162690.209131977
|
664 |
+
2123,146968.379365095
|
665 |
+
2124,181507.721372455
|
666 |
+
2125,191215.589752983
|
667 |
+
2126,189432.689844522
|
668 |
+
2127,207271.484957719
|
669 |
+
2128,170030.807488363
|
670 |
+
2129,148409.806476335
|
671 |
+
2130,193850.613979055
|
672 |
+
2131,193808.319298263
|
673 |
+
2132,166300.235380627
|
674 |
+
2133,163474.633393212
|
675 |
+
2134,177473.606564978
|
676 |
+
2135,157443.925537187
|
677 |
+
2136,180681.007992057
|
678 |
+
2137,183463.17030026
|
679 |
+
2138,182481.763081195
|
680 |
+
2139,193717.15117887
|
681 |
+
2140,182782.55099007
|
682 |
+
2141,175530.651633287
|
683 |
+
2142,177804.057884623
|
684 |
+
2143,159448.670848577
|
685 |
+
2144,181338.976717529
|
686 |
+
2145,178553.558537021
|
687 |
+
2146,162820.928264556
|
688 |
+
2147,188832.479997186
|
689 |
+
2148,164682.185899437
|
690 |
+
2149,181549.735943801
|
691 |
+
2150,199158.097008868
|
692 |
+
2151,152889.520990566
|
693 |
+
2152,181150.551679116
|
694 |
+
2153,181416.732376013
|
695 |
+
2154,164391.238182305
|
696 |
+
2155,185421.046498812
|
697 |
+
2156,193981.327550004
|
698 |
+
2157,178824.324789223
|
699 |
+
2158,209270.051606246
|
700 |
+
2159,177801.266806344
|
701 |
+
2160,179053.762236101
|
702 |
+
2161,178762.170601992
|
703 |
+
2162,184655.300458183
|
704 |
+
2163,191284.655779772
|
705 |
+
2164,179598.085818785
|
706 |
+
2165,167517.628078595
|
707 |
+
2166,182873.903794044
|
708 |
+
2167,177484.91371363
|
709 |
+
2168,188444.597319524
|
710 |
+
2169,179184.153848562
|
711 |
+
2170,184365.175780982
|
712 |
+
2171,184479.322005212
|
713 |
+
2172,182927.863869391
|
714 |
+
2173,178611.639373646
|
715 |
+
2174,181943.343613558
|
716 |
+
2175,175080.614768394
|
717 |
+
2176,190720.794649138
|
718 |
+
2177,198422.868144723
|
719 |
+
2178,184482.11308349
|
720 |
+
2179,139214.952187861
|
721 |
+
2180,169233.113601757
|
722 |
+
2181,180664.118686848
|
723 |
+
2182,178818.742632666
|
724 |
+
2183,180422.049969947
|
725 |
+
2184,178601.93645581
|
726 |
+
2185,183083.159775993
|
727 |
+
2186,173163.101499699
|
728 |
+
2187,185968.161159774
|
729 |
+
2188,171226.050683054
|
730 |
+
2189,281643.976116786
|
731 |
+
2190,160031.711281258
|
732 |
+
2191,162775.979779394
|
733 |
+
2192,160735.445970193
|
734 |
+
2193,166646.109048572
|
735 |
+
2194,188384.548444549
|
736 |
+
2195,165830.697255197
|
737 |
+
2196,182138.358533039
|
738 |
+
2197,171595.397975647
|
739 |
+
2198,160337.079183809
|
740 |
+
2199,191215.088671543
|
741 |
+
2200,166956.093232213
|
742 |
+
2201,186581.830878692
|
743 |
+
2202,176450.548582099
|
744 |
+
2203,193743.194909801
|
745 |
+
2204,198882.566078408
|
746 |
+
2205,176385.102235149
|
747 |
+
2206,162447.639333636
|
748 |
+
2207,193782.555676777
|
749 |
+
2208,183653.890897141
|
750 |
+
2209,210578.623546866
|
751 |
+
2210,158527.164107319
|
752 |
+
2211,163081.025723456
|
753 |
+
2212,174388.867432503
|
754 |
+
2213,191905.870131966
|
755 |
+
2214,174388.867432503
|
756 |
+
2215,161642.711648983
|
757 |
+
2216,186939.507215101
|
758 |
+
2217,172482.165792649
|
759 |
+
2218,159695.999763546
|
760 |
+
2219,157230.369671007
|
761 |
+
2220,179188.089925259
|
762 |
+
2221,157972.82120994
|
763 |
+
2222,156804.951429181
|
764 |
+
2223,211491.972463654
|
765 |
+
2224,186537.246201062
|
766 |
+
2225,200468.161070551
|
767 |
+
2226,182241.340444154
|
768 |
+
2227,157342.225898399
|
769 |
+
2228,182022.387105998
|
770 |
+
2229,181244.510876788
|
771 |
+
2230,178556.671573788
|
772 |
+
2231,189547.199876284
|
773 |
+
2232,187948.65165563
|
774 |
+
2233,194107.287565956
|
775 |
+
2234,183521.710369283
|
776 |
+
2235,183682.123638416
|
777 |
+
2236,178483.353073443
|
778 |
+
2237,184003.879764736
|
779 |
+
2238,171318.59033449
|
780 |
+
2239,162039.754313997
|
781 |
+
2240,154846.252190699
|
782 |
+
2241,194822.365690957
|
783 |
+
2242,169788.738771463
|
784 |
+
2243,178891.554489941
|
785 |
+
2244,152084.772428865
|
786 |
+
2245,139169.86642879
|
787 |
+
2246,192439.536044606
|
788 |
+
2247,161067.859766557
|
789 |
+
2248,158762.648504781
|
790 |
+
2249,175569.690441774
|
791 |
+
2250,183659.795012187
|
792 |
+
2251,280618.132617258
|
793 |
+
2252,180051.809151659
|
794 |
+
2253,176519.18031559
|
795 |
+
2254,179028.429210291
|
796 |
+
2255,177161.583857224
|
797 |
+
2256,180081.508849842
|
798 |
+
2257,205895.254584712
|
799 |
+
2258,183389.78131415
|
800 |
+
2259,178543.647859512
|
801 |
+
2260,194798.320499104
|
802 |
+
2261,162845.613675766
|
803 |
+
2262,148103.867006579
|
804 |
+
2263,201016.171121215
|
805 |
+
2264,277936.12694354
|
806 |
+
2265,249768.279823405
|
807 |
+
2266,161596.052159825
|
808 |
+
2267,158011.114889899
|
809 |
+
2268,194089.683858004
|
810 |
+
2269,181733.336941451
|
811 |
+
2270,182852.32772198
|
812 |
+
2271,189893.003058465
|
813 |
+
2272,194650.210979875
|
814 |
+
2273,187904.461286262
|
815 |
+
2274,171774.925622692
|
816 |
+
2275,177998.685921479
|
817 |
+
2276,175648.484325498
|
818 |
+
2277,196918.071362067
|
819 |
+
2278,184299.838071218
|
820 |
+
2279,182379.855682734
|
821 |
+
2280,184050.725802482
|
822 |
+
2281,158296.975970284
|
823 |
+
2282,175053.355553278
|
824 |
+
2283,162293.376090644
|
825 |
+
2284,186328.880047186
|
826 |
+
2285,151422.116936538
|
827 |
+
2286,181969.358707768
|
828 |
+
2287,189122.67702416
|
829 |
+
2288,185645.475220346
|
830 |
+
2289,182829.898109257
|
831 |
+
2290,195848.788183328
|
832 |
+
2291,198785.059550672
|
833 |
+
2292,181676.126555428
|
834 |
+
2293,194131.012663328
|
835 |
+
2294,201416.004864508
|
836 |
+
2295,185096.577205616
|
837 |
+
2296,195158.972598372
|
838 |
+
2297,184795.783735112
|
839 |
+
2298,189168.263864671
|
840 |
+
2299,216855.260149095
|
841 |
+
2300,184946.642483576
|
842 |
+
2301,189317.51282069
|
843 |
+
2302,180803.277842406
|
844 |
+
2303,175061.18585763
|
845 |
+
2304,179074.839090732
|
846 |
+
2305,145708.764336107
|
847 |
+
2306,142398.022752011
|
848 |
+
2307,161474.534863641
|
849 |
+
2308,157025.945155458
|
850 |
+
2309,163424.037827357
|
851 |
+
2310,164692.778645345
|
852 |
+
2311,152163.2443541
|
853 |
+
2312,192383.215486656
|
854 |
+
2313,182520.230322476
|
855 |
+
2314,187254.507549722
|
856 |
+
2315,176489.659740359
|
857 |
+
2316,181520.466841293
|
858 |
+
2317,186414.978214721
|
859 |
+
2318,185197.764639705
|
860 |
+
2319,178657.794083741
|
861 |
+
2320,179731.198023759
|
862 |
+
2321,161748.271317074
|
863 |
+
2322,158608.749069322
|
864 |
+
2323,178807.370559878
|
865 |
+
2324,184187.158803897
|
866 |
+
2325,181686.10402108
|
867 |
+
2326,190311.050228337
|
868 |
+
2327,192252.496354076
|
869 |
+
2328,193954.849525775
|
870 |
+
2329,181044.201560887
|
871 |
+
2330,180258.131219792
|
872 |
+
2331,199641.657313834
|
873 |
+
2332,197530.775205517
|
874 |
+
2333,191777.196949138
|
875 |
+
2334,195779.543033588
|
876 |
+
2335,202112.046522999
|
877 |
+
2336,192343.34807661
|
878 |
+
2337,185191.359443218
|
879 |
+
2338,186760.207965688
|
880 |
+
2339,177733.78193528
|
881 |
+
2340,164430.391189608
|
882 |
+
2341,185299.601552401
|
883 |
+
2342,186414.012339254
|
884 |
+
2343,176401.921054593
|
885 |
+
2344,182381.322639642
|
886 |
+
2345,176334.184710805
|
887 |
+
2346,184901.735847457
|
888 |
+
2347,180085.766885029
|
889 |
+
2348,184901.735847457
|
890 |
+
2349,183967.561548763
|
891 |
+
2350,193046.301574659
|
892 |
+
2351,168538.969495849
|
893 |
+
2352,170157.842016969
|
894 |
+
2353,196559.709259637
|
895 |
+
2354,177133.709361852
|
896 |
+
2355,181553.279576244
|
897 |
+
2356,185770.606634739
|
898 |
+
2357,177017.595099274
|
899 |
+
2358,184123.358536806
|
900 |
+
2359,165970.357492196
|
901 |
+
2360,158151.985049452
|
902 |
+
2361,177086.476441481
|
903 |
+
2362,196373.896176551
|
904 |
+
2363,172465.707083115
|
905 |
+
2364,168590.782409896
|
906 |
+
2365,158820.474171061
|
907 |
+
2366,151611.37057651
|
908 |
+
2367,152125.028585543
|
909 |
+
2368,158404.073081048
|
910 |
+
2369,160692.078640755
|
911 |
+
2370,170175.22684199
|
912 |
+
2371,169854.436591138
|
913 |
+
2372,183410.785819008
|
914 |
+
2373,180347.194026928
|
915 |
+
2374,178930.528374292
|
916 |
+
2375,153346.220086301
|
917 |
+
2376,182675.204270589
|
918 |
+
2377,180770.649792036
|
919 |
+
2378,188714.148087543
|
920 |
+
2379,191393.608594076
|
921 |
+
2380,174016.157494425
|
922 |
+
2381,183189.685319552
|
923 |
+
2382,183621.508757866
|
924 |
+
2383,168991.29635758
|
925 |
+
2384,185306.650665866
|
926 |
+
2385,189030.680303208
|
927 |
+
2386,179208.665698449
|
928 |
+
2387,174901.452792889
|
929 |
+
2388,168337.406544343
|
930 |
+
2389,158234.96461859
|
931 |
+
2390,179562.453368834
|
932 |
+
2391,174176.391640607
|
933 |
+
2392,173931.531845427
|
934 |
+
2393,184111.729429665
|
935 |
+
2394,179374.482001188
|
936 |
+
2395,207348.811884535
|
937 |
+
2396,186983.419339031
|
938 |
+
2397,206779.094049527
|
939 |
+
2398,177472.074683935
|
940 |
+
2399,156727.948324862
|
941 |
+
2400,157090.568462479
|
942 |
+
2401,160387.032696693
|
943 |
+
2402,172410.28005086
|
944 |
+
2403,191603.365657467
|
945 |
+
2404,182152.207151253
|
946 |
+
2405,180161.697340702
|
947 |
+
2406,169652.235284283
|
948 |
+
2407,182503.520140218
|
949 |
+
2408,179714.630677039
|
950 |
+
2409,180282.570719908
|
951 |
+
2410,192600.338060371
|
952 |
+
2411,166115.491248565
|
953 |
+
2412,186379.553524443
|
954 |
+
2413,184361.992258449
|
955 |
+
2414,186220.965458121
|
956 |
+
2415,198176.47090687
|
957 |
+
2416,168437.776500131
|
958 |
+
2417,178003.582312015
|
959 |
+
2418,179180.469244588
|
960 |
+
2419,191930.561104806
|
961 |
+
2420,175590.266214964
|
962 |
+
2421,176713.19307219
|
963 |
+
2422,180159.090947005
|
964 |
+
2423,188090.100808026
|
965 |
+
2424,186184.717727913
|
966 |
+
2425,223055.588672278
|
967 |
+
2426,158270.753116401
|
968 |
+
2427,184733.12846644
|
969 |
+
2428,199926.378957429
|
970 |
+
2429,175075.785166001
|
971 |
+
2430,180917.925148076
|
972 |
+
2431,182067.760625207
|
973 |
+
2432,178238.60191545
|
974 |
+
2433,173454.944606532
|
975 |
+
2434,176821.936262814
|
976 |
+
2435,183642.191304235
|
977 |
+
2436,177254.582741058
|
978 |
+
2437,168715.950111702
|
979 |
+
2438,180096.931198144
|
980 |
+
2439,160620.728178758
|
981 |
+
2440,175286.544392273
|
982 |
+
2441,153494.783276297
|
983 |
+
2442,156407.65915545
|
984 |
+
2443,162162.525245786
|
985 |
+
2444,166809.886827197
|
986 |
+
2445,172929.156408918
|
987 |
+
2446,193514.330894137
|
988 |
+
2447,181612.141603756
|
989 |
+
2448,191745.386377068
|
990 |
+
2449,171369.325038261
|
991 |
+
2450,184425.470567051
|
992 |
+
2451,170563.252355189
|
993 |
+
2452,184522.369240168
|
994 |
+
2453,164968.947931153
|
995 |
+
2454,157939.621592364
|
996 |
+
2455,151520.381580069
|
997 |
+
2456,176129.508722531
|
998 |
+
2457,171112.978971478
|
999 |
+
2458,169762.081624282
|
1000 |
+
2459,162246.828936295
|
1001 |
+
2460,171339.303381589
|
1002 |
+
2461,189034.753653813
|
1003 |
+
2462,175758.873595981
|
1004 |
+
2463,163351.721489893
|
1005 |
+
2464,189806.546645026
|
1006 |
+
2465,175370.990918319
|
1007 |
+
2466,196895.599900301
|
1008 |
+
2467,176905.917994834
|
1009 |
+
2468,176866.557227858
|
1010 |
+
2469,163590.677170026
|
1011 |
+
2470,212693.502958393
|
1012 |
+
2471,192686.931747717
|
1013 |
+
2472,181578.684951827
|
1014 |
+
2473,166475.457581812
|
1015 |
+
2474,185998.255166219
|
1016 |
+
2475,185527.714877908
|
1017 |
+
2476,159027.118197683
|
1018 |
+
2477,181169.654933769
|
1019 |
+
2478,176732.915304722
|
1020 |
+
2479,191619.294648838
|
1021 |
+
2480,189114.303789324
|
1022 |
+
2481,180934.635330334
|
1023 |
+
2482,164573.372223048
|
1024 |
+
2483,173902.011270196
|
1025 |
+
2484,165625.127741229
|
1026 |
+
2485,179555.219570787
|
1027 |
+
2486,196899.720661579
|
1028 |
+
2487,207566.12470446
|
1029 |
+
2488,163899.981149274
|
1030 |
+
2489,189179.428177786
|
1031 |
+
2490,193892.880023125
|
1032 |
+
2491,178980.874331431
|
1033 |
+
2492,179749.876244365
|
1034 |
+
2493,197999.674975598
|
1035 |
+
2494,203717.470295797
|
1036 |
+
2495,185249.261156892
|
1037 |
+
2496,201691.208274848
|
1038 |
+
2497,181956.548314794
|
1039 |
+
2498,171895.936275806
|
1040 |
+
2499,187245.168439419
|
1041 |
+
2500,157816.77461318
|
1042 |
+
2501,191702.912573325
|
1043 |
+
2502,198599.420028908
|
1044 |
+
2503,187193.313676329
|
1045 |
+
2504,220514.993999535
|
1046 |
+
2505,181814.527595192
|
1047 |
+
2506,183750.755371907
|
1048 |
+
2507,183000.431679579
|
1049 |
+
2508,185830.971906573
|
1050 |
+
2509,185497.872344187
|
1051 |
+
2510,179613.437681321
|
1052 |
+
2511,164454.967963631
|
1053 |
+
2512,185127.237217638
|
1054 |
+
2513,178750.613844623
|
1055 |
+
2514,160927.61044889
|
1056 |
+
2515,192562.808057836
|
1057 |
+
2516,180990.24148554
|
1058 |
+
2517,180064.941503122
|
1059 |
+
2518,196070.997393789
|
1060 |
+
2519,180352.919019023
|
1061 |
+
2520,183367.953769362
|
1062 |
+
2521,176734.841494027
|
1063 |
+
2522,180848.220765939
|
1064 |
+
2523,187806.059368823
|
1065 |
+
2524,180521.52640004
|
1066 |
+
2525,181502.754496154
|
1067 |
+
2526,174525.87942676
|
1068 |
+
2527,188927.984063168
|
1069 |
+
2528,184728.870431253
|
1070 |
+
2529,179857.975518011
|
1071 |
+
2530,180962.868071609
|
1072 |
+
2531,179194.066390078
|
1073 |
+
2532,179591.789259484
|
1074 |
+
2533,180638.463702549
|
1075 |
+
2534,185846.215131922
|
1076 |
+
2535,195174.031139141
|
1077 |
+
2536,192474.56829063
|
1078 |
+
2537,164200.595496827
|
1079 |
+
2538,178403.094096818
|
1080 |
+
2539,170774.84018302
|
1081 |
+
2540,179879.945898337
|
1082 |
+
2541,177668.192752792
|
1083 |
+
2542,180174.328610725
|
1084 |
+
2543,170643.303572141
|
1085 |
+
2544,165448.004289838
|
1086 |
+
2545,195531.754886222
|
1087 |
+
2546,165314.177682121
|
1088 |
+
2547,172532.757660882
|
1089 |
+
2548,203310.218069877
|
1090 |
+
2549,175090.062515883
|
1091 |
+
2550,230841.338626282
|
1092 |
+
2551,155225.19006632
|
1093 |
+
2552,168322.342441945
|
1094 |
+
2553,165956.259265265
|
1095 |
+
2554,193956.817564124
|
1096 |
+
2555,171070.367893827
|
1097 |
+
2556,166285.243628001
|
1098 |
+
2557,182875.801346628
|
1099 |
+
2558,218108.536769738
|
1100 |
+
2559,174378.777632042
|
1101 |
+
2560,164731.316372391
|
1102 |
+
2561,156969.695083273
|
1103 |
+
2562,173388.854342604
|
1104 |
+
2563,177559.628685119
|
1105 |
+
2564,194297.789279905
|
1106 |
+
2565,174894.588364005
|
1107 |
+
2566,196544.144075798
|
1108 |
+
2567,179036.158528149
|
1109 |
+
2568,211423.986511149
|
1110 |
+
2569,208156.398935188
|
1111 |
+
2570,159233.941347257
|
1112 |
+
2571,210820.115134931
|
1113 |
+
2572,140196.10979821
|
1114 |
+
2573,198678.469082978
|
1115 |
+
2574,186818.610760803
|
1116 |
+
2575,175044.797633861
|
1117 |
+
2576,180031.162892704
|
1118 |
+
2577,176889.171525162
|
1119 |
+
2578,159638.856165666
|
1120 |
+
2579,154287.264375509
|
1121 |
+
2580,191885.618181273
|
1122 |
+
2581,177503.378612934
|
1123 |
+
2582,166548.31684976
|
1124 |
+
2583,164475.14942856
|
1125 |
+
2584,167484.744857879
|
1126 |
+
2585,188683.160555403
|
1127 |
+
2586,162243.399502668
|
1128 |
+
2587,180807.213919103
|
1129 |
+
2588,176279.079637039
|
1130 |
+
2589,163438.959094218
|
1131 |
+
2590,161495.5393685
|
1132 |
+
2591,216032.303722443
|
1133 |
+
2592,176632.181541401
|
1134 |
+
2593,168743.001567144
|
1135 |
+
2594,183810.11848086
|
1136 |
+
2595,156794.36054728
|
1137 |
+
2596,169136.43011395
|
1138 |
+
2597,183203.318752456
|
1139 |
+
2598,213252.926930889
|
1140 |
+
2599,190550.327866959
|
1141 |
+
2600,234707.209860273
|
1142 |
+
2601,135751.318892816
|
1143 |
+
2602,164228.45886894
|
1144 |
+
2603,153219.437030419
|
1145 |
+
2604,164210.746523801
|
1146 |
+
2605,163883.229117973
|
1147 |
+
2606,154892.776269956
|
1148 |
+
2607,197092.08733832
|
1149 |
+
2608,228148.376399122
|
1150 |
+
2609,178680.587503997
|
1151 |
+
2610,165643.341167808
|
1152 |
+
2611,222406.642660249
|
1153 |
+
2612,184021.843582599
|
1154 |
+
2613,170871.094939159
|
1155 |
+
2614,189562.873697309
|
1156 |
+
2615,170591.884966356
|
1157 |
+
2616,172934.351682851
|
1158 |
+
2617,186425.069879189
|
1159 |
+
2618,218648.131133006
|
1160 |
+
2619,183035.606761141
|
1161 |
+
2620,178378.906069427
|
1162 |
+
2621,184516.716597846
|
1163 |
+
2622,181419.5253183
|
1164 |
+
2623,196858.923438425
|
1165 |
+
2624,189228.701486278
|
1166 |
+
2625,208973.380761028
|
1167 |
+
2626,180269.86896412
|
1168 |
+
2627,159488.713683953
|
1169 |
+
2628,191490.299507521
|
1170 |
+
2629,228684.245137946
|
1171 |
+
2630,201842.998700429
|
1172 |
+
2631,209242.82289186
|
1173 |
+
2632,202357.62258493
|
1174 |
+
2633,168238.61218265
|
1175 |
+
2634,202524.12465369
|
1176 |
+
2635,170588.771929588
|
1177 |
+
2636,198375.31512987
|
1178 |
+
2637,170636.827889889
|
1179 |
+
2638,181991.079479377
|
1180 |
+
2639,183994.54251844
|
1181 |
+
2640,182951.482193584
|
1182 |
+
2641,174126.297156192
|
1183 |
+
2642,170575.496742588
|
1184 |
+
2643,175332.239869971
|
1185 |
+
2644,167522.061539111
|
1186 |
+
2645,168095.583738538
|
1187 |
+
2646,154406.415627461
|
1188 |
+
2647,170996.973346087
|
1189 |
+
2648,159056.890245639
|
1190 |
+
2649,181373.6165193
|
1191 |
+
2650,152272.560975937
|
1192 |
+
2651,168664.346821336
|
1193 |
+
2652,211007.008292301
|
1194 |
+
2653,182909.515032911
|
1195 |
+
2654,203926.829353303
|
1196 |
+
2655,179082.825442944
|
1197 |
+
2656,206260.099795032
|
1198 |
+
2657,181732.443415757
|
1199 |
+
2658,189698.740693148
|
1200 |
+
2659,203074.34678979
|
1201 |
+
2660,201670.634365666
|
1202 |
+
2661,173756.812589691
|
1203 |
+
2662,181387.076390881
|
1204 |
+
2663,184859.155270535
|
1205 |
+
2664,158313.615666777
|
1206 |
+
2665,151951.955409666
|
1207 |
+
2666,162537.52704471
|
1208 |
+
2667,178998.337067854
|
1209 |
+
2668,186732.584943041
|
1210 |
+
2669,187323.318406165
|
1211 |
+
2670,199437.232798284
|
1212 |
+
2671,185546.680858653
|
1213 |
+
2672,161595.015798593
|
1214 |
+
2673,154672.422763036
|
1215 |
+
2674,159355.710116165
|
1216 |
+
2675,155919.014077746
|
1217 |
+
2676,182424.87095604
|
1218 |
+
2677,178100.589622319
|
1219 |
+
2678,202577.900044456
|
1220 |
+
2679,177862.778940605
|
1221 |
+
2680,182056.024744887
|
1222 |
+
2681,191403.199177104
|
1223 |
+
2682,196264.754980043
|
1224 |
+
2683,209375.003419718
|
1225 |
+
2684,196691.81930173
|
1226 |
+
2685,192458.431539585
|
1227 |
+
2686,182242.80926507
|
1228 |
+
2687,183259.503900506
|
1229 |
+
2688,188108.243748841
|
1230 |
+
2689,171418.640195797
|
1231 |
+
2690,194698.882220432
|
1232 |
+
2691,174841.84007522
|
1233 |
+
2692,172965.476488899
|
1234 |
+
2693,189386.323677132
|
1235 |
+
2694,185682.618340257
|
1236 |
+
2695,176412.012719061
|
1237 |
+
2696,174976.489722867
|
1238 |
+
2697,180718.581707643
|
1239 |
+
2698,186131.188248242
|
1240 |
+
2699,165220.786354033
|
1241 |
+
2700,164115.893800435
|
1242 |
+
2701,182125.729127024
|
1243 |
+
2702,182285.140233276
|
1244 |
+
2703,196325.442210366
|
1245 |
+
2704,164865.215329881
|
1246 |
+
2705,182694.492209823
|
1247 |
+
2706,185425.485520958
|
1248 |
+
2707,171414.7041191
|
1249 |
+
2708,183433.472466085
|
1250 |
+
2709,176844.981155794
|
1251 |
+
2710,180568.187753206
|
1252 |
+
2711,185948.625475832
|
1253 |
+
2712,189388.291715481
|
1254 |
+
2713,142754.489165865
|
1255 |
+
2714,156106.800760811
|
1256 |
+
2715,155895.397617561
|
1257 |
+
2716,159851.977738548
|
1258 |
+
2717,185157.832305524
|
1259 |
+
2718,180716.291710805
|
1260 |
+
2719,176901.093954071
|
1261 |
+
2720,181017.222455218
|
1262 |
+
2721,183269.159407668
|
1263 |
+
2722,193550.830097069
|
1264 |
+
2723,170625.842699726
|
1265 |
+
2724,182012.405942725
|
1266 |
+
2725,179162.507290733
|
1267 |
+
2726,183269.159407668
|
1268 |
+
2727,180589.836175042
|
1269 |
+
2728,181465.935198741
|
1270 |
+
2729,196053.029878304
|
1271 |
+
2730,183421.020319014
|
1272 |
+
2731,167926.839083612
|
1273 |
+
2732,168027.530997889
|
1274 |
+
2733,182164.26685407
|
1275 |
+
2734,172469.071592608
|
1276 |
+
2735,181059.374300472
|
1277 |
+
2736,182997.570115536
|
1278 |
+
2737,166140.504179894
|
1279 |
+
2738,198515.546934075
|
1280 |
+
2739,193789.648503294
|
1281 |
+
2740,173550.025727531
|
1282 |
+
2741,176487.943174734
|
1283 |
+
2742,188813.302559147
|
1284 |
+
2743,178531.911979192
|
1285 |
+
2744,182145.731469001
|
1286 |
+
2745,179196.465024103
|
1287 |
+
2746,169618.349900686
|
1288 |
+
2747,170010.168655046
|
1289 |
+
2748,181739.671652174
|
1290 |
+
2749,172846.934955574
|
1291 |
+
2750,195560.8830172
|
1292 |
+
2751,180358.114292956
|
1293 |
+
2752,211817.702818093
|
1294 |
+
2753,176170.128686742
|
1295 |
+
2754,234492.248263699
|
1296 |
+
2755,182450.956536015
|
1297 |
+
2756,174902.068073146
|
1298 |
+
2757,173684.174293738
|
1299 |
+
2758,147196.673677562
|
1300 |
+
2759,175231.189709791
|
1301 |
+
2760,193417.64740633
|
1302 |
+
2761,183313.601249761
|
1303 |
+
2762,180882.250849082
|
1304 |
+
2763,186735.697979808
|
1305 |
+
2764,172922.865411247
|
1306 |
+
2765,202551.677190573
|
1307 |
+
2766,190485.634074173
|
1308 |
+
2767,173439.49362151
|
1309 |
+
2768,196613.598849219
|
1310 |
+
2769,178152.259700828
|
1311 |
+
2770,174519.904825949
|
1312 |
+
2771,172627.796932837
|
1313 |
+
2772,173732.689486435
|
1314 |
+
2773,209219.844787023
|
1315 |
+
2774,181059.374300472
|
1316 |
+
2775,188515.443002459
|
1317 |
+
2776,182164.26685407
|
1318 |
+
2777,188137.901597981
|
1319 |
+
2778,158893.54306269
|
1320 |
+
2779,189579.65066771
|
1321 |
+
2780,165229.803505847
|
1322 |
+
2781,162186.071220207
|
1323 |
+
2782,166374.879866351
|
1324 |
+
2783,161665.184974757
|
1325 |
+
2784,175079.328798445
|
1326 |
+
2785,203840.874021305
|
1327 |
+
2786,152129.078861057
|
1328 |
+
2787,181012.141380101
|
1329 |
+
2788,161305.53503837
|
1330 |
+
2789,203326.392972343
|
1331 |
+
2790,168385.571141831
|
1332 |
+
2791,183564.365159986
|
1333 |
+
2792,163784.619440861
|
1334 |
+
2793,171989.192193993
|
1335 |
+
2794,180839.95616829
|
1336 |
+
2795,170895.923185907
|
1337 |
+
2796,174071.054808518
|
1338 |
+
2797,259423.859147546
|
1339 |
+
2798,188000.824679588
|
1340 |
+
2799,179171.703565498
|
1341 |
+
2800,171022.241447762
|
1342 |
+
2801,174126.297156192
|
1343 |
+
2802,187625.573271948
|
1344 |
+
2803,199567.946369234
|
1345 |
+
2804,205328.078219268
|
1346 |
+
2805,166231.535025379
|
1347 |
+
2806,154743.91606057
|
1348 |
+
2807,159714.537012622
|
1349 |
+
2808,185563.069082422
|
1350 |
+
2809,171500.796725006
|
1351 |
+
2810,180983.443844799
|
1352 |
+
2811,183141.236914997
|
1353 |
+
2812,178498.634450214
|
1354 |
+
2813,224323.710512388
|
1355 |
+
2814,218200.642127877
|
1356 |
+
2815,182283.177756557
|
1357 |
+
2816,190054.639237419
|
1358 |
+
2817,160192.453934518
|
1359 |
+
2818,171289.393581756
|
1360 |
+
2819,151131.098733642
|
1361 |
+
2820,181721.458225594
|
1362 |
+
2821,172725.053851858
|
1363 |
+
2822,222438.699143414
|
1364 |
+
2823,235419.373448928
|
1365 |
+
2824,185150.926027596
|
1366 |
+
2825,184772.239624699
|
1367 |
+
2826,180658.216435809
|
1368 |
+
2827,209673.316647174
|
1369 |
+
2828,205939.810625621
|
1370 |
+
2829,165633.573325837
|
1371 |
+
2830,186030.317211014
|
1372 |
+
2831,160312.319589212
|
1373 |
+
2832,190702.440251029
|
1374 |
+
2833,175122.810326699
|
1375 |
+
2834,183783.13937519
|
1376 |
+
2835,178290.666302221
|
1377 |
+
2836,181605.343963015
|
1378 |
+
2837,187992.451444752
|
1379 |
+
2838,188885.11781517
|
1380 |
+
2839,189959.344795118
|
1381 |
+
2840,179258.619211334
|
1382 |
+
2841,181518.750275669
|
1383 |
+
2842,193008.659237315
|
1384 |
+
2843,186313.89385619
|
1385 |
+
2844,181499.39185067
|
1386 |
+
2845,174126.297156192
|
1387 |
+
2846,183918.612062767
|
1388 |
+
2847,184114.270899227
|
1389 |
+
2848,158540.947801398
|
1390 |
+
2849,197034.759055859
|
1391 |
+
2850,185170.284452595
|
1392 |
+
2851,221134.533635148
|
1393 |
+
2852,184306.637575967
|
1394 |
+
2853,199792.302740996
|
1395 |
+
2854,143237.803559736
|
1396 |
+
2855,177294.838897736
|
1397 |
+
2856,182368.620883855
|
1398 |
+
2857,176487.943174734
|
1399 |
+
2858,183849.408762071
|
1400 |
+
2859,184964.141507413
|
1401 |
+
2860,196395.969632434
|
1402 |
+
2861,188374.936650438
|
1403 |
+
2862,176261.296806135
|
1404 |
+
2863,163628.142248426
|
1405 |
+
2864,180618.032628904
|
1406 |
+
2865,161647.329794081
|
1407 |
+
2866,167129.598867773
|
1408 |
+
2867,174750.988352687
|
1409 |
+
2868,177560.202116333
|
1410 |
+
2869,192577.796112839
|
1411 |
+
2870,199202.898960871
|
1412 |
+
2871,182818.156667308
|
1413 |
+
2872,148217.262540651
|
1414 |
+
2873,188997.797082492
|
1415 |
+
2874,185807.928877601
|
1416 |
+
2875,177030.477842021
|
1417 |
+
2876,175942.474593632
|
1418 |
+
2877,172912.518576433
|
1419 |
+
2878,198359.248864591
|
1420 |
+
2879,184379.133036383
|
1421 |
+
2880,194255.566948886
|
1422 |
+
2881,209449.651603064
|
1423 |
+
2882,169979.323958443
|
1424 |
+
2883,188206.281858748
|
1425 |
+
2884,186412.438609167
|
1426 |
+
2885,196761.386409959
|
1427 |
+
2886,208353.269558209
|
1428 |
+
2887,166548.067241044
|
1429 |
+
2888,175942.474593632
|
1430 |
+
2889,166790.457916434
|
1431 |
+
2890,160515.850579067
|
1432 |
+
2891,192167.621096362
|
1433 |
+
2892,178751.551083369
|
1434 |
+
2893,198678.894117024
|
1435 |
+
2894,164553.120272354
|
1436 |
+
2895,156887.932862327
|
1437 |
+
2896,164185.777305524
|
1438 |
+
2897,212992.120630876
|
1439 |
+
2898,197468.550532521
|
1440 |
+
2899,180106.84373966
|
1441 |
+
2900,183972.071056674
|
1442 |
+
2901,245283.198337927
|
1443 |
+
2902,170351.963410756
|
1444 |
+
2903,195596.307707478
|
1445 |
+
2904,189369.756330412
|
1446 |
+
2905,223667.404551664
|
1447 |
+
2906,169335.310624364
|
1448 |
+
2907,167411.02835165
|
1449 |
+
2908,187709.555003968
|
1450 |
+
2909,196526.002998991
|
1451 |
+
2910,137402.569855589
|
1452 |
+
2911,165086.775061735
|
1453 |
+
2912,188506.431412274
|
1454 |
+
2913,172917.456816012
|
1455 |
+
2914,166274.325225982
|
1456 |
+
2915,167081.220948984
|
1457 |
+
2916,164788.778231138
|
1458 |
+
2917,219222.423400059
|
1459 |
+
2918,184924.279658997
|
1460 |
+
2919,187741.866657478
|
aide/example_tasks/house_prices/test.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
aide/example_tasks/house_prices/train.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
aide/interpreter.py
ADDED
@@ -0,0 +1,311 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
Python interpreter for executing code snippets and capturing their output.
|
3 |
+
Supports:
|
4 |
+
- captures stdout and stderr
|
5 |
+
- captures exceptions and stack traces
|
6 |
+
- limits execution time
|
7 |
+
"""
|
8 |
+
|
9 |
+
import logging
|
10 |
+
import os
|
11 |
+
import queue
|
12 |
+
import signal
|
13 |
+
import sys
|
14 |
+
import time
|
15 |
+
import traceback
|
16 |
+
from dataclasses import dataclass
|
17 |
+
from multiprocessing import Process, Queue
|
18 |
+
from pathlib import Path
|
19 |
+
|
20 |
+
import humanize
|
21 |
+
from dataclasses_json import DataClassJsonMixin
|
22 |
+
|
23 |
+
logger = logging.getLogger("aide")
|
24 |
+
|
25 |
+
|
26 |
+
@dataclass
|
27 |
+
class ExecutionResult(DataClassJsonMixin):
|
28 |
+
"""
|
29 |
+
Result of executing a code snippet in the interpreter.
|
30 |
+
Contains the output, execution time, and exception information.
|
31 |
+
"""
|
32 |
+
|
33 |
+
term_out: list[str]
|
34 |
+
exec_time: float
|
35 |
+
exc_type: str | None
|
36 |
+
exc_info: dict | None = None
|
37 |
+
exc_stack: list[tuple] | None = None
|
38 |
+
|
39 |
+
|
40 |
+
def exception_summary(e, working_dir, exec_file_name, format_tb_ipython):
|
41 |
+
"""Generates a string that summarizes an exception and its stack trace (either in standard python repl or in IPython format)."""
|
42 |
+
if format_tb_ipython:
|
43 |
+
import IPython.core.ultratb
|
44 |
+
|
45 |
+
# tb_offset = 1 to skip parts of the stack trace in weflow code
|
46 |
+
tb = IPython.core.ultratb.VerboseTB(tb_offset=1, color_scheme="NoColor")
|
47 |
+
tb_str = str(tb.text(*sys.exc_info()))
|
48 |
+
else:
|
49 |
+
tb_lines = traceback.format_exception(e)
|
50 |
+
# skip parts of stack trace in weflow code
|
51 |
+
tb_str = "".join(
|
52 |
+
[
|
53 |
+
line
|
54 |
+
for line in tb_lines
|
55 |
+
if "aide/" not in line and "importlib" not in line
|
56 |
+
]
|
57 |
+
)
|
58 |
+
# tb_str = "".join([l for l in tb_lines])
|
59 |
+
|
60 |
+
# replace whole path to file with just filename (to remove agent workspace dir)
|
61 |
+
tb_str = tb_str.replace(str(working_dir / exec_file_name), exec_file_name)
|
62 |
+
|
63 |
+
exc_info = {}
|
64 |
+
if hasattr(e, "args"):
|
65 |
+
exc_info["args"] = [str(i) for i in e.args]
|
66 |
+
for att in ["name", "msg", "obj"]:
|
67 |
+
if hasattr(e, att):
|
68 |
+
exc_info[att] = str(getattr(e, att))
|
69 |
+
|
70 |
+
tb = traceback.extract_tb(e.__traceback__)
|
71 |
+
exc_stack = [(t.filename, t.lineno, t.name, t.line) for t in tb]
|
72 |
+
|
73 |
+
return tb_str, e.__class__.__name__, exc_info, exc_stack
|
74 |
+
|
75 |
+
|
76 |
+
class RedirectQueue:
|
77 |
+
def __init__(self, queue, timeout=5):
|
78 |
+
self.queue = queue
|
79 |
+
self.timeout = timeout
|
80 |
+
|
81 |
+
def write(self, msg):
|
82 |
+
try:
|
83 |
+
self.queue.put(msg, timeout=self.timeout)
|
84 |
+
except queue.Full:
|
85 |
+
logger.warning("Queue write timed out")
|
86 |
+
|
87 |
+
def flush(self):
|
88 |
+
pass
|
89 |
+
|
90 |
+
|
91 |
+
class Interpreter:
|
92 |
+
def __init__(
|
93 |
+
self,
|
94 |
+
working_dir: Path | str,
|
95 |
+
timeout: int = 3600,
|
96 |
+
format_tb_ipython: bool = False,
|
97 |
+
agent_file_name: str = "runfile.py",
|
98 |
+
):
|
99 |
+
"""
|
100 |
+
Simulates a standalone Python REPL with an execution time limit.
|
101 |
+
|
102 |
+
Args:
|
103 |
+
working_dir (Path | str): working directory of the agent
|
104 |
+
timeout (int, optional): Timeout for each code execution step. Defaults to 3600.
|
105 |
+
format_tb_ipython (bool, optional): Whether to use IPython or default python REPL formatting for exceptions. Defaults to False.
|
106 |
+
agent_file_name (str, optional): The name for the agent's code file. Defaults to "runfile.py".
|
107 |
+
"""
|
108 |
+
# this really needs to be a path, otherwise causes issues that don't raise exc
|
109 |
+
self.working_dir = Path(working_dir).resolve()
|
110 |
+
assert (
|
111 |
+
self.working_dir.exists()
|
112 |
+
), f"Working directory {self.working_dir} does not exist"
|
113 |
+
self.timeout = timeout
|
114 |
+
self.format_tb_ipython = format_tb_ipython
|
115 |
+
self.agent_file_name = agent_file_name
|
116 |
+
self.process: Process = None # type: ignore
|
117 |
+
|
118 |
+
def child_proc_setup(self, result_outq: Queue) -> None:
|
119 |
+
# disable all warnings (before importing anything)
|
120 |
+
import shutup
|
121 |
+
|
122 |
+
shutup.mute_warnings()
|
123 |
+
os.chdir(str(self.working_dir))
|
124 |
+
|
125 |
+
# this seems to only benecessary because we're exec'ing code from a string,
|
126 |
+
# a .py file should be able to import modules from the cwd anyway
|
127 |
+
sys.path.append(str(self.working_dir))
|
128 |
+
|
129 |
+
# capture stdout and stderr
|
130 |
+
# trunk-ignore(mypy/assignment)
|
131 |
+
sys.stdout = sys.stderr = RedirectQueue(result_outq)
|
132 |
+
|
133 |
+
def _run_session(
|
134 |
+
self, code_inq: Queue, result_outq: Queue, event_outq: Queue
|
135 |
+
) -> None:
|
136 |
+
self.child_proc_setup(result_outq)
|
137 |
+
|
138 |
+
global_scope: dict = {}
|
139 |
+
while True:
|
140 |
+
code = code_inq.get()
|
141 |
+
os.chdir(str(self.working_dir))
|
142 |
+
with open(self.agent_file_name, "w") as f:
|
143 |
+
f.write(code)
|
144 |
+
|
145 |
+
event_outq.put(("state:ready",))
|
146 |
+
try:
|
147 |
+
exec(compile(code, self.agent_file_name, "exec"), global_scope)
|
148 |
+
except BaseException as e:
|
149 |
+
tb_str, e_cls_name, exc_info, exc_stack = exception_summary(
|
150 |
+
e,
|
151 |
+
self.working_dir,
|
152 |
+
self.agent_file_name,
|
153 |
+
self.format_tb_ipython,
|
154 |
+
)
|
155 |
+
result_outq.put(tb_str)
|
156 |
+
if e_cls_name == "KeyboardInterrupt":
|
157 |
+
e_cls_name = "TimeoutError"
|
158 |
+
|
159 |
+
event_outq.put(("state:finished", e_cls_name, exc_info, exc_stack))
|
160 |
+
else:
|
161 |
+
event_outq.put(("state:finished", None, None, None))
|
162 |
+
|
163 |
+
# remove the file after execution (otherwise it might be included in the data preview)
|
164 |
+
os.remove(self.agent_file_name)
|
165 |
+
|
166 |
+
# put EOF marker to indicate that we're done
|
167 |
+
result_outq.put("<|EOF|>")
|
168 |
+
|
169 |
+
def create_process(self) -> None:
|
170 |
+
# we use three queues to communicate with the child process:
|
171 |
+
# - code_inq: send code to child to execute
|
172 |
+
# - result_outq: receive stdout/stderr from child
|
173 |
+
# - event_outq: receive events from child (e.g. state:ready, state:finished)
|
174 |
+
# trunk-ignore(mypy/var-annotated)
|
175 |
+
self.code_inq, self.result_outq, self.event_outq = Queue(), Queue(), Queue()
|
176 |
+
self.process = Process(
|
177 |
+
target=self._run_session,
|
178 |
+
args=(self.code_inq, self.result_outq, self.event_outq),
|
179 |
+
)
|
180 |
+
self.process.start()
|
181 |
+
|
182 |
+
def cleanup_session(self):
|
183 |
+
if self.process is None:
|
184 |
+
return
|
185 |
+
try:
|
186 |
+
# Reduce grace period from 2 seconds to 0.5
|
187 |
+
self.process.terminate()
|
188 |
+
self.process.join(timeout=0.5)
|
189 |
+
|
190 |
+
if self.process.exitcode is None:
|
191 |
+
logger.warning("Process failed to terminate, killing immediately")
|
192 |
+
self.process.kill()
|
193 |
+
self.process.join(timeout=0.5)
|
194 |
+
|
195 |
+
if self.process.exitcode is None:
|
196 |
+
logger.error("Process refuses to die, using SIGKILL")
|
197 |
+
os.kill(self.process.pid, signal.SIGKILL)
|
198 |
+
except Exception as e:
|
199 |
+
logger.error(f"Error during process cleanup: {e}")
|
200 |
+
finally:
|
201 |
+
if self.process is not None:
|
202 |
+
self.process.close()
|
203 |
+
self.process = None
|
204 |
+
|
205 |
+
def run(self, code: str, reset_session=True) -> ExecutionResult:
|
206 |
+
"""
|
207 |
+
Execute the provided Python command in a separate process and return its output.
|
208 |
+
|
209 |
+
Parameters:
|
210 |
+
code (str): Python code to execute.
|
211 |
+
reset_session (bool, optional): Whether to reset the interpreter session before executing the code. Defaults to True.
|
212 |
+
|
213 |
+
Returns:
|
214 |
+
ExecutionResult: Object containing the output and metadata of the code execution.
|
215 |
+
|
216 |
+
"""
|
217 |
+
|
218 |
+
logger.debug(f"REPL is executing code (reset_session={reset_session})")
|
219 |
+
|
220 |
+
if reset_session:
|
221 |
+
if self.process is not None:
|
222 |
+
# terminate and clean up previous process
|
223 |
+
self.cleanup_session()
|
224 |
+
self.create_process()
|
225 |
+
else:
|
226 |
+
# reset_session needs to be True on first exec
|
227 |
+
assert self.process is not None
|
228 |
+
|
229 |
+
assert self.process.is_alive()
|
230 |
+
|
231 |
+
self.code_inq.put(code)
|
232 |
+
|
233 |
+
# wait for child to actually start execution (we don't want interrupt child setup)
|
234 |
+
try:
|
235 |
+
state = self.event_outq.get(timeout=10)
|
236 |
+
except queue.Empty:
|
237 |
+
msg = "REPL child process failed to start execution"
|
238 |
+
logger.critical(msg)
|
239 |
+
while not self.result_outq.empty():
|
240 |
+
logger.error(f"REPL output queue dump: {self.result_outq.get()}")
|
241 |
+
raise RuntimeError(msg) from None
|
242 |
+
assert state[0] == "state:ready", state
|
243 |
+
start_time = time.time()
|
244 |
+
|
245 |
+
# this flag indicates that the child ahs exceeded the time limit and an interrupt was sent
|
246 |
+
# if the child process dies without this flag being set, it's an unexpected termination
|
247 |
+
child_in_overtime = False
|
248 |
+
|
249 |
+
while True:
|
250 |
+
try:
|
251 |
+
# check if the child is done
|
252 |
+
state = self.event_outq.get(timeout=1) # wait for state:finished
|
253 |
+
assert state[0] == "state:finished", state
|
254 |
+
exec_time = time.time() - start_time
|
255 |
+
break
|
256 |
+
except queue.Empty:
|
257 |
+
# we haven't heard back from the child -> check if it's still alive (assuming overtime interrupt wasn't sent yet)
|
258 |
+
if not child_in_overtime and not self.process.is_alive():
|
259 |
+
msg = "REPL child process died unexpectedly"
|
260 |
+
logger.critical(msg)
|
261 |
+
while not self.result_outq.empty():
|
262 |
+
logger.error(
|
263 |
+
f"REPL output queue dump: {self.result_outq.get()}"
|
264 |
+
)
|
265 |
+
raise RuntimeError(msg) from None
|
266 |
+
|
267 |
+
# child is alive and still executing -> check if we should sigint..
|
268 |
+
if self.timeout is None:
|
269 |
+
continue
|
270 |
+
running_time = time.time() - start_time
|
271 |
+
if running_time > self.timeout:
|
272 |
+
logger.warning(f"Execution exceeded timeout of {self.timeout}s")
|
273 |
+
os.kill(self.process.pid, signal.SIGINT)
|
274 |
+
child_in_overtime = True
|
275 |
+
|
276 |
+
# terminate if we're overtime by more than 5 seconds
|
277 |
+
if running_time > self.timeout + 5:
|
278 |
+
logger.warning("Child failed to terminate, killing it..")
|
279 |
+
self.cleanup_session()
|
280 |
+
|
281 |
+
state = (None, "TimeoutError", {}, [])
|
282 |
+
exec_time = self.timeout
|
283 |
+
break
|
284 |
+
|
285 |
+
output: list[str] = []
|
286 |
+
# read all stdout/stderr from child up to the EOF marker
|
287 |
+
# waiting until the queue is empty is not enough since
|
288 |
+
# the feeder thread in child might still be adding to the queue
|
289 |
+
start_collect = time.time()
|
290 |
+
while not self.result_outq.empty() or not output or output[-1] != "<|EOF|>":
|
291 |
+
try:
|
292 |
+
# Add 5-second timeout for output collection
|
293 |
+
if time.time() - start_collect > 5:
|
294 |
+
logger.warning("Output collection timed out")
|
295 |
+
break
|
296 |
+
output.append(self.result_outq.get(timeout=1))
|
297 |
+
except queue.Empty:
|
298 |
+
continue
|
299 |
+
output.pop() # remove the EOF marker
|
300 |
+
|
301 |
+
e_cls_name, exc_info, exc_stack = state[1:]
|
302 |
+
|
303 |
+
if e_cls_name == "TimeoutError":
|
304 |
+
output.append(
|
305 |
+
f"TimeoutError: Execution exceeded the time limit of {humanize.naturaldelta(self.timeout)}"
|
306 |
+
)
|
307 |
+
else:
|
308 |
+
output.append(
|
309 |
+
f"Execution time: {humanize.naturaldelta(exec_time)} seconds (time limit is {humanize.naturaldelta(self.timeout)})."
|
310 |
+
)
|
311 |
+
return ExecutionResult(output, exec_time, e_cls_name, exc_info, exc_stack)
|
aide/journal.py
ADDED
@@ -0,0 +1,192 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
The journal is the core datastructure in AIDE that contains:
|
3 |
+
- the generated code samples
|
4 |
+
- information how code samples relate to each other (the tree structure)
|
5 |
+
- code execution results
|
6 |
+
- evaluation information such as metrics
|
7 |
+
...
|
8 |
+
"""
|
9 |
+
|
10 |
+
import time
|
11 |
+
import uuid
|
12 |
+
from dataclasses import dataclass, field
|
13 |
+
from typing import Literal, Optional
|
14 |
+
|
15 |
+
from dataclasses_json import DataClassJsonMixin
|
16 |
+
from .interpreter import ExecutionResult
|
17 |
+
from .utils.metric import MetricValue
|
18 |
+
from .utils.response import trim_long_string
|
19 |
+
|
20 |
+
|
21 |
+
@dataclass(eq=False)
|
22 |
+
class Node(DataClassJsonMixin):
|
23 |
+
"""A single node in the solution tree. Contains code, execution results, and evaluation information."""
|
24 |
+
|
25 |
+
# ---- code & plan ----
|
26 |
+
code: str
|
27 |
+
plan: str = field(default=None, kw_only=True) # type: ignore
|
28 |
+
|
29 |
+
# ---- general attrs ----
|
30 |
+
step: int = field(default=None, kw_only=True) # type: ignore
|
31 |
+
id: str = field(default_factory=lambda: uuid.uuid4().hex, kw_only=True)
|
32 |
+
ctime: float = field(default_factory=lambda: time.time(), kw_only=True)
|
33 |
+
parent: Optional["Node"] = field(default=None, kw_only=True)
|
34 |
+
children: set["Node"] = field(default_factory=set, kw_only=True)
|
35 |
+
|
36 |
+
# ---- execution info ----
|
37 |
+
_term_out: list[str] = field(default=None, kw_only=True) # type: ignore
|
38 |
+
exec_time: float = field(default=None, kw_only=True) # type: ignore
|
39 |
+
exc_type: str | None = field(default=None, kw_only=True)
|
40 |
+
exc_info: dict | None = field(default=None, kw_only=True)
|
41 |
+
exc_stack: list[tuple] | None = field(default=None, kw_only=True)
|
42 |
+
|
43 |
+
# ---- evaluation ----
|
44 |
+
# post-execution result analysis (findings/feedback)
|
45 |
+
analysis: str = field(default=None, kw_only=True) # type: ignore
|
46 |
+
metric: MetricValue = field(default=None, kw_only=True) # type: ignore
|
47 |
+
# whether the agent decided that the code is buggy
|
48 |
+
# -> always True if exc_type is not None or no valid metric
|
49 |
+
is_buggy: bool = field(default=None, kw_only=True) # type: ignore
|
50 |
+
|
51 |
+
def __post_init__(self) -> None:
|
52 |
+
if self.parent is not None:
|
53 |
+
self.parent.children.add(self)
|
54 |
+
|
55 |
+
@property
|
56 |
+
def stage_name(self) -> Literal["draft", "debug", "improve"]:
|
57 |
+
"""
|
58 |
+
Return the stage of the node:
|
59 |
+
- "stage" if the node is an initial solution draft
|
60 |
+
- "debug" if the node is the result of a debugging step
|
61 |
+
- "improve" if the node is the result of an improvement step
|
62 |
+
"""
|
63 |
+
if self.parent is None:
|
64 |
+
return "draft"
|
65 |
+
return "debug" if self.parent.is_buggy else "improve"
|
66 |
+
|
67 |
+
def absorb_exec_result(self, exec_result: ExecutionResult):
|
68 |
+
"""Absorb the result of executing the code from this node."""
|
69 |
+
self._term_out = exec_result.term_out
|
70 |
+
self.exec_time = exec_result.exec_time
|
71 |
+
self.exc_type = exec_result.exc_type
|
72 |
+
self.exc_info = exec_result.exc_info
|
73 |
+
self.exc_stack = exec_result.exc_stack
|
74 |
+
|
75 |
+
@property
|
76 |
+
def term_out(self) -> str:
|
77 |
+
"""Get the terminal output of the code execution (after truncating it)."""
|
78 |
+
return trim_long_string("".join(self._term_out))
|
79 |
+
|
80 |
+
@property
|
81 |
+
def is_leaf(self) -> bool:
|
82 |
+
"""Check if the node is a leaf node in the solution tree."""
|
83 |
+
return not self.children
|
84 |
+
|
85 |
+
def __eq__(self, other):
|
86 |
+
return isinstance(other, Node) and self.id == other.id
|
87 |
+
|
88 |
+
def __hash__(self):
|
89 |
+
return hash(self.id)
|
90 |
+
|
91 |
+
@property
|
92 |
+
def debug_depth(self) -> int:
|
93 |
+
"""
|
94 |
+
Length of the current debug path
|
95 |
+
- 0 if the node is not a debug node (parent is not buggy)
|
96 |
+
- 1 if the parent is buggy but the skip parent isn't
|
97 |
+
- n if there were n consecutive debugging steps
|
98 |
+
"""
|
99 |
+
if self.stage_name != "debug":
|
100 |
+
return 0
|
101 |
+
return self.parent.debug_depth + 1 # type: ignore
|
102 |
+
|
103 |
+
|
104 |
+
@dataclass
|
105 |
+
class InteractiveSession(DataClassJsonMixin):
|
106 |
+
"""
|
107 |
+
A collection of nodes for an interaction session
|
108 |
+
(when the agent interacts with a Jupyter notebook-like interface).
|
109 |
+
"""
|
110 |
+
|
111 |
+
nodes: list[Node] = field(default_factory=list)
|
112 |
+
completed: bool = False
|
113 |
+
|
114 |
+
def append(self, node: Node) -> None:
|
115 |
+
node.step = len(self.nodes)
|
116 |
+
self.nodes.append(node)
|
117 |
+
|
118 |
+
def generate_nb_trace(self, include_prompt, comment_headers=True) -> str:
|
119 |
+
"""Generate a trace of the interactive session in IPython format."""
|
120 |
+
trace = []
|
121 |
+
header_prefix = "## " if comment_headers else ""
|
122 |
+
for n in self.nodes:
|
123 |
+
trace.append(f"\n{header_prefix}In [{n.step+1}]:\n")
|
124 |
+
trace.append(n.code)
|
125 |
+
trace.append(f"\n{header_prefix}Out [{n.step+1}]:\n")
|
126 |
+
trace.append(n.term_out)
|
127 |
+
|
128 |
+
if include_prompt and self.nodes:
|
129 |
+
trace.append(f"\n{header_prefix}In [{self.nodes[-1].step+2}]:\n")
|
130 |
+
|
131 |
+
return "\n".join(trace).strip()
|
132 |
+
|
133 |
+
|
134 |
+
@dataclass
|
135 |
+
class Journal(DataClassJsonMixin):
|
136 |
+
"""A collection of nodes representing the solution tree."""
|
137 |
+
|
138 |
+
nodes: list[Node] = field(default_factory=list)
|
139 |
+
# eda: InteractiveSession = field(default_factory=lambda: InteractiveSession())
|
140 |
+
|
141 |
+
def __getitem__(self, idx: int) -> Node:
|
142 |
+
return self.nodes[idx]
|
143 |
+
|
144 |
+
def __len__(self) -> int:
|
145 |
+
"""Return the number of nodes in the journal."""
|
146 |
+
return len(self.nodes)
|
147 |
+
|
148 |
+
def append(self, node: Node) -> None:
|
149 |
+
"""Append a new node to the journal."""
|
150 |
+
node.step = len(self.nodes)
|
151 |
+
self.nodes.append(node)
|
152 |
+
|
153 |
+
@property
|
154 |
+
def draft_nodes(self) -> list[Node]:
|
155 |
+
"""Return a list of nodes representing intial coding drafts"""
|
156 |
+
return [n for n in self.nodes if n.parent is None]
|
157 |
+
|
158 |
+
@property
|
159 |
+
def buggy_nodes(self) -> list[Node]:
|
160 |
+
"""Return a list of nodes that are considered buggy by the agent."""
|
161 |
+
return [n for n in self.nodes if n.is_buggy]
|
162 |
+
|
163 |
+
@property
|
164 |
+
def good_nodes(self) -> list[Node]:
|
165 |
+
"""Return a list of nodes that are not considered buggy by the agent."""
|
166 |
+
return [n for n in self.nodes if not n.is_buggy]
|
167 |
+
|
168 |
+
def get_metric_history(self) -> list[MetricValue]:
|
169 |
+
"""Return a list of all metric values in the journal."""
|
170 |
+
return [n.metric for n in self.nodes]
|
171 |
+
|
172 |
+
def get_best_node(self, only_good=True) -> None | Node:
|
173 |
+
"""Return the best solution found so far (node with the highest validation metric)."""
|
174 |
+
if only_good:
|
175 |
+
nodes = self.good_nodes
|
176 |
+
if not nodes:
|
177 |
+
return None
|
178 |
+
else:
|
179 |
+
nodes = self.nodes
|
180 |
+
return max(nodes, key=lambda n: n.metric)
|
181 |
+
|
182 |
+
def generate_summary(self, include_code: bool = False) -> str:
|
183 |
+
"""Generate a summary of the journal for the agent."""
|
184 |
+
summary = []
|
185 |
+
for n in self.good_nodes:
|
186 |
+
summary_part = f"Design: {n.plan}\n"
|
187 |
+
if include_code:
|
188 |
+
summary_part += f"Code: {n.code}\n"
|
189 |
+
summary_part += f"Results: {n.analysis}\n"
|
190 |
+
summary_part += f"Validation Metric: {n.metric.value}\n"
|
191 |
+
summary.append(summary_part)
|
192 |
+
return "\n-------------------------------\n".join(summary)
|
aide/journal2report.py
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from .backend import query
|
2 |
+
from .journal import Journal
|
3 |
+
from .utils.config import StageConfig
|
4 |
+
|
5 |
+
|
6 |
+
def journal2report(journal: Journal, task_desc: dict, rcfg: StageConfig):
|
7 |
+
"""
|
8 |
+
Generate a report from a journal, the report will be in markdown format.
|
9 |
+
"""
|
10 |
+
report_input = journal.generate_summary(include_code=True)
|
11 |
+
system_prompt_dict = {
|
12 |
+
"Role": "You are a research assistant that always uses concise language.",
|
13 |
+
"Goal": "The goal is to write a technical report summarising the empirical findings and technical decisions.",
|
14 |
+
"Input": "You are given a raw research journal with list of design attempts and their outcomes, and a task description.",
|
15 |
+
"Output": [
|
16 |
+
"Your output should be a single markdown document.",
|
17 |
+
"Your report should have the following sections: Introduction, Preprocessing, Modellind Methods, Results Discussion, Future Work",
|
18 |
+
"You can include subsections if needed.",
|
19 |
+
],
|
20 |
+
}
|
21 |
+
context_prompt = (
|
22 |
+
f"Here is the research journal of the agent: <journal>{report_input}<\\journal>, "
|
23 |
+
f"and the task description is: <task>{task_desc}<\\task>."
|
24 |
+
)
|
25 |
+
return query(
|
26 |
+
system_message=system_prompt_dict,
|
27 |
+
user_message=context_prompt,
|
28 |
+
model=rcfg.model,
|
29 |
+
temperature=rcfg.temp,
|
30 |
+
max_tokens=4096,
|
31 |
+
)
|
aide/run.py
ADDED
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import atexit
|
2 |
+
import logging
|
3 |
+
import shutil
|
4 |
+
|
5 |
+
from . import backend
|
6 |
+
|
7 |
+
from .agent import Agent
|
8 |
+
from .interpreter import Interpreter
|
9 |
+
from .journal import Journal, Node
|
10 |
+
from .journal2report import journal2report
|
11 |
+
from omegaconf import OmegaConf
|
12 |
+
from rich.columns import Columns
|
13 |
+
from rich.console import Group
|
14 |
+
from rich.live import Live
|
15 |
+
from rich.padding import Padding
|
16 |
+
from rich.panel import Panel
|
17 |
+
from rich.progress import (
|
18 |
+
BarColumn,
|
19 |
+
MofNCompleteColumn,
|
20 |
+
Progress,
|
21 |
+
TextColumn,
|
22 |
+
TimeRemainingColumn,
|
23 |
+
)
|
24 |
+
from rich.text import Text
|
25 |
+
from rich.status import Status
|
26 |
+
from rich.tree import Tree
|
27 |
+
from .utils.config import load_task_desc, prep_agent_workspace, save_run, load_cfg
|
28 |
+
|
29 |
+
logger = logging.getLogger("aide")
|
30 |
+
|
31 |
+
|
32 |
+
def journal_to_rich_tree(journal: Journal):
|
33 |
+
best_node = journal.get_best_node()
|
34 |
+
|
35 |
+
def append_rec(node: Node, tree):
|
36 |
+
if node.is_buggy:
|
37 |
+
s = "[red]◍ bug"
|
38 |
+
else:
|
39 |
+
style = "bold " if node is best_node else ""
|
40 |
+
|
41 |
+
if node is best_node:
|
42 |
+
s = f"[{style}green]● {node.metric.value:.3f} (best)"
|
43 |
+
else:
|
44 |
+
s = f"[{style}green]● {node.metric.value:.3f}"
|
45 |
+
|
46 |
+
subtree = tree.add(s)
|
47 |
+
for child in node.children:
|
48 |
+
append_rec(child, subtree)
|
49 |
+
|
50 |
+
tree = Tree("[bold blue]Solution tree")
|
51 |
+
for n in journal.draft_nodes:
|
52 |
+
append_rec(n, tree)
|
53 |
+
return tree
|
54 |
+
|
55 |
+
|
56 |
+
def run():
|
57 |
+
cfg = load_cfg()
|
58 |
+
logger.info(f'Starting run "{cfg.exp_name}"')
|
59 |
+
|
60 |
+
task_desc = load_task_desc(cfg)
|
61 |
+
task_desc_str = backend.compile_prompt_to_md(task_desc)
|
62 |
+
|
63 |
+
with Status("Preparing agent workspace (copying and extracting files) ..."):
|
64 |
+
prep_agent_workspace(cfg)
|
65 |
+
|
66 |
+
def cleanup():
|
67 |
+
if global_step == 0:
|
68 |
+
shutil.rmtree(cfg.workspace_dir)
|
69 |
+
|
70 |
+
atexit.register(cleanup)
|
71 |
+
|
72 |
+
journal = Journal()
|
73 |
+
agent = Agent(
|
74 |
+
task_desc=task_desc,
|
75 |
+
cfg=cfg,
|
76 |
+
journal=journal,
|
77 |
+
)
|
78 |
+
interpreter = Interpreter(
|
79 |
+
cfg.workspace_dir, **OmegaConf.to_container(cfg.exec) # type: ignore
|
80 |
+
)
|
81 |
+
|
82 |
+
global_step = len(journal)
|
83 |
+
prog = Progress(
|
84 |
+
TextColumn("[progress.description]{task.description}"),
|
85 |
+
BarColumn(bar_width=20),
|
86 |
+
MofNCompleteColumn(),
|
87 |
+
TimeRemainingColumn(),
|
88 |
+
)
|
89 |
+
status = Status("[green]Generating code...")
|
90 |
+
prog.add_task("Progress:", total=cfg.agent.steps, completed=global_step)
|
91 |
+
|
92 |
+
def exec_callback(*args, **kwargs):
|
93 |
+
status.update("[magenta]Executing code...")
|
94 |
+
res = interpreter.run(*args, **kwargs)
|
95 |
+
status.update("[green]Generating code...")
|
96 |
+
return res
|
97 |
+
|
98 |
+
def generate_live():
|
99 |
+
tree = journal_to_rich_tree(journal)
|
100 |
+
prog.update(prog.task_ids[0], completed=global_step)
|
101 |
+
|
102 |
+
file_paths = [
|
103 |
+
f"Result visualization:\n[yellow]▶ {str((cfg.log_dir / 'tree_plot.html'))}",
|
104 |
+
f"Agent workspace directory:\n[yellow]▶ {str(cfg.workspace_dir)}",
|
105 |
+
f"Experiment log directory:\n[yellow]▶ {str(cfg.log_dir)}",
|
106 |
+
]
|
107 |
+
left = Group(
|
108 |
+
Panel(Text(task_desc_str.strip()), title="Task description"), prog, status
|
109 |
+
)
|
110 |
+
right = tree
|
111 |
+
wide = Group(*file_paths)
|
112 |
+
|
113 |
+
return Panel(
|
114 |
+
Group(
|
115 |
+
Padding(wide, (1, 1, 1, 1)),
|
116 |
+
Columns(
|
117 |
+
[Padding(left, (1, 2, 1, 1)), Padding(right, (1, 1, 1, 2))],
|
118 |
+
equal=True,
|
119 |
+
),
|
120 |
+
),
|
121 |
+
title=f'[b]AIDE is working on experiment: [bold green]"{cfg.exp_name}[/b]"',
|
122 |
+
subtitle="Press [b]Ctrl+C[/b] to stop the run",
|
123 |
+
)
|
124 |
+
|
125 |
+
with Live(
|
126 |
+
generate_live(),
|
127 |
+
refresh_per_second=16,
|
128 |
+
screen=True,
|
129 |
+
) as live:
|
130 |
+
while global_step < cfg.agent.steps:
|
131 |
+
agent.step(exec_callback=exec_callback)
|
132 |
+
save_run(cfg, journal)
|
133 |
+
global_step = len(journal)
|
134 |
+
live.update(generate_live())
|
135 |
+
interpreter.cleanup_session()
|
136 |
+
|
137 |
+
if cfg.generate_report:
|
138 |
+
print("Generating final report from journal...")
|
139 |
+
report = journal2report(journal, task_desc, cfg.report)
|
140 |
+
print(report)
|
141 |
+
report_file_path = cfg.log_dir / "report.md"
|
142 |
+
with open(report_file_path, "w") as f:
|
143 |
+
f.write(report)
|
144 |
+
print("Report written to file:", report_file_path)
|
145 |
+
|
146 |
+
|
147 |
+
if __name__ == "__main__":
|
148 |
+
run()
|
aide/utils/__init__.py
ADDED
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
import shutil
|
3 |
+
import zipfile
|
4 |
+
from pathlib import Path
|
5 |
+
|
6 |
+
logger = logging.getLogger("aide")
|
7 |
+
|
8 |
+
|
9 |
+
def copytree(src: Path, dst: Path, use_symlinks=True):
|
10 |
+
"""
|
11 |
+
Copy contents of `src` to `dst`. Unlike shutil.copytree, the dst dir can exist and will be merged.
|
12 |
+
If src is a file, only that file will be copied. Optionally uses symlinks instead of copying.
|
13 |
+
|
14 |
+
Args:
|
15 |
+
src (Path): source directory
|
16 |
+
dst (Path): destination directory
|
17 |
+
"""
|
18 |
+
assert dst.is_dir()
|
19 |
+
|
20 |
+
if src.is_file():
|
21 |
+
dest_f = dst / src.name
|
22 |
+
assert not dest_f.exists(), dest_f
|
23 |
+
if use_symlinks:
|
24 |
+
(dest_f).symlink_to(src)
|
25 |
+
else:
|
26 |
+
shutil.copyfile(src, dest_f)
|
27 |
+
return
|
28 |
+
|
29 |
+
for f in src.iterdir():
|
30 |
+
dest_f = dst / f.name
|
31 |
+
assert not dest_f.exists(), dest_f
|
32 |
+
if use_symlinks:
|
33 |
+
(dest_f).symlink_to(f)
|
34 |
+
elif f.is_dir():
|
35 |
+
shutil.copytree(f, dest_f)
|
36 |
+
else:
|
37 |
+
shutil.copyfile(f, dest_f)
|
38 |
+
|
39 |
+
|
40 |
+
def clean_up_dataset(path: Path):
|
41 |
+
for item in path.rglob("__MACOSX"):
|
42 |
+
if item.is_dir():
|
43 |
+
shutil.rmtree(item)
|
44 |
+
for item in path.rglob(".DS_Store"):
|
45 |
+
if item.is_file():
|
46 |
+
item.unlink()
|
47 |
+
|
48 |
+
|
49 |
+
def extract_archives(path: Path):
|
50 |
+
"""
|
51 |
+
unzips all .zip files within `path` and cleans up task dir
|
52 |
+
|
53 |
+
[TODO] handle nested zips
|
54 |
+
"""
|
55 |
+
for zip_f in path.rglob("*.zip"):
|
56 |
+
f_out_dir = zip_f.with_suffix("")
|
57 |
+
|
58 |
+
# special case: the intended output path already exists (maybe data has already been extracted by user)
|
59 |
+
if f_out_dir.exists():
|
60 |
+
logger.debug(
|
61 |
+
f"Skipping {zip_f} as an item with the same name already exists."
|
62 |
+
)
|
63 |
+
# if it's a file, it's probably exactly the same as in the zip -> remove the zip
|
64 |
+
# [TODO] maybe add an extra check to see if zip file content matches the colliding file
|
65 |
+
if f_out_dir.is_file() and f_out_dir.suffix != "":
|
66 |
+
zip_f.unlink()
|
67 |
+
continue
|
68 |
+
|
69 |
+
logger.debug(f"Extracting: {zip_f}")
|
70 |
+
f_out_dir.mkdir(exist_ok=True)
|
71 |
+
with zipfile.ZipFile(zip_f, "r") as zip_ref:
|
72 |
+
zip_ref.extractall(f_out_dir)
|
73 |
+
|
74 |
+
# remove any unwanted files
|
75 |
+
clean_up_dataset(f_out_dir)
|
76 |
+
|
77 |
+
contents = list(f_out_dir.iterdir())
|
78 |
+
|
79 |
+
# special case: the zip contains a single dir/file with the same name as the zip
|
80 |
+
if len(contents) == 1 and contents[0].name == f_out_dir.name:
|
81 |
+
sub_item = contents[0]
|
82 |
+
# if it's a dir, move its contents to the parent and remove it
|
83 |
+
if sub_item.is_dir():
|
84 |
+
logger.debug(f"Special handling (child is dir) enabled for: {zip_f}")
|
85 |
+
for f in sub_item.rglob("*"):
|
86 |
+
shutil.move(f, f_out_dir)
|
87 |
+
sub_item.rmdir()
|
88 |
+
# if it's a file, rename it to the parent and remove the parent
|
89 |
+
elif sub_item.is_file():
|
90 |
+
logger.debug(f"Special handling (child is file) enabled for: {zip_f}")
|
91 |
+
sub_item_tmp = sub_item.rename(f_out_dir.with_suffix(".__tmp_rename"))
|
92 |
+
f_out_dir.rmdir()
|
93 |
+
sub_item_tmp.rename(f_out_dir)
|
94 |
+
|
95 |
+
zip_f.unlink()
|
96 |
+
|
97 |
+
|
98 |
+
def preproc_data(path: Path):
|
99 |
+
extract_archives(path)
|
100 |
+
clean_up_dataset(path)
|
aide/utils/config.py
ADDED
@@ -0,0 +1,199 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""configuration and setup utils"""
|
2 |
+
|
3 |
+
from dataclasses import dataclass
|
4 |
+
from pathlib import Path
|
5 |
+
from typing import Hashable, cast
|
6 |
+
|
7 |
+
import coolname
|
8 |
+
import rich
|
9 |
+
from omegaconf import OmegaConf
|
10 |
+
from rich.syntax import Syntax
|
11 |
+
import shutup
|
12 |
+
from rich.logging import RichHandler
|
13 |
+
import logging
|
14 |
+
|
15 |
+
from . import tree_export
|
16 |
+
from . import copytree, preproc_data, serialize
|
17 |
+
|
18 |
+
shutup.mute_warnings()
|
19 |
+
logging.basicConfig(
|
20 |
+
level="WARNING", format="%(message)s", datefmt="[%X]", handlers=[RichHandler()]
|
21 |
+
)
|
22 |
+
logger = logging.getLogger("aide")
|
23 |
+
logger.setLevel(logging.WARNING)
|
24 |
+
|
25 |
+
|
26 |
+
""" these dataclasses are just for type hinting, the actual config is in config.yaml """
|
27 |
+
|
28 |
+
|
29 |
+
@dataclass
|
30 |
+
class StageConfig:
|
31 |
+
model: str
|
32 |
+
temp: float
|
33 |
+
|
34 |
+
|
35 |
+
@dataclass
|
36 |
+
class SearchConfig:
|
37 |
+
max_debug_depth: int
|
38 |
+
debug_prob: float
|
39 |
+
num_drafts: int
|
40 |
+
|
41 |
+
|
42 |
+
@dataclass
|
43 |
+
class AgentConfig:
|
44 |
+
steps: int
|
45 |
+
k_fold_validation: int
|
46 |
+
expose_prediction: bool
|
47 |
+
data_preview: bool
|
48 |
+
|
49 |
+
code: StageConfig
|
50 |
+
feedback: StageConfig
|
51 |
+
|
52 |
+
search: SearchConfig
|
53 |
+
|
54 |
+
|
55 |
+
@dataclass
|
56 |
+
class ExecConfig:
|
57 |
+
timeout: int
|
58 |
+
agent_file_name: str
|
59 |
+
format_tb_ipython: bool
|
60 |
+
|
61 |
+
|
62 |
+
@dataclass
|
63 |
+
class Config(Hashable):
|
64 |
+
data_dir: Path
|
65 |
+
desc_file: Path | None
|
66 |
+
|
67 |
+
goal: str | None
|
68 |
+
eval: str | None
|
69 |
+
|
70 |
+
log_dir: Path
|
71 |
+
workspace_dir: Path
|
72 |
+
|
73 |
+
preprocess_data: bool
|
74 |
+
copy_data: bool
|
75 |
+
|
76 |
+
exp_name: str
|
77 |
+
|
78 |
+
exec: ExecConfig
|
79 |
+
generate_report: bool
|
80 |
+
report: StageConfig
|
81 |
+
agent: AgentConfig
|
82 |
+
|
83 |
+
|
84 |
+
def _get_next_logindex(dir: Path) -> int:
|
85 |
+
"""Get the next available index for a log directory."""
|
86 |
+
max_index = -1
|
87 |
+
for p in dir.iterdir():
|
88 |
+
try:
|
89 |
+
if current_index := int(p.name.split("-")[0]) > max_index:
|
90 |
+
max_index = current_index
|
91 |
+
except ValueError:
|
92 |
+
pass
|
93 |
+
return max_index + 1
|
94 |
+
|
95 |
+
|
96 |
+
def _load_cfg(
|
97 |
+
path: Path = Path(__file__).parent / "config.yaml", use_cli_args=True
|
98 |
+
) -> Config:
|
99 |
+
cfg = OmegaConf.load(path)
|
100 |
+
if use_cli_args:
|
101 |
+
cfg = OmegaConf.merge(cfg, OmegaConf.from_cli())
|
102 |
+
return cfg
|
103 |
+
|
104 |
+
|
105 |
+
def load_cfg(path: Path = Path(__file__).parent / "config.yaml") -> Config:
|
106 |
+
"""Load config from .yaml file and CLI args, and set up logging directory."""
|
107 |
+
return prep_cfg(_load_cfg(path))
|
108 |
+
|
109 |
+
|
110 |
+
def prep_cfg(cfg: Config):
|
111 |
+
if cfg.data_dir is None:
|
112 |
+
raise ValueError("`data_dir` must be provided.")
|
113 |
+
|
114 |
+
if cfg.desc_file is None and cfg.goal is None:
|
115 |
+
raise ValueError(
|
116 |
+
"You must provide either a description of the task goal (`goal=...`) or a path to a plaintext file containing the description (`desc_file=...`)."
|
117 |
+
)
|
118 |
+
|
119 |
+
if cfg.data_dir.startswith("example_tasks/"):
|
120 |
+
cfg.data_dir = Path(__file__).parent.parent / cfg.data_dir
|
121 |
+
cfg.data_dir = Path(cfg.data_dir).resolve()
|
122 |
+
|
123 |
+
if cfg.desc_file is not None:
|
124 |
+
cfg.desc_file = Path(cfg.desc_file).resolve()
|
125 |
+
|
126 |
+
top_log_dir = Path(cfg.log_dir).resolve()
|
127 |
+
top_log_dir.mkdir(parents=True, exist_ok=True)
|
128 |
+
|
129 |
+
top_workspace_dir = Path(cfg.workspace_dir).resolve()
|
130 |
+
top_workspace_dir.mkdir(parents=True, exist_ok=True)
|
131 |
+
|
132 |
+
# generate experiment name and prefix with consecutive index
|
133 |
+
ind = max(_get_next_logindex(top_log_dir), _get_next_logindex(top_workspace_dir))
|
134 |
+
cfg.exp_name = cfg.exp_name or coolname.generate_slug(3)
|
135 |
+
cfg.exp_name = f"{ind}-{cfg.exp_name}"
|
136 |
+
|
137 |
+
cfg.log_dir = (top_log_dir / cfg.exp_name).resolve()
|
138 |
+
cfg.workspace_dir = (top_workspace_dir / cfg.exp_name).resolve()
|
139 |
+
|
140 |
+
# validate the config
|
141 |
+
cfg_schema: Config = OmegaConf.structured(Config)
|
142 |
+
cfg = OmegaConf.merge(cfg_schema, cfg)
|
143 |
+
|
144 |
+
return cast(Config, cfg)
|
145 |
+
|
146 |
+
|
147 |
+
def print_cfg(cfg: Config) -> None:
|
148 |
+
rich.print(Syntax(OmegaConf.to_yaml(cfg), "yaml", theme="paraiso-dark"))
|
149 |
+
|
150 |
+
|
151 |
+
def load_task_desc(cfg: Config):
|
152 |
+
"""Load task description from markdown file or config str."""
|
153 |
+
|
154 |
+
# either load the task description from a file
|
155 |
+
if cfg.desc_file is not None:
|
156 |
+
if not (cfg.goal is None and cfg.eval is None):
|
157 |
+
logger.warning(
|
158 |
+
"Ignoring goal and eval args because task description file is provided."
|
159 |
+
)
|
160 |
+
|
161 |
+
with open(cfg.desc_file) as f:
|
162 |
+
return f.read()
|
163 |
+
|
164 |
+
# or generate it from the goal and eval args
|
165 |
+
if cfg.goal is None:
|
166 |
+
raise ValueError(
|
167 |
+
"`goal` (and optionally `eval`) must be provided if a task description file is not provided."
|
168 |
+
)
|
169 |
+
|
170 |
+
task_desc = {"Task goal": cfg.goal}
|
171 |
+
if cfg.eval is not None:
|
172 |
+
task_desc["Task evaluation"] = cfg.eval
|
173 |
+
|
174 |
+
return task_desc
|
175 |
+
|
176 |
+
|
177 |
+
def prep_agent_workspace(cfg: Config):
|
178 |
+
"""Setup the agent's workspace and preprocess data if necessary."""
|
179 |
+
(cfg.workspace_dir / "input").mkdir(parents=True, exist_ok=True)
|
180 |
+
(cfg.workspace_dir / "working").mkdir(parents=True, exist_ok=True)
|
181 |
+
|
182 |
+
copytree(cfg.data_dir, cfg.workspace_dir / "input", use_symlinks=not cfg.copy_data)
|
183 |
+
if cfg.preprocess_data:
|
184 |
+
preproc_data(cfg.workspace_dir / "input")
|
185 |
+
|
186 |
+
|
187 |
+
def save_run(cfg: Config, journal):
|
188 |
+
cfg.log_dir.mkdir(parents=True, exist_ok=True)
|
189 |
+
|
190 |
+
# save journal
|
191 |
+
serialize.dump_json(journal, cfg.log_dir / "journal.json")
|
192 |
+
# save config
|
193 |
+
OmegaConf.save(config=cfg, f=cfg.log_dir / "config.yaml")
|
194 |
+
# create the tree + code visualization
|
195 |
+
tree_export.generate(cfg, journal, cfg.log_dir / "tree_plot.html")
|
196 |
+
# save the best found solution
|
197 |
+
best_node = journal.get_best_node(only_good=False)
|
198 |
+
with open(cfg.log_dir / "best_solution.py", "w") as f:
|
199 |
+
f.write(best_node.code)
|
aide/utils/config.yaml
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# path to the task data directory
|
2 |
+
data_dir: null
|
3 |
+
|
4 |
+
# either provide a path to a plaintext file describing the task
|
5 |
+
desc_file: null
|
6 |
+
# or provide the task goal (and optionally evaluation information) as arguments
|
7 |
+
goal: null
|
8 |
+
eval: null
|
9 |
+
|
10 |
+
log_dir: logs
|
11 |
+
workspace_dir: workspaces
|
12 |
+
|
13 |
+
# whether to unzip any archives in the data directory
|
14 |
+
preprocess_data: True
|
15 |
+
# whether to copy the data to the workspace directory (otherwise it will be symlinked)
|
16 |
+
# copying is recommended to prevent the agent from accidentally modifying the original data
|
17 |
+
copy_data: True
|
18 |
+
|
19 |
+
exp_name: null # a random experiment name will be generated if not provided
|
20 |
+
|
21 |
+
# settings for code execution
|
22 |
+
exec:
|
23 |
+
timeout: 3600
|
24 |
+
agent_file_name: runfile.py
|
25 |
+
format_tb_ipython: False
|
26 |
+
|
27 |
+
generate_report: True
|
28 |
+
# LLM settings for final report from journal
|
29 |
+
report:
|
30 |
+
model: gpt-4-turbo
|
31 |
+
temp: 1.0
|
32 |
+
|
33 |
+
# agent hyperparams
|
34 |
+
agent:
|
35 |
+
# how many improvement iterations to run
|
36 |
+
steps: 20
|
37 |
+
# whether to instruct the agent to use CV (set to 1 to disable)
|
38 |
+
k_fold_validation: 5
|
39 |
+
# whether to instruct the agent to generate a prediction function
|
40 |
+
expose_prediction: False
|
41 |
+
# whether to provide the agent with a preview of the data
|
42 |
+
data_preview: True
|
43 |
+
|
44 |
+
# LLM settings for coding
|
45 |
+
code:
|
46 |
+
model: gpt-4-turbo
|
47 |
+
temp: 0.5
|
48 |
+
|
49 |
+
# LLM settings for evaluating program output / tracebacks
|
50 |
+
feedback:
|
51 |
+
model: gpt-4-turbo
|
52 |
+
temp: 0.5
|
53 |
+
|
54 |
+
# hyperparameters for the tree search
|
55 |
+
search:
|
56 |
+
max_debug_depth: 3
|
57 |
+
debug_prob: 0.5
|
58 |
+
num_drafts: 5
|
aide/utils/data_preview.py
ADDED
@@ -0,0 +1,153 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
Contains functions to manually generate a textual preview of some common file types (.csv, .json,..) for the agent.
|
3 |
+
"""
|
4 |
+
|
5 |
+
import json
|
6 |
+
from pathlib import Path
|
7 |
+
|
8 |
+
import humanize
|
9 |
+
import pandas as pd
|
10 |
+
from genson import SchemaBuilder
|
11 |
+
from pandas.api.types import is_numeric_dtype
|
12 |
+
|
13 |
+
# these files are treated as code (e.g. markdown wrapped)
|
14 |
+
code_files = {".py", ".sh", ".yaml", ".yml", ".md", ".html", ".xml", ".log", ".rst"}
|
15 |
+
# we treat these files as text (rather than binary) files
|
16 |
+
plaintext_files = {".txt", ".csv", ".json", ".tsv"} | code_files
|
17 |
+
|
18 |
+
|
19 |
+
def get_file_len_size(f: Path) -> tuple[int, str]:
|
20 |
+
"""
|
21 |
+
Calculate the size of a file (#lines for plaintext files, otherwise #bytes)
|
22 |
+
Also returns a human-readable string representation of the size.
|
23 |
+
"""
|
24 |
+
if f.suffix in plaintext_files:
|
25 |
+
num_lines = sum(1 for _ in open(f))
|
26 |
+
return num_lines, f"{num_lines} lines"
|
27 |
+
else:
|
28 |
+
s = f.stat().st_size
|
29 |
+
return s, humanize.naturalsize(s)
|
30 |
+
|
31 |
+
|
32 |
+
def file_tree(path: Path, depth=0) -> str:
|
33 |
+
"""Generate a tree structure of files in a directory"""
|
34 |
+
result = []
|
35 |
+
files = [p for p in Path(path).iterdir() if not p.is_dir()]
|
36 |
+
dirs = [p for p in Path(path).iterdir() if p.is_dir()]
|
37 |
+
max_n = 4 if len(files) > 30 else 8
|
38 |
+
for p in sorted(files)[:max_n]:
|
39 |
+
result.append(f"{' '*depth*4}{p.name} ({get_file_len_size(p)[1]})")
|
40 |
+
if len(files) > max_n:
|
41 |
+
result.append(f"{' '*depth*4}... and {len(files)-max_n} other files")
|
42 |
+
|
43 |
+
for p in sorted(dirs):
|
44 |
+
result.append(f"{' '*depth*4}{p.name}/")
|
45 |
+
result.append(file_tree(p, depth + 1))
|
46 |
+
|
47 |
+
return "\n".join(result)
|
48 |
+
|
49 |
+
|
50 |
+
def _walk(path: Path):
|
51 |
+
"""Recursively walk a directory (analogous to os.walk but for pathlib.Path)"""
|
52 |
+
for p in sorted(Path(path).iterdir()):
|
53 |
+
if p.is_dir():
|
54 |
+
yield from _walk(p)
|
55 |
+
continue
|
56 |
+
yield p
|
57 |
+
|
58 |
+
|
59 |
+
def preview_csv(p: Path, file_name: str, simple=True) -> str:
|
60 |
+
"""Generate a textual preview of a csv file
|
61 |
+
|
62 |
+
Args:
|
63 |
+
p (Path): the path to the csv file
|
64 |
+
file_name (str): the file name to use in the preview
|
65 |
+
simple (bool, optional): whether to use a simplified version of the preview. Defaults to True.
|
66 |
+
|
67 |
+
Returns:
|
68 |
+
str: the textual preview
|
69 |
+
"""
|
70 |
+
df = pd.read_csv(p)
|
71 |
+
|
72 |
+
out = []
|
73 |
+
|
74 |
+
out.append(f"-> {file_name} has {df.shape[0]} rows and {df.shape[1]} columns.")
|
75 |
+
|
76 |
+
if simple:
|
77 |
+
cols = df.columns.tolist()
|
78 |
+
sel_cols = 15
|
79 |
+
cols_str = ", ".join(cols[:sel_cols])
|
80 |
+
res = f"The columns are: {cols_str}"
|
81 |
+
if len(cols) > sel_cols:
|
82 |
+
res += f"... and {len(cols)-sel_cols} more columns"
|
83 |
+
out.append(res)
|
84 |
+
else:
|
85 |
+
out.append("Here is some information about the columns:")
|
86 |
+
for col in sorted(df.columns):
|
87 |
+
dtype = df[col].dtype
|
88 |
+
name = f"{col} ({dtype})"
|
89 |
+
|
90 |
+
nan_count = df[col].isnull().sum()
|
91 |
+
|
92 |
+
if dtype == "bool":
|
93 |
+
v = df[col][df[col].notnull()].mean()
|
94 |
+
out.append(f"{name} is {v*100:.2f}% True, {100-v*100:.2f}% False")
|
95 |
+
elif df[col].nunique() < 10:
|
96 |
+
out.append(
|
97 |
+
f"{name} has {df[col].nunique()} unique values: {df[col].unique().tolist()}"
|
98 |
+
)
|
99 |
+
elif is_numeric_dtype(df[col]):
|
100 |
+
out.append(
|
101 |
+
f"{name} has range: {df[col].min():.2f} - {df[col].max():.2f}, {nan_count} nan values"
|
102 |
+
)
|
103 |
+
elif dtype == "object":
|
104 |
+
out.append(
|
105 |
+
f"{name} has {df[col].nunique()} unique values. Some example values: {df[col].value_counts().head(4).index.tolist()}"
|
106 |
+
)
|
107 |
+
|
108 |
+
return "\n".join(out)
|
109 |
+
|
110 |
+
|
111 |
+
def preview_json(p: Path, file_name: str):
|
112 |
+
"""Generate a textual preview of a json file using a generated json schema"""
|
113 |
+
builder = SchemaBuilder()
|
114 |
+
with open(p) as f:
|
115 |
+
builder.add_object(json.load(f))
|
116 |
+
return f"-> {file_name} has auto-generated json schema:\n" + builder.to_json(
|
117 |
+
indent=2
|
118 |
+
)
|
119 |
+
|
120 |
+
|
121 |
+
def generate(base_path, include_file_details=True, simple=False):
|
122 |
+
"""
|
123 |
+
Generate a textual preview of a directory, including an overview of the directory
|
124 |
+
structure and previews of individual files
|
125 |
+
"""
|
126 |
+
tree = f"```\n{file_tree(base_path)}```"
|
127 |
+
out = [tree]
|
128 |
+
|
129 |
+
if include_file_details:
|
130 |
+
for fn in _walk(base_path):
|
131 |
+
file_name = str(fn.relative_to(base_path))
|
132 |
+
|
133 |
+
if fn.suffix == ".csv":
|
134 |
+
out.append(preview_csv(fn, file_name, simple=simple))
|
135 |
+
elif fn.suffix == ".json":
|
136 |
+
out.append(preview_json(fn, file_name))
|
137 |
+
elif fn.suffix in plaintext_files:
|
138 |
+
if get_file_len_size(fn)[0] < 30:
|
139 |
+
with open(fn) as f:
|
140 |
+
content = f.read()
|
141 |
+
if fn.suffix in code_files:
|
142 |
+
content = f"```\n{content}\n```"
|
143 |
+
out.append(f"-> {file_name} has content:\n\n{content}")
|
144 |
+
|
145 |
+
result = "\n\n".join(out)
|
146 |
+
|
147 |
+
# if the result is very long we generate a simpler version
|
148 |
+
if len(result) > 6_000 and not simple:
|
149 |
+
return generate(
|
150 |
+
base_path, include_file_details=include_file_details, simple=True
|
151 |
+
)
|
152 |
+
|
153 |
+
return result
|
aide/utils/metric.py
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dataclasses import dataclass, field
|
2 |
+
from functools import total_ordering
|
3 |
+
from typing import Any
|
4 |
+
|
5 |
+
import numpy as np
|
6 |
+
from dataclasses_json import DataClassJsonMixin
|
7 |
+
|
8 |
+
|
9 |
+
@dataclass
|
10 |
+
@total_ordering
|
11 |
+
class MetricValue(DataClassJsonMixin):
|
12 |
+
"""
|
13 |
+
Represents the value of a metric to be optimized, which can be compared to other metric values.
|
14 |
+
Comparisons (and max, min) are based on which value is better, not which is larger.
|
15 |
+
"""
|
16 |
+
|
17 |
+
value: float | int | np.number | np.floating | np.ndarray | None
|
18 |
+
maximize: bool | None = field(default=None, kw_only=True)
|
19 |
+
|
20 |
+
def __post_init__(self):
|
21 |
+
if self.value is not None:
|
22 |
+
assert isinstance(self.value, (float, int, np.number, np.floating))
|
23 |
+
self.value = float(self.value)
|
24 |
+
|
25 |
+
def __gt__(self, other) -> bool:
|
26 |
+
"""True if self is a _better_ (not necessarily larger) metric value than other"""
|
27 |
+
if self.value is None:
|
28 |
+
return False
|
29 |
+
if other.value is None:
|
30 |
+
return True
|
31 |
+
|
32 |
+
assert type(self) is type(other) and (self.maximize == other.maximize)
|
33 |
+
|
34 |
+
if self.value == other.value:
|
35 |
+
return False
|
36 |
+
|
37 |
+
comp = self.value > other.value
|
38 |
+
return comp if self.maximize else not comp # type: ignore
|
39 |
+
|
40 |
+
def __eq__(self, other: Any) -> bool:
|
41 |
+
return self.value == other.value
|
42 |
+
|
43 |
+
def __repr__(self) -> str:
|
44 |
+
return str(self)
|
45 |
+
|
46 |
+
def __str__(self) -> str:
|
47 |
+
if self.maximize is None:
|
48 |
+
opt_dir = "?"
|
49 |
+
elif self.maximize:
|
50 |
+
opt_dir = "↑"
|
51 |
+
else:
|
52 |
+
opt_dir = "↓"
|
53 |
+
return f"Metric{opt_dir}({self.value_npsafe:.4f})"
|
54 |
+
|
55 |
+
@property
|
56 |
+
def is_worst(self):
|
57 |
+
"""True if the metric value is the worst possible value."""
|
58 |
+
return self.value is None
|
59 |
+
|
60 |
+
@property
|
61 |
+
def value_npsafe(self):
|
62 |
+
return self.value if self.value is not None else float("nan")
|
63 |
+
|
64 |
+
|
65 |
+
@dataclass
|
66 |
+
class WorstMetricValue(MetricValue):
|
67 |
+
"""
|
68 |
+
Represents an invalid metric value, e.g. when the agent creates a buggy solution.
|
69 |
+
Always compares worse than any valid metric value.
|
70 |
+
"""
|
71 |
+
|
72 |
+
value: None = None
|
73 |
+
|
74 |
+
def __repr__(self):
|
75 |
+
return super().__repr__()
|
76 |
+
|
77 |
+
def __str__(self):
|
78 |
+
return super().__str__()
|
aide/utils/response.py
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
import re
|
3 |
+
|
4 |
+
import black
|
5 |
+
|
6 |
+
|
7 |
+
def wrap_code(code: str, lang="python") -> str:
|
8 |
+
"""Wraps code with three backticks."""
|
9 |
+
return f"```{lang}\n{code}\n```"
|
10 |
+
|
11 |
+
|
12 |
+
def is_valid_python_script(script):
|
13 |
+
"""Check if a script is a valid Python script."""
|
14 |
+
try:
|
15 |
+
compile(script, "<string>", "exec")
|
16 |
+
return True
|
17 |
+
except SyntaxError:
|
18 |
+
return False
|
19 |
+
|
20 |
+
|
21 |
+
def extract_jsons(text):
|
22 |
+
"""Extract all JSON objects from the text. Caveat: This function cannot handle nested JSON objects."""
|
23 |
+
json_objects = []
|
24 |
+
matches = re.findall(r"\{.*?\}", text, re.DOTALL)
|
25 |
+
for match in matches:
|
26 |
+
try:
|
27 |
+
json_obj = json.loads(match)
|
28 |
+
json_objects.append(json_obj)
|
29 |
+
except json.JSONDecodeError:
|
30 |
+
pass
|
31 |
+
|
32 |
+
# Sometimes chatgpt-turbo forget the last curly bracket, so we try to add it back when no json is found
|
33 |
+
if len(json_objects) == 0 and not text.endswith("}"):
|
34 |
+
json_objects = extract_jsons(text + "}")
|
35 |
+
if len(json_objects) > 0:
|
36 |
+
return json_objects
|
37 |
+
|
38 |
+
return json_objects
|
39 |
+
|
40 |
+
|
41 |
+
def trim_long_string(string, threshold=5100, k=2500):
|
42 |
+
# Check if the length of the string is longer than the threshold
|
43 |
+
if len(string) > threshold:
|
44 |
+
# Output the first k and last k characters
|
45 |
+
first_k_chars = string[:k]
|
46 |
+
last_k_chars = string[-k:]
|
47 |
+
|
48 |
+
truncated_len = len(string) - 2 * k
|
49 |
+
|
50 |
+
return f"{first_k_chars}\n ... [{truncated_len} characters truncated] ... \n{last_k_chars}"
|
51 |
+
else:
|
52 |
+
return string
|
53 |
+
|
54 |
+
|
55 |
+
def extract_code(text):
|
56 |
+
"""Extract python code blocks from the text."""
|
57 |
+
parsed_codes = []
|
58 |
+
|
59 |
+
# When code is in a text or python block
|
60 |
+
matches = re.findall(r"```(python)?\n*(.*?)\n*```", text, re.DOTALL)
|
61 |
+
for match in matches:
|
62 |
+
code_block = match[1]
|
63 |
+
parsed_codes.append(code_block)
|
64 |
+
|
65 |
+
# When the entire text is code or backticks of the code block is missing
|
66 |
+
if len(parsed_codes) == 0:
|
67 |
+
matches = re.findall(r"^(```(python)?)?\n?(.*?)\n?(```)?$", text, re.DOTALL)
|
68 |
+
if matches:
|
69 |
+
code_block = matches[0][2]
|
70 |
+
parsed_codes.append(code_block)
|
71 |
+
|
72 |
+
# validate the parsed codes
|
73 |
+
valid_code_blocks = [
|
74 |
+
format_code(c) for c in parsed_codes if is_valid_python_script(c)
|
75 |
+
]
|
76 |
+
return format_code("\n\n".join(valid_code_blocks))
|
77 |
+
|
78 |
+
|
79 |
+
def extract_text_up_to_code(s):
|
80 |
+
"""Extract (presumed) natural language text up to the start of the first code block."""
|
81 |
+
if "```" not in s:
|
82 |
+
return ""
|
83 |
+
return s[: s.find("```")].strip()
|
84 |
+
|
85 |
+
|
86 |
+
def format_code(code) -> str:
|
87 |
+
"""Format Python code using Black."""
|
88 |
+
try:
|
89 |
+
return black.format_str(code, mode=black.FileMode())
|
90 |
+
except black.parsing.InvalidInput: # type: ignore
|
91 |
+
return code
|
aide/utils/serialize.py
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import copy
|
2 |
+
import json
|
3 |
+
from pathlib import Path
|
4 |
+
from typing import Type, TypeVar
|
5 |
+
|
6 |
+
import dataclasses_json
|
7 |
+
from ..journal import Journal
|
8 |
+
|
9 |
+
|
10 |
+
def dumps_json(obj: dataclasses_json.DataClassJsonMixin):
|
11 |
+
"""Serialize AIDE dataclasses (such as Journals) to JSON."""
|
12 |
+
if isinstance(obj, Journal):
|
13 |
+
obj = copy.deepcopy(obj)
|
14 |
+
node2parent = {n.id: n.parent.id for n in obj.nodes if n.parent is not None}
|
15 |
+
for n in obj.nodes:
|
16 |
+
n.parent = None
|
17 |
+
n.children = set()
|
18 |
+
|
19 |
+
obj_dict = obj.to_dict()
|
20 |
+
|
21 |
+
if isinstance(obj, Journal):
|
22 |
+
obj_dict["node2parent"] = node2parent # type: ignore
|
23 |
+
obj_dict["__version"] = "2"
|
24 |
+
|
25 |
+
return json.dumps(obj_dict, separators=(",", ":"))
|
26 |
+
|
27 |
+
|
28 |
+
def dump_json(obj: dataclasses_json.DataClassJsonMixin, path: Path):
|
29 |
+
with open(path, "w") as f:
|
30 |
+
f.write(dumps_json(obj))
|
31 |
+
|
32 |
+
|
33 |
+
G = TypeVar("G", bound=dataclasses_json.DataClassJsonMixin)
|
34 |
+
|
35 |
+
|
36 |
+
def loads_json(s: str, cls: Type[G]) -> G:
|
37 |
+
"""Deserialize JSON to AIDE dataclasses."""
|
38 |
+
obj_dict = json.loads(s)
|
39 |
+
obj = cls.from_dict(obj_dict)
|
40 |
+
|
41 |
+
if isinstance(obj, Journal):
|
42 |
+
id2nodes = {n.id: n for n in obj.nodes}
|
43 |
+
for child_id, parent_id in obj_dict["node2parent"].items():
|
44 |
+
id2nodes[child_id].parent = id2nodes[parent_id]
|
45 |
+
id2nodes[child_id].__post_init__()
|
46 |
+
return obj
|
47 |
+
|
48 |
+
|
49 |
+
def load_json(path: Path, cls: Type[G]) -> G:
|
50 |
+
with open(path, "r") as f:
|
51 |
+
return loads_json(f.read(), cls)
|
aide/utils/tree_export.py
ADDED
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""Export journal to HTML visualization of tree + code."""
|
2 |
+
|
3 |
+
import json
|
4 |
+
import textwrap
|
5 |
+
from pathlib import Path
|
6 |
+
|
7 |
+
import numpy as np
|
8 |
+
from igraph import Graph
|
9 |
+
from ..journal import Journal
|
10 |
+
|
11 |
+
|
12 |
+
def get_edges(journal: Journal):
|
13 |
+
for node in journal:
|
14 |
+
for c in node.children:
|
15 |
+
yield (node.step, c.step)
|
16 |
+
|
17 |
+
|
18 |
+
def generate_layout(n_nodes, edges, layout_type="rt"):
|
19 |
+
"""Generate visual layout of graph"""
|
20 |
+
layout = Graph(
|
21 |
+
n_nodes,
|
22 |
+
edges=edges,
|
23 |
+
directed=True,
|
24 |
+
).layout(layout_type)
|
25 |
+
y_max = max(layout[k][1] for k in range(n_nodes))
|
26 |
+
layout_coords = []
|
27 |
+
for n in range(n_nodes):
|
28 |
+
layout_coords.append((layout[n][0], 2 * y_max - layout[n][1]))
|
29 |
+
return np.array(layout_coords)
|
30 |
+
|
31 |
+
|
32 |
+
def normalize_layout(layout: np.ndarray):
|
33 |
+
"""Normalize layout to [0, 1]"""
|
34 |
+
layout = (layout - layout.min(axis=0)) / (layout.max(axis=0) - layout.min(axis=0))
|
35 |
+
layout[:, 1] = 1 - layout[:, 1]
|
36 |
+
layout[:, 1] = np.nan_to_num(layout[:, 1], nan=0)
|
37 |
+
layout[:, 0] = np.nan_to_num(layout[:, 0], nan=0.5)
|
38 |
+
return layout
|
39 |
+
|
40 |
+
|
41 |
+
def strip_code_markers(code: str) -> str:
|
42 |
+
"""Remove markdown code block markers if present."""
|
43 |
+
code = code.strip()
|
44 |
+
if code.startswith("```"):
|
45 |
+
# Remove opening backticks and optional language identifier
|
46 |
+
first_newline = code.find("\n")
|
47 |
+
if first_newline != -1:
|
48 |
+
code = code[first_newline:].strip()
|
49 |
+
if code.endswith("```"):
|
50 |
+
code = code[:-3].strip()
|
51 |
+
return code
|
52 |
+
|
53 |
+
|
54 |
+
def cfg_to_tree_struct(cfg, jou: Journal):
|
55 |
+
edges = list(get_edges(jou))
|
56 |
+
layout = normalize_layout(generate_layout(len(jou), edges))
|
57 |
+
|
58 |
+
# metrics = np.array([n.metric.value_npsafe for n in jou])
|
59 |
+
# metrics = (metrics - np.nanmin(metrics)) / (np.nanmax(metrics) - np.nanmin(metrics))
|
60 |
+
# metrics = np.nan_to_num(metrics, nan=1)
|
61 |
+
# metrics[:] = 0
|
62 |
+
metrics = np.array([0 for n in jou])
|
63 |
+
|
64 |
+
return dict(
|
65 |
+
edges=edges,
|
66 |
+
layout=layout.tolist(),
|
67 |
+
plan=[textwrap.fill(n.plan, width=80) for n in jou.nodes],
|
68 |
+
code=[strip_code_markers(n.code) for n in jou],
|
69 |
+
term_out=[n.term_out for n in jou],
|
70 |
+
analysis=[n.analysis for n in jou],
|
71 |
+
exp_name=cfg.exp_name,
|
72 |
+
metrics=metrics.tolist(),
|
73 |
+
)
|
74 |
+
|
75 |
+
|
76 |
+
def generate_html(tree_graph_str: str):
|
77 |
+
template_dir = Path(__file__).parent / "viz_templates"
|
78 |
+
|
79 |
+
with open(template_dir / "template.js") as f:
|
80 |
+
js = f.read()
|
81 |
+
js = js.replace("<placeholder>", tree_graph_str)
|
82 |
+
|
83 |
+
with open(template_dir / "template.html") as f:
|
84 |
+
html = f.read()
|
85 |
+
html = html.replace("<!-- placeholder -->", js)
|
86 |
+
|
87 |
+
return html
|
88 |
+
|
89 |
+
|
90 |
+
def generate(cfg, jou: Journal, out_path: Path):
|
91 |
+
tree_graph_str = json.dumps(cfg_to_tree_struct(cfg, jou))
|
92 |
+
html = generate_html(tree_graph_str)
|
93 |
+
with open(out_path, "w") as f:
|
94 |
+
f.write(html)
|
aide/utils/viz_templates/template.html
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8" />
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
6 |
+
<script
|
7 |
+
id="p5scripttag"
|
8 |
+
src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.min.js"
|
9 |
+
integrity="sha512-uaz5GpnQoE6t5echKlX8P52czvsIGgLPcvlzfvRubLZ1Hp8JemUDnbUiAahbVtPb+jUVrNETuXvAhDDF/N3M4w=="
|
10 |
+
crossorigin="anonymous"
|
11 |
+
referrerpolicy="no-referrer"
|
12 |
+
></script>
|
13 |
+
|
14 |
+
<link
|
15 |
+
rel="stylesheet"
|
16 |
+
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css"
|
17 |
+
/>
|
18 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
19 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/python.min.js"></script>
|
20 |
+
|
21 |
+
<script>
|
22 |
+
<!-- placeholder -->
|
23 |
+
</script>
|
24 |
+
<title>AIDE Run Visualization</title>
|
25 |
+
<style>
|
26 |
+
body,
|
27 |
+
* {
|
28 |
+
margin: 0;
|
29 |
+
padding: 0;
|
30 |
+
box-sizing: border-box;
|
31 |
+
overflow: scroll;
|
32 |
+
}
|
33 |
+
body {
|
34 |
+
background-color: #f2f0e7;
|
35 |
+
}
|
36 |
+
canvas {
|
37 |
+
float: left;
|
38 |
+
height: 100vh;
|
39 |
+
width: 40vw;
|
40 |
+
}
|
41 |
+
#text-container {
|
42 |
+
float: right;
|
43 |
+
height: 100vh;
|
44 |
+
width: 50vw;
|
45 |
+
background-color: #282c34;
|
46 |
+
}
|
47 |
+
#plan {
|
48 |
+
/* border-left: 2px solid #282c34; */
|
49 |
+
background-color: #282c34;
|
50 |
+
color: #f2f0e7;
|
51 |
+
min-height: 5rem;
|
52 |
+
padding: 1em 0 1em 1em;
|
53 |
+
}
|
54 |
+
</style>
|
55 |
+
</head>
|
56 |
+
<body>
|
57 |
+
<pre
|
58 |
+
id="text-container"
|
59 |
+
><div id="plan"></div><hr><code id="code" class="language-python"></code></pre>
|
60 |
+
</body>
|
61 |
+
</html>
|
aide/utils/viz_templates/template.js
ADDED
@@ -0,0 +1,362 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const bgCol = "#F2F0E7";
|
2 |
+
const accentCol = "#fd4578";
|
3 |
+
|
4 |
+
hljs.initHighlightingOnLoad();
|
5 |
+
|
6 |
+
const updateTargetDims = () => {
|
7 |
+
// width is max-width of `.contentContainer` - its padding
|
8 |
+
// return [min(windowWidth, 900 - 80), 700]
|
9 |
+
return [windowWidth * (1 / 2), windowHeight];
|
10 |
+
};
|
11 |
+
|
12 |
+
const setCodeAndPlan = (code, plan) => {
|
13 |
+
const codeElm = document.getElementById("code");
|
14 |
+
if (codeElm) {
|
15 |
+
// codeElm.innerText = code;
|
16 |
+
codeElm.innerHTML = hljs.highlight(code, { language: "python" }).value;
|
17 |
+
}
|
18 |
+
|
19 |
+
const planElm = document.getElementById("plan");
|
20 |
+
if (planElm) {
|
21 |
+
// planElm.innerText = plan.trim();
|
22 |
+
planElm.innerHTML = hljs.highlight(plan, { language: "plaintext" }).value;
|
23 |
+
}
|
24 |
+
};
|
25 |
+
|
26 |
+
windowResized = () => {
|
27 |
+
resizeCanvas(...updateTargetDims());
|
28 |
+
awaitingPostResizeOps = true;
|
29 |
+
};
|
30 |
+
|
31 |
+
const animEase = (t) => 1 - (1 - Math.min(t, 1.0)) ** 5;
|
32 |
+
|
33 |
+
// ---- global constants ----
|
34 |
+
|
35 |
+
const globalAnimSpeed = 1.1;
|
36 |
+
const scaleFactor = 0.57;
|
37 |
+
|
38 |
+
// ---- global vars ----
|
39 |
+
|
40 |
+
let globalTime = 0;
|
41 |
+
let manualSelection = false;
|
42 |
+
|
43 |
+
let currentElemInd = 0;
|
44 |
+
|
45 |
+
let treeStructData = <placeholder>
|
46 |
+
|
47 |
+
let lastClick = 0;
|
48 |
+
let firstFrameTime = undefined;
|
49 |
+
|
50 |
+
let nodes = [];
|
51 |
+
let edges = [];
|
52 |
+
|
53 |
+
let lastScrollPos = 0;
|
54 |
+
|
55 |
+
setup = () => {
|
56 |
+
canvas = createCanvas(...updateTargetDims());
|
57 |
+
};
|
58 |
+
|
59 |
+
class Node {
|
60 |
+
x;
|
61 |
+
y;
|
62 |
+
size;
|
63 |
+
xT;
|
64 |
+
yT;
|
65 |
+
xB;
|
66 |
+
yB;
|
67 |
+
treeInd;
|
68 |
+
color;
|
69 |
+
relSize;
|
70 |
+
animationStart = Number.MAX_VALUE;
|
71 |
+
animationProgress = 0;
|
72 |
+
isStatic = false;
|
73 |
+
hasChildren = false;
|
74 |
+
isRootNode = true;
|
75 |
+
isStarred = false;
|
76 |
+
selected = false;
|
77 |
+
renderSize = 10;
|
78 |
+
edges = [];
|
79 |
+
bgCol;
|
80 |
+
|
81 |
+
constructor(x, y, relSize, treeInd) {
|
82 |
+
const minSize = 35;
|
83 |
+
const maxSize = 60;
|
84 |
+
|
85 |
+
const maxColor = 10;
|
86 |
+
const minColor = 125;
|
87 |
+
|
88 |
+
this.relSize = relSize;
|
89 |
+
this.treeInd = treeInd;
|
90 |
+
this.size = minSize + (maxSize - minSize) * relSize;
|
91 |
+
this.color = minColor + (maxColor - minColor) * relSize;
|
92 |
+
this.bgCol = Math.round(Math.max(this.color / 2, 0));
|
93 |
+
|
94 |
+
this.x = x;
|
95 |
+
this.y = y;
|
96 |
+
this.xT = x;
|
97 |
+
this.yT = y - this.size / 2;
|
98 |
+
this.xB = x;
|
99 |
+
this.yB = y + this.size / 2;
|
100 |
+
|
101 |
+
nodes.push(this);
|
102 |
+
}
|
103 |
+
|
104 |
+
startAnimation = (offset = 0) => {
|
105 |
+
if (this.animationStart == Number.MAX_VALUE)
|
106 |
+
this.animationStart = globalTime + offset;
|
107 |
+
};
|
108 |
+
|
109 |
+
child = (node) => {
|
110 |
+
let edge = new Edge(this, node);
|
111 |
+
this.edges.push(edge);
|
112 |
+
edges.push(edge);
|
113 |
+
this.hasChildren = true;
|
114 |
+
node.isRootNode = false;
|
115 |
+
return node;
|
116 |
+
};
|
117 |
+
|
118 |
+
render = () => {
|
119 |
+
if (globalTime - this.animationStart < 0) return;
|
120 |
+
|
121 |
+
const mouseXlocalCoords = (mouseX - width / 2) / scaleFactor;
|
122 |
+
const mouseYlocalCoords = (mouseY - height / 2) / scaleFactor;
|
123 |
+
const isMouseOver =
|
124 |
+
dist(mouseXlocalCoords, mouseYlocalCoords, this.x, this.y) <
|
125 |
+
this.renderSize / 1.5;
|
126 |
+
if (isMouseOver) cursor(HAND);
|
127 |
+
if (isMouseOver && mouseIsPressed) {
|
128 |
+
nodes.forEach((n) => (n.selected = false));
|
129 |
+
this.selected = true;
|
130 |
+
setCodeAndPlan(
|
131 |
+
treeStructData.code[this.treeInd],
|
132 |
+
treeStructData.plan[this.treeInd],
|
133 |
+
);
|
134 |
+
manualSelection = true;
|
135 |
+
}
|
136 |
+
|
137 |
+
this.renderSize = this.size;
|
138 |
+
if (!this.isStatic) {
|
139 |
+
this.animationProgress = animEase(
|
140 |
+
(globalTime - this.animationStart) / 1000,
|
141 |
+
);
|
142 |
+
if (this.animationProgress >= 1) {
|
143 |
+
this.isStatic = true;
|
144 |
+
} else {
|
145 |
+
this.renderSize =
|
146 |
+
this.size *
|
147 |
+
(0.8 +
|
148 |
+
0.2 *
|
149 |
+
(-3.33 * this.animationProgress ** 2 +
|
150 |
+
4.33 * this.animationProgress));
|
151 |
+
}
|
152 |
+
}
|
153 |
+
|
154 |
+
fill(this.color);
|
155 |
+
if (this.selected) {
|
156 |
+
fill(accentCol);
|
157 |
+
}
|
158 |
+
|
159 |
+
noStroke();
|
160 |
+
square(
|
161 |
+
this.x - this.renderSize / 2,
|
162 |
+
this.y - this.renderSize / 2,
|
163 |
+
this.renderSize,
|
164 |
+
10,
|
165 |
+
);
|
166 |
+
|
167 |
+
noStroke();
|
168 |
+
textAlign(CENTER, CENTER);
|
169 |
+
textSize(this.renderSize / 2);
|
170 |
+
fill(255);
|
171 |
+
// fill(lerpColor(color(accentCol), color(255), this.animationProgress))
|
172 |
+
text("{ }", this.x, this.y - 1);
|
173 |
+
// DEBUG PRINT:
|
174 |
+
// text(round(this.relSize, 2), this.x, this.y - 1)
|
175 |
+
// text(this.treeInd, this.x, this.y + 15)
|
176 |
+
|
177 |
+
const dotAnimThreshold = 0.85;
|
178 |
+
if (this.isStarred && this.animationProgress >= dotAnimThreshold) {
|
179 |
+
let dotAnimProgress =
|
180 |
+
(this.animationProgress - dotAnimThreshold) / (1 - dotAnimThreshold);
|
181 |
+
textSize(
|
182 |
+
((-3.33 * dotAnimProgress ** 2 + 4.33 * dotAnimProgress) *
|
183 |
+
this.renderSize) /
|
184 |
+
2,
|
185 |
+
);
|
186 |
+
if (this.selected) {
|
187 |
+
fill(0);
|
188 |
+
stroke(0);
|
189 |
+
} else {
|
190 |
+
fill(accentCol);
|
191 |
+
stroke(accentCol);
|
192 |
+
}
|
193 |
+
strokeWeight((-(dotAnimProgress ** 2) + dotAnimProgress) * 2);
|
194 |
+
text("*", this.x + 20, this.y - 11);
|
195 |
+
noStroke();
|
196 |
+
}
|
197 |
+
|
198 |
+
if (!this.isStatic) {
|
199 |
+
fill(bgCol);
|
200 |
+
const progressAnimBaseSize = this.renderSize + 5;
|
201 |
+
rect(
|
202 |
+
this.x - progressAnimBaseSize / 2,
|
203 |
+
this.y -
|
204 |
+
progressAnimBaseSize / 2 +
|
205 |
+
progressAnimBaseSize * this.animationProgress,
|
206 |
+
progressAnimBaseSize,
|
207 |
+
progressAnimBaseSize * (1 - this.animationProgress),
|
208 |
+
);
|
209 |
+
}
|
210 |
+
if (this.animationProgress >= 0.9) {
|
211 |
+
this.edges
|
212 |
+
.sort((a, b) => a.color() - b.color())
|
213 |
+
.forEach((e, i) => {
|
214 |
+
e.startAnimation((i / this.edges.length) ** 2 * 1000);
|
215 |
+
});
|
216 |
+
}
|
217 |
+
};
|
218 |
+
}
|
219 |
+
|
220 |
+
class Edge {
|
221 |
+
nodeT;
|
222 |
+
nodeB;
|
223 |
+
animX = 0;
|
224 |
+
animY = 0;
|
225 |
+
animationStart = Number.MAX_VALUE;
|
226 |
+
animationProgress = 0;
|
227 |
+
isStatic = false;
|
228 |
+
weight = 0;
|
229 |
+
|
230 |
+
constructor(nodeT, nodeB) {
|
231 |
+
this.nodeT = nodeT;
|
232 |
+
this.nodeB = nodeB;
|
233 |
+
this.weight = 2 + nodeB.relSize * 1;
|
234 |
+
}
|
235 |
+
|
236 |
+
color = () => this.nodeB.color;
|
237 |
+
|
238 |
+
startAnimation = (offset = 0) => {
|
239 |
+
if (this.animationStart == Number.MAX_VALUE)
|
240 |
+
this.animationStart = globalTime + offset;
|
241 |
+
};
|
242 |
+
|
243 |
+
render = () => {
|
244 |
+
if (globalTime - this.animationStart < 0) return;
|
245 |
+
|
246 |
+
if (!this.isStatic) {
|
247 |
+
this.animationProgress = animEase(
|
248 |
+
(globalTime - this.animationStart) / 1000,
|
249 |
+
);
|
250 |
+
if (this.animationProgress >= 1) {
|
251 |
+
this.isStatic = true;
|
252 |
+
this.animX = this.nodeB.xT;
|
253 |
+
this.animY = this.nodeB.yT;
|
254 |
+
} else {
|
255 |
+
this.animX = bezierPoint(
|
256 |
+
this.nodeT.xB,
|
257 |
+
this.nodeT.xB,
|
258 |
+
this.nodeB.xT,
|
259 |
+
this.nodeB.xT,
|
260 |
+
this.animationProgress,
|
261 |
+
);
|
262 |
+
|
263 |
+
this.animY = bezierPoint(
|
264 |
+
this.nodeT.yB,
|
265 |
+
(this.nodeT.yB + this.nodeB.yT) / 2,
|
266 |
+
(this.nodeT.yB + this.nodeB.yT) / 2,
|
267 |
+
this.nodeB.yT,
|
268 |
+
this.animationProgress,
|
269 |
+
);
|
270 |
+
}
|
271 |
+
}
|
272 |
+
if (this.animationProgress >= 0.97) {
|
273 |
+
this.nodeB.startAnimation();
|
274 |
+
}
|
275 |
+
|
276 |
+
strokeWeight(this.weight);
|
277 |
+
noFill();
|
278 |
+
stroke(
|
279 |
+
lerpColor(color(bgCol), color(accentCol), this.nodeB.relSize * 1 + 0.7),
|
280 |
+
);
|
281 |
+
bezier(
|
282 |
+
this.nodeT.xB,
|
283 |
+
this.nodeT.yB,
|
284 |
+
this.nodeT.xB,
|
285 |
+
(this.nodeT.yB + this.nodeB.yT) / 2,
|
286 |
+
this.animX,
|
287 |
+
(this.nodeT.yB + this.nodeB.yT) / 2,
|
288 |
+
this.animX,
|
289 |
+
this.animY,
|
290 |
+
);
|
291 |
+
};
|
292 |
+
}
|
293 |
+
|
294 |
+
draw = () => {
|
295 |
+
cursor(ARROW);
|
296 |
+
frameRate(120);
|
297 |
+
if (!firstFrameTime && frameCount <= 1) {
|
298 |
+
firstFrameTime = millis();
|
299 |
+
}
|
300 |
+
// ---- update global animation state ----
|
301 |
+
const initialSpeedScalingEaseIO =
|
302 |
+
(cos(min((millis() - firstFrameTime) / 8000, 1.0) * PI) + 1) / 2;
|
303 |
+
const initialSpeedScalingEase =
|
304 |
+
(cos(min((millis() - firstFrameTime) / 8000, 1.0) ** (1 / 2) * PI) + 1) / 2;
|
305 |
+
const initAnimationSpeedFactor = 1.0 - 0.4 * initialSpeedScalingEaseIO;
|
306 |
+
// update global scaling-aware clock
|
307 |
+
globalTime += globalAnimSpeed * initAnimationSpeedFactor * deltaTime;
|
308 |
+
|
309 |
+
if (nodes.length == 0) {
|
310 |
+
const spacingHeight = height * 1.3;
|
311 |
+
const spacingWidth = width * 1.3;
|
312 |
+
treeStructData.layout.forEach((lay, index) => {
|
313 |
+
new Node(
|
314 |
+
spacingWidth * lay[0] - spacingWidth / 2,
|
315 |
+
20 + spacingHeight * lay[1] - spacingHeight / 2,
|
316 |
+
1 - treeStructData.metrics[index],
|
317 |
+
index,
|
318 |
+
);
|
319 |
+
});
|
320 |
+
treeStructData.edges.forEach((ind) => {
|
321 |
+
nodes[ind[0]].child(nodes[ind[1]]);
|
322 |
+
});
|
323 |
+
nodes.forEach((n) => {
|
324 |
+
if (n.isRootNode) n.startAnimation();
|
325 |
+
});
|
326 |
+
nodes[0].selected = true;
|
327 |
+
setCodeAndPlan(
|
328 |
+
treeStructData.code[0],
|
329 |
+
treeStructData.plan[0],
|
330 |
+
)
|
331 |
+
}
|
332 |
+
|
333 |
+
const staticNodes = nodes.filter(
|
334 |
+
(n) => n.isStatic || n.animationProgress >= 0.7,
|
335 |
+
);
|
336 |
+
if (staticNodes.length > 0) {
|
337 |
+
const largestNode = staticNodes.reduce((prev, current) =>
|
338 |
+
prev.relSize > current.relSize ? prev : current,
|
339 |
+
);
|
340 |
+
if (!manualSelection) {
|
341 |
+
if (!largestNode.selected) {
|
342 |
+
setCodeAndPlan(
|
343 |
+
treeStructData.code[largestNode.treeInd],
|
344 |
+
treeStructData.plan[largestNode.treeInd],
|
345 |
+
);
|
346 |
+
}
|
347 |
+
staticNodes.forEach((node) => {
|
348 |
+
node.selected = node === largestNode;
|
349 |
+
});
|
350 |
+
}
|
351 |
+
}
|
352 |
+
background(bgCol);
|
353 |
+
// global animation transforms
|
354 |
+
translate(width / 2, height / 2);
|
355 |
+
scale(scaleFactor);
|
356 |
+
|
357 |
+
|
358 |
+
// ---- fg render ----
|
359 |
+
edges.forEach((e) => e.render());
|
360 |
+
nodes.forEach((n) => n.render());
|
361 |
+
|
362 |
+
};
|
aide/webui/__init__.py
ADDED
File without changes
|
aide/webui/app.py
ADDED
@@ -0,0 +1,599 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import streamlit.components.v1 as components
|
3 |
+
from pathlib import Path
|
4 |
+
import tempfile
|
5 |
+
import shutil
|
6 |
+
import os
|
7 |
+
import json
|
8 |
+
from omegaconf import OmegaConf
|
9 |
+
from rich.console import Console
|
10 |
+
import sys
|
11 |
+
from dotenv import load_dotenv
|
12 |
+
import logging
|
13 |
+
from aide import Experiment
|
14 |
+
|
15 |
+
# Set up logging configuration
|
16 |
+
logging.basicConfig(
|
17 |
+
level=logging.INFO,
|
18 |
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
19 |
+
handlers=[logging.StreamHandler(sys.stderr)],
|
20 |
+
)
|
21 |
+
|
22 |
+
logger = logging.getLogger("aide")
|
23 |
+
logger.setLevel(logging.INFO)
|
24 |
+
|
25 |
+
console = Console(file=sys.stderr)
|
26 |
+
|
27 |
+
|
28 |
+
class WebUI:
|
29 |
+
"""
|
30 |
+
WebUI encapsulates the Streamlit application logic for the AIDE Machine Learning Engineer Agent.
|
31 |
+
"""
|
32 |
+
|
33 |
+
def __init__(self):
|
34 |
+
"""
|
35 |
+
Initialize the WebUI with environment variables and session state.
|
36 |
+
"""
|
37 |
+
self.env_vars = self.load_env_variables()
|
38 |
+
self.project_root = Path(__file__).parent.parent.parent
|
39 |
+
self.config_session_state()
|
40 |
+
self.setup_page()
|
41 |
+
|
42 |
+
@staticmethod
|
43 |
+
def load_env_variables():
|
44 |
+
"""
|
45 |
+
Load API keys and environment variables from .env file.
|
46 |
+
|
47 |
+
Returns:
|
48 |
+
dict: Dictionary containing API keys.
|
49 |
+
"""
|
50 |
+
load_dotenv()
|
51 |
+
return {
|
52 |
+
"openai_key": os.getenv("OPENAI_API_KEY", ""),
|
53 |
+
"anthropic_key": os.getenv("ANTHROPIC_API_KEY", ""),
|
54 |
+
}
|
55 |
+
|
56 |
+
@staticmethod
|
57 |
+
def config_session_state():
|
58 |
+
"""
|
59 |
+
Configure default values for Streamlit session state.
|
60 |
+
"""
|
61 |
+
if "is_running" not in st.session_state:
|
62 |
+
st.session_state.is_running = False
|
63 |
+
if "current_step" not in st.session_state:
|
64 |
+
st.session_state.current_step = 0
|
65 |
+
if "total_steps" not in st.session_state:
|
66 |
+
st.session_state.total_steps = 0
|
67 |
+
if "progress" not in st.session_state:
|
68 |
+
st.session_state.progress = 0
|
69 |
+
if "results" not in st.session_state:
|
70 |
+
st.session_state.results = None
|
71 |
+
|
72 |
+
@staticmethod
|
73 |
+
def setup_page():
|
74 |
+
"""
|
75 |
+
Set up the Streamlit page configuration and load custom CSS.
|
76 |
+
"""
|
77 |
+
st.set_page_config(
|
78 |
+
page_title="AIDE: Machine Learning Engineer Agent",
|
79 |
+
layout="wide",
|
80 |
+
)
|
81 |
+
WebUI.load_css()
|
82 |
+
|
83 |
+
@staticmethod
|
84 |
+
def load_css():
|
85 |
+
"""
|
86 |
+
Load custom CSS styles from 'style.css' file.
|
87 |
+
"""
|
88 |
+
css_file = Path(__file__).parent / "style.css"
|
89 |
+
if css_file.exists():
|
90 |
+
with open(css_file) as f:
|
91 |
+
st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)
|
92 |
+
else:
|
93 |
+
st.warning(f"CSS file not found at: {css_file}")
|
94 |
+
|
95 |
+
def run(self):
|
96 |
+
"""
|
97 |
+
Run the main logic of the Streamlit application.
|
98 |
+
"""
|
99 |
+
self.render_sidebar()
|
100 |
+
input_col, results_col = st.columns([1, 3])
|
101 |
+
with input_col:
|
102 |
+
self.render_input_section(results_col)
|
103 |
+
|
104 |
+
def render_sidebar(self):
|
105 |
+
"""
|
106 |
+
Render the sidebar with API key settings.
|
107 |
+
"""
|
108 |
+
with st.sidebar:
|
109 |
+
st.header("⚙️ Settings")
|
110 |
+
st.markdown(
|
111 |
+
"<p style='text-align: center;'>OpenAI API Key</p>",
|
112 |
+
unsafe_allow_html=True,
|
113 |
+
)
|
114 |
+
openai_key = st.text_input(
|
115 |
+
"OpenAI API Key",
|
116 |
+
value=self.env_vars["openai_key"],
|
117 |
+
type="password",
|
118 |
+
label_visibility="collapsed",
|
119 |
+
)
|
120 |
+
st.markdown(
|
121 |
+
"<p style='text-align: center;'>Anthropic API Key</p>",
|
122 |
+
unsafe_allow_html=True,
|
123 |
+
)
|
124 |
+
anthropic_key = st.text_input(
|
125 |
+
"Anthropic API Key",
|
126 |
+
value=self.env_vars["anthropic_key"],
|
127 |
+
type="password",
|
128 |
+
label_visibility="collapsed",
|
129 |
+
)
|
130 |
+
if st.button("Save API Keys", use_container_width=True):
|
131 |
+
st.session_state.openai_key = openai_key
|
132 |
+
st.session_state.anthropic_key = anthropic_key
|
133 |
+
st.success("API keys saved!")
|
134 |
+
|
135 |
+
def render_input_section(self, results_col):
|
136 |
+
"""
|
137 |
+
Render the input section of the application.
|
138 |
+
|
139 |
+
Args:
|
140 |
+
results_col (st.delta_generator.DeltaGenerator): The results column to pass to methods.
|
141 |
+
"""
|
142 |
+
st.header("Input")
|
143 |
+
uploaded_files = self.handle_file_upload()
|
144 |
+
goal_text, eval_text, num_steps = self.handle_user_inputs()
|
145 |
+
if st.button("Run AIDE", type="primary", use_container_width=True):
|
146 |
+
with st.spinner("AIDE is running..."):
|
147 |
+
results = self.run_aide(
|
148 |
+
uploaded_files, goal_text, eval_text, num_steps, results_col
|
149 |
+
)
|
150 |
+
st.session_state.results = results
|
151 |
+
|
152 |
+
def handle_file_upload(self):
|
153 |
+
"""
|
154 |
+
Handle file uploads and example file loading.
|
155 |
+
|
156 |
+
Returns:
|
157 |
+
list: List of uploaded or example files.
|
158 |
+
"""
|
159 |
+
# Only show file uploader if no example files are loaded
|
160 |
+
if not st.session_state.get("example_files"):
|
161 |
+
uploaded_files = st.file_uploader(
|
162 |
+
"Upload Data Files",
|
163 |
+
accept_multiple_files=True,
|
164 |
+
type=["csv", "txt", "json", "md"],
|
165 |
+
label_visibility="collapsed",
|
166 |
+
)
|
167 |
+
|
168 |
+
if uploaded_files:
|
169 |
+
st.session_state.pop(
|
170 |
+
"example_files", None
|
171 |
+
) # Remove example files if any
|
172 |
+
return uploaded_files
|
173 |
+
|
174 |
+
# Only show example button if no files are uploaded
|
175 |
+
if st.button(
|
176 |
+
"Load Example Experiment", type="primary", use_container_width=True
|
177 |
+
):
|
178 |
+
st.session_state.example_files = self.load_example_files()
|
179 |
+
|
180 |
+
if st.session_state.get("example_files"):
|
181 |
+
st.info("Example files loaded! Click 'Run AIDE' to proceed.")
|
182 |
+
with st.expander("View Loaded Files", expanded=False):
|
183 |
+
for file in st.session_state.example_files:
|
184 |
+
st.text(f"📄 {file['name']}")
|
185 |
+
return st.session_state.example_files
|
186 |
+
|
187 |
+
return [] # Return empty list if no files are uploaded or loaded
|
188 |
+
|
189 |
+
def handle_user_inputs(self):
|
190 |
+
"""
|
191 |
+
Handle goal, evaluation criteria, and number of steps inputs.
|
192 |
+
|
193 |
+
Returns:
|
194 |
+
tuple: Goal text, evaluation criteria text, and number of steps.
|
195 |
+
"""
|
196 |
+
goal_text = st.text_area(
|
197 |
+
"Goal",
|
198 |
+
value=st.session_state.get("goal", ""),
|
199 |
+
placeholder="Example: Predict the sales price for each house",
|
200 |
+
)
|
201 |
+
eval_text = st.text_area(
|
202 |
+
"Evaluation Criteria",
|
203 |
+
value=st.session_state.get("eval", ""),
|
204 |
+
placeholder="Example: Use the RMSE metric between the logarithm of the predicted and observed values.",
|
205 |
+
)
|
206 |
+
num_steps = st.slider(
|
207 |
+
"Number of Steps",
|
208 |
+
min_value=1,
|
209 |
+
max_value=20,
|
210 |
+
value=st.session_state.get("steps", 10),
|
211 |
+
)
|
212 |
+
return goal_text, eval_text, num_steps
|
213 |
+
|
214 |
+
@staticmethod
|
215 |
+
def load_example_files():
|
216 |
+
"""
|
217 |
+
Load example files from the 'example_tasks/house_prices' directory.
|
218 |
+
|
219 |
+
Returns:
|
220 |
+
list: List of example files with their paths.
|
221 |
+
"""
|
222 |
+
package_root = Path(__file__).parent.parent
|
223 |
+
example_dir = package_root / "example_tasks" / "house_prices"
|
224 |
+
|
225 |
+
if not example_dir.exists():
|
226 |
+
st.error(f"Example directory not found at: {example_dir}")
|
227 |
+
return []
|
228 |
+
|
229 |
+
example_files = []
|
230 |
+
|
231 |
+
for file_path in example_dir.glob("*"):
|
232 |
+
if file_path.suffix.lower() in [".csv", ".txt", ".json", ".md"]:
|
233 |
+
with tempfile.NamedTemporaryFile(
|
234 |
+
delete=False, suffix=file_path.suffix
|
235 |
+
) as tmp_file:
|
236 |
+
tmp_file.write(file_path.read_bytes())
|
237 |
+
example_files.append(
|
238 |
+
{"name": file_path.name, "path": tmp_file.name}
|
239 |
+
)
|
240 |
+
|
241 |
+
if not example_files:
|
242 |
+
st.warning("No example files found in the example directory")
|
243 |
+
|
244 |
+
st.session_state["goal"] = "Predict the sales price for each house"
|
245 |
+
st.session_state["eval"] = (
|
246 |
+
"Use the RMSE metric between the logarithm of the predicted and observed values."
|
247 |
+
)
|
248 |
+
|
249 |
+
return example_files
|
250 |
+
|
251 |
+
def run_aide(self, files, goal_text, eval_text, num_steps, results_col):
|
252 |
+
"""
|
253 |
+
Run the AIDE experiment with the provided inputs.
|
254 |
+
|
255 |
+
Args:
|
256 |
+
files (list): List of uploaded or example files.
|
257 |
+
goal_text (str): The goal of the experiment.
|
258 |
+
eval_text (str): The evaluation criteria.
|
259 |
+
num_steps (int): Number of steps to run.
|
260 |
+
results_col (st.delta_generator.DeltaGenerator): Results column for displaying progress.
|
261 |
+
|
262 |
+
Returns:
|
263 |
+
dict: Dictionary containing the results of the experiment.
|
264 |
+
"""
|
265 |
+
try:
|
266 |
+
self.initialize_run_state(num_steps)
|
267 |
+
self.set_api_keys()
|
268 |
+
|
269 |
+
input_dir = self.prepare_input_directory(files)
|
270 |
+
if not input_dir:
|
271 |
+
return None
|
272 |
+
|
273 |
+
experiment = self.initialize_experiment(input_dir, goal_text, eval_text)
|
274 |
+
|
275 |
+
# Create separate placeholders for progress and config
|
276 |
+
progress_placeholder = results_col.empty()
|
277 |
+
config_placeholder = results_col.empty()
|
278 |
+
results_placeholder = results_col.empty()
|
279 |
+
|
280 |
+
for step in range(num_steps):
|
281 |
+
st.session_state.current_step = step + 1
|
282 |
+
progress = (step + 1) / num_steps
|
283 |
+
|
284 |
+
# Update progress
|
285 |
+
with progress_placeholder.container():
|
286 |
+
st.markdown(
|
287 |
+
f"### 🔥 Running Step {st.session_state.current_step}/{st.session_state.total_steps}"
|
288 |
+
)
|
289 |
+
st.progress(progress)
|
290 |
+
|
291 |
+
# Show config only for first step
|
292 |
+
if step == 0:
|
293 |
+
with config_placeholder.container():
|
294 |
+
st.markdown("### 📋 Configuration")
|
295 |
+
st.code(OmegaConf.to_yaml(experiment.cfg), language="yaml")
|
296 |
+
|
297 |
+
experiment.run(steps=1)
|
298 |
+
|
299 |
+
# Show results
|
300 |
+
with results_placeholder.container():
|
301 |
+
self.render_live_results(experiment)
|
302 |
+
|
303 |
+
# Clear config after first step
|
304 |
+
if step == 0:
|
305 |
+
config_placeholder.empty()
|
306 |
+
|
307 |
+
# Clear progress after all steps
|
308 |
+
progress_placeholder.empty()
|
309 |
+
|
310 |
+
# Update session state
|
311 |
+
st.session_state.is_running = False
|
312 |
+
st.session_state.results = self.collect_results(experiment)
|
313 |
+
return st.session_state.results
|
314 |
+
|
315 |
+
except Exception as e:
|
316 |
+
st.session_state.is_running = False
|
317 |
+
console.print_exception()
|
318 |
+
st.error(f"Error occurred: {str(e)}")
|
319 |
+
return None
|
320 |
+
|
321 |
+
@staticmethod
|
322 |
+
def initialize_run_state(num_steps):
|
323 |
+
"""
|
324 |
+
Initialize the running state for the experiment.
|
325 |
+
|
326 |
+
Args:
|
327 |
+
num_steps (int): Total number of steps in the experiment.
|
328 |
+
"""
|
329 |
+
st.session_state.is_running = True
|
330 |
+
st.session_state.current_step = 0
|
331 |
+
st.session_state.total_steps = num_steps
|
332 |
+
st.session_state.progress = 0
|
333 |
+
|
334 |
+
@staticmethod
|
335 |
+
def set_api_keys():
|
336 |
+
"""
|
337 |
+
Set the API keys in the environment variables from the session state.
|
338 |
+
"""
|
339 |
+
if st.session_state.get("openai_key"):
|
340 |
+
os.environ["OPENAI_API_KEY"] = st.session_state.openai_key
|
341 |
+
if st.session_state.get("anthropic_key"):
|
342 |
+
os.environ["ANTHROPIC_API_KEY"] = st.session_state.anthropic_key
|
343 |
+
|
344 |
+
def prepare_input_directory(self, files):
|
345 |
+
"""
|
346 |
+
Prepare the input directory and handle uploaded files.
|
347 |
+
|
348 |
+
Args:
|
349 |
+
files (list): List of uploaded or example files.
|
350 |
+
|
351 |
+
Returns:
|
352 |
+
Path: The input directory path, or None if files are missing.
|
353 |
+
"""
|
354 |
+
input_dir = self.project_root / "input"
|
355 |
+
input_dir.mkdir(parents=True, exist_ok=True)
|
356 |
+
|
357 |
+
if files:
|
358 |
+
for file in files:
|
359 |
+
if isinstance(file, dict): # Example files
|
360 |
+
shutil.copy2(file["path"], input_dir / file["name"])
|
361 |
+
else: # Uploaded files
|
362 |
+
with open(input_dir / file.name, "wb") as f:
|
363 |
+
f.write(file.getbuffer())
|
364 |
+
else:
|
365 |
+
st.error("Please upload data files")
|
366 |
+
return None
|
367 |
+
return input_dir
|
368 |
+
|
369 |
+
@staticmethod
|
370 |
+
def initialize_experiment(input_dir, goal_text, eval_text):
|
371 |
+
"""
|
372 |
+
Initialize the AIDE Experiment.
|
373 |
+
|
374 |
+
Args:
|
375 |
+
input_dir (Path): Path to the input directory.
|
376 |
+
goal_text (str): The goal of the experiment.
|
377 |
+
eval_text (str): The evaluation criteria.
|
378 |
+
|
379 |
+
Returns:
|
380 |
+
Experiment: The initialized Experiment object.
|
381 |
+
"""
|
382 |
+
experiment = Experiment(data_dir=str(input_dir), goal=goal_text, eval=eval_text)
|
383 |
+
return experiment
|
384 |
+
|
385 |
+
@staticmethod
|
386 |
+
def collect_results(experiment):
|
387 |
+
"""
|
388 |
+
Collect the results from the experiment.
|
389 |
+
|
390 |
+
Args:
|
391 |
+
experiment (Experiment): The Experiment object.
|
392 |
+
|
393 |
+
Returns:
|
394 |
+
dict: Dictionary containing the collected results.
|
395 |
+
"""
|
396 |
+
solution_path = experiment.cfg.log_dir / "best_solution.py"
|
397 |
+
if solution_path.exists():
|
398 |
+
solution = solution_path.read_text()
|
399 |
+
else:
|
400 |
+
solution = "No solution found"
|
401 |
+
|
402 |
+
journal_data = [
|
403 |
+
{
|
404 |
+
"step": node.step,
|
405 |
+
"code": str(node.code),
|
406 |
+
"metric": str(node.metric.value) if node.metric else None,
|
407 |
+
"is_buggy": node.is_buggy,
|
408 |
+
}
|
409 |
+
for node in experiment.journal.nodes
|
410 |
+
]
|
411 |
+
|
412 |
+
results = {
|
413 |
+
"solution": solution,
|
414 |
+
"config": OmegaConf.to_yaml(experiment.cfg),
|
415 |
+
"journal": json.dumps(journal_data, indent=2, default=str),
|
416 |
+
"tree_path": str(experiment.cfg.log_dir / "tree_plot.html"),
|
417 |
+
}
|
418 |
+
return results
|
419 |
+
|
420 |
+
@staticmethod
|
421 |
+
def render_tree_visualization(results):
|
422 |
+
"""
|
423 |
+
Render the tree visualization from the experiment results.
|
424 |
+
|
425 |
+
Args:
|
426 |
+
results (dict): The results dictionary containing paths and data.
|
427 |
+
"""
|
428 |
+
if "tree_path" in results:
|
429 |
+
tree_path = Path(results["tree_path"])
|
430 |
+
logger.info(f"Loading tree visualization from: {tree_path}")
|
431 |
+
if tree_path.exists():
|
432 |
+
with open(tree_path, "r", encoding="utf-8") as f:
|
433 |
+
html_content = f.read()
|
434 |
+
components.html(html_content, height=600, scrolling=True)
|
435 |
+
else:
|
436 |
+
st.error(f"Tree visualization file not found at: {tree_path}")
|
437 |
+
logger.error(f"Tree file not found at: {tree_path}")
|
438 |
+
else:
|
439 |
+
st.info("No tree visualization available for this run.")
|
440 |
+
|
441 |
+
@staticmethod
|
442 |
+
def render_best_solution(results):
|
443 |
+
"""
|
444 |
+
Display the best solution code.
|
445 |
+
|
446 |
+
Args:
|
447 |
+
results (dict): The results dictionary containing the solution.
|
448 |
+
"""
|
449 |
+
if "solution" in results:
|
450 |
+
solution_code = results["solution"]
|
451 |
+
st.code(solution_code, language="python")
|
452 |
+
else:
|
453 |
+
st.info("No solution available.")
|
454 |
+
|
455 |
+
@staticmethod
|
456 |
+
def render_config(results):
|
457 |
+
"""
|
458 |
+
Display the configuration used in the experiment.
|
459 |
+
|
460 |
+
Args:
|
461 |
+
results (dict): The results dictionary containing the config.
|
462 |
+
"""
|
463 |
+
if "config" in results:
|
464 |
+
st.code(results["config"], language="yaml")
|
465 |
+
else:
|
466 |
+
st.info("No configuration available.")
|
467 |
+
|
468 |
+
@staticmethod
|
469 |
+
def render_journal(results):
|
470 |
+
"""
|
471 |
+
Display the experiment journal as JSON.
|
472 |
+
|
473 |
+
Args:
|
474 |
+
results (dict): The results dictionary containing the journal.
|
475 |
+
"""
|
476 |
+
if "journal" in results:
|
477 |
+
try:
|
478 |
+
journal_data = json.loads(results["journal"])
|
479 |
+
formatted_journal = json.dumps(journal_data, indent=2)
|
480 |
+
st.code(formatted_journal, language="json")
|
481 |
+
except json.JSONDecodeError:
|
482 |
+
st.code(results["journal"], language="json")
|
483 |
+
else:
|
484 |
+
st.info("No journal available.")
|
485 |
+
|
486 |
+
@staticmethod
|
487 |
+
def get_best_metric(results):
|
488 |
+
"""
|
489 |
+
Extract the best validation metric from results.
|
490 |
+
"""
|
491 |
+
try:
|
492 |
+
journal_data = json.loads(results["journal"])
|
493 |
+
metrics = []
|
494 |
+
for node in journal_data:
|
495 |
+
if node["metric"] is not None:
|
496 |
+
try:
|
497 |
+
# Convert string metric to float
|
498 |
+
metric_value = float(node["metric"])
|
499 |
+
metrics.append(metric_value)
|
500 |
+
except (ValueError, TypeError):
|
501 |
+
continue
|
502 |
+
return max(metrics) if metrics else None
|
503 |
+
except (json.JSONDecodeError, KeyError):
|
504 |
+
return None
|
505 |
+
|
506 |
+
@staticmethod
|
507 |
+
def render_validation_plot(results, step):
|
508 |
+
"""
|
509 |
+
Render the validation score plot.
|
510 |
+
|
511 |
+
Args:
|
512 |
+
results (dict): The results dictionary
|
513 |
+
step (int): Current step number for unique key generation
|
514 |
+
"""
|
515 |
+
try:
|
516 |
+
journal_data = json.loads(results["journal"])
|
517 |
+
steps = []
|
518 |
+
metrics = []
|
519 |
+
|
520 |
+
for node in journal_data:
|
521 |
+
if node["metric"] is not None and node["metric"].lower() != "none":
|
522 |
+
try:
|
523 |
+
metric_value = float(node["metric"])
|
524 |
+
steps.append(node["step"])
|
525 |
+
metrics.append(metric_value)
|
526 |
+
except (ValueError, TypeError):
|
527 |
+
continue
|
528 |
+
|
529 |
+
if metrics:
|
530 |
+
import plotly.graph_objects as go
|
531 |
+
|
532 |
+
fig = go.Figure()
|
533 |
+
fig.add_trace(
|
534 |
+
go.Scatter(
|
535 |
+
x=steps,
|
536 |
+
y=metrics,
|
537 |
+
mode="lines+markers",
|
538 |
+
name="Validation Score",
|
539 |
+
line=dict(color="#F04370"),
|
540 |
+
marker=dict(color="#F04370"),
|
541 |
+
)
|
542 |
+
)
|
543 |
+
|
544 |
+
fig.update_layout(
|
545 |
+
title="Validation Score Progress",
|
546 |
+
xaxis_title="Step",
|
547 |
+
yaxis_title="Validation Score",
|
548 |
+
template="plotly_white",
|
549 |
+
hovermode="x unified",
|
550 |
+
plot_bgcolor="rgba(0,0,0,0)",
|
551 |
+
paper_bgcolor="rgba(0,0,0,0)",
|
552 |
+
)
|
553 |
+
|
554 |
+
# Only keep the key for plotly_chart
|
555 |
+
st.plotly_chart(fig, use_container_width=True, key=f"plot_{step}")
|
556 |
+
else:
|
557 |
+
st.info("No validation metrics available to plot")
|
558 |
+
|
559 |
+
except (json.JSONDecodeError, KeyError):
|
560 |
+
st.error("Could not parse validation metrics data")
|
561 |
+
|
562 |
+
def render_live_results(self, experiment):
|
563 |
+
"""
|
564 |
+
Render live results.
|
565 |
+
|
566 |
+
Args:
|
567 |
+
experiment (Experiment): The Experiment object
|
568 |
+
"""
|
569 |
+
results = self.collect_results(experiment)
|
570 |
+
|
571 |
+
# Create tabs for different result views
|
572 |
+
tabs = st.tabs(
|
573 |
+
[
|
574 |
+
"Tree Visualization",
|
575 |
+
"Best Solution",
|
576 |
+
"Config",
|
577 |
+
"Journal",
|
578 |
+
"Validation Plot",
|
579 |
+
]
|
580 |
+
)
|
581 |
+
|
582 |
+
with tabs[0]:
|
583 |
+
self.render_tree_visualization(results)
|
584 |
+
with tabs[1]:
|
585 |
+
self.render_best_solution(results)
|
586 |
+
with tabs[2]:
|
587 |
+
self.render_config(results)
|
588 |
+
with tabs[3]:
|
589 |
+
self.render_journal(results)
|
590 |
+
with tabs[4]:
|
591 |
+
best_metric = self.get_best_metric(results)
|
592 |
+
if best_metric is not None:
|
593 |
+
st.metric("Best Validation Score", f"{best_metric:.4f}")
|
594 |
+
self.render_validation_plot(results, step=st.session_state.current_step)
|
595 |
+
|
596 |
+
|
597 |
+
if __name__ == "__main__":
|
598 |
+
app = WebUI()
|
599 |
+
app.run()
|
aide/webui/style.css
ADDED
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.stVerticalBlock {
|
2 |
+
padding-top: 0rem;
|
3 |
+
padding-bottom: 0rem;
|
4 |
+
}
|
5 |
+
|
6 |
+
.block-container {
|
7 |
+
padding-top: 0rem;
|
8 |
+
padding-bottom: 0rem;
|
9 |
+
}
|
10 |
+
|
11 |
+
[data-testid="stVerticalBlock"] {
|
12 |
+
padding-top: 0rem;
|
13 |
+
padding-bottom: 0rem;
|
14 |
+
}
|
15 |
+
.st-emotion-cache-40pabj{
|
16 |
+
padding-top: 0rem;
|
17 |
+
padding-bottom: 0rem;
|
18 |
+
}
|
19 |
+
/* Make the toolbar transparent */
|
20 |
+
.st-emotion-cache-18ni7ap {
|
21 |
+
pointer-events: none;
|
22 |
+
background: rgb(255 255 255 / 0%)
|
23 |
+
}
|
24 |
+
|
25 |
+
.stAppHeader {
|
26 |
+
display: none;
|
27 |
+
}
|
28 |
+
|
29 |
+
header {visibility: hidden;}
|
30 |
+
#MainMenu {visibility: hidden;}
|
31 |
+
[data-testid="stDecoration"] {
|
32 |
+
display: none;
|
33 |
+
}
|
34 |
+
#root > div:nth-child(1) > div > div > div > div > section > div {
|
35 |
+
padding-top: 0rem;
|
36 |
+
}
|
37 |
+
|
38 |
+
section.stMain .block-container {
|
39 |
+
padding-top: 0rem;
|
40 |
+
z-index: 1;
|
41 |
+
}
|
42 |
+
|
43 |
+
/* Main container */
|
44 |
+
.stApp {
|
45 |
+
background-color: var(--background);
|
46 |
+
height: auto;
|
47 |
+
overflow: visible;
|
48 |
+
}
|
49 |
+
|
50 |
+
/* Widgets */
|
51 |
+
.stSelectbox,
|
52 |
+
.stTextInput,
|
53 |
+
.stNumberInput {
|
54 |
+
background-color: var(--card);
|
55 |
+
border: 1px solid var(--border);
|
56 |
+
border-radius: 0.4rem;
|
57 |
+
}
|
58 |
+
|
59 |
+
.stMarkdown {
|
60 |
+
color: var(--primary);
|
61 |
+
}
|
62 |
+
|
63 |
+
/* Code block styling */
|
64 |
+
.stCodeBlock {
|
65 |
+
max-height: 400px;
|
66 |
+
overflow-y: auto !important;
|
67 |
+
border: 1px solid var(--border);
|
68 |
+
border-radius: 0.4rem;
|
69 |
+
background-color: var(--background-shaded);
|
70 |
+
}
|
71 |
+
|
72 |
+
/* Custom scrollbar for code blocks */
|
73 |
+
.stCodeBlock::-webkit-scrollbar {
|
74 |
+
width: 8px;
|
75 |
+
height: 8px;
|
76 |
+
}
|
77 |
+
|
78 |
+
.stCodeBlock::-webkit-scrollbar-track {
|
79 |
+
background: var(--background-shaded);
|
80 |
+
border-radius: 4px;
|
81 |
+
}
|
82 |
+
|
83 |
+
.stCodeBlock::-webkit-scrollbar-thumb {
|
84 |
+
background: var(--accent);
|
85 |
+
border-radius: 4px;
|
86 |
+
}
|
87 |
+
|
88 |
+
.stCodeBlock::-webkit-scrollbar-thumb:hover {
|
89 |
+
background: #e13d68;
|
90 |
+
}
|
91 |
+
|
92 |
+
|
93 |
+
|
94 |
+
.scrollable-code-container {
|
95 |
+
height: 600px;
|
96 |
+
overflow-y: auto;
|
97 |
+
border: 1px solid var(--border);
|
98 |
+
padding: 15px;
|
99 |
+
border-radius: 5px;
|
100 |
+
background-color: var(--background-shaded);
|
101 |
+
}
|
102 |
+
|
103 |
+
.scrollable-code-container pre {
|
104 |
+
margin: 0;
|
105 |
+
white-space: pre;
|
106 |
+
overflow-x: auto;
|
107 |
+
font-family: monospace;
|
108 |
+
}
|
109 |
+
|
110 |
+
.scrollable-code-container code {
|
111 |
+
display: block;
|
112 |
+
min-width: 100%;
|
113 |
+
padding: 0;
|
114 |
+
tab-size: 4;
|
115 |
+
}
|
116 |
+
|
117 |
+
/* Add custom scrollbar styling for code containers */
|
118 |
+
.scrollable-code-container::-webkit-scrollbar {
|
119 |
+
width: 8px;
|
120 |
+
height: 8px;
|
121 |
+
}
|
122 |
+
|
123 |
+
.scrollable-code-container::-webkit-scrollbar-track {
|
124 |
+
background: var(--background-shaded);
|
125 |
+
border-radius: 4px;
|
126 |
+
}
|
127 |
+
|
128 |
+
.scrollable-code-container::-webkit-scrollbar-thumb {
|
129 |
+
background: var(--accent);
|
130 |
+
border-radius: 4px;
|
131 |
+
}
|
132 |
+
|
133 |
+
.scrollable-code-container::-webkit-scrollbar-thumb:hover {
|
134 |
+
background: #e13d68;
|
135 |
+
}
|
136 |
+
|
137 |
+
/* Style for expander */
|
138 |
+
.streamlit-expanderHeader {
|
139 |
+
background-color: var(--card);
|
140 |
+
border: 1px solid var(--border);
|
141 |
+
border-radius: 0.4rem;
|
142 |
+
padding: 0.5rem !important;
|
143 |
+
}
|
144 |
+
|
145 |
+
.streamlit-expanderHeader:hover {
|
146 |
+
border-color: var(--accent);
|
147 |
+
}
|
148 |
+
|
149 |
+
/* Style for expander content */
|
150 |
+
.streamlit-expanderContent {
|
151 |
+
background-color: var(--background-shaded);
|
152 |
+
border: 1px solid var(--border);
|
153 |
+
border-radius: 0 0 0.4rem 0.4rem;
|
154 |
+
margin-top: -1px;
|
155 |
+
padding: 0.5rem !important;
|
156 |
+
}
|
157 |
+
|
158 |
+
/* Style for st.code() blocks */
|
159 |
+
.stCode {
|
160 |
+
max-height: 600px;
|
161 |
+
overflow-y: auto;
|
162 |
+
background-color: var(--background-shaded) !important;
|
163 |
+
border: 1px solid var(--border) !important;
|
164 |
+
border-radius: 5px !important;
|
165 |
+
}
|
166 |
+
|
167 |
+
.stCode pre {
|
168 |
+
background-color: var(--background-shaded) !important;
|
169 |
+
}
|
170 |
+
|
171 |
+
div[data-testid="InputInstructions"] {
|
172 |
+
visibility: hidden;
|
173 |
+
}
|
app.py
CHANGED
@@ -35,7 +35,7 @@ class WebUI:
|
|
35 |
Initialize the WebUI with environment variables and session state.
|
36 |
"""
|
37 |
self.env_vars = self.load_env_variables()
|
38 |
-
self.project_root = Path(__file__).parent
|
39 |
self.config_session_state()
|
40 |
self.setup_page()
|
41 |
|
@@ -219,7 +219,7 @@ class WebUI:
|
|
219 |
Returns:
|
220 |
list: List of example files with their paths.
|
221 |
"""
|
222 |
-
package_root = Path(__file__).parent
|
223 |
example_dir = package_root / "example_tasks" / "house_prices"
|
224 |
|
225 |
if not example_dir.exists():
|
|
|
35 |
Initialize the WebUI with environment variables and session state.
|
36 |
"""
|
37 |
self.env_vars = self.load_env_variables()
|
38 |
+
self.project_root = Path(__file__).parent
|
39 |
self.config_session_state()
|
40 |
self.setup_page()
|
41 |
|
|
|
219 |
Returns:
|
220 |
list: List of example files with their paths.
|
221 |
"""
|
222 |
+
package_root = Path(__file__).parent / "aide"
|
223 |
example_dir = package_root / "example_tasks" / "house_prices"
|
224 |
|
225 |
if not example_dir.exists():
|
requirements.txt
ADDED
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# AIDE requirements
|
2 |
+
black==24.3.0
|
3 |
+
funcy==2.0
|
4 |
+
humanize==4.8.0
|
5 |
+
jsonschema==4.19.2
|
6 |
+
numpy==1.26.2
|
7 |
+
openai>=1.3.5
|
8 |
+
anthropic>=0.20.0
|
9 |
+
pandas==2.1.4
|
10 |
+
pytest==7.4.3
|
11 |
+
requests==2.32.2
|
12 |
+
scikit-learn==1.5.0
|
13 |
+
rich==13.7.0
|
14 |
+
scipy==1.11.4
|
15 |
+
dataclasses_json>=0.6.4
|
16 |
+
omegaconf>=2.3.0
|
17 |
+
loguru==0.7.2
|
18 |
+
shutup>=0.2.0
|
19 |
+
tqdm==4.66.3
|
20 |
+
coolname>=2.2.0
|
21 |
+
igraph>=0.11.3
|
22 |
+
genson>=1.2.0
|
23 |
+
|
24 |
+
# agent requirements (packages that the agent might need)
|
25 |
+
torch
|
26 |
+
torchvision
|
27 |
+
torchaudio
|
28 |
+
torchtext
|
29 |
+
|
30 |
+
lightgbm
|
31 |
+
matplotlib
|
32 |
+
seaborn
|
33 |
+
|
34 |
+
# tensorflow
|
35 |
+
# tensorflow-io
|
36 |
+
# tensorflow_hub
|
37 |
+
# tf-keras
|
38 |
+
# tensorflow_decision_forests
|
39 |
+
# keras
|
40 |
+
# keras-cv
|
41 |
+
# keras-nlp
|
42 |
+
|
43 |
+
gensim
|
44 |
+
|
45 |
+
scikit-image
|
46 |
+
opencv-python
|
47 |
+
scipy
|
48 |
+
scikit-learn
|
49 |
+
biopython
|
50 |
+
imbalanced-learn
|
51 |
+
h5py
|
52 |
+
biopython
|
53 |
+
numba
|
54 |
+
arrow
|
55 |
+
markovify
|
56 |
+
imgaug
|
57 |
+
scikit-optimize
|
58 |
+
plotly
|
59 |
+
hyperopt
|
60 |
+
bayesian-optimization
|
61 |
+
imagecodecs
|
62 |
+
hmmlearn
|
63 |
+
bayespy==0.5.1
|
64 |
+
sklearn-pandas
|
65 |
+
tensorpack
|
66 |
+
sentencepiece
|
67 |
+
librosa
|
68 |
+
ipykernel
|
69 |
+
ipython
|
70 |
+
nbformat
|
71 |
+
kornia
|
72 |
+
Pillow
|
73 |
+
pyparsing
|
74 |
+
pytz
|
75 |
+
PyYAML
|
76 |
+
tqdm
|
77 |
+
fastai
|
78 |
+
gym
|
79 |
+
optuna
|
80 |
+
transformers
|
81 |
+
datasets==2.1.0
|
82 |
+
torchmetrics
|
83 |
+
pytorch-lightning
|
84 |
+
sympy
|
85 |
+
timm
|
86 |
+
torchinfo
|
87 |
+
pdf2image
|
88 |
+
PyPDF
|
89 |
+
pyocr
|
90 |
+
pyarrow
|
91 |
+
xlrd
|
92 |
+
backoff
|
93 |
+
streamlit==1.40.2
|
94 |
+
python-dotenv
|
style.css
ADDED
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.stVerticalBlock {
|
2 |
+
padding-top: 0rem;
|
3 |
+
padding-bottom: 0rem;
|
4 |
+
}
|
5 |
+
|
6 |
+
.block-container {
|
7 |
+
padding-top: 0rem;
|
8 |
+
padding-bottom: 0rem;
|
9 |
+
}
|
10 |
+
|
11 |
+
[data-testid="stVerticalBlock"] {
|
12 |
+
padding-top: 0rem;
|
13 |
+
padding-bottom: 0rem;
|
14 |
+
}
|
15 |
+
.st-emotion-cache-40pabj{
|
16 |
+
padding-top: 0rem;
|
17 |
+
padding-bottom: 0rem;
|
18 |
+
}
|
19 |
+
/* Make the toolbar transparent */
|
20 |
+
.st-emotion-cache-18ni7ap {
|
21 |
+
pointer-events: none;
|
22 |
+
background: rgb(255 255 255 / 0%)
|
23 |
+
}
|
24 |
+
|
25 |
+
.stAppHeader {
|
26 |
+
display: none;
|
27 |
+
}
|
28 |
+
|
29 |
+
header {visibility: hidden;}
|
30 |
+
#MainMenu {visibility: hidden;}
|
31 |
+
[data-testid="stDecoration"] {
|
32 |
+
display: none;
|
33 |
+
}
|
34 |
+
#root > div:nth-child(1) > div > div > div > div > section > div {
|
35 |
+
padding-top: 0rem;
|
36 |
+
}
|
37 |
+
|
38 |
+
section.stMain .block-container {
|
39 |
+
padding-top: 0rem;
|
40 |
+
z-index: 1;
|
41 |
+
}
|
42 |
+
|
43 |
+
/* Main container */
|
44 |
+
.stApp {
|
45 |
+
background-color: var(--background);
|
46 |
+
height: auto;
|
47 |
+
overflow: visible;
|
48 |
+
}
|
49 |
+
|
50 |
+
/* Widgets */
|
51 |
+
.stSelectbox,
|
52 |
+
.stTextInput,
|
53 |
+
.stNumberInput {
|
54 |
+
background-color: var(--card);
|
55 |
+
border: 1px solid var(--border);
|
56 |
+
border-radius: 0.4rem;
|
57 |
+
}
|
58 |
+
|
59 |
+
.stMarkdown {
|
60 |
+
color: var(--primary);
|
61 |
+
}
|
62 |
+
|
63 |
+
/* Code block styling */
|
64 |
+
.stCodeBlock {
|
65 |
+
max-height: 400px;
|
66 |
+
overflow-y: auto !important;
|
67 |
+
border: 1px solid var(--border);
|
68 |
+
border-radius: 0.4rem;
|
69 |
+
background-color: var(--background-shaded);
|
70 |
+
}
|
71 |
+
|
72 |
+
/* Custom scrollbar for code blocks */
|
73 |
+
.stCodeBlock::-webkit-scrollbar {
|
74 |
+
width: 8px;
|
75 |
+
height: 8px;
|
76 |
+
}
|
77 |
+
|
78 |
+
.stCodeBlock::-webkit-scrollbar-track {
|
79 |
+
background: var(--background-shaded);
|
80 |
+
border-radius: 4px;
|
81 |
+
}
|
82 |
+
|
83 |
+
.stCodeBlock::-webkit-scrollbar-thumb {
|
84 |
+
background: var(--accent);
|
85 |
+
border-radius: 4px;
|
86 |
+
}
|
87 |
+
|
88 |
+
.stCodeBlock::-webkit-scrollbar-thumb:hover {
|
89 |
+
background: #e13d68;
|
90 |
+
}
|
91 |
+
|
92 |
+
|
93 |
+
|
94 |
+
.scrollable-code-container {
|
95 |
+
height: 600px;
|
96 |
+
overflow-y: auto;
|
97 |
+
border: 1px solid var(--border);
|
98 |
+
padding: 15px;
|
99 |
+
border-radius: 5px;
|
100 |
+
background-color: var(--background-shaded);
|
101 |
+
}
|
102 |
+
|
103 |
+
.scrollable-code-container pre {
|
104 |
+
margin: 0;
|
105 |
+
white-space: pre;
|
106 |
+
overflow-x: auto;
|
107 |
+
font-family: monospace;
|
108 |
+
}
|
109 |
+
|
110 |
+
.scrollable-code-container code {
|
111 |
+
display: block;
|
112 |
+
min-width: 100%;
|
113 |
+
padding: 0;
|
114 |
+
tab-size: 4;
|
115 |
+
}
|
116 |
+
|
117 |
+
/* Add custom scrollbar styling for code containers */
|
118 |
+
.scrollable-code-container::-webkit-scrollbar {
|
119 |
+
width: 8px;
|
120 |
+
height: 8px;
|
121 |
+
}
|
122 |
+
|
123 |
+
.scrollable-code-container::-webkit-scrollbar-track {
|
124 |
+
background: var(--background-shaded);
|
125 |
+
border-radius: 4px;
|
126 |
+
}
|
127 |
+
|
128 |
+
.scrollable-code-container::-webkit-scrollbar-thumb {
|
129 |
+
background: var(--accent);
|
130 |
+
border-radius: 4px;
|
131 |
+
}
|
132 |
+
|
133 |
+
.scrollable-code-container::-webkit-scrollbar-thumb:hover {
|
134 |
+
background: #e13d68;
|
135 |
+
}
|
136 |
+
|
137 |
+
/* Style for expander */
|
138 |
+
.streamlit-expanderHeader {
|
139 |
+
background-color: var(--card);
|
140 |
+
border: 1px solid var(--border);
|
141 |
+
border-radius: 0.4rem;
|
142 |
+
padding: 0.5rem !important;
|
143 |
+
}
|
144 |
+
|
145 |
+
.streamlit-expanderHeader:hover {
|
146 |
+
border-color: var(--accent);
|
147 |
+
}
|
148 |
+
|
149 |
+
/* Style for expander content */
|
150 |
+
.streamlit-expanderContent {
|
151 |
+
background-color: var(--background-shaded);
|
152 |
+
border: 1px solid var(--border);
|
153 |
+
border-radius: 0 0 0.4rem 0.4rem;
|
154 |
+
margin-top: -1px;
|
155 |
+
padding: 0.5rem !important;
|
156 |
+
}
|
157 |
+
|
158 |
+
/* Style for st.code() blocks */
|
159 |
+
.stCode {
|
160 |
+
max-height: 600px;
|
161 |
+
overflow-y: auto;
|
162 |
+
background-color: var(--background-shaded) !important;
|
163 |
+
border: 1px solid var(--border) !important;
|
164 |
+
border-radius: 5px !important;
|
165 |
+
}
|
166 |
+
|
167 |
+
.stCode pre {
|
168 |
+
background-color: var(--background-shaded) !important;
|
169 |
+
}
|
170 |
+
|
171 |
+
div[data-testid="InputInstructions"] {
|
172 |
+
visibility: hidden;
|
173 |
+
}
|