agentixx 0.2.2__tar.gz → 0.2.3__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 (80) hide show
  1. {agentixx-0.2.2 → agentixx-0.2.3}/PKG-INFO +1 -1
  2. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/__init__.py +1 -1
  3. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/cli/build.py +38 -19
  4. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/nix/wrapper.nix.tmpl +7 -1
  5. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/server/worker/client.py +16 -1
  6. {agentixx-0.2.2 → agentixx-0.2.3}/pyproject.toml +1 -1
  7. {agentixx-0.2.2 → agentixx-0.2.3}/.claude/scheduled_tasks.lock +0 -0
  8. {agentixx-0.2.2 → agentixx-0.2.3}/.claude/settings.local.json +0 -0
  9. {agentixx-0.2.2 → agentixx-0.2.3}/.claude/skills/agent-integration/SKILL.md +0 -0
  10. {agentixx-0.2.2 → agentixx-0.2.3}/.github/workflows/docs.yml +0 -0
  11. {agentixx-0.2.2 → agentixx-0.2.3}/.github/workflows/test.yml +0 -0
  12. {agentixx-0.2.2 → agentixx-0.2.3}/.gitignore +0 -0
  13. {agentixx-0.2.2 → agentixx-0.2.3}/ARCHITECTURE.md +0 -0
  14. {agentixx-0.2.2 → agentixx-0.2.3}/CLAUDE.md +0 -0
  15. {agentixx-0.2.2 → agentixx-0.2.3}/LICENSE +0 -0
  16. {agentixx-0.2.2 → agentixx-0.2.3}/README.md +0 -0
  17. {agentixx-0.2.2 → agentixx-0.2.3}/ROADMAP.md +0 -0
  18. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/cli/__init__.py +0 -0
  19. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/cli/__main__.py +0 -0
  20. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/cli/_resolve.py +0 -0
  21. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/deployment/__init__.py +0 -0
  22. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/deployment/_plugin.py +0 -0
  23. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/deployment/base.py +0 -0
  24. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/log/__init__.py +0 -0
  25. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/log/_bridge.py +0 -0
  26. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/nix/builder.nix +0 -0
  27. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/nix/flake.lock +0 -0
  28. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/nix/flake.nix +0 -0
  29. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/PROTOCOL.md +0 -0
  30. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/__init__.py +0 -0
  31. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/client/__init__.py +0 -0
  32. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/client/_sio_facade.py +0 -0
  33. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/client/client.py +0 -0
  34. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/server/__init__.py +0 -0
  35. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/server/app.py +0 -0
  36. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/server/sio.py +0 -0
  37. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/server/worker/__init__.py +0 -0
  38. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/server/worker/__main__.py +0 -0
  39. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/server/worker/invoker.py +0 -0
  40. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/server/worker/process.py +0 -0
  41. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/shared/__init__.py +0 -0
  42. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/shared/callables.py +0 -0
  43. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/shared/codec.py +0 -0
  44. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/shared/framing.py +0 -0
  45. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/shared/idents.py +0 -0
  46. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/runtime/shared/models.py +0 -0
  47. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/sio.py +0 -0
  48. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/trace/__init__.py +0 -0
  49. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/trace/_bridge.py +0 -0
  50. {agentixx-0.2.2 → agentixx-0.2.3}/agentix/trace/processors.py +0 -0
  51. {agentixx-0.2.2 → agentixx-0.2.3}/docs/DEPLOY.md +0 -0
  52. {agentixx-0.2.2 → agentixx-0.2.3}/docs/concepts/bundles.mdx +0 -0
  53. {agentixx-0.2.2 → agentixx-0.2.3}/docs/concepts/remote-calls.mdx +0 -0
  54. {agentixx-0.2.2 → agentixx-0.2.3}/docs/deployment.mdx +0 -0
  55. {agentixx-0.2.2 → agentixx-0.2.3}/docs/development.mdx +0 -0
  56. {agentixx-0.2.2 → agentixx-0.2.3}/docs/docs.json +0 -0
  57. {agentixx-0.2.2 → agentixx-0.2.3}/docs/index.mdx +0 -0
  58. {agentixx-0.2.2 → agentixx-0.2.3}/docs/integrate-agent.mdx +0 -0
  59. {agentixx-0.2.2 → agentixx-0.2.3}/docs/integrate-dataset.mdx +0 -0
  60. {agentixx-0.2.2 → agentixx-0.2.3}/docs/quickstart.mdx +0 -0
  61. {agentixx-0.2.2 → agentixx-0.2.3}/docs/reference/architecture.mdx +0 -0
  62. {agentixx-0.2.2 → agentixx-0.2.3}/docs/reference/cli.mdx +0 -0
  63. {agentixx-0.2.2 → agentixx-0.2.3}/tests/__init__.py +0 -0
  64. {agentixx-0.2.2 → agentixx-0.2.3}/tests/_concurrent_target.py +0 -0
  65. {agentixx-0.2.2 → agentixx-0.2.3}/tests/_namespace_target.py +0 -0
  66. {agentixx-0.2.2 → agentixx-0.2.3}/tests/_rpc_helpers.py +0 -0
  67. {agentixx-0.2.2 → agentixx-0.2.3}/tests/_trace_target.py +0 -0
  68. {agentixx-0.2.2 → agentixx-0.2.3}/tests/_user_app_target.py +0 -0
  69. {agentixx-0.2.2 → agentixx-0.2.3}/tests/_worker_target.py +0 -0
  70. {agentixx-0.2.2 → agentixx-0.2.3}/tests/conftest.py +0 -0
  71. {agentixx-0.2.2 → agentixx-0.2.3}/tests/test_concurrent_remote.py +0 -0
  72. {agentixx-0.2.2 → agentixx-0.2.3}/tests/test_cross_process_trace.py +0 -0
  73. {agentixx-0.2.2 → agentixx-0.2.3}/tests/test_models.py +0 -0
  74. {agentixx-0.2.2 → agentixx-0.2.3}/tests/test_namespace_roundtrip.py +0 -0
  75. {agentixx-0.2.2 → agentixx-0.2.3}/tests/test_plugin_axes.py +0 -0
  76. {agentixx-0.2.2 → agentixx-0.2.3}/tests/test_plugin_registry.py +0 -0
  77. {agentixx-0.2.2 → agentixx-0.2.3}/tests/test_remote_importable_module.py +0 -0
  78. {agentixx-0.2.2 → agentixx-0.2.3}/tests/test_rpc_protocol.py +0 -0
  79. {agentixx-0.2.2 → agentixx-0.2.3}/tests/test_worker_subprocess.py +0 -0
  80. {agentixx-0.2.2 → agentixx-0.2.3}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentixx
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: Sandboxed rollouts you call like typed Python (import as `agentix`)
5
5
  Project-URL: Homepage, https://github.com/Agentiix/Agentix
6
6
  Author: Agentiix
@@ -24,7 +24,7 @@ from agentix.runtime.client import RemoteCallError, RuntimeClient
24
24
  from agentix.runtime.client._sio_facade import AsyncClientNamespace
25
25
  from agentix.sio import Namespace, RemoteSioError, register_namespace
26
26
 
27
- __version__ = "0.2.2"
27
+ __version__ = "0.2.3"
28
28
 
29
29
  __all__ = [
30
30
  "AsyncClientNamespace",
@@ -87,13 +87,23 @@ def _stage_builder(dest: Path) -> None:
87
87
  (dest / fname).write_bytes(src.read_bytes())
88
88
 
89
89
 
90
- def _discover_plugin_nix(stage_plugin_dir: Path) -> list[str]:
91
- """Find every `agentix.<short>/default.nix` shipped by installed wheels.
92
-
93
- Returns the list of nix-relative paths (one per plugin) ready to drop
94
- into the generated wrapper flake. Each plugin's default.nix is copied
95
- into `stage_plugin_dir/<short>.nix` so the flake context is self-
96
- contained Nix won't follow absolute paths outside the flake root.
90
+ def _discover_plugin_nix(stage_plugin_dir: Path, project_src: Path) -> list[str]:
91
+ """Find every `default.nix` that contributes system binaries to the bundle.
92
+
93
+ Two sources, in order:
94
+
95
+ 1. Plugin wheels installed under the `agentix` namespace
96
+ (`agentix.<short>/default.nix`). These ship via `pip install
97
+ agentix-<plugin>` and are how runtime extensions add their CLI
98
+ deps (e.g. `agentix-runtime-basic` adds `bash`).
99
+ 2. The **user project root**'s own `default.nix`, if present —
100
+ lets a project pull in extra binaries (`claude`, `ffmpeg`, ...)
101
+ without packaging a fake plugin.
102
+
103
+ Each discovered file is copied into `stage_plugin_dir/<name>.nix`
104
+ so the flake context is self-contained; Nix won't follow absolute
105
+ paths outside the flake root. Returns the list of nix-relative
106
+ paths ready to drop into the generated wrapper flake.
97
107
  """
98
108
  stage_plugin_dir.mkdir(parents=True)
99
109
  nix_paths: list[str] = []
@@ -101,18 +111,27 @@ def _discover_plugin_nix(stage_plugin_dir: Path) -> list[str]:
101
111
  try:
102
112
  agentix_root = resources.files("agentix")
103
113
  except (ModuleNotFoundError, FileNotFoundError):
104
- return nix_paths
114
+ agentix_root = None
115
+
116
+ if agentix_root is not None:
117
+ for entry in agentix_root.iterdir():
118
+ if not entry.is_dir():
119
+ continue
120
+ nix_file = entry / "default.nix"
121
+ if not nix_file.is_file():
122
+ continue
123
+ short = entry.name
124
+ target = stage_plugin_dir / f"{short}.nix"
125
+ target.write_bytes(nix_file.read_bytes())
126
+ nix_paths.append(f"./plugins/{short}.nix")
127
+
128
+ # Project root default.nix, when present.
129
+ project_nix = project_src / "default.nix"
130
+ if project_nix.is_file():
131
+ target = stage_plugin_dir / "project.nix"
132
+ target.write_bytes(project_nix.read_bytes())
133
+ nix_paths.append("./plugins/project.nix")
105
134
 
106
- for entry in agentix_root.iterdir():
107
- if not entry.is_dir():
108
- continue
109
- nix_file = entry / "default.nix"
110
- if not nix_file.is_file():
111
- continue
112
- short = entry.name
113
- target = stage_plugin_dir / f"{short}.nix"
114
- target.write_bytes(nix_file.read_bytes())
115
- nix_paths.append(f"./plugins/{short}.nix")
116
135
  return nix_paths
117
136
 
118
137
 
@@ -274,7 +293,7 @@ def main(argv: Sequence[str] | None = None) -> int:
274
293
  def _stage(stage: Path) -> None:
275
294
  _stage_builder(stage / "_builder")
276
295
  _stage_project(src, stage / "project")
277
- plugin_paths = _discover_plugin_nix(stage / "plugins")
296
+ plugin_paths = _discover_plugin_nix(stage / "plugins", src)
278
297
  wrapper = _render_wrapper(
279
298
  name=name,
280
299
  tag=tag,
@@ -6,7 +6,13 @@
6
6
  outputs = { self, agentix }:
7
7
  let
8
8
  system = "@SYSTEM@";
9
- pkgs = agentix.inputs.nixpkgs.legacyPackages.${system};
9
+ # Re-import nixpkgs with `config.allowUnfree = true` so plugin
10
+ # `default.nix` files can pull unfree binaries (e.g. claude CLI).
11
+ # Plugins that don't need unfree packages are unaffected.
12
+ pkgs = import agentix.inputs.nixpkgs {
13
+ inherit system;
14
+ config.allowUnfree = true;
15
+ };
10
16
  in {
11
17
  packages.${system}.bundle = agentix.lib.mkBundle {
12
18
  inherit pkgs;
@@ -26,6 +26,11 @@ logger = logging.getLogger("agentix.runtime.server.worker.client")
26
26
 
27
27
  _WORKER_START_TIMEOUT = 15.0
28
28
  _DEFAULT_WORKER_PATH = "/usr/local/bin:/usr/bin:/bin"
29
+ # Plugin `default.nix` derivations are symlink-joined into this path
30
+ # inside the bundle image (see `agentix/nix/builder.nix`). Worker code
31
+ # (`subprocess.run("claude", ...)`, `c.remote(cc.run, ...)`, ...) must
32
+ # be able to find those binaries by bare name.
33
+ _RUNTIME_BIN_PATH = "/nix/runtime/bin"
29
34
  _STRIPPED_ENV = {
30
35
  "LD_LIBRARY_PATH",
31
36
  "LD_PRELOAD",
@@ -43,7 +48,17 @@ def _clean_worker_env(runtime_bin_dir: Path | None) -> dict[str, str]:
43
48
  for key, value in os.environ.items()
44
49
  if key not in _STRIPPED_ENV and not any(key.startswith(prefix) for prefix in _STRIPPED_ENV_PREFIXES)
45
50
  }
46
- env["PATH"] = f"{runtime_bin_dir}:{_DEFAULT_WORKER_PATH}" if runtime_bin_dir is not None else _DEFAULT_WORKER_PATH
51
+ # Build PATH from: the venv's bin (`runtime_bin_dir`), the bundle's
52
+ # symlink-join (`/nix/runtime/bin`), then a minimal system fallback.
53
+ # Inside the bundle image the first two are siblings and both must
54
+ # be searchable; outside the bundle, only the first one exists.
55
+ parts: list[str] = []
56
+ if runtime_bin_dir is not None:
57
+ parts.append(str(runtime_bin_dir))
58
+ if _RUNTIME_BIN_PATH not in parts:
59
+ parts.append(_RUNTIME_BIN_PATH)
60
+ parts.append(_DEFAULT_WORKER_PATH)
61
+ env["PATH"] = ":".join(parts)
47
62
  return env
48
63
 
49
64
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agentixx"
3
- version = "0.2.2"
3
+ version = "0.2.3"
4
4
  description = "Sandboxed rollouts you call like typed Python (import as `agentix`)"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
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