appworld 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. appworld-0.1.1/PKG-INFO +103 -0
  2. appworld-0.1.1/README.pypi.md +5 -0
  3. appworld-0.1.1/pyproject.toml +261 -0
  4. appworld-0.1.1/src/appworld/.source/apps.bundle +0 -0
  5. appworld-0.1.1/src/appworld/.source/tests.bundle +0 -0
  6. appworld-0.1.1/src/appworld/__init__.py +29 -0
  7. appworld-0.1.1/src/appworld/api_docs.py +517 -0
  8. appworld-0.1.1/src/appworld/apps/LICENSE +1 -0
  9. appworld-0.1.1/src/appworld/apps/README_BEFORE_SHARING.md +5 -0
  10. appworld-0.1.1/src/appworld/apps/__init__.py +282 -0
  11. appworld-0.1.1/src/appworld/apps/api_lib.py +1338 -0
  12. appworld-0.1.1/src/appworld/apps/factory_lib.py +41 -0
  13. appworld-0.1.1/src/appworld/apps/model_lib.py +2513 -0
  14. appworld-0.1.1/src/appworld/apps/response_lib.py +72 -0
  15. appworld-0.1.1/src/appworld/cli.py +721 -0
  16. appworld-0.1.1/src/appworld/collections/api_docs.py +247 -0
  17. appworld-0.1.1/src/appworld/collections/api_docs.pyi +965 -0
  18. appworld-0.1.1/src/appworld/collections/apis.py +194 -0
  19. appworld-0.1.1/src/appworld/collections/apis.pyi +2940 -0
  20. appworld-0.1.1/src/appworld/collections/models.py +572 -0
  21. appworld-0.1.1/src/appworld/collections/models.pyi +153 -0
  22. appworld-0.1.1/src/appworld/common/__init__.py +0 -0
  23. appworld-0.1.1/src/appworld/common/code_parsing.py +745 -0
  24. appworld-0.1.1/src/appworld/common/constants.py +34 -0
  25. appworld-0.1.1/src/appworld/common/copy.py +4 -0
  26. appworld-0.1.1/src/appworld/common/datetime.py +756 -0
  27. appworld-0.1.1/src/appworld/common/path_store.py +62 -0
  28. appworld-0.1.1/src/appworld/common/random.py +198 -0
  29. appworld-0.1.1/src/appworld/common/safety_guard.py +327 -0
  30. appworld-0.1.1/src/appworld/common/types.py +15 -0
  31. appworld-0.1.1/src/appworld/common/utils.py +4397 -0
  32. appworld-0.1.1/src/appworld/download.py +56 -0
  33. appworld-0.1.1/src/appworld/environment.py +806 -0
  34. appworld-0.1.1/src/appworld/evaluator.py +628 -0
  35. appworld-0.1.1/src/appworld/ground_truth.py +379 -0
  36. appworld-0.1.1/src/appworld/install.py +73 -0
  37. appworld-0.1.1/src/appworld/leaderboard.py +230 -0
  38. appworld-0.1.1/src/appworld/requester.py +767 -0
  39. appworld-0.1.1/src/appworld/serve/apis.py +30 -0
  40. appworld-0.1.1/src/appworld/serve/environment.py +250 -0
  41. appworld-0.1.1/src/appworld/serve/playground.html +701 -0
  42. appworld-0.1.1/src/appworld/serve/static/icon.png +0 -0
  43. appworld-0.1.1/src/appworld/task.py +295 -0
  44. appworld-0.1.1/src/appworld/verify.py +129 -0
@@ -0,0 +1,103 @@
1
+ Metadata-Version: 2.1
2
+ Name: appworld
3
+ Version: 0.1.1
4
+ Summary: AppWorld: A Controllable World of Apps and People for Benchmarking Interactive Coding Agents
5
+ Home-page: https://appworld.dev/
6
+ License: Apache-2.0
7
+ Keywords: ai-agents,ai-assistants,ai-planning,autonomous-agents,ai-environment,tool-usage,coding-agents,interactive-coding,nlp-machine-learning,nlp-datasets,llm,function-calling,llm-agents,ai-apis,acl-2024
8
+ Author: Harsh Trivedi
9
+ Author-email: harshjtrivedi94@gmail.com
10
+ Maintainer: Harsh Trivedi
11
+ Maintainer-email: harshjtrivedi94@gmail.com
12
+ Requires-Python: >=3.10,<4.0
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: Apache Software License
17
+ Classifier: Natural Language :: English
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
25
+ Classifier: Topic :: Scientific/Engineering :: Human Machine Interfaces
26
+ Classifier: Topic :: Software Development :: Code Generators
27
+ Provides-Extra: all
28
+ Provides-Extra: experiments
29
+ Requires-Dist: black (>=24.2.0,<25.0.0) ; extra == "all"
30
+ Requires-Dist: coverage (>=7.4.3,<8.0.0) ; extra == "all"
31
+ Requires-Dist: cryptography (>=39.0.0,<40.0.0)
32
+ Requires-Dist: diskcache (>=5.6.3,<6.0.0) ; extra == "experiments" or extra == "all"
33
+ Requires-Dist: email-validator (>=2.1.1,<3.0.0)
34
+ Requires-Dist: faker (>=24.0.0,<25.0.0)
35
+ Requires-Dist: fastapi (>=0.110.0,<0.111.0)
36
+ Requires-Dist: fastapi-login (==1.9.3)
37
+ Requires-Dist: filelock (>=3.14.0,<4.0.0) ; extra == "experiments" or extra == "all"
38
+ Requires-Dist: freezegun (<=1.2.2)
39
+ Requires-Dist: gitpython (>=3.1.42,<4.0.0) ; extra == "all"
40
+ Requires-Dist: httpx (>=0.27.0,<0.28.0)
41
+ Requires-Dist: icecream (>=2.1.3,<3.0.0) ; extra == "all"
42
+ Requires-Dist: inflection (>=0.5.1,<0.6.0)
43
+ Requires-Dist: ipython (>=8.18.0)
44
+ Requires-Dist: jinja2 (>=3.1.3,<4.0.0) ; extra == "experiments" or extra == "all"
45
+ Requires-Dist: jsonnet (>=0.20.0,<0.21.0) ; (sys_platform == "linux" or sys_platform == "darwin") and (extra == "experiments" or extra == "all")
46
+ Requires-Dist: jsonnet-binary (>=0.17.0,<0.18.0) ; (sys_platform == "win32") and (extra == "experiments" or extra == "all")
47
+ Requires-Dist: jsonref (>=1.1.0,<2.0.0)
48
+ Requires-Dist: libcst (>=1.2.0,<2.0.0)
49
+ Requires-Dist: litellm (>=1.35.0,<2.0.0) ; extra == "experiments" or extra == "all"
50
+ Requires-Dist: matplotlib (>=3.8.3,<4.0.0) ; extra == "all"
51
+ Requires-Dist: munch (>=4.0.0,<5.0.0)
52
+ Requires-Dist: mypy (>=1.8.0,<2.0.0) ; extra == "all"
53
+ Requires-Dist: numpy (>=1.25.0,<2.0.0) ; extra == "all"
54
+ Requires-Dist: openai (>=1.2.1,<2.0.0) ; extra == "experiments" or extra == "all"
55
+ Requires-Dist: openapi-spec-validator (>=0.7.1,<0.8.0) ; extra == "all"
56
+ Requires-Dist: orjson (>=3.6.0,<4.0.0)
57
+ Requires-Dist: pendulum (>=3.0.0)
58
+ Requires-Dist: plotext (>=5.2.8,<6.0.0) ; extra == "all"
59
+ Requires-Dist: polyfactory (>=2.15.0,<3.0.0)
60
+ Requires-Dist: pre-commit (>=3.6.2,<4.0.0) ; extra == "all"
61
+ Requires-Dist: psutil (>=5.9.8,<6.0.0)
62
+ Requires-Dist: pydantic (>=1.9.0,<2.0.0)
63
+ Requires-Dist: pyperclip (>=1.8.2,<2.0.0) ; extra == "all"
64
+ Requires-Dist: pytest (>=8.0.2,<9.0.0)
65
+ Requires-Dist: pytest-xdist (>=3.5.0,<4.0.0)
66
+ Requires-Dist: python-dotenv (>=1.0.1,<2.0.0)
67
+ Requires-Dist: python-multipart (>=0.0.9,<0.0.10)
68
+ Requires-Dist: pyyaml (>=6.0.0,<7.0.0)
69
+ Requires-Dist: recoma (==0.0.2) ; extra == "experiments"
70
+ Requires-Dist: registrable (>=0.0.4,<0.0.5)
71
+ Requires-Dist: requests (>=2.31.0,<3.0.0)
72
+ Requires-Dist: rich (>=13.7.1,<14.0.0)
73
+ Requires-Dist: ruff (>=0.3.0,<0.4.0) ; extra == "all"
74
+ Requires-Dist: seaborn (>=0.13.2,<0.14.0) ; extra == "all"
75
+ Requires-Dist: sqlalchemy-utils (>=0.41.1,<0.42.0)
76
+ Requires-Dist: sqlmodel (>=0.0.8,<0.0.11)
77
+ Requires-Dist: tiktoken (>=0.7.0,<0.8.0) ; extra == "experiments" or extra == "all"
78
+ Requires-Dist: tqdm (>=4.66.2,<5.0.0)
79
+ Requires-Dist: typer (>=0.12.3,<0.13.0)
80
+ Requires-Dist: types-decorator (>=5.1.8.20240106,<6.0.0.0) ; extra == "all"
81
+ Requires-Dist: types-psutil (>=5.9.5.20240205,<6.0.0.0) ; extra == "all"
82
+ Requires-Dist: types-pyyaml (>=6.0.12.12,<7.0.0.0) ; extra == "all"
83
+ Requires-Dist: types-requests (>=2.31.0.20240218,<3.0.0.0) ; extra == "all"
84
+ Requires-Dist: types-setuptools (>=69.1.0.20240302,<70.0.0.0) ; extra == "all"
85
+ Requires-Dist: types-six (>=1.16.21.20240301,<2.0.0.0) ; extra == "all"
86
+ Requires-Dist: types-tabulate (>=0.9.0.20240106,<0.10.0.0) ; extra == "all"
87
+ Requires-Dist: types-tqdm (>=4.66.0.20240106,<5.0.0.0) ; extra == "all"
88
+ Requires-Dist: types-typed-ast (>=1.5.8.7,<2.0.0.0) ; extra == "all"
89
+ Requires-Dist: types-ujson (>=5.9.0.0,<6.0.0.0) ; extra == "all"
90
+ Requires-Dist: uvicorn (>=0.27.1,<0.28.0)
91
+ Requires-Dist: uvloop (>=0.19.0,<0.20.0) ; sys_platform == "linux" or sys_platform == "darwin"
92
+ Requires-Dist: winloop (>=0.1.2,<0.2.0) ; sys_platform == "win32"
93
+ Requires-Dist: xxhash (>=3.0.0,<4.0.0)
94
+ Project-URL: Repository, https://github.com/stonybrooknlp/appworld
95
+ Project-URL: paper, https://arxiv.org/abs/2407.18901
96
+ Description-Content-Type: text/markdown
97
+
98
+ > Python package for the ACL 2024 paper, "AppWorld: A Controllable World of Apps and People for Benchmarking Interactive Coding Agents".
99
+
100
+ This work introduces AppWorld Engine, a high-fidelity execution environment of 9 day-to-day apps, operable via 457 APIs, populated with digital activities of ~100 people living in a simulated world, and an associated benchmark of natural, diverse, and challenging autonomous agent tasks requiring rich and interactive coding.
101
+
102
+ Checkout its [GitHub repository](https://github.com/stonybrooknlp/appworld) for readme.
103
+
@@ -0,0 +1,5 @@
1
+ > Python package for the ACL 2024 paper, "AppWorld: A Controllable World of Apps and People for Benchmarking Interactive Coding Agents".
2
+
3
+ This work introduces AppWorld Engine, a high-fidelity execution environment of 9 day-to-day apps, operable via 457 APIs, populated with digital activities of ~100 people living in a simulated world, and an associated benchmark of natural, diverse, and challenging autonomous agent tasks requiring rich and interactive coding.
4
+
5
+ Checkout its [GitHub repository](https://github.com/stonybrooknlp/appworld) for readme.
@@ -0,0 +1,261 @@
1
+ [tool.poetry]
2
+ name = "appworld"
3
+ version = "0.1.1"
4
+ homepage = "https://appworld.dev/"
5
+ repository = "https://github.com/stonybrooknlp/appworld"
6
+ description = "AppWorld: A Controllable World of Apps and People for Benchmarking Interactive Coding Agents"
7
+ # documentation = "https://docs.appworld.com/" # TODO: Add when ready.
8
+ authors = [
9
+ "Harsh Trivedi <harshjtrivedi94@gmail.com>",
10
+ "Tushar Khot <tushark@allenai.org>",
11
+ "Mareike Hartmann <mareikeh@coli.uni-saarland.de>",
12
+ "Ruskin Manku <rmanku@cs.stonybrook.edu>",
13
+ "Vinty Dong <vidong@cs.stonybrook.edu>",
14
+ "Edward Li <ejli@cs.stonybrook.edu>",
15
+ "Shashank Gupta <shashankg@allenai.org>",
16
+ "Ashish Sabharwal <AshishS@allenai.org>",
17
+ "Niranjan B <niranjan@cs.stonybrook.edu>",
18
+ ]
19
+ maintainers = ["Harsh Trivedi <harshjtrivedi94@gmail.com>"]
20
+ license = "Apache-2.0"
21
+ readme = "README.pypi.md"
22
+ packages = [{include = "appworld", from = "src" }]
23
+ exclude = [
24
+ "src/appworld/apps/*/**",
25
+ "**/*.yaml",
26
+ ]
27
+ include = [
28
+ "src/appworld/*.bundle",
29
+ "src/appworld/serve/playground.html",
30
+ "src/appworld/serve/static/icon.png",
31
+ ]
32
+ keywords = [
33
+ "ai-agents",
34
+ "ai-assistants",
35
+ "ai-planning",
36
+ "autonomous-agents",
37
+ "ai-environment",
38
+ "tool-usage",
39
+ "coding-agents",
40
+ "interactive-coding",
41
+ "nlp-machine-learning",
42
+ "nlp-datasets",
43
+ "llm",
44
+ "function-calling",
45
+ "llm-agents",
46
+ "ai-apis",
47
+ "acl-2024",
48
+ ]
49
+ classifiers = [
50
+ "Intended Audience :: Science/Research",
51
+ "Intended Audience :: Developers",
52
+ "Natural Language :: English",
53
+ "Operating System :: OS Independent",
54
+ "Programming Language :: Python :: 3.10",
55
+ "Programming Language :: Python :: 3.11",
56
+ "Programming Language :: Python :: 3.12",
57
+ "Programming Language :: Python :: 3.13",
58
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
59
+ "Topic :: Scientific/Engineering :: Human Machine Interfaces",
60
+ "Topic :: Software Development :: Code Generators",
61
+ "Development Status :: 3 - Alpha",
62
+ ]
63
+ [tool.poetry.urls]
64
+ "paper" = "https://arxiv.org/abs/2407.18901"
65
+
66
+ [tool.poetry.dependencies]
67
+ python = "^3.10"
68
+ fastapi = "^0.110.0"
69
+ fastapi-login = "1.9.3" # pinning because of logic _get_current_user override in apps/api_lib.py
70
+ typer = "^0.12.3"
71
+ orjson = "^3.6.0"
72
+ sqlmodel = ">=0.0.8,<0.0.11"
73
+ pydantic = "^1.9.0, <2.0.0"
74
+ requests = "^2.31.0"
75
+ inflection = "^0.5.1"
76
+ email-validator = "^2.1.1"
77
+ polyfactory = "^2.15.0"
78
+ faker = "^24.0.0"
79
+ xxhash = "^3.0.0"
80
+ munch = "^4.0.0"
81
+ ipython = ">=8.18.0" # fixes memory leak (prevents leaving fd open).
82
+ sqlalchemy-utils = "^0.41.1"
83
+ rich = "^13.7.1"
84
+ registrable = "^0.0.4"
85
+ tqdm = "^4.66.2"
86
+ freezegun = "<=1.2.2"
87
+ pendulum = ">=3.0.0"
88
+ python-dotenv = "^1.0.1"
89
+ uvicorn = "^0.27.1"
90
+ cryptography = "^39.0.0"
91
+ python-multipart = "^0.0.9"
92
+ httpx = "^0.27.0"
93
+ libcst = "^1.2.0"
94
+ uvloop = {version = "^0.19.0", markers = "sys_platform == 'linux' or sys_platform == 'darwin'"}
95
+ winloop = {version = "^0.1.2", markers = "sys_platform == 'win32'"}
96
+ pyyaml = "^6.0.0"
97
+ pytest = "^8.0.2"
98
+ pytest-xdist = "^3.5.0"
99
+ psutil = "^5.9.8" # needed only for memory leak testing.
100
+ jsonref = "^1.1.0"
101
+
102
+ # Extras for experiments
103
+ openai = {version = "^1.2.1", optional = true}
104
+ litellm = {version = "^1.35.0", optional = true}
105
+ recoma = { version = "0.0.2", optional = true}
106
+ diskcache = {version = "^5.6.3", optional = true}
107
+ tiktoken = {version = "^0.7.0", optional = true}
108
+ jinja2 = {version = "^3.1.3", optional = true}
109
+ jsonnet = {version = "^0.20.0", optional = true, markers = "sys_platform == 'linux' or sys_platform == 'darwin'"}
110
+ jsonnet-binary = {version = "^0.17.0", optional = true, markers = "sys_platform == 'win32'"}
111
+ filelock = "^3.14.0"
112
+
113
+ # Extras for internal development
114
+ openapi-spec-validator = {version = "^0.7.1", optional = true}
115
+ numpy = {version = "^1.25.0", optional = true}
116
+ matplotlib = {version = "^3.8.3", optional = true}
117
+ seaborn = {version = "^0.13.2", optional = true}
118
+ plotext = {version = "^5.2.8", optional = true}
119
+ coverage = {version = "^7.4.3", optional = true}
120
+ icecream = {version = "^2.1.3", optional = true}
121
+ gitpython = {version = "^3.1.42", optional = true}
122
+ pyperclip = {version = "^1.8.2", optional = true}
123
+ types-pyyaml = {version = "^6.0.12.12", optional = true}
124
+ types-psutil = {version = "^5.9.5.20240205", optional = true}
125
+ types-requests = {version = "^2.31.0.20240218", optional = true}
126
+ types-tqdm = {version = "^4.66.0.20240106", optional = true}
127
+ types-decorator = {version = "^5.1.8.20240106", optional = true}
128
+ types-setuptools = {version = "^69.1.0.20240302", optional = true}
129
+ types-six = {version = "^1.16.21.20240301", optional = true}
130
+ types-typed-ast = {version = "^1.5.8.7", optional = true}
131
+ types-ujson = {version = "^5.9.0.0", optional = true}
132
+ types-tabulate = {version = "^0.9.0.20240106", optional = true}
133
+ ruff = {version = "^0.3.0", optional = true}
134
+ black = {version = "^24.2.0", optional = true}
135
+ mypy = {version = "^1.8.0", optional = true}
136
+ pre-commit = {version = "^3.6.2", optional = true}
137
+
138
+ [tool.poetry.extras]
139
+ experiments = [
140
+ "openai",
141
+ "litellm",
142
+ "recoma",
143
+ "diskcache",
144
+ "tiktoken",
145
+ "jinja2",
146
+ "jsonnet",
147
+ "jsonnet-binary",
148
+ "filelock",
149
+ ]
150
+ all = [
151
+ # experiments:
152
+ "openai",
153
+ "litellm",
154
+ "diskcache",
155
+ "tiktoken",
156
+ "jinja2",
157
+ "jsonnet",
158
+ "jsonnet-binary",
159
+ "filelock",
160
+ # internal development:
161
+ "openapi-spec-validator",
162
+ "numpy",
163
+ "matplotlib",
164
+ "seaborn",
165
+ "plotext",
166
+ "coverage",
167
+ "icecream",
168
+ "gitpython",
169
+ "pyperclip",
170
+ "types-pyyaml",
171
+ "types-psutil",
172
+ "types-requests",
173
+ "types-tqdm",
174
+ "types-decorator",
175
+ "types-setuptools",
176
+ "types-six",
177
+ "types-typed-ast",
178
+ "types-ujson",
179
+ "types-tabulate",
180
+ "ruff",
181
+ "black",
182
+ "mypy",
183
+ "pre-commit",
184
+ ]
185
+
186
+ [tool.poetry.scripts]
187
+ appworld = "appworld.cli:main"
188
+
189
+ [build-system]
190
+ requires = ["poetry-core"]
191
+ build-backend = "poetry.core.masonry.api"
192
+
193
+ [tool.ruff]
194
+ target-version = "py39"
195
+ line-length = 100
196
+ respect-gitignore = true
197
+ output-format = "full"
198
+ extend-exclude = ["archive", "data", "experiments"]
199
+
200
+ [tool.ruff.lint]
201
+ select = [
202
+ "F", # pyflakes (default)
203
+ "E", # pycodestyle errors (default)
204
+ # enable others progressively:
205
+ "W", # pycodestyle warnings
206
+ "F", # pyflakes
207
+ "I", # isort
208
+ "N", # pep8-naming
209
+ "UP", # pyupgrade
210
+ "C", # flake8-comprehensions
211
+ "B", # flake8-bugbear
212
+ "RUF", # ruff
213
+ # following are unnecessary for now.
214
+ # "ANN", # flake8-annotations
215
+ # "A", # flake8-builtins
216
+ # "ARG", # flake8-unused-arguments
217
+ # "PTH", # flake8-use-pathlib
218
+ # "PL", # pylint
219
+ ]
220
+ ignore = [
221
+ "E501", # line too long, handled by black
222
+ "B008", # do not perform function calls in argument defaults
223
+ "C901", # too complex
224
+ "E731", # can't assign lambda a name.
225
+ "B023", # Checks for function definitions that use a loop variable.
226
+ "W605", # invalid escape sequence
227
+ ]
228
+
229
+ [tool.ruff.lint.isort]
230
+ lines-after-imports = 2
231
+ known-first-party = ["appworld"]
232
+ known-third-party = ["recoma"]
233
+
234
+ [tool.ruff.lint.pydocstyle]
235
+ convention = "google"
236
+
237
+ [tool.pytest.ini_options]
238
+ pythonpath = ["."]
239
+ markers = [
240
+ "api: custom marker for API tests",
241
+ "app: custom marker for Base DB tests",
242
+ ]
243
+ filterwarnings = ["ignore::Warning"]
244
+
245
+ [tool.coverage.html]
246
+ directory = ".coverage_report"
247
+
248
+ [tool.mypy]
249
+ plugins = [
250
+ "pydantic.mypy"
251
+ ]
252
+ exclude = ["archive", "data", "experiments", "generate", "tests"]
253
+ namespace_packages = false
254
+ install_types = true
255
+ ignore_missing_imports = true
256
+ disallow_untyped_defs = true
257
+
258
+ [tool.pydantic-mypy]
259
+ init_forbid_extra = true
260
+ init_typed = true
261
+ warn_required_dynamic_aliases = true
@@ -0,0 +1,29 @@
1
+ # ruff: noqa: F401
2
+
3
+ from appworld.common.path_store import path_store
4
+ from appworld.environment import AppWorld
5
+ from appworld.evaluator import Metric, evaluate_dataset, evaluate_task, evaluate_tasks
6
+ from appworld.task import load_task_ids
7
+
8
+
9
+ __version__ = "0.1.0"
10
+ FASTAPI_METADATA = {
11
+ "version": __version__,
12
+ "contact": {
13
+ "url": "https://appworld.dev/",
14
+ "name": "Harsh Trivedi",
15
+ "email": "hjtrivedi@cs.stonybrook.edu",
16
+ },
17
+ "license_info": {
18
+ "name": "On Github",
19
+ "url": "https://github.com/stonybrooknlp/appworld",
20
+ },
21
+ }
22
+
23
+
24
+ def update_root(root: str | None) -> str:
25
+ if root:
26
+ path_store.update_root(root)
27
+ else:
28
+ path_store.reload()
29
+ return path_store.root