Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/agent_harness/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,7 @@ def live_routes() -> dict[str, Chain]:
github=GitHub(args.repo) if args.repo else None,
base_branch=args.base,
ui_base_url=args.session_host,
context_budget=args.context_budget,
on_event=emit,
push=not args.no_push,
project_id=args.project,
Expand Down
14 changes: 13 additions & 1 deletion src/agent_harness/session_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ def __init__(
base_branch: str = "main",
branch_prefix: str = "harness/",
worktrees: Path | None = None,
context_budget: int = DEFAULT_CONTEXT_BUDGET,
ui_base_url: str = "",
session_max_age: float = DEFAULT_MAX_AGE_SECONDS,
on_event: Callable[[dict[str, Any]], None] | None = None,
Expand All @@ -195,6 +196,17 @@ def __init__(
self.base_branch = base_branch
self.branch_prefix = branch_prefix
self.worktrees = Path(worktrees) if worktrees else self.repo.parent / ".harness-work"
#: How much of a touched file the reviewer may be shown. Hardcoded to
#: the default when the review helpers were shared, which meant a
#: 272 KB file was always "too large to include" — and the reviewer
#: said so and rejected, correctly, for evidence it had been denied:
#:
#: "web/src/main.tsx is not included in full and I cannot inspect
#: the surrounding markup"
#:
#: The headless executor has taken this from configuration since #150.
#: Session mode reviewing large files needs the same lever.
self.context_budget = context_budget
self.ui_base_url = ui_base_url
self.session_max_age = session_max_age
self.on_event = on_event
Expand Down Expand Up @@ -774,7 +786,7 @@ def _review(
diff=diff[:20000],
# The same helpers the headless reviewer uses, so a correction to
# either cannot land in one executor and not the other (#167).
context=review_context(tree, diff, DEFAULT_CONTEXT_BUDGET),
context=review_context(tree, diff, self.context_budget),
checks=review_checks_prompt(self.checks.commands),
)
try:
Expand Down
25 changes: 25 additions & 0 deletions tests/test_reviewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,3 +274,28 @@ def test_a_short_verdict_is_kept_whole() -> None:
from agent_harness.executor import review_reason

assert review_reason("REJECTED\nToo narrow.") == "REJECTED\nToo narrow."


def test_the_session_reviewer_budget_is_configurable(tmp_path: Any) -> None:
"""A 272 KB file was always "too large to include", so the reviewer was
denied the evidence it then correctly rejected for lacking:

"web/src/main.tsx is not included in full and I cannot inspect the
surrounding markup"

The headless executor has taken this from configuration since #150; when
the review helpers were shared the session side got the default hardcoded
instead, which is a ceiling no deployment could raise.
"""
from agent_harness.executor import DEFAULT_CONTEXT_BUDGET
from agent_harness.session_executor import SessionExecutor
from agent_harness.work import WorkQueue

queue = WorkQueue(str(tmp_path / "w.sqlite"))
host = type("Host", (), {})()

default = SessionExecutor(queue, host, tmp_path)
raised = SessionExecutor(queue, host, tmp_path, context_budget=700_000)

assert default.context_budget == DEFAULT_CONTEXT_BUDGET, "unchanged by default"
assert raised.context_budget == 700_000, "and a deployment can raise it"
Loading