- harness/es.py: append-only event store + проекции (образец — кооп-портал) - harness/levels.py: уровни 1с/1м/1ч/1д, контекст ∝ масштабу - harness/scheduler.py: уровневые потоки, идемпотентные тики, absorbed-стабы - harness/isolated_runner.py + _llm_worker.py: LLM-тик в сабпроцессе (глобальный asyncio-рантайм Strands не переживает 2+ create_harness) - cli.py: init/task/tasks/status/events + requeue (написан самим минутным агентом) - 9router: отдельный ключ sk-simbiot, модель auto (glm-5.3 первым)
80 lines
2.9 KiB
Python
80 lines
2.9 KiB
Python
"""Locates the `monty` CLI binary that worker pools run as subprocesses.
|
|
|
|
The binary ships in the `pydantic-monty-runtime` wheel (a maturin `bin`-bindings
|
|
package, the same pattern `uv` and `ruff` use), which installs it into the
|
|
environment's scripts directory. Installing `pydantic-monty` pulls that in; the
|
|
`pydantic-monty-client` distribution alone does not, so the other resolution
|
|
steps below matter when only the bindings are installed.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import shutil
|
|
import sys
|
|
import sysconfig
|
|
from pathlib import Path
|
|
|
|
_BIN_NAME = 'monty.exe' if sys.platform == 'win32' else 'monty'
|
|
|
|
|
|
def find_monty_binary(explicit: str | Path | None = None) -> str:
|
|
"""Resolves the `monty` binary path used to spawn pool workers.
|
|
|
|
Resolution order:
|
|
|
|
1. the explicit `binary_path` argument, when given
|
|
2. the `MONTY_BIN` environment variable
|
|
3. the environment's scripts directory (where the `pydantic-monty-runtime`
|
|
wheel installs the binary)
|
|
4. a `monty` executable on `PATH`
|
|
5. a cargo-built binary in the monty workspace, when running from an
|
|
editable/development install of this package
|
|
"""
|
|
if explicit is not None:
|
|
return str(explicit)
|
|
env = os.environ.get('MONTY_BIN')
|
|
if env:
|
|
return env
|
|
for scripts_dir in _script_dirs():
|
|
candidate = scripts_dir / _BIN_NAME
|
|
if candidate.is_file():
|
|
return str(candidate)
|
|
found = shutil.which('monty')
|
|
if found:
|
|
return found
|
|
dev = _development_binary()
|
|
if dev is not None:
|
|
return str(dev)
|
|
raise FileNotFoundError(
|
|
'could not locate the `monty` binary required to run sandboxed code; '
|
|
'install it with `pip install pydantic-monty` (or `make dev-py` in the monty repo), '
|
|
'pass binary_path=..., or set the MONTY_BIN environment variable'
|
|
)
|
|
|
|
|
|
def _script_dirs() -> list[Path]:
|
|
"""Scripts directories of the current environment, most specific first."""
|
|
dirs = [Path(sysconfig.get_path('scripts'))]
|
|
# user-scheme installs (`pip install --user`) place scripts elsewhere
|
|
try:
|
|
dirs.append(Path(sysconfig.get_path('scripts', f'{os.name}_user')))
|
|
except KeyError:
|
|
pass
|
|
return dirs
|
|
|
|
|
|
def _development_binary() -> Path | None:
|
|
"""A cargo-built `monty` next to an editable install inside the monty repo.
|
|
|
|
With `maturin develop`, this file lives at
|
|
`<repo>/crates/monty-python/python/pydantic_monty/_binary.py`, so a
|
|
cargo-built binary is at `<repo>/target/{debug,release}/monty`. Prefer the
|
|
most recently built one so `cargo build` and `cargo build --release`
|
|
both behave as expected.
|
|
"""
|
|
repo = Path(__file__).resolve().parents[4]
|
|
if not (repo / 'Cargo.toml').is_file():
|
|
return None
|
|
candidates = [path for profile in ('debug', 'release') if (path := repo / 'target' / profile / _BIN_NAME).is_file()]
|
|
return max(candidates, key=lambda path: path.stat().st_mtime, default=None)
|