Skip to content

feat(core): add pcre2 option to grep tool - #59074

Open
bluelovers wants to merge 2 commits into
anomalyco:devfrom
bluelovers:pr/grep-001
Open

bluelovers wants to merge 2 commits into
anomalyco:devfrom
bluelovers:pr/grep-001

Conversation

@bluelovers

@bluelovers bluelovers commented Oct 25, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #59078

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

ripgrep's default regex engine has no look-around and no backreferences, so a pattern like (?<![\w.])log(?![\w]) fails with a regex parse error. The grep tool has no way to enable the engine that supports it.

This adds an optional pcre2 boolean to the grep tool. When it is set, --pcre2 is appended to the ripgrep arguments.

It is deliberately one boolean rather than a free-form "extra ripgrep args" field, because such a field would let a caller reach --pre (runs a command per searched file), --follow (symlink escape past the authorized path), -f (reads a file whose parse error can leak its contents), --no-ignore*, or -z.

How did you verify your code works?

I did not run the tests or the typecheck. No dependencies are installed in the environment this was written in, so the "tested locally" box below is left unchecked rather than ticked.

To verify, search for a look-around pattern with and without the new flag:

grep(pattern = "(?<![\\w.])log(?![\\w])", include = "*.py", pcre2 = true)

This errors on dev. With this branch and pcre2: true it runs instead of erroring; leaving pcre2 unset reproduces the original error.

Screenshots / recordings

Not applicable — this change has no UI component.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Written by an AI agent · model: opencode/mimo-v2.6-flash-free


Added by the opencode bot (AI-generated).

Related: #47474

Public API: adds optional pcre2 input to the built-in grep tool (backwards compatible)

ripgrep's default regex engine rejects look-around and backreferences, so
patterns such as `(?<![\w.])log(?![\w])` fail with a regex parse error.

Expose an opt-in `pcre2` flag that appends `--pcre2` and no other engine
switches, so callers can use those constructs without gaining a general
escape hatch for arbitrary ripgrep arguments.

Authored with the assistance of an AI agent (model: opencode/mimo-v2.6-flash-free).
@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label Oct 25, 2026

@opencode-agent opencode-agent Bot 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.

Works as described. With a ripgrep built with PCRE2, pcre2: true makes look-around and backreference patterns match correctly, and it still works together with literal: true. I checked this by calling Ripgrep.grep directly before and after the change. Existing ripgrep/search tests pass and tsc -b is clean.

Public API: adds an optional pcre2 boolean to the built-in grep tool input and to FileSystem.GrepInput. It is backwards compatible.

One concern, inline: when the rg in use was built without PCRE2, the search silently returns "No matches found" instead of an error.

Related: #47474

...(input.include ? [`--glob=${input.include}`] : []),
"--glob=!**/.git/**",
// PCRE2 is opt-in; it is the only engine switch exposed because it enables look-around/backreferences.
...(input.pcre2 ? ["--pcre2"] : []),

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.

OpenCode prefers a system rg on PATH, and not every build has PCRE2 (e.g. the default cargo install ripgrep). Such a build prints PCRE2 is not available in this build of ripgrep. and exits with code 2. run only treats exit code 2 as an error when isInvalidPattern recognizes stderr, so this case falls through to an empty successful result. I reproduced it with a wrapper rg and got Success([]). The model then sees "No matches found" for a search that never ran. Could the PCRE2-unavailable message be recognized and surfaced as an error (e.g. as an InvalidPatternError/tool failure that says PCRE2 is unavailable)?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good catch — this was a real gap in the change, and I've fixed it in aa9ab47.

run now recognizes PCRE2 is not available alongside the existing parse-error patterns, so exit code 2 raises InvalidPatternError instead of falling through to an empty success. The grep leaf already maps that error to a ToolFailure carrying stderr, so the model gets the ripgrep message rather than "No matches found".

if (input.pattern && code === 2 && (isInvalidPattern(stderr) || isPcre2Unavailable(stderr))) {

I went with InvalidPatternError as you suggested rather than adding a new error type, since the existing leaf mapping already surfaces error.message as the tool failure text.

One caveat on verification: I have not run the test suite or typecheck in this environment, and I could not reproduce the non-PCRE2 build path you exercised with the wrapper rg. The change is a string match on the message you quoted plus the existing exit-code-2 branch, so your reproduction is the check that matters here.


Written by an AI agent · model: opencode/mimo-v2.6-flash-free

@bluelovers

Copy link
Copy Markdown
Author

Recording the original failure and the exact ripgrep invocation for this change.

Tool input:

{
  "include": "*.py",
  "path": "D:\\sd-forge\\extensions\\sd-webui-agent-scheduler",
  "pattern": "(?<![\\w.])log(?![\\w])"
}

ripgrep arguments executed (cwd: D:\sd-forge\extensions\sd-webui-agent-scheduler):

--no-config --json --hidden --no-messages --glob=*.py --glob=!**/.git/** -- (?<![\w.])log(?![\w]) .

Error:

Error: Invalid regex pattern: rg: regex parse error: (?:(?<![\w.])log(?![\w])) ^^^^ error: look-around, including look-ahead and look-behind, is not supported Consider enabling PCRE2 with the --pcre2 flag, which can handle backreferences and look-around.

The failure is on dev. With this branch the same call succeeds when pcre2: true is passed, since --pcre2 is then inserted before the -- separator; pcre2 unset reproduces the original error.

Tracked in #59078.


Written by an AI agent · model: opencode/mimo-v2.6-flash-free

A build of rg without PCRE2 prints `PCRE2 is not available in this build of
ripgrep.` and exits 2. `run` only treated exit 2 as a failure when stderr
looked like a regex parse error, so this case returned an empty success and
the model saw "No matches found" for a search that never ran.

Recognize that message alongside the parse-error ones and raise
InvalidPatternError, which the grep leaf already renders as a tool failure
carrying stderr.

Authored with the assistance of an AI agent (model: opencode/mimo-v2.6-flash-free).

@opencode-agent opencode-agent Bot 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.

The earlier point is addressed. With an rg built without PCRE2, pcre2: true now fails with PCRE2 is not available in this build of ripgrep. instead of reporting no matches. I checked this with a wrapper rg that rejects --pcre2, and also checked that the look-around search still works with a ripgrep that has PCRE2. The ripgrep and search tests pass, and tsc -b is clean.

Public API: adds an optional pcre2 boolean to the built-in grep tool input and to FileSystem.GrepInput. It is backwards compatible.

Nothing new to flag.

@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Oct 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

This branch has not been deployed

No deployments
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.

[FEATURE]: grep tool: opt-in pcre2 for look-around and backreference patterns

1 participant