opal-optimizer 0.3.5__py3-none-any.whl
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.
- opal/__init__.py +7 -0
- opal/_version.py +3 -0
- opal/agent.py +394 -0
- opal/backends/__init__.py +31 -0
- opal/backends/_codex_client.py +450 -0
- opal/backends/_privacy.py +116 -0
- opal/backends/base.py +248 -0
- opal/backends/claude.py +665 -0
- opal/backends/codex.py +356 -0
- opal/backends/mailbox.py +1034 -0
- opal/backends/unavailable.py +161 -0
- opal/cli.py +396 -0
- opal/context.py +111 -0
- opal/defaults.json +11 -0
- opal/defaults.py +54 -0
- opal/estimate.py +120 -0
- opal/hf.py +109 -0
- opal/misc/__init__.py +2 -0
- opal/misc/aggressive.py +157 -0
- opal/misc/audit.py +84 -0
- opal/misc/boundary.py +226 -0
- opal/misc/checkpoint.py +399 -0
- opal/misc/ddp.py +147 -0
- opal/misc/integrity.py +263 -0
- opal/misc/nested.py +67 -0
- opal/misc/neutral_analysis.py +166 -0
- opal/misc/precision.py +210 -0
- opal/misc/recovery.py +231 -0
- opal/misc/schedulers.py +214 -0
- opal/misc/setup.py +253 -0
- opal/misc/skip.py +165 -0
- opal/misc/taskfacts.py +293 -0
- opal/misc/waiting.py +58 -0
- opal/programs.py +482 -0
- opal/prompts/example_updater.py +252 -0
- opal/prompts/neutral.md +206 -0
- opal/report.py +1001 -0
- opal/report_page.py +175 -0
- opal/report_privacy.py +159 -0
- opal/results.py +80 -0
- opal/schedule.py +134 -0
- opal/summaries.py +224 -0
- opal/wrapper.py +1674 -0
- opal_optimizer-0.3.5.dist-info/METADATA +232 -0
- opal_optimizer-0.3.5.dist-info/RECORD +49 -0
- opal_optimizer-0.3.5.dist-info/WHEEL +5 -0
- opal_optimizer-0.3.5.dist-info/entry_points.txt +2 -0
- opal_optimizer-0.3.5.dist-info/licenses/LICENSE +21 -0
- opal_optimizer-0.3.5.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: opal-optimizer
|
|
3
|
+
Version: 0.3.5
|
|
4
|
+
Summary: A coding agent inside your training run, rewriting the optimizer while it trains
|
|
5
|
+
Author: Xingjian Bai, Jia-Hao Liang, Jayden Teoh, Vincent Sitzmann
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: torch>=2.5; python_version < "3.13"
|
|
11
|
+
Requires-Dist: torch>=2.6; python_version >= "3.13"
|
|
12
|
+
Requires-Dist: numpy>=1.26.4
|
|
13
|
+
Provides-Extra: examples
|
|
14
|
+
Requires-Dist: torchvision>=0.20; python_version < "3.13" and extra == "examples"
|
|
15
|
+
Requires-Dist: torchvision>=0.21; python_version >= "3.13" and extra == "examples"
|
|
16
|
+
Requires-Dist: numpy>=1.26.4; extra == "examples"
|
|
17
|
+
Requires-Dist: pyarrow>=15.0; extra == "examples"
|
|
18
|
+
Requires-Dist: pillow>=10.2; extra == "examples"
|
|
19
|
+
Provides-Extra: test
|
|
20
|
+
Requires-Dist: pytest>=8.2; extra == "test"
|
|
21
|
+
Provides-Extra: hf
|
|
22
|
+
Requires-Dist: transformers>=4.57.1; extra == "hf"
|
|
23
|
+
Requires-Dist: accelerate>=1.4.0; extra == "hf"
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
<h1 align="center">OPAL: a reactive optimizer</h1>
|
|
28
|
+
|
|
29
|
+
<p align="center"><b>A PyTorch optimizer wrapper that lets a coding agent change the optimizer while your model trains.</b></p>
|
|
30
|
+
|
|
31
|
+
<p align="center">
|
|
32
|
+
<a href="https://xingjianbai.com/reactive-optimizers/">Blog post</a> ·
|
|
33
|
+
<a href="docs/GUIDE.md">Guide</a> ·
|
|
34
|
+
<a href="#start-with-your-coding-agent">Start with your agent</a> ·
|
|
35
|
+
<a href="examples/README.md">Examples</a>
|
|
36
|
+
</p>
|
|
37
|
+
|
|
38
|
+
Most networks are trained with an optimizer that is fixed before training starts. OPAL (OPtimizer with an Agent in
|
|
39
|
+
the Loop) turns the optimizer into a program that an agent keeps rewriting during the run. You wrap your PyTorch
|
|
40
|
+
optimizer in one line. Every so often the agent (Claude Code) reads what the run reports and decides whether to
|
|
41
|
+
rewrite two small programs: the optimizer program, which turns gradients into updates at every step, and an analysis
|
|
42
|
+
program, which measures whatever the agent wants to look at.
|
|
43
|
+
|
|
44
|
+
The agent can change anything that can be written as optimizer code: the update rule of each parameter group, the
|
|
45
|
+
learning rates and their schedules, momentum and β₂, preconditioning, clipping, guards against loss spikes. It is
|
|
46
|
+
asked not to touch your model, data, loss, batch size, number of steps or evaluation. Its programs run inside your
|
|
47
|
+
training process, so this is a rule, not a sandbox (see [Safety](docs/GUIDE.md#safety)). Until the agent changes
|
|
48
|
+
something, the wrapped run is bit-for-bit the same as the plain one.
|
|
49
|
+
|
|
50
|
+
## Start with your coding agent
|
|
51
|
+
|
|
52
|
+
Clone this repository, open your own project in a coding agent (Claude Code, Codex, Cursor or similar) and paste this
|
|
53
|
+
prompt. The agent installs OPAL, wires it into your training script, asks you what it cannot know, and checks that
|
|
54
|
+
nothing changed before anything costs money.
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
I want to train my model with OPAL, a reactive optimizer: a coding agent that rewrites the optimizer while the
|
|
58
|
+
model trains. OPAL is cloned at <PATH TO OPAL>. Please set it up for this project:
|
|
59
|
+
|
|
60
|
+
1. Read <PATH TO OPAL>/README.md and <PATH TO OPAL>/skills/train-with-agent/SKILL.md, and follow the skill. Do not
|
|
61
|
+
edit any file inside <PATH TO OPAL>; configure everything through opal.wrap arguments.
|
|
62
|
+
2. Install OPAL into the Python environment this project trains with (pip install -e <PATH TO OPAL>), and
|
|
63
|
+
run `opal doctor` (free, offline) to check that torch and Claude Code are ready on the machine that will run
|
|
64
|
+
training; run `opal doctor --live` (one tiny paid agent call) only once I approve an agent run. If Claude Code is
|
|
65
|
+
missing or not logged in there, tell me what to run; do not log in for me.
|
|
66
|
+
3. Find my training script and loop. Tell me what you found (optimizer, scheduler, number of steps, single GPU or
|
|
67
|
+
DDP, gradient clipping, mixed precision, checkpoints) and anything OPAL does not support.
|
|
68
|
+
4. Ask me for the goal sentence: what the run trains and what it is judged by at the end. Do not invent the metric.
|
|
69
|
+
5. Wrap the optimizer and show me the diff before running anything.
|
|
70
|
+
6. Smoke test: about 100 steps unwrapped and 100 steps wrapped with backend="keep" (no agent, no cost); the losses
|
|
71
|
+
must match step for step. Show me both. If I only asked for a dry run, stop here.
|
|
72
|
+
7. Before the real run, time an update in the smoke test and run `opal estimate --total-steps N --sec-per-step S`;
|
|
73
|
+
show me what it prints (how long training will wait for the agent, also as a multiple of the run's own time, and
|
|
74
|
+
the cost). Ask me for a cost cap (max_cost_usd) and how many times the agent should decide, and wait for my
|
|
75
|
+
go-ahead; then give me the exact command to launch it, and how to follow it (opal show, opal report).
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Start by hand
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install opal-optimizer # or: git clone, then pip install -e ".[examples]"
|
|
82
|
+
opal doctor # torch and Claude Code ready?
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The package is called `opal-optimizer` on PyPI, because `opal` there is an unrelated web framework. Both install as `import opal`, so do not install both.
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
import torch, opal
|
|
89
|
+
|
|
90
|
+
opt = torch.optim.AdamW(model.parameters(), lr=3e-4) # your optimizer, unchanged
|
|
91
|
+
sched = torch.optim.lr_scheduler.CosineAnnealingLR(opt, T_max=steps) # your scheduler, unchanged
|
|
92
|
+
opt = opal.wrap(opt, model, scheduler=sched, total_steps=steps,
|
|
93
|
+
goal="ResNet-18 on CIFAR-10; judged by test accuracy after the last update",
|
|
94
|
+
backend="keep") # a dry run: no agent, no cost. For the agent run, use max_cost_usd=20 instead.
|
|
95
|
+
|
|
96
|
+
for step in range(steps):
|
|
97
|
+
loss = criterion(model(x), y)
|
|
98
|
+
loss.backward()
|
|
99
|
+
opt.step(loss=loss) # pass the loss so the agent sees it
|
|
100
|
+
opt.zero_grad()
|
|
101
|
+
sched.step()
|
|
102
|
+
if step % 500 == 0:
|
|
103
|
+
opt.log(test_acc=evaluate(model)) # recorded for you, not shown to the agent
|
|
104
|
+
opt.close()
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`goal` is one sentence: what you train and how it is judged. Then:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
python train.py # backend="keep": must match the plain run exactly
|
|
111
|
+
opal doctor --live # one tiny agent call to check the setup
|
|
112
|
+
opal estimate --total-steps 10000 --sec-per-step 0.05 # waiting time and cost, before you launch
|
|
113
|
+
python train.py # with max_cost_usd=20: the agent rewrites the optimizer
|
|
114
|
+
opal show opal_runs/<folder> # one line per decision
|
|
115
|
+
opal report opal_runs/<folder> # one HTML page: loss, learning rates, rationales, code diffs
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The guide shows how to check the keep run against your plain run byte for byte, and how to use the Hugging Face
|
|
119
|
+
Trainer: [Try it without an agent](docs/GUIDE.md#try-it-without-an-agent).
|
|
120
|
+
|
|
121
|
+
## Prerequisites
|
|
122
|
+
|
|
123
|
+
- **A PyTorch training script** that uses `torch.optim` optimizers, on CPU, one GPU or several GPUs of one node (DDP).
|
|
124
|
+
Python 3.10 or newer, PyTorch 2.5 or newer (2.6 on Python 3.13).
|
|
125
|
+
- **For an agent run, Claude Code, logged in on the machine that runs rank 0.** Install
|
|
126
|
+
[Claude Code](https://docs.claude.com/en/docs/claude-code), run `claude` once and log in with a Claude subscription
|
|
127
|
+
or an API key. The agent's usage is billed to that account. `max_cost_usd` caps it; there is no cap by default.
|
|
128
|
+
The short summaries of code changes in the report are not counted (`summarize=False` turns them off). A dry run
|
|
129
|
+
with `backend="keep"` needs neither and makes no model calls.
|
|
130
|
+
- **No internet or no login on the GPU machine?** Run the agent on your laptop or a login node and connect it to the
|
|
131
|
+
training job through a shared folder (see [the mailbox broker](docs/GUIDE.md#gpu-machines-without-an-agent)).
|
|
132
|
+
|
|
133
|
+
## Results
|
|
134
|
+
|
|
135
|
+
Each number is one run, and each agent started from the task's own recipe:
|
|
136
|
+
|
|
137
|
+
| Example | Measure | Official recipe | Reactive optimizer |
|
|
138
|
+
|---|---|---|---|
|
|
139
|
+
| SiT-B/2, ImageNet 256, 400K updates | FID-50K ↓ | 35.7 (our evaluator) | 23.6 |
|
|
140
|
+
| RAEv2-B, ImageNet 256, 20 epochs | FID-50K ↓ | 3.39 | 3.10 (prompt asked for efficiency), 3.46 (neutral prompt); rerun on OPAL 0.3: 3.19 |
|
|
141
|
+
| Goldfish 125M GPT, Swahili | FLORES-200 bits ↓ | 79.37 | 77.60; rerun on OPAL 0.3: 77.25 |
|
|
142
|
+
| modded-nanogpt record #36 | validation loss ↓ | 3.2781 | 3.2749 |
|
|
143
|
+
| LightningDiT-B/1, ImageNet 256, 160 epochs | FID-50K ↓ (with guidance) | 3.22 | rerun on OPAL 0.3: 2.31 |
|
|
144
|
+
|
|
145
|
+
It does not always help: a run of modded-nanogpt on OPAL 0.2.0 ended at 3.2878, worse than record #36. Your
|
|
146
|
+
numbers may also differ from ours, because the agent can choose differently from one run to the next. The
|
|
147
|
+
[examples page](examples/README.md) has every number with its version, hardware, time and cost, the small CPU and
|
|
148
|
+
one-GPU scripts, and how to rerun each setting.
|
|
149
|
+
|
|
150
|
+
Our run records and final weights are on Hugging Face: [snow-leopard/opal-results](https://huggingface.co/datasets/snow-leopard/opal-results).
|
|
151
|
+
|
|
152
|
+
## How it works
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
training script ──grads──▶ updater.py ──▶ parameters (every step, every rank)
|
|
156
|
+
│ ▲
|
|
157
|
+
└──observations──▶ analysis.py ──reports──▶ agent (rank 0, every `every` steps / at decisions)
|
|
158
|
+
▲ │
|
|
159
|
+
└──── new programs ◀───┘ (at decision points)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
- **Two programs.** `updater.py` starts as a call to your own optimizer and scheduler. `analysis.py` starts with a few
|
|
163
|
+
statistics of the loss and the gradients. The agent edits both in `opal_runs/<folder>/workspace/`.
|
|
164
|
+
- **One conversation for the whole run.** The agent remembers what it tried, what it predicted and what happened. Each
|
|
165
|
+
decision ends with a short rationale: what it saw, what it changed and what it expects.
|
|
166
|
+
- **Safe swaps.** A new optimizer program takes over at the next step, on every GPU at once, and runs on trial for 20
|
|
167
|
+
steps. If it raises an error, the run goes back to the previous program. A failure at its first step is undone
|
|
168
|
+
exactly when a copy of the parameters and optimizer state fits in `snapshot_limit_gb` (default 2); a later failure
|
|
169
|
+
is not undone, and the agent is told. Every version is kept in `programs/`.
|
|
170
|
+
- **Training waits for the agent by default.** With `blocking=False` training keeps going while the agent thinks, and
|
|
171
|
+
`"auto"` waits only when an edit would land too late. Both are faster, and noisier.
|
|
172
|
+
- **What the agent sees.** Your goal sentence, the names and shapes of the parameters, the training losses, its own
|
|
173
|
+
analysis reports, and read-only copies of your training script and model code (`share_code=False` keeps them out).
|
|
174
|
+
Values you log are only recorded, unless you pass `show_agent=True`. With `validation=N` it also sees the
|
|
175
|
+
development-set values you report with `opt.report_dev(...)`.
|
|
176
|
+
|
|
177
|
+
## Options
|
|
178
|
+
|
|
179
|
+
| Option | Default | Meaning |
|
|
180
|
+
|---|---|---|
|
|
181
|
+
| `decisions` | see right | How many times the agent is asked. Each time it may also keep everything as it is. If you do not set it, a run that waits for the agent asks at most as many times as keep the waiting under 4× the run's own training time (`opal estimate` shows the number), and at most 50. If you set it, that cap is off. A fifth of the decisions fall in the first 5% of the run; `schedule="uniform"` spaces them evenly. More in the [guide](docs/GUIDE.md#cost-and-limits). |
|
|
182
|
+
| `every` | 50 | Steps between checks: losses are read, a non-finite loss is caught, the analysis program runs. |
|
|
183
|
+
| `blocking` | `True` | `False` or `"auto"` to keep training while the agent thinks. |
|
|
184
|
+
| `max_cost_usd` | none | Stop asking the agent once it has spent this much. |
|
|
185
|
+
| `backend_options` | `{}` | `model=` (default `claude-opus-5-5`), `effort=` (default `high`) and `timeout=`. A failed agent turn is retried with growing pauses; an agent that is unavailable (login, usage limit, outage) is waited for, with no deadline unless you set `unavailable_timeout=`. Details in the [guide](docs/GUIDE.md#cost-and-limits). |
|
|
186
|
+
| `prompt` | `"neutral"` | The agent's instructions: the facts of the run and the protocol, with no recommended values. `"aggressive"` adds a review of every group's hyperparameters at each decision. You can also pass the path of your own template. |
|
|
187
|
+
| `validation` | none | `N`: your script evaluates a held-out development set about every N updates, at times it does not announce, and reports it with `opt.report_dev(loss=..., accuracy=...)`. The agent sees each result. See the [guide](docs/GUIDE.md#what-it-can-and-cannot-change). |
|
|
188
|
+
| `eval_integrity` | on with `validation` | Flags a run whose program moves the parameters somewhere else for an evaluation and back afterwards. The agent is not told. |
|
|
189
|
+
|
|
190
|
+
Gradient accumulation, GradScaler, checkpoints and resume, DDP, GPU machines without internet, privacy and cost are
|
|
191
|
+
covered in the [guide](docs/GUIDE.md).
|
|
192
|
+
|
|
193
|
+
### Experimental Codex backend
|
|
194
|
+
|
|
195
|
+
Claude is the default. To use Codex, pass `backend="codex", backend_options=dict(model="gpt-6.1-sol", effort="high")`
|
|
196
|
+
(`xhigh` works too), or run `opal broker <box> --backend codex --model gpt-6.1-sol --effort high`. Log in separately
|
|
197
|
+
with `CODEX_HOME=~/.codex-opal codex login --device-auth`, and do not copy or link the `auth.json` of your default
|
|
198
|
+
Codex home. `max_cost_usd` does not cap Codex; `backend_options=dict(max_tokens=N)` is a soft token cap that a turn
|
|
199
|
+
in progress can exceed. The run stops with an error if Codex compacts the conversation (around 450k tokens of context
|
|
200
|
+
with Codex CLI 0.160.1).
|
|
201
|
+
|
|
202
|
+
## Tests
|
|
203
|
+
|
|
204
|
+
The whole test suite runs on CPU with no agent and no cost: `pip install -e ".[examples,test,hf]"`, then `pytest -q`. It
|
|
205
|
+
takes a few minutes on a laptop. Three tests are skipped unless you set `OPAL_REAL_CLI=1`; they start the real Claude
|
|
206
|
+
Code CLI against a local mock.
|
|
207
|
+
|
|
208
|
+
## Status and limitations
|
|
209
|
+
|
|
210
|
+
v0.3.5, under active development. Tested on one GPU and on DDP within one node (NCCL, eager and `torch.compile`).
|
|
211
|
+
Multi-node, FSDP and DeepSpeed are not supported. Accelerate works if you wrap after `accelerator.prepare`, without
|
|
212
|
+
fp16 GradScaler or Accelerate's gradient accumulation; the HF Trainer works through `opal.hf.OpalTrainer`. Both are
|
|
213
|
+
tested on CPU. Lightning should work through `opt.observe(loss)` but we have not tried it. The agent can make a run
|
|
214
|
+
worse: it cannot restart or roll back training, it can only fix its programs at the next decision.
|
|
215
|
+
|
|
216
|
+
## Citation
|
|
217
|
+
|
|
218
|
+
```bibtex
|
|
219
|
+
@misc{bai2026reactive,
|
|
220
|
+
title = {Reactive Optimizers},
|
|
221
|
+
author = {Bai, Xingjian and Liang, Jia-Hao and Teoh, Jayden and Sitzmann, Vincent},
|
|
222
|
+
year = {2026},
|
|
223
|
+
month = {oct},
|
|
224
|
+
note = {Blog post}
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## License
|
|
229
|
+
|
|
230
|
+
MIT, see [LICENSE](LICENSE).
|
|
231
|
+
|
|
232
|
+
*The name:* OPAL stands for OPtimizer with an Agent in the Loop.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
opal/__init__.py,sha256=fwHloDGWVKPtQ64W-hNliJrFQgFxXDZx9mj6EML4O2g,297
|
|
2
|
+
opal/_version.py,sha256=8Qwfz1FuIj88JNxZ-1enGh-BP7MM4PujBXwWr2XCsZk,97
|
|
3
|
+
opal/agent.py,sha256=iFFIiv0UJKjXgQ2548A_ikS7DNpsOF4e95h36rLK0zs,17984
|
|
4
|
+
opal/cli.py,sha256=gMncbxbm9qgR-PTxNX--STgD_2rKawPSp33Vsbqap_4,17153
|
|
5
|
+
opal/context.py,sha256=jJCzYx8W7bBm58tMumdEABH53XTxDYHr8hyhmrmTJQg,4279
|
|
6
|
+
opal/defaults.json,sha256=WZaO-nIw2lyWC69BeaN6yNLQlcOgzAj74PorA6eSvMg,805
|
|
7
|
+
opal/defaults.py,sha256=zTdxXjQxQY26h3UNAY50vtVI7JZ2Oq7_WX3zgPegPcA,2410
|
|
8
|
+
opal/estimate.py,sha256=5kORTiCmMhbRdrB2H-oXsikq-Mr7XaAgcEIMtfueLX0,6012
|
|
9
|
+
opal/hf.py,sha256=TK1E6By7XBeBNWnKLoP0cpPONrcGCyY14smfXvfBbdk,6210
|
|
10
|
+
opal/programs.py,sha256=mWOpestJ5IrqdugqY1ML6mpkvCyrI0R1pLlwmEZ34TA,19293
|
|
11
|
+
opal/report.py,sha256=WfFtfsXG9auy-p3nJRIhHR0n7xMpahM8z570S7ieek4,44899
|
|
12
|
+
opal/report_page.py,sha256=XVuELfYe_u3hY7LK3Oql7W3jyFw_imziKq_8gVWi9KQ,11067
|
|
13
|
+
opal/report_privacy.py,sha256=qH7o5FTel6ErAiVDy6e8sKUXKT8nS7jS9OfPTLX7DhU,6689
|
|
14
|
+
opal/results.py,sha256=DTGdk-jTWPr6PnXo3UnN57N0H8f7JvTD7iTqplx1ojM,3473
|
|
15
|
+
opal/schedule.py,sha256=mjNKrY-CIREowPsW7bIS2u-zfHkKiwD21k2vGWCGXzM,6625
|
|
16
|
+
opal/summaries.py,sha256=XGBkRL6009E9srxeEkBMJ90K-BljlyKuo0aMt6TccAo,10585
|
|
17
|
+
opal/wrapper.py,sha256=ja17mnYbPNENm2ISHn3zw-qZrEkohJ75PaqWkStpuNo,90503
|
|
18
|
+
opal/backends/__init__.py,sha256=rp3S8_ciBCKD6RzAMP3m0cl_dssR1L_B_NoZgnbViB0,1095
|
|
19
|
+
opal/backends/_codex_client.py,sha256=O-Pt8X7oz7hnOHnrRXJixXEBsVKonVGLdYza-fsgSl0,20089
|
|
20
|
+
opal/backends/_privacy.py,sha256=k7vdAVBNYYsFZAgZNrNNYF04XFo3J0mS62BNjO9tenA,5216
|
|
21
|
+
opal/backends/base.py,sha256=lJE8WcgfBqaUjxHhORH6Js8uLtDzlwJBz7b93zBAoUo,8824
|
|
22
|
+
opal/backends/claude.py,sha256=_Pnr8NhSCs18nqroLaNzT8CZ7f5Z6ZVsVZWH7hEFpSo,33604
|
|
23
|
+
opal/backends/codex.py,sha256=uSoW639ehxGvBOAixdFuEEZDrc67Mg2B1fN7gKZ6Sww,15370
|
|
24
|
+
opal/backends/mailbox.py,sha256=ndcdtA8AY1Im9LsDtVu1bCXAei1yyL114inExE22WnM,49165
|
|
25
|
+
opal/backends/unavailable.py,sha256=ObkhosUK6XqdY9sH-B2wglaHTCvpNG9_6qq_2yQhp8o,7878
|
|
26
|
+
opal/misc/__init__.py,sha256=BO6pbwOohIwjJR7HgxhoPUH2641PW_ior3R2-56000g,199
|
|
27
|
+
opal/misc/aggressive.py,sha256=91Jp63e6U087sNDYVsELqVKXqzz5xlqIL1HVqqo9YzI,9046
|
|
28
|
+
opal/misc/audit.py,sha256=SOT2pAXu2RNeYHU2gt9fplP8Dg-3KZ_IRuMx2mseplo,2755
|
|
29
|
+
opal/misc/boundary.py,sha256=ImBpX383F83e7Wg96sU45we193q5exBHoqGBu8nJL8I,7409
|
|
30
|
+
opal/misc/checkpoint.py,sha256=bNhdUxlCu_yXcX0GXM8GPoOOMdi3km3ftWltLhiuWZM,21401
|
|
31
|
+
opal/misc/ddp.py,sha256=UUgVHW2RNjF-iK_87HXjXOhTfXR20BiwkpHJD2-vqRU,6497
|
|
32
|
+
opal/misc/integrity.py,sha256=FVYYsPyDsIl7tipNQA09a5sNewEb0dFtw6QWjy6hJeY,13221
|
|
33
|
+
opal/misc/nested.py,sha256=tvyP9xBc385pd22wgpR2psi9piP8z5a8XOMXdAczDrY,2477
|
|
34
|
+
opal/misc/neutral_analysis.py,sha256=HKo3IN1CTDTW0wdlUfbG8kiC5eZyQmbPT6yEuHDbLNI,7861
|
|
35
|
+
opal/misc/precision.py,sha256=r0y6ZV5Ap7gvgU5xQdw4pKhpbSPnfNFDsTdx4tEuuXY,9992
|
|
36
|
+
opal/misc/recovery.py,sha256=PfFfKiwXRE5VFi10RDTUixNVPAg797dhxsBfWUievCU,12393
|
|
37
|
+
opal/misc/schedulers.py,sha256=n6Lbv_JPOdQyQpulshQxrtlC1H_P7PyvTgAjXzx7TgM,9853
|
|
38
|
+
opal/misc/setup.py,sha256=5S5PORtAvhnFbHar5tseBdu-SU28DT4kmkfhIg7lcMY,15506
|
|
39
|
+
opal/misc/skip.py,sha256=wkZ0CVkDSHbfhsW6bPJThpBNcYKaDlzUVEpYv3ttEqc,6593
|
|
40
|
+
opal/misc/taskfacts.py,sha256=nuUUjMfkQb7moI8B5J4HwPuNxn5ChD4YE_hGxQ_NFdw,12651
|
|
41
|
+
opal/misc/waiting.py,sha256=-C_wLC8LIPijgaFoaUkYEmJpcjV5lyjIVJlfYNAm84o,3079
|
|
42
|
+
opal/prompts/example_updater.py,sha256=51SPk1zoCMYlv9zu4yQXNXHDziJy6rZuSQqHOU2lkR8,12107
|
|
43
|
+
opal/prompts/neutral.md,sha256=h-e4N1as_8h8JeWyT64ysgPDwc350kUrZxbBz5Q-5X0,17744
|
|
44
|
+
opal_optimizer-0.3.5.dist-info/licenses/LICENSE,sha256=YukePKpIrgoeT10BATufIWmV1-QgiGy80jB2JF4coy4,1115
|
|
45
|
+
opal_optimizer-0.3.5.dist-info/METADATA,sha256=z41NANUJpnMYKGu9rR9FFAObsmYgMoqO4eodmlmTfBk,14607
|
|
46
|
+
opal_optimizer-0.3.5.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
47
|
+
opal_optimizer-0.3.5.dist-info/entry_points.txt,sha256=W4EYjFfKDoPezm-qdUmyBXvjE4UbwRF7S0zKDFH6cHI,39
|
|
48
|
+
opal_optimizer-0.3.5.dist-info/top_level.txt,sha256=HHQcsTW1cvYDMLPnfLdize_94TGmOwiMhMzu0ovk0nI,5
|
|
49
|
+
opal_optimizer-0.3.5.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Xingjian Bai, Jia-Hao Liang, Jayden Teoh, Vincent Sitzmann
|
|
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.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
opal
|