worldfoundry 0.2.0__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.
- worldfoundry-0.2.0/.github/workflows/release.yml +41 -0
- worldfoundry-0.2.0/.gitignore +14 -0
- worldfoundry-0.2.0/LICENSE +17 -0
- worldfoundry-0.2.0/PKG-INFO +238 -0
- worldfoundry-0.2.0/README.md +219 -0
- worldfoundry-0.2.0/docs/adk.md +24 -0
- worldfoundry-0.2.0/docs/roadmap.md +50 -0
- worldfoundry-0.2.0/docs/sdk-contract.md +81 -0
- worldfoundry-0.2.0/examples/curl_episode.sh +26 -0
- worldfoundry-0.2.0/examples/python_episode.py +29 -0
- worldfoundry-0.2.0/examples/sdk_training.py +20 -0
- worldfoundry-0.2.0/infrastructure/supabase/schema.sql +88 -0
- worldfoundry-0.2.0/infrastructure/supabase/storage_usage.sql +34 -0
- worldfoundry-0.2.0/pyproject.toml +40 -0
- worldfoundry-0.2.0/src/worldfoundry/__init__.py +8 -0
- worldfoundry-0.2.0/src/worldfoundry/__main__.py +3 -0
- worldfoundry-0.2.0/src/worldfoundry/cli.py +94 -0
- worldfoundry-0.2.0/src/worldfoundry/client.py +45 -0
- worldfoundry-0.2.0/src/worldfoundry/cloud.py +143 -0
- worldfoundry-0.2.0/src/worldfoundry/engine.py +142 -0
- worldfoundry-0.2.0/src/worldfoundry/environments.py +165 -0
- worldfoundry-0.2.0/src/worldfoundry/integrations/__init__.py +2 -0
- worldfoundry-0.2.0/src/worldfoundry/integrations/adk.py +25 -0
- worldfoundry-0.2.0/src/worldfoundry/models.py +84 -0
- worldfoundry-0.2.0/src/worldfoundry/platform.py +185 -0
- worldfoundry-0.2.0/src/worldfoundry/server.py +112 -0
- worldfoundry-0.2.0/src/worldfoundry/store.py +66 -0
- worldfoundry-0.2.0/supabase/functions/worldfoundry-api/index.ts +131 -0
- worldfoundry-0.2.0/tests/test_cli.py +19 -0
- worldfoundry-0.2.0/tests/test_engine.py +71 -0
- worldfoundry-0.2.0/tests/test_platform.py +41 -0
- worldfoundry-0.2.0/tests/test_server.py +75 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: WorldFoundry release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
branches:
|
|
8
|
+
- 'release/v*'
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
verify-and-build:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
with:
|
|
16
|
+
persist-credentials: false
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: '3.13'
|
|
20
|
+
- run: python -m pip install '.[dev]' build twine
|
|
21
|
+
- run: python -m pytest
|
|
22
|
+
- run: ruff check src tests examples
|
|
23
|
+
- run: python -m build
|
|
24
|
+
- run: python -m twine check dist/*
|
|
25
|
+
- uses: actions/upload-artifact@v4
|
|
26
|
+
with:
|
|
27
|
+
name: distributions
|
|
28
|
+
path: dist/
|
|
29
|
+
|
|
30
|
+
publish:
|
|
31
|
+
needs: verify-and-build
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
environment: pypi
|
|
34
|
+
permissions:
|
|
35
|
+
id-token: write
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/download-artifact@v4
|
|
38
|
+
with:
|
|
39
|
+
name: distributions
|
|
40
|
+
path: dist/
|
|
41
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
Copyright 2026 WorldFoundry
|
|
6
|
+
|
|
7
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
you may not use this file except in compliance with the License.
|
|
9
|
+
You may obtain a copy of the License at
|
|
10
|
+
|
|
11
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
|
|
13
|
+
Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
See the License for the specific language governing permissions and
|
|
17
|
+
limitations under the License.
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: worldfoundry
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Agent development and training-experience SDK
|
|
5
|
+
Author: WorldFoundry
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: agents,evaluation,simulation,training-environments
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Requires-Python: >=3.11
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
17
|
+
Requires-Dist: ruff>=0.8; extra == 'dev'
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
# WorldFoundry
|
|
21
|
+
|
|
22
|
+
**Training infrastructure for AI agents.**
|
|
23
|
+
|
|
24
|
+
WorldFoundry gives developers programmable environments where agents can practice real-world
|
|
25
|
+
tasks, interact with simulated systems, learn from failures, and improve through repeated
|
|
26
|
+
experiences.
|
|
27
|
+
|
|
28
|
+
Build agents anywhere. Train and test them in WorldFoundry.
|
|
29
|
+
|
|
30
|
+
> **Current status:** this repository builds the `worldfoundry` distribution locally. Check the
|
|
31
|
+
> [PyPI project page](https://pypi.org/project/worldfoundry/) for a published release before
|
|
32
|
+
> using registry install commands. The Homebrew formula is planned and is not published.
|
|
33
|
+
|
|
34
|
+
## What works now
|
|
35
|
+
|
|
36
|
+
- A Python SDK and `worldfoundry` / `wf` command-line interface.
|
|
37
|
+
- Persistent, stateful episodes in a simulated support desk.
|
|
38
|
+
- Declared action schemas and validation before actions mutate state.
|
|
39
|
+
- Deterministic task grading with per-check results and a numeric score.
|
|
40
|
+
- Complete traces for starts, successful actions, failed actions, and submissions.
|
|
41
|
+
- JSONL trace export.
|
|
42
|
+
- A dependency-free REST API usable with `curl`.
|
|
43
|
+
- Framework-neutral callables ready to wrap as Google ADK function tools.
|
|
44
|
+
- Local SDK resource registration and sequential callable-agent batch runs with JSON reports.
|
|
45
|
+
|
|
46
|
+
This is trajectory and evaluation infrastructure. It does **not** perform reinforcement learning,
|
|
47
|
+
fine-tuning, reward-model training, or model-weight updates.
|
|
48
|
+
|
|
49
|
+
The expanded SDK contract and its current limits are in [`docs/sdk-contract.md`](docs/sdk-contract.md).
|
|
50
|
+
The Supabase control-plane schema, private trace storage, and authenticated Edge API are deployed;
|
|
51
|
+
managed Python workers and customer billing are not yet deployed.
|
|
52
|
+
|
|
53
|
+
The cloud usage ledger records client-reported episodes for operational visibility; it is not a
|
|
54
|
+
billing system. Stripe metering, verified managed-compute usage, and payment webhooks are not
|
|
55
|
+
connected to the SDK. Source is published at [AMallur/WorldFoundry](https://github.com/AMallur/WorldFoundry).
|
|
56
|
+
The GitHub release workflow verifies the package before publishing through PyPI Trusted
|
|
57
|
+
Publishing.
|
|
58
|
+
|
|
59
|
+
## Install — verified local
|
|
60
|
+
|
|
61
|
+
From this repository:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
python3.13 -m venv .venv
|
|
65
|
+
source .venv/bin/activate
|
|
66
|
+
python -m pip install -e .
|
|
67
|
+
worldfoundry --version
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
With `uv`, without keeping a virtual environment:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
uvx --python 3.13 --from . worldfoundry --version
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The explicit Python version makes the verification environment reproducible; any supported
|
|
77
|
+
Python 3.11–3.13 interpreter can be used.
|
|
78
|
+
|
|
79
|
+
### Registry installation
|
|
80
|
+
|
|
81
|
+
Use these commands only when a release is visible on the
|
|
82
|
+
[PyPI project page](https://pypi.org/project/worldfoundry/):
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pip install worldfoundry
|
|
86
|
+
uvx worldfoundry
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Homebrew distribution is planned. This command does not work until a formula is published:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# FUTURE: no Homebrew formula has been published
|
|
93
|
+
brew install worldfoundry/tap/worldfoundry
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## One-minute CLI experience
|
|
97
|
+
|
|
98
|
+
Keep state in a project-local folder while experimenting:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
export WORLDFOUNDRY_HOME="$PWD/.wf-data"
|
|
102
|
+
|
|
103
|
+
worldfoundry environments list
|
|
104
|
+
worldfoundry episodes start support-desk --task incident-triage --seed 7
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Copy the returned episode ID, then act inside the same persistent simulation:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
EPISODE_ID=ep_replace_me
|
|
111
|
+
|
|
112
|
+
worldfoundry episodes act "$EPISODE_ID" get_ticket \
|
|
113
|
+
--params '{"ticket_id":"TCK-100"}'
|
|
114
|
+
worldfoundry episodes act "$EPISODE_ID" set_priority \
|
|
115
|
+
--params '{"ticket_id":"TCK-100","priority":"critical"}'
|
|
116
|
+
worldfoundry episodes act "$EPISODE_ID" assign \
|
|
117
|
+
--params '{"ticket_id":"TCK-100","assignee":"on-call"}'
|
|
118
|
+
worldfoundry episodes act "$EPISODE_ID" reply \
|
|
119
|
+
--params '{"ticket_id":"TCK-100","message":"We acknowledge the outage and have opened an incident."}'
|
|
120
|
+
worldfoundry episodes act "$EPISODE_ID" resolve \
|
|
121
|
+
--params '{"ticket_id":"TCK-100"}'
|
|
122
|
+
worldfoundry episodes submit "$EPISODE_ID"
|
|
123
|
+
worldfoundry traces export "$EPISODE_ID" --output trace.jsonl
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Submission is a terminal gate. A submitted episode becomes `passed` or `failed` and rejects later
|
|
127
|
+
actions. Start a fresh episode for another attempt.
|
|
128
|
+
|
|
129
|
+
## Python SDK
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from worldfoundry import WorldFoundry
|
|
133
|
+
|
|
134
|
+
wf = WorldFoundry(".wf-data")
|
|
135
|
+
episode = wf.start("support-desk", task="incident-triage", seed=7)
|
|
136
|
+
|
|
137
|
+
wf.act(episode.id, "set_priority", ticket_id="TCK-100", priority="critical")
|
|
138
|
+
wf.act(episode.id, "assign", ticket_id="TCK-100", assignee="on-call")
|
|
139
|
+
wf.act(
|
|
140
|
+
episode.id,
|
|
141
|
+
"reply",
|
|
142
|
+
ticket_id="TCK-100",
|
|
143
|
+
message="We acknowledge the outage and have opened an incident.",
|
|
144
|
+
)
|
|
145
|
+
wf.act(episode.id, "resolve", ticket_id="TCK-100")
|
|
146
|
+
|
|
147
|
+
result = wf.submit(episode.id)
|
|
148
|
+
print(result.passed, result.score)
|
|
149
|
+
wf.export_trace(episode.id, "trace.jsonl")
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
A complete runnable version is in [`examples/python_episode.py`](examples/python_episode.py).
|
|
153
|
+
|
|
154
|
+
## REST API and `curl`
|
|
155
|
+
|
|
156
|
+
Start the local server:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
WORLDFOUNDRY_HOME="$PWD/.wf-data" worldfoundry serve --port 8787
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
In another terminal:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
curl -s http://127.0.0.1:8787/health
|
|
166
|
+
|
|
167
|
+
curl -s -X POST http://127.0.0.1:8787/v1/episodes \
|
|
168
|
+
-H 'content-type: application/json' \
|
|
169
|
+
-d '{"environment":"support-desk","task":"incident-triage","seed":7}'
|
|
170
|
+
|
|
171
|
+
EPISODE_ID=ep_replace_me
|
|
172
|
+
|
|
173
|
+
curl -s -X POST "http://127.0.0.1:8787/v1/episodes/$EPISODE_ID/actions" \
|
|
174
|
+
-H 'content-type: application/json' \
|
|
175
|
+
-d '{"action":"set_priority","parameters":{"ticket_id":"TCK-100","priority":"critical"}}'
|
|
176
|
+
|
|
177
|
+
curl -s -X POST "http://127.0.0.1:8787/v1/episodes/$EPISODE_ID/submit"
|
|
178
|
+
curl -s "http://127.0.0.1:8787/v1/episodes/$EPISODE_ID/trace" > trace.jsonl
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
See [`examples/curl_episode.sh`](examples/curl_episode.sh) for an end-to-end REST run that extracts
|
|
182
|
+
the episode ID without requiring `jq`.
|
|
183
|
+
|
|
184
|
+
## Environment contract
|
|
185
|
+
|
|
186
|
+
Each environment supplies:
|
|
187
|
+
|
|
188
|
+
1. An initial state generated from a seed.
|
|
189
|
+
2. A task instruction.
|
|
190
|
+
3. Named actions with parameter schemas.
|
|
191
|
+
4. Stateful action handlers that return observations.
|
|
192
|
+
5. Deterministic validators that produce individual checks, a score, and pass/fail.
|
|
193
|
+
|
|
194
|
+
All interfaces use the same engine and local store. State lives in
|
|
195
|
+
`$WORLDFOUNDRY_HOME/episodes` or `~/.worldfoundry/episodes` by default. Set the environment variable
|
|
196
|
+
or pass `WorldFoundry(path)` / `--home PATH` for isolated runs.
|
|
197
|
+
|
|
198
|
+
## Google ADK integration path
|
|
199
|
+
|
|
200
|
+
`worldfoundry.integrations.adk.tools(client, episode_id)` returns two documented Python callables:
|
|
201
|
+
one for environment actions and one for submission. Google ADK can wrap them as function tools
|
|
202
|
+
without making ADK a hard dependency of the core package. See [`docs/adk.md`](docs/adk.md).
|
|
203
|
+
|
|
204
|
+
## Path to hosted SaaS
|
|
205
|
+
|
|
206
|
+
The local contract deliberately maps to a hosted service:
|
|
207
|
+
|
|
208
|
+
| Local MVP | Hosted evolution |
|
|
209
|
+
|---|---|
|
|
210
|
+
| File-backed episode store | Transactional database plus object storage |
|
|
211
|
+
| In-process environment | Isolated worker or sandbox per episode |
|
|
212
|
+
| Local identity | API keys, workspaces, roles, and scoped tokens |
|
|
213
|
+
| Synchronous action | Idempotent action endpoint with call IDs |
|
|
214
|
+
| JSONL file | Queryable traces plus immutable export |
|
|
215
|
+
| One built-in environment | Versioned environment registry and private environments |
|
|
216
|
+
| Deterministic validator | Versioned eval suites, cohorts, and regression dashboards |
|
|
217
|
+
|
|
218
|
+
Before a public service, add idempotency keys, optimistic concurrency, tenant isolation, quotas,
|
|
219
|
+
signed artifacts, structured logs, worker timeouts, and compatibility tests for environment
|
|
220
|
+
versions. See [`docs/roadmap.md`](docs/roadmap.md) for release gates.
|
|
221
|
+
|
|
222
|
+
## Develop and test
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
python3.13 -m venv .venv
|
|
226
|
+
source .venv/bin/activate
|
|
227
|
+
python -m pip install -e '.[dev]'
|
|
228
|
+
python -m pytest
|
|
229
|
+
python -m compileall -q src tests examples
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The test suite covers a passing SDK episode, failed-action trace recording, CLI persistence and
|
|
233
|
+
export, REST behavior, invalid parameters, and terminal submission semantics.
|
|
234
|
+
|
|
235
|
+
## License
|
|
236
|
+
|
|
237
|
+
Apache-2.0. See [`LICENSE`](LICENSE).
|
|
238
|
+
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# WorldFoundry
|
|
2
|
+
|
|
3
|
+
**Training infrastructure for AI agents.**
|
|
4
|
+
|
|
5
|
+
WorldFoundry gives developers programmable environments where agents can practice real-world
|
|
6
|
+
tasks, interact with simulated systems, learn from failures, and improve through repeated
|
|
7
|
+
experiences.
|
|
8
|
+
|
|
9
|
+
Build agents anywhere. Train and test them in WorldFoundry.
|
|
10
|
+
|
|
11
|
+
> **Current status:** this repository builds the `worldfoundry` distribution locally. Check the
|
|
12
|
+
> [PyPI project page](https://pypi.org/project/worldfoundry/) for a published release before
|
|
13
|
+
> using registry install commands. The Homebrew formula is planned and is not published.
|
|
14
|
+
|
|
15
|
+
## What works now
|
|
16
|
+
|
|
17
|
+
- A Python SDK and `worldfoundry` / `wf` command-line interface.
|
|
18
|
+
- Persistent, stateful episodes in a simulated support desk.
|
|
19
|
+
- Declared action schemas and validation before actions mutate state.
|
|
20
|
+
- Deterministic task grading with per-check results and a numeric score.
|
|
21
|
+
- Complete traces for starts, successful actions, failed actions, and submissions.
|
|
22
|
+
- JSONL trace export.
|
|
23
|
+
- A dependency-free REST API usable with `curl`.
|
|
24
|
+
- Framework-neutral callables ready to wrap as Google ADK function tools.
|
|
25
|
+
- Local SDK resource registration and sequential callable-agent batch runs with JSON reports.
|
|
26
|
+
|
|
27
|
+
This is trajectory and evaluation infrastructure. It does **not** perform reinforcement learning,
|
|
28
|
+
fine-tuning, reward-model training, or model-weight updates.
|
|
29
|
+
|
|
30
|
+
The expanded SDK contract and its current limits are in [`docs/sdk-contract.md`](docs/sdk-contract.md).
|
|
31
|
+
The Supabase control-plane schema, private trace storage, and authenticated Edge API are deployed;
|
|
32
|
+
managed Python workers and customer billing are not yet deployed.
|
|
33
|
+
|
|
34
|
+
The cloud usage ledger records client-reported episodes for operational visibility; it is not a
|
|
35
|
+
billing system. Stripe metering, verified managed-compute usage, and payment webhooks are not
|
|
36
|
+
connected to the SDK. Source is published at [AMallur/WorldFoundry](https://github.com/AMallur/WorldFoundry).
|
|
37
|
+
The GitHub release workflow verifies the package before publishing through PyPI Trusted
|
|
38
|
+
Publishing.
|
|
39
|
+
|
|
40
|
+
## Install — verified local
|
|
41
|
+
|
|
42
|
+
From this repository:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
python3.13 -m venv .venv
|
|
46
|
+
source .venv/bin/activate
|
|
47
|
+
python -m pip install -e .
|
|
48
|
+
worldfoundry --version
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
With `uv`, without keeping a virtual environment:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
uvx --python 3.13 --from . worldfoundry --version
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The explicit Python version makes the verification environment reproducible; any supported
|
|
58
|
+
Python 3.11–3.13 interpreter can be used.
|
|
59
|
+
|
|
60
|
+
### Registry installation
|
|
61
|
+
|
|
62
|
+
Use these commands only when a release is visible on the
|
|
63
|
+
[PyPI project page](https://pypi.org/project/worldfoundry/):
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pip install worldfoundry
|
|
67
|
+
uvx worldfoundry
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Homebrew distribution is planned. This command does not work until a formula is published:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# FUTURE: no Homebrew formula has been published
|
|
74
|
+
brew install worldfoundry/tap/worldfoundry
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## One-minute CLI experience
|
|
78
|
+
|
|
79
|
+
Keep state in a project-local folder while experimenting:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
export WORLDFOUNDRY_HOME="$PWD/.wf-data"
|
|
83
|
+
|
|
84
|
+
worldfoundry environments list
|
|
85
|
+
worldfoundry episodes start support-desk --task incident-triage --seed 7
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Copy the returned episode ID, then act inside the same persistent simulation:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
EPISODE_ID=ep_replace_me
|
|
92
|
+
|
|
93
|
+
worldfoundry episodes act "$EPISODE_ID" get_ticket \
|
|
94
|
+
--params '{"ticket_id":"TCK-100"}'
|
|
95
|
+
worldfoundry episodes act "$EPISODE_ID" set_priority \
|
|
96
|
+
--params '{"ticket_id":"TCK-100","priority":"critical"}'
|
|
97
|
+
worldfoundry episodes act "$EPISODE_ID" assign \
|
|
98
|
+
--params '{"ticket_id":"TCK-100","assignee":"on-call"}'
|
|
99
|
+
worldfoundry episodes act "$EPISODE_ID" reply \
|
|
100
|
+
--params '{"ticket_id":"TCK-100","message":"We acknowledge the outage and have opened an incident."}'
|
|
101
|
+
worldfoundry episodes act "$EPISODE_ID" resolve \
|
|
102
|
+
--params '{"ticket_id":"TCK-100"}'
|
|
103
|
+
worldfoundry episodes submit "$EPISODE_ID"
|
|
104
|
+
worldfoundry traces export "$EPISODE_ID" --output trace.jsonl
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Submission is a terminal gate. A submitted episode becomes `passed` or `failed` and rejects later
|
|
108
|
+
actions. Start a fresh episode for another attempt.
|
|
109
|
+
|
|
110
|
+
## Python SDK
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from worldfoundry import WorldFoundry
|
|
114
|
+
|
|
115
|
+
wf = WorldFoundry(".wf-data")
|
|
116
|
+
episode = wf.start("support-desk", task="incident-triage", seed=7)
|
|
117
|
+
|
|
118
|
+
wf.act(episode.id, "set_priority", ticket_id="TCK-100", priority="critical")
|
|
119
|
+
wf.act(episode.id, "assign", ticket_id="TCK-100", assignee="on-call")
|
|
120
|
+
wf.act(
|
|
121
|
+
episode.id,
|
|
122
|
+
"reply",
|
|
123
|
+
ticket_id="TCK-100",
|
|
124
|
+
message="We acknowledge the outage and have opened an incident.",
|
|
125
|
+
)
|
|
126
|
+
wf.act(episode.id, "resolve", ticket_id="TCK-100")
|
|
127
|
+
|
|
128
|
+
result = wf.submit(episode.id)
|
|
129
|
+
print(result.passed, result.score)
|
|
130
|
+
wf.export_trace(episode.id, "trace.jsonl")
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
A complete runnable version is in [`examples/python_episode.py`](examples/python_episode.py).
|
|
134
|
+
|
|
135
|
+
## REST API and `curl`
|
|
136
|
+
|
|
137
|
+
Start the local server:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
WORLDFOUNDRY_HOME="$PWD/.wf-data" worldfoundry serve --port 8787
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
In another terminal:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
curl -s http://127.0.0.1:8787/health
|
|
147
|
+
|
|
148
|
+
curl -s -X POST http://127.0.0.1:8787/v1/episodes \
|
|
149
|
+
-H 'content-type: application/json' \
|
|
150
|
+
-d '{"environment":"support-desk","task":"incident-triage","seed":7}'
|
|
151
|
+
|
|
152
|
+
EPISODE_ID=ep_replace_me
|
|
153
|
+
|
|
154
|
+
curl -s -X POST "http://127.0.0.1:8787/v1/episodes/$EPISODE_ID/actions" \
|
|
155
|
+
-H 'content-type: application/json' \
|
|
156
|
+
-d '{"action":"set_priority","parameters":{"ticket_id":"TCK-100","priority":"critical"}}'
|
|
157
|
+
|
|
158
|
+
curl -s -X POST "http://127.0.0.1:8787/v1/episodes/$EPISODE_ID/submit"
|
|
159
|
+
curl -s "http://127.0.0.1:8787/v1/episodes/$EPISODE_ID/trace" > trace.jsonl
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
See [`examples/curl_episode.sh`](examples/curl_episode.sh) for an end-to-end REST run that extracts
|
|
163
|
+
the episode ID without requiring `jq`.
|
|
164
|
+
|
|
165
|
+
## Environment contract
|
|
166
|
+
|
|
167
|
+
Each environment supplies:
|
|
168
|
+
|
|
169
|
+
1. An initial state generated from a seed.
|
|
170
|
+
2. A task instruction.
|
|
171
|
+
3. Named actions with parameter schemas.
|
|
172
|
+
4. Stateful action handlers that return observations.
|
|
173
|
+
5. Deterministic validators that produce individual checks, a score, and pass/fail.
|
|
174
|
+
|
|
175
|
+
All interfaces use the same engine and local store. State lives in
|
|
176
|
+
`$WORLDFOUNDRY_HOME/episodes` or `~/.worldfoundry/episodes` by default. Set the environment variable
|
|
177
|
+
or pass `WorldFoundry(path)` / `--home PATH` for isolated runs.
|
|
178
|
+
|
|
179
|
+
## Google ADK integration path
|
|
180
|
+
|
|
181
|
+
`worldfoundry.integrations.adk.tools(client, episode_id)` returns two documented Python callables:
|
|
182
|
+
one for environment actions and one for submission. Google ADK can wrap them as function tools
|
|
183
|
+
without making ADK a hard dependency of the core package. See [`docs/adk.md`](docs/adk.md).
|
|
184
|
+
|
|
185
|
+
## Path to hosted SaaS
|
|
186
|
+
|
|
187
|
+
The local contract deliberately maps to a hosted service:
|
|
188
|
+
|
|
189
|
+
| Local MVP | Hosted evolution |
|
|
190
|
+
|---|---|
|
|
191
|
+
| File-backed episode store | Transactional database plus object storage |
|
|
192
|
+
| In-process environment | Isolated worker or sandbox per episode |
|
|
193
|
+
| Local identity | API keys, workspaces, roles, and scoped tokens |
|
|
194
|
+
| Synchronous action | Idempotent action endpoint with call IDs |
|
|
195
|
+
| JSONL file | Queryable traces plus immutable export |
|
|
196
|
+
| One built-in environment | Versioned environment registry and private environments |
|
|
197
|
+
| Deterministic validator | Versioned eval suites, cohorts, and regression dashboards |
|
|
198
|
+
|
|
199
|
+
Before a public service, add idempotency keys, optimistic concurrency, tenant isolation, quotas,
|
|
200
|
+
signed artifacts, structured logs, worker timeouts, and compatibility tests for environment
|
|
201
|
+
versions. See [`docs/roadmap.md`](docs/roadmap.md) for release gates.
|
|
202
|
+
|
|
203
|
+
## Develop and test
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
python3.13 -m venv .venv
|
|
207
|
+
source .venv/bin/activate
|
|
208
|
+
python -m pip install -e '.[dev]'
|
|
209
|
+
python -m pytest
|
|
210
|
+
python -m compileall -q src tests examples
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
The test suite covers a passing SDK episode, failed-action trace recording, CLI persistence and
|
|
214
|
+
export, REST behavior, invalid parameters, and terminal submission semantics.
|
|
215
|
+
|
|
216
|
+
## License
|
|
217
|
+
|
|
218
|
+
Apache-2.0. See [`LICENSE`](LICENSE).
|
|
219
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Google ADK integration
|
|
2
|
+
|
|
3
|
+
The local package exposes framework-neutral Python functions instead of taking a hard dependency
|
|
4
|
+
on Google ADK:
|
|
5
|
+
|
|
6
|
+
```python
|
|
7
|
+
from worldfoundry import WorldFoundry
|
|
8
|
+
from worldfoundry.integrations.adk import tools
|
|
9
|
+
|
|
10
|
+
client = WorldFoundry(".wf-data")
|
|
11
|
+
episode = client.start("support-desk")
|
|
12
|
+
agent_tools = tools(client, episode.id)
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
In an ADK application, pass `agent_tools` to the agent's `tools` argument. The agent can call
|
|
16
|
+
`worldfoundry_action(action, parameters)` repeatedly and then call `worldfoundry_submit()`.
|
|
17
|
+
|
|
18
|
+
The application, not the adapter, controls the model, retry policy, budgets, and loop termination.
|
|
19
|
+
Treat a validation result as an evaluation signal; this adapter does not train or update model
|
|
20
|
+
weights.
|
|
21
|
+
|
|
22
|
+
Before publishing a dedicated `worldfoundry-adk` extra, pin a supported ADK version, add an
|
|
23
|
+
end-to-end example against that version, and test generated function schemas in CI.
|
|
24
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Product and distribution roadmap
|
|
2
|
+
|
|
3
|
+
## Already implemented in this repository
|
|
4
|
+
|
|
5
|
+
- Installable local Python project with SDK and two CLI entry points.
|
|
6
|
+
- Persistent stateful episodes and deterministic validators.
|
|
7
|
+
- JSONL traces and exports.
|
|
8
|
+
- Local HTTP API and end-to-end examples.
|
|
9
|
+
- Framework-neutral Google ADK tool adapter.
|
|
10
|
+
- Automated tests.
|
|
11
|
+
|
|
12
|
+
## Release gates
|
|
13
|
+
|
|
14
|
+
### PyPI and `uvx`
|
|
15
|
+
|
|
16
|
+
1. Confirm and reserve the `worldfoundry` distribution name through the package owner's PyPI account.
|
|
17
|
+
2. Add trusted publishing from tagged releases.
|
|
18
|
+
3. Build wheel and source distribution, inspect their contents, and test each in clean Python
|
|
19
|
+
3.11–3.13 environments.
|
|
20
|
+
4. Publish to TestPyPI, run the documented install flow, then publish to PyPI.
|
|
21
|
+
5. Only after that change the README from future commands to verified public commands.
|
|
22
|
+
|
|
23
|
+
### Homebrew
|
|
24
|
+
|
|
25
|
+
1. Create a tap owned by the company.
|
|
26
|
+
2. Generate a formula from the signed PyPI source artifact and its SHA-256 checksum.
|
|
27
|
+
3. Test on current Intel and Apple Silicon macOS runners.
|
|
28
|
+
4. Add release automation and a rollback procedure.
|
|
29
|
+
|
|
30
|
+
### Hosted SaaS
|
|
31
|
+
|
|
32
|
+
1. Freeze and version the REST contract.
|
|
33
|
+
2. Add workspaces, API keys, tenant authorization, quotas, metering, and audit logs.
|
|
34
|
+
3. Run each episode in a time- and resource-bounded isolated worker.
|
|
35
|
+
4. Require client-generated idempotency keys on action calls and reject conflicting replays.
|
|
36
|
+
5. Store traces immutably and keep mutable query indexes separate.
|
|
37
|
+
6. Add environment bundles with manifests, versioning, signatures, and compatibility checks.
|
|
38
|
+
7. Add hosted SDK transport while keeping the local transport for tests and offline development.
|
|
39
|
+
|
|
40
|
+
### Training and evaluation platform
|
|
41
|
+
|
|
42
|
+
1. Batch episode creation with dataset row identifiers and controlled seeds.
|
|
43
|
+
2. Eval-suite manifests, baselines, regression thresholds, and run comparison.
|
|
44
|
+
3. Human review queues and feedback exports.
|
|
45
|
+
4. Integrations for agent frameworks, CI systems, and experiment trackers.
|
|
46
|
+
|
|
47
|
+
Actual RL, fine-tuning, reward-model training, and weight updates remain separate systems. A future
|
|
48
|
+
WorldFoundry service may export trajectories and scores to those systems without claiming to be
|
|
49
|
+
the optimizer itself.
|
|
50
|
+
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# WorldFoundry SDK contract and deployment boundary
|
|
2
|
+
|
|
3
|
+
## Working locally
|
|
4
|
+
|
|
5
|
+
The `worldfoundry` distribution installs the `worldfoundry` import and CLI. The SDK runs
|
|
6
|
+
on the user's computer and uses a local resource registry plus the existing episode engine.
|
|
7
|
+
|
|
8
|
+
```python
|
|
9
|
+
from worldfoundry import WorldFoundry
|
|
10
|
+
|
|
11
|
+
def agent(task, tools):
|
|
12
|
+
tools.set_priority(ticket_id="TCK-100", priority="critical")
|
|
13
|
+
tools.assign(ticket_id="TCK-100", assignee="on-call")
|
|
14
|
+
tools.reply(ticket_id="TCK-100", message="We acknowledge the outage and opened an incident.")
|
|
15
|
+
tools.resolve(ticket_id="TCK-100")
|
|
16
|
+
tools.submit()
|
|
17
|
+
|
|
18
|
+
wf = WorldFoundry.local(".wf-data")
|
|
19
|
+
env = wf.environments.create(template="customer_support", difficulty="beginner")
|
|
20
|
+
registered = wf.agents.register(name="support", handler=agent)
|
|
21
|
+
run = wf.training.create(agent=registered, environment=env, episodes=10, seed=42)
|
|
22
|
+
print(run.summary, run.report_path)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Local resource managers presently include `projects`, `environments`, `agents`, `scenarios`,
|
|
26
|
+
`datasets`, `policies`, and `feedback`. Generic resource managers persist metadata, but only the
|
|
27
|
+
built-in support desk environment, Python callable agents, and sequential batch execution are
|
|
28
|
+
executable. A local agent registration's callable exists only in its Python process; the metadata
|
|
29
|
+
record is persistent, but the handler must be registered again after restart. `max_steps` is
|
|
30
|
+
enforced. `concurrency=1` is currently required. Advanced difficulty and remote endpoint agents
|
|
31
|
+
are rejected explicitly. `report_path` is a local JSON file; no hosted report URL is fabricated.
|
|
32
|
+
|
|
33
|
+
The lower-level `start`, `act`, `submit`, `export_trace`, REST, and CLI episode APIs remain usable.
|
|
34
|
+
|
|
35
|
+
## Cloud client boundary
|
|
36
|
+
|
|
37
|
+
`WorldFoundry(api_key="SUPABASE_USER_ACCESS_TOKEN", base_url="https://<ref>.supabase.co/functions/v1/worldfoundry-api")` constructs an
|
|
38
|
+
authenticated HTTP client. The token is a signed-in user's Supabase access token, not a project
|
|
39
|
+
publishable key or a service-role key. It sends `/v1/projects`, `/v1/environments`, `/v1/agents`,
|
|
40
|
+
`/v1/scenarios`, `/v1/datasets`, `/v1/training-runs`, and `/v1/episodes` requests. The cloud
|
|
41
|
+
client is a transport contract, not a deployed service. A Supabase database alone cannot execute
|
|
42
|
+
arbitrary Python agents or isolated simulation workers; it needs a WorldFoundry API and runner.
|
|
43
|
+
|
|
44
|
+
The project `bhvffruseefvifjcutzj` has the schema applied and the `worldfoundry-api` Edge Function
|
|
45
|
+
deployed at `https://bhvffruseefvifjcutzj.supabase.co/functions/v1/worldfoundry-api`. The API
|
|
46
|
+
authenticates Supabase user access tokens and performs project-scoped database operations through
|
|
47
|
+
row level security. A publishable key alone is not a user session.
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from worldfoundry.cloud import CloudWorldFoundry
|
|
51
|
+
|
|
52
|
+
wf = CloudWorldFoundry.sign_in(
|
|
53
|
+
project_url="https://bhvffruseefvifjcutzj.supabase.co",
|
|
54
|
+
publishable_key="<the project's publishable key>",
|
|
55
|
+
email="<your signed-up email>",
|
|
56
|
+
password="<your password>",
|
|
57
|
+
)
|
|
58
|
+
project = wf.projects.create(name="My agent lab")
|
|
59
|
+
environment = wf.environments.create(
|
|
60
|
+
project_id=project["id"], name="Support desk", template="support-desk"
|
|
61
|
+
)
|
|
62
|
+
agent = wf.agents.register(
|
|
63
|
+
project_id=project["id"], name="Support agent", framework="python"
|
|
64
|
+
)
|
|
65
|
+
result = wf.training.run_local(
|
|
66
|
+
project_id=project["id"], agent=agent, environment=environment,
|
|
67
|
+
handler=my_agent, episodes=10,
|
|
68
|
+
)
|
|
69
|
+
print(result["summary"])
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`run_local` executes the agent and simulations on the user's computer, then records episode scores
|
|
73
|
+
and private JSONL traces in the Supabase project. It does not offer managed remote execution.
|
|
74
|
+
The cloud API creates run records but has no hosted Python worker attached, so bare
|
|
75
|
+
`wf.training.create(...)` leaves a queued run until a runner processes it. The deployed endpoint
|
|
76
|
+
is live; signed-in end-to-end execution still needs a user account and session for verification.
|
|
77
|
+
|
|
78
|
+
For managed execution, add a durable queue, isolated Python workers, trace artifact storage,
|
|
79
|
+
worker authentication, and report generation. Store provider secrets in a managed secret service;
|
|
80
|
+
never put raw secrets in run traces or resource config.
|
|
81
|
+
|