Skip to content

feat(tools): READONLY_TOOLS filter + GitHub issue/PR pre-fetch (#193 PR 1/3)#194

Merged
Abernaughty merged 1 commit into
mainfrom
feat/issue-193-tool-filter-github-prefetch
Apr 17, 2026
Merged

feat(tools): READONLY_TOOLS filter + GitHub issue/PR pre-fetch (#193 PR 1/3)#194
Abernaughty merged 1 commit into
mainfrom
feat/issue-193-tool-filter-github-prefetch

Conversation

@Abernaughty

Copy link
Copy Markdown
Owner

Summary

Foundation PR (1 of 3) for #193 — read-only GitHub + filesystem tool access for the Planner and Architect.

  • READONLY_TOOLS frozenset in mcp_bridge.py naming the tools safe for read-only agents (filesystem_read, filesystem_list, github_read_diff). Excludes every write path.

  • Optional tool_filter param on get_tools() / aget_tools() so the Planner (and future Architect Phase 2) can request just the allowlisted tools.

  • New src/tools/github_fetch.py — standalone httpx-based fetcher for GitHub issues/PRs (the REST /issues/{n} endpoint covers both), with title + labels + body summaries, 2000-char per-ref cap, and best-effort failure handling.

  • extract_github_refs() with two regex patterns:

    • cross-repo owner/repo#N — matched without a qualifying word
    • same-repo <qualifier> #N — requires issue, fix(es|ed), close(s|d), resolve(s|d), ref(s), see, review, address, gh, pr, pull(s), pull request

    Bare #N is rejected to avoid false matches on markdown headings, CSS colors, etc. Capped at 5 refs per task description.

  • gather_context_node now runs the pre-fetch after file gathering and injects results into gathered_context with source: "github_issue", so the Architect sees issue bodies without calling tools.

Test plan

  • uv run ruff check src/ tests/ — clean
  • uv run pytest tests/ -q -m "not integration" — 1074 passed, 1 pre-existing failure in test_workspace.py::TestFromEnv::test_from_env_defaults (unrelated; reproducible on main)
  • New unit tests (72 new assertions):
    • test_github_fetch.py — pattern matching, issue fetch, best-effort fallback
    • test_mcp_tools.py::TestToolFilter — read/write partitioning, async variant
    • test_gather_context.py — end-to-end pre-fetch integration

Follow-ups

This PR is deliberately scoped to shared plumbing. The agent wiring comes next:

Refs #193

🤖 Generated with Claude Code

…193)

Foundation PR (1 of 3) for issue #193: read-only GitHub + filesystem
tool access for the Planner and Architect agents.

This PR lands the shared plumbing:

- `READONLY_TOOLS` frozenset in `mcp_bridge.py` naming the tools safe
  for read-only agents (filesystem_read, filesystem_list,
  github_read_diff). Excludes every write path.
- Optional `tool_filter` param on `get_tools()` / `aget_tools()` so the
  Planner and Architect Phase 2 can request just the allowlisted tools.
- New `src/tools/github_fetch.py` module — standalone httpx-based
  fetcher for GitHub issues and PRs (the REST /issues/{n} endpoint
  covers both). Summarises title + labels + body, caps per-ref at 2000
  chars, best-effort on auth / network / 404 failures.
- `extract_github_refs()` with two patterns:
  - cross-repo `owner/repo#N` — matched without a qualifying word
  - same-repo `<qualifier> #N` — requires `issue`, `fix(es|ed)`,
    `close(s|d)`, `resolve(s|d)`, `ref(s)`, `see`, `review`,
    `address`, `gh`, `pr`, `pull(s|s)`, `pull request`.
  Bare `#N` is rejected to avoid false matches on markdown headings,
  CSS colors, etc. Capped at 5 refs per task description.
- `gather_context_node` now runs the pre-fetch after file gathering and
  injects results into `gathered_context` with `source: github_issue`,
  so the Architect sees issue bodies without calling tools.

Unit tests cover: pattern matching (qualifiers, cross-repo, dedupe,
cap, false-positive rejection), tool filtering (readonly/write
partitioning, empty/unknown filters, async variant), issue fetch
(success, truncation, PR detection, 404, network error, malformed
JSON), and gather_context integration (pre-fetch success, no-refs
no-fetch, graceful degradation).

Follow-ups:
- PR 2: Planner conditional tool binding + TaskSpec.github_context
  pass-through
- PR 3: Architect two-phase (no-tools then tools) + integration test
  for "Fix issue #113" flow

Refs #193

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Abernaughty Abernaughty merged commit 1b5641d into main Apr 17, 2026
3 checks passed
@Abernaughty Abernaughty deleted the feat/issue-193-tool-filter-github-prefetch branch April 17, 2026 19:31
Abernaughty added a commit that referenced this pull request Apr 17, 2026
… (refs #193)

The Planner's system prompt unconditionally declared "ZERO tool access",
causing the LLM to tell users it could not look up GitHub issues even
when PR #195's deterministic pre-fetch had already injected the issue
body as a secondary system message. Users reported the bug with "Review
and implement the fix for GitHub Issue #113" — the Planner replied
"I don't have access to GitHub" despite the issue content being in its
context window.

Changes:
- _PLANNER_SYSTEM_PROMPT now explains the pre-fetch flow and explicitly
  forbids denying GitHub access when the PRE-FETCHED GITHUB CONTEXT
  block is present.
- _format_github_context_block wraps the payload in clear start/end
  markers that the system prompt references by name.
- _prefetch_github_refs_for_message logs a warning (not silent skip)
  when refs were detected but GITHUB_TOKEN is missing or the fetch
  returned zero items, so operators can diagnose environment issues.
- Four new tests in TestPlannerSystemPromptReconciliation cover: the
  system prompt no longer contains "ZERO tool access", the context
  block carries start/end markers, empty inputs produce no block, and
  the new warning log fires when refs are detected without a token.

Closes the AC #3 gap in issue #193 (Planner "fetches" GitHub issues
when referenced). All other ACs were already satisfied by PRs #194-#196.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Abernaughty added a commit that referenced this pull request Apr 17, 2026
… (refs #193) (#197)

The Planner's system prompt unconditionally declared "ZERO tool access",
causing the LLM to tell users it could not look up GitHub issues even
when PR #195's deterministic pre-fetch had already injected the issue
body as a secondary system message. Users reported the bug with "Review
and implement the fix for GitHub Issue #113" — the Planner replied
"I don't have access to GitHub" despite the issue content being in its
context window.

Changes:
- _PLANNER_SYSTEM_PROMPT now explains the pre-fetch flow and explicitly
  forbids denying GitHub access when the PRE-FETCHED GITHUB CONTEXT
  block is present.
- _format_github_context_block wraps the payload in clear start/end
  markers that the system prompt references by name.
- _prefetch_github_refs_for_message logs a warning (not silent skip)
  when refs were detected but GITHUB_TOKEN is missing or the fetch
  returned zero items, so operators can diagnose environment issues.
- Four new tests in TestPlannerSystemPromptReconciliation cover: the
  system prompt no longer contains "ZERO tool access", the context
  block carries start/end markers, empty inputs produce no block, and
  the new warning log fires when refs are detected without a token.

Closes the AC #3 gap in issue #193 (Planner "fetches" GitHub issues
when referenced). All other ACs were already satisfied by PRs #194-#196.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant