Skip to content

replace chunk with document when tokens are small - #167

Merged
aristachauhan merged 2 commits into
mainfrom
abc/chunk-to-document
Apr 23, 2026
Merged

replace chunk with document when tokens are small#167
aristachauhan merged 2 commits into
mainfrom
abc/chunk-to-document

Conversation

@aristachauhan

@aristachauhan aristachauhan commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Enhanced search results to include more complete document content from the database, improving the quality and relevance of search hits.
    • Added token counting capability to track document size information.
  • Bug Fixes

    • Improved document deduplication in search results to prevent duplicate entries.

@coderabbitai

coderabbitai Bot commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@aristachauhan has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 18 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 9 minutes and 18 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f660dd53-d5cd-44e1-8b1f-df3908e62b1d

📥 Commits

Reviewing files that changed from the base of the PR and between 0a0f8f2 and 942e355.

📒 Files selected for processing (2)
  • web/src/models/chat.ts
  • web/src/services/chatService.ts
📝 Walkthrough

Walkthrough

This PR extends the search functionality by adding document token counting and full document content retrieval. The PolicyMetadata type now includes a doc_tokens field, and the search service post-processes results to filter by token thresholds, deduplicate URLs, and fetch full document content from the database for eligible matches.

Changes

Cohort / File(s) Summary
Type Definitions
web/src/models/chat.ts
Added doc_tokens: number field to PolicyMetadata type to track document token counts.
Search Service Enhancement
web/src/services/chatService.ts
Added post-processing logic to getSearchResultsElastic to filter by token threshold, deduplicate by URL, and fetch full document content. Added two new exported functions: getDocumentByUrl for database lookups and addFullDocument for orchestrating full-text promotion into search results.

Sequence Diagram

sequenceDiagram
    participant Client
    participant SearchService
    participant Database
    
    Client->>SearchService: getSearchResultsElastic(query)
    SearchService->>SearchService: Execute Elasticsearch query
    SearchService->>SearchService: Filter by MAX_DOC_TOKENS threshold
    SearchService->>SearchService: Deduplicate by metadata.url
    SearchService->>SearchService: Identify eligible documents
    loop For eligible documents (capped at MAX_FULL_DOCS)
        SearchService->>Database: getDocumentByUrl(url)
        Database->>SearchService: Return full document content
    end
    SearchService->>SearchService: addFullDocument() - replace PolicyIndex.text
    SearchService->>Client: Return enhanced PolicyIndex[] results
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • add back in option to query elastic db #126 — Extends Elasticsearch search path with metadata addition (doc_tokens) and full document promotion helpers, directly extending the foundation for this PR.
  • hybrid search #166 — Modifies the same getSearchResultsElastic flow in chatService.ts with different enhancement logic (userInput-driven hybrid search), may have integration implications.

Suggested reviewers

  • srkirkland

Poem

🐰 Token counts now flow through every doc so bright,
Full documents fetched from databases deep in the night!
URLs deduplicated, the search results gleam,
A rabbit's delight—fulfilling each query dream! 📚✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly reflects the main change: replacing chunks with full documents when they have small token counts. The modifications show new doc_tokens tracking and logic to fetch full document content for eligible small documents, which aligns perfectly with the title's intent.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch abc/chunk-to-document

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: 3

🧹 Nitpick comments (1)
web/src/services/chatService.ts (1)

123-123: Hoist MAX_DOC_TOKENS and MAX_FULL_DOCS to module scope.

Both are thresholds that describe cross-function promotion policy and are re-created on every call. Pulling them out of the function bodies makes them easier to find, tune, and unit-test, and keeps addFullDocument / getSearchResultsElastic focused on logic.

♻️ Suggested placement (near `indexName`)
 const indexName = process.env.ELASTIC_INDEX ?? 'test_vectorstore4';
+
+const MAX_DOC_TOKENS = 20_000;
+const MAX_FULL_DOCS = 1;

Then remove the local declarations inside getSearchResultsElastic (line 123) and addFullDocument (line 230).

Also applies to: 230-230

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/services/chatService.ts` at line 123, Hoist the constants
MAX_DOC_TOKENS and MAX_FULL_DOCS to module scope (place them near the existing
indexName constant) so they are defined once for the module instead of being
recreated on each call; then remove the local declarations of MAX_DOC_TOKENS
inside getSearchResultsElastic and MAX_FULL_DOCS inside addFullDocument and
update those functions to reference the module-level constants directly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/models/chat.ts`:
- Line 78: The model field doc_tokens is declared required but some legacy
documents lack it, so either make the type optional in the chat model (change
doc_tokens to optional on the interface/type in web/src/models/chat.ts) or add
an explicit presence check in the token-gating logic in chatService.ts (before
comparing to MAX_DOC_TOKENS at the current check around line 190) to treat
missing/undefined as failing the gate; update references to use the optional
field or the explicit null/undefined check to avoid silently bypassing the token
limit.

In `@web/src/services/chatService.ts`:
- Around line 189-192: Guard against missing or non-numeric doc_tokens: in the
eligibility check that uses result.metadata.doc_tokens and MAX_DOC_TOKENS (the
block that currently returns when result.metadata.doc_tokens > MAX_DOC_TOKENS),
first verify that result.metadata.doc_tokens exists and is a number (e.g., using
typeof or Number.isFinite) before comparing; if it’s missing or not numeric,
treat the doc as ineligible (return) so legacy hits aren’t added to eligibleDocs
and later promoted to full-document fetches. Ensure the check is applied where
eligibleDocs is populated and references result.metadata.doc_tokens and
MAX_DOC_TOKENS.
- Around line 206-223: getDocumentByUrl currently uses
prisma.documents.findFirst({ where: { url } }) which can return an arbitrary row
because documents.url is not unique; make the selection deterministic by
ordering or by correlating via a stable id. Update getDocumentByUrl to either
query by a stable identifier (e.g., look up by documentId if you index that into
Elasticsearch) or add an explicit orderBy to the Prisma query (for example
orderBy: { lastUpdated: 'desc' } or orderBy: { id: 'desc' }) so the returned
documentContents.content is deterministic; adjust the call site accordingly if
you switch to documentId-based lookup.

---

Nitpick comments:
In `@web/src/services/chatService.ts`:
- Line 123: Hoist the constants MAX_DOC_TOKENS and MAX_FULL_DOCS to module scope
(place them near the existing indexName constant) so they are defined once for
the module instead of being recreated on each call; then remove the local
declarations of MAX_DOC_TOKENS inside getSearchResultsElastic and MAX_FULL_DOCS
inside addFullDocument and update those functions to reference the module-level
constants directly.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 72991a4d-d2b6-4371-8143-d1be377a9fd7

📥 Commits

Reviewing files that changed from the base of the PR and between 2bd8217 and 0a0f8f2.

📒 Files selected for processing (2)
  • web/src/models/chat.ts
  • web/src/services/chatService.ts

Comment thread web/src/models/chat.ts Outdated
Comment on lines +189 to +192
// filter out documents greater token limit
if (result.metadata.doc_tokens > MAX_DOC_TOKENS) {
return;
}

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.

⚠️ Potential issue | 🟠 Major

Guard against missing doc_tokens so legacy hits aren't silently promoted.

If a hit comes back without doc_tokens (e.g., indexed before this PR), result.metadata.doc_tokens > MAX_DOC_TOKENS is undefined > 20000false, so the URL is added to eligibleDocs and may get promoted to a potentially very large full-document fetch. Require the field to be present and numeric before considering the doc eligible.

🛡️ Proposed fix
-      // filter out documents greater token limit
-      if (result.metadata.doc_tokens > MAX_DOC_TOKENS) {
-        return;
-      }
+      // filter out docs missing a token count or exceeding the limit
+      const tokens = result.metadata.doc_tokens;
+      if (typeof tokens !== 'number' || tokens > MAX_DOC_TOKENS) {
+        return;
+      }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// filter out documents greater token limit
if (result.metadata.doc_tokens > MAX_DOC_TOKENS) {
return;
}
// filter out docs missing a token count or exceeding the limit
const tokens = result.metadata.doc_tokens;
if (typeof tokens !== 'number' || tokens > MAX_DOC_TOKENS) {
return;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/services/chatService.ts` around lines 189 - 192, Guard against
missing or non-numeric doc_tokens: in the eligibility check that uses
result.metadata.doc_tokens and MAX_DOC_TOKENS (the block that currently returns
when result.metadata.doc_tokens > MAX_DOC_TOKENS), first verify that
result.metadata.doc_tokens exists and is a number (e.g., using typeof or
Number.isFinite) before comparing; if it’s missing or not numeric, treat the doc
as ineligible (return) so legacy hits aren’t added to eligibleDocs and later
promoted to full-document fetches. Ensure the check is applied where
eligibleDocs is populated and references result.metadata.doc_tokens and
MAX_DOC_TOKENS.

Comment on lines +206 to +223
export const getDocumentByUrl = async (url: string): Promise<string | null> => {
if (!url) {
return null;
}

const document = await prisma.documents.findFirst({
where: { url },
select: {
documentContents: {
select: {
content: true,
},
},
},
});

return document?.documentContents?.content ?? null;
};

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.

⚠️ Potential issue | 🟡 Minor

documents.url is not unique — findFirst may return an arbitrary match.

Per web/prisma/schema.prisma, documents.url is a nullable String? with only a non-unique index (ix_documents_url); nothing prevents multiple rows sharing the same URL (e.g., re-ingests, historical versions). findFirst({ where: { url } }) will pick one non-deterministically, and the returned documentContents.content may not correspond to the Elasticsearch hit that was actually matched.

Consider one of:

  • Correlate by a stable identifier instead of URL (e.g., index the internal documentId into the ES metadata and look up by primary key).
  • Add an explicit orderBy (e.g., newest lastUpdated or highest id) so selection is deterministic.
  • If URLs are expected to be unique in practice, enforce that with a DB constraint.
♻️ Minimal deterministic fallback
   const document = await prisma.documents.findFirst({
     where: { url },
+    orderBy: { lastUpdated: 'desc' },
     select: {
       documentContents: {
         select: {
           content: true,
         },
       },
     },
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/services/chatService.ts` around lines 206 - 223, getDocumentByUrl
currently uses prisma.documents.findFirst({ where: { url } }) which can return
an arbitrary row because documents.url is not unique; make the selection
deterministic by ordering or by correlating via a stable id. Update
getDocumentByUrl to either query by a stable identifier (e.g., look up by
documentId if you index that into Elasticsearch) or add an explicit orderBy to
the Prisma query (for example orderBy: { lastUpdated: 'desc' } or orderBy: { id:
'desc' }) so the returned documentContents.content is deterministic; adjust the
call site accordingly if you switch to documentId-based lookup.

Co-authored-by: Copilot <copilot@github.com>
@aristachauhan
aristachauhan merged commit 8355a1a into main Apr 23, 2026
8 checks passed
@aristachauhan
aristachauhan deleted the abc/chunk-to-document branch April 23, 2026 23:19
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.

2 participants