/**
 * Strips repetitive boilerplate from `@librechat/agents` code-execution
 * tool output before LibreChat re-injects it into the assistant's
 * conversation history.
 *
 * The bash executor in `@librechat/agents` appends two kinds of noise
 * to every successful run:
 *
 * 1. **Trailing "Note:" paragraphs** — long behavioral hints repeating
 *    rules the agent already has via its system prompt
 *    ("Files from previous executions are automatically available...",
 *    "Files in 'Available files' are inputs..."). Re-stating them on
 *    every tool call wastes tokens at scale (50+ tokens × N tool calls).
 *
 * 2. **Per-file annotations** — each file in the `Generated files:` /
 *    `Available files (...):` lists gets a `| <annotation>` suffix
 *    (`File is already downloaded by the user`,
 *    `Image is already displayed to the user`,
 *    `Available as an input — already known to the user`). The two
 *    section headers already convey the new-vs-known distinction; the
 *    per-file annotations are redundant *and* phrased inconsistently
 *    ("downloaded" vs. "displayed" vs. "known to the user").
 *
 * Stripping happens in LibreChat (this file), not upstream, so the
 * cleaning is reversible — pin to a specific upstream version and the
 * patterns adjust here without releasing a new agents build. The
 * patterns are anchored conservatively: only the documented forms are
 * matched, so a future upstream string change leaves user-authored
 * `Note:` lines (or legitimate `|`-delimited filenames) untouched.
 */

/**
 * Matches a `Generated files:` or `Available files (...)` block —
 * the section header line plus the file-listing lines that follow.
 *
 * Group 1 captures the header (with trailing newline). Group 2
 * captures the file lines (each starts with `- /` per the executor's
 * format, accommodating both line-per-file (≥ 4 files) and inline
 * comma-separated (≤ 3 files: `- /a.txt | <ann>, - /b.txt | <ann>`)
 * layouts because the latter is still a single line that begins with
 * `- /`).
 *
 * The `Available files (...)` form has parenthesized content
 * (`(inputs, not generated by this execution)`) which the
 * `\([^)]*\)` segment matches without baking the exact phrasing in.
 *
 * Block ends at the first line that doesn't start with `- /` (next
 * iteration of the `+` quantifier fails). The blank line preceding
 * the trailing `Note:` paragraphs reliably terminates the block.
 */
const FILE_SECTION_PATTERN =
  /((?:Generated files:|Available files \([^)]*\):)\n)((?:- \/[^\n]*(?:\n|$))+)/g;

/**
 * Matches the per-file `| <annotation>` suffix the bash executor adds to
 * each file inside a `Generated files:` / `Available files (...):` block.
 * Two listing formats: line-per-file (≥ 4 files) and inline
 * comma-separated (≤ 3 files: `- /mnt/a.txt | <ann>, - /mnt/b.txt | <ann>`).
 * The non-greedy `[^,\n]*?` plus the `(?=,|\n|$)` boundary stops the match
 * at either end-of-line or the inline `, ` separator so an inline list
 * strips each file's annotation independently.
 *
 * Applied ONLY within file-section blocks captured by
 * `FILE_SECTION_PATTERN`, never globally — a user script that legitimately
 * echoes one of these phrases (`echo 'foo | File is already downloaded by
 * the user'`) would otherwise have its stdout silently mutated.
 */
const PER_FILE_ANNOTATION_PATTERN =
  /\s*\|\s*(?:File is already downloaded by the user|Image is already displayed to the user|Available as an input[^,\n]*?)(?=,|\n|$)/g;

/**
 * Matches the bash executor's trailing `Note:` paragraphs. Anchored to
 * the two known boilerplate openings (`Files from previous executions`,
 * `Files in "Available files"`) so a user-authored `Note:` line — even
 * one preceded by a blank line in stdout — is not eaten by the
 * `[\s\S]*$` tail. New upstream variants need to be added here
 * explicitly; that's the trade-off for not silently dropping content.
 */
const TRAILING_NOTES_PATTERN =
  /\n\s*\n\s*Note:\s*(?:Files from previous executions|Files in "Available files")[\s\S]*$/;

/**
 * Returns `content` with the bash-executor boilerplate removed. Safe
 * to call on any tool output — non-matching text is returned unchanged.
 *
 * Annotation stripping is scoped: only the contents of `Generated
 * files:` / `Available files (...):` blocks are mutated. Stdout that
 * happens to contain a phrase like
 * `| File is already downloaded by the user` (e.g. a script echoing
 * the very string we're scrubbing) passes through unchanged.
 */
export function cleanCodeToolOutput(content: string): string {
  if (!content) {
    return content;
  }
  const noAnnotations = content.replace(
    FILE_SECTION_PATTERN,
    (_match, header: string, files: string) =>
      header + files.replace(PER_FILE_ANNOTATION_PATTERN, ''),
  );
  const noTrailingNotes = noAnnotations.replace(TRAILING_NOTES_PATTERN, '');
  return noTrailingNotes.trimEnd();
}
