sbxloop 0.4.0__tar.gz → 0.4.2__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.
Files changed (42) hide show
  1. {sbxloop-0.4.0 → sbxloop-0.4.2}/.gitignore +4 -0
  2. {sbxloop-0.4.0 → sbxloop-0.4.2}/PKG-INFO +2 -2
  3. {sbxloop-0.4.0 → sbxloop-0.4.2}/hatch_build.py +6 -0
  4. {sbxloop-0.4.0 → sbxloop-0.4.2}/pyproject.toml +18 -3
  5. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/__init__.py +10 -1
  6. sbxloop-0.4.0/src/sbxloop/_vendor/sbxloop_worker-0.4.0-py3-none-any.whl → sbxloop-0.4.2/src/sbxloop/_vendor/sbxloop_worker-0.4.2-py3-none-any.whl +0 -0
  7. sbxloop-0.4.2/src/sbxloop/_version.py +24 -0
  8. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/cli/tui.py +15 -3
  9. {sbxloop-0.4.0 → sbxloop-0.4.2}/README.md +0 -0
  10. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/cli/__init__.py +0 -0
  11. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/cli/app.py +0 -0
  12. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/cli/doctor.py +0 -0
  13. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/config.py +0 -0
  14. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/deliver.py +0 -0
  15. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/engine/__init__.py +0 -0
  16. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/engine/engine.py +0 -0
  17. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/engine/model.py +0 -0
  18. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/engine/phases.py +0 -0
  19. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/engine/prompts/__init__.py +0 -0
  20. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/engine/prompts/decompose.md +0 -0
  21. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/engine/prompts/execute.md +0 -0
  22. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/engine/prompts/plan.md +0 -0
  23. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/engine/prompts/scrutinize.md +0 -0
  24. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/engine/prompts/validate.md +0 -0
  25. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/engine/store.py +0 -0
  26. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/errors.py +0 -0
  27. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/events.py +0 -0
  28. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/gh/__init__.py +0 -0
  29. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/gh/ops.py +0 -0
  30. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/gh/reporter.py +0 -0
  31. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/ids.py +0 -0
  32. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/py.typed +0 -0
  33. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/sbx/__init__.py +0 -0
  34. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/sbx/cli.py +0 -0
  35. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/sbx/models.py +0 -0
  36. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/sbx/pair.py +0 -0
  37. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/sbx/parse.py +0 -0
  38. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/sbx/provision.py +0 -0
  39. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/sbx/sandbox.py +0 -0
  40. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/worker/__init__.py +0 -0
  41. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/worker/client.py +0 -0
  42. {sbxloop-0.4.0 → sbxloop-0.4.2}/src/sbxloop/worker/wheel.py +0 -0
@@ -221,3 +221,7 @@ __marimo__/
221
221
  .sbxloop/
222
222
  .sdxloop/
223
223
  packages/sbxloop/src/sbxloop/_vendor/
224
+
225
+ # written at build time by hatch-vcs
226
+ packages/sbxloop/src/sbxloop/_version.py
227
+ packages/sbxloop-worker/src/sbxloop_worker/_version.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sbxloop
3
- Version: 0.4.0
3
+ Version: 0.4.2
4
4
  Summary: Agentic loop orchestration on Docker Sandboxes (sbx) with isolated credential domains
5
5
  Project-URL: Homepage, https://github.com/brettbergin/sbxloop
6
6
  Project-URL: Repository, https://github.com/brettbergin/sbxloop
@@ -19,7 +19,7 @@ Requires-Python: >=3.11
19
19
  Requires-Dist: pydantic>=2.7
20
20
  Requires-Dist: python-dotenv>=1.0
21
21
  Requires-Dist: rich>=13.7
22
- Requires-Dist: sbxloop-worker==0.4.0
22
+ Requires-Dist: sbxloop-worker
23
23
  Requires-Dist: typer>=0.12
24
24
  Description-Content-Type: text/markdown
25
25
 
@@ -29,6 +29,12 @@ class VendorWorkerWheelHook(BuildHookInterface): # type: ignore[type-arg]
29
29
  host_version = self.metadata.version
30
30
  expected = f"sbxloop_worker-{host_version}-py3-none-any.whl"
31
31
 
32
+ # The static dependency list can't carry an exact pin now that versions
33
+ # come from git tags (hatch-vcs), so add the lockstep pin to the wheel
34
+ # metadata here.
35
+ if self.target_name == "wheel":
36
+ build_data.setdefault("dependencies", []).append(f"sbxloop-worker=={host_version}")
37
+
32
38
  if (vendor_dir / expected).is_file():
33
39
  return
34
40
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sbxloop"
3
- version = "0.4.0"
3
+ dynamic = ["version"] # derived from git tags by hatch-vcs (see [tool.hatch.version])
4
4
  description = "Agentic loop orchestration on Docker Sandboxes (sbx) with isolated credential domains"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -21,7 +21,10 @@ dependencies = [
21
21
  "python-dotenv>=1.0",
22
22
  "typer>=0.12",
23
23
  "rich>=13.7",
24
- "sbxloop-worker==0.4.0",
24
+ # Unpinned here because the version is dynamic; the build hook
25
+ # (hatch_build.py) adds the exact lockstep pin `sbxloop-worker==X.Y.Z`
26
+ # to the wheel metadata at build time.
27
+ "sbxloop-worker",
25
28
  ]
26
29
 
27
30
  [project.scripts]
@@ -36,9 +39,21 @@ Issues = "https://github.com/brettbergin/sbxloop/issues"
36
39
  sbxloop-worker = { workspace = true }
37
40
 
38
41
  [build-system]
39
- requires = ["hatchling>=1.27"]
42
+ requires = ["hatchling>=1.27", "hatch-vcs"]
40
43
  build-backend = "hatchling.build"
41
44
 
45
+ # Both workspace packages version from the same repo-root git tag, keeping the
46
+ # lockstep invariant by construction. `fallback_root` lets a wheel built from
47
+ # an extracted sdist (no git) pick the version up from the sdist's PKG-INFO.
48
+ [tool.hatch.version]
49
+ source = "vcs"
50
+ raw-options = { root = "../..", fallback_root = ".", local_scheme = "no-local-version", fallback_version = "0.0.0" }
51
+
52
+ # Write the resolved version into the package so `sbxloop.__version__` and
53
+ # `sbxloop --version` report it at runtime.
54
+ [tool.hatch.build.hooks.vcs]
55
+ version-file = "src/sbxloop/_version.py"
56
+
42
57
  [tool.hatch.build.targets.wheel]
43
58
  packages = ["src/sbxloop"]
44
59
  artifacts = ["src/sbxloop/_vendor/*.whl"]
@@ -6,7 +6,16 @@ agentic layer, and a GitHub-ops sandbox holding only ``GH_TOKEN`` for
6
6
  user-facing GitHub interactions. The balanced network policy is the default.
7
7
  """
8
8
 
9
- __version__ = "0.4.0"
9
+ try:
10
+ # written at build time by hatch-vcs (see pyproject [tool.hatch.build.hooks.vcs])
11
+ from sbxloop._version import __version__
12
+ except ImportError: # pragma: no cover - raw source tree that was never built
13
+ try:
14
+ from importlib.metadata import version as _pkg_version
15
+
16
+ __version__ = _pkg_version("sbxloop")
17
+ except Exception:
18
+ __version__ = "0.0.0"
10
19
 
11
20
  from sbxloop.config import Budgets, Config, load_config
12
21
  from sbxloop.engine import LoopEngine, RunResult, run_outcome
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '0.4.2'
22
+ __version_tuple__ = version_tuple = (0, 4, 2)
23
+
24
+ __commit_id__ = commit_id = None
@@ -116,14 +116,22 @@ def render_event(event: Event) -> RenderableType | None:
116
116
  tool = data.get("tool") or "tool"
117
117
  success = data.get("success")
118
118
  exit_code = data.get("exit_code")
119
- if success is None and exit_code is None:
119
+ error = str(data.get("error") or "").strip()
120
+ if success is None and exit_code is None and not error:
120
121
  return None # nothing informative beyond the start line
121
- if success or (success is None and exit_code == 0):
122
+ if success or (success is None and exit_code == 0 and not error):
122
123
  suffix = " exit 0" if exit_code == 0 else ""
123
124
  return Text(f"{_stamp(event)} ✓ {tool}{suffix}", style="green dim")
124
125
  suffix = f" exit {exit_code}" if exit_code is not None else ""
125
126
  failure = Text(f"{_stamp(event)} ✗ {tool}{suffix}", style="red")
126
- tail = str(data.get("output") or "").strip()
127
+ args = _one_line(str(data.get("args") or ""))
128
+ if args:
129
+ failure.append(" $ ", style="bold red")
130
+ failure.append(args, style="red dim")
131
+ failure.overflow = "fold"
132
+ # Failed executions carry the reason in `error` (the SDK omits
133
+ # `output` on failure); prefer real output when both exist.
134
+ tail = str(data.get("output") or "").strip() or error
127
135
  if tail:
128
136
  return Group(
129
137
  failure,
@@ -224,13 +232,17 @@ def format_event(event: Event) -> str:
224
232
  if event.data.get("task_id"):
225
233
  parts.append(f"[{event.data['task_id']}]")
226
234
  keys = ("state", "content", "tool", "op", "line", "message", "outcome", "error", "url", "path")
235
+ picked = ""
227
236
  for key in keys:
228
237
  if event.data.get(key):
238
+ picked = key
229
239
  value = str(event.data[key]).replace("\n", " ")
230
240
  parts.append(value[:160])
231
241
  break
232
242
  if event.data.get("args"):
233
243
  parts.append(_one_line(str(event.data["args"]), 120))
244
+ if picked != "error" and event.data.get("error"):
245
+ parts.append(_one_line(str(event.data["error"]), 160))
234
246
  return " ".join(parts)
235
247
 
236
248
 
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