Skip to content

Conversation

Himanshvarma
Copy link
Contributor

@Himanshvarma Himanshvarma commented Oct 10, 2025

Description

added follow up query context gathering for attached files

Summary by CodeRabbit

  • New Features
    • Improved follow-up handling that detects follow-ups, carries relevant file and image attachment context, and routes follow-ups through a context-aware path when available.
  • Bug Fixes
    • More robust temporary file cleanup with retry/backoff to reduce intermittent file removal failures.
    • Reduced conversation stalls by making history and follow-up processing more error-tolerant.
  • Refactor
    • Unified, chain-break-aware history preprocessing and clearer follow-up context extraction and logging.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @Himanshvarma, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors and enhances the system's ability to handle follow-up queries, especially when they involve attached files. It introduces a standardized way to process message history, ensuring that even failed user queries contribute to a consistent conversation context. Furthermore, it improves the reliability of temporary file cleanup operations within the DuckDB integration, contributing to overall system stability.

Highlights

  • Enhanced Follow-up Context for Attached Files: The system now more effectively gathers and utilizes context from previously attached files in follow-up queries, ensuring relevant information is carried forward.
  • Refactored Message History Processing: A new utility, transformMessagesWithErrorHandling, has been introduced to normalize message history by creating synthetic assistant messages for user queries that resulted in an error but lacked an explicit assistant response. This improves consistency for context gathering.
  • Improved Context Collection Logic: The collectFollowupContext function has been enhanced to consider conversation boundaries (chain breaks) and sources from assistant messages, leading to more accurate and relevant context for subsequent queries.
  • Robust DuckDB File Cleanup: Temporary files generated during DuckDB operations now benefit from a unlinkWithRetry helper, making file deletion more resilient to transient file system errors like 'EBUSY' or 'EPERM'.
  • Granular Attachment Handling in Vespa Search: The Vespa search integration now distinguishes between different types of file IDs (e.g., att_ vs. attf_) for more precise searching of attached files.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 10, 2025

Caution

Review failed

The pull request is closed.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Threads an isFollowUp flag through classification and routing, refactors follow-up carry-forward to use a source- and chain-break-aware collectFollowupContext, conditionally routes file-backed follow-ups to a context-aware handler, and adds robust unlink/stream/cleanup logic for DuckDB temp files.

Changes

Cohort / File(s) Summary of changes
Agent & routing flow
server/api/chat/agents.ts, server/api/chat/chat.ts
Adds isFollowUp to classifier / parsed responses; replaces inline carry-forward with transformed message handling and collectFollowupContext; conditionally routes file-backed follow-ups to UnderstandMessageAndAnswerForGivenContext; updates attachment filtering and logging; wires derived fileIds / imageAttachmentFileIds into downstream calls.
Follow-up context collection
server/api/chat/utils.ts
Changes collectFollowupContext signature (removes startIdx), derives start index from messages, introduces chain-break awareness via extractChainBreakClassifications, processes assistant m.sources to collect source docIds, deduplicates and respects MAX_FILES, and breaks iteration on chain-break indices.
DuckDB streaming & cleanup
server/lib/duckdb.ts
Adds unlinkWithRetry(path, attempts, delay) to retry transient unlink errors; replaces direct 'finish' handling with end→close sequencing; defensively drops views before close; uses retry unlink for temp TSV/DB files and tightens cleanup/error logging.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant API as Chat API
  participant T as transformMessagesWithErrorHandling
  participant C as collectFollowupContext
  participant CL as Classifier
  participant UAC as UnderstandMessageAndAnswerForGivenContext
  participant UA as UnderstandMessageAndAnswer

  U->>API: send message + history
  API->>T: transformMessagesWithErrorHandling(messages)
  T-->>API: transformedMessages

  API->>C: collectFollowupContext(transformedMessages)
  C-->>API: workingSet {fileIds, imageAttachmentFileIds, ...}

  alt isFollowUp && file-backed context
    API->>UAC: call with fileIds/imageAttachmentFileIds (isFollowUp=true)
    UAC-->>API: file-context answer
  else isFollowUp without file context
    API->>CL: classify(query, include isFollowUp)
    CL-->>API: classification
    API->>UA: call UnderstandMessageAndAnswer(using classification)
    UA-->>API: answer
  end

  API-->>U: response (logs include isFollowUp and carried file/attachment IDs)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • zereraz
  • shivamashtikar
  • kalpadhwaryu
  • devesh-juspay
  • naSim087

Poem

I hop through histories, flags held high,
I stitch the follow-ups and chase the why.
I gather files and stop the break,
Clean up temp crumbs for goodness' sake.
A rabbit's nod — the pipeline's spry 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title Check ❓ Inconclusive The title “Fix/follow up context” references the follow-up context work but is vague and not a clear sentence summarizing the core change of gathering follow-up query context for attached files. Please update the title to a concise, descriptive sentence such as “Add follow-up query context handling for attached files” to clearly convey the main change.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 88bd2eb and 6d4b37f.

📒 Files selected for processing (1)
  • server/api/chat/chat.ts (4 hunks)

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.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the follow-up context gathering logic, centralizing it into new utility functions and applying it to both the standard chat and agent-based chat APIs. A new helper transformMessagesWithErrorHandling is introduced to normalize conversation history by injecting synthetic error responses. While the refactoring is a good step towards reducing code duplication and improving clarity, I've identified a few critical issues. There's a regression where file context from the current message is being overwritten instead of merged during follow-up queries. Additionally, a new utility function contains a logical bug in its condition that could lead to incorrect conversation history processing. I've also pointed out a minor maintainability issue with a brittle string check.

@Himanshvarma Himanshvarma requested a review from naSim087 October 10, 2025 08:07
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/api/chat/utils.ts (1)

98-145: Chain-break boundary applied after processing; stop before including boundary message

You currently process the chain-break message’s attachments/sources and then break, which can leak previous-topic context. Break before processing the boundary index.

   for (let i = startIdx; i >= 0 && hops < maxHops; i--, hops++) {
     const m = messages[i];
+    // Stop if we hit a chain break (previous conversation topic)
+    if (chainBreakIndices.has(i)) break

     // 1) attachments the user explicitly added
     if (Array.isArray(m.attachments)) {
       ...
     }
     ...
-    // Stop if we hit a chain break (previous conversation topic)
-    if (chainBreakIndices.has(i)) break
   }
🧹 Nitpick comments (3)
server/lib/duckdb.ts (1)

240-249: Simplify: Remove redundant ENOENT check.

The ENOENT check in the catch block is redundant since unlinkWithRetry already handles ENOENT by returning early without throwing (line 22).

Apply this diff to simplify the error handling:

     try {
       await unlinkWithRetry(dbPath);
       Logger.debug(`Temporary DuckDB file deleted: ${dbPath}`);
     } catch (e: any) {
-      if (e?.code === 'ENOENT') {
-        Logger.debug(`Temporary DuckDB file already removed: ${dbPath}`);
-      } else {
-        Logger.warn(`Failed to delete temporary DuckDB file ${dbPath}:`, e);
-      }
+      Logger.warn(`Failed to delete temporary DuckDB file ${dbPath}:`, e);
     }
server/api/chat/agents.ts (1)

4368-4376: Clarify boolean precedence for file/image context check

Add parentheses for readability (no behavior change).

-                  if (fileIds && fileIds.length > 0 || imageAttachmentFileIds && imageAttachmentFileIds.length > 0) {
+                  if ((fileIds && fileIds.length > 0) || (imageAttachmentFileIds && imageAttachmentFileIds.length > 0)) {
server/api/chat/chat.ts (1)

5187-5205: Tighten condition and remove unnecessary casts

  • Add parentheses for clarity.
  • No need to cast fileIds/imageAttachmentFileIds to string[].
-                if (fileIds && fileIds.length > 0 || imageAttachmentFileIds && imageAttachmentFileIds.length > 0) {
+                if ((fileIds && fileIds.length > 0) || (imageAttachmentFileIds && imageAttachmentFileIds.length > 0)) {
                   loggerWithChild({ email: email }).info(
                     `Follow-up query with file context detected. Using file-based context with NEW classification: ${JSON.stringify(classification)}, FileIds: ${JSON.stringify([fileIds, imageAttachmentFileIds])}`,
                   )
                   iterator = UnderstandMessageAndAnswerForGivenContext(
                     email,
                     ctx,
                     userMetadata,
                     message,
                     0.5,
-                    fileIds as string[],
+                    fileIds,
                     userRequestsReasoning,
                     understandSpan,
                     undefined,
-                    imageAttachmentFileIds as string[],
+                    imageAttachmentFileIds,
                     agentPromptValue,
                     undefined,
                     actualModelId || config.defaultBestModel,
                   )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb21713 and 7fc3a69.

📒 Files selected for processing (4)
  • server/api/chat/agents.ts (4 hunks)
  • server/api/chat/chat.ts (5 hunks)
  • server/api/chat/utils.ts (5 hunks)
  • server/lib/duckdb.ts (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
server/api/chat/utils.ts (1)
server/db/schema/messages.ts (2)
  • messages (31-78)
  • SelectMessage (88-88)
server/api/chat/chat.ts (3)
server/search/vespa.ts (1)
  • searchVespaInFiles (117-117)
server/api/chat/utils.ts (2)
  • transformMessagesWithErrorHandling (1298-1343)
  • collectFollowupContext (80-152)
server/db/schema/messages.ts (1)
  • messages (31-78)
server/api/chat/agents.ts (4)
server/ai/types.ts (3)
  • TemporalClassifier (279-282)
  • QueryRouterResponse (461-461)
  • ConverseResponse (311-323)
server/api/chat/types.ts (1)
  • ImageCitation (80-86)
server/api/chat/utils.ts (2)
  • transformMessagesWithErrorHandling (1298-1343)
  • collectFollowupContext (80-152)
server/api/chat/chat.ts (2)
  • UnderstandMessageAndAnswerForGivenContext (3881-3932)
  • UnderstandMessageAndAnswer (3744-3879)
🪛 GitHub Actions: TypeScript Build Check
server/api/chat/chat.ts

[error] 1990-1990: bunx tsc -b failed: Property 'attachmentRank' does not exist on type 'typeof SearchModes'.

🔇 Additional comments (5)
server/lib/duckdb.ts (2)

59-69: LGTM! Robust stream completion pattern.

The refactored flow properly waits for both the end() callback (which fires when 'finish' occurs) and the 'close' event, ensuring the stream is fully flushed. The error handler cleanup prevents potential memory leaks.


218-225: LGTM! Defensive VIEW cleanup.

Dropping the VIEW before closing the connection prevents potential resource leaks in DuckDB. The try-catch ensures cleanup continues even if the VIEW doesn't exist or can't be dropped.

server/api/chat/agents.ts (2)

4352-4356: Good call: transform messages before follow-up carry-forward

Using transformMessagesWithErrorHandling prior to collectFollowupContext prevents gaps when user errors lacked assistant replies. LGTM.


4295-4307: Avoid excess property error on classification

  • Extend QueryRouterResponseSchema with isFollowUp?: boolean (preferred)
  • Or locally widen the type:
    (TemporalClassifier & QueryRouterResponse) & { isFollowUp?: boolean }
server/api/chat/chat.ts (1)

5171-5185: Follow-up carry-forward integration looks good

Using the transformed history with collectFollowupContext and updating fileIds/imageAttachmentFileIds is sound.

Please confirm collectFollowupContext is intended to treat only image attachments as attachmentFileIds (utils.ts Lines 79–151 in provided snippet).

naSim087
naSim087 previously approved these changes Oct 13, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/api/chat/chat.ts (1)

3402-3416: Build error: remove unsupported 'selectedItem' from getItems params (or extend type)

selectedItem is not part of GetItemsParams; tsc fails.

-        searchResults = await getItems({
+        searchResults = await getItems({
           email,
           schema,
           app: agentApps ?? null,
           entity: entities ?? null,
           timestampRange,
           limit: userSpecifiedCountLimit + (classification.filters.offset || 0),
           offset: classification.filters.offset || 0,
           asc: sortDirection === "asc",
           intent: resolvedIntent || {},
           channelIds,
-          selectedItem: selectedItem,
           collectionSelections: agentSpecificCollectionSelections,
         })
-      const getItemsParams = {
+      const getItemsParams = {
         email,
         schema,
         app: apps ?? null,
         entity: entities ?? null,
         timestampRange,
         limit: userSpecifiedCountLimit + (classification.filters.offset || 0),
         offset: classification.filters.offset || 0,
         asc: sortDirection === "asc",
         intent: resolvedIntent || {},
         collectionSelections: agentSpecificCollectionSelections,
-        selectedItem: selectedItem,
       }

If selectedItem is required, extend GetItemsParams in @xyne/vespa-ts/types accordingly.

Also applies to: 3425-3441

♻️ Duplicate comments (4)
server/api/chat/utils.ts (1)

131-140: Guard against missing/invalid source.docId before pushing

m.sources entries can lack a valid docId, causing "f:undefined" in seen and pushing undefined into ws.fileIds. Add a per‑item guard.

-    if (Array.isArray(m.sources) && m.sources.length > 0 && ws.fileIds.length < MAX_FILES) {
-      for (const source of m.sources) {
-        if (!seen.has(`f:${source.docId}`)) {
-          ws.fileIds.push(source.docId);
-          ws.carriedFromMessageIds.push(m.externalId);
-          seen.add(`f:${source.docId}`);
-          if (ws.fileIds.length >= MAX_FILES) break;
-        }
-      }
-    }
+    if (Array.isArray(m.sources) && m.sources.length > 0 && ws.fileIds.length < MAX_FILES) {
+      for (const source of m.sources as any[]) {
+        const docId = (source as any)?.docId
+        if (typeof docId === "string" && docId && !seen.has(`f:${docId}`)) {
+          ws.fileIds.push(docId)
+          ws.carriedFromMessageIds.push(m.externalId)
+          seen.add(`f:${docId}`)
+          if (ws.fileIds.length >= MAX_FILES) break
+        }
+      }
+    }
server/api/chat/agents.ts (1)

4351-4372: Don’t overwrite existing file context—merge follow-up context

Overwriting fileIds and imageAttachmentFileIds drops attachments from the current message and extracted IDs. Replace with a union of existing and carried IDs:

-                  if (hasCarriedContext) {
-                    fileIds = workingSet.fileIds;
-                    imageAttachmentFileIds = workingSet.attachmentFileIds;
+                  if (hasCarriedContext) {
+                    fileIds = Array.from(new Set([...(fileIds || []), ...workingSet.fileIds]));
+                    imageAttachmentFileIds = Array.from(
+                      new Set([...(imageAttachmentFileIds || []), ...workingSet.attachmentFileIds])
+                    );
                     loggerWithChild({ email }).info(
                       `Carried forward context from follow-up: ${JSON.stringify(workingSet)}`,
                     );
                   }
server/api/chat/chat.ts (2)

1975-2006: Fix attachment/collection bucketing, remove brittle prefix checks, avoid shadowing, and replace invalid rankProfile

  • att_ must be treated as attachments (legacy) not collection files.
  • Non-collection must exclude both clf- and attachment prefixes.
  • Local const attachmentFileIds shadows function param; rename.
  • SearchModes.attachmentRank is invalid (build breaks).

Apply:

-      const collectionFileIds = fileIds.filter((fid) => fid.startsWith("clf-") || fid.startsWith("att_"))
-      const nonCollectionFileIds = fileIds.filter((fid) => !fid.startsWith("clf-") && !fid.startsWith("att"))
-      const attachmentFileIds = fileIds.filter((fid) => fid.startsWith("attf_"))
+      const isCollectionId = (fid: string) => fid.startsWith("clf-")
+      const isAttachmentId = (fid: string) => fid.startsWith("attf_") || fid.startsWith("att_") // new + legacy
+      const collectionFileIds = fileIds.filter(isCollectionId)
+      const nonCollectionFileIds = fileIds.filter(
+        (fid) => !isCollectionId(fid) && !isAttachmentId(fid)
+      )
+      const attachmentDocIds = fileIds.filter(isAttachmentId)
@@
-      if(attachmentFileIds && attachmentFileIds.length > 0) {
-        results = await searchVespaInFiles(builtUserQuery, email, attachmentFileIds, {
-          limit: fileIds?.length,
-          alpha: userAlpha,
-          rankProfile: SearchModes.attachmentRank,
-        })
+      if (attachmentDocIds.length > 0) {
+        results = await searchVespaInFiles(builtUserQuery, email, attachmentDocIds, {
+          limit: fileIds?.length,
+          alpha: userAlpha,
+          // Prefer dedicated attachment profile if available; else fallback.
+          rankProfile: (SearchModes as any).AttachmentRank ?? SearchModes.NativeRank,
+        })
         if (results.root.children) {
           combinedSearchResponse.push(...results.root.children)
         }
       }

To confirm the enum member:

#!/bin/bash
ast-grep --pattern $'enum $_ { $$$ }' | sed -n '1,120p' >/dev/null 2>&1
rg -nP 'SearchModes\.\w+' -C2
rg -nP '\bAttachmentRank\b' -C2

5217-5255: Do not overwrite carried context; merge with current message context

Replacing fileIds/imageAttachmentFileIds drops context from the current message. Merge and dedupe.

-                const workingSet = collectFollowupContext(filteredMessages);
+                const workingSet = collectFollowupContext(filteredMessages);
@@
-                if (hasCarriedContext) {
-                  fileIds = workingSet.fileIds;
-                  imageAttachmentFileIds = workingSet.attachmentFileIds;
+                if (hasCarriedContext) {
+                  fileIds = Array.from(new Set([...(fileIds || []), ...workingSet.fileIds]));
+                  imageAttachmentFileIds = Array.from(
+                    new Set([...(imageAttachmentFileIds || []), ...workingSet.attachmentFileIds])
+                  );
                   loggerWithChild({ email: email }).info(
                     `Carried forward context from follow-up: ${JSON.stringify(workingSet)}`,
                   );
                 }
🧹 Nitpick comments (1)
server/api/chat/agents.ts (1)

4374-4393: Add parentheses for clarity in mixed boolean condition

Avoid precedence confusion in (a && b || c && d).

-                  if (fileIds && fileIds.length > 0 || imageAttachmentFileIds && imageAttachmentFileIds.length > 0) {
+                  if ((fileIds && fileIds.length > 0) || (imageAttachmentFileIds && imageAttachmentFileIds.length > 0)) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3d7f351 and 88bd2eb.

📒 Files selected for processing (3)
  • server/api/chat/agents.ts (3 hunks)
  • server/api/chat/chat.ts (4 hunks)
  • server/api/chat/utils.ts (4 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-16T11:56:22.752Z
Learnt from: oindrila-b
PR: xynehq/xyne#545
File: server/integrations/google/index.ts:137-145
Timestamp: 2025-06-16T11:56:22.752Z
Learning: In server/integrations/google/index.ts, both Logger (base logger) and loggerWithChild (factory for email-scoped child loggers) are intentionally maintained to handle different logging scenarios - one for when email context is not available and one for when it is available.

Applied to files:

  • server/api/chat/agents.ts
🧬 Code graph analysis (3)
server/api/chat/chat.ts (3)
server/search/vespa.ts (1)
  • searchVespaInFiles (118-118)
server/db/schema/messages.ts (1)
  • messages (31-78)
server/api/chat/utils.ts (1)
  • collectFollowupContext (80-152)
server/api/chat/utils.ts (1)
server/db/schema/messages.ts (1)
  • messages (31-78)
server/api/chat/agents.ts (4)
server/ai/types.ts (3)
  • TemporalClassifier (279-282)
  • QueryRouterResponse (461-461)
  • ConverseResponse (311-323)
server/api/chat/types.ts (1)
  • ImageCitation (80-86)
server/api/chat/utils.ts (1)
  • collectFollowupContext (80-152)
server/api/chat/chat.ts (2)
  • UnderstandMessageAndAnswerForGivenContext (3919-3970)
  • UnderstandMessageAndAnswer (3782-3917)
🪛 GitHub Actions: TypeScript Build Check
server/api/chat/chat.ts

[error] 2001-2001: Property 'attachmentRank' does not exist on type 'typeof SearchModes'.


[error] 3412-3412: Object literal may only specify known properties, and 'selectedItem' does not exist in type 'Omit<GetItemsParams, "processedCollectionSelections"> & { collectionSelections?: { collectionIds?: string[] | undefined; collectionFolderIds?: string[] | undefined; collectionFileIds?: string[] | undefined; }[] | undefined; }'.

🔇 Additional comments (4)
server/api/chat/utils.ts (2)

143-145: Confirm chain‑break boundary semantics

You break after processing the chain‑break index. If the intent is to exclude the break message’s context, move the check before processing the loop body.


80-85: Deriving start index internally looks good

Starting from the latest message by default is sensible for follow‑ups.

If any caller relied on a custom startIdx previously, confirm no regressions.

server/api/chat/agents.ts (1)

4139-4147: Initialize parsed.isFollowUp default; verify upstream JSON shape

Defaulting isFollowUp to false is fine. Ensure jsonParseLLMOutput emits isFollowUp when applicable so classification remains accurate.

server/api/chat/chat.ts (1)

4733-4742: Avoid history truncation bug with synthetic messages
Slicing by messages.length - 1 can drop the wrong entries when synthetic messages are inserted. Instead, apply an error-handling transform and cut off at the last user message’s externalId:

const transformed = transformMessagesWithErrorHandling(messages);
const lastUser = messages[messages.length - 1];
const cutoff = transformed.findIndex(m => m.externalId === lastUser.externalId);
const filteredMessages = (cutoff >= 0
  ? transformed.slice(0, cutoff)
  : transformed.slice(0, transformed.length - 1)
)
  .filter(msg => !msg?.errorMessage)
  .filter(msg => !(msg.messageRole === MessageRole.Assistant && !msg.message));

Ensure transformMessagesWithErrorHandling is defined and imported from the correct module.

junaid-shirur
junaid-shirur previously approved these changes Oct 13, 2025
@junaid-shirur junaid-shirur merged commit 3e54f51 into main Oct 13, 2025
3 of 4 checks passed
@junaid-shirur junaid-shirur deleted the fix/followUpContext branch October 13, 2025 13:49
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.

3 participants