researchloop 0.3.3__tar.gz → 0.3.4__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.
- {researchloop-0.3.3 → researchloop-0.3.4}/PKG-INFO +1 -1
- {researchloop-0.3.3 → researchloop-0.3.4}/pyproject.toml +1 -1
- researchloop-0.3.4/researchloop/__init__.py +1 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/job_templates/sge.sh.j2 +11 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/job_templates/slurm.sh.j2 +11 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_runner.py +25 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/uv.lock +1 -1
- researchloop-0.3.3/researchloop/__init__.py +0 -1
- {researchloop-0.3.3 → researchloop-0.3.4}/.github/workflows/ci.yml +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/.github/workflows/docs.yml +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/.github/workflows/release.yml +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/.gitignore +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/CLAUDE.md +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/Dockerfile +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/LICENSE +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/README.md +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/docs/assets/mmlu-combined.gif +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/docs/assets/mmlu-combined.mp4 +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/docs/cli.md +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/docs/configuration.md +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/docs/dashboard.md +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/docs/deployment.md +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/docs/development.md +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/docs/getting-started.md +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/docs/index.md +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/docs/security.md +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/docs/slack.md +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/mkdocs.yml +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/__main__.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/cli.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/clusters/__init__.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/clusters/monitor.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/clusters/ssh.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/comms/__init__.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/comms/base.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/comms/ntfy.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/comms/router.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/comms/slack.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/core/__init__.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/core/config.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/core/credentials.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/core/models.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/core/orchestrator.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/__init__.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/app.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/auth.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/routes.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/templates/base.html +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/templates/login.html +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/templates/loop_detail.html +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/templates/loops.html +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/templates/search.html +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/templates/setup.html +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/templates/sprint_detail.html +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/templates/sprints.html +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/templates/studies.html +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/templates/study_detail.html +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/templates/study_form.html +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/templates/tweak_detail.html +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/db/__init__.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/db/database.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/db/migrations.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/db/queries.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/__init__.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/claude.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/job_templates/sge_tweak.sh.j2 +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/job_templates/slurm_tweak.sh.j2 +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/main.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/pipeline.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/templates/fix_issues.md.j2 +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/templates/idea_generator.md.j2 +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/templates/red_team.md.j2 +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/templates/report.md.j2 +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/templates/research_sprint.md.j2 +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/templates/summarizer.md.j2 +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/templates/tweak.md.j2 +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/upload.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/schedulers/__init__.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/schedulers/base.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/schedulers/local.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/schedulers/sge.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/schedulers/slurm.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/sprints/__init__.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/sprints/auto_loop.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/sprints/manager.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/studies/__init__.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/studies/manager.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/testing/__init__.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/testing/slack_mock.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop/testing/slack_simulator.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/researchloop.toml.example +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/slack-app-manifest.yml +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/__init__.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/conftest.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/docker/sge/Dockerfile +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/docker/sge/entrypoint.sh +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/docker/sge/mock_claude.sh +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/docker/slurm/Dockerfile +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/docker/slurm/entrypoint.sh +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/docker/slurm/mock_claude.sh +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/integration/__init__.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/integration/conftest.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/integration/test_loop_advancement.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/integration/test_loop_and_monitor.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/integration/test_sge_scheduler.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/integration/test_slurm_scheduler.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/integration/test_sprint_slurm.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/integration/test_webhook_and_refresh.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_api.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_auto_loop.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_cli.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_config.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_dashboard.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_database.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_models.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_notification.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_queries.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_schedulers.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_search.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_sge.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_slack.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_slack_events.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_slack_mock.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_slack_simulator.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_sprint_manager.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_study_manager.py +0 -0
- {researchloop-0.3.3 → researchloop-0.3.4}/tests/test_tweaks.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.4"
|
|
@@ -241,6 +241,17 @@ print(json.dumps({
|
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
_heartbeat_loop() {
|
|
244
|
+
# The parent script runs with `set -euo pipefail`, which is inherited
|
|
245
|
+
# by this backgrounded subshell. An unprotected command-substitution
|
|
246
|
+
# failure here (e.g. `ls -t pattern | head -1` racing into SIGPIPE on
|
|
247
|
+
# ls under pipefail, or a glob that matches nothing) is enough to kill
|
|
248
|
+
# the entire watchdog and leave the sprint without heartbeats or
|
|
249
|
+
# STUCK_PIPE detection for the rest of its wall-clock. Disable strict
|
|
250
|
+
# mode for the watchdog — a noisy heartbeat is far better than a
|
|
251
|
+
# silently-dead one.
|
|
252
|
+
set +e
|
|
253
|
+
set +o pipefail
|
|
254
|
+
|
|
244
255
|
# Watchdog: detect and recover from hung pipelines.
|
|
245
256
|
#
|
|
246
257
|
# STUCK_PIPE warn: the active step's stream-json file goes silent for
|
|
@@ -243,6 +243,17 @@ print(json.dumps({
|
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
_heartbeat_loop() {
|
|
246
|
+
# The parent script runs with `set -euo pipefail`, which is inherited
|
|
247
|
+
# by this backgrounded subshell. An unprotected command-substitution
|
|
248
|
+
# failure here (e.g. `ls -t pattern | head -1` racing into SIGPIPE on
|
|
249
|
+
# ls under pipefail, or a glob that matches nothing) is enough to kill
|
|
250
|
+
# the entire watchdog and leave the sprint without heartbeats or
|
|
251
|
+
# STUCK_PIPE detection for the rest of its wall-clock. Disable strict
|
|
252
|
+
# mode for the watchdog — a noisy heartbeat is far better than a
|
|
253
|
+
# silently-dead one.
|
|
254
|
+
set +e
|
|
255
|
+
set +o pipefail
|
|
256
|
+
|
|
246
257
|
# Watchdog: detect and recover from hung pipelines.
|
|
247
258
|
#
|
|
248
259
|
# STUCK_PIPE warn: the active step's stream-json file goes silent for
|
|
@@ -176,6 +176,21 @@ class TestJobScriptWatchdog:
|
|
|
176
176
|
# Once-per-stuck-episode flag, not log-every-heartbeat.
|
|
177
177
|
assert "stuck_warned" in script
|
|
178
178
|
|
|
179
|
+
def _assert_heartbeat_loop_disables_strict_mode(self, script: str) -> None:
|
|
180
|
+
# The parent script has set -euo pipefail. The backgrounded
|
|
181
|
+
# _heartbeat_loop inherits it — without explicitly disabling errexit
|
|
182
|
+
# and pipefail, a single command-substitution failure (e.g. an
|
|
183
|
+
# ls|head SIGPIPE race) can silently kill the watchdog and the
|
|
184
|
+
# sprint loses all heartbeat + STUCK_PIPE detection for the rest of
|
|
185
|
+
# its wall-clock. The first two `set` lines inside the function
|
|
186
|
+
# must disable both modes.
|
|
187
|
+
loop_idx = script.index("_heartbeat_loop() {")
|
|
188
|
+
body_idx = script.index("\n", loop_idx) + 1
|
|
189
|
+
# Check the disabling lines are at the top of the function body.
|
|
190
|
+
head = script[body_idx : body_idx + 800]
|
|
191
|
+
assert "set +e" in head
|
|
192
|
+
assert "set +o pipefail" in head
|
|
193
|
+
|
|
179
194
|
def _assert_hung_pipeline_recovery_present(self, script: str) -> None:
|
|
180
195
|
# claude must run in its own session so the watchdog can SIGTERM the
|
|
181
196
|
# whole group (claude + any leaked Bash-tool subprocesses) by pgid.
|
|
@@ -209,3 +224,13 @@ class TestJobScriptWatchdog:
|
|
|
209
224
|
|
|
210
225
|
def test_sge_template_includes_hung_pipeline_recovery(self):
|
|
211
226
|
self._assert_hung_pipeline_recovery_present(_render_job_template("sge.sh.j2"))
|
|
227
|
+
|
|
228
|
+
def test_slurm_heartbeat_loop_disables_strict_mode(self):
|
|
229
|
+
self._assert_heartbeat_loop_disables_strict_mode(
|
|
230
|
+
_render_job_template("slurm.sh.j2")
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
def test_sge_heartbeat_loop_disables_strict_mode(self):
|
|
234
|
+
self._assert_heartbeat_loop_disables_strict_mode(
|
|
235
|
+
_render_job_template("sge.sh.j2")
|
|
236
|
+
)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.3.3"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/templates/sprint_detail.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/templates/study_detail.html
RENAMED
|
File without changes
|
|
File without changes
|
{researchloop-0.3.3 → researchloop-0.3.4}/researchloop/dashboard/templates/tweak_detail.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/job_templates/slurm_tweak.sh.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/templates/idea_generator.md.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{researchloop-0.3.3 → researchloop-0.3.4}/researchloop/runner/templates/research_sprint.md.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|