Skip to content

Feat: replace delimiter text input with block-based builder (#15057)#15078

Open
Rene0422 wants to merge 4 commits into
infiniflow:mainfrom
Rene0422:feat/delimiter-block-builder
Open

Feat: replace delimiter text input with block-based builder (#15057)#15078
Rene0422 wants to merge 4 commits into
infiniflow:mainfrom
Rene0422:feat/delimiter-block-builder

Conversation

@Rene0422

Copy link
Copy Markdown
Contributor

Summary

Fixes #15057.

Replaces the free-text Delimiter for text input with a block-based
builder. The previous input forced users to know escape conventions
(\n vs \\n) and backtick rules for multi-char delimiters, gave no
visual feedback on what was configured, and made managing multiple
delimiters awkward.

What changed

  • web/src/components/delimiter-form-field.tsx

    • New parseDelimiterBlocks / serializeDelimiterBlocks helpers split
      the delimiter string into discrete blocks (single chars + backtick-
      wrapped multi-char sequences) and back. Round-trip verified on
      representative inputs (\n, \n。;!?, `###`\n, a`bc`d).
    • New DelimiterBuilder component:
      • Each delimiter renders as a removable Badge chip; \n / \t /
        \r display as / / for clarity.
      • + Add opens an inline Input; Enter commits, Escape
        cancels, blur commits. Multi-char entries are auto-wrapped in
        backticks at serialize time so users never type them.
      • Preset buttons (Newline, Tab, ## Heading, --- HR)
        one-click append the corresponding delimiter.
    • DelimiterFormField now renders DelimiterBuilder instead of the
      raw Input.
    • DelimiterInput (the legacy single-input component) is kept
      exported
      so the agent token-chunker form
      (pages/agent/form/token-chunker-form/index.tsx), which already has
      its own list UI, continues to work unchanged.
  • web/src/locales/en.ts, web/src/locales/zh.ts — six new keys
    under knowledgeDetails: delimiterAddPlaceholder,
    delimiterPresetsLabel, delimiterPresetNewline, delimiterPresetTab,
    delimiterPresetHeading, delimiterPresetHr. Per the frontend
    CLAUDE.md, added only to en.ts and zh.ts.

Wire format / backend compatibility

The persisted shape of parser_config.delimiter is unchanged — still
a single string consumed by rag.nlp.naive_merge in
rag/nlp/__init__.py, where backtick-
wrapped substrings denote multi-char delimiters and everything else is
treated as a single-char delimiter. No backend or schema changes.

Out of scope

  • The agent token-chunker form and children-delimiter-form.tsx already
    use useFieldArray-based list UIs with + Add / trash icons — no
    rework needed.
  • Per-chip inline edit: skipped to keep the diff minimal. Chips are
    removable and presets cover the common cases; to "change" a chip,
    remove + re-add.

Test plan

  • Open Dataset settings → General and the Chunk method dialog;
    confirm delimiter renders as chips, defaulting to for the
    seeded \n.
  • Click + Add, type ;, press Enter → new ; chip appears.
  • Click + Add, type ###, press Enter → chip shows ###;
    saved value contains `###` (backticks auto-added).
  • Click each preset (Newline, Tab, ##, ---) → corresponding chip
    appends; underlying value updates correctly.
  • Click × on a chip → chip removed; saved value updates.
  • Escape while editing the add input → input dismisses, no chip
    added.
  • Open an existing dataset whose delimiter is "\n`##`;"
    renders as [↵] [##] [;].
  • Save the dataset and re-open → chips persist; chunking behavior
    unchanged (sanity-check by uploading a test doc).
  • Knowledge Graph parser config also shows the builder.
  • Agent Token Chunker node still works unchanged (uses
    DelimiterInput, not the builder).
  • Switch UI language to 中文 → preset labels and placeholder render
    in Chinese.

Not verified

node_modules are not present in this worktree, so npm run lint and
tsc were not executed. Round-trip behavior of the parser was
unit-tested via standalone Node. Please run lint + typecheck in CI
before merging.

Type of change

  • Bug Fix (non-breaking change which fixes an issue)
  • New Feature (non-breaking change which adds functionality)
  • Documentation Update
  • Refactoring
  • Performance Improvement
  • Other (please describe):

@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label May 20, 2026
@coderabbitai

coderabbitai Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5d19b8d4-f874-48d4-87db-0e4a69305fa3

📥 Commits

Reviewing files that changed from the base of the PR and between 3656df0 and 30c925b.

📒 Files selected for processing (1)
  • web/src/components/delimiter-form-field.tsx

📝 Walkthrough

Walkthrough

Replaces the free-text delimiter input with a block-based DelimiterBuilder, adds parse/serialize utilities, renders removable chips and preset buttons with keyboard/blur behavior, integrates the builder into the form field, and adds English/Chinese locale keys.

Changes

Delimiter Block Builder Implementation

Layer / File(s) Summary
Imports and module wiring
web/src/components/delimiter-form-field.tsx
Update React and UI imports and adjust icon imports to support the new builder component.
Remove old DelimiterInput
web/src/components/delimiter-form-field.tsx
Remove the legacy DelimiterInput component and its escape/unescape handling for \n, \t, and \r.
Delimiter parsing and builder UI
web/src/components/delimiter-form-field.tsx
Add parseDelimiterBlocks() and serializeDelimiterBlocks() plus DelimiterBuilder: chips for blocks with remove, draft inline input (Enter/blur commits, Escape cancels), decode \\n/\\t/\\r in drafts, backtick handling, focus-on-add, and preset buttons (customizable).
Form field integration
web/src/components/delimiter-form-field.tsx
DelimiterFormField now renders DelimiterBuilder inside FormControl, forwarding field.value and field.onChange, and updates label/container classNames.
Locale entries
web/src/locales/en.ts, web/src/locales/zh.ts
Add translation keys for add placeholder, remove label, presets label, and preset names (Newline, Tab, Heading, Horizontal rule).

Sequence Diagram(s)

sequenceDiagram
  participant DelimiterFormField
  participant DelimiterBuilder
  participant parseDelimiterBlocks
  participant serializeDelimiterBlocks
  DelimiterFormField->>DelimiterBuilder: render(value, onChange)
  DelimiterBuilder->>parseDelimiterBlocks: parse(value)
  DelimiterBuilder->>serializeDelimiterBlocks: serialize(blocks)
  DelimiterBuilder->>DelimiterFormField: onChange(serialized)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

I nibble through backticks, chips held tight,
Newlines and tabs now gleam in sight.
Press Enter, blur, or pick a preset—hooray!
No more escapes to lead astray.
A rabbit hops and builds delimiters all day 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Feat: replace delimiter text input with block-based builder' clearly and concisely summarizes the main change in the PR.
Description check ✅ Passed The PR description is comprehensive, covers all required sections including problem statement, changes, wire format compatibility, test plan, and correctly marks the type of change.
Linked Issues check ✅ Passed All coding objectives from issue #15057 are met: block-based UI with chips, + Add input with Enter/Escape semantics, presets, visual symbols for special chars, backward compatibility, and existing form compatibility.
Out of Scope Changes check ✅ Passed All changes are scoped to the stated objectives: delimiter component replacement, helper functions, i18n additions, and no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/src/components/delimiter-form-field.tsx`:
- Around line 109-113: The remove-button in DelimiterFormField is using a
hardcoded English aria-label ("remove delimiter"); update the <button> in the
DelimiterFormField component to use the app's localization API (e.g., the
existing i18n/translation hook or function used elsewhere like t(...) or
useTranslations(...)) to produce the aria-label dynamically so it follows locale
changes; reference the button element and its onRemove handler and replace the
literal aria-label string with a translated key such as "removeDelimiter"
(ensure the translation key is added to locale files).
- Around line 83-87: serializeDelimiterBlocks currently embeds user-entered
backticks into the wire format unescaped; update serializeDelimiterBlocks to
first escape any backticks in each block (replace "`" with "\`") before wrapping
multi-char blocks in backticks and before joining, and apply the same escaping
to the other delimiter-serialization logic in this file (the second
serialization block around lines 143-150) so that any "`" in user input is
properly escaped and round-trips with the parser.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fbcae72d-27e9-4cbf-a7a6-d294804b0bf7

📥 Commits

Reviewing files that changed from the base of the PR and between dc01e0e and 1e11300.

📒 Files selected for processing (3)
  • web/src/components/delimiter-form-field.tsx
  • web/src/locales/en.ts
  • web/src/locales/zh.ts

Comment thread web/src/components/delimiter-form-field.tsx

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/src/components/delimiter-form-field.tsx`:
- Around line 110-114: The remove button in DelimiterFormField (the <button>
with onClick={onRemove}) removes the native outline but doesn't provide a
replacement focus indicator; update its class list to restore an accessible
visible focus state (e.g. remove or replace focus:outline-none with a
focus-visible or focus ring utility such as focus-visible:ring
focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-state-error
or equivalent CSS) so keyboard users can clearly see which chip's delete control
is focused while preserving the existing hover styles.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 67ea7192-f170-4ce5-9209-63a7d2fbc93c

📥 Commits

Reviewing files that changed from the base of the PR and between 1e11300 and 16f9a11.

📒 Files selected for processing (3)
  • web/src/components/delimiter-form-field.tsx
  • web/src/locales/en.ts
  • web/src/locales/zh.ts
✅ Files skipped from review due to trivial changes (1)
  • web/src/locales/zh.ts

Comment thread web/src/components/delimiter-form-field.tsx Outdated
@Rene0422 Rene0422 force-pushed the feat/delimiter-block-builder branch from f487f85 to 3656df0 Compare May 21, 2026 15:07

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/src/components/delimiter-form-field.tsx`:
- Around line 190-199: The Enter handling in the onKeyDown handler inside
delimiter-form-field.tsx currently calls handleSubmit() immediately and should
be guarded against IME composition; modify the onKeyDown callback (the branch
that checks e.key === 'Enter') to only call handleSubmit() when composition is
not in progress by checking !e.nativeEvent.isComposing and also handling the
legacy composition keyCode (skip if e.nativeEvent.isComposing === true or
e.keyCode === 229). Leave the Escape branch (which calls setDraft('') and
setAdding(false)) unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a26428c8-ffd7-46aa-a00b-14f634acfc76

📥 Commits

Reviewing files that changed from the base of the PR and between f487f85 and 3656df0.

📒 Files selected for processing (3)
  • web/src/components/delimiter-form-field.tsx
  • web/src/locales/en.ts
  • web/src/locales/zh.ts
✅ Files skipped from review due to trivial changes (2)
  • web/src/locales/en.ts
  • web/src/locales/zh.ts

Comment thread web/src/components/delimiter-form-field.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enhancement: Replace free-text "Delimiter for text" input with block-based delimiter builder

1 participant