Skip to content

fix(agent): steer background review to permitted tools - #65803

Closed
henrynguyeninfo1 wants to merge 1 commit into
NousResearch:mainfrom
henrynguyeninfo1:henrynguyeninfo1/issue-61521-background-review-toolset
Closed

fix(agent): steer background review to permitted tools#65803
henrynguyeninfo1 wants to merge 1 commit into
NousResearch:mainfrom
henrynguyeninfo1:henrynguyeninfo1/issue-61521-background-review-toolset

Conversation

@henrynguyeninfo1

Copy link
Copy Markdown

Summary

  • preserve the background review fork's parent tool schemas for prompt-cache byte parity
  • make denied file-tool results name the permitted skills_list, skill_view, and skill_manage path
  • cover the model-visible read_file denial through the real thread-local dispatch gate

Root cause

The review fork intentionally advertises the parent agent's full tool schema, but runtime dispatch only permits memory and skill tools. The denial result previously said only that memory/skill tools were allowed, so it did not redirect models from read_file or patch to the APIs that satisfy the skill manager's read-before-write guard.

Testing

  • uv run --extra dev pytest tests/run_agent/test_background_review.py tests/run_agent/test_background_review_cost_controls.py tests/run_agent/test_background_review_cache_parity.py tests/run_agent/test_background_review_summary.py tests/run_agent/test_background_review_toolset_restriction.py tests/test_background_review_session_isolation.py tests/test_background_review_list_shapes.py tests/hermes_cli/test_plugins.py::TestThreadToolWhitelist -q
  • uv run --extra dev ruff check agent/background_review.py tests/run_agent/test_background_review_toolset_restriction.py
  • uv run --extra dev python -m py_compile agent/background_review.py tests/run_agent/test_background_review_toolset_restriction.py

Tested on macOS.

Alternative considered

Narrowing the fork's advertised schemas would eliminate invalid calls earlier, but it would break the intentional byte parity with the parent request and lose prompt-cache reuse. This change keeps parity and improves self-correction at the dispatch boundary.

Fixes #61521

Rejected: narrow review tool schemas | breaks prompt-cache byte parity with the parent agent

Not-tested: live provider response after a denied file-tool call

RISK: model self-correction remains probabilistic across providers
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint duplicate This issue or pull request already exists labels Jul 16, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Duplicate of #61618: both update the background-review denial guidance to direct denied file-tool calls toward the permitted skill and memory tools. #61618 also updates the review prompt, making it the broader earlier version.

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Approved (read-only token — formal approval requires write access)

Improves the denial message for background review when a non-whitelisted tool is called. The new message guides users toward the correct tools (skill_view, skill_manage) instead of just saying "not allowed."

  • Small, helpful UX improvement
  • Good test coverage verifying the new message includes skill_view, skill_manage, and memory keywords

Reviewed by Hermes Agent

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the focused mitigation. The premise is confirmed on current main: agent/background_review.py:819-835 installs a memory/skills-only runtime whitelist while retaining parent schemas for cache parity, and its current denial text at agent/background_review.py:832-833 does not identify replacement tools. The thread-local dispatcher formats that message for blocked calls at hermes_cli/plugins.py:2137-2143; tools/skill_manager_tool.py:382-408 confirms that skill_view is the required read path before a review can mutate an existing skill.

Problems

  • tests/run_agent/test_background_review_toolset_restriction.py adds assertions for skill_view, skill_manage, and memory, but not skills_list. The message explicitly advertises skills_list; that portion can regress without coverage.

Suggested changes

  • Assert that skills_list is present in deny_msg.

A member has also identified open PR #61618 as the broader duplicate, including equivalent proactive-prompt guidance. This is an automated hermes-sweeper review.

assert "read_file" in deny_msg
assert "skill_view" in deny_msg
assert "skill_manage(action='patch'" in deny_msg
assert "memory" in deny_msg

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also assert "skills_list" in deny_msg. The changed production message advertises it as the discovery path, but the new regression test does not currently protect that wording.

@teknium1 teknium1 added the sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users label Jul 18, 2026
@GottZ

GottZ commented Aug 3, 2026

Copy link
Copy Markdown

This was generated by AI during triage.

Summary

Twenty-four PRs address or reference this background-review complex: they cover cache-key parity (system, tools[], and reasoning fields), reasoning inheritance, read-only file authority, configurable toolsets, multi-user review suppression, and the advertised-schema/runtime-whitelist mismatch. The merged reference implementations are #25434, #29704, and #64379; for issue #61521, #65803 is the recorded best available mitigation while preserving remote cache parity.

Related pull requests

Duplicates

#17276 and #25427 were salvaged into #25434; #29568 was salvaged into #29704; #18973, #20674, #27510, #30532, and the reasoning portion of #36995 converge on #64379. #27422, #40007, #40060, and #46684 share the one-off read_file approach; #45892, #45902, and #46049 share the read_file+search_files approach; #61529 and #65803 address #61521 through different trade-offs, while #65803 overlaps the broader #61618.

Suggested consolidation

Keep #65803 open with a salvage path: preserve its cache-parity-safe denial steering, add the reviewer-requested skills_list assertion, and reconcile or supersede it with #61618’s proactive prompt guidance rather than duplicating the same mitigation. Author action on #61529: rebase onto main and restrict schema narrowing to local or non-prefix-cache endpoints; close #40060 as duplicate of #40007, and close #45892 and #46049 as duplicates of #45902, while keeping arbitrary file-read authority contingent on an explicitly bounded design rather than reopening the rejected #40007 approach.

Complex graph

flowchart LR
    classDef open fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
    classDef merged fill:#dcfce7,stroke:#15803d,color:#14532d
    classDef closed fill:#e5e7eb,stroke:#6b7280,color:#1f2937
    classDef unverified fill:#f3f4f6,stroke:#9ca3af,color:#374151
    classDef best stroke-width:3px,stroke:#b45309
    classDef target stroke-width:3px,stroke:#4338ca
    I61521(["issue #61521 (open)"])
    subgraph Dup61529 ["PRs duplicating each other"]
        P61529["PR #61529 (open)"]
        P65803["PR #65803 (open)"]
    end
    P65803 -->|best fix| I61521
    class I61521 open
    class P61529 open
    class P65803 open
    class P65803 best
    class P65803 target
    click I61521 "https://github.com/NousResearch/hermes-agent/issues/61521"
    click P61529 "https://github.com/NousResearch/hermes-agent/pull/61529"
    click P65803 "https://github.com/NousResearch/hermes-agent/pull/65803"
Loading

Graph: solid arrow = fixes / best fix, dashed arrow = partial or unverified (see edge label); boxed group = PRs duplicating each other; amber border = best fix; indigo border = target; gray node = closed (state tag in the node label).

Cross-PR triage: Reviewed 24 pull requests and 7 issues in this complex. Each diff was read against this issue; Assessment working set: 179 kB of PR diffs, 96 kB of issue/PR text, 43 kB of discussion (53 comments), 51 verify verdicts. verdicts reflect diff content, not PR titles. Part of an automated triage batch.

@henrynguyeninfo1 henrynguyeninfo1 closed this by deleting the head repository Aug 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint duplicate This issue or pull request already exists P2 Medium — degraded but workaround exists sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users type/bug Something isn't working

Projects

None yet

5 participants