sbxloop-worker 0.2.0__tar.gz → 0.3.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.
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/PKG-INFO +1 -1
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/pyproject.toml +1 -1
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/src/sbxloop_worker/__init__.py +1 -1
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/src/sbxloop_worker/__main__.py +13 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/src/sbxloop_worker/backends/copilot.py +15 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/src/sbxloop_worker/backends/echo.py +9 -1
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/src/sbxloop_worker/protocol.py +4 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/.gitignore +0 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/README.md +0 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/src/sbxloop_worker/_json.py +0 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/src/sbxloop_worker/backends/__init__.py +0 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/src/sbxloop_worker/events.py +0 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/src/sbxloop_worker/githubops.py +0 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/src/sbxloop_worker/py.typed +0 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/src/sbxloop_worker/runner.py +0 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/tests/conftest.py +0 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/tests/test_githubops.py +0 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/tests/test_json_extract.py +0 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/tests/test_protocol.py +0 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/tests/test_runner_unit.py +0 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/tests/test_worker_contract.py +0 -0
- {sbxloop_worker-0.2.0 → sbxloop_worker-0.3.0}/tests/worker_harness.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sbxloop-worker
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: In-sandbox worker runtime for sbxloop (protocol models, agent backends, job runner)
|
|
5
5
|
Project-URL: Homepage, https://github.com/brettbergin/sbxloop
|
|
6
6
|
Project-URL: Repository, https://github.com/brettbergin/sbxloop
|
|
@@ -65,6 +65,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
65
65
|
run.add_argument("--result", required=True, type=Path)
|
|
66
66
|
run.add_argument("--heartbeat", type=float, default=15.0)
|
|
67
67
|
run.add_argument("--env-file", type=Path, default=DEFAULT_ENV_FILE)
|
|
68
|
+
run.add_argument("--cwd", type=Path, default=None)
|
|
68
69
|
args = parser.parse_args(argv)
|
|
69
70
|
|
|
70
71
|
apply_env_file(args.env_file)
|
|
@@ -76,6 +77,18 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
76
77
|
print(f"sbxloop_worker: invalid job file {args.job}: {exc}", file=sys.stderr)
|
|
77
78
|
return 64
|
|
78
79
|
|
|
80
|
+
if args.cwd is not None:
|
|
81
|
+
# Run the whole worker in the job's working directory so agent
|
|
82
|
+
# sessions (which inherit the process cwd) and shell commands both
|
|
83
|
+
# execute in the run workspace. Overwrite job.cwd with the resolved
|
|
84
|
+
# value so shell.check keeps its single code path.
|
|
85
|
+
try:
|
|
86
|
+
os.chdir(args.cwd)
|
|
87
|
+
except OSError as exc:
|
|
88
|
+
print(f"sbxloop_worker: cannot chdir to {args.cwd}: {exc}", file=sys.stderr)
|
|
89
|
+
return 64
|
|
90
|
+
job = job.model_copy(update={"cwd": str(Path.cwd())})
|
|
91
|
+
|
|
79
92
|
try:
|
|
80
93
|
JobRunner(
|
|
81
94
|
job,
|
|
@@ -142,6 +142,21 @@ class CopilotBackend:
|
|
|
142
142
|
kwargs["model"] = job.model
|
|
143
143
|
if job.system_message:
|
|
144
144
|
kwargs["system_message"] = {"mode": "append", "content": job.system_message}
|
|
145
|
+
if job.cwd:
|
|
146
|
+
# Belt-and-braces alongside the worker-level chdir; the kwarg
|
|
147
|
+
# name is unverified against the SDK (e2e-validated), so an
|
|
148
|
+
# unsupported signature must not fail the session.
|
|
149
|
+
kwargs["working_directory"] = job.cwd
|
|
150
|
+
try:
|
|
151
|
+
return await self._open(client, job, kwargs)
|
|
152
|
+
except TypeError:
|
|
153
|
+
if "working_directory" not in kwargs:
|
|
154
|
+
raise
|
|
155
|
+
del kwargs["working_directory"]
|
|
156
|
+
return await self._open(client, job, kwargs)
|
|
157
|
+
|
|
158
|
+
@staticmethod
|
|
159
|
+
async def _open(client: Any, job: JobRequest, kwargs: dict[str, Any]) -> Any:
|
|
145
160
|
if job.resume_session_id:
|
|
146
161
|
return await client.resume_session(job.resume_session_id, **kwargs)
|
|
147
162
|
return await client.create_session(**kwargs)
|
|
@@ -7,7 +7,11 @@ multi-job engine tests can script an entire run.
|
|
|
7
7
|
|
|
8
8
|
Response object shape (all fields optional):
|
|
9
9
|
``{"text": str, "json": dict|list, "session_id": str, "sleep_s": float,
|
|
10
|
-
"events": [{"type": str, "data": {...}}], "fail": str
|
|
10
|
+
"events": [{"type": str, "data": {...}}], "fail": str,
|
|
11
|
+
"files": {"relative/path": "content"}}``
|
|
12
|
+
|
|
13
|
+
``files`` are written relative to the worker process cwd — modelling an
|
|
14
|
+
executor that produces artifacts in the run workspace.
|
|
11
15
|
"""
|
|
12
16
|
|
|
13
17
|
from __future__ import annotations
|
|
@@ -73,6 +77,10 @@ class EchoBackend:
|
|
|
73
77
|
raise RuntimeError(str(response["fail"]))
|
|
74
78
|
if sleep_s := float(response.get("sleep_s", 0)):
|
|
75
79
|
time.sleep(sleep_s)
|
|
80
|
+
for relative, content in response.get("files", {}).items():
|
|
81
|
+
target = Path.cwd() / relative
|
|
82
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
83
|
+
target.write_text(str(content))
|
|
76
84
|
for scripted_event in response.get("events", []):
|
|
77
85
|
emit(scripted_event["type"], **scripted_event.get("data", {}))
|
|
78
86
|
text = str(response.get("text", ""))
|
|
@@ -92,6 +92,10 @@ class JobRequest(ProtocolModel):
|
|
|
92
92
|
|
|
93
93
|
# kind == "shell.check"
|
|
94
94
|
argv: list[str] | None = None
|
|
95
|
+
|
|
96
|
+
# agent.session + shell.check: in-sandbox working directory. The worker
|
|
97
|
+
# process chdirs here (via --cwd) so agent sessions and shell commands
|
|
98
|
+
# run in the run's canonical workspace.
|
|
95
99
|
cwd: str | None = None
|
|
96
100
|
|
|
97
101
|
# kind == "github.op"
|
|
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
|