Skip to content

ThinkingTagCleaner.Builder.withoutDefaultPatterns() does not disable default patterns #6499

Description

@gaoxiaolei-s59

Bug description

ThinkingTagCleaner.Builder#withoutDefaultPatterns() does not take effect unless a custom pattern is added afterwards, so the default patterns can be silently retained even though the method is documented to "Disable default patterns".

The builder clears the defaults lazily — only inside addPattern(...), and only the first time it runs after withoutDefaultPatterns() was called:

public Builder withoutDefaultPatterns() {
    this.useDefaultPatterns = false; // does not clear the defaults
    return this;
}

public Builder addPattern(String patternString) {
    Assert.hasText(patternString, "patternString cannot be empty");
    if (!this.useDefaultPatterns) {       // clearing happens here, lazily
        this.patterns.clear();
        this.useDefaultPatterns = true;
    }
    this.patterns.add(Pattern.compile(patternString, Pattern.CASE_INSENSITIVE));
    return this;
}

If addPattern(...) is never called, the defaults are never cleared.

Minimal reproducible example

ResponseTextCleaner cleaner = ThinkingTagCleaner.builder()
        .withoutDefaultPatterns()
        .build();

String result = cleaner.clean("<thinking>secret</thinking>visible");

Expected: the default <thinking> pattern is disabled, so it is not applied (and, since the cleaner now has no patterns, building should fail fast with the constructor's existing patterns cannot be empty assertion).

Actual: returns "visible" — the default <thinking> pattern was still applied, proving withoutDefaultPatterns() had no effect.

Environment

  • Spring AI version: 2.0.1-SNAPSHOT (main); class is @since 1.1.0

I'd be happy to submit a PR (with regression tests) that clears the defaults immediately in withoutDefaultPatterns() and removes the redundant lazy-clear flag.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions