outerloop-science 0.1.0.dev2__py3-none-any.whl → 0.1.0.dev4__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.
- outerloop/__init__.py +2 -2
- outerloop/appauth.py +17 -0
- outerloop/attempt.py +376 -101
- outerloop/brief.py +38 -25
- outerloop/cli.py +104 -6
- outerloop/climbboard.py +67 -22
- outerloop/compute.py +148 -53
- outerloop/contract.py +8 -0
- outerloop/dispatch.py +63 -18
- outerloop/evalcache.py +147 -0
- outerloop/followup.py +40 -25
- outerloop/github.py +67 -22
- outerloop/harness.py +22 -47
- outerloop/housekeeping.py +1 -17
- outerloop/image.py +0 -4
- outerloop/init.py +45 -2
- outerloop/intake.py +4 -7
- outerloop/launchlog.py +239 -0
- outerloop/maintain.py +353 -0
- outerloop/maintain_agent_cli.py +81 -0
- outerloop/maintain_post_cli.py +140 -0
- outerloop/measure.py +6 -0
- outerloop/orchestrator.py +141 -31
- outerloop/panel.py +3 -3
- outerloop/review.py +4 -0
- outerloop/review_agent.py +7 -7
- outerloop/review_agent_cli.py +2 -2
- outerloop/review_post_cli.py +2 -2
- outerloop/review_summarize_cli.py +8 -6
- outerloop/roles.py +27 -0
- outerloop/rolespec.py +3 -1
- outerloop/steward.py +7 -14
- outerloop/syscall.py +261 -47
- outerloop/syscall_cli.py +243 -12
- outerloop/tick.py +274 -313
- outerloop/verify_agent.py +8 -6
- outerloop/verify_post_cli.py +2 -2
- outerloop/watcher.py +203 -0
- {outerloop_science-0.1.0.dev2.dist-info → outerloop_science-0.1.0.dev4.dist-info}/METADATA +4 -1
- outerloop_science-0.1.0.dev4.dist-info/RECORD +59 -0
- outerloop_science-0.1.0.dev2.dist-info/RECORD +0 -53
- {outerloop_science-0.1.0.dev2.dist-info → outerloop_science-0.1.0.dev4.dist-info}/WHEEL +0 -0
- {outerloop_science-0.1.0.dev2.dist-info → outerloop_science-0.1.0.dev4.dist-info}/entry_points.txt +0 -0
- {outerloop_science-0.1.0.dev2.dist-info → outerloop_science-0.1.0.dev4.dist-info}/licenses/LICENSE +0 -0
- {outerloop_science-0.1.0.dev2.dist-info → outerloop_science-0.1.0.dev4.dist-info}/licenses/NOTICE +0 -0
outerloop/verify_agent.py
CHANGED
|
@@ -20,7 +20,7 @@ from outerloop.contract import find_contract
|
|
|
20
20
|
from outerloop.github import GitHubClient
|
|
21
21
|
from outerloop.harness import Harness, backend_id, budget_exhausted, outage
|
|
22
22
|
from outerloop.posting import EXPECTED_FAILURES, post_round, post_skip_stub
|
|
23
|
-
from outerloop.review_agent import
|
|
23
|
+
from outerloop.review_agent import emit_envelope, pull_request
|
|
24
24
|
from outerloop.role_runner import run_role
|
|
25
25
|
from outerloop.roles import verifier_spec, verify_result_from_role
|
|
26
26
|
from outerloop.rolespec import RoleSpec
|
|
@@ -81,19 +81,21 @@ def run_agent_verify(
|
|
|
81
81
|
# `detail` is already api-key-redacted by the harness (it owns its own
|
|
82
82
|
# secret), so no secret is passed here.
|
|
83
83
|
if emit_path is not None:
|
|
84
|
-
|
|
84
|
+
emit_envelope(
|
|
85
|
+
emit_path, repo, number, kind="skip-stub", detail=detail, reviewed_by=reviewed_by
|
|
86
|
+
)
|
|
85
87
|
else:
|
|
86
88
|
post_skip_stub(client, repo, number, "verification", RuntimeError(detail))
|
|
87
89
|
|
|
88
90
|
try:
|
|
89
|
-
pr, pr_data =
|
|
91
|
+
pr, pr_data = pull_request(client, repo, number)
|
|
90
92
|
skip = verify_skip_reason(pr, bot_login)
|
|
91
93
|
if skip is not None:
|
|
92
94
|
log.info("skipping verification of %s#%s: %s", repo, number, skip)
|
|
93
95
|
# a clean skip still leaves an envelope so the post job can REQUIRE
|
|
94
96
|
# an artifact — a missing one then always means a broken session
|
|
95
97
|
if emit_path is not None:
|
|
96
|
-
|
|
98
|
+
emit_envelope(emit_path, repo, number, kind="skip-clean", detail=skip)
|
|
97
99
|
return None
|
|
98
100
|
|
|
99
101
|
contract_text = _base_contract(client, repo, pr_data)
|
|
@@ -122,11 +124,11 @@ def run_agent_verify(
|
|
|
122
124
|
elif emit_path is not None:
|
|
123
125
|
# nothing worth posting, but the post job still needs an
|
|
124
126
|
# artifact so a MISSING one always means a broken session
|
|
125
|
-
|
|
127
|
+
emit_envelope(emit_path, repo, number, kind="skip-clean", detail=detail)
|
|
126
128
|
return None
|
|
127
129
|
|
|
128
130
|
if emit_path is not None:
|
|
129
|
-
|
|
131
|
+
emit_envelope(
|
|
130
132
|
emit_path,
|
|
131
133
|
repo,
|
|
132
134
|
number,
|
outerloop/verify_post_cli.py
CHANGED
|
@@ -20,7 +20,7 @@ from pathlib import Path
|
|
|
20
20
|
|
|
21
21
|
from outerloop.github import EnvTokenProvider, GitHubClient
|
|
22
22
|
from outerloop.posting import EXPECTED_FAILURES, post_round, post_skip_stub
|
|
23
|
-
from outerloop.review_agent import
|
|
23
|
+
from outerloop.review_agent import pull_request
|
|
24
24
|
from outerloop.verifier import (
|
|
25
25
|
VERIFY_MARKER,
|
|
26
26
|
format_verify_comment,
|
|
@@ -58,7 +58,7 @@ def post_from_file(
|
|
|
58
58
|
# the write authority re-checks the bot-only rule for EVERY kind: this
|
|
59
59
|
# side of the artifact boundary is the one that must never post on a
|
|
60
60
|
# non-bot PR — a forged envelope is still a post
|
|
61
|
-
pr, pr_data =
|
|
61
|
+
pr, pr_data = pull_request(client, repo, number)
|
|
62
62
|
skip = verify_skip_reason(pr, bot_login)
|
|
63
63
|
if skip is not None:
|
|
64
64
|
log.info("skipping post on %s#%s: %s", repo, number, skip)
|
outerloop/watcher.py
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"""The session watcher: a thread beside a live author session that answers its
|
|
2
|
+
questions through the syscall channel in seconds — `queue` (the kernel's jobs
|
|
3
|
+
in the cluster queue, every agent's) and `history` (this run's launches) —
|
|
4
|
+
where the tick would take a cadence. It changes no lifecycle state: it writes
|
|
5
|
+
answer files into the channel and nothing else; submitting, cancelling,
|
|
6
|
+
sealing and parking stay at the sleep boundary (docs/design/session-watcher.md).
|
|
7
|
+
|
|
8
|
+
Failure never reaches the session: an exception is logged and the request is
|
|
9
|
+
left standing, the tool times out and says so. A watcher that dies leaves the
|
|
10
|
+
session exactly as it is without one."""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
import re
|
|
16
|
+
import threading
|
|
17
|
+
import time
|
|
18
|
+
from collections.abc import Callable
|
|
19
|
+
from dataclasses import dataclass, field
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
from outerloop.climbboard import queue_rows
|
|
24
|
+
from outerloop.launchlog import history, why_by_job
|
|
25
|
+
from outerloop.runstate import run_dir
|
|
26
|
+
from outerloop.syscall import MAX_WHY_CHARS, mark_done, marker_requested, write_channel_json
|
|
27
|
+
|
|
28
|
+
log = logging.getLogger(__name__)
|
|
29
|
+
|
|
30
|
+
VERBS = ("queue", "history")
|
|
31
|
+
POLL_S = 2.0
|
|
32
|
+
# one scheduler query per this many seconds however often the marker is
|
|
33
|
+
# rewritten: a session cannot turn the watcher into a squeue loop
|
|
34
|
+
QUERY_GAP_S = 5.0
|
|
35
|
+
MAX_QUEUE_ROWS = 500
|
|
36
|
+
# squeue names a pending array `<id>_[0-15%4]` and a running task `<id>_3`
|
|
37
|
+
_ARRAY_THROTTLE = re.compile(r"_\[[^\]]*%(\d+)\]$")
|
|
38
|
+
# the lane's node states move slowly; one sinfo a minute is plenty
|
|
39
|
+
LANE_GAP_S = 60.0
|
|
40
|
+
# a stopped watcher may still be inside a scheduler query (its own timeout,
|
|
41
|
+
# a minute at most); the attempt waits this long for it, then moves on — the
|
|
42
|
+
# thread is a daemon and writes nothing once stopped
|
|
43
|
+
JOIN_S = 15.0
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass
|
|
47
|
+
class WatcherContext:
|
|
48
|
+
"""What the watcher needs to answer: where the channel is, which run it
|
|
49
|
+
serves, and the compute backend to ask (None = no queue, local mode)."""
|
|
50
|
+
|
|
51
|
+
workspace: Path
|
|
52
|
+
run_root: Path
|
|
53
|
+
run_id: str
|
|
54
|
+
target: str
|
|
55
|
+
agent_id: str
|
|
56
|
+
compute: Any = None
|
|
57
|
+
gpu_partition: str = ""
|
|
58
|
+
poll_s: float = POLL_S
|
|
59
|
+
query_gap_s: float = QUERY_GAP_S
|
|
60
|
+
lane_gap_s: float = LANE_GAP_S
|
|
61
|
+
clock: Callable[[], float] = field(default=time.time)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _kind(name: str) -> str:
|
|
65
|
+
"""A short label for a kernel job that is not a launch."""
|
|
66
|
+
for key in ("wake", "followup", "eval", "resident", "tick"):
|
|
67
|
+
if key in name:
|
|
68
|
+
return key
|
|
69
|
+
return name
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class SessionWatcher:
|
|
73
|
+
"""`with SessionWatcher(ctx):` around the harness subprocess. `service()`
|
|
74
|
+
is one pass, public so the loop is testable without the thread."""
|
|
75
|
+
|
|
76
|
+
def __init__(self, ctx: WatcherContext) -> None:
|
|
77
|
+
self.ctx = ctx
|
|
78
|
+
self._stop = threading.Event()
|
|
79
|
+
self._thread: threading.Thread | None = None
|
|
80
|
+
self._queue_cache: dict[str, Any] | None = None
|
|
81
|
+
self._queue_at = 0.0
|
|
82
|
+
self._lane_cache: dict[str, Any] | None = None
|
|
83
|
+
self._lane_at = 0.0
|
|
84
|
+
|
|
85
|
+
def __enter__(self) -> SessionWatcher:
|
|
86
|
+
self._thread = threading.Thread(target=self._loop, name="session-watcher", daemon=True)
|
|
87
|
+
self._thread.start()
|
|
88
|
+
return self
|
|
89
|
+
|
|
90
|
+
def __exit__(self, *exc: object) -> None:
|
|
91
|
+
self._stop.set()
|
|
92
|
+
if self._thread is not None:
|
|
93
|
+
self._thread.join(timeout=JOIN_S)
|
|
94
|
+
if self._thread.is_alive():
|
|
95
|
+
log.warning("session watcher still inside a scheduler query at session end")
|
|
96
|
+
|
|
97
|
+
def _loop(self) -> None:
|
|
98
|
+
# wait() is False on timeout: poll; True once stopped
|
|
99
|
+
while not self._stop.wait(self.ctx.poll_s):
|
|
100
|
+
self.service()
|
|
101
|
+
|
|
102
|
+
def service(self) -> None:
|
|
103
|
+
"""Answer every verb whose request marker is newer than its done marker."""
|
|
104
|
+
for verb in VERBS:
|
|
105
|
+
if self._stop.is_set():
|
|
106
|
+
return
|
|
107
|
+
try:
|
|
108
|
+
requested = marker_requested(self.ctx.workspace, f"{verb}-request", f"{verb}-done")
|
|
109
|
+
if requested is None:
|
|
110
|
+
continue
|
|
111
|
+
payload = self.queue_view() if verb == "queue" else self.history_view()
|
|
112
|
+
if self._stop.is_set():
|
|
113
|
+
return # the session ended meanwhile: nothing is written after it
|
|
114
|
+
write_channel_json(self.ctx.workspace, f"{verb}.json", payload)
|
|
115
|
+
mark_done(self.ctx.workspace, f"{verb}-done", requested)
|
|
116
|
+
except Exception as exc: # the request stands; the tool times out
|
|
117
|
+
log.warning("session watcher: %s failed: %s", verb, exc)
|
|
118
|
+
|
|
119
|
+
def history_view(self) -> dict[str, Any]:
|
|
120
|
+
ctx = self.ctx
|
|
121
|
+
return {
|
|
122
|
+
"at": ctx.clock(),
|
|
123
|
+
"run_id": ctx.run_id,
|
|
124
|
+
"history": history(run_dir(ctx.run_root, ctx.run_id)),
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
def queue_view(self) -> dict[str, Any]:
|
|
128
|
+
"""The kernel's jobs as the board projects them (attributed to agents),
|
|
129
|
+
each launch labelled with its author's `why`, plus the GPU lane's load.
|
|
130
|
+
Cached for `query_gap_s` — the rate limit on scheduler queries."""
|
|
131
|
+
ctx = self.ctx
|
|
132
|
+
now = ctx.clock()
|
|
133
|
+
if self._queue_cache is not None and now - self._queue_at < ctx.query_gap_s:
|
|
134
|
+
return {**self._queue_cache, "at": now, "cached": True}
|
|
135
|
+
error = ""
|
|
136
|
+
rows: list[dict[str, Any]] = []
|
|
137
|
+
try:
|
|
138
|
+
snapshot = ctx.compute.queue_snapshot() if ctx.compute is not None else []
|
|
139
|
+
rows = [
|
|
140
|
+
dict(r) for r in queue_rows(ctx.run_root, ctx.target, snapshot)[:MAX_QUEUE_ROWS]
|
|
141
|
+
]
|
|
142
|
+
except Exception as exc:
|
|
143
|
+
error = str(exc)[:200]
|
|
144
|
+
labels: dict[str, dict[str, Any]] = {}
|
|
145
|
+
for rid in {str(r.get("run_id") or "") for r in rows} - {""}:
|
|
146
|
+
labels.update(why_by_job(run_dir(ctx.run_root, rid)))
|
|
147
|
+
for r in rows:
|
|
148
|
+
rid = str(r.get("run_id") or "")
|
|
149
|
+
name = str(r.get("name") or "")
|
|
150
|
+
prefix = f"{rid}-launch-" if rid else ""
|
|
151
|
+
r["mine"] = bool(rid) and rid == ctx.run_id
|
|
152
|
+
job_id = str(r.get("id") or "")
|
|
153
|
+
throttle = _ARRAY_THROTTLE.search(job_id)
|
|
154
|
+
if throttle:
|
|
155
|
+
r["concurrency"] = int(throttle.group(1))
|
|
156
|
+
if prefix and name.startswith(prefix):
|
|
157
|
+
r["experiment"] = name[len(prefix) :]
|
|
158
|
+
# the ledger keys the array's id; squeue shows `<id>_<k>` or `<id>_[...]`
|
|
159
|
+
base = job_id.split("_", 1)[0]
|
|
160
|
+
label = labels.get(base, {})
|
|
161
|
+
r["why"] = str(label.get("why", ""))[:MAX_WHY_CHARS]
|
|
162
|
+
r["kind"] = "launch"
|
|
163
|
+
# the pace: the pending range says it; once only running tasks
|
|
164
|
+
# are left, the ledger does (the whole array when unset)
|
|
165
|
+
array = int(label.get("array") or 1)
|
|
166
|
+
if "concurrency" not in r and array > 1:
|
|
167
|
+
r["concurrency"] = int(label.get("concurrency") or array)
|
|
168
|
+
else:
|
|
169
|
+
r["experiment"] = ""
|
|
170
|
+
r["why"] = ""
|
|
171
|
+
r["kind"] = _kind(name)
|
|
172
|
+
view = {
|
|
173
|
+
"at": now,
|
|
174
|
+
"run_id": ctx.run_id,
|
|
175
|
+
"agent": ctx.agent_id,
|
|
176
|
+
"jobs": rows,
|
|
177
|
+
"lane": self._lane_load(),
|
|
178
|
+
"error": error,
|
|
179
|
+
}
|
|
180
|
+
self._queue_cache, self._queue_at = view, now
|
|
181
|
+
return view
|
|
182
|
+
|
|
183
|
+
def _lane_load(self) -> dict[str, Any]:
|
|
184
|
+
"""The GPU lane's node states, refreshed once per `lane_gap_s` (a
|
|
185
|
+
second scheduler query per request would defeat the rate limit). A
|
|
186
|
+
failed sinfo is reported in the answer, never passed off as a lane
|
|
187
|
+
with no state."""
|
|
188
|
+
ctx = self.ctx
|
|
189
|
+
load = getattr(ctx.compute, "lane_load", None)
|
|
190
|
+
if load is None or not ctx.gpu_partition:
|
|
191
|
+
return {}
|
|
192
|
+
now = ctx.clock()
|
|
193
|
+
if self._lane_cache is not None and now - self._lane_at < ctx.lane_gap_s:
|
|
194
|
+
return self._lane_cache
|
|
195
|
+
try:
|
|
196
|
+
lane: dict[str, Any] = {
|
|
197
|
+
"partition": ctx.gpu_partition,
|
|
198
|
+
"nodes": load(ctx.gpu_partition),
|
|
199
|
+
}
|
|
200
|
+
except Exception as exc:
|
|
201
|
+
lane = {"partition": ctx.gpu_partition, "nodes": {}, "error": str(exc)[:200]}
|
|
202
|
+
self._lane_cache, self._lane_at = lane, now
|
|
203
|
+
return lane
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: outerloop-science
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev4
|
|
4
4
|
Summary: Autonomous research agents that improve the benchmark you point them at, one verified pull request at a time
|
|
5
5
|
Project-URL: Homepage, https://outerloop.science
|
|
6
6
|
Project-URL: Repository, https://github.com/outerloop-science/outerloop
|
|
@@ -25,6 +25,9 @@ Description-Content-Type: text/markdown
|
|
|
25
25
|
# Outerloop
|
|
26
26
|
|
|
27
27
|
[](https://github.com/outerloop-science/outerloop/actions/workflows/ci.yml)
|
|
28
|
+
[](https://pypi.org/project/outerloop-science/)
|
|
29
|
+
[](https://pypi.org/project/outerloop-science/)
|
|
30
|
+
[](LICENSE)
|
|
28
31
|
|
|
29
32
|
**Autoresearch agents that improve your benchmark.**
|
|
30
33
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
outerloop/__init__.py,sha256=-UecbET4sxCC3TMirVP82LGWLLX79jmKAtdgjj8UspQ,636
|
|
2
|
+
outerloop/__main__.py,sha256=Fq2ADl3rjZ4i2m1svON_KO2kJqpwUnohLhdlacAnEpM,57
|
|
3
|
+
outerloop/appauth.py,sha256=0FJD8JdQ3r9DgCTpY7GgOudCB7s7BDbaVqBWpdt02oU,9666
|
|
4
|
+
outerloop/appmanifest.py,sha256=9L4NyUqVJhgE8BlBnK6BTpMdkhpukLtAnezZQcbyBwI,8459
|
|
5
|
+
outerloop/attempt.py,sha256=JAuJhpWHppK8uZPeNMfLiCQ6tz-W_Lq00sfSzdHqq0Y,171201
|
|
6
|
+
outerloop/brief.py,sha256=XGNrO5VZUASNRu4y_T3VHcGp-PCkpHPV8ACOpzXNT4M,25206
|
|
7
|
+
outerloop/cli.py,sha256=VDp_-ImCFUbXaj_zmjrPE6ceEgstcJR-fi5w9dH8J0s,24952
|
|
8
|
+
outerloop/climbboard.py,sha256=C7jVJp91hain3kxUouL6DK8n4Xpa_j_nyDtBphMP8K0,68452
|
|
9
|
+
outerloop/compute.py,sha256=aC5yecD4o6C1geA_OAiA4pzts1vXsiskzvLNbPOXPe0,27926
|
|
10
|
+
outerloop/contract.py,sha256=wGeLhFl57wQQi57uZmJYb9M_21H8Dj5hHIOLSs06zOY,25101
|
|
11
|
+
outerloop/contract_cli.py,sha256=Pa-sJe7G8BuLGed5tqnlq6L75fTT1HHO4d-XWZPW8U8,1992
|
|
12
|
+
outerloop/disk.py,sha256=FAgR1FJVPTu1YCcfNxcJtUFxJsBFcOaenF8lYAVPL1Y,5853
|
|
13
|
+
outerloop/dispatch.py,sha256=hRW8K_OxFR9cmWcUg89XZSc_t3UGCY5X2AxRhuGOehk,29207
|
|
14
|
+
outerloop/evalcache.py,sha256=uVCcG3HjHNpmFRuQbMyQDVYE_-W1a3v-vxN3mDGZoNY,5045
|
|
15
|
+
outerloop/followup.py,sha256=AYD1ir-PydgK1ItSZCqA2w-rZQ1lxMn5Ymr1tkry9cg,95200
|
|
16
|
+
outerloop/github.py,sha256=4Z0hFjuhWcWuIgM8VBabh218AWPKmYWORYFyejnC0w4,67854
|
|
17
|
+
outerloop/harness.py,sha256=2UH2WZOKgQaeERVsIx3KX3muZRarYMOC4f25SLRw7qA,66092
|
|
18
|
+
outerloop/housekeeping.py,sha256=w1GWSIRZq3yBgxmIi__f0f_OF8TtKqaR-WtLvsWEjHI,6001
|
|
19
|
+
outerloop/image.py,sha256=bXCB-VqFfzJnnYVgclC0JuCN-AXJZkq938z4vV8Bvoo,15330
|
|
20
|
+
outerloop/init.py,sha256=IwxAEG8mvESP__Z8A_tqnPG5c2cAoMcRf6W3gFodq_g,34393
|
|
21
|
+
outerloop/intake.py,sha256=UxJddNYfB2IuV57mcUZ_7ShfJTJXavfUiFm5xo7g9lg,5243
|
|
22
|
+
outerloop/launchlog.py,sha256=oJf8ADmptkB_yz8-Dp6smkPjgn3Yl3oKpEEFAlNflN0,8975
|
|
23
|
+
outerloop/limits.py,sha256=ubdBqhtN8SN4r5RoDhuptoolqtq_m-1KZPdW3iXaml8,3385
|
|
24
|
+
outerloop/maintain.py,sha256=9_4rpOvSMBLKiO9MZnSNkPLg6nu7fv8TVJpwPIZVDB4,15525
|
|
25
|
+
outerloop/maintain_agent_cli.py,sha256=QRF6VUDVR05_wxXJyBgvhsUUMqm3NvSIBbwdG9Cfn3Y,3010
|
|
26
|
+
outerloop/maintain_post_cli.py,sha256=0c_i5fa1QEqUKauqyq9hTa6opviIF9Y3v6X5ezvZvyo,5567
|
|
27
|
+
outerloop/markers.py,sha256=Bi_hwWCICW6qPQ8_yB--0IrUaLLh9C3K24aDaCxHNAY,1739
|
|
28
|
+
outerloop/measure.py,sha256=hUCy17FcWyd6yIFhRyNrLfLfNWtSs1yasFVYJKUbVd0,22795
|
|
29
|
+
outerloop/orchestrator.py,sha256=I7bYVJYCY4Pus9jqlS4JkVqYiKum5lQc_d43Z0KG6Jg,89372
|
|
30
|
+
outerloop/panel.py,sha256=DcK3E0WdUUZPao0DWFCz3uLtm-VDmhhv1QTQHiEYcEY,7677
|
|
31
|
+
outerloop/paths.py,sha256=SpOt3zU2KS9_KZ6FiNEH9vs9fbQt8y1rWMYbZskwxHA,1501
|
|
32
|
+
outerloop/posting.py,sha256=dUi7P46HzsQmVgs5BXy5GXGOkcTNjOZDO-x_y0yAaaU,6632
|
|
33
|
+
outerloop/progress.py,sha256=9vCKsO8_NGrw3-hhSif5QA6rLoqNOrQ8ICIpVBqD2VI,6133
|
|
34
|
+
outerloop/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
|
+
outerloop/review.py,sha256=rpqdqhNjlvmbRln_zNbhrGyNmpt39Pxu5Oq7jEVcYtI,27416
|
|
36
|
+
outerloop/review_agent.py,sha256=sPN2-mAfe1e3uLn2ogJrppIMAvGuS2NTgiitCQHlaRw,9999
|
|
37
|
+
outerloop/review_agent_cli.py,sha256=qWE79-rP8HqNPLFAgyuNJxoHCtxowV-Ee6GKJib644U,8371
|
|
38
|
+
outerloop/review_post_cli.py,sha256=VzZunoNOzNTDIR710hDJ2n3xE2lNtLGL3KFgwV-1Bmo,6264
|
|
39
|
+
outerloop/review_summarize_cli.py,sha256=f1MK9tMo6P4SfrwJS0CFbwV35XaACL_WyzhZCgT53rs,6862
|
|
40
|
+
outerloop/role_runner.py,sha256=4l4zw0TtiFrGDmzHW8T6vZ7OLq7vVD0cN4U4BoNbgUs,9681
|
|
41
|
+
outerloop/roles.py,sha256=PyhWGhZm7tEr_t5sfiPJplxO4BK3JGGB5lGgQFMKIcI,12253
|
|
42
|
+
outerloop/rolespec.py,sha256=Y9vsUsPLtSc1ricvFSaA2qmOMkOg76TPnHsdGZOi0ME,3935
|
|
43
|
+
outerloop/runstate.py,sha256=5bEczCz1KTbVI1cTwNvd4Oc2RXIX-9piWD5-g_S6tMo,17976
|
|
44
|
+
outerloop/steward.py,sha256=iv6OUpZ-QypJbQZJaoYKz89FfpmFH6Xy53ADyCVLF5s,34107
|
|
45
|
+
outerloop/style.py,sha256=icZQNq0hOLjhoXStpH7rxZm24fsAh4uL8NMH72nz9S0,497
|
|
46
|
+
outerloop/syscall.py,sha256=XsjS0TkzvdNt2HjOSiVxgcbwf8QKIXibfLq2DbDiQcI,54317
|
|
47
|
+
outerloop/syscall_cli.py,sha256=srjqlNDhSmrPJI4haYRxVsGwzy4uO-dx_Uhu5fneLk0,31768
|
|
48
|
+
outerloop/tick.py,sha256=95gHa44SWIldM9RHSkiD4vXJCPQm6K2PTTDYaMVNtbI,154872
|
|
49
|
+
outerloop/verifier.py,sha256=BeizeiAqXGiuL-pmGptedtFo_GWAxfguwZhoTdAn1qg,17793
|
|
50
|
+
outerloop/verify_agent.py,sha256=x9OINnpmISDIjq5q5wtJ1wUD13Obpc8UXvF18vfkONY,6550
|
|
51
|
+
outerloop/verify_agent_cli.py,sha256=3QCQTB7MSdtN-k9x9HovLPo8q988H9o9Uus8rmaR444,3908
|
|
52
|
+
outerloop/verify_post_cli.py,sha256=qbQ-tT_MQUzKIKLTrJEgLn0O320JnrJESKyBqqjznU4,4599
|
|
53
|
+
outerloop/watcher.py,sha256=l377ldNgnmDR_jsbQyM-QrExmAwNTha0wEVGDv1TVNc,8319
|
|
54
|
+
outerloop_science-0.1.0.dev4.dist-info/METADATA,sha256=HMkAzSFOFiDsi4fFF2_gSw3pSCKSuCoPnuH8-6gpigA,6967
|
|
55
|
+
outerloop_science-0.1.0.dev4.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
56
|
+
outerloop_science-0.1.0.dev4.dist-info/entry_points.txt,sha256=mLYW8Dxv8FnrYdCkKV8ekwcV3TnfzPYkdbJOkYzF5xE,49
|
|
57
|
+
outerloop_science-0.1.0.dev4.dist-info/licenses/LICENSE,sha256=Kqt7czAsZdfZp9B6a3WoTt9CZuy7_0sjPNMW7KHckk8,11375
|
|
58
|
+
outerloop_science-0.1.0.dev4.dist-info/licenses/NOTICE,sha256=VTBNz2gnaoM68CoUkQe1G7VbrV-R0WfqKHrZhYYbuqI,193
|
|
59
|
+
outerloop_science-0.1.0.dev4.dist-info/RECORD,,
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
outerloop/__init__.py,sha256=sIIc5yYu2cnaaZt1u9_X2RLGOYt3UlnLPwNhoWNIMyE,633
|
|
2
|
-
outerloop/__main__.py,sha256=Fq2ADl3rjZ4i2m1svON_KO2kJqpwUnohLhdlacAnEpM,57
|
|
3
|
-
outerloop/appauth.py,sha256=j4XG7gF8Zeg91R-MG7A2S1IxgmJCqSQEgaGA7iwRZtY,8898
|
|
4
|
-
outerloop/appmanifest.py,sha256=9L4NyUqVJhgE8BlBnK6BTpMdkhpukLtAnezZQcbyBwI,8459
|
|
5
|
-
outerloop/attempt.py,sha256=Unfne2yY9DeHKXKUdqcQHbC68LruwOPDu0k5LNhoQtM,159339
|
|
6
|
-
outerloop/brief.py,sha256=f8QeMQRhsZvyNEh28sbM684FwWZCGU-rwPL0o8lqtrw,24156
|
|
7
|
-
outerloop/cli.py,sha256=3FJqLpxlEsLQ1RoSiJhzQSWqChVHwXKZ-EJ1WeTpwRg,20859
|
|
8
|
-
outerloop/climbboard.py,sha256=GoucONPvtjIWHz3jH_9ewX4iSZfeh7q_PtR5atClogA,67011
|
|
9
|
-
outerloop/compute.py,sha256=z1nG559IBAi16qH3Ux9APWmDWG-oqkWGf9Y5GjV5ljs,24589
|
|
10
|
-
outerloop/contract.py,sha256=lj_EPz-oPNdM_LacF0M04-Jqlvs0r_qNRlr8zP1cOiI,24516
|
|
11
|
-
outerloop/contract_cli.py,sha256=Pa-sJe7G8BuLGed5tqnlq6L75fTT1HHO4d-XWZPW8U8,1992
|
|
12
|
-
outerloop/disk.py,sha256=FAgR1FJVPTu1YCcfNxcJtUFxJsBFcOaenF8lYAVPL1Y,5853
|
|
13
|
-
outerloop/dispatch.py,sha256=70Of08UygVco9drBpq8Xfqi5tunMBvNk--tPYZjcpNI,27401
|
|
14
|
-
outerloop/followup.py,sha256=dM6z2te4yOoQ2WNak2rr-npVCQ8WQtfDXjUe_BaYbFo,94680
|
|
15
|
-
outerloop/github.py,sha256=mOR6Hp_fAVEXZZ0NWyLyOEyqlM_5CGqnpgDSX2YYqzM,65305
|
|
16
|
-
outerloop/harness.py,sha256=0RXz-TWkSigxLhlAxnq0OcNQF0rHajJuuSraInHm5VA,67232
|
|
17
|
-
outerloop/housekeeping.py,sha256=nlyy9kWUwTPjW0FLizVwXI99xSTZj7JJDzIdzJzDfEk,6663
|
|
18
|
-
outerloop/image.py,sha256=nVnU2HQIWMXKgluUPw7exCcPDPv0fnKxsXBG2Sdo9os,15406
|
|
19
|
-
outerloop/init.py,sha256=w7HEJ76p0A9PWNuFkLQ27_LnlZJ4ON0o_djJyo4I_jw,31951
|
|
20
|
-
outerloop/intake.py,sha256=a3j1B6W7v3QpQv53CoJS0hh6vz7B3nLn_cV2G-nt6Uw,5424
|
|
21
|
-
outerloop/limits.py,sha256=ubdBqhtN8SN4r5RoDhuptoolqtq_m-1KZPdW3iXaml8,3385
|
|
22
|
-
outerloop/markers.py,sha256=Bi_hwWCICW6qPQ8_yB--0IrUaLLh9C3K24aDaCxHNAY,1739
|
|
23
|
-
outerloop/measure.py,sha256=NFAljbUV29py4JoqfFSI3JYGho8by_L1eDgPw2ubNjU,22493
|
|
24
|
-
outerloop/orchestrator.py,sha256=bH2pOhpfJdwhvZvjqlQnfrwTMMWwQOLB-Xh6Ew2468Q,84458
|
|
25
|
-
outerloop/panel.py,sha256=bSoQtuP2xqWbl7DBdeqihrGNyDz6-u5wWrV3nI-b0Js,7665
|
|
26
|
-
outerloop/paths.py,sha256=SpOt3zU2KS9_KZ6FiNEH9vs9fbQt8y1rWMYbZskwxHA,1501
|
|
27
|
-
outerloop/posting.py,sha256=dUi7P46HzsQmVgs5BXy5GXGOkcTNjOZDO-x_y0yAaaU,6632
|
|
28
|
-
outerloop/progress.py,sha256=9vCKsO8_NGrw3-hhSif5QA6rLoqNOrQ8ICIpVBqD2VI,6133
|
|
29
|
-
outerloop/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
|
-
outerloop/review.py,sha256=_vJcTCVdtrK7ymfd0pgjz-IE7oM3CVzMceNZt1AMhGk,27184
|
|
31
|
-
outerloop/review_agent.py,sha256=XxGrGVZb61pqd6F3I15lrFBQptduER7QNmxMmCaUNec,9961
|
|
32
|
-
outerloop/review_agent_cli.py,sha256=R9rZHvQ9LSttocSUuO0087fywLf3iHt-vldxo6Ygd7k,8355
|
|
33
|
-
outerloop/review_post_cli.py,sha256=XNw8BjxJMtEMzWRK4jKV-f_alOdIWeqJfwdndFCqTm8,6266
|
|
34
|
-
outerloop/review_summarize_cli.py,sha256=p_gmTGj_uEKik47EgVuHNDDtO18cw2dVznnvnm_9k3c,6791
|
|
35
|
-
outerloop/role_runner.py,sha256=4l4zw0TtiFrGDmzHW8T6vZ7OLq7vVD0cN4U4BoNbgUs,9681
|
|
36
|
-
outerloop/roles.py,sha256=hx8RrtJCBb0nsJGvxamHJ8Dk3j8lIFsTCapbOlQyKN0,10952
|
|
37
|
-
outerloop/rolespec.py,sha256=6VmrwTlLSsN17aQSDtLB2MvcEHYpbSOPIyPcY1uGny8,3915
|
|
38
|
-
outerloop/runstate.py,sha256=5bEczCz1KTbVI1cTwNvd4Oc2RXIX-9piWD5-g_S6tMo,17976
|
|
39
|
-
outerloop/steward.py,sha256=3MiYQsSDVR6KGU8dDji3v_vr8OUT5nl_6JWhUB4U9AE,34396
|
|
40
|
-
outerloop/style.py,sha256=icZQNq0hOLjhoXStpH7rxZm24fsAh4uL8NMH72nz9S0,497
|
|
41
|
-
outerloop/syscall.py,sha256=367I0rhhkEgm7-KNkXaX1h9960K_y2mTRmLjwcFqFCM,44601
|
|
42
|
-
outerloop/syscall_cli.py,sha256=e2Y_TQ9rAxAKjwLgSHHKgT93yMfu55SFO04k4s83OF4,22079
|
|
43
|
-
outerloop/tick.py,sha256=tLMDs-zoPy_y659s1FQuglevDURR84bXGZsVCROJX-Q,157004
|
|
44
|
-
outerloop/verifier.py,sha256=BeizeiAqXGiuL-pmGptedtFo_GWAxfguwZhoTdAn1qg,17793
|
|
45
|
-
outerloop/verify_agent.py,sha256=fzv5N_cm5g6ZcwMmIpd5S5UbqW3wAEXTQmPFWK_Zdi4,6482
|
|
46
|
-
outerloop/verify_agent_cli.py,sha256=3QCQTB7MSdtN-k9x9HovLPo8q988H9o9Uus8rmaR444,3908
|
|
47
|
-
outerloop/verify_post_cli.py,sha256=vw2WXzP10HlZW7inDDpt6k6Zq9sPQwFnmXrwvnpHjZg,4601
|
|
48
|
-
outerloop_science-0.1.0.dev2.dist-info/METADATA,sha256=vHimtrNg4OlCZSXbJMWvIrvvrJmvC7ZjO3qogLgRkYw,6659
|
|
49
|
-
outerloop_science-0.1.0.dev2.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
50
|
-
outerloop_science-0.1.0.dev2.dist-info/entry_points.txt,sha256=mLYW8Dxv8FnrYdCkKV8ekwcV3TnfzPYkdbJOkYzF5xE,49
|
|
51
|
-
outerloop_science-0.1.0.dev2.dist-info/licenses/LICENSE,sha256=Kqt7czAsZdfZp9B6a3WoTt9CZuy7_0sjPNMW7KHckk8,11375
|
|
52
|
-
outerloop_science-0.1.0.dev2.dist-info/licenses/NOTICE,sha256=VTBNz2gnaoM68CoUkQe1G7VbrV-R0WfqKHrZhYYbuqI,193
|
|
53
|
-
outerloop_science-0.1.0.dev2.dist-info/RECORD,,
|
|
File without changes
|
{outerloop_science-0.1.0.dev2.dist-info → outerloop_science-0.1.0.dev4.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{outerloop_science-0.1.0.dev2.dist-info → outerloop_science-0.1.0.dev4.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{outerloop_science-0.1.0.dev2.dist-info → outerloop_science-0.1.0.dev4.dist-info}/licenses/NOTICE
RENAMED
|
File without changes
|