Skip to content

🎯 feat: Tolerant Workspace Edits with Host-Rendered Conflict Diagnostics - #16520

Merged
danny-avila merged 5 commits into
devfrom
danny-avila/workspace-edit-matching
Sep 29, 2026
Merged

danny-avila merged 5 commits into
devfrom
danny-avila/workspace-edit-matching

Conversation

@danny-avila

@danny-avila danny-avila commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

edit_file in an attached (BYOM) workspace is the strictest of LibreChat's four edit_file variants, and the least informative when it fails. Over 10 days on one deployment, 125 of 2,935 calls (4.3%) failed with EDIT_CONFLICT, and 94 of those were multi-edit batches. Each failure reached the model the same way: the worker's JSON body with its newlines escaped, followed by a suffix saying "did not match exactly once… Re-read the file and retry". That suffix was appended to every 409, including a file that changed while the edit was in flight. The model could not tell which edit failed or why, so it retried blindly or re-read the whole file.

LibreChat-AI/code-interpreter#271 gives the worker per-edit diagnostics and two negotiated edit features: tolerant_match (whitespace-tolerant fallback) and replace_all. This PR is the LibreChat side:

  • Negotiation: it reads the worker's editFileFeatures from its status and carries them into the selected workspace.
  • Tolerant matching: it sends matching: 'tolerant' on edits and previews whenever the worker negotiated tolerant_match. So attached edits now tolerate trailing whitespace, CRLF and indentation shifts, as skill and sandbox edits already do. Operators can require exact matching with configSchema.edits.tolerantMatching: false. A match must still be unique unless replace_all is set.
  • replace_all: the edit_file schema gets replace_all, top level and per edit, for every variant.
    • On attached workspaces it is sent only when the worker negotiated replace_all. Otherwise it is refused before dispatch with a clear message.
    • Skill-file and sandbox edits support it in LibreChat's own matcher.
  • Conflict messages: a 409 never forwards worker text. parseEditConflict accepts only the worker's fixed diagnostic grammar and keeps bounded facts: which edits failed, not-found or ambiguous, counts, up to five line numbers, the strategy, and known hint kinds. Quoted file excerpts are dropped. formatEditConflict renders LibreChat's own sentences from those facts. A file that changed mid-edit gets its own message; anything outside the grammar gets generic retry guidance.
  • Bounded replace_all: exact matches are counted without retaining positions and rebuilt with split/join after a projected-size check. The whitespace-tolerant fallback stops collecting at 10,000 ranges.
  • Success text: it names any edit that matched by a non-exact strategy or replaced several locations. Edits that all matched exactly keep the current wording.
  • Tool descriptions: they describe replace_all, the whitespace-tolerant fallback on current workers, and the new failure reporting.

With an older worker or Code API, none of these fields are sent, and requests, results and messages stay exactly as they are today.

Depends on LibreChat-AI/code-interpreter#271 for the new worker behavior. Merging this first is safe: without the worker change, no features are advertised and nothing changes.

How it works

Code API worker status ── editFileFeatures ──> getCodeBridgeWorkerStatus (known names only)
  -> resolveCodeExecutionWorkspaceContext: codeWorkspace.editFileFeatures
    -> handleAttachedWorkspaceEditFileCall
         replace_all requested but not negotiated   -> refuse before dispatch
         tolerant_match negotiated (unless disabled)  -> matching: 'tolerant' (edit + protected preview)
         409 EDIT_CONFLICT                            -> parse facts -> host-rendered message / changed-file / generic
         result.matches                               -> per-edit strategy and occurrence notes
  • The transport (code/workspace.ts) accepts matching and per-edit replaceAll in requests.
  • Results must carry matches exactly when the request opted in: exact strategies only for non-tolerant requests, and more than one occurrence only for replaceAll edits. This mirrors the worker's own validation.
  • WorkspaceToolHttpError.editConflict exposes the worker's EDIT_CONFLICT text.
  • The feature and strategy names live in code/edits.ts, so bridge.ts and workspace.ts share them without an import cycle.

Type of change

  • Feature
  • Bug fix

Testing

Tested environments/configuration:

  • Node 24.16.0; unit and integration tests only. The live BYOM path needs code-interpreter#271 deployed to a worker.

Automated tests:

  • packages/api: npx jest src/agents/handlers.spec.ts src/code/workspace.spec.ts src/code/bridge.spec.ts src/code/capabilities.spec.ts src/agents/tools.spec.ts src/code/workspace.lanes.spec.ts, 489 passed. New coverage:
    • opting into tolerant matching and replace_all only when negotiated;
    • refusing replace_all before dispatch on a legacy worker;
    • diagnostic, changed-file and legacy 409 messages;
    • skill-file replace_all;
    • request and result validation for matching, replaceAll and matches;
    • parsing negotiated features (unknown names dropped) and carrying them into the workspace context.
  • api: npx jest server/services/Files/Code/process.spec.js, 166 passed, including forwarding matching and replaceAll on edits and previews.
  • npx tsc --noEmit in packages/api; eslint on the changed files; the pre-commit circular-dependency check.

Screenshots / recordings

Not applicable. No UI change; the tool result text changes only when a worker reports non-exact matches.

@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-29T20:25:41.494447Z db43838 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f9220dd621

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/api/src/agents/handlers.ts Outdated
Comment thread packages/api/src/agents/handlers.ts Outdated
Comment thread packages/api/src/agents/handlers.ts
@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review the latest head

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6302f23157

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/api/src/agents/handlers.ts
Comment thread packages/api/src/agents/handlers.ts
@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review the latest head

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ba17a0534c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/api/src/agents/handlers.ts Outdated
Comment thread packages/api/src/agents/tools.ts Outdated
@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review the latest head

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

parameters: attachedFileAuthoringParameters(CODE_EDIT_FILE_PARAMETERS, false),

P2 Badge Hide replace_all from legacy attached workers

When the selected attached worker does not advertise replace_all, this definition still exposes and recommends the option because the attached tool unconditionally reuses CODE_EDIT_FILE_PARAMETERS; any model call that follows that schema is then guaranteed to fail at the capability guard in handleAttachedWorkspaceEditFileCall. Build the attached definition from codeWorkspace.editFileFeatures (or explicitly describe the option as unavailable) so mixed-version deployments do not advertise an operation they reject.

AGENTS.md reference: AGENTS.md:L44-L47

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/api/src/agents/handlers.ts Outdated
Comment thread api/server/services/Files/Code/process.js Outdated
@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review the latest head, final review. no further reviews will be requested, last chance

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: db43838471

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@danny-avila danny-avila changed the title 🎯 feat: Opt Into Tolerant Workspace Edits and Pass Worker Diagnostics Through 🎯 feat: Tolerant Workspace Edits with Host-Rendered Conflict Diagnostics Sep 29, 2026
@danny-avila
danny-avila merged commit 3e19b18 into dev Sep 29, 2026
44 checks passed
@danny-avila
danny-avila deleted the danny-avila/workspace-edit-matching branch September 29, 2026 20:55
AnJuHyppolite pushed a commit to newjersey/nj-ai-assistant that referenced this pull request Sep 30, 2026
…ics (LibreChat-AI#16520)

* 🎯 feat: Opt Into Tolerant Workspace Edits and Pass Worker Diagnostics Through

* 🛡️ fix: Gate Tolerant Edits Behind Config, Render Worker Conflicts From Parsed Facts, Bound replace_all

* ⚖️ fix: Default Workspace Edits to Tolerant Matching and Stream Exact replace_all

* 🧱 fix: Build Exact replace_all Output in Bounded Chunks and Describe Both Matching Modes

* 🧹 fix: Keep Worker Conflict Bodies Out of Logs and Edit Matching Out of CJS
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