feat: add versioned execution profiles
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

This commit is contained in:
tegwick 2026-08-21 00:21:53 +02:00
parent 641e85f5a8
commit 1cd890d871
34 changed files with 2087 additions and 471 deletions

View file

@ -13,8 +13,15 @@ import shutil
import subprocess
from typing import Any
from glas_harness.contract import Rein, SandboxHandle, ToolCall, ToolResult
from glas_harness.reins._shared import git_head, write_task_file
from glas_harness.contract import (
ExecutionSummary,
HarnessProfile,
Rein,
SandboxHandle,
ToolCall,
ToolResult,
)
from glas_harness.reins._shared import git_head, parse_json_object, write_task_file
class ReinOpenWeightsNotInstalled(RuntimeError):
@ -22,9 +29,20 @@ class ReinOpenWeightsNotInstalled(RuntimeError):
class ReinOpenWeights(Rein):
def __init__(self, cli_bin: str = "rein-openweights", model: str | None = None) -> None:
def __init__(
self,
cli_bin: str = "rein-openweights",
model: str | None = None,
max_turns: int | None = None,
budget_tokens: int | None = None,
tool_profile: str | None = None,
) -> None:
self.cli_bin = cli_bin
self.model = model
self.max_turns = max_turns
self.budget_tokens = budget_tokens
self.tool_profile = tool_profile
self._last_result: dict[str, Any] = {}
def _bin(self) -> str:
resolved = shutil.which(self.cli_bin)
@ -35,7 +53,7 @@ class ReinOpenWeights(Rein):
return resolved
def start_session(
self, profile: dict[str, Any], inputs: dict[str, str], sandbox: SandboxHandle
self, profile: HarnessProfile, inputs: dict[str, str], sandbox: SandboxHandle
) -> dict[str, str]:
target_repo = (
inputs.get("target_repo")
@ -46,7 +64,10 @@ class ReinOpenWeights(Rein):
raise ValueError("no target_repo resolvable from inputs or sandbox reachability")
task_file = inputs.get("task_file") or write_task_file(
inputs["title"], inputs["description"], target_repo
inputs["title"],
inputs["description"],
target_repo,
timeout_seconds=profile.limits.timeout_seconds or 600,
)
return {
@ -60,14 +81,48 @@ class ReinOpenWeights(Rein):
argv = [self._bin(), "run", "--task-file", session["task_file"], "--no-hub"]
if self.model:
argv += ["--model", self.model]
if self.max_turns:
argv += ["--max-turns", str(self.max_turns)]
if self.budget_tokens:
argv += ["--budget-tokens", str(self.budget_tokens)]
if self.tool_profile:
argv += ["--tool-profile", self.tool_profile]
proc = subprocess.run(argv, capture_output=True, text=True)
ok = proc.returncode == 0
return ToolResult(ok=ok, output=proc.stdout, error=None if ok else proc.stderr)
self._last_result = parse_json_object(proc.stdout)
return ToolResult(
ok=ok,
output=proc.stdout,
error=None if ok else (proc.stderr or self._last_result.get("reason")),
events_completeness="unavailable",
tokens_spent=self._last_result.get("tokens_spent"),
duration_s=self._last_result.get("execution_time_s"),
resolved_model=self._last_result.get("model") or self.model,
metadata={
"turns": self._last_result.get("turns"),
"tool_profile": self._last_result.get("tool_profile") or self.tool_profile,
},
)
def end_session(self, session: dict[str, str]) -> dict[str, str]:
def end_session(self, session: dict[str, str]) -> ExecutionSummary:
head_after = git_head(session["target_repo"])
committed = bool(head_after) and head_after != session.get("head_before")
return {
"commit_sha": head_after or "",
"committed": str(committed),
}
reported_ok = bool(self._last_result.get("ok", committed))
reason = self._last_result.get("reason") or None
outcome = "succeeded" if committed and reported_ok else (
"refused" if reason == "no OpenRouter credential resolved" else "failed"
)
return ExecutionSummary(
commit_sha=head_after or None,
committed=committed,
outcome=outcome,
reason=reason,
tokens_spent=self._last_result.get("tokens_spent"),
duration_s=self._last_result.get("execution_time_s"),
resolved_model=self._last_result.get("model") or self.model,
artifacts=[head_after] if committed and head_after else [],
metadata={
"turns": self._last_result.get("turns"),
"tool_profile": self._last_result.get("tool_profile") or self.tool_profile,
},
)