Skip to content

feat(platform): let chat find entities by words in a question - #3106

Closed
Israeltheminer wants to merge 1 commit into
mainfrom
feat/chat-entity-word-search
Closed

feat(platform): let chat find entities by words in a question#3106
Israeltheminer wants to merge 1 commit into
mainfrom
feat/chat-entity-word-search

Conversation

@Israeltheminer

Copy link
Copy Markdown
Collaborator

Chat can now find a contact, product or knowledge entry from a multi-word question. Before this it compared the whole question as one string, so it found nothing.

Last code item on #2992.

Why

The entity legs pass a natural-language question straight through as a search term, and the queries match it as a single substring. "do we have red running shoes" only matches text literally containing that phrase, so it never matches. The tasks and projects legs already split the term into words; these three did not.

What changed

Word matching is added ALONGSIDE each entity's existing phrase match, never in place of it. A row matches if any meaningful word hits, or if the whole phrase hits as it does today.

That combination is the point. The phrase check reaches fields the word-match config cannot express — a product's translated name and description among them — so swapping to words alone would have quietly shrunk what is searchable. A customer running their catalogue in German would have found chat unable to locate a product by the name they actually use, while the products page still could.

Opt-in per call. The contacts and products pages search exactly as they do today; only the chat legs pass matchWords, because only they pass a question.

'any' mode is what makes a question usable: it drops stopwords and single characters, and requires a word-START match rather than any substring — without that floor, "ad" would pull in every row containing "overhead".

Risk

The two field lists differ on purpose. The word config covers a product's name, description, category, tags and code; the phrase check also covers translations. Anyone "tidying" one to match the other would silently delete translation search. Both strategy files say so.

Knowledge entries deliberately exclude content. The agent listing filters on topic alone, and matching whole bodies would turn a topic filter into a full-text search over every entry.

Two code paths in products. queryProducts filters in memory when externalId is an array, separately from the paginated walk. Both thread the word term, and both are tested — the first mutation I ran passed because it hit the untested branch, which is how I found out.

Tests

Seven cases: a multi-word question finding a product, the same question finding nothing without opting in, a translated name and a translated description both still found, a stopword-only question matching nothing, a mid-word fragment not matching while a real word does, and the externalId-array path.

Four deliberate breakages, all caught: word matching off, the opt-in ignored on each of the two paths, and all instead of any.

Scope

Adds matching; removes none. Ranking is unchanged — this decides whether a row matches, not how matches are ordered.

Gate: repo-wide typecheck, oxlint --type-aware, oxfmt, knip, SAST 0 findings, platform suite 75,819 passing.

@Israeltheminer

Copy link
Copy Markdown
Collaborator Author

Superseded by #3123, which does this against the Postgres backend.

Eight of the ten files this branch touches were deleted by #3107, including word_match.ts, both strategy files, and all four entity query modules. The branch cannot be rebased.

#3123 carries the same decision — word matching added alongside the phrase match, never replacing it — and covers two legs this one did not. The 0.5 chat shim reimplemented the tasks and projects legs as SQL with a whole-phrase ILIKE, so #2983's fix was not reaching them either.

Worth closing this once #3123 lands.

@Israeltheminer

Copy link
Copy Markdown
Collaborator Author

Closing: superseded by #3123, which is open and still needed — main has no word matching in the entity legs today.

Every one of the ten files this branch touches was deleted by #3125, so it cannot be rebased. #3123 carries the same decision (word matching added alongside the phrase match, never replacing it) and covers two legs this branch never touched: the port had reimplemented the tasks and projects legs as SQL with a whole-phrase ILIKE, so #2983's fix was not reaching those either.

The epic #2992 tracks the remainder.

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