Repository navigation
feat(core): add pcre2 option to grep tool - #59074
bluelovers wants to merge 2 commits into
Conversation
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).
There was a problem hiding this comment.
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"] : []), |
There was a problem hiding this comment.
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)?
There was a problem hiding this comment.
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
|
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: Error: The failure is on Tracked in #59078. Written by an AI agent · model: |
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).
There was a problem hiding this comment.
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.
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
Issue for this PR
Closes #59078
Type of change
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. Thegreptool has no way to enable the engine that supports it.This adds an optional
pcre2boolean to the grep tool. When it is set,--pcre2is 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:
This errors on
dev. With this branch andpcre2: trueit runs instead of erroring; leavingpcre2unset reproduces the original error.Screenshots / recordings
Not applicable — this change has no UI component.
Checklist
Written by an AI agent · model:
opencode/mimo-v2.6-flash-freeAdded by the opencode bot (AI-generated).
Related: #47474
Public API: adds optional
pcre2input to the built-in grep tool (backwards compatible)