[PR #59] [CLOSED] [WIP] Fix file state loss during multiple file operations #91

Closed
opened 2026-02-16 06:17:08 -05:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/langchain-ai/deepagentsjs/pull/59
Author: @Copilot
Created: 11/18/2025
Status: Closed

Base: mainHead: copilot/fix-file-state-loss


📝 Commits (1)

📄 Description

Thanks for asking me to work on this. I will get started on it and keep this PR's description up to date as I form a plan and make progress.

Original prompt

Bug: File state is lost when multiple file operations are performed

Problem Description

When tools that update files (like write_file or edit_file) are called, the new state in "files" only contains the most recently edited file. All other previously existing files disappear from the state.

Root Cause

The issue is in the wrapToolCall function in src/middleware/fs.ts (around lines 476-510). When accumulating file updates from multiple tool calls, the function only considers the updates from the current Command but doesn't preserve the existing state.

Specifically, this line:

const accumulatedFiles: Record<string, FileData> = {
  ...(update.files || {}),
};

Only spreads update.files (which might be empty or only contain the current update), but never includes the existing files from request.state.files.

Expected Behavior

When a file is written or edited:

  1. The modified file should be updated in the state
  2. All other existing files should remain in the state
  3. The fileDataReducer should properly merge the updates with the existing state

Solution

The accumulatedFiles initialization should include the current state:

const accumulatedFiles: Record<string, FileData | null> = {
  ...(request.state?.files || {}),  // Include existing files from state
  ...(update.files || {}),
};

Alternatively, the fileDataReducer should be called manually when processing file updates:

let accumulatedFiles = request.state?.files || {};

for (const msg of update.messages) {
  if (msg instanceof ToolMessage) {
    const processed = await processToolMessage(msg);
    processedMessages.push(processed.message);

    if (processed.filesUpdate) {
      hasLargeResults = true;
      // Manually call the reducer to properly merge updates
      accumulatedFiles = fileDataReducer(accumulatedFiles, processed.filesUpdate);
    }
  } else {
    processedMessages.push(msg);
  }
}

Impact

This bug causes significant data loss - all files except the most recently modified one disappear from the state after each file operation, making it impossible to maintain a proper filesystem state across multiple operations.

This pull request was created as a result of the following prompt from Copilot chat.

Bug: File state is lost when multiple file operations are performed

Problem Description

When tools that update files (like write_file or edit_file) are called, the new state in "files" only contains the most recently edited file. All other previously existing files disappear from the state.

Root Cause

The issue is in the wrapToolCall function in src/middleware/fs.ts (around lines 476-510). When accumulating file updates from multiple tool calls, the function only considers the updates from the current Command but doesn't preserve the existing state.

Specifically, this line:

const accumulatedFiles: Record<string, FileData> = {
  ...(update.files || {}),
};

Only spreads update.files (which might be empty or only contain the current update), but never includes the existing files from request.state.files.

Expected Behavior

When a file is written or edited:

  1. The modified file should be updated in the state
  2. All other existing files should remain in the state
  3. The fileDataReducer should properly merge the updates with the existing state

Solution

The accumulatedFiles initialization should include the current state:

const accumulatedFiles: Record<string, FileData | null> = {
  ...(request.state?.files || {}),  // Include existing files from state
  ...(update.files || {}),
};

Alternatively, the fileDataReducer should be called manually when processing file updates:

let accumulatedFiles = request.state?.files || {};

for (const msg of update.messages) {
  if (msg instanceof ToolMessage) {
    const processed = await processToolMessage(msg);
    processedMessages.push(processed.message);

    if (processed.filesUpdate) {
      hasLargeResults = true;
      // Manually call the reducer to properly merge updates
      accumulatedFiles = fileDataReducer(accumulatedFiles, processed.filesUpdate);
    }
  } else {
    processedMessages.push(msg);
  }
}

Impact

This bug causes significant data loss - all files except the most recently modified one disappear from the state after each file operation, making it impossible to maintain a proper filesystem state across multiple operations.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/langchain-ai/deepagentsjs/pull/59 **Author:** [@Copilot](https://github.com/apps/copilot-swe-agent) **Created:** 11/18/2025 **Status:** ❌ Closed **Base:** `main` ← **Head:** `copilot/fix-file-state-loss` --- ### 📝 Commits (1) - [`49a2543`](https://github.com/langchain-ai/deepagentsjs/commit/49a254316bb5daa0ad4fb09cb9250cde258aa109) Initial plan ### 📄 Description Thanks for asking me to work on this. I will get started on it and keep this PR's description up to date as I form a plan and make progress. <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > ## Bug: File state is lost when multiple file operations are performed > > ### Problem Description > > When tools that update files (like `write_file` or `edit_file`) are called, the new state in "files" only contains the most recently edited file. All other previously existing files disappear from the state. > > ### Root Cause > > The issue is in the `wrapToolCall` function in `src/middleware/fs.ts` (around lines 476-510). When accumulating file updates from multiple tool calls, the function only considers the updates from the current Command but doesn't preserve the existing state. > > Specifically, this line: > ```typescript > const accumulatedFiles: Record<string, FileData> = { > ...(update.files || {}), > }; > ``` > > Only spreads `update.files` (which might be empty or only contain the current update), but never includes the existing files from `request.state.files`. > > ### Expected Behavior > > When a file is written or edited: > 1. The modified file should be updated in the state > 2. All other existing files should remain in the state > 3. The `fileDataReducer` should properly merge the updates with the existing state > > ### Solution > > The `accumulatedFiles` initialization should include the current state: > > ```typescript > const accumulatedFiles: Record<string, FileData | null> = { > ...(request.state?.files || {}), // Include existing files from state > ...(update.files || {}), > }; > ``` > > Alternatively, the `fileDataReducer` should be called manually when processing file updates: > > ```typescript > let accumulatedFiles = request.state?.files || {}; > > for (const msg of update.messages) { > if (msg instanceof ToolMessage) { > const processed = await processToolMessage(msg); > processedMessages.push(processed.message); > > if (processed.filesUpdate) { > hasLargeResults = true; > // Manually call the reducer to properly merge updates > accumulatedFiles = fileDataReducer(accumulatedFiles, processed.filesUpdate); > } > } else { > processedMessages.push(msg); > } > } > ``` > > ### Impact > > This bug causes significant data loss - all files except the most recently modified one disappear from the state after each file operation, making it impossible to maintain a proper filesystem state across multiple operations. </details> *This pull request was created as a result of the following prompt from Copilot chat.* > ## Bug: File state is lost when multiple file operations are performed > > ### Problem Description > > When tools that update files (like `write_file` or `edit_file`) are called, the new state in "files" only contains the most recently edited file. All other previously existing files disappear from the state. > > ### Root Cause > > The issue is in the `wrapToolCall` function in `src/middleware/fs.ts` (around lines 476-510). When accumulating file updates from multiple tool calls, the function only considers the updates from the current Command but doesn't preserve the existing state. > > Specifically, this line: > ```typescript > const accumulatedFiles: Record<string, FileData> = { > ...(update.files || {}), > }; > ``` > > Only spreads `update.files` (which might be empty or only contain the current update), but never includes the existing files from `request.state.files`. > > ### Expected Behavior > > When a file is written or edited: > 1. The modified file should be updated in the state > 2. All other existing files should remain in the state > 3. The `fileDataReducer` should properly merge the updates with the existing state > > ### Solution > > The `accumulatedFiles` initialization should include the current state: > > ```typescript > const accumulatedFiles: Record<string, FileData | null> = { > ...(request.state?.files || {}), // Include existing files from state > ...(update.files || {}), > }; > ``` > > Alternatively, the `fileDataReducer` should be called manually when processing file updates: > > ```typescript > let accumulatedFiles = request.state?.files || {}; > > for (const msg of update.messages) { > if (msg instanceof ToolMessage) { > const processed = await processToolMessage(msg); > processedMessages.push(processed.message); > > if (processed.filesUpdate) { > hasLargeResults = true; > // Manually call the reducer to properly merge updates > accumulatedFiles = fileDataReducer(accumulatedFiles, processed.filesUpdate); > } > } else { > processedMessages.push(msg); > } > } > ``` > > ### Impact > > This bug causes significant data loss - all files except the most recently modified one disappear from the state after each file operation, making it impossible to maintain a proper filesystem state across multiple operations. <!-- START COPILOT CODING AGENT TIPS --> --- 💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey). --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-02-16 06:17:08 -05:00
yindo closed this issue 2026-02-16 06:17:08 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/deepagentsjs#91